@cloudflare/cabidela 0.0.17 → 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 CHANGED
@@ -6,14 +6,14 @@
6
6
 
7
7
 
8
8
  <p align="center">
9
- <em>Small, fast, eval-less, [Cloudflare Workers](https://developers.cloudflare.com/workers/) compatible, dynamic JSON Schema validator.</em>
9
+ <em>Small, fast, eval-less, <a href="https://developers.cloudflare.com/workers/">Cloudflare Workers</a> compatible, dynamic JSON Schema validator.</em>
10
10
  </p>
11
11
 
12
12
  <hr />
13
13
 
14
- # What is
14
+ ## What is
15
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.
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.
17
17
 
18
18
  ## How to use
19
19
 
@@ -187,11 +187,11 @@ JSON Schema validators like Ajv tend to follow this pattern:
187
187
  2. Compile the schema.
188
188
  3. Validate one or more payloads against the (compiled) schema.
189
189
 
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 applications we typically want to validate with the HTTP request, one payload at a time, and then we discard the validator.
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.
191
191
 
192
192
  Cabidela skips the compilation step and validates the payload directly against the schema.
193
193
 
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 on par or better than Ajv.
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.
195
195
 
196
196
  Here are some results:
197
197
 
@@ -239,7 +239,7 @@ npm run benchmark
239
239
 
240
240
  ## Current limitations
241
241
 
242
- Cabidela supports most of JSON Schema specification for most use-cases, we think. However it's not complete. **Currently** we do not support:
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:
243
243
 
244
244
  - Multiple (array of) types `{ "type": ["number", "string"] }`
245
245
  - Regular expressions
package/dist/index.js CHANGED
@@ -87,19 +87,12 @@ var Cabidela = class {
87
87
  }
88
88
  throw(message, needle) {
89
89
  const error = `${message}${this.options.fullErrors && needle.absorvErrors !== true && needle.errors.size > 0 ? `: ${Array.from(needle.errors).join(", ")}` : ``}`;
90
- throw new Error(
91
- this.options.errorMessages ? needle.schema.errorMessage ?? error : error
92
- );
90
+ throw new Error(this.options.errorMessages ? needle.schema.errorMessage ?? error : error);
93
91
  }
94
92
  parseAdditionalProperties(needle, contextAdditionalProperties, contextEvaluatedProperties) {
95
93
  let matchCount = 0;
96
- const { metadata, resolvedObject } = resolvePayload(
97
- needle.path,
98
- needle.payload
99
- );
100
- const unevaluatedProperties = metadata.properties.difference(
101
- contextEvaluatedProperties
102
- );
94
+ const { metadata, resolvedObject } = resolvePayload(needle.path, needle.payload);
95
+ const unevaluatedProperties = metadata.properties.difference(contextEvaluatedProperties);
103
96
  if (contextAdditionalProperties === false) {
104
97
  if (unevaluatedProperties.size > 0) {
105
98
  this.throw(
@@ -167,10 +160,7 @@ var Cabidela = class {
167
160
  );
168
161
  }
169
162
  if (needle.schema.hasOwnProperty("unevaluatedProperties")) {
170
- needle.evaluatedProperties = /* @__PURE__ */ new Set([
171
- ...needle.evaluatedProperties,
172
- ...localEvaluatedProperties
173
- ]);
163
+ needle.evaluatedProperties = /* @__PURE__ */ new Set([...needle.evaluatedProperties, ...localEvaluatedProperties]);
174
164
  matchCount += this.parseAdditionalProperties(
175
165
  needle,
176
166
  needle.schema.unevaluatedProperties,
@@ -178,13 +168,8 @@ var Cabidela = class {
178
168
  );
179
169
  }
180
170
  if (needle.schema.hasOwnProperty("required")) {
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
- );
171
+ if (new Set(needle.schema.required).difference(needle.evaluatedProperties.union(localEvaluatedProperties)).size > 0) {
172
+ this.throw(`required properties at '${pathToString(needle.path)}' is '${needle.schema.required}'`, needle);
188
173
  }
189
174
  }
190
175
  return matchCount ? true : false;
@@ -230,10 +215,7 @@ var Cabidela = class {
230
215
  return 1;
231
216
  }
232
217
  if (needle.schema.hasOwnProperty("allOf")) {
233
- const conditions = needle.schema.allOf.reduce(
234
- (r, c) => Object.assign(r, c),
235
- {}
236
- );
218
+ const conditions = needle.schema.allOf.reduce((r, c) => Object.assign(r, c), {});
237
219
  try {
238
220
  this.parseSubSchema({
239
221
  ...needle,
@@ -248,10 +230,7 @@ var Cabidela = class {
248
230
  return 0;
249
231
  }
250
232
  }
251
- const { metadata, resolvedObject } = resolvePayload(
252
- needle.path,
253
- needle.payload
254
- );
233
+ const { metadata, resolvedObject } = resolvePayload(needle.path, needle.payload);
255
234
  if (needle.schema.type === "array" && !metadata.types.has("binary") && !metadata.types.has("string")) {
256
235
  let matched = 0;
257
236
  for (let item in resolvedObject) {
@@ -265,6 +244,16 @@ var Cabidela = class {
265
244
  } else if (needle.schema.type === "object" || needle.schema.properties) {
266
245
  return this.parseObject(needle) ? 1 : 0;
267
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
+ }
268
257
  if (needle.schema.hasOwnProperty("enum")) {
269
258
  if (Array.isArray(needle.schema.enum)) {
270
259
  if (!needle.schema.enum.includes(resolvedObject)) {
@@ -276,10 +265,7 @@ var Cabidela = class {
276
265
  if (needle.schema.type == void 0) return 1;
277
266
  }
278
267
  } else {
279
- this.throw(
280
- `enum should be an array at '${pathToString(needle.path)}'`,
281
- needle
282
- );
268
+ this.throw(`enum should be an array at '${pathToString(needle.path)}'`, needle);
283
269
  }
284
270
  }
285
271
  if (needle.schema.hasOwnProperty("type") && !metadata.types.has(needle.schema.type)) {
@@ -292,10 +278,7 @@ var Cabidela = class {
292
278
  switch (needle.schema.type) {
293
279
  case "string":
294
280
  if (needle.schema.hasOwnProperty("maxLength") && metadata.size > needle.schema.maxLength) {
295
- this.throw(
296
- `Length of '${pathToString(needle.path)}' must be <= ${needle.schema.maxLength}`,
297
- needle
298
- );
281
+ this.throw(`Length of '${pathToString(needle.path)}' must be <= ${needle.schema.maxLength}`, needle);
299
282
  }
300
283
  if (needle.schema.hasOwnProperty("minLength") && metadata.size < needle.schema.minLength) {
301
284
  this.throw(
@@ -307,34 +290,19 @@ var Cabidela = class {
307
290
  case "number":
308
291
  case "integer":
309
292
  if (needle.schema.hasOwnProperty("minimum") && resolvedObject < needle.schema.minimum) {
310
- this.throw(
311
- `'${pathToString(needle.path)}' must be >= ${needle.schema.minimum}`,
312
- needle
313
- );
293
+ this.throw(`'${pathToString(needle.path)}' must be >= ${needle.schema.minimum}`, needle);
314
294
  }
315
295
  if (needle.schema.hasOwnProperty("exclusiveMinimum") && resolvedObject <= needle.schema.exclusiveMinimum) {
316
- this.throw(
317
- `'${pathToString(needle.path)}' must be > ${needle.schema.exclusiveMinimum}`,
318
- needle
319
- );
296
+ this.throw(`'${pathToString(needle.path)}' must be > ${needle.schema.exclusiveMinimum}`, needle);
320
297
  }
321
298
  if (needle.schema.hasOwnProperty("maximum") && resolvedObject > needle.schema.maximum) {
322
- this.throw(
323
- `'${pathToString(needle.path)}' must be <= ${needle.schema.maximum}`,
324
- needle
325
- );
299
+ this.throw(`'${pathToString(needle.path)}' must be <= ${needle.schema.maximum}`, needle);
326
300
  }
327
301
  if (needle.schema.hasOwnProperty("exclusiveMaximum") && resolvedObject >= needle.schema.exclusiveMaximum) {
328
- this.throw(
329
- `'${pathToString(needle.path)}' must be < ${needle.schema.exclusiveMaximum}`,
330
- needle
331
- );
302
+ this.throw(`'${pathToString(needle.path)}' must be < ${needle.schema.exclusiveMaximum}`, needle);
332
303
  }
333
304
  if (needle.schema.hasOwnProperty("multipleOf") && resolvedObject % needle.schema.multipleOf !== 0) {
334
- this.throw(
335
- `'${pathToString(needle.path)}' must be multiple of ${needle.schema.multipleOf}`,
336
- needle
337
- );
305
+ this.throw(`'${pathToString(needle.path)}' must be multiple of ${needle.schema.multipleOf}`, needle);
338
306
  }
339
307
  break;
340
308
  }
package/dist/index.mjs CHANGED
@@ -61,19 +61,12 @@ var Cabidela = class {
61
61
  }
62
62
  throw(message, needle) {
63
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
- );
64
+ throw new Error(this.options.errorMessages ? needle.schema.errorMessage ?? error : error);
67
65
  }
68
66
  parseAdditionalProperties(needle, contextAdditionalProperties, contextEvaluatedProperties) {
69
67
  let matchCount = 0;
70
- const { metadata, resolvedObject } = resolvePayload(
71
- needle.path,
72
- needle.payload
73
- );
74
- const unevaluatedProperties = metadata.properties.difference(
75
- contextEvaluatedProperties
76
- );
68
+ const { metadata, resolvedObject } = resolvePayload(needle.path, needle.payload);
69
+ const unevaluatedProperties = metadata.properties.difference(contextEvaluatedProperties);
77
70
  if (contextAdditionalProperties === false) {
78
71
  if (unevaluatedProperties.size > 0) {
79
72
  this.throw(
@@ -141,10 +134,7 @@ var Cabidela = class {
141
134
  );
142
135
  }
143
136
  if (needle.schema.hasOwnProperty("unevaluatedProperties")) {
144
- needle.evaluatedProperties = /* @__PURE__ */ new Set([
145
- ...needle.evaluatedProperties,
146
- ...localEvaluatedProperties
147
- ]);
137
+ needle.evaluatedProperties = /* @__PURE__ */ new Set([...needle.evaluatedProperties, ...localEvaluatedProperties]);
148
138
  matchCount += this.parseAdditionalProperties(
149
139
  needle,
150
140
  needle.schema.unevaluatedProperties,
@@ -152,13 +142,8 @@ var Cabidela = class {
152
142
  );
153
143
  }
154
144
  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
- );
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);
162
147
  }
163
148
  }
164
149
  return matchCount ? true : false;
@@ -204,10 +189,7 @@ var Cabidela = class {
204
189
  return 1;
205
190
  }
206
191
  if (needle.schema.hasOwnProperty("allOf")) {
207
- const conditions = needle.schema.allOf.reduce(
208
- (r, c) => Object.assign(r, c),
209
- {}
210
- );
192
+ const conditions = needle.schema.allOf.reduce((r, c) => Object.assign(r, c), {});
211
193
  try {
212
194
  this.parseSubSchema({
213
195
  ...needle,
@@ -222,10 +204,7 @@ var Cabidela = class {
222
204
  return 0;
223
205
  }
224
206
  }
225
- const { metadata, resolvedObject } = resolvePayload(
226
- needle.path,
227
- needle.payload
228
- );
207
+ const { metadata, resolvedObject } = resolvePayload(needle.path, needle.payload);
229
208
  if (needle.schema.type === "array" && !metadata.types.has("binary") && !metadata.types.has("string")) {
230
209
  let matched = 0;
231
210
  for (let item in resolvedObject) {
@@ -239,6 +218,16 @@ var Cabidela = class {
239
218
  } else if (needle.schema.type === "object" || needle.schema.properties) {
240
219
  return this.parseObject(needle) ? 1 : 0;
241
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
+ }
242
231
  if (needle.schema.hasOwnProperty("enum")) {
243
232
  if (Array.isArray(needle.schema.enum)) {
244
233
  if (!needle.schema.enum.includes(resolvedObject)) {
@@ -250,10 +239,7 @@ var Cabidela = class {
250
239
  if (needle.schema.type == void 0) return 1;
251
240
  }
252
241
  } else {
253
- this.throw(
254
- `enum should be an array at '${pathToString(needle.path)}'`,
255
- needle
256
- );
242
+ this.throw(`enum should be an array at '${pathToString(needle.path)}'`, needle);
257
243
  }
258
244
  }
259
245
  if (needle.schema.hasOwnProperty("type") && !metadata.types.has(needle.schema.type)) {
@@ -266,10 +252,7 @@ var Cabidela = class {
266
252
  switch (needle.schema.type) {
267
253
  case "string":
268
254
  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
- );
255
+ this.throw(`Length of '${pathToString(needle.path)}' must be <= ${needle.schema.maxLength}`, needle);
273
256
  }
274
257
  if (needle.schema.hasOwnProperty("minLength") && metadata.size < needle.schema.minLength) {
275
258
  this.throw(
@@ -281,34 +264,19 @@ var Cabidela = class {
281
264
  case "number":
282
265
  case "integer":
283
266
  if (needle.schema.hasOwnProperty("minimum") && resolvedObject < needle.schema.minimum) {
284
- this.throw(
285
- `'${pathToString(needle.path)}' must be >= ${needle.schema.minimum}`,
286
- needle
287
- );
267
+ this.throw(`'${pathToString(needle.path)}' must be >= ${needle.schema.minimum}`, needle);
288
268
  }
289
269
  if (needle.schema.hasOwnProperty("exclusiveMinimum") && resolvedObject <= needle.schema.exclusiveMinimum) {
290
- this.throw(
291
- `'${pathToString(needle.path)}' must be > ${needle.schema.exclusiveMinimum}`,
292
- needle
293
- );
270
+ this.throw(`'${pathToString(needle.path)}' must be > ${needle.schema.exclusiveMinimum}`, needle);
294
271
  }
295
272
  if (needle.schema.hasOwnProperty("maximum") && resolvedObject > needle.schema.maximum) {
296
- this.throw(
297
- `'${pathToString(needle.path)}' must be <= ${needle.schema.maximum}`,
298
- needle
299
- );
273
+ this.throw(`'${pathToString(needle.path)}' must be <= ${needle.schema.maximum}`, needle);
300
274
  }
301
275
  if (needle.schema.hasOwnProperty("exclusiveMaximum") && resolvedObject >= needle.schema.exclusiveMaximum) {
302
- this.throw(
303
- `'${pathToString(needle.path)}' must be < ${needle.schema.exclusiveMaximum}`,
304
- needle
305
- );
276
+ this.throw(`'${pathToString(needle.path)}' must be < ${needle.schema.exclusiveMaximum}`, needle);
306
277
  }
307
278
  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
- );
279
+ this.throw(`'${pathToString(needle.path)}' must be multiple of ${needle.schema.multipleOf}`, needle);
312
280
  }
313
281
  break;
314
282
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudflare/cabidela",
3
- "version": "0.0.17",
3
+ "version": "0.0.18",
4
4
  "description": "Cabidela is a small, fast, eval-less, Cloudflare Workers compatible, dynamic JSON Schema validator",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",