pwi-plata-type 0.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/bin/extras/plata-create-api.ts +58 -0
- package/bin/extras/plata-create-lib.ts +41 -0
- package/bin/extras/plata-create-tools.ts +98 -0
- package/bin/plata-create.ts +34 -0
- package/bin/plata.ts +76 -0
- package/index.ts +11 -0
- package/libs/cluster.ts +184 -0
- package/libs/env.ts +28 -0
- package/libs/routes.ts +34 -0
- package/libs/tools.ts +161 -0
- package/package.json +29 -0
- package/postinstall-tools.mjs +108 -0
- package/postinstall.js +38 -0
- package/templates/create-cli/config.ts +9 -0
- package/templates/create-cli/lib.ts +19 -0
- package/templates/create-cli/route.ts +11 -0
- package/templates/postinstall/api/.vscode/launch.json +34 -0
- package/templates/postinstall/api/Dockerfile +13 -0
- package/templates/postinstall/api/_install.mjs +28 -0
- package/templates/postinstall/api/configs/env.ts +9 -0
- package/templates/postinstall/api/envs/debug.env +8 -0
- package/templates/postinstall/api/envs/homolog.env +9 -0
- package/templates/postinstall/api/envs/prod.env +9 -0
- package/templates/postinstall/api/tsconfig.json +16 -0
- package/templates/postinstall/lib/_install.mjs +28 -0
- package/templates/postinstall/lib/postinstall-tools.mjs +112 -0
- package/templates/postinstall/lib/postinstall.js +29 -0
- package/templates/postinstall/lib/tsconfig.json +16 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { tools } from "./plata-create-tools.js";
|
|
2
|
+
import * as path from 'node:path'
|
|
3
|
+
|
|
4
|
+
export async function h() {
|
|
5
|
+
return tools.args.forEachArg(async (command, args) => {
|
|
6
|
+
const promises: any[] = []
|
|
7
|
+
|
|
8
|
+
switch (command) {
|
|
9
|
+
case 'lib':
|
|
10
|
+
const nameLib = args.shift()
|
|
11
|
+
promises.push(tools.files.deployFileToProject(
|
|
12
|
+
'configs',
|
|
13
|
+
'config',
|
|
14
|
+
`${nameLib.toLowerCase()}.ts`,
|
|
15
|
+
{ Name: `${nameLib}`, name: `${nameLib.toLowerCase()}` }
|
|
16
|
+
).finally(() => console.log(`Config ${nameLib.toLowerCase()} criada`)))
|
|
17
|
+
|
|
18
|
+
promises.push(tools.files.deployFileToProject(
|
|
19
|
+
'libs',
|
|
20
|
+
'lib',
|
|
21
|
+
`${nameLib.toLowerCase()}.ts`,
|
|
22
|
+
{ Name: `${nameLib}`, name: `${nameLib.toLowerCase()}` }
|
|
23
|
+
).finally(() => console.log(`Lib ${nameLib.toLowerCase()} criada`)))
|
|
24
|
+
break;
|
|
25
|
+
case 'config':
|
|
26
|
+
const nameConfig = args.shift()
|
|
27
|
+
promises.push(tools.files.deployFileToProject(
|
|
28
|
+
'configs',
|
|
29
|
+
'config',
|
|
30
|
+
`${nameConfig.toLowerCase()}.ts`,
|
|
31
|
+
{ Name: `${nameConfig}`, name: `${nameConfig.toLowerCase()}` }
|
|
32
|
+
).finally(() => console.log(`Config ${nameConfig.toLowerCase()} criada`)))
|
|
33
|
+
break;
|
|
34
|
+
case 'cluster':
|
|
35
|
+
console.log('CLUSTER AINDA NÃO CRIANDO AINDA')
|
|
36
|
+
break;
|
|
37
|
+
case 'route':
|
|
38
|
+
const routeArg = `${args.shift()}`.split('/')
|
|
39
|
+
|
|
40
|
+
const routeFileName = routeArg[routeArg.length - 1] === '' ? 'index' : routeArg.pop()
|
|
41
|
+
const routeFilePath = path.join('routes', ...routeArg.filter(v => v !== ''))
|
|
42
|
+
|
|
43
|
+
promises.push(tools.files.deployFileToProject(
|
|
44
|
+
routeFilePath,
|
|
45
|
+
'route',
|
|
46
|
+
`${routeFileName}.ts`,
|
|
47
|
+
{}
|
|
48
|
+
).finally(() => console.log(
|
|
49
|
+
`Rota ${routeFilePath}/${routeFileName === 'index' ? '' : routeFileName} criada`
|
|
50
|
+
)))
|
|
51
|
+
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
await Promise.all(promises)
|
|
56
|
+
return args
|
|
57
|
+
})
|
|
58
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { tools } from "./plata-create-tools.js";
|
|
2
|
+
|
|
3
|
+
export async function h() {
|
|
4
|
+
return tools.args.forEachArg(async (command, args) => {
|
|
5
|
+
const promises: any[] = []
|
|
6
|
+
|
|
7
|
+
switch (command) {
|
|
8
|
+
case 'lib':
|
|
9
|
+
const nameLib = args.shift()
|
|
10
|
+
promises.push(tools.files.deployFileToProject(
|
|
11
|
+
'configs',
|
|
12
|
+
'config',
|
|
13
|
+
`${nameLib.toLowerCase()}.ts`,
|
|
14
|
+
{ Name: `${nameLib}`, name: `${nameLib.toLowerCase()}` }
|
|
15
|
+
).finally(() => console.log(`Config ${nameLib.toLowerCase()} criada`)))
|
|
16
|
+
|
|
17
|
+
promises.push(tools.files.deployFileToProject(
|
|
18
|
+
'libs',
|
|
19
|
+
'lib',
|
|
20
|
+
`${nameLib.toLowerCase()}.ts`,
|
|
21
|
+
{ Name: `${nameLib}`, name: `${nameLib.toLowerCase()}` }
|
|
22
|
+
).finally(() => console.log(`Lib ${nameLib.toLowerCase()} criada`)))
|
|
23
|
+
break;
|
|
24
|
+
case 'config':
|
|
25
|
+
const nameConfig = args.shift()
|
|
26
|
+
promises.push(tools.files.deployFileToProject(
|
|
27
|
+
'configs',
|
|
28
|
+
'config',
|
|
29
|
+
`${nameConfig.toLowerCase()}.ts`,
|
|
30
|
+
{ Name: `${nameConfig}`, name: `${nameConfig.toLowerCase()}` }
|
|
31
|
+
).finally(() => console.log(`Config ${nameConfig.toLowerCase()} criada`)))
|
|
32
|
+
break;
|
|
33
|
+
case 'cluster':
|
|
34
|
+
console.log('CLUSTER AINDA NÃO CRIANDO AINDA')
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
await Promise.all(promises)
|
|
39
|
+
return args
|
|
40
|
+
})
|
|
41
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as fs from 'node:fs'
|
|
2
|
+
import * as path from 'node:path'
|
|
3
|
+
|
|
4
|
+
import { PlataDirs, PlataFiles } from '../../libs/tools.js'
|
|
5
|
+
|
|
6
|
+
export module tools {
|
|
7
|
+
export module files {
|
|
8
|
+
export async function mkdirIfNotExists(dir: string) {
|
|
9
|
+
try {
|
|
10
|
+
const p = path.resolve(dir)
|
|
11
|
+
|
|
12
|
+
if (!fs.existsSync(p)) {
|
|
13
|
+
fs.mkdirSync(p, { recursive: true })
|
|
14
|
+
}
|
|
15
|
+
} catch (err) {
|
|
16
|
+
console.error(err)
|
|
17
|
+
process.exit(1)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export async function copyFileIfNotExists(source: string, destination: string) {
|
|
22
|
+
try {
|
|
23
|
+
const s = path.resolve(source)
|
|
24
|
+
const d = path.resolve(destination)
|
|
25
|
+
|
|
26
|
+
if (!fs.existsSync(d)) {
|
|
27
|
+
fs.copyFileSync(s, d)
|
|
28
|
+
}
|
|
29
|
+
} catch (err) {
|
|
30
|
+
console.error(err)
|
|
31
|
+
process.exit(1)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export async function copyFileToProject(projectFolder: string, templateFile: string, fileName: string): Promise<string> {
|
|
36
|
+
const s = path.resolve(PlataDirs.getPlataTempleteDir('create-cli', `${templateFile}.ts`))
|
|
37
|
+
let d = path.resolve(PlataDirs.getProjectDir(), projectFolder)
|
|
38
|
+
|
|
39
|
+
await mkdirIfNotExists(d)
|
|
40
|
+
d = path.join(d, fileName)
|
|
41
|
+
await copyFileIfNotExists(s, d)
|
|
42
|
+
|
|
43
|
+
return d
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export async function deployFileToProject(projectFolder: string, templateFile: string, fileName: string, args: any) {
|
|
47
|
+
const fileInProject = await copyFileToProject(projectFolder, templateFile, fileName)
|
|
48
|
+
|
|
49
|
+
const content: any = await PlataFiles.readFileSync(fileInProject, (line) => {
|
|
50
|
+
if (line === '//@ts-nocheck') {
|
|
51
|
+
return ''
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (line === '') {
|
|
55
|
+
return ''
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Procura por texto para subistituir esse texto que esta no formato ç__PARAMETRO__ç
|
|
59
|
+
let lastIndex = 0
|
|
60
|
+
while(lastIndex !== -1) {
|
|
61
|
+
lastIndex = line.indexOf('ç__', lastIndex)
|
|
62
|
+
|
|
63
|
+
if (lastIndex !== -1) {
|
|
64
|
+
const pIndex = line.indexOf('__ç', lastIndex)
|
|
65
|
+
const param = line.slice(lastIndex + 3, pIndex)
|
|
66
|
+
|
|
67
|
+
line = line.replace(new RegExp(`ç__${param}__ç`, 'g'), args[param])
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return line
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
if (content.err !== undefined) {
|
|
75
|
+
console.log(content.err)
|
|
76
|
+
process.exit(1)
|
|
77
|
+
} else {
|
|
78
|
+
fs.writeFileSync(fileInProject, content)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export module args {
|
|
84
|
+
export type argsCallBack = (command: string, args: string[]) => Promise<string[]>
|
|
85
|
+
|
|
86
|
+
export async function forEachArg(callback: argsCallBack) {
|
|
87
|
+
let args = process.argv.slice(process.argv.indexOf('--') + 1)
|
|
88
|
+
|
|
89
|
+
while(args.length !== 0) {
|
|
90
|
+
const command = args.shift()
|
|
91
|
+
|
|
92
|
+
if (command !== undefined) {
|
|
93
|
+
args = await callback(command, args)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { PlataDirs } from "../libs/tools.js";
|
|
2
|
+
|
|
3
|
+
interface Handler {
|
|
4
|
+
h: () => Promise<void>
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
const main = async () => {
|
|
8
|
+
const projectPackage = await PlataDirs.ProjectJson
|
|
9
|
+
|
|
10
|
+
if (projectPackage.plata_no_setup !== undefined) {
|
|
11
|
+
console.log('Existe o parametro plata_no_setup no package.json ou seja a plata não esta configurada')
|
|
12
|
+
process.exit(0)
|
|
13
|
+
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let handler: Handler
|
|
17
|
+
|
|
18
|
+
switch(projectPackage.plata_type ?? 'api') {
|
|
19
|
+
case 'api':
|
|
20
|
+
handler = (await import('./extras/plata-create-api.js')) as unknown as Handler
|
|
21
|
+
break;
|
|
22
|
+
case 'lib':
|
|
23
|
+
handler = (await import('./extras/plata-create-lib.js')) as unknown as Handler
|
|
24
|
+
break;
|
|
25
|
+
default:
|
|
26
|
+
console.log(`tipo ${projectPackage.plata_type} não suportado pela plata`)
|
|
27
|
+
process.exit(0)
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
await handler.h()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
main()
|
package/bin/plata.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { PlataClusterManager, PlataClusterMsg } from "../libs/cluster.js"
|
|
2
|
+
import { loadEnvProjectFile } from "../libs/env.js"
|
|
3
|
+
import { loadExpressRoutes } from "../libs/routes.js"
|
|
4
|
+
import express, { Express } from "express"
|
|
5
|
+
|
|
6
|
+
const main = async () => {
|
|
7
|
+
const clusterLib = new PlataClusterManager();
|
|
8
|
+
|
|
9
|
+
if (clusterLib.isPrimary()) {
|
|
10
|
+
{
|
|
11
|
+
console.log('Carregando .env')
|
|
12
|
+
const err = await loadEnvProjectFile()
|
|
13
|
+
|
|
14
|
+
if (err !== null) {
|
|
15
|
+
console.log(err)
|
|
16
|
+
process.exit(1)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
console.log(process.env.ENV)
|
|
21
|
+
|
|
22
|
+
clusterLib.run({
|
|
23
|
+
name: '_plata_express',
|
|
24
|
+
onStart: async () => null,
|
|
25
|
+
env: process.env.ENV
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
clusterLib.loadClusters()
|
|
29
|
+
} else {
|
|
30
|
+
await loadEnvProjectFile()
|
|
31
|
+
|
|
32
|
+
process.on('message', async (msg: PlataClusterMsg) => {
|
|
33
|
+
process.emit(msg.id as any, msg as any)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
if (process.env._plata_name === '_plata_express') {
|
|
37
|
+
process.on('exit', () => process.send({
|
|
38
|
+
id: 0,
|
|
39
|
+
name: '_plata',
|
|
40
|
+
data: {
|
|
41
|
+
action: 'KILL'
|
|
42
|
+
}
|
|
43
|
+
}))
|
|
44
|
+
|
|
45
|
+
const port = process.env.PORT ?? 3050
|
|
46
|
+
const app: Express = express()
|
|
47
|
+
|
|
48
|
+
app.use(process.env._PLATA_API_ROOT ?? '/api',await loadExpressRoutes())
|
|
49
|
+
|
|
50
|
+
app.use((err, req, res, next) => {
|
|
51
|
+
return res.status(500).json({
|
|
52
|
+
errorId: 'B00000',
|
|
53
|
+
error: 'Erro interno da aplicação',
|
|
54
|
+
msg: err.message
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
app.all('*', (req, res) => {
|
|
59
|
+
return res.status(404).json({
|
|
60
|
+
errorId: 'B00001',
|
|
61
|
+
error: 'Rota não encontrada',
|
|
62
|
+
msg: req.path
|
|
63
|
+
})
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
app.listen(port, () => {
|
|
67
|
+
console.log(`Iniciando Worker Express na porta ${port}`)
|
|
68
|
+
setTimeout(() => process.removeAllListeners('exit'), 500)
|
|
69
|
+
})
|
|
70
|
+
} else {
|
|
71
|
+
await clusterLib.loadWorker()
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
main()
|
package/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as PlataCluster from './libs/cluster.js'
|
|
2
|
+
import * as PlataEnv from './libs/env.js'
|
|
3
|
+
import * as PlataRoutes from './libs/routes.js'
|
|
4
|
+
import * as PlataTools from './libs/tools.js'
|
|
5
|
+
|
|
6
|
+
export {
|
|
7
|
+
PlataCluster,
|
|
8
|
+
PlataEnv,
|
|
9
|
+
PlataRoutes,
|
|
10
|
+
PlataTools,
|
|
11
|
+
}
|
package/libs/cluster.ts
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { PlataRequire, PlataDirs, PlataFiles } from './tools.js'
|
|
2
|
+
import { cpus } from 'node:os'
|
|
3
|
+
import * as typeCluster from 'node:cluster'
|
|
4
|
+
|
|
5
|
+
export interface PlataClusterWorkerConfig {
|
|
6
|
+
name: string,
|
|
7
|
+
env: string,
|
|
8
|
+
onStart: () => Promise<void>
|
|
9
|
+
workers?: number,
|
|
10
|
+
workersEnv?: any,
|
|
11
|
+
onExit?: (worker: typeCluster.Worker, code: number, signal: string) => void,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface PlataCluster {
|
|
15
|
+
pids: number[],
|
|
16
|
+
config: PlataClusterWorkerConfig
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface PlataClusterMsg {
|
|
20
|
+
name: string,
|
|
21
|
+
id: string,
|
|
22
|
+
data: any
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface PlataClusterProcess {
|
|
26
|
+
clusters: PlataCluster[]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface _PlataClusterProcess extends NodeJS.Process {
|
|
30
|
+
_plata?: PlataClusterProcess
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function getClusterNodeProcess(): PlataClusterProcess {
|
|
34
|
+
const p = process as _PlataClusterProcess
|
|
35
|
+
|
|
36
|
+
if (p._plata === undefined) {
|
|
37
|
+
p._plata = {
|
|
38
|
+
clusters: []
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (p._plata.clusters === undefined) {
|
|
43
|
+
p._plata.clusters = []
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return p._plata
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export class PlataClusterManager {
|
|
50
|
+
private readonly Cluster = typeCluster.default as unknown as typeCluster.Cluster
|
|
51
|
+
private readonly Process = getClusterNodeProcess()
|
|
52
|
+
|
|
53
|
+
constructor() {
|
|
54
|
+
// Registra o evento que lida com
|
|
55
|
+
if (this.Cluster.isPrimary) {
|
|
56
|
+
if (this.Cluster.eventNames().indexOf('exit') === -1) {
|
|
57
|
+
this.Cluster.on('exit', (worker, code, signal) => {
|
|
58
|
+
if (worker.process.pid === undefined) return
|
|
59
|
+
|
|
60
|
+
const clusterIndex = this.Process.clusters.findIndex(cluster =>
|
|
61
|
+
cluster.pids.indexOf(worker.process.pid ?? 0) !== -1
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
if(clusterIndex !== -1) {
|
|
65
|
+
const cluster = this.Process.clusters[clusterIndex]
|
|
66
|
+
|
|
67
|
+
console.log(`O Worker ${worker.process.pid} do cluster ${cluster.config.name} morreu com o codigo ${code} ${signal ?? ''}`)
|
|
68
|
+
console.log(`Iniciando um novo worker no cluster ${cluster.config.name}`)
|
|
69
|
+
|
|
70
|
+
this.Cluster.emit(`_plata.cluster.worker.exit-${cluster.config.name}`, worker, code, signal)
|
|
71
|
+
|
|
72
|
+
const w = this.Cluster.fork({
|
|
73
|
+
...cluster.config.workersEnv,
|
|
74
|
+
ENV: cluster.config.env,
|
|
75
|
+
_plata_name: cluster.config.name
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
const pidIndex = cluster.pids.indexOf(worker.process.pid)
|
|
79
|
+
|
|
80
|
+
cluster.pids[pidIndex] = w.process.pid ?? 0
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (this.Cluster.eventNames().indexOf('message') === -1) {
|
|
86
|
+
this.Cluster.on('message', this._clusterMsgServer)
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
public async run(config: PlataClusterWorkerConfig) {
|
|
92
|
+
if (config.workers === undefined) {
|
|
93
|
+
if (config.env === 'prod') {
|
|
94
|
+
config.workers = cpus().length
|
|
95
|
+
} else {
|
|
96
|
+
config.workers = 1
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
console.log(`Iniciando ${config.workers} workers para o cluster ${config.name}`)
|
|
101
|
+
|
|
102
|
+
const cluster: PlataCluster = {
|
|
103
|
+
pids: [],
|
|
104
|
+
config
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for (let i = 0; i < config.workers; i++) {
|
|
108
|
+
const w = this.Cluster.fork({
|
|
109
|
+
...config.workersEnv,
|
|
110
|
+
ENV: cluster.config.env,
|
|
111
|
+
_plata_name: cluster.config.name
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
cluster.pids.push(w.process.pid ?? 0)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (config.onExit !== undefined)
|
|
118
|
+
this.Cluster.on(`_plata.cluster.worker.exit-${cluster.config.name}`, config.onExit)
|
|
119
|
+
;
|
|
120
|
+
|
|
121
|
+
this.Process.clusters.push(cluster)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
public isPrimary(): boolean {
|
|
125
|
+
return this.Cluster.isPrimary
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public async loadClusters() {
|
|
129
|
+
const required: any = await PlataRequire.requireFolderAsync<any>(PlataDirs.getProjectDirClusters()).then(
|
|
130
|
+
result => result,
|
|
131
|
+
err => {
|
|
132
|
+
return { err }
|
|
133
|
+
}
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
if (required.err !== undefined) {
|
|
137
|
+
console.log(required.err)
|
|
138
|
+
process.exit(1)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const TypedRequired: PlataRequire.Required<PlataClusterWorkerConfig>[] = required
|
|
142
|
+
const promisesClusters: any[] = []
|
|
143
|
+
|
|
144
|
+
for (let i = 0; i < TypedRequired.length; i++) {
|
|
145
|
+
const required = TypedRequired[i];
|
|
146
|
+
|
|
147
|
+
promisesClusters.push(this.run(required.exports))
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
return Promise.all(promisesClusters)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
public async loadWorker() {
|
|
155
|
+
const file: string | null = await PlataFiles.findFile(
|
|
156
|
+
[
|
|
157
|
+
PlataDirs.getProjectDirClusters()
|
|
158
|
+
],
|
|
159
|
+
`${process.env["_plata_name"]}.ts`
|
|
160
|
+
).catch(err => {
|
|
161
|
+
console.error(err)
|
|
162
|
+
return null
|
|
163
|
+
})
|
|
164
|
+
|
|
165
|
+
if (file !== null) {
|
|
166
|
+
const config: PlataClusterWorkerConfig = (await import(file) as any).default
|
|
167
|
+
|
|
168
|
+
await config.onStart()
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
private async _clusterMsgServer(worker: typeCluster.Worker, msg: PlataClusterMsg) {
|
|
173
|
+
if (msg.name !== '_plata') {
|
|
174
|
+
// TODO :::
|
|
175
|
+
} else {
|
|
176
|
+
switch(msg.data.action) {
|
|
177
|
+
case 'KILL':
|
|
178
|
+
console.log('Solicitado kill do app')
|
|
179
|
+
process.exit(0)
|
|
180
|
+
;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
package/libs/env.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { PlataDirs, PlataFiles } from "./tools.js"
|
|
2
|
+
|
|
3
|
+
export interface EnvConfig {
|
|
4
|
+
readonly env: 'prod' | 'debug' | 'homolog' | string
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export async function loadEnvProjectFile() {
|
|
8
|
+
const config = process.env['ENV'] === undefined ?
|
|
9
|
+
(await import(PlataDirs.getProjectConfigFileDir('env.js')) as any).default as EnvConfig
|
|
10
|
+
: { env: process.env['ENV'] }
|
|
11
|
+
|
|
12
|
+
return PlataFiles.readFileAsync(
|
|
13
|
+
PlataDirs.getProjectEnvFileDir(`${config.env}.env`),
|
|
14
|
+
async (line) => {
|
|
15
|
+
if (line[0] === '#') return
|
|
16
|
+
|
|
17
|
+
if (line !== '') {
|
|
18
|
+
const env = line.split('=')
|
|
19
|
+
|
|
20
|
+
if (env.length >= 2) {
|
|
21
|
+
const [ key, ...value ] = env
|
|
22
|
+
|
|
23
|
+
process.env[key.toUpperCase()] = value.join('')
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
)
|
|
28
|
+
}
|
package/libs/routes.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { PlataDirs, PlataRequire } from "./tools.js";
|
|
2
|
+
import express, { Express, Router } from "express";
|
|
3
|
+
|
|
4
|
+
export type PlataRouter = () => Router
|
|
5
|
+
|
|
6
|
+
export async function loadExpressRoutes(): Promise<Router> {
|
|
7
|
+
const promise = PlataRequire.requireFolderAsync<PlataRouter>(PlataDirs.getProjectRoutesDir())
|
|
8
|
+
|
|
9
|
+
const router = Router()
|
|
10
|
+
router.use(express.json())
|
|
11
|
+
|
|
12
|
+
const routes = await promise.catch(err => { return { error: err } })
|
|
13
|
+
|
|
14
|
+
if ((routes as any).error === undefined) {
|
|
15
|
+
const r = routes as PlataRequire.Required<PlataRouter>[]
|
|
16
|
+
|
|
17
|
+
for (let i = 0; i < r.length; i++) {
|
|
18
|
+
const element = r[i];
|
|
19
|
+
|
|
20
|
+
const httpRoute = element.filePath
|
|
21
|
+
.replace(PlataDirs.getProjectRoutesDir(), '')
|
|
22
|
+
.replace(/.(ts|js)$/, '')
|
|
23
|
+
.replace(/index/, '')
|
|
24
|
+
.replace(/\\/, '/')
|
|
25
|
+
;
|
|
26
|
+
|
|
27
|
+
router.use(httpRoute, element.exports())
|
|
28
|
+
}
|
|
29
|
+
} else {
|
|
30
|
+
console.log(routes)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return router
|
|
34
|
+
}
|
package/libs/tools.ts
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import * as path from 'node:path'
|
|
2
|
+
import * as fs from 'node:fs'
|
|
3
|
+
import * as readline from 'node:readline'
|
|
4
|
+
import * as tGlob from 'glob'
|
|
5
|
+
|
|
6
|
+
const glob = (tGlob as any).default as typeof tGlob
|
|
7
|
+
|
|
8
|
+
export module PlataDirs {
|
|
9
|
+
export function getProjectDir(): string {
|
|
10
|
+
return path.resolve('.')
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function getProjectDirClusters(): string {
|
|
14
|
+
return path.resolve('.', 'clusters')
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function getProjectDirConfig(): string {
|
|
18
|
+
return path.resolve('.', 'configs')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function getProjectConfigFileDir(file: string): string {
|
|
22
|
+
return path.resolve('.', 'configs', file)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function getProjectDirEnvs(): string {
|
|
26
|
+
return path.resolve('.', 'envs')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function getProjectEnvFileDir(file: string): string {
|
|
30
|
+
return path.resolve('.', 'envs', file)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function getProjectRoutesDir(): string {
|
|
34
|
+
return path.resolve('.', 'routes')
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export const ProjectJson: any = JSON.parse(
|
|
38
|
+
fs.readFileSync(
|
|
39
|
+
path.join(PlataDirs.getProjectDir(), 'package.json')
|
|
40
|
+
).toString()
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
export function getPlataDir(): string {
|
|
44
|
+
return path.resolve('.', 'node_modules', ProjectJson.plata_name)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function getPlataTempletesDir(): string {
|
|
48
|
+
return path.join(getPlataDir(), 'templates')
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function getPlataTempleteDir(group:string, template: string) {
|
|
52
|
+
return path.join(getPlataTempletesDir(), group, template)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export module PlataFiles {
|
|
58
|
+
export type readLineCallback = (line: string) => Promise<void>
|
|
59
|
+
|
|
60
|
+
export type readLineCallbackSync = (line: string) => string
|
|
61
|
+
|
|
62
|
+
export function readFileAsync(file: string, callback: readLineCallback): Promise<Error | null> {
|
|
63
|
+
return new Promise(resolve => {
|
|
64
|
+
try {
|
|
65
|
+
const promises: any = []
|
|
66
|
+
|
|
67
|
+
const stream = readline.createInterface({
|
|
68
|
+
input: fs.createReadStream(file),
|
|
69
|
+
crlfDelay: Infinity
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
stream.on('close', () => {
|
|
73
|
+
Promise.all(promises).then(
|
|
74
|
+
() => resolve(null),
|
|
75
|
+
(err) => resolve(err),
|
|
76
|
+
)
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
stream.on('line', (line) => {
|
|
80
|
+
promises.push(callback(line))
|
|
81
|
+
})
|
|
82
|
+
} catch (e) {
|
|
83
|
+
resolve(e)
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export function readFileSync(file: string, callback: readLineCallbackSync): Promise<string | { err: any }> {
|
|
89
|
+
return new Promise(resolve => {
|
|
90
|
+
try {
|
|
91
|
+
const content = []
|
|
92
|
+
const stream = readline.createInterface({
|
|
93
|
+
input: fs.createReadStream(file),
|
|
94
|
+
crlfDelay: Infinity
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
stream.on('close', () => {
|
|
98
|
+
resolve(content.join('\n'))
|
|
99
|
+
})
|
|
100
|
+
|
|
101
|
+
stream.on('line', (line) => {
|
|
102
|
+
content.push(callback(line))
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
} catch(e) {
|
|
106
|
+
resolve({ err: e })
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export async function findFile(folders: string[], file: string): Promise<string | null> {
|
|
112
|
+
for (let i = 0; i < folders.length; i++) {
|
|
113
|
+
const folder = folders[i];
|
|
114
|
+
|
|
115
|
+
const f = glob.sync(`${folder}/**/${file}`)[0]
|
|
116
|
+
|
|
117
|
+
if (f !== undefined) {
|
|
118
|
+
return f
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return null
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export module PlataRequire {
|
|
127
|
+
export interface Required<Type> {
|
|
128
|
+
filePath: string,
|
|
129
|
+
name: string,
|
|
130
|
+
exports: Type
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export async function requireAsync<Type>(file: string): Promise<Required<Type>> {
|
|
134
|
+
const p = path.resolve(file)
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
filePath: p,
|
|
138
|
+
name: path.basename(p).replace('.ts', '').replace('.js', ''),
|
|
139
|
+
exports: (await import(p) as any).default as Type
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export async function requireFolderAsync<Type>(folder: string): Promise<Required<Type>[]> {
|
|
144
|
+
const promises: Promise<Required<Type>>[] = []
|
|
145
|
+
const p = path.resolve(folder)
|
|
146
|
+
|
|
147
|
+
glob.sync(`${p}/**/*.ts`).forEach(value => {
|
|
148
|
+
value = value.replace('.ts', '.js')
|
|
149
|
+
|
|
150
|
+
promises.push(requireAsync<Type>(value))
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
return Promise.all(promises)
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export module PlataExtra {
|
|
158
|
+
export function Sleep(ms: number) {
|
|
159
|
+
return new Promise(resolve => setTimeout(resolve, ms))
|
|
160
|
+
}
|
|
161
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pwi-plata-type",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "index.ts",
|
|
6
|
+
"bin": {
|
|
7
|
+
"plata": "bin/plata.ts",
|
|
8
|
+
"plata-cli-create": "bin/plata-create.ts"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"postinstall": "node postinstall.js"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [],
|
|
14
|
+
"author": "",
|
|
15
|
+
"license": "UNLICENSED",
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@types/express": "^4.17.13",
|
|
18
|
+
"@types/glob": "^7.2.0",
|
|
19
|
+
"@types/jest": "^28.1.1",
|
|
20
|
+
"glob": "^8.0.3",
|
|
21
|
+
"jest": "^28.1.1",
|
|
22
|
+
"ts-jest": "^28.0.4",
|
|
23
|
+
"ts-node": "^10.8.1"
|
|
24
|
+
},
|
|
25
|
+
"description": "",
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"express": "^4.18.1"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import * as fs from 'node:fs'
|
|
2
|
+
import * as path from 'node:path'
|
|
3
|
+
|
|
4
|
+
export function tools(dirs) {
|
|
5
|
+
const tools = new Object(null)
|
|
6
|
+
|
|
7
|
+
tools.mkdirIfNotExists = async (dir) => {
|
|
8
|
+
try {
|
|
9
|
+
const p = path.resolve(dir)
|
|
10
|
+
|
|
11
|
+
if (!fs.existsSync(p)) {
|
|
12
|
+
fs.mkdirSync(p, { resolve: true })
|
|
13
|
+
}
|
|
14
|
+
} catch (err) {
|
|
15
|
+
console.error(err)
|
|
16
|
+
process.exit(1)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
tools.copyFile = async (source, destination) => {
|
|
21
|
+
try {
|
|
22
|
+
const s = path.resolve(source)
|
|
23
|
+
const d = path.resolve(destination)
|
|
24
|
+
|
|
25
|
+
fs.copyFileSync(s, d)
|
|
26
|
+
} catch (err) {
|
|
27
|
+
console.error(err)
|
|
28
|
+
process.exit(1)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
tools.copyFileIfNotExists = async (source, destination) => {
|
|
33
|
+
try {
|
|
34
|
+
const s = path.resolve(source)
|
|
35
|
+
const d = path.resolve(destination)
|
|
36
|
+
|
|
37
|
+
if (!fs.existsSync(d)) {
|
|
38
|
+
tools.copyFile(s, d)
|
|
39
|
+
}
|
|
40
|
+
} catch (err) {
|
|
41
|
+
console.error(err)
|
|
42
|
+
process.exit(1)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
tools.forEachFileInFolder = async (folder, callback) => {
|
|
47
|
+
try {
|
|
48
|
+
const f = path.resolve(folder)
|
|
49
|
+
const files = fs.readdirSync(f)
|
|
50
|
+
|
|
51
|
+
const promises = []
|
|
52
|
+
|
|
53
|
+
files.forEach(file => {
|
|
54
|
+
const filePath = path.join(f, file)
|
|
55
|
+
|
|
56
|
+
promises.push(
|
|
57
|
+
(async () => callback(file, filePath))()
|
|
58
|
+
)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
await Promise.all(promises)
|
|
62
|
+
} catch (err) {
|
|
63
|
+
console.error(err)
|
|
64
|
+
process.exit(1)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
tools.createFolderProject = (async (folder) =>
|
|
69
|
+
tools.mkdirIfNotExists(path.join(dirs.projectDir, folder))
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
tools.copyFolderToProject = async (folder) => {
|
|
73
|
+
const templateFolder = path.join(dirs.templateDir, folder)
|
|
74
|
+
const destination = path.join(dirs.projectDir, folder)
|
|
75
|
+
|
|
76
|
+
await tools.mkdirIfNotExists(destination)
|
|
77
|
+
|
|
78
|
+
await tools.forEachFileInFolder(templateFolder, async (file, filePath) =>
|
|
79
|
+
tools.copyFileIfNotExists(
|
|
80
|
+
filePath,
|
|
81
|
+
path.join(destination, file)
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
tools.syncFolderProject = async (folder) => {
|
|
87
|
+
const templateFolder = path.join(dirs.templateDir, folder)
|
|
88
|
+
const destination = path.join(dirs.projectDir, folder)
|
|
89
|
+
|
|
90
|
+
await tools.mkdirIfNotExists(destination)
|
|
91
|
+
|
|
92
|
+
await tools.forEachFileInFolder(templateFolder, async (file, filePath) =>
|
|
93
|
+
tools.copyFile(
|
|
94
|
+
filePath,
|
|
95
|
+
path.join(destination, file)
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
tools.syncFileToProject = async (file) => {
|
|
101
|
+
const templateFile = path.join(dirs.templateDir, file)
|
|
102
|
+
const destination = path.join(dirs.projectDir, file)
|
|
103
|
+
|
|
104
|
+
await tools.copyFile(templateFile, destination)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return tools
|
|
108
|
+
}
|
package/postinstall.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import * as fs from 'node:fs'
|
|
2
|
+
import * as path from 'node:path'
|
|
3
|
+
|
|
4
|
+
const main = async () => {
|
|
5
|
+
const plataDir = path.resolve('.')
|
|
6
|
+
const templatesDir = path.resolve(plataDir, 'templates', 'postinstall')
|
|
7
|
+
const projectDir = path.resolve(plataDir, '..', '..')
|
|
8
|
+
let projectPackageJson = JSON.parse(fs.readFileSync(path.join(projectDir, 'package.json')).toString())
|
|
9
|
+
const plataPackageJson = JSON.parse(fs.readFileSync(path.join(plataDir, 'package.json')))
|
|
10
|
+
|
|
11
|
+
if (projectPackageJson.plata_no_setup !== undefined) {
|
|
12
|
+
process.exit(0)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
projectPackageJson.plata_type = projectPackageJson.plata_type ?? 'api'
|
|
16
|
+
projectPackageJson.plata_name = plataPackageJson.name
|
|
17
|
+
projectPackageJson.license = "UNLICENSED"
|
|
18
|
+
|
|
19
|
+
const templateDir = path.join(templatesDir, projectPackageJson.plata_type)
|
|
20
|
+
|
|
21
|
+
const { install } = await import(path.join(templateDir, '_install.mjs'))
|
|
22
|
+
|
|
23
|
+
projectPackageJson = await install({
|
|
24
|
+
dirs: {
|
|
25
|
+
plataDir,
|
|
26
|
+
templateDir,
|
|
27
|
+
projectDir,
|
|
28
|
+
},
|
|
29
|
+
projectPackageJson
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
fs.writeFileSync(
|
|
33
|
+
path.join(projectDir, 'package.json'),
|
|
34
|
+
JSON.stringify(projectPackageJson, null, 4)
|
|
35
|
+
)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
main()
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//@ts-nocheck
|
|
2
|
+
import * as ç__Name__çConfigImport from '../configs/ç__name__ç.js'
|
|
3
|
+
const ç__Name__çConfig = ç__Name__çConfigImport.default as unknown as typeof ç__Name__çConfigImport
|
|
4
|
+
|
|
5
|
+
export class ç__Name__ç {
|
|
6
|
+
constructor(config: typeof ç__Name__çConfig) {
|
|
7
|
+
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function getç__Name__ç(): ç__Name__ç {
|
|
12
|
+
const p = process as any
|
|
13
|
+
|
|
14
|
+
if (p._plata._libç__Name__ç === undefined) {
|
|
15
|
+
p._plata._libç__Name__ç = new ç__Name__ç(ç__Name__çConfig)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return p._plata._libç__Name__ç
|
|
19
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Use IntelliSense to learn about possible attributes.
|
|
3
|
+
// Hover to view descriptions of existing attributes.
|
|
4
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"name": "DEV",
|
|
9
|
+
"request": "launch",
|
|
10
|
+
"runtimeArgs": [
|
|
11
|
+
"run-script",
|
|
12
|
+
"dev"
|
|
13
|
+
],
|
|
14
|
+
"runtimeExecutable": "npm",
|
|
15
|
+
"skipFiles": [
|
|
16
|
+
"<node_internals>/**"
|
|
17
|
+
],
|
|
18
|
+
"type": "node"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "DEBUG",
|
|
22
|
+
"request": "launch",
|
|
23
|
+
"runtimeArgs": [
|
|
24
|
+
"run-script",
|
|
25
|
+
"start"
|
|
26
|
+
],
|
|
27
|
+
"runtimeExecutable": "npm",
|
|
28
|
+
"skipFiles": [
|
|
29
|
+
"<node_internals>/**"
|
|
30
|
+
],
|
|
31
|
+
"type": "node"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export async function install({ dirs, projectPackageJson }) {
|
|
2
|
+
const { tools } = await import('../../../postinstall-tools.mjs')
|
|
3
|
+
const promises = []
|
|
4
|
+
|
|
5
|
+
const t = tools(dirs)
|
|
6
|
+
|
|
7
|
+
promises.push(t.createFolderProject('clusters'))
|
|
8
|
+
promises.push(t.createFolderProject('routes'))
|
|
9
|
+
promises.push(t.createFolderProject('libs'))
|
|
10
|
+
|
|
11
|
+
promises.push(t.copyFolderToProject('configs'))
|
|
12
|
+
promises.push(t.copyFolderToProject('envs'))
|
|
13
|
+
promises.push(t.syncFolderProject('.vscode'))
|
|
14
|
+
|
|
15
|
+
promises.push(t.syncFileToProject('Dockerfile'))
|
|
16
|
+
promises.push(t.syncFileToProject('tsconfig.json'))
|
|
17
|
+
|
|
18
|
+
projectPackageJson.type = "module"
|
|
19
|
+
projectPackageJson.scripts = new Object(null)
|
|
20
|
+
projectPackageJson.scripts.start = "ts-node --transpile-only --esm ./node_modules/.bin/plata"
|
|
21
|
+
projectPackageJson.scripts.create = "ts-node --transpile-only --esm ./node_modules/.bin/plata-cli-create --"
|
|
22
|
+
projectPackageJson.scripts.dev = "npx nodemon -e '.js,.mjs,.json,.ts' --exec 'npm start'"
|
|
23
|
+
projectPackageJson.main = undefined
|
|
24
|
+
|
|
25
|
+
await Promise.all(promises)
|
|
26
|
+
|
|
27
|
+
return projectPackageJson
|
|
28
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"strictNullChecks": true,
|
|
4
|
+
"module": "es2022",
|
|
5
|
+
"target": "es2022",
|
|
6
|
+
"noImplicitAny": true,
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"esModuleInterop": true
|
|
10
|
+
},
|
|
11
|
+
"include": [
|
|
12
|
+
"./node_modules/plata-type/**/*"
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export async function install({ dirs, projectPackageJson }) {
|
|
2
|
+
const { tools } = await import('../../../postinstall-tools.mjs')
|
|
3
|
+
const promises = []
|
|
4
|
+
|
|
5
|
+
const t = tools(dirs)
|
|
6
|
+
|
|
7
|
+
promises.push(t.createFolderProject('clusters'))
|
|
8
|
+
promises.push(t.createFolderProject('routes'))
|
|
9
|
+
promises.push(t.createFolderProject('libs'))
|
|
10
|
+
|
|
11
|
+
promises.push(t.createFolderProject('configs'))
|
|
12
|
+
promises.push(t.createFolderProject('bin'))
|
|
13
|
+
|
|
14
|
+
promises.push(t.syncFileToProject('postinstall.js'))
|
|
15
|
+
promises.push(t.syncFileToProject('postinstall-tools.mjs'))
|
|
16
|
+
promises.push(t.syncFileToProject('tsconfig.json'))
|
|
17
|
+
|
|
18
|
+
projectPackageJson.type = "module"
|
|
19
|
+
projectPackageJson.scripts = new Object(null)
|
|
20
|
+
projectPackageJson.scripts.dev = "ts-node"
|
|
21
|
+
projectPackageJson.scripts.postinstall = "node postinstall.js"
|
|
22
|
+
projectPackageJson.scripts.create = "ts-node --transpile-only --esm ./node_modules/.bin/plata-cli-create --"
|
|
23
|
+
projectPackageJson.main = undefined
|
|
24
|
+
|
|
25
|
+
await Promise.all(promises)
|
|
26
|
+
|
|
27
|
+
return projectPackageJson
|
|
28
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import * as fs from 'node:fs'
|
|
2
|
+
import * as path from 'node:path'
|
|
3
|
+
|
|
4
|
+
export function tools(dirs) {
|
|
5
|
+
const tools = new Object(null)
|
|
6
|
+
|
|
7
|
+
tools.mkdirIfNotExists = async (dir) => {
|
|
8
|
+
try {
|
|
9
|
+
const p = path.resolve(dir)
|
|
10
|
+
|
|
11
|
+
if (!fs.existsSync(p)) {
|
|
12
|
+
fs.mkdirSync(p, { resolve: true })
|
|
13
|
+
}
|
|
14
|
+
} catch (err) {
|
|
15
|
+
console.error(err)
|
|
16
|
+
process.exit(1)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
tools.copyFile = async (source, destination) => {
|
|
21
|
+
try {
|
|
22
|
+
const s = path.resolve(source)
|
|
23
|
+
const d = path.resolve(destination)
|
|
24
|
+
|
|
25
|
+
fs.copyFileSync(s, d)
|
|
26
|
+
} catch (err) {
|
|
27
|
+
console.error(err)
|
|
28
|
+
process.exit(1)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
tools.copyFileIfNotExists = async (source, destination) => {
|
|
33
|
+
try {
|
|
34
|
+
const s = path.resolve(source)
|
|
35
|
+
const d = path.resolve(destination)
|
|
36
|
+
|
|
37
|
+
if (!fs.existsSync(d) && fs.existsSync(s)) {
|
|
38
|
+
tools.copyFile(s, d)
|
|
39
|
+
}
|
|
40
|
+
} catch (err) {
|
|
41
|
+
console.error(err)
|
|
42
|
+
process.exit(1)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
tools.forEachFileInFolder = async (folder, callback) => {
|
|
47
|
+
try {
|
|
48
|
+
const f = path.resolve(folder)
|
|
49
|
+
if (!fs.existsSync(f)) {
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const files = fs.readdirSync(f)
|
|
54
|
+
|
|
55
|
+
const promises = []
|
|
56
|
+
|
|
57
|
+
files.forEach(file => {
|
|
58
|
+
const filePath = path.join(f, file)
|
|
59
|
+
|
|
60
|
+
promises.push(
|
|
61
|
+
(async () => callback(file, filePath))()
|
|
62
|
+
)
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
await Promise.all(promises)
|
|
66
|
+
} catch (err) {
|
|
67
|
+
console.error(err)
|
|
68
|
+
process.exit(1)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
tools.createFolderProject = (async (folder) =>
|
|
73
|
+
tools.mkdirIfNotExists(path.join(dirs.projectDir, folder))
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
tools.copyFolderToProject = async (folder) => {
|
|
77
|
+
const templateFolder = path.join(dirs.templateDir, folder)
|
|
78
|
+
const destination = path.join(dirs.projectDir, folder)
|
|
79
|
+
|
|
80
|
+
await tools.mkdirIfNotExists(destination)
|
|
81
|
+
|
|
82
|
+
await tools.forEachFileInFolder(templateFolder, async (file, filePath) =>
|
|
83
|
+
tools.copyFileIfNotExists(
|
|
84
|
+
filePath,
|
|
85
|
+
path.join(destination, file)
|
|
86
|
+
)
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
tools.syncFolderProject = async (folder) => {
|
|
91
|
+
const templateFolder = path.join(dirs.templateDir, folder)
|
|
92
|
+
const destination = path.join(dirs.projectDir, folder)
|
|
93
|
+
|
|
94
|
+
await tools.mkdirIfNotExists(destination)
|
|
95
|
+
|
|
96
|
+
await tools.forEachFileInFolder(templateFolder, async (file, filePath) =>
|
|
97
|
+
tools.copyFile(
|
|
98
|
+
filePath,
|
|
99
|
+
path.join(destination, file)
|
|
100
|
+
)
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
tools.syncFileToProject = async (file) => {
|
|
105
|
+
const templateFile = path.join(dirs.templateDir, file)
|
|
106
|
+
const destination = path.join(dirs.projectDir, file)
|
|
107
|
+
|
|
108
|
+
await tools.copyFile(templateFile, destination)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return tools
|
|
112
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as fs from 'node:fs'
|
|
2
|
+
import * as path from 'node:path'
|
|
3
|
+
import { tools } from './postinstall-tools.mjs'
|
|
4
|
+
|
|
5
|
+
const main = async() => {
|
|
6
|
+
const plataDir = path.resolve('.')
|
|
7
|
+
const projectDir = path.resolve(plataDir, '..', '..')
|
|
8
|
+
const projectPackageJson = JSON.parse(fs.readFileSync(path.join(projectDir, 'package.json')).toString())
|
|
9
|
+
|
|
10
|
+
if (projectPackageJson.plata_no_setup !== undefined) {
|
|
11
|
+
process.exit(0)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const t = tools({
|
|
15
|
+
plataDir,
|
|
16
|
+
projectDir,
|
|
17
|
+
templateDir: plataDir
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
const promises = []
|
|
21
|
+
|
|
22
|
+
promises.push(t.copyFolderToProject('configs'))
|
|
23
|
+
promises.push(t.syncFolderProject('clusters'))
|
|
24
|
+
promises.push(t.syncFolderProject('libs'))
|
|
25
|
+
|
|
26
|
+
await Promise.all(promises)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
main()
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"strictNullChecks": true,
|
|
4
|
+
"module": "es2022",
|
|
5
|
+
"target": "es2022",
|
|
6
|
+
"noImplicitAny": true,
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"esModuleInterop": true
|
|
10
|
+
},
|
|
11
|
+
"include": [
|
|
12
|
+
"./node_modules/plata-type/**/*"
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"strictNullChecks": true,
|
|
4
|
+
"module": "es2022",
|
|
5
|
+
"target": "es2022",
|
|
6
|
+
"noImplicitAny": true,
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"esModuleInterop": true
|
|
10
|
+
},
|
|
11
|
+
"include": [
|
|
12
|
+
"./node_modules/plata-type/**/*"
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
}
|
|
16
|
+
|