@azure-net/cli 5.0.0-3 → 5.0.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.
- package/bin/azure-net.js +5 -46
- package/bin/azure-net.ts +5 -5
- package/package.json +1 -1
- package/src/checks/checkDomain.js +8 -38
- package/src/checks/checkFoldersStructure.js +0 -14
- package/src/checks/checkHooks.js +0 -5
- package/src/checks/checkImports.js +0 -1
- package/src/checks/checkInternal.js +0 -1
- package/src/checks/checkLayerBoundaries.js +50 -54
- package/src/checks/checkLayerBoundaries.ts +55 -58
- package/src/checks/checkPresenterNames.js +1 -37
- package/src/checks/checkPresenterNames.ts +1 -6
- package/src/checks/checkProject.js +0 -6
- package/src/checks/checkProviderGraph.js +1 -38
- package/src/checks/checkProviderNames.js +0 -28
- package/src/checks/index.js +0 -1
- package/src/generate/layers/generateRepository.js +4 -19
- package/src/generate/layers/generateRepositoryMethod.js +0 -12
- package/src/generate/layers/generateUseCases.js +0 -6
- package/src/generate/layers/repositoryShared.js +41 -104
- package/src/generate/layers/repositoryShared.ts +17 -12
- package/src/generate/module/generateDomain.js +0 -25
- package/src/generate/module/generateModule.js +0 -10
- package/src/generate/module/generateModulePreset.js +10 -51
- package/src/generate/module/generateModulePreset.ts +9 -8
- package/src/generate/module/generatePresenter.js +366 -371
- package/src/generate/module/generatePresenter.ts +76 -20
- package/src/generate/module/generateRepository.js +0 -17
- package/src/generate/module/generateSchemaFromType.js +9 -58
- package/src/generate/module/generateSchemaFromType.ts +1 -2
- package/src/generate/module/generateTypesJson.js +4 -45
- package/src/generate/module/generateUseCases.js +0 -9
- package/src/generate/module/repositoryModuleShared.js +21 -98
- package/src/generate/module/repositoryModuleShared.ts +14 -10
- package/src/generate/ui/generateComponent.js +0 -16
- package/src/generate/ui/generateDesignComponent.js +0 -12
- package/src/generate/ui/generateWidget.js +0 -12
- package/src/init/initAliases.js +42 -64
- package/src/init/initAliases.ts +47 -42
- package/src/init/initEdges.js +0 -15
- package/src/init/initStructure.js +48 -21
- package/src/init/initStructure.ts +51 -3
- package/src/install/installFresh.js +0 -16
- package/src/plugins/addLint.js +11 -46
- package/src/scaffolds/createCoreSchema.js +6 -40
- package/src/scaffolds/createCoreSchema.ts +6 -18
- package/src/scaffolds/createDatasource.js +26 -61
- package/src/scaffolds/createDatasource.ts +26 -40
- package/src/scaffolds/createDatasourceProvider.js +19 -56
- package/src/scaffolds/createDatasourceProvider.ts +20 -34
- package/src/scaffolds/createPresenterFactory.js +67 -94
- package/src/scaffolds/createPresenterFactory.ts +7 -19
- package/src/scaffolds/createProgram.js +1 -5
- package/src/scaffolds/createResponse.js +3 -11
- package/src/scaffolds/createResponse.ts +3 -1
- package/src/scaffolds/createSchemaRule.js +3 -8
- package/src/scaffolds/createSchemaRule.ts +3 -1
- package/src/scaffolds/createTranslationManager.js +3 -14
- package/src/scaffolds/createTranslationManager.ts +3 -1
- package/src/utils/contextUtils.js +5 -20
- package/src/utils/contextUtils.ts +2 -3
- package/src/utils/fileUtils.js +3 -38
- package/src/utils/fileUtils.ts +0 -26
- package/src/utils/loadConfig.js +1 -14
- package/src/utils/loadConfig.ts +1 -3
- package/src/utils/sharedFoundation.js +48 -0
- package/src/utils/sharedFoundation.ts +70 -0
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
|
|
4
3
|
const TARGET_EXTENSIONS = new Set(['.ts', '.js']);
|
|
5
4
|
const IGNORED_DIRS = new Set(['node_modules', 'dist', '.svelte-kit', '.git']);
|
|
6
|
-
|
|
7
5
|
const toPosixPath = (value) => value.split(path.sep).join('/');
|
|
8
|
-
|
|
9
6
|
const getLineByIndex = (content, index) => {
|
|
10
7
|
let line = 1;
|
|
11
8
|
for (let i = 0; i < index; i += 1) {
|
|
@@ -13,38 +10,31 @@ const getLineByIndex = (content, index) => {
|
|
|
13
10
|
}
|
|
14
11
|
return line;
|
|
15
12
|
};
|
|
16
|
-
|
|
17
13
|
const listSourceFiles = async (rootDir) => {
|
|
18
14
|
const files = [];
|
|
19
15
|
const stack = [rootDir];
|
|
20
|
-
|
|
21
16
|
while (stack.length) {
|
|
22
17
|
const current = stack.pop();
|
|
23
18
|
if (!current) continue;
|
|
24
|
-
|
|
25
19
|
let entries = [];
|
|
26
20
|
try {
|
|
27
21
|
entries = await fs.readdir(current, { withFileTypes: true });
|
|
28
22
|
} catch {
|
|
29
23
|
continue;
|
|
30
24
|
}
|
|
31
|
-
|
|
32
25
|
for (const entry of entries) {
|
|
33
26
|
if (entry.isDirectory()) {
|
|
34
27
|
if (!IGNORED_DIRS.has(entry.name)) stack.push(path.join(current, entry.name));
|
|
35
28
|
continue;
|
|
36
29
|
}
|
|
37
|
-
|
|
38
30
|
if (!entry.isFile()) continue;
|
|
39
31
|
const filePath = path.join(current, entry.name);
|
|
40
32
|
if (!TARGET_EXTENSIONS.has(path.extname(filePath))) continue;
|
|
41
33
|
files.push(filePath);
|
|
42
34
|
}
|
|
43
35
|
}
|
|
44
|
-
|
|
45
36
|
return files;
|
|
46
37
|
};
|
|
47
|
-
|
|
48
38
|
const findMatchingBracket = (content, startIndex, openChar, closeChar) => {
|
|
49
39
|
let depth = 0;
|
|
50
40
|
for (let i = startIndex; i < content.length; i += 1) {
|
|
@@ -57,11 +47,9 @@ const findMatchingBracket = (content, startIndex, openChar, closeChar) => {
|
|
|
57
47
|
}
|
|
58
48
|
return -1;
|
|
59
49
|
};
|
|
60
|
-
|
|
61
50
|
const extractDependsOn = (configBlock) => {
|
|
62
51
|
const dependsOnMatch = configBlock.match(/dependsOn\s*:\s*\{([\s\S]*?)\}/m);
|
|
63
52
|
if (!dependsOnMatch?.[1]) return [];
|
|
64
|
-
|
|
65
53
|
const block = dependsOnMatch[1];
|
|
66
54
|
const deps = new Set();
|
|
67
55
|
const keyRegex = /([A-Za-z_$][A-Za-z0-9_$]*)\s*:/g;
|
|
@@ -72,20 +60,16 @@ const extractDependsOn = (configBlock) => {
|
|
|
72
60
|
}
|
|
73
61
|
return [...deps];
|
|
74
62
|
};
|
|
75
|
-
|
|
76
63
|
const parseProviderGraphFromFile = (content, filePath) => {
|
|
77
64
|
const nodes = [];
|
|
78
65
|
const token = 'createBoundaryProvider(';
|
|
79
66
|
let fromIndex = 0;
|
|
80
|
-
|
|
81
67
|
while (fromIndex < content.length) {
|
|
82
68
|
const start = content.indexOf(token, fromIndex);
|
|
83
69
|
if (start === -1) break;
|
|
84
|
-
|
|
85
70
|
const openParenIndex = start + token.length - 1;
|
|
86
71
|
const closeParenIndex = findMatchingBracket(content, openParenIndex, '(', ')');
|
|
87
72
|
if (closeParenIndex === -1) break;
|
|
88
|
-
|
|
89
73
|
const fullCall = content.slice(openParenIndex + 1, closeParenIndex);
|
|
90
74
|
const idMatch = fullCall.match(/^\s*(['"`])([^'"`]+)\1\s*,/m);
|
|
91
75
|
const providerName = idMatch?.[2];
|
|
@@ -96,7 +80,6 @@ const parseProviderGraphFromFile = (content, filePath) => {
|
|
|
96
80
|
const absoluteObjectEnd = findMatchingBracket(content, absoluteObjectStart, '{', '}');
|
|
97
81
|
const configBlock =
|
|
98
82
|
absoluteObjectEnd !== -1 ? content.slice(absoluteObjectStart, absoluteObjectEnd + 1) : fullCall.slice(objectStartInCall);
|
|
99
|
-
|
|
100
83
|
nodes.push({
|
|
101
84
|
name: providerName,
|
|
102
85
|
file: filePath,
|
|
@@ -112,24 +95,19 @@ const parseProviderGraphFromFile = (content, filePath) => {
|
|
|
112
95
|
});
|
|
113
96
|
}
|
|
114
97
|
}
|
|
115
|
-
|
|
116
98
|
fromIndex = closeParenIndex + 1;
|
|
117
99
|
}
|
|
118
|
-
|
|
119
100
|
return nodes;
|
|
120
101
|
};
|
|
121
|
-
|
|
122
102
|
const findCycles = (graph) => {
|
|
123
103
|
const cycles = [];
|
|
124
104
|
const visited = new Set();
|
|
125
105
|
const inStack = new Set();
|
|
126
106
|
const stack = [];
|
|
127
|
-
|
|
128
107
|
const dfs = (node) => {
|
|
129
108
|
visited.add(node);
|
|
130
109
|
inStack.add(node);
|
|
131
110
|
stack.push(node);
|
|
132
|
-
|
|
133
111
|
const neighbors = graph.get(node) ?? [];
|
|
134
112
|
for (const next of neighbors) {
|
|
135
113
|
if (!graph.has(next)) continue;
|
|
@@ -142,18 +120,14 @@ const findCycles = (graph) => {
|
|
|
142
120
|
if (idx !== -1) cycles.push([...stack.slice(idx), next]);
|
|
143
121
|
}
|
|
144
122
|
}
|
|
145
|
-
|
|
146
123
|
stack.pop();
|
|
147
124
|
inStack.delete(node);
|
|
148
125
|
};
|
|
149
|
-
|
|
150
126
|
for (const node of graph.keys()) {
|
|
151
127
|
if (!visited.has(node)) dfs(node);
|
|
152
128
|
}
|
|
153
|
-
|
|
154
129
|
return cycles;
|
|
155
130
|
};
|
|
156
|
-
|
|
157
131
|
export default async function checkProviderGraph() {
|
|
158
132
|
const srcPath = path.join(process.cwd(), 'src');
|
|
159
133
|
try {
|
|
@@ -163,40 +137,32 @@ export default async function checkProviderGraph() {
|
|
|
163
137
|
process.exitCode = 1;
|
|
164
138
|
return;
|
|
165
139
|
}
|
|
166
|
-
|
|
167
140
|
const files = await listSourceFiles(srcPath);
|
|
168
141
|
const providers = [];
|
|
169
|
-
|
|
170
142
|
for (const filePath of files) {
|
|
171
143
|
const content = await fs.readFile(filePath, 'utf-8');
|
|
172
144
|
providers.push(...parseProviderGraphFromFile(content, filePath));
|
|
173
145
|
}
|
|
174
|
-
|
|
175
146
|
if (!providers.length) {
|
|
176
147
|
console.log('✅ No createBoundaryProvider declarations found.');
|
|
177
148
|
return;
|
|
178
149
|
}
|
|
179
|
-
|
|
180
150
|
const graph = new Map();
|
|
181
151
|
const issues = [];
|
|
182
152
|
const byName = new Map();
|
|
183
|
-
|
|
184
153
|
for (const provider of providers) {
|
|
185
154
|
if (byName.has(provider.name)) {
|
|
186
155
|
const existing = byName.get(provider.name);
|
|
187
156
|
issues.push({
|
|
188
157
|
file: provider.file,
|
|
189
158
|
line: provider.line,
|
|
190
|
-
message: `Provider graph ambiguity: duplicate provider id "${provider.name}" (first declared at ${toPosixPath(
|
|
191
|
-
path.relative(process.cwd(), existing.file)
|
|
192
|
-
)}:${existing.line})`
|
|
159
|
+
message: `Provider graph ambiguity: duplicate provider id "${provider.name}" (first declared at ${toPosixPath(path.relative(process.cwd(), existing.file))}:${existing.line})`
|
|
193
160
|
});
|
|
194
161
|
continue;
|
|
195
162
|
}
|
|
196
163
|
byName.set(provider.name, provider);
|
|
197
164
|
graph.set(provider.name, provider.dependsOn);
|
|
198
165
|
}
|
|
199
|
-
|
|
200
166
|
const cycles = findCycles(graph);
|
|
201
167
|
for (const cycle of cycles) {
|
|
202
168
|
const firstNode = byName.get(cycle[0] ?? '');
|
|
@@ -206,16 +172,13 @@ export default async function checkProviderGraph() {
|
|
|
206
172
|
message: `Circular provider dependency detected: ${cycle.join(' -> ')}`
|
|
207
173
|
});
|
|
208
174
|
}
|
|
209
|
-
|
|
210
175
|
if (!issues.length) {
|
|
211
176
|
console.log(`✅ Provider graph check passed (${providers.length} providers).`);
|
|
212
177
|
return;
|
|
213
178
|
}
|
|
214
|
-
|
|
215
179
|
console.error('❌ Provider graph check failed:');
|
|
216
180
|
for (const issue of issues) {
|
|
217
181
|
console.error(`• ${toPosixPath(path.relative(process.cwd(), issue.file))}:${issue.line} — ${issue.message}`);
|
|
218
182
|
}
|
|
219
|
-
|
|
220
183
|
process.exitCode = 1;
|
|
221
184
|
}
|
|
@@ -1,47 +1,38 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
|
|
4
3
|
const TARGET_EXTENSIONS = new Set(['.ts', '.js', '.svelte']);
|
|
5
4
|
const IGNORED_DIRS = new Set(['node_modules', 'dist', '.svelte-kit', '.git']);
|
|
6
5
|
const IMPORT_PATTERN = 'import\\s*\\{([^}]+)\\}\\s*from\\s*[\'"]([^\'"]+)[\'"]';
|
|
7
6
|
const CALL_PATTERN = '\\b([A-Za-z_$][A-Za-z0-9_$]*)\\s*\\(\\s*([\'"`])([^\'"`]*)\\2';
|
|
8
|
-
|
|
9
7
|
const toPosixPath = (value) => value.split(path.sep).join('/');
|
|
10
|
-
|
|
11
8
|
const parseImportAliases = (rawImports, importName) => {
|
|
12
9
|
const aliases = [];
|
|
13
10
|
for (const segment of rawImports.split(',')) {
|
|
14
11
|
const item = segment.trim();
|
|
15
12
|
if (!item.length) continue;
|
|
16
|
-
|
|
17
13
|
const aliasMatch = item.match(/^([A-Za-z_$][A-Za-z0-9_$]*)\s+as\s+([A-Za-z_$][A-Za-z0-9_$]*)$/);
|
|
18
14
|
if (aliasMatch?.[1] === importName && aliasMatch[2]) {
|
|
19
15
|
aliases.push(aliasMatch[2]);
|
|
20
16
|
continue;
|
|
21
17
|
}
|
|
22
|
-
|
|
23
18
|
if (item === importName) {
|
|
24
19
|
aliases.push(importName);
|
|
25
20
|
}
|
|
26
21
|
}
|
|
27
22
|
return aliases;
|
|
28
23
|
};
|
|
29
|
-
|
|
30
24
|
const listSourceFiles = async (rootDir) => {
|
|
31
25
|
const files = [];
|
|
32
26
|
const stack = [rootDir];
|
|
33
|
-
|
|
34
27
|
while (stack.length) {
|
|
35
28
|
const current = stack.pop();
|
|
36
29
|
if (!current) continue;
|
|
37
|
-
|
|
38
30
|
let entries = [];
|
|
39
31
|
try {
|
|
40
32
|
entries = await fs.readdir(current, { withFileTypes: true });
|
|
41
33
|
} catch {
|
|
42
34
|
continue;
|
|
43
35
|
}
|
|
44
|
-
|
|
45
36
|
for (const entry of entries) {
|
|
46
37
|
if (entry.isDirectory()) {
|
|
47
38
|
if (!IGNORED_DIRS.has(entry.name)) {
|
|
@@ -49,17 +40,14 @@ const listSourceFiles = async (rootDir) => {
|
|
|
49
40
|
}
|
|
50
41
|
continue;
|
|
51
42
|
}
|
|
52
|
-
|
|
53
43
|
if (!entry.isFile()) continue;
|
|
54
44
|
const filepath = path.join(current, entry.name);
|
|
55
45
|
if (!TARGET_EXTENSIONS.has(path.extname(filepath))) continue;
|
|
56
46
|
files.push(filepath);
|
|
57
47
|
}
|
|
58
48
|
}
|
|
59
|
-
|
|
60
49
|
return files;
|
|
61
50
|
};
|
|
62
|
-
|
|
63
51
|
const getLineByIndex = (content, index) => {
|
|
64
52
|
let line = 1;
|
|
65
53
|
for (let i = 0; i < index; i += 1) {
|
|
@@ -67,12 +55,10 @@ const getLineByIndex = (content, index) => {
|
|
|
67
55
|
}
|
|
68
56
|
return line;
|
|
69
57
|
};
|
|
70
|
-
|
|
71
58
|
const extractBoundaryFactoryAliases = (content) => {
|
|
72
59
|
const importRegex = new RegExp(IMPORT_PATTERN, 'g');
|
|
73
60
|
const aliases = new Set(['createBoundaryProvider']);
|
|
74
61
|
let match;
|
|
75
|
-
|
|
76
62
|
while ((match = importRegex.exec(content)) !== null) {
|
|
77
63
|
const rawImports = match[1];
|
|
78
64
|
if (!rawImports) continue;
|
|
@@ -80,25 +66,20 @@ const extractBoundaryFactoryAliases = (content) => {
|
|
|
80
66
|
aliases.add(alias);
|
|
81
67
|
}
|
|
82
68
|
}
|
|
83
|
-
|
|
84
69
|
return aliases;
|
|
85
70
|
};
|
|
86
|
-
|
|
87
71
|
const collectProviderOccurrences = (content, filepath) => {
|
|
88
72
|
const aliases = extractBoundaryFactoryAliases(content);
|
|
89
73
|
const callRegex = new RegExp(CALL_PATTERN, 'g');
|
|
90
74
|
const occurrences = [];
|
|
91
75
|
let match;
|
|
92
|
-
|
|
93
76
|
while ((match = callRegex.exec(content)) !== null) {
|
|
94
77
|
const callee = match[1];
|
|
95
78
|
const quote = match[2];
|
|
96
79
|
const providerId = match[3];
|
|
97
|
-
|
|
98
80
|
if (!callee || !providerId) continue;
|
|
99
81
|
if (!aliases.has(callee)) continue;
|
|
100
82
|
if (quote === '`' && providerId.includes('${')) continue;
|
|
101
|
-
|
|
102
83
|
occurrences.push({
|
|
103
84
|
id: providerId,
|
|
104
85
|
file: filepath,
|
|
@@ -106,10 +87,8 @@ const collectProviderOccurrences = (content, filepath) => {
|
|
|
106
87
|
callee
|
|
107
88
|
});
|
|
108
89
|
}
|
|
109
|
-
|
|
110
90
|
return occurrences;
|
|
111
91
|
};
|
|
112
|
-
|
|
113
92
|
export default async function checkProviderNames() {
|
|
114
93
|
const srcPath = path.join(process.cwd(), 'src');
|
|
115
94
|
try {
|
|
@@ -119,33 +98,27 @@ export default async function checkProviderNames() {
|
|
|
119
98
|
process.exitCode = 1;
|
|
120
99
|
return;
|
|
121
100
|
}
|
|
122
|
-
|
|
123
101
|
const files = await listSourceFiles(srcPath);
|
|
124
102
|
const occurrences = [];
|
|
125
|
-
|
|
126
103
|
for (const filepath of files) {
|
|
127
104
|
const content = await fs.readFile(filepath, 'utf-8');
|
|
128
105
|
occurrences.push(...collectProviderOccurrences(content, filepath));
|
|
129
106
|
}
|
|
130
|
-
|
|
131
107
|
if (!occurrences.length) {
|
|
132
108
|
console.log('✅ No providers declarations found.');
|
|
133
109
|
return;
|
|
134
110
|
}
|
|
135
|
-
|
|
136
111
|
const grouped = new Map();
|
|
137
112
|
for (const occurrence of occurrences) {
|
|
138
113
|
const list = grouped.get(occurrence.id) ?? [];
|
|
139
114
|
list.push(occurrence);
|
|
140
115
|
grouped.set(occurrence.id, list);
|
|
141
116
|
}
|
|
142
|
-
|
|
143
117
|
const duplicated = Array.from(grouped.entries()).filter(([, list]) => list.length > 1);
|
|
144
118
|
if (!duplicated.length) {
|
|
145
119
|
console.log(`✅ Provider names are unique (${occurrences.length} found).`);
|
|
146
120
|
return;
|
|
147
121
|
}
|
|
148
|
-
|
|
149
122
|
console.error('❌ Duplicate provider names found:');
|
|
150
123
|
for (const [providerId, list] of duplicated) {
|
|
151
124
|
console.error(`\n- "${providerId}"`);
|
|
@@ -153,6 +126,5 @@ export default async function checkProviderNames() {
|
|
|
153
126
|
console.error(` • ${toPosixPath(path.relative(process.cwd(), item.file))}:${item.line} (${item.callee})`);
|
|
154
127
|
}
|
|
155
128
|
}
|
|
156
|
-
|
|
157
129
|
process.exitCode = 1;
|
|
158
130
|
}
|
package/src/checks/index.js
CHANGED
|
@@ -9,4 +9,3 @@ export { default as checkLayerBoundaries } from './checkLayerBoundaries.js';
|
|
|
9
9
|
export { default as checkFoldersStructure } from './checkFoldersStructure.js';
|
|
10
10
|
export { default as checkInternal } from './checkInternal.js';
|
|
11
11
|
export { default as checkProject } from './checkProject.js';
|
|
12
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
promptMethodDefinition
|
|
17
17
|
} from './repositoryShared.js';
|
|
18
18
|
import { updateIndexTs, writeIfNotExists } from '../../utils/fileUtils.js';
|
|
19
|
-
|
|
20
19
|
export default async function generateRepository() {
|
|
21
20
|
const { rawName } = await prompts({
|
|
22
21
|
type: 'text',
|
|
@@ -24,7 +23,6 @@ export default async function generateRepository() {
|
|
|
24
23
|
message: 'Repository name:',
|
|
25
24
|
validate: (value) => (String(value ?? '').trim().length > 0 ? true : 'Repository name is required')
|
|
26
25
|
});
|
|
27
|
-
|
|
28
26
|
const className = ensureRepositoryName(rawName);
|
|
29
27
|
const meta = getRepositoryMeta(className);
|
|
30
28
|
const contextName = await selectContext('Select context for repository:');
|
|
@@ -32,13 +30,11 @@ export default async function generateRepository() {
|
|
|
32
30
|
process.exitCode = 1;
|
|
33
31
|
return;
|
|
34
32
|
}
|
|
35
|
-
|
|
36
33
|
const datasource = await selectDatasource(contextName);
|
|
37
34
|
if (!datasource) {
|
|
38
35
|
process.exitCode = 1;
|
|
39
36
|
return;
|
|
40
37
|
}
|
|
41
|
-
|
|
42
38
|
const { methodsCountRaw } = await prompts({
|
|
43
39
|
type: 'number',
|
|
44
40
|
name: 'methodsCountRaw',
|
|
@@ -46,30 +42,25 @@ export default async function generateRepository() {
|
|
|
46
42
|
initial: 1,
|
|
47
43
|
min: 0
|
|
48
44
|
});
|
|
49
|
-
|
|
50
45
|
const methodsCount = Number(methodsCountRaw ?? 0);
|
|
51
46
|
if (!Number.isFinite(methodsCount) || methodsCount < 0) {
|
|
52
47
|
console.error('❌ Invalid methods count.');
|
|
53
48
|
process.exitCode = 1;
|
|
54
49
|
return;
|
|
55
50
|
}
|
|
56
|
-
|
|
57
51
|
const methods = [];
|
|
58
52
|
for (let index = 0; index < methodsCount; index += 1) {
|
|
59
53
|
console.log(`\n🧩 Method ${index + 1} of ${methodsCount}`);
|
|
60
|
-
// eslint-disable-next-line no-await-in-loop
|
|
61
54
|
const method = await promptMethodDefinition();
|
|
62
55
|
methods.push(method);
|
|
63
56
|
}
|
|
64
|
-
|
|
65
57
|
const { contexts } = await getConfigState();
|
|
66
58
|
const contextAlias = resolveContextAlias(contexts, contextName);
|
|
67
59
|
const repositoriesPath = resolveRepositoriesPath(contextName);
|
|
68
60
|
await fs.mkdir(repositoriesPath, { recursive: true });
|
|
69
61
|
const repositoryPath = path.join(repositoriesPath, `${meta.className}.ts`);
|
|
70
|
-
|
|
71
62
|
for (const method of methods) {
|
|
72
|
-
|
|
63
|
+
if (!method) continue;
|
|
73
64
|
const ensuredResponseType = await ensureDomainType({
|
|
74
65
|
contextName,
|
|
75
66
|
domainName: meta.domainName,
|
|
@@ -78,9 +69,7 @@ export default async function generateRepository() {
|
|
|
78
69
|
});
|
|
79
70
|
method.responseType = ensuredResponseType.interfaceName;
|
|
80
71
|
method.responseLayer = ensuredResponseType.layer;
|
|
81
|
-
|
|
82
72
|
if (method.requestType) {
|
|
83
|
-
// eslint-disable-next-line no-await-in-loop
|
|
84
73
|
const ensuredRequestType = await ensureDomainType({
|
|
85
74
|
contextName,
|
|
86
75
|
domainName: meta.domainName,
|
|
@@ -91,16 +80,15 @@ export default async function generateRepository() {
|
|
|
91
80
|
method.requestLayer = ensuredRequestType.layer;
|
|
92
81
|
}
|
|
93
82
|
}
|
|
94
|
-
|
|
95
|
-
await ensureRepositoryInterfaceFile({ contextName, meta, methods });
|
|
83
|
+
const filteredMethods = methods.filter(Boolean);
|
|
84
|
+
await ensureRepositoryInterfaceFile({ contextName, meta, methods: filteredMethods });
|
|
96
85
|
const repositoryContent = buildRepositoryContent({
|
|
97
86
|
meta,
|
|
98
87
|
contextAlias,
|
|
99
88
|
datasourceImportPath: datasource.importPath,
|
|
100
89
|
datasourceName: datasource.name,
|
|
101
|
-
methods
|
|
90
|
+
methods: filteredMethods
|
|
102
91
|
});
|
|
103
|
-
|
|
104
92
|
const created = await writeIfNotExists(repositoryPath, repositoryContent);
|
|
105
93
|
await updateIndexTs(repositoriesPath);
|
|
106
94
|
if (!created) {
|
|
@@ -108,17 +96,14 @@ export default async function generateRepository() {
|
|
|
108
96
|
process.exitCode = 1;
|
|
109
97
|
return;
|
|
110
98
|
}
|
|
111
|
-
|
|
112
99
|
const { shouldCreateUseCases } = await prompts({
|
|
113
100
|
type: 'confirm',
|
|
114
101
|
name: 'shouldCreateUseCases',
|
|
115
102
|
message: 'Create UseCases for this repository?',
|
|
116
103
|
initial: true
|
|
117
104
|
});
|
|
118
|
-
|
|
119
105
|
if (shouldCreateUseCases) {
|
|
120
106
|
await ensureUseCasesFile({ contextName, contextAlias, meta });
|
|
121
107
|
}
|
|
122
|
-
|
|
123
108
|
console.log(`✅ Repository generated: ${repositoryPath}`);
|
|
124
109
|
}
|
|
@@ -14,14 +14,12 @@ import {
|
|
|
14
14
|
selectContext,
|
|
15
15
|
promptMethodDefinition
|
|
16
16
|
} from './repositoryShared.js';
|
|
17
|
-
|
|
18
17
|
export default async function generateRepositoryMethod() {
|
|
19
18
|
const contextName = await selectContext('Select context for repository method:');
|
|
20
19
|
if (!contextName) {
|
|
21
20
|
process.exitCode = 1;
|
|
22
21
|
return;
|
|
23
22
|
}
|
|
24
|
-
|
|
25
23
|
const repositoriesPath = resolveRepositoriesPath(contextName);
|
|
26
24
|
const repositories = await getAvailableTsNames(repositoriesPath);
|
|
27
25
|
if (!repositories.length) {
|
|
@@ -29,7 +27,6 @@ export default async function generateRepositoryMethod() {
|
|
|
29
27
|
process.exitCode = 1;
|
|
30
28
|
return;
|
|
31
29
|
}
|
|
32
|
-
|
|
33
30
|
const { repositoryName } = await prompts({
|
|
34
31
|
type: 'select',
|
|
35
32
|
name: 'repositoryName',
|
|
@@ -37,16 +34,13 @@ export default async function generateRepositoryMethod() {
|
|
|
37
34
|
choices: repositories.map((name) => ({ title: name, value: name })),
|
|
38
35
|
initial: 0
|
|
39
36
|
});
|
|
40
|
-
|
|
41
37
|
if (!repositoryName) {
|
|
42
38
|
process.exitCode = 1;
|
|
43
39
|
return;
|
|
44
40
|
}
|
|
45
|
-
|
|
46
41
|
const meta = getRepositoryMeta(String(repositoryName));
|
|
47
42
|
const repositoryPath = path.join(repositoriesPath, `${meta.className}.ts`);
|
|
48
43
|
const method = await promptMethodDefinition();
|
|
49
|
-
|
|
50
44
|
const ensuredResponseType = await ensureDomainType({
|
|
51
45
|
contextName,
|
|
52
46
|
domainName: meta.domainName,
|
|
@@ -55,7 +49,6 @@ export default async function generateRepositoryMethod() {
|
|
|
55
49
|
});
|
|
56
50
|
method.responseType = ensuredResponseType.interfaceName;
|
|
57
51
|
method.responseLayer = ensuredResponseType.layer;
|
|
58
|
-
|
|
59
52
|
if (method.requestType) {
|
|
60
53
|
const ensuredRequestType = await ensureDomainType({
|
|
61
54
|
contextName,
|
|
@@ -66,7 +59,6 @@ export default async function generateRepositoryMethod() {
|
|
|
66
59
|
method.requestType = ensuredRequestType.interfaceName;
|
|
67
60
|
method.requestLayer = ensuredRequestType.layer;
|
|
68
61
|
}
|
|
69
|
-
|
|
70
62
|
let repositoryContent = '';
|
|
71
63
|
try {
|
|
72
64
|
repositoryContent = await fs.readFile(repositoryPath, 'utf-8');
|
|
@@ -75,14 +67,12 @@ export default async function generateRepositoryMethod() {
|
|
|
75
67
|
process.exitCode = 1;
|
|
76
68
|
return;
|
|
77
69
|
}
|
|
78
|
-
|
|
79
70
|
const existingMethods = parseRepositoryMethods(repositoryContent);
|
|
80
71
|
if (existingMethods.some((item) => item.name === method.name)) {
|
|
81
72
|
console.warn(`⚠️ Method "${method.name}" already exists in ${meta.className}.`);
|
|
82
73
|
process.exitCode = 1;
|
|
83
74
|
return;
|
|
84
75
|
}
|
|
85
|
-
|
|
86
76
|
const { contexts } = await getConfigState();
|
|
87
77
|
const contextAlias = resolveContextAlias(contexts, contextName);
|
|
88
78
|
await appendRepositoryMethod({
|
|
@@ -91,12 +81,10 @@ export default async function generateRepositoryMethod() {
|
|
|
91
81
|
contextAlias,
|
|
92
82
|
domainName: meta.domainName
|
|
93
83
|
});
|
|
94
|
-
|
|
95
84
|
await ensureRepositoryInterfaceFile({
|
|
96
85
|
contextName,
|
|
97
86
|
meta,
|
|
98
87
|
methods: [...existingMethods, method]
|
|
99
88
|
});
|
|
100
|
-
|
|
101
89
|
console.log(`✅ Method "${method.name}" added to ${meta.className}`);
|
|
102
90
|
}
|
|
@@ -8,14 +8,12 @@ import {
|
|
|
8
8
|
resolveRepositoriesPath,
|
|
9
9
|
selectContext
|
|
10
10
|
} from './repositoryShared.js';
|
|
11
|
-
|
|
12
11
|
export default async function generateUseCases() {
|
|
13
12
|
const contextName = await selectContext('Select context for UseCases:');
|
|
14
13
|
if (!contextName) {
|
|
15
14
|
process.exitCode = 1;
|
|
16
15
|
return;
|
|
17
16
|
}
|
|
18
|
-
|
|
19
17
|
const repositoriesPath = resolveRepositoriesPath(contextName);
|
|
20
18
|
const repositories = await getAvailableTsNames(repositoriesPath);
|
|
21
19
|
if (!repositories.length) {
|
|
@@ -23,7 +21,6 @@ export default async function generateUseCases() {
|
|
|
23
21
|
process.exitCode = 1;
|
|
24
22
|
return;
|
|
25
23
|
}
|
|
26
|
-
|
|
27
24
|
const { repositoryName } = await prompts({
|
|
28
25
|
type: 'select',
|
|
29
26
|
name: 'repositoryName',
|
|
@@ -31,12 +28,10 @@ export default async function generateUseCases() {
|
|
|
31
28
|
choices: repositories.map((name) => ({ title: name, value: name })),
|
|
32
29
|
initial: 0
|
|
33
30
|
});
|
|
34
|
-
|
|
35
31
|
if (!repositoryName) {
|
|
36
32
|
process.exitCode = 1;
|
|
37
33
|
return;
|
|
38
34
|
}
|
|
39
|
-
|
|
40
35
|
const { contexts } = await getConfigState();
|
|
41
36
|
const contextAlias = resolveContextAlias(contexts, contextName);
|
|
42
37
|
const meta = getRepositoryMeta(String(repositoryName));
|
|
@@ -45,6 +40,5 @@ export default async function generateUseCases() {
|
|
|
45
40
|
process.exitCode = 1;
|
|
46
41
|
return;
|
|
47
42
|
}
|
|
48
|
-
|
|
49
43
|
console.log(`✅ UseCases generated: ${meta.useCasesClassName}`);
|
|
50
44
|
}
|