@currentjs/gen 0.3.2 → 0.5.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +10 -611
  2. package/README.md +623 -427
  3. package/dist/cli.js +2 -1
  4. package/dist/commands/commit.js +25 -42
  5. package/dist/commands/createApp.js +1 -0
  6. package/dist/commands/createModule.js +151 -45
  7. package/dist/commands/diff.js +27 -40
  8. package/dist/commands/generateAll.js +141 -291
  9. package/dist/commands/migrateCommit.js +6 -18
  10. package/dist/commands/migratePush.d.ts +1 -0
  11. package/dist/commands/migratePush.js +135 -0
  12. package/dist/commands/migrateUpdate.d.ts +1 -0
  13. package/dist/commands/migrateUpdate.js +147 -0
  14. package/dist/commands/newGenerateAll.d.ts +4 -0
  15. package/dist/commands/newGenerateAll.js +336 -0
  16. package/dist/generators/controllerGenerator.d.ts +43 -19
  17. package/dist/generators/controllerGenerator.js +547 -329
  18. package/dist/generators/domainLayerGenerator.d.ts +21 -0
  19. package/dist/generators/domainLayerGenerator.js +276 -0
  20. package/dist/generators/dtoGenerator.d.ts +21 -0
  21. package/dist/generators/dtoGenerator.js +518 -0
  22. package/dist/generators/newControllerGenerator.d.ts +55 -0
  23. package/dist/generators/newControllerGenerator.js +644 -0
  24. package/dist/generators/newServiceGenerator.d.ts +19 -0
  25. package/dist/generators/newServiceGenerator.js +266 -0
  26. package/dist/generators/newStoreGenerator.d.ts +39 -0
  27. package/dist/generators/newStoreGenerator.js +408 -0
  28. package/dist/generators/newTemplateGenerator.d.ts +29 -0
  29. package/dist/generators/newTemplateGenerator.js +510 -0
  30. package/dist/generators/serviceGenerator.d.ts +16 -51
  31. package/dist/generators/serviceGenerator.js +167 -586
  32. package/dist/generators/storeGenerator.d.ts +35 -32
  33. package/dist/generators/storeGenerator.js +291 -238
  34. package/dist/generators/storeGeneratorV2.d.ts +31 -0
  35. package/dist/generators/storeGeneratorV2.js +190 -0
  36. package/dist/generators/templateGenerator.d.ts +21 -21
  37. package/dist/generators/templateGenerator.js +393 -268
  38. package/dist/generators/templates/appTemplates.d.ts +3 -1
  39. package/dist/generators/templates/appTemplates.js +15 -10
  40. package/dist/generators/templates/data/appYamlTemplate +5 -2
  41. package/dist/generators/templates/data/cursorRulesTemplate +315 -221
  42. package/dist/generators/templates/data/frontendScriptTemplate +45 -11
  43. package/dist/generators/templates/data/mainViewTemplate +1 -1
  44. package/dist/generators/templates/data/systemTsTemplate +5 -0
  45. package/dist/generators/templates/index.d.ts +0 -3
  46. package/dist/generators/templates/index.js +0 -3
  47. package/dist/generators/templates/newStoreTemplates.d.ts +5 -0
  48. package/dist/generators/templates/newStoreTemplates.js +141 -0
  49. package/dist/generators/templates/storeTemplates.d.ts +1 -5
  50. package/dist/generators/templates/storeTemplates.js +102 -219
  51. package/dist/generators/templates/viewTemplates.js +1 -1
  52. package/dist/generators/useCaseGenerator.d.ts +13 -0
  53. package/dist/generators/useCaseGenerator.js +188 -0
  54. package/dist/types/configTypes.d.ts +148 -0
  55. package/dist/types/configTypes.js +10 -0
  56. package/dist/utils/childEntityUtils.d.ts +18 -0
  57. package/dist/utils/childEntityUtils.js +78 -0
  58. package/dist/utils/commandUtils.d.ts +43 -0
  59. package/dist/utils/commandUtils.js +124 -0
  60. package/dist/utils/commitUtils.d.ts +4 -1
  61. package/dist/utils/constants.d.ts +10 -0
  62. package/dist/utils/constants.js +13 -1
  63. package/dist/utils/diResolver.d.ts +32 -0
  64. package/dist/utils/diResolver.js +204 -0
  65. package/dist/utils/new_parts_of_migrationUtils.d.ts +0 -0
  66. package/dist/utils/new_parts_of_migrationUtils.js +164 -0
  67. package/dist/utils/typeUtils.d.ts +19 -0
  68. package/dist/utils/typeUtils.js +70 -0
  69. package/package.json +7 -3
