@based/schema 2.6.0 → 2.7.1

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.
Files changed (40) hide show
  1. package/dist/src/compat/newToOld.d.ts +2 -2
  2. package/dist/src/compat/newToOld.js +172 -29
  3. package/dist/src/compat/oldToNew.d.ts +1 -1
  4. package/dist/src/compat/oldToNew.js +200 -25
  5. package/dist/src/display/number.d.ts +2 -1
  6. package/dist/src/display/number.js +10 -0
  7. package/dist/src/display/string.d.ts +3 -1
  8. package/dist/src/display/string.js +5 -0
  9. package/dist/src/display/timestamp.d.ts +3 -1
  10. package/dist/src/display/timestamp.js +9 -0
  11. package/dist/src/error.d.ts +3 -1
  12. package/dist/src/error.js +2 -0
  13. package/dist/src/index.d.ts +1 -1
  14. package/dist/src/index.js +1 -1
  15. package/dist/src/types.d.ts +4 -3
  16. package/dist/src/types.js +74 -0
  17. package/dist/src/validateSchema/basedSchemaTypeValidator.d.ts +3 -0
  18. package/dist/src/validateSchema/basedSchemaTypeValidator.js +45 -0
  19. package/dist/src/validateSchema/fieldValidators.d.ts +27 -0
  20. package/dist/src/validateSchema/fieldValidators.js +360 -0
  21. package/dist/src/validateSchema/index.d.ts +17 -0
  22. package/dist/src/validateSchema/index.js +109 -0
  23. package/dist/src/validateSchema/utils.d.ts +25 -0
  24. package/dist/src/validateSchema/utils.js +61 -0
  25. package/dist/test/compat.js +19 -3
  26. package/dist/test/data/newSchemas.d.ts +2 -2
  27. package/dist/test/data/newSchemas.js +241 -0
  28. package/dist/test/data/oldSchemas.js +122 -122
  29. package/dist/test/validateSchema/basic.js +94 -0
  30. package/dist/test/validateSchema/fields.d.ts +1 -0
  31. package/dist/test/validateSchema/fields.js +436 -0
  32. package/dist/test/validateSchema/languages.d.ts +1 -0
  33. package/dist/test/validateSchema/languages.js +124 -0
  34. package/dist/test/validateSchema/realWorld.d.ts +1 -0
  35. package/dist/test/validateSchema/realWorld.js +13 -0
  36. package/package.json +4 -3
  37. package/dist/src/validateSchema.d.ts +0 -4
  38. package/dist/src/validateSchema.js +0 -35
  39. package/dist/test/validateSchema.js +0 -38
  40. /package/dist/test/{validateSchema.d.ts → validateSchema/basic.d.ts} +0 -0
