Skip to content

Commit 46315f8

Browse files
committed
chore: enhance schema merging logic to prioritize OpenAPI and Swagger versions, and improve info and server merging
1 parent 4674566 commit 46315f8

File tree

1 file changed

+52
-9
lines changed

1 file changed

+52
-9
lines changed

lib/index.ts

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -340,20 +340,63 @@ export class $RefParser {
340340
throw ono("mergeMany called with no schemas. Did you run parseMany?");
341341
}
342342

343-
const first: any = schemas[0] || {};
344343
const merged: any = {};
345344

346-
if (typeof first.openapi === "string") {
347-
merged.openapi = first.openapi;
345+
// Determine spec version: prefer first occurrence of openapi, else swagger
346+
let chosenOpenapi: string | undefined;
347+
let chosenSwagger: string | undefined;
348+
for (const s of schemas) {
349+
if (!chosenOpenapi && s && typeof (s as any).openapi === "string") {
350+
chosenOpenapi = (s as any).openapi;
351+
}
352+
if (!chosenSwagger && s && typeof (s as any).swagger === "string") {
353+
chosenSwagger = (s as any).swagger;
354+
}
355+
if (chosenOpenapi && chosenSwagger) {
356+
break;
357+
}
358+
}
359+
if (typeof chosenOpenapi === "string") {
360+
merged.openapi = chosenOpenapi;
361+
} else if (typeof chosenSwagger === "string") {
362+
merged.swagger = chosenSwagger;
363+
}
364+
365+
// Merge info: take first non-empty per-field across inputs
366+
const infoAccumulator: any = {};
367+
for (const s of schemas) {
368+
const info = (s as any)?.info;
369+
if (info && typeof info === "object") {
370+
for (const [k, v] of Object.entries(info)) {
371+
if (infoAccumulator[k] === undefined && v !== undefined) {
372+
infoAccumulator[k] = JSON.parse(JSON.stringify(v));
373+
}
374+
}
375+
}
348376
}
349-
if (typeof first.swagger === "string") {
350-
merged.swagger = first.swagger;
377+
if (Object.keys(infoAccumulator).length > 0) {
378+
merged.info = infoAccumulator;
351379
}
352-
if (first.info) {
353-
merged.info = JSON.parse(JSON.stringify(first.info));
380+
381+
// Merge servers: union by url+description
382+
const servers: any[] = [];
383+
const seenServers = new Set<string>();
384+
for (const s of schemas) {
385+
const arr = (s as any)?.servers;
386+
if (Array.isArray(arr)) {
387+
for (const srv of arr) {
388+
if (srv && typeof srv === "object") {
389+
const key = `${srv.url || ""}|${srv.description || ""}`;
390+
if (!seenServers.has(key)) {
391+
seenServers.add(key);
392+
servers.push(JSON.parse(JSON.stringify(srv)));
393+
}
394+
}
395+
}
396+
}
354397
}
355-
if (first.servers) {
356-
merged.servers = JSON.parse(JSON.stringify(first.servers));
398+
if (servers.length > 0) {
399+
merged.servers = servers;
357400
}
358401

359402
merged.paths = {};

0 commit comments

Comments
 (0)