@bayajidalam/apollo-cli 1.0.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 +97 -0
- package/dist/bin/index.js +17 -0
- package/dist/commands/build.js +43 -0
- package/dist/commands/generate.js +64 -0
- package/dist/commands/init.js +181 -0
- package/dist/commands/prisma.js +35 -0
- package/dist/utils/generator.js +42 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Apollo CLI
|
|
2
|
+
|
|
3
|
+
A CLI tool for scaffolding and managing Apollo backend projects (Express + TypeScript + Prisma + PostgreSQL).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
### Global Installation
|
|
8
|
+
|
|
9
|
+
To install the CLI globally:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g apollo-cli
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Local Development Setup
|
|
16
|
+
|
|
17
|
+
If you are developing this tool locally and want to test it:
|
|
18
|
+
|
|
19
|
+
1. **Build the CLI**:
|
|
20
|
+
```bash
|
|
21
|
+
npm run build
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
2. **Link it globally**:
|
|
25
|
+
```bash
|
|
26
|
+
npm link
|
|
27
|
+
```
|
|
28
|
+
This makes the `apollo-cli` command available in your terminal.
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
### 1. `generate` (alias: `g`)
|
|
33
|
+
|
|
34
|
+
Generates a new module structure including controller, service, route, interface, validation, and constants.
|
|
35
|
+
|
|
36
|
+
**Syntax:**
|
|
37
|
+
```bash
|
|
38
|
+
apollo-cli generate module <ModuleName>
|
|
39
|
+
# OR
|
|
40
|
+
apollo-cli g module <ModuleName>
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Example:**
|
|
44
|
+
Generate a `User` module:
|
|
45
|
+
```bash
|
|
46
|
+
apollo-cli g module User
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
This will create the following files in `src/app/modules/User`:
|
|
50
|
+
- `user.controller.ts`
|
|
51
|
+
- `user.service.ts`
|
|
52
|
+
- `user.route.ts`
|
|
53
|
+
- `user.interface.ts`
|
|
54
|
+
- `user.validation.ts`
|
|
55
|
+
- `user.constant.ts`
|
|
56
|
+
|
|
57
|
+
### 2. `build`
|
|
58
|
+
|
|
59
|
+
Builds the application for production deployment.
|
|
60
|
+
|
|
61
|
+
**Syntax:**
|
|
62
|
+
```bash
|
|
63
|
+
apollo-cli build
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**What it does:**
|
|
67
|
+
- Cleans the `dist` folder.
|
|
68
|
+
- Compiles TypeScript files.
|
|
69
|
+
- Copies `package.json`, `package-lock.json`, and `.env` to the `dist` folder.
|
|
70
|
+
|
|
71
|
+
### 3. `prisma`
|
|
72
|
+
|
|
73
|
+
Helper commands for Prisma ORM.
|
|
74
|
+
|
|
75
|
+
**Generate Client:**
|
|
76
|
+
```bash
|
|
77
|
+
apollo-cli prisma generate
|
|
78
|
+
```
|
|
79
|
+
*(Runs `npx prisma generate`)*
|
|
80
|
+
|
|
81
|
+
**Run Migrations:**
|
|
82
|
+
```bash
|
|
83
|
+
apollo-cli prisma migrate
|
|
84
|
+
```
|
|
85
|
+
*(Runs `npx prisma migrate dev`)*
|
|
86
|
+
|
|
87
|
+
## Development
|
|
88
|
+
|
|
89
|
+
To run the CLI directly from source without building:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
npx ts-node src/bin/index.ts <command>
|
|
93
|
+
```
|
|
94
|
+
Example:
|
|
95
|
+
```bash
|
|
96
|
+
npx ts-node src/bin/index.ts generate module Product
|
|
97
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const generate_1 = require("../commands/generate");
|
|
6
|
+
const build_1 = require("../commands/build");
|
|
7
|
+
const prisma_1 = require("../commands/prisma");
|
|
8
|
+
const init_1 = require("../commands/init");
|
|
9
|
+
const program = new commander_1.Command();
|
|
10
|
+
program
|
|
11
|
+
.version('1.0.0')
|
|
12
|
+
.description('Apollo CLI Tool');
|
|
13
|
+
program.addCommand(generate_1.generateCommand);
|
|
14
|
+
program.addCommand(build_1.buildCommand);
|
|
15
|
+
program.addCommand(prisma_1.prismaCommand);
|
|
16
|
+
program.addCommand(init_1.initCommand);
|
|
17
|
+
program.parse(process.argv);
|
|
@@ -0,0 +1,43 @@
|
|
|
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.buildCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const child_process_1 = require("child_process");
|
|
9
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
12
|
+
exports.buildCommand = new commander_1.Command('build')
|
|
13
|
+
.description('Build the application for production')
|
|
14
|
+
.action(async () => {
|
|
15
|
+
console.log(chalk_1.default.blue('š Starting build process...'));
|
|
16
|
+
try {
|
|
17
|
+
// 1. Clean dist folder
|
|
18
|
+
const distPath = path_1.default.join(process.cwd(), 'dist');
|
|
19
|
+
if (fs_extra_1.default.existsSync(distPath)) {
|
|
20
|
+
console.log(chalk_1.default.yellow('š§¹ Cleaning dist folder...'));
|
|
21
|
+
await fs_extra_1.default.remove(distPath);
|
|
22
|
+
}
|
|
23
|
+
// 2. Run TypeScript Compiler
|
|
24
|
+
console.log(chalk_1.default.blue('šØ Compiling TypeScript...'));
|
|
25
|
+
(0, child_process_1.execSync)('npx tsc', { stdio: 'inherit' });
|
|
26
|
+
// 3. Copy Key Files
|
|
27
|
+
console.log(chalk_1.default.blue('š Copying static files...'));
|
|
28
|
+
const filesToCopy = ['package.json', 'package-lock.json', '.env'];
|
|
29
|
+
for (const file of filesToCopy) {
|
|
30
|
+
const srcPath = path_1.default.join(process.cwd(), file);
|
|
31
|
+
if (fs_extra_1.default.existsSync(srcPath)) {
|
|
32
|
+
await fs_extra_1.default.copy(srcPath, path_1.default.join(distPath, file));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
console.log(chalk_1.default.green('\nā
Build completed successfully!'));
|
|
36
|
+
console.log(chalk_1.default.white('To deploy, upload the "dist" folder and run:'));
|
|
37
|
+
console.log(chalk_1.default.cyan('npm install --production'));
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.error(chalk_1.default.red('ā Build failed:'), error);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
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.generateCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const generator_1 = require("../utils/generator");
|
|
11
|
+
exports.generateCommand = new commander_1.Command('generate')
|
|
12
|
+
.alias('g')
|
|
13
|
+
.description('Generate a new resource')
|
|
14
|
+
.argument('[type]', 'Type of resource to generate (e.g., module)')
|
|
15
|
+
.argument('[name]', 'Name of the resource')
|
|
16
|
+
.action(async (type, name) => {
|
|
17
|
+
// 1. Validate Input
|
|
18
|
+
if (!type) {
|
|
19
|
+
const answers = await inquirer_1.default.prompt([{
|
|
20
|
+
type: 'list',
|
|
21
|
+
name: 'type',
|
|
22
|
+
message: 'What would you like to generate?',
|
|
23
|
+
choices: ['module']
|
|
24
|
+
}]);
|
|
25
|
+
type = answers.type;
|
|
26
|
+
}
|
|
27
|
+
if (type !== 'module') {
|
|
28
|
+
console.error('Only "module" generation is currently supported.');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (!name) {
|
|
32
|
+
const answers = await inquirer_1.default.prompt([{
|
|
33
|
+
type: 'input',
|
|
34
|
+
name: 'name',
|
|
35
|
+
message: 'What is the name of the module?',
|
|
36
|
+
validate: (input) => input.trim() !== '' ? 'Module name is required' : true
|
|
37
|
+
}]);
|
|
38
|
+
name = answers.name;
|
|
39
|
+
}
|
|
40
|
+
const moduleNameRaw = name.trim();
|
|
41
|
+
// 2. Format Casing
|
|
42
|
+
const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
43
|
+
const camelize = (s) => s.charAt(0).toLowerCase() + s.slice(1);
|
|
44
|
+
const moduleNamePascal = capitalize(moduleNameRaw);
|
|
45
|
+
const moduleNameCamel = camelize(moduleNameRaw);
|
|
46
|
+
console.log(`Generating module: ${moduleNamePascal}...`);
|
|
47
|
+
// 3. Define Output Paths
|
|
48
|
+
// Assume we are in the project root
|
|
49
|
+
const baseDir = path_1.default.join(process.cwd(), 'src/app/modules', moduleNamePascal);
|
|
50
|
+
// 4. Generate Files
|
|
51
|
+
const files = [
|
|
52
|
+
{ template: 'module/controller.ejs', output: `${moduleNameCamel}.controller.ts` },
|
|
53
|
+
{ template: 'module/service.ejs', output: `${moduleNameCamel}.service.ts` },
|
|
54
|
+
{ template: 'module/route.ejs', output: `${moduleNameCamel}.route.ts` },
|
|
55
|
+
{ template: 'module/interface.ejs', output: `${moduleNameCamel}.interface.ts` },
|
|
56
|
+
{ template: 'module/validation.ejs', output: `${moduleNameCamel}.validation.ts` },
|
|
57
|
+
{ template: 'module/constant.ejs', output: `${moduleNameCamel}.constant.ts` },
|
|
58
|
+
];
|
|
59
|
+
for (const file of files) {
|
|
60
|
+
await (0, generator_1.renderTemplate)(file.template, path_1.default.join(baseDir, file.output), { moduleName: moduleNamePascal, camelModuleName: moduleNameCamel });
|
|
61
|
+
}
|
|
62
|
+
// 5. Success Message
|
|
63
|
+
console.log('\nModule generated successfully! š');
|
|
64
|
+
});
|
|
@@ -0,0 +1,181 @@
|
|
|
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.initCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
9
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
12
|
+
const child_process_1 = require("child_process");
|
|
13
|
+
exports.initCommand = new commander_1.Command('init')
|
|
14
|
+
.description('Initialize a new Apollo Gears project')
|
|
15
|
+
.argument('[projectName]', 'Name of the project directory')
|
|
16
|
+
.action(async (projectName) => {
|
|
17
|
+
// 1. Prompt for Project Name if missing
|
|
18
|
+
if (!projectName) {
|
|
19
|
+
const answers = await inquirer_1.default.prompt([
|
|
20
|
+
{
|
|
21
|
+
type: 'input',
|
|
22
|
+
name: 'name',
|
|
23
|
+
message: 'What is the name of your project?',
|
|
24
|
+
default: 'my-apollo-app',
|
|
25
|
+
validate: (input) => input.trim() !== '' ? true : 'Project name is required'
|
|
26
|
+
}
|
|
27
|
+
]);
|
|
28
|
+
projectName = answers.name;
|
|
29
|
+
}
|
|
30
|
+
const projectRoot = path_1.default.join(process.cwd(), projectName);
|
|
31
|
+
if (fs_extra_1.default.existsSync(projectRoot)) {
|
|
32
|
+
console.error(chalk_1.default.red(`Error: Directory "${projectName}" already exists.`));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
console.log(chalk_1.default.blue(`\nš Initializing project in ${projectRoot}...\n`));
|
|
36
|
+
try {
|
|
37
|
+
// 2. Create Directory
|
|
38
|
+
await fs_extra_1.default.ensureDir(projectRoot);
|
|
39
|
+
// 3. Create Package.json
|
|
40
|
+
const packageJson = {
|
|
41
|
+
name: projectName,
|
|
42
|
+
version: "1.0.0",
|
|
43
|
+
description: "Backend project generated by Apollo Gears CLI",
|
|
44
|
+
main: "dist/server.js",
|
|
45
|
+
scripts: {
|
|
46
|
+
"start": "node dist/server.js",
|
|
47
|
+
"dev": "ts-node-dev --respawn --transpile-only src/server.ts",
|
|
48
|
+
"build": "tsc",
|
|
49
|
+
"lint": "eslint src/**/*.ts",
|
|
50
|
+
"lint:fix": "eslint src/**/*.ts --fix",
|
|
51
|
+
"format": "prettier --write ."
|
|
52
|
+
},
|
|
53
|
+
keywords: ["express", "prisma", "typescript", "apollo-gears"],
|
|
54
|
+
author: "",
|
|
55
|
+
license: "ISC",
|
|
56
|
+
dependencies: {
|
|
57
|
+
"express": "^4.18.2",
|
|
58
|
+
"cors": "^2.8.5",
|
|
59
|
+
"dotenv": "^16.3.1",
|
|
60
|
+
"http-status": "^1.7.3",
|
|
61
|
+
"@prisma/client": "^5.7.1"
|
|
62
|
+
},
|
|
63
|
+
devDependencies: {
|
|
64
|
+
"typescript": "^5.3.3",
|
|
65
|
+
"ts-node-dev": "^2.0.0",
|
|
66
|
+
"@types/node": "^20.10.4",
|
|
67
|
+
"@types/express": "^4.17.21",
|
|
68
|
+
"@types/cors": "^2.8.17",
|
|
69
|
+
"prisma": "^5.7.1",
|
|
70
|
+
"eslint": "^8.55.0",
|
|
71
|
+
"prettier": "^3.1.1"
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
await fs_extra_1.default.writeJson(path_1.default.join(projectRoot, 'package.json'), packageJson, { spaces: 2 });
|
|
75
|
+
// 4. Create tsconfig.json
|
|
76
|
+
const tsconfig = {
|
|
77
|
+
"compilerOptions": {
|
|
78
|
+
"target": "ES2021",
|
|
79
|
+
"module": "commonjs",
|
|
80
|
+
"moduleResolution": "node",
|
|
81
|
+
"outDir": "./dist",
|
|
82
|
+
"rootDir": "./src",
|
|
83
|
+
"strict": true,
|
|
84
|
+
"esModuleInterop": true,
|
|
85
|
+
"skipLibCheck": true,
|
|
86
|
+
"forceConsistentCasingInFileNames": true
|
|
87
|
+
},
|
|
88
|
+
"include": ["src/**/*"],
|
|
89
|
+
"exclude": ["node_modules"]
|
|
90
|
+
};
|
|
91
|
+
await fs_extra_1.default.writeJson(path_1.default.join(projectRoot, 'tsconfig.json'), tsconfig, { spaces: 2 });
|
|
92
|
+
// 5. Create Scaffolding Folders
|
|
93
|
+
const folders = [
|
|
94
|
+
'src/app/modules',
|
|
95
|
+
'src/app/middlewares',
|
|
96
|
+
'src/app/routes',
|
|
97
|
+
'src/app/utils',
|
|
98
|
+
'src/app/errors',
|
|
99
|
+
'src/app/config'
|
|
100
|
+
];
|
|
101
|
+
for (const folder of folders) {
|
|
102
|
+
await fs_extra_1.default.ensureDir(path_1.default.join(projectRoot, folder));
|
|
103
|
+
}
|
|
104
|
+
// 6. Create Essential Files
|
|
105
|
+
// src/server.ts
|
|
106
|
+
const serverContent = `import app from './app';
|
|
107
|
+
import config from './app/config';
|
|
108
|
+
|
|
109
|
+
async function main() {
|
|
110
|
+
try {
|
|
111
|
+
app.listen(config.port, () => {
|
|
112
|
+
console.log(\`Example app listening on port \${config.port}\`);
|
|
113
|
+
});
|
|
114
|
+
} catch (err) {
|
|
115
|
+
console.log(err);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
main();`;
|
|
120
|
+
await fs_extra_1.default.writeFile(path_1.default.join(projectRoot, 'src/server.ts'), serverContent);
|
|
121
|
+
// src/app.ts
|
|
122
|
+
const appContent = `import express, { Application, Request, Response } from 'express';
|
|
123
|
+
import cors from 'cors';
|
|
124
|
+
|
|
125
|
+
const app: Application = express();
|
|
126
|
+
|
|
127
|
+
// parsers
|
|
128
|
+
app.use(express.json());
|
|
129
|
+
app.use(cors());
|
|
130
|
+
|
|
131
|
+
// application routes
|
|
132
|
+
// app.use('/api/v1', router);
|
|
133
|
+
|
|
134
|
+
app.get('/', (req: Request, res: Response) => {
|
|
135
|
+
res.send('Hello from Apollo Gears World!');
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
export default app;`;
|
|
139
|
+
await fs_extra_1.default.writeFile(path_1.default.join(projectRoot, 'src/app.ts'), appContent);
|
|
140
|
+
// src/app/config/index.ts
|
|
141
|
+
const configContent = `import dotenv from 'dotenv';
|
|
142
|
+
import path from 'path';
|
|
143
|
+
|
|
144
|
+
dotenv.config({ path: path.join(process.cwd(), '.env') });
|
|
145
|
+
|
|
146
|
+
export default {
|
|
147
|
+
port: process.env.PORT,
|
|
148
|
+
database_url: process.env.DATABASE_URL,
|
|
149
|
+
};`;
|
|
150
|
+
await fs_extra_1.default.writeFile(path_1.default.join(projectRoot, 'src/app/config/index.ts'), configContent);
|
|
151
|
+
// .env
|
|
152
|
+
const envContent = `PORT=5000
|
|
153
|
+
DATABASE_URL="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"`;
|
|
154
|
+
await fs_extra_1.default.writeFile(path_1.default.join(projectRoot, '.env'), envContent);
|
|
155
|
+
// .gitignore
|
|
156
|
+
const gitignoreContent = `node_modules
|
|
157
|
+
dist
|
|
158
|
+
.env`;
|
|
159
|
+
await fs_extra_1.default.writeFile(path_1.default.join(projectRoot, '.gitignore'), gitignoreContent);
|
|
160
|
+
console.log(chalk_1.default.green('\nā
Project structure created successfully!'));
|
|
161
|
+
// 7. Install Dependencies Prompt
|
|
162
|
+
const { install } = await inquirer_1.default.prompt([
|
|
163
|
+
{
|
|
164
|
+
type: 'confirm',
|
|
165
|
+
name: 'install',
|
|
166
|
+
message: 'Would you like to install dependencies now?',
|
|
167
|
+
default: true
|
|
168
|
+
}
|
|
169
|
+
]);
|
|
170
|
+
if (install) {
|
|
171
|
+
console.log(chalk_1.default.yellow('\nš¦ Installing dependencies...'));
|
|
172
|
+
(0, child_process_1.execSync)('npm install', { cwd: projectRoot, stdio: 'inherit' });
|
|
173
|
+
console.log(chalk_1.default.green('\nā
Dependencies installed!'));
|
|
174
|
+
}
|
|
175
|
+
console.log(chalk_1.default.cyan(`\nTo get started:\n cd ${projectName}\n ${install ? 'npm run dev' : 'npm install && npm run dev'}\n`));
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
console.error(chalk_1.default.red('ā Initialization failed:'), error);
|
|
179
|
+
process.exit(1);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
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.prismaCommand = void 0;
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const child_process_1 = require("child_process");
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
exports.prismaCommand = new commander_1.Command('prisma')
|
|
11
|
+
.description('Prisma utility commands')
|
|
12
|
+
.argument('<action>', 'Action to perform (generate, migrate)')
|
|
13
|
+
.action(async (action) => {
|
|
14
|
+
try {
|
|
15
|
+
if (action === 'generate') {
|
|
16
|
+
console.log(chalk_1.default.blue('š Generating Prisma Client...'));
|
|
17
|
+
(0, child_process_1.execSync)('npx prisma generate', { stdio: 'inherit' });
|
|
18
|
+
console.log(chalk_1.default.green('ā
Prisma Client generated!'));
|
|
19
|
+
}
|
|
20
|
+
else if (action === 'migrate') {
|
|
21
|
+
console.log(chalk_1.default.blue('š Running Migrations...'));
|
|
22
|
+
(0, child_process_1.execSync)('npx prisma migrate dev', { stdio: 'inherit' });
|
|
23
|
+
console.log(chalk_1.default.green('ā
Migrations applied!'));
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
console.error(chalk_1.default.red(`Unknown action: ${action}`));
|
|
27
|
+
console.log('Available actions: generate, migrate');
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
// Error is already logged by inherit stdio usually, but we catch to prevent crash dump
|
|
32
|
+
console.error(chalk_1.default.red('ā Prisma command failed.'));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
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.renderTemplate = void 0;
|
|
7
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const ejs_1 = __importDefault(require("ejs"));
|
|
10
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
+
const renderTemplate = async (templateName, targetPath, data) => {
|
|
12
|
+
try {
|
|
13
|
+
// Resolve template path - assuming templates are in src/templates or dist/templates
|
|
14
|
+
// We look up from the current file location
|
|
15
|
+
const templateDir = path_1.default.resolve(__dirname, '../../src/templates');
|
|
16
|
+
const templatePath = path_1.default.join(templateDir, templateName);
|
|
17
|
+
// Fallback for dist structure if src not found (pseudo-logic for now, ideally strictly copy them)
|
|
18
|
+
// If running in ts-node, __dirname is src/utils, so ../templates works if we are at src
|
|
19
|
+
// Let's rely on standard path resolution relative to this file
|
|
20
|
+
// Check if template exists
|
|
21
|
+
if (!fs_extra_1.default.existsSync(templatePath)) {
|
|
22
|
+
// Try looking in dist if we are in dist
|
|
23
|
+
const distTemplatePath = path_1.default.join(__dirname, '../templates', templateName);
|
|
24
|
+
if (!fs_extra_1.default.existsSync(distTemplatePath)) {
|
|
25
|
+
console.error(chalk_1.default.red(`Template not found at: ${templatePath}`));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const templateContent = await fs_extra_1.default.readFile(templatePath, 'utf-8');
|
|
30
|
+
const renderedContent = ejs_1.default.render(templateContent, data);
|
|
31
|
+
// Create directory if it doesn't exist
|
|
32
|
+
await fs_extra_1.default.ensureDir(path_1.default.dirname(targetPath));
|
|
33
|
+
// Write file
|
|
34
|
+
await fs_extra_1.default.writeFile(targetPath, renderedContent);
|
|
35
|
+
console.log(chalk_1.default.green(`ā Created: ${path_1.default.relative(process.cwd(), targetPath)}`));
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
console.error(chalk_1.default.red('Error generating file:'), error);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
exports.renderTemplate = renderTemplate;
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bayajidalam/apollo-cli",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI tool for speed up backend projects",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"apollo-cli": "dist/bin/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"start": "ts-node src/index.ts",
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"watch": "tsc -w",
|
|
14
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
15
|
+
"cli": "ts-node src/bin/index.ts"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"cli",
|
|
19
|
+
"express",
|
|
20
|
+
"prisma",
|
|
21
|
+
"postgres",
|
|
22
|
+
"typescript"
|
|
23
|
+
],
|
|
24
|
+
"author": "Bayajid Alam Joyel",
|
|
25
|
+
"repository": {
|
|
26
|
+
"url": "https://github.com/BayajidAlam/apollo-cli"
|
|
27
|
+
},
|
|
28
|
+
"license": "ISC",
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"chalk": "^4.1.2",
|
|
34
|
+
"commander": "^13.1.0",
|
|
35
|
+
"ejs": "^3.1.10",
|
|
36
|
+
"fs-extra": "^11.3.0",
|
|
37
|
+
"inquirer": "^8.2.6"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/ejs": "^3.1.5",
|
|
41
|
+
"@types/fs-extra": "^11.0.4",
|
|
42
|
+
"@types/inquirer": "^8.2.6",
|
|
43
|
+
"@types/node": "^22.13.1",
|
|
44
|
+
"ts-node": "^10.9.2",
|
|
45
|
+
"typescript": "^5.7.3"
|
|
46
|
+
}
|
|
47
|
+
}
|