@based/schema 0.0.16 → 1.0.2

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 (105) hide show
  1. package/dist/error.d.ts +18 -0
  2. package/dist/error.js +31 -0
  3. package/dist/error.js.map +1 -0
  4. package/dist/index.d.ts +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/index.js.map +1 -1
  7. package/dist/set/collections.js +14 -32
  8. package/dist/set/collections.js.map +1 -1
  9. package/dist/set/error.d.ts +1 -2
  10. package/dist/set/error.js +3 -8
  11. package/dist/set/error.js.map +1 -1
  12. package/dist/set/fields/array.d.ts +2 -0
  13. package/dist/set/fields/array.js +96 -0
  14. package/dist/set/fields/array.js.map +1 -0
  15. package/dist/set/fields/index.d.ts +3 -0
  16. package/dist/set/fields/index.js +72 -0
  17. package/dist/set/fields/index.js.map +1 -0
  18. package/dist/set/fields/number.d.ts +4 -0
  19. package/dist/set/fields/number.js +121 -0
  20. package/dist/set/fields/number.js.map +1 -0
  21. package/dist/set/fields/object.d.ts +3 -0
  22. package/dist/set/fields/object.js +33 -0
  23. package/dist/set/fields/object.js.map +1 -0
  24. package/dist/set/fields/references.d.ts +3 -0
  25. package/dist/set/fields/references.js +106 -0
  26. package/dist/set/fields/references.js.map +1 -0
  27. package/dist/set/fields/set.d.ts +2 -0
  28. package/dist/set/fields/set.js +63 -0
  29. package/dist/set/fields/set.js.map +1 -0
  30. package/dist/set/fields/string.d.ts +3 -0
  31. package/dist/set/fields/string.js +190 -0
  32. package/dist/set/fields/string.js.map +1 -0
  33. package/dist/set/index.d.ts +2 -5
  34. package/dist/set/index.js +101 -126
  35. package/dist/set/index.js.map +1 -1
  36. package/dist/set/isValidId.d.ts +2 -0
  37. package/dist/set/isValidId.js +21 -0
  38. package/dist/set/isValidId.js.map +1 -0
  39. package/dist/set/number.js +23 -36
  40. package/dist/set/number.js.map +1 -1
  41. package/dist/set/parseDefaultAndValue.js +1 -3
  42. package/dist/set/parseDefaultAndValue.js.map +1 -1
  43. package/dist/set/references.js +5 -12
  44. package/dist/set/references.js.map +1 -1
  45. package/dist/set/rest.js +4 -4
  46. package/dist/set/rest.js.map +1 -1
  47. package/dist/set/string.js +35 -35
  48. package/dist/set/string.js.map +1 -1
  49. package/dist/set/types.d.ts +0 -5
  50. package/dist/set/types.js +0 -2
  51. package/dist/types.d.ts +7 -1
  52. package/dist/types.js.map +1 -1
  53. package/dist/walker/args.d.ts +31 -0
  54. package/dist/walker/args.js +120 -0
  55. package/dist/walker/args.js.map +1 -0
  56. package/dist/walker/index.d.ts +6 -0
  57. package/dist/walker/index.js +40 -0
  58. package/dist/walker/index.js.map +1 -0
  59. package/dist/walker/parse.d.ts +2 -0
  60. package/dist/walker/parse.js +157 -0
  61. package/dist/walker/parse.js.map +1 -0
  62. package/dist/walker/types.d.ts +44 -0
  63. package/dist/walker/types.js +9 -0
  64. package/dist/walker/types.js.map +1 -0
  65. package/package.json +2 -2
  66. package/src/{set/error.ts → error.ts} +3 -1
  67. package/src/index.ts +2 -2
  68. package/src/set/fields/array.ts +111 -0
  69. package/src/set/fields/index.ts +69 -0
  70. package/src/set/fields/number.ts +134 -0
  71. package/src/set/fields/object.ts +30 -0
  72. package/src/set/fields/references.ts +114 -0
  73. package/src/set/fields/set.ts +63 -0
  74. package/src/set/fields/string.ts +199 -0
  75. package/src/set/index.ts +105 -187
  76. package/src/set/isValidId.ts +23 -0
  77. package/src/set/types.ts +0 -20
  78. package/src/types.ts +4 -2
  79. package/src/walker/args.ts +159 -0
  80. package/src/walker/index.ts +35 -0
  81. package/src/walker/parse.ts +193 -0
  82. package/src/walker/types.ts +75 -0
  83. package/test/number.ts +289 -543
  84. package/test/reference.ts +150 -198
  85. package/test/rest.ts +227 -0
  86. package/test/string.ts +139 -183
  87. package/test/utils/index.ts +23 -0
  88. package/test/walker.ts +558 -3
  89. package/dist/set2/index.d.ts +0 -0
  90. package/dist/set2/index.js +0 -71
  91. package/dist/set2/index.js.map +0 -1
  92. package/dist/walker.d.ts +0 -51
  93. package/dist/walker.js +0 -120
  94. package/dist/walker.js.map +0 -1
  95. package/src/set/collections.ts +0 -338
  96. package/src/set/number.ts +0 -167
  97. package/src/set/parseDefaultAndValue.ts +0 -54
  98. package/src/set/parsers.ts +0 -20
  99. package/src/set/references.ts +0 -113
  100. package/src/set/rest.ts +0 -135
  101. package/src/set/string.ts +0 -254
  102. package/src/set2/index.ts +0 -71
  103. package/src/walker.ts +0 -201
  104. package/test/setWalker.ts +0 -494
  105. package/test/text.ts +0 -171
