@based/schema 0.0.15 → 1.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.
Files changed (112) hide show
  1. package/dist/{set/error.d.ts → error.d.ts} +4 -2
  2. package/dist/{set/error.js → error.js} +2 -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/fields/array.d.ts +2 -0
  8. package/dist/set/fields/array.js +96 -0
  9. package/dist/set/fields/array.js.map +1 -0
  10. package/dist/set/fields/index.d.ts +3 -0
  11. package/dist/set/fields/index.js +72 -0
  12. package/dist/set/fields/index.js.map +1 -0
  13. package/dist/set/fields/number.d.ts +4 -0
  14. package/dist/set/fields/number.js +121 -0
  15. package/dist/set/fields/number.js.map +1 -0
  16. package/dist/set/fields/object.d.ts +3 -0
  17. package/dist/set/fields/object.js +33 -0
  18. package/dist/set/fields/object.js.map +1 -0
  19. package/dist/set/fields/references.d.ts +3 -0
  20. package/dist/set/fields/references.js +106 -0
  21. package/dist/set/fields/references.js.map +1 -0
  22. package/dist/set/fields/set.d.ts +2 -0
  23. package/dist/set/fields/set.js +63 -0
  24. package/dist/set/fields/set.js.map +1 -0
  25. package/dist/set/fields/string.d.ts +3 -0
  26. package/dist/set/fields/string.js +190 -0
  27. package/dist/set/fields/string.js.map +1 -0
  28. package/dist/set/index.d.ts +2 -5
  29. package/dist/set/index.js +98 -126
  30. package/dist/set/index.js.map +1 -1
  31. package/dist/set/isValidId.d.ts +2 -0
  32. package/dist/set/isValidId.js +21 -0
  33. package/dist/set/isValidId.js.map +1 -0
  34. package/dist/set/types.d.ts +0 -5
  35. package/dist/set/types.js +0 -2
  36. package/dist/types.d.ts +7 -1
  37. package/dist/types.js.map +1 -1
  38. package/dist/walker/args.d.ts +31 -0
  39. package/dist/walker/args.js +120 -0
  40. package/dist/walker/args.js.map +1 -0
  41. package/dist/walker/index.d.ts +6 -0
  42. package/dist/walker/index.js +40 -0
  43. package/dist/walker/index.js.map +1 -0
  44. package/dist/walker/parse.d.ts +2 -0
  45. package/dist/walker/parse.js +157 -0
  46. package/dist/walker/parse.js.map +1 -0
  47. package/dist/walker/types.d.ts +44 -0
  48. package/dist/walker/types.js +9 -0
  49. package/dist/walker/types.js.map +1 -0
  50. package/package.json +2 -2
  51. package/src/{set/error.ts → error.ts} +3 -1
  52. package/src/index.ts +2 -2
  53. package/src/set/fields/array.ts +111 -0
  54. package/src/set/fields/index.ts +69 -0
  55. package/src/set/fields/number.ts +134 -0
  56. package/src/set/fields/object.ts +30 -0
  57. package/src/set/fields/references.ts +114 -0
  58. package/src/set/fields/set.ts +63 -0
  59. package/src/set/fields/string.ts +199 -0
  60. package/src/set/index.ts +103 -188
  61. package/src/set/isValidId.ts +23 -0
  62. package/src/set/types.ts +0 -20
  63. package/src/types.ts +4 -2
  64. package/src/walker/args.ts +159 -0
  65. package/src/walker/index.ts +35 -0
  66. package/src/walker/parse.ts +193 -0
  67. package/src/walker/types.ts +75 -0
  68. package/test/number.ts +289 -543
  69. package/test/reference.ts +150 -198
  70. package/test/rest.ts +227 -0
  71. package/test/string.ts +139 -183
  72. package/test/utils/index.ts +23 -0
  73. package/test/walker.ts +579 -16
  74. package/dist/set/collections.d.ts +0 -5
  75. package/dist/set/collections.js +0 -229
  76. package/dist/set/collections.js.map +0 -1
  77. package/dist/set/error.js.map +0 -1
  78. package/dist/set/number.d.ts +0 -4
  79. package/dist/set/number.js +0 -124
  80. package/dist/set/number.js.map +0 -1
  81. package/dist/set/parseDefaultAndValue.d.ts +0 -3
  82. package/dist/set/parseDefaultAndValue.js +0 -35
  83. package/dist/set/parseDefaultAndValue.js.map +0 -1
  84. package/dist/set/parsers.d.ts +0 -3
  85. package/dist/set/parsers.js +0 -42
  86. package/dist/set/parsers.js.map +0 -1
  87. package/dist/set/references.d.ts +0 -3
  88. package/dist/set/references.js +0 -84
  89. package/dist/set/references.js.map +0 -1
  90. package/dist/set/rest.d.ts +0 -5
  91. package/dist/set/rest.js +0 -76
  92. package/dist/set/rest.js.map +0 -1
  93. package/dist/set/string.d.ts +0 -3
  94. package/dist/set/string.js +0 -173
  95. package/dist/set/string.js.map +0 -1
  96. package/dist/set2/index.d.ts +0 -0
  97. package/dist/set2/index.js +0 -71
  98. package/dist/set2/index.js.map +0 -1
  99. package/dist/walker.d.ts +0 -49
  100. package/dist/walker.js +0 -120
  101. package/dist/walker.js.map +0 -1
  102. package/src/set/collections.ts +0 -338
  103. package/src/set/number.ts +0 -167
  104. package/src/set/parseDefaultAndValue.ts +0 -54
  105. package/src/set/parsers.ts +0 -20
  106. package/src/set/references.ts +0 -113
  107. package/src/set/rest.ts +0 -135
  108. package/src/set/string.ts +0 -254
  109. package/src/set2/index.ts +0 -71
  110. package/src/walker.ts +0 -191
  111. package/test/setWalker.ts +0 -494
  112. package/test/text.ts +0 -171
