fumadocs-openapi
Version:
Generate MDX docs for your OpenAPI spec
135 lines (133 loc) • 3.62 kB
JavaScript
import { deepEqual } from "./deep-equal.js";
//#region src/utils/merge-schema.ts
/**
* Merge `allOf` object schema
*/
function mergeAllOf(schema) {
if (typeof schema === "boolean" || !schema.allOf) return schema;
const { allOf, ...rest } = schema;
let result = rest;
for (const item of allOf) result = intersection(result, item);
return result;
}
function intersection(a, b) {
a = mergeAllOf(a);
b = mergeAllOf(b);
if (typeof a === "boolean" && typeof b === "boolean") return a && b;
if (typeof a === "boolean") return a;
if (typeof b === "boolean") return b;
const result = { ...a };
for (const _k in b) {
const key = _k;
switch (key) {
case "$id":
case "$comment":
case "description":
case "additionalItems":
case "examples":
case "allOf":
case "writeOnly":
case "readOnly": break;
case "title": {
const value = b[key];
if (value === void 0) break;
if (result[key]) result[key] = `${result[key]} & ${value}`;
else result[key] = value;
break;
}
case "minItems":
case "minimum":
case "exclusiveMinimum":
case "minProperties":
case "minContains":
case "minLength": {
const value = b[key];
if (value === void 0) break;
result[key] = result[key] === void 0 ? value : Math.max(result[key], value);
break;
}
case "maxContains":
case "maxItems":
case "maxLength":
case "maxProperties":
case "maximum":
case "exclusiveMaximum": {
const value = b[key];
if (value === void 0) break;
result[key] = result[key] === void 0 ? value : Math.min(result[key], value);
break;
}
case "enum":
case "anyOf":
case "oneOf": {
const value = b[key];
if (value === void 0) break;
result[key] = result[key] === void 0 ? value : intersectArray(result[key], value);
break;
}
case "format":
case "const":
case "type": {
const value = b[key];
if (value === void 0) break;
result[key] ??= value;
if (!deepEqual(result[key], value)) return false;
break;
}
case "required": {
const value = b[key];
if (value === void 0) break;
result[key] = [...result[key] ?? [], ...value];
break;
}
case "properties":
case "patternProperties": {
const value = b[key];
if (value === void 0) break;
if (result[key] === void 0) {
result[key] = value;
break;
}
const out = {};
const allProps = /* @__PURE__ */ new Set();
for (const k in result[key]) allProps.add(k);
for (const k in value) allProps.add(k);
for (const prop of allProps) {
const aProp = result[key][prop];
const bProp = value[prop];
if (aProp === void 0) out[prop] = bProp;
else if (bProp === void 0) out[prop] = aProp;
else out[prop] = intersection(aProp, bProp);
}
result[key] = out;
break;
}
case "additionalProperties":
case "contains":
case "items": {
const value = b[key];
if (value === void 0) break;
result[key] = result[key] === void 0 ? value : intersection(result[key], value);
break;
}
case "not": {
const value = b[key];
if (value === void 0) break;
if (result[key] && value) result.not = { anyOf: [result[key], value] };
else if (value) result.not = value;
break;
}
default: result[key] = b[key];
}
}
return result;
}
function intersectArray(a, b) {
const out = /* @__PURE__ */ new Set();
for (const item of a) if (b.includes(item)) out.add(item);
for (const item of b) if (a.includes(item)) out.add(item);
return Array.from(out);
}
//#endregion
export { mergeAllOf };
//# sourceMappingURL=merge-schema.js.map