nestcraftx 0.2.5 → 0.2.6
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/CLI_USAGE.fr.md +331 -331
- package/CLI_USAGE.md +364 -364
- package/LICENSE +21 -21
- package/bin/nestcraft.js +84 -64
- package/commands/demo.js +333 -330
- package/commands/generate.js +93 -0
- package/commands/generateConf.js +91 -0
- package/commands/info.js +48 -48
- package/commands/new.js +338 -335
- package/commands/start.js +19 -19
- package/commands/test.js +7 -7
- package/package.json +1 -1
- package/utils/cliParser.js +133 -76
- package/utils/colors.js +62 -62
- package/utils/configs/configureDocker.js +120 -120
- package/utils/configs/setupCleanArchitecture.js +15 -13
- package/utils/configs/setupLightArchitecture.js +15 -9
- package/utils/file-utils/saveProjectConfig.js +36 -0
- package/utils/fullModeInput.js +607 -607
- package/utils/generators/application/dtoUpdater.js +54 -0
- package/utils/generators/cleanModuleGenerator.js +475 -0
- package/utils/generators/database/setupDatabase.js +31 -0
- package/utils/generators/domain/entityUpdater.js +78 -0
- package/utils/generators/infrastructure/mapperUpdater.js +65 -0
- package/utils/generators/lightModuleGenerator.js +131 -0
- package/utils/generators/relation/relation.engine.js +64 -0
- package/utils/interactive/askEntityInputs.js +165 -0
- package/utils/loggers/logError.js +7 -7
- package/utils/loggers/logInfo.js +7 -7
- package/utils/loggers/logSuccess.js +7 -7
- package/utils/loggers/logWarning.js +7 -7
- package/utils/setups/orms/typeOrmSetup.js +630 -630
- package/utils/setups/setupAuth.js +28 -15
- package/utils/setups/setupDatabase.js +75 -75
- package/utils/setups/setupPrisma.js +802 -630
- package/utils/shell.js +32 -32
- package/utils/spinner.js +57 -57
- package/utils/systemCheck.js +124 -124
- package/utils/userInput.js +421 -421
- package/utils/utils.js +27 -27
|
@@ -6,7 +6,7 @@ const { generateDto } = require("../utils");
|
|
|
6
6
|
|
|
7
7
|
async function setupAuth(inputs) {
|
|
8
8
|
logInfo(
|
|
9
|
-
"🚀 Déploiement de l'architecture Auth Ultime (Mappers, DTOs, Multi-ORM)..."
|
|
9
|
+
"🚀 Déploiement de l'architecture Auth Ultime (Mappers, DTOs, Multi-ORM)...",
|
|
10
10
|
);
|
|
11
11
|
|
|
12
12
|
const { dbConfig, useSwagger, mode = "full" } = inputs;
|
|
@@ -15,11 +15,11 @@ async function setupAuth(inputs) {
|
|
|
15
15
|
// 1. INSTALLATION DES DÉPENDANCES
|
|
16
16
|
await runCommand(
|
|
17
17
|
`npm install @nestjs/jwt @nestjs/passport passport passport-jwt bcrypt uuid`,
|
|
18
|
-
"Erreur install deps auth"
|
|
18
|
+
"Erreur install deps auth",
|
|
19
19
|
);
|
|
20
20
|
await runCommand(
|
|
21
21
|
`npm install -D @types/passport-jwt @types/bcrypt @types/uuid`,
|
|
22
|
-
"Erreur install dev-deps auth"
|
|
22
|
+
"Erreur install dev-deps auth",
|
|
23
23
|
);
|
|
24
24
|
|
|
25
25
|
// 2. DÉFINITION DES CHEMINS (CLEAN ARCHITECTURE)
|
|
@@ -75,6 +75,8 @@ export class Session {
|
|
|
75
75
|
import { Session } from '${paths.entities}/session.entity';
|
|
76
76
|
import { CreateSessionPersistenceDto } from '${paths.appDtos}/create-session.dto';
|
|
77
77
|
|
|
78
|
+
export const ISessionRepositoryName = 'ISessionRepository';
|
|
79
|
+
|
|
78
80
|
export interface ISessionRepository {
|
|
79
81
|
save(dto: CreateSessionPersistenceDto): Promise<Session>;
|
|
80
82
|
findByToken(token: string): Promise<Session | null>;
|
|
@@ -137,9 +139,9 @@ export interface CreateSessionPersistenceDto {
|
|
|
137
139
|
// Définition dynamique des types et injections
|
|
138
140
|
const repoType = isFull ? "ISessionRepository" : "SessionRepository";
|
|
139
141
|
const repoImport = isFull
|
|
140
|
-
? `import { ISessionRepository } from '${paths.interfaces}/session.repository.interface';`
|
|
142
|
+
? `import { ISessionRepositoryName, type ISessionRepository } from '${paths.interfaces}/session.repository.interface';`
|
|
141
143
|
: `import { SessionRepository } from '${paths.persistence}/session.repository';`;
|
|
142
|
-
const injectDecorator = isFull ? `@Inject(
|
|
144
|
+
const injectDecorator = isFull ? `@Inject(ISessionRepositoryName) ` : "";
|
|
143
145
|
|
|
144
146
|
await createFile({
|
|
145
147
|
path: `${paths.services}/session.service.ts`,
|
|
@@ -247,11 +249,12 @@ import { SendOtpDto } from '${paths.appDtos}/sendOtp.dto';
|
|
|
247
249
|
import { VerifyOtpDto } from '${paths.appDtos}/verifyOtp.dto';
|
|
248
250
|
import { ForgotPasswordDto } from '${paths.appDtos}/forgotPassword.dto';
|
|
249
251
|
import { ResetPasswordDto } from '${paths.appDtos}/resetPassword.dto';
|
|
252
|
+
${enumImport}
|
|
250
253
|
${
|
|
251
254
|
mode === "light"
|
|
252
255
|
? `import { UserRepository } from '${userRepoPath}';
|
|
253
256
|
import { CreateUserDto } from '${userDtoPath}/user.dto';`
|
|
254
|
-
: `import { IUserRepository } from '${userRepoPath}';
|
|
257
|
+
: `import type { IUserRepository } from '${userRepoPath}';
|
|
255
258
|
import { CreateUserDto } from '${userDtoPath}/user.dto';`
|
|
256
259
|
}
|
|
257
260
|
|
|
@@ -329,27 +332,32 @@ export class AuthService {
|
|
|
329
332
|
async refreshToken(token: RefreshTokenDto) {
|
|
330
333
|
const session = await this.sessionService.validate(token.refreshToken);
|
|
331
334
|
if (!session) throw new UnauthorizedException('Session expired or invalid');
|
|
332
|
-
const payload
|
|
335
|
+
const payload: {
|
|
336
|
+
sub: string;
|
|
337
|
+
email: string;
|
|
338
|
+
sid: string;
|
|
339
|
+
role: Role;
|
|
340
|
+
} = this.jwtService.decode(token.refreshToken) as any;
|
|
333
341
|
return { accessToken: this.jwtService.sign({ sub: payload.sub, email: payload.email }, { expiresIn: '15m' }) };
|
|
334
342
|
}
|
|
335
343
|
|
|
336
344
|
// 📲 Send OTP
|
|
337
|
-
|
|
345
|
+
sendOtp(dto: SendOtpDto) {
|
|
338
346
|
const otp = Math.floor(100000 + Math.random() * 900000).toString();
|
|
339
347
|
this.otps.set(dto.email, otp);
|
|
340
348
|
console.log(\`[OTP] for \${dto.email} is \${otp}\`);
|
|
341
349
|
return { message: 'OTP sent' };
|
|
342
|
-
|
|
350
|
+
}
|
|
343
351
|
|
|
344
|
-
|
|
345
|
-
|
|
352
|
+
// Verify OTP
|
|
353
|
+
verifyOtp(dto: VerifyOtpDto) {
|
|
346
354
|
const valid = this.otps.get(dto.email);
|
|
347
355
|
if (valid === dto.otp) {
|
|
348
356
|
this.otps.delete(dto.email);
|
|
349
357
|
return { message: 'OTP verified' };
|
|
350
358
|
}
|
|
351
359
|
throw new UnauthorizedException('Invalid OTP');
|
|
352
|
-
|
|
360
|
+
}
|
|
353
361
|
|
|
354
362
|
// 📬 Forgot Password
|
|
355
363
|
async forgotPassword(dto: ForgotPasswordDto) {
|
|
@@ -413,7 +421,7 @@ export class SessionMapper {
|
|
|
413
421
|
|
|
414
422
|
// On prépare l'entête dynamiquement
|
|
415
423
|
const interfaceImport = isFull
|
|
416
|
-
? `import { ISessionRepository } from '${paths.interfaces}/session.repository.interface';`
|
|
424
|
+
? `import type { ISessionRepository } from '${paths.interfaces}/session.repository.interface';`
|
|
417
425
|
: "";
|
|
418
426
|
const implementsClause = isFull ? "implements ISessionRepository " : "";
|
|
419
427
|
|
|
@@ -796,6 +804,11 @@ import { Session, SessionSchema } from '${schemaRelativePath}';`;
|
|
|
796
804
|
dbProviders = "PrismaModule,";
|
|
797
805
|
}
|
|
798
806
|
|
|
807
|
+
if (inputs.mode == "full") {
|
|
808
|
+
dbImports =
|
|
809
|
+
+"import { ISessionRepositoryName } from '${paths.interfaces}/session.repository.interface';";
|
|
810
|
+
}
|
|
811
|
+
|
|
799
812
|
await createFile({
|
|
800
813
|
path: `${paths.root}/auth.module.ts`,
|
|
801
814
|
contente: `
|
|
@@ -832,7 +845,7 @@ import { SessionRepository } from '${paths.persistence}/session.repository';
|
|
|
832
845
|
JwtStrategy,
|
|
833
846
|
${
|
|
834
847
|
isFull
|
|
835
|
-
? "{ provide:
|
|
848
|
+
? "{ provide: ISessionRepositoryName, useClass: SessionRepository }"
|
|
836
849
|
: "SessionRepository"
|
|
837
850
|
}
|
|
838
851
|
|
|
@@ -953,7 +966,7 @@ export class AuthModule {}`.trim(),
|
|
|
953
966
|
});
|
|
954
967
|
|
|
955
968
|
logSuccess(
|
|
956
|
-
` Authentification Enterprise avec support ${dbConfig.orm.toUpperCase()} et Mappers terminée
|
|
969
|
+
` Authentification Enterprise avec support ${dbConfig.orm.toUpperCase()} et Mappers terminée !`,
|
|
957
970
|
);
|
|
958
971
|
}
|
|
959
972
|
|
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
const { logInfo } = require("../loggers/logInfo");
|
|
2
|
-
const { runCommand } = require("../shell");
|
|
3
|
-
const { setupTypeORM } = require("./orms/typeOrmSetup");
|
|
4
|
-
const { setupMongoose } = require("./setupMongoose");
|
|
5
|
-
const { setupPrisma } = require("./setupPrisma");
|
|
6
|
-
|
|
7
|
-
async function setupDatabase(inputs) {
|
|
8
|
-
logInfo("🚀 Configuring the database...");
|
|
9
|
-
|
|
10
|
-
await runCommand(
|
|
11
|
-
"npm install dotenv",
|
|
12
|
-
"Error installing dotenv automatically, please run it manually now"
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
switch (inputs.selectedDB) {
|
|
16
|
-
case "postgresql":
|
|
17
|
-
await setupPostgres(inputs); // PostgreSQL Configuration
|
|
18
|
-
break;
|
|
19
|
-
case "mysql":
|
|
20
|
-
await setupMySQL(inputs); // MySQL Configuration
|
|
21
|
-
break;
|
|
22
|
-
case "mongodb":
|
|
23
|
-
await setupMongoDB(inputs); // MongoDB Configuration
|
|
24
|
-
break;
|
|
25
|
-
case "sqlite":
|
|
26
|
-
await setupSQLite(inputs); // SQLite Configuration
|
|
27
|
-
break;
|
|
28
|
-
case "firebase":
|
|
29
|
-
await setupFirebase(inputs); // Firebase Configuration
|
|
30
|
-
break;
|
|
31
|
-
case "redis":
|
|
32
|
-
await setupRedis(inputs); // Redis Configuration
|
|
33
|
-
break;
|
|
34
|
-
default:
|
|
35
|
-
throw new Error("Unsupported database.");
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async function setupMongoDB(inputs) {
|
|
40
|
-
logInfo("Configuring MongoDB...");
|
|
41
|
-
await setupMongoose(inputs);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async function setupSQLite(inputs) {
|
|
45
|
-
logInfo("Configuring SQLite..."); // Calls a SQLite-specific script
|
|
46
|
-
await setupSQLiteConfig(inputs);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
async function setupMySQL(inputs) {
|
|
50
|
-
logInfo("Configuring MySQL..."); // Calls a MySQL-specific script
|
|
51
|
-
await setupMySQLConfig(inputs);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async function setupFirebase(inputs) {
|
|
55
|
-
logInfo("Configuring Firebase..."); // Calls a Firebase-specific script
|
|
56
|
-
await setupFirebaseConfig(inputs);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async function setupPostgres(inputs) {
|
|
60
|
-
// Checks which ORM was chosen and calls the corresponding function
|
|
61
|
-
if (inputs.dbConfig.orm === "prisma") {
|
|
62
|
-
await setupPrisma(inputs);
|
|
63
|
-
} else if (inputs.dbConfig.orm === "typeorm") {
|
|
64
|
-
await setupTypeORM(inputs);
|
|
65
|
-
} else {
|
|
66
|
-
throw new Error("Unsupported ORM: " + inputs.dbConfig.orm);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async function setupRedis(inputs) {
|
|
71
|
-
logInfo("Configuring Redis..."); // Calls a Redis-specific script
|
|
72
|
-
await setupRedisConfig(inputs);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
module.exports = { setupDatabase };
|
|
1
|
+
const { logInfo } = require("../loggers/logInfo");
|
|
2
|
+
const { runCommand } = require("../shell");
|
|
3
|
+
const { setupTypeORM } = require("./orms/typeOrmSetup");
|
|
4
|
+
const { setupMongoose } = require("./setupMongoose");
|
|
5
|
+
const { setupPrisma } = require("./setupPrisma");
|
|
6
|
+
|
|
7
|
+
async function setupDatabase(inputs) {
|
|
8
|
+
logInfo("🚀 Configuring the database...");
|
|
9
|
+
|
|
10
|
+
await runCommand(
|
|
11
|
+
"npm install dotenv",
|
|
12
|
+
"Error installing dotenv automatically, please run it manually now"
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
switch (inputs.selectedDB) {
|
|
16
|
+
case "postgresql":
|
|
17
|
+
await setupPostgres(inputs); // PostgreSQL Configuration
|
|
18
|
+
break;
|
|
19
|
+
case "mysql":
|
|
20
|
+
await setupMySQL(inputs); // MySQL Configuration
|
|
21
|
+
break;
|
|
22
|
+
case "mongodb":
|
|
23
|
+
await setupMongoDB(inputs); // MongoDB Configuration
|
|
24
|
+
break;
|
|
25
|
+
case "sqlite":
|
|
26
|
+
await setupSQLite(inputs); // SQLite Configuration
|
|
27
|
+
break;
|
|
28
|
+
case "firebase":
|
|
29
|
+
await setupFirebase(inputs); // Firebase Configuration
|
|
30
|
+
break;
|
|
31
|
+
case "redis":
|
|
32
|
+
await setupRedis(inputs); // Redis Configuration
|
|
33
|
+
break;
|
|
34
|
+
default:
|
|
35
|
+
throw new Error("Unsupported database.");
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function setupMongoDB(inputs) {
|
|
40
|
+
logInfo("Configuring MongoDB...");
|
|
41
|
+
await setupMongoose(inputs);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function setupSQLite(inputs) {
|
|
45
|
+
logInfo("Configuring SQLite..."); // Calls a SQLite-specific script
|
|
46
|
+
await setupSQLiteConfig(inputs);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function setupMySQL(inputs) {
|
|
50
|
+
logInfo("Configuring MySQL..."); // Calls a MySQL-specific script
|
|
51
|
+
await setupMySQLConfig(inputs);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function setupFirebase(inputs) {
|
|
55
|
+
logInfo("Configuring Firebase..."); // Calls a Firebase-specific script
|
|
56
|
+
await setupFirebaseConfig(inputs);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function setupPostgres(inputs) {
|
|
60
|
+
// Checks which ORM was chosen and calls the corresponding function
|
|
61
|
+
if (inputs.dbConfig.orm === "prisma") {
|
|
62
|
+
await setupPrisma(inputs);
|
|
63
|
+
} else if (inputs.dbConfig.orm === "typeorm") {
|
|
64
|
+
await setupTypeORM(inputs);
|
|
65
|
+
} else {
|
|
66
|
+
throw new Error("Unsupported ORM: " + inputs.dbConfig.orm);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function setupRedis(inputs) {
|
|
71
|
+
logInfo("Configuring Redis..."); // Calls a Redis-specific script
|
|
72
|
+
await setupRedisConfig(inputs);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
module.exports = { setupDatabase };
|