@alleen/cli 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/README.md ADDED
@@ -0,0 +1,148 @@
1
+ # @alleen/cli
2
+
3
+ > CLI for **alleen-api** — Manage multi-database Prisma setup with a single command.
4
+
5
+ ---
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @alleen/cli --save-dev
11
+ ```
12
+
13
+ Or use directly via npx:
14
+
15
+ ```bash
16
+ npx alleen db:add --name=phoenix --url=postgresql://...
17
+ ```
18
+
19
+ ---
20
+
21
+ ## Commands
22
+
23
+ ### `alleen db:add`
24
+ Add a new database. Generates **everything** automatically:
25
+
26
+ ```bash
27
+ alleen db:add --name=phoenix --url=postgresql://user:pass@host/dbname
28
+ ```
29
+
30
+ **What it generates:**
31
+ ```
32
+ ✅ prisma/phoenix/schema.prisma ← ready to add your models
33
+ ✅ src/prisma/phoenix.service.ts ← NestJS PrismaService
34
+ ✅ .env ← DATABASE_PHOENIX_URL added
35
+ ✅ src/prisma/prisma.registry.ts ← auto-updated, no manual switch needed
36
+ ```
37
+
38
+ Options:
39
+ | Option | Description | Default |
40
+ |---|---|---|
41
+ | `--name` | Database name *(required)* | — |
42
+ | `--url` | Connection URL *(required)* | — |
43
+ | `--provider` | DB provider | `postgresql` |
44
+
45
+ Supported providers: `postgresql`, `mysql`, `sqlite`, `sqlserver`, `mongodb`
46
+
47
+ ---
48
+
49
+ ### `alleen db:remove`
50
+ Remove a database and clean up all generated files:
51
+
52
+ ```bash
53
+ alleen db:remove --name=phoenix
54
+ ```
55
+
56
+ **What it removes:**
57
+ ```
58
+ 🗑️ src/prisma/phoenix.service.ts
59
+ 🗑️ prisma/phoenix/
60
+ 🗑️ DATABASE_PHOENIX_URL from .env
61
+ ✅ src/prisma/prisma.registry.ts regenerated
62
+ ```
63
+
64
+ ---
65
+
66
+ ### `alleen db:list`
67
+ List all registered databases with their status:
68
+
69
+ ```bash
70
+ alleen db:list
71
+ ```
72
+
73
+ ```
74
+ 🗄️ alleen db:list — Registered databases
75
+
76
+ 1. phoenix ✅ .env ✅ schema
77
+ 2. bulk ✅ .env ✅ schema
78
+ 3. finance ✅ .env ❌ schema missing
79
+
80
+ Total: 3 database(s)
81
+ ```
82
+
83
+ ---
84
+
85
+ ### `alleen db:generate`
86
+ Regenerate the registry from existing service files.
87
+ Useful after cloning the project or manually adding files:
88
+
89
+ ```bash
90
+ alleen db:generate
91
+ ```
92
+
93
+ ---
94
+
95
+ ## How it works
96
+
97
+ Instead of maintaining a manual switch statement:
98
+
99
+ ```ts
100
+ // ❌ Before — manual, breaks every time you add a DB
101
+ switch (database) {
102
+ case 'phoenix': dbInstance = this.phoenixPrismaService; break;
103
+ case 'bulk': dbInstance = this.bulkPrismaService; break;
104
+ // ... forever
105
+ }
106
+ ```
107
+
108
+ `@alleen/cli` auto-generates a registry:
109
+
110
+ ```ts
111
+ // ✅ After — auto-generated, never touch it manually
112
+ // src/prisma/prisma.registry.ts
113
+
114
+ import { PhoenixPrismaService } from './phoenix.service';
115
+ import { BulkPrismaService } from './bulk.service';
116
+
117
+ export const PRISMA_REGISTRY = {
118
+ 'phoenix': PhoenixPrismaService,
119
+ 'bulk': BulkPrismaService,
120
+ };
121
+ ```
122
+
123
+ And your service becomes 3 lines:
124
+
125
+ ```ts
126
+ const ServiceClass = PRISMA_REGISTRY[database];
127
+ if (!ServiceClass) throw new Error(`Database "${database}" not found`);
128
+ const dbInstance = this.moduleRef.get(ServiceClass, { strict: false });
129
+ ```
130
+
131
+ ---
132
+
133
+ ## After adding a database
134
+
135
+ ```bash
136
+ # 1. Add your models in prisma/phoenix/schema.prisma
137
+ # 2. Generate the Prisma client
138
+ npx prisma generate --schema=prisma/phoenix/schema.prisma
139
+
140
+ # 3. Run migrations
141
+ npx prisma migrate dev --schema=prisma/phoenix/schema.prisma
142
+ ```
143
+
144
+ ---
145
+
146
+ ## License
147
+
148
+ MIT © olivier adou
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=alleen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alleen.d.ts","sourceRoot":"","sources":["../../src/bin/alleen.ts"],"names":[],"mappings":""}
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const db_add_1 = require("../commands/db-add");
6
+ const db_remove_1 = require("../commands/db-remove");
7
+ const db_list_1 = require("../commands/db-list");
8
+ const db_generate_1 = require("../commands/db-generate");
9
+ const program = new commander_1.Command();
10
+ program
11
+ .name('alleen')
12
+ .description('alleen-api CLI — Multi-database Prisma manager')
13
+ .version('0.1.0');
14
+ program
15
+ .command('db:add')
16
+ .description('Add a new database and generate all required files')
17
+ .requiredOption('--name <name>', 'Database name (e.g. phoenix)')
18
+ .requiredOption('--url <url>', 'Database connection URL')
19
+ .option('--provider <provider>', 'Database provider (postgresql, mysql, sqlite)', 'postgresql')
20
+ .action(db_add_1.dbAddCommand);
21
+ program
22
+ .command('db:remove')
23
+ .description('Remove a database and clean up generated files')
24
+ .requiredOption('--name <name>', 'Database name to remove')
25
+ .action(db_remove_1.dbRemoveCommand);
26
+ program
27
+ .command('db:list')
28
+ .description('List all registered databases')
29
+ .action(db_list_1.dbListCommand);
30
+ program
31
+ .command('db:generate')
32
+ .description('Regenerate the registry from existing databases')
33
+ .action(db_generate_1.dbGenerateCommand);
34
+ program.parse(process.argv);
35
+ //# sourceMappingURL=alleen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alleen.js","sourceRoot":"","sources":["../../src/bin/alleen.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,+CAAkD;AAClD,qDAAwD;AACxD,iDAAoD;AACpD,yDAA4D;AAE5D,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,gDAAgD,CAAC;KAC7D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,oDAAoD,CAAC;KACjE,cAAc,CAAC,eAAe,EAAE,8BAA8B,CAAC;KAC/D,cAAc,CAAC,aAAa,EAAE,yBAAyB,CAAC;KACxD,MAAM,CAAC,uBAAuB,EAAE,+CAA+C,EAAE,YAAY,CAAC;KAC9F,MAAM,CAAC,qBAAY,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,WAAW,CAAC;KACpB,WAAW,CAAC,gDAAgD,CAAC;KAC7D,cAAc,CAAC,eAAe,EAAE,yBAAyB,CAAC;KAC1D,MAAM,CAAC,2BAAe,CAAC,CAAC;AAE3B,OAAO;KACJ,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,+BAA+B,CAAC;KAC5C,MAAM,CAAC,uBAAa,CAAC,CAAC;AAEzB,OAAO;KACJ,OAAO,CAAC,aAAa,CAAC;KACtB,WAAW,CAAC,iDAAiD,CAAC;KAC9D,MAAM,CAAC,+BAAiB,CAAC,CAAC;AAE7B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ interface DbAddOptions {
2
+ name: string;
3
+ url: string;
4
+ provider: string;
5
+ }
6
+ export declare function dbAddCommand(options: DbAddOptions): Promise<void>;
7
+ export {};
8
+ //# sourceMappingURL=db-add.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-add.d.ts","sourceRoot":"","sources":["../../src/commands/db-add.ts"],"names":[],"mappings":"AAiBA,UAAU,YAAY;IACpB,IAAI,EAAM,MAAM,CAAC;IACjB,GAAG,EAAO,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA8DvE"}
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.dbAddCommand = dbAddCommand;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const ora_1 = __importDefault(require("ora"));
42
+ const path = __importStar(require("path"));
43
+ const fs_utils_1 = require("../utils/fs.utils");
44
+ const templates_utils_1 = require("../utils/templates.utils");
45
+ const registry_utils_1 = require("../utils/registry.utils");
46
+ async function dbAddCommand(options) {
47
+ const { name, url, provider } = options;
48
+ const cleanName = name.toLowerCase().trim();
49
+ console.log('');
50
+ console.log(chalk_1.default.bold.cyan(`🗄️ alleen db:add — Adding "${cleanName}" database`));
51
+ console.log('');
52
+ const existing = (0, fs_utils_1.getRegisteredDatabases)();
53
+ if (existing.includes(cleanName)) {
54
+ console.log(chalk_1.default.yellow(`⚠️ Database "${cleanName}" is already registered.`));
55
+ console.log(chalk_1.default.gray(` To update its URL, edit your .env file directly.`));
56
+ console.log(chalk_1.default.gray(` To remove it, run: alleen db:remove --name=${cleanName}`));
57
+ process.exit(0);
58
+ }
59
+ const schemaStep = (0, ora_1.default)(`Creating prisma/${cleanName}/schema.prisma`).start();
60
+ const schemaPath = path.join(fs_utils_1.PRISMA_DIR, cleanName, 'schema.prisma');
61
+ if ((0, fs_utils_1.fileExists)(schemaPath)) {
62
+ schemaStep.warn(chalk_1.default.yellow(`prisma/${cleanName}/schema.prisma already exists — skipped`));
63
+ }
64
+ else {
65
+ (0, fs_utils_1.writeFile)(schemaPath, (0, templates_utils_1.buildSchema)(cleanName, provider));
66
+ schemaStep.succeed(chalk_1.default.green(`prisma/${cleanName}/schema.prisma created`));
67
+ }
68
+ const serviceStep = (0, ora_1.default)(`Creating src/prisma/${cleanName}.service.ts`).start();
69
+ const servicePath = path.join(fs_utils_1.PRISMA_SERVICES_DIR, `${cleanName}.service.ts`);
70
+ if ((0, fs_utils_1.fileExists)(servicePath)) {
71
+ serviceStep.warn(chalk_1.default.yellow(`src/prisma/${cleanName}.service.ts already exists — skipped`));
72
+ }
73
+ else {
74
+ (0, fs_utils_1.writeFile)(servicePath, (0, templates_utils_1.buildPrismaService)(cleanName));
75
+ serviceStep.succeed(chalk_1.default.green(`src/prisma/${cleanName}.service.ts created`));
76
+ }
77
+ const envStep = (0, ora_1.default)(`Updating .env`).start();
78
+ const envKey = (0, fs_utils_1.toEnvKey)(cleanName);
79
+ const envResult = (0, fs_utils_1.addEnvVar)(envKey, url);
80
+ if (envResult === 'exists') {
81
+ envStep.warn(chalk_1.default.yellow(`.env: ${envKey} already exists — skipped`));
82
+ }
83
+ else {
84
+ envStep.succeed(chalk_1.default.green(`.env updated — ${envKey} added`));
85
+ }
86
+ const registryStep = (0, ora_1.default)(`Regenerating prisma.registry.ts`).start();
87
+ (0, registry_utils_1.regenerateRegistry)();
88
+ registryStep.succeed(chalk_1.default.green(`src/prisma/prisma.registry.ts updated`));
89
+ console.log('');
90
+ console.log(chalk_1.default.bold.green('🎉 Done! Next steps:'));
91
+ console.log('');
92
+ console.log(chalk_1.default.gray(' 1. Define your models in:'));
93
+ console.log(chalk_1.default.white(` prisma/${cleanName}/schema.prisma`));
94
+ console.log('');
95
+ console.log(chalk_1.default.gray(' 2. Generate the Prisma client:'));
96
+ console.log(chalk_1.default.white(` npx prisma generate --schema=prisma/${cleanName}/schema.prisma`));
97
+ console.log('');
98
+ console.log(chalk_1.default.gray(' 3. Run migrations:'));
99
+ console.log(chalk_1.default.white(` npx prisma migrate dev --schema=prisma/${cleanName}/schema.prisma`));
100
+ console.log('');
101
+ }
102
+ //# sourceMappingURL=db-add.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-add.js","sourceRoot":"","sources":["../../src/commands/db-add.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function dbGenerateCommand(): Promise<void>;
2
+ //# sourceMappingURL=db-generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-generate.d.ts","sourceRoot":"","sources":["../../src/commands/db-generate.ts"],"names":[],"mappings":"AAMA,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAwBvD"}
@@ -0,0 +1,31 @@
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.dbGenerateCommand = dbGenerateCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const ora_1 = __importDefault(require("ora"));
9
+ const fs_utils_1 = require("../utils/fs.utils");
10
+ const registry_utils_1 = require("../utils/registry.utils");
11
+ async function dbGenerateCommand() {
12
+ console.log('');
13
+ console.log(chalk_1.default.bold.cyan('⚙️ alleen db:generate — Regenerating registry'));
14
+ console.log('');
15
+ const databases = (0, fs_utils_1.getRegisteredDatabases)();
16
+ if (databases.length === 0) {
17
+ console.log(chalk_1.default.gray(' No databases found. Add one with:'));
18
+ console.log(chalk_1.default.white(' alleen db:add --name=<n> --url=<url>'));
19
+ console.log('');
20
+ return;
21
+ }
22
+ console.log(chalk_1.default.gray(` Found ${databases.length} database(s): ${databases.join(', ')}`));
23
+ console.log('');
24
+ const step = (0, ora_1.default)('Regenerating prisma.registry.ts').start();
25
+ (0, registry_utils_1.regenerateRegistry)();
26
+ step.succeed(chalk_1.default.green('src/prisma/prisma.registry.ts regenerated'));
27
+ console.log('');
28
+ console.log(chalk_1.default.bold.green('✅ Registry up to date!'));
29
+ console.log('');
30
+ }
31
+ //# sourceMappingURL=db-generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-generate.js","sourceRoot":"","sources":["../../src/commands/db-generate.ts"],"names":[],"mappings":";;;;;AAMA,8CAwBC;AA9BD,kDAA0B;AAC1B,8CAAwB;AAExB,gDAA2D;AAC3D,4DAAiE;AAE1D,KAAK,UAAU,iBAAiB;IACrC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC,CAAC;IAC/E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,SAAS,GAAG,IAAA,iCAAsB,GAAE,CAAC;IAE3C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC,CAAC;QACnE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,WAAW,SAAS,CAAC,MAAM,iBAAiB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5F,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,IAAI,GAAG,IAAA,aAAG,EAAC,iCAAiC,CAAC,CAAC,KAAK,EAAE,CAAC;IAC5D,IAAA,mCAAkB,GAAE,CAAC;IACrB,IAAI,CAAC,OAAO,CAAC,eAAK,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC,CAAC;IAEvE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function dbListCommand(): Promise<void>;
2
+ //# sourceMappingURL=db-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-list.d.ts","sourceRoot":"","sources":["../../src/commands/db-list.ts"],"names":[],"mappings":"AAaA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAiCnD"}
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.dbListCommand = dbListCommand;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const path = __importStar(require("path"));
42
+ const fs_utils_1 = require("../utils/fs.utils");
43
+ async function dbListCommand() {
44
+ const databases = (0, fs_utils_1.getRegisteredDatabases)();
45
+ console.log('');
46
+ console.log(chalk_1.default.bold.cyan('🗄️ alleen db:list — Registered databases'));
47
+ console.log('');
48
+ if (databases.length === 0) {
49
+ console.log(chalk_1.default.gray(' No databases registered yet.'));
50
+ console.log(chalk_1.default.gray(' Run: alleen db:add --name=<n> --url=<url>'));
51
+ console.log('');
52
+ return;
53
+ }
54
+ const envContent = (0, fs_utils_1.fileExists)(fs_utils_1.ENV_PATH) ? (0, fs_utils_1.readFile)(fs_utils_1.ENV_PATH) : '';
55
+ databases.forEach((name, i) => {
56
+ const envKey = (0, fs_utils_1.toEnvKey)(name);
57
+ const hasEnv = envContent.includes(`${envKey}=`);
58
+ const hasSchema = (0, fs_utils_1.fileExists)(path.join(fs_utils_1.PRISMA_DIR, name, 'schema.prisma'));
59
+ const statusEnv = hasEnv ? chalk_1.default.green('.env') : chalk_1.default.red('❌ .env missing');
60
+ const statusSchema = hasSchema ? chalk_1.default.green('schema') : chalk_1.default.red('❌ schema missing');
61
+ console.log(` ${chalk_1.default.bold.white(String(i + 1).padStart(2, ' '))}. ` +
62
+ chalk_1.default.bold.yellow(name.padEnd(20, ' ')) +
63
+ ` ${statusEnv} ${statusSchema}`);
64
+ });
65
+ console.log('');
66
+ console.log(chalk_1.default.gray(` Total: ${databases.length} database(s)`));
67
+ console.log('');
68
+ }
69
+ //# sourceMappingURL=db-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-list.js","sourceRoot":"","sources":["../../src/commands/db-list.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,sCAiCC;AA9CD,kDAA0B;AAE1B,2CAA6B;AAE7B,gDAO2B;AAEpB,KAAK,UAAU,aAAa;IACjC,MAAM,SAAS,GAAG,IAAA,iCAAsB,GAAE,CAAC;IAE3C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC,CAAC;IAC3E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GAAG,IAAA,qBAAU,EAAC,mBAAQ,CAAC,CAAC,CAAC,CAAC,IAAA,mBAAQ,EAAC,mBAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAElE,SAAS,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QAC5B,MAAM,MAAM,GAAQ,IAAA,mBAAQ,EAAC,IAAI,CAAC,CAAC;QACnC,MAAM,MAAM,GAAQ,UAAU,CAAC,QAAQ,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;QACtD,MAAM,SAAS,GAAK,IAAA,qBAAU,EAAC,IAAI,CAAC,IAAI,CAAC,qBAAU,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC;QAC7E,MAAM,SAAS,GAAK,MAAM,CAAI,CAAC,CAAC,eAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAI,CAAC,CAAC,eAAK,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACrF,MAAM,YAAY,GAAE,SAAS,CAAC,CAAC,CAAC,eAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAE,CAAC,CAAC,eAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAEvF,OAAO,CAAC,GAAG,CACT,KAAK,eAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI;YACzD,eAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;YACvC,KAAK,SAAS,MAAM,YAAY,EAAE,CACnC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,YAAY,SAAS,CAAC,MAAM,cAAc,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,6 @@
1
+ interface DbRemoveOptions {
2
+ name: string;
3
+ }
4
+ export declare function dbRemoveCommand(options: DbRemoveOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=db-remove.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-remove.d.ts","sourceRoot":"","sources":["../../src/commands/db-remove.ts"],"names":[],"mappings":"AAeA,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAmD7E"}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.dbRemoveCommand = dbRemoveCommand;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const ora_1 = __importDefault(require("ora"));
42
+ const path = __importStar(require("path"));
43
+ const fs = __importStar(require("fs"));
44
+ const fs_utils_1 = require("../utils/fs.utils");
45
+ const registry_utils_1 = require("../utils/registry.utils");
46
+ async function dbRemoveCommand(options) {
47
+ const cleanName = options.name.toLowerCase().trim();
48
+ console.log('');
49
+ console.log(chalk_1.default.bold.red(`🗑️ alleen db:remove — Removing "${cleanName}" database`));
50
+ console.log('');
51
+ const existing = (0, fs_utils_1.getRegisteredDatabases)();
52
+ if (!existing.includes(cleanName)) {
53
+ console.log(chalk_1.default.yellow(`⚠️ Database "${cleanName}" is not registered.`));
54
+ console.log(chalk_1.default.gray(` Run "alleen db:list" to see registered databases.`));
55
+ process.exit(0);
56
+ }
57
+ const serviceStep = (0, ora_1.default)(`Removing src/prisma/${cleanName}.service.ts`).start();
58
+ const servicePath = path.join(fs_utils_1.PRISMA_SERVICES_DIR, `${cleanName}.service.ts`);
59
+ if ((0, fs_utils_1.fileExists)(servicePath)) {
60
+ fs.unlinkSync(servicePath);
61
+ serviceStep.succeed(chalk_1.default.green(`src/prisma/${cleanName}.service.ts removed`));
62
+ }
63
+ else {
64
+ serviceStep.warn(chalk_1.default.yellow(`src/prisma/${cleanName}.service.ts not found — skipped`));
65
+ }
66
+ const schemaStep = (0, ora_1.default)(`Removing prisma/${cleanName}/`).start();
67
+ const schemaDir = path.join(fs_utils_1.PRISMA_DIR, cleanName);
68
+ if ((0, fs_utils_1.fileExists)(schemaDir)) {
69
+ fs.rmSync(schemaDir, { recursive: true, force: true });
70
+ schemaStep.succeed(chalk_1.default.green(`prisma/${cleanName}/ removed`));
71
+ }
72
+ else {
73
+ schemaStep.warn(chalk_1.default.yellow(`prisma/${cleanName}/ not found — skipped`));
74
+ }
75
+ const envStep = (0, ora_1.default)(`Cleaning .env`).start();
76
+ const envKey = (0, fs_utils_1.toEnvKey)(cleanName);
77
+ const removed = (0, fs_utils_1.removeEnvVar)(envKey);
78
+ if (removed) {
79
+ envStep.succeed(chalk_1.default.green(`.env cleaned — ${envKey} removed`));
80
+ }
81
+ else {
82
+ envStep.warn(chalk_1.default.yellow(`.env: ${envKey} not found — skipped`));
83
+ }
84
+ const registryStep = (0, ora_1.default)(`Regenerating prisma.registry.ts`).start();
85
+ (0, registry_utils_1.regenerateRegistry)();
86
+ registryStep.succeed(chalk_1.default.green(`src/prisma/prisma.registry.ts updated`));
87
+ console.log('');
88
+ console.log(chalk_1.default.bold.green(`✅ Database "${cleanName}" removed successfully.`));
89
+ console.log('');
90
+ }
91
+ //# sourceMappingURL=db-remove.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-remove.js","sourceRoot":"","sources":["../../src/commands/db-remove.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export declare const ROOT: string;
2
+ export declare const PRISMA_DIR: string;
3
+ export declare const SRC_DIR: string;
4
+ export declare const PRISMA_SERVICES_DIR: string;
5
+ export declare const REGISTRY_PATH: string;
6
+ export declare const ENV_PATH: string;
7
+ export declare const CONFIG_PATH: string;
8
+ export declare function capitalize(s: string): string;
9
+ export declare function toEnvKey(name: string): string;
10
+ export declare function ensureDir(dirPath: string): void;
11
+ export declare function writeFile(filePath: string, content: string): void;
12
+ export declare function readFile(filePath: string): string;
13
+ export declare function fileExists(filePath: string): boolean;
14
+ export declare function addEnvVar(key: string, value: string): 'added' | 'exists';
15
+ export declare function removeEnvVar(key: string): boolean;
16
+ export declare function getRegisteredDatabases(): string[];
17
+ //# sourceMappingURL=fs.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.utils.d.ts","sourceRoot":"","sources":["../../src/utils/fs.utils.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,IAAI,QAAsB,CAAC;AACxC,eAAO,MAAM,UAAU,QAA4B,CAAC;AACpD,eAAO,MAAM,OAAO,QAA4B,CAAC;AACjD,eAAO,MAAM,mBAAmB,QAA+B,CAAC;AAChE,eAAO,MAAM,aAAa,QAA6D,CAAC;AACxF,eAAO,MAAM,QAAQ,QAAqC,CAAC;AAC3D,eAAO,MAAM,WAAW,QAA8C,CAAC;AAGvE,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE7C;AAGD,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAGjE;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD;AAGD,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAOxE;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOjD;AAGD,wBAAgB,sBAAsB,IAAI,MAAM,EAAE,CAMjD"}
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CONFIG_PATH = exports.ENV_PATH = exports.REGISTRY_PATH = exports.PRISMA_SERVICES_DIR = exports.SRC_DIR = exports.PRISMA_DIR = exports.ROOT = void 0;
37
+ exports.capitalize = capitalize;
38
+ exports.toEnvKey = toEnvKey;
39
+ exports.ensureDir = ensureDir;
40
+ exports.writeFile = writeFile;
41
+ exports.readFile = readFile;
42
+ exports.fileExists = fileExists;
43
+ exports.addEnvVar = addEnvVar;
44
+ exports.removeEnvVar = removeEnvVar;
45
+ exports.getRegisteredDatabases = getRegisteredDatabases;
46
+ const fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ // ─── Paths ────────────────────────────────────────────────────────
49
+ exports.ROOT = process.cwd();
50
+ exports.PRISMA_DIR = path.join(exports.ROOT, 'prisma');
51
+ exports.SRC_DIR = path.join(exports.ROOT, 'src');
52
+ exports.PRISMA_SERVICES_DIR = path.join(exports.SRC_DIR, 'prisma');
53
+ exports.REGISTRY_PATH = path.join(exports.PRISMA_SERVICES_DIR, 'prisma.registry.ts');
54
+ exports.ENV_PATH = path.join(exports.ROOT, '.env');
55
+ exports.CONFIG_PATH = path.join(exports.ROOT, 'alleen.config.ts');
56
+ // ─── String helpers ───────────────────────────────────────────────
57
+ function capitalize(s) {
58
+ return s.charAt(0).toUpperCase() + s.slice(1);
59
+ }
60
+ function toEnvKey(name) {
61
+ return `DATABASE_${name.toUpperCase()}_URL`;
62
+ }
63
+ // ─── Filesystem helpers ───────────────────────────────────────────
64
+ function ensureDir(dirPath) {
65
+ fs.mkdirSync(dirPath, { recursive: true });
66
+ }
67
+ function writeFile(filePath, content) {
68
+ ensureDir(path.dirname(filePath));
69
+ fs.writeFileSync(filePath, content, 'utf-8');
70
+ }
71
+ function readFile(filePath) {
72
+ return fs.readFileSync(filePath, 'utf-8');
73
+ }
74
+ function fileExists(filePath) {
75
+ return fs.existsSync(filePath);
76
+ }
77
+ // ─── .env helpers ─────────────────────────────────────────────────
78
+ function addEnvVar(key, value) {
79
+ let content = fileExists(exports.ENV_PATH) ? readFile(exports.ENV_PATH) : '';
80
+ if (content.includes(`${key}=`))
81
+ return 'exists';
82
+ const line = `${key}="${value}"`;
83
+ content = content.trimEnd() + `\n${line}\n`;
84
+ fs.writeFileSync(exports.ENV_PATH, content);
85
+ return 'added';
86
+ }
87
+ function removeEnvVar(key) {
88
+ if (!fileExists(exports.ENV_PATH))
89
+ return false;
90
+ const lines = readFile(exports.ENV_PATH).split('\n');
91
+ const filtered = lines.filter(l => !l.startsWith(`${key}=`));
92
+ if (filtered.length === lines.length)
93
+ return false;
94
+ fs.writeFileSync(exports.ENV_PATH, filtered.join('\n'));
95
+ return true;
96
+ }
97
+ // ─── DB list helper ───────────────────────────────────────────────
98
+ function getRegisteredDatabases() {
99
+ if (!fileExists(exports.PRISMA_SERVICES_DIR))
100
+ return [];
101
+ return fs
102
+ .readdirSync(exports.PRISMA_SERVICES_DIR)
103
+ .filter(f => f.endsWith('.service.ts'))
104
+ .map(f => f.replace('.service.ts', ''));
105
+ }
106
+ //# sourceMappingURL=fs.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.utils.js","sourceRoot":"","sources":["../../src/utils/fs.utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function regenerateRegistry(): void;
2
+ //# sourceMappingURL=registry.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.utils.d.ts","sourceRoot":"","sources":["../../src/utils/registry.utils.ts"],"names":[],"mappings":"AAQA,wBAAgB,kBAAkB,IAAI,IAAI,CAIzC"}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.regenerateRegistry = regenerateRegistry;
4
+ const fs_utils_1 = require("./fs.utils");
5
+ function regenerateRegistry() {
6
+ const databases = (0, fs_utils_1.getRegisteredDatabases)();
7
+ const content = buildRegistryContent(databases);
8
+ (0, fs_utils_1.writeFile)(fs_utils_1.REGISTRY_PATH, content);
9
+ }
10
+ function buildRegistryContent(databases) {
11
+ if (databases.length === 0) {
12
+ return `// ⚠️ AUTO-GÉNÉRÉ par @alleen/cli — ne pas modifier manuellement
13
+ // Utilisez: alleen db:add / alleen db:remove
14
+
15
+ export const PRISMA_REGISTRY: Record<string, any> = {};
16
+ export const PRISMA_PROVIDERS: any[] = [];
17
+ `;
18
+ }
19
+ const imports = databases
20
+ .map(n => `import { ${(0, fs_utils_1.capitalize)(n)}PrismaService } from './${n}.service';`)
21
+ .join('\n');
22
+ const registry = databases
23
+ .map(n => ` '${n}': ${(0, fs_utils_1.capitalize)(n)}PrismaService,`)
24
+ .join('\n');
25
+ const providers = databases
26
+ .map(n => ` ${(0, fs_utils_1.capitalize)(n)}PrismaService,`)
27
+ .join('\n');
28
+ return `// ⚠️ AUTO-GÉNÉRÉ par @alleen/cli — ne pas modifier manuellement
29
+ // Utilisez: alleen db:add / alleen db:remove
30
+ // Dernière mise à jour : ${new Date().toISOString()}
31
+
32
+ ${imports}
33
+
34
+ export const PRISMA_REGISTRY: Record<string, any> = {
35
+ ${registry}
36
+ };
37
+
38
+ export const PRISMA_PROVIDERS: any[] = [
39
+ ${providers}
40
+ ];
41
+ `;
42
+ }
43
+ //# sourceMappingURL=registry.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.utils.js","sourceRoot":"","sources":["../../src/utils/registry.utils.ts"],"names":[],"mappings":";;AAQA,gDAIC;AAZD,yCAMoB;AAEpB,SAAgB,kBAAkB;IAChC,MAAM,SAAS,GAAG,IAAA,iCAAsB,GAAE,CAAC;IAC3C,MAAM,OAAO,GAAK,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAClD,IAAA,oBAAS,EAAC,wBAAa,EAAE,OAAO,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,oBAAoB,CAAC,SAAmB;IAC/C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO;;;;;CAKV,CAAC;IACA,CAAC;IAED,MAAM,OAAO,GAAG,SAAS;SACtB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,IAAA,qBAAU,EAAC,CAAC,CAAC,2BAA2B,CAAC,YAAY,CAAC;SAC3E,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,QAAQ,GAAG,SAAS;SACvB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,IAAA,qBAAU,EAAC,CAAC,CAAC,gBAAgB,CAAC;SACpD,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,MAAM,SAAS,GAAG,SAAS;SACxB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,IAAA,qBAAU,EAAC,CAAC,CAAC,gBAAgB,CAAC;SAC5C,IAAI,CAAC,IAAI,CAAC,CAAC;IAEd,OAAO;;4BAEmB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;;EAElD,OAAO;;;EAGP,QAAQ;;;;EAIR,SAAS;;CAEV,CAAC;AACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function buildSchema(name: string, provider: string): string;
2
+ export declare function buildPrismaService(name: string): string;
3
+ //# sourceMappingURL=templates.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.utils.d.ts","sourceRoot":"","sources":["../../src/utils/templates.utils.ts"],"names":[],"mappings":"AAGA,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAyBlE;AAGD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmCvD"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildSchema = buildSchema;
4
+ exports.buildPrismaService = buildPrismaService;
5
+ const fs_utils_1 = require("../utils/fs.utils");
6
+ // ─── schema.prisma template ───────────────────────────────────────
7
+ function buildSchema(name, provider) {
8
+ const envKey = (0, fs_utils_1.toEnvKey)(name);
9
+ return `// Generated by @alleen/cli — alleen db:add --name=${name}
10
+ // Edit this file to add your models, then run:
11
+ // npx prisma migrate dev --schema=prisma/${name}/schema.prisma
12
+
13
+ generator client {
14
+ provider = "prisma-client-js"
15
+ output = "../../node_modules/@prisma/${name}-client"
16
+ }
17
+
18
+ datasource db {
19
+ provider = "${provider}"
20
+ url = env("${envKey}")
21
+ }
22
+
23
+ // ─── Add your models below ────────────────────────────────────────
24
+ // Example:
25
+ //
26
+ // model User {
27
+ // id Int @id @default(autoincrement())
28
+ // email String @unique
29
+ // createdAt DateTime @default(now())
30
+ // }
31
+ `;
32
+ }
33
+ // ─── PrismaService template ───────────────────────────────────────
34
+ function buildPrismaService(name) {
35
+ const className = `${(0, fs_utils_1.capitalize)(name)}PrismaService`;
36
+ return `// Generated by @alleen/cli — alleen db:add --name=${name}
37
+ // Do NOT edit manually
38
+ import { Injectable, OnModuleInit, OnModuleDestroy, Logger } from '@nestjs/common';
39
+ import { PrismaClient } from '@prisma/${name}-client';
40
+ import { withRetry, healthCheck, PrismaHealthResult } from '@alleen/prisma';
41
+
42
+ @Injectable()
43
+ export class ${className}
44
+ extends PrismaClient
45
+ implements OnModuleInit, OnModuleDestroy
46
+ {
47
+ readonly alleenName = '${name}';
48
+ private readonly logger = new Logger(${className}.name);
49
+
50
+ async onModuleInit(): Promise<void> {
51
+ await withRetry(() => this.\$connect(), {
52
+ attempts: 3,
53
+ delay: 3000,
54
+ logger: this.logger,
55
+ dbName: this.alleenName,
56
+ });
57
+ }
58
+
59
+ async onModuleDestroy(): Promise<void> {
60
+ await this.\$disconnect();
61
+ this.logger.log('Disconnected from "${name}"');
62
+ }
63
+
64
+ async healthCheck(): Promise<PrismaHealthResult> {
65
+ return healthCheck(this, this.alleenName);
66
+ }
67
+ }
68
+ `;
69
+ }
70
+ //# sourceMappingURL=templates.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"templates.utils.js","sourceRoot":"","sources":["../../src/utils/templates.utils.ts"],"names":[],"mappings":";;AAGA,kCAyBC;AAGD,gDAmCC;AAlED,gDAAyD;AAEzD,qEAAqE;AACrE,SAAgB,WAAW,CAAC,IAAY,EAAE,QAAgB;IACxD,MAAM,MAAM,GAAG,IAAA,mBAAQ,EAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,sDAAsD,IAAI;;8CAErB,IAAI;;;;2CAIP,IAAI;;;;gBAI/B,QAAQ;oBACJ,MAAM;;;;;;;;;;;CAWzB,CAAC;AACF,CAAC;AAED,qEAAqE;AACrE,SAAgB,kBAAkB,CAAC,IAAY;IAC7C,MAAM,SAAS,GAAG,GAAG,IAAA,qBAAU,EAAC,IAAI,CAAC,eAAe,CAAC;IACrD,OAAO,sDAAsD,IAAI;;;wCAG3B,IAAI;;;;eAI7B,SAAS;;;;2BAIG,IAAI;yCACU,SAAS;;;;;;;;;;;;;0CAaR,IAAI;;;;;;;CAO7C,CAAC;AACF,CAAC"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@alleen/cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI for alleen-api — manage multi-database Prisma setup",
5
+ "bin": {
6
+ "alleen": "./dist/bin/alleen.js"
7
+ },
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "README.md"
14
+ ],
15
+ "main": "./dist/index.js",
16
+ "types": "./dist/index.d.ts",
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "dev": "ts-node src/bin/alleen.ts"
20
+ },
21
+ "dependencies": {
22
+ "chalk": "^5.3.0",
23
+ "commander": "^12.0.0",
24
+ "ora": "^8.0.0"
25
+ },
26
+ "devDependencies": {
27
+ "@types/node": "^20.0.0",
28
+ "ts-node": "^10.9.2",
29
+ "typescript": "^5.4.0"
30
+ },
31
+ "engines": {
32
+ "node": ">=18.0.0"
33
+ },
34
+ "author": "OLIVIER ADOU",
35
+ "license": "ISC"
36
+ }