(
schema: T,
externalSchema: Record<string, unknown>,
externalSchemaFile: string,
options: { conflictingDefinitionNamePrefix?: string } = {}
)
| 1449 | } |
| 1450 | |
| 1451 | export function inlineExternalSchemaDefinitions<T>( |
| 1452 | schema: T, |
| 1453 | externalSchema: Record<string, unknown>, |
| 1454 | externalSchemaFile: string, |
| 1455 | options: { conflictingDefinitionNamePrefix?: string } = {} |
| 1456 | ): { schema: T; inlinedDefinitionNames: Set<string> } { |
| 1457 | const cloned = cloneSchemaForCodegen(schema) as Record<string, unknown>; |
| 1458 | const externalRefs = collectExternalSchemaRefNames(cloned).get(externalSchemaFile); |
| 1459 | if (!externalRefs || externalRefs.size === 0) { |
| 1460 | return { schema: cloned as T, inlinedDefinitionNames: new Set<string>() }; |
| 1461 | } |
| 1462 | |
| 1463 | const externalDefinitions = collectDefinitions(externalSchema); |
| 1464 | const reachableDefinitions = collectReachableDefinitionNames(externalSchema, externalRefs); |
| 1465 | const inlinedDefinitionNames = new Set<string>(); |
| 1466 | const targetDefinitions = { |
| 1467 | ...((cloned.definitions ?? {}) as Record<string, JSONSchema7Definition>), |
| 1468 | }; |
| 1469 | const nameMap = new Map<string, string>(); |
| 1470 | const usedNames = new Set([...Object.keys(targetDefinitions), ...reachableDefinitions]); |
| 1471 | |
| 1472 | for (const name of [...reachableDefinitions].sort()) { |
| 1473 | const definition = externalDefinitions[name]; |
| 1474 | if (definition === undefined) continue; |
| 1475 | |
| 1476 | const existing = targetDefinitions[name]; |
| 1477 | if ( |
| 1478 | existing !== undefined && |
| 1479 | stableStringify(normalizeDefinitionForComparison(existing)) !== |
| 1480 | stableStringify(normalizeDefinitionForComparison(definition)) |
| 1481 | ) { |
| 1482 | if (!options.conflictingDefinitionNamePrefix) { |
| 1483 | throw new Error( |
| 1484 | `Cannot inline ${externalSchemaFile}#/definitions/${name}; api.schema.json already defines a different schema with that name.` |
| 1485 | ); |
| 1486 | } |
| 1487 | |
| 1488 | let renamed = `${options.conflictingDefinitionNamePrefix}${name}`; |
| 1489 | let suffix = 2; |
| 1490 | while (usedNames.has(renamed)) { |
| 1491 | renamed = `${options.conflictingDefinitionNamePrefix}${name}${suffix++}`; |
| 1492 | } |
| 1493 | usedNames.add(renamed); |
| 1494 | nameMap.set(name, renamed); |
| 1495 | } else { |
| 1496 | nameMap.set(name, name); |
| 1497 | } |
| 1498 | } |
| 1499 | |
| 1500 | const rewriteInlinedRefs = (value: unknown): unknown => { |
| 1501 | if (Array.isArray(value)) { |
| 1502 | return value.map((item) => rewriteInlinedRefs(item)); |
| 1503 | } |
| 1504 | |
| 1505 | if (!value || typeof value !== "object") { |
| 1506 | return value; |
| 1507 | } |
| 1508 |
no test coverage detected
searching dependent graphs…