@cloudflare/cabidela 0.0.15 → 0.0.18
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/README.md +17 -6
- package/dist/index.d.mts +29 -0
- package/dist/index.d.ts +7 -5
- package/dist/index.js +45 -4
- package/dist/index.mjs +317 -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, <a href="https://developers.cloudflare.com/workers/">Cloudflare Workers</a> 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 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
|
|
@@ -176,11 +187,11 @@ JSON Schema validators like Ajv tend to follow this pattern:
|
|
176
187
|
2. Compile the schema.
|
177
188
|
3. Validate one or more payloads against the (compiled) schema.
|
178
189
|
|
179
|
-
All of these steps have a cost. Compiling the schema makes sense if you are going to validate multiple payloads in the same session. But in the case of a Workers
|
190
|
+
All of these steps have a cost. Compiling the schema makes sense if you are going to validate multiple payloads in the same session. But in the case of a Workers application we typically want to validate with the HTTP request, one payload at a time, and then we discard the validator.
|
180
191
|
|
181
192
|
Cabidela skips the compilation step and validates the payload directly against the schema.
|
182
193
|
|
183
|
-
In our benchmarks, Cabidela is significantly faster than Ajv on all operations if you don't reuse the validator. Even when we skip the instantiation and compilation steps from Ajv, Cabidela still performs
|
194
|
+
In our benchmarks, Cabidela is significantly faster than Ajv on all operations if you don't reuse the validator. Even when we skip the instantiation and compilation steps from Ajv, Cabidela still performs relatively well.
|
184
195
|
|
185
196
|
Here are some results:
|
186
197
|
|
@@ -228,7 +239,7 @@ npm run benchmark
|
|
228
239
|
|
229
240
|
## Current limitations
|
230
241
|
|
231
|
-
Cabidela supports most of JSON Schema specification for
|
242
|
+
Cabidela supports most of JSON Schema specification, and should be useful for many applications, but it's not complete. **Currently** we do not support:
|
232
243
|
|
233
244
|
- Multiple (array of) types `{ "type": ["number", "string"] }`
|
234
245
|
- Regular expressions
|
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;
|
@@ -213,6 +244,16 @@ var Cabidela = class {
|
|
213
244
|
} else if (needle.schema.type === "object" || needle.schema.properties) {
|
214
245
|
return this.parseObject(needle) ? 1 : 0;
|
215
246
|
} else if (resolvedObject !== void 0) {
|
247
|
+
if (needle.schema.hasOwnProperty("const")) {
|
248
|
+
if (resolvedObject !== needle.schema.const) {
|
249
|
+
this.throw(
|
250
|
+
`const ${resolvedObject} doesn't match ${needle.schema.const} at '${pathToString(needle.path)}'`,
|
251
|
+
needle
|
252
|
+
);
|
253
|
+
} else {
|
254
|
+
if (needle.schema.type == void 0) return 1;
|
255
|
+
}
|
256
|
+
}
|
216
257
|
if (needle.schema.hasOwnProperty("enum")) {
|
217
258
|
if (Array.isArray(needle.schema.enum)) {
|
218
259
|
if (!needle.schema.enum.includes(resolvedObject)) {
|
@@ -297,7 +338,7 @@ var Cabidela = class {
|
|
297
338
|
return true;
|
298
339
|
}
|
299
340
|
};
|
300
|
-
export
|
341
|
+
// Annotate the CommonJS export names for ESM import in node:
|
342
|
+
0 && (module.exports = {
|
301
343
|
Cabidela
|
302
|
-
};
|
303
|
-
//# sourceMappingURL=index.js.map
|
344
|
+
});
|
package/dist/index.mjs
ADDED
@@ -0,0 +1,317 @@
|
|
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(this.options.errorMessages ? needle.schema.errorMessage ?? error : error);
|
65
|
+
}
|
66
|
+
parseAdditionalProperties(needle, contextAdditionalProperties, contextEvaluatedProperties) {
|
67
|
+
let matchCount = 0;
|
68
|
+
const { metadata, resolvedObject } = resolvePayload(needle.path, needle.payload);
|
69
|
+
const unevaluatedProperties = metadata.properties.difference(contextEvaluatedProperties);
|
70
|
+
if (contextAdditionalProperties === false) {
|
71
|
+
if (unevaluatedProperties.size > 0) {
|
72
|
+
this.throw(
|
73
|
+
`Additional or unevaluated properties '${Array.from(unevaluatedProperties).join(", ")}' at '${pathToString(needle.path)}' not allowed`,
|
74
|
+
{
|
75
|
+
...needle,
|
76
|
+
schema: contextAdditionalProperties,
|
77
|
+
payload: resolvedObject
|
78
|
+
}
|
79
|
+
);
|
80
|
+
}
|
81
|
+
} else {
|
82
|
+
for (let property of unevaluatedProperties) {
|
83
|
+
if (this.parseSubSchema({
|
84
|
+
path: [property],
|
85
|
+
schema: contextAdditionalProperties,
|
86
|
+
payload: resolvedObject,
|
87
|
+
evaluatedProperties: /* @__PURE__ */ new Set(),
|
88
|
+
errors: /* @__PURE__ */ new Set()
|
89
|
+
})) {
|
90
|
+
matchCount++;
|
91
|
+
needle.evaluatedProperties.add(property);
|
92
|
+
}
|
93
|
+
}
|
94
|
+
}
|
95
|
+
return matchCount;
|
96
|
+
}
|
97
|
+
// Iterates through the properties of an "object" schema
|
98
|
+
parseObject(needle) {
|
99
|
+
if (needle.schema.hasOwnProperty("minProperties")) {
|
100
|
+
if (Object.keys(needle.payload).length < needle.schema.minProperties) {
|
101
|
+
this.throw(
|
102
|
+
`minProperties at '${pathToString(needle.path)}' is ${needle.schema.minProperties}, got ${Object.keys(needle.payload).length}`,
|
103
|
+
needle
|
104
|
+
);
|
105
|
+
}
|
106
|
+
}
|
107
|
+
if (needle.schema.hasOwnProperty("maxProperties")) {
|
108
|
+
if (Object.keys(needle.payload).length > needle.schema.maxProperties) {
|
109
|
+
this.throw(
|
110
|
+
`maxProperties at '${pathToString(needle.path)}' is ${needle.schema.minProperties}, got ${Object.keys(needle.payload).length}`,
|
111
|
+
needle
|
112
|
+
);
|
113
|
+
}
|
114
|
+
}
|
115
|
+
const localEvaluatedProperties = /* @__PURE__ */ new Set([]);
|
116
|
+
let matchCount = 0;
|
117
|
+
if (needle.schema.hasOwnProperty("properties")) {
|
118
|
+
for (let property in needle.schema.properties) {
|
119
|
+
if (this.parseSubSchema({
|
120
|
+
...needle,
|
121
|
+
path: [...needle.path, property],
|
122
|
+
schema: needle.schema.properties[property]
|
123
|
+
})) {
|
124
|
+
localEvaluatedProperties.add(property);
|
125
|
+
matchCount++;
|
126
|
+
}
|
127
|
+
}
|
128
|
+
}
|
129
|
+
if (needle.schema.hasOwnProperty("additionalProperties")) {
|
130
|
+
matchCount += this.parseAdditionalProperties(
|
131
|
+
needle,
|
132
|
+
needle.schema.additionalProperties,
|
133
|
+
localEvaluatedProperties
|
134
|
+
);
|
135
|
+
}
|
136
|
+
if (needle.schema.hasOwnProperty("unevaluatedProperties")) {
|
137
|
+
needle.evaluatedProperties = /* @__PURE__ */ new Set([...needle.evaluatedProperties, ...localEvaluatedProperties]);
|
138
|
+
matchCount += this.parseAdditionalProperties(
|
139
|
+
needle,
|
140
|
+
needle.schema.unevaluatedProperties,
|
141
|
+
needle.evaluatedProperties
|
142
|
+
);
|
143
|
+
}
|
144
|
+
if (needle.schema.hasOwnProperty("required")) {
|
145
|
+
if (new Set(needle.schema.required).difference(needle.evaluatedProperties.union(localEvaluatedProperties)).size > 0) {
|
146
|
+
this.throw(`required properties at '${pathToString(needle.path)}' is '${needle.schema.required}'`, needle);
|
147
|
+
}
|
148
|
+
}
|
149
|
+
return matchCount ? true : false;
|
150
|
+
}
|
151
|
+
parseList(list, needle, breakCondition) {
|
152
|
+
let rounds = 0;
|
153
|
+
for (let option in list) {
|
154
|
+
try {
|
155
|
+
rounds += this.parseSubSchema({
|
156
|
+
...needle,
|
157
|
+
schema: { type: needle.schema.type, ...list[option] },
|
158
|
+
carryProperties: true,
|
159
|
+
absorvErrors: true
|
160
|
+
});
|
161
|
+
if (breakCondition && breakCondition(rounds)) break;
|
162
|
+
} catch (e) {
|
163
|
+
needle.errors.add(e.message);
|
164
|
+
}
|
165
|
+
}
|
166
|
+
return rounds;
|
167
|
+
}
|
168
|
+
// Parses a JSON Schema sub-schema object - reentrant
|
169
|
+
parseSubSchema(needle) {
|
170
|
+
if (needle.schema == void 0) {
|
171
|
+
this.throw(`No schema for path '${pathToString(needle.path)}'`, needle);
|
172
|
+
}
|
173
|
+
if (needle.schema.hasOwnProperty("oneOf")) {
|
174
|
+
if (this.parseList(needle.schema.oneOf, needle) !== 1) {
|
175
|
+
if (needle.path.length == 0) {
|
176
|
+
this.throw(`oneOf at '${pathToString(needle.path)}' not met`, needle);
|
177
|
+
}
|
178
|
+
return 0;
|
179
|
+
}
|
180
|
+
return 1;
|
181
|
+
}
|
182
|
+
if (needle.schema.hasOwnProperty("anyOf")) {
|
183
|
+
if (this.parseList(needle.schema.anyOf, needle, (r) => r !== 0) === 0) {
|
184
|
+
if (needle.path.length == 0) {
|
185
|
+
this.throw(`anyOf at '${pathToString(needle.path)}' not met`, needle);
|
186
|
+
}
|
187
|
+
return 0;
|
188
|
+
}
|
189
|
+
return 1;
|
190
|
+
}
|
191
|
+
if (needle.schema.hasOwnProperty("allOf")) {
|
192
|
+
const conditions = needle.schema.allOf.reduce((r, c) => Object.assign(r, c), {});
|
193
|
+
try {
|
194
|
+
this.parseSubSchema({
|
195
|
+
...needle,
|
196
|
+
schema: { type: needle.schema.type, ...conditions },
|
197
|
+
carryProperties: true
|
198
|
+
});
|
199
|
+
} catch (e) {
|
200
|
+
if (needle.path.length == 0) {
|
201
|
+
throw e;
|
202
|
+
}
|
203
|
+
needle.errors.add(e.message);
|
204
|
+
return 0;
|
205
|
+
}
|
206
|
+
}
|
207
|
+
const { metadata, resolvedObject } = resolvePayload(needle.path, needle.payload);
|
208
|
+
if (needle.schema.type === "array" && !metadata.types.has("binary") && !metadata.types.has("string")) {
|
209
|
+
let matched = 0;
|
210
|
+
for (let item in resolvedObject) {
|
211
|
+
matched += this.parseSubSchema({
|
212
|
+
...needle,
|
213
|
+
path: [...needle.path, item],
|
214
|
+
schema: needle.schema.items
|
215
|
+
});
|
216
|
+
}
|
217
|
+
return matched;
|
218
|
+
} else if (needle.schema.type === "object" || needle.schema.properties) {
|
219
|
+
return this.parseObject(needle) ? 1 : 0;
|
220
|
+
} else if (resolvedObject !== void 0) {
|
221
|
+
if (needle.schema.hasOwnProperty("const")) {
|
222
|
+
if (resolvedObject !== needle.schema.const) {
|
223
|
+
this.throw(
|
224
|
+
`const ${resolvedObject} doesn't match ${needle.schema.const} at '${pathToString(needle.path)}'`,
|
225
|
+
needle
|
226
|
+
);
|
227
|
+
} else {
|
228
|
+
if (needle.schema.type == void 0) return 1;
|
229
|
+
}
|
230
|
+
}
|
231
|
+
if (needle.schema.hasOwnProperty("enum")) {
|
232
|
+
if (Array.isArray(needle.schema.enum)) {
|
233
|
+
if (!needle.schema.enum.includes(resolvedObject)) {
|
234
|
+
this.throw(
|
235
|
+
`enum ${resolvedObject} not in ${needle.schema.enum.join(",")} at '${pathToString(needle.path)}'`,
|
236
|
+
needle
|
237
|
+
);
|
238
|
+
} else {
|
239
|
+
if (needle.schema.type == void 0) return 1;
|
240
|
+
}
|
241
|
+
} else {
|
242
|
+
this.throw(`enum should be an array at '${pathToString(needle.path)}'`, needle);
|
243
|
+
}
|
244
|
+
}
|
245
|
+
if (needle.schema.hasOwnProperty("type") && !metadata.types.has(needle.schema.type)) {
|
246
|
+
this.throw(
|
247
|
+
`Type mismatch of '${pathToString(needle.path)}', '${needle.schema.type}' not in ${JSON.stringify(Array.from(metadata.types))}`,
|
248
|
+
needle
|
249
|
+
);
|
250
|
+
}
|
251
|
+
if (needle.schema !== true) {
|
252
|
+
switch (needle.schema.type) {
|
253
|
+
case "string":
|
254
|
+
if (needle.schema.hasOwnProperty("maxLength") && metadata.size > needle.schema.maxLength) {
|
255
|
+
this.throw(`Length of '${pathToString(needle.path)}' must be <= ${needle.schema.maxLength}`, needle);
|
256
|
+
}
|
257
|
+
if (needle.schema.hasOwnProperty("minLength") && metadata.size < needle.schema.minLength) {
|
258
|
+
this.throw(
|
259
|
+
`Length of '${pathToString(needle.path)}' must be >= ${needle.schema.minLength} not met`,
|
260
|
+
needle
|
261
|
+
);
|
262
|
+
}
|
263
|
+
break;
|
264
|
+
case "number":
|
265
|
+
case "integer":
|
266
|
+
if (needle.schema.hasOwnProperty("minimum") && resolvedObject < needle.schema.minimum) {
|
267
|
+
this.throw(`'${pathToString(needle.path)}' must be >= ${needle.schema.minimum}`, needle);
|
268
|
+
}
|
269
|
+
if (needle.schema.hasOwnProperty("exclusiveMinimum") && resolvedObject <= needle.schema.exclusiveMinimum) {
|
270
|
+
this.throw(`'${pathToString(needle.path)}' must be > ${needle.schema.exclusiveMinimum}`, needle);
|
271
|
+
}
|
272
|
+
if (needle.schema.hasOwnProperty("maximum") && resolvedObject > needle.schema.maximum) {
|
273
|
+
this.throw(`'${pathToString(needle.path)}' must be <= ${needle.schema.maximum}`, needle);
|
274
|
+
}
|
275
|
+
if (needle.schema.hasOwnProperty("exclusiveMaximum") && resolvedObject >= needle.schema.exclusiveMaximum) {
|
276
|
+
this.throw(`'${pathToString(needle.path)}' must be < ${needle.schema.exclusiveMaximum}`, needle);
|
277
|
+
}
|
278
|
+
if (needle.schema.hasOwnProperty("multipleOf") && resolvedObject % needle.schema.multipleOf !== 0) {
|
279
|
+
this.throw(`'${pathToString(needle.path)}' must be multiple of ${needle.schema.multipleOf}`, needle);
|
280
|
+
}
|
281
|
+
break;
|
282
|
+
}
|
283
|
+
}
|
284
|
+
if (needle.carryProperties) {
|
285
|
+
needle.evaluatedProperties.add(needle.path[needle.path.length - 1]);
|
286
|
+
}
|
287
|
+
return 1;
|
288
|
+
}
|
289
|
+
if (this.options.applyDefaults === true && needle.schema.hasOwnProperty("default")) {
|
290
|
+
needle.path.reduce(function(prev, curr, index) {
|
291
|
+
if (prev[curr] === void 0) {
|
292
|
+
prev[curr] = {};
|
293
|
+
}
|
294
|
+
if (index == needle.path.length - 1) {
|
295
|
+
prev[curr] = needle.schema.default;
|
296
|
+
needle.evaluatedProperties.add(needle.path[needle.path.length - 1]);
|
297
|
+
}
|
298
|
+
return prev ? prev[curr] : void 0;
|
299
|
+
}, needle.payload);
|
300
|
+
}
|
301
|
+
return 0;
|
302
|
+
}
|
303
|
+
validate(payload) {
|
304
|
+
const needle = {
|
305
|
+
errors: /* @__PURE__ */ new Set(),
|
306
|
+
evaluatedProperties: /* @__PURE__ */ new Set(),
|
307
|
+
path: [],
|
308
|
+
schema: this.schema,
|
309
|
+
payload
|
310
|
+
};
|
311
|
+
this.parseSubSchema(needle);
|
312
|
+
return true;
|
313
|
+
}
|
314
|
+
};
|
315
|
+
export {
|
316
|
+
Cabidela
|
317
|
+
};
|
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.18",
|
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": ";AA0CO,IAAM,iBAAiB,CAAC,MAA8B,QAA+B;AAC1F,MAAI,iBAAiB,KAAK,OAAO,SAAU,MAAM,MAAM;AACrD,WAAO,OAAO,KAAK,IAAI,IAAI;AAAA,EAC7B,GAAG,GAAG;AAEN,SAAO,EAAE,UAAU,YAAY,cAAc,GAAG,eAAe;AACjE;AAEO,IAAM,eAAe,CAAC,SAAiC;AAC5D,SAAO,KAAK,UAAU,IAAI,MAAM,KAAK,IAAI,CAAC,SAAU,OAAO,SAAS,WAAW,IAAI,IAAI,MAAM,IAAI,IAAI,EAAG,EAAE,KAAK,EAAE;AACnH;AAIO,IAAM,cAAc,CAAC,UAAyB;AACnD,MAAI,OAAO;AACX,MAAI,QAAQ,oBAAI,IAAI,CAAC,CAAC;AACtB,MAAI,aAAa,oBAAI,IAAI,CAAC,CAAC;AAC3B,MAAI,UAAU,MAAM;AAClB,UAAM,IAAI,MAAM;AAAA,EAClB,WAAW,OAAO,SAAS,UAAU;AACnC,UAAM,IAAI,QAAQ;AAClB,WAAO,MAAM;AAAA,EACf,WAAW,OAAO,SAAS,UAAU;AACnC,WAAO;AACP,UAAM,IAAI,QAAQ;AAClB,QAAI,OAAO,UAAU,KAAK,GAAG;AAC3B,YAAM,IAAI,SAAS;AAAA,IACrB;AAAA,EACF,WAAW,OAAO,SAAS,WAAW;AACpC,UAAM,IAAI,SAAS;AACnB,WAAO;AAAA,EACT,WAAW,MAAM,QAAQ,KAAK,GAAG;AAC/B,WAAO,MAAM;AACb,UAAM,IAAI,OAAO;AACjB,QAAI,MAAM,KAAK,CAAC,SAAS,OAAO,SAAS,YAAY,OAAO,SAAS,QAAQ,KAAK,QAAW;AAC3F,YAAM,IAAI,QAAQ;AAAA,IACpB;AAAA,EACF,WAAW,OAAO,SAAS,UAAU;AACnC,UAAM,IAAI,QAAQ;AAClB,WAAO,OAAO,KAAK,KAAK,EAAE;AAC1B,iBAAa,IAAI,IAAI,OAAO,KAAK,KAAK,CAAC;AAAA,EACzC;AACA,SAAO,EAAE,OAAO,MAAM,WAAW;AACnC;;;ACpEO,IAAM,WAAN,MAAe;AAAA,EACb;AAAA,EACA;AAAA,EAEP,YAAY,QAAa,SAA2B;AAClD,SAAK,SAAS;AACd,SAAK,UAAU,EAAE,YAAY,MAAM,eAAe,OAAO,eAAe,OAAO,GAAI,WAAW,CAAC,EAAG;AAAA,EACpG;AAAA,EAEA,UAAU,QAAa;AACrB,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,WAAW,SAA0B;AACnC,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAM,SAAiB,QAA0B;AAC/C,UAAM,QAAQ,GAAG,OAAO,GAAG,KAAK,QAAQ,cAAc,OAAO,iBAAiB,QAAQ,OAAO,OAAO,OAAO,IAAI,KAAK,MAAM,KAAK,OAAO,MAAM,EAAE,KAAK,IAAI,CAAC,KAAK,EAAE;AAC/J,UAAM,IAAI,MAAM,KAAK,QAAQ,gBAAiB,OAAO,OAAO,gBAAgB,QAAS,KAAK;AAAA,EAC5F;AAAA,EAEA,0BACE,QACA,6BACA,4BACQ;AACR,QAAI,aAAa;AACjB,UAAM,EAAE,UAAU,eAAe,IAAI,eAAe,OAAO,MAAM,OAAO,OAAO;AAE/E,UAAM,wBAAwB,SAAS,WAAW,WAAW,0BAA0B;AAGvF,QAAI,gCAAgC,OAAO;AACzC,UAAI,sBAAsB,OAAO,GAAG;AAClC,aAAK;AAAA,UACH,yCAAyC,MAAM,KAAK,qBAAqB,EAAE,KAAK,IAAI,CAAC,SAAS,aAAa,OAAO,IAAI,CAAC;AAAA,UACvH;AAAA,YACE,GAAG;AAAA,YACH,QAAQ;AAAA,YACR,SAAS;AAAA,UACX;AAAA,QACF;AAAA,MACF;AAAA,IACF,OAAO;AACL,eAAS,YAAY,uBAAuB;AAC1C,YACE,KAAK,eAAe;AAAA,UAClB,MAAM,CAAC,QAAQ;AAAA,UACf,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,qBAAqB,oBAAI,IAAI;AAAA,UAC7B,QAAQ,oBAAI,IAAI;AAAA,QAClB,CAAC,GACD;AACA;AACA,iBAAO,oBAAoB,IAAI,QAAQ;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,YAAY,QAAmC;AAC7C,QAAI,OAAO,OAAO,eAAe,eAAe,GAAG;AACjD,UAAI,OAAO,KAAK,OAAO,OAAO,EAAE,SAAS,OAAO,OAAO,eAAe;AACpE,aAAK;AAAA,UACH,qBAAqB,aAAa,OAAO,IAAI,CAAC,QAAQ,OAAO,OAAO,aAAa,SAAS,OAAO,KAAK,OAAO,OAAO,EAAE,MAAM;AAAA,UAC5H;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,OAAO,OAAO,eAAe,eAAe,GAAG;AACjD,UAAI,OAAO,KAAK,OAAO,OAAO,EAAE,SAAS,OAAO,OAAO,eAAe;AACpE,aAAK;AAAA,UACH,qBAAqB,aAAa,OAAO,IAAI,CAAC,QAAQ,OAAO,OAAO,aAAa,SAAS,OAAO,KAAK,OAAO,OAAO,EAAE,MAAM;AAAA,UAC5H;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,2BAA2B,oBAAI,IAAI,CAAC,CAAC;AAC3C,QAAI,aAAqB;AAEzB,QAAI,OAAO,OAAO,eAAe,YAAY,GAAG;AAC9C,eAAS,YAAY,OAAO,OAAO,YAAY;AAC7C,YACE,KAAK,eAAe;AAAA,UAClB,GAAG;AAAA,UACH,MAAM,CAAC,GAAG,OAAO,MAAM,QAAQ;AAAA,UAC/B,QAAQ,OAAO,OAAO,WAAW,QAAQ;AAAA,QAC3C,CAAC,GACD;AACA,mCAAyB,IAAI,QAAQ;AACrC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,OAAO,eAAe,sBAAsB,GAAG;AACxD,oBAAc,KAAK;AAAA,QACjB;AAAA,QACA,OAAO,OAAO;AAAA,QACd;AAAA,MACF;AAAA,IACF;AAGA,QAAI,OAAO,OAAO,eAAe,uBAAuB,GAAG;AACzD,aAAO,sBAAsB,oBAAI,IAAI,CAAC,GAAG,OAAO,qBAAqB,GAAG,wBAAwB,CAAC;AACjG,oBAAc,KAAK;AAAA,QACjB;AAAA,QACA,OAAO,OAAO;AAAA,QACd,OAAO;AAAA,MACT;AAAA,IACF;AAGA,QAAI,OAAO,OAAO,eAAe,UAAU,GAAG;AAC5C,UACE,IAAI,IAAI,OAAO,OAAO,QAAQ,EAAE,WAAW,OAAO,oBAAoB,MAAM,wBAAwB,CAAC,EAAE,OAAO,GAC9G;AACA,aAAK,MAAM,2BAA2B,aAAa,OAAO,IAAI,CAAC,SAAS,OAAO,OAAO,QAAQ,KAAK,MAAM;AAAA,MAC3G;AAAA,IACF;AACA,WAAO,aAAa,OAAO;AAAA,EAC7B;AAAA,EAEA,UAAU,MAAW,QAA0B,gBAA2B;AACxE,QAAI,SAAS;AACb,aAAS,UAAU,MAAM;AACvB,UAAI;AACF,kBAAU,KAAK,eAAe;AAAA,UAC5B,GAAG;AAAA,UACH,QAAQ,EAAE,MAAM,OAAO,OAAO,MAAM,GAAG,KAAK,MAAM,EAAE;AAAA,UACpD,iBAAiB;AAAA,UACjB,cAAc;AAAA,QAChB,CAAC;AACD,YAAI,kBAAkB,eAAe,MAAM,EAAG;AAAA,MAChD,SAAS,GAAG;AACV,eAAO,OAAO,IAAI,EAAE,OAAO;AAAA,MAC7B;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,eAAe,QAA0B;AACvC,QAAI,OAAO,UAAU,QAAW;AAC9B,WAAK,MAAM,uBAAuB,aAAa,OAAO,IAAI,CAAC,KAAK,MAAM;AAAA,IACxE;AAGA,QAAI,OAAO,OAAO,eAAe,OAAO,GAAG;AACzC,UAAI,KAAK,UAAU,OAAO,OAAO,OAAO,MAAM,MAAM,GAAG;AACrD,YAAI,OAAO,KAAK,UAAU,GAAG;AAC3B,eAAK,MAAM,aAAa,aAAa,OAAO,IAAI,CAAC,aAAa,MAAM;AAAA,QACtE;AACA,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAGA,QAAI,OAAO,OAAO,eAAe,OAAO,GAAG;AACzC,UAAI,KAAK,UAAU,OAAO,OAAO,OAAO,QAAQ,CAAC,MAAc,MAAM,CAAC,MAAM,GAAG;AAC7E,YAAI,OAAO,KAAK,UAAU,GAAG;AAC3B,eAAK,MAAM,aAAa,aAAa,OAAO,IAAI,CAAC,aAAa,MAAM;AAAA,QACtE;AACA,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAGA,QAAI,OAAO,OAAO,eAAe,OAAO,GAAG;AACzC,YAAM,aAAa,OAAO,OAAO,MAAM,OAAO,CAAC,GAAQ,MAAW,OAAO,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC;AACzF,UAAI;AACF,aAAK,eAAe;AAAA,UAClB,GAAG;AAAA,UACH,QAAQ,EAAE,MAAM,OAAO,OAAO,MAAM,GAAG,WAAW;AAAA,UAClD,iBAAiB;AAAA,QACnB,CAAC;AAAA,MACH,SAAS,GAAG;AACV,YAAI,OAAO,KAAK,UAAU,GAAG;AAC3B,gBAAM;AAAA,QACR;AACA,eAAO,OAAO,IAAI,EAAE,OAAO;AAC3B,eAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,EAAE,UAAU,eAAe,IAAI,eAAe,OAAO,MAAM,OAAO,OAAO;AAG/E,QAAI,OAAO,OAAO,SAAS,WAAW,CAAC,SAAS,MAAM,IAAI,QAAQ,KAAK,CAAC,SAAS,MAAM,IAAI,QAAQ,GAAG;AACpG,UAAI,UAAU;AACd,eAAS,QAAQ,gBAAgB;AAC/B,mBAAW,KAAK,eAAe;AAAA,UAC7B,GAAG;AAAA,UACH,MAAM,CAAC,GAAG,OAAO,MAAM,IAAI;AAAA,UAC3B,QAAQ,OAAO,OAAO;AAAA,QACxB,CAAC;AAAA,MACH;AACA,aAAO;AAAA,IACT,WAAW,OAAO,OAAO,SAAS,YAAY,OAAO,OAAO,YAAY;AACtE,aAAO,KAAK,YAAY,MAAM,IAAI,IAAI;AAAA,IACxC,WAAW,mBAAmB,QAAW;AAEvC,UAAI,OAAO,OAAO,eAAe,MAAM,GAAG;AACxC,YAAI,MAAM,QAAQ,OAAO,OAAO,IAAI,GAAG;AACrC,cAAI,CAAC,OAAO,OAAO,KAAK,SAAS,cAAc,GAAG;AAChD,iBAAK;AAAA,cACH,QAAQ,cAAc,WAAW,OAAO,OAAO,KAAK,KAAK,GAAG,CAAC,QAAQ,aAAa,OAAO,IAAI,CAAC;AAAA,cAC9F;AAAA,YACF;AAAA,UACF,OAAO;AAGL,gBAAI,OAAO,OAAO,QAAQ,OAAW,QAAO;AAAA,UAC9C;AAAA,QACF,OAAO;AACL,eAAK,MAAM,+BAA+B,aAAa,OAAO,IAAI,CAAC,KAAK,MAAM;AAAA,QAChF;AAAA,MACF;AAEA,UAAI,OAAO,OAAO,eAAe,MAAM,KAAK,CAAC,SAAS,MAAM,IAAI,OAAO,OAAO,IAAI,GAAG;AACnF,aAAK;AAAA,UACH,qBAAqB,aAAa,OAAO,IAAI,CAAC,OAAO,OAAO,OAAO,IAAI,YAAY,KAAK,UAAU,MAAM,KAAK,SAAS,KAAK,CAAC,CAAC;AAAA,UAC7H;AAAA,QACF;AAAA,MACF;AAEA,UAAI,OAAO,WAAW,MAAM;AAE1B,gBAAQ,OAAO,OAAO,MAAM;AAAA,UAC1B,KAAK;AACH,gBAAI,OAAO,OAAO,eAAe,WAAW,KAAK,SAAS,OAAO,OAAO,OAAO,WAAW;AACxF,mBAAK,MAAM,cAAc,aAAa,OAAO,IAAI,CAAC,gBAAgB,OAAO,OAAO,SAAS,IAAI,MAAM;AAAA,YACrG;AACA,gBAAI,OAAO,OAAO,eAAe,WAAW,KAAK,SAAS,OAAO,OAAO,OAAO,WAAW;AACxF,mBAAK;AAAA,gBACH,cAAc,aAAa,OAAO,IAAI,CAAC,gBAAgB,OAAO,OAAO,SAAS;AAAA,gBAC9E;AAAA,cACF;AAAA,YACF;AACA;AAAA,UACF,KAAK;AAAA,UACL,KAAK;AACH,gBAAI,OAAO,OAAO,eAAe,SAAS,KAAK,iBAAiB,OAAO,OAAO,SAAS;AACrF,mBAAK,MAAM,IAAI,aAAa,OAAO,IAAI,CAAC,gBAAgB,OAAO,OAAO,OAAO,IAAI,MAAM;AAAA,YACzF;AACA,gBAAI,OAAO,OAAO,eAAe,kBAAkB,KAAK,kBAAkB,OAAO,OAAO,kBAAkB;AACxG,mBAAK,MAAM,IAAI,aAAa,OAAO,IAAI,CAAC,eAAe,OAAO,OAAO,gBAAgB,IAAI,MAAM;AAAA,YACjG;AACA,gBAAI,OAAO,OAAO,eAAe,SAAS,KAAK,iBAAiB,OAAO,OAAO,SAAS;AACrF,mBAAK,MAAM,IAAI,aAAa,OAAO,IAAI,CAAC,gBAAgB,OAAO,OAAO,OAAO,IAAI,MAAM;AAAA,YACzF;AACA,gBAAI,OAAO,OAAO,eAAe,kBAAkB,KAAK,kBAAkB,OAAO,OAAO,kBAAkB;AACxG,mBAAK,MAAM,IAAI,aAAa,OAAO,IAAI,CAAC,eAAe,OAAO,OAAO,gBAAgB,IAAI,MAAM;AAAA,YACjG;AACA,gBAAI,OAAO,OAAO,eAAe,YAAY,KAAK,iBAAiB,OAAO,OAAO,eAAe,GAAG;AACjG,mBAAK,MAAM,IAAI,aAAa,OAAO,IAAI,CAAC,yBAAyB,OAAO,OAAO,UAAU,IAAI,MAAM;AAAA,YACrG;AACA;AAAA,QACJ;AAAA,MACF;AACA,UAAI,OAAO,iBAAiB;AAC1B,eAAO,oBAAoB,IAAI,OAAO,KAAK,OAAO,KAAK,SAAS,CAAC,CAAC;AAAA,MACpE;AACA,aAAO;AAAA,IACT;AAEA,QAAI,KAAK,QAAQ,kBAAkB,QAAQ,OAAO,OAAO,eAAe,SAAS,GAAG;AAClF,aAAO,KAAK,OAAO,SAAU,MAAM,MAAM,OAAO;AAE9C,YAAI,KAAK,IAAI,MAAM,QAAW;AAC5B,eAAK,IAAI,IAAI,CAAC;AAAA,QAChB;AACA,YAAI,SAAS,OAAO,KAAK,SAAS,GAAG;AACnC,eAAK,IAAI,IAAI,OAAO,OAAO;AAE3B,iBAAO,oBAAoB,IAAI,OAAO,KAAK,OAAO,KAAK,SAAS,CAAC,CAAC;AAAA,QACpE;AACA,eAAO,OAAO,KAAK,IAAI,IAAI;AAAA,MAC7B,GAAG,OAAO,OAAO;AAAA,IACnB;AACA,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,SAAc;AACrB,UAAM,SAA2B;AAAA,MAC/B,QAAQ,oBAAI,IAAI;AAAA,MAChB,qBAAqB,oBAAI,IAAI;AAAA,MAC7B,MAAM,CAAC;AAAA,MACP,QAAQ,KAAK;AAAA,MACb;AAAA,IACF;AACA,SAAK,eAAe,MAAM;AAC1B,WAAO;AAAA,EACT;AACF;",
|
6
|
-
"names": []
|
7
|
-
}
|