fix: documentation plugin use of immer

This commit is contained in:
Rémi de Juvigny 2024-12-23 18:10:29 +01:00
parent e46cc77de9
commit 1177a4558c

View File

@ -1,6 +1,6 @@
import path from 'path';
import fs from 'fs-extra';
import { produce } from 'immer';
import { createDraft, finishDraft, produce } from 'immer';
import type { Core } from '@strapi/types';
import { builApiEndpointPath, buildComponentSchema } from './helpers';
@ -117,86 +117,89 @@ const createService = ({ strapi }: { strapi: Core.Strapi }) => {
);
// Initialize the generated documentation with defaults
const generatedDocumentation = await produce(config, async (draft) => {
if (draft.servers?.length === 0) {
// When no servers found set the defaults
const serverUrl = strapi.config.get('server.absoluteUrl');
const apiPath = strapi.config.get('api.rest.prefix');
draft.servers = [
{
url: `${serverUrl}${apiPath}`,
description: 'Development server',
},
];
const draftConfiguration = createDraft(config);
if (draftConfiguration.servers?.length === 0) {
// When no servers found set the defaults
const serverUrl = strapi.config.get('server.absoluteUrl');
const apiPath = strapi.config.get('api.rest.prefix');
draftConfiguration.servers = [
{
url: `${serverUrl}${apiPath}`,
description: 'Development server',
},
];
}
if (!draftConfiguration.components) {
draftConfiguration.components = {};
}
// Set the generated date
draftConfiguration.info['x-generation-date'] = new Date().toISOString();
// Set the plugins that need documentation
draftConfiguration['x-strapi-config'].plugins = pluginsThatNeedDocumentation;
// Delete the mutateDocumentation key from the config so it doesn't end up in the spec
delete draftConfiguration['x-strapi-config'].mutateDocumentation;
// Generate the documentation for each api and update the generatedDocumentation
for (const api of apisThatNeedGeneratedDocumentation) {
const newApiPath = builApiEndpointPath(api);
const generatedSchemas = buildComponentSchema(api);
if (generatedSchemas) {
draftConfiguration.components.schemas = {
...draftConfiguration.components.schemas,
...generatedSchemas,
};
}
if (!draft.components) {
draft.components = {};
if (newApiPath) {
draftConfiguration.paths = { ...draftConfiguration.paths, ...newApiPath };
}
}
// 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 the mutateDocumentation key from the config so it doesn't end up in the spec
delete draft['x-strapi-config'].mutateDocumentation;
// Generate the documentation for each api and update the generatedDocumentation
for (const api of apisThatNeedGeneratedDocumentation) {
const newApiPath = builApiEndpointPath(api);
const generatedSchemas = buildComponentSchema(api);
if (generatedSchemas) {
draft.components.schemas = { ...draft.components.schemas, ...generatedSchemas };
}
if (newApiPath) {
draft.paths = { ...draft.paths, ...newApiPath };
}
}
// When overrides are present update the generatedDocumentation
if (overrideService.registeredOverrides.length > 0) {
overrideService.registeredOverrides.forEach((override: Partial<PluginConfig>) => {
// Only run the overrrides when no override version is provided,
// or when the generated documentation version matches the override version
if (!override?.info?.version || override.info.version === version) {
if (override.tags) {
// Merge override tags with the generated tags
draft.tags = draft.tags || [];
draft.tags.push(...override.tags);
}
if (override.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, ...override.paths };
}
if (override.components) {
const keys = Object.keys(override.components) as Array<
keyof typeof override.components
>;
keys.forEach((overrideKey) => {
draft.components = draft.components || {};
const overrideValue = override.components?.[overrideKey];
const originalValue = draft.components?.[overrideKey];
Object.assign(draft.components, {
[overrideKey]: {
...originalValue,
...overrideValue,
},
});
});
}
// When overrides are present update the generatedDocumentation
if (overrideService.registeredOverrides.length > 0) {
overrideService.registeredOverrides.forEach((override: Partial<PluginConfig>) => {
// Only run the overrrides when no override version is provided,
// or when the generated documentation version matches the override version
if (!override?.info?.version || override.info.version === version) {
if (override.tags) {
// Merge override tags with the generated tags
draftConfiguration.tags = draftConfiguration.tags || [];
draftConfiguration.tags.push(...override.tags);
}
});
}
});
if (override.paths) {
// Merge override paths with the generated paths
// The override will add a new path or replace the value of an existing path
draftConfiguration.paths = { ...draftConfiguration.paths, ...override.paths };
}
if (override.components) {
const keys = Object.keys(override.components) as Array<
keyof typeof override.components
>;
keys.forEach((overrideKey) => {
draftConfiguration.components = draftConfiguration.components || {};
const overrideValue = override.components?.[overrideKey];
const originalValue = draftConfiguration.components?.[overrideKey];
Object.assign(draftConfiguration.components, {
[overrideKey]: {
...originalValue,
...overrideValue,
},
});
});
}
}
});
}
const generatedDocumentation = finishDraft(draftConfiguration);
// 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