@currentjs/gen 0.5.0 → 0.5.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/CHANGELOG.md +19 -0
- package/README.md +374 -996
- package/dist/cli.js +28 -10
- package/dist/commands/createModel.d.ts +1 -0
- package/dist/commands/createModel.js +764 -0
- package/dist/commands/createModule.js +13 -0
- package/dist/commands/generateAll.d.ts +1 -0
- package/dist/commands/generateAll.js +1 -1
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/{createApp.js → init.js} +2 -2
- package/dist/commands/migrateCommit.js +33 -68
- package/dist/generators/controllerGenerator.d.ts +7 -0
- package/dist/generators/controllerGenerator.js +56 -17
- package/dist/generators/domainLayerGenerator.js +51 -8
- package/dist/generators/dtoGenerator.js +13 -8
- package/dist/generators/serviceGenerator.d.ts +6 -0
- package/dist/generators/serviceGenerator.js +219 -23
- package/dist/generators/storeGenerator.d.ts +4 -0
- package/dist/generators/storeGenerator.js +116 -9
- package/dist/generators/templateGenerator.d.ts +1 -0
- package/dist/generators/templateGenerator.js +8 -2
- package/dist/generators/templates/appTemplates.js +1 -1
- package/dist/generators/templates/data/cursorRulesTemplate +11 -755
- package/dist/generators/templates/data/frontendScriptTemplate +11 -4
- package/dist/generators/templates/data/mainViewTemplate +1 -0
- package/dist/generators/templates/storeTemplates.d.ts +1 -1
- package/dist/generators/templates/storeTemplates.js +3 -26
- package/dist/generators/useCaseGenerator.js +6 -3
- package/dist/types/configTypes.d.ts +6 -0
- package/dist/utils/migrationUtils.d.ts +9 -19
- package/dist/utils/migrationUtils.js +80 -110
- package/dist/utils/promptUtils.d.ts +37 -0
- package/dist/utils/promptUtils.js +149 -0
- package/dist/utils/typeUtils.d.ts +4 -0
- package/dist/utils/typeUtils.js +7 -0
- package/package.json +1 -1
- package/dist/commands/createApp.d.ts +0 -1
- package/dist/commands/migratePush.d.ts +0 -1
- package/dist/commands/migratePush.js +0 -135
- package/dist/commands/migrateUpdate.d.ts +0 -1
- package/dist/commands/migrateUpdate.js +0 -147
- package/dist/commands/newGenerateAll.d.ts +0 -4
- package/dist/commands/newGenerateAll.js +0 -336
- package/dist/generators/domainModelGenerator.d.ts +0 -41
- package/dist/generators/domainModelGenerator.js +0 -242
- package/dist/generators/newControllerGenerator.d.ts +0 -55
- package/dist/generators/newControllerGenerator.js +0 -644
- package/dist/generators/newServiceGenerator.d.ts +0 -19
- package/dist/generators/newServiceGenerator.js +0 -266
- package/dist/generators/newStoreGenerator.d.ts +0 -39
- package/dist/generators/newStoreGenerator.js +0 -408
- package/dist/generators/newTemplateGenerator.d.ts +0 -29
- package/dist/generators/newTemplateGenerator.js +0 -510
- package/dist/generators/storeGeneratorV2.d.ts +0 -31
- package/dist/generators/storeGeneratorV2.js +0 -190
- package/dist/generators/templates/controllerTemplates.d.ts +0 -43
- package/dist/generators/templates/controllerTemplates.js +0 -82
- package/dist/generators/templates/newStoreTemplates.d.ts +0 -5
- package/dist/generators/templates/newStoreTemplates.js +0 -141
- package/dist/generators/templates/serviceTemplates.d.ts +0 -16
- package/dist/generators/templates/serviceTemplates.js +0 -59
- package/dist/generators/templates/validationTemplates.d.ts +0 -25
- package/dist/generators/templates/validationTemplates.js +0 -66
- package/dist/generators/templates/viewTemplates.d.ts +0 -25
- package/dist/generators/templates/viewTemplates.js +0 -491
- package/dist/generators/validationGenerator.d.ts +0 -29
- package/dist/generators/validationGenerator.js +0 -250
- package/dist/utils/new_parts_of_migrationUtils.d.ts +0 -0
- package/dist/utils/new_parts_of_migrationUtils.js +0 -164
- package/howto.md +0 -667
|
@@ -1,190 +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.StoreGeneratorV2 = void 0;
|
|
37
|
-
const yaml_1 = require("yaml");
|
|
38
|
-
const fs = __importStar(require("fs"));
|
|
39
|
-
const path = __importStar(require("path"));
|
|
40
|
-
const storeTemplates_1 = require("./templates/storeTemplates");
|
|
41
|
-
const generationRegistry_1 = require("../utils/generationRegistry");
|
|
42
|
-
const colors_1 = require("../utils/colors");
|
|
43
|
-
class StoreGeneratorV2 {
|
|
44
|
-
constructor() {
|
|
45
|
-
this.typeMapping = {
|
|
46
|
-
string: 'string',
|
|
47
|
-
number: 'number',
|
|
48
|
-
boolean: 'boolean',
|
|
49
|
-
datetime: 'Date',
|
|
50
|
-
json: 'any',
|
|
51
|
-
array: 'any[]',
|
|
52
|
-
object: 'object'
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
mapType(yamlType) {
|
|
56
|
-
return this.typeMapping[yamlType] || 'any';
|
|
57
|
-
}
|
|
58
|
-
generateRowFields(modelConfig) {
|
|
59
|
-
const fields = [];
|
|
60
|
-
modelConfig.fields.forEach(field => {
|
|
61
|
-
if (field.name === 'createdAt') {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const tsType = this.mapType(field.type);
|
|
65
|
-
const isOptional = !field.required && !field.auto;
|
|
66
|
-
const fieldDef = ` ${field.name}${isOptional ? '?' : ''}: ${tsType};`;
|
|
67
|
-
fields.push(fieldDef);
|
|
68
|
-
});
|
|
69
|
-
return fields.join('\n');
|
|
70
|
-
}
|
|
71
|
-
generateFilterableFields(modelConfig) {
|
|
72
|
-
const filterableFields = modelConfig.fields
|
|
73
|
-
.filter(field => ['string', 'number', 'boolean'].includes(field.type))
|
|
74
|
-
.map(field => `'${field.name}'`);
|
|
75
|
-
return filterableFields.join(' | ');
|
|
76
|
-
}
|
|
77
|
-
generateFilterableFieldsArray(modelConfig) {
|
|
78
|
-
const filterableFields = modelConfig.fields
|
|
79
|
-
.filter(field => ['string', 'number', 'boolean'].includes(field.type))
|
|
80
|
-
.map(field => `'${field.name}'`);
|
|
81
|
-
return filterableFields.join(', ');
|
|
82
|
-
}
|
|
83
|
-
generateUpdatableFieldsArray(modelConfig) {
|
|
84
|
-
const updatableFields = modelConfig.fields
|
|
85
|
-
.filter(field => field.name !== 'id' && field.name !== 'createdAt')
|
|
86
|
-
.map(field => `'${field.name}'`);
|
|
87
|
-
return updatableFields.join(', ');
|
|
88
|
-
}
|
|
89
|
-
generateRowToModelMapping(modelConfig) {
|
|
90
|
-
const mappings = modelConfig.fields.map(field => {
|
|
91
|
-
if (field.name === 'createdAt') {
|
|
92
|
-
return ' row.created_at';
|
|
93
|
-
}
|
|
94
|
-
return ` row.${field.name}`;
|
|
95
|
-
});
|
|
96
|
-
return mappings.join(',\n');
|
|
97
|
-
}
|
|
98
|
-
generateModelToRowMapping(modelConfig) {
|
|
99
|
-
const mappings = modelConfig.fields.map(field => {
|
|
100
|
-
if (field.name === 'createdAt') {
|
|
101
|
-
return ' created_at: model.createdAt';
|
|
102
|
-
}
|
|
103
|
-
return ` ${field.name}: model.${field.name}`;
|
|
104
|
-
});
|
|
105
|
-
return mappings.join(',\n');
|
|
106
|
-
}
|
|
107
|
-
replaceTemplateVars(template, variables) {
|
|
108
|
-
let result = template;
|
|
109
|
-
Object.entries(variables).forEach(([key, value]) => {
|
|
110
|
-
const regex = new RegExp(`{{${key}}}`, 'g');
|
|
111
|
-
result = result.replace(regex, value);
|
|
112
|
-
});
|
|
113
|
-
return result;
|
|
114
|
-
}
|
|
115
|
-
generateStoreInterface() {
|
|
116
|
-
return storeTemplates_1.fileTemplates.storeInterface;
|
|
117
|
-
}
|
|
118
|
-
generateStore(modelConfig) {
|
|
119
|
-
const entityName = modelConfig.name;
|
|
120
|
-
const tableName = entityName.toLowerCase() + 's';
|
|
121
|
-
const variables = {
|
|
122
|
-
ENTITY_NAME: entityName,
|
|
123
|
-
TABLE_NAME: tableName,
|
|
124
|
-
ROW_FIELDS: this.generateRowFields(modelConfig),
|
|
125
|
-
FILTERABLE_FIELDS: this.generateFilterableFields(modelConfig),
|
|
126
|
-
FILTERABLE_FIELDS_ARRAY: this.generateFilterableFieldsArray(modelConfig),
|
|
127
|
-
UPDATABLE_FIELDS_ARRAY: this.generateUpdatableFieldsArray(modelConfig),
|
|
128
|
-
ROW_TO_MODEL_MAPPING: this.generateRowToModelMapping(modelConfig),
|
|
129
|
-
MODEL_TO_ROW_MAPPING: this.generateModelToRowMapping(modelConfig)
|
|
130
|
-
};
|
|
131
|
-
const rowInterface = this.replaceTemplateVars(storeTemplates_1.storeTemplates.rowInterface, variables);
|
|
132
|
-
const conversionMethods = this.replaceTemplateVars(storeTemplates_1.storeTemplates.conversionMethods, variables);
|
|
133
|
-
const storeClass = this.replaceTemplateVars(storeTemplates_1.storeTemplates.storeClass, {
|
|
134
|
-
...variables,
|
|
135
|
-
CONVERSION_METHODS: conversionMethods
|
|
136
|
-
});
|
|
137
|
-
return this.replaceTemplateVars(storeTemplates_1.fileTemplates.storeFile, {
|
|
138
|
-
ENTITY_NAME: entityName,
|
|
139
|
-
ROW_INTERFACE: rowInterface,
|
|
140
|
-
STORE_CLASS: storeClass
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
generateStores(models) {
|
|
144
|
-
const result = {};
|
|
145
|
-
models.forEach(model => {
|
|
146
|
-
result[model.name] = this.generateStore(model);
|
|
147
|
-
});
|
|
148
|
-
return result;
|
|
149
|
-
}
|
|
150
|
-
generateFromYamlFile(yamlFilePath) {
|
|
151
|
-
const yamlContent = fs.readFileSync(yamlFilePath, 'utf8');
|
|
152
|
-
const config = (0, yaml_1.parse)(yamlContent);
|
|
153
|
-
const result = {};
|
|
154
|
-
if (config.modules) {
|
|
155
|
-
Object.values(config.modules).forEach(moduleConfig => {
|
|
156
|
-
if (moduleConfig.models && moduleConfig.models.length > 0) {
|
|
157
|
-
const stores = this.generateStores(moduleConfig.models);
|
|
158
|
-
Object.assign(result, stores);
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
else if (config.models) {
|
|
163
|
-
const module = config;
|
|
164
|
-
if (module.models && module.models.length > 0) {
|
|
165
|
-
const stores = this.generateStores(module.models);
|
|
166
|
-
Object.assign(result, stores);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
return result;
|
|
170
|
-
}
|
|
171
|
-
async generateAndSaveFiles(yamlFilePath = 'app.yaml', outputDir = 'infrastructure', opts) {
|
|
172
|
-
const stores = this.generateFromYamlFile(yamlFilePath);
|
|
173
|
-
const storesDir = path.join(outputDir, 'stores');
|
|
174
|
-
const interfacesDir = path.join(outputDir, 'interfaces');
|
|
175
|
-
fs.mkdirSync(storesDir, { recursive: true });
|
|
176
|
-
fs.mkdirSync(interfacesDir, { recursive: true });
|
|
177
|
-
const storeInterface = this.generateStoreInterface();
|
|
178
|
-
const interfaceFilePath = path.join(interfacesDir, 'StoreInterface.ts');
|
|
179
|
-
await (0, generationRegistry_1.writeGeneratedFile)(interfaceFilePath, storeInterface, { force: !!(opts === null || opts === void 0 ? void 0 : opts.force), skipOnConflict: !!(opts === null || opts === void 0 ? void 0 : opts.skipOnConflict) });
|
|
180
|
-
for (const [entityName, storeCode] of Object.entries(stores)) {
|
|
181
|
-
const fileName = `${entityName}Store.ts`;
|
|
182
|
-
const filePath = path.join(storesDir, fileName);
|
|
183
|
-
// eslint-disable-next-line no-await-in-loop
|
|
184
|
-
await (0, generationRegistry_1.writeGeneratedFile)(filePath, storeCode, { force: !!(opts === null || opts === void 0 ? void 0 : opts.force), skipOnConflict: !!(opts === null || opts === void 0 ? void 0 : opts.skipOnConflict) });
|
|
185
|
-
}
|
|
186
|
-
// eslint-disable-next-line no-console
|
|
187
|
-
console.log('\n' + colors_1.colors.green('All store files generated successfully!') + '\n');
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
exports.StoreGeneratorV2 = StoreGeneratorV2;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
export declare const controllerTemplates: {
|
|
2
|
-
controllerClass: string;
|
|
3
|
-
controllerMethod: string;
|
|
4
|
-
userExtraction: string;
|
|
5
|
-
methodImplementations: {
|
|
6
|
-
list: string;
|
|
7
|
-
get: string;
|
|
8
|
-
create: string;
|
|
9
|
-
update: string;
|
|
10
|
-
delete: string;
|
|
11
|
-
empty: string;
|
|
12
|
-
};
|
|
13
|
-
responseFormats: {
|
|
14
|
-
list: string;
|
|
15
|
-
get: string;
|
|
16
|
-
create: string;
|
|
17
|
-
update: string;
|
|
18
|
-
delete: string;
|
|
19
|
-
};
|
|
20
|
-
statusCodes: {
|
|
21
|
-
list: {
|
|
22
|
-
success: number;
|
|
23
|
-
error: number;
|
|
24
|
-
};
|
|
25
|
-
get: {
|
|
26
|
-
success: number;
|
|
27
|
-
error: number;
|
|
28
|
-
};
|
|
29
|
-
create: {
|
|
30
|
-
success: number;
|
|
31
|
-
error: number;
|
|
32
|
-
};
|
|
33
|
-
update: {
|
|
34
|
-
success: number;
|
|
35
|
-
error: number;
|
|
36
|
-
};
|
|
37
|
-
delete: {
|
|
38
|
-
success: number;
|
|
39
|
-
error: number;
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
};
|
|
43
|
-
export declare const controllerFileTemplate = "import { {{ENTITY_NAME}} } from '../../domain/entities/{{ENTITY_NAME}}';\nimport { {{ENTITY_NAME}}Service } from '../../application/services/{{ENTITY_NAME}}Service';\nimport { {{ENTITY_NAME}}DTO } from '../../application/validation/{{ENTITY_NAME}}Validation';{{JWT_IMPORT}}\nimport { Get, Post, Put, Patch, Delete, Controller, Render } from '@currentjs/router';\nimport type { IContext } from '@currentjs/router';\n\n{{CONTROLLER_CLASS}}";
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.controllerFileTemplate = exports.controllerTemplates = void 0;
|
|
4
|
-
exports.controllerTemplates = {
|
|
5
|
-
controllerClass: `@Controller('{{CONTROLLER_BASE}}', {})
|
|
6
|
-
export class {{CONTROLLER_NAME}} {
|
|
7
|
-
constructor(
|
|
8
|
-
private {{ENTITY_LOWER}}Service: {{ENTITY_NAME}}Service
|
|
9
|
-
) {}
|
|
10
|
-
|
|
11
|
-
{{CONTROLLER_METHODS}}
|
|
12
|
-
}`,
|
|
13
|
-
controllerMethod: ` @{{HTTP_DECORATOR}}("{{ENDPOINT_PATH}}"){{RENDER_DECORATOR}}
|
|
14
|
-
async {{METHOD_NAME}}(context: IContext): Promise<{{RETURN_TYPE}}> {
|
|
15
|
-
{{METHOD_IMPLEMENTATION}}
|
|
16
|
-
}`,
|
|
17
|
-
userExtraction: ` const user = context.request.user;
|
|
18
|
-
if (!user) {
|
|
19
|
-
throw new Error('User authentication required');
|
|
20
|
-
}`,
|
|
21
|
-
methodImplementations: {
|
|
22
|
-
list: `{{USER_EXTRACTION}}
|
|
23
|
-
// Extract pagination from URL parameters
|
|
24
|
-
const page = parseInt(context.request.parameters.page as string) || 1;
|
|
25
|
-
const limit = parseInt(context.request.parameters.limit as string) || 10;
|
|
26
|
-
|
|
27
|
-
const {{ENTITY_LOWER}}s = await this.{{ENTITY_LOWER}}Service.list(page, limit{{USER_PARAM}});
|
|
28
|
-
return {{ENTITY_LOWER}}s;`,
|
|
29
|
-
get: `{{USER_EXTRACTION}}
|
|
30
|
-
const id = parseInt(context.request.parameters.id as string);
|
|
31
|
-
if (isNaN(id)) {
|
|
32
|
-
throw new Error('Invalid ID parameter');
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const {{ENTITY_LOWER}} = await this.{{ENTITY_LOWER}}Service.get(id{{USER_PARAM}});
|
|
36
|
-
return {{ENTITY_LOWER}};`,
|
|
37
|
-
create: `{{USER_EXTRACTION}}
|
|
38
|
-
const new{{ENTITY_NAME}} = await this.{{ENTITY_LOWER}}Service.create(context.request.body as {{ENTITY_NAME}}DTO{{USER_PARAM}});
|
|
39
|
-
return new{{ENTITY_NAME}};`,
|
|
40
|
-
update: `{{USER_EXTRACTION}}
|
|
41
|
-
const id = parseInt(context.request.parameters.id as string);
|
|
42
|
-
if (isNaN(id)) {
|
|
43
|
-
throw new Error('Invalid ID parameter');
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const updated{{ENTITY_NAME}} = await this.{{ENTITY_LOWER}}Service.update(id, context.request.body as {{ENTITY_NAME}}DTO{{USER_PARAM}});
|
|
47
|
-
return updated{{ENTITY_NAME}};`,
|
|
48
|
-
delete: `{{USER_EXTRACTION}}
|
|
49
|
-
const id = parseInt(context.request.parameters.id as string);
|
|
50
|
-
if (isNaN(id)) {
|
|
51
|
-
throw new Error('Invalid ID parameter');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const result = await this.{{ENTITY_LOWER}}Service.delete(id{{USER_PARAM}});
|
|
55
|
-
return result;`,
|
|
56
|
-
empty: `{{USER_EXTRACTION}}
|
|
57
|
-
// Provide an empty/default {{ENTITY_NAME}} for create form rendering
|
|
58
|
-
// Note: actual create happens via API endpoint using custom form handling
|
|
59
|
-
return {} as any;`
|
|
60
|
-
},
|
|
61
|
-
responseFormats: {
|
|
62
|
-
list: `{ data: {{ENTITY_LOWER}}s, page, limit }`,
|
|
63
|
-
get: `{ data: {{ENTITY_LOWER}} }`,
|
|
64
|
-
create: `{ data: new{{ENTITY_NAME}}, message: '{{ENTITY_NAME}} created successfully' }`,
|
|
65
|
-
update: `{ data: updated{{ENTITY_NAME}}, message: '{{ENTITY_NAME}} updated successfully' }`,
|
|
66
|
-
delete: `result`
|
|
67
|
-
},
|
|
68
|
-
statusCodes: {
|
|
69
|
-
list: { success: 200, error: 500 },
|
|
70
|
-
get: { success: 200, error: 404 },
|
|
71
|
-
create: { success: 201, error: 400 },
|
|
72
|
-
update: { success: 200, error: 400 },
|
|
73
|
-
delete: { success: 200, error: 400 }
|
|
74
|
-
}
|
|
75
|
-
};
|
|
76
|
-
exports.controllerFileTemplate = `import { {{ENTITY_NAME}} } from '../../domain/entities/{{ENTITY_NAME}}';
|
|
77
|
-
import { {{ENTITY_NAME}}Service } from '../../application/services/{{ENTITY_NAME}}Service';
|
|
78
|
-
import { {{ENTITY_NAME}}DTO } from '../../application/validation/{{ENTITY_NAME}}Validation';{{JWT_IMPORT}}
|
|
79
|
-
import { Get, Post, Put, Patch, Delete, Controller, Render } from '@currentjs/router';
|
|
80
|
-
import type { IContext } from '@currentjs/router';
|
|
81
|
-
|
|
82
|
-
{{CONTROLLER_CLASS}}`;
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export declare const newStoreTemplates: {
|
|
2
|
-
rowInterface: string;
|
|
3
|
-
storeClass: string;
|
|
4
|
-
};
|
|
5
|
-
export declare const newStoreFileTemplate = "import { {{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";
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.newStoreFileTemplate = exports.newStoreTemplates = void 0;
|
|
4
|
-
exports.newStoreTemplates = {
|
|
5
|
-
rowInterface: `export interface {{ENTITY_NAME}}Row {
|
|
6
|
-
id: number;
|
|
7
|
-
{{ROW_FIELDS}}
|
|
8
|
-
created_at: string;
|
|
9
|
-
updated_at: string;
|
|
10
|
-
deleted_at?: string;
|
|
11
|
-
}`,
|
|
12
|
-
storeClass: `/**
|
|
13
|
-
* Data access layer for {{ENTITY_NAME}}
|
|
14
|
-
*/
|
|
15
|
-
export class {{ENTITY_NAME}}Store {
|
|
16
|
-
private tableName = '{{TABLE_NAME}}';
|
|
17
|
-
|
|
18
|
-
constructor(private db: ISqlProvider) {}
|
|
19
|
-
|
|
20
|
-
private toMySQLDatetime(date: Date): string {
|
|
21
|
-
return date.toISOString().slice(0, 19).replace('T', ' ');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
private rowToModel(row: {{ENTITY_NAME}}Row): {{ENTITY_NAME}} {
|
|
25
|
-
return new {{ENTITY_NAME}}(
|
|
26
|
-
row.id,
|
|
27
|
-
{{ROW_TO_MODEL_MAPPING}}
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async getAll(page: number = 1, limit: number = 20): Promise<{{ENTITY_NAME}}[]> {
|
|
32
|
-
const offset = (page - 1) * limit;
|
|
33
|
-
const result = await this.db.query(
|
|
34
|
-
\`SELECT {{FIELD_NAMES}} FROM \\\`\${this.tableName}\\\` WHERE deleted_at IS NULL LIMIT :limit OFFSET :offset\`,
|
|
35
|
-
{ limit: String(limit), offset: String(offset) }
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
if (result.success && result.data) {
|
|
39
|
-
return result.data.map((row: {{ENTITY_NAME}}Row) => this.rowToModel(row));
|
|
40
|
-
}
|
|
41
|
-
return [];
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async count(): Promise<number> {
|
|
45
|
-
const result = await this.db.query(
|
|
46
|
-
\`SELECT COUNT(*) as count FROM \\\`\${this.tableName}\\\` WHERE deleted_at IS NULL\`,
|
|
47
|
-
{}
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
if (result.success && result.data && result.data.length > 0) {
|
|
51
|
-
return parseInt(result.data[0].count, 10);
|
|
52
|
-
}
|
|
53
|
-
return 0;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
async getById(id: number): Promise<{{ENTITY_NAME}} | null> {
|
|
57
|
-
const result = await this.db.query(
|
|
58
|
-
\`SELECT {{FIELD_NAMES}} FROM \\\`\${this.tableName}\\\` WHERE id = :id AND deleted_at IS NULL\`,
|
|
59
|
-
{ id }
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
if (result.success && result.data && result.data.length > 0) {
|
|
63
|
-
return this.rowToModel(result.data[0] as {{ENTITY_NAME}}Row);
|
|
64
|
-
}
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
async insert(entity: {{ENTITY_NAME}}): Promise<{{ENTITY_NAME}}> {
|
|
69
|
-
const now = new Date();
|
|
70
|
-
const data: Partial<{{ENTITY_NAME}}Row> = {
|
|
71
|
-
{{INSERT_DATA_MAPPING}},
|
|
72
|
-
created_at: this.toMySQLDatetime(now),
|
|
73
|
-
updated_at: this.toMySQLDatetime(now)
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
const fieldsList = Object.keys(data).map(f => \`\\\`\${f}\\\`\`).join(', ');
|
|
77
|
-
const placeholders = Object.keys(data).map(f => \`:\${f}\`).join(', ');
|
|
78
|
-
|
|
79
|
-
const result = await this.db.query(
|
|
80
|
-
\`INSERT INTO \\\`\${this.tableName}\\\` (\${fieldsList}) VALUES (\${placeholders})\`,
|
|
81
|
-
data
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
if (result.success && result.insertId) {
|
|
85
|
-
const newId = typeof result.insertId === 'string' ? parseInt(result.insertId, 10) : result.insertId;
|
|
86
|
-
return this.getById(newId) as Promise<{{ENTITY_NAME}}>;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
throw new Error('Failed to insert {{ENTITY_NAME}}');
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
async update(id: number, entity: {{ENTITY_NAME}}): Promise<{{ENTITY_NAME}}> {
|
|
93
|
-
const now = new Date();
|
|
94
|
-
const data: Partial<{{ENTITY_NAME}}Row> & { id: number } = {
|
|
95
|
-
{{UPDATE_DATA_MAPPING}},
|
|
96
|
-
updated_at: this.toMySQLDatetime(now),
|
|
97
|
-
id
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const updateFields = {{UPDATE_FIELDS_ARRAY}}.map(f => \`\\\`\${f}\\\` = :\${f}\`).join(', ');
|
|
101
|
-
|
|
102
|
-
const result = await this.db.query(
|
|
103
|
-
\`UPDATE \\\`\${this.tableName}\\\` SET \${updateFields}, updated_at = :updated_at WHERE id = :id\`,
|
|
104
|
-
data
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
if (result.success) {
|
|
108
|
-
return this.getById(id) as Promise<{{ENTITY_NAME}}>;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
throw new Error('Failed to update {{ENTITY_NAME}}');
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
async softDelete(id: number): Promise<boolean> {
|
|
115
|
-
const now = new Date();
|
|
116
|
-
const result = await this.db.query(
|
|
117
|
-
\`UPDATE \\\`\${this.tableName}\\\` SET deleted_at = :deleted_at WHERE id = :id\`,
|
|
118
|
-
{ deleted_at: this.toMySQLDatetime(now), id }
|
|
119
|
-
);
|
|
120
|
-
|
|
121
|
-
return result.success;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
async hardDelete(id: number): Promise<boolean> {
|
|
125
|
-
const result = await this.db.query(
|
|
126
|
-
\`DELETE FROM \\\`\${this.tableName}\\\` WHERE id = :id\`,
|
|
127
|
-
{ id }
|
|
128
|
-
);
|
|
129
|
-
|
|
130
|
-
return result.success;
|
|
131
|
-
}
|
|
132
|
-
{{GET_BY_PARENT_ID_METHOD}}
|
|
133
|
-
{{GET_RESOURCE_OWNER_METHOD}}}`
|
|
134
|
-
};
|
|
135
|
-
exports.newStoreFileTemplate = `import { {{ENTITY_NAME}} } from '../../domain/entities/{{ENTITY_NAME}}';
|
|
136
|
-
import type { ISqlProvider } from '@currentjs/provider-mysql';{{VALUE_OBJECT_IMPORTS}}
|
|
137
|
-
|
|
138
|
-
{{ROW_INTERFACE}}
|
|
139
|
-
|
|
140
|
-
{{STORE_CLASS}}
|
|
141
|
-
`;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export declare const serviceTemplates: {
|
|
2
|
-
serviceClass: string;
|
|
3
|
-
serviceMethod: string;
|
|
4
|
-
permissionCheck: string;
|
|
5
|
-
ownerPermissionCheck: string;
|
|
6
|
-
defaultImplementations: {
|
|
7
|
-
list: string;
|
|
8
|
-
get: string;
|
|
9
|
-
getById: string;
|
|
10
|
-
create: string;
|
|
11
|
-
update: string;
|
|
12
|
-
delete: string;
|
|
13
|
-
};
|
|
14
|
-
customActionImplementation: string;
|
|
15
|
-
};
|
|
16
|
-
export declare const serviceFileTemplate = "import { {{ENTITY_NAME}} } from '../../domain/entities/{{ENTITY_NAME}}';\nimport { {{ENTITY_NAME}}Store } from '../../infrastructure/stores/{{ENTITY_NAME}}Store';\nimport { {{ENTITY_NAME}}DTO, validateCreate{{ENTITY_NAME}}, validateUpdate{{ENTITY_NAME}} } from '../validation/{{ENTITY_NAME}}Validation';{{PERMISSIONS_IMPORT}}{{CUSTOM_IMPORTS}}\n\n{{SERVICE_CLASS}}";
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.serviceFileTemplate = exports.serviceTemplates = void 0;
|
|
4
|
-
exports.serviceTemplates = {
|
|
5
|
-
serviceClass: `export class {{ENTITY_NAME}}Service {
|
|
6
|
-
constructor(
|
|
7
|
-
private {{ENTITY_LOWER}}Store: {{ENTITY_NAME}}Store{{AUTH_SERVICE_PARAM}}
|
|
8
|
-
) {}
|
|
9
|
-
|
|
10
|
-
{{SERVICE_METHODS}}
|
|
11
|
-
}`,
|
|
12
|
-
serviceMethod: ` async {{METHOD_NAME}}({{METHOD_PARAMS}}{{USER_PARAM}}): Promise<{{RETURN_TYPE}}> {
|
|
13
|
-
{{PERMISSION_CHECK}}
|
|
14
|
-
{{METHOD_IMPLEMENTATION}}
|
|
15
|
-
}`,
|
|
16
|
-
permissionCheck: ` // Role check: {{REQUIRED_ROLES}}
|
|
17
|
-
const allowedRoles = [{{ROLES_ARRAY}}];
|
|
18
|
-
if (allowedRoles.length > 0 && !allowedRoles.includes(user.role)) {
|
|
19
|
-
throw new Error('Insufficient permissions to perform this action');
|
|
20
|
-
}`,
|
|
21
|
-
ownerPermissionCheck: ``,
|
|
22
|
-
defaultImplementations: {
|
|
23
|
-
list: `const {{ENTITY_LOWER}}s = await this.{{ENTITY_LOWER}}Store.getAll(page, limit);
|
|
24
|
-
return {{ENTITY_LOWER}}s;`,
|
|
25
|
-
get: `const {{ENTITY_LOWER}} = await this.{{ENTITY_LOWER}}Store.getById(id);
|
|
26
|
-
if (!{{ENTITY_LOWER}}) {
|
|
27
|
-
throw new Error('{{ENTITY_NAME}} not found');
|
|
28
|
-
}
|
|
29
|
-
return {{ENTITY_LOWER}};`,
|
|
30
|
-
getById: `const {{ENTITY_LOWER}} = await this.{{ENTITY_LOWER}}Store.getById(id);
|
|
31
|
-
if (!{{ENTITY_LOWER}}) {
|
|
32
|
-
throw new Error('{{ENTITY_NAME}} not found');
|
|
33
|
-
}
|
|
34
|
-
return {{ENTITY_LOWER}};`,
|
|
35
|
-
create: `validateCreate{{ENTITY_NAME}}({{ENTITY_LOWER}}Data);
|
|
36
|
-
const {{ENTITY_LOWER}} = new {{ENTITY_NAME}}(0, {{CONSTRUCTOR_ARGS}});
|
|
37
|
-
return await this.{{ENTITY_LOWER}}Store.insert({{ENTITY_LOWER}});`,
|
|
38
|
-
update: `validateUpdate{{ENTITY_NAME}}({{ENTITY_LOWER}}Data);
|
|
39
|
-
const existing{{ENTITY_NAME}} = await this.{{ENTITY_LOWER}}Store.getById(id);
|
|
40
|
-
if (!existing{{ENTITY_NAME}}) {
|
|
41
|
-
throw new Error('{{ENTITY_NAME}} not found');
|
|
42
|
-
}
|
|
43
|
-
{{UPDATE_SETTER_CALLS}}
|
|
44
|
-
return await this.{{ENTITY_LOWER}}Store.update(id, existing{{ENTITY_NAME}});`,
|
|
45
|
-
delete: `const success = await this.{{ENTITY_LOWER}}Store.softDelete(id);
|
|
46
|
-
if (!success) {
|
|
47
|
-
throw new Error('{{ENTITY_NAME}} not found or could not be deleted');
|
|
48
|
-
}
|
|
49
|
-
return { success: true, message: '{{ENTITY_NAME}} deleted successfully' };`
|
|
50
|
-
},
|
|
51
|
-
customActionImplementation: `// Custom action implementation
|
|
52
|
-
const result = await {{CUSTOM_FUNCTION_CALL}};
|
|
53
|
-
return result;`
|
|
54
|
-
};
|
|
55
|
-
exports.serviceFileTemplate = `import { {{ENTITY_NAME}} } from '../../domain/entities/{{ENTITY_NAME}}';
|
|
56
|
-
import { {{ENTITY_NAME}}Store } from '../../infrastructure/stores/{{ENTITY_NAME}}Store';
|
|
57
|
-
import { {{ENTITY_NAME}}DTO, validateCreate{{ENTITY_NAME}}, validateUpdate{{ENTITY_NAME}} } from '../validation/{{ENTITY_NAME}}Validation';{{PERMISSIONS_IMPORT}}{{CUSTOM_IMPORTS}}
|
|
58
|
-
|
|
59
|
-
{{SERVICE_CLASS}}`;
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export declare const validationTemplates: {
|
|
2
|
-
inputInterface: string;
|
|
3
|
-
validationFunction: string;
|
|
4
|
-
requiredStringValidation: string;
|
|
5
|
-
optionalStringValidation: string;
|
|
6
|
-
requiredNumberValidation: string;
|
|
7
|
-
optionalNumberValidation: string;
|
|
8
|
-
requiredBooleanValidation: string;
|
|
9
|
-
optionalBooleanValidation: string;
|
|
10
|
-
requiredDateValidation: string;
|
|
11
|
-
optionalDateValidation: string;
|
|
12
|
-
requiredComplexValidation: string;
|
|
13
|
-
optionalComplexValidation: string;
|
|
14
|
-
validationFileTemplate: string;
|
|
15
|
-
dtoInterface: string;
|
|
16
|
-
};
|
|
17
|
-
export declare const typeMapping: {
|
|
18
|
-
string: string;
|
|
19
|
-
number: string;
|
|
20
|
-
boolean: string;
|
|
21
|
-
datetime: string;
|
|
22
|
-
json: string;
|
|
23
|
-
object: string;
|
|
24
|
-
array: string;
|
|
25
|
-
};
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.typeMapping = exports.validationTemplates = void 0;
|
|
4
|
-
exports.validationTemplates = {
|
|
5
|
-
inputInterface: `export interface {{INTERFACE_NAME}} {
|
|
6
|
-
{{INTERFACE_FIELDS}}
|
|
7
|
-
}`,
|
|
8
|
-
validationFunction: `export function {{FUNCTION_NAME}}(data: any): boolean {
|
|
9
|
-
const errors: string[] = [];
|
|
10
|
-
|
|
11
|
-
{{VALIDATION_LOGIC}}
|
|
12
|
-
|
|
13
|
-
if (errors.length > 0) {
|
|
14
|
-
throw new Error(\`Validation failed: \${errors.join(', ')}\`);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return true;
|
|
18
|
-
}`,
|
|
19
|
-
requiredStringValidation: ` if (!data.{{FIELD_NAME}} || typeof data.{{FIELD_NAME}} !== 'string') {
|
|
20
|
-
errors.push('{{FIELD_NAME}} is required and must be a string');
|
|
21
|
-
}`,
|
|
22
|
-
optionalStringValidation: ` if (data.{{FIELD_NAME}} !== undefined && typeof data.{{FIELD_NAME}} !== 'string') {
|
|
23
|
-
errors.push('{{FIELD_NAME}} must be a string');
|
|
24
|
-
}`,
|
|
25
|
-
requiredNumberValidation: ` if (data.{{FIELD_NAME}} === undefined || data.{{FIELD_NAME}} === null || typeof data.{{FIELD_NAME}} !== 'number' || isNaN(data.{{FIELD_NAME}})) {
|
|
26
|
-
errors.push('{{FIELD_NAME}} is required and must be a number');
|
|
27
|
-
}`,
|
|
28
|
-
optionalNumberValidation: ` if (data.{{FIELD_NAME}} !== undefined && (typeof data.{{FIELD_NAME}} !== 'number' || isNaN(data.{{FIELD_NAME}}))) {
|
|
29
|
-
errors.push('{{FIELD_NAME}} must be a number');
|
|
30
|
-
}`,
|
|
31
|
-
requiredBooleanValidation: ` if (data.{{FIELD_NAME}} === undefined || data.{{FIELD_NAME}} === null || typeof data.{{FIELD_NAME}} !== 'boolean') {
|
|
32
|
-
errors.push('{{FIELD_NAME}} is required and must be a boolean');
|
|
33
|
-
}`,
|
|
34
|
-
optionalBooleanValidation: ` if (data.{{FIELD_NAME}} !== undefined && typeof data.{{FIELD_NAME}} !== 'boolean') {
|
|
35
|
-
errors.push('{{FIELD_NAME}} must be a boolean');
|
|
36
|
-
}`,
|
|
37
|
-
requiredDateValidation: ` if (!data.{{FIELD_NAME}} || !(data.{{FIELD_NAME}} instanceof Date) && isNaN(Date.parse(data.{{FIELD_NAME}}))) {
|
|
38
|
-
errors.push('{{FIELD_NAME}} is required and must be a valid date');
|
|
39
|
-
}`,
|
|
40
|
-
optionalDateValidation: ` if (data.{{FIELD_NAME}} !== undefined && !(data.{{FIELD_NAME}} instanceof Date) && isNaN(Date.parse(data.{{FIELD_NAME}}))) {
|
|
41
|
-
errors.push('{{FIELD_NAME}} must be a valid date');
|
|
42
|
-
}`,
|
|
43
|
-
// For complex types, just pass through for now
|
|
44
|
-
requiredComplexValidation: ` if (data.{{FIELD_NAME}} === undefined || data.{{FIELD_NAME}} === null) {
|
|
45
|
-
errors.push('{{FIELD_NAME}} is required');
|
|
46
|
-
}`,
|
|
47
|
-
optionalComplexValidation: ` // {{FIELD_NAME}} - complex type validation to be implemented later`,
|
|
48
|
-
validationFileTemplate: `// Generated validation for {{ENTITY_NAME}}
|
|
49
|
-
|
|
50
|
-
{{DTO_INTERFACES}}
|
|
51
|
-
|
|
52
|
-
{{VALIDATION_FUNCTIONS}}
|
|
53
|
-
`,
|
|
54
|
-
dtoInterface: `export interface {{DTO_NAME}} {
|
|
55
|
-
{{DTO_FIELDS}}
|
|
56
|
-
}`
|
|
57
|
-
};
|
|
58
|
-
exports.typeMapping = {
|
|
59
|
-
string: 'string',
|
|
60
|
-
number: 'number',
|
|
61
|
-
boolean: 'boolean',
|
|
62
|
-
datetime: 'Date',
|
|
63
|
-
json: 'any',
|
|
64
|
-
object: 'any',
|
|
65
|
-
array: 'any[]'
|
|
66
|
-
};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
type FieldConfig = {
|
|
2
|
-
name: string;
|
|
3
|
-
type: string;
|
|
4
|
-
required?: boolean;
|
|
5
|
-
auto?: boolean;
|
|
6
|
-
unique?: boolean;
|
|
7
|
-
enum?: string[];
|
|
8
|
-
displayFields?: string[];
|
|
9
|
-
};
|
|
10
|
-
type RelationshipContext = {
|
|
11
|
-
routePaths: Map<string, string>;
|
|
12
|
-
apiPaths: Map<string, string>;
|
|
13
|
-
};
|
|
14
|
-
declare function setAvailableModels(models: string[]): void;
|
|
15
|
-
declare function setRelationshipContext(context: RelationshipContext): void;
|
|
16
|
-
declare function isRelationshipField(field: FieldConfig): boolean;
|
|
17
|
-
declare function getForeignKeyFieldName(field: FieldConfig): string;
|
|
18
|
-
export declare function toFileNameFromTemplateName(name: string): string;
|
|
19
|
-
export { setAvailableModels, setRelationshipContext, isRelationshipField, getForeignKeyFieldName };
|
|
20
|
-
export declare function renderListTemplate(entityName: string, templateName: string, basePath: string, fields: FieldConfig[], apiBase?: string): string;
|
|
21
|
-
export declare function renderDetailTemplate(entityName: string, templateName: string, fields: FieldConfig[]): string;
|
|
22
|
-
export declare function renderCreateTemplate(entityName: string, templateName: string, apiBase: string, fields: FieldConfig[], strategy?: string[], basePath?: string): string;
|
|
23
|
-
export declare function renderUpdateTemplate(entityName: string, templateName: string, apiBase: string, fields: FieldConfig[], strategy?: string[], basePath?: string): string;
|
|
24
|
-
export declare function renderDeleteTemplate(entityName: string, templateName: string, apiBase: string, strategy?: string[], basePath?: string): string;
|
|
25
|
-
export declare function renderLayoutTemplate(layoutName: string): string;
|