@currentjs/gen 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/cli.js +0 -0
  3. package/dist/generators/controllerGenerator.d.ts +7 -0
  4. package/dist/generators/controllerGenerator.js +56 -17
  5. package/dist/generators/domainLayerGenerator.js +17 -7
  6. package/dist/generators/dtoGenerator.js +13 -8
  7. package/dist/generators/serviceGenerator.d.ts +6 -0
  8. package/dist/generators/serviceGenerator.js +219 -23
  9. package/dist/generators/storeGenerator.d.ts +4 -0
  10. package/dist/generators/storeGenerator.js +116 -9
  11. package/dist/generators/templates/appTemplates.js +1 -1
  12. package/dist/generators/templates/data/frontendScriptTemplate +11 -4
  13. package/dist/generators/templates/data/mainViewTemplate +1 -0
  14. package/dist/generators/templates/storeTemplates.d.ts +1 -1
  15. package/dist/generators/templates/storeTemplates.js +3 -26
  16. package/dist/generators/useCaseGenerator.js +6 -3
  17. package/dist/types/configTypes.d.ts +1 -0
  18. package/dist/utils/typeUtils.d.ts +4 -0
  19. package/dist/utils/typeUtils.js +7 -0
  20. package/package.json +1 -1
  21. package/dist/commands/migratePush.d.ts +0 -1
  22. package/dist/commands/migratePush.js +0 -135
  23. package/dist/commands/migrateUpdate.d.ts +0 -1
  24. package/dist/commands/migrateUpdate.js +0 -147
  25. package/dist/commands/newGenerateAll.d.ts +0 -4
  26. package/dist/commands/newGenerateAll.js +0 -336
  27. package/dist/generators/domainModelGenerator.d.ts +0 -41
  28. package/dist/generators/domainModelGenerator.js +0 -242
  29. package/dist/generators/newControllerGenerator.d.ts +0 -55
  30. package/dist/generators/newControllerGenerator.js +0 -644
  31. package/dist/generators/newServiceGenerator.d.ts +0 -19
  32. package/dist/generators/newServiceGenerator.js +0 -266
  33. package/dist/generators/newStoreGenerator.d.ts +0 -39
  34. package/dist/generators/newStoreGenerator.js +0 -408
  35. package/dist/generators/newTemplateGenerator.d.ts +0 -29
  36. package/dist/generators/newTemplateGenerator.js +0 -510
  37. package/dist/generators/storeGeneratorV2.d.ts +0 -31
  38. package/dist/generators/storeGeneratorV2.js +0 -190
  39. package/dist/generators/templates/controllerTemplates.d.ts +0 -43
  40. package/dist/generators/templates/controllerTemplates.js +0 -82
  41. package/dist/generators/templates/newStoreTemplates.d.ts +0 -5
  42. package/dist/generators/templates/newStoreTemplates.js +0 -141
  43. package/dist/generators/templates/serviceTemplates.d.ts +0 -16
  44. package/dist/generators/templates/serviceTemplates.js +0 -59
  45. package/dist/generators/templates/validationTemplates.d.ts +0 -25
  46. package/dist/generators/templates/validationTemplates.js +0 -66
  47. package/dist/generators/templates/viewTemplates.d.ts +0 -25
  48. package/dist/generators/templates/viewTemplates.js +0 -491
  49. package/dist/generators/validationGenerator.d.ts +0 -29
  50. package/dist/generators/validationGenerator.js +0 -250
  51. package/dist/utils/new_parts_of_migrationUtils.d.ts +0 -0
  52. package/dist/utils/new_parts_of_migrationUtils.js +0 -164
@@ -1,6 +1,8 @@
1
1
  import { ModuleConfig } from '../types/configTypes';
