@cloudflare/cabidela 0.0.15

Sign up to get free protection for your applications and to get access to all the features.
package/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2023 Cloudflare, Inc.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
package/README.md ADDED
@@ -0,0 +1,241 @@
1
+ # Cabidela
2
+
3
+ Cabidela is a small, fast, eval-less, [Cloudflare Workers](https://developers.cloudflare.com/workers/) compatible, dynamic JSON Schema validator.
4
+
5
+ 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
+
7
+ ## How to use
8
+
9
+ Install the package:
10
+
11
+ ```bash
12
+ npm install @cloudflare/cabidela --save
13
+ ```
14
+
15
+ Import it:
16
+
17
+ ```ts
18
+ import { Cabidela } from "@cloudflare/cabidela";
19
+ ```
20
+
21
+ Use it:
22
+
23
+ ```ts
24
+ let schema: any = {
25
+ type: "object",
26
+ properties: {
27
+ prompt: {
28
+ type: "string",
29
+ minLength: 1,
30
+ maxLength: 131072,
31
+ description: "The input text prompt for the model to generate a response.",
32
+ },
33
+ num_steps: {
34
+ type: "number",
35
+ minimum: 0,
36
+ maximum: 20,
37
+ description: "Increases the likelihood of the model introducing new topics.",
38
+ },
39
+ },
40
+ required: ["prompt"],
41
+ };
42
+
43
+ const cabidela = new Cabidela(schema);
44
+
45
+ cabidela.validate({
46
+ prompt: "Tell me a joke",
47
+ num_steps: 5,
48
+ });
49
+ ```
50
+
51
+ Cabidela implements a [Exception-Driven Validation](https://json-schema.org/implementers/interfaces#exception-driven-validation) approach. If any condition in the schema is not met, we throw an error.
52
+
53
+ ## API
54
+
55
+ ### New instance
56
+
57
+ `const cabidela = new Cabidela(schema: any, options?: CabidelaOptions)`
58
+
59
+ Cabidela takes a JSON-Schema and optional configuration flags:
60
+
61
+ - `applyDefaults`: boolean - If true, the validator will apply default values to the input object. Default is false.
62
+ - `errorMessages`: boolean - If true, the validator will use custom `errorMessage` messages from the schema. Default is false.
63
+ - `fullErrors`: boolean - If true, the validator will be more verbose when throwing errors for complex schemas (example: anyOf, oneOf's), set to false for shorter exceptions. Default is true.
64
+
65
+ Returns a validation object.
66
+
67
+ You can change the schema at any time by calling `cabidela.setSchema(schema: any)`.
68
+
69
+ You can change the options at any time by calling `cabidela.setOptions(options: CabidelaOptions)`.
70
+
71
+ ### Validate payload
72
+
73
+ Call `cabidela.validate(payload: any)` to validate your payload.
74
+
75
+ Returns truth if the payload is valid, throws an error otherwise.
76
+
77
+ ```js
78
+ const payload = {
79
+ messages: [
80
+ { role: "system", content: "You're a helpful assistant" },
81
+ { role: "user", content: "What is Cloudflare?" },
82
+ ],
83
+ };
84
+
85
+ try {
86
+ cabidela.validate(payload);
87
+ console.log("Payload is valid");
88
+ } catch (e) {
89
+ console.error(e);
90
+ }
91
+ ```
92
+
93
+ ## Modifying the payload
94
+
95
+ Some options, like `applyDefaults`, will modify the input object.
96
+
97
+ ```js
98
+ const schema = {
99
+ type: "object",
100
+ properties: {
101
+ prompt: {
102
+ type: "string",
103
+ },
104
+ num_steps: {
105
+ type: "number",
106
+ default: 10,
107
+ },
108
+ },
109
+ };
110
+
111
+ const cabidela = new Cabidela(schema, { applyDefaults: true });
112
+
113
+ const payload = {
114
+ prompt: "Tell me a joke",
115
+ });
116
+
117
+ cabidela.validate(payload);
118
+
119
+ console.log(payload);
120
+
121
+ // {
122
+ // prompt: 'Tell me a joke',
123
+ // num_steps: 10
124
+ // }
125
+
126
+ ```
127
+
128
+ ## Custom errors
129
+
130
+ If the new instance options has the `errorMessages` flag set to true, you can use the property `errorMessage` in the schema to define custom error messages.
131
+
132
+ ```js
133
+ const schema = {
134
+ type: "object",
135
+ properties: {
136
+ prompt: {
137
+ type: "string",
138
+ },
139
+ },
140
+ required: ["prompt"],
141
+ errorMessage: "prompt required",
142
+ };
143
+
144
+ const cabidela = new Cabidela(schema, { errorMessages: true });
145
+
146
+ const payload = {
147
+ missing: "prompt",
148
+ });
149
+
150
+ cabidela.validate(payload);
151
+ // throws "Error: prompt required"
152
+ ```
153
+
154
+ ## Tests
155
+
156
+ The tests can be found [here](./tests/).
157
+
158
+ Cabidela uses [vitest](https://vitest.dev/) to test internal methods and compliance with the [JSON Schema specification](https://json-schema.org/). To run the tests type:
159
+
160
+ ```bash
161
+ npm run test
162
+ ```
163
+
164
+ You can also run the tests with [Ajv](https://ajv.js.org/), or both. This allows us to compare the results and double-check how we interpret the specification.
165
+
166
+ ```bash
167
+ npm run test-ajv
168
+ npm run test-all
169
+ ```
170
+
171
+ ## Performance
172
+
173
+ JSON Schema validators like Ajv tend to follow this pattern:
174
+
175
+ 1. Instantiate a validator.
176
+ 2. Compile the schema.
177
+ 3. Validate one or more payloads against the (compiled) schema.
178
+
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 applications we typically want to validate with the HTTP request, one payload at a time, and then we discard the validator.
180
+
181
+ Cabidela skips the compilation step and validates the payload directly against the schema.
182
+
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 on par or better than Ajv.
184
+
185
+ Here are some results:
186
+
187
+ ```bash
188
+ Cabidela - benchmarks/00-basic.bench.js > allOf, two properties
189
+ 1929.61x faster than Ajv
190
+
191
+ Cabidela - benchmarks/00-basic.bench.js > allOf, two objects
192
+ 1351.41x faster than Ajv
193
+
194
+ Cabidela - benchmarks/00-basic.bench.js > anyOf, two conditions
195
+ 227.48x faster than Ajv
196
+
197
+ Cabidela - benchmarks/00-basic.bench.js > oneOf, two conditions
198
+ 224.49x faster than Ajv
199
+
200
+ Cabidela - benchmarks/80-big-ops.bench.js > Big array payload
201
+ 386.44x faster than Ajv
202
+
203
+ Cabidela - benchmarks/80-big-ops.bench.js > Big object payload
204
+ 6.08x faster than Ajv
205
+
206
+ Cabidela - benchmarks/80-big-ops.bench.js > Deep schema, deep payload
207
+ 59.75x faster than Ajv
208
+
209
+ Cabidela - benchmarks/80-big-ops.bench.js > allOf, two properties
210
+ 1701.95x faster than Ajv
211
+
212
+ Cabidela - benchmarks/80-big-ops.bench.js > allOf, two objects
213
+ 1307.04x faster than Ajv
214
+
215
+ Cabidela - benchmarks/80-big-ops.bench.js > anyOf, two conditions
216
+ 207.73x faster than Ajv
217
+
218
+ Cabidela - benchmarks/80-big-ops.bench.js > oneOf, two conditions
219
+ 211.72x faster than Ajv
220
+ ```
221
+
222
+ We use Vitest's [bench](https://vitest.dev/api/#bench) feature to run the benchmarks. You can find the benchmarks in the [benchmarks](./benchmarks/) folder and you can run them with:
223
+
224
+ ```bash
225
+ npm run benchmark
226
+ ```
227
+
228
+
229
+ ## Current limitations
230
+
231
+ Cabidela supports most of JSON Schema specification for most use-cases, we think. However it's not complete. **Currently** we do not support:
232
+
233
+ - Multiple (array of) types `{ "type": ["number", "string"] }`
234
+ - Regular expressions
235
+ - Pattern properties
236
+ - `not`
237
+ - `dependentRequired`, `dependentSchemas`, `If-Then-Else`
238
+ - `$ref`, `$defs` and `$id`
239
+
240
+ yet.
241
+
@@ -0,0 +1,13 @@
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;
@@ -0,0 +1,27 @@
1
+ export type CabidelaOptions = {
2
+ applyDefaults?: boolean;
3
+ errorMessages?: boolean;
4
+ fullErrors?: boolean;
5
+ };
6
+ export 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
+ export 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
+ }
package/dist/index.js ADDED
@@ -0,0 +1,303 @@
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 = { fullErrors: true, applyDefaults: false, errorMessages: false, ...options || {} };
50
+ }
51
+ setSchema(schema) {
52
+ this.schema = schema;
53
+ }
54
+ setOptions(options) {
55
+ this.options = options;
56
+ }
57
+ throw(message, needle) {
58
+ const error = `${message}${this.options.fullErrors && needle.absorvErrors !== true && needle.errors.size > 0 ? `: ${Array.from(needle.errors).join(", ")}` : ``}`;
59
+ throw new Error(this.options.errorMessages ? needle.schema.errorMessage ?? error : error);
60
+ }
61
+ parseAdditionalProperties(needle, contextAdditionalProperties, contextEvaluatedProperties) {
62
+ let matchCount = 0;
63
+ const { metadata, resolvedObject } = resolvePayload(needle.path, needle.payload);
64
+ const unevaluatedProperties = metadata.properties.difference(contextEvaluatedProperties);
65
+ if (contextAdditionalProperties === false) {
66
+ if (unevaluatedProperties.size > 0) {
67
+ this.throw(
68
+ `Additional or unevaluated properties '${Array.from(unevaluatedProperties).join(", ")}' at '${pathToString(needle.path)}' not allowed`,
69
+ {
70
+ ...needle,
71
+ schema: contextAdditionalProperties,
72
+ payload: resolvedObject
73
+ }
74
+ );
75
+ }
76
+ } else {
77
+ for (let property of unevaluatedProperties) {
78
+ if (this.parseSubSchema({
79
+ path: [property],
80
+ schema: contextAdditionalProperties,
81
+ payload: resolvedObject,
82
+ evaluatedProperties: /* @__PURE__ */ new Set(),
83
+ errors: /* @__PURE__ */ new Set()
84
+ })) {
85
+ matchCount++;
86
+ needle.evaluatedProperties.add(property);
87
+ }
88
+ }
89
+ }
90
+ return matchCount;
91
+ }
92
+ // Iterates through the properties of an "object" schema
93
+ parseObject(needle) {
94
+ if (needle.schema.hasOwnProperty("minProperties")) {
95
+ if (Object.keys(needle.payload).length < needle.schema.minProperties) {
96
+ this.throw(
97
+ `minProperties at '${pathToString(needle.path)}' is ${needle.schema.minProperties}, got ${Object.keys(needle.payload).length}`,
98
+ needle
99
+ );
100
+ }
101
+ }
102
+ if (needle.schema.hasOwnProperty("maxProperties")) {
103
+ if (Object.keys(needle.payload).length > needle.schema.maxProperties) {
104
+ this.throw(
105
+ `maxProperties at '${pathToString(needle.path)}' is ${needle.schema.minProperties}, got ${Object.keys(needle.payload).length}`,
106
+ needle
107
+ );
108
+ }
109
+ }
110
+ const localEvaluatedProperties = /* @__PURE__ */ new Set([]);
111
+ let matchCount = 0;
112
+ if (needle.schema.hasOwnProperty("properties")) {
113
+ for (let property in needle.schema.properties) {
114
+ if (this.parseSubSchema({
115
+ ...needle,
116
+ path: [...needle.path, property],
117
+ schema: needle.schema.properties[property]
118
+ })) {
119
+ localEvaluatedProperties.add(property);
120
+ matchCount++;
121
+ }
122
+ }
123
+ }
124
+ if (needle.schema.hasOwnProperty("additionalProperties")) {
125
+ matchCount += this.parseAdditionalProperties(
126
+ needle,
127
+ needle.schema.additionalProperties,
128
+ localEvaluatedProperties
129
+ );
130
+ }
131
+ if (needle.schema.hasOwnProperty("unevaluatedProperties")) {
132
+ needle.evaluatedProperties = /* @__PURE__ */ new Set([...needle.evaluatedProperties, ...localEvaluatedProperties]);
133
+ matchCount += this.parseAdditionalProperties(
134
+ needle,
135
+ needle.schema.unevaluatedProperties,
136
+ needle.evaluatedProperties
137
+ );
138
+ }
139
+ if (needle.schema.hasOwnProperty("required")) {
140
+ if (new Set(needle.schema.required).difference(needle.evaluatedProperties.union(localEvaluatedProperties)).size > 0) {
141
+ this.throw(`required properties at '${pathToString(needle.path)}' is '${needle.schema.required}'`, needle);
142
+ }
143
+ }
144
+ return matchCount ? true : false;
145
+ }
146
+ parseList(list, needle, breakCondition) {
147
+ let rounds = 0;
148
+ for (let option in list) {
149
+ try {
150
+ rounds += this.parseSubSchema({
151
+ ...needle,
152
+ schema: { type: needle.schema.type, ...list[option] },
153
+ carryProperties: true,
154
+ absorvErrors: true
155
+ });
156
+ if (breakCondition && breakCondition(rounds)) break;
157
+ } catch (e) {
158
+ needle.errors.add(e.message);
159
+ }
160
+ }
161
+ return rounds;
162
+ }
163
+ // Parses a JSON Schema sub-schema object - reentrant
164
+ parseSubSchema(needle) {
165
+ if (needle.schema == void 0) {
166
+ this.throw(`No schema for path '${pathToString(needle.path)}'`, needle);
167
+ }
168
+ if (needle.schema.hasOwnProperty("oneOf")) {
169
+ if (this.parseList(needle.schema.oneOf, needle) !== 1) {
170
+ if (needle.path.length == 0) {
171
+ this.throw(`oneOf at '${pathToString(needle.path)}' not met`, needle);
172
+ }
173
+ return 0;
174
+ }
175
+ return 1;
176
+ }
177
+ if (needle.schema.hasOwnProperty("anyOf")) {
178
+ if (this.parseList(needle.schema.anyOf, needle, (r) => r !== 0) === 0) {
179
+ if (needle.path.length == 0) {
180
+ this.throw(`anyOf at '${pathToString(needle.path)}' not met`, needle);
181
+ }
182
+ return 0;
183
+ }
184
+ return 1;
185
+ }
186
+ if (needle.schema.hasOwnProperty("allOf")) {
187
+ const conditions = needle.schema.allOf.reduce((r, c) => Object.assign(r, c), {});
188
+ try {
189
+ this.parseSubSchema({
190
+ ...needle,
191
+ schema: { type: needle.schema.type, ...conditions },
192
+ carryProperties: true
193
+ });
194
+ } catch (e) {
195
+ if (needle.path.length == 0) {
196
+ throw e;
197
+ }
198
+ needle.errors.add(e.message);
199
+ return 0;
200
+ }
201
+ }
202
+ const { metadata, resolvedObject } = resolvePayload(needle.path, needle.payload);
203
+ if (needle.schema.type === "array" && !metadata.types.has("binary") && !metadata.types.has("string")) {
204
+ let matched = 0;
205
+ for (let item in resolvedObject) {
206
+ matched += this.parseSubSchema({
207
+ ...needle,
208
+ path: [...needle.path, item],
209
+ schema: needle.schema.items
210
+ });
211
+ }
212
+ return matched;
213
+ } else if (needle.schema.type === "object" || needle.schema.properties) {
214
+ return this.parseObject(needle) ? 1 : 0;
215
+ } else if (resolvedObject !== void 0) {
216
+ if (needle.schema.hasOwnProperty("enum")) {
217
+ if (Array.isArray(needle.schema.enum)) {
218
+ if (!needle.schema.enum.includes(resolvedObject)) {
219
+ this.throw(
220
+ `enum ${resolvedObject} not in ${needle.schema.enum.join(",")} at '${pathToString(needle.path)}'`,
221
+ needle
222
+ );
223
+ } else {
224
+ if (needle.schema.type == void 0) return 1;
225
+ }
226
+ } else {
227
+ this.throw(`enum should be an array at '${pathToString(needle.path)}'`, needle);
228
+ }
229
+ }
230
+ if (needle.schema.hasOwnProperty("type") && !metadata.types.has(needle.schema.type)) {
231
+ this.throw(
232
+ `Type mismatch of '${pathToString(needle.path)}', '${needle.schema.type}' not in ${JSON.stringify(Array.from(metadata.types))}`,
233
+ needle
234
+ );
235
+ }
236
+ if (needle.schema !== true) {
237
+ switch (needle.schema.type) {
238
+ case "string":
239
+ if (needle.schema.hasOwnProperty("maxLength") && metadata.size > needle.schema.maxLength) {
240
+ this.throw(`Length of '${pathToString(needle.path)}' must be <= ${needle.schema.maxLength}`, needle);
241
+ }
242
+ if (needle.schema.hasOwnProperty("minLength") && metadata.size < needle.schema.minLength) {
243
+ this.throw(
244
+ `Length of '${pathToString(needle.path)}' must be >= ${needle.schema.minLength} not met`,
245
+ needle
246
+ );
247
+ }
248
+ break;
249
+ case "number":
250
+ case "integer":
251
+ if (needle.schema.hasOwnProperty("minimum") && resolvedObject < needle.schema.minimum) {
252
+ this.throw(`'${pathToString(needle.path)}' must be >= ${needle.schema.minimum}`, needle);
253
+ }
254
+ if (needle.schema.hasOwnProperty("exclusiveMinimum") && resolvedObject <= needle.schema.exclusiveMinimum) {
255
+ this.throw(`'${pathToString(needle.path)}' must be > ${needle.schema.exclusiveMinimum}`, needle);
256
+ }
257
+ if (needle.schema.hasOwnProperty("maximum") && resolvedObject > needle.schema.maximum) {
258
+ this.throw(`'${pathToString(needle.path)}' must be <= ${needle.schema.maximum}`, needle);
259
+ }
260
+ if (needle.schema.hasOwnProperty("exclusiveMaximum") && resolvedObject >= needle.schema.exclusiveMaximum) {
261
+ this.throw(`'${pathToString(needle.path)}' must be < ${needle.schema.exclusiveMaximum}`, needle);
262
+ }
263
+ if (needle.schema.hasOwnProperty("multipleOf") && resolvedObject % needle.schema.multipleOf !== 0) {
264
+ this.throw(`'${pathToString(needle.path)}' must be multiple of ${needle.schema.multipleOf}`, needle);
265
+ }
266
+ break;
267
+ }
268
+ }
269
+ if (needle.carryProperties) {
270
+ needle.evaluatedProperties.add(needle.path[needle.path.length - 1]);
271
+ }
272
+ return 1;
273
+ }
274
+ if (this.options.applyDefaults === true && needle.schema.hasOwnProperty("default")) {
275
+ needle.path.reduce(function(prev, curr, index) {
276
+ if (prev[curr] === void 0) {
277
+ prev[curr] = {};
278
+ }
279
+ if (index == needle.path.length - 1) {
280
+ prev[curr] = needle.schema.default;
281
+ needle.evaluatedProperties.add(needle.path[needle.path.length - 1]);
282
+ }
283
+ return prev ? prev[curr] : void 0;
284
+ }, needle.payload);
285
+ }
286
+ return 0;
287
+ }
288
+ validate(payload) {
289
+ const needle = {
290
+ errors: /* @__PURE__ */ new Set(),
291
+ evaluatedProperties: /* @__PURE__ */ new Set(),
292
+ path: [],
293
+ schema: this.schema,
294
+ payload
295
+ };
296
+ this.parseSubSchema(needle);
297
+ return true;
298
+ }
299
+ };
300
+ export {
301
+ Cabidela
302
+ };
303
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
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
+ }
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@cloudflare/cabidela",
3
+ "version": "0.0.15",
4
+ "type": "module",
5
+ "description": "Cabidela is a small, fast, eval-less, Cloudflare Workers compatible, dynamic JSON Schema validator",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "author": "Celso Martinho <celso@cloudflare.com>",
9
+ "license": "Apache 2.0",
10
+ "scripts": {
11
+ "test": "npm run test-cabidela",
12
+ "test-all": "npm run test-cabidela && npm run test-ajv",
13
+ "test-cabidela": "vitest run --dir tests --reporter=verbose",
14
+ "test-ajv": "AJV=true vitest run --dir tests --reporter=verbose",
15
+ "benchmark": "vitest bench --dir benchmarks --reporter=verbose --watch false",
16
+ "build": "npm run build-tsc && npm run build-esbuild",
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",
19
+ "dry-publish": "npm pack --dry-run"
20
+ },
21
+ "keywords": [
22
+ "json-schema"
23
+ ],
24
+ "files": [
25
+ "dist/*"
26
+ ],
27
+ "devDependencies": {
28
+ "@vitest/ui": "^3.0.3",
29
+ "ajv": "^8.17.1",
30
+ "ajv-errors": "^3.0.0",
31
+ "esbuild": "^0.24.2",
32
+ "typescript": "^5.7.3",
33
+ "vitest": "^3.0.3"
34
+ }
35
+ }