@squiz/dx-json-schema-lib 1.87.0 → 1.89.0
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/CHANGELOG.md +14 -0
- package/lib/browser.d.ts +21 -0
- package/lib/browser.js +61 -0
- package/lib/browser.js.map +1 -0
- package/lib/formatted-text/v1/resolveFormattedTextNodes.d.ts +5 -2
- package/lib/formatted-text/v1/resolveFormattedTextNodes.js +12 -6
- package/lib/formatted-text/v1/resolveFormattedTextNodes.js.map +1 -1
- package/lib/formatted-text/v1/resolveFormattedTextNodes.spec.js +58 -0
- package/lib/formatted-text/v1/resolveFormattedTextNodes.spec.js.map +1 -1
- package/lib/index.d.ts +1 -15
- package/lib/index.js +4 -38
- package/lib/index.js.map +1 -1
- package/lib/primitiveTypes/FormattedText.js +36 -3
- package/lib/primitiveTypes/FormattedText.js.map +1 -1
- package/lib/utils/jsonBreakDetector/checks/findArrayConstraintNarrowing.d.ts +6 -0
- package/lib/utils/jsonBreakDetector/checks/findArrayConstraintNarrowing.js +93 -0
- package/lib/utils/jsonBreakDetector/checks/findArrayConstraintNarrowing.js.map +1 -0
- package/lib/utils/jsonBreakDetector/checks/findConstChanges.d.ts +6 -0
- package/lib/utils/jsonBreakDetector/checks/findConstChanges.js +75 -0
- package/lib/utils/jsonBreakDetector/checks/findConstChanges.js.map +1 -0
- package/lib/utils/jsonBreakDetector/checks/findEnumNarrowing.d.ts +6 -0
- package/lib/utils/jsonBreakDetector/checks/findEnumNarrowing.js +90 -0
- package/lib/utils/jsonBreakDetector/checks/findEnumNarrowing.js.map +1 -0
- package/lib/utils/jsonBreakDetector/checks/findFieldTypeChanges.d.ts +8 -0
- package/lib/utils/jsonBreakDetector/checks/findFieldTypeChanges.js +86 -0
- package/lib/utils/jsonBreakDetector/checks/findFieldTypeChanges.js.map +1 -0
- package/lib/utils/jsonBreakDetector/checks/findNewRequiredFields.d.ts +6 -0
- package/lib/utils/jsonBreakDetector/checks/findNewRequiredFields.js +68 -0
- package/lib/utils/jsonBreakDetector/checks/findNewRequiredFields.js.map +1 -0
- package/lib/utils/jsonBreakDetector/checks/findNumericConstraintNarrowing.d.ts +6 -0
- package/lib/utils/jsonBreakDetector/checks/findNumericConstraintNarrowing.js +179 -0
- package/lib/utils/jsonBreakDetector/checks/findNumericConstraintNarrowing.js.map +1 -0
- package/lib/utils/jsonBreakDetector/checks/findStringConstraintNarrowing.d.ts +6 -0
- package/lib/utils/jsonBreakDetector/checks/findStringConstraintNarrowing.js +106 -0
- package/lib/utils/jsonBreakDetector/checks/findStringConstraintNarrowing.js.map +1 -0
- package/lib/utils/jsonBreakDetector/compareSubschemas.d.ts +9 -0
- package/lib/utils/jsonBreakDetector/compareSubschemas.js +49 -0
- package/lib/utils/jsonBreakDetector/compareSubschemas.js.map +1 -0
- package/lib/utils/jsonBreakDetector/dereference/dereference.d.ts +6 -0
- package/lib/utils/jsonBreakDetector/dereference/dereference.js +52 -0
- package/lib/utils/jsonBreakDetector/dereference/dereference.js.map +1 -0
- package/lib/utils/jsonBreakDetector/dereference/dereference.spec.d.ts +1 -0
- package/lib/utils/jsonBreakDetector/dereference/dereference.spec.js +225 -0
- package/lib/utils/jsonBreakDetector/dereference/dereference.spec.js.map +1 -0
- package/lib/utils/jsonBreakDetector/jsonBreakDetector.d.ts +8 -0
- package/lib/utils/jsonBreakDetector/jsonBreakDetector.js +35 -0
- package/lib/utils/jsonBreakDetector/jsonBreakDetector.js.map +1 -0
- package/lib/utils/jsonBreakDetector/jsonBreakDetector.spec.d.ts +1 -0
- package/lib/utils/jsonBreakDetector/jsonBreakDetector.spec.js +2761 -0
- package/lib/utils/jsonBreakDetector/jsonBreakDetector.spec.js.map +1 -0
- package/lib/utils/jsonBreakDetector/types.d.ts +25 -0
- package/lib/utils/jsonBreakDetector/types.js +28 -0
- package/lib/utils/jsonBreakDetector/types.js.map +1 -0
- package/package.json +10 -1
- package/src/browser.ts +27 -0
- package/src/formatted-text/v1/resolveFormattedTextNodes.spec.ts +70 -0
- package/src/formatted-text/v1/resolveFormattedTextNodes.ts +19 -4
- package/src/index.ts +4 -20
- package/src/primitiveTypes/FormattedText.ts +1 -1
- package/src/utils/jsonBreakDetector/checks/findArrayConstraintNarrowing.ts +121 -0
- package/src/utils/jsonBreakDetector/checks/findConstChanges.ts +97 -0
- package/src/utils/jsonBreakDetector/checks/findEnumNarrowing.ts +124 -0
- package/src/utils/jsonBreakDetector/checks/findFieldTypeChanges.ts +105 -0
- package/src/utils/jsonBreakDetector/checks/findNewRequiredFields.ts +97 -0
- package/src/utils/jsonBreakDetector/checks/findNumericConstraintNarrowing.ts +243 -0
- package/src/utils/jsonBreakDetector/checks/findStringConstraintNarrowing.ts +139 -0
- package/src/utils/jsonBreakDetector/compareSubschemas.ts +67 -0
- package/src/utils/jsonBreakDetector/dereference/dereference.spec.ts +245 -0
- package/src/utils/jsonBreakDetector/dereference/dereference.ts +65 -0
- package/src/utils/jsonBreakDetector/jsonBreakDetector.spec.ts +3041 -0
- package/src/utils/jsonBreakDetector/jsonBreakDetector.ts +36 -0
- package/src/utils/jsonBreakDetector/types.ts +29 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findStringConstraintNarrowing = findStringConstraintNarrowing;
|
|
4
|
+
exports.checkStringConstraintNarrowing = checkStringConstraintNarrowing;
|
|
5
|
+
const types_1 = require("../types");
|
|
6
|
+
/** Recursively detects narrowed string constraints at each schema level, accumulating dotted paths. */
|
|
7
|
+
function findStringConstraintNarrowing(beforeSchema, afterSchema, path, breaks) {
|
|
8
|
+
var _a, _b;
|
|
9
|
+
const beforeProperties = (_a = beforeSchema.properties) !== null && _a !== void 0 ? _a : {};
|
|
10
|
+
const afterProperties = (_b = afterSchema.properties) !== null && _b !== void 0 ? _b : {};
|
|
11
|
+
// Recurse into latest nested object properties.
|
|
12
|
+
for (const [key, afterPropertySchema] of Object.entries(afterProperties)) {
|
|
13
|
+
// Skip if the property is not an object.
|
|
14
|
+
if (!afterPropertySchema || typeof afterPropertySchema !== 'object') {
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
const beforePropertySchema = beforeProperties[key];
|
|
18
|
+
const childPath = path ? `${path}.${key}` : key;
|
|
19
|
+
// Only compare string constraints on fields that existed in the before schema. New fields are skipped.
|
|
20
|
+
if (beforePropertySchema && typeof beforePropertySchema === 'object') {
|
|
21
|
+
checkStringConstraintNarrowing(beforePropertySchema, afterPropertySchema, childPath, breaks);
|
|
22
|
+
findStringConstraintNarrowing(beforePropertySchema, afterPropertySchema, childPath, breaks);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const beforeItems = beforeSchema.items;
|
|
26
|
+
const afterItems = afterSchema.items;
|
|
27
|
+
// Recurse into latest nested array items.
|
|
28
|
+
if (afterItems && typeof afterItems === 'object' && !Array.isArray(afterItems)) {
|
|
29
|
+
const itemsPath = path ? `${path}[]` : '[]';
|
|
30
|
+
const beforeItemSchema = beforeItems && typeof beforeItems === 'object' && !Array.isArray(beforeItems) ? beforeItems : undefined;
|
|
31
|
+
// Only compare string constraints on items that existed in the before schema. New items are skipped.
|
|
32
|
+
if (beforeItemSchema) {
|
|
33
|
+
checkStringConstraintNarrowing(beforeItemSchema, afterItems, itemsPath, breaks);
|
|
34
|
+
findStringConstraintNarrowing(beforeItemSchema, afterItems, itemsPath, breaks);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** Returns true when a schema represents a string field. */
|
|
39
|
+
function isStringFieldSchema(schema) {
|
|
40
|
+
const type = schema.type;
|
|
41
|
+
if (type === 'string') {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
// Type can be defined as a union of strings e.g. ['string', 'number'], so check if 'string' is included.
|
|
45
|
+
if (Array.isArray(type) && type.includes('string')) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
return (schema.minLength !== undefined ||
|
|
49
|
+
schema.maxLength !== undefined ||
|
|
50
|
+
schema.format !== undefined ||
|
|
51
|
+
schema.pattern !== undefined);
|
|
52
|
+
}
|
|
53
|
+
/** Returns true when afterSchema requires a longer string than beforeSchema. */
|
|
54
|
+
function hasMinLengthIncreased(beforeSchema, afterSchema) {
|
|
55
|
+
var _a, _b;
|
|
56
|
+
const beforeMinLength = (_a = beforeSchema.minLength) !== null && _a !== void 0 ? _a : 0;
|
|
57
|
+
const afterMinLength = (_b = afterSchema.minLength) !== null && _b !== void 0 ? _b : 0;
|
|
58
|
+
return afterMinLength > beforeMinLength;
|
|
59
|
+
}
|
|
60
|
+
/** Returns true when afterSchema allows a shorter string than beforeSchema. */
|
|
61
|
+
function hasMaxLengthLowered(beforeSchema, afterSchema) {
|
|
62
|
+
const beforeMaxLength = beforeSchema.maxLength;
|
|
63
|
+
const afterMaxLength = afterSchema.maxLength;
|
|
64
|
+
if (afterMaxLength === undefined) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
if (beforeMaxLength === undefined) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
return afterMaxLength < beforeMaxLength;
|
|
71
|
+
}
|
|
72
|
+
/** Returns true when afterSchema adds or changes a format constraint. */
|
|
73
|
+
function hasFormatChanged(beforeSchema, afterSchema) {
|
|
74
|
+
const afterFormat = afterSchema.format;
|
|
75
|
+
if (afterFormat === undefined) {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
return beforeSchema.format !== afterFormat;
|
|
79
|
+
}
|
|
80
|
+
/** Returns true when afterSchema adds or changes a pattern constraint. */
|
|
81
|
+
function hasPatternChanged(beforeSchema, afterSchema) {
|
|
82
|
+
const afterPattern = afterSchema.pattern;
|
|
83
|
+
if (afterPattern === undefined) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
return beforeSchema.pattern !== afterPattern;
|
|
87
|
+
}
|
|
88
|
+
/** Checks string constraint keywords on a single schema for narrowing changes. */
|
|
89
|
+
function checkStringConstraintNarrowing(beforeSchema, afterSchema, path, breaks) {
|
|
90
|
+
if (!isStringFieldSchema(beforeSchema) && !isStringFieldSchema(afterSchema)) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
if (hasMinLengthIncreased(beforeSchema, afterSchema)) {
|
|
94
|
+
(0, types_1.pushBreak)(breaks, path, types_1.BREAK_MESSAGES.minLength);
|
|
95
|
+
}
|
|
96
|
+
if (hasMaxLengthLowered(beforeSchema, afterSchema)) {
|
|
97
|
+
(0, types_1.pushBreak)(breaks, path, types_1.BREAK_MESSAGES.maxLength);
|
|
98
|
+
}
|
|
99
|
+
if (hasFormatChanged(beforeSchema, afterSchema)) {
|
|
100
|
+
(0, types_1.pushBreak)(breaks, path, types_1.BREAK_MESSAGES.format);
|
|
101
|
+
}
|
|
102
|
+
if (hasPatternChanged(beforeSchema, afterSchema)) {
|
|
103
|
+
(0, types_1.pushBreak)(breaks, path, types_1.BREAK_MESSAGES.pattern);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=findStringConstraintNarrowing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findStringConstraintNarrowing.js","sourceRoot":"","sources":["../../../../src/utils/jsonBreakDetector/checks/findStringConstraintNarrowing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { JSONSchema } from '@squiz/json-schema-library';
|
|
2
|
+
import { JsonBreak } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Compares two schemas at the same path using every jsonBreakDetector check,
|
|
5
|
+
* including leaf-level constraints on the current node.
|
|
6
|
+
*/
|
|
7
|
+
export declare function compareSubschemas(beforeSchema: JSONSchema, afterSchema: JSONSchema, path: string, breaks: JsonBreak[]): void;
|
|
8
|
+
/** Compares array `contains` subschemas using the full jsonBreakDetector check suite. */
|
|
9
|
+
export declare function compareContainsSubschemas(beforeArraySchema: JSONSchema, afterArraySchema: JSONSchema, arrayPath: string, breaks: JsonBreak[]): void;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compareSubschemas = compareSubschemas;
|
|
4
|
+
exports.compareContainsSubschemas = compareContainsSubschemas;
|
|
5
|
+
const findArrayConstraintNarrowing_1 = require("./checks/findArrayConstraintNarrowing");
|
|
6
|
+
const findConstChanges_1 = require("./checks/findConstChanges");
|
|
7
|
+
const findFieldTypeChanges_1 = require("./checks/findFieldTypeChanges");
|
|
8
|
+
const findNewRequiredFields_1 = require("./checks/findNewRequiredFields");
|
|
9
|
+
const findNumericConstraintNarrowing_1 = require("./checks/findNumericConstraintNarrowing");
|
|
10
|
+
const findEnumNarrowing_1 = require("./checks/findEnumNarrowing");
|
|
11
|
+
const findStringConstraintNarrowing_1 = require("./checks/findStringConstraintNarrowing");
|
|
12
|
+
const types_1 = require("./types");
|
|
13
|
+
/**
|
|
14
|
+
* Compares two schemas at the same path using every jsonBreakDetector check,
|
|
15
|
+
* including leaf-level constraints on the current node.
|
|
16
|
+
*/
|
|
17
|
+
function compareSubschemas(beforeSchema, afterSchema, path, breaks) {
|
|
18
|
+
// Only applicable to nested schemas (from `contains` subschemas), not the root schema.
|
|
19
|
+
if (path !== '') {
|
|
20
|
+
if ((0, findFieldTypeChanges_1.hasTypeChange)(beforeSchema, afterSchema)) {
|
|
21
|
+
(0, types_1.pushBreak)(breaks, path, types_1.BREAK_MESSAGES.type);
|
|
22
|
+
}
|
|
23
|
+
(0, findEnumNarrowing_1.checkEnumNarrowingAtNode)(beforeSchema, afterSchema, path, breaks);
|
|
24
|
+
(0, findConstChanges_1.checkConstNarrowingAtNode)(beforeSchema, afterSchema, path, breaks);
|
|
25
|
+
}
|
|
26
|
+
(0, findArrayConstraintNarrowing_1.checkArrayConstraintNarrowing)(beforeSchema, afterSchema, path, breaks);
|
|
27
|
+
(0, findNumericConstraintNarrowing_1.checkNumericConstraintNarrowing)(beforeSchema, afterSchema, path, breaks);
|
|
28
|
+
(0, findStringConstraintNarrowing_1.checkStringConstraintNarrowing)(beforeSchema, afterSchema, path, breaks);
|
|
29
|
+
// Find breaking changes at children properties and items
|
|
30
|
+
(0, findNewRequiredFields_1.findNewRequiredFields)(beforeSchema, afterSchema, path, breaks);
|
|
31
|
+
(0, findFieldTypeChanges_1.findFieldTypeChanges)(beforeSchema, afterSchema, path, breaks);
|
|
32
|
+
(0, findEnumNarrowing_1.findEnumNarrowing)(beforeSchema, afterSchema, path, breaks);
|
|
33
|
+
(0, findConstChanges_1.findConstChanges)(beforeSchema, afterSchema, path, breaks);
|
|
34
|
+
(0, findArrayConstraintNarrowing_1.findArrayConstraintNarrowing)(beforeSchema, afterSchema, path, breaks);
|
|
35
|
+
(0, findNumericConstraintNarrowing_1.findNumericConstraintNarrowing)(beforeSchema, afterSchema, path, breaks);
|
|
36
|
+
(0, findStringConstraintNarrowing_1.findStringConstraintNarrowing)(beforeSchema, afterSchema, path, breaks);
|
|
37
|
+
}
|
|
38
|
+
/** Compares array `contains` subschemas using the full jsonBreakDetector check suite. */
|
|
39
|
+
function compareContainsSubschemas(beforeArraySchema, afterArraySchema, arrayPath, breaks) {
|
|
40
|
+
const afterContains = afterArraySchema.contains;
|
|
41
|
+
if (!afterContains || typeof afterContains !== 'object') {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const beforeContains = beforeArraySchema.contains;
|
|
45
|
+
const containsPath = arrayPath ? `${arrayPath}.{contains}` : '{contains}';
|
|
46
|
+
const beforeSubschema = beforeContains && typeof beforeContains === 'object' ? beforeContains : {};
|
|
47
|
+
compareSubschemas(beforeSubschema, afterContains, containsPath, breaks);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=compareSubschemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compareSubschemas.js","sourceRoot":"","sources":["../../../src/utils/jsonBreakDetector/compareSubschemas.ts"],"names":[],"mappings":";;AAkBA,8CA4BC;AAGD,8DAiBC;AAhED,wFAAoH;AACpH,gEAAwF;AACxF,wEAAoF;AACpF,0EAAuE;AACvE,4FAGiD;AACjD,kEAAyF;AACzF,0FAAuH;AACvH,mCAA+D;AAE/D;;;GAGG;AACH,SAAgB,iBAAiB,CAC/B,YAAwB,EACxB,WAAuB,EACvB,IAAY,EACZ,MAAmB;IAEnB,uFAAuF;IACvF,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QAChB,IAAI,IAAA,oCAAa,EAAC,YAAY,EAAE,WAAW,CAAC,EAAE,CAAC;YAC7C,IAAA,iBAAS,EAAC,MAAM,EAAE,IAAI,EAAE,sBAAc,CAAC,IAAI,CAAC,CAAC;QAC/C,CAAC;QAED,IAAA,4CAAwB,EAAC,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAClE,IAAA,4CAAyB,EAAC,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACrE,CAAC;IAED,IAAA,4DAA6B,EAAC,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACvE,IAAA,gEAA+B,EAAC,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACzE,IAAA,8DAA8B,EAAC,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAExE,yDAAyD;IACzD,IAAA,6CAAqB,EAAC,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC/D,IAAA,2CAAoB,EAAC,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9D,IAAA,qCAAiB,EAAC,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC3D,IAAA,mCAAgB,EAAC,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1D,IAAA,2DAA4B,EAAC,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACtE,IAAA,+DAA8B,EAAC,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACxE,IAAA,6DAA6B,EAAC,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;AACzE,CAAC;AAED,yFAAyF;AACzF,SAAgB,yBAAyB,CACvC,iBAA6B,EAC7B,gBAA4B,EAC5B,SAAiB,EACjB,MAAmB;IAEnB,MAAM,aAAa,GAAG,gBAAgB,CAAC,QAAQ,CAAC;IAEhD,IAAI,CAAC,aAAa,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;QACxD,OAAO;IACT,CAAC;IAED,MAAM,cAAc,GAAG,iBAAiB,CAAC,QAAQ,CAAC;IAClD,MAAM,YAAY,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,aAAa,CAAC,CAAC,CAAC,YAAY,CAAC;IAC1E,MAAM,eAAe,GAAG,cAAc,IAAI,OAAO,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAE,cAA6B,CAAC,CAAC,CAAC,EAAE,CAAC;IAEnH,iBAAiB,CAAC,eAAe,EAAE,aAA2B,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;AACxF,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { JSONSchema } from '@squiz/json-schema-library';
|
|
2
|
+
export type GenericSchema = Record<string, any>;
|
|
3
|
+
/**
|
|
4
|
+
* Synchronously dereferences internal ($ref: "#/...") JSON schema references.
|
|
5
|
+
*/
|
|
6
|
+
export declare function dereferenceLocal<T extends GenericSchema = JSONSchema>(schema: T): T;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dereferenceLocal = dereferenceLocal;
|
|
4
|
+
/**
|
|
5
|
+
* Synchronously dereferences internal ($ref: "#/...") JSON schema references.
|
|
6
|
+
*/
|
|
7
|
+
function dereferenceLocal(schema) {
|
|
8
|
+
function resolvePointer(root, pointer) {
|
|
9
|
+
if (!pointer.startsWith('#/')) {
|
|
10
|
+
throw new Error(`Only internal references starting with "#/" are supported. Received: "${pointer}"`);
|
|
11
|
+
}
|
|
12
|
+
const pathSegments = pointer.replace(/^#\//, '').split('/');
|
|
13
|
+
return pathSegments.reduce((acc, key) => {
|
|
14
|
+
// Decode RFC 6901 JSON Pointer escaped sequences (~1 -> /, ~0 -> ~)
|
|
15
|
+
const unescapedKey = key.replace(/~1/g, '/').replace(/~0/g, '~');
|
|
16
|
+
if (acc && typeof acc === 'object' && unescapedKey in acc) {
|
|
17
|
+
return acc[unescapedKey];
|
|
18
|
+
}
|
|
19
|
+
throw new Error(`Could not resolve JSON pointer reference: "${pointer}" at segment "${key}"`);
|
|
20
|
+
}, root);
|
|
21
|
+
}
|
|
22
|
+
function walk(node, root, seen = new WeakSet()) {
|
|
23
|
+
if (node === null || typeof node !== 'object') {
|
|
24
|
+
return node;
|
|
25
|
+
}
|
|
26
|
+
// Prevent infinite loops on circular references
|
|
27
|
+
if (seen.has(node)) {
|
|
28
|
+
return node;
|
|
29
|
+
}
|
|
30
|
+
seen.add(node);
|
|
31
|
+
if (Array.isArray(node)) {
|
|
32
|
+
return node.map((item) => walk(item, root, seen));
|
|
33
|
+
}
|
|
34
|
+
// Check if current object contains a string $ref property
|
|
35
|
+
if (typeof node.$ref === 'string') {
|
|
36
|
+
const resolvedTarget = resolvePointer(root, node.$ref);
|
|
37
|
+
// Separate $ref from rest of keys (JSON Schema draft 2019-09+ allows sibling properties)
|
|
38
|
+
const { $ref: _ref, ...rest } = node;
|
|
39
|
+
return {
|
|
40
|
+
...walk(resolvedTarget, root, seen),
|
|
41
|
+
...walk(rest, root, seen),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
const result = {};
|
|
45
|
+
for (const [key, value] of Object.entries(node)) {
|
|
46
|
+
result[key] = walk(value, root, seen);
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
return walk(schema, schema);
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=dereference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dereference.js","sourceRoot":"","sources":["../../../../src/utils/jsonBreakDetector/dereference/dereference.ts"],"names":[],"mappings":";;AAOA,4CAyDC;AA5DD;;GAEG;AACH,SAAgB,gBAAgB,CAAuC,MAAS;IAC9E,SAAS,cAAc,CAAC,IAAyB,EAAE,OAAe;QAChE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,yEAAyE,OAAO,GAAG,CAAC,CAAC;QACvG,CAAC;QAED,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE5D,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACtC,oEAAoE;YACpE,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAEjE,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,YAAY,IAAI,GAAG,EAAE,CAAC;gBAC1D,OAAO,GAAG,CAAC,YAAY,CAAC,CAAC;YAC3B,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,8CAA8C,OAAO,iBAAiB,GAAG,GAAG,CAAC,CAAC;QAChG,CAAC,EAAE,IAAI,CAAC,CAAC;IACX,CAAC;IAED,SAAS,IAAI,CAAC,IAAS,EAAE,IAAyB,EAAE,OAAO,IAAI,OAAO,EAAU;QAC9E,IAAI,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9C,OAAO,IAAI,CAAC;QACd,CAAC;QAED,gDAAgD;QAChD,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAEf,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;QACpD,CAAC;QAED,0DAA0D;QAC1D,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAClC,MAAM,cAAc,GAAG,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAEvD,yFAAyF;YACzF,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;YAErC,OAAO;gBACL,GAAG,IAAI,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,CAAC;gBACnC,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;aAC1B,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAwB,EAAE,CAAC;QACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAChD,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,IAAI,CAAC,MAAM,EAAE,MAAM,CAAM,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const dereference_1 = require("./dereference");
|
|
4
|
+
describe('dereferenceLocal', () => {
|
|
5
|
+
describe('JSON Schema Draft 7', () => {
|
|
6
|
+
it('dereferences a top-level $ref to a definition', () => {
|
|
7
|
+
const schema = {
|
|
8
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
9
|
+
$ref: '#/definitions/Person',
|
|
10
|
+
definitions: {
|
|
11
|
+
Person: {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
name: { type: 'string' },
|
|
15
|
+
},
|
|
16
|
+
required: ['name'],
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
expect((0, dereference_1.dereferenceLocal)(schema)).toEqual({
|
|
21
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
22
|
+
definitions: {
|
|
23
|
+
Person: {
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: {
|
|
26
|
+
name: { type: 'string' },
|
|
27
|
+
},
|
|
28
|
+
required: ['name'],
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
type: 'object',
|
|
32
|
+
properties: {
|
|
33
|
+
name: { type: 'string' },
|
|
34
|
+
},
|
|
35
|
+
required: ['name'],
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
it('dereferences nested $refs in properties', () => {
|
|
39
|
+
const schema = {
|
|
40
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
41
|
+
type: 'object',
|
|
42
|
+
properties: {
|
|
43
|
+
address: { $ref: '#/definitions/Address' },
|
|
44
|
+
},
|
|
45
|
+
definitions: {
|
|
46
|
+
Address: {
|
|
47
|
+
type: 'object',
|
|
48
|
+
properties: {
|
|
49
|
+
city: { $ref: '#/definitions/City' },
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
City: {
|
|
53
|
+
type: 'string',
|
|
54
|
+
minLength: 1,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
expect((0, dereference_1.dereferenceLocal)(schema)).toEqual({
|
|
59
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
60
|
+
type: 'object',
|
|
61
|
+
properties: {
|
|
62
|
+
address: {
|
|
63
|
+
type: 'object',
|
|
64
|
+
properties: {
|
|
65
|
+
city: {
|
|
66
|
+
type: 'string',
|
|
67
|
+
minLength: 1,
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
definitions: {
|
|
73
|
+
Address: {
|
|
74
|
+
type: 'object',
|
|
75
|
+
properties: {
|
|
76
|
+
city: { $ref: '#/definitions/City' },
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
City: {
|
|
80
|
+
type: 'string',
|
|
81
|
+
minLength: 1,
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
it('dereferences $refs inside combinators', () => {
|
|
87
|
+
const schema = {
|
|
88
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
89
|
+
oneOf: [{ $ref: '#/definitions/StringValue' }, { $ref: '#/definitions/NumberValue' }],
|
|
90
|
+
definitions: {
|
|
91
|
+
StringValue: { type: 'string' },
|
|
92
|
+
NumberValue: { type: 'number' },
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
expect((0, dereference_1.dereferenceLocal)(schema)).toEqual({
|
|
96
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
97
|
+
oneOf: [{ type: 'string' }, { type: 'number' }],
|
|
98
|
+
definitions: {
|
|
99
|
+
StringValue: { type: 'string' },
|
|
100
|
+
NumberValue: { type: 'number' },
|
|
101
|
+
},
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
it('dereferences chained $refs', () => {
|
|
105
|
+
const schema = {
|
|
106
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
107
|
+
$ref: '#/definitions/Outer',
|
|
108
|
+
definitions: {
|
|
109
|
+
Outer: { $ref: '#/definitions/Inner' },
|
|
110
|
+
Inner: {
|
|
111
|
+
type: 'boolean',
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
expect((0, dereference_1.dereferenceLocal)(schema)).toEqual({
|
|
116
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
117
|
+
definitions: {
|
|
118
|
+
Outer: { $ref: '#/definitions/Inner' },
|
|
119
|
+
Inner: {
|
|
120
|
+
type: 'boolean',
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
type: 'boolean',
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
it('merges sibling properties alongside a $ref', () => {
|
|
127
|
+
const schema = {
|
|
128
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
129
|
+
properties: {
|
|
130
|
+
title: {
|
|
131
|
+
$ref: '#/definitions/NonEmptyString',
|
|
132
|
+
description: 'A human-readable title',
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
definitions: {
|
|
136
|
+
NonEmptyString: {
|
|
137
|
+
type: 'string',
|
|
138
|
+
minLength: 1,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
expect((0, dereference_1.dereferenceLocal)(schema)).toEqual({
|
|
143
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
144
|
+
properties: {
|
|
145
|
+
title: {
|
|
146
|
+
type: 'string',
|
|
147
|
+
minLength: 1,
|
|
148
|
+
description: 'A human-readable title',
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
definitions: {
|
|
152
|
+
NonEmptyString: {
|
|
153
|
+
type: 'string',
|
|
154
|
+
minLength: 1,
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
it('resolves JSON pointer escaped property names', () => {
|
|
160
|
+
const schema = {
|
|
161
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
162
|
+
properties: {
|
|
163
|
+
'foo/bar': { $ref: '#/definitions/foo~1bar' },
|
|
164
|
+
},
|
|
165
|
+
definitions: {
|
|
166
|
+
'foo/bar': {
|
|
167
|
+
type: 'string',
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
expect((0, dereference_1.dereferenceLocal)(schema)).toEqual({
|
|
172
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
173
|
+
properties: {
|
|
174
|
+
'foo/bar': {
|
|
175
|
+
type: 'string',
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
definitions: {
|
|
179
|
+
'foo/bar': {
|
|
180
|
+
type: 'string',
|
|
181
|
+
},
|
|
182
|
+
},
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
it('does not infinitely recurse on circular definitions', () => {
|
|
186
|
+
const schema = {
|
|
187
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
188
|
+
$ref: '#/definitions/Node',
|
|
189
|
+
definitions: {
|
|
190
|
+
Node: {
|
|
191
|
+
type: 'object',
|
|
192
|
+
properties: {
|
|
193
|
+
child: { $ref: '#/definitions/Node' },
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
};
|
|
198
|
+
const result = (0, dereference_1.dereferenceLocal)(schema);
|
|
199
|
+
expect(result.type).toBe('object');
|
|
200
|
+
expect(result.properties.child).toEqual({
|
|
201
|
+
type: 'object',
|
|
202
|
+
properties: {
|
|
203
|
+
child: { $ref: '#/definitions/Node' },
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
it('throws when a reference is not internal', () => {
|
|
208
|
+
const schema = {
|
|
209
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
210
|
+
$ref: 'https://example.com/schema.json',
|
|
211
|
+
};
|
|
212
|
+
expect(() => (0, dereference_1.dereferenceLocal)(schema)).toThrow('Only internal references starting with "#/" are supported. Received: "https://example.com/schema.json"');
|
|
213
|
+
});
|
|
214
|
+
it('throws when a JSON pointer cannot be resolved', () => {
|
|
215
|
+
const schema = {
|
|
216
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
217
|
+
properties: {
|
|
218
|
+
missing: { $ref: '#/definitions/DoesNotExist' },
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
expect(() => (0, dereference_1.dereferenceLocal)(schema)).toThrow('Could not resolve JSON pointer reference: "#/definitions/DoesNotExist" at segment "definitions"');
|
|
222
|
+
});
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
//# sourceMappingURL=dereference.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dereference.spec.js","sourceRoot":"","sources":["../../../../src/utils/jsonBreakDetector/dereference/dereference.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { JSONSchema } from '@squiz/json-schema-library';
|
|
2
|
+
import { JsonBreak } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Detects breaking schema changes between beforeSchema and afterSchema.
|
|
5
|
+
* Returns each break with a dotted path location, e.g. `subtitle`, `image.width`, `tags[]`,
|
|
6
|
+
* `tags.{contains}`, and a message identifying the kind of break.
|
|
7
|
+
*/
|
|
8
|
+
export default function jsonBreakDetector(beforeSchema: JSONSchema, afterSchema: JSONSchema): JsonBreak[];
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = jsonBreakDetector;
|
|
4
|
+
const dereference_1 = require("./dereference/dereference");
|
|
5
|
+
const compareSubschemas_1 = require("./compareSubschemas");
|
|
6
|
+
const types_1 = require("./types");
|
|
7
|
+
/**
|
|
8
|
+
* Detects breaking schema changes between beforeSchema and afterSchema.
|
|
9
|
+
* Returns each break with a dotted path location, e.g. `subtitle`, `image.width`, `tags[]`,
|
|
10
|
+
* `tags.{contains}`, and a message identifying the kind of break.
|
|
11
|
+
*/
|
|
12
|
+
function jsonBreakDetector(beforeSchema, afterSchema) {
|
|
13
|
+
const breaks = [];
|
|
14
|
+
// Unfold $refs so inline schemas and $defs references can be compared on equal footing.
|
|
15
|
+
let processedBeforeSchema;
|
|
16
|
+
try {
|
|
17
|
+
processedBeforeSchema = (0, dereference_1.dereferenceLocal)(beforeSchema);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
(0, types_1.pushBreak)(breaks, '', error instanceof Error ? error.message : 'Could not dereference schema');
|
|
21
|
+
}
|
|
22
|
+
let processedAfterSchema;
|
|
23
|
+
try {
|
|
24
|
+
processedAfterSchema = (0, dereference_1.dereferenceLocal)(afterSchema);
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
(0, types_1.pushBreak)(breaks, '', error instanceof Error ? error.message : 'Could not dereference schema');
|
|
28
|
+
}
|
|
29
|
+
if (processedBeforeSchema === undefined || processedAfterSchema === undefined) {
|
|
30
|
+
return breaks;
|
|
31
|
+
}
|
|
32
|
+
(0, compareSubschemas_1.compareSubschemas)(processedBeforeSchema, processedAfterSchema, '', breaks);
|
|
33
|
+
return breaks;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=jsonBreakDetector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsonBreakDetector.js","sourceRoot":"","sources":["../../../src/utils/jsonBreakDetector/jsonBreakDetector.ts"],"names":[],"mappings":";;AAWA,oCAwBC;AAjCD,2DAA6D;AAC7D,2DAAwD;AACxD,mCAA+C;AAE/C;;;;GAIG;AACH,SAAwB,iBAAiB,CAAC,YAAwB,EAAE,WAAuB;IACzF,MAAM,MAAM,GAAgB,EAAE,CAAC;IAE/B,wFAAwF;IACxF,IAAI,qBAA6C,CAAC;IAClD,IAAI,CAAC;QACH,qBAAqB,GAAG,IAAA,8BAAgB,EAAC,YAAY,CAAC,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAA,iBAAS,EAAC,MAAM,EAAE,EAAE,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC;IACjG,CAAC;IAED,IAAI,oBAA4C,CAAC;IACjD,IAAI,CAAC;QACH,oBAAoB,GAAG,IAAA,8BAAgB,EAAC,WAAW,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAA,iBAAS,EAAC,MAAM,EAAE,EAAE,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAC;IACjG,CAAC;IAED,IAAI,qBAAqB,KAAK,SAAS,IAAI,oBAAoB,KAAK,SAAS,EAAE,CAAC;QAC9E,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAA,qCAAiB,EAAC,qBAAqB,EAAE,oBAAoB,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;IAC3E,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|