pwi-plata-type 0.2.10 → 0.2.13
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 +11 -11
- package/bin/extras/plata-create-lib.ts +9 -9
- package/bin/extras/plata-create-tools.ts +2 -2
- package/bin/plata-swagger-gen.ts +190 -0
- package/bin/plata.ts +6 -5
- package/index.ts +2 -0
- package/libs/cluster.ts +12 -13
- package/libs/routes.ts +46 -18
- package/libs/swagger.ts +78 -0
- package/libs/tools.ts +88 -15
- package/package.json +5 -2
- package/postinstall-tools.mjs +2 -2
- package/postinstall.js +2 -2
- package/templates/create-cli/lib.ts +1 -1
- package/templates/create-cli/route.ts +3 -3
- package/templates/postinstall/api/_install.mjs +2 -1
- package/templates/postinstall/lib/_install.mjs +1 -1
- package/templates/postinstall/lib/postinstall-tools.mjs +2 -2
- package/templates/postinstall/lib/postinstall.js +2 -2
- package/templates/swagger-cli/header.json +21 -0
- package/templates/swagger-cli/rota/body.json +10 -0
- package/templates/swagger-cli/rota/header.json +18 -0
- package/templates/swagger-cli/rota/response.json +23 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { tools } from "./plata-create-tools.js";
|
|
2
2
|
import { PlataDirs } from "../../libs/tools.js"
|
|
3
|
-
import
|
|
3
|
+
import path from 'node:path'
|
|
4
4
|
|
|
5
5
|
export async function h() {
|
|
6
6
|
return tools.args.forEachArg(async (command, args) => {
|
|
@@ -12,25 +12,25 @@ export async function h() {
|
|
|
12
12
|
promises.push(tools.files.deployFileToProject(
|
|
13
13
|
'configs',
|
|
14
14
|
'config',
|
|
15
|
-
`${nameLib.toLowerCase()
|
|
16
|
-
{ Name: `${nameLib}`, name: `${nameLib
|
|
17
|
-
).finally(() => console.log(`Config ${nameLib
|
|
15
|
+
`${nameLib}.ts`.toLowerCase(),
|
|
16
|
+
{ Name: `${nameLib}`, name: `${nameLib}`.toLowerCase() }
|
|
17
|
+
).finally(() => console.log(`Config ${nameLib} criada`)))
|
|
18
18
|
|
|
19
19
|
promises.push(tools.files.deployFileToProject(
|
|
20
20
|
'libs',
|
|
21
21
|
'lib',
|
|
22
|
-
`${nameLib.toLowerCase()
|
|
23
|
-
{ Name: `${nameLib}`, name: `${nameLib
|
|
24
|
-
).finally(() => console.log(`Lib ${nameLib
|
|
22
|
+
`${nameLib}.ts`.toLowerCase(),
|
|
23
|
+
{ Name: `${nameLib}`, name: `${nameLib}`.toLowerCase() }
|
|
24
|
+
).finally(() => console.log(`Lib ${nameLib} criada`)))
|
|
25
25
|
break;
|
|
26
26
|
case 'config':
|
|
27
27
|
const nameConfig = `${args.shift()}`
|
|
28
28
|
promises.push(tools.files.deployFileToProject(
|
|
29
29
|
'configs',
|
|
30
30
|
'config',
|
|
31
|
-
`${nameConfig.toLowerCase()
|
|
32
|
-
{ Name: `${nameConfig}`, name: `${nameConfig
|
|
33
|
-
).finally(() => console.log(`Config ${nameConfig
|
|
31
|
+
`${nameConfig}.ts`.toLowerCase(),
|
|
32
|
+
{ Name: `${nameConfig}`, name: `${nameConfig}`.toLowerCase() }
|
|
33
|
+
).finally(() => console.log(`Config ${nameConfig} criada`)))
|
|
34
34
|
break;
|
|
35
35
|
case 'cluster':
|
|
36
36
|
console.log('CLUSTER AINDA NÃO CRIANDO AINDA')
|
|
@@ -58,7 +58,7 @@ export async function h() {
|
|
|
58
58
|
promises.push(tools.files.deployFileToProject(
|
|
59
59
|
'models',
|
|
60
60
|
'model',
|
|
61
|
-
`${modelName.toLowerCase()
|
|
61
|
+
`${modelName}.ts`.toLowerCase(),
|
|
62
62
|
{ Name: `${modelName}`, PlataName: `${plataName}` }
|
|
63
63
|
).finally(() => console.log(`Model ${modelName} criada`)))
|
|
64
64
|
break;
|
|
@@ -10,25 +10,25 @@ export async function h() {
|
|
|
10
10
|
promises.push(tools.files.deployFileToProject(
|
|
11
11
|
'configs',
|
|
12
12
|
'config',
|
|
13
|
-
`${nameLib.toLowerCase()
|
|
14
|
-
{ Name: `${nameLib}`, name: `${nameLib
|
|
15
|
-
).finally(() => console.log(`Config ${nameLib
|
|
13
|
+
`${nameLib}.ts`.toLowerCase(),
|
|
14
|
+
{ Name: `${nameLib}`, name: `${nameLib}`.toLowerCase() }
|
|
15
|
+
).finally(() => console.log(`Config ${nameLib} criada`)))
|
|
16
16
|
|
|
17
17
|
promises.push(tools.files.deployFileToProject(
|
|
18
18
|
'libs',
|
|
19
19
|
'lib',
|
|
20
|
-
`${nameLib.toLowerCase()
|
|
21
|
-
{ Name: `${nameLib}`, name: `${nameLib
|
|
22
|
-
).finally(() => console.log(`Lib ${nameLib
|
|
20
|
+
`${nameLib}.ts`.toLowerCase(),
|
|
21
|
+
{ Name: `${nameLib}`, name: `${nameLib}`.toLowerCase() }
|
|
22
|
+
).finally(() => console.log(`Lib ${nameLib} criada`)))
|
|
23
23
|
break;
|
|
24
24
|
case 'config':
|
|
25
25
|
const nameConfig = args.shift()
|
|
26
26
|
promises.push(tools.files.deployFileToProject(
|
|
27
27
|
'configs',
|
|
28
28
|
'config',
|
|
29
|
-
`${nameConfig.toLowerCase()
|
|
30
|
-
{ Name: `${nameConfig}`, name: `${nameConfig
|
|
31
|
-
).finally(() => console.log(`Config ${nameConfig
|
|
29
|
+
`${nameConfig}.ts`.toLowerCase(),
|
|
30
|
+
{ Name: `${nameConfig}`, name: `${nameConfig}`.toLowerCase() }
|
|
31
|
+
).finally(() => console.log(`Config ${nameConfig} criada`)))
|
|
32
32
|
break;
|
|
33
33
|
case 'cluster':
|
|
34
34
|
console.log('CLUSTER AINDA NÃO CRIANDO AINDA')
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import fs from 'node:fs'
|
|
3
|
+
import { loadExpressRoutes } from '../libs/routes.js'
|
|
4
|
+
import { PlataResultado, PlataDirs, PlataFiles, PlataError } from '../libs/tools.js'
|
|
5
|
+
|
|
6
|
+
interface dumpParameter {
|
|
7
|
+
name: string,
|
|
8
|
+
required: boolean,
|
|
9
|
+
in: 'path',
|
|
10
|
+
type: 'string'
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface dumpRoute {
|
|
14
|
+
httpRoute: string,
|
|
15
|
+
metodo: string,
|
|
16
|
+
params: dumpParameter[]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface swaggerFiles {
|
|
20
|
+
swaggerHeader: any,
|
|
21
|
+
rota: {
|
|
22
|
+
header: any,
|
|
23
|
+
body: any,
|
|
24
|
+
response: any,
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async function toProjectSwagger(file: string, content: any): Promise<PlataError | null> {
|
|
29
|
+
try {
|
|
30
|
+
const p = path.resolve(file)
|
|
31
|
+
|
|
32
|
+
const r = await PlataFiles.createFileIfNotExists(p, JSON.stringify(content, null, 4))
|
|
33
|
+
|
|
34
|
+
return r.errorID !== undefined ? r : null
|
|
35
|
+
|
|
36
|
+
} catch (e) {
|
|
37
|
+
return {
|
|
38
|
+
errorID: '',
|
|
39
|
+
msg: `Erro ao salvar o arquivo ${file}`,
|
|
40
|
+
error: e
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function fromTemplateJson(file: string): PlataResultado<any> {
|
|
46
|
+
try {
|
|
47
|
+
const p = path.resolve(file)
|
|
48
|
+
|
|
49
|
+
const j = JSON.parse(fs.readFileSync(p).toString())
|
|
50
|
+
|
|
51
|
+
return j
|
|
52
|
+
} catch (e) {
|
|
53
|
+
return {
|
|
54
|
+
errorID: 'PBSW0001',
|
|
55
|
+
msg: `Erro ao ler o templete da plata ${file}`,
|
|
56
|
+
error: e
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function loadSwaggerFiles(): swaggerFiles {
|
|
62
|
+
const f = {
|
|
63
|
+
rota: {}
|
|
64
|
+
}
|
|
65
|
+
const files = f as swaggerFiles
|
|
66
|
+
|
|
67
|
+
const header = fromTemplateJson(
|
|
68
|
+
PlataDirs.getPlataTempleteDir('swagger-cli', 'header.json')
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
if (header.errorID !== undefined) {
|
|
72
|
+
throw header
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
files.swaggerHeader = header
|
|
76
|
+
|
|
77
|
+
const rotaHeader = fromTemplateJson(
|
|
78
|
+
PlataDirs.getPlataTempleteDir('swagger-cli', 'rota', 'header.json')
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
if (rotaHeader.errorID !== undefined) {
|
|
82
|
+
throw rotaHeader
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
files.rota.header = rotaHeader
|
|
86
|
+
|
|
87
|
+
const rotaBody = fromTemplateJson(
|
|
88
|
+
PlataDirs.getPlataTempleteDir('swagger-cli', 'rota', 'body.json')
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
if (rotaBody.errorID !== undefined) {
|
|
92
|
+
throw rotaBody
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
files.rota.body = rotaBody
|
|
96
|
+
|
|
97
|
+
const rotaReturn = fromTemplateJson(
|
|
98
|
+
PlataDirs.getPlataTempleteDir('swagger-cli', 'rota', 'response.json')
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
if (rotaReturn.errorID !== undefined) {
|
|
102
|
+
throw rotaReturn
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
files.rota.response = rotaReturn
|
|
106
|
+
|
|
107
|
+
return files
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function dumpRotas(): Promise<dumpRoute[]> {
|
|
111
|
+
const rotas = await loadExpressRoutes()
|
|
112
|
+
const rotasMetodos: dumpRoute[] = []
|
|
113
|
+
const regex = /[:|?](.*?)\//g
|
|
114
|
+
for (let i = 0; i < rotas.length; i++) {
|
|
115
|
+
const r = rotas[i]
|
|
116
|
+
const expressRouter = await r.exports()
|
|
117
|
+
|
|
118
|
+
if (expressRouter.swaggerHide) {
|
|
119
|
+
continue
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
for (let j = 0; j < expressRouter.stack.length; j++) {
|
|
123
|
+
const layer = expressRouter.stack[j];
|
|
124
|
+
const httpLayerRoute = path.normalize(`${r.httpRoute}/${layer.route.path}/`)
|
|
125
|
+
|
|
126
|
+
for (const metodo in layer.route.methods) {
|
|
127
|
+
const urlParms = httpLayerRoute.match(regex) ?? []
|
|
128
|
+
const routeParams: dumpParameter[] = []
|
|
129
|
+
|
|
130
|
+
for (let k = 0; k < urlParms.length; k++) {
|
|
131
|
+
const p = urlParms[k];
|
|
132
|
+
|
|
133
|
+
routeParams.push({
|
|
134
|
+
name: p.slice(1, -1),
|
|
135
|
+
required: p[0] === ':',
|
|
136
|
+
in: 'path',
|
|
137
|
+
type: 'string'
|
|
138
|
+
})
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
rotasMetodos.push({
|
|
142
|
+
httpRoute: httpLayerRoute.replace(regex, '{$1}/'),
|
|
143
|
+
params: routeParams,
|
|
144
|
+
metodo,
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return rotasMetodos
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const main = async () => {
|
|
154
|
+
const rotas = await dumpRotas()
|
|
155
|
+
const files = loadSwaggerFiles()
|
|
156
|
+
|
|
157
|
+
{
|
|
158
|
+
const pathSwaggerRotas = PlataDirs.getProjectDirSwaggerRotas()
|
|
159
|
+
|
|
160
|
+
for (let i = 0; i < rotas.length; i++) {
|
|
161
|
+
const r = rotas[i];
|
|
162
|
+
// https://developer.mozilla.org/en-US/docs/Glossary/Deep_copy
|
|
163
|
+
const f = JSON.parse(JSON.stringify(files))
|
|
164
|
+
|
|
165
|
+
f.rota.header.parameters.push(...r.params)
|
|
166
|
+
|
|
167
|
+
for (const json in f.rota) {
|
|
168
|
+
const result = await toProjectSwagger(
|
|
169
|
+
path.join(pathSwaggerRotas, r.httpRoute, r.metodo.toLocaleLowerCase(), `${json}.json`),
|
|
170
|
+
f.rota[json]
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
if (result !== null) throw result
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
{
|
|
179
|
+
const result = await toProjectSwagger(
|
|
180
|
+
path.join( PlataDirs.getProjectDirSwagger(), 'header.json'),
|
|
181
|
+
files.swaggerHeader
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
if (result !== null) throw result
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
console.log('swagger do projeto atualizado com novas rotas')
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
main()
|
package/bin/plata.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PlataClusterManager, PlataClusterMsg } from "../libs/cluster.js"
|
|
2
2
|
import { loadEnvProjectFile } from "../libs/env.js"
|
|
3
|
-
import {
|
|
3
|
+
import { buildExpressRouter } from "../libs/routes.js"
|
|
4
4
|
import express, { Express } from "express"
|
|
5
5
|
import { createServer } from 'node:https'
|
|
6
6
|
import fs from 'node:fs'
|
|
@@ -56,7 +56,7 @@ const main = async () => {
|
|
|
56
56
|
const port = process.env.PORT ?? 3050
|
|
57
57
|
const app: Express = express()
|
|
58
58
|
|
|
59
|
-
app.use(process.env._PLATA_API_ROOT ?? '/api',await
|
|
59
|
+
app.use(process.env._PLATA_API_ROOT ?? '/api',await buildExpressRouter())
|
|
60
60
|
|
|
61
61
|
app.use((err, req, res, next) => {
|
|
62
62
|
return res.status(500).json({
|
|
@@ -89,14 +89,15 @@ const main = async () => {
|
|
|
89
89
|
console.log(`cert: ${process.env._PLATA_API_SSL_CERT}`)
|
|
90
90
|
|
|
91
91
|
const https = createServer({
|
|
92
|
-
cert: fs.
|
|
92
|
+
cert: fs.readFileSync(path.normalize(path.join(
|
|
93
93
|
PlataDirs.getProjectDir(),
|
|
94
94
|
process.env._PLATA_API_SSL_CERT
|
|
95
95
|
))),
|
|
96
|
-
key: fs.
|
|
96
|
+
key: fs.readFileSync(path.normalize(path.join(
|
|
97
97
|
PlataDirs.getProjectDir(),
|
|
98
98
|
process.env._PLATA_API_SSL_KEY
|
|
99
|
-
)))
|
|
99
|
+
))),
|
|
100
|
+
// TODO :::: passphrase:
|
|
100
101
|
}, app)
|
|
101
102
|
|
|
102
103
|
https.listen(port, () => {
|
package/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import * as PlataRoutes from './libs/routes.js'
|
|
|
4
4
|
import { PlataRoute } from './libs/routes.js'
|
|
5
5
|
import * as PlataTools from './libs/tools.js'
|
|
6
6
|
import * as PlataModels from './libs/model.js'
|
|
7
|
+
import { PlataSwagger } from './libs/swagger.js'
|
|
7
8
|
|
|
8
9
|
export {
|
|
9
10
|
PlataCluster,
|
|
@@ -12,4 +13,5 @@ export {
|
|
|
12
13
|
PlataTools,
|
|
13
14
|
PlataModels,
|
|
14
15
|
PlataRoute,
|
|
16
|
+
PlataSwagger
|
|
15
17
|
}
|
package/libs/cluster.ts
CHANGED
|
@@ -126,25 +126,24 @@ export class PlataClusterManager {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
public async loadClusters() {
|
|
129
|
-
const required
|
|
130
|
-
result => result,
|
|
131
|
-
err => {
|
|
132
|
-
return { err }
|
|
133
|
-
}
|
|
134
|
-
)
|
|
129
|
+
const required = await PlataRequire.requireFolderAsync<PlataClusterWorkerConfig>(PlataDirs.getProjectDirClusters())
|
|
135
130
|
|
|
136
|
-
if (required.
|
|
137
|
-
console.log(required
|
|
131
|
+
if (required.errorID !== undefined) {
|
|
132
|
+
console.log(required)
|
|
138
133
|
process.exit(1)
|
|
139
134
|
}
|
|
140
135
|
|
|
141
|
-
const TypedRequired: PlataRequire.Required<PlataClusterWorkerConfig>[] = required
|
|
142
136
|
const promisesClusters: any[] = []
|
|
143
137
|
|
|
144
|
-
for (let i = 0; i <
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
138
|
+
for (let i = 0; i < required.length; i++) {
|
|
139
|
+
const r = required[i];
|
|
140
|
+
|
|
141
|
+
if (r.errorID !== undefined) {
|
|
142
|
+
console.log(required)
|
|
143
|
+
process.exit(1)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
promisesClusters.push(this.run(r.exports))
|
|
148
147
|
}
|
|
149
148
|
|
|
150
149
|
|
package/libs/routes.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { PlataDirs, PlataRequire, PlataError } from "./tools.js";
|
|
2
2
|
import express, { Router } from "express";
|
|
3
3
|
|
|
4
|
-
export type
|
|
4
|
+
export type _Router = Router & { swaggerHide?: boolean }
|
|
5
|
+
|
|
6
|
+
export type PlataRouter = () => _Router | Promise<_Router>
|
|
5
7
|
|
|
6
8
|
export type PlataRequest = express.Request & { user: any, extras: any }
|
|
7
9
|
|
|
@@ -14,35 +16,61 @@ export interface PlataResponse extends express.Response {
|
|
|
14
16
|
addOnResponse(callback: PlataOnResponse): void
|
|
15
17
|
}
|
|
16
18
|
|
|
17
|
-
export
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
const router = Router()
|
|
21
|
-
router.use(express.json())
|
|
19
|
+
export interface PlataRequiredRoute extends PlataRequire.RequiredInterface<PlataRouter> {
|
|
20
|
+
httpRoute: string
|
|
21
|
+
}
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
export async function loadExpressRoutes(): Promise<PlataRequiredRoute[]> {
|
|
24
|
+
const routes = await PlataRequire.requireFolderAsync<PlataRouter>(PlataDirs.getProjectRoutesDir())
|
|
24
25
|
|
|
25
|
-
if (
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
if (routes.errorID === undefined) {
|
|
27
|
+
if (routes.findIndex(r => r.errorID !== undefined) !== -1) {
|
|
28
|
+
routes.forEach(r => {
|
|
29
|
+
if (r.errorID !== undefined) {
|
|
30
|
+
console.log(r)
|
|
31
|
+
}
|
|
32
|
+
})
|
|
28
33
|
|
|
29
|
-
|
|
30
|
-
}
|
|
34
|
+
throw {}
|
|
35
|
+
}
|
|
31
36
|
|
|
32
|
-
|
|
33
|
-
const element = r[i];
|
|
37
|
+
let r = (routes as PlataRequiredRoute[])
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
// Cria as rotas http no array
|
|
40
|
+
r = r.map(route => {
|
|
41
|
+
route.httpRoute = route.filePath
|
|
36
42
|
.replace(PlataDirs.getProjectRoutesDir(), '')
|
|
37
43
|
.replace(/.(ts|js)$/, '')
|
|
38
44
|
.replace(/index/, '')
|
|
39
45
|
.replace(/\\/g, '/')
|
|
40
|
-
;
|
|
41
46
|
|
|
42
|
-
|
|
43
|
-
}
|
|
47
|
+
return route
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
// coloca o index na frente de todas as rotas
|
|
51
|
+
r = r.sort((x,y) => {
|
|
52
|
+
if (x.name === 'index') return -1
|
|
53
|
+
|
|
54
|
+
return +(x.name > y.name)
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
return r
|
|
44
58
|
} else {
|
|
45
59
|
console.log(routes)
|
|
60
|
+
throw {}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export async function buildExpressRouter(): Promise<Router> {
|
|
65
|
+
const router = Router()
|
|
66
|
+
router.use(express.json())
|
|
67
|
+
|
|
68
|
+
const routes = await loadExpressRoutes()
|
|
69
|
+
|
|
70
|
+
for (let i = 0; i < routes.length; i++) {
|
|
71
|
+
const r = routes[i];
|
|
72
|
+
|
|
73
|
+
router.use(r.httpRoute, await r.exports())
|
|
46
74
|
}
|
|
47
75
|
|
|
48
76
|
return router
|
package/libs/swagger.ts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import swaggerUi from 'swagger-ui-express'
|
|
2
|
+
import { Router } from 'express'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import { _Router } from './routes.js';
|
|
5
|
+
import { PlataFiles, PlataDirs } from "./tools.js";
|
|
6
|
+
|
|
7
|
+
export module PlataSwagger {
|
|
8
|
+
export async function swagger(): Promise<_Router> {
|
|
9
|
+
const router = Router() as _Router
|
|
10
|
+
router.swaggerHide = true
|
|
11
|
+
|
|
12
|
+
if (process.env._plata_name === '_plata_express') {
|
|
13
|
+
router.use(swaggerUi.serve, swaggerUi.setup(
|
|
14
|
+
await _loadSwaggerConfig(),
|
|
15
|
+
{}
|
|
16
|
+
))
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return router
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function _loadSwaggerConfig(): Promise<any> {
|
|
23
|
+
const obj = PlataFiles.readJsonSync(path.join(PlataDirs.getProjectDirSwagger(), 'header.json'))
|
|
24
|
+
|
|
25
|
+
obj.paths = new Object(null)
|
|
26
|
+
|
|
27
|
+
{
|
|
28
|
+
const routes = await PlataFiles.findFiles([PlataDirs.getProjectDirSwaggerRotas()], 'header.json')
|
|
29
|
+
|
|
30
|
+
for (let i = 0; i < routes.length; i++) {
|
|
31
|
+
const route = routes[i];
|
|
32
|
+
|
|
33
|
+
const docPath = path.normalize(path.dirname(route))
|
|
34
|
+
const metodo = path.normalize(path.basename(docPath))
|
|
35
|
+
const httpPath = path.normalize(
|
|
36
|
+
path.dirname(docPath.replace(PlataDirs.getProjectDirSwaggerRotas(), ''))
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
const header = PlataFiles.readJsonSync(path.join(docPath, 'header.json'))
|
|
40
|
+
const body = PlataFiles.readJsonSync(path.join(docPath, 'body.json'))
|
|
41
|
+
const response = PlataFiles.readJsonSync(path.join(docPath, 'response.json'))
|
|
42
|
+
|
|
43
|
+
if (obj.paths[httpPath] === undefined) {
|
|
44
|
+
obj.paths[httpPath] = new Object(null)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
obj.paths[httpPath][metodo] = { ...header, responses: response }
|
|
48
|
+
|
|
49
|
+
if (body !== {}) {
|
|
50
|
+
if (!Array.isArray(obj.paths[httpPath][metodo].parameters)) {
|
|
51
|
+
obj.paths[httpPath][metodo].parameters = []
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const swaggerRouteBody = {
|
|
55
|
+
name: "body",
|
|
56
|
+
description: body.description,
|
|
57
|
+
in: "body",
|
|
58
|
+
schema: {
|
|
59
|
+
type: body.type ?? "object",
|
|
60
|
+
}
|
|
61
|
+
} as any
|
|
62
|
+
|
|
63
|
+
if (swaggerRouteBody.schema.type === 'array') {
|
|
64
|
+
swaggerRouteBody.schema.items = {
|
|
65
|
+
example: body.example
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
swaggerRouteBody.schema.properties = body.example
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
obj.paths[httpPath][metodo].parameters.push(swaggerRouteBody)
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return obj
|
|
77
|
+
}
|
|
78
|
+
}
|
package/libs/tools.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import fs from 'node:fs'
|
|
3
|
+
import readline from 'node:readline'
|
|
4
4
|
import * as tGlob from 'glob'
|
|
5
5
|
|
|
6
6
|
const glob = (tGlob as any).default as typeof tGlob
|
|
@@ -18,6 +18,14 @@ export module PlataDirs {
|
|
|
18
18
|
return path.resolve('.')
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
+
export function getProjectDirSwagger(): string {
|
|
22
|
+
return path.resolve('.', 'swagger')
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function getProjectDirSwaggerRotas(): string {
|
|
26
|
+
return path.resolve('.', 'swagger', 'rotas')
|
|
27
|
+
}
|
|
28
|
+
|
|
21
29
|
export function getProjectDirClusters(): string {
|
|
22
30
|
return path.resolve('.', 'clusters')
|
|
23
31
|
}
|
|
@@ -56,8 +64,8 @@ export module PlataDirs {
|
|
|
56
64
|
return path.join(getPlataDir(), 'templates')
|
|
57
65
|
}
|
|
58
66
|
|
|
59
|
-
export function getPlataTempleteDir(group:string, template: string) {
|
|
60
|
-
return path.join(getPlataTempletesDir(), group, template)
|
|
67
|
+
export function getPlataTempleteDir(group:string, ...template: string[]) {
|
|
68
|
+
return path.join(getPlataTempletesDir(), group, ...template)
|
|
61
69
|
}
|
|
62
70
|
|
|
63
71
|
export function getPlataBinExtraFile(file: string): string {
|
|
@@ -133,10 +141,55 @@ export module PlataFiles {
|
|
|
133
141
|
|
|
134
142
|
return null
|
|
135
143
|
}
|
|
144
|
+
|
|
145
|
+
export async function findFiles(folders: string[], file: string): Promise<string[]> {
|
|
146
|
+
const files: string[] = []
|
|
147
|
+
|
|
148
|
+
for (let i = 0; i < folders.length; i++) {
|
|
149
|
+
const folder = folders[i]
|
|
150
|
+
|
|
151
|
+
files.push(...glob.sync(`${folder.replace(/\\/g, '/')}/**/${file}`))
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return files
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export async function createFileIfNotExists(filePath: string, content: string): Promise<PlataResultado<string>> {
|
|
158
|
+
const p = path.resolve(filePath)
|
|
159
|
+
|
|
160
|
+
if (!fs.existsSync(p)) {
|
|
161
|
+
return createFile(filePath, content)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return p
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export async function createFile(filePath: string, content: string): Promise<PlataResultado<string>> {
|
|
168
|
+
try {
|
|
169
|
+
const p = path.resolve(filePath)
|
|
170
|
+
|
|
171
|
+
fs.mkdirSync(path.dirname(p), { recursive: true })
|
|
172
|
+
fs.writeFileSync(p, content)
|
|
173
|
+
|
|
174
|
+
return p
|
|
175
|
+
} catch (e) {
|
|
176
|
+
return {
|
|
177
|
+
errorID: 'PLTPF0001',
|
|
178
|
+
msg: `Erro ao criar ao criar o arquivo ${filePath}`,
|
|
179
|
+
error: e
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export function readJsonSync(filePath: string): any {
|
|
186
|
+
return JSON.parse(fs.readFileSync(filePath).toString())
|
|
187
|
+
}
|
|
136
188
|
}
|
|
137
189
|
|
|
138
190
|
export module PlataRequire {
|
|
139
|
-
export
|
|
191
|
+
export type Required<Type> = PlataResultado<RequiredInterface<Type>>
|
|
192
|
+
export interface RequiredInterface<Type> {
|
|
140
193
|
filePath: string,
|
|
141
194
|
name: string,
|
|
142
195
|
exports: Type
|
|
@@ -145,24 +198,44 @@ export module PlataRequire {
|
|
|
145
198
|
export async function requireAsync<Type>(file: string): Promise<Required<Type>> {
|
|
146
199
|
const p = path.resolve(file)
|
|
147
200
|
|
|
201
|
+
const e = await import(`file:///${p}`.replace(/\\/g, '/')).catch(e => { return {_plataError: e } })
|
|
202
|
+
|
|
203
|
+
if (e._plataError !== undefined) {
|
|
204
|
+
return {
|
|
205
|
+
errorID: 'PLTRF0001',
|
|
206
|
+
msg: `Erro ao importar o arquivo ${file}`,
|
|
207
|
+
error: e._plataError
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
148
211
|
return {
|
|
149
212
|
filePath: p,
|
|
150
213
|
name: path.basename(p).replace('.ts', '').replace('.js', ''),
|
|
151
|
-
exports: (
|
|
214
|
+
exports: (e as any).default as Type
|
|
152
215
|
}
|
|
153
216
|
}
|
|
154
217
|
|
|
155
|
-
export async function requireFolderAsync<Type>(folder: string): Promise<Required<Type>[]
|
|
218
|
+
export async function requireFolderAsync<Type>(folder: string): Promise<PlataResultado<Required<Type>[]>> {
|
|
156
219
|
const promises: Promise<Required<Type>>[] = []
|
|
157
220
|
const p = path.resolve(folder)
|
|
158
221
|
|
|
159
|
-
glob.sync(`${p.replace(/\\/g, '/')}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
222
|
+
glob.sync(`${p.replace(/\\/g, '/')}/**/*.+(js|ts)`)
|
|
223
|
+
.filter(file => !file.endsWith('.d.ts'))
|
|
224
|
+
.forEach(file => {
|
|
225
|
+
file = file.replace('.ts', '.js')
|
|
226
|
+
|
|
227
|
+
promises.push(requireAsync<Type>(file))
|
|
228
|
+
})
|
|
229
|
+
|
|
230
|
+
return Promise.all(promises).catch(
|
|
231
|
+
e => {
|
|
232
|
+
return {
|
|
233
|
+
errorID: 'PLTRF0002',
|
|
234
|
+
msg: `Erro ao importar a pasta ${folder}`,
|
|
235
|
+
error: e
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
)
|
|
166
239
|
}
|
|
167
240
|
}
|
|
168
241
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pwi-plata-type",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "index.ts",
|
|
6
6
|
"bin": {
|
|
7
7
|
"plata": "bin/plata.ts",
|
|
8
|
-
"plata-cli-create": "bin/plata-create.ts"
|
|
8
|
+
"plata-cli-create": "bin/plata-create.ts",
|
|
9
|
+
"plata-swagger-gen": "bin/plata-swagger-gen.ts"
|
|
9
10
|
},
|
|
10
11
|
"scripts": {
|
|
11
12
|
"postinstall": "node postinstall.js"
|
|
@@ -17,8 +18,10 @@
|
|
|
17
18
|
"@types/express": "^4.17.13",
|
|
18
19
|
"@types/glob": "^7.2.0",
|
|
19
20
|
"@types/jest": "^28.1.1",
|
|
21
|
+
"@types/swagger-ui-express": "^4.1.3",
|
|
20
22
|
"glob": "^8.0.3",
|
|
21
23
|
"jest": "^28.1.1",
|
|
24
|
+
"swagger-ui-express": "^4.4.0",
|
|
22
25
|
"ts-jest": "^28.0.4",
|
|
23
26
|
"ts-node": "^10.8.1"
|
|
24
27
|
},
|
package/postinstall-tools.mjs
CHANGED
package/postinstall.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import * as ç__Name__çConfig from '../configs/ç__name__ç.js'
|
|
3
3
|
|
|
4
4
|
export class ç__Name__ç {
|
|
5
|
-
private readonly config: typeof ç__Name__çConfig
|
|
5
|
+
private readonly config: typeof ç__Name__çConfig.default
|
|
6
6
|
|
|
7
7
|
constructor(config: typeof ç__Name__çConfig.default) {
|
|
8
8
|
this.config = config
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
//@ts-nocheck
|
|
2
2
|
import { Router } from 'express'
|
|
3
|
-
import { PlataRoute } from 'ç__PlataName__ç'
|
|
3
|
+
import { PlataRoute, PlataRoutes } from 'ç__PlataName__ç'
|
|
4
4
|
|
|
5
|
-
export default ():
|
|
6
|
-
const router = Router()
|
|
5
|
+
export default (): PlataRoutes._Router => {
|
|
6
|
+
const router = Router() as PlataRoutes._Router
|
|
7
7
|
|
|
8
8
|
router.get('/', PlataRoute(async (req, res) => {
|
|
9
9
|
return res.status(200).json({})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path'
|
|
2
2
|
|
|
3
3
|
export async function install({ dirs, projectPackageJson }) {
|
|
4
4
|
const { tools } = await import(`file:///${path.resolve(dirs.plataDir, 'postinstall-tools.mjs')}`.replace(/\\/g, '/'))
|
|
@@ -23,6 +23,7 @@ export async function install({ dirs, projectPackageJson }) {
|
|
|
23
23
|
projectPackageJson.scripts.start = `ts-node --transpile-only --esm ./node_modules/${projectPackageJson.plata_name}/bin/plata`
|
|
24
24
|
projectPackageJson.scripts.create = `ts-node --transpile-only --esm ./node_modules/${projectPackageJson.plata_name}/bin/plata-create --`
|
|
25
25
|
projectPackageJson.scripts.dev = "npx nodemon -e '.js,.mjs,.json,.ts' --exec 'npm start'"
|
|
26
|
+
projectPackageJson.scripts['swagger:gen'] = `ts-node --transpile-only --esm ./node_modules/${projectPackageJson.plata_name}/bin/plata-swagger-gen`
|
|
26
27
|
projectPackageJson.main = undefined
|
|
27
28
|
|
|
28
29
|
await Promise.all(promises)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"swagger": "2.0",
|
|
3
|
+
"info": {
|
|
4
|
+
"title": "",
|
|
5
|
+
"description": "",
|
|
6
|
+
"version": ""
|
|
7
|
+
},
|
|
8
|
+
"host": "",
|
|
9
|
+
"basePath": "/api",
|
|
10
|
+
"schemes": [
|
|
11
|
+
"https",
|
|
12
|
+
"http"
|
|
13
|
+
],
|
|
14
|
+
"securityDefinitions": {
|
|
15
|
+
"apiKeyAuth": {
|
|
16
|
+
"type": "apiKey",
|
|
17
|
+
"name": "x-access-token",
|
|
18
|
+
"in": "header"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"summary": "summary",
|
|
3
|
+
"description": "Descrião da rota",
|
|
4
|
+
"security": [
|
|
5
|
+
{
|
|
6
|
+
"apiKeyAuth": []
|
|
7
|
+
}
|
|
8
|
+
],
|
|
9
|
+
"parameters": [
|
|
10
|
+
{
|
|
11
|
+
"name": "test",
|
|
12
|
+
"description": "",
|
|
13
|
+
"in": "header",
|
|
14
|
+
"required": false,
|
|
15
|
+
"type": "string"
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"200": {
|
|
3
|
+
"description": "Okay",
|
|
4
|
+
"examples": {
|
|
5
|
+
"status": "Okay"
|
|
6
|
+
}
|
|
7
|
+
},
|
|
8
|
+
"400": {
|
|
9
|
+
"description": "Requisição invalida",
|
|
10
|
+
"example":{
|
|
11
|
+
"errorID": "string",
|
|
12
|
+
"msg": "string"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"500": {
|
|
16
|
+
"description": "Erro Interno",
|
|
17
|
+
"examples": {
|
|
18
|
+
"errorID": "string",
|
|
19
|
+
"msg": "string",
|
|
20
|
+
"error": "any"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|