@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,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findConstChanges = findConstChanges;
|
|
4
|
+
exports.checkConstNarrowingAtNode = checkConstNarrowingAtNode;
|
|
5
|
+
const types_1 = require("../types");
|
|
6
|
+
/** Recursively detects added or changed `const` values at each schema level, accumulating dotted paths. */
|
|
7
|
+
function findConstChanges(beforeSchema, afterSchema, path, constChanges) {
|
|
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 nested object properties.
|
|
12
|
+
for (const [key, afterPropertySchema] of Object.entries(afterProperties)) {
|
|
13
|
+
if (!afterPropertySchema || typeof afterPropertySchema !== 'object') {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
const beforePropertySchema = beforeProperties[key];
|
|
17
|
+
const childPath = path ? `${path}.${key}` : key;
|
|
18
|
+
if (beforePropertySchema && typeof beforePropertySchema === 'object') {
|
|
19
|
+
// Only compare const on fields that existed in the before schema.
|
|
20
|
+
if (hasConstChange(beforePropertySchema, afterPropertySchema)) {
|
|
21
|
+
(0, types_1.pushBreak)(constChanges, childPath, types_1.BREAK_MESSAGES.const);
|
|
22
|
+
}
|
|
23
|
+
// Compare `const` on this property, then recurse into nested schemas for child fields.
|
|
24
|
+
findConstChanges(beforePropertySchema, afterPropertySchema, childPath, constChanges);
|
|
25
|
+
}
|
|
26
|
+
// New properties in afterSchema are skipped; adding a field is not a const change.
|
|
27
|
+
}
|
|
28
|
+
const beforeItems = beforeSchema.items;
|
|
29
|
+
const afterItems = afterSchema.items;
|
|
30
|
+
// Recurse into array item schemas (tuple items are not supported).
|
|
31
|
+
if (afterItems && typeof afterItems === 'object' && !Array.isArray(afterItems)) {
|
|
32
|
+
const itemsPath = path ? `${path}[]` : '[]';
|
|
33
|
+
const beforeItemSchema = beforeItems && typeof beforeItems === 'object' && !Array.isArray(beforeItems) ? beforeItems : undefined;
|
|
34
|
+
// Compare `items.const`, e.g. `version[]` when each item must match a new fixed value.
|
|
35
|
+
if (beforeItemSchema && hasConstChange(beforeItemSchema, afterItems)) {
|
|
36
|
+
(0, types_1.pushBreak)(constChanges, itemsPath, types_1.BREAK_MESSAGES.const);
|
|
37
|
+
}
|
|
38
|
+
if (beforeItemSchema) {
|
|
39
|
+
findConstChanges(beforeItemSchema, afterItems, itemsPath, constChanges);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** Reports added or changed fixed values on a single schema node. */
|
|
44
|
+
function checkConstNarrowingAtNode(beforeSchema, afterSchema, path, breaks) {
|
|
45
|
+
if (hasConstChange(beforeSchema, afterSchema)) {
|
|
46
|
+
(0, types_1.pushBreak)(breaks, path, types_1.BREAK_MESSAGES.const);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Returns true when afterSchema adds or changes an effective fixed value (`const` or single-value `enum`). */
|
|
50
|
+
function hasConstChange(beforeSchema, afterSchema) {
|
|
51
|
+
const afterValue = getEffectiveConstValue(afterSchema);
|
|
52
|
+
if (afterValue === undefined) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
const beforeValue = getEffectiveConstValue(beforeSchema);
|
|
56
|
+
if (beforeValue === undefined) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
return JSON.stringify(beforeValue) !== JSON.stringify(afterValue);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Returns a schema's fixed value from `const`, or from `enum` when it contains exactly one value.
|
|
63
|
+
* A single-value enum and a const are equivalent ways to restrict a field to one value.
|
|
64
|
+
*/
|
|
65
|
+
function getEffectiveConstValue(schema) {
|
|
66
|
+
if (schema.const !== undefined) {
|
|
67
|
+
return schema.const;
|
|
68
|
+
}
|
|
69
|
+
const enumValues = schema.enum;
|
|
70
|
+
if (enumValues && enumValues.length === 1) {
|
|
71
|
+
return enumValues[0];
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=findConstChanges.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findConstChanges.js","sourceRoot":"","sources":["../../../../src/utils/jsonBreakDetector/checks/findConstChanges.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { JsonBreak } from '../types';
|
|
2
|
+
import { JSONSchema } from '@squiz/json-schema-library';
|
|
3
|
+
/** Recursively detects enum narrowing at each schema level, accumulating dotted paths. */
|
|
4
|
+
export declare function findEnumNarrowing(beforeSchema: JSONSchema, afterSchema: JSONSchema, path: string, breaks: JsonBreak[]): void;
|
|
5
|
+
/** Reports enum narrowing on a single schema node. */
|
|
6
|
+
export declare function checkEnumNarrowingAtNode(beforeSchema: JSONSchema, afterSchema: JSONSchema, path: string, breaks: JsonBreak[]): void;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findEnumNarrowing = findEnumNarrowing;
|
|
4
|
+
exports.checkEnumNarrowingAtNode = checkEnumNarrowingAtNode;
|
|
5
|
+
const types_1 = require("../types");
|
|
6
|
+
/** Recursively detects enum narrowing at each schema level, accumulating dotted paths. */
|
|
7
|
+
function findEnumNarrowing(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 nested object properties.
|
|
12
|
+
for (const [key, afterPropertySchema] of Object.entries(afterProperties)) {
|
|
13
|
+
if (!afterPropertySchema || typeof afterPropertySchema !== 'object') {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
const beforePropertySchema = beforeProperties[key];
|
|
17
|
+
const childPath = path ? `${path}.${key}` : key;
|
|
18
|
+
if (beforePropertySchema && typeof beforePropertySchema === 'object') {
|
|
19
|
+
// Only compare enum on fields that existed in the before schema.
|
|
20
|
+
reportEnumNarrowingAtNode(beforePropertySchema, afterPropertySchema, childPath, breaks);
|
|
21
|
+
// Compare `enum` on this property, then recurse into nested schemas for child fields.
|
|
22
|
+
findEnumNarrowing(beforePropertySchema, afterPropertySchema, childPath, breaks);
|
|
23
|
+
}
|
|
24
|
+
// New properties in afterSchema are skipped; adding a field is not an enum change.
|
|
25
|
+
}
|
|
26
|
+
const beforeItems = beforeSchema.items;
|
|
27
|
+
const afterItems = afterSchema.items;
|
|
28
|
+
// Recurse into array item schemas.
|
|
29
|
+
if (afterItems && typeof afterItems === 'object' && !Array.isArray(afterItems)) {
|
|
30
|
+
const itemsPath = path ? `${path}[]` : '[]';
|
|
31
|
+
const beforeItemSchema = beforeItems && typeof beforeItems === 'object' && !Array.isArray(beforeItems) ? beforeItems : undefined;
|
|
32
|
+
// Only compare enum on items that existed in the before schema. New items are skipped.
|
|
33
|
+
if (beforeItemSchema) {
|
|
34
|
+
reportEnumNarrowingAtNode(beforeItemSchema, afterItems, itemsPath, breaks);
|
|
35
|
+
findEnumNarrowing(beforeItemSchema, afterItems, itemsPath, breaks);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/** Reports enum narrowing on a single schema node. */
|
|
40
|
+
function reportEnumNarrowingAtNode(beforeSchema, afterSchema, path, breaks) {
|
|
41
|
+
// Removing an options could leave old default value that matched that invalid, so report as breaking.
|
|
42
|
+
if (hasRemovedEnumOptions(beforeSchema, afterSchema)) {
|
|
43
|
+
(0, types_1.pushBreak)(breaks, path, types_1.BREAK_MESSAGES.enum);
|
|
44
|
+
}
|
|
45
|
+
// Adding an enum constraint could leave old values that dont match invalid, so report as breaking.
|
|
46
|
+
if (hasAddedEnum(beforeSchema, afterSchema)) {
|
|
47
|
+
(0, types_1.pushBreak)(breaks, path, types_1.BREAK_MESSAGES.enumAdded);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Reports enum narrowing on a single schema node. */
|
|
51
|
+
function checkEnumNarrowingAtNode(beforeSchema, afterSchema, path, breaks) {
|
|
52
|
+
reportEnumNarrowingAtNode(beforeSchema, afterSchema, path, breaks);
|
|
53
|
+
}
|
|
54
|
+
/** Returns true when afterSchema adds an enum where the before schema had none. */
|
|
55
|
+
function hasAddedEnum(beforeSchema, afterSchema) {
|
|
56
|
+
const afterEnum = afterSchema.enum;
|
|
57
|
+
// No enum constraint is not breaking.
|
|
58
|
+
if (!afterEnum || afterEnum.length === 0) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
const beforeEnum = beforeSchema.enum;
|
|
62
|
+
if (beforeEnum && beforeEnum.length > 0) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
// Check if a before const has been converted to an enum. e.g. const: 'published' -> enum: ['draft', 'published'].
|
|
66
|
+
if (beforeSchema.const !== undefined) {
|
|
67
|
+
return !afterEnum.some((value) => JSON.stringify(value) === JSON.stringify(beforeSchema.const));
|
|
68
|
+
}
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
/** Returns true when afterSchema.enum no longer allows every value from beforeSchema.enum. */
|
|
72
|
+
function hasRemovedEnumOptions(beforeSchema, afterSchema) {
|
|
73
|
+
const beforeEnum = beforeSchema.enum;
|
|
74
|
+
if (!beforeEnum || beforeEnum.length === 0) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
const afterEnum = afterSchema.enum;
|
|
78
|
+
const afterConst = afterSchema.const;
|
|
79
|
+
// Enum removed entirely is a relaxation, not a breaking change.
|
|
80
|
+
if (!afterEnum) {
|
|
81
|
+
if (afterConst === undefined) {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
// True when any former enum value is not matched by the new `const`.
|
|
85
|
+
return beforeEnum.some((beforeValue) => JSON.stringify(beforeValue) !== JSON.stringify(afterConst));
|
|
86
|
+
}
|
|
87
|
+
// True when any former enum value is missing from the after `enum` list.
|
|
88
|
+
return beforeEnum.some((beforeValue) => !afterEnum.some((afterValue) => JSON.stringify(beforeValue) === JSON.stringify(afterValue)));
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=findEnumNarrowing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findEnumNarrowing.js","sourceRoot":"","sources":["../../../../src/utils/jsonBreakDetector/checks/findEnumNarrowing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { JsonBreak } from '../types';
|
|
2
|
+
import { JSONSchema } from '@squiz/json-schema-library';
|
|
3
|
+
/**
|
|
4
|
+
* Recursively function to compare field type values at each schema level, accumulating dotted paths.
|
|
5
|
+
* */
|
|
6
|
+
export declare function findFieldTypeChanges(beforeSchema: JSONSchema, afterSchema: JSONSchema, path: string, typeChanges: JsonBreak[]): void;
|
|
7
|
+
/** Returns true when the JSON Schema `type` keyword narrows between two schemas. */
|
|
8
|
+
export declare function hasTypeChange(beforeSchema: JSONSchema, afterSchema: JSONSchema): boolean;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findFieldTypeChanges = findFieldTypeChanges;
|
|
4
|
+
exports.hasTypeChange = hasTypeChange;
|
|
5
|
+
const types_1 = require("../types");
|
|
6
|
+
/**
|
|
7
|
+
* Recursively function to compare field type values at each schema level, accumulating dotted paths.
|
|
8
|
+
* */
|
|
9
|
+
function findFieldTypeChanges(beforeSchema, afterSchema, path, typeChanges) {
|
|
10
|
+
var _a, _b;
|
|
11
|
+
// Get the current schema level child properties
|
|
12
|
+
const beforeProperties = (_a = beforeSchema.properties) !== null && _a !== void 0 ? _a : {};
|
|
13
|
+
const afterProperties = (_b = afterSchema.properties) !== null && _b !== void 0 ? _b : {};
|
|
14
|
+
// Recurse into latest nested object properties.
|
|
15
|
+
for (const [key, afterPropertySchema] of Object.entries(afterProperties)) {
|
|
16
|
+
// Only objects have types
|
|
17
|
+
if (!afterPropertySchema || typeof afterPropertySchema !== 'object') {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const beforePropertySchema = beforeProperties[key];
|
|
21
|
+
const childPath = path ? `${path}.${key}` : key;
|
|
22
|
+
// Only compare type on fields that existed in the before schema. New fields are skipped.
|
|
23
|
+
if (beforePropertySchema && typeof beforePropertySchema === 'object') {
|
|
24
|
+
// Only compare type on fields that existed in the before schema.
|
|
25
|
+
if (hasTypeChange(beforePropertySchema, afterPropertySchema)) {
|
|
26
|
+
(0, types_1.pushBreak)(typeChanges, childPath, types_1.BREAK_MESSAGES.type);
|
|
27
|
+
}
|
|
28
|
+
// Compare `type` on this property, then recurse into its nested schema so child fields are checked too.
|
|
29
|
+
findFieldTypeChanges(beforePropertySchema, afterPropertySchema, childPath, typeChanges);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// If instead the current schema level is an array, get the items schema
|
|
33
|
+
const beforeItems = beforeSchema.items;
|
|
34
|
+
const afterItems = afterSchema.items;
|
|
35
|
+
// Recurse into latest array item schemas.
|
|
36
|
+
if (afterItems && typeof afterItems === 'object' && !Array.isArray(afterItems)) {
|
|
37
|
+
const itemsPath = path ? `${path}[]` : '[]';
|
|
38
|
+
const beforeItemSchema = beforeItems && typeof beforeItems === 'object' && !Array.isArray(beforeItems) ? beforeItems : undefined;
|
|
39
|
+
// Compare the `items` schema `type` for array fields, e.g. `tags[]` when
|
|
40
|
+
// `items: { type: 'string' }` becomes `items: { type: 'number' }`.
|
|
41
|
+
if (beforeItemSchema) {
|
|
42
|
+
if (hasTypeChange(beforeItemSchema, afterItems)) {
|
|
43
|
+
(0, types_1.pushBreak)(typeChanges, itemsPath, types_1.BREAK_MESSAGES.type);
|
|
44
|
+
}
|
|
45
|
+
findFieldTypeChanges(beforeItemSchema, afterItems, itemsPath, typeChanges);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function toTypeArray(type) {
|
|
50
|
+
return Array.isArray(type) ? type : [type];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Returns true when every type allowed by `beforeType` is still allowed by `afterType`.
|
|
54
|
+
* In JSON Schema, integer is a subset of number, so relaxing integer to number is not breaking.
|
|
55
|
+
*/
|
|
56
|
+
function isBeforeTypeCoveredByAfterType(beforeType, afterType) {
|
|
57
|
+
const afterTypes = new Set(toTypeArray(afterType));
|
|
58
|
+
for (const type of toTypeArray(beforeType)) {
|
|
59
|
+
// Integer is a subset of number, so relaxing integer to number is not breaking.
|
|
60
|
+
if (type === 'integer') {
|
|
61
|
+
if (afterTypes.has('integer') || afterTypes.has('number')) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
if (!afterTypes.has(type)) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
/** Returns true when the JSON Schema `type` keyword narrows between two schemas. */
|
|
73
|
+
function hasTypeChange(beforeSchema, afterSchema) {
|
|
74
|
+
const beforeType = beforeSchema.type;
|
|
75
|
+
const afterType = afterSchema.type;
|
|
76
|
+
// If both types are undefined, there is no change.
|
|
77
|
+
if (beforeType === undefined && afterType === undefined) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
// If one type is undefined, there is a change.
|
|
81
|
+
if (beforeType === undefined || afterType === undefined) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
return !isBeforeTypeCoveredByAfterType(beforeType, afterType);
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=findFieldTypeChanges.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findFieldTypeChanges.js","sourceRoot":"","sources":["../../../../src/utils/jsonBreakDetector/checks/findFieldTypeChanges.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { JSONSchema } from '@squiz/json-schema-library';
|
|
2
|
+
import { JsonBreak } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Recursively compares required and dependentRequired fields at each schema level, accumulating dotted paths.
|
|
5
|
+
*/
|
|
6
|
+
export declare function findNewRequiredFields(beforeSchema: JSONSchema, afterSchema: JSONSchema, path: string, newRequiredFields: JsonBreak[]): void;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findNewRequiredFields = findNewRequiredFields;
|
|
4
|
+
const types_1 = require("../types");
|
|
5
|
+
function getDependentRequired(schema) {
|
|
6
|
+
const dependentRequired = schema.dependentRequired;
|
|
7
|
+
return dependentRequired !== null && dependentRequired !== void 0 ? dependentRequired : {};
|
|
8
|
+
}
|
|
9
|
+
function findNewDependentRequiredFields(beforeSchema, afterSchema, path, newRequiredFields) {
|
|
10
|
+
var _a, _b;
|
|
11
|
+
const beforeDependentRequired = getDependentRequired(beforeSchema);
|
|
12
|
+
const afterDependentRequired = getDependentRequired(afterSchema);
|
|
13
|
+
const beforeProperties = (_a = beforeSchema.properties) !== null && _a !== void 0 ? _a : {};
|
|
14
|
+
for (const [triggerField, afterDependentFields] of Object.entries(afterDependentRequired)) {
|
|
15
|
+
if (!Array.isArray(afterDependentFields)) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
// Adding dependentRequired for a newly added trigger field is not a breaking change.
|
|
19
|
+
if (!(triggerField in beforeProperties)) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
const beforeDependentFields = (_b = beforeDependentRequired[triggerField]) !== null && _b !== void 0 ? _b : [];
|
|
23
|
+
for (const field of afterDependentFields) {
|
|
24
|
+
if (!beforeDependentFields.includes(field)) {
|
|
25
|
+
(0, types_1.pushBreak)(newRequiredFields, path ? `${path}.${field}` : field, types_1.BREAK_MESSAGES.dependentRequired);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Recursively compares required and dependentRequired fields at each schema level, accumulating dotted paths.
|
|
32
|
+
*/
|
|
33
|
+
function findNewRequiredFields(beforeSchema, afterSchema, path, newRequiredFields) {
|
|
34
|
+
var _a, _b, _c, _d;
|
|
35
|
+
// Get whats required at the current schema level
|
|
36
|
+
const beforeRequired = (_a = beforeSchema.required) !== null && _a !== void 0 ? _a : [];
|
|
37
|
+
const afterRequired = (_b = afterSchema.required) !== null && _b !== void 0 ? _b : [];
|
|
38
|
+
// Collect fields present in afterSchema.required but not in beforeSchema.required.
|
|
39
|
+
for (const field of afterRequired) {
|
|
40
|
+
if (!beforeRequired.includes(field)) {
|
|
41
|
+
(0, types_1.pushBreak)(newRequiredFields, path ? `${path}.${field}` : field, types_1.BREAK_MESSAGES.required);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
findNewDependentRequiredFields(beforeSchema, afterSchema, path, newRequiredFields);
|
|
45
|
+
// Get the current schema level child properties
|
|
46
|
+
const beforeProperties = (_c = beforeSchema.properties) !== null && _c !== void 0 ? _c : {};
|
|
47
|
+
const afterProperties = (_d = afterSchema.properties) !== null && _d !== void 0 ? _d : {};
|
|
48
|
+
// Recurse into latest nested object properties.
|
|
49
|
+
for (const [key, afterPropertySchema] of Object.entries(afterProperties)) {
|
|
50
|
+
// Skip if the property is not an object.
|
|
51
|
+
if (!afterPropertySchema || typeof afterPropertySchema !== 'object') {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const beforePropertySchema = beforeProperties[key];
|
|
55
|
+
const childPath = path ? `${path}.${key}` : key;
|
|
56
|
+
// Missing before property is treated as an empty schema with no required fields.
|
|
57
|
+
findNewRequiredFields(beforePropertySchema && typeof beforePropertySchema === 'object' ? beforePropertySchema : {}, afterPropertySchema, childPath, newRequiredFields);
|
|
58
|
+
}
|
|
59
|
+
// If instead the current schema level is an array, get the items schema
|
|
60
|
+
const beforeItems = beforeSchema.items;
|
|
61
|
+
const afterItems = afterSchema.items;
|
|
62
|
+
// Recurse into array item schemas (tuple items are not supported).
|
|
63
|
+
if (afterItems && typeof afterItems === 'object' && !Array.isArray(afterItems)) {
|
|
64
|
+
const itemsPath = path ? `${path}[]` : '[]';
|
|
65
|
+
findNewRequiredFields(beforeItems && typeof beforeItems === 'object' && !Array.isArray(beforeItems) ? beforeItems : {}, afterItems, itemsPath, newRequiredFields);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=findNewRequiredFields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findNewRequiredFields.js","sourceRoot":"","sources":["../../../../src/utils/jsonBreakDetector/checks/findNewRequiredFields.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { JsonBreak } from '../types';
|
|
2
|
+
import { JSONSchema } from '@squiz/json-schema-library';
|
|
3
|
+
/** Recursively detects narrowed numeric constraints at each schema level, accumulating dotted paths. */
|
|
4
|
+
export declare function findNumericConstraintNarrowing(beforeSchema: JSONSchema, afterSchema: JSONSchema, path: string, breaks: JsonBreak[]): void;
|
|
5
|
+
/** Checks numeric constraint keywords on a single schema for narrowing changes. */
|
|
6
|
+
export declare function checkNumericConstraintNarrowing(beforeSchema: JSONSchema, afterSchema: JSONSchema, path: string, breaks: JsonBreak[]): void;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findNumericConstraintNarrowing = findNumericConstraintNarrowing;
|
|
4
|
+
exports.checkNumericConstraintNarrowing = checkNumericConstraintNarrowing;
|
|
5
|
+
const types_1 = require("../types");
|
|
6
|
+
/** Recursively detects narrowed numeric constraints at each schema level, accumulating dotted paths. */
|
|
7
|
+
function findNumericConstraintNarrowing(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
|
+
if (!afterPropertySchema || typeof afterPropertySchema !== 'object') {
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
const beforePropertySchema = beforeProperties[key];
|
|
17
|
+
const childPath = path ? `${path}.${key}` : key;
|
|
18
|
+
// Only compare numeric constraints on fields that existed in the before schema. New fields are skipped.
|
|
19
|
+
if (beforePropertySchema && typeof beforePropertySchema === 'object') {
|
|
20
|
+
checkNumericConstraintNarrowing(beforePropertySchema, afterPropertySchema, childPath, breaks);
|
|
21
|
+
findNumericConstraintNarrowing(beforePropertySchema, afterPropertySchema, childPath, breaks);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const beforeItems = beforeSchema.items;
|
|
25
|
+
const afterItems = afterSchema.items;
|
|
26
|
+
// Recurse into latest nested array items.
|
|
27
|
+
if (afterItems && typeof afterItems === 'object' && !Array.isArray(afterItems)) {
|
|
28
|
+
const itemsPath = path ? `${path}[]` : '[]';
|
|
29
|
+
const beforeItemSchema = beforeItems && typeof beforeItems === 'object' && !Array.isArray(beforeItems) ? beforeItems : undefined;
|
|
30
|
+
// Only compare numeric constraints on items that existed in the before schema. New items are skipped.
|
|
31
|
+
if (beforeItemSchema) {
|
|
32
|
+
checkNumericConstraintNarrowing(beforeItemSchema, afterItems, itemsPath, breaks);
|
|
33
|
+
findNumericConstraintNarrowing(beforeItemSchema, afterItems, itemsPath, breaks);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/** Returns true when a schema represents a numeric field. */
|
|
38
|
+
function isNumericFieldSchema(schema) {
|
|
39
|
+
const type = schema.type;
|
|
40
|
+
if (type === 'number' || type === 'integer') {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
// Type can be defined as a union of strings e.g. ['number', 'integer'], so check if 'number' or 'integer' is included.
|
|
44
|
+
if (Array.isArray(type) && (type.includes('number') || type.includes('integer'))) {
|
|
45
|
+
return true;
|
|
46
|
+
}
|
|
47
|
+
return (schema.minimum !== undefined ||
|
|
48
|
+
schema.exclusiveMinimum !== undefined ||
|
|
49
|
+
schema.maximum !== undefined ||
|
|
50
|
+
schema.exclusiveMaximum !== undefined ||
|
|
51
|
+
schema.multipleOf !== undefined);
|
|
52
|
+
}
|
|
53
|
+
/** Returns the strictest lower bound from `minimum` and `exclusiveMinimum`, which may both be set. */
|
|
54
|
+
function getEffectiveLowerBound(schema) {
|
|
55
|
+
const minimum = schema.minimum;
|
|
56
|
+
const exclusiveMinimum = schema.exclusiveMinimum;
|
|
57
|
+
// Both are defined, need to figure out which is lower
|
|
58
|
+
if (minimum !== undefined && exclusiveMinimum !== undefined) {
|
|
59
|
+
// min 5 is same as exclusiveMinimum 6 (x >= minimum and x > exclusiveMinimum)
|
|
60
|
+
// so if they are the same exclusiveMinimum is the effective lower bound
|
|
61
|
+
if (minimum > exclusiveMinimum) {
|
|
62
|
+
return { value: minimum, keyword: 'minimum' };
|
|
63
|
+
}
|
|
64
|
+
return { value: exclusiveMinimum, keyword: 'exclusiveMinimum' };
|
|
65
|
+
}
|
|
66
|
+
if (minimum !== undefined) {
|
|
67
|
+
return { value: minimum, keyword: 'minimum' };
|
|
68
|
+
}
|
|
69
|
+
if (exclusiveMinimum !== undefined) {
|
|
70
|
+
return { value: exclusiveMinimum, keyword: 'exclusiveMinimum' };
|
|
71
|
+
}
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
/** Returns the strictest upper bound from `maximum` and `exclusiveMaximum`, which may both be set. */
|
|
75
|
+
function getEffectiveUpperBound(schema) {
|
|
76
|
+
const maximum = schema.maximum;
|
|
77
|
+
const exclusiveMaximum = schema.exclusiveMaximum;
|
|
78
|
+
if (maximum !== undefined && exclusiveMaximum !== undefined) {
|
|
79
|
+
// max 4 is same as exclusiveMaximum 5 (x <= maximum and x < exclusiveMaximum)
|
|
80
|
+
// so if they are the same exclusiveMaximum is the effective upper bound
|
|
81
|
+
if (maximum < exclusiveMaximum) {
|
|
82
|
+
return { value: maximum, keyword: 'maximum' };
|
|
83
|
+
}
|
|
84
|
+
return { value: exclusiveMaximum, keyword: 'exclusiveMaximum' };
|
|
85
|
+
}
|
|
86
|
+
if (maximum !== undefined) {
|
|
87
|
+
return { value: maximum, keyword: 'maximum' };
|
|
88
|
+
}
|
|
89
|
+
if (exclusiveMaximum !== undefined) {
|
|
90
|
+
return { value: exclusiveMaximum, keyword: 'exclusiveMaximum' };
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
/** Returns true when afterSchema requires a stricter lower bound than beforeSchema. */
|
|
95
|
+
function hasLowerBoundIncreased(beforeSchema, afterSchema) {
|
|
96
|
+
const beforeBound = getEffectiveLowerBound(beforeSchema);
|
|
97
|
+
const afterBound = getEffectiveLowerBound(afterSchema);
|
|
98
|
+
if (afterBound === undefined) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
if (beforeBound === undefined) {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
if (afterBound.value > beforeBound.value) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
if (afterBound.value < beforeBound.value) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
// Same effective value, but inclusive vs exclusive still differs (e.g. minimum: 5 allows 5, exclusiveMinimum: 5 does not).
|
|
111
|
+
return afterBound.keyword === 'exclusiveMinimum' && beforeBound.keyword === 'minimum';
|
|
112
|
+
}
|
|
113
|
+
/** Returns true when afterSchema allows a stricter upper bound than beforeSchema. */
|
|
114
|
+
function hasUpperBoundLowered(beforeSchema, afterSchema) {
|
|
115
|
+
const beforeBound = getEffectiveUpperBound(beforeSchema);
|
|
116
|
+
const afterBound = getEffectiveUpperBound(afterSchema);
|
|
117
|
+
if (afterBound === undefined) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
if (beforeBound === undefined) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
if (afterBound.value < beforeBound.value) {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
if (afterBound.value > beforeBound.value) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
// Same effective value, but inclusive vs exclusive still differs (e.g. maximum: 10 allows 10, exclusiveMaximum: 10 does not).
|
|
130
|
+
return afterBound.keyword === 'exclusiveMaximum' && beforeBound.keyword === 'maximum';
|
|
131
|
+
}
|
|
132
|
+
/** Picks the break message for the keyword that supplies the effective lower bound in the after schema. */
|
|
133
|
+
function getLowerBoundBreakMessage(_beforeSchema, afterSchema) {
|
|
134
|
+
const afterBound = getEffectiveLowerBound(afterSchema);
|
|
135
|
+
return (afterBound === null || afterBound === void 0 ? void 0 : afterBound.keyword) === 'exclusiveMinimum' ? types_1.BREAK_MESSAGES.exclusiveMinimum : types_1.BREAK_MESSAGES.minimum;
|
|
136
|
+
}
|
|
137
|
+
/** Picks the break message for the keyword that supplies the effective upper bound in the after schema. */
|
|
138
|
+
function getUpperBoundBreakMessage(_beforeSchema, afterSchema) {
|
|
139
|
+
const afterBound = getEffectiveUpperBound(afterSchema);
|
|
140
|
+
return (afterBound === null || afterBound === void 0 ? void 0 : afterBound.keyword) === 'exclusiveMaximum' ? types_1.BREAK_MESSAGES.exclusiveMaximum : types_1.BREAK_MESSAGES.maximum;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Returns true when afterSchema narrows the set of allowed multiples.
|
|
144
|
+
* A value valid under the before `multipleOf` may be invalid under the after `multipleOf`
|
|
145
|
+
* unless the before factor is itself a multiple of the after factor.
|
|
146
|
+
*/
|
|
147
|
+
function hasMultipleOfNarrowed(beforeSchema, afterSchema) {
|
|
148
|
+
const afterMultipleOf = afterSchema.multipleOf;
|
|
149
|
+
const beforeMultipleOf = beforeSchema.multipleOf;
|
|
150
|
+
if (afterMultipleOf === undefined) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
if (beforeMultipleOf === undefined) {
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
if (beforeMultipleOf === afterMultipleOf) {
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
// Check if the constraint is strictly narrowed
|
|
160
|
+
// e.g. from 4 to 2 is ok as previous valid entries will still be valid
|
|
161
|
+
// but from 4 to 3 is not
|
|
162
|
+
return beforeMultipleOf % afterMultipleOf !== 0;
|
|
163
|
+
}
|
|
164
|
+
/** Checks numeric constraint keywords on a single schema for narrowing changes. */
|
|
165
|
+
function checkNumericConstraintNarrowing(beforeSchema, afterSchema, path, breaks) {
|
|
166
|
+
if (!isNumericFieldSchema(beforeSchema) && !isNumericFieldSchema(afterSchema)) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (hasLowerBoundIncreased(beforeSchema, afterSchema)) {
|
|
170
|
+
(0, types_1.pushBreak)(breaks, path, getLowerBoundBreakMessage(beforeSchema, afterSchema));
|
|
171
|
+
}
|
|
172
|
+
if (hasUpperBoundLowered(beforeSchema, afterSchema)) {
|
|
173
|
+
(0, types_1.pushBreak)(breaks, path, getUpperBoundBreakMessage(beforeSchema, afterSchema));
|
|
174
|
+
}
|
|
175
|
+
if (hasMultipleOfNarrowed(beforeSchema, afterSchema)) {
|
|
176
|
+
(0, types_1.pushBreak)(breaks, path, types_1.BREAK_MESSAGES.multipleOf);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=findNumericConstraintNarrowing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findNumericConstraintNarrowing.js","sourceRoot":"","sources":["../../../../src/utils/jsonBreakDetector/checks/findNumericConstraintNarrowing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { JsonBreak } from '../types';
|
|
2
|
+
import { JSONSchema } from '@squiz/json-schema-library';
|
|
3
|
+
/** Recursively detects narrowed string constraints at each schema level, accumulating dotted paths. */
|
|
4
|
+
export declare function findStringConstraintNarrowing(beforeSchema: JSONSchema, afterSchema: JSONSchema, path: string, breaks: JsonBreak[]): void;
|
|
5
|
+
/** Checks string constraint keywords on a single schema for narrowing changes. */
|
|
6
|
+
export declare function checkStringConstraintNarrowing(beforeSchema: JSONSchema, afterSchema: JSONSchema, path: string, breaks: JsonBreak[]): void;
|