@@ -0,0 +1,13 @@
1
+ import { ModuleConfig } from '../types/configTypes';
2
+ export declare class UseCaseGenerator {
3
+ private availableAggregates;
4
+ private generateUseCaseMethod;
5
+ private generateGetResourceOwnerMethod;
6
+ private generateUseCase;
7
+ generateFromConfig(config: ModuleConfig): Record<string, string>;
8
+ generateFromYamlFile(yamlFilePath: string): Record<string, string>;
9
+ generateAndSaveFiles(yamlFilePath: string, moduleDir: string, opts?: {
10
+ force?: boolean;
11
+ skipOnConflict?: boolean;
12
+ }): Promise<void>;
13
+ }
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.UseCaseGenerator = void 0;
37
+ const yaml_1 = require("yaml");
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const generationRegistry_1 = require("../utils/generationRegistry");
41
+ const colors_1 = require("../utils/colors");
42
+ const configTypes_1 = require("../types/configTypes");
43
+ const typeUtils_1 = require("../utils/typeUtils");
44
+ class UseCaseGenerator {
45
+ constructor() {
46
+ this.availableAggregates = new Map();
47
+ }
48
+ generateUseCaseMethod(modelName, actionName, useCaseConfig) {
49
+ const methodName = actionName;
50
+ const inputType = `${modelName}${(0, typeUtils_1.capitalize)(actionName)}Input`;
51
+ // Determine the return type based on action
52
+ let returnType;
53
+ if (useCaseConfig.output === 'void') {
54
+ returnType = '{ success: boolean; message: string }';
55
+ }
56
+ else if (actionName === 'list') {
57
+ returnType = `{ items: ${modelName}[]; total: number; page: number; limit: number }`;
58
+ }
59
+ else {
60
+ returnType = modelName;
61
+ }
62
+ // Generate handler calls
63
+ const handlerCalls = useCaseConfig.handlers.map((handler, index) => {
64
+ var _a;
65
+ const isLast = index === useCaseConfig.handlers.length - 1;
66
+ if (handler.startsWith('default:')) {
67
+ // Default handler - call service method directly
68
+ const defaultAction = handler.replace('default:', '');
69
+ const resultVar = isLast ? 'result' : `result${index}`;
70
+ // Determine parameters based on action
71
+ let params = '';
72
+ if (defaultAction === 'list') {
73
+ params = ((_a = useCaseConfig.input) === null || _a === void 0 ? void 0 : _a.pagination)
74
+ ? 'input.page || 1, input.limit || 20'
75
+ : '';
76
+ }
77
+ else if (defaultAction === 'get') {
78
+ params = 'input.id';
79
+ }
80
+ else if (defaultAction === 'create') {
81
+ params = 'input';
82
+ }
83
+ else if (defaultAction === 'update') {
84
+ params = 'input.id, input';
85
+ }
86
+ else if (defaultAction === 'delete') {
87
+ params = 'input.id';
88
+ }
89
+ else {
90
+ params = 'input';
91
+ }
92
+ return ` const ${resultVar} = await this.${modelName.toLowerCase()}Service.${defaultAction}(${params});`;
93
+ }
94
+ else {
95
+ // Custom handler
96
+ const prevResult = index === 0 ? 'null' : `result${index - 1}`;
97
+ const resultVar = isLast ? 'result' : `result${index}`;
98
+ return ` const ${resultVar} = await this.${modelName.toLowerCase()}Service.${handler}(${prevResult}, input);`;
99
+ }
100
+ }).join('\n');
101
+ const returnStatement = '\n return result;';
102
+ return ` async ${methodName}(input: ${inputType}): Promise<${returnType}> {
103
+ ${handlerCalls}${returnStatement}
104
+ }`;
105
+ }
106
+ generateGetResourceOwnerMethod(modelName) {
107
+ const serviceVar = `${modelName.toLowerCase()}Service`;
108
+ return `
109
+ /**
110
+ * Get the owner ID of a resource by its ID.
111
+ * Used for pre-mutation authorization checks in controllers.
112
+ */
113
+ async getResourceOwner(id: number): Promise<number | null> {
114
+ return await this.${serviceVar}.getResourceOwner(id);
115
+ }`;
116
+ }
117
+ generateUseCase(modelName, useCases) {
118
+ const className = `${modelName}UseCase`;
119
+ const serviceName = `${modelName}Service`;
120
+ const serviceVar = `${modelName.toLowerCase()}Service`;
121
+ // Generate imports for DTOs (only Input types since UseCases return models)
122
+ const dtoImports = Object.keys(useCases)
123
+ .map(actionName => {
124
+ const inputType = `${modelName}${(0, typeUtils_1.capitalize)(actionName)}Input`;
125
+ return `import { ${inputType} } from '../dto/${modelName}${(0, typeUtils_1.capitalize)(actionName)}';`;
126
+ })
127
+ .join('\n');
128
+ // Generate methods
129
+ const methods = Object.entries(useCases)
130
+ .map(([actionName, useCaseConfig]) => this.generateUseCaseMethod(modelName, actionName, useCaseConfig))
131
+ .join('\n\n');
132
+ const getResourceOwnerMethod = this.generateGetResourceOwnerMethod(modelName);
133
+ return `import { Injectable } from '../../../../system';
134
+ import { ${modelName} } from '../../domain/entities/${modelName}';
135
+ ${dtoImports}
136
+ import { ${serviceName} } from '../services/${serviceName}';
137
+
138
+ /**
139
+ * Use Case orchestrator for ${modelName}
140
+ * Coordinates business logic by calling service handlers in sequence
141
+ */
142
+ @Injectable()
143
+ export class ${className} {
144
+ constructor(
145
+ private ${serviceVar}: ${serviceName}
146
+ ) {}
147
+
148
+ ${methods}${getResourceOwnerMethod}
149
+ }`;
150
+ }
151
+ generateFromConfig(config) {
152
+ var _a;
153
+ const result = {};
154
+ // Collect all aggregates to know which are roots
155
+ this.availableAggregates.clear();
156
+ if ((_a = config.domain) === null || _a === void 0 ? void 0 : _a.aggregates) {
157
+ Object.entries(config.domain.aggregates).forEach(([name, aggConfig]) => {
158
+ this.availableAggregates.set(name, aggConfig);
159
+ });
160
+ }
161
+ // Generate a UseCase file for each model
162
+ Object.entries(config.useCases).forEach(([modelName, useCases]) => {
163
+ result[modelName] = this.generateUseCase(modelName, useCases);
164
+ });
165
+ return result;
166
+ }
167
+ generateFromYamlFile(yamlFilePath) {
168
+ const yamlContent = fs.readFileSync(yamlFilePath, 'utf8');
169
+ const config = (0, yaml_1.parse)(yamlContent);
170
+ if (!(0, configTypes_1.isValidModuleConfig)(config)) {
171
+ throw new Error('Configuration does not match new module format. Expected useCases structure.');
172
+ }
173
+ return this.generateFromConfig(config);
174
+ }
175
+ async generateAndSaveFiles(yamlFilePath, moduleDir, opts) {
176
+ const useCasesByModel = this.generateFromYamlFile(yamlFilePath);
177
+ const useCasesDir = path.join(moduleDir, 'application', 'useCases');
178
+ fs.mkdirSync(useCasesDir, { recursive: true });
179
+ for (const [modelName, code] of Object.entries(useCasesByModel)) {
180
+ const filePath = path.join(useCasesDir, `${modelName}UseCase.ts`);
181
+ // eslint-disable-next-line no-await-in-loop
182
+ await (0, generationRegistry_1.writeGeneratedFile)(filePath, code, { force: !!(opts === null || opts === void 0 ? void 0 : opts.force), skipOnConflict: !!(opts === null || opts === void 0 ? void 0 : opts.skipOnConflict) });
183
+ }
184
+ // eslint-disable-next-line no-console
185
+ console.log('\n' + colors_1.colors.green('Use Case files generated successfully!') + '\n');
186
+ }
187
+ }
188
+ exports.UseCaseGenerator = UseCaseGenerator;
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Type definitions for the Clean Architecture module configuration
3
+ */
4
+ export interface FieldDefinition {
5
+ type: string;
6
+ constraints?: {
7
+ min?: number;
8
+ max?: number;
9
+ pattern?: string;
10
+ unique?: boolean;
11
+ };
12
+ }
13
+ export interface ValueObjectConfig {
14
+ fields: Record<string, FieldDefinition | {
15
+ type: string;
16
+ values: string[];
17
+ }>;
18
+ }
19
+ export interface AggregateFieldConfig {
20
+ type: string;
21
+ required?: boolean;
22
+ unique?: boolean;
23
+ auto?: boolean;
24
+ values?: string[];
25
+ }
26
+ export interface AggregateConfig {
27
+ root?: boolean;
28
+ fields: Record<string, AggregateFieldConfig>;
29
+ entities?: string[];
30
+ }
31
+ export interface DomainConfig {
32
+ aggregates: Record<string, AggregateConfig>;
33
+ valueObjects?: Record<string, ValueObjectConfig>;
34
+ }
35
+ export interface PaginationConfig {
36
+ type: 'cursor' | 'offset';
37
+ defaults?: {
38
+ limit?: number;
39
+ maxLimit?: number;
40
+ };
41
+ }
42
+ export interface FilterFieldConfig {
43
+ type: string;
44
+ enum?: string[];
45
+ optional?: boolean;
46
+ searchIn?: string[];
47
+ }
48
+ export interface SortingConfig {
49
+ allow: string[];
50
+ default?: {
51
+ field: string;
52
+ order: 'asc' | 'desc';
53
+ };
54
+ }
55
+ /** Additional input field definition (type only; used in add) */
56
+ export interface UseCaseInputAddField {
57
+ type: string;
58
+ source?: string;
59
+ }
60
+ export interface UseCaseInputConfig {
61
+ from?: string;
62
+ pick?: string[];
63
+ omit?: string[];
64
+ add?: Record<string, UseCaseInputAddField>;
65
+ validate?: Record<string, unknown>;
66
+ identifier?: string;
67
+ partial?: boolean;
68
+ pagination?: PaginationConfig;
69
+ filters?: Record<string, FilterFieldConfig>;
70
+ sorting?: SortingConfig;
71
+ parentId?: string;
72
+ }
73
+ export interface UseCaseOutputInclude {
74
+ from: string;
75
+ pick?: string[];
76
+ }
77
+ export interface UseCaseOutputConfig {
78
+ from?: string;
79
+ pick?: string[];
80
+ include?: Record<string, UseCaseOutputInclude>;
81
+ add?: Record<string, {
82
+ type: string;
83
+ source?: string;
84
+ }>;
85
+ pagination?: boolean;
86
+ }
87
+ export interface UseCaseDefinition {
88
+ input?: UseCaseInputConfig;
89
+ output?: UseCaseOutputConfig | 'void';
90
+ handlers: string[];
91
+ withChild?: boolean;
92
+ }
93
+ export interface UseCasesConfig {
94
+ [modelName: string]: {
95
+ [actionName: string]: UseCaseDefinition;
96
+ };
97
+ }
98
+ /**
99
+ * Auth configuration for endpoints.
100
+ * Can be:
101
+ * - 'all': Public access (no authentication required)
102
+ * - 'authenticated': Any logged-in user
103
+ * - 'owner': User must own the resource (checks owner_id field)
104
+ * - string (e.g., 'admin', 'editor'): User must have this role
105
+ * - string[] (e.g., ['owner', 'admin']): User must match ANY of these (OR logic)
106
+ */
107
+ export type AuthConfig = 'all' | 'authenticated' | 'owner' | string | string[];
108
+ export interface ApiEndpointConfig {
109
+ method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
110
+ path: string;
111
+ useCase: string;
112
+ auth?: AuthConfig;
113
+ }
114
+ export interface ApiResourceConfig {
115
+ prefix: string;
116
+ endpoints: ApiEndpointConfig[];
117
+ }
118
+ export type ApiConfig = Record<string, ApiResourceConfig>;
119
+ export interface WebPageConfig {
120
+ path: string;
121
+ method?: 'GET' | 'POST';
122
+ useCase?: string;
123
+ view?: string;
124
+ auth?: AuthConfig;
125
+ onSuccess?: {
126
+ redirect?: string;
127
+ toast?: string;
128
+ back?: boolean;
129
+ stay?: boolean;
130
+ };
131
+ onError?: {
132
+ stay?: boolean;
133
+ toast?: string | 'error';
134
+ };
135
+ }
136
+ export interface WebResourceConfig {
137
+ prefix: string;
138
+ layout?: string;
139
+ pages: WebPageConfig[];
140
+ }
141
+ export type WebConfig = Record<string, WebResourceConfig>;
142
+ export interface ModuleConfig {
143
+ domain: DomainConfig;
144
+ useCases: UseCasesConfig;
145
+ api?: ApiConfig;
146
+ web?: WebConfig;
147
+ }
148
+ export declare function isValidModuleConfig(config: any): config is ModuleConfig;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ /**
3
+ * Type definitions for the Clean Architecture module configuration
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.isValidModuleConfig = isValidModuleConfig;
7
+ // Type guard to validate module config (domain + useCases)
8
+ function isValidModuleConfig(config) {
9
+ return config && typeof config === 'object' && 'domain' in config && 'useCases' in config;
10
+ }
@@ -0,0 +1,18 @@
1
+ import { ModuleConfig, AggregateFieldConfig } from '../types/configTypes';
2
+ export interface ChildEntityInfo {
3
+ parentEntityName: string;
4
+ parentIdField: string;
5
+ parentTableName: string;
6
+ }
7
+ export interface ParentChildInfo {
8
+ childEntityName: string;
9
+ parentIdField: string;
10
+ childFields: Record<string, AggregateFieldConfig>;
11
+ childWebPrefix?: string;
12
+ }
13
+ export declare function buildChildEntityMap(config: ModuleConfig): Map<string, ChildEntityInfo>;
14
+ /**
15
+ * Returns all child entities of a given parent aggregate, with field definitions and web prefix.
16
+ * Used by template and controller generators when withChild is true.
17
+ */
18
+ export declare function getChildrenOfParent(config: ModuleConfig, parentName: string): ParentChildInfo[];
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildChildEntityMap = buildChildEntityMap;
4
+ exports.getChildrenOfParent = getChildrenOfParent;
5
+ function buildChildEntityMap(config) {
6
+ var _a;
7
+ const map = new Map();
8
+ if (!((_a = config.domain) === null || _a === void 0 ? void 0 : _a.aggregates) || !config.useCases) {
9
+ return map;
10
+ }
11
+ const aggregates = config.domain.aggregates;
12
+ Object.entries(aggregates).forEach(([parentName, aggregateConfig]) => {
13
+ const entities = aggregateConfig.entities || [];
14
+ entities.forEach(childName => {
15
+ const childUseCases = config.useCases[childName];
16
+ if (!childUseCases) {
17
+ return;
18
+ }
19
+ let parentIdField;
20
+ Object.values(childUseCases).forEach(useCaseDef => {
21
+ const input = useCaseDef.input;
22
+ if (input && typeof input.parentId === 'string' && !parentIdField) {
23
+ parentIdField = input.parentId;
24
+ }
25
+ });
26
+ if (!parentIdField) {
27
+ return;
28
+ }
29
+ map.set(childName, {
30
+ parentEntityName: parentName,
31
+ parentIdField,
32
+ parentTableName: parentName.toLowerCase(),
33
+ });
34
+ });
35
+ });
36
+ return map;
37
+ }
38
+ /**
39
+ * Returns all child entities of a given parent aggregate, with field definitions and web prefix.
40
+ * Used by template and controller generators when withChild is true.
41
+ */
42
+ function getChildrenOfParent(config, parentName) {
43
+ var _a, _b, _c, _d;
44
+ const result = [];
45
+ if (!((_a = config.domain) === null || _a === void 0 ? void 0 : _a.aggregates) || !config.useCases) {
46
+ return result;
47
+ }
48
+ const parentAggregate = config.domain.aggregates[parentName];
49
+ if (!((_b = parentAggregate === null || parentAggregate === void 0 ? void 0 : parentAggregate.entities) === null || _b === void 0 ? void 0 : _b.length)) {
50
+ return result;
51
+ }
52
+ for (const childName of parentAggregate.entities) {
53
+ const childUseCases = config.useCases[childName];
54
+ if (!childUseCases)
55
+ continue;
56
+ let parentIdField;
57
+ for (const useCaseDef of Object.values(childUseCases)) {
58
+ const input = useCaseDef.input;
59
+ if (input === null || input === void 0 ? void 0 : input.parentId) {
60
+ parentIdField = input.parentId;
61
+ break;
62
+ }
63
+ }
64
+ if (!parentIdField)
65
+ continue;
66
+ const childAggregate = config.domain.aggregates[childName];
67
+ if (!(childAggregate === null || childAggregate === void 0 ? void 0 : childAggregate.fields))
68
+ continue;
69
+ const childWebPrefix = (_d = (_c = config.web) === null || _c === void 0 ? void 0 : _c[childName]) === null || _d === void 0 ? void 0 : _d.prefix;
70
+ result.push({
71
+ childEntityName: childName,
72
+ parentIdField,
73
+ childFields: childAggregate.fields,
74
+ childWebPrefix,
75
+ });
76
+ }
77
+ return result;
78
+ }
@@ -0,0 +1,43 @@
1
+ import { DomainLayerGenerator } from '../generators/domainLayerGenerator';
2
+ import { DtoGenerator } from '../generators/dtoGenerator';
3
+ import { UseCaseGenerator } from '../generators/useCaseGenerator';
4
+ import { ServiceGenerator } from '../generators/serviceGenerator';
5
+ import { ControllerGenerator } from '../generators/controllerGenerator';
6
+ import { StoreGenerator } from '../generators/storeGenerator';
7
+ import { TemplateGenerator } from '../generators/templateGenerator';
8
+ export interface ModuleEntry {
9
+ path: string;
10
+ database?: string;
11
+ styling?: string;
12
+ identifiers?: string;
13
+ }
14
+ export interface GlobalConfig {
15
+ database?: string;
16
+ styling?: string;
17
+ identifiers?: string;
18
+ }
19
+ export interface AppConfig {
20
+ providers?: Record<string, string>;
21
+ config?: GlobalConfig;
22
+ modules: Record<string, ModuleEntry>;
23
+ }
24
+ export declare function loadAppConfig(yamlPath: string): AppConfig;
25
+ export declare function getModuleList(config: AppConfig): string[];
26
+ export interface ModuleEntryResolved {
27
+ name: string;
28
+ path: string;
29
+ database: string;
30
+ styling: string;
31
+ identifiers: string;
32
+ }
33
+ export declare function getModuleEntries(config: AppConfig): ModuleEntryResolved[];
34
+ export declare function shouldIncludeModule(moduleYamlRel: string, moduleName?: string): boolean;
35
+ export declare function createGenerators(): {
36
+ domainGen: DomainLayerGenerator;
37
+ dtoGen: DtoGenerator;
38
+ useCaseGen: UseCaseGenerator;
39
+ serviceGen: ServiceGenerator;
40
+ controllerGen: ControllerGenerator;
41
+ templateGen: TemplateGenerator;
42
+ storeGen: StoreGenerator;
43
+ };
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.loadAppConfig = loadAppConfig;
37
+ exports.getModuleList = getModuleList;
38
+ exports.getModuleEntries = getModuleEntries;
39
+ exports.shouldIncludeModule = shouldIncludeModule;
40
+ exports.createGenerators = createGenerators;
41
+ /**
42
+ * Shared command infrastructure: app config loading, module filtering, generator creation.
43
+ */
44
+ const fs = __importStar(require("fs"));
45
+ const path = __importStar(require("path"));
46
+ const yaml_1 = require("yaml");
47
+ const domainLayerGenerator_1 = require("../generators/domainLayerGenerator");
48
+ const dtoGenerator_1 = require("../generators/dtoGenerator");
49
+ const useCaseGenerator_1 = require("../generators/useCaseGenerator");
50
+ const serviceGenerator_1 = require("../generators/serviceGenerator");
51
+ const controllerGenerator_1 = require("../generators/controllerGenerator");
52
+ const storeGenerator_1 = require("../generators/storeGenerator");
53
+ const templateGenerator_1 = require("../generators/templateGenerator");
54
+ const DEFAULT_DATABASE = 'mysql';
55
+ const DEFAULT_STYLING = 'bootstrap';
56
+ const DEFAULT_IDENTIFIERS = 'id';
57
+ function loadAppConfig(yamlPath) {
58
+ const raw = fs.readFileSync(yamlPath, 'utf8');
59
+ const parsed = (0, yaml_1.parse)(raw);
60
+ if (!parsed || typeof parsed !== 'object') {
61
+ return { modules: {} };
62
+ }
63
+ const modules = parsed.modules && typeof parsed.modules === 'object' && !Array.isArray(parsed.modules)
64
+ ? parsed.modules
65
+ : {};
66
+ return {
67
+ providers: parsed.providers,
68
+ config: parsed.config,
69
+ modules
70
+ };
71
+ }
72
+ function getModuleList(config) {
73
+ if (!config.modules || typeof config.modules !== 'object')
74
+ return [];
75
+ return Object.values(config.modules).map((e) => e.path);
76
+ }
77
+ function getModuleEntries(config) {
78
+ var _a, _b, _c;
79
+ if (!config.modules || typeof config.modules !== 'object')
80
+ return [];
81
+ const global = config.config || {};
82
+ const database = (_a = global.database) !== null && _a !== void 0 ? _a : DEFAULT_DATABASE;
83
+ const styling = (_b = global.styling) !== null && _b !== void 0 ? _b : DEFAULT_STYLING;
84
+ const identifiers = (_c = global.identifiers) !== null && _c !== void 0 ? _c : DEFAULT_IDENTIFIERS;
85
+ const globalConfig = { database, styling, identifiers };
86
+ return Object.entries(config.modules).map(([name, entry]) => {
87
+ var _a, _b, _c;
88
+ return ({
89
+ name,
90
+ path: entry.path,
91
+ database: (_a = entry.database) !== null && _a !== void 0 ? _a : globalConfig.database,
92
+ styling: (_b = entry.styling) !== null && _b !== void 0 ? _b : globalConfig.styling,
93
+ identifiers: (_c = entry.identifiers) !== null && _c !== void 0 ? _c : globalConfig.identifiers
94
+ });
95
+ });
96
+ }
97
+ function shouldIncludeModule(moduleYamlRel, moduleName) {
98
+ if (!moduleName || moduleName === '*')
99
+ return true;
100
+ const moduleNameLc = moduleName.toLowerCase();
101
+ const relNormalized = moduleYamlRel.replace(/\\/g, '/').toLowerCase();
102
+ if (relNormalized.endsWith(`/${moduleNameLc}.yaml`))
103
+ return true;
104
+ const moduleYamlPath = path.isAbsolute(moduleYamlRel)
105
+ ? moduleYamlRel
106
+ : path.resolve(process.cwd(), moduleYamlRel);
107
+ const dirName = path.basename(path.dirname(moduleYamlPath)).toLowerCase();
108
+ if (dirName === moduleNameLc)
109
+ return true;
110
+ if (relNormalized.includes(`/${moduleNameLc}/`) || relNormalized.endsWith(`/${moduleNameLc}`))
111
+ return true;
112
+ return false;
113
+ }
114
+ function createGenerators() {
115
+ return {
116
+ domainGen: new domainLayerGenerator_1.DomainLayerGenerator(),
117
+ dtoGen: new dtoGenerator_1.DtoGenerator(),
118
+ useCaseGen: new useCaseGenerator_1.UseCaseGenerator(),
119
+ serviceGen: new serviceGenerator_1.ServiceGenerator(),
120
+ controllerGen: new controllerGenerator_1.ControllerGenerator(),
121
+ templateGen: new templateGenerator_1.TemplateGenerator(),
122
+ storeGen: new storeGenerator_1.StoreGenerator()
123
+ };
124
+ }
@@ -8,6 +8,9 @@ export type DiffHunk = {
8
8
  ctxBeforeOld?: string[];
9
9
  ctxAfterOld?: string[];
10
10
  };