@@ -0,0 +1,94 @@
1
+ import anyTest from 'ava';
2
+ import { validateSchema } from '../../src/validateSchema/index.js';
3
+ import { ParseError } from '../../src/error.js';
4
+ const test = anyTest;
5
+ test('invalid properties in schema root should fail', async (t) => {
6
+ // @ts-ignore
7
+ t.deepEqual(await validateSchema({ invalidProperty: true }), {
8
+ errors: [{ code: ParseError.invalidProperty, path: ['invalidProperty'] }],
9
+ });
10
+ });
11
+ test('root', async (t) => {
12
+ t.deepEqual(await validateSchema({
13
+ root: {
14
+ // @ts-ignore
15
+ wawa: true,
16
+ },
17
+ }), {
18
+ errors: [{ code: ParseError.invalidProperty, path: ['root', 'wawa'] }],
19
+ });
20
+ for (const key of ['directory', 'title', 'description']) {
21
+ const result = await validateSchema({
22
+ root: {
23
+ // @ts-ignore
24
+ [key]: true,
25
+ },
26
+ });
27
+ t.deepEqual(result, {
28
+ errors: [{ code: ParseError.incorrectFormat, path: ['root', key] }],
29
+ });
30
+ }
31
+ t.deepEqual(await validateSchema({
32
+ root: {
33
+ // @ts-ignore
34
+ fields: 'wa',
35
+ },
36
+ }), {
37
+ errors: [{ code: ParseError.incorrectFormat, path: ['root', 'fields'] }],
38
+ });
39
+ t.deepEqual(await validateSchema({
40
+ root: {
41
+ prefix: 'wa',
42
+ },
43
+ }), {
44
+ errors: [{ code: ParseError.incorrectFormat, path: ['root', 'prefix'] }],
45
+ });
46
+ t.deepEqual(await validateSchema({
47
+ root: {
48
+ // @ts-ignore
49
+ prefix: true,
50
+ },
51
+ }), {
52
+ errors: [{ code: ParseError.incorrectFormat, path: ['root', 'prefix'] }],
53
+ });
54
+ t.deepEqual(await validateSchema({
55
+ root: {
56
+ prefix: 'ro',
57
+ },
58
+ }), {
59
+ valid: true,
60
+ });
61
+ t.deepEqual(await validateSchema({
62
+ root: {
63
+ required: ['astring'],
64
+ },
65
+ }), {
66
+ valid: true,
67
+ });
68
+ t.deepEqual(await validateSchema({
69
+ root: {
70
+ // @ts-ignore
71
+ required: 'anotherString',
72
+ },
73
+ }), {
74
+ errors: [
75
+ { code: ParseError.incorrectFormat, path: ['root', 'required'] },
76
+ ],
77
+ });
78
+ t.deepEqual(await validateSchema({
79
+ root: {
80
+ $delete: true,
81
+ },
82
+ }), {
83
+ valid: true,
84
+ });
85
+ t.deepEqual(await validateSchema({
86
+ root: {
87
+ // @ts-ignore
88
+ $delete: 'aString',
89
+ },
90
+ }), {
91
+ errors: [{ code: ParseError.incorrectFormat, path: ['root', '$delete'] }],
92
+ });
93
+ });
94
+ //# sourceMappingURL=basic.js.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,436 @@
1
+ import anyTest from 'ava';
2
+ import { validateSchema } from '../../src/validateSchema/index.js';
3
+ import { ParseError } from '../../src/error.js';
4
+ const test = anyTest;
5
+ test('shared', async (t) => {
6
+ t.deepEqual(await validateSchema({
7
+ root: {
8
+ fields: {
9
+ stringField: {
10
+ type: 'string',
11
+ // @ts-ignore
12
+ wawa: true,
13
+ },
14
+ },
15
+ },
16
+ }), {
17
+ errors: [
18
+ {
19
+ code: ParseError.invalidProperty,
20
+ path: ['root', 'fields', 'stringField', 'wawa'],
21
+ },
22
+ ],
23
+ }, 'invalid property');
24
+ t.deepEqual(await validateSchema({
25
+ root: {
26
+ fields: {
27
+ stringField: {
28
+ type: 'string',
29
+ hooks: { hook: 'aHook' },
30
+ },
31
+ },
32
+ },
33
+ }), {
34
+ valid: true,
35
+ });
36
+ t.deepEqual(await validateSchema({
37
+ root: {
38
+ fields: {
39
+ stringField: {
40
+ type: 'string',
41
+ hooks: [
42
+ { hook: 'aHook', interval: 1000 },
43
+ { hook: 'anotherHook', interval: 2000 },
44
+ ],
45
+ },
46
+ },
47
+ },
48
+ }), {
49
+ valid: true,
50
+ });
51
+ t.deepEqual(await validateSchema({
52
+ root: {
53
+ fields: {
54
+ stringField: {
55
+ type: 'string',
56
+ // @ts-ignore
57
+ hooks: true,
58
+ },
59
+ },
60
+ },
61
+ }), {
62
+ errors: [
63
+ {
64
+ code: ParseError.incorrectFormat,
65
+ path: ['root', 'fields', 'stringField', 'hooks'],
66
+ },
67
+ ],
68
+ }, 'hooks format is wrong');
69
+ t.deepEqual(await validateSchema({
70
+ root: {
71
+ fields: {
72
+ stringField: {
73
+ type: 'string',
74
+ // @ts-ignore
75
+ hooks: {
76
+ hook: 'aHook',
77
+ // @ts-ignore
78
+ interval: '2000',
79
+ },
80
+ },
81
+ },
82
+ },
83
+ }), {
84
+ errors: [
85
+ {
86
+ code: ParseError.incorrectFormat,
87
+ path: ['root', 'fields', 'stringField', 'hooks', 'interval'],
88
+ },
89
+ ],
90
+ }, 'hooks format is wrong');
91
+ t.deepEqual(await validateSchema({
92
+ root: {
93
+ fields: {
94
+ stringField: {
95
+ type: 'string',
96
+ // @ts-ignore
97
+ hooks: [
98
+ { hook: 'aHook', interval: 1000 },
99
+ // @ts-ignore
100
+ { hook: 'anotherHook', interval: '2000' },
101
+ ],
102
+ },
103
+ },
104
+ },
105
+ }), {
106
+ errors: [
107
+ {
108
+ code: ParseError.incorrectFormat,
109
+ path: ['root', 'fields', 'stringField', 'hooks', '1', 'interval'],
110
+ },
111
+ ],
112
+ }, 'hooks format is wrong');
113
+ });
114
+ test('string', async (t) => {
115
+ t.deepEqual(await validateSchema({
116
+ root: {
117
+ fields: {
118
+ stringField: {
119
+ type: 'string',
120
+ },
121
+ },
122
+ },
123
+ }), {
124
+ valid: true,
125
+ });
126
+ t.deepEqual(await validateSchema({
127
+ types: {
128
+ aType: {
129
+ fields: {
130
+ stringField: {
131
+ type: 'string',
132
+ },
133
+ },
134
+ },
135
+ },
136
+ }), {
137
+ valid: true,
138
+ });
139
+ t.deepEqual(await validateSchema({
140
+ root: {
141
+ fields: {
142
+ stringField: {
143
+ type: 'string',
144
+ // @ts-ignore
145
+ values: {
146
+ type: 'string',
147
+ },
148
+ },
149
+ },
150
+ },
151
+ }), {
152
+ errors: [
153
+ {
154
+ code: ParseError.invalidProperty,
155
+ path: ['root', 'fields', 'stringField', 'values'],
156
+ },
157
+ ],
158
+ });
159
+ t.deepEqual(await validateSchema({
160
+ types: {
161
+ aType: {
162
+ fields: {
163
+ stringField: {
164
+ type: 'string',
165
+ // @ts-ignore
166
+ values: {
167
+ type: 'string',
168
+ },
169
+ },
170
+ },
171
+ },
172
+ },
173
+ }), {
174
+ errors: [
175
+ {
176
+ code: ParseError.invalidProperty,
177
+ path: ['types', 'aType', 'fields', 'stringField', 'values'],
178
+ },
179
+ ],
180
+ });
181
+ });
182
+ test('objects', async (t) => {
183
+ t.deepEqual(await validateSchema({
184
+ root: {
185
+ fields: {
186
+ objectField: {
187
+ type: 'object',
188
+ properties: {
189
+ aStringField: {
190
+ type: 'string',
191
+ },
192
+ },
193
+ },
194
+ },
195
+ },
196
+ }), {
197
+ valid: true,
198
+ });
199
+ t.deepEqual(await validateSchema({
200
+ root: {
201
+ fields: {
202
+ objectField: {
203
+ type: 'object',
204
+ properties: {
205
+ aStringField: {
206
+ // @ts-ignore
207
+ wawa: true,
208
+ },
209
+ },
210
+ },
211
+ },
212
+ },
213
+ }), {
214
+ errors: [
215
+ {
216
+ code: ParseError.invalidProperty,
217
+ path: [
218
+ 'root',
219
+ 'fields',
220
+ 'objectField',
221
+ 'properties',
222
+ 'aStringField',
223
+ 'wawa',
224
+ ],
225
+ },
226
+ ],
227
+ });
228
+ t.deepEqual(await validateSchema({
229
+ root: {
230
+ fields: {
231
+ objectField: {
232
+ type: 'object',
233
+ properties: {
234
+ anotherObjectField: {
235
+ type: 'object',
236
+ properties: {
237
+ aWrongObjectField: {
238
+ type: 'object',
239
+ // @ts-ignore
240
+ values: { type: 'string' },
241
+ },
242
+ },
243
+ },
244
+ },
245
+ },
246
+ },
247
+ },
248
+ }), {
249
+ errors: [
250
+ {
251
+ code: ParseError.invalidProperty,
252
+ path: [
253
+ 'root',
254
+ 'fields',
255
+ 'objectField',
256
+ 'properties',
257
+ 'anotherObjectField',
258
+ 'properties',
259
+ 'aWrongObjectField',
260
+ 'values',
261
+ ],
262
+ },
263
+ ],
264
+ });
265
+ });
266
+ test('records', async (t) => {
267
+ t.deepEqual(await validateSchema({
268
+ root: {
269
+ fields: {
270
+ recordField: {
271
+ type: 'record',
272
+ values: {
273
+ type: 'string',
274
+ },
275
+ },
276
+ },
277
+ },
278
+ }), {
279
+ valid: true,
280
+ });
281
+ t.deepEqual(await validateSchema({
282
+ root: {
283
+ fields: {
284
+ recordField: {
285
+ type: 'record',
286
+ values: {
287
+ type: 'object',
288
+ properties: {
289
+ aWrongObjectField: {
290
+ type: 'object',
291
+ // @ts-ignore
292
+ values: { type: 'string' },
293
+ },
294
+ },
295
+ },
296
+ },
297
+ },
298
+ },
299
+ }), {
300
+ errors: [
301
+ {
302
+ code: ParseError.invalidProperty,
303
+ path: [
304
+ 'root',
305
+ 'fields',
306
+ 'recordField',
307
+ 'values',
308
+ 'properties',
309
+ 'aWrongObjectField',
310
+ 'values',
311
+ ],
312
+ },
313
+ ],
314
+ });
315
+ });
316
+ test('arrays', async (t) => {
317
+ t.deepEqual(await validateSchema({
318
+ root: {
319
+ fields: {
320
+ arrayField: {
321
+ type: 'array',
322
+ values: {
323
+ type: 'string',
324
+ },
325
+ },
326
+ },
327
+ },
328
+ }), {
329
+ valid: true,
330
+ });
331
+ t.deepEqual(await validateSchema({
332
+ root: {
333
+ fields: {
334
+ arrayField: {
335
+ type: 'array',
336
+ values: {
337
+ type: 'object',
338
+ properties: {
339
+ aWrongObjectField: {
340
+ type: 'object',
341
+ // @ts-ignore
342
+ values: { type: 'string' },
343
+ },
344
+ },
345
+ },
346
+ },
347
+ },
348
+ },
349
+ }), {
350
+ errors: [
351
+ {
352
+ code: ParseError.invalidProperty,
353
+ path: [
354
+ 'root',
355
+ 'fields',
356
+ 'arrayField',
357
+ 'values',
358
+ 'properties',
359
+ 'aWrongObjectField',
360
+ 'values',
361
+ ],
362
+ },
363
+ ],
364
+ });
365
+ });
366
+ test('enum', async (t) => {
367
+ t.deepEqual(await validateSchema({
368
+ root: {
369
+ fields: {
370
+ enumField: {
371
+ enum: ['one', 'two'],
372
+ },
373
+ },
374
+ },
375
+ }), {
376
+ valid: true,
377
+ });
378
+ t.deepEqual(await validateSchema({
379
+ root: {
380
+ fields: {
381
+ enumField: {
382
+ enum: [1, 2],
383
+ },
384
+ },
385
+ },
386
+ }), {
387
+ valid: true,
388
+ });
389
+ t.deepEqual(await validateSchema({
390
+ root: {
391
+ fields: {
392
+ enumField: {
393
+ enum: [{ one: 'one' }, { two: 'two' }],
394
+ },
395
+ },
396
+ },
397
+ }), {
398
+ valid: true,
399
+ });
400
+ t.deepEqual(await validateSchema({
401
+ root: {
402
+ fields: {
403
+ enumField: {
404
+ // @ts-ignore
405
+ enum: 'invalidEnum',
406
+ },
407
+ },
408
+ },
409
+ }), {
410
+ errors: [
411
+ {
412
+ code: ParseError.incorrectFormat,
413
+ path: ['root', 'fields', 'enumField', 'enum'],
414
+ },
415
+ ],
416
+ });
417
+ t.deepEqual(await validateSchema({
418
+ root: {
419
+ fields: {
420
+ enumField: {
421
+ enum: ['one', 'two'],
422
+ // @ts-ignore
423
+ invalidProperty: 'invalid',
424
+ },
425
+ },
426
+ },
427
+ }), {
428
+ errors: [
429
+ {
430
+ code: ParseError.invalidProperty,
431
+ path: ['root', 'fields', 'enumField', 'invalidProperty'],
432
+ },
433
+ ],
434
+ });
435
+ });
436
+ //# sourceMappingURL=fields.js.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,124 @@
1
+ import anyTest from 'ava';
2
+ import { validateSchema } from '../../src/validateSchema/index.js';
3
+ import { ParseError } from '../../src/error.js';
4
+ const test = anyTest;
5
+ test('should not allow non object schemas', async (t) => {
6
+ t.deepEqual(await validateSchema(undefined), {
7
+ errors: [{ code: ParseError.invalidSchemaFormat }],
8
+ });
9
+ t.deepEqual(await validateSchema(null), {
10
+ errors: [{ code: ParseError.invalidSchemaFormat }],
11
+ });
12
+ // @ts-ignore
13
+ t.deepEqual(await validateSchema('this is a string'), {
14
+ errors: [{ code: ParseError.invalidSchemaFormat }],
15
+ });
16
+ // @ts-ignore
17
+ t.deepEqual(await validateSchema(1), {
18
+ errors: [{ code: ParseError.invalidSchemaFormat }],
19
+ });
20
+ });
21
+ test('`languages` property', async (t) => {
22
+ t.deepEqual(await validateSchema({ language: 'en' }), {
23
+ valid: true,
24
+ });
25
+ // @ts-ignore
26
+ t.deepEqual(await validateSchema({ language: 'xx' }), {
27
+ errors: [{ code: ParseError.languageNotSupported, path: ['language'] }],
28
+ });
29
+ });
30
+ test('`translations` property', async (t) => {
31
+ t.deepEqual(await validateSchema({
32
+ language: 'en',
33
+ translations: ['fr', 'pt'],
34
+ }), {
35
+ valid: true,
36
+ });
37
+ t.deepEqual(await validateSchema({
38
+ language: 'en',
39
+ // @ts-ignore
40
+ translations: 'de',
41
+ }), {
42
+ errors: [{ code: ParseError.incorrectFormat, path: ['translations'] }],
43
+ });
44
+ t.deepEqual(await validateSchema({
45
+ language: 'en',
46
+ // @ts-ignore
47
+ translations: ['pt', 'xx'],
48
+ }), {
49
+ errors: [
50
+ { code: ParseError.languageNotSupported, path: ['translations'] },
51
+ ],
52
+ });
53
+ });
54
+ test('`languageFallbacks` property', async (t) => {
55
+ t.deepEqual(await validateSchema({
56
+ language: 'en',
57
+ translations: ['fr', 'pt'],
58
+ languageFallbacks: {
59
+ fr: ['en'],
60
+ pt: ['fr', 'pt'],
61
+ },
62
+ }), {
63
+ valid: true,
64
+ });
65
+ t.deepEqual(await validateSchema({
66
+ language: 'en',
67
+ translations: ['fr', 'pt'],
68
+ // @ts-ignore
69
+ languageFallbacks: 'pt',
70
+ }), {
71
+ errors: [
72
+ { code: ParseError.incorrectFormat, path: ['languageFallbacks'] },
73
+ ],
74
+ });
75
+ t.deepEqual(await validateSchema({
76
+ language: 'en',
77
+ translations: ['fr', 'pt'],
78
+ // @ts-ignore
79
+ languageFallbacks: ['pt'],
80
+ }), {
81
+ errors: [
82
+ { code: ParseError.incorrectFormat, path: ['languageFallbacks'] },
83
+ ],
84
+ });
85
+ t.deepEqual(await validateSchema({
86
+ language: 'en',
87
+ translations: ['fr', 'pt'],
88
+ languageFallbacks: {
89
+ fr: ['en'],
90
+ // @ts-ignore
91
+ pt: ['xx', 'pt'],
92
+ },
93
+ }), {
94
+ errors: [
95
+ { code: ParseError.noLanguageFound, path: ['languageFallbacks'] },
96
+ ],
97
+ });
98
+ t.deepEqual(await validateSchema({
99
+ language: 'en',
100
+ translations: ['fr', 'pt'],
101
+ languageFallbacks: {
102
+ // @ts-ignore
103
+ fr: 'en',
104
+ },
105
+ }), {
106
+ errors: [
107
+ { code: ParseError.incorrectFormat, path: ['languageFallbacks'] },
108
+ ],
109
+ });
110
+ t.deepEqual(await validateSchema({
111
+ language: 'en',
112
+ translations: ['fr', 'pt'],
113
+ languageFallbacks: {
114
+ fr: ['en'],
115
+ // @ts-ignore
116
+ xx: ['fr', 'pt'],
117
+ },
118
+ }), {
119
+ errors: [
120
+ { code: ParseError.noLanguageFound, path: ['languageFallbacks'] },
121
+ ],
122
+ });
123
+ });
124
+ //# sourceMappingURL=languages.js.map
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import test from 'ava';
2
+ import { newSchemas } from '../data/newSchemas.js';
3
+ import { validateSchema } from '../../src/index.js';
4
+ test('these schemas should work', async (t) => {
5
+ await Promise.all(newSchemas.map(async (validSchema) => {
6
+ const validation = await validateSchema(validSchema);
7
+ if (!validation.valid) {
8
+ console.dir(validation.errors, { depth: null });
9
+ }
10
+ t.true(validation.valid);
11
+ }));
12
+ });
13
+ //# sourceMappingURL=realWorld.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@based/schema",
3
- "version": "2.6.0",
3
+ "version": "2.7.1",
4
4
  "license": "MIT",
5
5
  "main": "dist/src/index.js",
6
6
  "files": [
@@ -26,7 +26,8 @@
26
26
  "ava": {
27
27
  "timeout": "2m",
28
28
  "files": [
29
- "./dist/test/*.js"
29
+ "./dist/test/*.js",
30
+ "./dist/test/validateSchema/*.js"
30
31
  ]
31
32
  },
32
33
  "devDependencies": {
@@ -35,6 +36,6 @@
35
36
  "ts-node": "10.9.1",
36
37
  "typescript": "^5.1.6",
37
38
  "rimraf": "^3.0.2",
38
- "ava": "5.3.1"
39
+ "ava": "6.1.1"
39
40
  }
40
41
  }
@@ -1,4 +0,0 @@
1
- import { BasedSchemaPartial, BasedSchemaFieldPartial, BasedSchemaTypePartial } from './types.js';
2
- export declare const validateType: (_fromSchema: BasedSchemaPartial, typeName: string, type: BasedSchemaTypePartial) => void;
3
- export declare const validateField: (_fromSchema: BasedSchemaPartial, _path: string[], _field: BasedSchemaFieldPartial) => void;
4
- export declare const validateSchema: (schema: BasedSchemaPartial) => BasedSchemaPartial;