@wc-toolkit/cem-generator-cli 0.1.1 → 0.1.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/README.md +22 -4
- package/dist/cli.js +247 -26
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@ pnpm add -w @wc-toolkit/cem-generator-cli
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
13
|
```bash
|
|
14
|
-
# Create a config and choose
|
|
14
|
+
# Create a config and choose parser plugins and integrations interactively
|
|
15
15
|
cem init
|
|
16
16
|
|
|
17
17
|
# Create a config with selected plugins without prompting
|
|
@@ -35,15 +35,33 @@ cem generate --no-inheritance
|
|
|
35
35
|
|
|
36
36
|
## Options
|
|
37
37
|
|
|
38
|
-
`cem init` writes `cem-generator.config.mjs
|
|
38
|
+
`cem init` writes `cem-generator.config.mjs`. In interactive mode it first asks
|
|
39
|
+
which parser plugins to use, then presents a multi-select list of integrations:
|
|
40
|
+
`react-wrappers`, `jsx-types`, `vuejs-types`, and `svelte-types`. The type
|
|
41
|
+
integrations use `./types` and strongly typed events by default. The command
|
|
42
|
+
also supports `--plugin <names...>`,
|
|
39
43
|
`--yes`, `--force`, and `--config <path>`.
|
|
40
44
|
|
|
45
|
+
`cem generate` uses source-oriented include/exclude defaults when those flags
|
|
46
|
+
are omitted. Supplying either flag replaces its defaults. The TypeScript
|
|
47
|
+
configuration still controls which files enter the program.
|
|
48
|
+
|
|
49
|
+
When `cem init` installs dependencies, CLI mode installs
|
|
50
|
+
`@wc-toolkit/cem-generator-cli`, while code mode installs
|
|
51
|
+
`@wc-toolkit/cem-generator` and `tsx`. Selected parser and integration
|
|
52
|
+
packages are installed alongside the workflow package. The command prints the
|
|
53
|
+
`package.json` script to add and the package-manager command to run it.
|
|
54
|
+
|
|
55
|
+
In an interactive terminal, use the arrow keys to move through lists, Space to
|
|
56
|
+
toggle checkbox selections, and Enter to confirm. Non-interactive input falls
|
|
57
|
+
back to comma-separated selection numbers.
|
|
58
|
+
|
|
41
59
|
| Option | Description | Default |
|
|
42
60
|
|--------|-------------|---------|
|
|
43
61
|
| `-c, --config <path>` | Path to tsconfig.json | `./tsconfig.json` |
|
|
44
62
|
| `-o, --output <path>` | Output file path | `./custom-elements.json` |
|
|
45
|
-
| `--include <patterns...>` | Glob patterns to include |
|
|
46
|
-
| `--exclude <patterns...>` | Glob patterns to exclude |
|
|
63
|
+
| `--include <patterns...>` | Glob patterns to include | `src/**/*.{ts,tsx,js,jsx}` when `src/` exists |
|
|
64
|
+
| `--exclude <patterns...>` | Glob patterns to exclude | Tests, specs, stories, `dist/`, and `node_modules/` |
|
|
47
65
|
| `--no-inheritance` | Disable inheritance materialization | - |
|
|
48
66
|
| `--plugin <paths...>` | Additional plugin paths to load | - |
|
|
49
67
|
| `--conflict-policy <policy>` | Detector conflict policy: `throw` \| `last-wins` | `last-wins` |
|
package/dist/cli.js
CHANGED
|
@@ -6,6 +6,7 @@ import fs from "node:fs";
|
|
|
6
6
|
import readline from "node:readline/promises";
|
|
7
7
|
import { stdin as input, stdout as output } from "node:process";
|
|
8
8
|
import { spawnSync } from "node:child_process";
|
|
9
|
+
import inquirer from "inquirer";
|
|
9
10
|
import { generateCem, loadConfig, mergeConfig } from "@wc-toolkit/cem-generator";
|
|
10
11
|
const __filename = fileURLToPath(import.meta.url);
|
|
11
12
|
const __dirname = path.dirname(__filename);
|
|
@@ -18,6 +19,40 @@ const PLUGIN_CHOICES = [
|
|
|
18
19
|
{ name: "solid", packageName: "@wc-toolkit/cem-generator-solid", factory: "solidPlugin" },
|
|
19
20
|
{ name: "svelte", packageName: "@wc-toolkit/cem-generator-svelte", factory: "sveltePlugin" },
|
|
20
21
|
];
|
|
22
|
+
const INTEGRATION_CHOICES = [
|
|
23
|
+
{
|
|
24
|
+
name: "react-wrappers",
|
|
25
|
+
packageName: "@wc-toolkit/react-wrappers",
|
|
26
|
+
factory: "reactWrapperGeneratorPlugin",
|
|
27
|
+
options: { stronglyTypedEvents: true },
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "jsx-types",
|
|
31
|
+
packageName: "@wc-toolkit/jsx-types",
|
|
32
|
+
factory: "jsxTypesGeneratorPlugin",
|
|
33
|
+
options: { outdir: "./types", stronglyTypedEvents: true },
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: "vuejs-types",
|
|
37
|
+
packageName: "@wc-toolkit/vuejs-types",
|
|
38
|
+
factory: "vuejsTypesGeneratorPlugin",
|
|
39
|
+
options: { outdir: "./types", stronglyTypedEvents: true },
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: "svelte-types",
|
|
43
|
+
packageName: "@wc-toolkit/svelte-types",
|
|
44
|
+
factory: "svelteTypesGeneratorPlugin",
|
|
45
|
+
options: { outdir: "./types", stronglyTypedEvents: true },
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
const DEFAULT_SOURCE_INCLUDE = ["src/**/*.{ts,tsx,js,jsx}"];
|
|
49
|
+
const DEFAULT_SOURCE_EXCLUDE = [
|
|
50
|
+
"**/*.test.*",
|
|
51
|
+
"**/*.spec.*",
|
|
52
|
+
"**/*.stories.*",
|
|
53
|
+
"**/dist/**",
|
|
54
|
+
"**/node_modules/**",
|
|
55
|
+
];
|
|
21
56
|
const program = new Command();
|
|
22
57
|
program
|
|
23
58
|
.name("cem")
|
|
@@ -47,8 +82,8 @@ program
|
|
|
47
82
|
});
|
|
48
83
|
const cliOptions = {
|
|
49
84
|
tsConfigPath: path.resolve(options.tsconfig),
|
|
50
|
-
include: options.include,
|
|
51
|
-
exclude: options.exclude,
|
|
85
|
+
include: options.include ?? getDefaultInclude(cwd),
|
|
86
|
+
exclude: options.exclude ?? DEFAULT_SOURCE_EXCLUDE,
|
|
52
87
|
sort: options.sort !== false,
|
|
53
88
|
};
|
|
54
89
|
if (options.deprecatedLast) {
|
|
@@ -111,28 +146,47 @@ program
|
|
|
111
146
|
.option("-c, --config <path>", "Config file path", "./cem-generator.config.mjs")
|
|
112
147
|
.option("--mode <mode>", "How to run the generator: cli | code")
|
|
113
148
|
.option("--output <path>", "Generated code file path", "./generate-cem.ts")
|
|
114
|
-
.option("--plugin <names...>", "
|
|
149
|
+
.option("--plugin <names...>", "Parser plugins to include (lit, fast, stencil, preact, vue, solid, svelte)")
|
|
115
150
|
.option("--install", "Install selected plugin packages")
|
|
116
151
|
.option("--yes", "Create a config without prompting for plugins")
|
|
117
152
|
.option("--force", "Overwrite existing output files")
|
|
118
153
|
.action(async (options) => {
|
|
119
154
|
try {
|
|
155
|
+
const cwd = process.cwd();
|
|
120
156
|
let mode;
|
|
121
157
|
let selectedNames;
|
|
158
|
+
let selectedIntegrationNames;
|
|
122
159
|
if (options.yes) {
|
|
123
160
|
mode = options.mode ? validateInitMode(options.mode) : "cli";
|
|
124
161
|
selectedNames = [];
|
|
162
|
+
selectedIntegrationNames = [];
|
|
125
163
|
}
|
|
126
164
|
else if (options.mode) {
|
|
127
165
|
mode = validateInitMode(options.mode);
|
|
128
|
-
|
|
166
|
+
if (options.plugin) {
|
|
167
|
+
selectedNames = validatePluginNames(options.plugin);
|
|
168
|
+
selectedIntegrationNames = [];
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
({ selectedNames, selectedIntegrationNames } = await promptForPluginsAndIntegrations());
|
|
172
|
+
}
|
|
129
173
|
}
|
|
130
174
|
else {
|
|
131
|
-
({ mode, selectedNames } = options.plugin
|
|
175
|
+
({ mode, selectedNames, selectedIntegrationNames } = options.plugin
|
|
132
176
|
? await promptForModeAndPlugins(options.plugin)
|
|
133
177
|
: await promptForModeAndPlugins());
|
|
134
178
|
}
|
|
135
179
|
const selectedPlugins = PLUGIN_CHOICES.filter((plugin) => selectedNames.includes(plugin.name));
|
|
180
|
+
const selectedIntegrations = INTEGRATION_CHOICES.filter((integration) => selectedIntegrationNames.includes(integration.name));
|
|
181
|
+
const generatorPackage = mode === "cli"
|
|
182
|
+
? "@wc-toolkit/cem-generator-cli"
|
|
183
|
+
: "@wc-toolkit/cem-generator";
|
|
184
|
+
const packagesToInstall = [
|
|
185
|
+
generatorPackage,
|
|
186
|
+
...(mode === "code" ? ["tsx"] : []),
|
|
187
|
+
...selectedPlugins.map((plugin) => plugin.packageName),
|
|
188
|
+
...selectedIntegrations.map((integration) => integration.packageName),
|
|
189
|
+
];
|
|
136
190
|
const configPath = path.resolve(options.config);
|
|
137
191
|
const outputPath = path.resolve(options.output);
|
|
138
192
|
const targetPaths = mode === "cli" ? [configPath] : [configPath, outputPath];
|
|
@@ -140,18 +194,19 @@ program
|
|
|
140
194
|
if (existingPath && !options.force) {
|
|
141
195
|
throw new Error(`Output file already exists: ${existingPath}. Use --force to overwrite it.`);
|
|
142
196
|
}
|
|
143
|
-
const shouldInstall = options.install ?? (!options.yes && !options.mode
|
|
197
|
+
const shouldInstall = options.install ?? (!options.yes && !options.mode
|
|
144
198
|
? await promptForInstall()
|
|
145
199
|
: false);
|
|
146
|
-
if (shouldInstall
|
|
147
|
-
installPluginDependencies(
|
|
200
|
+
if (shouldInstall) {
|
|
201
|
+
installPluginDependencies(packagesToInstall);
|
|
148
202
|
}
|
|
149
|
-
fs.writeFileSync(configPath, createConfigSource(selectedPlugins), "utf-8");
|
|
203
|
+
fs.writeFileSync(configPath, createConfigSource(selectedPlugins, selectedIntegrations, getDefaultInclude(cwd), DEFAULT_SOURCE_EXCLUDE), "utf-8");
|
|
150
204
|
console.log(`Created config file at ${configPath}`);
|
|
151
205
|
if (mode === "code") {
|
|
152
206
|
fs.writeFileSync(outputPath, createCodeSource(configPath, outputPath), "utf-8");
|
|
153
207
|
console.log(`Created code file at ${outputPath}`);
|
|
154
208
|
}
|
|
209
|
+
printNextSteps(mode, configPath, outputPath);
|
|
155
210
|
}
|
|
156
211
|
catch (error) {
|
|
157
212
|
console.error("Error initializing project:", error instanceof Error ? error.message : error);
|
|
@@ -164,6 +219,9 @@ function validateInitMode(mode) {
|
|
|
164
219
|
}
|
|
165
220
|
return mode;
|
|
166
221
|
}
|
|
222
|
+
function getDefaultInclude(cwd) {
|
|
223
|
+
return fs.existsSync(path.join(cwd, "src")) ? DEFAULT_SOURCE_INCLUDE : undefined;
|
|
224
|
+
}
|
|
167
225
|
async function promptForMode(prompt) {
|
|
168
226
|
const answer = await prompt.question("How will you run the generator? (1) CLI (2) code: ");
|
|
169
227
|
if (answer.trim() === "1" || answer.trim().toLowerCase() === "cli")
|
|
@@ -174,7 +232,14 @@ async function promptForMode(prompt) {
|
|
|
174
232
|
}
|
|
175
233
|
async function promptForModeAndPlugins(pluginNames) {
|
|
176
234
|
if (pluginNames) {
|
|
177
|
-
return {
|
|
235
|
+
return {
|
|
236
|
+
mode: await promptForModeWithInput(),
|
|
237
|
+
selectedNames: validatePluginNames(pluginNames),
|
|
238
|
+
selectedIntegrationNames: [],
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
if (isInteractiveTerminal()) {
|
|
242
|
+
return promptForInteractiveSelections();
|
|
178
243
|
}
|
|
179
244
|
const prompt = readline.createInterface({ input, output });
|
|
180
245
|
const lines = prompt[Symbol.asyncIterator]();
|
|
@@ -191,13 +256,37 @@ async function promptForModeAndPlugins(pluginNames) {
|
|
|
191
256
|
const pluginsLine = await lines.next();
|
|
192
257
|
if (pluginsLine.done)
|
|
193
258
|
throw new Error("No plugin selection provided.");
|
|
194
|
-
|
|
259
|
+
const selectedNames = parsePluginSelection(pluginsLine.value);
|
|
260
|
+
console.log("Which project integrations should be included? (multi-select)");
|
|
261
|
+
INTEGRATION_CHOICES.forEach((integration, index) => console.log(` ${index + 1}. ${integration.name}`));
|
|
262
|
+
console.log("Enter numbers separated by commas, or press Enter for no integrations.");
|
|
263
|
+
output.write("Integrations: ");
|
|
264
|
+
const integrationsLine = await lines.next();
|
|
265
|
+
if (integrationsLine.done)
|
|
266
|
+
throw new Error("No integration selection provided.");
|
|
267
|
+
return {
|
|
268
|
+
mode,
|
|
269
|
+
selectedNames,
|
|
270
|
+
selectedIntegrationNames: parseIntegrationSelection(integrationsLine.value),
|
|
271
|
+
};
|
|
195
272
|
}
|
|
196
273
|
finally {
|
|
197
274
|
prompt.close();
|
|
198
275
|
}
|
|
199
276
|
}
|
|
200
277
|
async function promptForModeWithInput() {
|
|
278
|
+
if (isInteractiveTerminal()) {
|
|
279
|
+
const { mode } = await inquirer.prompt({
|
|
280
|
+
type: "select",
|
|
281
|
+
name: "mode",
|
|
282
|
+
message: "How will you run the generator?",
|
|
283
|
+
choices: [
|
|
284
|
+
{ name: "CLI", value: "cli" },
|
|
285
|
+
{ name: "Code", value: "code" },
|
|
286
|
+
],
|
|
287
|
+
});
|
|
288
|
+
return mode;
|
|
289
|
+
}
|
|
201
290
|
const prompt = readline.createInterface({ input, output });
|
|
202
291
|
try {
|
|
203
292
|
return await promptForMode(prompt);
|
|
@@ -207,6 +296,15 @@ async function promptForModeWithInput() {
|
|
|
207
296
|
}
|
|
208
297
|
}
|
|
209
298
|
async function promptForInstall() {
|
|
299
|
+
if (isInteractiveTerminal()) {
|
|
300
|
+
const { install } = await inquirer.prompt({
|
|
301
|
+
type: "confirm",
|
|
302
|
+
name: "install",
|
|
303
|
+
message: "Install selected plugin packages now?",
|
|
304
|
+
default: true,
|
|
305
|
+
});
|
|
306
|
+
return install;
|
|
307
|
+
}
|
|
210
308
|
const prompt = readline.createInterface({ input, output });
|
|
211
309
|
try {
|
|
212
310
|
const answer = await prompt.question("Install selected plugin packages now? (Y/n): ");
|
|
@@ -231,6 +329,35 @@ function installPluginDependencies(packages) {
|
|
|
231
329
|
throw new Error(`Failed to install plugin packages with ${packageManager}.`);
|
|
232
330
|
}
|
|
233
331
|
}
|
|
332
|
+
function printNextSteps(mode, configPath, outputPath) {
|
|
333
|
+
console.log("\nNext steps:");
|
|
334
|
+
const packageManager = detectPackageManager();
|
|
335
|
+
if (mode === "cli") {
|
|
336
|
+
const defaultConfigPath = path.resolve(process.cwd(), "cem-generator.config.mjs");
|
|
337
|
+
const configArgument = configPath === defaultConfigPath ? "" : ` --config ${toCommandPath(configPath)}`;
|
|
338
|
+
printPackageScript(`cem generate${configArgument}`, packageManager);
|
|
339
|
+
}
|
|
340
|
+
else {
|
|
341
|
+
printPackageScript(`tsx ${toCommandPath(outputPath)}`, packageManager);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
function printPackageScript(command, packageManager) {
|
|
345
|
+
const runCommand = packageManager === "npm"
|
|
346
|
+
? "npm run cem"
|
|
347
|
+
: packageManager === "yarn"
|
|
348
|
+
? "yarn cem"
|
|
349
|
+
: packageManager === "bun"
|
|
350
|
+
? "bun run cem"
|
|
351
|
+
: "pnpm run cem";
|
|
352
|
+
console.log(" Add this script to package.json:");
|
|
353
|
+
console.log(` \"cem\": \"${command}\"`);
|
|
354
|
+
console.log(` Run it with: ${runCommand}`);
|
|
355
|
+
}
|
|
356
|
+
function toCommandPath(filePath) {
|
|
357
|
+
const relativePath = path.relative(process.cwd(), filePath).replaceAll(path.sep, "/");
|
|
358
|
+
const normalizedPath = relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
|
|
359
|
+
return /\s/.test(normalizedPath) ? JSON.stringify(normalizedPath) : normalizedPath;
|
|
360
|
+
}
|
|
234
361
|
function detectPackageManager() {
|
|
235
362
|
if (fs.existsSync(path.resolve("pnpm-lock.yaml")))
|
|
236
363
|
return "pnpm";
|
|
@@ -248,41 +375,135 @@ function validatePluginNames(names) {
|
|
|
248
375
|
}
|
|
249
376
|
return [...new Set(names)];
|
|
250
377
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
378
|
+
function validateIntegrationNames(names) {
|
|
379
|
+
const validNames = new Set(INTEGRATION_CHOICES.map((integration) => integration.name));
|
|
380
|
+
const invalidNames = names.filter((name) => !validNames.has(name));
|
|
381
|
+
if (invalidNames.length > 0) {
|
|
382
|
+
throw new Error(`Unknown integration(s): ${invalidNames.join(", ")}. Choose from: ${[...validNames].join(", ")}`);
|
|
383
|
+
}
|
|
384
|
+
return [...new Set(names)];
|
|
385
|
+
}
|
|
386
|
+
async function promptForPluginsAndIntegrations() {
|
|
387
|
+
if (isInteractiveTerminal()) {
|
|
388
|
+
const { plugin, integrations } = await inquirer.prompt([
|
|
389
|
+
{
|
|
390
|
+
type: "select",
|
|
391
|
+
name: "plugin",
|
|
392
|
+
message: "Which framework plugins should be included?",
|
|
393
|
+
choices: PLUGIN_CHOICES.map((plugin) => ({ name: plugin.name, value: plugin.name })),
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
type: "checkbox",
|
|
397
|
+
name: "integrations",
|
|
398
|
+
message: "Which project integrations should be included?",
|
|
399
|
+
choices: INTEGRATION_CHOICES.map((integration) => ({
|
|
400
|
+
name: integration.name,
|
|
401
|
+
value: integration.name,
|
|
402
|
+
})),
|
|
403
|
+
},
|
|
404
|
+
]);
|
|
405
|
+
return { selectedNames: [plugin], selectedIntegrationNames: integrations };
|
|
406
|
+
}
|
|
407
|
+
const prompt = readline.createInterface({ input, output });
|
|
408
|
+
const lines = prompt[Symbol.asyncIterator]();
|
|
409
|
+
try {
|
|
410
|
+
console.log("Which framework plugins should be included?");
|
|
411
|
+
PLUGIN_CHOICES.forEach((plugin, index) => console.log(` ${index + 1}. ${plugin.name}`));
|
|
412
|
+
console.log("Enter numbers separated by commas, or press Enter for vanilla only.");
|
|
413
|
+
output.write("Plugins: ");
|
|
414
|
+
const pluginsLine = await lines.next();
|
|
415
|
+
if (pluginsLine.done)
|
|
416
|
+
throw new Error("No plugin selection provided.");
|
|
417
|
+
console.log("Which project integrations should be included? (multi-select)");
|
|
418
|
+
INTEGRATION_CHOICES.forEach((integration, index) => console.log(` ${index + 1}. ${integration.name}`));
|
|
419
|
+
console.log("Enter numbers separated by commas, or press Enter for no integrations.");
|
|
420
|
+
output.write("Integrations: ");
|
|
421
|
+
const integrationsLine = await lines.next();
|
|
422
|
+
if (integrationsLine.done)
|
|
423
|
+
throw new Error("No integration selection provided.");
|
|
424
|
+
return {
|
|
425
|
+
selectedNames: parsePluginSelection(pluginsLine.value),
|
|
426
|
+
selectedIntegrationNames: parseIntegrationSelection(integrationsLine.value),
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
finally {
|
|
430
|
+
prompt.close();
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
async function promptForInteractiveSelections() {
|
|
434
|
+
const { mode, plugin, integrations } = await inquirer.prompt([
|
|
435
|
+
{
|
|
436
|
+
type: "select",
|
|
437
|
+
name: "mode",
|
|
438
|
+
message: "How will you run the generator?",
|
|
439
|
+
choices: [
|
|
440
|
+
{ name: "CLI", value: "cli" },
|
|
441
|
+
{ name: "Code", value: "code" },
|
|
442
|
+
],
|
|
443
|
+
},
|
|
444
|
+
{
|
|
445
|
+
type: "select",
|
|
446
|
+
name: "plugin",
|
|
447
|
+
message: "Which framework plugins should be included?",
|
|
448
|
+
choices: PLUGIN_CHOICES.map((plugin) => ({ name: plugin.name, value: plugin.name })),
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
type: "checkbox",
|
|
452
|
+
name: "integrations",
|
|
453
|
+
message: "Which project integrations should be included?",
|
|
454
|
+
choices: INTEGRATION_CHOICES.map((integration) => ({
|
|
455
|
+
name: integration.name,
|
|
456
|
+
value: integration.name,
|
|
457
|
+
})),
|
|
458
|
+
},
|
|
459
|
+
]);
|
|
460
|
+
return { mode, selectedNames: [plugin], selectedIntegrationNames: integrations };
|
|
461
|
+
}
|
|
462
|
+
function isInteractiveTerminal() {
|
|
463
|
+
return Boolean(input.isTTY && output.isTTY);
|
|
259
464
|
}
|
|
260
465
|
function parsePluginSelection(answer) {
|
|
466
|
+
return parseSelection(answer, PLUGIN_CHOICES, "plugin");
|
|
467
|
+
}
|
|
468
|
+
function parseIntegrationSelection(answer) {
|
|
469
|
+
return validateIntegrationNames(parseSelection(answer, INTEGRATION_CHOICES, "integration"));
|
|
470
|
+
}
|
|
471
|
+
function parseSelection(answer, choices, label) {
|
|
261
472
|
const values = answer
|
|
262
473
|
.split(",")
|
|
263
474
|
.map((value) => value.trim())
|
|
264
475
|
.filter(Boolean);
|
|
265
476
|
const names = values.map((value) => {
|
|
266
477
|
const index = Number(value) - 1;
|
|
267
|
-
if (!Number.isInteger(index) || index < 0 || index >=
|
|
268
|
-
throw new Error(`Invalid
|
|
478
|
+
if (!Number.isInteger(index) || index < 0 || index >= choices.length) {
|
|
479
|
+
throw new Error(`Invalid ${label} selection: ${value}`);
|
|
269
480
|
}
|
|
270
|
-
return
|
|
481
|
+
return choices[index].name;
|
|
271
482
|
});
|
|
272
|
-
return
|
|
483
|
+
return names;
|
|
273
484
|
}
|
|
274
|
-
function createConfigSource(plugins) {
|
|
275
|
-
const
|
|
276
|
-
const
|
|
485
|
+
function createConfigSource(plugins, integrations = [], include, exclude = DEFAULT_SOURCE_EXCLUDE) {
|
|
486
|
+
const choices = [...plugins, ...integrations];
|
|
487
|
+
const imports = choices.map((plugin) => `import { ${plugin.factory} } from "${plugin.packageName}";`);
|
|
488
|
+
const factories = choices.map((plugin) => ` ${plugin.factory}(${getPluginOptionsSource(plugin)}),`);
|
|
277
489
|
return [
|
|
278
490
|
...imports,
|
|
279
491
|
imports.length ? "" : undefined,
|
|
280
492
|
"export default {",
|
|
493
|
+
...(include ? [` include: ${JSON.stringify(include)},`] : []),
|
|
494
|
+
` exclude: ${JSON.stringify(exclude)},`,
|
|
281
495
|
...(factories.length ? [" plugins: [", ...factories, " ],"] : []),
|
|
282
496
|
"};",
|
|
283
497
|
"",
|
|
284
498
|
].filter((line) => line !== undefined).join("\n");
|
|
285
499
|
}
|
|
500
|
+
function getPluginOptionsSource(plugin) {
|
|
501
|
+
if (!("options" in plugin) || !plugin.options)
|
|
502
|
+
return "";
|
|
503
|
+
return `{ ${Object.entries(plugin.options)
|
|
504
|
+
.map(([key, value]) => `${key}: ${JSON.stringify(value)}`)
|
|
505
|
+
.join(", ")} }`;
|
|
506
|
+
}
|
|
286
507
|
function createCodeSource(configPath, outputPath) {
|
|
287
508
|
let configImport = path.relative(path.dirname(outputPath), configPath).replaceAll(path.sep, "/");
|
|
288
509
|
if (!configImport.startsWith("."))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wc-toolkit/cem-generator-cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "CLI for generating Custom Elements Manifests.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -34,8 +34,9 @@
|
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"commander": "^12.1.0",
|
|
36
36
|
"custom-elements-manifest": "^2.1.0",
|
|
37
|
-
"
|
|
38
|
-
"@wc-toolkit/cem-generator
|
|
37
|
+
"inquirer": "^14.2.2",
|
|
38
|
+
"@wc-toolkit/cem-generator": "0.1.2",
|
|
39
|
+
"@wc-toolkit/cem-generator-utils": "0.1.1"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
42
|
"@types/node": "^26.4.1",
|