@contractual/differs.core 0.1.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/assemble.d.ts +10 -0
- package/dist/assemble.d.ts.map +1 -0
- package/dist/assemble.js +42 -0
- package/dist/assemble.js.map +1 -0
- package/dist/classifiers.d.ts +87 -0
- package/dist/classifiers.d.ts.map +1 -0
- package/dist/classifiers.js +375 -0
- package/dist/classifiers.js.map +1 -0
- package/dist/format.d.ts +12 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +127 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/ref-resolver.d.ts +73 -0
- package/dist/ref-resolver.d.ts.map +1 -0
- package/dist/ref-resolver.js +345 -0
- package/dist/ref-resolver.js.map +1 -0
- package/dist/types.d.ts +170 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +151 -0
- package/dist/types.js.map +1 -0
- package/dist/walker.d.ts +17 -0
- package/dist/walker.d.ts.map +1 -0
- package/dist/walker.js +1195 -0
- package/dist/walker.js.map +1 -0
- package/package.json +56 -0
package/dist/format.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Human-readable message formatting for raw changes
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Format a human-readable message for a change
|
|
6
|
+
*
|
|
7
|
+
* @param change - The raw change to format
|
|
8
|
+
* @returns Human-readable message describing the change
|
|
9
|
+
*/
|
|
10
|
+
export function formatChangeMessage(change) {
|
|
11
|
+
const pathDisplay = change.path || '/';
|
|
12
|
+
switch (change.type) {
|
|
13
|
+
case 'property-added':
|
|
14
|
+
return `Property added at ${pathDisplay}`;
|
|
15
|
+
case 'property-removed':
|
|
16
|
+
return `Property removed at ${pathDisplay}`;
|
|
17
|
+
case 'required-added':
|
|
18
|
+
return `Field "${formatRequiredFieldName(change.newValue)}" made required at ${pathDisplay}`;
|
|
19
|
+
case 'required-removed':
|
|
20
|
+
return `Field "${formatRequiredFieldName(change.oldValue)}" made optional at ${pathDisplay}`;
|
|
21
|
+
case 'type-changed':
|
|
22
|
+
return `Type changed from ${formatValue(change.oldValue)} to ${formatValue(change.newValue)} at ${pathDisplay}`;
|
|
23
|
+
case 'type-narrowed':
|
|
24
|
+
return `Type narrowed from ${formatValue(change.oldValue)} to ${formatValue(change.newValue)} at ${pathDisplay}`;
|
|
25
|
+
case 'type-widened':
|
|
26
|
+
return `Type widened from ${formatValue(change.oldValue)} to ${formatValue(change.newValue)} at ${pathDisplay}`;
|
|
27
|
+
case 'enum-value-added':
|
|
28
|
+
return `Enum value ${formatValue(change.newValue)} added at ${pathDisplay}`;
|
|
29
|
+
case 'enum-value-removed':
|
|
30
|
+
return `Enum value ${formatValue(change.oldValue)} removed at ${pathDisplay}`;
|
|
31
|
+
case 'enum-added':
|
|
32
|
+
return `Enum constraint added at ${pathDisplay}`;
|
|
33
|
+
case 'enum-removed':
|
|
34
|
+
return `Enum constraint removed at ${pathDisplay}`;
|
|
35
|
+
case 'constraint-tightened':
|
|
36
|
+
return formatConstraintMessage(change, 'tightened', pathDisplay);
|
|
37
|
+
case 'constraint-loosened':
|
|
38
|
+
return formatConstraintMessage(change, 'loosened', pathDisplay);
|
|
39
|
+
case 'format-added':
|
|
40
|
+
return `Format "${change.newValue}" added at ${pathDisplay}`;
|
|
41
|
+
case 'format-removed':
|
|
42
|
+
return `Format "${change.oldValue}" removed at ${pathDisplay}`;
|
|
43
|
+
case 'format-changed':
|
|
44
|
+
return `Format changed from "${change.oldValue}" to "${change.newValue}" at ${pathDisplay}`;
|
|
45
|
+
case 'additional-properties-denied':
|
|
46
|
+
return `Additional properties denied at ${pathDisplay}`;
|
|
47
|
+
case 'additional-properties-allowed':
|
|
48
|
+
return `Additional properties allowed at ${pathDisplay}`;
|
|
49
|
+
case 'additional-properties-changed':
|
|
50
|
+
return `Additional properties schema changed at ${pathDisplay}`;
|
|
51
|
+
case 'items-changed':
|
|
52
|
+
return `Array items schema changed at ${pathDisplay}`;
|
|
53
|
+
case 'min-items-increased':
|
|
54
|
+
return `Minimum items increased from ${formatValue(change.oldValue)} to ${formatValue(change.newValue)} at ${pathDisplay}`;
|
|
55
|
+
case 'max-items-decreased':
|
|
56
|
+
return `Maximum items decreased from ${formatValue(change.oldValue)} to ${formatValue(change.newValue)} at ${pathDisplay}`;
|
|
57
|
+
case 'composition-changed':
|
|
58
|
+
return `Composition (allOf/anyOf/oneOf) changed at ${pathDisplay}`;
|
|
59
|
+
case 'ref-target-changed':
|
|
60
|
+
return `Reference target changed at ${pathDisplay}`;
|
|
61
|
+
case 'description-changed':
|
|
62
|
+
return `Description changed at ${pathDisplay}`;
|
|
63
|
+
case 'title-changed':
|
|
64
|
+
return `Title changed at ${pathDisplay}`;
|
|
65
|
+
case 'default-changed':
|
|
66
|
+
return `Default value changed at ${pathDisplay}`;
|
|
67
|
+
case 'examples-changed':
|
|
68
|
+
return `Examples changed at ${pathDisplay}`;
|
|
69
|
+
case 'unknown-change':
|
|
70
|
+
default:
|
|
71
|
+
return `Unknown change at ${pathDisplay}`;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Format a value for display in messages
|
|
76
|
+
*/
|
|
77
|
+
function formatValue(value) {
|
|
78
|
+
if (value === undefined) {
|
|
79
|
+
return 'undefined';
|
|
80
|
+
}
|
|
81
|
+
if (value === null) {
|
|
82
|
+
return 'null';
|
|
83
|
+
}
|
|
84
|
+
if (typeof value === 'string') {
|
|
85
|
+
return `"${value}"`;
|
|
86
|
+
}
|
|
87
|
+
if (Array.isArray(value)) {
|
|
88
|
+
return JSON.stringify(value);
|
|
89
|
+
}
|
|
90
|
+
if (typeof value === 'object') {
|
|
91
|
+
return JSON.stringify(value);
|
|
92
|
+
}
|
|
93
|
+
return String(value);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Format required field name from change value
|
|
97
|
+
*/
|
|
98
|
+
function formatRequiredFieldName(value) {
|
|
99
|
+
if (typeof value === 'string') {
|
|
100
|
+
return value;
|
|
101
|
+
}
|
|
102
|
+
return String(value);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Format constraint change message
|
|
106
|
+
*/
|
|
107
|
+
function formatConstraintMessage(change, direction, pathDisplay) {
|
|
108
|
+
const constraintName = extractConstraintName(change.path);
|
|
109
|
+
const oldVal = change.oldValue !== undefined ? formatValue(change.oldValue) : 'none';
|
|
110
|
+
const newVal = change.newValue !== undefined ? formatValue(change.newValue) : 'none';
|
|
111
|
+
if (constraintName) {
|
|
112
|
+
return `Constraint "${constraintName}" ${direction} from ${oldVal} to ${newVal} at ${pathDisplay}`;
|
|
113
|
+
}
|
|
114
|
+
return `Constraint ${direction} from ${oldVal} to ${newVal} at ${pathDisplay}`;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Extract constraint name from path
|
|
118
|
+
*/
|
|
119
|
+
function extractConstraintName(path) {
|
|
120
|
+
const segments = path.split('/');
|
|
121
|
+
const lastSegment = segments[segments.length - 1];
|
|
122
|
+
if (lastSegment && lastSegment !== '') {
|
|
123
|
+
return lastSegment;
|
|
124
|
+
}
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../src/format.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { walk } from './walker.js';
|
|
2
|
+
export { classify, classifyPropertyAdded, classifyAll, CLASSIFICATION_SETS } from './classifiers.js';
|
|
3
|
+
export { resolveRefs, hasUnresolvedRefs, extractRefs, validateRefs, type ResolveResult } from './ref-resolver.js';
|
|
4
|
+
export { formatChangeMessage } from './format.js';
|
|
5
|
+
export { assembleResult, type AssembleOptions } from './assemble.js';
|
|
6
|
+
export type { ResolvedSchema, JSONSchemaType, NormalizedType, ConstraintKey, ConstraintDirection, ConstraintMeta, CompositionKeyword, MetadataKey, AnnotationKey, ContentKey, WalkerContext, } from './types.js';
|
|
7
|
+
export { isSchemaObject, isSchemaArray, normalizeType, arraysEqual, deepEqual, escapeJsonPointer, joinPath, CONSTRAINT_KEYS, CONSTRAINT_DIRECTION, COMPOSITION_KEYWORDS, METADATA_KEYS, ANNOTATION_KEYS, CONTENT_KEYS, DEFAULT_MAX_DEPTH, } from './types.js';
|
|
8
|
+
export type { ChangeType, ChangeSeverity, RawChange, Change, DiffResult, DiffSummary, SuggestedBump } from '@contractual/types';
|
|
9
|
+
export { CHANGE_TYPE_SEVERITY } from '@contractual/types';
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAGnC,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAGrG,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGlH,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,EAAE,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrE,YAAY,EACV,cAAc,EACd,cAAc,EACd,cAAc,EACd,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,UAAU,EACV,aAAa,GACd,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,cAAc,EACd,aAAa,EACb,aAAa,EACb,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAChI,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Core walker
|
|
2
|
+
export { walk } from './walker.js';
|
|
3
|
+
// Classification
|
|
4
|
+
export { classify, classifyPropertyAdded, classifyAll, CLASSIFICATION_SETS } from './classifiers.js';
|
|
5
|
+
// Ref resolution
|
|
6
|
+
export { resolveRefs, hasUnresolvedRefs, extractRefs, validateRefs } from './ref-resolver.js';
|
|
7
|
+
// Message formatting
|
|
8
|
+
export { formatChangeMessage } from './format.js';
|
|
9
|
+
// Result assembly
|
|
10
|
+
export { assembleResult } from './assemble.js';
|
|
11
|
+
export { isSchemaObject, isSchemaArray, normalizeType, arraysEqual, deepEqual, escapeJsonPointer, joinPath, CONSTRAINT_KEYS, CONSTRAINT_DIRECTION, COMPOSITION_KEYWORDS, METADATA_KEYS, ANNOTATION_KEYS, CONTENT_KEYS, DEFAULT_MAX_DEPTH, } from './types.js';
|
|
12
|
+
export { CHANGE_TYPE_SEVERITY } from '@contractual/types';
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAEnC,iBAAiB;AACjB,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAErG,iBAAiB;AACjB,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,YAAY,EAAsB,MAAM,mBAAmB,CAAC;AAElH,qBAAqB;AACrB,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,kBAAkB;AAClB,OAAO,EAAE,cAAc,EAAwB,MAAM,eAAe,CAAC;AAiBrE,OAAO,EACL,cAAc,EACd,aAAa,EACb,aAAa,EACb,WAAW,EACX,SAAS,EACT,iBAAiB,EACjB,QAAQ,EACR,eAAe,EACf,oBAAoB,EACpB,oBAAoB,EACpB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Schema $ref Resolver
|
|
3
|
+
*
|
|
4
|
+
* Resolves all $ref pointers in a JSON Schema, producing a self-contained schema.
|
|
5
|
+
* Handles internal references ($defs, definitions) and detects circular references.
|
|
6
|
+
*
|
|
7
|
+
* This resolver operates on in-memory schema objects and does not fetch external URLs.
|
|
8
|
+
* External references are flagged as warnings.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Result of resolving references in a schema
|
|
12
|
+
*/
|
|
13
|
+
export interface ResolveResult {
|
|
14
|
+
/** The resolved schema with $refs replaced */
|
|
15
|
+
readonly schema: unknown;
|
|
16
|
+
/** Warnings encountered during resolution (circular refs, external refs, etc.) */
|
|
17
|
+
readonly warnings: string[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Resolve all $ref pointers in a JSON Schema
|
|
21
|
+
*
|
|
22
|
+
* Creates a self-contained schema by inlining all internal references.
|
|
23
|
+
* Does not modify the original schema.
|
|
24
|
+
*
|
|
25
|
+
* @param schema - The JSON Schema to resolve
|
|
26
|
+
* @returns The resolved schema and any warnings
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const schema = {
|
|
31
|
+
* type: 'object',
|
|
32
|
+
* properties: {
|
|
33
|
+
* user: { $ref: '#/$defs/User' }
|
|
34
|
+
* },
|
|
35
|
+
* $defs: {
|
|
36
|
+
* User: { type: 'object', properties: { name: { type: 'string' } } }
|
|
37
|
+
* }
|
|
38
|
+
* };
|
|
39
|
+
*
|
|
40
|
+
* const result = resolveRefs(schema);
|
|
41
|
+
* // result.schema.properties.user === { type: 'object', properties: { name: { type: 'string' } } }
|
|
42
|
+
* // result.warnings === []
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare function resolveRefs(schema: unknown): ResolveResult;
|
|
46
|
+
/**
|
|
47
|
+
* Check if a schema contains any unresolved $refs
|
|
48
|
+
*
|
|
49
|
+
* @param schema - The schema to check
|
|
50
|
+
* @returns True if the schema contains $ref pointers
|
|
51
|
+
*/
|
|
52
|
+
export declare function hasUnresolvedRefs(schema: unknown): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Extract all $ref pointers from a schema
|
|
55
|
+
*
|
|
56
|
+
* @param schema - The schema to analyze
|
|
57
|
+
* @returns Array of { pointer, path } objects
|
|
58
|
+
*/
|
|
59
|
+
export declare function extractRefs(schema: unknown): Array<{
|
|
60
|
+
pointer: string;
|
|
61
|
+
path: string;
|
|
62
|
+
}>;
|
|
63
|
+
/**
|
|
64
|
+
* Validate that all internal references in a schema are resolvable
|
|
65
|
+
*
|
|
66
|
+
* @param schema - The schema to validate
|
|
67
|
+
* @returns Object with valid flag and any error messages
|
|
68
|
+
*/
|
|
69
|
+
export declare function validateRefs(schema: unknown): {
|
|
70
|
+
valid: boolean;
|
|
71
|
+
errors: string[];
|
|
72
|
+
};
|
|
73
|
+
//# sourceMappingURL=ref-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ref-resolver.d.ts","sourceRoot":"","sources":["../src/ref-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,kFAAkF;IAClF,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;CAC7B;AAkBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,aAAa,CAe1D;AA2PD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CA0B1D;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAIrF;AAiCD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,GAAG;IAC7C,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAoBA"}
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON Schema $ref Resolver
|
|
3
|
+
*
|
|
4
|
+
* Resolves all $ref pointers in a JSON Schema, producing a self-contained schema.
|
|
5
|
+
* Handles internal references ($defs, definitions) and detects circular references.
|
|
6
|
+
*
|
|
7
|
+
* This resolver operates on in-memory schema objects and does not fetch external URLs.
|
|
8
|
+
* External references are flagged as warnings.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Resolve all $ref pointers in a JSON Schema
|
|
12
|
+
*
|
|
13
|
+
* Creates a self-contained schema by inlining all internal references.
|
|
14
|
+
* Does not modify the original schema.
|
|
15
|
+
*
|
|
16
|
+
* @param schema - The JSON Schema to resolve
|
|
17
|
+
* @returns The resolved schema and any warnings
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const schema = {
|
|
22
|
+
* type: 'object',
|
|
23
|
+
* properties: {
|
|
24
|
+
* user: { $ref: '#/$defs/User' }
|
|
25
|
+
* },
|
|
26
|
+
* $defs: {
|
|
27
|
+
* User: { type: 'object', properties: { name: { type: 'string' } } }
|
|
28
|
+
* }
|
|
29
|
+
* };
|
|
30
|
+
*
|
|
31
|
+
* const result = resolveRefs(schema);
|
|
32
|
+
* // result.schema.properties.user === { type: 'object', properties: { name: { type: 'string' } } }
|
|
33
|
+
* // result.warnings === []
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export function resolveRefs(schema) {
|
|
37
|
+
const context = {
|
|
38
|
+
root: schema,
|
|
39
|
+
warnings: [],
|
|
40
|
+
resolving: new Set(),
|
|
41
|
+
cache: new Map(),
|
|
42
|
+
currentPath: '',
|
|
43
|
+
};
|
|
44
|
+
const resolved = resolveNode(schema, context);
|
|
45
|
+
return {
|
|
46
|
+
schema: resolved,
|
|
47
|
+
warnings: context.warnings,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Recursively resolve a schema node
|
|
52
|
+
*/
|
|
53
|
+
function resolveNode(node, context) {
|
|
54
|
+
// Handle non-objects
|
|
55
|
+
if (!isObject(node)) {
|
|
56
|
+
return node;
|
|
57
|
+
}
|
|
58
|
+
const obj = node;
|
|
59
|
+
// Check if this is a $ref node
|
|
60
|
+
if (typeof obj['$ref'] === 'string') {
|
|
61
|
+
return resolveRef(obj['$ref'], obj, context);
|
|
62
|
+
}
|
|
63
|
+
// Recursively resolve all properties
|
|
64
|
+
const resolved = {};
|
|
65
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
66
|
+
const previousPath = context.currentPath;
|
|
67
|
+
context.currentPath = `${context.currentPath}/${encodeJsonPointerSegment(key)}`;
|
|
68
|
+
if (Array.isArray(value)) {
|
|
69
|
+
resolved[key] = value.map((item, index) => {
|
|
70
|
+
const itemPath = context.currentPath;
|
|
71
|
+
context.currentPath = `${itemPath}/${index}`;
|
|
72
|
+
const resolvedItem = resolveNode(item, context);
|
|
73
|
+
context.currentPath = itemPath;
|
|
74
|
+
return resolvedItem;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
resolved[key] = resolveNode(value, context);
|
|
79
|
+
}
|
|
80
|
+
context.currentPath = previousPath;
|
|
81
|
+
}
|
|
82
|
+
return resolved;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Resolve a $ref pointer
|
|
86
|
+
*/
|
|
87
|
+
function resolveRef(ref, refNode, context) {
|
|
88
|
+
// Check for external references
|
|
89
|
+
if (isExternalRef(ref)) {
|
|
90
|
+
context.warnings.push(`External reference not resolved: ${ref} at ${context.currentPath || '/'}`);
|
|
91
|
+
// Return the $ref node as-is for external refs
|
|
92
|
+
return refNode;
|
|
93
|
+
}
|
|
94
|
+
// Check for circular reference
|
|
95
|
+
if (context.resolving.has(ref)) {
|
|
96
|
+
context.warnings.push(`Circular reference detected: ${ref} at ${context.currentPath || '/'}`);
|
|
97
|
+
// Return a placeholder to break the cycle
|
|
98
|
+
return {
|
|
99
|
+
$circularRef: ref,
|
|
100
|
+
$comment: 'Circular reference - see original location',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
// Check cache
|
|
104
|
+
if (context.cache.has(ref)) {
|
|
105
|
+
return context.cache.get(ref);
|
|
106
|
+
}
|
|
107
|
+
// Mark as currently resolving
|
|
108
|
+
context.resolving.add(ref);
|
|
109
|
+
try {
|
|
110
|
+
// Resolve the reference
|
|
111
|
+
const target = resolvePointer(ref, context.root);
|
|
112
|
+
if (target === undefined) {
|
|
113
|
+
context.warnings.push(`Reference not found: ${ref} at ${context.currentPath || '/'}`);
|
|
114
|
+
// Return the $ref node as-is if target not found
|
|
115
|
+
return refNode;
|
|
116
|
+
}
|
|
117
|
+
// Recursively resolve the target (it may contain more $refs)
|
|
118
|
+
const resolved = resolveNode(target, context);
|
|
119
|
+
// Merge any sibling properties from the $ref node
|
|
120
|
+
// JSON Schema allows properties alongside $ref in draft 2019-09+
|
|
121
|
+
const siblings = extractSiblingProperties(refNode);
|
|
122
|
+
const merged = mergeSiblings(resolved, siblings);
|
|
123
|
+
// Cache the result
|
|
124
|
+
context.cache.set(ref, merged);
|
|
125
|
+
return merged;
|
|
126
|
+
}
|
|
127
|
+
finally {
|
|
128
|
+
// Remove from resolving set
|
|
129
|
+
context.resolving.delete(ref);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Check if a reference is external (http://, https://, file://)
|
|
134
|
+
*/
|
|
135
|
+
function isExternalRef(ref) {
|
|
136
|
+
return (ref.startsWith('http://') ||
|
|
137
|
+
ref.startsWith('https://') ||
|
|
138
|
+
ref.startsWith('file://') ||
|
|
139
|
+
// Relative file references (not starting with #)
|
|
140
|
+
(!ref.startsWith('#') &&
|
|
141
|
+
(ref.endsWith('.json') || ref.endsWith('.yaml') || ref.endsWith('.yml'))));
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Resolve a JSON Pointer within a document
|
|
145
|
+
*
|
|
146
|
+
* Supports:
|
|
147
|
+
* - #/$defs/Name
|
|
148
|
+
* - #/definitions/Name
|
|
149
|
+
* - #/properties/field/items
|
|
150
|
+
*
|
|
151
|
+
* @param pointer - The JSON Pointer (e.g., '#/$defs/User')
|
|
152
|
+
* @param root - The root document
|
|
153
|
+
* @returns The resolved value or undefined if not found
|
|
154
|
+
*/
|
|
155
|
+
function resolvePointer(pointer, root) {
|
|
156
|
+
// Handle empty or root pointer
|
|
157
|
+
if (pointer === '#' || pointer === '') {
|
|
158
|
+
return root;
|
|
159
|
+
}
|
|
160
|
+
// Remove the leading # if present
|
|
161
|
+
let path = pointer;
|
|
162
|
+
if (path.startsWith('#')) {
|
|
163
|
+
path = path.slice(1);
|
|
164
|
+
}
|
|
165
|
+
// Remove leading slash
|
|
166
|
+
if (path.startsWith('/')) {
|
|
167
|
+
path = path.slice(1);
|
|
168
|
+
}
|
|
169
|
+
// Handle empty path after normalization
|
|
170
|
+
if (!path) {
|
|
171
|
+
return root;
|
|
172
|
+
}
|
|
173
|
+
// Split into segments and navigate
|
|
174
|
+
const segments = path.split('/');
|
|
175
|
+
let current = root;
|
|
176
|
+
for (const segment of segments) {
|
|
177
|
+
if (!isObject(current) && !Array.isArray(current)) {
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
const decoded = decodeJsonPointerSegment(segment);
|
|
181
|
+
if (Array.isArray(current)) {
|
|
182
|
+
const index = parseInt(decoded, 10);
|
|
183
|
+
if (isNaN(index) || index < 0 || index >= current.length) {
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
current = current[index];
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
const obj = current;
|
|
190
|
+
if (!(decoded in obj)) {
|
|
191
|
+
return undefined;
|
|
192
|
+
}
|
|
193
|
+
current = obj[decoded];
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return current;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Decode a JSON Pointer segment (RFC 6901)
|
|
200
|
+
*
|
|
201
|
+
* ~0 -> ~
|
|
202
|
+
* ~1 -> /
|
|
203
|
+
*/
|
|
204
|
+
function decodeJsonPointerSegment(segment) {
|
|
205
|
+
return segment.replace(/~1/g, '/').replace(/~0/g, '~');
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Encode a JSON Pointer segment (RFC 6901)
|
|
209
|
+
*
|
|
210
|
+
* ~ -> ~0
|
|
211
|
+
* / -> ~1
|
|
212
|
+
*/
|
|
213
|
+
function encodeJsonPointerSegment(segment) {
|
|
214
|
+
return segment.replace(/~/g, '~0').replace(/\//g, '~1');
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Extract sibling properties from a $ref node
|
|
218
|
+
*
|
|
219
|
+
* In JSON Schema draft 2019-09+, properties alongside $ref are allowed
|
|
220
|
+
* and should be merged with the referenced schema.
|
|
221
|
+
*/
|
|
222
|
+
function extractSiblingProperties(refNode) {
|
|
223
|
+
const siblings = {};
|
|
224
|
+
for (const [key, value] of Object.entries(refNode)) {
|
|
225
|
+
if (key !== '$ref') {
|
|
226
|
+
siblings[key] = value;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return siblings;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Merge sibling properties with a resolved schema
|
|
233
|
+
*/
|
|
234
|
+
function mergeSiblings(resolved, siblings) {
|
|
235
|
+
// If no siblings, return as-is
|
|
236
|
+
if (Object.keys(siblings).length === 0) {
|
|
237
|
+
return resolved;
|
|
238
|
+
}
|
|
239
|
+
// If resolved is not an object, wrap in allOf
|
|
240
|
+
if (!isObject(resolved)) {
|
|
241
|
+
return {
|
|
242
|
+
allOf: [resolved, siblings],
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
// Merge properties, siblings override resolved
|
|
246
|
+
return {
|
|
247
|
+
...resolved,
|
|
248
|
+
...siblings,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Type guard for objects
|
|
253
|
+
*/
|
|
254
|
+
function isObject(value) {
|
|
255
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Check if a schema contains any unresolved $refs
|
|
259
|
+
*
|
|
260
|
+
* @param schema - The schema to check
|
|
261
|
+
* @returns True if the schema contains $ref pointers
|
|
262
|
+
*/
|
|
263
|
+
export function hasUnresolvedRefs(schema) {
|
|
264
|
+
if (!isObject(schema)) {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
const obj = schema;
|
|
268
|
+
// Check if this node is a $ref
|
|
269
|
+
if (typeof obj['$ref'] === 'string' && !obj['$circularRef']) {
|
|
270
|
+
return true;
|
|
271
|
+
}
|
|
272
|
+
// Check children
|
|
273
|
+
for (const value of Object.values(obj)) {
|
|
274
|
+
if (Array.isArray(value)) {
|
|
275
|
+
for (const item of value) {
|
|
276
|
+
if (hasUnresolvedRefs(item)) {
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
else if (hasUnresolvedRefs(value)) {
|
|
282
|
+
return true;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Extract all $ref pointers from a schema
|
|
289
|
+
*
|
|
290
|
+
* @param schema - The schema to analyze
|
|
291
|
+
* @returns Array of { pointer, path } objects
|
|
292
|
+
*/
|
|
293
|
+
export function extractRefs(schema) {
|
|
294
|
+
const refs = [];
|
|
295
|
+
collectRefs(schema, '', refs);
|
|
296
|
+
return refs;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Recursively collect $refs
|
|
300
|
+
*/
|
|
301
|
+
function collectRefs(node, path, refs) {
|
|
302
|
+
if (!isObject(node)) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const obj = node;
|
|
306
|
+
if (typeof obj['$ref'] === 'string') {
|
|
307
|
+
refs.push({ pointer: obj['$ref'], path: path || '/' });
|
|
308
|
+
}
|
|
309
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
310
|
+
const childPath = `${path}/${encodeJsonPointerSegment(key)}`;
|
|
311
|
+
if (Array.isArray(value)) {
|
|
312
|
+
value.forEach((item, index) => {
|
|
313
|
+
collectRefs(item, `${childPath}/${index}`, refs);
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
collectRefs(value, childPath, refs);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Validate that all internal references in a schema are resolvable
|
|
323
|
+
*
|
|
324
|
+
* @param schema - The schema to validate
|
|
325
|
+
* @returns Object with valid flag and any error messages
|
|
326
|
+
*/
|
|
327
|
+
export function validateRefs(schema) {
|
|
328
|
+
const errors = [];
|
|
329
|
+
const refs = extractRefs(schema);
|
|
330
|
+
for (const { pointer, path } of refs) {
|
|
331
|
+
// Skip external refs for this validation
|
|
332
|
+
if (isExternalRef(pointer)) {
|
|
333
|
+
continue;
|
|
334
|
+
}
|
|
335
|
+
const resolved = resolvePointer(pointer, schema);
|
|
336
|
+
if (resolved === undefined) {
|
|
337
|
+
errors.push(`Invalid reference at ${path}: ${pointer} not found`);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
valid: errors.length === 0,
|
|
342
|
+
errors,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
//# sourceMappingURL=ref-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ref-resolver.js","sourceRoot":"","sources":["../src/ref-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA4BH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,WAAW,CAAC,MAAe;IACzC,MAAM,OAAO,GAAG;QACd,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,EAAE;QACZ,SAAS,EAAE,IAAI,GAAG,EAAE;QACpB,KAAK,EAAE,IAAI,GAAG,EAAE;QAChB,WAAW,EAAE,EAAE;KACS,CAAC;IAE3B,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAE9C,OAAO;QACL,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAAC,IAAa,EAAE,OAAuB;IACzD,qBAAqB;IACrB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,GAAG,GAAG,IAA+B,CAAC;IAE5C,+BAA+B;IAC/B,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;QACpC,OAAO,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAED,qCAAqC;IACrC,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAE7C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;QACzC,OAAO,CAAC,WAAW,GAAG,GAAG,OAAO,CAAC,WAAW,IAAI,wBAAwB,CAAC,GAAG,CAAC,EAAE,CAAC;QAEhF,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;gBACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,CAAC;gBACrC,OAAO,CAAC,WAAW,GAAG,GAAG,QAAQ,IAAI,KAAK,EAAE,CAAC;gBAC7C,MAAM,YAAY,GAAG,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;gBAChD,OAAO,CAAC,WAAW,GAAG,QAAQ,CAAC;gBAC/B,OAAO,YAAY,CAAC;YACtB,CAAC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC9C,CAAC;QAED,OAAO,CAAC,WAAW,GAAG,YAAY,CAAC;IACrC,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CACjB,GAAW,EACX,OAAgC,EAChC,OAAuB;IAEvB,gCAAgC;IAChC,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,QAAQ,CAAC,IAAI,CACnB,oCAAoC,GAAG,OAAO,OAAO,CAAC,WAAW,IAAI,GAAG,EAAE,CAC3E,CAAC;QACF,+CAA+C;QAC/C,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,+BAA+B;IAC/B,IAAI,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,gCAAgC,GAAG,OAAO,OAAO,CAAC,WAAW,IAAI,GAAG,EAAE,CAAC,CAAC;QAC9F,0CAA0C;QAC1C,OAAO;YACL,YAAY,EAAE,GAAG;YACjB,QAAQ,EAAE,4CAA4C;SACvD,CAAC;IACJ,CAAC;IAED,cAAc;IACd,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,8BAA8B;IAC9B,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAE3B,IAAI,CAAC;QACH,wBAAwB;QACxB,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAEjD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,wBAAwB,GAAG,OAAO,OAAO,CAAC,WAAW,IAAI,GAAG,EAAE,CAAC,CAAC;YACtF,iDAAiD;YACjD,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,6DAA6D;QAC7D,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAE9C,kDAAkD;QAClD,iEAAiE;QACjE,MAAM,QAAQ,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAEjD,mBAAmB;QACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QAE/B,OAAO,MAAM,CAAC;IAChB,CAAC;YAAS,CAAC;QACT,4BAA4B;QAC5B,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,GAAW;IAChC,OAAO,CACL,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;QACzB,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC;QAC1B,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;QACzB,iDAAiD;QACjD,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;YACnB,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAC5E,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,cAAc,CAAC,OAAe,EAAE,IAAa;IACpD,+BAA+B;IAC/B,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,EAAE,EAAE,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kCAAkC;IAClC,IAAI,IAAI,GAAG,OAAO,CAAC;IACnB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,uBAAuB;IACvB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzB,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,CAAC;IAED,wCAAwC;IACxC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,IAAI,CAAC;IACd,CAAC;IAED,mCAAmC;IACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,OAAO,GAAY,IAAI,CAAC;IAE5B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAClD,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAElD,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACpC,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACzD,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,GAAG,OAAkC,CAAC;YAC/C,IAAI,CAAC,CAAC,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC;gBACtB,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,SAAS,wBAAwB,CAAC,OAAe;IAC/C,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACzD,CAAC;AAED;;;;;GAKG;AACH,SAAS,wBAAwB,CAAC,OAAe;IAC/C,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;GAKG;AACH,SAAS,wBAAwB,CAAC,OAAgC;IAChE,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAE7C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;YACnB,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACxB,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,QAAiB,EAAE,QAAiC;IACzE,+BAA+B;IAC/B,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,8CAA8C;IAC9C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxB,OAAO;YACL,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC;SAC5B,CAAC;IACJ,CAAC;IAED,+CAA+C;IAC/C,OAAO;QACL,GAAI,QAAoC;QACxC,GAAG,QAAQ;KACZ,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAe;IAC/C,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,GAAG,GAAG,MAAiC,CAAC;IAE9C,+BAA+B;IAC/B,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;QAC5D,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iBAAiB;IACjB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QACvC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC5B,OAAO,IAAI,CAAC;gBACd,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,MAAe;IACzC,MAAM,IAAI,GAA6C,EAAE,CAAC;IAC1D,WAAW,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IAC9B,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAS,WAAW,CAClB,IAAa,EACb,IAAY,EACZ,IAA8C;IAE9C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,OAAO;IACT,CAAC;IAED,MAAM,GAAG,GAAG,IAA+B,CAAC;IAE5C,IAAI,OAAO,GAAG,CAAC,MAAM,CAAC,KAAK,QAAQ,EAAE,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,SAAS,GAAG,GAAG,IAAI,IAAI,wBAAwB,CAAC,GAAG,CAAC,EAAE,CAAC;QAE7D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;gBAC5B,WAAW,CAAC,IAAI,EAAE,GAAG,SAAS,IAAI,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC;YACnD,CAAC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,MAAe;IAI1C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IAEjC,KAAK,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QACrC,yCAAyC;QACzC,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,SAAS;QACX,CAAC;QAED,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACjD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,wBAAwB,IAAI,KAAK,OAAO,YAAY,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC;QAC1B,MAAM;KACP,CAAC;AACJ,CAAC"}
|