@kosdev-code/kos-ui-cli 2.0.30 → 2.0.32
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/package.json +2 -2
- package/src/lib/cli.mjs +534 -8
- package/src/lib/generators/component/index.mjs +6 -0
- package/src/lib/generators/i18n/namespace.mjs +5 -0
- package/src/lib/generators/model/add-future.mjs +80 -0
- package/src/lib/generators/model/companion.mjs +21 -1
- package/src/lib/generators/model/container.mjs +10 -0
- package/src/lib/generators/model/context.mjs +5 -0
- package/src/lib/generators/model/hook.mjs +5 -0
- package/src/lib/generators/model/model.mjs +14 -2
- package/src/lib/generators/plugin/index.mjs +72 -7
- package/src/lib/generators/project/app.mjs +1 -0
- package/src/lib/generators/project/i18n.mjs +1 -0
- package/src/lib/generators/project/plugin.mjs +1 -0
- package/src/lib/generators/project/splash.mjs +1 -0
- package/src/lib/generators/project/theme.mjs +1 -0
- package/src/lib/generators/workspace/index.mjs +4 -0
- package/src/lib/plopfile.mjs +2 -0
- package/src/lib/utils/prompts.mjs +30 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kosdev-code/kos-ui-cli",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.32",
|
|
4
4
|
"bin": {
|
|
5
5
|
"kosui": "./src/lib/cli.mjs"
|
|
6
6
|
},
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"main": "./src/index.js",
|
|
21
21
|
"kos": {
|
|
22
22
|
"build": {
|
|
23
|
-
"gitHash": "
|
|
23
|
+
"gitHash": "ea8751ddd6a1c43f56f22bab3bf99a0e3bd3f824"
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"publishConfig": {
|
package/src/lib/cli.mjs
CHANGED
|
@@ -28,34 +28,560 @@ const showBanner =
|
|
|
28
28
|
command !== "help" && process.env.DISABLE_CLI_BANNER !== "true";
|
|
29
29
|
|
|
30
30
|
async function launch() {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
clearCache();
|
|
35
|
-
return "[ok] CLI cache cleared successfully.";
|
|
36
|
-
});
|
|
37
|
-
|
|
31
|
+
// Check for help modes before initializing plop to avoid expensive model parsing
|
|
32
|
+
const shouldShowHelp = parsedArgs.help;
|
|
33
|
+
|
|
38
34
|
if (!command || command === "help") {
|
|
35
|
+
// For general help, we still need plop to list generators
|
|
36
|
+
const plop = await nodePlop(configPath);
|
|
37
|
+
|
|
39
38
|
console.warn("--- KOS CLI Help ---");
|
|
39
|
+
console.log("\nAvailable Generators:");
|
|
40
40
|
plop.getGeneratorList().forEach((g) => {
|
|
41
41
|
console.log(`- ${g.name}: ${g.description}`);
|
|
42
42
|
});
|
|
43
|
+
|
|
44
|
+
console.log("\nUsage:");
|
|
45
|
+
console.log(" kosui <generator> [options]");
|
|
46
|
+
console.log(" kosui <generator> --help # Show generator-specific help");
|
|
47
|
+
console.log("\nGlobal Options:");
|
|
48
|
+
console.log(" --no-cache Disable cache");
|
|
49
|
+
console.log(" --refresh Clear cache and refresh");
|
|
50
|
+
console.log(
|
|
51
|
+
" --interactive, -i Force interactive mode (ignore provided arguments)"
|
|
52
|
+
);
|
|
53
|
+
console.log(" --help Show this help");
|
|
54
|
+
|
|
43
55
|
return;
|
|
44
56
|
}
|
|
45
57
|
|
|
58
|
+
// For generator-specific help, check if we can show help without full plop initialization
|
|
59
|
+
if (shouldShowHelp) {
|
|
60
|
+
const earlyMeta = await getGeneratorMetadata(command);
|
|
61
|
+
|
|
62
|
+
if (earlyMeta && Object.keys(earlyMeta).length > 0) {
|
|
63
|
+
// Show help immediately for --help flag
|
|
64
|
+
console.log(`--- ${earlyMeta?.name || command} Help ---`);
|
|
65
|
+
console.log(earlyMeta.description || "No description available");
|
|
66
|
+
|
|
67
|
+
if (earlyMeta?.namedArguments) {
|
|
68
|
+
console.log("\nNamed Arguments:");
|
|
69
|
+
Object.entries(earlyMeta.namedArguments).forEach(([cliArg, promptName]) => {
|
|
70
|
+
console.log(` --${cliArg} Maps to prompt: ${promptName}`);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
console.log("\nExamples:");
|
|
75
|
+
|
|
76
|
+
// Generate examples dynamically from the generator's named arguments
|
|
77
|
+
if (earlyMeta?.namedArguments) {
|
|
78
|
+
const args = Object.keys(earlyMeta.namedArguments);
|
|
79
|
+
|
|
80
|
+
// Generate example values based on argument names
|
|
81
|
+
const generateExampleValue = (argName) => {
|
|
82
|
+
switch (argName) {
|
|
83
|
+
case 'name':
|
|
84
|
+
case 'componentName':
|
|
85
|
+
return command.includes('plugin') ? 'MyPlugin' : 'MyComponent';
|
|
86
|
+
case 'modelName':
|
|
87
|
+
return 'my-model';
|
|
88
|
+
case 'workspaceName':
|
|
89
|
+
return 'my-workspace';
|
|
90
|
+
case 'project':
|
|
91
|
+
case 'componentProject':
|
|
92
|
+
case 'modelProject':
|
|
93
|
+
return 'my-ui-lib';
|
|
94
|
+
case 'registrationProject':
|
|
95
|
+
return 'my-lib';
|
|
96
|
+
case 'companionParent':
|
|
97
|
+
return 'parent-model';
|
|
98
|
+
case 'extensionPoint':
|
|
99
|
+
return 'utility';
|
|
100
|
+
case 'group':
|
|
101
|
+
return 'appearance';
|
|
102
|
+
case 'locale':
|
|
103
|
+
return 'en';
|
|
104
|
+
case 'container':
|
|
105
|
+
case 'singleton':
|
|
106
|
+
case 'parentAware':
|
|
107
|
+
case 'dataServices':
|
|
108
|
+
return true;
|
|
109
|
+
case 'dryRun':
|
|
110
|
+
return true;
|
|
111
|
+
default:
|
|
112
|
+
return `my-${argName}`;
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
// Create basic example with most important arguments
|
|
117
|
+
const basicArgs = [];
|
|
118
|
+
const booleanArgs = ['container', 'singleton', 'parentAware', 'dataServices', 'dryRun'];
|
|
119
|
+
|
|
120
|
+
// Pick the most relevant arguments for each generator type
|
|
121
|
+
const getRelevantArgs = (args, command) => {
|
|
122
|
+
const relevantArgs = [];
|
|
123
|
+
|
|
124
|
+
// Always prefer name-type arguments first
|
|
125
|
+
const nameArgs = ['name', 'componentName', 'modelName', 'workspaceName'].filter(arg => args.includes(arg));
|
|
126
|
+
if (nameArgs.length > 0) {
|
|
127
|
+
relevantArgs.push(nameArgs[0]); // Take the first name argument
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Then add project-type arguments
|
|
131
|
+
const projectArgs = ['project', 'componentProject', 'modelProject', 'registrationProject'].filter(arg => args.includes(arg));
|
|
132
|
+
if (projectArgs.length > 0) {
|
|
133
|
+
relevantArgs.push(projectArgs[0]); // Take the first project argument
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Add other specific arguments
|
|
137
|
+
const otherArgs = args.filter(arg =>
|
|
138
|
+
!nameArgs.includes(arg) &&
|
|
139
|
+
!projectArgs.includes(arg) &&
|
|
140
|
+
!booleanArgs.includes(arg) &&
|
|
141
|
+
arg !== 'interactive'
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
// Add up to 2 more relevant arguments
|
|
145
|
+
relevantArgs.push(...otherArgs.slice(0, 2));
|
|
146
|
+
|
|
147
|
+
return relevantArgs;
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const relevantArgs = getRelevantArgs(args, command);
|
|
151
|
+
|
|
152
|
+
relevantArgs.forEach(argName => {
|
|
153
|
+
const value = generateExampleValue(argName);
|
|
154
|
+
basicArgs.push(`--${argName} ${value}`);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// Create advanced example with boolean flags
|
|
158
|
+
const advancedBooleanArgs = [];
|
|
159
|
+
booleanArgs.forEach(argName => {
|
|
160
|
+
if (args.includes(argName)) {
|
|
161
|
+
advancedBooleanArgs.push(`--${argName}`);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Show basic example
|
|
166
|
+
if (basicArgs.length > 0) {
|
|
167
|
+
console.log(` kosui ${command} ${basicArgs.join(' ')}`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Show advanced example with boolean flags if any exist
|
|
171
|
+
if (basicArgs.length > 0 && advancedBooleanArgs.length > 0) {
|
|
172
|
+
console.log(` kosui ${command} ${basicArgs.slice(0, 2).join(' ')} ${advancedBooleanArgs.join(' ')}`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// If no basic args, show a minimal example
|
|
176
|
+
if (basicArgs.length === 0) {
|
|
177
|
+
console.log(` kosui ${command} [options]`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
console.log(` kosui ${command} --interactive # Force interactive mode`);
|
|
182
|
+
console.log(` kosui ${command} -i # Force interactive mode (short form)`);
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Also check for no-arguments case (when only global flags like --no-cache are present)
|
|
188
|
+
const earlyMeta = await getGeneratorMetadata(command);
|
|
189
|
+
if (earlyMeta?.namedArguments) {
|
|
190
|
+
const namedArgumentsMap = earlyMeta.namedArguments;
|
|
191
|
+
const providedAnswers = {};
|
|
192
|
+
Object.entries(namedArgumentsMap).forEach(([cliArg, promptName]) => {
|
|
193
|
+
if (cliArg === "interactive") return;
|
|
194
|
+
if (parsedArgs[cliArg] !== undefined) {
|
|
195
|
+
let value = parsedArgs[cliArg];
|
|
196
|
+
if (value === "true" || value === "y" || value === "yes") {
|
|
197
|
+
value = true;
|
|
198
|
+
} else if (value === "false" || value === "n" || value === "no") {
|
|
199
|
+
value = false;
|
|
200
|
+
}
|
|
201
|
+
providedAnswers[promptName] = value;
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
const hasAnyAnswers = Object.keys(providedAnswers).length > 0;
|
|
205
|
+
const forceInteractive = parsedArgs.interactive || parsedArgs.i;
|
|
206
|
+
|
|
207
|
+
// Show help for no-arguments case
|
|
208
|
+
if (!hasAnyAnswers && !forceInteractive) {
|
|
209
|
+
console.log(`--- ${earlyMeta?.name || command} Help ---`);
|
|
210
|
+
console.log(earlyMeta.description || "No description available");
|
|
211
|
+
|
|
212
|
+
if (earlyMeta?.namedArguments) {
|
|
213
|
+
console.log("\nNamed Arguments:");
|
|
214
|
+
Object.entries(earlyMeta.namedArguments).forEach(([cliArg, promptName]) => {
|
|
215
|
+
console.log(` --${cliArg} Maps to prompt: ${promptName}`);
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
console.log("\nExamples:");
|
|
220
|
+
|
|
221
|
+
// Generate examples dynamically from the generator's named arguments
|
|
222
|
+
if (earlyMeta?.namedArguments) {
|
|
223
|
+
const args = Object.keys(earlyMeta.namedArguments);
|
|
224
|
+
|
|
225
|
+
// Generate example values based on argument names
|
|
226
|
+
const generateExampleValue = (argName) => {
|
|
227
|
+
switch (argName) {
|
|
228
|
+
case 'name':
|
|
229
|
+
case 'componentName':
|
|
230
|
+
return command.includes('plugin') ? 'MyPlugin' : 'MyComponent';
|
|
231
|
+
case 'modelName':
|
|
232
|
+
return 'my-model';
|
|
233
|
+
case 'workspaceName':
|
|
234
|
+
return 'my-workspace';
|
|
235
|
+
case 'project':
|
|
236
|
+
case 'componentProject':
|
|
237
|
+
case 'modelProject':
|
|
238
|
+
return 'my-ui-lib';
|
|
239
|
+
case 'registrationProject':
|
|
240
|
+
return 'my-lib';
|
|
241
|
+
case 'companionParent':
|
|
242
|
+
return 'parent-model';
|
|
243
|
+
case 'extensionPoint':
|
|
244
|
+
return 'utility';
|
|
245
|
+
case 'group':
|
|
246
|
+
return 'appearance';
|
|
247
|
+
case 'locale':
|
|
248
|
+
return 'en';
|
|
249
|
+
case 'container':
|
|
250
|
+
case 'singleton':
|
|
251
|
+
case 'parentAware':
|
|
252
|
+
case 'dataServices':
|
|
253
|
+
return true;
|
|
254
|
+
case 'dryRun':
|
|
255
|
+
return true;
|
|
256
|
+
default:
|
|
257
|
+
return `my-${argName}`;
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
// Create basic example with most important arguments
|
|
262
|
+
const basicArgs = [];
|
|
263
|
+
const booleanArgs = ['container', 'singleton', 'parentAware', 'dataServices', 'dryRun'];
|
|
264
|
+
|
|
265
|
+
// Pick the most relevant arguments for each generator type
|
|
266
|
+
const getRelevantArgs = (args, command) => {
|
|
267
|
+
const relevantArgs = [];
|
|
268
|
+
|
|
269
|
+
// Always prefer name-type arguments first
|
|
270
|
+
const nameArgs = ['name', 'componentName', 'modelName', 'workspaceName'].filter(arg => args.includes(arg));
|
|
271
|
+
if (nameArgs.length > 0) {
|
|
272
|
+
relevantArgs.push(nameArgs[0]); // Take the first name argument
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Then add project-type arguments
|
|
276
|
+
const projectArgs = ['project', 'componentProject', 'modelProject', 'registrationProject'].filter(arg => args.includes(arg));
|
|
277
|
+
if (projectArgs.length > 0) {
|
|
278
|
+
relevantArgs.push(projectArgs[0]); // Take the first project argument
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Add other specific arguments
|
|
282
|
+
const otherArgs = args.filter(arg =>
|
|
283
|
+
!nameArgs.includes(arg) &&
|
|
284
|
+
!projectArgs.includes(arg) &&
|
|
285
|
+
!booleanArgs.includes(arg) &&
|
|
286
|
+
arg !== 'interactive'
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
// Add up to 2 more relevant arguments
|
|
290
|
+
relevantArgs.push(...otherArgs.slice(0, 2));
|
|
291
|
+
|
|
292
|
+
return relevantArgs;
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
const relevantArgs = getRelevantArgs(args, command);
|
|
296
|
+
|
|
297
|
+
relevantArgs.forEach(argName => {
|
|
298
|
+
const value = generateExampleValue(argName);
|
|
299
|
+
basicArgs.push(`--${argName} ${value}`);
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
// Create advanced example with boolean flags
|
|
303
|
+
const advancedBooleanArgs = [];
|
|
304
|
+
booleanArgs.forEach(argName => {
|
|
305
|
+
if (args.includes(argName)) {
|
|
306
|
+
advancedBooleanArgs.push(`--${argName}`);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// Show basic example
|
|
311
|
+
if (basicArgs.length > 0) {
|
|
312
|
+
console.log(` kosui ${command} ${basicArgs.join(' ')}`);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// Show advanced example with boolean flags if any exist
|
|
316
|
+
if (basicArgs.length > 0 && advancedBooleanArgs.length > 0) {
|
|
317
|
+
console.log(` kosui ${command} ${basicArgs.slice(0, 2).join(' ')} ${advancedBooleanArgs.join(' ')}`);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// If no basic args, show a minimal example
|
|
321
|
+
if (basicArgs.length === 0) {
|
|
322
|
+
console.log(` kosui ${command} [options]`);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
console.log(` kosui ${command} --interactive # Force interactive mode`);
|
|
327
|
+
console.log(` kosui ${command} -i # Force interactive mode (short form)`);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const plop = await nodePlop(configPath);
|
|
333
|
+
|
|
334
|
+
plop.setActionType("clearCache", (answers, config, plop) => {
|
|
335
|
+
clearCache();
|
|
336
|
+
return "[ok] CLI cache cleared successfully.";
|
|
337
|
+
});
|
|
338
|
+
|
|
46
339
|
const generator = plop.getGenerator(command);
|
|
47
340
|
|
|
48
341
|
if (!generator) {
|
|
49
342
|
console.error(`[kos-cli] Generator "${command}" not found.`);
|
|
50
343
|
process.exit(1);
|
|
51
344
|
}
|
|
345
|
+
|
|
52
346
|
const meta = await getGeneratorMetadata(command);
|
|
347
|
+
|
|
348
|
+
|
|
53
349
|
if (showBanner) {
|
|
54
350
|
console.log(`--- Running KOS Generator: ${meta?.name || command} ---`);
|
|
55
351
|
}
|
|
56
352
|
|
|
57
353
|
try {
|
|
58
|
-
|
|
354
|
+
// Extract positional arguments for prompt bypass
|
|
355
|
+
const positionalArgs = parsedArgs._.slice(1); // Remove command from args
|
|
356
|
+
|
|
357
|
+
// Get named arguments mapping from generator metadata
|
|
358
|
+
const namedArgumentsMap = meta?.namedArguments || {};
|
|
359
|
+
|
|
360
|
+
// Convert CLI args to answer format using generator's mapping
|
|
361
|
+
const providedAnswers = {};
|
|
362
|
+
Object.entries(namedArgumentsMap).forEach(([cliArg, promptName]) => {
|
|
363
|
+
// Skip 'interactive' - it's handled as a special CLI flag, not a prompt argument
|
|
364
|
+
if (cliArg === "interactive") {
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
if (parsedArgs[cliArg] !== undefined) {
|
|
369
|
+
let value = parsedArgs[cliArg];
|
|
370
|
+
|
|
371
|
+
// Convert string boolean values to actual booleans
|
|
372
|
+
if (value === "true" || value === "y" || value === "yes") {
|
|
373
|
+
value = true;
|
|
374
|
+
} else if (value === "false" || value === "n" || value === "no") {
|
|
375
|
+
value = false;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
providedAnswers[promptName] = value;
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
// Also handle positional arguments
|
|
383
|
+
const prompts = generator.prompts || [];
|
|
384
|
+
positionalArgs.forEach((arg, index) => {
|
|
385
|
+
if (prompts[index] && !prompts[index].when) {
|
|
386
|
+
// Only non-conditional prompts
|
|
387
|
+
const promptName = prompts[index].name;
|
|
388
|
+
if (providedAnswers[promptName] === undefined) {
|
|
389
|
+
let value = arg;
|
|
390
|
+
|
|
391
|
+
// Convert string boolean values to actual booleans
|
|
392
|
+
if (value === "true" || value === "y" || value === "yes") {
|
|
393
|
+
value = true;
|
|
394
|
+
} else if (value === "false" || value === "n" || value === "no") {
|
|
395
|
+
value = false;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
providedAnswers[promptName] = value;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
// Check if we have ANY provided answers
|
|
404
|
+
const hasAnyAnswers = Object.keys(providedAnswers).length > 0;
|
|
405
|
+
|
|
406
|
+
let answers;
|
|
407
|
+
|
|
408
|
+
// Check if user wants to force interactive mode
|
|
409
|
+
const forceInteractive = parsedArgs.interactive || parsedArgs.i;
|
|
410
|
+
|
|
411
|
+
// If no arguments provided and no interactive flag, show help
|
|
412
|
+
if (!hasAnyAnswers && !forceInteractive) {
|
|
413
|
+
console.log(`--- ${meta?.name || command} Help ---`);
|
|
414
|
+
console.log(generator.description || "No description available");
|
|
415
|
+
|
|
416
|
+
if (meta?.namedArguments) {
|
|
417
|
+
console.log("\nNamed Arguments:");
|
|
418
|
+
Object.entries(meta.namedArguments).forEach(([cliArg, promptName]) => {
|
|
419
|
+
console.log(` --${cliArg} Maps to prompt: ${promptName}`);
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
console.log("\nExamples:");
|
|
424
|
+
|
|
425
|
+
// Generate examples dynamically from the generator's named arguments
|
|
426
|
+
if (meta?.namedArguments) {
|
|
427
|
+
const args = Object.keys(meta.namedArguments);
|
|
428
|
+
|
|
429
|
+
// Generate example values based on argument names
|
|
430
|
+
const generateExampleValue = (argName) => {
|
|
431
|
+
switch (argName) {
|
|
432
|
+
case 'name':
|
|
433
|
+
case 'componentName':
|
|
434
|
+
return command.includes('plugin') ? 'MyPlugin' : 'MyComponent';
|
|
435
|
+
case 'modelName':
|
|
436
|
+
return 'my-model';
|
|
437
|
+
case 'workspaceName':
|
|
438
|
+
return 'my-workspace';
|
|
439
|
+
case 'project':
|
|
440
|
+
case 'componentProject':
|
|
441
|
+
case 'modelProject':
|
|
442
|
+
return 'my-ui-lib';
|
|
443
|
+
case 'registrationProject':
|
|
444
|
+
return 'my-lib';
|
|
445
|
+
case 'companionParent':
|
|
446
|
+
return 'parent-model';
|
|
447
|
+
case 'extensionPoint':
|
|
448
|
+
return 'utility';
|
|
449
|
+
case 'group':
|
|
450
|
+
return 'appearance';
|
|
451
|
+
case 'locale':
|
|
452
|
+
return 'en';
|
|
453
|
+
case 'container':
|
|
454
|
+
case 'singleton':
|
|
455
|
+
case 'parentAware':
|
|
456
|
+
case 'dataServices':
|
|
457
|
+
return true;
|
|
458
|
+
case 'dryRun':
|
|
459
|
+
return true;
|
|
460
|
+
default:
|
|
461
|
+
return `my-${argName}`;
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
|
|
465
|
+
// Create basic example with most important arguments
|
|
466
|
+
const basicArgs = [];
|
|
467
|
+
const booleanArgs = ['container', 'singleton', 'parentAware', 'dataServices', 'dryRun'];
|
|
468
|
+
|
|
469
|
+
// Pick the most relevant arguments for each generator type
|
|
470
|
+
const getRelevantArgs = (args, command) => {
|
|
471
|
+
const relevantArgs = [];
|
|
472
|
+
|
|
473
|
+
// Always prefer name-type arguments first
|
|
474
|
+
const nameArgs = ['name', 'componentName', 'modelName', 'workspaceName'].filter(arg => args.includes(arg));
|
|
475
|
+
if (nameArgs.length > 0) {
|
|
476
|
+
relevantArgs.push(nameArgs[0]); // Take the first name argument
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// Then add project-type arguments
|
|
480
|
+
const projectArgs = ['project', 'componentProject', 'modelProject', 'registrationProject'].filter(arg => args.includes(arg));
|
|
481
|
+
if (projectArgs.length > 0) {
|
|
482
|
+
relevantArgs.push(projectArgs[0]); // Take the first project argument
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// Add other specific arguments
|
|
486
|
+
const otherArgs = args.filter(arg =>
|
|
487
|
+
!nameArgs.includes(arg) &&
|
|
488
|
+
!projectArgs.includes(arg) &&
|
|
489
|
+
!booleanArgs.includes(arg) &&
|
|
490
|
+
arg !== 'interactive'
|
|
491
|
+
);
|
|
492
|
+
|
|
493
|
+
// Add up to 2 more relevant arguments
|
|
494
|
+
relevantArgs.push(...otherArgs.slice(0, 2));
|
|
495
|
+
|
|
496
|
+
return relevantArgs;
|
|
497
|
+
};
|
|
498
|
+
|
|
499
|
+
const relevantArgs = getRelevantArgs(args, command);
|
|
500
|
+
|
|
501
|
+
relevantArgs.forEach(argName => {
|
|
502
|
+
const value = generateExampleValue(argName);
|
|
503
|
+
basicArgs.push(`--${argName} ${value}`);
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
// Create advanced example with boolean flags
|
|
507
|
+
const advancedBooleanArgs = [];
|
|
508
|
+
booleanArgs.forEach(argName => {
|
|
509
|
+
if (args.includes(argName)) {
|
|
510
|
+
advancedBooleanArgs.push(`--${argName}`);
|
|
511
|
+
}
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
// Show basic example
|
|
515
|
+
if (basicArgs.length > 0) {
|
|
516
|
+
console.log(` kosui ${command} ${basicArgs.join(' ')}`);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// Show advanced example with boolean flags if any exist
|
|
520
|
+
if (basicArgs.length > 0 && advancedBooleanArgs.length > 0) {
|
|
521
|
+
console.log(` kosui ${command} ${basicArgs.slice(0, 2).join(' ')} ${advancedBooleanArgs.join(' ')}`);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// If no basic args, show a minimal example
|
|
525
|
+
if (basicArgs.length === 0) {
|
|
526
|
+
console.log(` kosui ${command} [options]`);
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
console.log(` kosui ${command} --interactive # Force interactive mode`);
|
|
531
|
+
console.log(` kosui ${command} -i # Force interactive mode (short form)`);
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
if (hasAnyAnswers && !forceInteractive) {
|
|
536
|
+
// Create bypass array for all prompts
|
|
537
|
+
const bypassArgs = [];
|
|
538
|
+
|
|
539
|
+
// Fill bypass array with provided values or defaults
|
|
540
|
+
for (const prompt of prompts) {
|
|
541
|
+
if (prompt.when) {
|
|
542
|
+
// Skip conditional prompts - they can't be bypassed
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
const providedValue = providedAnswers[prompt.name];
|
|
547
|
+
if (providedValue !== undefined) {
|
|
548
|
+
bypassArgs.push(providedValue);
|
|
549
|
+
} else {
|
|
550
|
+
// Use default value or skip with "_"
|
|
551
|
+
bypassArgs.push(prompt.default !== undefined ? prompt.default : "_");
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
// Only bypass if we have all non-conditional prompts
|
|
556
|
+
const nonConditionalPrompts = prompts.filter((p) => !p.when);
|
|
557
|
+
if (bypassArgs.length === nonConditionalPrompts.length) {
|
|
558
|
+
// We can bypass all non-conditional prompts
|
|
559
|
+
answers = await generator.runPrompts(bypassArgs);
|
|
560
|
+
|
|
561
|
+
// Add any conditional prompt values that were provided
|
|
562
|
+
Object.assign(answers, providedAnswers);
|
|
563
|
+
} else {
|
|
564
|
+
// Fall back to interactive mode
|
|
565
|
+
console.log(
|
|
566
|
+
"Note: Running interactive mode. Your provided arguments will be applied automatically."
|
|
567
|
+
);
|
|
568
|
+
answers = await generator.runPrompts();
|
|
569
|
+
Object.assign(answers, providedAnswers);
|
|
570
|
+
}
|
|
571
|
+
} else {
|
|
572
|
+
// Run prompts interactively
|
|
573
|
+
if (forceInteractive) {
|
|
574
|
+
console.log(
|
|
575
|
+
"Note: Running in interactive mode. All prompts will be shown."
|
|
576
|
+
);
|
|
577
|
+
|
|
578
|
+
// In interactive mode, ignore provided arguments and run all prompts
|
|
579
|
+
answers = await generator.runPrompts();
|
|
580
|
+
} else {
|
|
581
|
+
answers = await generator.runPrompts();
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
59
585
|
const results = await generator.runActions(answers);
|
|
60
586
|
|
|
61
587
|
console.log("[kos-cli] Generator completed successfully!");
|
|
@@ -7,6 +7,12 @@ import { required } from "../../utils/validators.mjs";
|
|
|
7
7
|
export const metadata = {
|
|
8
8
|
key: "component",
|
|
9
9
|
name: "KOS React Component",
|
|
10
|
+
namedArguments: {
|
|
11
|
+
name: "componentName",
|
|
12
|
+
componentName: "componentName",
|
|
13
|
+
project: "componentProject",
|
|
14
|
+
componentProject: "componentProject"
|
|
15
|
+
}
|
|
10
16
|
};
|
|
11
17
|
|
|
12
18
|
export default async function (plop) {
|
|
@@ -8,6 +8,11 @@ import { required } from "../../utils/validators.mjs";
|
|
|
8
8
|
export const metadata = {
|
|
9
9
|
key: "i18n:namespace",
|
|
10
10
|
name: "KOS i18n Project Namespace",
|
|
11
|
+
namedArguments: {
|
|
12
|
+
name: "name",
|
|
13
|
+
locale: "locale",
|
|
14
|
+
project: "project",
|
|
15
|
+
},
|
|
11
16
|
};
|
|
12
17
|
|
|
13
18
|
export default async function (plop) {
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// generators/model/add-future.mjs
|
|
2
|
+
import { actionFactory } from "../../utils/action-factory.mjs";
|
|
3
|
+
import { execute } from "../../utils/exec.mjs";
|
|
4
|
+
import { getAllModels } from "../../utils/nx-context.mjs";
|
|
5
|
+
import { DEFAULT_PROMPTS } from "../../utils/prompts.mjs";
|
|
6
|
+
|
|
7
|
+
export const metadata = {
|
|
8
|
+
key: "add-future",
|
|
9
|
+
name: "Add Future Support to Model",
|
|
10
|
+
invalidateCache: true,
|
|
11
|
+
namedArguments: {
|
|
12
|
+
modelName: "modelName",
|
|
13
|
+
project: "modelProject",
|
|
14
|
+
modelProject: "modelProject",
|
|
15
|
+
futureType: "futureType",
|
|
16
|
+
updateServices: "updateServices",
|
|
17
|
+
dryRun: "dryRun",
|
|
18
|
+
interactive: "interactive",
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default async function (plop) {
|
|
23
|
+
const allModels = await getAllModels();
|
|
24
|
+
const modelChoices = allModels.map((m) => ({
|
|
25
|
+
name: `${m.model} (${m.project})`,
|
|
26
|
+
value: m.model,
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
plop.setActionType("addFutureToModel", async function (answers) {
|
|
30
|
+
const modelProject = allModels.find(
|
|
31
|
+
(m) => m.model === answers.modelName
|
|
32
|
+
)?.project;
|
|
33
|
+
|
|
34
|
+
const command = `npx nx generate @kosdev-code/kos-nx-plugin:kos-add-future-to-model \\
|
|
35
|
+
--modelName=${answers.modelName} \\
|
|
36
|
+
--modelProject=${modelProject} \\
|
|
37
|
+
--futureType=${answers.futureType} \\
|
|
38
|
+
--updateServices=${!!answers.updateServices} \\
|
|
39
|
+
--no-interactive ${answers.dryRun ? "--dryRun" : ""} --verbose`;
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
await execute(command);
|
|
43
|
+
} catch (error) {
|
|
44
|
+
throw new Error(error);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return `Future support (${answers.futureType}) added to model ${answers.modelName} in ${modelProject}`;
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
plop.setGenerator("add-future", {
|
|
51
|
+
description: "Add Future support to an existing KOS Model",
|
|
52
|
+
prompts: [
|
|
53
|
+
...DEFAULT_PROMPTS,
|
|
54
|
+
{
|
|
55
|
+
type: "list",
|
|
56
|
+
name: "modelName",
|
|
57
|
+
message: "Which model do you want to add Future support to?",
|
|
58
|
+
choices: modelChoices,
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
type: "list",
|
|
62
|
+
name: "futureType",
|
|
63
|
+
message: "What type of Future support?",
|
|
64
|
+
choices: [
|
|
65
|
+
{ name: "Minimal (external access only)", value: "minimal" },
|
|
66
|
+
{ name: "Complete (internal + external access)", value: "complete" },
|
|
67
|
+
],
|
|
68
|
+
default: "minimal",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
type: "confirm",
|
|
72
|
+
name: "updateServices",
|
|
73
|
+
message: "Update/create services file with Future operations?",
|
|
74
|
+
default: true,
|
|
75
|
+
},
|
|
76
|
+
],
|
|
77
|
+
|
|
78
|
+
actions: actionFactory("addFutureToModel", metadata),
|
|
79
|
+
});
|
|
80
|
+
}
|
|
@@ -6,12 +6,30 @@ import {
|
|
|
6
6
|
getLibraryProjects,
|
|
7
7
|
getProjectDetails,
|
|
8
8
|
} from "../../utils/nx-context.mjs";
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
COMPANION_PROMPTS,
|
|
11
|
+
DEFAULT_PROMPTS,
|
|
12
|
+
MODEL_PROMPTS,
|
|
13
|
+
} from "../../utils/prompts.mjs";
|
|
10
14
|
import { required } from "../../utils/validators.mjs";
|
|
11
15
|
|
|
12
16
|
export const metadata = {
|
|
13
17
|
key: "model:companion",
|
|
14
18
|
name: "KOS Companion Model",
|
|
19
|
+
namedArguments: {
|
|
20
|
+
name: "modelName",
|
|
21
|
+
modelName: "modelName",
|
|
22
|
+
project: "modelProject",
|
|
23
|
+
modelProject: "modelProject",
|
|
24
|
+
companionParent: "companionParent",
|
|
25
|
+
companionPattern: "companionPattern",
|
|
26
|
+
container: "container",
|
|
27
|
+
parentAware: "parentAware",
|
|
28
|
+
singleton: "singleton",
|
|
29
|
+
dataServices: "dataServices",
|
|
30
|
+
dryRun: "dryRun",
|
|
31
|
+
interactive: "interactive",
|
|
32
|
+
},
|
|
15
33
|
};
|
|
16
34
|
|
|
17
35
|
export default async function (plop) {
|
|
@@ -39,6 +57,7 @@ export default async function (plop) {
|
|
|
39
57
|
--companion=true \
|
|
40
58
|
--companionModel=${answers.companionParent} \
|
|
41
59
|
--companionModelProject=${companionProject} \
|
|
60
|
+
--companionPattern=${answers.companionPattern} \
|
|
42
61
|
--no-interactive ${answers.dryRun ? "--dryRun" : ""} --verbose`;
|
|
43
62
|
|
|
44
63
|
try {
|
|
@@ -71,6 +90,7 @@ export default async function (plop) {
|
|
|
71
90
|
message: "Select the companion parent model",
|
|
72
91
|
choices: modelChoices,
|
|
73
92
|
},
|
|
93
|
+
...COMPANION_PROMPTS,
|
|
74
94
|
...MODEL_PROMPTS,
|
|
75
95
|
],
|
|
76
96
|
actions: actionFactory("createCompanionModel", metadata),
|
|
@@ -11,6 +11,16 @@ import { DEFAULT_PROMPTS, MODEL_PROMPTS } from "../../utils/prompts.mjs";
|
|
|
11
11
|
export const metadata = {
|
|
12
12
|
key: "container",
|
|
13
13
|
name: "KOS Container Model",
|
|
14
|
+
namedArguments: {
|
|
15
|
+
modelName: "modelName",
|
|
16
|
+
registrationProject: "registrationProject",
|
|
17
|
+
container: "container",
|
|
18
|
+
parentAware: "parentAware",
|
|
19
|
+
singleton: "singleton",
|
|
20
|
+
dataServices: "dataServices",
|
|
21
|
+
dryRun: "dryRun",
|
|
22
|
+
interactive: "interactive",
|
|
23
|
+
},
|
|
14
24
|
};
|
|
15
25
|
|
|
16
26
|
export default async function (plop) {
|
|
@@ -5,6 +5,11 @@ import { getAllModels, getAllProjects } from "../../utils/nx-context.mjs";
|
|
|
5
5
|
export const metadata = {
|
|
6
6
|
key: "context",
|
|
7
7
|
name: "KOS Model React Context",
|
|
8
|
+
namedArguments: {
|
|
9
|
+
modelName: "modelName",
|
|
10
|
+
componentProject: "componentProject",
|
|
11
|
+
project: "componentProject",
|
|
12
|
+
},
|
|
8
13
|
};
|
|
9
14
|
|
|
10
15
|
export default async function (plop) {
|
|
@@ -5,6 +5,11 @@ import { getAllModels, getAllProjects } from "../../utils/nx-context.mjs";
|
|
|
5
5
|
export const metadata = {
|
|
6
6
|
key: "hook",
|
|
7
7
|
name: "KOS Model React Hook",
|
|
8
|
+
namedArguments: {
|
|
9
|
+
modelName: "modelName",
|
|
10
|
+
componentProject: "componentProject",
|
|
11
|
+
project: "componentProject"
|
|
12
|
+
}
|
|
8
13
|
};
|
|
9
14
|
|
|
10
15
|
export default async function (plop) {
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import { actionFactory } from "../../utils/action-factory.mjs";
|
|
3
3
|
import { execute } from "../../utils/exec.mjs";
|
|
4
4
|
import {
|
|
5
|
-
getAllProjects,
|
|
6
5
|
getLibraryProjects,
|
|
7
6
|
getProjectDetails,
|
|
8
7
|
} from "../../utils/nx-context.mjs";
|
|
@@ -13,10 +12,22 @@ export const metadata = {
|
|
|
13
12
|
key: "model",
|
|
14
13
|
name: "KOS Model",
|
|
15
14
|
invalidateCache: true,
|
|
15
|
+
namedArguments: {
|
|
16
|
+
name: "modelName",
|
|
17
|
+
modelName: "modelName",
|
|
18
|
+
project: "modelProject",
|
|
19
|
+
modelProject: "modelProject",
|
|
20
|
+
container: "container",
|
|
21
|
+
parentAware: "parentAware",
|
|
22
|
+
singleton: "singleton",
|
|
23
|
+
dataServices: "dataServices",
|
|
24
|
+
futureAware: "futureAware",
|
|
25
|
+
dryRun: "dryRun",
|
|
26
|
+
interactive: "interactive"
|
|
27
|
+
}
|
|
16
28
|
};
|
|
17
29
|
|
|
18
30
|
export default async function (plop) {
|
|
19
|
-
const allProjects = await getAllProjects();
|
|
20
31
|
const libraryProjects = await getLibraryProjects();
|
|
21
32
|
|
|
22
33
|
plop.setActionType("createModel", async function (answers) {
|
|
@@ -29,6 +40,7 @@ export default async function (plop) {
|
|
|
29
40
|
--dataServices=${!!answers.dataServices} \
|
|
30
41
|
--singleton=${!!answers.singleton} \
|
|
31
42
|
--parentAware=${!!answers.parentAware} \
|
|
43
|
+
--futureAware=${answers.futureAware || 'none'} \
|
|
32
44
|
--no-interactive ${answers.dryRun ? "--dryRun" : ""} --verbose`;
|
|
33
45
|
|
|
34
46
|
try {
|
|
@@ -4,13 +4,78 @@ import { execute } from "../../utils/exec.mjs";
|
|
|
4
4
|
import { getAllProjects } from "../../utils/nx-context.mjs";
|
|
5
5
|
import { required } from "../../utils/validators.mjs";
|
|
6
6
|
export const metadata = [
|
|
7
|
-
{
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
{
|
|
8
|
+
key: "pluginComponent",
|
|
9
|
+
name: "KOS UI Plugin Component",
|
|
10
|
+
namedArguments: {
|
|
11
|
+
name: "componentName",
|
|
12
|
+
componentName: "componentName",
|
|
13
|
+
project: "componentProject",
|
|
14
|
+
componentProject: "componentProject",
|
|
15
|
+
extensionPoint: "extensionPoint"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
key: "plugin:cui",
|
|
20
|
+
name: "KOS UI Plugin CUI Configuration",
|
|
21
|
+
namedArguments: {
|
|
22
|
+
name: "componentName",
|
|
23
|
+
componentName: "componentName",
|
|
24
|
+
project: "componentProject",
|
|
25
|
+
componentProject: "componentProject"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
key: "plugin:setup",
|
|
30
|
+
name: "KOS UI Plugin Setup Step",
|
|
31
|
+
namedArguments: {
|
|
32
|
+
name: "componentName",
|
|
33
|
+
componentName: "componentName",
|
|
34
|
+
project: "componentProject",
|
|
35
|
+
componentProject: "componentProject"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
key: "plugin:utility",
|
|
40
|
+
name: "KOS UI Plugin Utility",
|
|
41
|
+
namedArguments: {
|
|
42
|
+
name: "componentName",
|
|
43
|
+
componentName: "componentName",
|
|
44
|
+
project: "componentProject",
|
|
45
|
+
componentProject: "componentProject"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
key: "plugin:setting",
|
|
50
|
+
name: "KOS UI Plugin Setting",
|
|
51
|
+
namedArguments: {
|
|
52
|
+
name: "componentName",
|
|
53
|
+
componentName: "componentName",
|
|
54
|
+
project: "componentProject",
|
|
55
|
+
componentProject: "componentProject",
|
|
56
|
+
group: "group"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
key: "plugin:nav",
|
|
61
|
+
name: "KOS UI Plugin Navigation View",
|
|
62
|
+
namedArguments: {
|
|
63
|
+
name: "componentName",
|
|
64
|
+
componentName: "componentName",
|
|
65
|
+
project: "componentProject",
|
|
66
|
+
componentProject: "componentProject"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
key: "plugin:cp",
|
|
71
|
+
name: "KOS UI Plugin Control Pour",
|
|
72
|
+
namedArguments: {
|
|
73
|
+
name: "componentName",
|
|
74
|
+
componentName: "componentName",
|
|
75
|
+
project: "componentProject",
|
|
76
|
+
componentProject: "componentProject"
|
|
77
|
+
}
|
|
78
|
+
},
|
|
14
79
|
];
|
|
15
80
|
|
|
16
81
|
export default async function (plop) {
|
|
@@ -7,6 +7,7 @@ export const metadata = {
|
|
|
7
7
|
key: "project:splash",
|
|
8
8
|
name: "KOS Splash Screen Project",
|
|
9
9
|
invalidateCache: true,
|
|
10
|
+
namedArguments: { name: "name" },
|
|
10
11
|
};
|
|
11
12
|
export default async function (plop) {
|
|
12
13
|
plop.setActionType("createSplashProject", async function (answers) {
|
|
@@ -5,6 +5,10 @@ import { required } from "../../utils/validators.mjs";
|
|
|
5
5
|
export const metadata = {
|
|
6
6
|
key: "workspace",
|
|
7
7
|
name: "Create a new KOS UI Workspace",
|
|
8
|
+
namedArguments: {
|
|
9
|
+
name: "workspaceName",
|
|
10
|
+
workspaceName: "workspaceName"
|
|
11
|
+
}
|
|
8
12
|
};
|
|
9
13
|
export default async function (plop) {
|
|
10
14
|
plop.setActionType("createWorkspace", async function (answers) {
|
package/src/lib/plopfile.mjs
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { detectWorkspace } from "./utils/nx-context.mjs";
|
|
3
3
|
|
|
4
4
|
// Generator registration
|
|
5
|
+
import registerAddFuture from "./generators/model/add-future.mjs";
|
|
5
6
|
import registerCompanion from "./generators/model/companion.mjs";
|
|
6
7
|
import registerContainer from "./generators/model/container.mjs";
|
|
7
8
|
import registerContext from "./generators/model/context.mjs";
|
|
@@ -40,6 +41,7 @@ export default async function (plop) {
|
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
await registerKosModel(plop);
|
|
44
|
+
await registerAddFuture(plop);
|
|
43
45
|
await registerHook(plop);
|
|
44
46
|
await registerCompanion(plop);
|
|
45
47
|
await registerContainer(plop);
|
|
@@ -29,7 +29,6 @@ export const MODEL_PROMPTS = [
|
|
|
29
29
|
name: "parentAware",
|
|
30
30
|
message: "Aware of parent container?",
|
|
31
31
|
default: false,
|
|
32
|
-
when: (answers) => !!answers.container,
|
|
33
32
|
},
|
|
34
33
|
{
|
|
35
34
|
type: "confirm",
|
|
@@ -43,4 +42,34 @@ export const MODEL_PROMPTS = [
|
|
|
43
42
|
message: "Create data services?",
|
|
44
43
|
default: true,
|
|
45
44
|
},
|
|
45
|
+
{
|
|
46
|
+
type: "list",
|
|
47
|
+
name: "futureAware",
|
|
48
|
+
message: "Include Future-aware capabilities?",
|
|
49
|
+
choices: [
|
|
50
|
+
{ name: "No Future support", value: "none" },
|
|
51
|
+
{ name: "Minimal (external access only)", value: "minimal" },
|
|
52
|
+
{ name: "Complete (internal + external access)", value: "complete" },
|
|
53
|
+
],
|
|
54
|
+
default: "none",
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
export const COMPANION_PROMPTS = [
|
|
59
|
+
{
|
|
60
|
+
type: "list",
|
|
61
|
+
name: "companionPattern",
|
|
62
|
+
message: "Which companion pattern to use?",
|
|
63
|
+
choices: [
|
|
64
|
+
{
|
|
65
|
+
name: "Composition (recommended) - explicit parent access via this.parent",
|
|
66
|
+
value: "composition",
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: "Decorator - transparent parent access, drop-in replacement",
|
|
70
|
+
value: "decorator",
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
default: "composition",
|
|
74
|
+
},
|
|
46
75
|
];
|