@gyxer-studio/generator 0.1.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 +63 -0
- package/dist/generators/app.generator.d.ts +19 -0
- package/dist/generators/app.generator.d.ts.map +1 -0
- package/dist/generators/app.generator.js +237 -0
- package/dist/generators/app.generator.js.map +1 -0
- package/dist/generators/controller.generator.d.ts +10 -0
- package/dist/generators/controller.generator.d.ts.map +1 -0
- package/dist/generators/controller.generator.js +88 -0
- package/dist/generators/controller.generator.js.map +1 -0
- package/dist/generators/docker.generator.d.ts +15 -0
- package/dist/generators/docker.generator.d.ts.map +1 -0
- package/dist/generators/docker.generator.js +82 -0
- package/dist/generators/docker.generator.js.map +1 -0
- package/dist/generators/dto.generator.d.ts +23 -0
- package/dist/generators/dto.generator.d.ts.map +1 -0
- package/dist/generators/dto.generator.js +271 -0
- package/dist/generators/dto.generator.js.map +1 -0
- package/dist/generators/module.generator.d.ts +6 -0
- package/dist/generators/module.generator.d.ts.map +1 -0
- package/dist/generators/module.generator.js +20 -0
- package/dist/generators/module.generator.js.map +1 -0
- package/dist/generators/prisma.generator.d.ts +6 -0
- package/dist/generators/prisma.generator.d.ts.map +1 -0
- package/dist/generators/prisma.generator.js +243 -0
- package/dist/generators/prisma.generator.js.map +1 -0
- package/dist/generators/service.generator.d.ts +6 -0
- package/dist/generators/service.generator.d.ts.map +1 -0
- package/dist/generators/service.generator.js +97 -0
- package/dist/generators/service.generator.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/auth-jwt.generator.d.ts +20 -0
- package/dist/modules/auth-jwt.generator.d.ts.map +1 -0
- package/dist/modules/auth-jwt.generator.js +431 -0
- package/dist/modules/auth-jwt.generator.js.map +1 -0
- package/dist/project-generator.d.ts +16 -0
- package/dist/project-generator.d.ts.map +1 -0
- package/dist/project-generator.js +199 -0
- package/dist/project-generator.js.map +1 -0
- package/dist/security/report.d.ts +24 -0
- package/dist/security/report.d.ts.map +1 -0
- package/dist/security/report.js +108 -0
- package/dist/security/report.js.map +1 -0
- package/dist/utils.d.ts +16 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +44 -0
- package/dist/utils.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import * as fs from 'fs-extra';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { toKebabCase } from './utils.js';
|
|
4
|
+
import { generatePrismaSchema } from './generators/prisma.generator.js';
|
|
5
|
+
import { generateCreateDto, generateUpdateDto } from './generators/dto.generator.js';
|
|
6
|
+
import { generateService } from './generators/service.generator.js';
|
|
7
|
+
import { generateController } from './generators/controller.generator.js';
|
|
8
|
+
import { generateModule } from './generators/module.generator.js';
|
|
9
|
+
import { generateMain, generateAppModule, generatePrismaService, generatePrismaModule, generatePrismaExceptionFilter, } from './generators/app.generator.js';
|
|
10
|
+
import { generateDockerfile, generateDockerCompose, generateEnvFile, generateEnvExample, } from './generators/docker.generator.js';
|
|
11
|
+
import { generateSecurityReport, formatSecurityReport } from './security/report.js';
|
|
12
|
+
import { generateAuthJwtFiles, getAuthEnvVars, getAuthDependencies, getAuthDevDependencies, } from './modules/auth-jwt.generator.js';
|
|
13
|
+
/**
|
|
14
|
+
* Generate a complete NestJS project from a GyxerProject schema.
|
|
15
|
+
*/
|
|
16
|
+
export async function generateProject(project, options) {
|
|
17
|
+
const { outputDir, silent = false } = options;
|
|
18
|
+
const filesCreated = [];
|
|
19
|
+
const log = (msg) => {
|
|
20
|
+
if (!silent)
|
|
21
|
+
console.log(msg);
|
|
22
|
+
};
|
|
23
|
+
// Ensure output directory
|
|
24
|
+
await fs.ensureDir(outputDir);
|
|
25
|
+
log(`Generating project "${project.name}" in ${outputDir}...`);
|
|
26
|
+
// ─── Prisma ───────────────────────────────────────────
|
|
27
|
+
const prismaDir = path.join(outputDir, 'prisma');
|
|
28
|
+
await fs.ensureDir(prismaDir);
|
|
29
|
+
const prismaSchema = generatePrismaSchema(project);
|
|
30
|
+
await writeFile(path.join(prismaDir, 'schema.prisma'), prismaSchema, filesCreated);
|
|
31
|
+
log(' + prisma/schema.prisma');
|
|
32
|
+
// ─── src/prisma (PrismaService + PrismaModule) ─────
|
|
33
|
+
const srcPrismaDir = path.join(outputDir, 'src', 'prisma');
|
|
34
|
+
await fs.ensureDir(srcPrismaDir);
|
|
35
|
+
await writeFile(path.join(srcPrismaDir, 'prisma.service.ts'), generatePrismaService(), filesCreated);
|
|
36
|
+
await writeFile(path.join(srcPrismaDir, 'prisma.module.ts'), generatePrismaModule(), filesCreated);
|
|
37
|
+
await writeFile(path.join(srcPrismaDir, 'prisma-exception.filter.ts'), generatePrismaExceptionFilter(), filesCreated);
|
|
38
|
+
log(' + src/prisma/prisma.service.ts');
|
|
39
|
+
log(' + src/prisma/prisma.module.ts');
|
|
40
|
+
log(' + src/prisma/prisma-exception.filter.ts');
|
|
41
|
+
// ─── Entity modules ───────────────────────────────────
|
|
42
|
+
for (const entity of project.entities) {
|
|
43
|
+
const kebab = toKebabCase(entity.name);
|
|
44
|
+
const entityDir = path.join(outputDir, 'src', kebab);
|
|
45
|
+
const dtoDir = path.join(entityDir, 'dto');
|
|
46
|
+
await fs.ensureDir(dtoDir);
|
|
47
|
+
// DTOs
|
|
48
|
+
await writeFile(path.join(dtoDir, `create-${kebab}.dto.ts`), generateCreateDto(entity, project), filesCreated);
|
|
49
|
+
await writeFile(path.join(dtoDir, `update-${kebab}.dto.ts`), generateUpdateDto(entity, project), filesCreated);
|
|
50
|
+
// Service
|
|
51
|
+
await writeFile(path.join(entityDir, `${kebab}.service.ts`), generateService(entity, project), filesCreated);
|
|
52
|
+
// Controller
|
|
53
|
+
await writeFile(path.join(entityDir, `${kebab}.controller.ts`), generateController(entity, project), filesCreated);
|
|
54
|
+
// Module
|
|
55
|
+
await writeFile(path.join(entityDir, `${kebab}.module.ts`), generateModule(entity), filesCreated);
|
|
56
|
+
log(` + src/${kebab}/ (module, controller, service, DTOs)`);
|
|
57
|
+
}
|
|
58
|
+
// ─── Auth JWT module ────────────────────────────────────
|
|
59
|
+
const hasAuthJwt = project.modules.some((m) => m.name === 'auth-jwt' && m.enabled !== false);
|
|
60
|
+
if (hasAuthJwt) {
|
|
61
|
+
const authFiles = generateAuthJwtFiles(project);
|
|
62
|
+
for (const [relativePath, content] of authFiles) {
|
|
63
|
+
const fullPath = path.join(outputDir, relativePath);
|
|
64
|
+
await fs.ensureDir(path.dirname(fullPath));
|
|
65
|
+
await writeFile(fullPath, content, filesCreated);
|
|
66
|
+
}
|
|
67
|
+
log(' + src/auth/ (module, controller, service, DTOs, JWT strategy, guards, decorators)');
|
|
68
|
+
}
|
|
69
|
+
// ─── App bootstrap ─────────────────────────────────────
|
|
70
|
+
const srcDir = path.join(outputDir, 'src');
|
|
71
|
+
await fs.ensureDir(srcDir);
|
|
72
|
+
await writeFile(path.join(srcDir, 'main.ts'), generateMain(project), filesCreated);
|
|
73
|
+
await writeFile(path.join(srcDir, 'app.module.ts'), generateAppModule(project), filesCreated);
|
|
74
|
+
log(' + src/main.ts');
|
|
75
|
+
log(' + src/app.module.ts');
|
|
76
|
+
// ─── Project config files ──────────────────────────────
|
|
77
|
+
await writeFile(path.join(outputDir, 'package.json'), generatePackageJson(project), filesCreated);
|
|
78
|
+
await writeFile(path.join(outputDir, 'tsconfig.json'), generateTsConfig(), filesCreated);
|
|
79
|
+
await writeFile(path.join(outputDir, 'tsconfig.build.json'), generateTsBuildConfig(), filesCreated);
|
|
80
|
+
await writeFile(path.join(outputDir, '.gitignore'), generateGitignore(), filesCreated);
|
|
81
|
+
log(' + package.json, tsconfig.json, .gitignore');
|
|
82
|
+
// ─── Docker ────────────────────────────────────────────
|
|
83
|
+
if (project.settings.docker) {
|
|
84
|
+
await writeFile(path.join(outputDir, 'Dockerfile'), generateDockerfile(), filesCreated);
|
|
85
|
+
await writeFile(path.join(outputDir, 'docker-compose.yml'), generateDockerCompose(project), filesCreated);
|
|
86
|
+
log(' + Dockerfile, docker-compose.yml');
|
|
87
|
+
}
|
|
88
|
+
// ─── Environment ───────────────────────────────────────
|
|
89
|
+
let envContent = generateEnvFile(project);
|
|
90
|
+
let envExampleContent = generateEnvExample(project);
|
|
91
|
+
if (hasAuthJwt) {
|
|
92
|
+
envContent += getAuthEnvVars();
|
|
93
|
+
envExampleContent += 'JWT_SECRET=your-secret-key\nJWT_EXPIRES_IN=15m\nJWT_REFRESH_SECRET=your-refresh-secret\nJWT_REFRESH_EXPIRES_IN=7d\n';
|
|
94
|
+
}
|
|
95
|
+
await writeFile(path.join(outputDir, '.env'), envContent, filesCreated);
|
|
96
|
+
await writeFile(path.join(outputDir, '.env.example'), envExampleContent, filesCreated);
|
|
97
|
+
log(' + .env, .env.example');
|
|
98
|
+
// ─── Security Report ───────────────────────────────────
|
|
99
|
+
const securityReport = generateSecurityReport(project);
|
|
100
|
+
await writeFile(path.join(outputDir, 'security-report.json'), JSON.stringify(securityReport, null, 2), filesCreated);
|
|
101
|
+
log(formatSecurityReport(securityReport));
|
|
102
|
+
log('');
|
|
103
|
+
log(`Done! ${filesCreated.length} files created.`);
|
|
104
|
+
log('');
|
|
105
|
+
log('Next steps:');
|
|
106
|
+
log(` cd ${outputDir}`);
|
|
107
|
+
log(' npm install');
|
|
108
|
+
log(' npx prisma migrate dev --name init');
|
|
109
|
+
log(' npm run start:dev');
|
|
110
|
+
return { outputDir, filesCreated, securityReport };
|
|
111
|
+
}
|
|
112
|
+
// ─── Helper generators ──────────────────────────────────────
|
|
113
|
+
function generatePackageJson(project) {
|
|
114
|
+
const hasAuthJwt = project.modules.some((m) => m.name === 'auth-jwt' && m.enabled !== false);
|
|
115
|
+
const pkg = {
|
|
116
|
+
name: project.name,
|
|
117
|
+
version: project.version,
|
|
118
|
+
description: project.description,
|
|
119
|
+
private: true,
|
|
120
|
+
scripts: {
|
|
121
|
+
build: 'nest build',
|
|
122
|
+
format: 'prettier --write "src/**/*.ts"',
|
|
123
|
+
start: 'nest start',
|
|
124
|
+
'start:dev': 'nest start --watch',
|
|
125
|
+
'start:debug': 'nest start --debug --watch',
|
|
126
|
+
'start:prod': 'node dist/main',
|
|
127
|
+
lint: 'eslint "{src,apps,libs,test}/**/*.ts" --fix',
|
|
128
|
+
},
|
|
129
|
+
dependencies: {
|
|
130
|
+
'@nestjs/common': '^10.4.0',
|
|
131
|
+
'@nestjs/core': '^10.4.0',
|
|
132
|
+
'@nestjs/platform-express': '^10.4.0',
|
|
133
|
+
'@nestjs/swagger': '^8.0.0',
|
|
134
|
+
'@prisma/client': '^6.0.0',
|
|
135
|
+
'class-transformer': '^0.5.1',
|
|
136
|
+
'class-validator': '^0.14.1',
|
|
137
|
+
helmet: '^8.0.0',
|
|
138
|
+
'reflect-metadata': '^0.2.0',
|
|
139
|
+
rxjs: '^7.8.0',
|
|
140
|
+
...(project.settings.enableRateLimit
|
|
141
|
+
? { '@nestjs/throttler': '^6.0.0' }
|
|
142
|
+
: {}),
|
|
143
|
+
...(hasAuthJwt ? getAuthDependencies() : {}),
|
|
144
|
+
},
|
|
145
|
+
devDependencies: {
|
|
146
|
+
'@nestjs/cli': '^10.4.0',
|
|
147
|
+
'@types/express': '^5.0.0',
|
|
148
|
+
'@types/node': '^22.0.0',
|
|
149
|
+
prisma: '^6.0.0',
|
|
150
|
+
typescript: '^5.7.0',
|
|
151
|
+
prettier: '^3.4.0',
|
|
152
|
+
...(hasAuthJwt ? getAuthDevDependencies() : {}),
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
return JSON.stringify(pkg, null, 2) + '\n';
|
|
156
|
+
}
|
|
157
|
+
function generateTsConfig() {
|
|
158
|
+
return JSON.stringify({
|
|
159
|
+
compilerOptions: {
|
|
160
|
+
module: 'commonjs',
|
|
161
|
+
declaration: true,
|
|
162
|
+
removeComments: true,
|
|
163
|
+
emitDecoratorMetadata: true,
|
|
164
|
+
experimentalDecorators: true,
|
|
165
|
+
allowSyntheticDefaultImports: true,
|
|
166
|
+
target: 'ES2021',
|
|
167
|
+
sourceMap: true,
|
|
168
|
+
outDir: './dist',
|
|
169
|
+
baseUrl: './',
|
|
170
|
+
incremental: true,
|
|
171
|
+
skipLibCheck: true,
|
|
172
|
+
strictNullChecks: true,
|
|
173
|
+
noImplicitAny: true,
|
|
174
|
+
strictBindCallApply: true,
|
|
175
|
+
forceConsistentCasingInFileNames: true,
|
|
176
|
+
noFallthroughCasesInSwitch: true,
|
|
177
|
+
},
|
|
178
|
+
}, null, 2) + '\n';
|
|
179
|
+
}
|
|
180
|
+
function generateTsBuildConfig() {
|
|
181
|
+
return JSON.stringify({
|
|
182
|
+
extends: './tsconfig.json',
|
|
183
|
+
exclude: ['node_modules', 'test', 'dist', '**/*spec.ts'],
|
|
184
|
+
}, null, 2) + '\n';
|
|
185
|
+
}
|
|
186
|
+
function generateGitignore() {
|
|
187
|
+
return `node_modules/
|
|
188
|
+
dist/
|
|
189
|
+
.env
|
|
190
|
+
*.tsbuildinfo
|
|
191
|
+
coverage/
|
|
192
|
+
.DS_Store
|
|
193
|
+
`;
|
|
194
|
+
}
|
|
195
|
+
async function writeFile(filePath, content, files) {
|
|
196
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
197
|
+
files.push(filePath);
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=project-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-generator.js","sourceRoot":"","sources":["../src/project-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { GyxerProject } from '@gyxer-studio/schema';
|
|
2
|
+
export interface SecurityCheck {
|
|
3
|
+
name: string;
|
|
4
|
+
passed: boolean;
|
|
5
|
+
message: string;
|
|
6
|
+
severity: 'info' | 'warning' | 'critical';
|
|
7
|
+
}
|
|
8
|
+
export interface SecurityReport {
|
|
9
|
+
projectName: string;
|
|
10
|
+
timestamp: string;
|
|
11
|
+
checks: SecurityCheck[];
|
|
12
|
+
passed: number;
|
|
13
|
+
failed: number;
|
|
14
|
+
score: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Generate a security report for the project configuration.
|
|
18
|
+
*/
|
|
19
|
+
export declare function generateSecurityReport(project: GyxerProject): SecurityReport;
|
|
20
|
+
/**
|
|
21
|
+
* Format security report for console output.
|
|
22
|
+
*/
|
|
23
|
+
export declare function formatSecurityReport(report: SecurityReport): string;
|
|
24
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/security/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;CAC3C;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,YAAY,GAAG,cAAc,CA4F5E;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAqBnE"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a security report for the project configuration.
|
|
3
|
+
*/
|
|
4
|
+
export function generateSecurityReport(project) {
|
|
5
|
+
const checks = [];
|
|
6
|
+
// Helmet
|
|
7
|
+
checks.push({
|
|
8
|
+
name: 'Helmet (Security Headers)',
|
|
9
|
+
passed: project.settings.enableHelmet,
|
|
10
|
+
message: project.settings.enableHelmet
|
|
11
|
+
? 'Helmet is enabled — security headers will be set'
|
|
12
|
+
: 'Helmet is disabled — consider enabling for security headers (XSS, CSP, etc.)',
|
|
13
|
+
severity: 'critical',
|
|
14
|
+
});
|
|
15
|
+
// CORS
|
|
16
|
+
checks.push({
|
|
17
|
+
name: 'CORS Configuration',
|
|
18
|
+
passed: project.settings.enableCors,
|
|
19
|
+
message: project.settings.enableCors
|
|
20
|
+
? 'CORS is enabled — configure allowed origins for production'
|
|
21
|
+
: 'CORS is disabled — API won\'t be accessible from browsers on other domains',
|
|
22
|
+
severity: 'warning',
|
|
23
|
+
});
|
|
24
|
+
// Rate Limiting
|
|
25
|
+
checks.push({
|
|
26
|
+
name: 'Rate Limiting',
|
|
27
|
+
passed: project.settings.enableRateLimit,
|
|
28
|
+
message: project.settings.enableRateLimit
|
|
29
|
+
? `Rate limiting: ${project.settings.rateLimitMax} requests per ${project.settings.rateLimitTtl}s`
|
|
30
|
+
: 'Rate limiting is disabled — API is vulnerable to brute force attacks',
|
|
31
|
+
severity: 'critical',
|
|
32
|
+
});
|
|
33
|
+
// Validation Pipe (always enabled)
|
|
34
|
+
checks.push({
|
|
35
|
+
name: 'Input Validation',
|
|
36
|
+
passed: true,
|
|
37
|
+
message: 'ValidationPipe with whitelist enabled — unknown properties will be stripped',
|
|
38
|
+
severity: 'info',
|
|
39
|
+
});
|
|
40
|
+
// Docker
|
|
41
|
+
checks.push({
|
|
42
|
+
name: 'Docker Configuration',
|
|
43
|
+
passed: project.settings.docker,
|
|
44
|
+
message: project.settings.docker
|
|
45
|
+
? 'Docker setup included — multi-stage build for smaller image'
|
|
46
|
+
: 'Docker setup skipped — consider containerizing for consistent deployments',
|
|
47
|
+
severity: 'info',
|
|
48
|
+
});
|
|
49
|
+
// .env.example
|
|
50
|
+
checks.push({
|
|
51
|
+
name: 'Environment Variables',
|
|
52
|
+
passed: true,
|
|
53
|
+
message: '.env.example generated — secrets are not hardcoded',
|
|
54
|
+
severity: 'critical',
|
|
55
|
+
});
|
|
56
|
+
// Authentication
|
|
57
|
+
const hasAuthJwt = project.modules?.some((m) => m.name === 'auth-jwt' && m.enabled !== false);
|
|
58
|
+
checks.push({
|
|
59
|
+
name: 'Authentication',
|
|
60
|
+
passed: !!hasAuthJwt,
|
|
61
|
+
message: hasAuthJwt
|
|
62
|
+
? 'JWT authentication enabled — routes protected by default, bcrypt password hashing'
|
|
63
|
+
: 'No authentication module — API endpoints are publicly accessible',
|
|
64
|
+
severity: 'critical',
|
|
65
|
+
});
|
|
66
|
+
// Swagger in production warning
|
|
67
|
+
if (project.settings.enableSwagger) {
|
|
68
|
+
checks.push({
|
|
69
|
+
name: 'Swagger Docs',
|
|
70
|
+
passed: true,
|
|
71
|
+
message: 'Swagger is enabled — consider disabling in production or adding auth',
|
|
72
|
+
severity: 'warning',
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
const passed = checks.filter((c) => c.passed).length;
|
|
76
|
+
const failed = checks.filter((c) => !c.passed).length;
|
|
77
|
+
const score = Math.round((passed / checks.length) * 100);
|
|
78
|
+
return {
|
|
79
|
+
projectName: project.name,
|
|
80
|
+
timestamp: new Date().toISOString(),
|
|
81
|
+
checks,
|
|
82
|
+
passed,
|
|
83
|
+
failed,
|
|
84
|
+
score,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Format security report for console output.
|
|
89
|
+
*/
|
|
90
|
+
export function formatSecurityReport(report) {
|
|
91
|
+
const lines = [];
|
|
92
|
+
lines.push('');
|
|
93
|
+
lines.push('=== GYXER SECURITY REPORT ===');
|
|
94
|
+
lines.push(`Project: ${report.projectName}`);
|
|
95
|
+
lines.push(`Score: ${report.score}%`);
|
|
96
|
+
lines.push('');
|
|
97
|
+
for (const check of report.checks) {
|
|
98
|
+
const icon = check.passed ? '[PASS]' : '[FAIL]';
|
|
99
|
+
const severity = check.severity.toUpperCase();
|
|
100
|
+
lines.push(` ${icon} [${severity}] ${check.name}`);
|
|
101
|
+
lines.push(` ${check.message}`);
|
|
102
|
+
}
|
|
103
|
+
lines.push('');
|
|
104
|
+
lines.push(`Results: ${report.passed} passed, ${report.failed} failed`);
|
|
105
|
+
lines.push('=============================');
|
|
106
|
+
return lines.join('\n');
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/security/report.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for code generation.
|
|
3
|
+
*/
|
|
4
|
+
/** Convert PascalCase to kebab-case: "BlogPost" → "blog-post" */
|
|
5
|
+
export declare function toKebabCase(str: string): string;
|
|
6
|
+
/** Convert PascalCase to camelCase: "BlogPost" → "blogPost" */
|
|
7
|
+
export declare function toCamelCase(str: string): string;
|
|
8
|
+
/** Convert PascalCase to SCREAMING_SNAKE: "BlogPost" → "BLOG_POST" */
|
|
9
|
+
export declare function toScreamingSnake(str: string): string;
|
|
10
|
+
/** Convert to snake_case: "BlogPost" → "blog_post" */
|
|
11
|
+
export declare function toSnakeCase(str: string): string;
|
|
12
|
+
/** Pluralize a word (simple English rules) */
|
|
13
|
+
export declare function pluralize(str: string): string;
|
|
14
|
+
/** Indent each line of a multi-line string */
|
|
15
|
+
export declare function indent(str: string, spaces?: number): string;
|
|
16
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,iEAAiE;AACjE,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK/C;AAED,+DAA+D;AAC/D,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKpD;AAED,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,8CAA8C;AAC9C,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQ7C;AAED,8CAA8C;AAC9C,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAU,GAAG,MAAM,CAM9D"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for code generation.
|
|
3
|
+
*/
|
|
4
|
+
/** Convert PascalCase to kebab-case: "BlogPost" → "blog-post" */
|
|
5
|
+
export function toKebabCase(str) {
|
|
6
|
+
return str
|
|
7
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
8
|
+
.replace(/([A-Z])([A-Z][a-z])/g, '$1-$2')
|
|
9
|
+
.toLowerCase();
|
|
10
|
+
}
|
|
11
|
+
/** Convert PascalCase to camelCase: "BlogPost" → "blogPost" */
|
|
12
|
+
export function toCamelCase(str) {
|
|
13
|
+
return str.charAt(0).toLowerCase() + str.slice(1);
|
|
14
|
+
}
|
|
15
|
+
/** Convert PascalCase to SCREAMING_SNAKE: "BlogPost" → "BLOG_POST" */
|
|
16
|
+
export function toScreamingSnake(str) {
|
|
17
|
+
return str
|
|
18
|
+
.replace(/([a-z])([A-Z])/g, '$1_$2')
|
|
19
|
+
.replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')
|
|
20
|
+
.toUpperCase();
|
|
21
|
+
}
|
|
22
|
+
/** Convert to snake_case: "BlogPost" → "blog_post" */
|
|
23
|
+
export function toSnakeCase(str) {
|
|
24
|
+
return toScreamingSnake(str).toLowerCase();
|
|
25
|
+
}
|
|
26
|
+
/** Pluralize a word (simple English rules) */
|
|
27
|
+
export function pluralize(str) {
|
|
28
|
+
if (str.endsWith('y') && !str.endsWith('ay') && !str.endsWith('ey') && !str.endsWith('oy')) {
|
|
29
|
+
return str.slice(0, -1) + 'ies';
|
|
30
|
+
}
|
|
31
|
+
if (str.endsWith('s') || str.endsWith('x') || str.endsWith('ch') || str.endsWith('sh')) {
|
|
32
|
+
return str + 'es';
|
|
33
|
+
}
|
|
34
|
+
return str + 's';
|
|
35
|
+
}
|
|
36
|
+
/** Indent each line of a multi-line string */
|
|
37
|
+
export function indent(str, spaces = 2) {
|
|
38
|
+
const pad = ' '.repeat(spaces);
|
|
39
|
+
return str
|
|
40
|
+
.split('\n')
|
|
41
|
+
.map((line) => (line.trim() ? pad + line : line))
|
|
42
|
+
.join('\n');
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,iEAAiE;AACjE,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,GAAG;SACP,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;SACnC,OAAO,CAAC,sBAAsB,EAAE,OAAO,CAAC;SACxC,WAAW,EAAE,CAAC;AACnB,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,OAAO,GAAG;SACP,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;SACnC,OAAO,CAAC,sBAAsB,EAAE,OAAO,CAAC;SACxC,WAAW,EAAE,CAAC;AACnB,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;AAC7C,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3F,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;IAClC,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACvF,OAAO,GAAG,GAAG,IAAI,CAAC;IACpB,CAAC;IACD,OAAO,GAAG,GAAG,GAAG,CAAC;AACnB,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,MAAM,CAAC,GAAW,EAAE,SAAiB,CAAC;IACpD,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/B,OAAO,GAAG;SACP,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;SAChD,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gyxer-studio/generator",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "NestJS project code generator — generates full CRUD APIs from schema",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./utils": {
|
|
14
|
+
"types": "./dist/utils.d.ts",
|
|
15
|
+
"import": "./dist/utils.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc",
|
|
23
|
+
"dev": "tsc --watch",
|
|
24
|
+
"prepublishOnly": "npm run build"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"gyxer",
|
|
28
|
+
"generator",
|
|
29
|
+
"nestjs",
|
|
30
|
+
"codegen",
|
|
31
|
+
"backend",
|
|
32
|
+
"prisma",
|
|
33
|
+
"crud",
|
|
34
|
+
"api"
|
|
35
|
+
],
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "https://github.com/Gyxer513/gyxer-studio.git",
|
|
39
|
+
"directory": "packages/generator"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/Gyxer513/gyxer-studio#readme",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/Gyxer513/gyxer-studio/issues"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=20.0.0"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@gyxer-studio/schema": "0.1.0",
|
|
50
|
+
"handlebars": "^4.7.8",
|
|
51
|
+
"fs-extra": "^11.2.0"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@types/fs-extra": "^11.0.4",
|
|
55
|
+
"typescript": "^5.7.0"
|
|
56
|
+
},
|
|
57
|
+
"license": "MIT"
|
|
58
|
+
}
|