mirror of
https://github.com/strapi/strapi.git
synced 2025-08-16 04:34:40 +00:00
Apply overrides for specified versions
This commit is contained in:
parent
0798cf75f3
commit
19ce046512
@ -17,7 +17,7 @@ module.exports = () => ({
|
||||
documentation: {
|
||||
config: {
|
||||
info: {
|
||||
version: '2.0.0',
|
||||
version: '1.0.0',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -16,12 +16,11 @@ module.exports = {
|
||||
name: 'Apache 2.0',
|
||||
url: 'https://www.apache.org/licenses/LICENSE-2.0.html',
|
||||
},
|
||||
'x-strapi-generation-date': new Date().toISOString(),
|
||||
},
|
||||
'x-strapi-config': {
|
||||
path: '/documentation',
|
||||
plugins: null,
|
||||
customizer: null,
|
||||
mutateDocumentation: null,
|
||||
},
|
||||
servers: [],
|
||||
externalDocs: {
|
||||
|
@ -154,13 +154,15 @@ describe('Documentation service', () => {
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
global.strapi.config.get = () => ({ ...userConfig });
|
||||
const docService = documentation({ strapi: global.strapi });
|
||||
await docService.generateFullDoc();
|
||||
const lastMockCall = fse.writeJson.mock.calls[fse.writeJson.mock.calls.length - 1];
|
||||
const mockFinalDoc = lastMockCall[1];
|
||||
|
||||
expect(mockFinalDoc.info).toEqual(userConfig.info);
|
||||
// The generation data is dynamically added, it cannot be modified by the user
|
||||
const { 'x-generation-date': generationConfig, ...mockFinalDocInfo } = mockFinalDoc.info;
|
||||
expect(mockFinalDocInfo).toEqual(userConfig.info);
|
||||
expect(mockFinalDoc['x-strapi-config']).toEqual(userConfig['x-strapi-config']);
|
||||
expect(mockFinalDoc.externalDocs).toEqual(userConfig.externalDocs);
|
||||
expect(mockFinalDoc.security).toEqual(userConfig.security);
|
||||
@ -319,6 +321,66 @@ describe('Documentation service', () => {
|
||||
'test-new-component'
|
||||
);
|
||||
});
|
||||
it('overrides only the specified version', async () => {
|
||||
const overrideService = override({ strapi: global.strapi });
|
||||
// Simulate override from upload plugin
|
||||
overrideService.registerOverride(
|
||||
{
|
||||
// Only override for version 1.0.0
|
||||
info: { version: '1.0.0' },
|
||||
components: {
|
||||
schemas: {
|
||||
// This component schema exists after generating with mock data, replace it
|
||||
ShouldNotBeAdded: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ pluginOrigin: 'upload' }
|
||||
);
|
||||
// Simulate override from upload plugin
|
||||
overrideService.registerOverride(
|
||||
{
|
||||
// Only override for version 2.0.0
|
||||
info: { version: '2.0.0' },
|
||||
components: {
|
||||
schemas: {
|
||||
// This component schema exists after generating with mock data, replace it
|
||||
ShouldBeAdded: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ pluginOrigin: 'upload' }
|
||||
);
|
||||
// Simulate override from upload plugin
|
||||
overrideService.registerOverride(
|
||||
{
|
||||
components: {
|
||||
schemas: {
|
||||
// This component schema exists after generating with mock data, replace it
|
||||
ShouldAlsoBeAdded: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ pluginOrigin: 'upload' }
|
||||
);
|
||||
global.strapi.plugins.documentation = {
|
||||
service: jest.fn((name) => {
|
||||
const mockServices = {
|
||||
override: overrideService,
|
||||
};
|
||||
|
||||
return mockServices[name];
|
||||
}),
|
||||
};
|
||||
const docService = documentation({ strapi: global.strapi });
|
||||
await docService.generateFullDoc('2.0.0');
|
||||
const lastMockCall = fse.writeJson.mock.calls[fse.writeJson.mock.calls.length - 1];
|
||||
const mockFinalDoc = lastMockCall[1];
|
||||
|
||||
expect(mockFinalDoc.components.schemas.ShouldNotBeAdded).toBeUndefined();
|
||||
expect(mockFinalDoc.components.schemas.ShouldBeAdded).toBeDefined();
|
||||
expect(mockFinalDoc.components.schemas.ShouldAlsoBeAdded).toBeDefined();
|
||||
});
|
||||
it('excludes apis and plugins from generation', async () => {
|
||||
const overrideService = override({ strapi: global.strapi });
|
||||
|
||||
@ -346,12 +408,12 @@ describe('Documentation service', () => {
|
||||
Object.keys(mockFinalDoc.components.schemas).find((compo) => compo.includes('Kitchensink'))
|
||||
).toBeUndefined();
|
||||
});
|
||||
it("applies a user's customizer function", async () => {
|
||||
it("applies a user's mutateDocumentation function", async () => {
|
||||
global.strapi.config.get = () => ({
|
||||
...defaultConfig,
|
||||
'x-strapi-config': {
|
||||
...defaultConfig['x-strapi-config'],
|
||||
customizer(draft) {
|
||||
mutateDocumentation(draft) {
|
||||
draft.paths['/kitchensinks'] = { get: { responses: { 200: { description: 'test' } } } };
|
||||
},
|
||||
},
|
||||
|
@ -176,7 +176,6 @@ module.exports = ({ strapi }) => {
|
||||
'full_documentation.json'
|
||||
);
|
||||
|
||||
// Set config defaults
|
||||
const serverUrl = getAbsoluteServerUrl(strapi.config);
|
||||
const apiPath = strapi.config.get('api.rest.prefix');
|
||||
const generatedDocumentation = produce(config, (draft) => {
|
||||
@ -189,42 +188,49 @@ module.exports = ({ strapi }) => {
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
// Set the generated date
|
||||
draft.info['x-generation-date'] = new Date().toISOString();
|
||||
// Set the plugins that need documentation
|
||||
draft['x-strapi-config'].plugins = pluginsThatNeedDocumentation;
|
||||
// Delete it from the config so it doesn't end up in the spec
|
||||
delete draft['x-strapi-config'].customizer;
|
||||
|
||||
delete draft['x-strapi-config'].mutateDocumentation;
|
||||
// Set the generated paths
|
||||
draft.paths = paths;
|
||||
// Merge the generated component schemas with the defaults
|
||||
draft.components = _.merge(defaultOpenApiComponents, { schemas });
|
||||
// Check for overrides and then add them
|
||||
if (overrideService.registeredOverrides.length > 0) {
|
||||
overrideService.registeredOverrides.forEach((doc) => {
|
||||
// Only run the overrrides when no override version is provided,
|
||||
// or when the generated documentation version matches the override version
|
||||
if (!doc?.info?.version || doc.info.version === version) {
|
||||
if (doc.tags) {
|
||||
// Merge override tags with the generated tags
|
||||
draft.tags = draft.tags || [];
|
||||
draft.tags.push(...doc.tags);
|
||||
}
|
||||
|
||||
overrideService.registeredOverrides.forEach((doc) => {
|
||||
if (doc.tags) {
|
||||
// Merge override tags with the generated tags
|
||||
draft.tags = draft.tags || [];
|
||||
draft.tags.push(...doc.tags);
|
||||
}
|
||||
if (doc.paths) {
|
||||
// Merge override paths with the generated paths
|
||||
// The override will add a new path or replace the value of an existing path
|
||||
draft.paths = { ...draft.paths, ...doc.paths };
|
||||
}
|
||||
|
||||
if (doc.paths) {
|
||||
// Merge override paths with the generated paths
|
||||
// The override will add a new path or replace the value of an existing path
|
||||
draft.paths = { ...draft.paths, ...doc.paths };
|
||||
}
|
||||
|
||||
if (doc.components) {
|
||||
Object.entries(doc.components).forEach(([key, val]) => {
|
||||
draft.components[key] = draft.components[key] || {};
|
||||
// Merge override components with the generated components,
|
||||
// The override will add a new component or replace the value of an existing component
|
||||
draft.components[key] = { ...draft.components[key], ...val };
|
||||
});
|
||||
}
|
||||
});
|
||||
if (doc.components) {
|
||||
Object.entries(doc.components).forEach(([key, val]) => {
|
||||
draft.components[key] = draft.components[key] || {};
|
||||
// Merge override components with the generated components,
|
||||
// The override will add a new component or replace the value of an existing component
|
||||
draft.components[key] = { ...draft.components[key], ...val };
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
// Get the documentation customizer
|
||||
const documentationCustomizer = config['x-strapi-config'].customizer;
|
||||
// Escape hatch, allow the user to provide a customizer function that can manipulate
|
||||
// Get the documentation mutateDocumentation
|
||||
const documentationCustomizer = config['x-strapi-config'].mutateDocumentation;
|
||||
// Escape hatch, allow the user to provide a mutateDocumentation function that can alter any part of
|
||||
// the generated documentation before it is written to the file system
|
||||
const finalDocumentation = documentationCustomizer
|
||||
? produce(generatedDocumentation, documentationCustomizer)
|
||||
|
@ -5,53 +5,48 @@ const { getPluginsThatNeedDocumentation } = require('./utils/get-plugins-that-ne
|
||||
module.exports = ({ strapi }) => {
|
||||
const registeredOverrides = [];
|
||||
const excludedFromGeneration = [];
|
||||
/**
|
||||
*
|
||||
* @param {string | string[]} api - The name of the api or and array of apis to exclude from generation
|
||||
*/
|
||||
const excludeFromGeneration = (api) => {
|
||||
if (Array.isArray(api)) {
|
||||
excludedFromGeneration.push(...api);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
excludedFromGeneration.push(api);
|
||||
};
|
||||
/**
|
||||
* @TODO pluginOrigin should be required in next major release
|
||||
* @param {object} doc - The openapi specifcation to override
|
||||
* @param {object} options - The options to override the documentation
|
||||
* @param {string} options.pluginOrigin - The name of the plugin that is overriding the documentation
|
||||
* @param {string[]} options.excludeFromGeneration - The name of the plugin that is overriding the documentation
|
||||
*/
|
||||
const registerOverride = (override, { pluginOrigin, excludeFromGeneration = [] }) => {
|
||||
const pluginsThatNeedDocumentation = getPluginsThatNeedDocumentation(
|
||||
strapi.config.get('plugin.documentation')
|
||||
);
|
||||
// Don't apply the override if the plugin is not in the list of plugins that need documentation
|
||||
if (pluginOrigin && !pluginsThatNeedDocumentation.includes(pluginOrigin)) return;
|
||||
|
||||
if (excludeFromGeneration.length) {
|
||||
strapi
|
||||
.plugin('documentation')
|
||||
.service('override')
|
||||
.excludeFromGeneration(excludeFromGeneration);
|
||||
}
|
||||
|
||||
let overrideToRegister = override;
|
||||
// Parse yaml if we receive a string
|
||||
if (typeof override === 'string') {
|
||||
overrideToRegister = require('yaml').parse(overrideToRegister);
|
||||
}
|
||||
// receive an object we can register it directly
|
||||
registeredOverrides.push(overrideToRegister);
|
||||
};
|
||||
|
||||
return {
|
||||
registeredOverrides,
|
||||
registerOverride,
|
||||
excludeFromGeneration,
|
||||
excludedFromGeneration,
|
||||
/**
|
||||
*
|
||||
* @param {string | string[]} api - The name of the api or and array of apis to exclude from generation
|
||||
*/
|
||||
excludeFromGeneration(api) {
|
||||
if (Array.isArray(api)) {
|
||||
excludedFromGeneration.push(...api);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
excludedFromGeneration.push(api);
|
||||
},
|
||||
/**
|
||||
* @TODO pluginOrigin should be required in next major release
|
||||
* @param {object} doc - The openapi specifcation to override
|
||||
* @param {object} options - The options to override the documentation
|
||||
* @param {string} options.pluginOrigin - The name of the plugin that is overriding the documentation
|
||||
* @param {string[]} options.excludeFromGeneration - The name of the plugin that is overriding the documentation
|
||||
*/
|
||||
registerOverride(override, { pluginOrigin, excludeFromGeneration = [] }) {
|
||||
const pluginsThatNeedDocumentation = getPluginsThatNeedDocumentation(
|
||||
strapi.config.get('plugin.documentation')
|
||||
);
|
||||
// Don't apply the override if the plugin is not in the list of plugins that need documentation
|
||||
if (pluginOrigin && !pluginsThatNeedDocumentation.includes(pluginOrigin)) return;
|
||||
|
||||
if (excludeFromGeneration.length) {
|
||||
this.excludeFromGeneration(excludeFromGeneration);
|
||||
}
|
||||
|
||||
let overrideToRegister = override;
|
||||
// Parse yaml if we receive a string
|
||||
if (typeof override === 'string') {
|
||||
overrideToRegister = require('yaml').parse(overrideToRegister);
|
||||
}
|
||||
// receive an object we can register it directly
|
||||
registeredOverrides.push(overrideToRegister);
|
||||
},
|
||||
};
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user