@nest-extended/cli 0.0.1 → 0.0.2-beta-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 CHANGED
@@ -4,14 +4,51 @@ A powerful command-line interface for the **NestExtended** ecosystem. This CLI a
4
4
 
5
5
  ## Installation
6
6
 
7
+ To install globally (recommended for scaffolding new apps):
8
+
7
9
  ```bash
8
- yarn add -D @nest-extended/cli
10
+ npm install -g @nest-extended/cli
9
11
  # or
12
+ yarn global add @nest-extended/cli
13
+ ```
14
+
15
+ To install as a dev dependency in an existing project:
16
+
17
+ ```bash
10
18
  npm install -D @nest-extended/cli
19
+ # or
20
+ yarn add -D @nest-extended/cli
11
21
  ```
12
22
 
13
23
  ## Commands
14
24
 
25
+ ### Generate Application (`g app`)
26
+
27
+ Generates a fully configured NestJS application with standard best-practices built right in.
28
+ It interactive prompts for your choice of database (currently supporting MongoDB) and handles scaffolding the app.
29
+
30
+ **Includes:**
31
+ - Running `@nestjs/cli`'s `nest new` command internally
32
+ - `Mongoose` schema integration out of the box
33
+ - Context-mapping out of the box using `nestjs-cls`
34
+ - Built-in `AuthModule` with JSON Web Token (JWT) handling via `@nestjs/jwt` and password hashing with `bcrypt`
35
+ - Fully functional `UsersModule` equipped with standard fields and authentication logic implementations.
36
+ - Pre-configured `NestExtendedModule` context for soft deletes functionality
37
+
38
+ **Usage:**
39
+
40
+ ```bash
41
+ nest-cli g app <app-name>
42
+ # or
43
+ nest-cli generate app <app-name>
44
+ ```
45
+
46
+ **Example:**
47
+
48
+ ```bash
49
+ nest-cli g app e-commerce-dashboard
50
+ ```
51
+
15
52
  ### Generate Service (`g service`)
16
53
 
17
54
  Generates a complete resource bundle including:
@@ -27,15 +64,15 @@ It also automatically updates your `src/app.module.ts` to include the new module
27
64
  **Usage:**
28
65
 
29
66
  ```bash
30
- nestx-cli g service <name>
67
+ nest-cli g service <name>
31
68
  # or
32
- nestx-cli generate service <name>
69
+ nest-cli generate service <name>
33
70
  ```
34
71
 
35
72
  **Example:**
36
73
 
37
74
  ```bash
38
- nestx-cli g service user-profile
75
+ nest-cli g service user-profile
39
76
  ```
40
77
 
41
78
  This will create:
package/package.json CHANGED
@@ -1,23 +1,25 @@
1
1
  {
2
2
  "name": "@nest-extended/cli",
3
- "version": "0.0.1",
3
+ "version": "0.0.2-beta-1",
4
4
  "private": false,
5
5
  "main": "./src/index.js",
6
6
  "types": "./src/index.d.ts",
7
7
  "bin": {
8
- "nestx-cli": "./src/index.js"
8
+ "nest-cli": "./src/index.js"
9
9
  },
10
10
  "dependencies": {
11
- "tslib": "^2.3.0",
12
- "commander": "^11.0.0",
11
+ "@nestjs/cli": "^11.0.16",
13
12
  "chalk": "^4.1.2",
13
+ "commander": "^11.0.0",
14
+ "fs-extra": "^11.1.1",
14
15
  "inquirer": "^8.2.5",
15
- "fs-extra": "^11.1.1"
16
+ "tslib": "^2.3.0"
16
17
  },
17
18
  "devDependencies": {
18
- "@types/node": "^18.16.9",
19
+ "@types/fs-extra": "^11.0.1",
20
+ "@types/glob": "^9.0.0",
19
21
  "@types/inquirer": "^9.0.3",
20
- "@types/fs-extra": "^11.0.1"
22
+ "@types/node": "^18.16.9"
21
23
  },
22
24
  "type": "commonjs"
23
25
  }
@@ -3,6 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateCommand = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const commander_1 = require("commander");
6
+ const inquirer = require("inquirer");
7
+ const chalk = require("chalk");
8
+ const path = require("path");
9
+ const fs = require("fs-extra");
10
+ const child_process_1 = require("child_process");
6
11
  const create_file_1 = require("../lib/create-file");
7
12
  const update_app_module_1 = require("../lib/update-app-module");
8
13
  const module_template_1 = require("../templates/module.template");
@@ -12,6 +17,8 @@ const dto_template_1 = require("../templates/dto.template");
12
17
  const schema_template_1 = require("../templates/schema.template");
