nestjs-ddd-cli 2.2.1 → 3.2.2
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 +247 -408
- package/ddd.schema.json +111 -0
- package/dist/commands/aggregate-validator.d.ts +9 -0
- package/dist/commands/aggregate-validator.js +953 -0
- package/dist/commands/aggregate-validator.js.map +1 -0
- package/dist/commands/ai-assist.d.ts +8 -0
- package/dist/commands/ai-assist.js +337 -0
- package/dist/commands/ai-assist.js.map +1 -0
- package/dist/commands/api-contracts.d.ts +9 -0
- package/dist/commands/api-contracts.js +1368 -0
- package/dist/commands/api-contracts.js.map +1 -0
- package/dist/commands/api-docs.d.ts +8 -0
- package/dist/commands/api-docs.js +408 -0
- package/dist/commands/api-docs.js.map +1 -0
- package/dist/commands/api-versioning.d.ts +11 -0
- package/dist/commands/api-versioning.js +643 -0
- package/dist/commands/api-versioning.js.map +1 -0
- package/dist/commands/audit-logging.d.ts +9 -0
- package/dist/commands/audit-logging.js +1129 -0
- package/dist/commands/audit-logging.js.map +1 -0
- package/dist/commands/batch-generate.d.ts +10 -0
- package/dist/commands/batch-generate.js +405 -0
- package/dist/commands/batch-generate.js.map +1 -0
- package/dist/commands/caching-strategies.d.ts +9 -0
- package/dist/commands/caching-strategies.js +874 -0
- package/dist/commands/caching-strategies.js.map +1 -0
- package/dist/commands/code-analyzer.d.ts +42 -0
- package/dist/commands/code-analyzer.js +474 -0
- package/dist/commands/code-analyzer.js.map +1 -0
- package/dist/commands/database-seeding.d.ts +6 -0
- package/dist/commands/database-seeding.js +621 -0
- package/dist/commands/database-seeding.js.map +1 -0
- package/dist/commands/db-optimization.d.ts +7 -0
- package/dist/commands/db-optimization.js +687 -0
- package/dist/commands/db-optimization.js.map +1 -0
- package/dist/commands/dependency-graph.d.ts +6 -0
- package/dist/commands/dependency-graph.js +329 -0
- package/dist/commands/dependency-graph.js.map +1 -0
- package/dist/commands/doctor-enhanced.d.ts +22 -0
- package/dist/commands/doctor-enhanced.js +543 -0
- package/dist/commands/doctor-enhanced.js.map +1 -0
- package/dist/commands/doctor.d.ts +4 -0
- package/dist/commands/doctor.js +151 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/env-manager.d.ts +6 -0
- package/dist/commands/env-manager.js +419 -0
- package/dist/commands/env-manager.js.map +1 -0
- package/dist/commands/event-sourcing-full.d.ts +10 -0
- package/dist/commands/event-sourcing-full.js +1107 -0
- package/dist/commands/event-sourcing-full.js.map +1 -0
- package/dist/commands/feature-flags.d.ts +9 -0
- package/dist/commands/feature-flags.js +824 -0
- package/dist/commands/feature-flags.js.map +1 -0
- package/dist/commands/filter-dsl.d.ts +10 -0
- package/dist/commands/filter-dsl.js +1407 -0
- package/dist/commands/filter-dsl.js.map +1 -0
- package/dist/commands/generate-all.js +525 -36
- package/dist/commands/generate-all.js.map +1 -1
- package/dist/commands/generate-deployment.d.ts +8 -0
- package/dist/commands/generate-deployment.js +746 -0
- package/dist/commands/generate-deployment.js.map +1 -0
- package/dist/commands/generate-domain-service.d.ts +14 -0
- package/dist/commands/generate-domain-service.js +796 -0
- package/dist/commands/generate-domain-service.js.map +1 -0
- package/dist/commands/generate-entity.js +87 -25
- package/dist/commands/generate-entity.js.map +1 -1
- package/dist/commands/generate-from-schema.d.ts +56 -0
- package/dist/commands/generate-from-schema.js +222 -0
- package/dist/commands/generate-from-schema.js.map +1 -0
- package/dist/commands/generate-module.js +37 -29
- package/dist/commands/generate-module.js.map +1 -1
- package/dist/commands/generate-orchestrator.d.ts +14 -0
- package/dist/commands/generate-orchestrator.js +887 -0
- package/dist/commands/generate-orchestrator.js.map +1 -0
- package/dist/commands/generate-repository.d.ts +14 -0
- package/dist/commands/generate-repository.js +1019 -0
- package/dist/commands/generate-repository.js.map +1 -0
- package/dist/commands/generate-shared.d.ts +4 -0
- package/dist/commands/generate-shared.js +388 -0
- package/dist/commands/generate-shared.js.map +1 -0
- package/dist/commands/generate-value-object.d.ts +32 -0
- package/dist/commands/generate-value-object.js +700 -0
- package/dist/commands/generate-value-object.js.map +1 -0
- package/dist/commands/graphql-subscriptions.d.ts +6 -0
- package/dist/commands/graphql-subscriptions.js +607 -0
- package/dist/commands/graphql-subscriptions.js.map +1 -0
- package/dist/commands/graphql-types.d.ts +5 -0
- package/dist/commands/graphql-types.js +423 -0
- package/dist/commands/graphql-types.js.map +1 -0
- package/dist/commands/health-probes-advanced.d.ts +6 -0
- package/dist/commands/health-probes-advanced.js +655 -0
- package/dist/commands/health-probes-advanced.js.map +1 -0
- package/dist/commands/i18n-setup.d.ts +10 -0
- package/dist/commands/i18n-setup.js +677 -0
- package/dist/commands/i18n-setup.js.map +1 -0
- package/dist/commands/init-config.d.ts +6 -0
- package/dist/commands/init-config.js +370 -0
- package/dist/commands/init-config.js.map +1 -0
- package/dist/commands/init-project.js +56 -6
- package/dist/commands/init-project.js.map +1 -1
- package/dist/commands/interactive-scaffold.d.ts +5 -0
- package/dist/commands/interactive-scaffold.js +271 -0
- package/dist/commands/interactive-scaffold.js.map +1 -0
- package/dist/commands/metrics-prometheus.d.ts +6 -0
- package/dist/commands/metrics-prometheus.js +681 -0
- package/dist/commands/metrics-prometheus.js.map +1 -0
- package/dist/commands/migration-engine.d.ts +6 -0
- package/dist/commands/migration-engine.js +446 -0
- package/dist/commands/migration-engine.js.map +1 -0
- package/dist/commands/migration.d.ts +12 -0
- package/dist/commands/migration.js +484 -0
- package/dist/commands/migration.js.map +1 -0
- package/dist/commands/monorepo.d.ts +8 -0
- package/dist/commands/monorepo.js +483 -0
- package/dist/commands/monorepo.js.map +1 -0
- package/dist/commands/multi-database.d.ts +5 -0
- package/dist/commands/multi-database.js +439 -0
- package/dist/commands/multi-database.js.map +1 -0
- package/dist/commands/observability-tracing.d.ts +10 -0
- package/dist/commands/observability-tracing.js +740 -0
- package/dist/commands/observability-tracing.js.map +1 -0
- package/dist/commands/openapi-export.d.ts +8 -0
- package/dist/commands/openapi-export.js +359 -0
- package/dist/commands/openapi-export.js.map +1 -0
- package/dist/commands/perf-analyzer.d.ts +8 -0
- package/dist/commands/perf-analyzer.js +423 -0
- package/dist/commands/perf-analyzer.js.map +1 -0
- package/dist/commands/rate-limiting.d.ts +10 -0
- package/dist/commands/rate-limiting.js +953 -0
- package/dist/commands/rate-limiting.js.map +1 -0
- package/dist/commands/recipe-plugin.d.ts +56 -0
- package/dist/commands/recipe-plugin.js +315 -0
- package/dist/commands/recipe-plugin.js.map +1 -0
- package/dist/commands/recipe.d.ts +6 -0
- package/dist/commands/recipe.js +3988 -0
- package/dist/commands/recipe.js.map +1 -0
- package/dist/commands/recipes/elasticsearch.recipe.d.ts +1 -0
- package/dist/commands/recipes/elasticsearch.recipe.js +761 -0
- package/dist/commands/recipes/elasticsearch.recipe.js.map +1 -0
- package/dist/commands/recipes/event-sourcing.recipe.d.ts +1 -0
- package/dist/commands/recipes/event-sourcing.recipe.js +889 -0
- package/dist/commands/recipes/event-sourcing.recipe.js.map +1 -0
- package/dist/commands/recipes/index.d.ts +8 -0
- package/dist/commands/recipes/index.js +25 -0
- package/dist/commands/recipes/index.js.map +1 -0
- package/dist/commands/recipes/joi-env.recipe.d.ts +1 -0
- package/dist/commands/recipes/joi-env.recipe.js +301 -0
- package/dist/commands/recipes/joi-env.recipe.js.map +1 -0
- package/dist/commands/recipes/message-queue.recipe.d.ts +1 -0
- package/dist/commands/recipes/message-queue.recipe.js +706 -0
- package/dist/commands/recipes/message-queue.recipe.js.map +1 -0
- package/dist/commands/recipes/middleware.recipe.d.ts +1 -0
- package/dist/commands/recipes/middleware.recipe.js +383 -0
- package/dist/commands/recipes/middleware.recipe.js.map +1 -0
- package/dist/commands/recipes/multi-tenancy.recipe.d.ts +1 -0
- package/dist/commands/recipes/multi-tenancy.recipe.js +520 -0
- package/dist/commands/recipes/multi-tenancy.recipe.js.map +1 -0
- package/dist/commands/recipes/oauth2.recipe.d.ts +1 -0
- package/dist/commands/recipes/oauth2.recipe.js +472 -0
- package/dist/commands/recipes/oauth2.recipe.js.map +1 -0
- package/dist/commands/recipes/websocket.recipe.d.ts +1 -0
- package/dist/commands/recipes/websocket.recipe.js +453 -0
- package/dist/commands/recipes/websocket.recipe.js.map +1 -0
- package/dist/commands/resilience-patterns.d.ts +13 -0
- package/dist/commands/resilience-patterns.js +1029 -0
- package/dist/commands/resilience-patterns.js.map +1 -0
- package/dist/commands/security-patterns.d.ts +11 -0
- package/dist/commands/security-patterns.js +2233 -0
- package/dist/commands/security-patterns.js.map +1 -0
- package/dist/commands/template-debug.d.ts +27 -0
- package/dist/commands/template-debug.js +388 -0
- package/dist/commands/template-debug.js.map +1 -0
- package/dist/commands/test-factory-full.d.ts +9 -0
- package/dist/commands/test-factory-full.js +1570 -0
- package/dist/commands/test-factory-full.js.map +1 -0
- package/dist/commands/test-scaffold.d.ts +7 -0
- package/dist/commands/test-scaffold.js +621 -0
- package/dist/commands/test-scaffold.js.map +1 -0
- package/dist/index.js +1092 -1
- package/dist/index.js.map +1 -1
- package/dist/templates/ai-context/CLAUDE.md.hbs +173 -0
- package/dist/templates/ai-context/conventions.md.hbs +161 -0
- package/dist/templates/command/create-command.hbs +6 -14
- package/dist/templates/command/delete-command.hbs +19 -0
- package/dist/templates/command/update-command.hbs +24 -0
- package/dist/templates/controller/controller.hbs +64 -17
- package/dist/templates/dto/create-dto.hbs +29 -5
- package/dist/templates/dto/filter-dto.hbs +52 -0
- package/dist/templates/dto/filter-query.dto.hbs +148 -0
- package/dist/templates/dto/paginated-response.dto.hbs +29 -0
- package/dist/templates/dto/pagination-query.dto.hbs +30 -0
- package/dist/templates/dto/response-dto.hbs +38 -0
- package/dist/templates/dto/update-dto.hbs +11 -0
- package/dist/templates/entity/entity.hbs +32 -1
- package/dist/templates/event/domain-event.hbs +33 -7
- package/dist/templates/event/event-handler.hbs +40 -0
- package/dist/templates/exception/base-exceptions.hbs +69 -0
- package/dist/templates/exception/entity-not-found.exception.hbs +7 -0
- package/dist/templates/mapper/mapper.hbs +49 -24
- package/dist/templates/module/module.hbs +34 -10
- package/dist/templates/orm-entity/orm-entity.hbs +63 -12
- package/dist/templates/prisma/prisma-mapper.hbs +71 -0
- package/dist/templates/prisma/prisma-repository.hbs +114 -0
- package/dist/templates/prisma/prisma-schema.hbs +20 -0
- package/dist/templates/prisma/prisma-service.hbs +51 -0
- package/dist/templates/query/get-all.query.hbs +50 -0
- package/dist/templates/query/get-by-id.query.hbs +31 -0
- package/dist/templates/repository/repository.hbs +56 -14
- package/dist/templates/resolver/graphql-input.hbs +54 -0
- package/dist/templates/resolver/graphql-type.hbs +58 -0
- package/dist/templates/resolver/pagination-args.hbs +33 -0
- package/dist/templates/resolver/resolver.hbs +62 -0
- package/dist/templates/shared/prisma-query-builder.util.hbs +189 -0
- package/dist/templates/shared/query-builder.util.hbs +218 -0
- package/dist/templates/test/controller.spec.hbs +124 -0
- package/dist/templates/test/repository.spec.hbs +158 -0
- package/dist/templates/test/usecase.spec.hbs +116 -0
- package/dist/templates/usecase/create-usecase.hbs +20 -8
- package/dist/templates/usecase/delete-usecase.hbs +17 -0
- package/dist/templates/usecase/update-usecase.hbs +31 -0
- package/dist/utils/config.utils.d.ts +45 -0
- package/dist/utils/config.utils.js +211 -0
- package/dist/utils/config.utils.js.map +1 -0
- package/dist/utils/dependency.utils.d.ts +2 -0
- package/dist/utils/dependency.utils.js +44 -3
- package/dist/utils/dependency.utils.js.map +1 -1
- package/dist/utils/error.utils.d.ts +145 -0
- package/dist/utils/error.utils.js +422 -0
- package/dist/utils/error.utils.js.map +1 -0
- package/dist/utils/field.utils.d.ts +54 -0
- package/dist/utils/field.utils.js +401 -0
- package/dist/utils/field.utils.js.map +1 -0
- package/dist/utils/file.utils.d.ts +33 -8
- package/dist/utils/file.utils.js +237 -5
- package/dist/utils/file.utils.js.map +1 -1
- package/dist/utils/idempotency.utils.d.ts +123 -0
- package/dist/utils/idempotency.utils.js +444 -0
- package/dist/utils/idempotency.utils.js.map +1 -0
- package/dist/utils/naming.utils.js +24 -5
- package/dist/utils/naming.utils.js.map +1 -1
- package/dist/utils/performance.utils.d.ts +37 -0
- package/dist/utils/performance.utils.js +158 -0
- package/dist/utils/performance.utils.js.map +1 -0
- package/dist/utils/relation.utils.d.ts +92 -0
- package/dist/utils/relation.utils.js +388 -0
- package/dist/utils/relation.utils.js.map +1 -0
- package/dist/utils/rollback.utils.d.ts +49 -0
- package/dist/utils/rollback.utils.js +306 -0
- package/dist/utils/rollback.utils.js.map +1 -0
- package/dist/utils/schema.utils.d.ts +123 -0
- package/dist/utils/schema.utils.js +419 -0
- package/dist/utils/schema.utils.js.map +1 -0
- package/dist/utils/security.utils.d.ts +57 -0
- package/dist/utils/security.utils.js +315 -0
- package/dist/utils/security.utils.js.map +1 -0
- package/dist/utils/template-engine.utils.d.ts +80 -0
- package/dist/utils/template-engine.utils.js +478 -0
- package/dist/utils/template-engine.utils.js.map +1 -0
- package/dist/utils/validation-registry.utils.d.ts +160 -0
- package/dist/utils/validation-registry.utils.js +526 -0
- package/dist/utils/validation-registry.utils.js.map +1 -0
- package/package.json +12 -8
package/dist/utils/file.utils.js
CHANGED
|
@@ -43,12 +43,51 @@ exports.writeFile = writeFile;
|
|
|
43
43
|
exports.readTemplate = readTemplate;
|
|
44
44
|
exports.compileTemplate = compileTemplate;
|
|
45
45
|
exports.generateFromTemplate = generateFromTemplate;
|
|
46
|
+
exports.resetDryRunFiles = resetDryRunFiles;
|
|
47
|
+
exports.getDryRunFiles = getDryRunFiles;
|
|
48
|
+
exports.addDryRunFile = addDryRunFile;
|
|
49
|
+
exports.writeGeneratedFile = writeGeneratedFile;
|
|
50
|
+
exports.updateBarrelFile = updateBarrelFile;
|
|
46
51
|
exports.getModulePath = getModulePath;
|
|
47
52
|
const fs = __importStar(require("fs-extra"));
|
|
48
53
|
const path = __importStar(require("path"));
|
|
49
54
|
const handlebars_1 = __importDefault(require("handlebars"));
|
|
50
55
|
const naming_utils_1 = require("./naming.utils");
|
|
51
|
-
|
|
56
|
+
const field_utils_1 = require("./field.utils");
|
|
57
|
+
// Register Handlebars helpers
|
|
58
|
+
handlebars_1.default.registerHelper('eq', function (a, b) {
|
|
59
|
+
return a === b;
|
|
60
|
+
});
|
|
61
|
+
handlebars_1.default.registerHelper('lowercase', function (str) {
|
|
62
|
+
return typeof str === 'string' ? str.toLowerCase() : str;
|
|
63
|
+
});
|
|
64
|
+
handlebars_1.default.registerHelper('uppercase', function (str) {
|
|
65
|
+
return typeof str === 'string' ? str.toUpperCase() : str;
|
|
66
|
+
});
|
|
67
|
+
handlebars_1.default.registerHelper('pascalCase', function (str) {
|
|
68
|
+
return typeof str === 'string' ? (0, naming_utils_1.toPascalCase)(str) : str;
|
|
69
|
+
});
|
|
70
|
+
handlebars_1.default.registerHelper('camelCase', function (str) {
|
|
71
|
+
return typeof str === 'string' ? (0, naming_utils_1.toCamelCase)(str) : str;
|
|
72
|
+
});
|
|
73
|
+
handlebars_1.default.registerHelper('kebabCase', function (str) {
|
|
74
|
+
return typeof str === 'string' ? (0, naming_utils_1.toKebabCase)(str) : str;
|
|
75
|
+
});
|
|
76
|
+
function prepareTemplateData(entityName, moduleName, fieldsString) {
|
|
77
|
+
const parsedFields = fieldsString ? (0, field_utils_1.parseFields)(fieldsString) : null;
|
|
78
|
+
const fieldsTemplateData = parsedFields?.fields.length
|
|
79
|
+
? (0, field_utils_1.generateFieldsTemplateData)(parsedFields.fields)
|
|
80
|
+
: null;
|
|
81
|
+
// Check for relations and generate imports
|
|
82
|
+
const relationFields = parsedFields?.fields.filter((f) => f.isRelation) || [];
|
|
83
|
+
const hasRelations = relationFields.length > 0;
|
|
84
|
+
// Generate unique relation imports
|
|
85
|
+
const relationTargets = [...new Set(relationFields.map((f) => f.relationTarget).filter(Boolean))];
|
|
86
|
+
const relationImports = relationTargets.length > 0
|
|
87
|
+
? relationTargets
|
|
88
|
+
.map((target) => `import { ${target}OrmEntity } from "./${(0, naming_utils_1.toKebabCase)(target)}.orm-entity";`)
|
|
89
|
+
.join('\n')
|
|
90
|
+
: '';
|
|
52
91
|
return {
|
|
53
92
|
entityName,
|
|
54
93
|
entityNamePascal: (0, naming_utils_1.toPascalCase)(entityName),
|
|
@@ -56,17 +95,78 @@ function prepareTemplateData(entityName, moduleName) {
|
|
|
56
95
|
entityNameKebab: (0, naming_utils_1.toKebabCase)(entityName),
|
|
57
96
|
entityNameSnake: (0, naming_utils_1.toSnakeCase)(entityName),
|
|
58
97
|
entityNamePlural: (0, naming_utils_1.toPlural)((0, naming_utils_1.toPascalCase)(entityName)),
|
|
98
|
+
entityNamePluralPascal: (0, naming_utils_1.toPlural)((0, naming_utils_1.toPascalCase)(entityName)),
|
|
99
|
+
entityNamePluralCamel: (0, naming_utils_1.toCamelCase)((0, naming_utils_1.toPlural)(entityName)),
|
|
59
100
|
entityNamePluralKebab: (0, naming_utils_1.toKebabCase)((0, naming_utils_1.toPlural)(entityName)),
|
|
60
101
|
tableName: (0, naming_utils_1.toTableName)(entityName),
|
|
61
|
-
moduleName,
|
|
102
|
+
moduleName: (0, naming_utils_1.toPascalCase)(moduleName),
|
|
62
103
|
moduleNameKebab: (0, naming_utils_1.toKebabCase)(moduleName),
|
|
104
|
+
moduleNamePascal: (0, naming_utils_1.toPascalCase)(moduleName),
|
|
105
|
+
// Field-aware properties
|
|
106
|
+
fields: parsedFields?.fields || [],
|
|
107
|
+
hasFields: (parsedFields?.fields.length || 0) > 0,
|
|
108
|
+
entityProperties: fieldsTemplateData?.entityProperties || '',
|
|
109
|
+
entityPropsInterface: fieldsTemplateData?.entityPropsInterface || '',
|
|
110
|
+
dtoProperties: fieldsTemplateData?.dtoProperties || '',
|
|
111
|
+
ormColumns: fieldsTemplateData?.ormColumns || '',
|
|
112
|
+
migrationColumns: fieldsTemplateData?.migrationColumns || '',
|
|
113
|
+
responseProperties: fieldsTemplateData?.responseProperties || '',
|
|
114
|
+
// Relation properties
|
|
115
|
+
hasRelations,
|
|
116
|
+
relationImports,
|
|
63
117
|
};
|
|
64
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Validate that a path is safe and within allowed bounds
|
|
121
|
+
* Prevents path traversal attacks (OWASP A01:2021)
|
|
122
|
+
*/
|
|
123
|
+
function validatePath(targetPath, basePath) {
|
|
124
|
+
if (!targetPath || typeof targetPath !== 'string') {
|
|
125
|
+
throw new Error('Path must be a non-empty string');
|
|
126
|
+
}
|
|
127
|
+
// Check for null bytes (can bypass security checks)
|
|
128
|
+
if (targetPath.includes('\0')) {
|
|
129
|
+
throw new Error('Path contains null byte');
|
|
130
|
+
}
|
|
131
|
+
// Check for path traversal patterns
|
|
132
|
+
const normalizedPath = path.normalize(targetPath);
|
|
133
|
+
if (normalizedPath.includes('..')) {
|
|
134
|
+
// After normalization, if .. still exists, it's going above root
|
|
135
|
+
const resolvedPath = path.resolve(targetPath);
|
|
136
|
+
const cwdPath = basePath || process.cwd();
|
|
137
|
+
if (!resolvedPath.startsWith(cwdPath)) {
|
|
138
|
+
throw new Error('Path traversal detected: path escapes base directory');
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Block access to sensitive system directories
|
|
142
|
+
const blockedPatterns = [
|
|
143
|
+
/^\/etc\//i,
|
|
144
|
+
/^\/proc\//i,
|
|
145
|
+
/^\/sys\//i,
|
|
146
|
+
/^\/dev\//i,
|
|
147
|
+
/^\/root\//i,
|
|
148
|
+
/^C:\\Windows/i,
|
|
149
|
+
/^C:\\Program Files/i,
|
|
150
|
+
/\.env$/i,
|
|
151
|
+
/\.git\//i,
|
|
152
|
+
/\.ssh\//i,
|
|
153
|
+
/id_rsa/i,
|
|
154
|
+
/\.pem$/i,
|
|
155
|
+
/\.key$/i,
|
|
156
|
+
];
|
|
157
|
+
for (const pattern of blockedPatterns) {
|
|
158
|
+
if (pattern.test(normalizedPath)) {
|
|
159
|
+
throw new Error(`Access to path is blocked: ${normalizedPath}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
65
163
|
async function ensureDir(dirPath) {
|
|
164
|
+
validatePath(dirPath);
|
|
66
165
|
await fs.ensureDir(dirPath);
|
|
67
166
|
}
|
|
68
167
|
async function fileExists(filePath) {
|
|
69
168
|
try {
|
|
169
|
+
validatePath(filePath);
|
|
70
170
|
await fs.access(filePath);
|
|
71
171
|
return true;
|
|
72
172
|
}
|
|
@@ -75,20 +175,152 @@ async function fileExists(filePath) {
|
|
|
75
175
|
}
|
|
76
176
|
}
|
|
77
177
|
async function writeFile(filePath, content) {
|
|
178
|
+
validatePath(filePath);
|
|
179
|
+
// Validate content size (prevent DoS via huge files)
|
|
180
|
+
validateContentSize(content);
|
|
78
181
|
await ensureDir(path.dirname(filePath));
|
|
79
182
|
await fs.writeFile(filePath, content, 'utf-8');
|
|
80
183
|
}
|
|
184
|
+
function validateContentSize(content) {
|
|
185
|
+
const maxContentSize = 10 * 1024 * 1024; // 10MB max
|
|
186
|
+
if (content && content.length > maxContentSize) {
|
|
187
|
+
throw new Error(`Content exceeds maximum size of ${maxContentSize} bytes`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
81
190
|
async function readTemplate(templatePath) {
|
|
191
|
+
validatePath(templatePath);
|
|
192
|
+
// Get file stats to check size before reading
|
|
193
|
+
try {
|
|
194
|
+
const stats = await fs.stat(templatePath);
|
|
195
|
+
const maxTemplateSize = 1024 * 1024; // 1MB max for templates
|
|
196
|
+
if (stats.size > maxTemplateSize) {
|
|
197
|
+
throw new Error(`Template file exceeds maximum size of ${maxTemplateSize} bytes`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
if (error.code === 'ENOENT') {
|
|
202
|
+
throw new Error(`Template file not found: ${templatePath}`);
|
|
203
|
+
}
|
|
204
|
+
throw error;
|
|
205
|
+
}
|
|
82
206
|
return fs.readFile(templatePath, 'utf-8');
|
|
83
207
|
}
|
|
84
208
|
function compileTemplate(template, data) {
|
|
85
|
-
const compiledTemplate = handlebars_1.default.compile(template);
|
|
209
|
+
const compiledTemplate = handlebars_1.default.compile(template, { noEscape: true });
|
|
86
210
|
return compiledTemplate(data);
|
|
87
211
|
}
|
|
88
|
-
async function generateFromTemplate(templatePath, outputPath, data) {
|
|
212
|
+
async function generateFromTemplate(templatePath, outputPath, data, dryRun = false) {
|
|
89
213
|
const template = await readTemplate(templatePath);
|
|
90
214
|
const content = compileTemplate(template, data);
|
|
91
|
-
await
|
|
215
|
+
await writeGeneratedFile(outputPath, content, dryRun);
|
|
216
|
+
return outputPath;
|
|
217
|
+
}
|
|
218
|
+
let dryRunFiles = [];
|
|
219
|
+
function resetDryRunFiles() {
|
|
220
|
+
dryRunFiles = [];
|
|
221
|
+
}
|
|
222
|
+
function getDryRunFiles() {
|
|
223
|
+
return [...dryRunFiles];
|
|
224
|
+
}
|
|
225
|
+
function addDryRunFile(filePath, action = 'create') {
|
|
226
|
+
if (dryRunFiles.some((change) => change.filePath === filePath)) {
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
dryRunFiles.push({ filePath, action });
|
|
230
|
+
}
|
|
231
|
+
async function writeGeneratedFile(filePath, content, dryRun = false) {
|
|
232
|
+
validatePath(filePath);
|
|
233
|
+
validateContentSize(content);
|
|
234
|
+
if (dryRun) {
|
|
235
|
+
addDryRunFile(filePath, (await fileExists(filePath)) ? 'update' : 'create');
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
await writeFile(filePath, content);
|
|
239
|
+
}
|
|
240
|
+
async function updateBarrelFile(filePath, update) {
|
|
241
|
+
validatePath(filePath);
|
|
242
|
+
let content = '';
|
|
243
|
+
if (await fileExists(filePath)) {
|
|
244
|
+
content = await fs.readFile(filePath, 'utf-8');
|
|
245
|
+
}
|
|
246
|
+
const originalContent = content;
|
|
247
|
+
content = appendUniqueLines(content, update.exports || [], update.arrayName);
|
|
248
|
+
content = appendUniqueLines(content, update.imports || [], update.arrayName);
|
|
249
|
+
if (update.arrayName && update.arrayItems?.length) {
|
|
250
|
+
content = mergeExportedArray(content, update.arrayName, update.arrayItems);
|
|
251
|
+
}
|
|
252
|
+
content = normalizeFileContent(content);
|
|
253
|
+
if (content !== normalizeFileContent(originalContent)) {
|
|
254
|
+
await writeGeneratedFile(filePath, content, !!update.dryRun);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
function appendUniqueLines(content, lines, beforeArrayName) {
|
|
258
|
+
const existingLines = new Set(content
|
|
259
|
+
.split(/\r?\n/)
|
|
260
|
+
.map((line) => line.trim())
|
|
261
|
+
.filter(Boolean));
|
|
262
|
+
const missingLines = lines
|
|
263
|
+
.map((line) => line.trim())
|
|
264
|
+
.filter((line) => line.length > 0 && !existingLines.has(line));
|
|
265
|
+
if (!missingLines.length) {
|
|
266
|
+
return content;
|
|
267
|
+
}
|
|
268
|
+
const insertion = `${missingLines.join('\n')}\n`;
|
|
269
|
+
if (beforeArrayName) {
|
|
270
|
+
const arrayPattern = new RegExp(`export const ${escapeRegExp(beforeArrayName)}(:[^=]+)?\\s*=\\s*\\[`);
|
|
271
|
+
const arrayMatch = arrayPattern.exec(content);
|
|
272
|
+
if (arrayMatch?.index !== undefined) {
|
|
273
|
+
const beforeArray = content.slice(0, arrayMatch.index).trimEnd();
|
|
274
|
+
const afterArray = content.slice(arrayMatch.index);
|
|
275
|
+
const prefix = beforeArray.length > 0 ? `${beforeArray}\n` : '';
|
|
276
|
+
return `${prefix}${insertion}${afterArray}`;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
const trimmedContent = content.trimEnd();
|
|
280
|
+
const prefix = trimmedContent.length > 0 ? `${trimmedContent}\n` : '';
|
|
281
|
+
return `${prefix}${insertion}`;
|
|
282
|
+
}
|
|
283
|
+
function mergeExportedArray(content, arrayName, arrayItems) {
|
|
284
|
+
const uniqueItems = [...new Set(arrayItems.map((item) => item.trim()).filter(Boolean))];
|
|
285
|
+
const escapedArrayName = escapeRegExp(arrayName);
|
|
286
|
+
const arrayPattern = new RegExp(`export const ${escapedArrayName}(:[^=]+)?\\s*=\\s*\\[([\\s\\S]*?)\\];`);
|
|
287
|
+
const match = arrayPattern.exec(content);
|
|
288
|
+
if (!match) {
|
|
289
|
+
const arrayContent = uniqueItems.map((item) => ` ${item},`).join('\n');
|
|
290
|
+
return appendUniqueLines(content, [`export const ${arrayName} = [\n${arrayContent}\n];`]);
|
|
291
|
+
}
|
|
292
|
+
const typeAnnotation = match[1] || '';
|
|
293
|
+
const body = match[2] || '';
|
|
294
|
+
const missingItems = uniqueItems.filter((item) => !hasArrayItem(body, item));
|
|
295
|
+
if (!missingItems.length) {
|
|
296
|
+
return content;
|
|
297
|
+
}
|
|
298
|
+
const nextBody = appendArrayItems(body, missingItems);
|
|
299
|
+
const nextArray = `export const ${arrayName}${typeAnnotation} = [${nextBody}];`;
|
|
300
|
+
return content.replace(match[0], nextArray);
|
|
301
|
+
}
|
|
302
|
+
function hasArrayItem(body, item) {
|
|
303
|
+
return new RegExp(`(^|[^A-Za-z0-9_$])${escapeRegExp(item)}([^A-Za-z0-9_$]|$)`).test(body);
|
|
304
|
+
}
|
|
305
|
+
function appendArrayItems(body, missingItems) {
|
|
306
|
+
const linesToAdd = missingItems.map((item) => ` ${item},`).join('\n');
|
|
307
|
+
const trimmedBody = body.trim();
|
|
308
|
+
if (!trimmedBody) {
|
|
309
|
+
return `\n${linesToAdd}\n`;
|
|
310
|
+
}
|
|
311
|
+
if (!body.includes('\n')) {
|
|
312
|
+
return `\n ${trimmedBody.replace(/,\s*$/, '')},\n${linesToAdd}\n`;
|
|
313
|
+
}
|
|
314
|
+
const bodyWithTrailingComma = /,\s*$/.test(body.trimEnd())
|
|
315
|
+
? body.trimEnd()
|
|
316
|
+
: `${body.trimEnd()},`;
|
|
317
|
+
return `${bodyWithTrailingComma}\n${linesToAdd}\n`;
|
|
318
|
+
}
|
|
319
|
+
function normalizeFileContent(content) {
|
|
320
|
+
return content.trimEnd() ? `${content.trimEnd()}\n` : '';
|
|
321
|
+
}
|
|
322
|
+
function escapeRegExp(str) {
|
|
323
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
92
324
|
}
|
|
93
325
|
function getModulePath(basePath, moduleName) {
|
|
94
326
|
return path.join(basePath, 'src', 'modules', (0, naming_utils_1.toKebabCase)(moduleName));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file.utils.js","sourceRoot":"","sources":["../../src/utils/file.utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,kDAaC;AAED,8BAEC;AAED,gCAOC;AAED,8BAGC;AAED,oCAEC;AAED,0CAGC;AAED,oDAQC;AAED,sCAEC;AA9ED,6CAA+B;AAC/B,2CAA6B;AAC7B,4DAAoC;AACpC,iDAA4G;AAqB5G,SAAgB,mBAAmB,CAAC,UAAkB,EAAE,UAAkB;IACxE,OAAO;QACL,UAAU;QACV,gBAAgB,EAAE,IAAA,2BAAY,EAAC,UAAU,CAAC;QAC1C,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QACxC,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QACxC,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QACxC,gBAAgB,EAAE,IAAA,uBAAQ,EAAC,IAAA,2BAAY,EAAC,UAAU,CAAC,CAAC;QACpD,qBAAqB,EAAE,IAAA,0BAAW,EAAC,IAAA,uBAAQ,EAAC,UAAU,CAAC,CAAC;QACxD,SAAS,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QAClC,UAAU;QACV,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;KACzC,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,SAAS,CAAC,OAAe;IAC7C,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,SAAS,CAAC,QAAgB,EAAE,OAAe;IAC/D,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxC,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC;AAEM,KAAK,UAAU,YAAY,CAAC,YAAoB;IACrD,OAAO,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,SAAgB,eAAe,CAAC,QAAgB,EAAE,IAAkB;IAClE,MAAM,gBAAgB,GAAG,oBAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACtD,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAEM,KAAK,UAAU,oBAAoB,CACxC,YAAoB,EACpB,UAAkB,EAClB,IAAkB;IAElB,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAChD,MAAM,SAAS,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,SAAgB,aAAa,CAAC,QAAgB,EAAE,UAAkB;IAChE,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC,CAAC,CAAC;AACxE,CAAC"}
|
|
1
|
+
{"version":3,"file":"file.utils.js","sourceRoot":"","sources":["../../src/utils/file.utils.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkEA,kDAqDC;AAoDD,8BAGC;AAED,gCAQC;AAED,8BAQC;AASD,oCAkBC;AAED,0CAGC;AAED,oDAYC;AAYD,4CAEC;AAED,wCAEC;AAED,sCAMC;AAED,gDAcC;AAUD,4CAsBC;AAgGD,sCAEC;AA5ZD,6CAA+B;AAC/B,2CAA6B;AAC7B,4DAAoC;AACpC,iDAOwB;AACxB,+CAAyF;AAEzF,8BAA8B;AAC9B,oBAAU,CAAC,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC;IAC5C,OAAO,CAAC,KAAK,CAAC,CAAC;AACjB,CAAC,CAAC,CAAC;AAEH,oBAAU,CAAC,cAAc,CAAC,WAAW,EAAE,UAAU,GAAG;IAClD,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AAC3D,CAAC,CAAC,CAAC;AAEH,oBAAU,CAAC,cAAc,CAAC,WAAW,EAAE,UAAU,GAAG;IAClD,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AAC3D,CAAC,CAAC,CAAC;AAEH,oBAAU,CAAC,cAAc,CAAC,YAAY,EAAE,UAAU,GAAG;IACnD,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAA,2BAAY,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC3D,CAAC,CAAC,CAAC;AAEH,oBAAU,CAAC,cAAc,CAAC,WAAW,EAAE,UAAU,GAAG;IAClD,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAA,0BAAW,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC1D,CAAC,CAAC,CAAC;AAEH,oBAAU,CAAC,cAAc,CAAC,WAAW,EAAE,UAAU,GAAG;IAClD,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAA,0BAAW,EAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAC1D,CAAC,CAAC,CAAC;AA8BH,SAAgB,mBAAmB,CACjC,UAAkB,EAClB,UAAkB,EAClB,YAAqB;IAErB,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,IAAA,yBAAW,EAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACrE,MAAM,kBAAkB,GAAG,YAAY,EAAE,MAAM,CAAC,MAAM;QACpD,CAAC,CAAC,IAAA,wCAA0B,EAAC,YAAY,CAAC,MAAM,CAAC;QACjD,CAAC,CAAC,IAAI,CAAC;IAET,2CAA2C;IAC3C,MAAM,cAAc,GAAG,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;IAC9E,MAAM,YAAY,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC;IAE/C,mCAAmC;IACnC,MAAM,eAAe,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAClG,MAAM,eAAe,GACnB,eAAe,CAAC,MAAM,GAAG,CAAC;QACxB,CAAC,CAAC,eAAe;aACZ,GAAG,CACF,CAAC,MAAM,EAAE,EAAE,CACT,YAAY,MAAM,uBAAuB,IAAA,0BAAW,EAAC,MAAO,CAAC,eAAe,CAC/E;aACA,IAAI,CAAC,IAAI,CAAC;QACf,CAAC,CAAC,EAAE,CAAC;IAET,OAAO;QACL,UAAU;QACV,gBAAgB,EAAE,IAAA,2BAAY,EAAC,UAAU,CAAC;QAC1C,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QACxC,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QACxC,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QACxC,gBAAgB,EAAE,IAAA,uBAAQ,EAAC,IAAA,2BAAY,EAAC,UAAU,CAAC,CAAC;QACpD,sBAAsB,EAAE,IAAA,uBAAQ,EAAC,IAAA,2BAAY,EAAC,UAAU,CAAC,CAAC;QAC1D,qBAAqB,EAAE,IAAA,0BAAW,EAAC,IAAA,uBAAQ,EAAC,UAAU,CAAC,CAAC;QACxD,qBAAqB,EAAE,IAAA,0BAAW,EAAC,IAAA,uBAAQ,EAAC,UAAU,CAAC,CAAC;QACxD,SAAS,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QAClC,UAAU,EAAE,IAAA,2BAAY,EAAC,UAAU,CAAC;QACpC,eAAe,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC;QACxC,gBAAgB,EAAE,IAAA,2BAAY,EAAC,UAAU,CAAC;QAC1C,yBAAyB;QACzB,MAAM,EAAE,YAAY,EAAE,MAAM,IAAI,EAAE;QAClC,SAAS,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC;QACjD,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,IAAI,EAAE;QAC5D,oBAAoB,EAAE,kBAAkB,EAAE,oBAAoB,IAAI,EAAE;QACpE,aAAa,EAAE,kBAAkB,EAAE,aAAa,IAAI,EAAE;QACtD,UAAU,EAAE,kBAAkB,EAAE,UAAU,IAAI,EAAE;QAChD,gBAAgB,EAAE,kBAAkB,EAAE,gBAAgB,IAAI,EAAE;QAC5D,kBAAkB,EAAE,kBAAkB,EAAE,kBAAkB,IAAI,EAAE;QAChE,sBAAsB;QACtB,YAAY;QACZ,eAAe;KAChB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CAAC,UAAkB,EAAE,QAAiB;IACzD,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;IAED,oDAAoD;IACpD,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC7C,CAAC;IAED,oCAAoC;IACpC,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,IAAI,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,iEAAiE;QACjE,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAE1C,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IAED,+CAA+C;IAC/C,MAAM,eAAe,GAAG;QACtB,WAAW;QACX,YAAY;QACZ,WAAW;QACX,WAAW;QACX,YAAY;QACZ,eAAe;QACf,qBAAqB;QACrB,SAAS;QACT,UAAU;QACV,UAAU;QACV,SAAS;QACT,SAAS;QACT,SAAS;KACV,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACtC,IAAI,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,8BAA8B,cAAc,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,SAAS,CAAC,OAAe;IAC7C,YAAY,CAAC,OAAO,CAAC,CAAC;IACtB,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AAC9B,CAAC;AAEM,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,IAAI,CAAC;QACH,YAAY,CAAC,QAAQ,CAAC,CAAC;QACvB,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,SAAS,CAAC,QAAgB,EAAE,OAAe;IAC/D,YAAY,CAAC,QAAQ,CAAC,CAAC;IAEvB,qDAAqD;IACrD,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAE7B,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IACxC,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAe;IAC1C,MAAM,cAAc,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,WAAW;IACpD,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,cAAc,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,mCAAmC,cAAc,QAAQ,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC;AAEM,KAAK,UAAU,YAAY,CAAC,YAAoB;IACrD,YAAY,CAAC,YAAY,CAAC,CAAC;IAE3B,8CAA8C;IAC9C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1C,MAAM,eAAe,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,wBAAwB;QAC7D,IAAI,KAAK,CAAC,IAAI,GAAG,eAAe,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,yCAAyC,eAAe,QAAQ,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,4BAA4B,YAAY,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IAED,OAAO,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,SAAgB,eAAe,CAAC,QAAgB,EAAE,IAAkB;IAClE,MAAM,gBAAgB,GAAG,oBAAU,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1E,OAAO,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAChC,CAAC;AAEM,KAAK,UAAU,oBAAoB,CACxC,YAAoB,EACpB,UAAkB,EAClB,IAAkB,EAClB,MAAM,GAAG,KAAK;IAEd,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAEhD,MAAM,kBAAkB,CAAC,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAEtD,OAAO,UAAU,CAAC;AACpB,CAAC;AAUD,IAAI,WAAW,GAAmB,EAAE,CAAC;AAErC,SAAgB,gBAAgB;IAC9B,WAAW,GAAG,EAAE,CAAC;AACnB,CAAC;AAED,SAAgB,cAAc;IAC5B,OAAO,CAAC,GAAG,WAAW,CAAC,CAAC;AAC1B,CAAC;AAED,SAAgB,aAAa,CAAC,QAAgB,EAAE,SAAuB,QAAQ;IAC7E,IAAI,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC,EAAE,CAAC;QAC/D,OAAO;IACT,CAAC;IAED,WAAW,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;AACzC,CAAC;AAEM,KAAK,UAAU,kBAAkB,CACtC,QAAgB,EAChB,OAAe,EACf,MAAM,GAAG,KAAK;IAEd,YAAY,CAAC,QAAQ,CAAC,CAAC;IACvB,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAE7B,IAAI,MAAM,EAAE,CAAC;QACX,aAAa,CAAC,QAAQ,EAAE,CAAC,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC5E,OAAO;IACT,CAAC;IAED,MAAM,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AACrC,CAAC;AAUM,KAAK,UAAU,gBAAgB,CAAC,QAAgB,EAAE,MAAwB;IAC/E,YAAY,CAAC,QAAQ,CAAC,CAAC;IAEvB,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,MAAM,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC/B,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,eAAe,GAAG,OAAO,CAAC;IAEhC,OAAO,GAAG,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7E,OAAO,GAAG,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAE7E,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC;QAClD,OAAO,GAAG,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAExC,IAAI,OAAO,KAAK,oBAAoB,CAAC,eAAe,CAAC,EAAE,CAAC;QACtD,MAAM,kBAAkB,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAe,EAAE,KAAe,EAAE,eAAwB;IACnF,MAAM,aAAa,GAAG,IAAI,GAAG,CAC3B,OAAO;SACJ,KAAK,CAAC,OAAO,CAAC;SACd,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,OAAO,CAAC,CACnB,CAAC;IACF,MAAM,YAAY,GAAG,KAAK;SACvB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAC1B,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;IAEjE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,SAAS,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAEjD,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,YAAY,GAAG,IAAI,MAAM,CAC7B,gBAAgB,YAAY,CAAC,eAAe,CAAC,uBAAuB,CACrE,CAAC;QACF,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAE9C,IAAI,UAAU,EAAE,KAAK,KAAK,SAAS,EAAE,CAAC;YACpC,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;YACjE,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAChE,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,EAAE,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,cAAc,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,OAAO,GAAG,MAAM,GAAG,SAAS,EAAE,CAAC;AACjC,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAe,EAAE,SAAiB,EAAE,UAAoB;IAClF,MAAM,WAAW,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACxF,MAAM,gBAAgB,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,YAAY,GAAG,IAAI,MAAM,CAC7B,gBAAgB,gBAAgB,uCAAuC,CACxE,CAAC;IACF,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAEzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxE,OAAO,iBAAiB,CAAC,OAAO,EAAE,CAAC,gBAAgB,SAAS,SAAS,YAAY,MAAM,CAAC,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC5B,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAE7E,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,gBAAgB,SAAS,GAAG,cAAc,OAAO,QAAQ,IAAI,CAAC;IAEhF,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;AAC9C,CAAC;AAED,SAAS,YAAY,CAAC,IAAY,EAAE,IAAY;IAC9C,OAAO,IAAI,MAAM,CAAC,qBAAqB,YAAY,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC5F,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY,EAAE,YAAsB;IAC5D,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvE,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAEhC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,KAAK,UAAU,IAAI,CAAC;IAC7B,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,OAAO,OAAO,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,UAAU,IAAI,CAAC;IACrE,CAAC;IAED,MAAM,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACxD,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE;QAChB,CAAC,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC;IAEzB,OAAO,GAAG,qBAAqB,KAAK,UAAU,IAAI,CAAC;AACrD,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAe;IAC3C,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3D,CAAC;AAED,SAAS,YAAY,CAAC,GAAW;IAC/B,OAAO,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AACpD,CAAC;AAED,SAAgB,aAAa,CAAC,QAAgB,EAAE,UAAkB;IAChE,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAA,0BAAW,EAAC,UAAU,CAAC,CAAC,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Idempotency & Consistency System
|
|
3
|
+
* Tracks generated files and ensures safe re-generation
|
|
4
|
+
*/
|
|
5
|
+
export interface GenerationManifest {
|
|
6
|
+
version: string;
|
|
7
|
+
generatedAt: string;
|
|
8
|
+
lastModified: string;
|
|
9
|
+
generator: string;
|
|
10
|
+
entities: EntityManifest[];
|
|
11
|
+
files: FileManifest[];
|
|
12
|
+
checksums: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
export interface EntityManifest {
|
|
15
|
+
name: string;
|
|
16
|
+
module: string;
|
|
17
|
+
fields: string[];
|
|
18
|
+
relations: string[];
|
|
19
|
+
generatedFiles: string[];
|
|
20
|
+
hash: string;
|
|
21
|
+
generatedAt: string;
|
|
22
|
+
}
|
|
23
|
+
export interface FileManifest {
|
|
24
|
+
path: string;
|
|
25
|
+
type: 'entity' | 'dto' | 'service' | 'controller' | 'repository' | 'module' | 'test' | 'other';
|
|
26
|
+
entity?: string;
|
|
27
|
+
module?: string;
|
|
28
|
+
hash: string;
|
|
29
|
+
generatedAt: string;
|
|
30
|
+
modifiedAt?: string;
|
|
31
|
+
isModified: boolean;
|
|
32
|
+
mergeStrategy: MergeStrategy;
|
|
33
|
+
}
|
|
34
|
+
export type MergeStrategy = 'overwrite' | 'skip' | 'merge' | 'backup' | 'prompt';
|
|
35
|
+
export interface GenerationPlan {
|
|
36
|
+
create: FileOperation[];
|
|
37
|
+
update: FileOperation[];
|
|
38
|
+
skip: FileOperation[];
|
|
39
|
+
conflict: FileOperation[];
|
|
40
|
+
}
|
|
41
|
+
export interface FileOperation {
|
|
42
|
+
path: string;
|
|
43
|
+
action: 'create' | 'update' | 'skip' | 'conflict' | 'backup';
|
|
44
|
+
reason?: string;
|
|
45
|
+
content?: string;
|
|
46
|
+
existingHash?: string;
|
|
47
|
+
newHash?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Load or create generation manifest
|
|
51
|
+
*/
|
|
52
|
+
export declare function loadManifest(basePath: string): GenerationManifest;
|
|
53
|
+
/**
|
|
54
|
+
* Create an empty manifest
|
|
55
|
+
*/
|
|
56
|
+
export declare function createEmptyManifest(): GenerationManifest;
|
|
57
|
+
/**
|
|
58
|
+
* Save manifest to disk
|
|
59
|
+
*/
|
|
60
|
+
export declare function saveManifest(basePath: string, manifest: GenerationManifest): void;
|
|
61
|
+
/**
|
|
62
|
+
* Calculate file hash
|
|
63
|
+
*/
|
|
64
|
+
export declare function calculateHash(content: string): string;
|
|
65
|
+
/**
|
|
66
|
+
* Check if a file has been manually modified
|
|
67
|
+
*/
|
|
68
|
+
export declare function isFileModified(filePath: string, manifest: GenerationManifest): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Plan generation operations with conflict detection
|
|
71
|
+
*/
|
|
72
|
+
export declare function planGeneration(basePath: string, filesToGenerate: Array<{
|
|
73
|
+
path: string;
|
|
74
|
+
content: string;
|
|
75
|
+
type: FileManifest['type'];
|
|
76
|
+
}>, manifest: GenerationManifest, options?: {
|
|
77
|
+
mergeStrategy?: MergeStrategy;
|
|
78
|
+
force?: boolean;
|
|
79
|
+
}): GenerationPlan;
|
|
80
|
+
/**
|
|
81
|
+
* Execute a generation plan
|
|
82
|
+
*/
|
|
83
|
+
export declare function executePlan(basePath: string, plan: GenerationPlan, manifest: GenerationManifest): {
|
|
84
|
+
success: boolean;
|
|
85
|
+
created: number;
|
|
86
|
+
updated: number;
|
|
87
|
+
skipped: number;
|
|
88
|
+
errors: string[];
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Backup a file before overwriting
|
|
92
|
+
*/
|
|
93
|
+
export declare function backupFile(basePath: string, filePath: string): string;
|
|
94
|
+
/**
|
|
95
|
+
* Restore a file from backup
|
|
96
|
+
*/
|
|
97
|
+
export declare function restoreFile(basePath: string, filePath: string, backupTimestamp?: string): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Register an entity in the manifest
|
|
100
|
+
*/
|
|
101
|
+
export declare function registerEntity(manifest: GenerationManifest, entity: {
|
|
102
|
+
name: string;
|
|
103
|
+
module: string;
|
|
104
|
+
fields: string[];
|
|
105
|
+
relations: string[];
|
|
106
|
+
generatedFiles: string[];
|
|
107
|
+
}): void;
|
|
108
|
+
/**
|
|
109
|
+
* Check if an entity was previously generated
|
|
110
|
+
*/
|
|
111
|
+
export declare function wasEntityGenerated(manifest: GenerationManifest, entityName: string, moduleName: string): boolean;
|
|
112
|
+
/**
|
|
113
|
+
* Get entity manifest
|
|
114
|
+
*/
|
|
115
|
+
export declare function getEntityManifest(manifest: GenerationManifest, entityName: string, moduleName: string): EntityManifest | undefined;
|
|
116
|
+
/**
|
|
117
|
+
* Clean up old backups (keep last N)
|
|
118
|
+
*/
|
|
119
|
+
export declare function cleanupBackups(basePath: string, keepLast?: number): number;
|
|
120
|
+
/**
|
|
121
|
+
* Generate a summary of what will change
|
|
122
|
+
*/
|
|
123
|
+
export declare function summarizePlan(plan: GenerationPlan): string;
|