@trinacria/cli 0.1.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -0
- package/README.npm.md +109 -0
- package/dist/cli.d.ts +19 -0
- package/dist/cli.js +88 -0
- package/dist/commands/build.d.ts +2 -0
- package/dist/commands/build.js +102 -0
- package/dist/commands/dev.d.ts +28 -0
- package/dist/commands/dev.js +186 -0
- package/dist/commands/new.d.ts +41 -0
- package/dist/commands/new.js +280 -0
- package/dist/commands/start.d.ts +13 -0
- package/dist/commands/start.js +110 -0
- package/dist/config/config.contract.d.ts +9 -0
- package/dist/config/config.contract.js +2 -0
- package/dist/config/default-config.d.ts +2 -0
- package/dist/config/default-config.js +11 -0
- package/dist/config/load-config.d.ts +2 -0
- package/dist/config/load-config.js +113 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/templates/api-events-rabbitmq/.env.example +23 -0
- package/dist/templates/api-events-rabbitmq/Dockerfile +18 -0
- package/dist/templates/api-events-rabbitmq/README.md +97 -0
- package/dist/templates/api-events-rabbitmq/docker-compose.yml +30 -0
- package/dist/templates/api-events-rabbitmq/package.json +21 -0
- package/dist/templates/api-events-rabbitmq/src/global/config.service.ts +95 -0
- package/dist/templates/api-events-rabbitmq/src/global/controllers/swagger/docs.html +28 -0
- package/dist/templates/api-events-rabbitmq/src/global/controllers/swagger/swagger-docs.controller.ts +79 -0
- package/dist/templates/api-events-rabbitmq/src/global/rabbitmq.service.ts +86 -0
- package/dist/templates/api-events-rabbitmq/src/global/register-global-controllers.ts +20 -0
- package/dist/templates/api-events-rabbitmq/src/main.ts +89 -0
- package/dist/templates/api-events-rabbitmq/src/modules/events/dto/event.dto.ts +24 -0
- package/dist/templates/api-events-rabbitmq/src/modules/events/dto/index.ts +2 -0
- package/dist/templates/api-events-rabbitmq/src/modules/events/dto/publish-event.dto.ts +12 -0
- package/dist/templates/api-events-rabbitmq/src/modules/events/events.controller.ts +76 -0
- package/dist/templates/api-events-rabbitmq/src/modules/events/events.module.ts +27 -0
- package/dist/templates/api-events-rabbitmq/src/modules/events/events.provider.ts +28 -0
- package/dist/templates/api-events-rabbitmq/src/modules/events/events.service.ts +19 -0
- package/dist/templates/api-events-rabbitmq/src/modules/events/events.store.ts +42 -0
- package/dist/templates/api-events-rabbitmq/src/modules/events/events.tokens.ts +11 -0
- package/dist/templates/api-events-rabbitmq/trinacria.config.mjs +12 -0
- package/dist/templates/api-events-rabbitmq/tsconfig.json +14 -0
- package/dist/templates/api-events-redis/.env.example +18 -0
- package/dist/templates/api-events-redis/Dockerfile +18 -0
- package/dist/templates/api-events-redis/README.md +97 -0
- package/dist/templates/api-events-redis/docker-compose.yml +33 -0
- package/dist/templates/api-events-redis/package.json +18 -0
- package/dist/templates/api-events-redis/src/global/config.service.ts +93 -0
- package/dist/templates/api-events-redis/src/global/controllers/swagger/docs.html +28 -0
- package/dist/templates/api-events-redis/src/global/controllers/swagger/swagger-docs.controller.ts +79 -0
- package/dist/templates/api-events-redis/src/global/redis.service.ts +50 -0
- package/dist/templates/api-events-redis/src/global/register-global-controllers.ts +20 -0
- package/dist/templates/api-events-redis/src/main.ts +88 -0
- package/dist/templates/api-events-redis/src/modules/events/dto/event.dto.ts +24 -0
- package/dist/templates/api-events-redis/src/modules/events/dto/index.ts +2 -0
- package/dist/templates/api-events-redis/src/modules/events/dto/publish-event.dto.ts +12 -0
- package/dist/templates/api-events-redis/src/modules/events/events.controller.ts +76 -0
- package/dist/templates/api-events-redis/src/modules/events/events.module.ts +27 -0
- package/dist/templates/api-events-redis/src/modules/events/events.provider.ts +28 -0
- package/dist/templates/api-events-redis/src/modules/events/events.service.ts +19 -0
- package/dist/templates/api-events-redis/src/modules/events/events.store.ts +42 -0
- package/dist/templates/api-events-redis/src/modules/events/events.tokens.ts +11 -0
- package/dist/templates/api-events-redis/trinacria.config.mjs +12 -0
- package/dist/templates/api-events-redis/tsconfig.json +14 -0
- package/dist/templates/api-mongoose-mongodb/.env.example +17 -0
- package/dist/templates/api-mongoose-mongodb/Dockerfile +18 -0
- package/dist/templates/api-mongoose-mongodb/README.md +98 -0
- package/dist/templates/api-mongoose-mongodb/docker-compose.yml +34 -0
- package/dist/templates/api-mongoose-mongodb/package.json +17 -0
- package/dist/templates/api-mongoose-mongodb/src/global/config.service.ts +92 -0
- package/dist/templates/api-mongoose-mongodb/src/global/controllers/swagger/docs.html +28 -0
- package/dist/templates/api-mongoose-mongodb/src/global/controllers/swagger/swagger-docs.controller.ts +79 -0
- package/dist/templates/api-mongoose-mongodb/src/global/mongoose-schema.provider.ts +18 -0
- package/dist/templates/api-mongoose-mongodb/src/global/mongoose.service.ts +36 -0
- package/dist/templates/api-mongoose-mongodb/src/global/register-global-controllers.ts +20 -0
- package/dist/templates/api-mongoose-mongodb/src/main.ts +70 -0
- package/dist/templates/api-mongoose-mongodb/src/modules/users/dto/create-user.dto.ts +14 -0
- package/dist/templates/api-mongoose-mongodb/src/modules/users/dto/index.ts +2 -0
- package/dist/templates/api-mongoose-mongodb/src/modules/users/dto/public-user.dto.ts +22 -0
- package/dist/templates/api-mongoose-mongodb/src/modules/users/users.controller.ts +89 -0
- package/dist/templates/api-mongoose-mongodb/src/modules/users/users.module.ts +17 -0
- package/dist/templates/api-mongoose-mongodb/src/modules/users/users.schema.ts +35 -0
- package/dist/templates/api-mongoose-mongodb/src/modules/users/users.service.ts +35 -0
- package/dist/templates/api-mongoose-mongodb/src/modules/users/users.tokens.ts +9 -0
- package/dist/templates/api-mongoose-mongodb/trinacria.config.mjs +12 -0
- package/dist/templates/api-mongoose-mongodb/tsconfig.json +14 -0
- package/dist/templates/api-prisma-postgresql/.env.example +19 -0
- package/dist/templates/api-prisma-postgresql/Dockerfile +24 -0
- package/dist/templates/api-prisma-postgresql/README.md +107 -0
- package/dist/templates/api-prisma-postgresql/docker-compose.yml +38 -0
- package/dist/templates/api-prisma-postgresql/package.json +26 -0
- package/dist/templates/api-prisma-postgresql/prisma/schema.prisma +15 -0
- package/dist/templates/api-prisma-postgresql/prisma.config.ts +9 -0
- package/dist/templates/api-prisma-postgresql/src/global/config.service.ts +92 -0
- package/dist/templates/api-prisma-postgresql/src/global/controllers/swagger/docs.html +28 -0
- package/dist/templates/api-prisma-postgresql/src/global/controllers/swagger/swagger-docs.controller.ts +79 -0
- package/dist/templates/api-prisma-postgresql/src/global/prisma.service.ts +20 -0
- package/dist/templates/api-prisma-postgresql/src/global/register-global-controllers.ts +20 -0
- package/dist/templates/api-prisma-postgresql/src/main.ts +70 -0
- package/dist/templates/api-prisma-postgresql/src/modules/users/dto/create-user.dto.ts +14 -0
- package/dist/templates/api-prisma-postgresql/src/modules/users/dto/index.ts +2 -0
- package/dist/templates/api-prisma-postgresql/src/modules/users/dto/public-user.dto.ts +22 -0
- package/dist/templates/api-prisma-postgresql/src/modules/users/users.controller.ts +89 -0
- package/dist/templates/api-prisma-postgresql/src/modules/users/users.module.ts +15 -0
- package/dist/templates/api-prisma-postgresql/src/modules/users/users.service.ts +36 -0
- package/dist/templates/api-prisma-postgresql/src/modules/users/users.tokens.ts +7 -0
- package/dist/templates/api-prisma-postgresql/trinacria.config.mjs +12 -0
- package/dist/templates/api-prisma-postgresql/tsconfig.json +14 -0
- package/dist/templates/app-starter/.env.example +1 -0
- package/dist/templates/app-starter/Dockerfile +13 -0
- package/dist/templates/app-starter/README.md +32 -0
- package/dist/templates/app-starter/docker-compose.yml +8 -0
- package/dist/templates/app-starter/package.json +14 -0
- package/dist/templates/app-starter/src/main.ts +14 -0
- package/dist/templates/app-starter/trinacria.config.mjs +12 -0
- package/dist/templates/app-starter/tsconfig.json +14 -0
- package/dist/templates/cron-example/.env.example +11 -0
- package/dist/templates/cron-example/Dockerfile +13 -0
- package/dist/templates/cron-example/README.md +68 -0
- package/dist/templates/cron-example/docker-compose.yml +11 -0
- package/dist/templates/cron-example/package.json +15 -0
- package/dist/templates/cron-example/src/config.service.ts +46 -0
- package/dist/templates/cron-example/src/main.ts +41 -0
- package/dist/templates/cron-example/src/modules/cron/cron.module.ts +15 -0
- package/dist/templates/cron-example/src/modules/cron/cron.tokens.ts +6 -0
- package/dist/templates/cron-example/src/modules/cron/example-cron-jobs.provider.ts +48 -0
- package/dist/templates/cron-example/trinacria.config.mjs +12 -0
- package/dist/templates/cron-example/tsconfig.json +14 -0
- package/package.json +32 -0
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# @trinacria/cli
|
|
2
|
+
|
|
3
|
+
`@trinacria/cli` is the command-line tool for Trinacria apps.
|
|
4
|
+
|
|
5
|
+
It provides:
|
|
6
|
+
|
|
7
|
+
- app scaffolding (`new`, `create`, `init`)
|
|
8
|
+
- development mode with watch/restart (`dev`)
|
|
9
|
+
- TypeScript build (`build`)
|
|
10
|
+
- production start from compiled output (`start`)
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
Use it without global install:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx @trinacria/cli@alpha --help
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Or install in your project:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm i -D @trinacria/cli
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Create a new app
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx @trinacria/cli@alpha new my-app
|
|
30
|
+
cd my-app
|
|
31
|
+
npm install
|
|
32
|
+
npm run dev
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Quick start with explicit templates:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx @trinacria/cli@alpha new my-app --template app-starter
|
|
39
|
+
npx @trinacria/cli@alpha new my-cron --template cron-example
|
|
40
|
+
npx @trinacria/cli@alpha new my-api-pg --template api-prisma-postgresql
|
|
41
|
+
npx @trinacria/cli@alpha new my-api-mongo --template api-mongoose-mongodb
|
|
42
|
+
npx @trinacria/cli@alpha new my-api-redis --template api-events-redis
|
|
43
|
+
npx @trinacria/cli@alpha new my-api-rabbit --template api-events-rabbitmq
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Aliases:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx @trinacria/cli@alpha create my-app
|
|
50
|
+
npx @trinacria/cli@alpha init my-app
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Available templates
|
|
54
|
+
|
|
55
|
+
- `app-starter` (aliases: `minimal`, `starter`, `base`, `default`)
|
|
56
|
+
- `cron-example`
|
|
57
|
+
- `api-prisma-postgresql`
|
|
58
|
+
- `api-mongoose-mongodb`
|
|
59
|
+
- `api-events-redis`
|
|
60
|
+
- `api-events-rabbitmq`
|
|
61
|
+
|
|
62
|
+
Example:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx @trinacria/cli@alpha new my-app --template minimal
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Commands
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
trinacria new <project-name> [--template <name>] [--no-install] [--no-git] [--force]
|
|
72
|
+
trinacria dev
|
|
73
|
+
trinacria build
|
|
74
|
+
trinacria start
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Config file
|
|
78
|
+
|
|
79
|
+
Supported config names in your app root:
|
|
80
|
+
|
|
81
|
+
- `trinacria.config.js`
|
|
82
|
+
- `trinacria.config.cjs`
|
|
83
|
+
- `trinacria.config.mjs`
|
|
84
|
+
|
|
85
|
+
Example:
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
/** @type {import('@trinacria/cli').TrinacriaConfig} */
|
|
89
|
+
export default {
|
|
90
|
+
entry: "src/main.ts",
|
|
91
|
+
outDir: "dist",
|
|
92
|
+
watchDir: "src",
|
|
93
|
+
env: "development",
|
|
94
|
+
};
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Notes
|
|
98
|
+
|
|
99
|
+
- In generated apps, `@trinacria/cli` is added to `devDependencies`.
|
|
100
|
+
- Generated app includes `.env` created from `.env.example` (if present).
|
|
101
|
+
- Generated app keeps `.gitignore` (and writes a default one if missing).
|
|
102
|
+
- `@trinacria/*` dependencies are pinned to the same version as the CLI release used for scaffolding.
|
|
103
|
+
- `dev` uses watch mode with automatic restart on source changes.
|
|
104
|
+
- `start` runs the compiled file mapped from your configured entry.
|
|
105
|
+
|
|
106
|
+
## Links
|
|
107
|
+
|
|
108
|
+
- Repository: [https://github.com/tascaenzo/trinacria](https://github.com/tascaenzo/trinacria)
|
|
109
|
+
- Documentation: see `docs/en` and `docs/it` in the repository.
|
package/README.npm.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# @trinacria/cli
|
|
2
|
+
|
|
3
|
+
`@trinacria/cli` is the command-line tool for Trinacria apps.
|
|
4
|
+
|
|
5
|
+
It provides:
|
|
6
|
+
|
|
7
|
+
- app scaffolding (`new`, `create`, `init`)
|
|
8
|
+
- development mode with watch/restart (`dev`)
|
|
9
|
+
- TypeScript build (`build`)
|
|
10
|
+
- production start from compiled output (`start`)
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
Use it without global install:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx @trinacria/cli@alpha --help
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Or install in your project:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npm i -D @trinacria/cli
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Create a new app
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx @trinacria/cli@alpha new my-app
|
|
30
|
+
cd my-app
|
|
31
|
+
npm install
|
|
32
|
+
npm run dev
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Quick start with explicit templates:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npx @trinacria/cli@alpha new my-app --template app-starter
|
|
39
|
+
npx @trinacria/cli@alpha new my-cron --template cron-example
|
|
40
|
+
npx @trinacria/cli@alpha new my-api-pg --template api-prisma-postgresql
|
|
41
|
+
npx @trinacria/cli@alpha new my-api-mongo --template api-mongoose-mongodb
|
|
42
|
+
npx @trinacria/cli@alpha new my-api-redis --template api-events-redis
|
|
43
|
+
npx @trinacria/cli@alpha new my-api-rabbit --template api-events-rabbitmq
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Aliases:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npx @trinacria/cli@alpha create my-app
|
|
50
|
+
npx @trinacria/cli@alpha init my-app
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Available templates
|
|
54
|
+
|
|
55
|
+
- `app-starter` (aliases: `minimal`, `starter`, `base`, `default`)
|
|
56
|
+
- `cron-example`
|
|
57
|
+
- `api-prisma-postgresql`
|
|
58
|
+
- `api-mongoose-mongodb`
|
|
59
|
+
- `api-events-redis`
|
|
60
|
+
- `api-events-rabbitmq`
|
|
61
|
+
|
|
62
|
+
Example:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npx @trinacria/cli@alpha new my-app --template minimal
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Commands
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
trinacria new <project-name> [--template <name>] [--no-install] [--no-git] [--force]
|
|
72
|
+
trinacria dev
|
|
73
|
+
trinacria build
|
|
74
|
+
trinacria start
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Config file
|
|
78
|
+
|
|
79
|
+
Supported config names in your app root:
|
|
80
|
+
|
|
81
|
+
- `trinacria.config.js`
|
|
82
|
+
- `trinacria.config.cjs`
|
|
83
|
+
- `trinacria.config.mjs`
|
|
84
|
+
|
|
85
|
+
Example:
|
|
86
|
+
|
|
87
|
+
```js
|
|
88
|
+
/** @type {import('@trinacria/cli').TrinacriaConfig} */
|
|
89
|
+
export default {
|
|
90
|
+
entry: "src/main.ts",
|
|
91
|
+
outDir: "dist",
|
|
92
|
+
watchDir: "src",
|
|
93
|
+
env: "development",
|
|
94
|
+
};
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Notes
|
|
98
|
+
|
|
99
|
+
- In generated apps, `@trinacria/cli` is added to `devDependencies`.
|
|
100
|
+
- Generated app includes `.env` created from `.env.example` (if present).
|
|
101
|
+
- Generated app keeps `.gitignore` (and writes a default one if missing).
|
|
102
|
+
- `@trinacria/*` dependencies are pinned to the same version as the CLI release used for scaffolding.
|
|
103
|
+
- `dev` uses watch mode with automatic restart on source changes.
|
|
104
|
+
- `start` runs the compiled file mapped from your configured entry.
|
|
105
|
+
|
|
106
|
+
## Links
|
|
107
|
+
|
|
108
|
+
- Repository: [https://github.com/tascaenzo/trinacria](https://github.com/tascaenzo/trinacria)
|
|
109
|
+
- Documentation: see `docs/en` and `docs/it` in the repository.
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { dev } from "./commands/dev";
|
|
2
|
+
import { build } from "./commands/build";
|
|
3
|
+
import { start } from "./commands/start";
|
|
4
|
+
import { createNewApp } from "./commands/new";
|
|
5
|
+
import { loadConfig } from "./config/load-config";
|
|
6
|
+
export declare function printHelp(): void;
|
|
7
|
+
interface CliDeps {
|
|
8
|
+
loadConfig: typeof loadConfig;
|
|
9
|
+
dev: typeof dev;
|
|
10
|
+
build: typeof build;
|
|
11
|
+
start: typeof start;
|
|
12
|
+
createNewApp: typeof createNewApp;
|
|
13
|
+
printHelp: () => void;
|
|
14
|
+
exit: (code: number) => void;
|
|
15
|
+
logError: (message: string, error?: unknown) => void;
|
|
16
|
+
}
|
|
17
|
+
export declare function runCli(args: string[], deps?: CliDeps): Promise<void>;
|
|
18
|
+
export declare function main(): Promise<void>;
|
|
19
|
+
export {};
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.printHelp = printHelp;
|
|
4
|
+
exports.runCli = runCli;
|
|
5
|
+
exports.main = main;
|
|
6
|
+
const dev_1 = require("./commands/dev");
|
|
7
|
+
const build_1 = require("./commands/build");
|
|
8
|
+
const start_1 = require("./commands/start");
|
|
9
|
+
const new_1 = require("./commands/new");
|
|
10
|
+
const load_config_1 = require("./config/load-config");
|
|
11
|
+
const core_1 = require("@trinacria/core");
|
|
12
|
+
const context = "TrinacriaCLI";
|
|
13
|
+
const log = new core_1.ConsoleLogger(context);
|
|
14
|
+
function printHelp() {
|
|
15
|
+
console.log(`
|
|
16
|
+
Trinacria CLI
|
|
17
|
+
|
|
18
|
+
Usage:
|
|
19
|
+
trinacria new <project-name> [--template <name>] [--no-install] [--no-git] [--force]
|
|
20
|
+
trinacria create <project-name> [--template <name>] [--no-install] [--no-git] [--force]
|
|
21
|
+
trinacria init <project-name> [--template <name>] [--no-install] [--no-git] [--force]
|
|
22
|
+
trinacria dev
|
|
23
|
+
trinacria build
|
|
24
|
+
trinacria start
|
|
25
|
+
|
|
26
|
+
Options:
|
|
27
|
+
--config <path> Specify custom config file
|
|
28
|
+
--help Show help
|
|
29
|
+
|
|
30
|
+
Notes:
|
|
31
|
+
- default template is "app-starter" (alias: minimal, starter, base, default)
|
|
32
|
+
`);
|
|
33
|
+
}
|
|
34
|
+
const defaultDeps = {
|
|
35
|
+
loadConfig: load_config_1.loadConfig,
|
|
36
|
+
dev: dev_1.dev,
|
|
37
|
+
build: build_1.build,
|
|
38
|
+
start: start_1.start,
|
|
39
|
+
createNewApp: new_1.createNewApp,
|
|
40
|
+
printHelp,
|
|
41
|
+
exit: (code) => process.exit(code),
|
|
42
|
+
logError: (message, error) => log.error(message, error, context),
|
|
43
|
+
};
|
|
44
|
+
async function runCli(args, deps = defaultDeps) {
|
|
45
|
+
const command = args[0];
|
|
46
|
+
if (!command || command === "--help") {
|
|
47
|
+
deps.printHelp();
|
|
48
|
+
deps.exit(0);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
switch (command) {
|
|
53
|
+
case "new":
|
|
54
|
+
case "create":
|
|
55
|
+
case "init":
|
|
56
|
+
await deps.createNewApp(args.slice(1));
|
|
57
|
+
break;
|
|
58
|
+
case "dev":
|
|
59
|
+
case "build":
|
|
60
|
+
case "start": {
|
|
61
|
+
const config = await deps.loadConfig(args);
|
|
62
|
+
if (command === "dev") {
|
|
63
|
+
await deps.dev(config);
|
|
64
|
+
}
|
|
65
|
+
else if (command === "build") {
|
|
66
|
+
await deps.build(config);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
await deps.start(config);
|
|
70
|
+
}
|
|
71
|
+
break;
|
|
72
|
+
}
|
|
73
|
+
default:
|
|
74
|
+
deps.logError(`Unknown command: ${command}`);
|
|
75
|
+
deps.printHelp();
|
|
76
|
+
deps.exit(1);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
deps.logError("CLI execution failed", err);
|
|
82
|
+
deps.exit(1);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async function main() {
|
|
87
|
+
await runCli(process.argv.slice(2));
|
|
88
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.build = build;
|
|
7
|
+
const typescript_1 = __importDefault(require("typescript"));
|
|
8
|
+
const node_perf_hooks_1 = require("node:perf_hooks");
|
|
9
|
+
const color = {
|
|
10
|
+
reset: "\x1b[0m",
|
|
11
|
+
bold: "\x1b[1m",
|
|
12
|
+
dim: "\x1b[2m",
|
|
13
|
+
red: "\x1b[31m",
|
|
14
|
+
yellow: "\x1b[33m",
|
|
15
|
+
green: "\x1b[32m",
|
|
16
|
+
cyan: "\x1b[36m",
|
|
17
|
+
};
|
|
18
|
+
function title(msg) {
|
|
19
|
+
console.log(`${color.cyan}${color.bold}TRINACRIA${color.reset} ${msg}`);
|
|
20
|
+
}
|
|
21
|
+
function success(msg) {
|
|
22
|
+
console.log(`${color.green}✔ ${msg}${color.reset}`);
|
|
23
|
+
}
|
|
24
|
+
function error(msg) {
|
|
25
|
+
console.error(`${color.red}✖ ${msg}${color.reset}`);
|
|
26
|
+
}
|
|
27
|
+
function warning(msg) {
|
|
28
|
+
console.warn(`${color.yellow}⚠ ${msg}${color.reset}`);
|
|
29
|
+
}
|
|
30
|
+
async function build(config) {
|
|
31
|
+
title("Building application...\n");
|
|
32
|
+
const startTime = node_perf_hooks_1.performance.now();
|
|
33
|
+
const configPath = typescript_1.default.findConfigFile(process.cwd(), typescript_1.default.sys.fileExists, "tsconfig.json");
|
|
34
|
+
if (!configPath) {
|
|
35
|
+
error("Could not find tsconfig.json");
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
const configFile = typescript_1.default.readConfigFile(configPath, typescript_1.default.sys.readFile);
|
|
39
|
+
if (configFile.error) {
|
|
40
|
+
const message = typescript_1.default.formatDiagnosticsWithColorAndContext([configFile.error], formatHost());
|
|
41
|
+
error(message);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
const parsed = typescript_1.default.parseJsonConfigFileContent(configFile.config, typescript_1.default.sys, process.cwd(), {
|
|
45
|
+
outDir: config.outDir,
|
|
46
|
+
});
|
|
47
|
+
const program = typescript_1.default.createProgram(parsed.fileNames, parsed.options);
|
|
48
|
+
// 📦 Mostra file compilati (non declaration)
|
|
49
|
+
const sourceFiles = program
|
|
50
|
+
.getSourceFiles()
|
|
51
|
+
.filter((f) => !f.isDeclarationFile);
|
|
52
|
+
console.log(`${color.dim}Compiling ${sourceFiles.length} files...${color.reset}\n`);
|
|
53
|
+
const emitResult = program.emit();
|
|
54
|
+
const diagnostics = typescript_1.default
|
|
55
|
+
.getConfigFileParsingDiagnostics(parsed)
|
|
56
|
+
.concat(typescript_1.default.getPreEmitDiagnostics(program), emitResult.diagnostics);
|
|
57
|
+
let errorCount = 0;
|
|
58
|
+
let warningCount = 0;
|
|
59
|
+
diagnostics.forEach((diagnostic) => {
|
|
60
|
+
const message = typescript_1.default.flattenDiagnosticMessageText(diagnostic.messageText, "\n");
|
|
61
|
+
if (diagnostic.category === typescript_1.default.DiagnosticCategory.Error) {
|
|
62
|
+
errorCount++;
|
|
63
|
+
}
|
|
64
|
+
else if (diagnostic.category === typescript_1.default.DiagnosticCategory.Warning) {
|
|
65
|
+
warningCount++;
|
|
66
|
+
}
|
|
67
|
+
if (diagnostic.file && diagnostic.start !== undefined) {
|
|
68
|
+
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
|
69
|
+
const location = `${diagnostic.file.fileName}:${line + 1}:${character + 1}`;
|
|
70
|
+
if (diagnostic.category === typescript_1.default.DiagnosticCategory.Error) {
|
|
71
|
+
error(`${location} - ${message}`);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
warning(`${location} - ${message}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
if (diagnostic.category === typescript_1.default.DiagnosticCategory.Error) {
|
|
79
|
+
error(message);
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
warning(message);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
const duration = (node_perf_hooks_1.performance.now() - startTime).toFixed(2);
|
|
87
|
+
console.log(""); // spacing
|
|
88
|
+
if (emitResult.emitSkipped || errorCount > 0) {
|
|
89
|
+
error(`Build failed with ${errorCount} error(s) and ${warningCount} warning(s)`);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
success(`Build completed in ${duration}ms`);
|
|
93
|
+
console.log(`${color.dim}Output directory:${color.reset} ${config.outDir}`);
|
|
94
|
+
console.log(`${color.dim}Files compiled:${color.reset} ${sourceFiles.length}\n`);
|
|
95
|
+
}
|
|
96
|
+
function formatHost() {
|
|
97
|
+
return {
|
|
98
|
+
getCanonicalFileName: (fileName) => fileName,
|
|
99
|
+
getCurrentDirectory: () => process.cwd(),
|
|
100
|
+
getNewLine: () => "\n",
|
|
101
|
+
};
|
|
102
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ChildProcess } from "node:child_process";
|
|
2
|
+
import { ResolvedConfig } from "../config/config.contract";
|
|
3
|
+
interface DevDeps {
|
|
4
|
+
watch: (watchDir: string) => {
|
|
5
|
+
on(event: "all", listener: () => void): void;
|
|
6
|
+
close(): Promise<void>;
|
|
7
|
+
};
|
|
8
|
+
startApp: (entry: string) => ChildProcess;
|
|
9
|
+
stopChild: (child: ChildProcess) => Promise<void>;
|
|
10
|
+
setTimeoutFn: typeof setTimeout;
|
|
11
|
+
clearTimeoutFn: typeof clearTimeout;
|
|
12
|
+
now: () => number;
|
|
13
|
+
onSignal: (signal: NodeJS.Signals, handler: () => void) => void;
|
|
14
|
+
exit: (code: number) => void;
|
|
15
|
+
info: (message: string) => void;
|
|
16
|
+
error: (message: string) => void;
|
|
17
|
+
}
|
|
18
|
+
export declare function runDev(config: ResolvedConfig, deps?: DevDeps): Promise<void>;
|
|
19
|
+
export declare function dev(config: ResolvedConfig): Promise<void>;
|
|
20
|
+
declare function resolveTsxCliPath(): string;
|
|
21
|
+
declare function resetTsxCliEntryCacheForTests(): void;
|
|
22
|
+
declare function stopChild(child: ChildProcess): Promise<void>;
|
|
23
|
+
export declare const __devTestUtils: {
|
|
24
|
+
resolveTsxCliPath: typeof resolveTsxCliPath;
|
|
25
|
+
stopChild: typeof stopChild;
|
|
26
|
+
resetTsxCliEntryCacheForTests: typeof resetTsxCliEntryCacheForTests;
|
|
27
|
+
};
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.__devTestUtils = void 0;
|
|
7
|
+
exports.runDev = runDev;
|
|
8
|
+
exports.dev = dev;
|
|
9
|
+
const node_child_process_1 = require("node:child_process");
|
|
10
|
+
const chokidar_1 = __importDefault(require("chokidar"));
|
|
11
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
12
|
+
const core_1 = require("@trinacria/core");
|
|
13
|
+
const context = "TrinacriaCLI";
|
|
14
|
+
const log = new core_1.ConsoleLogger(context);
|
|
15
|
+
const RESTART_DEBOUNCE_MS = 100;
|
|
16
|
+
const STOP_TIMEOUT_MS = 3000;
|
|
17
|
+
const NON_RESTARTABLE_EXIT_CODES = new Set([78]);
|
|
18
|
+
let tsxCliEntryCache = null;
|
|
19
|
+
const defaultDevDeps = {
|
|
20
|
+
watch: (watchDir) => chokidar_1.default.watch(watchDir, {
|
|
21
|
+
ignoreInitial: true,
|
|
22
|
+
}),
|
|
23
|
+
startApp,
|
|
24
|
+
stopChild,
|
|
25
|
+
setTimeoutFn: setTimeout,
|
|
26
|
+
clearTimeoutFn: clearTimeout,
|
|
27
|
+
now: () => Date.now(),
|
|
28
|
+
onSignal: (signal, handler) => {
|
|
29
|
+
process.once(signal, handler);
|
|
30
|
+
},
|
|
31
|
+
exit: (code) => {
|
|
32
|
+
process.exit(code);
|
|
33
|
+
},
|
|
34
|
+
info: (message) => {
|
|
35
|
+
log.info(message, context);
|
|
36
|
+
},
|
|
37
|
+
error: (message) => {
|
|
38
|
+
log.error(message, context);
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
async function runDev(config, deps = defaultDevDeps) {
|
|
42
|
+
const entry = node_path_1.default.resolve(config.entry);
|
|
43
|
+
const crashLoopWindowMs = config.crashLoopWindowMs;
|
|
44
|
+
const maxConsecutiveCrashRestarts = config.maxConsecutiveCrashRestarts;
|
|
45
|
+
deps.info("Starting in dev mode");
|
|
46
|
+
const watcher = deps.watch(config.watchDir);
|
|
47
|
+
let restarting = false;
|
|
48
|
+
let pendingRestart = false;
|
|
49
|
+
let stopping = false;
|
|
50
|
+
let crashCount = 0;
|
|
51
|
+
let crashWindowStartedAt = 0;
|
|
52
|
+
let restartTimeout = null;
|
|
53
|
+
const handleChildExit = (code) => {
|
|
54
|
+
if (stopping || restarting) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (code !== 0) {
|
|
58
|
+
if (code !== null && NON_RESTARTABLE_EXIT_CODES.has(code)) {
|
|
59
|
+
deps.error(`Application stopped with non-restartable exit code ${code}. Waiting for source changes...`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (isCrashLoop()) {
|
|
63
|
+
deps.error(`Application crashed ${maxConsecutiveCrashRestarts} times in ${Math.floor(crashLoopWindowMs / 1000)}s. Waiting for source changes...`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
scheduleRestart(`App crashed (code ${code})`);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const createTrackedChild = () => {
|
|
70
|
+
const next = deps.startApp(entry);
|
|
71
|
+
next.on("exit", handleChildExit);
|
|
72
|
+
next.on("error", (err) => {
|
|
73
|
+
if (!stopping) {
|
|
74
|
+
scheduleRestart(`App process failed to start: ${err instanceof Error ? err.message : String(err)}`);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return next;
|
|
78
|
+
};
|
|
79
|
+
let child = createTrackedChild();
|
|
80
|
+
const scheduleRestart = (reason) => {
|
|
81
|
+
if (restartTimeout) {
|
|
82
|
+
deps.clearTimeoutFn(restartTimeout);
|
|
83
|
+
}
|
|
84
|
+
restartTimeout = deps.setTimeoutFn(() => {
|
|
85
|
+
void restart(reason);
|
|
86
|
+
}, RESTART_DEBOUNCE_MS);
|
|
87
|
+
};
|
|
88
|
+
const restart = async (reason) => {
|
|
89
|
+
if (stopping)
|
|
90
|
+
return;
|
|
91
|
+
if (restarting) {
|
|
92
|
+
pendingRestart = true;
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
restarting = true;
|
|
96
|
+
try {
|
|
97
|
+
do {
|
|
98
|
+
pendingRestart = false;
|
|
99
|
+
deps.info(`${reason} — restarting application`);
|
|
100
|
+
await deps.stopChild(child);
|
|
101
|
+
child = createTrackedChild();
|
|
102
|
+
} while (pendingRestart);
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
restarting = false;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
watcher.on("all", () => {
|
|
109
|
+
crashCount = 0;
|
|
110
|
+
crashWindowStartedAt = 0;
|
|
111
|
+
scheduleRestart("Source changed");
|
|
112
|
+
});
|
|
113
|
+
const cleanup = async (signal) => {
|
|
114
|
+
stopping = true;
|
|
115
|
+
if (restartTimeout) {
|
|
116
|
+
deps.clearTimeoutFn(restartTimeout);
|
|
117
|
+
restartTimeout = null;
|
|
118
|
+
}
|
|
119
|
+
await watcher.close();
|
|
120
|
+
await deps.stopChild(child);
|
|
121
|
+
deps.exit(signal === "SIGINT" ? 130 : 143);
|
|
122
|
+
};
|
|
123
|
+
deps.onSignal("SIGINT", () => {
|
|
124
|
+
void cleanup("SIGINT");
|
|
125
|
+
});
|
|
126
|
+
deps.onSignal("SIGTERM", () => {
|
|
127
|
+
void cleanup("SIGTERM");
|
|
128
|
+
});
|
|
129
|
+
function isCrashLoop() {
|
|
130
|
+
const now = deps.now();
|
|
131
|
+
if (crashWindowStartedAt === 0 ||
|
|
132
|
+
now - crashWindowStartedAt > crashLoopWindowMs) {
|
|
133
|
+
crashWindowStartedAt = now;
|
|
134
|
+
crashCount = 1;
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
crashCount += 1;
|
|
138
|
+
return crashCount >= maxConsecutiveCrashRestarts;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
async function dev(config) {
|
|
142
|
+
await runDev(config);
|
|
143
|
+
}
|
|
144
|
+
function startApp(entry) {
|
|
145
|
+
return (0, node_child_process_1.spawn)(process.execPath, [resolveTsxCliPath(), entry], {
|
|
146
|
+
stdio: "inherit",
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
function resolveTsxCliPath() {
|
|
150
|
+
if (tsxCliEntryCache) {
|
|
151
|
+
return tsxCliEntryCache;
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
tsxCliEntryCache = require.resolve("tsx/cli");
|
|
155
|
+
return tsxCliEntryCache;
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
throw new Error(`Unable to resolve tsx CLI entry. Ensure \"tsx\" is installed. ${error instanceof Error ? error.message : String(error)}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
function resetTsxCliEntryCacheForTests() {
|
|
162
|
+
tsxCliEntryCache = null;
|
|
163
|
+
}
|
|
164
|
+
function stopChild(child) {
|
|
165
|
+
if (child.exitCode !== null || child.signalCode !== null) {
|
|
166
|
+
return Promise.resolve();
|
|
167
|
+
}
|
|
168
|
+
return new Promise((resolve) => {
|
|
169
|
+
const forceKillTimer = setTimeout(() => {
|
|
170
|
+
if (child.exitCode === null && child.signalCode === null) {
|
|
171
|
+
child.kill("SIGKILL");
|
|
172
|
+
}
|
|
173
|
+
}, STOP_TIMEOUT_MS);
|
|
174
|
+
forceKillTimer.unref();
|
|
175
|
+
child.once("exit", () => {
|
|
176
|
+
clearTimeout(forceKillTimer);
|
|
177
|
+
resolve();
|
|
178
|
+
});
|
|
179
|
+
child.kill("SIGTERM");
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
exports.__devTestUtils = {
|
|
183
|
+
resolveTsxCliPath,
|
|
184
|
+
stopChild,
|
|
185
|
+
resetTsxCliEntryCacheForTests,
|
|
186
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
declare const TEMPLATE_APP_NAMES: readonly ["app-starter", "cron-example", "api-prisma-postgresql", "api-mongoose-mongodb", "api-events-redis", "api-events-rabbitmq"];
|
|
3
|
+
type TemplateAppName = (typeof TEMPLATE_APP_NAMES)[number];
|
|
4
|
+
interface NewOptions {
|
|
5
|
+
projectName: string;
|
|
6
|
+
template: TemplateAppName;
|
|
7
|
+
install: boolean;
|
|
8
|
+
git: boolean;
|
|
9
|
+
force: boolean;
|
|
10
|
+
}
|
|
11
|
+
interface NewDeps {
|
|
12
|
+
cwd: () => string;
|
|
13
|
+
templatesRoot: () => string;
|
|
14
|
+
pathExists: (target: string) => boolean;
|
|
15
|
+
mkdir: (target: string) => void;
|
|
16
|
+
readdir: (target: string) => fs.Dirent[];
|
|
17
|
+
stat: (target: string) => fs.Stats;
|
|
18
|
+
readFile: (target: string) => string;
|
|
19
|
+
writeFile: (target: string, content: string) => void;
|
|
20
|
+
copyFile: (from: string, to: string) => void;
|
|
21
|
+
runCommand: (command: string, args: string[], cwd: string) => Promise<void>;
|
|
22
|
+
info: (message: string) => void;
|
|
23
|
+
}
|
|
24
|
+
export declare function createNewApp(args: string[], deps?: NewDeps): Promise<void>;
|
|
25
|
+
declare function parseNewArgs(args: string[]): NewOptions;
|
|
26
|
+
declare function normalizeTemplateName(templateInput: string): TemplateAppName;
|
|
27
|
+
declare function ensureTargetDirectory(targetDir: string, force: boolean, deps: NewDeps): void;
|
|
28
|
+
declare function ensureGeneratedProjectFiles(targetDir: string, deps: NewDeps): void;
|
|
29
|
+
declare function adaptGeneratedPackageJson(targetDir: string, projectName: string, trinacriaVersion: string, deps: NewDeps): void;
|
|
30
|
+
declare function normalizeScripts(scriptsInput: Record<string, unknown> | undefined): Record<string, string>;
|
|
31
|
+
declare function normalizeDependencyMap(input: Record<string, unknown> | undefined, trinacriaVersion: string): Record<string, string>;
|
|
32
|
+
export declare const __newTestUtils: {
|
|
33
|
+
parseNewArgs: typeof parseNewArgs;
|
|
34
|
+
normalizeTemplateName: typeof normalizeTemplateName;
|
|
35
|
+
normalizeDependencyMap: typeof normalizeDependencyMap;
|
|
36
|
+
normalizeScripts: typeof normalizeScripts;
|
|
37
|
+
adaptGeneratedPackageJson: typeof adaptGeneratedPackageJson;
|
|
38
|
+
ensureGeneratedProjectFiles: typeof ensureGeneratedProjectFiles;
|
|
39
|
+
ensureTargetDirectory: typeof ensureTargetDirectory;
|
|
40
|
+
};
|
|
41
|
+
export {};
|