13
18
  const service_spec_template_1 = require("../templates/service.spec.template");
14
19
  const controller_spec_template_1 = require("../templates/controller.spec.template");
20
+ const auth_template_1 = require("../templates/auth.template");
21
+ const users_template_1 = require("../templates/users.template");
15
22
  exports.generateCommand = new commander_1.Command('generate')
16
23
  .alias('g')
17
24
  .description('Generate a new element');
@@ -36,4 +43,140 @@ exports.generateCommand
36
43
  (0, create_file_1.createFileWithContent)(`src/services/${name}/${name}.controller.spec.ts`, (0, controller_spec_template_1.getControllerSpec)(Name, name));
37
44
  yield (0, update_app_module_1.updateAppModule)(Name, name);
38
45
  }));
46
+ exports.generateCommand
47
+ .command('app <name>')
48
+ .description('Generate a new application')
49
+ .action((appName) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
50
+ const questions = [
51
+ {
52
+ type: 'list',
53
+ name: 'database',
54
+ message: 'Which database would you like to use?',
55
+ choices: ['mongo', 'sql'],
56
+ },
57
+ ];
58
+ // @ts-ignore
59
+ const answers = yield inquirer.prompt(questions);
60
+ const database = answers['database'];
61
+ if (database === 'sql') {
62
+ console.error(chalk.red('Error: We are not supporting sql now'));
63
+ process.exit(1);
64
+ }
65
+ console.log(chalk.blue(`Generating NestJS app: ${appName}`));
66
+ // 1. Run nest new
67
+ yield new Promise((resolve, reject) => {
68
+ const child = (0, child_process_1.spawn)('npx', ['@nestjs/cli', 'new', appName, '--package-manager', 'npm'], {
69
+ stdio: 'inherit',
70
+ shell: true,
71
+ });
72
+ child.on('close', (code) => {
73
+ if (code === 0)
74
+ resolve();
75
+ else
76
+ reject(new Error(`nest new failed with code ${code}`));
77
+ });
78
+ });
79
+ const appDir = path.join(process.cwd(), appName);
80
+ console.log(chalk.blue('Installing additional dependencies...'));
81
+ // 2. Install dependencies
82
+ yield new Promise((resolve, reject) => {
83
+ const child = (0, child_process_1.spawn)('npm', [
84
+ 'install',
85
+ '@nestjs/mongoose',
86
+ 'mongoose',
87
+ '@nestjs/config',
88
+ 'nestjs-cls',
89
+ '@nestjs/jwt',
90
+ 'bcrypt',
91
+ '@nest-extended/core',
92
+ '@nest-extended/mongoose',
93
+ '@nest-extended/decorators',
94
+ 'zod'
95
+ ], {
96
+ stdio: 'inherit',
97
+ cwd: appDir,
98
+ shell: true,
99
+ });
100
+ child.on('close', (code) => {
101
+ if (code === 0)
102
+ resolve();
103
+ else
104
+ reject(new Error(`npm install failed with code ${code}`));
105
+ });
106
+ });
107
+ // 3. Install Dev dependencies
108
+ yield new Promise((resolve, reject) => {
109
+ const child = (0, child_process_1.spawn)('npm', ['install', '-D', '@types/bcrypt'], {
110
+ stdio: 'inherit',
111
+ cwd: appDir,
112
+ shell: true,
113
+ });
114
+ child.on('close', (code) => {
115
+ if (code === 0)
116
+ resolve();
117
+ else
118
+ reject(new Error(`npm install -D failed with code ${code}`));
119
+ });
120
+ });
121
+ console.log(chalk.blue('Configuring project...'));
122
+ // 4. Update app.module.ts
123
+ const appModulePath = path.join(appDir, 'src/app.module.ts');
124
+ let appModuleContent = fs.readFileSync(appModulePath, 'utf8');
125
+ const importsToAdd = `
126
+ import { ConfigModule } from '@nestjs/config';
127
+ import { ClsModule } from 'nestjs-cls';
128
+ import { NestExtendedModule } from '@nest-extended/core';
129
+ import { MongooseModule } from '@nestjs/mongoose';
130
+ import { AuthModule } from './services/auth/auth.module';
131
+ import { UsersModule } from './services/users/users.module';
132
+ `;
133
+ appModuleContent = importsToAdd + appModuleContent;
134
+ const nestImports = `
135
+ ConfigModule.forRoot({
136
+ envFilePath: ['.env'],
137
+ isGlobal: true,
138
+ }),
139
+ ClsModule.forRoot({
140
+ global: true,
141
+ middleware: { mount: true },
142
+ }),
143
+ NestExtendedModule.forRoot({
144
+ softDelete: {
145
+ getQuery: () => ({ deleted: { $ne: true } }),
146
+ getData: (user: any) => ({
147
+ deleted: true,
148
+ deletedBy: user?._id,
149
+ deletedAt: new Date(),
150
+ }),
151
+ },
152
+ }),
153
+ MongooseModule.forRoot(process.env.MONGODB_URI || 'mongodb://localhost:27017/test'),
154
+ AuthModule,
155
+ UsersModule,`;
156
+ appModuleContent = appModuleContent.replace(/imports:\s*\[/, `imports: [\n${nestImports}`);
157
+ fs.writeFileSync(appModulePath, appModuleContent);
158
+ // 5. Generate Users Service
159
+ const usersDir = path.join(appDir, 'src/services/users');
160
+ const schemasDir = path.join(appDir, 'src/schemas');
161
+ fs.ensureDirSync(usersDir);
162
+ fs.ensureDirSync(schemasDir);
163
+ fs.writeFileSync(path.join(schemasDir, 'users.schema.ts'), (0, users_template_1.getUsersSchema)());
164
+ fs.writeFileSync(path.join(usersDir, 'users.module.ts'), (0, module_template_1.getModule)('Users', 'users'));
165
+ fs.writeFileSync(path.join(usersDir, 'users.service.ts'), (0, users_template_1.getUsersService)());
166
+ fs.writeFileSync(path.join(usersDir, 'users.controller.ts'), (0, controller_template_1.getController)('Users', 'users', 'users'));
167
+ fs.ensureDirSync(path.join(usersDir, 'dto'));
168
+ fs.writeFileSync(path.join(usersDir, 'dto/users.dto.ts'), (0, dto_template_1.getDto)('Users'));
169
+ // 6. Generate Auth Service
170
+ const authDir = path.join(appDir, 'src/services/auth');
171
+ fs.ensureDirSync(authDir);
172
+ fs.ensureDirSync(path.join(authDir, 'constants'));
173
+ fs.ensureDirSync(path.join(authDir, 'decorators'));
174
+ fs.writeFileSync(path.join(authDir, 'auth.module.ts'), (0, auth_template_1.getAuthModule)());
175
+ fs.writeFileSync(path.join(authDir, 'auth.service.ts'), (0, auth_template_1.getAuthService)());
176
+ fs.writeFileSync(path.join(authDir, 'auth.controller.ts'), (0, auth_template_1.getAuthController)());
177
+ fs.writeFileSync(path.join(authDir, 'auth.guard.ts'), (0, auth_template_1.getAuthGuard)());
178
+ fs.writeFileSync(path.join(authDir, 'constants/jwt-constants.ts'), (0, auth_template_1.getJwtConstants)());
179
+ fs.writeFileSync(path.join(authDir, 'decorators/public.decorator.ts'), (0, auth_template_1.getPublicDecorator)());
180
+ console.log(chalk.green('App generated successfully!'));
181
+ }));
39
182
  //# sourceMappingURL=generate.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../../../packages/cli/src/commands/generate.ts"],"names":[],"mappings":";;;;AACA,yCAAoC;AACpC,oDAA2D;AAC3D,gEAA2D;AAC3D,kEAAyD;AACzD,oEAA2D;AAC3D,0EAAiE;AACjE,4DAAmD;AACnD,kEAAyD;AACzD,8EAAoE;AACpE,oFAA0E;AAE7D,QAAA,eAAe,GAAG,IAAI,mBAAO,CAAC,UAAU,CAAC;KACjD,KAAK,CAAC,GAAG,CAAC;KACV,WAAW,CAAC,wBAAwB,CAAC,CAAC;AAE3C,uBAAe;KACV,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,wBAAwB,CAAC;KACrC,MAAM,CAAC,CAAO,OAAe,EAAE,EAAE;IAC9B,qEAAqE;IACrE,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;QAC5B,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACxE,CAAC,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY;IAEhE,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,KAAK,IAAI,GAAG,CAAC,CAAC;IAEzD,IAAA,mCAAqB,EAAC,eAAe,IAAI,YAAY,EAAE,IAAA,2BAAS,EAAC,IAAI,CAAC,CAAC,CAAC;IACxE,IAAA,mCAAqB,EAAC,gBAAgB,IAAI,IAAI,IAAI,YAAY,EAAE,IAAA,2BAAS,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IACvF,IAAA,mCAAqB,EAAC,gBAAgB,IAAI,IAAI,IAAI,aAAa,EAAE,IAAA,6BAAU,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IACzF,IAAA,mCAAqB,EACjB,gBAAgB,IAAI,IAAI,IAAI,gBAAgB,EAC5C,IAAA,mCAAa,EAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CACrC,CAAC;IACF,IAAA,mCAAqB,EAAC,gBAAgB,IAAI,QAAQ,IAAI,SAAS,EAAE,IAAA,qBAAM,EAAC,IAAI,CAAC,CAAC,CAAC;IAC/E,IAAA,mCAAqB,EACjB,gBAAgB,IAAI,IAAI,IAAI,kBAAkB,EAC9C,IAAA,sCAAc,EAAC,IAAI,EAAE,IAAI,CAAC,CAC7B,CAAC;IACF,IAAA,mCAAqB,EACjB,gBAAgB,IAAI,IAAI,IAAI,qBAAqB,EACjD,IAAA,4CAAiB,EAAC,IAAI,EAAE,IAAI,CAAC,CAChC,CAAC;IAEF,MAAM,IAAA,mCAAe,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACtC,CAAC,CAAA,CAAC,CAAC"}
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../../../packages/cli/src/commands/generate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const migrationCommand: Command;
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.migrationCommand = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const commander_1 = require("commander");
6
+ const fs = require("fs-extra");
7
+ const path = require("path");
8
+ const glob_1 = require("glob");
9
+ exports.migrationCommand = new commander_1.Command('migration')
10
+ .alias('m')
11
+ .description('Migrate project to newer version');
12
+ exports.migrationCommand
13
+ .command('run')
14
+ .description('Run migration scripts')
15
+ .action(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
16
+ console.log('Running migration...');
17
+ const files = yield (0, glob_1.glob)('src/**/*.ts', { ignore: ['node_modules/**'] });
18
+ let updateCount = 0;
19
+ for (const file of files) {
20
+ const filePath = path.resolve(file);
21
+ let content = yield fs.readFile(filePath, 'utf-8');
22
+ let hasChanges = false;
23
+ // Check for imports from @nest-extended/core
24
+ if (content.includes('@nest-extended/core')) {
25
+ // Regex to find named imports from @nest-extended/core
26
+ const importRegex = /import\s+{([^}]+)}\s+from\s+['"]@nest-extended\/core['"];?/g;
27
+ content = content.replace(importRegex, (match, imports) => {
28
+ const importedItems = imports.split(',').map((item) => item.trim());
29
+ const decoratorsToMove = ['ModifyBody', 'User', 'Public', 'setCreatedBy'];
30
+ const movedItems = importedItems.filter((item) => decoratorsToMove.includes(item));
31
+ const remainingItems = importedItems.filter((item) => !decoratorsToMove.includes(item));
32
+ if (movedItems.length > 0) {
33
+ hasChanges = true;
34
+ const parts = [];
35
+ if (remainingItems.length > 0) {
36
+ parts.push(`import { ${remainingItems.join(', ')} } from '@nest-extended/core';`);
37
+ }
38
+ parts.push(`import { ${movedItems.join(', ')} } from '@nest-extended/decorators';`);
39
+ return parts.join('\n');
40
+ }
41
+ return match;
42
+ });
43
+ }
44
+ if (hasChanges) {
45
+ yield fs.writeFile(filePath, content, 'utf-8');
46
+ console.log(`Updated ${file}`);
47
+ updateCount++;
48
+ }
49
+ }
50
+ console.log(`Migration completed. Updated ${updateCount} files.`);
51
+ }));
52
+ //# sourceMappingURL=migration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration.js","sourceRoot":"","sources":["../../../../../packages/cli/src/commands/migration.ts"],"names":[],"mappings":";;;;AAAA,yCAAoC;AACpC,+BAA+B;AAC/B,6BAA6B;AAC7B,+BAA4B;AAEf,QAAA,gBAAgB,GAAG,IAAI,mBAAO,CAAC,WAAW,CAAC;KACnD,KAAK,CAAC,GAAG,CAAC;KACV,WAAW,CAAC,kCAAkC,CAAC,CAAC;AAErD,wBAAgB;KACX,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,uBAAuB,CAAC;KACpC,MAAM,CAAC,GAAS,EAAE;IACf,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,MAAM,IAAA,WAAI,EAAC,aAAa,EAAE,EAAE,MAAM,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;IAEzE,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,UAAU,GAAG,KAAK,CAAC;QAEvB,6CAA6C;QAC7C,IAAI,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC;YAC1C,uDAAuD;YACvD,MAAM,WAAW,GAAG,6DAA6D,CAAC;YAElF,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,KAAa,EAAE,OAAe,EAAE,EAAE;gBACtE,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAE5E,MAAM,gBAAgB,GAAG,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,CAAC,CAAC;gBAC1E,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC3F,MAAM,cAAc,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;gBAEhG,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,UAAU,GAAG,IAAI,CAAC;oBAClB,MAAM,KAAK,GAAG,EAAE,CAAC;oBAEjB,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC5B,KAAK,CAAC,IAAI,CAAC,YAAY,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;oBACtF,CAAC;oBAED,KAAK,CAAC,IAAI,CAAC,YAAY,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;oBAEpF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC5B,CAAC;gBAED,OAAO,KAAK,CAAC;YACjB,CAAC,CAAC,CAAC;QACP,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YACb,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC;YAC/B,WAAW,EAAE,CAAC;QAClB,CAAC;IACL,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,gCAAgC,WAAW,SAAS,CAAC,CAAC;AACtE,CAAC,CAAA,CAAC,CAAC"}
package/src/index.js CHANGED
@@ -3,11 +3,46 @@
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  const commander_1 = require("commander");
5
5
  const generate_1 = require("./commands/generate");
