|
1 | 1 | import {JSONSchemaTypeName, LinkedJSONSchema, NormalizedJSONSchema, Parent} from './types/JSONSchema' |
2 | 2 | import {appendToDescription, escapeBlockComment, isSchemaLike, justName, toSafeString, traverse} from './utils' |
3 | 3 | import {Options} from './' |
4 | | - |
5 | | -type Rule = (schema: LinkedJSONSchema, fileName: string, options: Options) => void |
| 4 | +import {DereferencedPaths} from './resolver' |
| 5 | + |
| 6 | +type Rule = ( |
| 7 | + schema: LinkedJSONSchema, |
| 8 | + fileName: string, |
| 9 | + options: Options, |
| 10 | + key: string | null, |
| 11 | + dereferencedPaths: DereferencedPaths |
| 12 | +) => void |
6 | 13 | const rules = new Map<string, Rule>() |
7 | 14 |
|
8 | 15 | function hasType(schema: LinkedJSONSchema, type: JSONSchemaTypeName) { |
@@ -65,10 +72,31 @@ rules.set('Transform id to $id', (schema, fileName) => { |
65 | 72 | } |
66 | 73 | }) |
67 | 74 |
|
68 | | -rules.set('Default top level $id', (schema, fileName) => { |
69 | | - const isRoot = schema[Parent] === null |
70 | | - if (isRoot && !schema.$id) { |
| 75 | +rules.set('Add an $id to anything that needs it', (schema, fileName, _options, _key, dereferencedPaths) => { |
| 76 | + if (!isSchemaLike(schema)) { |
| 77 | + return |
| 78 | + } |
| 79 | + |
| 80 | + // Top-level schema |
| 81 | + if (!schema.$id && !schema[Parent]) { |
71 | 82 | schema.$id = toSafeString(justName(fileName)) |
| 83 | + return |
| 84 | + } |
| 85 | + |
| 86 | + // Sub-schemas with references |
| 87 | + if (!isArrayType(schema) && !isObjectType(schema)) { |
| 88 | + return |
| 89 | + } |
| 90 | + |
| 91 | + // We'll infer from $id and title downstream |
| 92 | + // TODO: Normalize upstream |
| 93 | + const dereferencedName = dereferencedPaths.get(schema) |
| 94 | + if (!schema.$id && !schema.title && dereferencedName) { |
| 95 | + schema.$id = toSafeString(justName(dereferencedName)) |
| 96 | + } |
| 97 | + |
| 98 | + if (dereferencedName) { |
| 99 | + dereferencedPaths.delete(schema) |
72 | 100 | } |
73 | 101 | }) |
74 | 102 |
|
@@ -188,7 +216,12 @@ rules.set('Transform const to singleton enum', schema => { |
188 | 216 | } |
189 | 217 | }) |
190 | 218 |
|
191 | | -export function normalize(rootSchema: LinkedJSONSchema, filename: string, options: Options): NormalizedJSONSchema { |
192 | | - rules.forEach(rule => traverse(rootSchema, schema => rule(schema, filename, options))) |
| 219 | +export function normalize( |
| 220 | + rootSchema: LinkedJSONSchema, |
| 221 | + dereferencedPaths: DereferencedPaths, |
| 222 | + filename: string, |
| 223 | + options: Options |
| 224 | +): NormalizedJSONSchema { |
| 225 | + rules.forEach(rule => traverse(rootSchema, (schema, key) => rule(schema, filename, options, key, dereferencedPaths))) |
193 | 226 | return rootSchema as NormalizedJSONSchema |
194 | 227 | } |
0 commit comments