nestgen-cli 0.1.0 → 0.2.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/dist/engine/file-transaction.js +166 -0
- package/dist/engine/generated-code.js +26 -0
- package/dist/engine/generation-manifest.js +118 -0
- package/dist/engine/migration-plan.js +78 -0
- package/dist/engine/module-generator.js +80 -65
- package/dist/engine/project-config.js +5 -2
- package/dist/engine/project-path.js +25 -0
- package/dist/engine/project-preflight.js +96 -0
- package/dist/engine/resource-generator.js +1104 -68
- package/dist/engine/resource-spec.js +254 -11
- package/examples/store-api/README.md +76 -0
- package/examples/store-api/definitions/customers.resource.json +14 -0
- package/examples/store-api/definitions/order-items.resource.json +26 -0
- package/examples/store-api/definitions/orders.resource.json +22 -0
- package/examples/store-api/definitions/products.resource.json +19 -0
- package/examples/store-api/nestgen.example.json +7 -0
- package/nestgen.js +450 -71
- package/nestjs-generator/features/configure_bootstrap.mjs +5 -2
- package/nestjs-generator/features/operational_foundation.mjs +210 -0
- package/nestjs-generator/features/operations.sh +16 -0
- package/nestjs-generator/features/preflight.mjs +2 -44
- package/nestjs-generator/generate_project.sh +7 -1
- package/package.json +11 -4
- package/readme.md +234 -13
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { projectPath } from './project-path.js';
|
|
4
|
+
function error(message) {
|
|
5
|
+
throw new Error(`Préflight échoué : ${message}`);
|
|
6
|
+
}
|
|
7
|
+
function projectFile(root, relative, required, missingMessage) {
|
|
8
|
+
const target = projectPath(root, relative);
|
|
9
|
+
const stat = fs.lstatSync(target, { throwIfNoEntry: false });
|
|
10
|
+
if (!stat) {
|
|
11
|
+
if (required)
|
|
12
|
+
error(missingMessage ?? `${relative} introuvable.`);
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
if (!stat.isFile())
|
|
16
|
+
error(`fichier régulier attendu : ${relative}.`);
|
|
17
|
+
return target;
|
|
18
|
+
}
|
|
19
|
+
function readObject(file) {
|
|
20
|
+
try {
|
|
21
|
+
const value = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
22
|
+
if (!value || typeof value !== 'object' || Array.isArray(value))
|
|
23
|
+
throw new Error('objet JSON attendu');
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
catch (cause) {
|
|
27
|
+
error(`JSON invalide dans ${file} : ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** Read-only prerequisite checks shared by module, resource and legacy entry points. */
|
|
31
|
+
export function inspectProject(projectRoot, orm, options = {}) {
|
|
32
|
+
const root = fs.realpathSync(projectRoot);
|
|
33
|
+
const packagePath = projectFile(root, 'package.json', true, 'package.json introuvable. Exécute la commande à la racine d’un projet NestJS.');
|
|
34
|
+
const nestCliPath = projectFile(root, 'nest-cli.json', false);
|
|
35
|
+
const packageJson = readObject(packagePath);
|
|
36
|
+
const nestCli = nestCliPath ? readObject(nestCliPath) : null;
|
|
37
|
+
const projects = nestCli?.projects;
|
|
38
|
+
const applicationNames = Object.entries(projects ?? {})
|
|
39
|
+
.filter(([, project]) => project.type === undefined || project.type === 'application')
|
|
40
|
+
.map(([name]) => name);
|
|
41
|
+
if (nestCli?.monorepo && applicationNames.length === 0)
|
|
42
|
+
error('workspaces Nest : aucune application déclarée dans nest-cli.json.');
|
|
43
|
+
const application = options.application;
|
|
44
|
+
if (application && !applicationNames.includes(application))
|
|
45
|
+
error(`application inconnue : ${application}. Applications disponibles : ${applicationNames.join(', ') || 'aucune'}.`);
|
|
46
|
+
if (!application && applicationNames.length > 1)
|
|
47
|
+
error(`workspace ambigu : utilise --application. Applications disponibles : ${applicationNames.join(', ')}.`);
|
|
48
|
+
const selected = application
|
|
49
|
+
? projects[application]
|
|
50
|
+
: applicationNames.length === 1
|
|
51
|
+
? projects[applicationNames[0]]
|
|
52
|
+
: nestCli;
|
|
53
|
+
const sourceRoot = selected?.sourceRoot ?? 'src';
|
|
54
|
+
if (typeof sourceRoot !== 'string' || !sourceRoot || path.isAbsolute(sourceRoot) || sourceRoot.includes('..'))
|
|
55
|
+
error('sourceRoot invalide dans nest-cli.json.');
|
|
56
|
+
const appModulePath = projectFile(root, `${sourceRoot}/app.module.ts`, true, sourceRoot === 'src'
|
|
57
|
+
? `${sourceRoot}/app.module.ts introuvable.`
|
|
58
|
+
: `sourceRoot personnalisé : ${sourceRoot}/app.module.ts introuvable.`);
|
|
59
|
+
const dependencies = {
|
|
60
|
+
...packageJson.dependencies,
|
|
61
|
+
...packageJson.devDependencies,
|
|
62
|
+
};
|
|
63
|
+
const required = ['@nestjs/common', '@nestjs/core'];
|
|
64
|
+
if (options.cqrs !== false)
|
|
65
|
+
required.push('@nestjs/cqrs');
|
|
66
|
+
if (orm === 'typeorm')
|
|
67
|
+
required.push('@nestjs/typeorm', 'typeorm');
|
|
68
|
+
else if (orm === 'prisma')
|
|
69
|
+
required.push('@prisma/client');
|
|
70
|
+
else
|
|
71
|
+
error(`ORM non supporté : ${orm}.`);
|
|
72
|
+
const unavailable = required.filter((dependency) => !dependencies[dependency]);
|
|
73
|
+
if (unavailable.length)
|
|
74
|
+
error(`dépendances manquantes : ${unavailable.join(', ')}.`);
|
|
75
|
+
if (orm === 'prisma') {
|
|
76
|
+
projectFile(root, 'prisma/schema.prisma', true);
|
|
77
|
+
projectFile(root, `${sourceRoot}/prisma/prisma.service.ts`, false);
|
|
78
|
+
projectFile(root, `${sourceRoot}/prisma/prisma.module.ts`, false);
|
|
79
|
+
}
|
|
80
|
+
const appModule = fs.readFileSync(appModulePath, 'utf8');
|
|
81
|
+
if (!/@Module\s*\(/.test(appModule))
|
|
82
|
+
error(`le décorateur @Module est introuvable dans ${sourceRoot}/app.module.ts.`);
|
|
83
|
+
return {
|
|
84
|
+
root,
|
|
85
|
+
appModulePath,
|
|
86
|
+
sourceRoot,
|
|
87
|
+
packageManager: projectFile(root, 'pnpm-lock.yaml', false)
|
|
88
|
+
? 'pnpm'
|
|
89
|
+
: projectFile(root, 'yarn.lock', false)
|
|
90
|
+
? 'yarn'
|
|
91
|
+
: projectFile(root, 'package-lock.json', false)
|
|
92
|
+
? 'npm'
|
|
93
|
+
: null,
|
|
94
|
+
hasRootTypeOrmConnection: /\bTypeOrmModule\.forRoot\s*\(/.test(appModule),
|
|
95
|
+
};
|
|
96
|
+
}
|