package/src/walker.ts DELETED
@@ -1,201 +0,0 @@
1
- import { ParseError } from './set/error'
2
- import { BasedSchema, BasedSetHandlers, BasedSetTarget } from './types'
3
- import { BasedSchemaType, BasedSchemaFields } from './types'
4
-
5
- type Path = (string | number)[]
6
-
7
- type ErrorHandler<T> = (args: Args<T>, code: ParseError) => void
8
-
9
- type Parse<T> = (
10
- args: Args<T>,
11
- key?: string | number,
12
- value?: any
13
- ) => Promise<Args<T> | void> // If true will not continue
14
-
15
- type BackTrack<T> = (
16
- args: Args<T>,
17
- fromBackTrack: any[],
18
- collectedCommands: any[]
19
- ) => any
20
-
21
- export type Args<
22
- T,
23
- K extends keyof BasedSchemaFields = keyof BasedSchemaFields
24
- > = {
25
- schema: BasedSchema
26
- parentValue?: any
27
- skipCollection?: boolean
28
- fieldSchema?: BasedSchemaFields[K]
29
- typeSchema?: BasedSchemaType
30
- path: Path
31
- key?: number | string
32
- value: any
33
- target: T
34
- fromBackTrack: any[]
35
- parse: Parse<T>
36
- collect: (args: Args<T>) => any
37
- backtrack: BackTrack<T>
38
- requiresAsyncValidation: (validationType: any) => Promise<any>
39
- error: ErrorHandler<T>
40
- }
41
-
42
- export type FieldParser<K extends keyof BasedSchemaFields, T = any> = (
43
- args: Args<T, K>
44
- ) => Promise<Args<T> | void>
45
-
46
- export type KeyParser<T = any> = (
47
- args: Args<T, keyof BasedSchemaFields>
48
- ) => Promise<Args<T> | void>
49
-
50
- export type Opts<T> = {
51
- schema: BasedSchema
52
- init: (args: Args<T>) => Promise<Args<T>>
53
- parsers: {
54
- fields: Partial<{
55
- [Key in keyof BasedSchemaFields]: FieldParser<Key, T>
56
- }>
57
- keys: { [key: string]: KeyParser<T> } // $list -> true
58
- any: KeyParser<T> // y.x
59
- }
60
- collect?: (args: Args<T>) => any
61
- backtrack?: BackTrack<T>
62
- requiresAsyncValidation?: (validationType: any) => Promise<boolean>
63
- errorsCollector?: ErrorHandler<T>
64
- }
65
-
66
- export const walk = async <T>(
67
- opts: Opts<T>,
68
- value: any
69
- ): Promise<{
70
- target: T
71
- errors: { code: ParseError; message: string }[]
72
- }> => {
73
- const errors: { code: ParseError; message: string }[] = []
74
-
75
- if (!('collect' in opts)) {
76
- opts.collect = () => {}
77
- }
78
-
79
- if (!('backtrack' in opts)) {
80
- opts.backtrack = (args, btC, c) => btC
81
- }
82
-
83
- if (!('requiresAsyncValidation' in opts)) {
84
- opts.requiresAsyncValidation = async () => true
85
- }
86
-
87
- const errorsCollector: ErrorHandler<T> = (args, code) => {
88
- const err = {
89
- code,
90
- message: `Error in ${args.path.join('.')}`,
91
- }
92
- if (opts.errorsCollector) {
93
- opts.errorsCollector(args, code)
94
- }
95
- errors.push(err)
96
- }
97
-
98
- const parse: Parse<T> = async (prevArgs, key, value) => {
99
- const collectedCommands: any[] = []
100
- const fromBackTrack: any[] = []
101
- const args: Args<T> = {
102
- schema: opts.schema,
103
- path: key ? [...prevArgs.path, key] : prevArgs.path,
104
- key: key ?? prevArgs.path[prevArgs.path.length - 1],
105
- parentValue: value ? prevArgs.value : undefined,
106
- value: value ?? prevArgs.value,
107
- target: prevArgs.target,
108
- parse: prevArgs.parse,
109
- collect: (args) => {
110
- collectedCommands.push(opts.collect(args))
111
- },
112
- fromBackTrack,
113
- backtrack: opts.backtrack,
114
- error: errorsCollector,
115
- requiresAsyncValidation: prevArgs.requiresAsyncValidation,
116
- }
117
- if (typeof args.value === 'object' && args.value !== null) {
118
- const q: Promise<Args<T> | void>[] = []
119
-
120
- if (args.typeSchema && !args.fieldSchema) {
121
- // top level
122
- }
123
-
124
- if (args.fieldSchema) {
125
- //
126
- }
127
-
128
- // first do key parsers
129
-
130
- if (Array.isArray(args.value)) {
131
- for (let i = 0; i < args.value.length; i++) {
132
- const parser = opts.parsers.keys[i] || opts.parsers.any
133
- const j = i
134
- q.push(
135
- (async () => {
136
- const newArgs = await parser({
137
- ...args,
138
- value: args.value[j],
139
- path: [...args.path, j],
140
- key: j,
141
- })
142
- if (newArgs) {
143
- return parse(newArgs)
144
- }
145
- })()
146
- )
147
- }
148
- } else {
149
- for (const key in args.value) {
150
- const parser = opts.parsers.keys[key] || opts.parsers.any
151
- q.push(
152
- (async () => {
153
- const newArgs = await parser({
154
- ...args,
155
- value: args.value[key],
156
- path: [...args.path, key],
157
- key,
158
- })
159
- if (newArgs) {
160
- return parse(newArgs)
161
- }
162
- })()
163
- )
164
- }
165
- }
166
-
167
- await Promise.all(q)
168
-
169
- if (fromBackTrack.length || collectedCommands.length) {
170
- const x = args.backtrack(args, fromBackTrack, collectedCommands)
171
- if (x) {
172
- prevArgs.fromBackTrack?.push(x)
173
- }
174
- }
175
- }
176
- }
177
- const args: Args<T> = await opts.init(<Args<T>>{
178
- schema: opts.schema,
179
- path: [],
180
- value,
181
- parse,
182
- collect: opts.collect,
183
- backtrack: opts.backtrack,
184
- error: errorsCollector,
185
- requiresAsyncValidation: opts.requiresAsyncValidation,
186
- })
187
-
188
- if (!args) {
189
- return {
190
- // TODO: temp
191
- // @ts-ignore // for now
192
- target: {},
193
- errors,
194
- }
195
- }
196
- await parse(args)
197
- return {
198
- target: args.target,
199
- errors,
200
- }
201
- }
package/test/setWalker.ts DELETED
@@ -1,494 +0,0 @@
1
- import test from 'ava'
2
- import { BasedSchema, setWalker } from '../src/index'
3
-
4
- const schema: BasedSchema = {
5
- types: {
6
- bla: {
7
- prefix: 'bl',
8
- fields: {
9
- visits: {
10
- type: 'cardinality',
11
- },
12
- blub: {
13
- type: 'number',
14
- },
15
- flap: {
16
- type: 'number',
17
- },
18
- snurpobject: {
19
- type: 'object',
20
- properties: {
21
- x: {
22
- type: 'string',
23
- },
24
- },
25
- },
26
- snurp: {
27
- type: 'array',
28
- values: {
29
- type: 'object',
30
- properties: {
31
- x: {
32
- type: 'array',
33
- values: {
34
- type: 'number',
35
- },
36
- },
37
- },
38
- },
39
- },
40
- setje: {
41
- type: 'set',
42
- items: { type: 'number' },
43
- },
44
- specialArray: {
45
- type: 'array',
46
- values: {
47
- type: 'string',
48
- },
49
- },
50
- snurpArray: {
51
- type: 'array',
52
- values: {
53
- type: 'number',
54
- },
55
- },
56
- powerLevel: {
57
- type: 'integer',
58
- },
59
- bla: {
60
- type: 'boolean',
61
- },
62
- time: {
63
- type: 'timestamp',
64
- },
65
- form: {
66
- title: 'A registration form',
67
- description: 'A simple form example.',
68
- type: 'object',
69
- required: ['firstName', 'lastName'],
70
- properties: {
71
- bla: {
72
- type: 'references',
73
- },
74
- blab: {
75
- type: 'references',
76
- },
77
- snurp: {
78
- type: 'reference',
79
- },
80
- things: {
81
- enum: ['yuzi', 'jux', 'mr tony', 9000],
82
- },
83
- blub: {
84
- type: 'set',
85
- items: { type: 'string' },
86
- },
87
- json: {
88
- type: 'json',
89
- },
90
- firstName: {
91
- type: 'string',
92
- title: 'First name',
93
- default: 'Chuck',
94
- },
95
- lastName: {
96
- type: 'string',
97
- title: 'Last name',
98
- },
99
- age: {
100
- type: 'integer',
101
- title: 'Age',
102
- },
103
- bio: {
104
- type: 'string',
105
- title: 'Bio',
106
- },
107
- password: {
108
- type: 'string',
109
- title: 'Password',
110
- minLength: 3,
111
- },
112
- telephone: {
113
- type: 'string',
114
- title: 'Telephone',
115
- minLength: 10,
116
- },
117
- },
118
- },
119
- },
120
- },
121
- },
122
- $defs: {},
123
- languages: ['en'],
124
- root: {
125
- fields: {},
126
- },
127
- prefixToTypeMapping: {
128
- bl: 'bla',
129
- },
130
- }
131
-
132
- test('collect correctly', async (t) => {
133
- const results: { path: (string | number)[]; value: any }[] = []
134
- const now = Date.now()
135
- await setWalker(
136
- schema,
137
- {
138
- $id: 'bl1',
139
- visits: {
140
- flap: true,
141
- snurp: false,
142
- ua: '123435',
143
- },
144
- blub: {
145
- $increment: 1,
146
- },
147
- bla: false,
148
- time: now,
149
- setje: [1, 2, 3],
150
- form: {
151
- lastName: 'de beer',
152
- bla: ['bl123', 'bl234'],
153
- blab: { $add: ['bl456'] },
154
- blub: ['x'],
155
- json: { bla: 1, x: 2, y: 3 },
156
- snurp: 'blx12',
157
- things: 'mr tony',
158
- password: 'mypassword!',
159
- },
160
- snurpArray: {
161
- $assign: {
162
- $idx: 0,
163
- $value: 100,
164
- },
165
- },
166
- specialArray: {
167
- $insert: {
168
- $value: ['a', 'b', 'c'],
169
- $idx: 0,
170
- },
171
- },
172
- snurp: [
173
- {
174
- x: [1, 2, 3],
175
- },
176
- ],
177
- },
178
- {
179
- collectErrors: (info) => {
180
- // fix fields (too heavy)
181
- },
182
- collect: ({ path, value, typeSchema, fieldSchema, target }) => {
183
- results.push({
184
- path,
185
- value,
186
- })
187
- },
188
- checkRequiredFields: async (path) => {
189
- return true
190
- },
191
- referenceFilterCondition: async (id, filter) => {
192
- return true
193
- },
194
- }
195
- )
196
-
197
- const result = [
198
- { path: ['visits'], value: '3a9009740ee' },
199
- { path: ['blub'], value: { $increment: 1 } },
200
- { path: ['time'], value: now },
201
- { path: ['form', 'snurp'], value: 'blx12' },
202
- {
203
- path: ['snurpArray', 0],
204
- value: 100,
205
- },
206
- { path: ['bla'], value: false },
207
- { path: ['form', 'lastName'], value: 'de beer' },
208
- { path: ['form', 'json'], value: '{"bla":1,"x":2,"y":3}' },
209
- { path: ['form', 'things'], value: 2 },
210
- { path: ['form', 'password'], value: 'mypassword!' },
211
- { path: ['form', 'bla'], value: { $value: ['bl123', 'bl234'] } },
212
- { path: ['form', 'blab'], value: { $add: ['bl456'] } },
213
- { path: ['setje'], value: { $value: [1, 2, 3] } },
214
- { path: ['form', 'blub'], value: { $value: ['x'] } },
215
- {
216
- path: ['specialArray'],
217
- value: { $insert: { $value: ['a', 'b', 'c'], $idx: 0 } },
218
- },
219
- { path: ['snurp'], value: { $delete: true } },
220
- { path: ['snurp', 0, 'x'], value: { $delete: true } },
221
- { path: ['snurp', 0, 'x', 0], value: 1 },
222
- { path: ['snurp', 0, 'x', 1], value: 2 },
223
- { path: ['snurp', 0, 'x', 2], value: 3 },
224
- ]
225
-
226
- t.deepEqual(results, result)
227
-
228
- const results2: any[] = []
229
- await setWalker(
230
- schema,
231
- {
232
- $id: 'bl1',
233
- blub: {
234
- $value: 4,
235
- },
236
- flap: {
237
- $default: 1,
238
- },
239
- },
240
- {
241
- collectErrors: (info) => {
242
- // {
243
- // path,
244
- // value,
245
- // typeSchema,
246
- // fieldSchema,
247
- // target,
248
- // code,
249
- // message,
250
- // }
251
-
252
- console.error(info.message)
253
- // fix fields (too heavy)
254
- },
255
- collect: ({ path, value, typeSchema, fieldSchema, target }) => {
256
- results2.push({
257
- path,
258
- value,
259
- })
260
- },
261
- checkRequiredFields: async (path) => {
262
- return false
263
- },
264
- referenceFilterCondition: async (id, filter) => {
265
- return true
266
- },
267
- }
268
- )
269
-
270
- t.deepEqual(results2, [
271
- { path: ['blub'], value: { $value: 4 } },
272
- { path: ['flap'], value: { $default: 1 } },
273
- ])
274
-
275
- const results3: any[] = []
276
- await setWalker(
277
- schema,
278
- {
279
- $id: 'bl1',
280
- snurpArray: {
281
- $push: 1,
282
- },
283
- specialArray: {
284
- $push: { $value: 'flap' },
285
- },
286
- },
287
- {
288
- collectErrors: (info) => {
289
- // {
290
- // path,
291
- // value,
292
- // typeSchema,
293
- // fieldSchema,
294
- // target,
295
- // code,
296
- // message,
297
- // }
298
-
299
- console.error(info.message)
300
- // fix fields (too heavy)
301
- },
302
- collect: ({ path, value, typeSchema, fieldSchema, target }) => {
303
- results3.push({
304
- path,
305
- value,
306
- })
307
- },
308
- checkRequiredFields: async (path) => {
309
- return false
310
- },
311
- referenceFilterCondition: async (id, filter) => {
312
- return true
313
- },
314
- }
315
- )
316
-
317
- t.deepEqual(results3, [
318
- { path: ['snurpArray'], value: { $push: [1] } },
319
- { path: ['specialArray'], value: { $push: [{ $value: 'flap' }] } },
320
- ])
321
- })
322
-
323
- test('required', async (t) => {
324
- const schema: BasedSchema = {
325
- types: {
326
- bla: {
327
- prefix: 'bl',
328
- required: ['blub', 'flap', 'snurp'],
329
- fields: {
330
- blub: {
331
- type: 'number',
332
- },
333
- flap: {
334
- type: 'number',
335
- },
336
- snurp: {
337
- type: 'object',
338
- required: ['x'],
339
- properties: {
340
- x: {
341
- type: 'object',
342
- required: ['a', 'b', 'c'],
343
- properties: {
344
- a: { type: 'string' },
345
- b: { type: 'string' },
346
- c: { type: 'string' },
347
- },
348
- },
349
- },
350
- },
351
- array: {
352
- type: 'array',
353
- values: {
354
- type: 'object',
355
- required: ['a', 'b', 'c'],
356
- properties: {
357
- a: { type: 'string' },
358
- b: { type: 'string' },
359
- c: { type: 'string' },
360
- },
361
- },
362
- },
363
- },
364
- },
365
- },
366
- $defs: {},
367
- languages: ['en'],
368
- root: {
369
- fields: {},
370
- },
371
- prefixToTypeMapping: {
372
- bl: 'bla',
373
- },
374
- }
375
-
376
- const t1 = await setWalker(
377
- schema,
378
- {
379
- type: 'bla',
380
- blub: 1,
381
- flap: 1,
382
- snurp: {
383
- x: { a: 'b' },
384
- },
385
- },
386
- {
387
- collectErrors: (info) => {
388
- // {
389
- // path,
390
- // value,
391
- // typeSchema,
392
- // fieldSchema,
393
- // target,
394
- // code,
395
- // message,
396
- // }
397
-
398
- console.error(info.message)
399
- // fix fields (too heavy)
400
- },
401
- collect: ({ path, value, typeSchema, fieldSchema, target }) => {},
402
- checkRequiredFields: async (paths) => {
403
- return true
404
- },
405
- referenceFilterCondition: async (id, filter) => {
406
- return true
407
- },
408
- }
409
- )
410
-
411
- t.deepEqual(t1.required, [
412
- ['snurp', 'x', 'b'],
413
- ['snurp', 'x', 'c'],
414
- ])
415
-
416
- const t2 = await setWalker(
417
- schema,
418
- {
419
- type: 'bla',
420
- array: [
421
- {
422
- a: 'hello', // say cant set non existing field
423
- },
424
- ],
425
- },
426
- {
427
- collectErrors: (info) => {
428
- // {
429
- // path,
430
- // value,
431
- // typeSchema,
432
- // fieldSchema,
433
- // target,
434
- // code,
435
- // message,
436
- // }
437
-
438
- console.error(info.message)
439
- // fix fields (too heavy)
440
- },
441
- collect: ({ path, value, typeSchema, fieldSchema, target }) => {},
442
- checkRequiredFields: async (paths) => {
443
- // should be [snurp.x.b, snurp.x.c]
444
- return true
445
- },
446
- referenceFilterCondition: async (id, filter) => {
447
- return true
448
- },
449
- }
450
- )
451
-
452
- t.deepEqual(t2.required, [
453
- ['array', 0, 'b'],
454
- ['array', 0, 'c'],
455
- ['blub'],
456
- ['flap'],
457
- ['snurp'],
458
- ])
459
-
460
- t.true(true)
461
- })
462
-
463
- test.only('collect all errors', async (t) => {
464
- try {
465
- await setWalker(
466
- schema,
467
- {
468
- type: 'bla',
469
- blub: 'snux',
470
- flap: 'gurt',
471
- snurpobject: {
472
- x: 1,
473
- },
474
- // wrong validate total objects
475
- snurp: {
476
- // checking non formatted objects
477
- x: { a: 20220 },
478
- },
479
- },
480
- {
481
- checkRequiredFields: async (paths) => {
482
- return true
483
- },
484
- referenceFilterCondition: async (id, filter) => {
485
- return true
486
- },
487
- }
488
- )
489
- } catch (err) {
490
- console.info(err)
491
- }
492
-
493
- t.true(true)
494
- })