11
+ export interface CommitMeta {
12
+ [key: string]: unknown;
13
+ }
11
14
  type StoredCommit = {
12
15
  createdAt?: string;
13
16
  files: Array<{
@@ -20,7 +23,7 @@ type StoredCommit = {
20
23
  baseHash?: string;
21
24
  resultHash?: string;
22
25
  hunks?: DiffHunk[];
23
- meta?: Record<string, any>;
26
+ meta?: CommitMeta;
24
27
  }>;
25
28
  };
26
29
  export declare function loadAllCommitRecords(rootDir: string): Array<{
@@ -53,3 +53,13 @@ export declare const GENERATOR_SUFFIXES: {
53
53
  readonly API_CONTROLLER: "ApiController";
54
54
  readonly WEB_CONTROLLER: "WebController";
55
55
  };
56
+ export declare const AUTH_ROLES: {
57
+ readonly ALL: "all";
58
+ readonly AUTHENTICATED: "authenticated";
59
+ readonly OWNER: "owner";
60
+ };
61
+ export declare const AUTH_ERRORS: {
62
+ readonly REQUIRED: "Authentication required";
63
+ readonly ACCESS_DENIED: "Access denied: you do not own this resource";
64
+ readonly INSUFFICIENT_PERMISSIONS: "Insufficient permissions";
65
+ };
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // Common constants used across the generator
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.GENERATOR_SUFFIXES = exports.SERVER = exports.MODULE_STRUCTURE = exports.DEFAULTS = exports.PATH_PATTERNS = exports.GENERATOR_MARKERS = exports.COMMON_FILES = exports.FILE_EXTENSIONS = void 0;
4
+ exports.AUTH_ERRORS = exports.AUTH_ROLES = exports.GENERATOR_SUFFIXES = exports.SERVER = exports.MODULE_STRUCTURE = exports.DEFAULTS = exports.PATH_PATTERNS = exports.GENERATOR_MARKERS = exports.COMMON_FILES = exports.FILE_EXTENSIONS = void 0;
5
5
  // File extensions
6
6
  exports.FILE_EXTENSIONS = {
7
7
  YAML: '.yaml',
@@ -65,3 +65,15 @@ exports.GENERATOR_SUFFIXES = {
65
65
  API_CONTROLLER: 'ApiController',
66
66
  WEB_CONTROLLER: 'WebController'
67
67
  };
68
+ // Auth roles (magic strings used in controller auth generation)
69
+ exports.AUTH_ROLES = {
70
+ ALL: 'all',
71
+ AUTHENTICATED: 'authenticated',
72
+ OWNER: 'owner',
73
+ };
74
+ // Auth error messages (used in controller auth check generation)
75
+ exports.AUTH_ERRORS = {
76
+ REQUIRED: 'Authentication required',
77
+ ACCESS_DENIED: 'Access denied: you do not own this resource',
78
+ INSUFFICIENT_PERMISSIONS: 'Insufficient permissions',
79
+ };