UNPKG

@common-grants/cli

Version:
97 lines (96 loc) 4.26 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.deepFlattenAllOf = deepFlattenAllOf; const json_schema_merge_allof_1 = __importDefault(require("json-schema-merge-allof")); // Simple cache to avoid redundant flattening of the same schemas const flattenCache = new WeakMap(); /** * Deeply flatten `allOf` and `anyOf` in a schema by: * 1) Resolving anyOf by selecting the first compatible option * 2) Merging top-level allOf into a single schema * 3) Recursively descending into properties, items, additionalProperties, etc. * 4) Repeating if new allOfs or anyOfs appear after processing */ function deepFlattenAllOf(schema) { // Check cache first if (flattenCache.has(schema)) { return flattenCache.get(schema); } // Keep processing until no more allOf or anyOf structures remain let processedSchema = schema; let hasStructures = true; while (hasStructures) { // 1) Resolve anyOf (if any) processedSchema = resolveAnyOf(processedSchema); // 2) Merge allOf (if any) if (processedSchema.allOf && Array.isArray(processedSchema.allOf)) { try { processedSchema = (0, json_schema_merge_allof_1.default)(processedSchema); } catch (error) { console.warn("Failed to merge allOf, keeping original schema:", error); // Remove allOf but keep the rest of the schema delete processedSchema.allOf; } } // 3) Recursively flatten sub-schemas processedSchema = recursivelyFlattenSubSchemas(processedSchema); // 4) Check if we still have structures to process hasStructures = !!(processedSchema.allOf && Array.isArray(processedSchema.allOf)) || !!(processedSchema.anyOf && Array.isArray(processedSchema.anyOf)); } // Cache the result flattenCache.set(schema, processedSchema); return processedSchema; } /** * Resolve anyOf by selecting the first option that's not a reference. * This is a simplified approach that avoids complex union type resolution. */ function resolveAnyOf(schema) { if (!schema.anyOf || schema.anyOf.length === 0) { return schema; } // For now, select the first option that's not a reference for (let i = 0; i < schema.anyOf.length; i++) { const option = schema.anyOf[i]; if (typeof option === "object" && option !== null && !("$ref" in option)) { // Recursively process the selected option const processedOption = deepFlattenAllOf(option); // Merge the selected option with the base schema const baseSchema = { ...schema }; delete baseSchema.anyOf; return { ...baseSchema, ...processedOption }; } } // If no suitable anyOf option found, keep original schema return schema; } /** * Recursively flatten sub-schemas in properties, items, additionalProperties, etc. */ function recursivelyFlattenSubSchemas(schema) { // We only handle object fields if the schema is actually an object in practice // (or we handle them unconditionally, depending on your usage). // If `schema.type` is "object" or is missing, we still might have `properties`. if (schema.properties && typeof schema.properties === "object") { for (const [propName, propSchema] of Object.entries(schema.properties)) { if (propSchema && typeof propSchema === "object") { schema.properties[propName] = deepFlattenAllOf(propSchema); } } } // If the schema is an array type and has an `items` property that is an object if (schema.type === "array" && schema.items && typeof schema.items === "object") { schema.items = deepFlattenAllOf(schema.items); } // If the schema has `additionalProperties` as an object if (schema.additionalProperties && typeof schema.additionalProperties === "object") { schema.additionalProperties = deepFlattenAllOf(schema.additionalProperties); } return schema; }