etherpad-lite/admin/scripts/merge-openapi.mjs
John McLear 9a9a27f30a feat(admin): mergeOpenAPI helper for codegen pipeline (#7693)
Pure-JS deep-merge of two OpenAPI 3.0 documents. Unions paths and
components by key; throws on collisions. Public document's info,
servers, and root security win over the admin document's. Used by
dump-spec.ts to produce a single merged JSON for openapi-typescript.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 16:03:54 +01:00

56 lines
1.8 KiB
JavaScript

// admin/scripts/merge-openapi.mjs
//
// Deep-merges the public-API OpenAPI document with the admin OpenAPI
// document into a single document for openapi-typescript to consume.
//
// Rules:
// - paths: union by key; collision throws
// - components.{schemas,parameters,responses,securitySchemes}: union by name; collision throws
// - root info, servers, security: public wins (admin's are ignored at the root)
// - per-operation security on admin paths is preserved untouched
const unionMap = (label, a = {}, b = {}) => {
const out = {...a};
for (const [k, v] of Object.entries(b)) {
if (k in out) {
throw new Error(`${label} on key "${k}"`);
}
out[k] = v;
}
return out;
};
export const mergeOpenAPI = (publicDoc, adminDoc) => {
if (!publicDoc || !adminDoc) {
throw new Error('mergeOpenAPI requires both publicDoc and adminDoc');
}
return {
openapi: publicDoc.openapi || adminDoc.openapi,
info: publicDoc.info,
...(publicDoc.servers ? {servers: publicDoc.servers} : {}),
...(publicDoc.security ? {security: publicDoc.security} : {}),
paths: unionMap('path collision', publicDoc.paths, adminDoc.paths),
components: {
schemas: unionMap(
'schema collision',
publicDoc.components?.schemas,
adminDoc.components?.schemas,
),
parameters: unionMap(
'parameter collision',
publicDoc.components?.parameters,
adminDoc.components?.parameters,
),
responses: unionMap(
'response collision',
publicDoc.components?.responses,
adminDoc.components?.responses,
),
securitySchemes: unionMap(
'securityScheme collision',
publicDoc.components?.securitySchemes,
adminDoc.components?.securitySchemes,
),
},
};
};