@based/schema 0.0.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.
- package/README.md +21 -0
- package/dist/deepPartial.d.ts +0 -0
- package/dist/deepPartial.js +3 -0
- package/dist/deepPartial.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/languages.d.ts +187 -0
- package/dist/languages.js +190 -0
- package/dist/languages.js.map +1 -0
- package/dist/schema.d.ts +1 -0
- package/dist/schema.js +3 -0
- package/dist/schema.js.map +1 -0
- package/dist/set/enum.d.ts +2 -0
- package/dist/set/enum.js +15 -0
- package/dist/set/enum.js.map +1 -0
- package/dist/set/fieldValidator.d.ts +6 -0
- package/dist/set/fieldValidator.js +144 -0
- package/dist/set/fieldValidator.js.map +1 -0
- package/dist/set/handleError.d.ts +1 -0
- package/dist/set/handleError.js +9 -0
- package/dist/set/handleError.js.map +1 -0
- package/dist/set/index.d.ts +5 -0
- package/dist/set/index.js +93 -0
- package/dist/set/index.js.map +1 -0
- package/dist/set/parsers.d.ts +6 -0
- package/dist/set/parsers.js +287 -0
- package/dist/set/parsers.js.map +1 -0
- package/dist/setWalker.d.ts +11 -0
- package/dist/setWalker.js +189 -0
- package/dist/setWalker.js.map +1 -0
- package/dist/transformers.d.ts +3 -0
- package/dist/transformers.js +18 -0
- package/dist/transformers.js.map +1 -0
- package/dist/typeWalker.d.ts +3 -0
- package/dist/typeWalker.js +18 -0
- package/dist/typeWalker.js.map +1 -0
- package/dist/types.d.ts +163 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +4 -0
- package/dist/validate.js +34 -0
- package/dist/validate.js.map +1 -0
- package/dist/validateFields.d.ts +4 -0
- package/dist/validateFields.js +34 -0
- package/dist/validateFields.js.map +1 -0
- package/dist/validateSchema copy.d.ts +4 -0
- package/dist/validateSchema copy.js +34 -0
- package/dist/validateSchema copy.js.map +1 -0
- package/dist/validateSchema.d.ts +4 -0
- package/dist/validateSchema.js +34 -0
- package/dist/validateSchema.js.map +1 -0
- package/package.json +35 -0
- package/src/index.ts +5 -0
- package/src/languages.ts +188 -0
- package/src/set/handleError.ts +15 -0
- package/src/set/index.ts +135 -0
- package/src/set/parsers.ts +448 -0
- package/src/types.ts +277 -0
- package/src/validateSchema.ts +56 -0
- package/test/setWalker.ts +197 -0
- package/test/validateSchema.ts +42 -0
- package/tsconfig.json +9 -0
package/src/set/index.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BasedSchemaField,
|
|
3
|
+
BasedSchemaType,
|
|
4
|
+
BasedSetHandlers,
|
|
5
|
+
BasedSchema,
|
|
6
|
+
BasedSetTarget,
|
|
7
|
+
} from '../types'
|
|
8
|
+
import { createError } from './handleError'
|
|
9
|
+
import parsers from './parsers'
|
|
10
|
+
|
|
11
|
+
// Collect is a pretty good place for checking if a user is allowed to set something
|
|
12
|
+
// also make collect async
|
|
13
|
+
|
|
14
|
+
// add extra function for loading required
|
|
15
|
+
|
|
16
|
+
export const fieldWalker = async (
|
|
17
|
+
path: (string | number)[],
|
|
18
|
+
value: any,
|
|
19
|
+
fieldSchema: BasedSchemaField,
|
|
20
|
+
typeSchema: BasedSchemaType,
|
|
21
|
+
target: BasedSetTarget,
|
|
22
|
+
handlers: BasedSetHandlers
|
|
23
|
+
): Promise<void> => {
|
|
24
|
+
if ('$ref' in fieldSchema) {
|
|
25
|
+
// TODO: when we have this it has to get it from the schema and redo the parsing with the correct fieldSchema
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
const valueType = typeof value
|
|
29
|
+
|
|
30
|
+
const valueIsObject = value && valueType === 'object'
|
|
31
|
+
if (valueIsObject && value.$delete === true) {
|
|
32
|
+
handlers.collect({ path, value, typeSchema, fieldSchema, target })
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const typeDef =
|
|
37
|
+
'type' in fieldSchema
|
|
38
|
+
? fieldSchema.type
|
|
39
|
+
: 'enum' in fieldSchema
|
|
40
|
+
? 'enum'
|
|
41
|
+
: ''
|
|
42
|
+
|
|
43
|
+
if (!typeDef) {
|
|
44
|
+
throw createError(path, target.type, typeDef, path[path.length - 1])
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if ('customValidator' in fieldSchema) {
|
|
48
|
+
const customValidator = fieldSchema.customValidator
|
|
49
|
+
if (!(await customValidator(value, path, target))) {
|
|
50
|
+
throw createError(path, target.type, typeDef, value)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const parse = parsers[typeDef]
|
|
55
|
+
|
|
56
|
+
await parse(path, value, fieldSchema, typeSchema, target, handlers)
|
|
57
|
+
|
|
58
|
+
return
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const setWalker = async (
|
|
62
|
+
schema: BasedSchema,
|
|
63
|
+
value: { [key: string]: any },
|
|
64
|
+
handlers: BasedSetHandlers
|
|
65
|
+
): Promise<BasedSetTarget> => {
|
|
66
|
+
let type: string
|
|
67
|
+
|
|
68
|
+
if (value.$id) {
|
|
69
|
+
type = schema.prefixToTypeMapping[value.$id.slice(0, 2)]
|
|
70
|
+
if (!type) {
|
|
71
|
+
throw new Error(`Cannot find type for $id ${value.$id}`)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (value.type) {
|
|
76
|
+
if (type && value.type !== type) {
|
|
77
|
+
throw new Error(
|
|
78
|
+
`type from "$id" ${value.$id} does not match "type" field ${value.type}`
|
|
79
|
+
)
|
|
80
|
+
}
|
|
81
|
+
type = value.type
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const schemaType = schema.types[type]
|
|
85
|
+
|
|
86
|
+
if (!schemaType) {
|
|
87
|
+
throw new Error(`Cannot find schema definition for type ${type}`)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const target: BasedSetTarget = {
|
|
91
|
+
type,
|
|
92
|
+
schema,
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (value.$id) {
|
|
96
|
+
target.$id = value.$id
|
|
97
|
+
} else if (value.$alias) {
|
|
98
|
+
target.$alias = value.$alias
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const q: Promise<void>[] = []
|
|
102
|
+
|
|
103
|
+
for (const key in value) {
|
|
104
|
+
if (key[0] === '$') {
|
|
105
|
+
console.info('key is operator', key)
|
|
106
|
+
} else {
|
|
107
|
+
const fieldSchema = schemaType.fields[key]
|
|
108
|
+
if (!fieldSchema) {
|
|
109
|
+
throw new Error(
|
|
110
|
+
`Field does not exist in schema "${key}" on type "${type}"`
|
|
111
|
+
)
|
|
112
|
+
} else {
|
|
113
|
+
q.push(
|
|
114
|
+
fieldWalker(
|
|
115
|
+
[key],
|
|
116
|
+
value[key],
|
|
117
|
+
fieldSchema,
|
|
118
|
+
schemaType,
|
|
119
|
+
target,
|
|
120
|
+
handlers
|
|
121
|
+
)
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
await Promise.all(q)
|
|
128
|
+
|
|
129
|
+
// required fields (collect them!)
|
|
130
|
+
// if (!(await handlers.requiredFields(value, [], target))) {
|
|
131
|
+
// throw new Error('Missing required fields')
|
|
132
|
+
// }
|
|
133
|
+
|
|
134
|
+
return target
|
|
135
|
+
}
|
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BasedSchemaField,
|
|
3
|
+
BasedSchemaType,
|
|
4
|
+
BasedSetHandlers,
|
|
5
|
+
BasedSetTarget,
|
|
6
|
+
} from '../types'
|
|
7
|
+
import { deepEqual } from '@saulx/utils'
|
|
8
|
+
import { createError } from './handleError'
|
|
9
|
+
import { fieldWalker } from '.'
|
|
10
|
+
|
|
11
|
+
type Parser = (
|
|
12
|
+
path: (string | number)[],
|
|
13
|
+
value: any,
|
|
14
|
+
fieldSchema: BasedSchemaField,
|
|
15
|
+
typeSchema: BasedSchemaType,
|
|
16
|
+
target: BasedSetTarget,
|
|
17
|
+
handlers: BasedSetHandlers
|
|
18
|
+
) => Promise<void>
|
|
19
|
+
|
|
20
|
+
const reference: Parser = async (
|
|
21
|
+
path,
|
|
22
|
+
value,
|
|
23
|
+
fieldSchema,
|
|
24
|
+
typeSchema,
|
|
25
|
+
target,
|
|
26
|
+
handlers
|
|
27
|
+
) => {
|
|
28
|
+
// $no root
|
|
29
|
+
|
|
30
|
+
// prob pass these as options
|
|
31
|
+
// value .default
|
|
32
|
+
// $value
|
|
33
|
+
|
|
34
|
+
if (typeof value !== 'string') {
|
|
35
|
+
throw createError(path, target.type, 'reference', value)
|
|
36
|
+
}
|
|
37
|
+
if ('allowedTypes' in fieldSchema) {
|
|
38
|
+
const prefix = value.slice(0, 2)
|
|
39
|
+
const targetType = target.schema.prefixToTypeMapping[prefix]
|
|
40
|
+
if (!targetType) {
|
|
41
|
+
throw createError(
|
|
42
|
+
path,
|
|
43
|
+
target.type,
|
|
44
|
+
'reference',
|
|
45
|
+
value,
|
|
46
|
+
'',
|
|
47
|
+
`${prefix} does not exist in database`
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
let typeMatches = false
|
|
51
|
+
for (const t of fieldSchema.allowedTypes) {
|
|
52
|
+
if (typeof t === 'string') {
|
|
53
|
+
if (t === targetType) {
|
|
54
|
+
typeMatches = true
|
|
55
|
+
break
|
|
56
|
+
}
|
|
57
|
+
} else {
|
|
58
|
+
if (t.type && t.type === targetType) {
|
|
59
|
+
typeMatches = true
|
|
60
|
+
if (t.$filter) {
|
|
61
|
+
if (!(await handlers.referenceFilterCondition(value, t.$filter))) {
|
|
62
|
+
throw createError(
|
|
63
|
+
path,
|
|
64
|
+
target.type,
|
|
65
|
+
'reference',
|
|
66
|
+
value,
|
|
67
|
+
'',
|
|
68
|
+
`${targetType} does not match allowedReferences`
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
} else if (!t.type && t.$filter) {
|
|
73
|
+
if (!(await handlers.referenceFilterCondition(value, t.$filter))) {
|
|
74
|
+
throw createError(
|
|
75
|
+
path,
|
|
76
|
+
target.type,
|
|
77
|
+
'reference',
|
|
78
|
+
value,
|
|
79
|
+
'',
|
|
80
|
+
`${targetType} does not match allowedReferences`
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (typeMatches === false) {
|
|
87
|
+
throw createError(
|
|
88
|
+
path,
|
|
89
|
+
target.type,
|
|
90
|
+
'reference',
|
|
91
|
+
value,
|
|
92
|
+
'',
|
|
93
|
+
`${targetType} does not match allowedReferences`
|
|
94
|
+
)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
handlers.collect({ path, value, typeSchema, fieldSchema, target })
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const parsers: {
|
|
101
|
+
[key: string]: Parser
|
|
102
|
+
} = {
|
|
103
|
+
enum: async (path, value, fieldSchema, typeSchema, target, handlers) => {
|
|
104
|
+
// value .default
|
|
105
|
+
|
|
106
|
+
// @ts-ignore
|
|
107
|
+
const enumValues = fieldSchema.enum
|
|
108
|
+
for (let i = 0; i < enumValues.length; i++) {
|
|
109
|
+
if (deepEqual(enumValues[i], value)) {
|
|
110
|
+
handlers.collect({ path, value: i, typeSchema, fieldSchema, target })
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
throw createError(path, target.type, 'enum', value)
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
array: async (path, value, fieldSchema, typeSchema, target, handlers) => {
|
|
118
|
+
// value .default
|
|
119
|
+
|
|
120
|
+
// TODO: ADD ARRAY OPERATORS
|
|
121
|
+
const isArray = Array.isArray(value)
|
|
122
|
+
|
|
123
|
+
if (typeof value === 'object' && !isArray) {
|
|
124
|
+
const q: Promise<void>[] = []
|
|
125
|
+
|
|
126
|
+
if (value.$insert) {
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (value.$remove) {
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (value.$push) {
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (value.$assign) {
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// value.$value :/
|
|
139
|
+
// fix
|
|
140
|
+
handlers.collect({ path, value, typeSchema, fieldSchema, target })
|
|
141
|
+
|
|
142
|
+
return
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (!isArray) {
|
|
146
|
+
throw createError(path, target.type, 'array', value)
|
|
147
|
+
}
|
|
148
|
+
const q: Promise<void>[] = []
|
|
149
|
+
for (let i = 0; i < value.length; i++) {
|
|
150
|
+
q.push(
|
|
151
|
+
fieldWalker(
|
|
152
|
+
[...path, i],
|
|
153
|
+
value[i],
|
|
154
|
+
// @ts-ignore
|
|
155
|
+
fieldSchema.values,
|
|
156
|
+
typeSchema,
|
|
157
|
+
target,
|
|
158
|
+
handlers
|
|
159
|
+
)
|
|
160
|
+
)
|
|
161
|
+
}
|
|
162
|
+
await Promise.all(q)
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
object: async (path, value, fieldSchema, typeSchema, target, handlers) => {
|
|
166
|
+
// value .default
|
|
167
|
+
|
|
168
|
+
if (typeof value !== 'object') {
|
|
169
|
+
throw createError(path, target.type, 'object', value)
|
|
170
|
+
}
|
|
171
|
+
const isArray = Array.isArray(value)
|
|
172
|
+
if (isArray) {
|
|
173
|
+
throw createError(path, target.type, 'object', value)
|
|
174
|
+
}
|
|
175
|
+
const q: Promise<void>[] = []
|
|
176
|
+
for (const key in value) {
|
|
177
|
+
// @ts-ignore
|
|
178
|
+
const propDef = fieldSchema.properties[key]
|
|
179
|
+
if (!propDef) {
|
|
180
|
+
throw createError(
|
|
181
|
+
[...path, key],
|
|
182
|
+
target.type,
|
|
183
|
+
'object',
|
|
184
|
+
value[key],
|
|
185
|
+
key
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
q.push(
|
|
189
|
+
fieldWalker(
|
|
190
|
+
[...path, key],
|
|
191
|
+
value[key],
|
|
192
|
+
propDef,
|
|
193
|
+
typeSchema,
|
|
194
|
+
target,
|
|
195
|
+
handlers
|
|
196
|
+
)
|
|
197
|
+
)
|
|
198
|
+
}
|
|
199
|
+
await Promise.all(q)
|
|
200
|
+
},
|
|
201
|
+
|
|
202
|
+
set: async (path, value, fieldSchema, typeSchema, target, handlers) => {
|
|
203
|
+
// value .default
|
|
204
|
+
|
|
205
|
+
const q: Promise<void>[] = []
|
|
206
|
+
// @ts-ignore
|
|
207
|
+
const fieldDef = fieldSchema.items
|
|
208
|
+
|
|
209
|
+
if (Array.isArray(value)) {
|
|
210
|
+
const handlerNest = {
|
|
211
|
+
...handlers,
|
|
212
|
+
collect: ({ path, value }) => {
|
|
213
|
+
parsedArray.push(value)
|
|
214
|
+
},
|
|
215
|
+
}
|
|
216
|
+
const parsedArray = []
|
|
217
|
+
for (let i = 0; i < value.length; i++) {
|
|
218
|
+
q.push(
|
|
219
|
+
fieldWalker(
|
|
220
|
+
[...path, i],
|
|
221
|
+
value[i],
|
|
222
|
+
fieldDef,
|
|
223
|
+
typeSchema,
|
|
224
|
+
target,
|
|
225
|
+
handlerNest
|
|
226
|
+
)
|
|
227
|
+
)
|
|
228
|
+
}
|
|
229
|
+
await Promise.all(q)
|
|
230
|
+
handlers.collect({
|
|
231
|
+
path,
|
|
232
|
+
value: parsedArray,
|
|
233
|
+
typeSchema,
|
|
234
|
+
fieldSchema,
|
|
235
|
+
target,
|
|
236
|
+
})
|
|
237
|
+
} else {
|
|
238
|
+
const handlerNest = {
|
|
239
|
+
...handlers,
|
|
240
|
+
collect: ({ path, value }) => {},
|
|
241
|
+
}
|
|
242
|
+
if (value.$add) {
|
|
243
|
+
for (let i = 0; i < value.$add.length; i++) {
|
|
244
|
+
q.push(
|
|
245
|
+
fieldWalker(
|
|
246
|
+
[...path, '$add', i],
|
|
247
|
+
value.$add[i],
|
|
248
|
+
fieldDef,
|
|
249
|
+
typeSchema,
|
|
250
|
+
target,
|
|
251
|
+
handlerNest
|
|
252
|
+
)
|
|
253
|
+
)
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
if (value.$delete) {
|
|
257
|
+
for (let i = 0; i < value.$add.length; i++) {
|
|
258
|
+
q.push(
|
|
259
|
+
fieldWalker(
|
|
260
|
+
[...path, '$delete', i],
|
|
261
|
+
value.$delete[i],
|
|
262
|
+
fieldDef,
|
|
263
|
+
typeSchema,
|
|
264
|
+
target,
|
|
265
|
+
handlerNest
|
|
266
|
+
)
|
|
267
|
+
)
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
await Promise.all(q)
|
|
271
|
+
handlers.collect({ path, value, typeSchema, fieldSchema, target })
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
|
|
275
|
+
json: async (path, value, fieldSchema, typeSchema, target, handlers) => {
|
|
276
|
+
// value .default
|
|
277
|
+
|
|
278
|
+
try {
|
|
279
|
+
const parsedValue = JSON.stringify(value)
|
|
280
|
+
handlers.collect({
|
|
281
|
+
path,
|
|
282
|
+
value: parsedValue,
|
|
283
|
+
typeSchema,
|
|
284
|
+
fieldSchema,
|
|
285
|
+
target,
|
|
286
|
+
})
|
|
287
|
+
} catch (err) {
|
|
288
|
+
throw createError(path, target.type, 'json', value)
|
|
289
|
+
}
|
|
290
|
+
},
|
|
291
|
+
|
|
292
|
+
number: async (path, value, fieldSchema, typeSchema, target, handlers) => {
|
|
293
|
+
// value .default
|
|
294
|
+
// $increment / $decrement
|
|
295
|
+
|
|
296
|
+
if (typeof value !== 'number') {
|
|
297
|
+
throw createError(path, target.type, 'number', value)
|
|
298
|
+
}
|
|
299
|
+
handlers.collect({ path, value, typeSchema, fieldSchema, target })
|
|
300
|
+
},
|
|
301
|
+
|
|
302
|
+
integer: async (path, value, fieldSchema, typeSchema, target, handlers) => {
|
|
303
|
+
// value .default
|
|
304
|
+
// $increment / $decrement
|
|
305
|
+
|
|
306
|
+
if (typeof value !== 'number' || value - Math.floor(value) !== 0) {
|
|
307
|
+
throw createError(path, target.type, 'integer', value)
|
|
308
|
+
}
|
|
309
|
+
handlers.collect({ path, value, typeSchema, fieldSchema, target })
|
|
310
|
+
},
|
|
311
|
+
|
|
312
|
+
string: async (path, value, fieldSchema, typeSchema, target, handlers) => {
|
|
313
|
+
// default
|
|
314
|
+
|
|
315
|
+
if (typeof value !== 'string') {
|
|
316
|
+
throw createError(path, target.type, 'string', value)
|
|
317
|
+
}
|
|
318
|
+
// @ts-ignore
|
|
319
|
+
if (fieldSchema.minLength && value.length < fieldSchema.minLength) {
|
|
320
|
+
throw createError(path, target.type, 'string', value)
|
|
321
|
+
}
|
|
322
|
+
// @ts-ignore
|
|
323
|
+
if (fieldSchema.maxLength && value.length > fieldSchema.maxLength) {
|
|
324
|
+
throw createError(path, target.type, 'string', value)
|
|
325
|
+
}
|
|
326
|
+
handlers.collect({ path, value, typeSchema, fieldSchema, target })
|
|
327
|
+
},
|
|
328
|
+
|
|
329
|
+
text: async (path, value, fieldSchema, typeSchema, target, handlers) => {
|
|
330
|
+
// default
|
|
331
|
+
|
|
332
|
+
const valueType = typeof value
|
|
333
|
+
if (target.$language && valueType === 'string') {
|
|
334
|
+
// @ts-ignore
|
|
335
|
+
if (fieldSchema.minLength && value.length < fieldSchema.minLength) {
|
|
336
|
+
throw createError(path, target.type, 'text', value)
|
|
337
|
+
}
|
|
338
|
+
// @ts-ignore
|
|
339
|
+
if (fieldSchema.maxLength && value.length > fieldSchema.maxLength) {
|
|
340
|
+
throw createError(path, target.type, 'text', value)
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
handlers.collect({
|
|
344
|
+
path,
|
|
345
|
+
value: { [target.$language]: value },
|
|
346
|
+
typeSchema,
|
|
347
|
+
fieldSchema,
|
|
348
|
+
target,
|
|
349
|
+
})
|
|
350
|
+
return
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if (valueType !== 'object') {
|
|
354
|
+
throw createError(path, target.type, 'text', value)
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
for (const key in value) {
|
|
358
|
+
// @ts-ignore
|
|
359
|
+
if (fieldSchema.minLength && value[key].length < fieldSchema.minLength) {
|
|
360
|
+
throw createError([...path, key], target.type, 'text', value)
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
// @ts-ignore
|
|
364
|
+
if (fieldSchema.maxLength && value[key].length > fieldSchema.maxLength) {
|
|
365
|
+
throw createError([...path, key], target.type, 'text', value)
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (typeof value[key] === 'object' && value[key].$delete === true) {
|
|
369
|
+
handlers.collect({
|
|
370
|
+
path: [...path, key],
|
|
371
|
+
value: null,
|
|
372
|
+
typeSchema,
|
|
373
|
+
fieldSchema,
|
|
374
|
+
target,
|
|
375
|
+
})
|
|
376
|
+
continue
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (typeof value[key] !== 'string') {
|
|
380
|
+
throw createError([...path, key], target.type, 'text', value)
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
handlers.collect({
|
|
384
|
+
path: [...path, key],
|
|
385
|
+
value: value[key],
|
|
386
|
+
typeSchema,
|
|
387
|
+
fieldSchema,
|
|
388
|
+
target,
|
|
389
|
+
})
|
|
390
|
+
}
|
|
391
|
+
},
|
|
392
|
+
|
|
393
|
+
reference,
|
|
394
|
+
|
|
395
|
+
references: async (
|
|
396
|
+
path,
|
|
397
|
+
value,
|
|
398
|
+
fieldSchema,
|
|
399
|
+
typeSchema,
|
|
400
|
+
target,
|
|
401
|
+
handlers
|
|
402
|
+
) => {
|
|
403
|
+
// default
|
|
404
|
+
// $no root
|
|
405
|
+
|
|
406
|
+
if (Array.isArray(value)) {
|
|
407
|
+
const handler = {
|
|
408
|
+
...handlers,
|
|
409
|
+
collect: () => {},
|
|
410
|
+
}
|
|
411
|
+
await Promise.all(
|
|
412
|
+
value.map((v, i) => {
|
|
413
|
+
return reference(
|
|
414
|
+
[...path, i],
|
|
415
|
+
v,
|
|
416
|
+
fieldSchema,
|
|
417
|
+
typeSchema,
|
|
418
|
+
target,
|
|
419
|
+
handler
|
|
420
|
+
)
|
|
421
|
+
})
|
|
422
|
+
)
|
|
423
|
+
} else if (typeof value === 'object') {
|
|
424
|
+
if (value.$add) {
|
|
425
|
+
const handler = {
|
|
426
|
+
...handlers,
|
|
427
|
+
collect: () => {},
|
|
428
|
+
}
|
|
429
|
+
await Promise.all(
|
|
430
|
+
value.$add.map((v, i) => {
|
|
431
|
+
return reference(
|
|
432
|
+
[...path, '$add', i],
|
|
433
|
+
v,
|
|
434
|
+
fieldSchema,
|
|
435
|
+
typeSchema,
|
|
436
|
+
target,
|
|
437
|
+
handler
|
|
438
|
+
)
|
|
439
|
+
})
|
|
440
|
+
)
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
handlers.collect({ path, value, typeSchema, fieldSchema, target })
|
|
445
|
+
},
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
export default parsers
|