2
2
  export declare class StoreGenerator {
3
3
  private availableValueObjects;
4
+ private availableAggregates;
5
+ private isAggregateField;
4
6
  private isValueObjectType;
5
7
  private getValueObjectName;
6
8
  private getValueObjectConfig;
@@ -31,6 +33,8 @@ export declare class StoreGenerator {
31
33
  private generateUpdateDataMapping;
32
34
  private generateUpdateFieldsArray;
33
35
  private generateValueObjectImports;
36
+ private generateAggregateRefImports;
37
+ private generateListMethods;
34
38
  private generateGetByParentIdMethod;
35
39
  private generateGetResourceOwnerMethod;
36
40
  private generateStore;
@@ -46,6 +46,10 @@ const typeUtils_1 = require("../utils/typeUtils");
46
46
  class StoreGenerator {
47
47
  constructor() {
48
48
  this.availableValueObjects = new Map();
49
+ this.availableAggregates = new Set();
50
+ }
51
+ isAggregateField(fieldConfig) {
52
+ return (0, typeUtils_1.isAggregateReference)(fieldConfig.type, this.availableAggregates);
49
53
  }
50
54
  isValueObjectType(fieldType) {
51
55
  const capitalizedType = (0, typeUtils_1.capitalize)(fieldType);
@@ -64,8 +68,8 @@ class StoreGenerator {
64
68
  */
65
69
  sortFieldsForConstructor(fields) {
66
70
  return [...fields].sort((a, b) => {
67
- const aRequired = a[1].required !== false && !a[1].auto;
68
- const bRequired = b[1].required !== false && !b[1].auto;
71
+ const aRequired = a[1].required !== false && !a[1].auto && !this.isAggregateField(a[1]);
72
+ const bRequired = b[1].required !== false && !b[1].auto && !this.isAggregateField(b[1]);
69
73
  if (aRequired === bRequired)
70
74
  return 0;
71
75
  return aRequired ? -1 : 1;
@@ -139,6 +143,10 @@ class StoreGenerator {
139
143
  const ownerOrParentField = childInfo ? childInfo.parentIdField : 'ownerId';
140
144
  result.push(` ${ownerOrParentField}: number;`);
141
145
  fields.forEach(([fieldName, fieldConfig]) => {
146
+ if (this.isAggregateField(fieldConfig)) {
147
+ result.push(` ${fieldName}_id?: number;`);
148
+ return;
149
+ }
142
150
  const tsType = this.mapTypeToRowType(fieldConfig.type);
143
151
  const isOptional = !fieldConfig.required;
144
152
  result.push(` ${fieldName}${isOptional ? '?' : ''}: ${tsType};`);
@@ -148,15 +156,26 @@ class StoreGenerator {
148
156
  generateFieldNamesStr(fields, childInfo) {
149
157
  const fieldNames = ['id'];
150
158
  fieldNames.push(childInfo ? childInfo.parentIdField : 'ownerId');
151
- fieldNames.push(...fields.map(([name]) => name));
159
+ fieldNames.push(...fields.map(([name, config]) => this.isAggregateField(config) ? `${name}_id` : name));
152
160
  return fieldNames.map(f => `\\\`${f}\\\``).join(', ');
153
161
  }
154
- generateRowToModelMapping(fields, childInfo) {
162
+ generateRowToModelMapping(modelName, fields, childInfo) {
155
163
  const result = [];
156
164
  const ownerOrParentField = childInfo ? childInfo.parentIdField : 'ownerId';
157
165
  result.push(` row.${ownerOrParentField}`);
158
166
  fields.forEach(([fieldName, fieldConfig]) => {
159
167
  const fieldType = fieldConfig.type;
168
+ // Handle enum type - cast string to the generated union type
169
+ if (fieldType === 'enum' && fieldConfig.values && fieldConfig.values.length > 0) {
170
+ const enumTypeName = `${modelName}${(0, typeUtils_1.capitalize)(fieldName)}`;
171
+ result.push(` row.${fieldName} as ${enumTypeName}`);
172
+ return;
173
+ }
174
+ // Handle aggregate reference - create stub from FK
175
+ if (this.isAggregateField(fieldConfig)) {
176
+ result.push(` row.${fieldName}_id != null ? ({ id: row.${fieldName}_id } as unknown as ${fieldType}) : undefined`);
177
+ return;
178
+ }
160
179
  // Handle datetime/date conversion
161
180
  if (fieldType === 'datetime' || fieldType === 'date') {
162
181
  result.push(this.generateDatetimeConversion(fieldName, 'toDate'));
@@ -189,6 +208,11 @@ class StoreGenerator {
189
208
  result.push(` ${ownerOrParentField}: entity.${ownerOrParentField}`);
190
209
  fields.forEach(([fieldName, fieldConfig]) => {
191
210
  const fieldType = fieldConfig.type;
211
+ // Handle aggregate reference - extract FK id
212
+ if (this.isAggregateField(fieldConfig)) {
213
+ result.push(` ${fieldName}_id: entity.${fieldName}?.id`);
214
+ return;
215
+ }
192
216
  // Handle datetime/date - convert Date to MySQL DATETIME format
193
217
  if (fieldType === 'datetime' || fieldType === 'date') {
194
218
  result.push(this.generateDatetimeConversion(fieldName, 'toMySQL'));
@@ -213,6 +237,9 @@ class StoreGenerator {
213
237
  return fields
214
238
  .map(([fieldName, fieldConfig]) => {
215
239
  const fieldType = fieldConfig.type;
240
+ if (this.isAggregateField(fieldConfig)) {
241
+ return ` ${fieldName}_id: entity.${fieldName}?.id`;
242
+ }
216
243
  if (fieldType === 'datetime' || fieldType === 'date') {
217
244
  return this.generateDatetimeConversion(fieldName, 'toMySQL');
218
245
  }
@@ -228,7 +255,7 @@ class StoreGenerator {
228
255
  .join(',\n');
229
256
  }
230
257
  generateUpdateFieldsArray(fields) {
231
- return JSON.stringify(fields.map(([name]) => name));
258
+ return JSON.stringify(fields.map(([name, config]) => this.isAggregateField(config) ? `${name}_id` : name));
232
259
  }
233
260
  generateValueObjectImports(fields) {
234
261
  const imports = [];
@@ -255,10 +282,71 @@ class StoreGenerator {
255
282
  }
256
283
  return '\n' + uniqueImports.join('\n');
257
284
  }
285
+ generateAggregateRefImports(modelName, fields) {
286
+ const imports = [];
287
+ fields.forEach(([, fieldConfig]) => {
288
+ if (this.isAggregateField(fieldConfig) && fieldConfig.type !== modelName) {
289
+ imports.push(`import { ${fieldConfig.type} } from '../../domain/entities/${fieldConfig.type}';`);
290
+ }
291
+ });
292
+ const uniqueImports = [...new Set(imports)];
293
+ if (uniqueImports.length === 0)
294
+ return '';
295
+ return '\n' + uniqueImports.join('\n');
296
+ }
297
+ generateListMethods(modelName, fieldNamesStr, childInfo) {
298
+ const isRoot = !childInfo;
299
+ const ownerParam = isRoot ? ', ownerId?: number' : '';
300
+ const ownerFilter = isRoot
301
+ ? `\n const ownerFilter = ownerId != null ? ' AND \\\`ownerId\\\` = :ownerId' : '';`
302
+ : '';
303
+ const ownerFilterRef = isRoot ? '\${ownerFilter}' : '';
304
+ const ownerParamsSetup = isRoot
305
+ ? `\n if (ownerId != null) params.ownerId = ownerId;`
306
+ : '';
307
+ const getPaginated = ` async getPaginated(page: number = 1, limit: number = 20${ownerParam}): Promise<${modelName}[]> {
308
+ const offset = (page - 1) * limit;${ownerFilter}
309
+ const params: Record<string, any> = { limit: String(limit), offset: String(offset) };${ownerParamsSetup}
310
+ const result = await this.db.query(
311
+ \`SELECT ${fieldNamesStr} FROM \\\`\${this.tableName}\\\` WHERE deleted_at IS NULL${ownerFilterRef} LIMIT :limit OFFSET :offset\`,
312
+ params
313
+ );
314
+
315
+ if (result.success && result.data) {
316
+ return result.data.map((row: ${modelName}Row) => this.rowToModel(row));
317
+ }
318
+ return [];
319
+ }`;
320
+ const getAll = ` async getAll(${isRoot ? 'ownerId?: number' : ''}): Promise<${modelName}[]> {${ownerFilter}
321
+ const params: Record<string, any> = {};${ownerParamsSetup}
322
+ const result = await this.db.query(
323
+ \`SELECT ${fieldNamesStr} FROM \\\`\${this.tableName}\\\` WHERE deleted_at IS NULL${ownerFilterRef}\`,
324
+ params
325
+ );
326
+
327
+ if (result.success && result.data) {
328
+ return result.data.map((row: ${modelName}Row) => this.rowToModel(row));
329
+ }
330
+ return [];
331
+ }`;
332
+ const count = ` async count(${isRoot ? 'ownerId?: number' : ''}): Promise<number> {${ownerFilter}
333
+ const params: Record<string, any> = {};${ownerParamsSetup}
334
+ const result = await this.db.query(
335
+ \`SELECT COUNT(*) as count FROM \\\`\${this.tableName}\\\` WHERE deleted_at IS NULL${ownerFilterRef}\`,
336
+ params
337
+ );
338
+
339
+ if (result.success && result.data && result.data.length > 0) {
340
+ return parseInt(result.data[0].count, 10);
341
+ }
342
+ return 0;
343
+ }`;
344
+ return `${getPaginated}\n\n${getAll}\n\n${count}`;
345
+ }
258
346
  generateGetByParentIdMethod(modelName, fields, childInfo) {
259
347
  if (!childInfo)
260
348
  return '';
261
- const fieldList = ['id', childInfo.parentIdField, ...fields.map(([name]) => name)].map(f => '\\`' + f + '\\`').join(', ');
349
+ const fieldList = ['id', childInfo.parentIdField, ...fields.map(([name, config]) => this.isAggregateField(config) ? `${name}_id` : name)].map(f => '\\`' + f + '\\`').join(', ');
262
350
  const parentIdField = childInfo.parentIdField;
263
351
  return `
264
352
 
@@ -319,26 +407,38 @@ class StoreGenerator {
319
407
  const fields = Object.entries(aggregateConfig.fields);
320
408
  // Sort fields for rowToModel to match entity constructor order (required first, optional second)
321
409
  const sortedFields = this.sortFieldsForConstructor(fields);
410
+ const fieldNamesStr = this.generateFieldNamesStr(fields, childInfo);
322
411
  const variables = {
323
412
  ENTITY_NAME: modelName,
324
413
  TABLE_NAME: tableName,
325
414
  ROW_FIELDS: this.generateRowFields(fields, childInfo),
326
- FIELD_NAMES: this.generateFieldNamesStr(fields, childInfo),
327
- ROW_TO_MODEL_MAPPING: this.generateRowToModelMapping(sortedFields, childInfo),
415
+ FIELD_NAMES: fieldNamesStr,
416
+ ROW_TO_MODEL_MAPPING: this.generateRowToModelMapping(modelName, sortedFields, childInfo),
328
417
  INSERT_DATA_MAPPING: this.generateInsertDataMapping(fields, childInfo),
329
418
  UPDATE_DATA_MAPPING: this.generateUpdateDataMapping(fields),
330
419
  UPDATE_FIELDS_ARRAY: this.generateUpdateFieldsArray(fields),
331
420
  VALUE_OBJECT_IMPORTS: this.generateValueObjectImports(fields),
421
+ AGGREGATE_REF_IMPORTS: this.generateAggregateRefImports(modelName, fields),
422
+ LIST_METHODS: this.generateListMethods(modelName, fieldNamesStr, childInfo),
332
423
  GET_BY_PARENT_ID_METHOD: this.generateGetByParentIdMethod(modelName, fields, childInfo),
333
424
  GET_RESOURCE_OWNER_METHOD: this.generateGetResourceOwnerMethod(childInfo)
334
425
  };
335
426
  const rowInterface = this.replaceTemplateVars(storeTemplates_1.storeTemplates.rowInterface, variables);
336
427
  const storeClass = this.replaceTemplateVars(storeTemplates_1.storeTemplates.storeClass, variables);
428
+ // Build entity import items: entity name + any enum type names
429
+ const entityImportItems = [modelName];
430
+ fields.forEach(([fieldName, fieldConfig]) => {
431
+ if (fieldConfig.type === 'enum' && fieldConfig.values && fieldConfig.values.length > 0) {
432
+ entityImportItems.push(`${modelName}${(0, typeUtils_1.capitalize)(fieldName)}`);
433
+ }
434
+ });
337
435
  return this.replaceTemplateVars(storeTemplates_1.storeFileTemplate, {
338
436
  ENTITY_NAME: modelName,
437
+ ENTITY_IMPORT_ITEMS: entityImportItems.join(', '),
339
438
  ROW_INTERFACE: rowInterface,
340
439
  STORE_CLASS: storeClass,
341
- VALUE_OBJECT_IMPORTS: variables.VALUE_OBJECT_IMPORTS
440
+ VALUE_OBJECT_IMPORTS: variables.VALUE_OBJECT_IMPORTS,
441
+ AGGREGATE_REF_IMPORTS: variables.AGGREGATE_REF_IMPORTS
342
442
  });
343
443
  }
344
444
  generateFromConfig(config) {
@@ -350,6 +450,13 @@ class StoreGenerator {
350
450
  this.availableValueObjects.set(name, voConfig);
351
451
  });
352
452
  }
453
+ // Collect all aggregate names for detecting entity references
454
+ this.availableAggregates.clear();
455
+ if (config.domain.aggregates) {
456
+ Object.keys(config.domain.aggregates).forEach(name => {
457
+ this.availableAggregates.add(name);
458
+ });
459
+ }
353
460
  // Generate a store for each aggregate
354
461
  const childEntityMap = (0, childEntityUtils_1.buildChildEntityMap)(config);
355
462
  if (config.domain.aggregates) {
@@ -60,7 +60,7 @@ const packageJsonTemplate = (appName) => JSON.stringify({
60
60
  devDependencies: {
61
61
  typescript: '^5.6.3',
62
62
  '@types/node': '^22.7.4',
63
- '@koz1024/path-fixer': '^0.2.1',
63
+ '@koz1024/path-fixer': '^0.2.2',
64
64
  },
65
65
  type: 'module'
66
66
  }, null, 2);
@@ -374,7 +374,10 @@ window.AppConfig = {
374
374
  */
375
375
  function navigateToPage(url, targetElement = null) {
376
376
  const target = targetElement || document.querySelector('#main');
377
- if (!target) return;
377
+ if (!target) {
378
+ window.location.href = url;
379
+ return;
380
+ }
378
381
 
379
382
  showLoading('#main');
380
383
 
@@ -388,18 +391,22 @@ window.AppConfig = {
388
391
  if (!response.ok) {
389
392
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
390
393
  }
394
+ const targetLayout = response.headers.get('X-Layout') || '';
395
+ const currentLayout = (document.querySelector('meta[name="app-layout"]') || {}).content || '';
396
+ if (targetLayout !== currentLayout) {
397
+ window.location.href = url;
398
+ return null;
399
+ }
391
400
  return response.text();
392
401
  })
393
402
  .then(html => {
403
+ if (html === null) return;
394
404
  target.innerHTML = html;
395
- // Update browser history
396
405
  window.history.pushState({}, '', url);
397
- // No need to re-initialize - delegation handles new content automatically
398
406
  })
399
407
  .catch(error => {
400
408
  console.error('Navigation failed:', error);
401
409
  showToast('Failed to load page', 'error');
402
- // Fallback to normal navigation
403
410
  window.location.href = url;
404
411
  })
405
412
  .finally(() => {
@@ -5,6 +5,7 @@
5
5
  <meta charset="UTF-8">
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
7
  <title>Your App</title>
8
+ <meta name="app-layout" content="main_view">
8
9
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
9
10
  <script src="/app.js"></script>
10
11
  </head>
@@ -2,4 +2,4 @@ export declare const storeTemplates: {
2
2
  rowInterface: string;
3
3
  storeClass: string;
4
4
  };
5
- export declare const storeFileTemplate = "import { Injectable } from '../../../../system';\nimport { {{ENTITY_NAME}} } from '../../domain/entities/{{ENTITY_NAME}}';\nimport type { ISqlProvider } from '@currentjs/provider-mysql';{{VALUE_OBJECT_IMPORTS}}\n\n{{ROW_INTERFACE}}\n\n{{STORE_CLASS}}\n";
5
+ export declare const storeFileTemplate = "import { Injectable } from '../../../../system';\nimport { {{ENTITY_IMPORT_ITEMS}} } from '../../domain/entities/{{ENTITY_NAME}}';\nimport type { ISqlProvider } from '@currentjs/provider-mysql';{{VALUE_OBJECT_IMPORTS}}{{AGGREGATE_REF_IMPORTS}}\n\n{{ROW_INTERFACE}}\n\n{{STORE_CLASS}}\n";
@@ -29,30 +29,7 @@ export class {{ENTITY_NAME}}Store {
29
29
  );
30
30
  }
31
31
 
32
- async getAll(page: number = 1, limit: number = 20): Promise<{{ENTITY_NAME}}[]> {
33
- const offset = (page - 1) * limit;
34
- const result = await this.db.query(
35
- \`SELECT {{FIELD_NAMES}} FROM \\\`\${this.tableName}\\\` WHERE deleted_at IS NULL LIMIT :limit OFFSET :offset\`,
36
- { limit: String(limit), offset: String(offset) }
37
- );
38
-
39
- if (result.success && result.data) {
40
- return result.data.map((row: {{ENTITY_NAME}}Row) => this.rowToModel(row));
41
- }
42
- return [];
43
- }
44
-
45
- async count(): Promise<number> {
46
- const result = await this.db.query(
47
- \`SELECT COUNT(*) as count FROM \\\`\${this.tableName}\\\` WHERE deleted_at IS NULL\`,
48
- {}
49
- );
50
-
51
- if (result.success && result.data && result.data.length > 0) {
52
- return parseInt(result.data[0].count, 10);
53
- }
54
- return 0;
55
- }
32
+ {{LIST_METHODS}}
56
33
 
57
34
  async getById(id: number): Promise<{{ENTITY_NAME}} | null> {
58
35
  const result = await this.db.query(
@@ -134,8 +111,8 @@ export class {{ENTITY_NAME}}Store {
134
111
  {{GET_RESOURCE_OWNER_METHOD}}}`
135
112
  };
136
113
  exports.storeFileTemplate = `import { Injectable } from '../../../../system';
137
- import { {{ENTITY_NAME}} } from '../../domain/entities/{{ENTITY_NAME}}';
138
- import type { ISqlProvider } from '@currentjs/provider-mysql';{{VALUE_OBJECT_IMPORTS}}
114
+ import { {{ENTITY_IMPORT_ITEMS}} } from '../../domain/entities/{{ENTITY_NAME}}';
115
+ import type { ISqlProvider } from '@currentjs/provider-mysql';{{VALUE_OBJECT_IMPORTS}}{{AGGREGATE_REF_IMPORTS}}
139
116
 
140
117
  {{ROW_INTERFACE}}
141
118
 
@@ -71,8 +71,8 @@ class UseCaseGenerator {
71
71
  let params = '';
72
72
  if (defaultAction === 'list') {
73
73
  params = ((_a = useCaseConfig.input) === null || _a === void 0 ? void 0 : _a.pagination)
74
- ? 'input.page || 1, input.limit || 20'
75
- : '';
74
+ ? 'input.page || 1, input.limit || 20, ownerId'
75
+ : 'ownerId';
76
76
  }
77
77
  else if (defaultAction === 'get') {
78
78
  params = 'input.id';
@@ -99,7 +99,10 @@ class UseCaseGenerator {
99
99
  }
100
100
  }).join('\n');
101
101
  const returnStatement = '\n return result;';
102
- return ` async ${methodName}(input: ${inputType}): Promise<${returnType}> {
102
+ const methodParams = actionName === 'list'
103
+ ? `input: ${inputType}, ownerId?: number`
104
+ : `input: ${inputType}`;
105
+ return ` async ${methodName}(${methodParams}): Promise<${returnType}> {
103
106
  ${handlerCalls}${returnStatement}
104
107
  }`;
105
108
  }
@@ -121,6 +121,7 @@ export interface WebPageConfig {
121
121
  method?: 'GET' | 'POST';
122
122
  useCase?: string;
123
123
  view?: string;
124
+ layout?: string;
124
125
  auth?: AuthConfig;
125
126
  onSuccess?: {
126
127
  redirect?: string;
@@ -13,6 +13,10 @@ export declare function capitalize(str: string): string;
13
13
  * Map a YAML field type to TypeScript type, resolving aggregates and value objects by name.
14
14
  */
15
15
  export declare function mapType(yamlType: string, aggregates?: Set<string> | Map<string, unknown>, valueObjects?: Set<string> | Map<string, unknown>): string;
16
+ /**
17
+ * Check if a YAML field type references another aggregate entity.
18
+ */
19
+ export declare function isAggregateReference(yamlType: string, aggregates?: Set<string> | Map<string, unknown>): boolean;
16
20
  /**
17
21
  * Map a YAML type to the store row TypeScript type (value objects become string).
18
22
  */
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.ROW_TYPE_MAPPING = exports.TYPE_MAPPING = void 0;
7
7
  exports.capitalize = capitalize;
8
8
  exports.mapType = mapType;
9
+ exports.isAggregateReference = isAggregateReference;
9
10
  exports.mapRowType = mapRowType;
10
11
  /** Standard YAML type to TypeScript (domain) type mapping. */
11
12
  exports.TYPE_MAPPING = {
@@ -55,6 +56,12 @@ function mapType(yamlType, aggregates, valueObjects) {
55
56
  }
56
57
  return (_a = exports.TYPE_MAPPING[yamlType]) !== null && _a !== void 0 ? _a : 'any';
57
58
  }
59
+ /**
60
+ * Check if a YAML field type references another aggregate entity.
61
+ */
62
+ function isAggregateReference(yamlType, aggregates) {
63
+ return !!(aggregates === null || aggregates === void 0 ? void 0 : aggregates.has(yamlType));
64
+ }
58
65
  /**
59
66
  * Map a YAML type to the store row TypeScript type (value objects become string).
60
67
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@currentjs/gen",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "CLI code generator",
5
5
  "license": "LGPL-3.0",
6
6
  "author": "Konstantin Zavalny",
@@ -1 +0,0 @@
1
- export declare function handleMigratePush(yamlPath?: string): Promise<void>;
@@ -1,135 +0,0 @@
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.handleMigratePush = handleMigratePush;
37
- const fs = __importStar(require("fs"));
38
- const path = __importStar(require("path"));
39
- const colors_1 = require("../utils/colors");
40
- const cliUtils_1 = require("../utils/cliUtils");
41
- const migrationUtils_1 = require("../utils/migrationUtils");
42
- async function handleMigratePush(yamlPath) {
43
- let connection;
44
- try {
45
- const resolvedYamlPath = (0, cliUtils_1.resolveYamlPath)(yamlPath);
46
- const projectRoot = path.dirname(resolvedYamlPath);
47
- const migrationsDir = path.join(projectRoot, 'migrations');
48
- // Check if migrations directory exists
49
- if (!fs.existsSync(migrationsDir)) {
50
- // eslint-disable-next-line no-console
51
- console.log(colors_1.colors.yellow('⚠️ No migrations directory found. Run "currentjs migrate commit" first.'));
52
- return;
53
- }
54
- // Get all migration files
55
- const migrationFiles = fs.readdirSync(migrationsDir)
56
- .filter(f => f.endsWith('.sql'))
57
- .sort();
58
- if (migrationFiles.length === 0) {
59
- // eslint-disable-next-line no-console
60
- console.log(colors_1.colors.yellow('⚠️ No migration files found. Run "currentjs migrate commit" first.'));
61
- return;
62
- }
63
- // eslint-disable-next-line no-console
64
- console.log(colors_1.colors.cyan('\n🔌 Connecting to database...'));
65
- // Verify environment variables
66
- if (!process.env.DB_HOST || !process.env.DB_USER || !process.env.DB_NAME) {
67
- // eslint-disable-next-line no-console
68
- console.log(colors_1.colors.yellow('\n💡 Database configuration:'));
69
- // eslint-disable-next-line no-console
70
- console.log(colors_1.colors.gray(` Host: ${process.env.DB_HOST || 'localhost (default)'}`));
71
- // eslint-disable-next-line no-console
72
- console.log(colors_1.colors.gray(` Port: ${process.env.DB_PORT || '3306 (default)'}`));
73
- // eslint-disable-next-line no-console
74
- console.log(colors_1.colors.gray(` User: ${process.env.DB_USER || 'root (default)'}`));
75
- // eslint-disable-next-line no-console
76
- console.log(colors_1.colors.gray(` Database: ${process.env.DB_NAME || 'test (default)'}`));
77
- if (!process.env.DB_HOST || !process.env.DB_USER || !process.env.DB_NAME) {
78
- // eslint-disable-next-line no-console
79
- console.log(colors_1.colors.yellow('\n⚠️ Environment variables not set. Using defaults.'));
80
- // eslint-disable-next-line no-console
81
- console.log(colors_1.colors.cyan(' Set DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME to configure.'));
82
- }
83
- }
84
- connection = await (0, migrationUtils_1.connectToDatabase)();
85
- // eslint-disable-next-line no-console
86
- console.log(colors_1.colors.green('✓ Connected to database'));
87
- // Get already applied migrations
88
- // eslint-disable-next-line no-console
89
- console.log(colors_1.colors.cyan('\n📖 Checking applied migrations...'));
90
- const appliedMigrations = await (0, migrationUtils_1.getAppliedMigrations)(connection);
91
- // eslint-disable-next-line no-console
92
- console.log(colors_1.colors.gray(` Applied: ${appliedMigrations.length} migration(s)`));
93
- // Find pending migrations
94
- const pendingMigrations = migrationFiles.filter(f => !appliedMigrations.includes(f));
95
- if (pendingMigrations.length === 0) {
96
- // eslint-disable-next-line no-console
97
- console.log(colors_1.colors.green('\n✅ Database is up to date. No pending migrations.'));
98
- return;
99
- }
100
- // eslint-disable-next-line no-console
101
- console.log(colors_1.colors.cyan(`\n🚀 Applying ${pendingMigrations.length} migration(s)...`));
102
- // Apply pending migrations
103
- for (const migrationFile of pendingMigrations) {
104
- const migrationPath = path.join(migrationsDir, migrationFile);
105
- const migrationSQL = fs.readFileSync(migrationPath, 'utf8');
106
- // eslint-disable-next-line no-console
107
- console.log(colors_1.colors.gray(` → ${migrationFile}...`));
108
- try {
109
- await (0, migrationUtils_1.executeMigration)(connection, migrationSQL);
110
- await (0, migrationUtils_1.recordMigration)(connection, migrationFile);
111
- // eslint-disable-next-line no-console
112
- console.log(colors_1.colors.green(` ✓ ${migrationFile} applied`));
113
- }
114
- catch (error) {
115
- // eslint-disable-next-line no-console
116
- console.error(colors_1.colors.red(` ✗ Failed to apply ${migrationFile}:`));
117
- // eslint-disable-next-line no-console
118
- console.error(colors_1.colors.red(` ${error instanceof Error ? error.message : String(error)}`));
119
- throw error;
120
- }
121
- }
122
- // eslint-disable-next-line no-console
123
- console.log(colors_1.colors.green('\n✅ All migrations applied successfully!'));
124
- }
125
- catch (error) {
126
- // eslint-disable-next-line no-console
127
- console.error(colors_1.colors.red('\n❌ Error applying migrations:'), error instanceof Error ? error.message : String(error));
128
- process.exitCode = 1;
129
- }
130
- finally {
131
- if (connection) {
132
- await connection.end();
133
- }
134
- }
135
- }
@@ -1 +0,0 @@
1
- export declare function handleMigrateUpdate(yamlPath?: string): Promise<void>;