6
+ const migration_1 = require("./commands/migration");
6
7
  const program = new commander_1.Command();
8
+ const chalk = require("chalk");
7
9
  program
8
- .name('nestx-cli')
10
+ .name('nest-cli')
9
11
  .description('CLI for @nest-extended packages')
10
12
  .version('0.0.1');
11
13
  program.addCommand(generate_1.generateCommand);
14
+ program.addCommand(migration_1.migrationCommand);
15
+ program.command('help')
16
+ .description('display comprehensive help for all commands')
17
+ .action(() => {
18
+ console.log('');
19
+ console.log(chalk.bold.cyan('🪹 NestExtended CLI'));
20
+ console.log(chalk.gray(' A powerful command-line interface for the NestExtended ecosystem.'));
21
+ console.log('');
22
+ console.log(`${chalk.bold('USAGE')}`);
23
+ console.log(` $ ${chalk.green('nest-cli')} ${chalk.yellow('[command]')} ${chalk.cyan('[options]')}`);
24
+ console.log('');
25
+ console.log(`${chalk.bold('COMMANDS')}`);
26
+ program.commands.forEach((cmd) => {
27
+ if (cmd.name() === 'help')
28
+ return;
29
+ const aliases = cmd.alias() ? ` | ${cmd.alias()}` : '';
30
+ console.log(` ${chalk.green.bold(cmd.name())}${chalk.gray(aliases)}`);
31
+ console.log(` ${chalk.white(cmd.description())}`);
32
+ if (cmd.commands && cmd.commands.length > 0) {
33
+ console.log('');
34
+ cmd.commands.forEach((sub) => {
35
+ const args = sub.registeredArguments.map(arg => arg.required ? `<${arg.name()}>` : `[${arg.name()}]`).join(' ');
36
+ console.log(` ${chalk.cyan('nest-cli')} ${chalk.cyan(cmd.name())} ${chalk.green(sub.name())} ${chalk.yellow(args)}`);
37
+ console.log(` ${chalk.gray('└─')} ${sub.description()}`);
38
+ });
39
+ }
40
+ console.log(''); // spacer
41
+ });
42
+ console.log(`${chalk.bold('OPTIONS')}`);
43
+ console.log(` ${chalk.cyan('-V, --version')} Output the version number`);
44
+ console.log(` ${chalk.cyan('-h, --help')} Display help for command`);
45
+ console.log('');
46
+ });
12
47
  program.parse(process.argv);
