@takeshape/json-schema 11.52.0 → 11.55.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/dist/__tests__/schema-validator.test.d.ts +1 -0
- package/dist/__tests__/schema-validator.test.js +295 -0
- package/dist/converters/__tests__/schema-converter.test.d.ts +1 -0
- package/dist/converters/__tests__/schema-converter.test.js +1134 -0
- package/dist/converters/__tests__/search-shape-schema.json +495 -0
- package/dist/converters/index.d.ts +1 -2
- package/dist/converters/index.js +1 -16
- package/dist/converters/schema-converter.d.ts +0 -1
- package/dist/converters/schema-converter.js +540 -643
- package/dist/index.d.ts +1 -2
- package/dist/index.js +1 -16
- package/dist/schema-validator.d.ts +1 -2
- package/dist/schema-validator.js +163 -189
- package/dist/utils/__tests__/references.test.d.ts +1 -0
- package/dist/utils/__tests__/references.test.js +121 -0
- package/dist/utils/__tests__/type-utils.test.d.ts +1 -0
- package/dist/utils/__tests__/type-utils.test.js +143 -0
- package/dist/utils/constants.d.ts +0 -1
- package/dist/utils/constants.js +49 -7
- package/dist/utils/index.d.ts +4 -5
- package/dist/utils/index.js +4 -49
- package/dist/utils/keys.d.ts +0 -1
- package/dist/utils/keys.js +5 -12
- package/dist/utils/references.d.ts +0 -1
- package/dist/utils/references.js +56 -57
- package/dist/utils/type-utils.d.ts +1 -2
- package/dist/utils/type-utils.js +36 -53
- package/dist/utils/types.d.ts +0 -1
- package/dist/utils/types.js +1 -5
- package/package.json +18 -25
- package/dist/converters/index.d.ts.map +0 -1
- package/dist/converters/schema-converter.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/schema-validator.d.ts.map +0 -1
- package/dist/utils/constants.d.ts.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/keys.d.ts.map +0 -1
- package/dist/utils/references.d.ts.map +0 -1
- package/dist/utils/type-utils.d.ts.map +0 -1
- package/dist/utils/types.d.ts.map +0 -1
- package/es/converters/index.js +0 -1
- package/es/converters/schema-converter.js +0 -654
- package/es/index.js +0 -1
- package/es/schema-validator.js +0 -207
- package/es/utils/constants.js +0 -1
- package/es/utils/index.js +0 -4
- package/es/utils/keys.js +0 -9
- package/es/utils/references.js +0 -66
- package/es/utils/type-utils.js +0 -36
- package/es/utils/types.js +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export * from './schema-validator';
|
|
2
|
-
//# sourceMappingURL=index.d.ts.map
|
|
1
|
+
export * from './schema-validator.ts';
|
package/dist/index.js
CHANGED
|
@@ -1,16 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
var _schemaValidator = require("./schema-validator");
|
|
7
|
-
Object.keys(_schemaValidator).forEach(function (key) {
|
|
8
|
-
if (key === "default" || key === "__esModule") return;
|
|
9
|
-
if (key in exports && exports[key] === _schemaValidator[key]) return;
|
|
10
|
-
Object.defineProperty(exports, key, {
|
|
11
|
-
enumerable: true,
|
|
12
|
-
get: function () {
|
|
13
|
-
return _schemaValidator[key];
|
|
14
|
-
}
|
|
15
|
-
});
|
|
16
|
-
});
|
|
1
|
+
export * from "./schema-validator.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ErrorObject, Options, SchemaObject } from 'ajv';
|
|
2
|
-
import Ajv from 'ajv';
|
|
2
|
+
import { Ajv } from 'ajv';
|
|
3
3
|
export type Data = any;
|
|
4
4
|
export type ValidateParams = {
|
|
5
5
|
ignoreMissing: boolean;
|
|
@@ -29,4 +29,3 @@ export declare function createAjv(options?: Options): Ajv;
|
|
|
29
29
|
*/
|
|
30
30
|
export declare function fixSchema(schema: SchemaObject): SchemaObject;
|
|
31
31
|
export declare function createSchemaValidator(schema: SchemaObject | SchemaObject[], metaSchemas?: SchemaObject[], options?: Options): Validator;
|
|
32
|
-
//# sourceMappingURL=schema-validator.d.ts.map
|
package/dist/schema-validator.js
CHANGED
|
@@ -1,226 +1,200 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
return _ajv.default;
|
|
10
|
-
}
|
|
11
|
-
});
|
|
12
|
-
exports.createAjv = createAjv;
|
|
13
|
-
exports.createSchemaValidator = createSchemaValidator;
|
|
14
|
-
exports.fixSchema = fixSchema;
|
|
15
|
-
exports.followSchemaPath = followSchemaPath;
|
|
16
|
-
exports.isInvalidPropertyRequired = isInvalidPropertyRequired;
|
|
17
|
-
exports.parseDataPath = parseDataPath;
|
|
18
|
-
exports.refToPath = refToPath;
|
|
19
|
-
exports.validate = validate;
|
|
20
|
-
var _util = require("@takeshape/util");
|
|
21
|
-
var _ajv = _interopRequireDefault(require("ajv"));
|
|
22
|
-
var _ajvFormats = _interopRequireDefault(require("ajv-formats"));
|
|
23
|
-
var _get = _interopRequireDefault(require("lodash/get"));
|
|
24
|
-
var _isString = _interopRequireDefault(require("lodash/isString"));
|
|
25
|
-
var _unset = _interopRequireDefault(require("lodash/unset"));
|
|
26
|
-
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
27
|
-
function parseDataPath(instancePath) {
|
|
28
|
-
return instancePath.substr(1).split('/');
|
|
1
|
+
import { visit } from '@takeshape/util';
|
|
2
|
+
import { Ajv } from 'ajv';
|
|
3
|
+
import addFormats from 'ajv-formats';
|
|
4
|
+
import get from 'lodash/get.js';
|
|
5
|
+
import isString from 'lodash/isString.js';
|
|
6
|
+
import unset from 'lodash/unset.js';
|
|
7
|
+
export function parseDataPath(instancePath) {
|
|
8
|
+
return instancePath.substr(1).split('/');
|
|
29
9
|
}
|
|
30
10
|
function getData(error, data) {
|
|
31
|
-
|
|
11
|
+
return get(data, parseDataPath(error.instancePath));
|
|
32
12
|
}
|
|
33
13
|
function ignoreMissing(error) {
|
|
34
|
-
|
|
35
|
-
|
|
14
|
+
// ignore top level missing errors
|
|
15
|
+
return !(error.instancePath === '' && error.keyword === 'required');
|
|
36
16
|
}
|
|
37
17
|
function ignoreNull(error, data, topLevelSchema) {
|
|
38
|
-
|
|
18
|
+
return !((error.keyword === 'type' || error.keyword === 'oneOf') &&
|
|
19
|
+
getData(error, data) === null &&
|
|
20
|
+
!isInvalidPropertyRequired(topLevelSchema, error));
|
|
39
21
|
}
|
|
40
22
|
function getErrorFilter(params, data, schema) {
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
function isInvalidPropertyRequired(topLevelSchema, error) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
23
|
+
return (error) => (!params.ignoreMissing || ignoreMissing(error)) && (!params.ignoreNulls || ignoreNull(error, data, schema));
|
|
24
|
+
}
|
|
25
|
+
export function isInvalidPropertyRequired(topLevelSchema, error) {
|
|
26
|
+
const instancePath = parseDataPath(error.instancePath);
|
|
27
|
+
const parentDataPath = instancePath.slice(0, instancePath.length - 1);
|
|
28
|
+
const parentSchema = followSchemaPath(topLevelSchema, parentDataPath);
|
|
29
|
+
const name = getName(error.instancePath);
|
|
30
|
+
if (!parentSchema) {
|
|
31
|
+
throw new Error('Unexpected error cannot find parent schema');
|
|
32
|
+
}
|
|
33
|
+
return isRequired(topLevelSchema, parentSchema, name);
|
|
52
34
|
}
|
|
53
35
|
function isRequired(topLevelSchema, schema, name) {
|
|
54
|
-
|
|
55
|
-
|
|
36
|
+
const schemas = schema.allOf || schema.anyOf || schema.oneOf || [schema];
|
|
37
|
+
return schemas.some((childSchema) => followRef(topLevelSchema, childSchema)?.required?.includes(name));
|
|
56
38
|
}
|
|
57
39
|
function getName(path) {
|
|
58
|
-
|
|
59
|
-
|
|
40
|
+
const parts = parseDataPath(path);
|
|
41
|
+
return parts[parts.length - 1];
|
|
60
42
|
}
|
|
61
|
-
function refToPath(ref) {
|
|
62
|
-
|
|
43
|
+
export function refToPath(ref) {
|
|
44
|
+
return ref.substring(2).split('/');
|
|
63
45
|
}
|
|
64
46
|
function followRef(topLevelSchema, schema) {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
47
|
+
if (schema.$ref) {
|
|
48
|
+
const referencedSchema = get(topLevelSchema, refToPath(schema.$ref));
|
|
49
|
+
if (!referencedSchema) {
|
|
50
|
+
throw new Error(`Could not resolve ${schema.$ref}`);
|
|
51
|
+
}
|
|
52
|
+
return referencedSchema;
|
|
69
53
|
}
|
|
70
|
-
return
|
|
71
|
-
}
|
|
72
|
-
return schema;
|
|
54
|
+
return schema;
|
|
73
55
|
}
|
|
74
|
-
|
|
75
56
|
/**
|
|
76
57
|
* Given a schema object traverse it using a "instancePath" and return the schema at that path
|
|
77
58
|
*/
|
|
78
|
-
function followSchemaPath(topLevelSchema, instancePath) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
const combinedSchemas = schema.allOf || schema.anyOf || schema.oneOf;
|
|
85
|
-
if (combinedSchemas) {
|
|
86
|
-
for (const childSchema of combinedSchemas) {
|
|
87
|
-
const result = followPath(childSchema, path);
|
|
88
|
-
if (result) {
|
|
89
|
-
return result;
|
|
59
|
+
export function followSchemaPath(topLevelSchema, instancePath) {
|
|
60
|
+
const followPath = (schemaObject, path) => {
|
|
61
|
+
const schema = followRef(topLevelSchema, schemaObject);
|
|
62
|
+
if (path.length === 0) {
|
|
63
|
+
return schema;
|
|
90
64
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
65
|
+
const combinedSchemas = schema.allOf || schema.anyOf || schema.oneOf;
|
|
66
|
+
if (combinedSchemas) {
|
|
67
|
+
for (const childSchema of combinedSchemas) {
|
|
68
|
+
const result = followPath(childSchema, path);
|
|
69
|
+
if (result) {
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const [first, ...rest] = path;
|
|
75
|
+
if (schema.items && /^\d+$/.exec(first)) {
|
|
76
|
+
return followPath(schema.items, rest);
|
|
77
|
+
}
|
|
78
|
+
const prop = schema?.properties?.[first];
|
|
79
|
+
if (prop) {
|
|
80
|
+
return rest.length ? followPath(prop, rest) : prop;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
return followPath(topLevelSchema, instancePath);
|
|
103
84
|
}
|
|
104
85
|
function isSchemaObject(schema) {
|
|
105
|
-
|
|
86
|
+
return typeof schema === 'object';
|
|
106
87
|
}
|
|
107
88
|
function getSchemaWithDefinitions(ajv, id) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
89
|
+
if (id.startsWith('#')) {
|
|
90
|
+
const rootSchema = ajv.getSchema('#')?.schema;
|
|
91
|
+
if (isSchemaObject(rootSchema)) {
|
|
92
|
+
const path = refToPath(id);
|
|
93
|
+
const { definitions } = rootSchema;
|
|
94
|
+
return {
|
|
95
|
+
...get(rootSchema, path),
|
|
96
|
+
definitions
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return ajv.getSchema(id)?.schema;
|
|
101
|
+
}
|
|
102
|
+
export function validate(ajv, id, data, options) {
|
|
103
|
+
const params = {
|
|
104
|
+
ignoreMissing: false,
|
|
105
|
+
ignoreNulls: true,
|
|
106
|
+
errorsText: false,
|
|
107
|
+
...options
|
|
108
|
+
};
|
|
109
|
+
let valid = ajv.validate(id, data);
|
|
110
|
+
let errors;
|
|
111
|
+
if (valid) {
|
|
112
|
+
errors = [];
|
|
119
113
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
};
|
|
130
|
-
let valid = ajv.validate(id, data);
|
|
131
|
-
let errors;
|
|
132
|
-
if (valid) {
|
|
133
|
-
errors = [];
|
|
134
|
-
} else {
|
|
135
|
-
errors = ajv.errors;
|
|
136
|
-
if (params.ignoreNulls || params.ignoreMissing) {
|
|
137
|
-
const schema = getSchemaWithDefinitions(ajv, id);
|
|
138
|
-
if (isSchemaObject(schema)) {
|
|
139
|
-
errors = errors.filter(getErrorFilter(params, data, schema));
|
|
140
|
-
valid = errors.length === 0;
|
|
141
|
-
}
|
|
114
|
+
else {
|
|
115
|
+
errors = ajv.errors;
|
|
116
|
+
if (params.ignoreNulls || params.ignoreMissing) {
|
|
117
|
+
const schema = getSchemaWithDefinitions(ajv, id);
|
|
118
|
+
if (isSchemaObject(schema)) {
|
|
119
|
+
errors = errors.filter(getErrorFilter(params, data, schema));
|
|
120
|
+
valid = errors.length === 0;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
142
123
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
*/
|
|
165
|
-
ajv.addFormat('unix-time', /^[0-9]{10}$/);
|
|
166
|
-
ajv.addFormat('decimal', /^[0-9]+\.[0-9]{1,12}$/);
|
|
167
|
-
return ajv;
|
|
168
|
-
}
|
|
169
|
-
|
|
124
|
+
const errorsText = params.errorsText && !valid ? ajv.errorsText(errors) : '';
|
|
125
|
+
return { valid, errors, errorsText };
|
|
126
|
+
}
|
|
127
|
+
export { Ajv };
|
|
128
|
+
export function createAjv(options) {
|
|
129
|
+
const ajv = new Ajv({
|
|
130
|
+
discriminator: true,
|
|
131
|
+
allErrors: true,
|
|
132
|
+
unevaluated: true,
|
|
133
|
+
strict: false,
|
|
134
|
+
...options
|
|
135
|
+
});
|
|
136
|
+
addFormats.default(ajv);
|
|
137
|
+
/**
|
|
138
|
+
* Formats ingested by Stripe OpenAPI and possibly other — trigger warnings
|
|
139
|
+
* in the client when Stripe types are loaded.
|
|
140
|
+
*/
|
|
141
|
+
ajv.addFormat('unix-time', /^[0-9]{10}$/);
|
|
142
|
+
ajv.addFormat('decimal', /^[0-9]+\.[0-9]{1,12}$/);
|
|
143
|
+
return ajv;
|
|
144
|
+
}
|
|
170
145
|
/**
|
|
171
146
|
* Determine whether a string is a valid regular expression
|
|
172
147
|
*/
|
|
173
148
|
function isValidRegex(str) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
|
|
149
|
+
try {
|
|
150
|
+
new RegExp(str, 'u');
|
|
151
|
+
return true;
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
182
157
|
/**
|
|
183
158
|
* Apply various fixes to the schema to work around AJV issues and bugs.
|
|
184
159
|
* See inline comments for more.
|
|
185
160
|
*/
|
|
186
|
-
function fixSchema(schema) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
161
|
+
export function fixSchema(schema) {
|
|
162
|
+
visit(schema, ['pattern', 'oneOf'], (value, path) => {
|
|
163
|
+
const key = path.slice(-1)[0];
|
|
164
|
+
const parent = get(schema, path.slice(0, -1));
|
|
165
|
+
/**
|
|
166
|
+
* Fix schema by removing any broken regexes that will cause ajv to throw a compile error.
|
|
167
|
+
* It is better to remove the invalid regex rather than forgo validation altogether
|
|
168
|
+
* This should be fixed in ajv see the comment here
|
|
169
|
+
* https://github.com/ajv-validator/ajv/blob/9f1c3eaa4b91ca17b72b122cdac9b108d1ac30cb/lib/vocabularies/validation/pattern.ts#L21
|
|
170
|
+
*/
|
|
171
|
+
if (key === 'pattern') {
|
|
172
|
+
if (parent.type === 'string' && (!isString(value) || !isValidRegex(value))) {
|
|
173
|
+
unset(schema, path);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
return schema;
|
|
178
|
+
}
|
|
179
|
+
export function createSchemaValidator(schema, metaSchemas = [], options = {}) {
|
|
180
|
+
const schemas = Array.isArray(schema) ? schema : [schema];
|
|
181
|
+
const ajv = createAjv({
|
|
182
|
+
removeAdditional: true,
|
|
183
|
+
...options
|
|
184
|
+
});
|
|
185
|
+
if (metaSchemas) {
|
|
186
|
+
for (const metaSchema of metaSchemas) {
|
|
187
|
+
ajv.addMetaSchema(metaSchema);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
for (const schema of schemas) {
|
|
191
|
+
ajv.addSchema(fixSchema(schema));
|
|
201
192
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
function createSchemaValidator(schema, metaSchemas = [], options = {}) {
|
|
206
|
-
const schemas = Array.isArray(schema) ? schema : [schema];
|
|
207
|
-
const ajv = createAjv({
|
|
208
|
-
removeAdditional: true,
|
|
209
|
-
...options
|
|
210
|
-
});
|
|
211
|
-
if (metaSchemas) {
|
|
212
|
-
for (const metaSchema of metaSchemas) {
|
|
213
|
-
ajv.addMetaSchema(metaSchema);
|
|
193
|
+
const defaultRef = schemas[0].$id;
|
|
194
|
+
if (!defaultRef) {
|
|
195
|
+
throw Error('Failed to create schema validator: schema is missing $id');
|
|
214
196
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
const defaultRef = schemas[0].$id;
|
|
220
|
-
if (!defaultRef) {
|
|
221
|
-
throw Error('Failed to create schema validator: schema is missing $id');
|
|
222
|
-
}
|
|
223
|
-
return (data, options) => {
|
|
224
|
-
return validate(ajv, defaultRef, data, options);
|
|
225
|
-
};
|
|
226
|
-
}
|
|
197
|
+
return (data, options) => {
|
|
198
|
+
return validate(ajv, defaultRef, data, options);
|
|
199
|
+
};
|
|
200
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { getReferenceMap } from "../references.js";
|
|
3
|
+
describe('getReferenceMap', () => {
|
|
4
|
+
it('should return an empty map when no definitions are provided', () => {
|
|
5
|
+
const definitions = {};
|
|
6
|
+
const result = getReferenceMap(definitions);
|
|
7
|
+
expect(result.size).toBe(0);
|
|
8
|
+
});
|
|
9
|
+
it('should collect references from property schemas', () => {
|
|
10
|
+
const definitions = {
|
|
11
|
+
A: {
|
|
12
|
+
type: 'object',
|
|
13
|
+
properties: {
|
|
14
|
+
b: { $ref: '#/definitions/B' }
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
B: {
|
|
18
|
+
type: 'object',
|
|
19
|
+
properties: {}
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const result = getReferenceMap(definitions);
|
|
23
|
+
expect(result.get('A')).toEqual(new Set(['B']));
|
|
24
|
+
});
|
|
25
|
+
it('should collect references from allOf schemas', () => {
|
|
26
|
+
const definitions = {
|
|
27
|
+
A: {
|
|
28
|
+
allOf: [{ $ref: '#/definitions/B' }]
|
|
29
|
+
},
|
|
30
|
+
B: {
|
|
31
|
+
type: 'object',
|
|
32
|
+
properties: {}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
const result = getReferenceMap(definitions);
|
|
36
|
+
expect(result.get('A')).toEqual(new Set(['B']));
|
|
37
|
+
});
|
|
38
|
+
it('should collect references from anyOf schemas', () => {
|
|
39
|
+
const definitions = {
|
|
40
|
+
A: {
|
|
41
|
+
anyOf: [{ $ref: '#/definitions/B' }]
|
|
42
|
+
},
|
|
43
|
+
B: {
|
|
44
|
+
type: 'object',
|
|
45
|
+
properties: {}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const result = getReferenceMap(definitions);
|
|
49
|
+
expect(result.get('A')).toEqual(new Set(['B']));
|
|
50
|
+
});
|
|
51
|
+
it('should collect references from oneOf schemas', () => {
|
|
52
|
+
const definitions = {
|
|
53
|
+
A: {
|
|
54
|
+
oneOf: [{ $ref: '#/definitions/B' }]
|
|
55
|
+
},
|
|
56
|
+
B: {
|
|
57
|
+
type: 'object',
|
|
58
|
+
properties: {}
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const result = getReferenceMap(definitions);
|
|
62
|
+
expect(result.get('A')).toEqual(new Set(['B']));
|
|
63
|
+
});
|
|
64
|
+
it('should collect references from items schemas', () => {
|
|
65
|
+
const definitions = {
|
|
66
|
+
A: {
|
|
67
|
+
type: 'array',
|
|
68
|
+
items: { $ref: '#/definitions/B' }
|
|
69
|
+
},
|
|
70
|
+
B: {
|
|
71
|
+
type: 'object',
|
|
72
|
+
properties: {}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const result = getReferenceMap(definitions);
|
|
76
|
+
expect(result.get('A')).toEqual(new Set(['B']));
|
|
77
|
+
});
|
|
78
|
+
it('should handle circular references', () => {
|
|
79
|
+
const definitions = {
|
|
80
|
+
A: {
|
|
81
|
+
$ref: '#/definitions/B'
|
|
82
|
+
},
|
|
83
|
+
B: {
|
|
84
|
+
$ref: '#/definitions/A'
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
const result = getReferenceMap(definitions);
|
|
88
|
+
expect(result.get('A')).toEqual(new Set(['B']));
|
|
89
|
+
expect(result.get('B')).toEqual(new Set(['A']));
|
|
90
|
+
});
|
|
91
|
+
it('should handle deeply nested references', () => {
|
|
92
|
+
const definitions = {
|
|
93
|
+
Z: {
|
|
94
|
+
type: 'string'
|
|
95
|
+
},
|
|
96
|
+
A: {
|
|
97
|
+
type: 'object',
|
|
98
|
+
properties: {
|
|
99
|
+
Z: {
|
|
100
|
+
$ref: '#/definitions/Z'
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
B: {
|
|
105
|
+
type: 'object',
|
|
106
|
+
properties: {
|
|
107
|
+
C: {
|
|
108
|
+
type: 'object',
|
|
109
|
+
properties: {
|
|
110
|
+
D: {
|
|
111
|
+
$ref: '#/definitions/A'
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const result = getReferenceMap(definitions);
|
|
119
|
+
expect(result.get('B')).toEqual(new Set(['A', 'Z']));
|
|
120
|
+
});
|
|
121
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|