@bedrockio/yada 1.7.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 1.8.0
2
+
3
+ - Removed undefined `format` field.
4
+ - Changed JSON schema `oneOf` to `anyOf`.
5
+ - Added `requireAll` and `requireAllWithin`.
6
+
1
7
  ## 1.7.0
2
8
 
3
9
  - Partial revert of 1.6.0. Dot syntax expanding no longer default but enabled.
@@ -223,15 +223,14 @@ class Schema {
223
223
  */
224
224
  toJSON(extra) {
225
225
  const {
226
- format,
227
226
  tags
228
227
  } = this.meta;
229
228
  return {
230
- format,
231
229
  ...tags,
232
230
  ...this.getAnyType(),
233
231
  ...this.getDefault(),
234
232
  ...this.getNullable(),
233
+ ...this.getFormat(),
235
234
  ...this.getEnum(),
236
235
  ...this.expandExtra(extra)
237
236
  };
@@ -255,6 +254,16 @@ class Schema {
255
254
  };
256
255
  }
257
256
  }
257
+ getFormat() {
258
+ const {
259
+ format
260
+ } = this.meta;
261
+ if (format) {
262
+ return {
263
+ format
264
+ };
265
+ }
266
+ }
258
267
  getDefault() {
259
268
  const {
260
269
  default: defaultValue
@@ -293,13 +302,23 @@ class Schema {
293
302
  enum: allowed
294
303
  };
295
304
  } else {
296
- const oneOf = [];
305
+ // Note that "oneOf" is subtly different to "anyOf" in that ONLY one branch
306
+ // can pass. Currently yada allows any successful branch to allow the schema
307
+ // to pass validation. In addition to being more semantically correct, "oneOf":
308
+ //
309
+ // 1. Is computationally expensive (must test multiple times).
310
+ // 2. Is disallowed by OpenAI: https://tinyurl.com/33cr388a
311
+ const anyOf = [];
297
312
  for (let entry of allowed) {
298
313
  if (isSchema(entry)) {
299
- oneOf.push(entry.toJSON());
314
+ anyOf.push(entry.toJSON());
315
+ } else if (entry === null) {
316
+ anyOf.push({
317
+ type: 'null'
318
+ });
300
319
  } else {
301
320
  const type = typeof entry;
302
- let forType = oneOf.find(el => {
321
+ let forType = anyOf.find(el => {
303
322
  return el.type === type;
304
323
  });
305
324
  if (!forType) {
@@ -307,7 +326,7 @@ class Schema {
307
326
  type,
308
327
  enum: []
309
328
  };
310
- oneOf.push(forType);
329
+ anyOf.push(forType);
311
330
  }
312
331
  if (forType.enum) {
313
332
  forType.enum.push(entry);
@@ -315,11 +334,36 @@ class Schema {
315
334
  }
316
335
  }
317
336
  return {
318
- oneOf
337
+ anyOf
319
338
  };
320
339
  }
321
340
  }
322
341
  }
342
+
343
+ /**
344
+ * Augments the schema to make all fields required
345
+ * including fields in all nested schemas.
346
+ * @returns {this}
347
+ */
348
+ requireAllWithin() {
349
+ let {
350
+ enum: allowed
351
+ } = this.meta;
352
+ if (allowed) {
353
+ allowed = allowed.map(el => {
354
+ if (el?.requireAllWithin) {
355
+ return el.requireAllWithin();
356
+ } else {
357
+ return el;
358
+ }
359
+ });
360
+ return this.clone({
361
+ enum: allowed
362
+ }).required();
363
+ } else {
364
+ return this.required();
365
+ }
366
+ }
323
367
  expandExtra(extra = {}) {
324
368
  const {
325
369
  tag,
package/dist/cjs/array.js CHANGED
@@ -118,7 +118,7 @@ class ArraySchema extends _TypeSchema.default {
118
118
  } = this.meta;
119
119
  if (schemas.length > 1) {
120
120
  other = {
121
- oneOf: schemas.map(schema => {
121
+ anyOf: schemas.map(schema => {
122
122
  return schema.toJSON();
123
123
  })
124
124
  };
@@ -207,6 +207,32 @@ class ObjectSchema extends _TypeSchema.default {
207
207
  return this.append(update);
208
208
  }
209
209
 
210
+ /**
211
+ * Augments the object schema to make all fields required.
212
+ */
213
+ requireAll() {
214
+ const update = {};
215
+ for (let field of Object.keys(this.meta.fields)) {
216
+ (0, _lodash.set)(update, field, this.get(field).required());
217
+ }
218
+ return this.append(update);
219
+ }
220
+
221
+ /**
222
+ * Augments the object schema to make all fields required
223
+ * including fields in all nested schemas.
224
+ * @returns {this}
225
+ */
226
+ requireAllWithin() {
227
+ const update = {};
228
+ for (let field of Object.keys(this.meta.fields)) {
229
+ (0, _lodash.set)(update, field, this.get(field).requireAllWithin());
230
+ }
231
+
232
+ // @ts-ignore
233
+ return this.append(update).required();
234
+ }
235
+
210
236
  /**
211
237
  * Returns the schema's fields as an object allowing them
212
238
  * to be "spread" to create new schemas. Note that doing
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bedrockio/yada",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "Validation library inspired by Joi.",
5
5
  "scripts": {
6
6
  "test": "jest",
package/src/Schema.js CHANGED
@@ -215,13 +215,13 @@ export default class Schema {
215
215
  * @param {Object} [extra]
216
216
  */
217
217
  toJSON(extra) {
218
- const { format, tags } = this.meta;
218
+ const { tags } = this.meta;
219
219
  return {
220
- format,
221
220
  ...tags,
222
221
  ...this.getAnyType(),
223
222
  ...this.getDefault(),
224
223
  ...this.getNullable(),
224
+ ...this.getFormat(),
225
225
  ...this.getEnum(),
226
226
  ...this.expandExtra(extra),
227
227
  };
@@ -244,6 +244,13 @@ export default class Schema {
244
244
  }
245
245
  }
246
246
 
247
+ getFormat() {
248
+ const { format } = this.meta;
249
+ if (format) {
250
+ return { format };
251
+ }
252
+ }
253
+
247
254
  getDefault() {
248
255
  const { default: defaultValue } = this.meta;
249
256
  if (typeof defaultValue === 'function') {
@@ -278,13 +285,23 @@ export default class Schema {
278
285
  enum: allowed,
279
286
  };
280
287
  } else {
281
- const oneOf = [];
288
+ // Note that "oneOf" is subtly different to "anyOf" in that ONLY one branch
289
+ // can pass. Currently yada allows any successful branch to allow the schema
290
+ // to pass validation. In addition to being more semantically correct, "oneOf":
291
+ //
292
+ // 1. Is computationally expensive (must test multiple times).
293
+ // 2. Is disallowed by OpenAI: https://tinyurl.com/33cr388a
294
+ const anyOf = [];
282
295
  for (let entry of allowed) {
283
296
  if (isSchema(entry)) {
284
- oneOf.push(entry.toJSON());
297
+ anyOf.push(entry.toJSON());
298
+ } else if (entry === null) {
299
+ anyOf.push({
300
+ type: 'null',
301
+ });
285
302
  } else {
286
303
  const type = typeof entry;
287
- let forType = oneOf.find((el) => {
304
+ let forType = anyOf.find((el) => {
288
305
  return el.type === type;
289
306
  });
290
307
  if (!forType) {
@@ -292,18 +309,39 @@ export default class Schema {
292
309
  type,
293
310
  enum: [],
294
311
  };
295
- oneOf.push(forType);
312
+ anyOf.push(forType);
296
313
  }
297
314
  if (forType.enum) {
298
315
  forType.enum.push(entry);
299
316
  }
300
317
  }
301
318
  }
302
- return { oneOf };
319
+ return { anyOf };
303
320
  }
304
321
  }
305
322
  }
306
323
 
324
+ /**
325
+ * Augments the schema to make all fields required
326
+ * including fields in all nested schemas.
327
+ * @returns {this}
328
+ */
329
+ requireAllWithin() {
330
+ let { enum: allowed } = this.meta;
331
+ if (allowed) {
332
+ allowed = allowed.map((el) => {
333
+ if (el?.requireAllWithin) {
334
+ return el.requireAllWithin();
335
+ } else {
336
+ return el;
337
+ }
338
+ });
339
+ return this.clone({ enum: allowed }).required();
340
+ } else {
341
+ return this.required();
342
+ }
343
+ }
344
+
307
345
  expandExtra(extra = {}) {
308
346
  const { tag, ...rest } = extra;
309
347
  if (typeof extra?.tag === 'function') {
package/src/array.js CHANGED
@@ -115,7 +115,7 @@ class ArraySchema extends TypeSchema {
115
115
  const { schemas } = this.meta;
116
116
  if (schemas.length > 1) {
117
117
  other = {
118
- oneOf: schemas.map((schema) => {
118
+ anyOf: schemas.map((schema) => {
119
119
  return schema.toJSON();
120
120
  }),
121
121
  };
package/src/object.js CHANGED
@@ -69,6 +69,7 @@ class ObjectSchema extends TypeSchema {
69
69
  delete obj[key];
70
70
  return;
71
71
  }
72
+
72
73
  try {
73
74
  // Do not pass down message into validators
74
75
  // to allow custom messages to take precedence.
@@ -200,6 +201,35 @@ class ObjectSchema extends TypeSchema {
200
201
  return this.append(update);
201
202
  }
202
203
 
204
+ /**
205
+ * Augments the object schema to make all fields required.
206
+ */
207
+ requireAll() {
208
+ const update = {};
209
+
210
+ for (let field of Object.keys(this.meta.fields)) {
211
+ set(update, field, this.get(field).required());
212
+ }
213
+
214
+ return this.append(update);
215
+ }
216
+
217
+ /**
218
+ * Augments the object schema to make all fields required
219
+ * including fields in all nested schemas.
220
+ * @returns {this}
221
+ */
222
+ requireAllWithin() {
223
+ const update = {};
224
+
225
+ for (let field of Object.keys(this.meta.fields)) {
226
+ set(update, field, this.get(field).requireAllWithin());
227
+ }
228
+
229
+ // @ts-ignore
230
+ return this.append(update).required();
231
+ }
232
+
203
233
  /**
204
234
  * Returns the schema's fields as an object allowing them
205
235
  * to be "spread" to create new schemas. Note that doing
package/types/Schema.d.ts CHANGED
@@ -86,6 +86,9 @@ export default class Schema {
86
86
  getAnyType(): {
87
87
  type: string[];
88
88
  };
89
+ getFormat(): {
90
+ format: any;
91
+ };
89
92
  getDefault(): {
90
93
  default?: undefined;
91
94
  } | {
@@ -95,6 +98,12 @@ export default class Schema {
95
98
  nullable: boolean;
96
99
  };
97
100
  getEnum(): any;
101
+ /**
102
+ * Augments the schema to make all fields required
103
+ * including fields in all nested schemas.
104
+ * @returns {this}
105
+ */
106
+ requireAllWithin(): this;
98
107
  expandExtra(extra?: {}): {};
99
108
  inspect(): string;
100
109
  get(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"Schema.d.ts","sourceRoot":"","sources":["../src/Schema.js"],"names":[],"mappings":"AAgBA,kDAEC;AAED;IACE,uBAGC;IAFC,kBAAoB;IACpB,SAAgB;IAKlB;;OAEG;IACH,YAFa,IAAI,CAQhB;IAED;;;OAGG;IACH,mBAFa,IAAI,CAShB;IAED;;;;OAIG;IACH,sBAFa,IAAI,CAShB;IAED;;;;OAIG;IACH,uBAFa,IAAI,CAShB;IAED;;;;OAIG;IACH,mBAFa,IAAI,CAIhB;IAED;;;OAGG;IACH,sBAFa,IAAI,CAIhB;IAED;;;OAGG;IACH,uBAFa,IAAI,CAIhB;IAED;;;OAGG;IACH,YAFa,IAAI,CAIhB;IAED;;OAEG;IACH,uBAFa,IAAI,CAIhB;IAED;;OAEG;IACH,gBAFa,IAAI,CAShB;IAED;;OAEG;IACH,+BAFa,IAAI,CAMhB;IAED;;OAEG;IACH,uBAFa,IAAI,CAIhB;IAED,iDAwCC;IAED;;OAEG;IACH,kBAFa,IAAI,CAOhB;IAED;;;OAGG;IACH,qBAFa,MAAM,CAMlB;IAED;;;;;OAKG;IACH,yBAWC;IAED;;;OAGG;IACH,gCAEC;IAED;;MAOC;IAED;;;;MASC;IAED;;MAOC;IAED,eAsCC;IAED,4BAMC;IAED,kBAEC;IAED,YAGC;IAID;;OAEG;IACH,kCAFa,IAAI,CAsDhB;IAED;;OAEG;IACH,4BAFa,IAAI,CAUhB;IAED,oCAKC;IAED,gEAQC;IAED;;OAEG;IACH,oBAFa,IAAI,CAShB;IAED,gCAGC;IAED,qEAYC;CACF"}
1
+ {"version":3,"file":"Schema.d.ts","sourceRoot":"","sources":["../src/Schema.js"],"names":[],"mappings":"AAgBA,kDAEC;AAED;IACE,uBAGC;IAFC,kBAAoB;IACpB,SAAgB;IAKlB;;OAEG;IACH,YAFa,IAAI,CAQhB;IAED;;;OAGG;IACH,mBAFa,IAAI,CAShB;IAED;;;;OAIG;IACH,sBAFa,IAAI,CAShB;IAED;;;;OAIG;IACH,uBAFa,IAAI,CAShB;IAED;;;;OAIG;IACH,mBAFa,IAAI,CAIhB;IAED;;;OAGG;IACH,sBAFa,IAAI,CAIhB;IAED;;;OAGG;IACH,uBAFa,IAAI,CAIhB;IAED;;;OAGG;IACH,YAFa,IAAI,CAIhB;IAED;;OAEG;IACH,uBAFa,IAAI,CAIhB;IAED;;OAEG;IACH,gBAFa,IAAI,CAShB;IAED;;OAEG;IACH,+BAFa,IAAI,CAMhB;IAED;;OAEG;IACH,uBAFa,IAAI,CAIhB;IAED,iDAwCC;IAED;;OAEG;IACH,kBAFa,IAAI,CAOhB;IAED;;;OAGG;IACH,qBAFa,MAAM,CAMlB;IAED;;;;;OAKG;IACH,yBAWC;IAED;;;OAGG;IACH,gCAEC;IAED;;MAOC;IAED;;MAKC;IAED;;;;MASC;IAED;;MAOC;IAED,eAgDC;IAED;;;;OAIG;IACH,oBAFa,IAAI,CAgBhB;IAED,4BAMC;IAED,kBAEC;IAED,YAGC;IAID;;OAEG;IACH,kCAFa,IAAI,CAsDhB;IAED;;OAEG;IACH,4BAFa,IAAI,CAUhB;IAED,oCAKC;IAED,gEAQC;IAED;;OAEG;IACH,oBAFa,IAAI,CAShB;IAED,gCAGC;IAED,qEAYC;CACF"}
package/types/object.d.ts CHANGED
@@ -52,6 +52,16 @@ declare class ObjectSchema extends TypeSchema {
52
52
  * @param {Array<string>} fields
53
53
  */
54
54
  require(...fields: string[]): ObjectSchema;
55
+ /**
56
+ * Augments the object schema to make all fields required.
57
+ */
58
+ requireAll(): ObjectSchema;
59
+ /**
60
+ * Augments the object schema to make all fields required
61
+ * including fields in all nested schemas.
62
+ * @returns {this}
63
+ */
64
+ requireAllWithin(): this;
55
65
  /**
56
66
  * Returns the schema's fields as an object allowing them
57
67
  * to be "spread" to create new schemas. Note that doing
@@ -1 +1 @@
1
- {"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../src/object.js"],"names":[],"mappings":"AAkYA;;;;;;GAMG;AACH,uCAJW,SAAS,gBAQnB;wBAlYY;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG,EAAE;AAD3C;;GAEG;AAEH;IACE,uBAGC;IAED,cA8EC;IAED;;;;;;OAMG;IACH,WAFW,MAAM,GAAC,KAAK,CAAC,MAAM,CAAC,OAsB9B;IAED;;;;;;OAMG;IACH,cAFW,MAAM,GAAC,KAAK,CAAC,MAAM,CAAC,OAY9B;IAED;;;;OAIG;IACH,gBAFc,MAAM,EAAA,gBASnB;IAED;;;;OAIG;IACH,gBAFc,MAAM,EAAA,gBASnB;IAED;;;;;;;OAOG;IACH,mBAHc,MAAM,EAAA,gBAmBnB;IAED;;;;;;OAMG;IACH,cAEC;IAED;;;;;;;;;OASG;IACH,YAFW,SAAS,GAAC,MAAM,gBA+B1B;IAED;;;;;;;;;;;OAWG;IACH,kBALG;QAA0B,UAAU,GAA5B,OAAO;QACW,YAAY,GAA9B,OAAO;QACW,aAAa,GAA/B,OAAO;QACW,cAAc,GAAhC,OAAO;KAA0B,QAI3C;CAwBF;mBAlSgC,UAAU;uBACpB,cAAc"}
1
+ {"version":3,"file":"object.d.ts","sourceRoot":"","sources":["../src/object.js"],"names":[],"mappings":"AAgaA;;;;;;GAMG;AACH,uCAJW,SAAS,gBAQnB;wBAhaY;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GAAG,EAAE;AAD3C;;GAEG;AAEH;IACE,uBAGC;IAED,cA+EC;IAED;;;;;;OAMG;IACH,WAFW,MAAM,GAAC,KAAK,CAAC,MAAM,CAAC,OAsB9B;IAED;;;;;;OAMG;IACH,cAFW,MAAM,GAAC,KAAK,CAAC,MAAM,CAAC,OAY9B;IAED;;;;OAIG;IACH,gBAFc,MAAM,EAAA,gBASnB;IAED;;;;OAIG;IACH,gBAFc,MAAM,EAAA,gBASnB;IAED;;;;;;;OAOG;IACH,mBAHc,MAAM,EAAA,gBAmBnB;IAED;;OAEG;IACH,2BAQC;IAED;;;;OAIG;IACH,oBAFa,IAAI,CAWhB;IAED;;;;;;OAMG;IACH,cAEC;IAED;;;;;;;;;OASG;IACH,YAFW,SAAS,GAAC,MAAM,gBA+B1B;IAED;;;;;;;;;;;OAWG;IACH,kBALG;QAA0B,UAAU,GAA5B,OAAO;QACW,YAAY,GAA9B,OAAO;QACW,aAAa,GAA/B,OAAO;QACW,cAAc,GAAhC,OAAO;KAA0B,QAI3C;CAwBF;mBAhUgC,UAAU;uBACpB,cAAc"}