@cloudflare/cabidela 0.0.15 → 0.0.17
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +14 -3
- package/dist/index.d.mts +29 -0
- package/dist/index.d.ts +7 -5
- package/dist/index.js +92 -19
- package/dist/index.mjs +349 -0
- package/package.json +19 -9
- package/dist/helpers.d.ts +0 -13
- package/dist/index.js.map +0 -7
package/README.md
CHANGED
@@ -1,8 +1,19 @@
|
|
1
|
-
|
1
|
+
<div align="center">
|
2
|
+
<a href="https://cabidela.pages.dev/">
|
3
|
+
<img src="https://raw.githubusercontent.com/cloudflare/cabidela/refs/heads/main/assets/cabidela.png" width="500" height="auto" alt="cabidela"/>
|
4
|
+
</a>
|
5
|
+
</div>
|
2
6
|
|
3
|
-
Cabidela is a small, fast, eval-less, [Cloudflare Workers](https://developers.cloudflare.com/workers/) compatible, dynamic JSON Schema validator.
|
4
7
|
|
5
|
-
|
8
|
+
<p align="center">
|
9
|
+
<em>Small, fast, eval-less, [Cloudflare Workers](https://developers.cloudflare.com/workers/) compatible, dynamic JSON Schema validator.</em>
|
10
|
+
</p>
|
11
|
+
|
12
|
+
<hr />
|
13
|
+
|
14
|
+
# What is
|
15
|
+
|
16
|
+
Cabidela is a small, fast, eval-less, [Cloudflare Workers](https://developers.cloudflare.com/workers/) compatible, dynamic JSON Schema validator. It implements a large subset of <https://json-schema.org/draft/2020-12/json-schema-validation> that should cover most use-cases. But not all. See limitations below.
|
6
17
|
|
7
18
|
## How to use
|
8
19
|
|
package/dist/index.d.mts
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
type CabidelaOptions = {
|
2
|
+
applyDefaults?: boolean;
|
3
|
+
errorMessages?: boolean;
|
4
|
+
fullErrors?: boolean;
|
5
|
+
};
|
6
|
+
type SchemaNavigation = {
|
7
|
+
path: Array<string>;
|
8
|
+
schema: any;
|
9
|
+
payload: any;
|
10
|
+
evaluatedProperties: Set<string>;
|
11
|
+
carryProperties?: boolean;
|
12
|
+
absorvErrors?: boolean;
|
13
|
+
errors: Set<string>;
|
14
|
+
};
|
15
|
+
declare class Cabidela {
|
16
|
+
schema: any;
|
17
|
+
options: CabidelaOptions;
|
18
|
+
constructor(schema: any, options?: CabidelaOptions);
|
19
|
+
setSchema(schema: any): void;
|
20
|
+
setOptions(options: CabidelaOptions): void;
|
21
|
+
throw(message: string, needle: SchemaNavigation): void;
|
22
|
+
parseAdditionalProperties(needle: SchemaNavigation, contextAdditionalProperties: any, contextEvaluatedProperties: Set<string>): number;
|
23
|
+
parseObject(needle: SchemaNavigation): boolean;
|
24
|
+
parseList(list: any, needle: SchemaNavigation, breakCondition?: Function): number;
|
25
|
+
parseSubSchema(needle: SchemaNavigation): number;
|
26
|
+
validate(payload: any): boolean;
|
27
|
+
}
|
28
|
+
|
29
|
+
export { Cabidela, type CabidelaOptions, type SchemaNavigation };
|
package/dist/index.d.ts
CHANGED
@@ -1,18 +1,18 @@
|
|
1
|
-
|
1
|
+
type CabidelaOptions = {
|
2
2
|
applyDefaults?: boolean;
|
3
3
|
errorMessages?: boolean;
|
4
4
|
fullErrors?: boolean;
|
5
5
|
};
|
6
|
-
|
6
|
+
type SchemaNavigation = {
|
7
7
|
path: Array<string>;
|
8
8
|
schema: any;
|
9
9
|
payload: any;
|
10
|
-
evaluatedProperties
|
10
|
+
evaluatedProperties: Set<string>;
|
11
11
|
carryProperties?: boolean;
|
12
12
|
absorvErrors?: boolean;
|
13
|
-
errors
|
13
|
+
errors: Set<string>;
|
14
14
|
};
|
15
|
-
|
15
|
+
declare class Cabidela {
|
16
16
|
schema: any;
|
17
17
|
options: CabidelaOptions;
|
18
18
|
constructor(schema: any, options?: CabidelaOptions);
|
@@ -25,3 +25,5 @@ export declare class Cabidela {
|
|
25
25
|
parseSubSchema(needle: SchemaNavigation): number;
|
26
26
|
validate(payload: any): boolean;
|
27
27
|
}
|
28
|
+
|
29
|
+
export { Cabidela, type CabidelaOptions, type SchemaNavigation };
|
package/dist/index.js
CHANGED
@@ -1,3 +1,29 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __defProp = Object.defineProperty;
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
6
|
+
var __export = (target, all) => {
|
7
|
+
for (var name in all)
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
9
|
+
};
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
12
|
+
for (let key of __getOwnPropNames(from))
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
15
|
+
}
|
16
|
+
return to;
|
17
|
+
};
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
19
|
+
|
20
|
+
// src/index.ts
|
21
|
+
var index_exports = {};
|
22
|
+
__export(index_exports, {
|
23
|
+
Cabidela: () => Cabidela
|
24
|
+
});
|
25
|
+
module.exports = __toCommonJS(index_exports);
|
26
|
+
|
1
27
|
// src/helpers.ts
|
2
28
|
var resolvePayload = (path, obj) => {
|
3
29
|
let resolvedObject = path.reduce(function(prev, curr) {
|
@@ -46,7 +72,12 @@ var Cabidela = class {
|
|
46
72
|
options;
|
47
73
|
constructor(schema, options) {
|
48
74
|
this.schema = schema;
|
49
|
-
this.options = {
|
75
|
+
this.options = {
|
76
|
+
fullErrors: true,
|
77
|
+
applyDefaults: false,
|
78
|
+
errorMessages: false,
|
79
|
+
...options || {}
|
80
|
+
};
|
50
81
|
}
|
51
82
|
setSchema(schema) {
|
52
83
|
this.schema = schema;
|
@@ -56,12 +87,19 @@ var Cabidela = class {
|
|
56
87
|
}
|
57
88
|
throw(message, needle) {
|
58
89
|
const error = `${message}${this.options.fullErrors && needle.absorvErrors !== true && needle.errors.size > 0 ? `: ${Array.from(needle.errors).join(", ")}` : ``}`;
|
59
|
-
throw new Error(
|
90
|
+
throw new Error(
|
91
|
+
this.options.errorMessages ? needle.schema.errorMessage ?? error : error
|
92
|
+
);
|
60
93
|
}
|
61
94
|
parseAdditionalProperties(needle, contextAdditionalProperties, contextEvaluatedProperties) {
|
62
95
|
let matchCount = 0;
|
63
|
-
const { metadata, resolvedObject } = resolvePayload(
|
64
|
-
|
96
|
+
const { metadata, resolvedObject } = resolvePayload(
|
97
|
+
needle.path,
|
98
|
+
needle.payload
|
99
|
+
);
|
100
|
+
const unevaluatedProperties = metadata.properties.difference(
|
101
|
+
contextEvaluatedProperties
|
102
|
+
);
|
65
103
|
if (contextAdditionalProperties === false) {
|
66
104
|
if (unevaluatedProperties.size > 0) {
|
67
105
|
this.throw(
|
@@ -129,7 +167,10 @@ var Cabidela = class {
|
|
129
167
|
);
|
130
168
|
}
|
131
169
|
if (needle.schema.hasOwnProperty("unevaluatedProperties")) {
|
132
|
-
needle.evaluatedProperties = /* @__PURE__ */ new Set([
|
170
|
+
needle.evaluatedProperties = /* @__PURE__ */ new Set([
|
171
|
+
...needle.evaluatedProperties,
|
172
|
+
...localEvaluatedProperties
|
173
|
+
]);
|
133
174
|
matchCount += this.parseAdditionalProperties(
|
134
175
|
needle,
|
135
176
|
needle.schema.unevaluatedProperties,
|
@@ -137,8 +178,13 @@ var Cabidela = class {
|
|
137
178
|
);
|
138
179
|
}
|
139
180
|
if (needle.schema.hasOwnProperty("required")) {
|
140
|
-
if (new Set(needle.schema.required).difference(
|
141
|
-
|
181
|
+
if (new Set(needle.schema.required).difference(
|
182
|
+
needle.evaluatedProperties.union(localEvaluatedProperties)
|
183
|
+
).size > 0) {
|
184
|
+
this.throw(
|
185
|
+
`required properties at '${pathToString(needle.path)}' is '${needle.schema.required}'`,
|
186
|
+
needle
|
187
|
+
);
|
142
188
|
}
|
143
189
|
}
|
144
190
|
return matchCount ? true : false;
|
@@ -184,7 +230,10 @@ var Cabidela = class {
|
|
184
230
|
return 1;
|
185
231
|
}
|
186
232
|
if (needle.schema.hasOwnProperty("allOf")) {
|
187
|
-
const conditions = needle.schema.allOf.reduce(
|
233
|
+
const conditions = needle.schema.allOf.reduce(
|
234
|
+
(r, c) => Object.assign(r, c),
|
235
|
+
{}
|
236
|
+
);
|
188
237
|
try {
|
189
238
|
this.parseSubSchema({
|
190
239
|
...needle,
|
@@ -199,7 +248,10 @@ var Cabidela = class {
|
|
199
248
|
return 0;
|
200
249
|
}
|
201
250
|
}
|
202
|
-
const { metadata, resolvedObject } = resolvePayload(
|
251
|
+
const { metadata, resolvedObject } = resolvePayload(
|
252
|
+
needle.path,
|
253
|
+
needle.payload
|
254
|
+
);
|
203
255
|
if (needle.schema.type === "array" && !metadata.types.has("binary") && !metadata.types.has("string")) {
|
204
256
|
let matched = 0;
|
205
257
|
for (let item in resolvedObject) {
|
@@ -224,7 +276,10 @@ var Cabidela = class {
|
|
224
276
|
if (needle.schema.type == void 0) return 1;
|
225
277
|
}
|
226
278
|
} else {
|
227
|
-
this.throw(
|
279
|
+
this.throw(
|
280
|
+
`enum should be an array at '${pathToString(needle.path)}'`,
|
281
|
+
needle
|
282
|
+
);
|
228
283
|
}
|
229
284
|
}
|
230
285
|
if (needle.schema.hasOwnProperty("type") && !metadata.types.has(needle.schema.type)) {
|
@@ -237,7 +292,10 @@ var Cabidela = class {
|
|
237
292
|
switch (needle.schema.type) {
|
238
293
|
case "string":
|
239
294
|
if (needle.schema.hasOwnProperty("maxLength") && metadata.size > needle.schema.maxLength) {
|
240
|
-
this.throw(
|
295
|
+
this.throw(
|
296
|
+
`Length of '${pathToString(needle.path)}' must be <= ${needle.schema.maxLength}`,
|
297
|
+
needle
|
298
|
+
);
|
241
299
|
}
|
242
300
|
if (needle.schema.hasOwnProperty("minLength") && metadata.size < needle.schema.minLength) {
|
243
301
|
this.throw(
|
@@ -249,19 +307,34 @@ var Cabidela = class {
|
|
249
307
|
case "number":
|
250
308
|
case "integer":
|
251
309
|
if (needle.schema.hasOwnProperty("minimum") && resolvedObject < needle.schema.minimum) {
|
252
|
-
this.throw(
|
310
|
+
this.throw(
|
311
|
+
`'${pathToString(needle.path)}' must be >= ${needle.schema.minimum}`,
|
312
|
+
needle
|
313
|
+
);
|
253
314
|
}
|
254
315
|
if (needle.schema.hasOwnProperty("exclusiveMinimum") && resolvedObject <= needle.schema.exclusiveMinimum) {
|
255
|
-
this.throw(
|
316
|
+
this.throw(
|
317
|
+
`'${pathToString(needle.path)}' must be > ${needle.schema.exclusiveMinimum}`,
|
318
|
+
needle
|
319
|
+
);
|
256
320
|
}
|
257
321
|
if (needle.schema.hasOwnProperty("maximum") && resolvedObject > needle.schema.maximum) {
|
258
|
-
this.throw(
|
322
|
+
this.throw(
|
323
|
+
`'${pathToString(needle.path)}' must be <= ${needle.schema.maximum}`,
|
324
|
+
needle
|
325
|
+
);
|
259
326
|
}
|
260
327
|
if (needle.schema.hasOwnProperty("exclusiveMaximum") && resolvedObject >= needle.schema.exclusiveMaximum) {
|
261
|
-
this.throw(
|
328
|
+
this.throw(
|
329
|
+
`'${pathToString(needle.path)}' must be < ${needle.schema.exclusiveMaximum}`,
|
330
|
+
needle
|
331
|
+
);
|
262
332
|
}
|
263
333
|
if (needle.schema.hasOwnProperty("multipleOf") && resolvedObject % needle.schema.multipleOf !== 0) {
|
264
|
-
this.throw(
|
334
|
+
this.throw(
|
335
|
+
`'${pathToString(needle.path)}' must be multiple of ${needle.schema.multipleOf}`,
|
336
|
+
needle
|
337
|
+
);
|
265
338
|
}
|
266
339
|
break;
|
267
340
|
}
|
@@ -297,7 +370,7 @@ var Cabidela = class {
|
|
297
370
|
return true;
|
298
371
|
}
|
299
372
|
};
|
300
|
-
export
|
373
|
+
// Annotate the CommonJS export names for ESM import in node:
|
374
|
+
0 && (module.exports = {
|
301
375
|
Cabidela
|
302
|
-
};
|
303
|
-
//# sourceMappingURL=index.js.map
|
376
|
+
});
|
package/dist/index.mjs
ADDED
@@ -0,0 +1,349 @@
|
|
1
|
+
// src/helpers.ts
|
2
|
+
var resolvePayload = (path, obj) => {
|
3
|
+
let resolvedObject = path.reduce(function(prev, curr) {
|
4
|
+
return prev ? prev[curr] : void 0;
|
5
|
+
}, obj);
|
6
|
+
return { metadata: getMetaData(resolvedObject), resolvedObject };
|
7
|
+
};
|
8
|
+
var pathToString = (path) => {
|
9
|
+
return path.length == 0 ? `.` : path.map((item) => typeof item === "number" ? `[${item}]` : `.${item}`).join("");
|
10
|
+
};
|
11
|
+
var getMetaData = (value) => {
|
12
|
+
let size = 0;
|
13
|
+
let types = /* @__PURE__ */ new Set([]);
|
14
|
+
let properties = /* @__PURE__ */ new Set([]);
|
15
|
+
if (value === null) {
|
16
|
+
types.add("null");
|
17
|
+
} else if (typeof value == "string") {
|
18
|
+
types.add("string");
|
19
|
+
size = value.length;
|
20
|
+
} else if (typeof value == "number") {
|
21
|
+
size = 1;
|
22
|
+
types.add("number");
|
23
|
+
if (Number.isInteger(value)) {
|
24
|
+
types.add("integer");
|
25
|
+
}
|
26
|
+
} else if (typeof value == "boolean") {
|
27
|
+
types.add("boolean");
|
28
|
+
size = 1;
|
29
|
+
} else if (Array.isArray(value)) {
|
30
|
+
size = value.length;
|
31
|
+
types.add("array");
|
32
|
+
if (value.find((item) => typeof item !== "number" && typeof item !== "string") == void 0) {
|
33
|
+
types.add("binary");
|
34
|
+
}
|
35
|
+
} else if (typeof value == "object") {
|
36
|
+
types.add("object");
|
37
|
+
size = Object.keys(value).length;
|
38
|
+
properties = new Set(Object.keys(value));
|
39
|
+
}
|
40
|
+
return { types, size, properties };
|
41
|
+
};
|
42
|
+
|
43
|
+
// src/index.ts
|
44
|
+
var Cabidela = class {
|
45
|
+
schema;
|
46
|
+
options;
|
47
|
+
constructor(schema, options) {
|
48
|
+
this.schema = schema;
|
49
|
+
this.options = {
|
50
|
+
fullErrors: true,
|
51
|
+
applyDefaults: false,
|
52
|
+
errorMessages: false,
|
53
|
+
...options || {}
|
54
|
+
};
|
55
|
+
}
|
56
|
+
setSchema(schema) {
|
57
|
+
this.schema = schema;
|
58
|
+
}
|
59
|
+
setOptions(options) {
|
60
|
+
this.options = options;
|
61
|
+
}
|
62
|
+
throw(message, needle) {
|
63
|
+
const error = `${message}${this.options.fullErrors && needle.absorvErrors !== true && needle.errors.size > 0 ? `: ${Array.from(needle.errors).join(", ")}` : ``}`;
|
64
|
+
throw new Error(
|
65
|
+
this.options.errorMessages ? needle.schema.errorMessage ?? error : error
|
66
|
+
);
|
67
|
+
}
|
68
|
+
parseAdditionalProperties(needle, contextAdditionalProperties, contextEvaluatedProperties) {
|
69
|
+
let matchCount = 0;
|
70
|
+
const { metadata, resolvedObject } = resolvePayload(
|
71
|
+
needle.path,
|
72
|
+
needle.payload
|
73
|
+
);
|
74
|
+
const unevaluatedProperties = metadata.properties.difference(
|
75
|
+
contextEvaluatedProperties
|
76
|
+
);
|
77
|
+
if (contextAdditionalProperties === false) {
|
78
|
+
if (unevaluatedProperties.size > 0) {
|
79
|
+
this.throw(
|
80
|
+
`Additional or unevaluated properties '${Array.from(unevaluatedProperties).join(", ")}' at '${pathToString(needle.path)}' not allowed`,
|
81
|
+
{
|
82
|
+
...needle,
|
83
|
+
schema: contextAdditionalProperties,
|
84
|
+
payload: resolvedObject
|
85
|
+
}
|
86
|
+
);
|
87
|
+
}
|
88
|
+
} else {
|
89
|
+
for (let property of unevaluatedProperties) {
|
90
|
+
if (this.parseSubSchema({
|
91
|
+
path: [property],
|
92
|
+
schema: contextAdditionalProperties,
|
93
|
+
payload: resolvedObject,
|
94
|
+
evaluatedProperties: /* @__PURE__ */ new Set(),
|
95
|
+
errors: /* @__PURE__ */ new Set()
|
96
|
+
})) {
|
97
|
+
matchCount++;
|
98
|
+
needle.evaluatedProperties.add(property);
|
99
|
+
}
|
100
|
+
}
|
101
|
+
}
|
102
|
+
return matchCount;
|
103
|
+
}
|
104
|
+
// Iterates through the properties of an "object" schema
|
105
|
+
parseObject(needle) {
|
106
|
+
if (needle.schema.hasOwnProperty("minProperties")) {
|
107
|
+
if (Object.keys(needle.payload).length < needle.schema.minProperties) {
|
108
|
+
this.throw(
|
109
|
+
`minProperties at '${pathToString(needle.path)}' is ${needle.schema.minProperties}, got ${Object.keys(needle.payload).length}`,
|
110
|
+
needle
|
111
|
+
);
|
112
|
+
}
|
113
|
+
}
|
114
|
+
if (needle.schema.hasOwnProperty("maxProperties")) {
|
115
|
+
if (Object.keys(needle.payload).length > needle.schema.maxProperties) {
|
116
|
+
this.throw(
|
117
|
+
`maxProperties at '${pathToString(needle.path)}' is ${needle.schema.minProperties}, got ${Object.keys(needle.payload).length}`,
|
118
|
+
needle
|
119
|
+
);
|
120
|
+
}
|
121
|
+
}
|
122
|
+
const localEvaluatedProperties = /* @__PURE__ */ new Set([]);
|
123
|
+
let matchCount = 0;
|
124
|
+
if (needle.schema.hasOwnProperty("properties")) {
|
125
|
+
for (let property in needle.schema.properties) {
|
126
|
+
if (this.parseSubSchema({
|
127
|
+
...needle,
|
128
|
+
path: [...needle.path, property],
|
129
|
+
schema: needle.schema.properties[property]
|
130
|
+
})) {
|
131
|
+
localEvaluatedProperties.add(property);
|
132
|
+
matchCount++;
|
133
|
+
}
|
134
|
+
}
|
135
|
+
}
|
136
|
+
if (needle.schema.hasOwnProperty("additionalProperties")) {
|
137
|
+
matchCount += this.parseAdditionalProperties(
|
138
|
+
needle,
|
139
|
+
needle.schema.additionalProperties,
|
140
|
+
localEvaluatedProperties
|
141
|
+
);
|
142
|
+
}
|
143
|
+
if (needle.schema.hasOwnProperty("unevaluatedProperties")) {
|
144
|
+
needle.evaluatedProperties = /* @__PURE__ */ new Set([
|
145
|
+
...needle.evaluatedProperties,
|
146
|
+
...localEvaluatedProperties
|
147
|
+
]);
|
148
|
+
matchCount += this.parseAdditionalProperties(
|
149
|
+
needle,
|
150
|
+
needle.schema.unevaluatedProperties,
|
151
|
+
needle.evaluatedProperties
|
152
|
+
);
|
153
|
+
}
|
154
|
+
if (needle.schema.hasOwnProperty("required")) {
|
155
|
+
if (new Set(needle.schema.required).difference(
|
156
|
+
needle.evaluatedProperties.union(localEvaluatedProperties)
|
157
|
+
).size > 0) {
|
158
|
+
this.throw(
|
159
|
+
`required properties at '${pathToString(needle.path)}' is '${needle.schema.required}'`,
|
160
|
+
needle
|
161
|
+
);
|
162
|
+
}
|
163
|
+
}
|
164
|
+
return matchCount ? true : false;
|
165
|
+
}
|
166
|
+
parseList(list, needle, breakCondition) {
|
167
|
+
let rounds = 0;
|
168
|
+
for (let option in list) {
|
169
|
+
try {
|
170
|
+
rounds += this.parseSubSchema({
|
171
|
+
...needle,
|
172
|
+
schema: { type: needle.schema.type, ...list[option] },
|
173
|
+
carryProperties: true,
|
174
|
+
absorvErrors: true
|
175
|
+
});
|
176
|
+
if (breakCondition && breakCondition(rounds)) break;
|
177
|
+
} catch (e) {
|
178
|
+
needle.errors.add(e.message);
|
179
|
+
}
|
180
|
+
}
|
181
|
+
return rounds;
|
182
|
+
}
|
183
|
+
// Parses a JSON Schema sub-schema object - reentrant
|
184
|
+
parseSubSchema(needle) {
|
185
|
+
if (needle.schema == void 0) {
|
186
|
+
this.throw(`No schema for path '${pathToString(needle.path)}'`, needle);
|
187
|
+
}
|
188
|
+
if (needle.schema.hasOwnProperty("oneOf")) {
|
189
|
+
if (this.parseList(needle.schema.oneOf, needle) !== 1) {
|
190
|
+
if (needle.path.length == 0) {
|
191
|
+
this.throw(`oneOf at '${pathToString(needle.path)}' not met`, needle);
|
192
|
+
}
|
193
|
+
return 0;
|
194
|
+
}
|
195
|
+
return 1;
|
196
|
+
}
|
197
|
+
if (needle.schema.hasOwnProperty("anyOf")) {
|
198
|
+
if (this.parseList(needle.schema.anyOf, needle, (r) => r !== 0) === 0) {
|
199
|
+
if (needle.path.length == 0) {
|
200
|
+
this.throw(`anyOf at '${pathToString(needle.path)}' not met`, needle);
|
201
|
+
}
|
202
|
+
return 0;
|
203
|
+
}
|
204
|
+
return 1;
|
205
|
+
}
|
206
|
+
if (needle.schema.hasOwnProperty("allOf")) {
|
207
|
+
const conditions = needle.schema.allOf.reduce(
|
208
|
+
(r, c) => Object.assign(r, c),
|
209
|
+
{}
|
210
|
+
);
|
211
|
+
try {
|
212
|
+
this.parseSubSchema({
|
213
|
+
...needle,
|
214
|
+
schema: { type: needle.schema.type, ...conditions },
|
215
|
+
carryProperties: true
|
216
|
+
});
|
217
|
+
} catch (e) {
|
218
|
+
if (needle.path.length == 0) {
|
219
|
+
throw e;
|
220
|
+
}
|
221
|
+
needle.errors.add(e.message);
|
222
|
+
return 0;
|
223
|
+
}
|
224
|
+
}
|
225
|
+
const { metadata, resolvedObject } = resolvePayload(
|
226
|
+
needle.path,
|
227
|
+
needle.payload
|
228
|
+
);
|
229
|
+
if (needle.schema.type === "array" && !metadata.types.has("binary") && !metadata.types.has("string")) {
|
230
|
+
let matched = 0;
|
231
|
+
for (let item in resolvedObject) {
|
232
|
+
matched += this.parseSubSchema({
|
233
|
+
...needle,
|
234
|
+
path: [...needle.path, item],
|
235
|
+
schema: needle.schema.items
|
236
|
+
});
|
237
|
+
}
|
238
|
+
return matched;
|
239
|
+
} else if (needle.schema.type === "object" || needle.schema.properties) {
|
240
|
+
return this.parseObject(needle) ? 1 : 0;
|
241
|
+
} else if (resolvedObject !== void 0) {
|
242
|
+
if (needle.schema.hasOwnProperty("enum")) {
|
243
|
+
if (Array.isArray(needle.schema.enum)) {
|
244
|
+
if (!needle.schema.enum.includes(resolvedObject)) {
|
245
|
+
this.throw(
|
246
|
+
`enum ${resolvedObject} not in ${needle.schema.enum.join(",")} at '${pathToString(needle.path)}'`,
|
247
|
+
needle
|
248
|
+
);
|
249
|
+
} else {
|
250
|
+
if (needle.schema.type == void 0) return 1;
|
251
|
+
}
|
252
|
+
} else {
|
253
|
+
this.throw(
|
254
|
+
`enum should be an array at '${pathToString(needle.path)}'`,
|
255
|
+
needle
|
256
|
+
);
|
257
|
+
}
|
258
|
+
}
|
259
|
+
if (needle.schema.hasOwnProperty("type") && !metadata.types.has(needle.schema.type)) {
|
260
|
+
this.throw(
|
261
|
+
`Type mismatch of '${pathToString(needle.path)}', '${needle.schema.type}' not in ${JSON.stringify(Array.from(metadata.types))}`,
|
262
|
+
needle
|
263
|
+
);
|
264
|
+
}
|
265
|
+
if (needle.schema !== true) {
|
266
|
+
switch (needle.schema.type) {
|
267
|
+
case "string":
|
268
|
+
if (needle.schema.hasOwnProperty("maxLength") && metadata.size > needle.schema.maxLength) {
|
269
|
+
this.throw(
|
270
|
+
`Length of '${pathToString(needle.path)}' must be <= ${needle.schema.maxLength}`,
|
271
|
+
needle
|
272
|
+
);
|
273
|
+
}
|
274
|
+
if (needle.schema.hasOwnProperty("minLength") && metadata.size < needle.schema.minLength) {
|
275
|
+
this.throw(
|
276
|
+
`Length of '${pathToString(needle.path)}' must be >= ${needle.schema.minLength} not met`,
|
277
|
+
needle
|
278
|
+
);
|
279
|
+
}
|
280
|
+
break;
|
281
|
+
case "number":
|
282
|
+
case "integer":
|
283
|
+
if (needle.schema.hasOwnProperty("minimum") && resolvedObject < needle.schema.minimum) {
|
284
|
+
this.throw(
|
285
|
+
`'${pathToString(needle.path)}' must be >= ${needle.schema.minimum}`,
|
286
|
+
needle
|
287
|
+
);
|
288
|
+
}
|
289
|
+
if (needle.schema.hasOwnProperty("exclusiveMinimum") && resolvedObject <= needle.schema.exclusiveMinimum) {
|
290
|
+
this.throw(
|
291
|
+
`'${pathToString(needle.path)}' must be > ${needle.schema.exclusiveMinimum}`,
|
292
|
+
needle
|
293
|
+
);
|
294
|
+
}
|
295
|
+
if (needle.schema.hasOwnProperty("maximum") && resolvedObject > needle.schema.maximum) {
|
296
|
+
this.throw(
|
297
|
+
`'${pathToString(needle.path)}' must be <= ${needle.schema.maximum}`,
|
298
|
+
needle
|
299
|
+
);
|
300
|
+
}
|
301
|
+
if (needle.schema.hasOwnProperty("exclusiveMaximum") && resolvedObject >= needle.schema.exclusiveMaximum) {
|
302
|
+
this.throw(
|
303
|
+
`'${pathToString(needle.path)}' must be < ${needle.schema.exclusiveMaximum}`,
|
304
|
+
needle
|
305
|
+
);
|
306
|
+
}
|
307
|
+
if (needle.schema.hasOwnProperty("multipleOf") && resolvedObject % needle.schema.multipleOf !== 0) {
|
308
|
+
this.throw(
|
309
|
+
`'${pathToString(needle.path)}' must be multiple of ${needle.schema.multipleOf}`,
|
310
|
+
needle
|
311
|
+
);
|
312
|
+
}
|
313
|
+
break;
|
314
|
+
}
|
315
|
+
}
|
316
|
+
if (needle.carryProperties) {
|
317
|
+
needle.evaluatedProperties.add(needle.path[needle.path.length - 1]);
|
318
|
+
}
|
319
|
+
return 1;
|
320
|
+
}
|
321
|
+
if (this.options.applyDefaults === true && needle.schema.hasOwnProperty("default")) {
|
322
|
+
needle.path.reduce(function(prev, curr, index) {
|
323
|
+
if (prev[curr] === void 0) {
|
324
|
+
prev[curr] = {};
|
325
|
+
}
|
326
|
+
if (index == needle.path.length - 1) {
|
327
|
+
prev[curr] = needle.schema.default;
|
328
|
+
needle.evaluatedProperties.add(needle.path[needle.path.length - 1]);
|
329
|
+
}
|
330
|
+
return prev ? prev[curr] : void 0;
|
331
|
+
}, needle.payload);
|
332
|
+
}
|
333
|
+
return 0;
|
334
|
+
}
|
335
|
+
validate(payload) {
|
336
|
+
const needle = {
|
337
|
+
errors: /* @__PURE__ */ new Set(),
|
338
|
+
evaluatedProperties: /* @__PURE__ */ new Set(),
|
339
|
+
path: [],
|
340
|
+
schema: this.schema,
|
341
|
+
payload
|
342
|
+
};
|
343
|
+
this.parseSubSchema(needle);
|
344
|
+
return true;
|
345
|
+
}
|
346
|
+
};
|
347
|
+
export {
|
348
|
+
Cabidela
|
349
|
+
};
|
package/package.json
CHANGED
@@ -1,34 +1,44 @@
|
|
1
1
|
{
|
2
2
|
"name": "@cloudflare/cabidela",
|
3
|
-
"version": "0.0.
|
4
|
-
"type": "module",
|
3
|
+
"version": "0.0.17",
|
5
4
|
"description": "Cabidela is a small, fast, eval-less, Cloudflare Workers compatible, dynamic JSON Schema validator",
|
6
5
|
"main": "dist/index.js",
|
6
|
+
"module": "dist/index.mjs",
|
7
7
|
"types": "dist/index.d.ts",
|
8
8
|
"author": "Celso Martinho <celso@cloudflare.com>",
|
9
|
-
"license": "
|
9
|
+
"license": "Cloudflare",
|
10
10
|
"scripts": {
|
11
11
|
"test": "npm run test-cabidela",
|
12
12
|
"test-all": "npm run test-cabidela && npm run test-ajv",
|
13
13
|
"test-cabidela": "vitest run --dir tests --reporter=verbose",
|
14
14
|
"test-ajv": "AJV=true vitest run --dir tests --reporter=verbose",
|
15
15
|
"benchmark": "vitest bench --dir benchmarks --reporter=verbose --watch false",
|
16
|
-
"build": "
|
17
|
-
"build-esbuild": "esbuild src/index.ts --bundle --outfile=dist/index.js --sourcemap --format=esm",
|
18
|
-
"build-tsc": "tsc --declaration --emitDeclarationOnly --outDir ./dist --target esnext src/index.ts",
|
16
|
+
"build": "rm -rf dist/ && tsup src/index.ts --format cjs,esm --dts --config tsconfig.json",
|
19
17
|
"dry-publish": "npm pack --dry-run"
|
20
18
|
},
|
21
19
|
"keywords": [
|
22
|
-
"json-schema"
|
20
|
+
"json-schema",
|
21
|
+
"cloudflare",
|
22
|
+
"cloudflare workers"
|
23
23
|
],
|
24
24
|
"files": [
|
25
|
-
"dist
|
25
|
+
"dist",
|
26
|
+
"LICENSE",
|
27
|
+
"README.md"
|
26
28
|
],
|
29
|
+
"repository": {
|
30
|
+
"type": "git",
|
31
|
+
"url": "https://github.com/cloudflare/cabidela.git"
|
32
|
+
},
|
33
|
+
"bugs": {
|
34
|
+
"url": "https://github.com/cloudflare/cabidela/issues"
|
35
|
+
},
|
27
36
|
"devDependencies": {
|
37
|
+
"@types/node": "^22.13.1",
|
28
38
|
"@vitest/ui": "^3.0.3",
|
29
39
|
"ajv": "^8.17.1",
|
30
40
|
"ajv-errors": "^3.0.0",
|
31
|
-
"
|
41
|
+
"tsup": "^8.3.6",
|
32
42
|
"typescript": "^5.7.3",
|
33
43
|
"vitest": "^3.0.3"
|
34
44
|
}
|
package/dist/helpers.d.ts
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
export type metaData = {
|
2
|
-
types: Set<string>;
|
3
|
-
size: number;
|
4
|
-
properties: Set<string>;
|
5
|
-
};
|
6
|
-
export type resolvedResponse = {
|
7
|
-
metadata: metaData;
|
8
|
-
resolvedObject: any;
|
9
|
-
};
|
10
|
-
export declare const includesAll: (arr: Array<any>, values: Array<any>) => boolean;
|
11
|
-
export declare const resolvePayload: (path: Array<string | number>, obj: any) => resolvedResponse;
|
12
|
-
export declare const pathToString: (path: Array<string | number>) => string;
|
13
|
-
export declare const getMetaData: (value: any) => metaData;
|
package/dist/index.js.map
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"version": 3,
|
3
|
-
"sources": ["../src/helpers.ts", "../src/index.ts"],
|
4
|
-
"sourcesContent": ["export type metaData = {\n types: Set<string>;\n size: number;\n properties: Set<string>;\n};\n\nexport type resolvedResponse = {\n metadata: metaData;\n resolvedObject: any;\n};\n\nexport const includesAll = (arr: Array<any>, values: Array<any>) => {\n return values.every((v) => arr.includes(v));\n};\n\n/* Resolves a path in an object\n\n obj = {\n prompt: \"hello\",\n messages: [\n { role: \"system\", content: \"you are a helpful assistant\" },\n { role: \"user\", content: \"tell me a joke\" },\n ]\n }\n\n path = [\"messages\"]\n returns [\n { role: \"system\", content: \"you are a helpful assistant\" },\n { role: \"user\", content: \"tell me a joke\" },\n ]\n\n path = [\"messages\", 1, \"role\"]\n returns \"system\"\n\n path = [\"prompt\"]\n returns \"hello\"\n\n path = [\"invalid\", \"path\"]\n returns undefined\n\n */\n\nexport const resolvePayload = (path: Array<string | number>, obj: any): resolvedResponse => {\n let resolvedObject = path.reduce(function (prev, curr) {\n return prev ? prev[curr] : undefined;\n }, obj);\n\n return { metadata: getMetaData(resolvedObject), resolvedObject };\n};\n\nexport const pathToString = (path: Array<string | number>) => {\n return path.length == 0 ? `.` : path.map((item) => (typeof item === \"number\" ? `[${item}]` : `.${item}`)).join(\"\");\n};\n\n// https://json-schema.org/understanding-json-schema/reference/type\n\nexport const getMetaData = (value: any): metaData => {\n let size = 0;\n let types = new Set([]);\n let properties = new Set([]);\n if (value === null) {\n types.add(\"null\");\n } else if (typeof value == \"string\") {\n types.add(\"string\");\n size = value.length;\n } else if (typeof value == \"number\") {\n size = 1;\n types.add(\"number\");\n if (Number.isInteger(value)) {\n types.add(\"integer\");\n }\n } else if (typeof value == \"boolean\") {\n types.add(\"boolean\");\n size = 1;\n } else if (Array.isArray(value)) {\n size = value.length;\n types.add(\"array\");\n if (value.find((item) => typeof item !== \"number\" && typeof item !== \"string\") == undefined) {\n types.add(\"binary\");\n }\n } else if (typeof value == \"object\") {\n types.add(\"object\");\n size = Object.keys(value).length;\n properties = new Set(Object.keys(value));\n }\n return { types, size, properties };\n};\n", "import { resolvePayload, pathToString } from \"./helpers\";\n\nexport type CabidelaOptions = {\n applyDefaults?: boolean;\n errorMessages?: boolean;\n fullErrors?: boolean;\n};\n\nexport type SchemaNavigation = {\n path: Array<string>;\n schema: any;\n payload: any;\n evaluatedProperties?: Set<string>;\n carryProperties?: boolean;\n absorvErrors?: boolean;\n errors?: Set<string>;\n};\n\nexport class Cabidela {\n public schema: any;\n public options: CabidelaOptions;\n\n constructor(schema: any, options?: CabidelaOptions) {\n this.schema = schema;\n this.options = { fullErrors: true, applyDefaults: false, errorMessages: false, ...(options || {}) };\n }\n\n setSchema(schema: any) {\n this.schema = schema;\n }\n\n setOptions(options: CabidelaOptions) {\n this.options = options;\n }\n\n throw(message: string, needle: SchemaNavigation) {\n const error = `${message}${this.options.fullErrors && needle.absorvErrors !== true && needle.errors.size > 0 ? `: ${Array.from(needle.errors).join(\", \")}` : ``}`;\n throw new Error(this.options.errorMessages ? (needle.schema.errorMessage ?? error) : error);\n }\n\n parseAdditionalProperties(\n needle: SchemaNavigation,\n contextAdditionalProperties: any,\n contextEvaluatedProperties: Set<string>,\n ): number {\n let matchCount = 0;\n const { metadata, resolvedObject } = resolvePayload(needle.path, needle.payload);\n\n const unevaluatedProperties = metadata.properties.difference(contextEvaluatedProperties);\n\n // Setting the additionalProperties schema to false means no additional properties will be allowed.\n if (contextAdditionalProperties === false) {\n if (unevaluatedProperties.size > 0) {\n this.throw(\n `Additional or unevaluated properties '${Array.from(unevaluatedProperties).join(\", \")}' at '${pathToString(needle.path)}' not allowed`,\n {\n ...needle,\n schema: contextAdditionalProperties,\n payload: resolvedObject,\n },\n );\n }\n } else {\n for (let property of unevaluatedProperties) {\n if (\n this.parseSubSchema({\n path: [property],\n schema: contextAdditionalProperties,\n payload: resolvedObject,\n evaluatedProperties: new Set(),\n errors: new Set(),\n })\n ) {\n matchCount++;\n needle.evaluatedProperties.add(property);\n }\n }\n }\n return matchCount;\n }\n\n // Iterates through the properties of an \"object\" schema\n parseObject(needle: SchemaNavigation): boolean {\n if (needle.schema.hasOwnProperty(\"minProperties\")) {\n if (Object.keys(needle.payload).length < needle.schema.minProperties) {\n this.throw(\n `minProperties at '${pathToString(needle.path)}' is ${needle.schema.minProperties}, got ${Object.keys(needle.payload).length}`,\n needle,\n );\n }\n }\n\n if (needle.schema.hasOwnProperty(\"maxProperties\")) {\n if (Object.keys(needle.payload).length > needle.schema.maxProperties) {\n this.throw(\n `maxProperties at '${pathToString(needle.path)}' is ${needle.schema.minProperties}, got ${Object.keys(needle.payload).length}`,\n needle,\n );\n }\n }\n\n const localEvaluatedProperties = new Set([]);\n let matchCount: number = 0;\n\n if (needle.schema.hasOwnProperty(\"properties\")) {\n for (let property in needle.schema.properties) {\n if (\n this.parseSubSchema({\n ...needle,\n path: [...needle.path, property],\n schema: needle.schema.properties[property],\n })\n ) {\n localEvaluatedProperties.add(property);\n matchCount++;\n }\n }\n }\n\n // additionalProperties only recognizes properties declared in the same subschema as itself.\n if (needle.schema.hasOwnProperty(\"additionalProperties\")) {\n matchCount += this.parseAdditionalProperties(\n needle,\n needle.schema.additionalProperties,\n localEvaluatedProperties,\n );\n }\n\n // unevaluatedProperties keyword is similar to additionalProperties except that it can recognize properties declared in subschemas.\n if (needle.schema.hasOwnProperty(\"unevaluatedProperties\")) {\n needle.evaluatedProperties = new Set([...needle.evaluatedProperties, ...localEvaluatedProperties]);\n matchCount += this.parseAdditionalProperties(\n needle,\n needle.schema.unevaluatedProperties,\n needle.evaluatedProperties,\n );\n }\n\n // this has to be last\n if (needle.schema.hasOwnProperty(\"required\")) {\n if (\n new Set(needle.schema.required).difference(needle.evaluatedProperties.union(localEvaluatedProperties)).size > 0\n ) {\n this.throw(`required properties at '${pathToString(needle.path)}' is '${needle.schema.required}'`, needle);\n }\n }\n return matchCount ? true : false;\n }\n\n parseList(list: any, needle: SchemaNavigation, breakCondition?: Function) {\n let rounds = 0;\n for (let option in list) {\n try {\n rounds += this.parseSubSchema({\n ...needle,\n schema: { type: needle.schema.type, ...list[option] },\n carryProperties: true,\n absorvErrors: true,\n });\n if (breakCondition && breakCondition(rounds)) break;\n } catch (e) {\n needle.errors.add(e.message);\n }\n }\n return rounds;\n }\n\n // Parses a JSON Schema sub-schema object - reentrant\n parseSubSchema(needle: SchemaNavigation) {\n if (needle.schema == undefined) {\n this.throw(`No schema for path '${pathToString(needle.path)}'`, needle);\n }\n\n // To validate against oneOf, the given data must be valid against exactly one of the given subschemas.\n if (needle.schema.hasOwnProperty(\"oneOf\")) {\n if (this.parseList(needle.schema.oneOf, needle) !== 1) {\n if (needle.path.length == 0) {\n this.throw(`oneOf at '${pathToString(needle.path)}' not met`, needle);\n }\n return 0;\n }\n return 1;\n }\n\n // To validate against anyOf, the given data must be valid against any (one or more) of the given subschemas.\n if (needle.schema.hasOwnProperty(\"anyOf\")) {\n if (this.parseList(needle.schema.anyOf, needle, (r: number) => r !== 0) === 0) {\n if (needle.path.length == 0) {\n this.throw(`anyOf at '${pathToString(needle.path)}' not met`, needle);\n }\n return 0;\n }\n return 1;\n }\n\n // To validate against allOf, the given data must be valid against all of the given subschemas.\n if (needle.schema.hasOwnProperty(\"allOf\")) {\n const conditions = needle.schema.allOf.reduce((r: any, c: any) => Object.assign(r, c), {});\n try {\n this.parseSubSchema({\n ...needle,\n schema: { type: needle.schema.type, ...conditions },\n carryProperties: true,\n });\n } catch (e) {\n if (needle.path.length == 0) {\n throw e;\n }\n needle.errors.add(e.message);\n return 0;\n }\n }\n\n const { metadata, resolvedObject } = resolvePayload(needle.path, needle.payload);\n\n // array, but object is not binary\n if (needle.schema.type === \"array\" && !metadata.types.has(\"binary\") && !metadata.types.has(\"string\")) {\n let matched = 0;\n for (let item in resolvedObject) {\n matched += this.parseSubSchema({\n ...needle,\n path: [...needle.path, item],\n schema: needle.schema.items,\n });\n }\n return matched;\n } else if (needle.schema.type === \"object\" || needle.schema.properties) {\n return this.parseObject(needle) ? 1 : 0;\n } else if (resolvedObject !== undefined) {\n // This has to be before type checking\n if (needle.schema.hasOwnProperty(\"enum\")) {\n if (Array.isArray(needle.schema.enum)) {\n if (!needle.schema.enum.includes(resolvedObject)) {\n this.throw(\n `enum ${resolvedObject} not in ${needle.schema.enum.join(\",\")} at '${pathToString(needle.path)}'`,\n needle,\n );\n } else {\n // You can use enum even without a type, to accept values of different types.\n // If that's the case, then skip type checking below\n if (needle.schema.type == undefined) return 1;\n }\n } else {\n this.throw(`enum should be an array at '${pathToString(needle.path)}'`, needle);\n }\n }\n // This has to be after handling enum\n if (needle.schema.hasOwnProperty(\"type\") && !metadata.types.has(needle.schema.type)) {\n this.throw(\n `Type mismatch of '${pathToString(needle.path)}', '${needle.schema.type}' not in ${JSON.stringify(Array.from(metadata.types))}`,\n needle,\n );\n }\n /* If property === true, then it's declared validated no matter what the value is */\n if (needle.schema !== true) {\n /* Otherwise check schema type */\n switch (needle.schema.type) {\n case \"string\":\n if (needle.schema.hasOwnProperty(\"maxLength\") && metadata.size > needle.schema.maxLength) {\n this.throw(`Length of '${pathToString(needle.path)}' must be <= ${needle.schema.maxLength}`, needle);\n }\n if (needle.schema.hasOwnProperty(\"minLength\") && metadata.size < needle.schema.minLength) {\n this.throw(\n `Length of '${pathToString(needle.path)}' must be >= ${needle.schema.minLength} not met`,\n needle,\n );\n }\n break;\n case \"number\":\n case \"integer\":\n if (needle.schema.hasOwnProperty(\"minimum\") && resolvedObject < needle.schema.minimum) {\n this.throw(`'${pathToString(needle.path)}' must be >= ${needle.schema.minimum}`, needle);\n }\n if (needle.schema.hasOwnProperty(\"exclusiveMinimum\") && resolvedObject <= needle.schema.exclusiveMinimum) {\n this.throw(`'${pathToString(needle.path)}' must be > ${needle.schema.exclusiveMinimum}`, needle);\n }\n if (needle.schema.hasOwnProperty(\"maximum\") && resolvedObject > needle.schema.maximum) {\n this.throw(`'${pathToString(needle.path)}' must be <= ${needle.schema.maximum}`, needle);\n }\n if (needle.schema.hasOwnProperty(\"exclusiveMaximum\") && resolvedObject >= needle.schema.exclusiveMaximum) {\n this.throw(`'${pathToString(needle.path)}' must be < ${needle.schema.exclusiveMaximum}`, needle);\n }\n if (needle.schema.hasOwnProperty(\"multipleOf\") && resolvedObject % needle.schema.multipleOf !== 0) {\n this.throw(`'${pathToString(needle.path)}' must be multiple of ${needle.schema.multipleOf}`, needle);\n }\n break;\n }\n }\n if (needle.carryProperties) {\n needle.evaluatedProperties.add(needle.path[needle.path.length - 1]);\n }\n return 1;\n }\n // Apply defaults\n if (this.options.applyDefaults === true && needle.schema.hasOwnProperty(\"default\")) {\n needle.path.reduce(function (prev, curr, index) {\n // create objects as needed along the path, if they don't exist, so we can apply defaults at the end\n if (prev[curr] === undefined) {\n prev[curr] = {};\n }\n if (index == needle.path.length - 1) {\n prev[curr] = needle.schema.default;\n // defaults add to evaluatedProperties and can meet \"required\" constraints\n needle.evaluatedProperties.add(needle.path[needle.path.length - 1]);\n }\n return prev ? prev[curr] : undefined;\n }, needle.payload);\n }\n return 0;\n }\n\n validate(payload: any) {\n const needle: SchemaNavigation = {\n errors: new Set(),\n evaluatedProperties: new Set(),\n path: [],\n schema: this.schema,\n payload,\n };\n this.parseSubSchema(needle);\n return true;\n }\n}\n"],
|
5
|
-
"mappings": "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",
|
6
|
-
"names": []
|
7
|
-
}
|