13
48
  //# sourceMappingURL=index.js.map
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/cli/src/index.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,kDAAsD;AAEtD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACF,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,iCAAiC,CAAC;KAC9C,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,OAAO,CAAC,UAAU,CAAC,0BAAe,CAAC,CAAC;AAEpC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/cli/src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare const getAuthController: () => string;
2
+ export declare const getAuthService: () => string;
3
+ export declare const getAuthModule: () => string;
4
+ export declare const getAuthGuard: () => string;
5
+ export declare const getPublicDecorator: () => string;
6
+ export declare const getJwtConstants: () => string;
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getJwtConstants = exports.getPublicDecorator = exports.getAuthGuard = exports.getAuthModule = exports.getAuthService = exports.getAuthController = void 0;
4
+ const getAuthController = () => `import {
5
+ Body,
6
+ Controller,
7
+ Post,
8
+ HttpCode,
9
+ HttpStatus,
10
+ Get,
11
+ Request,
12
+ BadRequestException,
13
+ } from '@nestjs/common';
14
+ import { AuthService } from './auth.service';
15
+ import { Public } from './decorators/public.decorator';
16
+ import { UsersService } from '../users/users.service';
17
+
18
+ @Controller('authentication')
19
+ export class AuthController {
20
+ constructor(
21
+ private authService: AuthService,
22
+ private usersService: UsersService,
23
+ ) {}
24
+
25
+ @Public()
26
+ @HttpCode(HttpStatus.OK)
27
+ @Post('')
28
+ signIn(@Body() signInDto: Record<string, any>) {
29
+ if (signInDto.strategy === 'local') {
30
+ return this.authService.signInLocal(signInDto.email, signInDto.password);
31
+ }
32
+ throw new BadRequestException('Invalid Strategy');
33
+ }
34
+
35
+ @Get('verify')
36
+ getProfile(@Request() req: any) {
37
+ return {
38
+ user: this.usersService.sanitizeUser(req.user),
39
+ organizationUsers: req.orgUsers,
40
+ };
41
+ }
42
+ }
43
+ `;
44
+ exports.getAuthController = getAuthController;
45
+ const getAuthService = () => `import { Injectable, UnauthorizedException } from '@nestjs/common';
46
+ import { JwtService } from '@nestjs/jwt';
47
+ import * as bcrypt from 'bcrypt';
48
+ import { UsersService } from '../users/users.service';
49
+
50
+ @Injectable()
51
+ export class AuthService {
52
+ constructor(
53
+ private usersService: UsersService,
54
+ private jwtService: JwtService,
55
+ ) { }
56
+
57
+ async signInLocal(email: string, pass: string): Promise<any> {
58
+ const [user] = await this.usersService._find({
59
+ email,
60
+ $limit: 1,
61
+ $select: [
62
+ '_id',
63
+ 'firstName',
64
+ 'lastName',
65
+ 'email',
66
+ 'password',
67
+ 'createdAt',
68
+ 'updatedAt',
69
+ ],
70
+ }, { pagination: false });
71
+
72
+ if (!user) throw new UnauthorizedException();
73
+
74
+ const passwordValid = await bcrypt.compare(pass, user.password);
75
+ if (!passwordValid) {
76
+ throw new UnauthorizedException();
77
+ }
78
+
79
+ const sanitizedUser = this.usersService.sanitizeUser(user);
80
+ const payload = { sub: { id: user._id }, user };
81
+ return {
82
+ accessToken: await this.jwtService.signAsync(payload),
83
+ user: sanitizedUser,
84
+ };
85
+ }
86
+ }
87
+ `;
88
+ exports.getAuthService = getAuthService;
89
+ const getAuthModule = () => `import { Module } from '@nestjs/common';
90
+ import { AuthService } from './auth.service';
91
+ import { JwtModule } from '@nestjs/jwt';
92
+ import { AuthController } from './auth.controller';
93
+ import { APP_GUARD } from '@nestjs/core';
94
+ import { AuthGuard } from './auth.guard';
95
+ import { UsersModule } from '../users/users.module';
96
+ import { jwtConstants } from './constants/jwt-constants';
97
+
98
+ @Module({
99
+ imports: [
100
+ UsersModule,
101
+ JwtModule.register({
102
+ global: true,
103
+ secret: jwtConstants.secret,
104
+ signOptions: { expiresIn: '365d' },
105
+ }),
106
+ ],
107
+ providers: [
108
+ AuthService,
109
+ {
110
+ provide: APP_GUARD,
111
+ useClass: AuthGuard,
112
+ },
113
+ ],
114
+ controllers: [AuthController],
115
+ exports: [AuthService],
116
+ })
117
+ export class AuthModule {}
118
+ `;
119
+ exports.getAuthModule = getAuthModule;
120
+ const getAuthGuard = () => `import {
121
+ CanActivate,
122
+ ExecutionContext,
123
+ Injectable,
124
+ UnauthorizedException,
125
+ } from '@nestjs/common';
126
+ import { Reflector } from '@nestjs/core';
127
+ import { JwtService } from '@nestjs/jwt';
128
+ import { Request } from 'express';
129
+ import { IS_PUBLIC_KEY } from './decorators/public.decorator';
130
+ import { UsersService } from '../users/users.service';
131
+ import { jwtConstants } from './constants/jwt-constants';
132
+ import { ClsService } from 'nestjs-cls';
133
+
134
+ @Injectable()
135
+ export class AuthGuard implements CanActivate {
136
+ constructor(
137
+ private usersService: UsersService,
138
+ private jwtService: JwtService,
139
+ private reflector: Reflector,
140
+ private cls: ClsService,
141
+ ) {}
142
+
143
+ async canActivate(context: ExecutionContext): Promise<boolean> {
144
+ const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
145
+ context.getHandler(),
146
+ context.getClass(),
147
+ ]);
148
+ if (isPublic) {
149
+ return true;
150
+ }
151
+ const request = context.switchToHttp().getRequest();
152
+ const token = this.extractTokenFromHeader(request as Request);
153
+ if (!token) {
154
+ throw new UnauthorizedException();
155
+ }
156
+ try {
157
+ const payload = await this.jwtService.verifyAsync(token, {
158
+ secret: jwtConstants.secret,
159
+ });
160
+ const user = await this.usersService._get(payload.sub.id);
161
+ if (user) {
162
+ request['user'] = user;
163
+ this.cls.set('user', user);
164
+ return true;
165
+ }
166
+ } catch {
167
+ throw new UnauthorizedException();
168
+ }
169
+ throw new UnauthorizedException();
170
+ }
171
+
172
+ private extractTokenFromHeader(request: Request): string | undefined {
173
+ const [type, token] = request.headers.authorization?.split(' ') ?? [];
174
+ return type === 'Bearer' ? token : undefined;
175
+ }
176
+ }
177
+ `;
178
+ exports.getAuthGuard = getAuthGuard;
179
+ const getPublicDecorator = () => `import { SetMetadata } from '@nestjs/common';
180
+ export const IS_PUBLIC_KEY = 'isPublic';
181
+ export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
182
+ `;
183
+ exports.getPublicDecorator = getPublicDecorator;
184
+ const getJwtConstants = () => `import { randomBytes } from 'crypto';
185
+ // NOTE: For a real application, consider using a more secure way to inject the secret (like ConfigService)
186
+ export const jwtConstants = {
187
+ secret: process.env.JWT_SECRET || randomBytes(32).toString('hex'),
188
+ };
189
+ `;
190
+ exports.getJwtConstants = getJwtConstants;
191
+ //# sourceMappingURL=auth.template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.template.js","sourceRoot":"","sources":["../../../../../packages/cli/src/templates/auth.template.ts"],"names":[],"mappings":";;;AAAO,MAAM,iBAAiB,GAAG,GAAW,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuC9C,CAAC;AAvCW,QAAA,iBAAiB,qBAuC5B;AAEK,MAAM,cAAc,GAAG,GAAW,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0C3C,CAAC;AA1CW,QAAA,cAAc,kBA0CzB;AAEK,MAAM,aAAa,GAAG,GAAW,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B1C,CAAC;AA7BW,QAAA,aAAa,iBA6BxB;AAEK,MAAM,YAAY,GAAG,GAAW,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyDzC,CAAC;AAzDW,QAAA,YAAY,gBAyDvB;AAEK,MAAM,kBAAkB,GAAG,GAAW,EAAE,CAAC;;;CAG/C,CAAC;AAHW,QAAA,kBAAkB,sBAG7B;AAEK,MAAM,eAAe,GAAG,GAAW,EAAE,CAAC;;;;;CAK5C,CAAC;AALW,QAAA,eAAe,mBAK1B"}
@@ -12,9 +12,8 @@ const getController = (Name, name, url) => `import {
12
12
  Query,
13
13
  } from '@nestjs/common';
14
14
  import { ${Name}Service } from './${name}.service';
15
- import { User } from '@nest-extended/core';
15
+ import { User, ModifyBody, setCreatedBy } from '@nest-extended/decorators';
16
16
  import { ${Name} } from 'src/schemas/${name}.schema';
17
- import { ModifyBody, setCreatedBy } from '@nest-extended/core';
18
17
 
19
18
  @Controller('${url}')
20
19
  export class ${Name}Controller {
@@ -1 +1 @@
1
- {"version":3,"file":"controller.template.js","sourceRoot":"","sources":["../../../../../packages/cli/src/templates/controller.template.ts"],"names":[],"mappings":";;;AACO,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,IAAY,EAAE,GAAW,EAAU,EAAE,CAAC;;;;;;;;;;WAUvE,IAAI,qBAAqB,IAAI;;WAE7B,IAAI,wBAAwB,IAAI;;;eAG5B,GAAG;eACH,IAAI;iCACc,IAAI,YAAY,IAAI;;;;wBAI7B,IAAI;;;;;wBAKJ,IAAI;;;;;wCAKY,IAAI,QAAQ,IAAI;;wBAEhC,IAAI,yBAAyB,IAAI;;;;;;mBAMtC,IAAI,gBAAgB,IAAI;;;wBAGnB,IAAI,2BAA2B,IAAI;;;;;wBAKnC,IAAI;;;CAG3B,CAAC;AAlDW,QAAA,aAAa,iBAkDxB"}
1
+ {"version":3,"file":"controller.template.js","sourceRoot":"","sources":["../../../../../packages/cli/src/templates/controller.template.ts"],"names":[],"mappings":";;;AACO,MAAM,aAAa,GAAG,CAAC,IAAY,EAAE,IAAY,EAAE,GAAW,EAAU,EAAE,CAAC;;;;;;;;;;WAUvE,IAAI,qBAAqB,IAAI;;WAE7B,IAAI,wBAAwB,IAAI;;eAE5B,GAAG;eACH,IAAI;iCACc,IAAI,YAAY,IAAI;;;;wBAI7B,IAAI;;;;;wBAKJ,IAAI;;;;;wCAKY,IAAI,QAAQ,IAAI;;wBAEhC,IAAI,yBAAyB,IAAI;;;;;;mBAMtC,IAAI,gBAAgB,IAAI;;;wBAGnB,IAAI,2BAA2B,IAAI;;;;;wBAKnC,IAAI;;;CAG3B,CAAC;AAjDW,QAAA,aAAa,iBAiDxB"}
@@ -4,7 +4,7 @@ exports.getSchema = void 0;
4
4
  const getSchema = (Name, UserEntity = 'Users') => `import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
