pwi-plata-type 0.3.17 → 0.4.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.
Files changed (117) hide show
  1. package/__BUILD__/bin/extras/create-api-cli.js +96 -0
  2. package/__BUILD__/bin/extras/create-api-cli.js.map +1 -0
  3. package/__BUILD__/bin/extras/create-lib-cli.js +62 -0
  4. package/__BUILD__/bin/extras/create-lib-cli.js.map +1 -0
  5. package/__BUILD__/bin/extras/plata-create-tools.js +94 -0
  6. package/__BUILD__/bin/extras/plata-create-tools.js.map +1 -0
  7. package/__BUILD__/bin/plata-api.js +138 -0
  8. package/__BUILD__/bin/plata-api.js.map +1 -0
  9. package/__BUILD__/bin/plata-create.js +24 -0
  10. package/__BUILD__/bin/plata-create.js.map +1 -0
  11. package/__BUILD__/bin/plata-runtime.js +156 -0
  12. package/__BUILD__/bin/plata-runtime.js.map +1 -0
  13. package/__BUILD__/bin/plata-swagger.js +82 -0
  14. package/__BUILD__/bin/plata-swagger.js.map +1 -0
  15. package/__BUILD__/bin/runtime/_setupRuntime.js +43 -0
  16. package/__BUILD__/bin/runtime/_setupRuntime.js.map +1 -0
  17. package/__BUILD__/bin/runtime/class.js +18 -0
  18. package/__BUILD__/bin/runtime/class.js.map +1 -0
  19. package/__BUILD__/bin/runtime/dirs.js +16 -0
  20. package/__BUILD__/bin/runtime/dirs.js.map +1 -0
  21. package/__BUILD__/bin/runtime/promises.js +15 -0
  22. package/__BUILD__/bin/runtime/promises.js.map +1 -0
  23. package/__BUILD__/bin/runtime/require.js +88 -0
  24. package/__BUILD__/bin/runtime/require.js.map +1 -0
  25. package/__BUILD__/index.js +42 -0
  26. package/__BUILD__/index.js.map +1 -0
  27. package/__BUILD__/libs/axios.js +42 -0
  28. package/__BUILD__/libs/axios.js.map +1 -0
  29. package/__BUILD__/libs/cluster.js +160 -0
  30. package/__BUILD__/libs/cluster.js.map +1 -0
  31. package/__BUILD__/libs/fs.js +206 -0
  32. package/__BUILD__/libs/fs.js.map +1 -0
  33. package/__BUILD__/libs/model-validations.js +356 -0
  34. package/__BUILD__/libs/model-validations.js.map +1 -0
  35. package/__BUILD__/libs/model.js +185 -0
  36. package/__BUILD__/libs/model.js.map +1 -0
  37. package/__BUILD__/libs/router.js +127 -0
  38. package/__BUILD__/libs/router.js.map +1 -0
  39. package/__BUILD__/libs/swagger.js +64 -0
  40. package/__BUILD__/libs/swagger.js.map +1 -0
  41. package/__BUILD__/libs/tasks.js +134 -0
  42. package/__BUILD__/libs/tasks.js.map +1 -0
  43. package/__BUILD__/libs/tools.js +231 -0
  44. package/__BUILD__/libs/tools.js.map +1 -0
  45. package/__BUILD__/scripts/post-install/api.js +25 -0
  46. package/__BUILD__/scripts/post-install/api.js.map +1 -0
  47. package/__BUILD__/scripts/post-install/lib.js +25 -0
  48. package/__BUILD__/scripts/post-install/lib.js.map +1 -0
  49. package/__BUILD__/scripts/post-install.js +65 -0
  50. package/__BUILD__/scripts/post-install.js.map +1 -0
  51. package/__BUILD__/scripts/pre-test.js +25 -0
  52. package/__BUILD__/scripts/pre-test.js.map +1 -0
  53. package/package.json +18 -16
  54. package/src/@types/cluster.actions.d.ts +7 -0
  55. package/src/@types/cluster.d.ts +33 -0
  56. package/src/@types/create-cli.d.ts +9 -0
  57. package/src/@types/exported.d.ts +24 -0
  58. package/src/@types/global.d.ts +69 -0
  59. package/src/@types/model.d.ts +69 -0
  60. package/src/@types/router.d.ts +75 -0
  61. package/src/@types/swagger.d.ts +23 -0
  62. package/{bin/extras/plata-create-api.ts → src/bin/extras/create-api-cli.ts} +5 -6
  63. package/{bin/extras/plata-create-lib.ts → src/bin/extras/create-lib-cli.ts} +3 -4
  64. package/{bin → src/bin}/extras/plata-create-tools.ts +4 -4
  65. package/src/bin/plata-api.ts +172 -0
  66. package/src/bin/plata-create.ts +21 -0
  67. package/src/bin/plata-runtime.ts +188 -0
  68. package/src/bin/plata-swagger.ts +100 -0
  69. package/src/bin/runtime/_setupRuntime.ts +49 -0
  70. package/src/bin/runtime/_types.d.ts +4 -0
  71. package/src/bin/runtime/class.ts +21 -0
  72. package/src/bin/runtime/dirs.ts +26 -0
  73. package/src/bin/runtime/promises.ts +15 -0
  74. package/src/bin/runtime/require.ts +104 -0
  75. package/{index.ts → src/index.ts} +2 -4
  76. package/{libs → src/libs}/axios.ts +0 -0
  77. package/src/libs/cluster.ts +189 -0
  78. package/src/libs/fs.ts +382 -0
  79. package/{libs/model.ts → src/libs/model-validations.ts} +28 -262
  80. package/src/libs/model.ts +233 -0
  81. package/src/libs/router.ts +147 -0
  82. package/src/libs/swagger.ts +81 -0
  83. package/{libs → src/libs}/tasks.ts +0 -0
  84. package/{libs → src/libs}/tools.ts +3 -18
  85. package/src/scripts/post-install/api.ts +32 -0
  86. package/src/scripts/post-install/lib.ts +30 -0
  87. package/src/scripts/post-install.ts +65 -0
  88. package/src/scripts/pre-test.ts +34 -0
  89. package/src/tests/assets/config/test.txt +1 -0
  90. package/src/tests/config.test.ts +13 -0
  91. package/src/tests/model.test.ts +115 -0
  92. package/templates/create-cli/cluster.ts +7 -9
  93. package/templates/create-cli/config.ts +2 -8
  94. package/templates/create-cli/lib.ts +7 -17
  95. package/templates/create-cli/model.ts +10 -21
  96. package/templates/create-cli/route.ts +1 -3
  97. package/templates/postinstall/api/configs/env.ts +2 -8
  98. package/templates/postinstall/api/tsconfig.json +20 -37
  99. package/templates/postinstall/lib/postinstall-tools.mjs +1 -1
  100. package/templates/postinstall/lib/postinstall.js +1 -0
  101. package/templates/postinstall/lib/tsconfig.json +21 -38
  102. package/tsconfig.json +25 -37
  103. package/Dockerfile +0 -13
  104. package/bin/extras/plata-build-tool.ts +0 -151
  105. package/bin/plata-build.ts +0 -144
  106. package/bin/plata-create.ts +0 -28
  107. package/bin/plata-reload.ts +0 -13
  108. package/bin/plata-swagger-gen.ts +0 -183
  109. package/bin/plata.ts +0 -122
  110. package/libs/cluster.ts +0 -219
  111. package/libs/env.ts +0 -28
  112. package/libs/routes.ts +0 -275
  113. package/libs/swagger.ts +0 -79
  114. package/postinstall-tools.mjs +0 -115
  115. package/postinstall.mjs +0 -42
  116. package/templates/postinstall/api/_install.mjs +0 -34
  117. package/templates/postinstall/lib/_install.mjs +0 -30
