@based/schema 2.0.0 → 2.1.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/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +17 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/src/error.ts +0 -19
- package/src/index.ts +0 -7
- package/src/languages.ts +0 -188
- package/src/set/fields/array.ts +0 -155
- package/src/set/fields/index.ts +0 -70
- package/src/set/fields/number.ts +0 -144
- package/src/set/fields/object.ts +0 -31
- package/src/set/fields/references.ts +0 -140
- package/src/set/fields/set.ts +0 -63
- package/src/set/fields/string.ts +0 -291
- package/src/set/index.ts +0 -186
- package/src/set/isValidId.ts +0 -23
- package/src/set/types.ts +0 -0
- package/src/types.ts +0 -365
- package/src/updateSchema.ts +0 -18
- package/src/validateSchema.ts +0 -64
- package/src/walker/args.ts +0 -209
- package/src/walker/index.ts +0 -48
- package/src/walker/parse.ts +0 -233
- package/src/walker/types.ts +0 -81
- package/test/array.ts +0 -388
- package/test/number.ts +0 -435
- package/test/reference.ts +0 -219
- package/test/rest.ts +0 -185
- package/test/set.ts +0 -104
- package/test/string.ts +0 -118
- package/test/text.ts +0 -348
- package/test/utils/index.ts +0 -23
- package/test/validateSchema.ts +0 -41
- package/test/walker.ts +0 -319
- package/tsconfig.json +0 -9
package/src/set/isValidId.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { BasedSchema } from '../types'
|
|
2
|
-
|
|
3
|
-
export const isValidId = (schema: BasedSchema, id: any): boolean => {
|
|
4
|
-
if (typeof id !== 'string') {
|
|
5
|
-
return false
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
if (id === 'root') {
|
|
9
|
-
return true
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
if (id.length > 16) {
|
|
13
|
-
return false
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const prefix = id.slice(0, 2)
|
|
17
|
-
|
|
18
|
-
if (!schema.prefixToTypeMapping[prefix]) {
|
|
19
|
-
return false
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return true
|
|
23
|
-
}
|
package/src/set/types.ts
DELETED
|
File without changes
|
package/src/types.ts
DELETED
|
@@ -1,365 +0,0 @@
|
|
|
1
|
-
import type { Language } from './languages'
|
|
2
|
-
import type { PartialDeep, SetOptional } from 'type-fest'
|
|
3
|
-
import { ParseError } from './error'
|
|
4
|
-
import { ArgsClass, Path } from './walker'
|
|
5
|
-
|
|
6
|
-
// Schema type
|
|
7
|
-
// inspiration from https://json-schema.org/understanding-json-schema/index.html
|
|
8
|
-
// but added a few extra types
|
|
9
|
-
// reference
|
|
10
|
-
// references
|
|
11
|
-
// set
|
|
12
|
-
// record
|
|
13
|
-
|
|
14
|
-
// https://json-schema.org/learn/examples/geographical-location.schema.json
|
|
15
|
-
|
|
16
|
-
// contentSchema can be used for JSON types as well
|
|
17
|
-
// contentSchema can be used for reference / refrences
|
|
18
|
-
|
|
19
|
-
// TODO parser / validator / parseOut / parseIn (parsIn after validator)
|
|
20
|
-
|
|
21
|
-
// for refs etc check https://json-schema.org/understanding-json-schema/structuring.html#defs
|
|
22
|
-
|
|
23
|
-
export type AllowedTypes = (string | { type?: string; $filter: any | any[] })[]
|
|
24
|
-
|
|
25
|
-
export type BasedSchemaFieldType =
|
|
26
|
-
| 'array'
|
|
27
|
-
| 'object'
|
|
28
|
-
| 'record'
|
|
29
|
-
| 'set'
|
|
30
|
-
| 'string'
|
|
31
|
-
| 'boolean'
|
|
32
|
-
| 'number'
|
|
33
|
-
| 'json'
|
|
34
|
-
| 'integer'
|
|
35
|
-
| 'timestamp'
|
|
36
|
-
| 'reference'
|
|
37
|
-
| 'references'
|
|
38
|
-
| 'text'
|
|
39
|
-
| 'cardinality'
|
|
40
|
-
|
|
41
|
-
export const isCollection = (type: string): boolean => {
|
|
42
|
-
return type === 'array' || type === 'object' || type === 'record'
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export type BasedSchemaPattern = string // RE ^[A-Za-z_][A-Za-z0-9_]*$
|
|
46
|
-
|
|
47
|
-
export type BasedSchemaLanguage = Language // fix
|
|
48
|
-
|
|
49
|
-
export type BasedSchemaTypePrefix = string // fix
|
|
50
|
-
|
|
51
|
-
// Some examples
|
|
52
|
-
export type BasedSchemaContentMediaType =
|
|
53
|
-
| 'text/html'
|
|
54
|
-
| 'text/plain'
|
|
55
|
-
| 'text/markdown'
|
|
56
|
-
| 'image/png'
|
|
57
|
-
| 'image/jpeg'
|
|
58
|
-
| 'video/mp4'
|
|
59
|
-
| 'image/*'
|
|
60
|
-
| 'video/*'
|
|
61
|
-
| 'audio/*'
|
|
62
|
-
| '*/*'
|
|
63
|
-
| `${string}/${string}`
|
|
64
|
-
|
|
65
|
-
export type BasedSchemaFieldShared = {
|
|
66
|
-
hooks?:
|
|
67
|
-
| { interval?: number; hook: string }
|
|
68
|
-
| { interval?: number; hook: string }[]
|
|
69
|
-
type?: BasedSchemaFieldType
|
|
70
|
-
$id?: string
|
|
71
|
-
$schema?: string
|
|
72
|
-
isRequired?: boolean
|
|
73
|
-
title?: string
|
|
74
|
-
description?: string
|
|
75
|
-
index?: number // Determines the order of fields
|
|
76
|
-
readOnly?: boolean
|
|
77
|
-
writeOnly?: boolean
|
|
78
|
-
$comment?: string
|
|
79
|
-
examples?: any[] // <--- make this generic
|
|
80
|
-
default?: any // <-- make this generic
|
|
81
|
-
// extra thing by us allow users to overwrite entire validations
|
|
82
|
-
customValidator?: (
|
|
83
|
-
value: any,
|
|
84
|
-
path: (number | string)[],
|
|
85
|
-
target: BasedSetTarget
|
|
86
|
-
) => Promise<boolean>
|
|
87
|
-
$defs?: { [key: string]: BasedSchemaField }
|
|
88
|
-
// TODO: This is an option. Should be in another place
|
|
89
|
-
$delete?: boolean
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// -------------- Primitive ---------------
|
|
93
|
-
export type BasedSchemaStringShared = {
|
|
94
|
-
minLength?: number
|
|
95
|
-
maxLength?: number
|
|
96
|
-
contentMediaEncoding?: string // base64
|
|
97
|
-
contentMediaType?: BasedSchemaContentMediaType // 'image/*'
|
|
98
|
-
pattern?: BasedSchemaPattern // TODO: does not exist
|
|
99
|
-
format?:
|
|
100
|
-
| 'email'
|
|
101
|
-
| 'URL'
|
|
102
|
-
| 'MACAddress'
|
|
103
|
-
| 'IP'
|
|
104
|
-
| 'IPRange'
|
|
105
|
-
| 'FQDN'
|
|
106
|
-
| 'IBAN'
|
|
107
|
-
| 'BIC'
|
|
108
|
-
| 'alpha'
|
|
109
|
-
| 'alphaLocales'
|
|
110
|
-
| 'alphanumeric'
|
|
111
|
-
| 'alphanumericLocales'
|
|
112
|
-
| 'passportNumber'
|
|
113
|
-
| 'port'
|
|
114
|
-
| 'lowercase'
|
|
115
|
-
| 'uppercase'
|
|
116
|
-
| 'ascii'
|
|
117
|
-
| 'semVer'
|
|
118
|
-
| 'surrogatePair'
|
|
119
|
-
| 'IMEI'
|
|
120
|
-
| 'hexadecimal'
|
|
121
|
-
| 'octal'
|
|
122
|
-
| 'hexColor'
|
|
123
|
-
| 'rgbColor'
|
|
124
|
-
| 'HSL'
|
|
125
|
-
| 'ISRC'
|
|
126
|
-
| 'MD5'
|
|
127
|
-
| 'JWT'
|
|
128
|
-
| 'UUID'
|
|
129
|
-
| 'luhnNumber'
|
|
130
|
-
| 'creditCard'
|
|
131
|
-
| 'identityCard'
|
|
132
|
-
| 'EAN'
|
|
133
|
-
| 'ISIN'
|
|
134
|
-
| 'ISBN'
|
|
135
|
-
| 'ISSN'
|
|
136
|
-
| 'mobilePhone'
|
|
137
|
-
| 'mobilePhoneLocales'
|
|
138
|
-
| 'postalCode'
|
|
139
|
-
| 'postalCodeLocales'
|
|
140
|
-
| 'ethereumAddress'
|
|
141
|
-
| 'currency'
|
|
142
|
-
| 'btcAddress'
|
|
143
|
-
| 'ISO6391'
|
|
144
|
-
| 'ISO8601'
|
|
145
|
-
| 'RFC3339'
|
|
146
|
-
| 'ISO31661Alpha2'
|
|
147
|
-
| 'ISO31661Alpha3'
|
|
148
|
-
| 'ISO4217'
|
|
149
|
-
| 'base32'
|
|
150
|
-
| 'base58'
|
|
151
|
-
| 'base64'
|
|
152
|
-
| 'dataURI'
|
|
153
|
-
| 'magnetURI'
|
|
154
|
-
| 'mimeType'
|
|
155
|
-
| 'latLong'
|
|
156
|
-
| 'slug'
|
|
157
|
-
| 'strongPassword'
|
|
158
|
-
| 'taxID'
|
|
159
|
-
| 'licensePlate'
|
|
160
|
-
| 'VAT'
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
export type BasedSchemaFieldString = {
|
|
164
|
-
type: 'string'
|
|
165
|
-
|
|
166
|
-
// maybe add some more? e.g. phone
|
|
167
|
-
} & BasedSchemaFieldShared &
|
|
168
|
-
BasedSchemaStringShared
|
|
169
|
-
|
|
170
|
-
export type BasedSchemaFieldEnum = {
|
|
171
|
-
enum: any[]
|
|
172
|
-
} & BasedSchemaFieldShared
|
|
173
|
-
|
|
174
|
-
// TODO: check if we want this later
|
|
175
|
-
// export type BasedSchemaFieldConst = {
|
|
176
|
-
// const: any
|
|
177
|
-
// } & BasedSchemaFieldShared
|
|
178
|
-
|
|
179
|
-
type NumberDefaults = {
|
|
180
|
-
multipleOf?: number
|
|
181
|
-
minimum?: number
|
|
182
|
-
maximum?: number
|
|
183
|
-
exclusiveMaximum?: boolean
|
|
184
|
-
exclusiveMinimum?: boolean
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
export type BasedSchemaFieldNumber = NumberDefaults & {
|
|
188
|
-
type: 'number'
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
export type BasedSchemaFieldCardinality = {
|
|
192
|
-
type: 'cardinality'
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export type BasedSchemaFieldInteger = NumberDefaults & {
|
|
196
|
-
type: 'integer'
|
|
197
|
-
} & BasedSchemaFieldShared
|
|
198
|
-
|
|
199
|
-
export type BasedSchemaFieldTimeStamp = NumberDefaults & {
|
|
200
|
-
type: 'timestamp'
|
|
201
|
-
} & BasedSchemaFieldShared
|
|
202
|
-
|
|
203
|
-
export type BasedSchemaFieldBoolean = {
|
|
204
|
-
type: 'boolean'
|
|
205
|
-
} & BasedSchemaFieldShared
|
|
206
|
-
|
|
207
|
-
// Can support full json SCHEMA validation for this
|
|
208
|
-
export type BasedSchemaFieldJSON = {
|
|
209
|
-
type: 'json'
|
|
210
|
-
} & BasedSchemaFieldShared
|
|
211
|
-
|
|
212
|
-
export type BasedSchemaFieldPrimitive =
|
|
213
|
-
| BasedSchemaFieldString
|
|
214
|
-
| BasedSchemaFieldNumber
|
|
215
|
-
| BasedSchemaFieldInteger
|
|
216
|
-
| BasedSchemaFieldTimeStamp
|
|
217
|
-
| BasedSchemaFieldJSON
|
|
218
|
-
| BasedSchemaFieldBoolean
|
|
219
|
-
| BasedSchemaFieldEnum
|
|
220
|
-
| BasedSchemaFieldShared
|
|
221
|
-
|
|
222
|
-
// -------------- Enumerable ---------------
|
|
223
|
-
export type BasedSchemaFieldText = {
|
|
224
|
-
type: 'text'
|
|
225
|
-
required?: BasedSchemaLanguage[]
|
|
226
|
-
} & BasedSchemaFieldShared &
|
|
227
|
-
BasedSchemaStringShared
|
|
228
|
-
|
|
229
|
-
export type BasedSchemaFieldObject = {
|
|
230
|
-
type: 'object'
|
|
231
|
-
properties: {
|
|
232
|
-
[name: string]: BasedSchemaField
|
|
233
|
-
}
|
|
234
|
-
required?: string[]
|
|
235
|
-
} & BasedSchemaFieldShared
|
|
236
|
-
|
|
237
|
-
export type BasedSchemaFieldRecord = {
|
|
238
|
-
type: 'record'
|
|
239
|
-
values: BasedSchemaField
|
|
240
|
-
} & BasedSchemaFieldShared
|
|
241
|
-
|
|
242
|
-
export type BasedSchemaFieldArray = {
|
|
243
|
-
type: 'array'
|
|
244
|
-
values: BasedSchemaField
|
|
245
|
-
} & BasedSchemaFieldShared
|
|
246
|
-
|
|
247
|
-
export type BasedSchemaFieldSet = {
|
|
248
|
-
type: 'set'
|
|
249
|
-
items: BasedSchemaFieldPrimitive
|
|
250
|
-
} & BasedSchemaFieldShared
|
|
251
|
-
|
|
252
|
-
export type BasedSchemaFieldEnumerable =
|
|
253
|
-
| BasedSchemaFieldText
|
|
254
|
-
| BasedSchemaFieldObject
|
|
255
|
-
| BasedSchemaFieldRecord
|
|
256
|
-
| BasedSchemaFieldArray
|
|
257
|
-
| BasedSchemaFieldSet
|
|
258
|
-
|
|
259
|
-
// -------------- Reference ---------------
|
|
260
|
-
export type BasedSchemaFieldReference = {
|
|
261
|
-
type: 'reference'
|
|
262
|
-
bidirectional?: {
|
|
263
|
-
fromField: string
|
|
264
|
-
}
|
|
265
|
-
// TODO: selva filters { $operator: 'includes', $value: 'image/', $field: 'mimeType' }
|
|
266
|
-
allowedTypes?: AllowedTypes
|
|
267
|
-
} & BasedSchemaFieldShared
|
|
268
|
-
|
|
269
|
-
// make extra package called based db - query (maybe in based-db)
|
|
270
|
-
export type BasedSchemaFieldReferences = {
|
|
271
|
-
type: 'references'
|
|
272
|
-
bidirectional?: {
|
|
273
|
-
fromField: string
|
|
274
|
-
}
|
|
275
|
-
allowedTypes?: AllowedTypes
|
|
276
|
-
} & BasedSchemaFieldShared
|
|
277
|
-
|
|
278
|
-
// return type can be typed - sort of
|
|
279
|
-
export type BasedSchemaField =
|
|
280
|
-
| BasedSchemaFieldEnumerable
|
|
281
|
-
| BasedSchemaFieldPrimitive
|
|
282
|
-
| BasedSchemaFieldReference
|
|
283
|
-
| BasedSchemaFieldReferences
|
|
284
|
-
| BasedSchemaFieldCardinality
|
|
285
|
-
| {
|
|
286
|
-
type?: BasedSchemaFieldType
|
|
287
|
-
isRequired?: boolean // our own
|
|
288
|
-
$ref: string // to mimic json schema will just load it in place (so only for setting)
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
export type BasedSchemaFields = {
|
|
292
|
-
enum: BasedSchemaFieldEnum
|
|
293
|
-
array: BasedSchemaFieldArray
|
|
294
|
-
object: BasedSchemaFieldObject
|
|
295
|
-
set: BasedSchemaFieldSet
|
|
296
|
-
record: BasedSchemaFieldRecord
|
|
297
|
-
string: BasedSchemaFieldString
|
|
298
|
-
boolean: BasedSchemaFieldBoolean
|
|
299
|
-
number: BasedSchemaFieldNumber
|
|
300
|
-
json: BasedSchemaFieldJSON
|
|
301
|
-
integer: BasedSchemaFieldInteger
|
|
302
|
-
timestamp: BasedSchemaFieldTimeStamp
|
|
303
|
-
reference: BasedSchemaFieldReference
|
|
304
|
-
references: BasedSchemaFieldReferences
|
|
305
|
-
text: BasedSchemaFieldText
|
|
306
|
-
cardinality: BasedSchemaFieldCardinality
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
export type BasedSchemaType = {
|
|
310
|
-
fields: {
|
|
311
|
-
[name: string]: BasedSchemaField
|
|
312
|
-
}
|
|
313
|
-
title?: string
|
|
314
|
-
description?: string
|
|
315
|
-
prefix?: BasedSchemaTypePrefix
|
|
316
|
-
examples?: any[]
|
|
317
|
-
required?: string[]
|
|
318
|
-
$defs?: { [key: string]: BasedSchemaField }
|
|
319
|
-
// TODO: This is an option. Should be in another place
|
|
320
|
-
$delete?: boolean
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
// this is the return value,, optional for insert
|
|
324
|
-
export type BasedSchema = {
|
|
325
|
-
language: BasedSchemaLanguage
|
|
326
|
-
translations?: BasedSchemaLanguage[]
|
|
327
|
-
languageFallbacks?: Partial<
|
|
328
|
-
Record<BasedSchemaLanguage, BasedSchemaLanguage[]>
|
|
329
|
-
>
|
|
330
|
-
root: BasedSchemaType
|
|
331
|
-
// in our setup this is used as top level /$defs/[name]/
|
|
332
|
-
// in our setup this is used as top level /types/[name]/$defs/[name]
|
|
333
|
-
// #/$defs/name
|
|
334
|
-
$defs: { [name: string]: BasedSchemaField }
|
|
335
|
-
types: {
|
|
336
|
-
[type: string]: BasedSchemaType
|
|
337
|
-
}
|
|
338
|
-
prefixToTypeMapping: {
|
|
339
|
-
[prefix: string]: string
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
export type BasedSchemaTypePartial = PartialDeep<BasedSchemaType>
|
|
344
|
-
|
|
345
|
-
export type BasedSchemaFieldPartial = PartialDeep<BasedSchemaField>
|
|
346
|
-
|
|
347
|
-
export type BasedSchemaPartial = PartialDeep<BasedSchema>
|
|
348
|
-
|
|
349
|
-
export type BasedSetTarget = {
|
|
350
|
-
type: string
|
|
351
|
-
$alias?: string
|
|
352
|
-
$id?: string
|
|
353
|
-
schema: BasedSchema
|
|
354
|
-
$merge?: boolean
|
|
355
|
-
$language?: BasedSchemaLanguage
|
|
356
|
-
required: (number | string)[][]
|
|
357
|
-
collected: BasedSchemaCollectProps[]
|
|
358
|
-
errors: { code: ParseError; path: Path }[]
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
export type BasedSchemaCollectProps = ArgsClass<BasedSetTarget> & {
|
|
362
|
-
root: ArgsClass<BasedSetTarget> & {
|
|
363
|
-
typeSchema: BasedSchemaType
|
|
364
|
-
}
|
|
365
|
-
}
|
package/src/updateSchema.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { BasedSchema, BasedSchemaPartial } from './types'
|
|
2
|
-
|
|
3
|
-
export const updateSchema = async (
|
|
4
|
-
newSchema: BasedSchemaPartial,
|
|
5
|
-
oldSchema: BasedSchema = {
|
|
6
|
-
$defs: {},
|
|
7
|
-
types: {},
|
|
8
|
-
language: 'en',
|
|
9
|
-
root: { fields: {} },
|
|
10
|
-
prefixToTypeMapping: {},
|
|
11
|
-
}
|
|
12
|
-
): Promise<BasedSchema> => {
|
|
13
|
-
// add sha
|
|
14
|
-
|
|
15
|
-
// put isRequired on the new schema in REQUIRED arrays
|
|
16
|
-
|
|
17
|
-
return oldSchema
|
|
18
|
-
}
|
package/src/validateSchema.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
BasedSchemaPartial,
|
|
3
|
-
BasedSchemaFieldPartial,
|
|
4
|
-
BasedSchemaTypePartial,
|
|
5
|
-
} from './types'
|
|
6
|
-
|
|
7
|
-
// gaurd in the schema for refs in arrays
|
|
8
|
-
|
|
9
|
-
export const validateType = (
|
|
10
|
-
fromSchema: BasedSchemaPartial,
|
|
11
|
-
typeName: string,
|
|
12
|
-
type: BasedSchemaTypePartial
|
|
13
|
-
) => {
|
|
14
|
-
if (
|
|
15
|
-
type.prefix &&
|
|
16
|
-
(typeof type.prefix !== 'string' || type.prefix.length !== 2)
|
|
17
|
-
) {
|
|
18
|
-
throw new Error(
|
|
19
|
-
`Incorrect prefix "${type.prefix}" for type "${typeName}" has to be a string of 2 alphanumerical characters e.g. "Az", "ab", "cc", "10"`
|
|
20
|
-
)
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export const validateField = (
|
|
25
|
-
fromSchema: BasedSchemaPartial,
|
|
26
|
-
path: string[],
|
|
27
|
-
field: BasedSchemaFieldPartial
|
|
28
|
-
) => {
|
|
29
|
-
//
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export const validateSchema = (
|
|
33
|
-
schema: BasedSchemaPartial
|
|
34
|
-
): BasedSchemaPartial => {
|
|
35
|
-
// rewrite schema things like required / required: []
|
|
36
|
-
|
|
37
|
-
if (typeof schema !== 'object') {
|
|
38
|
-
throw new Error('Schema is not an object')
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (schema.language && typeof schema.language !== 'string') {
|
|
42
|
-
throw new Error('Language must be a string')
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (schema.translations && !Array.isArray(schema.translations)) {
|
|
46
|
-
throw new Error('Translations needs to be an array')
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (schema.$defs) {
|
|
50
|
-
// first defs ofc
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (schema.root) {
|
|
54
|
-
validateType(schema, 'root', schema.root)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (schema.types) {
|
|
58
|
-
for (const type in schema.types) {
|
|
59
|
-
validateType(schema, type, schema.types[type])
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return schema
|
|
64
|
-
}
|
package/src/walker/args.ts
DELETED
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import { BasedSchema } from '../types'
|
|
2
|
-
import { BasedSchemaType, BasedSchemaFields } from '../types'
|
|
3
|
-
import { ArgsOpts, Path, Opts, Stopped, Collect } from './types'
|
|
4
|
-
import { parse } from './parse'
|
|
5
|
-
import { ParseError } from '../error'
|
|
6
|
-
import { deepEqual } from '@saulx/utils'
|
|
7
|
-
|
|
8
|
-
let id = 0
|
|
9
|
-
|
|
10
|
-
export class ArgsClass<
|
|
11
|
-
T,
|
|
12
|
-
K extends keyof BasedSchemaFields = keyof BasedSchemaFields
|
|
13
|
-
> {
|
|
14
|
-
errors: any[]
|
|
15
|
-
|
|
16
|
-
id: number
|
|
17
|
-
|
|
18
|
-
prev: ArgsClass<T, K>
|
|
19
|
-
|
|
20
|
-
root: ArgsClass<T, K> // getter
|
|
21
|
-
|
|
22
|
-
// only on root
|
|
23
|
-
_opts: Opts<T>
|
|
24
|
-
|
|
25
|
-
_target: T
|
|
26
|
-
|
|
27
|
-
_stopObject?: boolean
|
|
28
|
-
|
|
29
|
-
_schema: BasedSchema
|
|
30
|
-
|
|
31
|
-
parseTopLevel?: boolean
|
|
32
|
-
|
|
33
|
-
_collectOverride: Collect<T>
|
|
34
|
-
|
|
35
|
-
fieldSchema?: BasedSchemaFields[K]
|
|
36
|
-
|
|
37
|
-
typeSchema?: BasedSchemaType
|
|
38
|
-
|
|
39
|
-
path: Path
|
|
40
|
-
|
|
41
|
-
skipCollection: boolean
|
|
42
|
-
|
|
43
|
-
value: any
|
|
44
|
-
|
|
45
|
-
stopped: Stopped | void
|
|
46
|
-
|
|
47
|
-
fromBackTrack: any[]
|
|
48
|
-
|
|
49
|
-
collectedCommands: any[]
|
|
50
|
-
|
|
51
|
-
constructor(opts: ArgsOpts<T, K>, prev?: ArgsClass<T, K>) {
|
|
52
|
-
this.id = ++id
|
|
53
|
-
this.fromBackTrack = []
|
|
54
|
-
this.collectedCommands = []
|
|
55
|
-
if (opts.prev) {
|
|
56
|
-
prev = opts.prev
|
|
57
|
-
}
|
|
58
|
-
if (opts.parseTopLevel) {
|
|
59
|
-
this.parseTopLevel = opts.parseTopLevel
|
|
60
|
-
}
|
|
61
|
-
if (prev) {
|
|
62
|
-
this.prev = prev
|
|
63
|
-
this.root = prev.root
|
|
64
|
-
this.fieldSchema = prev.fieldSchema
|
|
65
|
-
}
|
|
66
|
-
if (opts.path) {
|
|
67
|
-
this.path = opts.path
|
|
68
|
-
} else if (prev && opts.key !== undefined) {
|
|
69
|
-
this.path = [...prev.path, opts.key]
|
|
70
|
-
} else if (opts && prev) {
|
|
71
|
-
this.path = prev.path
|
|
72
|
-
} else {
|
|
73
|
-
this.path = []
|
|
74
|
-
}
|
|
75
|
-
this.value = opts.value
|
|
76
|
-
if (opts.fieldSchema) {
|
|
77
|
-
// @ts-ignore K is too loose
|
|
78
|
-
this.fieldSchema = opts.fieldSchema
|
|
79
|
-
}
|
|
80
|
-
if (opts.typeSchema) {
|
|
81
|
-
this.typeSchema = opts.typeSchema
|
|
82
|
-
}
|
|
83
|
-
if (opts.target) {
|
|
84
|
-
this._target = opts.target
|
|
85
|
-
}
|
|
86
|
-
if (opts.collect) {
|
|
87
|
-
this._collectOverride = opts.collect
|
|
88
|
-
} else if (prev?._collectOverride) {
|
|
89
|
-
this._collectOverride = prev._collectOverride
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (opts.skipCollection) {
|
|
93
|
-
this.skipCollection = opts.skipCollection
|
|
94
|
-
} else if (prev?.skipCollection) {
|
|
95
|
-
this.skipCollection = true
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
get schema(): BasedSchema {
|
|
100
|
-
if (this._schema) {
|
|
101
|
-
return this.schema
|
|
102
|
-
}
|
|
103
|
-
return this.root._schema
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
get key(): number | string {
|
|
107
|
-
return this.path[this.path.length - 1] ?? ''
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
get target(): T {
|
|
111
|
-
if (this._target) {
|
|
112
|
-
return this._target
|
|
113
|
-
}
|
|
114
|
-
let p = this.prev
|
|
115
|
-
while (p) {
|
|
116
|
-
if (p._target) {
|
|
117
|
-
return p._target
|
|
118
|
-
}
|
|
119
|
-
p = p.prev
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
stop(onllyStopFieldSchemaParser?: boolean) {
|
|
124
|
-
const target = this
|
|
125
|
-
if (onllyStopFieldSchemaParser) {
|
|
126
|
-
target.stopped = Stopped.onlyStopFieldParser
|
|
127
|
-
} else {
|
|
128
|
-
target.stopped = Stopped.stopAll
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
create(opts?: ArgsOpts<T>): ArgsClass<T> {
|
|
133
|
-
const newArgs = new ArgsClass(opts, this)
|
|
134
|
-
if (this._collectOverride && !opts.collect) {
|
|
135
|
-
newArgs._collectOverride = this._collectOverride
|
|
136
|
-
}
|
|
137
|
-
if (this.skipCollection && opts.skipCollection !== false) {
|
|
138
|
-
newArgs.skipCollection = this.skipCollection
|
|
139
|
-
}
|
|
140
|
-
if (!('value' in opts)) {
|
|
141
|
-
newArgs.value = this.value
|
|
142
|
-
}
|
|
143
|
-
return newArgs
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
async parse(opts?: ArgsOpts<T>): Promise<ArgsClass<T> | void> {
|
|
147
|
-
if (!opts) {
|
|
148
|
-
return parse(this)
|
|
149
|
-
} else {
|
|
150
|
-
const newArgs = new ArgsClass(opts, this)
|
|
151
|
-
|
|
152
|
-
if (newArgs.value === undefined) {
|
|
153
|
-
newArgs.value = this.value
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
return newArgs.parse()
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
getTopPaths(): Path[] {
|
|
161
|
-
let argPath = []
|
|
162
|
-
let p = this
|
|
163
|
-
while (p) {
|
|
164
|
-
argPath.unshift({ path: p.path, id: p.id })
|
|
165
|
-
// @ts-ignore
|
|
166
|
-
p = p.prev
|
|
167
|
-
}
|
|
168
|
-
return argPath
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
getBackTrackTarget(): ArgsClass<T> {
|
|
172
|
-
let p: ArgsClass<T> = this
|
|
173
|
-
while (p) {
|
|
174
|
-
if (p.prev) {
|
|
175
|
-
if (deepEqual(p.prev.path, p.path)) {
|
|
176
|
-
p = p.prev
|
|
177
|
-
} else {
|
|
178
|
-
p = p.prev
|
|
179
|
-
break
|
|
180
|
-
}
|
|
181
|
-
} else {
|
|
182
|
-
break
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
return p
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
getCollectTarget() {}
|
|
189
|
-
|
|
190
|
-
collect(value?: any) {
|
|
191
|
-
if (this.skipCollection) {
|
|
192
|
-
return
|
|
193
|
-
}
|
|
194
|
-
const collectArgs =
|
|
195
|
-
value !== undefined ? new ArgsClass({ value }, this) : this
|
|
196
|
-
|
|
197
|
-
let collectTarget = this.prev
|
|
198
|
-
|
|
199
|
-
if (this._collectOverride) {
|
|
200
|
-
collectTarget.collectedCommands.push(this._collectOverride(collectArgs))
|
|
201
|
-
} else {
|
|
202
|
-
collectTarget.collectedCommands.push(this.root._opts.collect(collectArgs))
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
error(code: ParseError): void {
|
|
207
|
-
this.root._opts.error(code, this)
|
|
208
|
-
}
|
|
209
|
-
}
|