pwi-plata-type 0.3.8 → 0.3.11
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/bin/extras/plata-create-api.ts +18 -0
- package/index.ts +4 -1
- package/libs/axios.ts +43 -0
- package/libs/cluster.ts +8 -5
- package/libs/model.ts +110 -28
- package/libs/tools.ts +6 -2
- package/package.json +2 -1
- package/templates/create-cli/cluster.ts +17 -0
- package/templates/postinstall/api/tsconfig.json +1 -1
|
@@ -141,4 +141,22 @@ program.command('task <tasks...>')
|
|
|
141
141
|
})
|
|
142
142
|
;
|
|
143
143
|
|
|
144
|
+
program.command('cluster <clusters...>')
|
|
145
|
+
.description('Cria o arquivo do worker utilizando o templete da plata')
|
|
146
|
+
.action(async clusters => {
|
|
147
|
+
if (!Array.isArray(clusters)) return
|
|
148
|
+
|
|
149
|
+
const promises: any[] = []
|
|
150
|
+
const plataName = PlataDirs.ProjectJson.plata_name
|
|
151
|
+
|
|
152
|
+
for (const cluster of clusters) {
|
|
153
|
+
promises.push(tools.files.deployFileToProject(
|
|
154
|
+
'clusters',
|
|
155
|
+
'cluster',
|
|
156
|
+
`${cluster}.ts`.toLowerCase(),
|
|
157
|
+
{ Name: `${cluster}`, PlataName: `${plataName}` }
|
|
158
|
+
).finally(() => console.log(`Worker ${cluster} criada`)))
|
|
159
|
+
}
|
|
160
|
+
})
|
|
161
|
+
;
|
|
144
162
|
export const cli = program
|
package/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import * as PlataTools from './libs/tools'
|
|
|
5
5
|
import * as PlataModels from './libs/model'
|
|
6
6
|
import * as PlataTasks from './libs/tasks'
|
|
7
7
|
import { PlataSwagger } from './libs/swagger'
|
|
8
|
+
import { PlataAxios, PlataAxiosUnsafe } from './libs/axios'
|
|
8
9
|
|
|
9
10
|
export {
|
|
10
11
|
PlataCluster,
|
|
@@ -13,5 +14,7 @@ export {
|
|
|
13
14
|
PlataTools,
|
|
14
15
|
PlataModels,
|
|
15
16
|
PlataSwagger,
|
|
16
|
-
PlataTasks
|
|
17
|
+
PlataTasks,
|
|
18
|
+
PlataAxios,
|
|
19
|
+
PlataAxiosUnsafe,
|
|
17
20
|
}
|
package/libs/axios.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import axios, { AxiosResponse, AxiosRequestConfig } from 'axios'
|
|
2
|
+
import { PlataExtra, PlataResultado } from './tools';
|
|
3
|
+
|
|
4
|
+
export async function PlataAxios<T = any>(config: AxiosRequestConfig): Promise<PlataResultado<AxiosResponse<T>>> {
|
|
5
|
+
config.timeout = config.timeout ?? 1000
|
|
6
|
+
|
|
7
|
+
if (config.timeout === 0) {
|
|
8
|
+
return PlataAxiosUnsafe(config)
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const axiosPromise = PlataAxiosUnsafe(config)
|
|
12
|
+
const timeoutPromise = PlataExtra.timeout(config.timeout, {
|
|
13
|
+
errorID: 'PLAX0003',
|
|
14
|
+
msg: 'API externa não respondeu'
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
return Promise.race([axiosPromise, timeoutPromise])
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export async function PlataAxiosUnsafe<T = any>(config: AxiosRequestConfig): Promise<PlataResultado<AxiosResponse<T>>> {
|
|
21
|
+
return axios(config).then(
|
|
22
|
+
resp => resp,
|
|
23
|
+
err => {
|
|
24
|
+
if (err.response) {
|
|
25
|
+
return err.response
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (err.request) {
|
|
29
|
+
return {
|
|
30
|
+
errorID: 'PLAX0001',
|
|
31
|
+
msg: 'Erro ao se comunicar com API externa',
|
|
32
|
+
error: err
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
errorID: 'PLAX0002',
|
|
38
|
+
msg: 'Erro inesperado ao se comunicar com API externa',
|
|
39
|
+
error: err
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
}
|
package/libs/cluster.ts
CHANGED
|
@@ -2,13 +2,15 @@ import { PlataRequire, PlataDirs, PlataFiles } from './tools'
|
|
|
2
2
|
import { cpus } from 'node:os'
|
|
3
3
|
import * as typeCluster from 'node:cluster'
|
|
4
4
|
|
|
5
|
+
export type PlataWorker = typeCluster.Worker
|
|
6
|
+
|
|
5
7
|
export interface PlataClusterWorkerConfig {
|
|
6
8
|
name: string,
|
|
7
9
|
env: string,
|
|
8
10
|
onStart: () => Promise<void>
|
|
9
11
|
workers?: number,
|
|
10
12
|
workersEnv?: any,
|
|
11
|
-
onExit?: (worker:
|
|
13
|
+
onExit?: (worker: PlataWorker, code: number, signal: string) => void,
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export interface PlataCluster {
|
|
@@ -30,6 +32,7 @@ export interface _PlataClusterProcess extends NodeJS.Process {
|
|
|
30
32
|
_plata?: PlataClusterProcess
|
|
31
33
|
}
|
|
32
34
|
|
|
35
|
+
|
|
33
36
|
export function getClusterNodeProcess(): PlataClusterProcess {
|
|
34
37
|
const p = process as _PlataClusterProcess
|
|
35
38
|
|
|
@@ -51,7 +54,7 @@ export class PlataClusterManager {
|
|
|
51
54
|
private readonly Process = getClusterNodeProcess()
|
|
52
55
|
|
|
53
56
|
constructor() {
|
|
54
|
-
// Registra o evento que lida com
|
|
57
|
+
// Registra o evento que lida com a morte de workers
|
|
55
58
|
if (this.Cluster.isPrimary) {
|
|
56
59
|
if (this.Cluster.eventNames().indexOf('exit') === -1) {
|
|
57
60
|
this.Cluster.on('exit', (worker, code, signal) => {
|
|
@@ -88,7 +91,7 @@ export class PlataClusterManager {
|
|
|
88
91
|
}
|
|
89
92
|
}
|
|
90
93
|
|
|
91
|
-
public async run(config: PlataClusterWorkerConfig) {
|
|
94
|
+
public async run(config: PlataClusterWorkerConfig): Promise<void> {
|
|
92
95
|
if (config.workers === undefined) {
|
|
93
96
|
if (config.env === 'prod') {
|
|
94
97
|
config.workers = cpus().length
|
|
@@ -125,7 +128,7 @@ export class PlataClusterManager {
|
|
|
125
128
|
return this.Cluster.isPrimary
|
|
126
129
|
}
|
|
127
130
|
|
|
128
|
-
public async loadClusters() {
|
|
131
|
+
public async loadClusters(): Promise<void[]> {
|
|
129
132
|
const required = await PlataRequire.requireFolderAsync<PlataClusterWorkerConfig>(PlataDirs.getProjectDirClusters())
|
|
130
133
|
|
|
131
134
|
if (required.errorID !== undefined) {
|
|
@@ -133,7 +136,7 @@ export class PlataClusterManager {
|
|
|
133
136
|
process.exit(1)
|
|
134
137
|
}
|
|
135
138
|
|
|
136
|
-
const promisesClusters:
|
|
139
|
+
const promisesClusters: Promise<void>[] = []
|
|
137
140
|
|
|
138
141
|
for (const r of required) {
|
|
139
142
|
if (r.errorID !== undefined) {
|
package/libs/model.ts
CHANGED
|
@@ -5,27 +5,28 @@ export interface RetornoValidacaoPrimitivo {
|
|
|
5
5
|
continua: boolean
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
export interface RetornoValicadaoModel {
|
|
9
|
-
value: any,
|
|
10
|
-
errors: PlataError[]
|
|
11
|
-
}
|
|
12
|
-
|
|
13
8
|
export type ModelValicacao = (value: any) => Promise<PlataError | null>
|
|
14
9
|
|
|
15
|
-
export type ModelTratamento<T> = (value: T) => T
|
|
10
|
+
export type ModelTratamento<T = any> = (value: T) => T
|
|
16
11
|
|
|
17
|
-
export type ModelValicacaoPrimitivo = (nome: string, valor:
|
|
12
|
+
export type ModelValicacaoPrimitivo<T = any, D = null> = (nome: string, valor: T | D) => Promise<RetornoValidacaoPrimitivo> & { _output?: T | D }
|
|
18
13
|
|
|
19
14
|
export interface ModelType {
|
|
20
15
|
[name: string]: ModelValicacaoPrimitivo[] | ModelType[] | ModelType
|
|
21
16
|
}
|
|
22
17
|
|
|
23
|
-
export
|
|
24
|
-
|
|
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
25
|
public readonly validacoes: Map<string, ModelValicacao>
|
|
26
|
-
public readonly tratamentos: Map<string, ModelTratamento
|
|
26
|
+
public readonly tratamentos: Map<string, ModelTratamento>
|
|
27
|
+
public readonly _type: ExtractType<T>
|
|
27
28
|
|
|
28
|
-
constructor(template:
|
|
29
|
+
constructor(template: T) {
|
|
29
30
|
this.template = template
|
|
30
31
|
this.validacoes = new Map()
|
|
31
32
|
this.tratamentos = new Map()
|
|
@@ -56,15 +57,15 @@ export async function _validaCampo(value: any, pipelines: ModelValicacaoPrimitiv
|
|
|
56
57
|
return null
|
|
57
58
|
}
|
|
58
59
|
|
|
59
|
-
export function _trataModel<T>(value: T, model: Model)
|
|
60
|
+
export function _trataModel<T,Y extends ModelType>(value: T, model: Model<Y>) {
|
|
60
61
|
model.tratamentos.forEach(tratamento => {
|
|
61
62
|
value = tratamento(value)
|
|
62
63
|
})
|
|
63
64
|
|
|
64
|
-
return value
|
|
65
|
+
return value as unknown as typeof model._type
|
|
65
66
|
}
|
|
66
67
|
|
|
67
|
-
export function _filtraModel(value: any, model: Model)
|
|
68
|
+
export function _filtraModel<Y extends ModelType>(value: any, model: Model<Y>) {
|
|
68
69
|
for (const campo in model.template) {
|
|
69
70
|
const t = model.template[campo]
|
|
70
71
|
|
|
@@ -99,10 +100,10 @@ export function _filtraModel(value: any, model: Model): any {
|
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
|
|
102
|
-
return value
|
|
103
|
+
return value as unknown as typeof model._type
|
|
103
104
|
}
|
|
104
105
|
|
|
105
|
-
export async function _validaModel(value: any, model: Model
|
|
106
|
+
export async function _validaModel<Y extends ModelType>(value: any, model: Model<Y>, name?: string): Promise<PlataError[]> {
|
|
106
107
|
let promises: any[] = []
|
|
107
108
|
|
|
108
109
|
for(const campo in model.template) {
|
|
@@ -182,17 +183,58 @@ export async function _validaModel(value: any, model: Model, name?: string): Pro
|
|
|
182
183
|
return Erros as PlataError[]
|
|
183
184
|
}
|
|
184
185
|
|
|
185
|
-
export async function valida(value: any, model: Model
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
value = _trataModel(value, model)
|
|
186
|
+
export async function valida<Y extends ModelType>(value: any, model: Model<Y>) {
|
|
187
|
+
const v: typeof model._type = _trataModel(_filtraModel(value, model), model)
|
|
189
188
|
|
|
190
189
|
return {
|
|
191
|
-
value,
|
|
190
|
+
value: v,
|
|
192
191
|
errors: await _validaModel(value, model),
|
|
193
192
|
}
|
|
194
193
|
}
|
|
195
194
|
|
|
195
|
+
export function Min(min: number): ModelValicacaoPrimitivo {
|
|
196
|
+
return async (nome: string, valor: any) => {
|
|
197
|
+
if (valor < min) return {
|
|
198
|
+
error: {
|
|
199
|
+
errorID: "BPMVMIN001",
|
|
200
|
+
msg: `O valor de ${nome} tem que ser maior que ${min}`
|
|
201
|
+
},
|
|
202
|
+
continua: false,
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return { continua: true }
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export function Max(max: number): ModelValicacaoPrimitivo {
|
|
210
|
+
return async (nome: string, valor: any) => {
|
|
211
|
+
if (valor > max) return {
|
|
212
|
+
error: {
|
|
213
|
+
errorID: "BPMVMIN001",
|
|
214
|
+
msg: `O valor de ${nome} tem que ser maior que ${max}`
|
|
215
|
+
},
|
|
216
|
+
continua: false,
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return { continua: true }
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
export function Enum(...valores: any[]): ModelValicacaoPrimitivo {
|
|
224
|
+
return async (nome: string, valor: any) => {
|
|
225
|
+
if (valores.find(v => `${valor}` === `${v}`)) return {
|
|
226
|
+
error: {
|
|
227
|
+
errorID: 'BPMVEN0001',
|
|
228
|
+
msg: `O campo ${nome} so pode ter os valores: ${valores.join(', ')}`,
|
|
229
|
+
error: `${valor}`
|
|
230
|
+
},
|
|
231
|
+
continua: false,
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return { continua: true }
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
196
238
|
export function DateTime(): ModelValicacaoPrimitivo {
|
|
197
239
|
return async (nome: string, valor: any) => {
|
|
198
240
|
const regex = /(\d{4})-([01]\d)-([0-3]\d)T([0-2]\d):([0-5]\d):([0-5]\d)/
|
|
@@ -233,7 +275,7 @@ export function DateTime(): ModelValicacaoPrimitivo {
|
|
|
233
275
|
}
|
|
234
276
|
}
|
|
235
277
|
|
|
236
|
-
export function Decimal(tamanhoInteiro: number, casasDecimais: number): ModelValicacaoPrimitivo {
|
|
278
|
+
export function Decimal(tamanhoInteiro: number, casasDecimais: number, min?: number, max?: number): ModelValicacaoPrimitivo {
|
|
237
279
|
return async (nome: string, valor: any) => {
|
|
238
280
|
if (isNaN(+valor)) {
|
|
239
281
|
return {
|
|
@@ -281,11 +323,19 @@ export function Decimal(tamanhoInteiro: number, casasDecimais: number): ModelVal
|
|
|
281
323
|
}
|
|
282
324
|
}
|
|
283
325
|
|
|
326
|
+
if (min !== undefined) {
|
|
327
|
+
return Min(min)(nome, valor)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
if (max !== undefined) {
|
|
331
|
+
return Max(max)(nome, valor)
|
|
332
|
+
}
|
|
333
|
+
|
|
284
334
|
return { continua: true }
|
|
285
335
|
}
|
|
286
336
|
}
|
|
287
337
|
|
|
288
|
-
export function Int(): ModelValicacaoPrimitivo {
|
|
338
|
+
export function Int(min?: number, max?: number): ModelValicacaoPrimitivo {
|
|
289
339
|
return async (nome: string, valor: any) => {
|
|
290
340
|
if (isNaN(+valor)) {
|
|
291
341
|
return {
|
|
@@ -309,11 +359,19 @@ export function Int(): ModelValicacaoPrimitivo {
|
|
|
309
359
|
}
|
|
310
360
|
}
|
|
311
361
|
|
|
362
|
+
if (min !== undefined) {
|
|
363
|
+
return Min(min)(nome, valor)
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (max !== undefined) {
|
|
367
|
+
return Max(max)(nome, valor)
|
|
368
|
+
}
|
|
369
|
+
|
|
312
370
|
return { continua: true }
|
|
313
371
|
}
|
|
314
372
|
}
|
|
315
373
|
|
|
316
|
-
export function isArray(tamanhoMaximo?: number): ModelValicacaoPrimitivo {
|
|
374
|
+
export function isArray(tamanhoMaximo?: number, tamanhoMinimo?: number): ModelValicacaoPrimitivo {
|
|
317
375
|
return async (nome: string, valor: any) => {
|
|
318
376
|
if (valor === null) {
|
|
319
377
|
return {
|
|
@@ -335,8 +393,20 @@ export function isArray(tamanhoMaximo?: number): ModelValicacaoPrimitivo {
|
|
|
335
393
|
}
|
|
336
394
|
}
|
|
337
395
|
|
|
338
|
-
if (
|
|
339
|
-
if (valor.length >
|
|
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) {
|
|
340
410
|
return {
|
|
341
411
|
error: {
|
|
342
412
|
errorID: "BPCVARR003",
|
|
@@ -525,18 +595,30 @@ export function TelefoneDDI(): ModelValicacaoPrimitivo {
|
|
|
525
595
|
}
|
|
526
596
|
}
|
|
527
597
|
|
|
528
|
-
export function VarChar(size: number): ModelValicacaoPrimitivo {
|
|
598
|
+
export function VarChar(size: number, min?: number): ModelValicacaoPrimitivo {
|
|
529
599
|
return async (nome: string, valor: any) => {
|
|
530
600
|
if (valor.length > size) {
|
|
531
601
|
return {
|
|
532
602
|
error: {
|
|
533
603
|
errorID: "BPVVARC001",
|
|
534
|
-
msg: `O campo ${nome} tem que menos de ${size} caracteres`
|
|
604
|
+
msg: `O campo ${nome} tem que ter menos de ${size} caracteres`
|
|
535
605
|
},
|
|
536
606
|
continua: false
|
|
537
607
|
}
|
|
538
608
|
}
|
|
539
609
|
|
|
610
|
+
if (min !== undefined) {
|
|
611
|
+
if (valor.length < min) {
|
|
612
|
+
return {
|
|
613
|
+
error: {
|
|
614
|
+
errorID: "BPVVARC002",
|
|
615
|
+
msg: `O campo ${nome} tem que ter no minimo ${size} caracteres`
|
|
616
|
+
},
|
|
617
|
+
continua: false
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
540
622
|
return { continua: true }
|
|
541
623
|
}
|
|
542
624
|
}
|
package/libs/tools.ts
CHANGED
|
@@ -140,7 +140,7 @@ export namespace PlataFiles {
|
|
|
140
140
|
|
|
141
141
|
export async function findFile(folders: string[], file: string): Promise<string | null> {
|
|
142
142
|
for (const folder of folders) {
|
|
143
|
-
const f = glob.sync(`${folder.replace(/\\/g, '/')}/**/${file}
|
|
143
|
+
const f = glob.sync(`${folder.replace(/\\/g, '/')}/**/${file.toLowerCase()}*`)[0]
|
|
144
144
|
|
|
145
145
|
if (f !== undefined) {
|
|
146
146
|
return f
|
|
@@ -246,7 +246,11 @@ export namespace PlataRequire {
|
|
|
246
246
|
}
|
|
247
247
|
|
|
248
248
|
export namespace PlataExtra {
|
|
249
|
-
export function
|
|
249
|
+
export function sleep(ms: number) {
|
|
250
250
|
return new Promise(resolve => setTimeout(resolve, ms))
|
|
251
251
|
}
|
|
252
|
+
|
|
253
|
+
export function timeout(ms: number, error: PlataError): Promise<PlataError> {
|
|
254
|
+
return new Promise((_, reject) => setTimeout(() => reject(error), ms))
|
|
255
|
+
}
|
|
252
256
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pwi-plata-type",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.11",
|
|
4
4
|
"main": "index.ts",
|
|
5
5
|
"bin": {
|
|
6
6
|
"plata": "bin/plata.ts",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"@types/jest": "^28.1.1",
|
|
22
22
|
"@types/node-schedule": "^2.1.0",
|
|
23
23
|
"@types/swagger-ui-express": "^4.1.3",
|
|
24
|
+
"axios": "^0.27.2",
|
|
24
25
|
"commander": "^9.4.0",
|
|
25
26
|
"express": "^4.18.1",
|
|
26
27
|
"glob": "^8.0.3",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//@ts-nocheck
|
|
2
|
+
import { PlataCluster } from "ç__PlataName__ç"
|
|
3
|
+
|
|
4
|
+
const onStart = async () => {
|
|
5
|
+
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const onExit = (worker: PlataCluster.PlataWorker, code: number, signal: string) => {
|
|
9
|
+
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export default {
|
|
13
|
+
name: "ç__Name__ç",
|
|
14
|
+
env: process.env.ENV ?? 'debug',
|
|
15
|
+
onStart: onStart,
|
|
16
|
+
onExit: onExit
|
|
17
|
+
} as PlataCluster.PlataClusterWorkerConfig
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"@Models/*": [ "./models/*" ],
|
|
31
31
|
"@Clusters/*": [ "./clusters/*" ],
|
|
32
32
|
"@Plata/*": [ "./node_modules/pwi-plata-type/*" ],
|
|
33
|
-
"@PlataBin/*": [ "./node_modules/pwi-plata-type/bin/*" ]
|
|
33
|
+
"@PlataBin/*": [ "./node_modules/pwi-plata-type/bin/*" ]
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
"include": [
|