@bedrockio/model 0.1.9 → 0.1.10

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.
@@ -107,13 +107,15 @@ function validateDefinition(definition) {
107
107
  }
108
108
  }
109
109
  function resolveSort(sort, schema) {
110
- if (!Array.isArray(sort)) {
110
+ if (!sort) {
111
+ sort = [];
112
+ } else if (!Array.isArray(sort)) {
111
113
  sort = [sort];
112
114
  }
113
115
  for (let {
114
116
  field
115
117
  } of sort) {
116
- if (!schema.path(field)) {
118
+ if (!field || !schema.path(field)) {
117
119
  throw new Error(`Unknown sort field "${field}".`);
118
120
  }
119
121
  }
@@ -19,31 +19,33 @@ var _softDelete = require("./soft-delete");
19
19
  var _utils = require("./utils");
20
20
  var _include = require("./include");
21
21
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
- const DATE_SCHEMA = _yada.default.date().iso().tag({
22
+ const DATE_TAGS = {
23
23
  'x-schema': 'DateTime',
24
24
  'x-description': 'A `string` in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format.'
25
+ };
26
+ const OBJECT_ID_SCHEMA = _yada.default.string().mongo().tag({
27
+ 'x-schema': 'ObjectId',
28
+ 'x-description': 'A 24 character hexadecimal string representing a Mongo [ObjectId](https://bit.ly/3YPtGlU).'
25
29
  });
26
- const OBJECT_ID_DESCRIPTION = `
30
+ exports.OBJECT_ID_SCHEMA = OBJECT_ID_SCHEMA;
31
+ const REFERENCE_SCHEMA = _yada.default.allow(OBJECT_ID_SCHEMA, _yada.default.object({
32
+ id: OBJECT_ID_SCHEMA.required()
33
+ }).custom(obj => {
34
+ return obj.id;
35
+ })).tag({
36
+ 'x-schema': 'Reference',
37
+ 'x-description': `
27
38
  A 24 character hexadecimal string representing a Mongo [ObjectId](https://bit.ly/3YPtGlU).
28
39
  An object with an \`id\` field may also be passed, which will be converted into a string.
29
- `;
30
- const OBJECT_ID_SCHEMA = _yada.default.custom(async val => {
31
- const id = String(val.id || val);
32
- await namedSchemas.objectId.validate(id);
33
- return id;
34
- }).tag({
35
- type: 'ObjectId',
36
- 'x-schema': 'ObjectId',
37
- 'x-description': OBJECT_ID_DESCRIPTION.trim()
40
+ `.trim()
38
41
  });
39
- exports.OBJECT_ID_SCHEMA = OBJECT_ID_SCHEMA;
40
42
  const namedSchemas = {
41
43
  // Email is special as we are assuming that in
42
44
  // all cases lowercase should be allowed but coerced.
43
45
  email: _yada.default.string().lowercase().email(),
44
46
  // Force "objectId" to have parity with refs.
45
47
  // "mongo" is notably excluded here for this reason.
46
- objectId: _yada.default.string().mongo(),
48
+ objectId: OBJECT_ID_SCHEMA,
47
49
  ascii: _yada.default.string().ascii(),
48
50
  base64: _yada.default.string().base64(),
49
51
  btc: _yada.default.string().btc(),
@@ -77,6 +79,7 @@ function applyValidation(schema, definition) {
77
79
  allowIncludes: true,
78
80
  stripDeleted: true,
79
81
  stripTimestamps: true,
82
+ allowExpandedRefs: true,
80
83
  requireWriteAccess: true,
81
84
  ...(hasUnique && {
82
85
  assertUniqueOptions: {
@@ -94,6 +97,7 @@ function applyValidation(schema, definition) {
94
97
  stripUnknown: true,
95
98
  stripDeleted: true,
96
99
  stripTimestamps: true,
100
+ allowExpandedRefs: true,
97
101
  requireWriteAccess: true,
98
102
  ...(hasUnique && {
99
103
  assertUniqueOptions: {
@@ -213,7 +217,7 @@ function getObjectSchema(arg, options) {
213
217
  }
214
218
  return schema;
215
219
  } else {
216
- return getSchemaForType(arg);
220
+ return getSchemaForType(arg, options);
217
221
  }
218
222
  }
219
223
  function getArraySchema(arr, options) {
@@ -247,7 +251,7 @@ function getSchemaForTypedef(typedef, options = {}) {
247
251
  } else if (typeof type === 'object') {
248
252
  schema = getObjectSchema(type, options);
249
253
  } else {
250
- schema = getSchemaForType(type);
254
+ schema = getSchemaForType(type, options);
251
255
  }
252
256
  if (isRequired(typedef, options)) {
253
257
  schema = schema.required();
@@ -280,7 +284,7 @@ function getSchemaForTypedef(typedef, options = {}) {
280
284
  }
281
285
  return schema;
282
286
  }
283
- function getSchemaForType(type) {
287
+ function getSchemaForType(type, options) {
284
288
  switch (type) {
285
289
  case 'String':
286
290
  return _yada.default.string();
@@ -289,14 +293,18 @@ function getSchemaForType(type) {
289
293
  case 'Boolean':
290
294
  return _yada.default.boolean();
291
295
  case 'Date':
292
- return DATE_SCHEMA;
296
+ return _yada.default.date().iso().tag(DATE_TAGS);
293
297
  case 'Mixed':
294
298
  case 'Object':
295
299
  return _yada.default.object();
296
300
  case 'Array':
297
301
  return _yada.default.array();
298
302
  case 'ObjectId':
299
- return OBJECT_ID_SCHEMA;
303
+ if (options.allowExpandedRefs) {
304
+ return REFERENCE_SCHEMA;
305
+ } else {
306
+ return OBJECT_ID_SCHEMA;
307
+ }
300
308
  default:
301
309
  throw new TypeError(`Unknown schema type ${type}`);
302
310
  }
@@ -315,19 +323,19 @@ function getSearchSchema(schema, type) {
315
323
  } else if (type === 'Date') {
316
324
  return _yada.default.allow(schema, _yada.default.array(schema), _yada.default.object({
317
325
  lt: _yada.default.date().iso().tag({
318
- 'x-ref': 'DateTime',
326
+ ...DATE_TAGS,
319
327
  description: 'Select dates occurring before.'
320
328
  }),
321
329
  gt: _yada.default.date().iso().tag({
322
- 'x-ref': 'DateTime',
330
+ ...DATE_TAGS,
323
331
  description: 'Select dates occurring after.'
324
332
  }),
325
333
  lte: _yada.default.date().iso().tag({
326
- 'x-ref': 'DateTime',
334
+ ...DATE_TAGS,
327
335
  description: 'Select dates occurring on or before.'
328
336
  }),
329
337
  gte: _yada.default.date().iso().tag({
330
- 'x-ref': 'DateTime',
338
+ ...DATE_TAGS,
331
339
  description: 'Select dates occurring on or after.'
332
340
  })
333
341
  }).tag({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bedrockio/model",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "Bedrock utilities for model creation.",
5
5
  "type": "module",
6
6
  "scripts": {
package/src/search.js CHANGED
@@ -119,11 +119,13 @@ function validateDefinition(definition) {
119
119
  }
120
120
 
121
121
  function resolveSort(sort, schema) {
122
- if (!Array.isArray(sort)) {
122
+ if (!sort) {
123
+ sort = [];
124
+ } else if (!Array.isArray(sort)) {
123
125
  sort = [sort];
124
126
  }
125
127
  for (let { field } of sort) {
126
- if (!schema.path(field)) {
128
+ if (!field || !schema.path(field)) {
127
129
  throw new Error(`Unknown sort field "${field}".`);
128
130
  }
129
131
  }
package/src/validation.js CHANGED
@@ -10,27 +10,35 @@ import { hasUniqueConstraints, assertUnique } from './soft-delete';
10
10
  import { isMongooseSchema, isSchemaTypedef } from './utils';
11
11
  import { INCLUDE_FIELD_SCHEMA } from './include';
12
12
 
13
- const DATE_SCHEMA = yd.date().iso().tag({
13
+ const DATE_TAGS = {
14
14
  'x-schema': 'DateTime',
15
15
  'x-description':
16
16
  'A `string` in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format.',
17
+ };
18
+
19
+ export const OBJECT_ID_SCHEMA = yd.string().mongo().tag({
20
+ 'x-schema': 'ObjectId',
21
+ 'x-description':
22
+ 'A 24 character hexadecimal string representing a Mongo [ObjectId](https://bit.ly/3YPtGlU).',
17
23
  });
18
24
 
19
- const OBJECT_ID_DESCRIPTION = `
25
+ const REFERENCE_SCHEMA = yd
26
+ .allow(
27
+ OBJECT_ID_SCHEMA,
28
+ yd
29
+ .object({
30
+ id: OBJECT_ID_SCHEMA.required(),
31
+ })
32
+ .custom((obj) => {
33
+ return obj.id;
34
+ })
35
+ )
36
+ .tag({
37
+ 'x-schema': 'Reference',
38
+ 'x-description': `
20
39
  A 24 character hexadecimal string representing a Mongo [ObjectId](https://bit.ly/3YPtGlU).
21
40
  An object with an \`id\` field may also be passed, which will be converted into a string.
22
- `;
23
-
24
- export const OBJECT_ID_SCHEMA = yd
25
- .custom(async (val) => {
26
- const id = String(val.id || val);
27
- await namedSchemas.objectId.validate(id);
28
- return id;
29
- })
30
- .tag({
31
- type: 'ObjectId',
32
- 'x-schema': 'ObjectId',
33
- 'x-description': OBJECT_ID_DESCRIPTION.trim(),
41
+ `.trim(),
34
42
  });
35
43
 
36
44
  const namedSchemas = {
@@ -39,7 +47,7 @@ const namedSchemas = {
39
47
  email: yd.string().lowercase().email(),
40
48
  // Force "objectId" to have parity with refs.
41
49
  // "mongo" is notably excluded here for this reason.
42
- objectId: yd.string().mongo(),
50
+ objectId: OBJECT_ID_SCHEMA,
43
51
 
44
52
  ascii: yd.string().ascii(),
45
53
  base64: yd.string().base64(),
@@ -79,6 +87,7 @@ export function applyValidation(schema, definition) {
79
87
  allowIncludes: true,
80
88
  stripDeleted: true,
81
89
  stripTimestamps: true,
90
+ allowExpandedRefs: true,
82
91
  requireWriteAccess: true,
83
92
  ...(hasUnique && {
84
93
  assertUniqueOptions: {
@@ -100,6 +109,7 @@ export function applyValidation(schema, definition) {
100
109
  stripUnknown: true,
101
110
  stripDeleted: true,
102
111
  stripTimestamps: true,
112
+ allowExpandedRefs: true,
103
113
  requireWriteAccess: true,
104
114
  ...(hasUnique && {
105
115
  assertUniqueOptions: {
@@ -216,7 +226,7 @@ function getObjectSchema(arg, options) {
216
226
 
217
227
  return schema;
218
228
  } else {
219
- return getSchemaForType(arg);
229
+ return getSchemaForType(arg, options);
220
230
  }
221
231
  }
222
232
 
@@ -252,7 +262,7 @@ function getSchemaForTypedef(typedef, options = {}) {
252
262
  } else if (typeof type === 'object') {
253
263
  schema = getObjectSchema(type, options);
254
264
  } else {
255
- schema = getSchemaForType(type);
265
+ schema = getSchemaForType(type, options);
256
266
  }
257
267
 
258
268
  if (isRequired(typedef, options)) {
@@ -288,7 +298,7 @@ function getSchemaForTypedef(typedef, options = {}) {
288
298
  return schema;
289
299
  }
290
300
 
291
- function getSchemaForType(type) {
301
+ function getSchemaForType(type, options) {
292
302
  switch (type) {
293
303
  case 'String':
294
304
  return yd.string();
@@ -297,14 +307,18 @@ function getSchemaForType(type) {
297
307
  case 'Boolean':
298
308
  return yd.boolean();
299
309
  case 'Date':
300
- return DATE_SCHEMA;
310
+ return yd.date().iso().tag(DATE_TAGS);
301
311
  case 'Mixed':
302
312
  case 'Object':
303
313
  return yd.object();
304
314
  case 'Array':
305
315
  return yd.array();
306
316
  case 'ObjectId':
307
- return OBJECT_ID_SCHEMA;
317
+ if (options.allowExpandedRefs) {
318
+ return REFERENCE_SCHEMA;
319
+ } else {
320
+ return OBJECT_ID_SCHEMA;
321
+ }
308
322
  default:
309
323
  throw new TypeError(`Unknown schema type ${type}`);
310
324
  }
@@ -341,22 +355,34 @@ function getSearchSchema(schema, type) {
341
355
  yd.array(schema),
342
356
  yd
343
357
  .object({
344
- lt: yd.date().iso().tag({
345
- 'x-ref': 'DateTime',
346
- description: 'Select dates occurring before.',
347
- }),
348
- gt: yd.date().iso().tag({
349
- 'x-ref': 'DateTime',
350
- description: 'Select dates occurring after.',
351
- }),
352
- lte: yd.date().iso().tag({
353
- 'x-ref': 'DateTime',
354
- description: 'Select dates occurring on or before.',
355
- }),
356
- gte: yd.date().iso().tag({
357
- 'x-ref': 'DateTime',
358
- description: 'Select dates occurring on or after.',
359
- }),
358
+ lt: yd
359
+ .date()
360
+ .iso()
361
+ .tag({
362
+ ...DATE_TAGS,
363
+ description: 'Select dates occurring before.',
364
+ }),
365
+ gt: yd
366
+ .date()
367
+ .iso()
368
+ .tag({
369
+ ...DATE_TAGS,
370
+ description: 'Select dates occurring after.',
371
+ }),
372
+ lte: yd
373
+ .date()
374
+ .iso()
375
+ .tag({
376
+ ...DATE_TAGS,
377
+ description: 'Select dates occurring on or before.',
378
+ }),
379
+ gte: yd
380
+ .date()
381
+ .iso()
382
+ .tag({
383
+ ...DATE_TAGS,
384
+ description: 'Select dates occurring on or after.',
385
+ }),
360
386
  })
361
387
  .tag({
362
388
  'x-schema': 'DateRange',
@@ -9,5 +9,95 @@ export function getTupleValidator(types: any): {
9
9
  (val: any): Promise<void>;
10
10
  schema: any;
11
11
  };
12
- export const OBJECT_ID_SCHEMA: import("@bedrockio/yada/types/Schema").default;
12
+ export const OBJECT_ID_SCHEMA: {
13
+ length(length: number): any;
14
+ min(length: number): any;
15
+ max(length: number): any;
16
+ trim(): any;
17
+ lowercase(assert?: boolean): any;
18
+ uppercase(assert?: boolean): any;
19
+ match(reg: RegExp): any;
20
+ email(): any;
21
+ phone(): any;
22
+ hex(): any;
23
+ md5(): any;
24
+ sha1(): any;
25
+ ascii(): any;
26
+ base64(options?: {
27
+ urlSafe?: boolean;
28
+ }): any;
29
+ creditCard(): any;
30
+ ip(): any;
31
+ country(): any;
32
+ locale(): any;
33
+ jwt(): any;
34
+ slug(): any;
35
+ latlng(): any;
36
+ postalCode(locale?: string): any;
37
+ password(options?: {
38
+ minLength?: number;
39
+ minNumbers?: number;
40
+ minSymbols?: number;
41
+ minLowercase?: number;
42
+ minUppercase?: number;
43
+ }): any;
44
+ url(options?: {
45
+ require_protocol?: boolean;
46
+ require_valid_protocol?: boolean;
47
+ require_host?: boolean;
48
+ require_port?: boolean;
49
+ allow_protocol_relative_urls?: boolean;
50
+ allow_fragments?: boolean;
51
+ allow_query_components?: boolean;
52
+ validate_length?: boolean;
53
+ protocols?: string[];
54
+ }): any;
55
+ domain(options?: {
56
+ require_tld?: boolean;
57
+ allow_underscores?: boolean;
58
+ allow_trailing_dot?: boolean;
59
+ allow_numeric_tld?: boolean;
60
+ allow_wildcard?: boolean;
61
+ ignore_max_length?: boolean;
62
+ }): any;
63
+ uuid(version?: 1 | 2 | 5 | 3 | 4): any;
64
+ btc(): any;
65
+ eth(): any;
66
+ swift(): any;
67
+ mongo(): any;
68
+ format(name: any, fn: any): import("@bedrockio/yada/types/TypeSchema").default;
69
+ toString(): any;
70
+ assertions: any[];
71
+ meta: {};
72
+ required(): any;
73
+ default(value: any): any;
74
+ custom(...args: import("@bedrockio/yada/types/Schema").CustomSignature): any;
75
+ strip(strip: any): any;
76
+ allow(...set: any[]): any;
77
+ reject(...set: any[]): any;
78
+ message(message: any): any;
79
+ tag(tags: any): any;
80
+ description(description: any): any;
81
+ options(options: any): any;
82
+ validate(value: any, options?: {}): Promise<any>;
83
+ clone(meta: any): any;
84
+ append(schema: any): any;
85
+ toOpenApi(extra: any): any;
86
+ expandExtra(extra?: {}): {};
87
+ assertEnum(set: any, allow: any): any;
88
+ assert(type: any, fn: any): any;
89
+ pushAssertion(assertion: any): void;
90
+ transform(fn: any): any;
91
+ getSortIndex(type: any): number;
92
+ runAssertion(assertion: any, value: any, options?: {}): Promise<any>;
93
+ enumToOpenApi(): {
94
+ type: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function";
95
+ enum: any;
96
+ oneOf?: undefined;
97
+ } | {
98
+ oneOf: any[];
99
+ type?: undefined;
100
+ enum?: undefined;
101
+ };
102
+ };
13
103
  //# sourceMappingURL=validation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.js"],"names":[],"mappings":"AAiEA,kDAEC;AAED,oEA4EC;AAsBD,wEAkBC;AA0PD;;;EAEC;AAED;;;EAOC;AAvaD,8EAUK"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.js"],"names":[],"mappings":"AAyEA,kDAEC;AAED,oEA8EC;AAsBD,wEAkBC;AA0QD;;;EAEC;AAED;;;EAOC;AAtcD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIG"}