5
5
  import { HydratedDocument, Types } from 'mongoose';
6
6
  import { ${UserEntity} } from './users.schema';
7
- import EnsureObjectId from '@nest-extended/core/common/ensureObjectId';
7
+ import { EnsureObjectId } from '@nest-extended/mongoose';
8
8
 
9
9
  export type ${Name}Document = HydratedDocument<${Name}>;
10
10
 
@@ -0,0 +1,2 @@
1
+ export declare const getUsersSchema: () => string;
2
+ export declare const getUsersService: () => string;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getUsersService = exports.getUsersSchema = void 0;
4
+ const getUsersSchema = () => `import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
5
+ import { HydratedDocument, Types } from 'mongoose';
6
+
7
+ export type UsersDocument = HydratedDocument<Users>;
8
+
9
+ @Schema({
10
+ timestamps: true,
11
+ })
12
+ export class Users {
13
+ _id: Types.ObjectId;
14
+
15
+ @Prop({ type: String, trim: true, required: true })
16
+ firstName: string;
17
+
18
+ @Prop({ type: String, trim: true, required: true })
19
+ lastName: string;
20
+
21
+ @Prop({ type: String, trim: true, unique: true, required: true })
22
+ email: string;
23
+
24
+ @Prop({ type: String, required: true, select: false })
25
+ password: string;
26
+
27
+ @Prop({ type: String, trim: true, required: false })
28
+ phone?: string;
29
+
30
+ @Prop({ type: Number, enum: [1, 2, 3], default: 1 })
31
+ role: number;
32
+ }
33
+
34
+ export const UsersSchema = SchemaFactory.createForClass(Users);
35
+ `;
36
+ exports.getUsersSchema = getUsersSchema;
37
+ const getUsersService = () => `import { Model } from 'mongoose';
38
+ import { Injectable } from '@nestjs/common';
39
+ import { InjectModel } from '@nestjs/mongoose';
40
+ import { NestService } from '@nest-extended/mongoose';
41
+ import { Users, UsersDocument } from 'src/schemas/users.schema';
42
+
43
+ @Injectable()
44
+ export class UsersService extends NestService<Users, UsersDocument> {
45
+ constructor(
46
+ @InjectModel(Users.name) private readonly usersModel: Model<UsersDocument>,
47
+ ) {
48
+ super(usersModel);
49
+ }
50
+
51
+ sanitizeUser(user: Users) {
52
+ // @ts-expect-error can be error
53
+ const sanitized = user.toObject ? user.toObject() : { ...user };
54
+ delete sanitized['password'];
55
+ return sanitized;
56
+ }
57
+ }
58
+ `;
59
+ exports.getUsersService = getUsersService;
60
+ //# sourceMappingURL=users.template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.template.js","sourceRoot":"","sources":["../../../../../packages/cli/src/templates/users.template.ts"],"names":[],"mappings":";;;AAAO,MAAM,cAAc,GAAG,GAAW,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+B3C,CAAC;AA/BW,QAAA,cAAc,kBA+BzB;AAEK,MAAM,eAAe,GAAG,GAAW,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;CAqB5C,CAAC;AArBW,QAAA,eAAe,mBAqB1B"}