@@ -0,0 +1,193 @@
1
+ import {
2
+ BasedSchemaField,
3
+ BasedSchemaFieldObject,
4
+ BasedSchemaFieldRecord,
5
+ BasedSchemaFields,
6
+ } from '../types'
7
+ import { ArgsClass } from './args'
8
+ import { ArgsOpts, FieldParser, KeyParser, Stopped } from './types'
9
+
10
+ type ParseResult<T> = ArgsClass<T> | void
11
+
12
+ // TODO needs cleaning
13
+ function createOrUseArgs<T>(
14
+ from: ArgsClass<T>,
15
+ newArgs: ArgsClass<T> | ArgsOpts<T> | void
16
+ ): ParseResult<T> {
17
+ if (!newArgs) {
18
+ return
19
+ }
20
+ if (newArgs instanceof ArgsClass) {
21
+ return newArgs
22
+ }
23
+ return from.create(newArgs)
24
+ }
25
+
26
+ async function parseKey<T>(
27
+ from: ArgsClass<T>,
28
+ key: string | number,
29
+ parser: KeyParser<T>
30
+ ): Promise<ParseResult<T>> {
31
+ const keyArgs = new ArgsClass(
32
+ {
33
+ key,
34
+ value: from.value[key],
35
+ fieldSchema: from.fieldSchema,
36
+ },
37
+ from
38
+ )
39
+ const newArgs = createOrUseArgs(keyArgs, await parser(keyArgs))
40
+ if (newArgs) {
41
+ return newArgs.parse()
42
+ }
43
+ }
44
+
45
+ function createFieldArgs<T>(
46
+ from: ArgsClass<T>,
47
+ key: string | number,
48
+ fieldSchema: BasedSchemaField
49
+ ): ArgsClass<T> {
50
+ return new ArgsClass(
51
+ {
52
+ key,
53
+ value: from.value[key],
54
+ // @ts-ignore needs key
55
+ fieldSchema,
56
+ },
57
+ from
58
+ )
59
+ }
60
+
61
+ function getFieldParser<T>(
62
+ args: ArgsClass<T>
63
+ ): void | FieldParser<keyof BasedSchemaFields> {
64
+ const fieldParser =
65
+ 'enum' in args.fieldSchema
66
+ ? args.root._opts.parsers.fields.enum
67
+ : args.root._opts.parsers.fields[args.fieldSchema.type]
68
+ return fieldParser
69
+ }
70
+
71
+ export async function parse<T>(
72
+ args: ArgsClass<T>
73
+ ): Promise<ArgsClass<T> | void> {
74
+ const opts = args.root._opts
75
+
76
+ if (args.parseTopLevel) {
77
+ const parser = opts.parsers.any
78
+ if (parser) {
79
+ await parser(args)
80
+ }
81
+ }
82
+
83
+ if (typeof args.value === 'object' && args.value !== null) {
84
+ const keyQ: Promise<ParseResult<T>>[] = []
85
+ const keysHandled: Set<string | number> = new Set()
86
+ let allKeysHandled = false
87
+
88
+ for (const key in opts.parsers.keys) {
89
+ if (key in args.value) {
90
+ keysHandled.add(key)
91
+ keyQ.push(parseKey(args, key, opts.parsers.keys[key]))
92
+ }
93
+ }
94
+ await Promise.all(keyQ)
95
+
96
+ if (args.stopped === undefined) {
97
+ const fieldQ: Promise<ParseResult<T>>[] = []
98
+ if (args.typeSchema && !args.fieldSchema) {
99
+ for (const key in args.typeSchema.fields) {
100
+ const fieldSchema = args.typeSchema.fields[key]
101
+ if (key in args.value) {
102
+ keysHandled.add(key)
103
+ fieldQ.push(createFieldArgs(args, key, fieldSchema).parse())
104
+ }
105
+ }
106
+ } else if (args.fieldSchema && !args.stopped) {
107
+ if (args.fieldSchema.type === 'object') {
108
+ // @ts-ignore should detect from line above
109
+ const objFieldSchema: BasedSchemaFieldObject = args.fieldSchema
110
+ for (const key in objFieldSchema.properties) {
111
+ const fieldSchema = objFieldSchema.properties[key]
112
+ if (key in args.value) {
113
+ keysHandled.add(key)
114
+ fieldQ.push(createFieldArgs(args, key, fieldSchema).parse())
115
+ }
116
+ }
117
+ } else if (args.fieldSchema.type === 'record') {
118
+ // @ts-ignore should detect from line above
119
+ const objFieldSchema: BasedSchemaFieldRecord = args.fieldSchema
120
+ for (const key in args.value) {
121
+ const fieldSchema = objFieldSchema.values
122
+ keysHandled.add(key)
123
+ fieldQ.push(createFieldArgs(args, key, fieldSchema).parse())
124
+ }
125
+ } else if (args.fieldSchema) {
126
+ const fieldParser = getFieldParser(args)
127
+ if (fieldParser) {
128
+ const newArgs = createOrUseArgs(args, await fieldParser(args))
129
+ if (newArgs) {
130
+ return newArgs.parse()
131
+ }
132
+ }
133
+ }
134
+ }
135
+ await Promise.all(fieldQ)
136
+ }
137
+
138
+ if (args.stopped !== Stopped.stopAll) {
139
+ const parser = opts.parsers.any || opts.parsers.catch
140
+ if (parser) {
141
+ const q: Promise<ParseResult<T>>[] = []
142
+ if (Array.isArray(args.value)) {
143
+ for (let i = 0; i < args.value.length; i++) {
144
+ if ((!opts.parsers.any && keysHandled.has(i)) || allKeysHandled) {
145
+ continue
146
+ }
147
+ q.push(parseKey(args, i, parser))
148
+ }
149
+ } else {
150
+ for (const key in args.value) {
151
+ if ((!opts.parsers.any && keysHandled.has(key)) || allKeysHandled) {
152
+ continue
153
+ }
154
+ q.push(parseKey(args, key, parser))
155
+ }
156
+ }
157
+ await Promise.all(q)
158
+ }
159
+ }
160
+
161
+ if (
162
+ opts.backtrack &&
163
+ !args.skipCollection &&
164
+ (args.fromBackTrack.length || args.collectedCommands.length)
165
+ ) {
166
+ const backtracked = opts.backtrack(
167
+ this,
168
+ args.fromBackTrack ?? [],
169
+ args.collectedCommands ?? []
170
+ )
171
+ if (backtracked && this.prev) {
172
+ if (!this.prev.fromBackTrack) {
173
+ this.prev.fromBackTrack = []
174
+ }
175
+ this.prev.fromBackTrack.push(backtracked)
176
+ }
177
+ }
178
+ } else {
179
+ if (args.fieldSchema) {
180
+ const fieldParser = getFieldParser(args)
181
+ if (fieldParser) {
182
+ const newArgs = createOrUseArgs(args, await fieldParser(args))
183
+ if (newArgs) {
184
+ return newArgs.parse()
185
+ }
186
+ } else {
187
+ console.warn('fieldSchema type not implemented yet!', args.fieldSchema)
188
+ const anyParser = opts.parsers.any || opts.parsers.catch
189
+ anyParser(args)
190
+ }
191
+ }
192
+ }
193
+ }
@@ -0,0 +1,75 @@
1
+ import { ParseError } from '../error'
2
+ import {
3
+ BasedSchemaType,
4
+ BasedSchemaFields,
5
+ BasedSchemaField,
6
+ BasedSchema,
7
+ } from '../types'
8
+ import { ArgsClass } from './args'
9
+
10
+ export type Path = (string | number)[]
11
+
12
+ export type ErrorHandler<T> = (
13
+ code: ParseError,
14
+ args: ArgsClass<T> | ArgsOpts<T>
15
+ ) => void
16
+
17
+ export type Collect<T> = (args: ArgsClass<T>) => any
18
+
19
+ export type FieldParser<K extends keyof BasedSchemaFields, T = any> = (
20
+ args: ArgsClass<T, K>
21
+ ) => Promise<ArgsClass<T> | ArgsOpts<T> | void>
22
+
23
+ export type KeyParser<T = any> = (
24
+ args: ArgsClass<T, keyof BasedSchemaFields>
25
+ ) => Promise<ArgsOpts<T> | ArgsClass<T> | void>
26
+
27
+ export type FieldParsers<T = any> = {
28
+ [Key in keyof BasedSchemaFields]: FieldParser<Key, T>
29
+ }
30
+
31
+ export type Opts<T> = {
32
+ init: (
33
+ value: any,
34
+ schema: BasedSchema,
35
+ error: ErrorHandler<T>
36
+ ) => Promise<ArgsOpts<T>>
37
+ parsers: {
38
+ fields: Partial<{
39
+ [Key in keyof BasedSchemaFields]: FieldParser<Key, T>
40
+ }>
41
+ keys: { [key: string]: KeyParser<T> }
42
+ any?: KeyParser<T>
43
+ catch?: KeyParser<T>
44
+ }
45
+ collect?: (args: ArgsClass<T>) => any
46
+ error?: ErrorHandler<T>
47
+ backtrack?: (
48
+ args: ArgsClass<T>,
49
+ fromBackTrack: any[],
50
+ collectedCommands: any[]
51
+ ) => any
52
+ // fix this
53
+ requiresAsyncValidation?: (validationType: any) => Promise<boolean>
54
+ }
55
+
56
+ export enum Stopped {
57
+ onlyStopFieldParser,
58
+ stopAll,
59
+ }
60
+
61
+ export type ArgsOpts<
62
+ T,
63
+ K extends keyof BasedSchemaFields = keyof BasedSchemaFields
64
+ > = {
65
+ parseTopLevel?: boolean
66
+ target?: T
67
+ key?: string | number
68
+ path?: Path
69
+ value?: any
70
+ prev?: ArgsClass<T, K>
71
+ fieldSchema?: BasedSchemaField
72
+ typeSchema?: BasedSchemaType
73
+ skipCollection?: boolean
74
+ collect?: (args: ArgsClass<T, K>, value?: any) => any
75
+ }