@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 +41 -4
- package/package.json +9 -7
- package/src/commands/generate.js +143 -0
- package/src/commands/generate.js.map +1 -1
- package/src/commands/migration.d.ts +2 -0
- package/src/commands/migration.js +52 -0
- package/src/commands/migration.js.map +1 -0
- package/src/index.js +36 -1
- package/src/index.js.map +1 -1
- package/src/templates/auth.template.d.ts +6 -0
- package/src/templates/auth.template.js +191 -0
- package/src/templates/auth.template.js.map +1 -0
- package/src/templates/controller.template.js +1 -2
- package/src/templates/controller.template.js.map +1 -1
- package/src/templates/schema.template.js +1 -1
- package/src/templates/users.template.d.ts +2 -0
- package/src/templates/users.template.js +60 -0
- package/src/templates/users.template.js.map +1 -0
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
|
-
|
|
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
|
-
|
|
67
|
+
nest-cli g service <name>
|
|
31
68
|
# or
|
|
32
|
-
|
|
69
|
+
nest-cli generate service <name>
|
|
33
70
|
```
|
|
34
71
|
|
|
35
72
|
**Example:**
|
|
36
73
|
|
|
37
74
|
```bash
|
|
38
|
-
|
|
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
|
-
"
|
|
8
|
+
"nest-cli": "./src/index.js"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"
|
|
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
|
-
"
|
|
16
|
+
"tslib": "^2.3.0"
|
|
16
17
|
},
|
|
17
18
|
"devDependencies": {
|
|
18
|
-
"@types/
|
|
19
|
+
"@types/fs-extra": "^11.0.1",
|
|
20
|
+
"@types/glob": "^9.0.0",
|
|
19
21
|
"@types/inquirer": "^9.0.3",
|
|
20
|
-
"@types/
|
|
22
|
+
"@types/node": "^18.16.9"
|
|
21
23
|
},
|
|
22
24
|
"type": "commonjs"
|
|
23
25
|
}
|
package/src/commands/generate.js
CHANGED
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../../../packages/cli/src/commands/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -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('
|
|
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;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/cli/src/index.ts"],"names":[],"mappings":";;;AACA,yCAAoC;AACpC,kDAAsD;AACtD,oDAAwD;AAExD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,+BAA+B;AAE/B,OAAO;KACF,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,iCAAiC,CAAC;KAC9C,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,OAAO,CAAC,UAAU,CAAC,0BAAe,CAAC,CAAC;AACpC,OAAO,CAAC,UAAU,CAAC,4BAAgB,CAAC,CAAC;AAErC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;KAClB,WAAW,CAAC,6CAA6C,CAAC;KAC1D,MAAM,CAAC,GAAG,EAAE;IACT,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC,CAAC;IAChG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IACtG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAEzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QAC7B,IAAI,GAAG,CAAC,IAAI,EAAE,KAAK,MAAM;YAAE,OAAO;QAElC,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC;QAEnD,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;gBACzB,MAAM,IAAI,GAAG,GAAG,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAChH,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACxH,OAAO,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAChE,CAAC,CAAC,CAAC;QACP,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS;IAC9B,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,+BAA+B,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,iCAAiC,CAAC,CAAC;IAC5E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC;AAEP,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
|
|
@@ -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/
|
|
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
|
|
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/
|
|
7
|
+
import { EnsureObjectId } from '@nest-extended/mongoose';
|
|
8
8
|
|
|
9
9
|
export type ${Name}Document = HydratedDocument<${Name}>;
|
|
10
10
|
|
|
@@ -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"}
|