@@ -1,198 +1,4 @@
1
- import { PlataError } from "./tools"
2
-
3
- export interface RetornoValidacaoPrimitivo {
4
- error?: PlataError
5
- continua: boolean
6
- }
7
-
8
- export type ModelValicacao = (value: any) => Promise<PlataError | null>
9
-
10
- export type ModelTratamento<T = any> = (value: T) => T
11
-
12
- export type ModelValicacaoPrimitivo<T = any, D = null> = (nome: string, valor: T | D) => Promise<RetornoValidacaoPrimitivo> & { _output?: T | D }
13
-
14
- export interface ModelType {
15
- [name: string]: ModelValicacaoPrimitivo[] | ModelType[] | ModelType
16
- }
17
-
18
- export type ExtractType<T extends ModelType> = {
19
- [P in keyof T]: T[P] extends ModelType ? ExtractType<T[P]> :
20
- T[P] extends ModelType[] ? ExtractType<T[P][0]>[] : any
21
- }
22
-
23
- export class Model<T extends ModelType>{
24
- public readonly template: T
25
- public readonly validacoes: Map<string, ModelValicacao>
26
- public readonly tratamentos: Map<string, ModelTratamento>
27
- public readonly _type: ExtractType<T>
28
-
29
- constructor(template: T) {
30
- this.template = template
31
- this.validacoes = new Map()
32
- this.tratamentos = new Map()
33
- }
34
-
35
- public addValidacao(nome: string, callback: ModelValicacao) {
36
- this.validacoes.set(nome, callback)
37
- }
38
-
39
- public addTratamento<T>(nome: string, callback: ModelTratamento<T>) {
40
- this.tratamentos.set(nome, callback)
41
- }
42
- }
43
-
44
- export async function _validaCampo(value: any, pipelines: ModelValicacaoPrimitivo[], name: string): Promise<PlataError | null> {
45
- for (const pipeline of pipelines) {
46
- const result = await pipeline(name, value)
47
-
48
- if (result.error !== undefined) {
49
- return result.error
50
- }
51
-
52
- if (!result.continua) {
53
- break
54
- }
55
- }
56
-
57
- return null
58
- }
59
-
60
- export function _trataModel<T,Y extends ModelType>(value: T, model: Model<Y>) {
61
- model.tratamentos.forEach(tratamento => {
62
- value = tratamento(value)
63
- })
64
-
65
- return value as unknown as typeof model._type
66
- }
67
-
68
- export function _filtraModel<Y extends ModelType>(value: any, model: Model<Y>) {
69
- for (const campo in model.template) {
70
- const t = model.template[campo]
71
-
72
- if (t.length === undefined) {
73
- if (value[campo] === undefined) {
74
- value[campo] = {}
75
- }
76
-
77
- const m = new Model(t as ModelType)
78
- value[campo] = _filtraModel(value[campo], m)
79
- continue
80
- }
81
-
82
- if (typeof t[0] === 'function') {
83
- if (value[campo] === undefined) {
84
- value[campo] = null
85
- }
86
-
87
- continue
88
- }
89
-
90
- if (value[campo] === undefined) {
91
- value[campo] = []
92
-
93
- continue
94
- }
95
-
96
- const m = new Model(t[0] as ModelType)
97
-
98
- for (let i = 0; i < value[campo].length; i++) {
99
- value[campo][i] = _filtraModel(value[campo][i], m)
100
- }
101
- }
102
-
103
- return value as unknown as typeof model._type
104
- }
105
-
106
- export async function _validaModel<Y extends ModelType>(value: any, model: Model<Y>, name?: string): Promise<PlataError[]> {
107
- let promises: any[] = []
108
-
109
- for(const campo in model.template) {
110
- const t = model.template[campo]
111
-
112
- if (t.length === undefined) {
113
- const m = new Model(t as ModelType)
114
-
115
- promises.push(_validaModel(value[campo], m, `${name ?? ''}${campo}.`))
116
- continue
117
- }
118
-
119
- if (typeof t[0] === 'function') {
120
- promises.push(
121
- _validaCampo(
122
- value[campo],
123
- t as ModelValicacaoPrimitivo[],
124
- `${name ?? ''}${campo}`
125
- )
126
- )
127
- continue
128
- }
129
-
130
- const m = new Model(t[0])
131
-
132
- for (let i = 0; i < value[campo].length; i++) {
133
- promises.push(
134
- _validaModel(
135
- value[campo][i],
136
- m,
137
- `${name ?? ''}${campo}[${i}].`
138
- )
139
- )
140
- }
141
- }
142
-
143
- let Erros = await Promise.all(promises).then(
144
- result => [].concat(...result).filter(v => v !== null),
145
- err => {
146
- return {
147
- errorID: 'BPLM0002',
148
- error: err,
149
- msg: 'Erro ao validar o body',
150
- }
151
- }
152
- )
153
-
154
- if ((Erros as any).errorID !== undefined) {
155
- return Erros as PlataError[]
156
- }
157
-
158
- if ((Erros as any[]).length !== 0) {
159
- return Erros as PlataError[]
160
- }
161
-
162
- promises = []
163
-
164
- for (const [ _, callback ] of model.validacoes) {
165
- promises.push(callback(value))
166
- }
167
-
168
- Erros = await Promise.all(promises).then(
169
- result => [].concat(...result).filter(v => v !== null),
170
- err => {
171
- return {
172
- errorID: 'BPLM0003',
173
- error: err,
174
- msg: 'Erro ao validar o body',
175
- }
176
- }
177
- )
178
-
179
- if ((Erros as any).errorID !== undefined) {
180
- return Erros as PlataError[]
181
- }
182
-
183
- return Erros as PlataError[]
184
- }
185
-
186
- export async function valida<Y extends ModelType>(value: any, model: Model<Y>) {
187
- const v: typeof model._type = _trataModel(_filtraModel(value, model), model)
188
-
189
- return {
190
- value: v,
191
- errors: await _validaModel(value, model),
192
- }
193
- }
194
-
195
- export function Min(min: number): ModelValicacaoPrimitivo {
1
+ export function Min(min: number): Model.PrimitiveValidationType<any> {
196
2
  return async (nome: string, valor: any) => {
197
3
  if (valor < min) return {
198
4
  error: {
@@ -206,7 +12,7 @@ export function Min(min: number): ModelValicacaoPrimitivo {
206
12
  }
207
13
  }
208
14
 
209
- export function Max(max: number): ModelValicacaoPrimitivo {
15
+ export function Max(max: number): Model.PrimitiveValidationType<any> {
210
16
  return async (nome: string, valor: any) => {
211
17
  if (valor > max) return {
212
18
  error: {
@@ -220,9 +26,9 @@ export function Max(max: number): ModelValicacaoPrimitivo {
220
26
  }
221
27
  }
222
28
 
223
- export function Enum(...valores: any[]): ModelValicacaoPrimitivo {
29
+ export function Enum<T extends readonly any[]>(valores: T): Model.PrimitiveValidationType<T[number]> {
224
30
  return async (nome: string, valor: any) => {
225
- if (valores.find(v => `${valor}` === `${v}`)) return {
31
+ if (valores.findIndex(v => `${valor}` === `${v}`) === -1) return {
226
32
  error: {
227
33
  errorID: 'BPMVEN0001',
228
34
  msg: `O campo ${nome} so pode ter os valores: ${valores.join(', ')}`,
@@ -235,14 +41,14 @@ export function Enum(...valores: any[]): ModelValicacaoPrimitivo {
235
41
  }
236
42
  }
237
43
 
238
- export function DateTime(): ModelValicacaoPrimitivo {
44
+ export function StringDateTime(): Model.PrimitiveValidationType<string> {
239
45
  return async (nome: string, valor: any) => {
240
46
  const regex = /(\d{4})-([01]\d)-([0-3]\d)T([0-2]\d):([0-5]\d):([0-5]\d)/
241
47
 
242
48
  if (!regex.test(valor)) {
243
49
  return {
244
50
  error: {
245
- errorID: "BPMVDT001",
51
+ errorID: "BPVSDT001",
246
52
  msg: `A data no campo ${nome} tem que está no formato yyyy-mm-ddTHH:MM:SS`,
247
53
  },
248
54
  continua: false
@@ -254,7 +60,7 @@ export function DateTime(): ModelValicacaoPrimitivo {
254
60
  if (isNaN(+ano) || isNaN(+mes) || isNaN(+dia) || isNaN(+hora) || isNaN(+minutos) || isNaN(+segundos) ){
255
61
  return {
256
62
  error: {
257
- errorID: "BPMVDT002",
63
+ errorID: "BPVSDT002",
258
64
  msg: `A data no campo ${nome} tem que está no formato yyyy-mm-ddTHH:MM:SS`
259
65
  },
260
66
  continua: false
@@ -264,7 +70,7 @@ export function DateTime(): ModelValicacaoPrimitivo {
264
70
  if ((+dia) > 31 || (+mes) > 12 || (+hora) > 24){
265
71
  return {
266
72
  error: {
267
- errorID: "BCVDT003",
73
+ errorID: "BCVSDT003",
268
74
  msg: `A data no campo ${nome} tem que está no formato yyyy-mm-ddTHH:MM:SS`,
269
75
  },
270
76
  continua: false
@@ -275,7 +81,17 @@ export function DateTime(): ModelValicacaoPrimitivo {
275
81
  }
276
82
  }
277
83
 
278
- export function Decimal(tamanhoInteiro: number, casasDecimais: number, min?: number, max?: number): ModelValicacaoPrimitivo {
84
+ export function DateTime(): Model.PrimitiveValidationType<Date> {
85
+ return async (nome, value) => value instanceof Date ? { continua: true } : {
86
+ error: {
87
+ errorID: 'BPVDT001',
88
+ msg: `O campo ${nome} não é do tipo Date`
89
+ },
90
+ continua: false
91
+ }
92
+ }
93
+
94
+ export function Decimal(tamanhoInteiro: number, casasDecimais: number, min?: number, max?: number): Model.PrimitiveValidationType<number> {
279
95
  return async (nome: string, valor: any) => {
280
96
  if (isNaN(+valor)) {
281
97
  return {
@@ -335,7 +151,7 @@ export function Decimal(tamanhoInteiro: number, casasDecimais: number, min?: num
335
151
  }
336
152
  }
337
153
 
338
- export function Int(min?: number, max?: number): ModelValicacaoPrimitivo {
154
+ export function Int(min?: number, max?: number): Model.PrimitiveValidationType<number> {
339
155
  return async (nome: string, valor: any) => {
340
156
  if (isNaN(+valor)) {
341
157
  return {
@@ -371,57 +187,7 @@ export function Int(min?: number, max?: number): ModelValicacaoPrimitivo {
371
187
  }
372
188
  }
373
189
 
374
- export function isArray(tamanhoMaximo?: number, tamanhoMinimo?: number): ModelValicacaoPrimitivo {
375
- return async (nome: string, valor: any) => {
376
- if (valor === null) {
377
- return {
378
- error: {
379
- errorID: "BPCVARR001",
380
- msg: `O campo ${nome} tem ser um array`
381
- },
382
- continua: false
383
- }
384
- }
385
-
386
- if (valor.length === undefined) {
387
- return {
388
- error: {
389
- errorID: "BPCVARR002",
390
- msg: `O campo ${nome} tem ser um array`
391
- },
392
- continua: false
393
- }
394
- }
395
-
396
- if (tamanhoMinimo !== undefined) {
397
- if (valor.length > tamanhoMinimo) {
398
- return {
399
- error: {
400
- errorID: "BPCVARR004",
401
- msg: `O campo ${nome} não pode ter menos que ${tamanhoMinimo} itens`
402
- },
403
- continua: false
404
- }
405
- }
406
- }
407
-
408
- if (tamanhoMaximo !== undefined) {
409
- if (valor.length < tamanhoMaximo) {
410
- return {
411
- error: {
412
- errorID: "BPCVARR003",
413
- msg: `O campo ${nome} não pode ter mais de ${tamanhoMaximo} itens`
414
- },
415
- continua: false
416
- }
417
- }
418
- }
419
-
420
- return { continua: true }
421
- }
422
- }
423
-
424
- export function Optional(): ModelValicacaoPrimitivo {
190
+ export function Optional(): Model.PrimitiveValidationType<any, null> {
425
191
  return async (_nome: string, valor: any) => {
426
192
  if (!valor) {
427
193
  return { continua: false }
@@ -431,7 +197,7 @@ export function Optional(): ModelValicacaoPrimitivo {
431
197
  }
432
198
  }
433
199
 
434
- export function Required(): ModelValicacaoPrimitivo {
200
+ export function Required(): Model.PrimitiveValidationType {
435
201
  return async (nome: string, valor: any) => {
436
202
  if (valor === null) {
437
203
  return {
@@ -447,7 +213,7 @@ export function Required(): ModelValicacaoPrimitivo {
447
213
  }
448
214
  }
449
215
 
450
- export function SmallDateTime(): ModelValicacaoPrimitivo {
216
+ export function SmallDateTime(): Model.PrimitiveValidationType<string> {
451
217
  return async (nome: string, valor: any) => {
452
218
  const regex = /(\d{4})-([01]\d)-([0-3]\d)/
453
219
 
@@ -498,7 +264,7 @@ export function SmallDateTime(): ModelValicacaoPrimitivo {
498
264
  }
499
265
  }
500
266
 
501
- export function Telefone(): ModelValicacaoPrimitivo {
267
+ export function Telefone(): Model.PrimitiveValidationType<string> {
502
268
  return async (nome: string, valor: any) => {
503
269
  const v = `${valor}`.split('-')
504
270
 
@@ -536,7 +302,7 @@ export function Telefone(): ModelValicacaoPrimitivo {
536
302
  }
537
303
  }
538
304
 
539
- export function TelefoneDDI(): ModelValicacaoPrimitivo {
305
+ export function TelefoneDDI(): Model.PrimitiveValidationType<string> {
540
306
  return async (nome: string, valor: any) => {
541
307
  const [ ddi, t ] = `${valor}`.split(' ')
542
308
  const telefone = `${t}`.split('-')
@@ -595,9 +361,9 @@ export function TelefoneDDI(): ModelValicacaoPrimitivo {
595
361
  }
596
362
  }
597
363
 
598
- export function VarChar(size: number, min?: number): ModelValicacaoPrimitivo {
364
+ export function VarChar(size: number, min?: number): Model.PrimitiveValidationType<string> {
599
365
  return async (nome: string, valor: any) => {
600
- if (valor.length > size) {
366
+ if (`${valor}`.length > size) {
601
367
  return {
602
368
  error: {
603
369
  errorID: "BPVVARC001",
@@ -608,7 +374,7 @@ export function VarChar(size: number, min?: number): ModelValicacaoPrimitivo {
608
374
  }
609
375
 
610
376
  if (min !== undefined) {
611
- if (valor.length < min) {
377
+ if (`${valor}`.length < min) {
612
378
  return {
613
379
  error: {
614
380
  errorID: "BPVVARC002",
@@ -0,0 +1,233 @@
1
+ export namespace Internals {
2
+ export function filterTemplate<Y extends Model.Template>(value: any, template: Y) {
3
+ for (const param in template) {
4
+ const t = template[param]
5
+
6
+ if (t.length === undefined) {
7
+ if (value[param] === undefined) {
8
+ value[param] = new Object(null)
9
+ }
10
+
11
+ value[param] = filterTemplate(value[param], t as Model.Template)
12
+ continue
13
+ }
14
+
15
+ if (typeof t[0] === 'function') {
16
+ if (value[param] === undefined) {
17
+ value[param] = null
18
+ }
19
+
20
+ continue
21
+ }
22
+
23
+ if (t[0].length !== undefined) {
24
+ if (value[param] === undefined) {
25
+ value[param] = []
26
+ }
27
+
28
+ if (!Array.isArray(value[param])) {
29
+ value[param] = []
30
+ }
31
+
32
+ continue
33
+ }
34
+
35
+ if (value[param] === undefined) {
36
+ value[param] = []
37
+
38
+ continue
39
+ }
40
+
41
+ for (let i = 0; i < value[param].length; i++) {
42
+ value[param][i] = filterTemplate(value[param][i], t[0])
43
+ }
44
+ }
45
+
46
+ return value as Model.ExtractTemplateTypeNotValid<typeof template>
47
+ }
48
+
49
+ export async function validateParameter(value: any, pipeline: Model.PrimitiveValidationType[], name: string): Promise<Model.ValidateReturn> {
50
+ for (const validation of pipeline) {
51
+ const result = await validation(name, value)
52
+
53
+ if (result.error !== undefined) {
54
+ return result.error
55
+ }
56
+
57
+ if (!result.continua) {
58
+ break
59
+ }
60
+ }
61
+
62
+ return null
63
+ }
64
+
65
+ export async function validateTemplate<Y extends Model.Template>(value: any, template: Y, name?: string): PlataPromise<PlataError[]> {
66
+ const promises: any[] = []
67
+ for (const param in template) {
68
+ const t = template[param]
69
+
70
+ if (t.length === undefined) {
71
+ promises.push(validateTemplate(
72
+ value[param],
73
+ t as Model.Template,
74
+ `${name ?? ''}${param}.`
75
+ ))
76
+
77
+ continue
78
+ }
79
+
80
+ if (typeof t[0] === 'function') {
81
+ promises.push(
82
+ validateParameter(
83
+ value[param],
84
+ t as Model.PrimitiveValidationType[],
85
+ `${name ?? ''}${param}`
86
+ )
87
+ )
88
+
89
+ continue
90
+ }
91
+
92
+ if (t[0].length !== undefined) {
93
+ for (let i = 0; i < value[param].length; i++) {
94
+ promises.push(
95
+ validateParameter(
96
+ value[param][i],
97
+ t[0],
98
+ `${name ?? ''}${param}[${i}]`
99
+ )
100
+ )
101
+ }
102
+
103
+ continue
104
+ }
105
+
106
+ for (let i = 0; i < value[param].length; i++) {
107
+ promises.push(
108
+ validateTemplate(
109
+ value[param][i],
110
+ t[0],
111
+ `${name ?? ''}${param}[${i}].`
112
+ )
113
+ )
114
+ }
115
+ }
116
+
117
+ return Plata.FastPromise(() => Promise.all(promises)).then(
118
+ result => [].concat(...result).filter(v => v !== null),
119
+ err => {
120
+ return {
121
+ errorID: 'BPLM0001',
122
+ msg: `unexpected error while validating template (${name})`,
123
+ error: err
124
+ }
125
+ }
126
+ )
127
+ }
128
+ }
129
+
130
+ export class ModelTemplate<T extends Model.Template, C extends Model.Converters<T>> {
131
+ public readonly template: T
132
+ public readonly converters: C | {}
133
+ public readonly validations: Map<string, Model.ModelTemplateValidation<T>>
134
+ public readonly filters: Map<string, Model.ModelTemplateFilter<T>>
135
+ public readonly type: Model.ExtractTemplateType<T>
136
+
137
+ constructor(template: T, converters: C | {}) {
138
+ this.template = template
139
+ this.converters = converters
140
+ this.validations = new Map()
141
+ this.filters = new Map()
142
+ }
143
+
144
+ public addValidation(nome: string, callback: Model.ModelTemplateValidation<T>) {
145
+ this.validations.set(nome, callback)
146
+ }
147
+
148
+ public addFilter(nome: string, callback: Model.ModelTemplateFilter<T>) {
149
+ this.filters.set(nome, callback)
150
+ }
151
+
152
+ public convert: Model.ModelConvertFuntion<T, C> = (value, to) => {
153
+ const c: Model.ConvertFunction<T, any> | undefined = this.converters[to as string]
154
+
155
+ if (c === undefined)
156
+ return {
157
+ errorID: 'BPLM0002',
158
+ msg: 'Invalid Converter',
159
+ error: to
160
+ }
161
+ ;
162
+
163
+ try {
164
+ return c(value)
165
+ } catch (e) {
166
+ return {
167
+ errorID: 'BPLM0003',
168
+ msg: 'Unexpected converter error',
169
+ error: e
170
+ }
171
+ }
172
+ }
173
+
174
+ public filter(value: any) {
175
+ let v = Internals.filterTemplate(value, this.template)
176
+
177
+ this.filters.forEach(f => {
178
+ v = f(v)
179
+ })
180
+
181
+ return v
182
+ }
183
+
184
+ public async validate(value: any): Promise<Model.ModelValidateReturn<T>> {
185
+ const v = this.filter(value)
186
+ const errors = await Internals.validateTemplate(v, this.template)
187
+
188
+ if (errors.errorID !== undefined) {
189
+ return {
190
+ value: v as any,
191
+ errors: [errors]
192
+ }
193
+ }
194
+
195
+ if (errors.length !== 0) {
196
+ return {
197
+ value: v as any,
198
+ errors
199
+ }
200
+ }
201
+
202
+ const promises: Promise<Model.ValidateReturn>[] = []
203
+
204
+ this.validations.forEach(validation => {
205
+ promises.push(validation(v as any))
206
+ })
207
+
208
+ const result: PlataResult<PlataError[]> = await Plata.FastPromise(() => Promise.all(promises)).then(
209
+ r => ([] as Model.ValidateReturn[]).concat(...r).filter(v => v !== null),
210
+ err => {
211
+ return {
212
+ errorID: 'BPLM0002',
213
+ msg: `unexpected error while validating model`,
214
+ error: err
215
+ }
216
+ }
217
+ ) as any
218
+
219
+ if (result.errorID !== undefined) {
220
+ return {
221
+ value: v as any,
222
+ errors: [result]
223
+ }
224
+ }
225
+
226
+ return {
227
+ value: v as any,
228
+ errors: result.length !== 0 ? result : undefined
229
+ }
230
+ }
231
+ }
232
+
233
+ export * from './model-validations'