@currentjs/gen 0.3.1 → 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 +8 -289
  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 +76 -47
  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,204 @@
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.parseClassFile = parseClassFile;
37
+ exports.scanModuleClasses = scanModuleClasses;
38
+ exports.buildInstantiationOrder = buildInstantiationOrder;
39
+ exports.resolveProviderImport = resolveProviderImport;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const INJECTABLE_RE = /@Injectable\s*\(/;
43
+ const CONTROLLER_RE = /@Controller\s*\(/;
44
+ const EXPORT_CLASS_RE = /export\s+class\s+(\w+)/;
45
+ const CONSTRUCTOR_PARAMS_RE = /constructor\s*\(([^)]*)\)/s;
46
+ const PARAM_RE = /(?:private|protected|public)\s+(\w+)\s*:\s*([A-Za-z_]\w*)/g;
47
+ function parseClassFile(filePath) {
48
+ let content;
49
+ try {
50
+ content = fs.readFileSync(filePath, 'utf8');
51
+ }
52
+ catch {
53
+ return null;
54
+ }
55
+ const classMatch = content.match(EXPORT_CLASS_RE);
56
+ if (!classMatch)
57
+ return null;
58
+ const isInjectable = INJECTABLE_RE.test(content);
59
+ const isController = CONTROLLER_RE.test(content);
60
+ if (!isInjectable && !isController)
61
+ return null;
62
+ const className = classMatch[1];
63
+ const constructorParams = [];
64
+ const ctorMatch = content.match(CONSTRUCTOR_PARAMS_RE);
65
+ if (ctorMatch) {
66
+ const paramsSrc = ctorMatch[1].replace(/\n/g, ' ');
67
+ let match;
68
+ const paramRe = new RegExp(PARAM_RE.source, PARAM_RE.flags);
69
+ while ((match = paramRe.exec(paramsSrc))) {
70
+ constructorParams.push({ name: match[1], type: match[2] });
71
+ }
72
+ }
73
+ return { className, filePath, isController, isInjectable, constructorParams };
74
+ }
75
+ function walkTsFiles(dir) {
76
+ const results = [];
77
+ let entries;
78
+ try {
79
+ entries = fs.readdirSync(dir, { withFileTypes: true });
80
+ }
81
+ catch {
82
+ return results;
83
+ }
84
+ for (const entry of entries) {
85
+ const fullPath = path.join(dir, entry.name);
86
+ if (entry.isDirectory()) {
87
+ results.push(...walkTsFiles(fullPath));
88
+ }
89
+ else if (entry.isFile() && entry.name.endsWith('.ts')) {
90
+ results.push(fullPath);
91
+ }
92
+ }
93
+ return results;
94
+ }
95
+ function scanModuleClasses(moduleDir) {
96
+ const tsFiles = walkTsFiles(moduleDir);
97
+ const classes = [];
98
+ for (const file of tsFiles) {
99
+ const info = parseClassFile(file);
100
+ if (info)
101
+ classes.push(info);
102
+ }
103
+ return classes;
104
+ }
105
+ /**
106
+ * @param classes - All discovered @Injectable and @Controller classes
107
+ * @param providerVarByType - Default mapping from interface type to variable name (e.g., ISqlProvider -> dbMysql)
108
+ * @param classProviderVar - Per-class override for provider variable (className -> varName).
109
+ * Used when different modules use different database providers.
110
+ * @param srcDir - Absolute path to src/ directory (for computing relative import paths)
111
+ */
112
+ function buildInstantiationOrder(classes, providerVarByType, classProviderVar, srcDir) {
113
+ const classMap = new Map();
114
+ for (const cls of classes) {
115
+ if (!classMap.has(cls.className)) {
116
+ classMap.set(cls.className, cls);
117
+ }
118
+ }
119
+ const graph = new Map();
120
+ for (const cls of classMap.values()) {
121
+ const deps = [];
122
+ for (const param of cls.constructorParams) {
123
+ if (classMap.has(param.type)) {
124
+ deps.push(param.type);
125
+ }
126
+ }
127
+ graph.set(cls.className, deps);
128
+ }
129
+ const sorted = topologicalSort(graph);
130
+ const steps = [];
131
+ const varNames = new Map();
132
+ for (const className of sorted) {
133
+ const cls = classMap.get(className);
134
+ const varName = className.charAt(0).toLowerCase() + className.slice(1);
135
+ varNames.set(className, varName);
136
+ const constructorArgs = [];
137
+ for (const param of cls.constructorParams) {
138
+ if (classProviderVar.has(className) && providerVarByType.has(param.type)) {
139
+ constructorArgs.push(classProviderVar.get(className));
140
+ }
141
+ else if (providerVarByType.has(param.type)) {
142
+ constructorArgs.push(providerVarByType.get(param.type));
143
+ }
144
+ else if (varNames.has(param.type)) {
145
+ constructorArgs.push(varNames.get(param.type));
146
+ }
147
+ }
148
+ const relPath = path.relative(srcDir, cls.filePath)
149
+ .replace(/\\/g, '/')
150
+ .replace(/\.ts$/, '');
151
+ const importPath = relPath.startsWith('.') ? relPath : `./${relPath}`;
152
+ steps.push({
153
+ className,
154
+ varName,
155
+ importPath,
156
+ constructorArgs,
157
+ isController: cls.isController
158
+ });
159
+ }
160
+ return steps;
161
+ }
162
+ function topologicalSort(graph) {
163
+ const visited = new Set();
164
+ const visiting = new Set();
165
+ const result = [];
166
+ function visit(node) {
167
+ if (visited.has(node))
168
+ return;
169
+ if (visiting.has(node)) {
170
+ throw new Error(`Circular dependency detected involving: ${node}`);
171
+ }
172
+ visiting.add(node);
173
+ const deps = graph.get(node) || [];
174
+ for (const dep of deps) {
175
+ if (graph.has(dep)) {
176
+ visit(dep);
177
+ }
178
+ }
179
+ visiting.delete(node);
180
+ visited.add(node);
181
+ result.push(node);
182
+ }
183
+ for (const node of graph.keys()) {
184
+ visit(node);
185
+ }
186
+ return result;
187
+ }
188
+ function resolveProviderImport(importSpec, appTsDir) {
189
+ const baseName = importSpec.split('/').pop() || 'provider';
190
+ const className = baseName
191
+ .replace(/^[^a-zA-Z_]*/g, '')
192
+ .split(/[-_]/)
193
+ .map(s => s.charAt(0).toUpperCase() + s.slice(1))
194
+ .join('');
195
+ const isLocal = importSpec.startsWith('.') || importSpec.startsWith('/');
196
+ if (isLocal) {
197
+ const absPath = path.resolve(appTsDir, importSpec);
198
+ let relPath = path.relative(appTsDir, absPath).replace(/\\/g, '/');
199
+ if (!relPath.startsWith('.'))
200
+ relPath = `./${relPath}`;
201
+ return { importPath: relPath, className };
202
+ }
203
+ return { importPath: importSpec, className };
204
+ }
File without changes
@@ -0,0 +1,164 @@
1
+ "use strict";
2
+ /*
3
+ export async function connectToDatabase(): Promise<mysql.Connection> {
4
+ const config = {
5
+ host: process.env.DB_HOST || 'localhost',
6
+ port: parseInt(process.env.DB_PORT || '3306'),
7
+ user: process.env.DB_USER || 'root',
8
+ password: process.env.DB_PASSWORD || '',
9
+ database: process.env.DB_NAME || 'test',
10
+ };
11
+
12
+ try {
13
+ const connection = await mysql.createConnection(config);
14
+ return connection;
15
+ } catch (error) {
16
+ throw new Error(`Failed to connect to database: ${error instanceof Error ? error.message : String(error)}`);
17
+ }
18
+ }
19
+
20
+ export async function getTableNames(connection: mysql.Connection): Promise<string[]> {
21
+ const [rows] = await connection.query('SHOW TABLES');
22
+ const tableKey = Object.keys(rows[0] as object)[0];
23
+ return (rows as any[]).map(row => row[tableKey]);
24
+ }
25
+
26
+ export async function getTableSchema(connection: mysql.Connection, tableName: string): Promise<ColumnInfo[]> {
27
+ const [rows] = await connection.query(`DESCRIBE ${tableName}`);
28
+ return rows as ColumnInfo[];
29
+ }
30
+
31
+ export async function getForeignKeys(connection: mysql.Connection, tableName: string): Promise<ForeignKeyInfo[]> {
32
+ const [rows] = await connection.query(
33
+ `SELECT
34
+ CONSTRAINT_NAME,
35
+ COLUMN_NAME,
36
+ REFERENCED_TABLE_NAME,
37
+ REFERENCED_COLUMN_NAME
38
+ FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
39
+ WHERE TABLE_SCHEMA = DATABASE()
40
+ AND TABLE_NAME = ?
41
+ AND REFERENCED_TABLE_NAME IS NOT NULL`,
42
+ [tableName]
43
+ );
44
+ return rows as ForeignKeyInfo[];
45
+ }
46
+
47
+
48
+ export function sqlTypeToYamlType(sqlType: string): string {
49
+ const upperType = sqlType.toUpperCase();
50
+
51
+ if (upperType.includes('VARCHAR') || upperType.includes('TEXT') || upperType.includes('CHAR')) {
52
+ return 'string';
53
+ }
54
+ if (upperType.includes('INT') || upperType.includes('DECIMAL') || upperType.includes('FLOAT') || upperType.includes('DOUBLE')) {
55
+ return 'number';
56
+ }
57
+ if (upperType.includes('TINYINT(1)') || upperType.includes('BOOLEAN')) {
58
+ return 'boolean';
59
+ }
60
+ if (upperType.includes('DATETIME') || upperType.includes('TIMESTAMP') || upperType.includes('DATE')) {
61
+ return 'datetime';
62
+ }
63
+ if (upperType.includes('JSON')) {
64
+ return 'json';
65
+ }
66
+
67
+ return 'string'; // Default
68
+ }
69
+
70
+
71
+ export async function extractSchemaFromDatabase(connection: mysql.Connection): Promise<ModelConfig[]> {
72
+ const models: ModelConfig[] = [];
73
+ const tables = await getTableNames(connection);
74
+
75
+ for (const table of tables) {
76
+ // Skip migration log table
77
+ if (table === 'migration_log') {
78
+ continue;
79
+ }
80
+
81
+ const columns = await getTableSchema(connection, table);
82
+ const foreignKeys = await getForeignKeys(connection, table);
83
+
84
+ // Convert table name to model name (e.g., cats -> Cat)
85
+ const modelName = table.slice(0, -1).charAt(0).toUpperCase() + table.slice(1, -1);
86
+
87
+ const fields: FieldConfig[] = [];
88
+
89
+ for (const column of columns) {
90
+ // Skip standard columns
91
+ if (['id', 'created_at', 'updated_at', 'deleted_at'].includes(column.Field)) {
92
+ continue;
93
+ }
94
+
95
+ // Check if this is a foreign key
96
+ const fk = foreignKeys.find(fk => fk.COLUMN_NAME === column.Field);
97
+
98
+ if (fk) {
99
+ // This is a foreign key - extract the relationship field name
100
+ const fieldName = column.Field.endsWith('Id')
101
+ ? column.Field.slice(0, -2)
102
+ : column.Field;
103
+
104
+ // Convert referenced table to model name
105
+ const refModelName = fk.REFERENCED_TABLE_NAME.slice(0, -1).charAt(0).toUpperCase() +
106
+ fk.REFERENCED_TABLE_NAME.slice(1, -1);
107
+
108
+ fields.push({
109
+ name: fieldName,
110
+ type: refModelName,
111
+ required: column.Null === 'NO'
112
+ });
113
+ } else {
114
+ // Regular field
115
+ fields.push({
116
+ name: column.Field,
117
+ type: sqlTypeToYamlType(column.Type),
118
+ required: column.Null === 'NO'
119
+ });
120
+ }
121
+ }
122
+
123
+ models.push({
124
+ name: modelName,
125
+ fields
126
+ });
127
+ }
128
+
129
+ return models;
130
+ }
131
+ */
132
+ /*
133
+ export async function executeMigration(connection: mysql.Connection, migrationSQL: string): Promise<void> {
134
+ // Split by semicolons and execute each statement
135
+ const statements = migrationSQL
136
+ .split(';')
137
+ .map(s => s.trim())
138
+ .filter(s => s.length > 0 && !s.startsWith('--'));
139
+
140
+ for (const statement of statements) {
141
+ await connection.query(statement);
142
+ }
143
+ }
144
+
145
+ export async function ensureMigrationLogTable(connection: mysql.Connection): Promise<void> {
146
+ await connection.query(`
147
+ CREATE TABLE IF NOT EXISTS migration_log (
148
+ id INT AUTO_INCREMENT PRIMARY KEY,
149
+ filename VARCHAR(255) NOT NULL UNIQUE,
150
+ applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
151
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
152
+ `);
153
+ }
154
+
155
+ export async function getAppliedMigrations(connection: mysql.Connection): Promise<string[]> {
156
+ await ensureMigrationLogTable(connection);
157
+ const [rows] = await connection.query('SELECT filename FROM migration_log ORDER BY applied_at');
158
+ return (rows as any[]).map(row => row.filename);
159
+ }
160
+
161
+ export async function recordMigration(connection: mysql.Connection, filename: string): Promise<void> {
162
+ await connection.query('INSERT INTO migration_log (filename) VALUES (?)', [filename]);
163
+ }
164
+ */
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Shared type mapping and string utilities used across generators.
3
+ */
4
+ export interface TypeMapping {
5
+ [key: string]: string;
6
+ }
7
+ /** Standard YAML type to TypeScript (domain) type mapping. */
8
+ export declare const TYPE_MAPPING: Record<string, string>;
9
+ /** Store-specific: YAML type to DB row TypeScript type (e.g. datetime -> string). */
10
+ export declare const ROW_TYPE_MAPPING: Record<string, string>;
11
+ export declare function capitalize(str: string): string;
12
+ /**
13
+ * Map a YAML field type to TypeScript type, resolving aggregates and value objects by name.
14
+ */
15
+ export declare function mapType(yamlType: string, aggregates?: Set<string> | Map<string, unknown>, valueObjects?: Set<string> | Map<string, unknown>): string;
16
+ /**
17
+ * Map a YAML type to the store row TypeScript type (value objects become string).
18
+ */
19
+ export declare function mapRowType(yamlType: string, valueObjects?: Set<string> | Map<string, unknown>): string;
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ /**
3
+ * Shared type mapping and string utilities used across generators.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ROW_TYPE_MAPPING = exports.TYPE_MAPPING = void 0;
7
+ exports.capitalize = capitalize;
8
+ exports.mapType = mapType;
9
+ exports.mapRowType = mapRowType;
10
+ /** Standard YAML type to TypeScript (domain) type mapping. */
11
+ exports.TYPE_MAPPING = {
12
+ string: 'string',
13
+ number: 'number',
14
+ integer: 'number',
15
+ decimal: 'number',
16
+ boolean: 'boolean',
17
+ datetime: 'Date',
18
+ date: 'Date',
19
+ id: 'number',
20
+ json: 'any',
21
+ array: 'any[]',
22
+ object: 'object',
23
+ enum: 'string'
24
+ };
25
+ /** Store-specific: YAML type to DB row TypeScript type (e.g. datetime -> string). */
26
+ exports.ROW_TYPE_MAPPING = {
27
+ string: 'string',
28
+ number: 'number',
29
+ integer: 'number',
30
+ decimal: 'number',
31
+ boolean: 'boolean',
32
+ datetime: 'string',
33
+ date: 'string',
34
+ id: 'number',
35
+ json: 'string',
36
+ array: 'string',
37
+ object: 'string',
38
+ enum: 'string'
39
+ };
40
+ function capitalize(str) {
41
+ return str.charAt(0).toUpperCase() + str.slice(1);
42
+ }
43
+ /**
44
+ * Map a YAML field type to TypeScript type, resolving aggregates and value objects by name.
45
+ */
46
+ function mapType(yamlType, aggregates, valueObjects) {
47
+ var _a;
48
+ if (aggregates === null || aggregates === void 0 ? void 0 : aggregates.has(yamlType))
49
+ return yamlType;
50
+ const capitalizedType = capitalize(yamlType);
51
+ if (valueObjects) {
52
+ const has = valueObjects instanceof Set ? valueObjects.has(capitalizedType) : valueObjects.has(capitalizedType);
53
+ if (has)
54
+ return capitalizedType;
55
+ }
56
+ return (_a = exports.TYPE_MAPPING[yamlType]) !== null && _a !== void 0 ? _a : 'any';
57
+ }
58
+ /**
59
+ * Map a YAML type to the store row TypeScript type (value objects become string).
60
+ */
61
+ function mapRowType(yamlType, valueObjects) {
62
+ var _a;
63
+ if (valueObjects) {
64
+ const capitalizedType = capitalize(yamlType);
65
+ const has = valueObjects instanceof Set ? valueObjects.has(capitalizedType) : valueObjects.has(capitalizedType);
66
+ if (has)
67
+ return 'string';
68
+ }
69
+ return (_a = exports.ROW_TYPE_MAPPING[yamlType]) !== null && _a !== void 0 ? _a : 'string';
70
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@currentjs/gen",
3
- "version": "0.3.1",
3
+ "version": "0.5.0",
4
4
  "description": "CLI code generator",
5
5
  "license": "LGPL-3.0",
6
6
  "author": "Konstantin Zavalny",
@@ -29,8 +29,12 @@
29
29
  "scripts": {
30
30
  "build": "tsc -p tsconfig.json && npm run copy-templates",
31
31
  "copy-templates": "mkdir -p dist/generators/templates/data && cp src/generators/templates/data/* dist/generators/templates/data/",
32
- "clean": "rm -rf dist",
33
- "prepack": "npm run build"
32
+ "clean": "rm -rf dist dist-test",
33
+ "prepack": "npm run build",
34
+ "test:build": "tsc -p tsconfig.test.json && mkdir -p dist-test/src/generators/templates/data && cp src/generators/templates/data/* dist-test/src/generators/templates/data/",
35
+ "test": "npm run test:build && node --test dist-test/tests/unit/*.test.js",
36
+ "test:integration": "npm run test:build && node --test dist-test/tests/integration/*.test.js",
37
+ "test:all": "npm run test:build && node --test dist-test/tests/unit/*.test.js dist-test/tests/integration/*.test.js"
34
38
  },
35
39
  "engines": {
36
40
  "node": ">=18"