@cordy/electro-cli 1.2.19 → 1.2.20
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/dist/index.mjs +102 -62
- package/package.json +8 -7
package/dist/index.mjs
CHANGED
|
@@ -491,7 +491,36 @@ const cac = (name = "") => new CAC(name);
|
|
|
491
491
|
|
|
492
492
|
//#endregion
|
|
493
493
|
//#region package.json
|
|
494
|
-
var version$1 = "1.2.
|
|
494
|
+
var version$1 = "1.2.20";
|
|
495
|
+
|
|
496
|
+
//#endregion
|
|
497
|
+
//#region src/dev/bridge-types.ts
|
|
498
|
+
const GENERATED_BRIDGE_DIRS = ["views", "windows"];
|
|
499
|
+
const VIEW_BRIDGE_MODULE_FILE = "bridge.gen.ts";
|
|
500
|
+
/**
|
|
501
|
+
* Resolve generated bridge declaration file for a view.
|
|
502
|
+
* Supports both historical `generated/windows/*` and current `generated/views/*`.
|
|
503
|
+
*/
|
|
504
|
+
function findBridgeTypesForView(files, viewName) {
|
|
505
|
+
const byPath = files.find((f) => f.path === `generated/views/${viewName}.bridge.d.ts`) ?? files.find((f) => f.path === `generated/windows/${viewName}.bridge.d.ts`);
|
|
506
|
+
if (byPath) return byPath;
|
|
507
|
+
return files.find((f) => f.path.endsWith(`/${viewName}.bridge.d.ts`)) ?? null;
|
|
508
|
+
}
|
|
509
|
+
/** Target location for per-view bridge types next to the config file. */
|
|
510
|
+
function resolveViewBridgePath(view) {
|
|
511
|
+
if (!view.__source) return null;
|
|
512
|
+
return resolve(dirname(view.__source), VIEW_BRIDGE_MODULE_FILE);
|
|
513
|
+
}
|
|
514
|
+
/** Convert generated bridge declaration content into runtime-accessible bridge module. */
|
|
515
|
+
function createViewBridgeModuleContent(bridgeTypesContent) {
|
|
516
|
+
return `${bridgeTypesContent.trimEnd()}\n\nexport const electro = window.electro as ElectroBridge;\n`;
|
|
517
|
+
}
|
|
518
|
+
function isGeneratedBridgeTypesPath(path) {
|
|
519
|
+
return GENERATED_BRIDGE_DIRS.some((dir) => path.startsWith(`generated/${dir}/`) && path.endsWith(".bridge.d.ts"));
|
|
520
|
+
}
|
|
521
|
+
function generatedBridgeTypesPaths(viewName) {
|
|
522
|
+
return GENERATED_BRIDGE_DIRS.map((dir) => `generated/${dir}/${viewName}.bridge.d.ts`);
|
|
523
|
+
}
|
|
495
524
|
|
|
496
525
|
//#endregion
|
|
497
526
|
//#region src/dev/logger.ts
|
|
@@ -587,29 +616,47 @@ function footer(message, url) {
|
|
|
587
616
|
function toProjectRelative(root, absolutePath) {
|
|
588
617
|
return relative(root, absolutePath) || ".";
|
|
589
618
|
}
|
|
590
|
-
function
|
|
619
|
+
function logSession(meta) {
|
|
591
620
|
if (levels[currentLevel] > levels.info) return;
|
|
592
621
|
const isBuild = meta.mode === "build";
|
|
593
622
|
const projectName = basename(meta.root);
|
|
594
|
-
const
|
|
623
|
+
const runtimeEntry = toProjectRelative(meta.root, meta.runtime);
|
|
595
624
|
const preloadEntry = meta.preload ? toProjectRelative(meta.root, meta.preload) : `${dim$1}(none)${reset$1}`;
|
|
596
|
-
const
|
|
625
|
+
const firstView = meta.views?.[0] ?? null;
|
|
626
|
+
const viewEntry = firstView ? toProjectRelative(meta.root, firstView.entry) : `${dim$1}(none)${reset$1}`;
|
|
597
627
|
const command = isBuild ? "build" : "dev";
|
|
598
628
|
console.log(`\n${bold}${yellow$1}⚡ electro ${command}${reset$1} → ${cyan}${projectName}${reset$1}\n`);
|
|
599
|
-
const
|
|
629
|
+
const runtimeMode = isBuild ? "build" : "watch";
|
|
600
630
|
const preloadMode = isBuild ? "build" : "watch";
|
|
601
|
-
const
|
|
602
|
-
const
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
631
|
+
const viewsMode = isBuild ? "build" : "dev server";
|
|
632
|
+
const rows = [
|
|
633
|
+
{
|
|
634
|
+
scope: `${cyan}runtime${reset$1}`,
|
|
635
|
+
entry: runtimeEntry,
|
|
636
|
+
mode: `${dim$1}${runtimeMode}${reset$1}`
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
scope: `${yellow$1}preload${reset$1}`,
|
|
640
|
+
entry: preloadEntry,
|
|
641
|
+
mode: `${dim$1}${preloadMode}${reset$1}`
|
|
642
|
+
},
|
|
643
|
+
{
|
|
644
|
+
scope: `${green}view${reset$1}`,
|
|
645
|
+
entry: viewEntry,
|
|
646
|
+
mode: `${dim$1}${viewsMode}${reset$1}`
|
|
647
|
+
}
|
|
648
|
+
];
|
|
649
|
+
const scopeWidth = Math.max(5, ...rows.map((r) => visibleLength(r.scope))) + 2;
|
|
650
|
+
const entryWidth = Math.max(5, ...rows.map((r) => visibleLength(r.entry))) + 2;
|
|
651
|
+
console.log(` ${dim$1}${padVisible("Scope", scopeWidth)}${padVisible("Entry", entryWidth)}Mode${reset$1}`);
|
|
652
|
+
for (const row of rows) console.log(` ${padVisible(row.scope, scopeWidth)}${padVisible(row.entry, entryWidth)}${row.mode}`);
|
|
653
|
+
if (meta.views && meta.views.length > 0) {
|
|
608
654
|
console.log("");
|
|
609
|
-
console.log(` ${dim$1}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
655
|
+
console.log(` ${dim$1}Views${reset$1} ${meta.views.length} configured`);
|
|
656
|
+
const viewNameWidth = Math.max(4, ...meta.views.map((v) => v.name.length)) + 2;
|
|
657
|
+
for (const view of meta.views) {
|
|
658
|
+
const entry = toProjectRelative(meta.root, view.entry);
|
|
659
|
+
console.log(` ${padVisible(view.name, viewNameWidth)}${dim$1}${entry}${reset$1}`);
|
|
613
660
|
}
|
|
614
661
|
}
|
|
615
662
|
console.log("");
|
|
@@ -619,6 +666,13 @@ const VITE_TAG_RE = new RegExp(String.raw`(?:\x1b\[[0-9;]*m)*\[(vite(?:-plugin-[
|
|
|
619
666
|
function retagMessage(msg) {
|
|
620
667
|
return msg.replace(VITE_TAG_RE, `[${bold}${yellow$1}electro${reset$1}]`);
|
|
621
668
|
}
|
|
669
|
+
function visibleLength(value) {
|
|
670
|
+
return value.replace(ANSI_RE, "").length;
|
|
671
|
+
}
|
|
672
|
+
function padVisible(value, width) {
|
|
673
|
+
const len = visibleLength(value);
|
|
674
|
+
return value + " ".repeat(Math.max(0, width - len));
|
|
675
|
+
}
|
|
622
676
|
/**
|
|
623
677
|
* Patch a Vite logger to rebrand `[vite]` → `[electro]`,
|
|
624
678
|
* suppress startup noise ("ready in", "➜"), and extract
|
|
@@ -788,6 +842,10 @@ async function loadConfig(configPath) {
|
|
|
788
842
|
const config = (await import(absolutePath)).default;
|
|
789
843
|
if (!config) throw new Error(`${configPath} must have a default export`);
|
|
790
844
|
if (!config.runtime) throw new Error(`${configPath} must define a runtime via defineRuntime()`);
|
|
845
|
+
if (!config.codegen || !config.codegen?.scanDir) config.codegen = { scanDir: resolve(root, "src") };
|
|
846
|
+
if (config.views && config.views?.length > 0) {
|
|
847
|
+
for (const view of config.views) if (!view.entry) view.entry = "./index.html";
|
|
848
|
+
}
|
|
791
849
|
validateConfig(config);
|
|
792
850
|
return {
|
|
793
851
|
config,
|
|
@@ -2145,10 +2203,7 @@ function resolveSourcemap(mode) {
|
|
|
2145
2203
|
}
|
|
2146
2204
|
function createRendererConfig(opts) {
|
|
2147
2205
|
const input = {};
|
|
2148
|
-
for (const view of opts.views)
|
|
2149
|
-
const sourceDir = dirname(view.__source);
|
|
2150
|
-
input[view.name] = resolve(sourceDir, view.entry);
|
|
2151
|
-
}
|
|
2206
|
+
for (const view of opts.views) input[view.name] = resolve(view.root, view.entry);
|
|
2152
2207
|
const isBuild = !!opts.outDir;
|
|
2153
2208
|
const config = {
|
|
2154
2209
|
configFile: false,
|
|
@@ -2201,35 +2256,6 @@ function deduplicatePlugins(plugins) {
|
|
|
2201
2256
|
return result;
|
|
2202
2257
|
}
|
|
2203
2258
|
|
|
2204
|
-
//#endregion
|
|
2205
|
-
//#region src/dev/bridge-types.ts
|
|
2206
|
-
const GENERATED_BRIDGE_DIRS = ["views", "windows"];
|
|
2207
|
-
const VIEW_BRIDGE_MODULE_FILE = "bridge.gen.ts";
|
|
2208
|
-
/**
|
|
2209
|
-
* Resolve generated bridge declaration file for a view.
|
|
2210
|
-
* Supports both historical `generated/windows/*` and current `generated/views/*`.
|
|
2211
|
-
*/
|
|
2212
|
-
function findBridgeTypesForView(files, viewName) {
|
|
2213
|
-
const byPath = files.find((f) => f.path === `generated/views/${viewName}.bridge.d.ts`) ?? files.find((f) => f.path === `generated/windows/${viewName}.bridge.d.ts`);
|
|
2214
|
-
if (byPath) return byPath;
|
|
2215
|
-
return files.find((f) => f.path.endsWith(`/${viewName}.bridge.d.ts`)) ?? null;
|
|
2216
|
-
}
|
|
2217
|
-
/** Target location for per-view bridge types next to the config file. */
|
|
2218
|
-
function resolveViewBridgePath(view) {
|
|
2219
|
-
if (!view.__source) return null;
|
|
2220
|
-
return resolve(dirname(view.__source), VIEW_BRIDGE_MODULE_FILE);
|
|
2221
|
-
}
|
|
2222
|
-
/** Convert generated bridge declaration content into runtime-accessible bridge module. */
|
|
2223
|
-
function createViewBridgeModuleContent(bridgeTypesContent) {
|
|
2224
|
-
return `${bridgeTypesContent.trimEnd()}\n\nexport const electro = window.electro as ElectroBridge;\n`;
|
|
2225
|
-
}
|
|
2226
|
-
function isGeneratedBridgeTypesPath(path) {
|
|
2227
|
-
return GENERATED_BRIDGE_DIRS.some((dir) => path.startsWith(`generated/${dir}/`) && path.endsWith(".bridge.d.ts"));
|
|
2228
|
-
}
|
|
2229
|
-
function generatedBridgeTypesPaths(viewName) {
|
|
2230
|
-
return GENERATED_BRIDGE_DIRS.map((dir) => `generated/${dir}/${viewName}.bridge.d.ts`);
|
|
2231
|
-
}
|
|
2232
|
-
|
|
2233
2259
|
//#endregion
|
|
2234
2260
|
//#region src/plugins/utils.ts
|
|
2235
2261
|
/** Strip query and hash from a URL/path. */
|
|
@@ -2312,7 +2338,7 @@ async function findElectronBin(root) {
|
|
|
2312
2338
|
const electronDir = resolve(root, "node_modules/electron");
|
|
2313
2339
|
const pathTxtPath = resolve(electronDir, "path.txt");
|
|
2314
2340
|
if (await fileExists(pathTxtPath)) {
|
|
2315
|
-
const resolved = resolve(electronDir, (await readFile(pathTxtPath, "utf-8")).trim());
|
|
2341
|
+
const resolved = resolve(electronDir, "dist", (await readFile(pathTxtPath, "utf-8")).trim());
|
|
2316
2342
|
if (await fileExists(resolved)) return resolved;
|
|
2317
2343
|
}
|
|
2318
2344
|
} catch {}
|
|
@@ -2919,9 +2945,9 @@ async function build$1(options) {
|
|
|
2919
2945
|
const views = config.views ?? [];
|
|
2920
2946
|
const rendererViews = views.filter((v) => v.entry);
|
|
2921
2947
|
const srcDir = resolve(root, "src");
|
|
2922
|
-
|
|
2948
|
+
logSession({
|
|
2923
2949
|
root,
|
|
2924
|
-
|
|
2950
|
+
runtime: resolve(dirname(config.runtime.__source), config.runtime.entry),
|
|
2925
2951
|
preload: rendererViews.length > 0 ? resolve(codegenDir, "generated/preload") : null,
|
|
2926
2952
|
renderer: rendererViews.length > 0 ? resolve(root, dirname(relative(root, rendererViews[0].__source))) : null,
|
|
2927
2953
|
mode: "build",
|
|
@@ -3210,24 +3236,26 @@ var DevServer = class {
|
|
|
3210
3236
|
this.outputDir = this.outDirOverride ? resolve(this.root, this.outDirOverride) : resolve(this.root, ".electro");
|
|
3211
3237
|
this.nodeFormat = await resolveNodeOutputFormat(this.root);
|
|
3212
3238
|
this.configPaths.add(loaded.configPath);
|
|
3213
|
-
for (const view of this.config.views ?? [])
|
|
3239
|
+
for (const view of this.config.views ?? []) {
|
|
3240
|
+
view.root = dirname(view.__source);
|
|
3241
|
+
this.configPaths.add(view.__source);
|
|
3242
|
+
}
|
|
3214
3243
|
const views = this.config.views ?? [];
|
|
3215
3244
|
const rendererViews = views.filter((v) => v.entry);
|
|
3216
|
-
const
|
|
3217
|
-
|
|
3218
|
-
session({
|
|
3245
|
+
const runtimeEntry = resolve(dirname(this.config.runtime.__source), this.config.runtime.entry);
|
|
3246
|
+
logSession({
|
|
3219
3247
|
root: this.root,
|
|
3220
|
-
|
|
3248
|
+
runtime: runtimeEntry,
|
|
3221
3249
|
preload: rendererViews.length > 0 ? resolve(this.outputDir, "generated/preload") : null,
|
|
3222
|
-
|
|
3223
|
-
windows: rendererViews.map((w) => ({
|
|
3250
|
+
views: rendererViews.map((w) => ({
|
|
3224
3251
|
name: w.name,
|
|
3225
|
-
|
|
3252
|
+
root: w.root,
|
|
3253
|
+
entry: resolve(w.root, w.entry)
|
|
3226
3254
|
}))
|
|
3227
3255
|
});
|
|
3228
3256
|
const codegenTimer = startTimer();
|
|
3229
3257
|
try {
|
|
3230
|
-
await this.runCodegen(this.outputDir,
|
|
3258
|
+
await this.runCodegen(this.outputDir, this.config.codegen.scanDir);
|
|
3231
3259
|
step("codegen", codegenTimer());
|
|
3232
3260
|
} catch (err) {
|
|
3233
3261
|
stepFail("codegen", err instanceof Error ? err.message : String(err));
|
|
@@ -3667,7 +3695,19 @@ function sanitizeRuntimeWebPreferences(webPreferences) {
|
|
|
3667
3695
|
//#endregion
|
|
3668
3696
|
//#region src/commands/dev.ts
|
|
3669
3697
|
async function dev(options) {
|
|
3698
|
+
if (options.remoteDebuggingPort) process.env.REMOTE_DEBUGGING_PORT = options.remoteDebuggingPort;
|
|
3699
|
+
if (options.inspect) {
|
|
3700
|
+
const port = typeof options.inspect === "number" ? options.inspect : 9229;
|
|
3701
|
+
process.env.NODE_OPTIONS = `--inspect=${port}`;
|
|
3702
|
+
}
|
|
3703
|
+
if (options.inspectBrk) {
|
|
3704
|
+
const port = typeof options.inspectBrk === "number" ? options.inspectBrk : 9229;
|
|
3705
|
+
process.env.NODE_OPTIONS = `--inspect-brk=${port}`;
|
|
3706
|
+
}
|
|
3707
|
+
if (options.noSandbox) process.env.NO_SANDBOX = "1";
|
|
3708
|
+
if (options["--"]) process.env.ELECTRON_CLI_ARGS = JSON.stringify(options["--"]);
|
|
3670
3709
|
if (options.sourcemap) validateSourcemap(options.sourcemap);
|
|
3710
|
+
process.env.ELECTRO_MODE = "development";
|
|
3671
3711
|
const createServer = () => new DevServer(options.config, {
|
|
3672
3712
|
logLevel: options.logLevel,
|
|
3673
3713
|
clearScreen: options.clearScreen,
|
|
@@ -3798,7 +3838,7 @@ const cli = cac("electro");
|
|
|
3798
3838
|
cli.command("generate", "Generate preload scripts, bridge types, and context types").option("-c, --config <path>", "Path to electro.config.ts", { default: "electro.config.ts" }).option("-o, --output <dir>", "Output directory", { default: ".electro" }).action(generate$1);
|
|
3799
3839
|
cli.command("build", "Build for production").option("-c, --config <path>", "Path to electro.config.ts", { default: "electro.config.ts" }).option("-o, --outDir <dir>", "Output directory", { default: "dist" }).option("--sourcemap <mode>", "Sourcemap mode (linked | inline | external | none)").option("--minify", "Minify output (default: true)", { default: true }).option("--no-minify", "Disable minification").option("--bytecode", "Compile main/preload to V8 bytecode for source protection").option("-l, --logLevel <level>", "Log level (info | warn | error | silent)").action(build$1);
|
|
3800
3840
|
cli.command("preview", "Build and preview in Electron").option("-c, --config <path>", "Path to electro.config.ts", { default: "electro.config.ts" }).option("-o, --outDir <dir>", "Output directory", { default: "dist" }).option("--sourcemap <mode>", "Sourcemap mode (linked | inline | external | none)").option("--minify", "Minify output (default: true)", { default: true }).option("--no-minify", "Disable minification").option("--bytecode", "Compile main/preload to V8 bytecode for source protection").option("--skip-build", "Skip build step and launch from existing output").option("-l, --logLevel <level>", "Log level (info | warn | error | silent)").action(preview);
|
|
3801
|
-
cli.command("dev", "Start development server with Electron").option("
|
|
3841
|
+
cli.command("dev", "Start development server with Electron").option("--config <path>", "Path to electro.config.ts", { default: "electro.config.ts" }).option("--clearScreen", "Clear screen on rebuild", { default: true }).option("--logLevel <level>", "Log level (info | warn | error | silent)").option("--sourcemap <mode>", "Sourcemap mode (linked | inline | external | none)").option("--outDir <dir>", "Output directory override (default: .electro)").option("--inspect [port]", `[boolean | number] enable V8 inspector on the specified port`).option("--inspectBrk [port]", `[boolean | number] enable V8 inspector on the specified port`).option("--remoteDebuggingPort <port>", `[string] port for remote debugging`).option("--noSandbox", `[boolean] forces renderer process to run un-sandboxed`).option("--rendererOnly", `[boolean] only dev server for the renderer`).action(dev);
|
|
3802
3842
|
cli.help();
|
|
3803
3843
|
cli.version(version$1);
|
|
3804
3844
|
cli.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cordy/electro-cli",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.20",
|
|
4
4
|
"description": "CLI for @cordy/electro — dev server, build, and code generation commands",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -30,10 +30,11 @@
|
|
|
30
30
|
"main": "./dist/index.mjs",
|
|
31
31
|
"types": "./dist/index.d.mts",
|
|
32
32
|
"files": [
|
|
33
|
+
"bin",
|
|
33
34
|
"dist"
|
|
34
35
|
],
|
|
35
36
|
"bin": {
|
|
36
|
-
"electro": "
|
|
37
|
+
"electro": "bin/cli.js"
|
|
37
38
|
},
|
|
38
39
|
"exports": {
|
|
39
40
|
".": {
|
|
@@ -48,19 +49,19 @@
|
|
|
48
49
|
},
|
|
49
50
|
"peerDependencies": {
|
|
50
51
|
"@cordy/electro": "1.2.19",
|
|
51
|
-
"electron": ">=40.
|
|
52
|
+
"electron": ">=40.6.0",
|
|
52
53
|
"vite": ">=8.0.0"
|
|
53
54
|
},
|
|
54
55
|
"dependencies": {
|
|
55
56
|
"@cordy/electro-generator": "1.2.19"
|
|
56
57
|
},
|
|
57
58
|
"devDependencies": {
|
|
58
|
-
"@cordy/electro": "1.2.
|
|
59
|
-
"@types/node": "^25.
|
|
59
|
+
"@cordy/electro": "1.2.20",
|
|
60
|
+
"@types/node": "^25.3.0",
|
|
60
61
|
"cac": "^6.7.14",
|
|
61
|
-
"electron": "^40.
|
|
62
|
+
"electron": "^40.6.0",
|
|
62
63
|
"magic-string": "^0.30.21",
|
|
63
64
|
"tsdown": "^0.20.3",
|
|
64
|
-
"vite": "^8.0.0-beta.
|
|
65
|
+
"vite": "^8.0.0-beta.15"
|
|
65
66
|
}
|
|
66
67
|
}
|