@cordy/electro-cli 1.0.9 → 1.1.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/dist/index.mjs +74 -70
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -490,7 +490,7 @@ const cac = (name = "") => new CAC(name);
|
|
|
490
490
|
|
|
491
491
|
//#endregion
|
|
492
492
|
//#region package.json
|
|
493
|
-
var version$1 = "1.
|
|
493
|
+
var version$1 = "1.1.1";
|
|
494
494
|
|
|
495
495
|
//#endregion
|
|
496
496
|
//#region src/dev/logger.ts
|
|
@@ -714,23 +714,23 @@ function validateConfig(config) {
|
|
|
714
714
|
error(`Main entry not found: ${mainEntry}`);
|
|
715
715
|
process.exit(1);
|
|
716
716
|
}
|
|
717
|
-
const
|
|
717
|
+
const views = config.views ?? [];
|
|
718
718
|
const names = /* @__PURE__ */ new Set();
|
|
719
|
-
for (const
|
|
720
|
-
if (names.has(
|
|
721
|
-
error(`Duplicate
|
|
719
|
+
for (const view of views) {
|
|
720
|
+
if (names.has(view.name)) {
|
|
721
|
+
error(`Duplicate view name "${view.name}". View names must be unique.`);
|
|
722
722
|
process.exit(1);
|
|
723
723
|
}
|
|
724
|
-
names.add(
|
|
724
|
+
names.add(view.name);
|
|
725
725
|
}
|
|
726
|
-
for (const
|
|
727
|
-
const
|
|
728
|
-
if (!existsSync(
|
|
729
|
-
error(`
|
|
726
|
+
for (const view of views) {
|
|
727
|
+
const viewEntry = resolve(dirname(view.__source), view.entry);
|
|
728
|
+
if (!existsSync(viewEntry)) {
|
|
729
|
+
error(`View "${view.name}" entry not found: ${viewEntry}`);
|
|
730
730
|
process.exit(1);
|
|
731
731
|
}
|
|
732
732
|
}
|
|
733
|
-
for (const
|
|
733
|
+
for (const view of views) if (view.features && view.features.length === 0) warn(`View "${view.name}" has an empty features array — it won't have access to any services.`);
|
|
734
734
|
}
|
|
735
735
|
/** Validate --sourcemap CLI value. Warns on unrecognized values. */
|
|
736
736
|
function validateSourcemap(value) {
|
|
@@ -905,9 +905,9 @@ function resolveSourcemap(mode) {
|
|
|
905
905
|
}
|
|
906
906
|
function createRendererConfig(opts) {
|
|
907
907
|
const input = {};
|
|
908
|
-
for (const
|
|
909
|
-
const sourceDir = dirname(
|
|
910
|
-
input[
|
|
908
|
+
for (const view of opts.views) {
|
|
909
|
+
const sourceDir = dirname(view.__source);
|
|
910
|
+
input[view.name] = resolve(sourceDir, view.entry);
|
|
911
911
|
}
|
|
912
912
|
const isBuild = !!opts.outDir;
|
|
913
913
|
const config = {
|
|
@@ -934,10 +934,32 @@ function createRendererConfig(opts) {
|
|
|
934
934
|
if (opts.userViteConfigs?.length) {
|
|
935
935
|
let merged = config;
|
|
936
936
|
for (const userConfig of opts.userViteConfigs) merged = mergeConfig(merged, userConfig);
|
|
937
|
+
merged.plugins = deduplicatePlugins(merged.plugins);
|
|
937
938
|
return merged;
|
|
938
939
|
}
|
|
939
940
|
return config;
|
|
940
941
|
}
|
|
942
|
+
/**
|
|
943
|
+
* Deduplicate plugins by name — keeps the first occurrence of each named plugin.
|
|
944
|
+
* This allows multiple views to declare the same plugins (e.g. react()) without
|
|
945
|
+
* causing duplicate injection errors when configs are merged.
|
|
946
|
+
*/
|
|
947
|
+
function deduplicatePlugins(plugins) {
|
|
948
|
+
if (!plugins) return [];
|
|
949
|
+
const seen = /* @__PURE__ */ new Set();
|
|
950
|
+
const result = [];
|
|
951
|
+
for (const plugin of plugins.flat(Infinity)) {
|
|
952
|
+
const name = plugin?.name;
|
|
953
|
+
if (!name) {
|
|
954
|
+
result.push(plugin);
|
|
955
|
+
continue;
|
|
956
|
+
}
|
|
957
|
+
if (seen.has(name)) continue;
|
|
958
|
+
seen.add(name);
|
|
959
|
+
result.push(plugin);
|
|
960
|
+
}
|
|
961
|
+
return result;
|
|
962
|
+
}
|
|
941
963
|
|
|
942
964
|
//#endregion
|
|
943
965
|
//#region ../../node_modules/.bun/@jridgewell+sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
|
|
@@ -2636,15 +2658,15 @@ async function build$1(options) {
|
|
|
2636
2658
|
const root = loaded.root;
|
|
2637
2659
|
const outDir = resolve(root, options.outDir);
|
|
2638
2660
|
const codegenDir = resolve(root, ".electro");
|
|
2639
|
-
const
|
|
2661
|
+
const views = config.views ?? [];
|
|
2640
2662
|
const srcDir = resolve(root, "src");
|
|
2641
2663
|
session({
|
|
2642
2664
|
root,
|
|
2643
2665
|
main: resolve(dirname(config.runtime.__source), config.runtime.entry),
|
|
2644
|
-
preload:
|
|
2645
|
-
renderer:
|
|
2666
|
+
preload: views.length > 0 ? resolve(codegenDir, "generated/preload") : null,
|
|
2667
|
+
renderer: views.length > 0 ? resolve(root, dirname(relative(root, views[0].__source))) : null,
|
|
2646
2668
|
mode: "build",
|
|
2647
|
-
windows:
|
|
2669
|
+
windows: views.map((w) => ({
|
|
2648
2670
|
name: w.name,
|
|
2649
2671
|
entry: resolve(dirname(w.__source), w.entry)
|
|
2650
2672
|
}))
|
|
@@ -2653,7 +2675,7 @@ async function build$1(options) {
|
|
|
2653
2675
|
try {
|
|
2654
2676
|
const { files, envTypes } = generate({
|
|
2655
2677
|
scanResult: await scan(srcDir),
|
|
2656
|
-
|
|
2678
|
+
views,
|
|
2657
2679
|
outputDir: codegenDir,
|
|
2658
2680
|
srcDir
|
|
2659
2681
|
});
|
|
@@ -2688,7 +2710,7 @@ async function build$1(options) {
|
|
|
2688
2710
|
stepFail("main", err instanceof Error ? err.message : String(err));
|
|
2689
2711
|
process.exit(1);
|
|
2690
2712
|
}
|
|
2691
|
-
if (
|
|
2713
|
+
if (views.length > 0) try {
|
|
2692
2714
|
buildScope("preload");
|
|
2693
2715
|
await buildPreload({
|
|
2694
2716
|
config,
|
|
@@ -2704,12 +2726,12 @@ async function build$1(options) {
|
|
|
2704
2726
|
stepFail("preload", err instanceof Error ? err.message : String(err));
|
|
2705
2727
|
process.exit(1);
|
|
2706
2728
|
}
|
|
2707
|
-
if (
|
|
2729
|
+
if (views.length > 0) try {
|
|
2708
2730
|
buildScope("renderer");
|
|
2709
|
-
const userViteConfigs =
|
|
2731
|
+
const userViteConfigs = views.filter((w) => w.vite).map((w) => w.vite);
|
|
2710
2732
|
await build(createRendererConfig({
|
|
2711
2733
|
root,
|
|
2712
|
-
|
|
2734
|
+
views,
|
|
2713
2735
|
userViteConfigs: userViteConfigs.length > 0 ? userViteConfigs : void 0,
|
|
2714
2736
|
logLevel: "info",
|
|
2715
2737
|
customLogger: logger,
|
|
@@ -2717,7 +2739,7 @@ async function build$1(options) {
|
|
|
2717
2739
|
minify: options.minify,
|
|
2718
2740
|
sourcemap: options.sourcemap
|
|
2719
2741
|
}));
|
|
2720
|
-
await flattenRendererOutput(resolve(outDir, "renderer"),
|
|
2742
|
+
await flattenRendererOutput(resolve(outDir, "renderer"), views, root);
|
|
2721
2743
|
} catch (err) {
|
|
2722
2744
|
stepFail("renderer", err instanceof Error ? err.message : String(err));
|
|
2723
2745
|
process.exit(1);
|
|
@@ -2727,14 +2749,6 @@ async function build$1(options) {
|
|
|
2727
2749
|
async function buildMain(args) {
|
|
2728
2750
|
const runtimeEntry = args.config.runtime.entry;
|
|
2729
2751
|
const entry = resolve(dirname(args.config.runtime.__source), runtimeEntry);
|
|
2730
|
-
const windowDefs = (args.config.windows ?? []).map((w) => ({
|
|
2731
|
-
name: w.name,
|
|
2732
|
-
type: w.type,
|
|
2733
|
-
lifecycle: w.lifecycle,
|
|
2734
|
-
autoShow: w.autoShow,
|
|
2735
|
-
behavior: w.behavior,
|
|
2736
|
-
window: w.window
|
|
2737
|
-
}));
|
|
2738
2752
|
await build(createNodeConfig({
|
|
2739
2753
|
scope: "main",
|
|
2740
2754
|
root: args.root,
|
|
@@ -2751,14 +2765,13 @@ async function buildMain(args) {
|
|
|
2751
2765
|
userViteConfig: args.config.runtime.vite,
|
|
2752
2766
|
sourcemap: args.sourcemap,
|
|
2753
2767
|
customLogger: args.logger,
|
|
2754
|
-
logLevel: "info"
|
|
2755
|
-
define: { __ELECTRO_WINDOW_DEFINITIONS__: JSON.stringify(windowDefs) }
|
|
2768
|
+
logLevel: "info"
|
|
2756
2769
|
}));
|
|
2757
2770
|
}
|
|
2758
2771
|
async function buildPreload(args) {
|
|
2759
|
-
const
|
|
2772
|
+
const views = args.config.views ?? [];
|
|
2760
2773
|
const input = {};
|
|
2761
|
-
for (const
|
|
2774
|
+
for (const view of views) input[view.name] = resolve(args.codegenDir, `generated/preload/${view.name}.gen.ts`);
|
|
2762
2775
|
const firstEntry = Object.values(input)[0];
|
|
2763
2776
|
const preloadOutDir = resolve(args.outDir, "preload");
|
|
2764
2777
|
const preloadPlugins = [
|
|
@@ -2809,12 +2822,12 @@ async function buildPreload(args) {
|
|
|
2809
2822
|
* (e.g., `src/windows/main/index.html`) to `{name}/index.html`.
|
|
2810
2823
|
* Adjusts relative asset references to match the new depth.
|
|
2811
2824
|
*/
|
|
2812
|
-
async function flattenRendererOutput(rendererDir,
|
|
2825
|
+
async function flattenRendererOutput(rendererDir, views, root) {
|
|
2813
2826
|
const dirsToClean = /* @__PURE__ */ new Set();
|
|
2814
|
-
for (const
|
|
2815
|
-
const relPath = relative(root, resolve(dirname(
|
|
2827
|
+
for (const view of views) {
|
|
2828
|
+
const relPath = relative(root, resolve(dirname(view.__source), view.entry));
|
|
2816
2829
|
const oldHtmlPath = resolve(rendererDir, relPath);
|
|
2817
|
-
const newHtmlPath = resolve(rendererDir,
|
|
2830
|
+
const newHtmlPath = resolve(rendererDir, view.name, "index.html");
|
|
2818
2831
|
if (oldHtmlPath === newHtmlPath) continue;
|
|
2819
2832
|
let html = await readFile(oldHtmlPath, "utf-8");
|
|
2820
2833
|
const depthDiff = relPath.split("/").length - 1 - 1;
|
|
@@ -2827,7 +2840,7 @@ async function flattenRendererOutput(rendererDir, windows, root) {
|
|
|
2827
2840
|
await writeFile(newHtmlPath, html);
|
|
2828
2841
|
await unlink(oldHtmlPath);
|
|
2829
2842
|
const topDir = relPath.split("/")[0];
|
|
2830
|
-
if (topDir !==
|
|
2843
|
+
if (topDir !== view.name) dirsToClean.add(resolve(rendererDir, topDir));
|
|
2831
2844
|
}
|
|
2832
2845
|
for (const dir of dirsToClean) await rm(dir, {
|
|
2833
2846
|
recursive: true,
|
|
@@ -2885,16 +2898,16 @@ var DevServer = class {
|
|
|
2885
2898
|
this.root = loaded.root;
|
|
2886
2899
|
this.outputDir = this.outDirOverride ? resolve(this.root, this.outDirOverride) : resolve(this.root, ".electro");
|
|
2887
2900
|
this.configPaths.add(loaded.configPath);
|
|
2888
|
-
for (const
|
|
2889
|
-
const
|
|
2901
|
+
for (const view of this.config.views ?? []) this.configPaths.add(view.__source);
|
|
2902
|
+
const views = this.config.views ?? [];
|
|
2890
2903
|
const srcDir = resolve(this.root, "src");
|
|
2891
2904
|
const mainEntry = resolve(dirname(this.config.runtime.__source), this.config.runtime.entry);
|
|
2892
2905
|
session({
|
|
2893
2906
|
root: this.root,
|
|
2894
2907
|
main: mainEntry,
|
|
2895
|
-
preload:
|
|
2896
|
-
renderer:
|
|
2897
|
-
windows:
|
|
2908
|
+
preload: views.length > 0 ? resolve(this.outputDir, "generated/preload") : null,
|
|
2909
|
+
renderer: views.length > 0 ? resolve(this.root, dirname(relative(this.root, views[0].__source))) : null,
|
|
2910
|
+
windows: views.map((w) => ({
|
|
2898
2911
|
name: w.name,
|
|
2899
2912
|
entry: resolve(dirname(w.__source), w.entry)
|
|
2900
2913
|
}))
|
|
@@ -2907,7 +2920,7 @@ var DevServer = class {
|
|
|
2907
2920
|
stepFail("codegen", err instanceof Error ? err.message : String(err));
|
|
2908
2921
|
throw err;
|
|
2909
2922
|
}
|
|
2910
|
-
if (
|
|
2923
|
+
if (views.length > 0) {
|
|
2911
2924
|
const rendererTimer = startTimer();
|
|
2912
2925
|
try {
|
|
2913
2926
|
await this.startRenderer();
|
|
@@ -2924,7 +2937,7 @@ var DevServer = class {
|
|
|
2924
2937
|
return;
|
|
2925
2938
|
}
|
|
2926
2939
|
const externals = await resolveExternals(this.root);
|
|
2927
|
-
if (
|
|
2940
|
+
if (views.length > 0) {
|
|
2928
2941
|
const preloadTimer = startTimer();
|
|
2929
2942
|
try {
|
|
2930
2943
|
await this.buildPreload(externals);
|
|
@@ -2991,7 +3004,7 @@ var DevServer = class {
|
|
|
2991
3004
|
this.lastScanResult = scanResult;
|
|
2992
3005
|
const { files, envTypes } = generate({
|
|
2993
3006
|
scanResult,
|
|
2994
|
-
|
|
3007
|
+
views: this.config.views ?? [],
|
|
2995
3008
|
outputDir,
|
|
2996
3009
|
srcDir
|
|
2997
3010
|
});
|
|
@@ -3006,11 +3019,11 @@ var DevServer = class {
|
|
|
3006
3019
|
await writeFile(envTypesPath, envTypes.content);
|
|
3007
3020
|
}
|
|
3008
3021
|
async startRenderer() {
|
|
3009
|
-
const
|
|
3010
|
-
const userViteConfigs =
|
|
3022
|
+
const views = this.config.views ?? [];
|
|
3023
|
+
const userViteConfigs = views.filter((w) => w.vite).map((w) => w.vite);
|
|
3011
3024
|
this.rendererServer = await createServer(createRendererConfig({
|
|
3012
3025
|
root: this.root,
|
|
3013
|
-
|
|
3026
|
+
views,
|
|
3014
3027
|
userViteConfigs: userViteConfigs.length > 0 ? userViteConfigs : void 0,
|
|
3015
3028
|
logLevel: this.logLevel,
|
|
3016
3029
|
clearScreen: this.clearScreen
|
|
@@ -3021,10 +3034,10 @@ var DevServer = class {
|
|
|
3021
3034
|
this.rendererUrl = `http://localhost:${typeof addr === "object" && addr ? addr.port : 5173}`;
|
|
3022
3035
|
}
|
|
3023
3036
|
async buildPreload(externals) {
|
|
3024
|
-
const
|
|
3037
|
+
const views = this.config.views ?? [];
|
|
3025
3038
|
const preloadOutDir = resolve(this.outputDir, "preload");
|
|
3026
3039
|
const input = {};
|
|
3027
|
-
for (const
|
|
3040
|
+
for (const view of views) input[view.name] = resolve(this.outputDir, `generated/preload/${view.name}.gen.ts`);
|
|
3028
3041
|
const firstEntry = Object.values(input)[0];
|
|
3029
3042
|
const baseConfig = createNodeConfig({
|
|
3030
3043
|
scope: "preload",
|
|
@@ -3086,14 +3099,6 @@ var DevServer = class {
|
|
|
3086
3099
|
async buildMain(externals) {
|
|
3087
3100
|
const runtimeEntry = this.config.runtime.entry;
|
|
3088
3101
|
const entry = resolve(dirname(this.config.runtime.__source), runtimeEntry);
|
|
3089
|
-
const windowDefs = (this.config.windows ?? []).map((w) => ({
|
|
3090
|
-
name: w.name,
|
|
3091
|
-
type: w.type,
|
|
3092
|
-
lifecycle: w.lifecycle,
|
|
3093
|
-
autoShow: w.autoShow,
|
|
3094
|
-
behavior: w.behavior,
|
|
3095
|
-
window: w.window
|
|
3096
|
-
}));
|
|
3097
3102
|
const mainConfig = createNodeConfig({
|
|
3098
3103
|
scope: "main",
|
|
3099
3104
|
root: this.root,
|
|
@@ -3109,8 +3114,7 @@ var DevServer = class {
|
|
|
3109
3114
|
logLevel: this.logLevel,
|
|
3110
3115
|
clearScreen: this.clearScreen,
|
|
3111
3116
|
userViteConfig: this.config.runtime.vite,
|
|
3112
|
-
sourcemap: this.sourcemap
|
|
3113
|
-
define: { __ELECTRO_WINDOW_DEFINITIONS__: JSON.stringify(windowDefs) }
|
|
3117
|
+
sourcemap: this.sourcemap
|
|
3114
3118
|
});
|
|
3115
3119
|
const self = this;
|
|
3116
3120
|
let firstBuild = true;
|
|
@@ -3147,10 +3151,10 @@ var DevServer = class {
|
|
|
3147
3151
|
const addr = this.rendererServer.httpServer?.address();
|
|
3148
3152
|
const port = typeof addr === "object" && addr ? addr.port : 5173;
|
|
3149
3153
|
env.ELECTRO_RENDERER_BASE = `http://localhost:${port}`;
|
|
3150
|
-
for (const
|
|
3151
|
-
const entryPath = resolve(dirname(
|
|
3154
|
+
for (const view of this.config.views ?? []) {
|
|
3155
|
+
const entryPath = resolve(dirname(view.__source), view.entry);
|
|
3152
3156
|
const relPath = relative(this.root, entryPath);
|
|
3153
|
-
env[`ELECTRO_DEV_URL_${
|
|
3157
|
+
env[`ELECTRO_DEV_URL_${view.name}`] = `http://localhost:${port}/${relPath}`;
|
|
3154
3158
|
}
|
|
3155
3159
|
}
|
|
3156
3160
|
const proc = await launchElectron({
|
|
@@ -3287,15 +3291,15 @@ async function generate$1(options) {
|
|
|
3287
3291
|
console.error("Error: electro.config.ts must have a default export");
|
|
3288
3292
|
process.exit(1);
|
|
3289
3293
|
}
|
|
3290
|
-
const
|
|
3291
|
-
console.log(`Loaded config with ${
|
|
3294
|
+
const views = config.views ?? [];
|
|
3295
|
+
console.log(`Loaded config with ${views.length} view(s)`);
|
|
3292
3296
|
const srcDir = resolve(process.cwd(), "src");
|
|
3293
3297
|
console.log(`Scanning ${srcDir}...`);
|
|
3294
3298
|
const scanResult = await scan(srcDir);
|
|
3295
3299
|
console.log(`Found ${scanResult.features.length} feature(s)`);
|
|
3296
3300
|
const { files, envTypes } = generate({
|
|
3297
3301
|
scanResult,
|
|
3298
|
-
|
|
3302
|
+
views,
|
|
3299
3303
|
outputDir,
|
|
3300
3304
|
srcDir
|
|
3301
3305
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cordy/electro-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "CLI for @cordy/electro — dev server, build, and code generation commands",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -47,15 +47,15 @@
|
|
|
47
47
|
"prepublishOnly": "bun run build"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"@cordy/electro": "1.
|
|
50
|
+
"@cordy/electro": "1.1.1",
|
|
51
51
|
"electron": ">=40.4.1",
|
|
52
52
|
"vite": ">=8.0.0"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@cordy/electro-generator": "1.
|
|
55
|
+
"@cordy/electro-generator": "1.1.1"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
|
-
"@cordy/electro": "1.
|
|
58
|
+
"@cordy/electro": "1.1.1",
|
|
59
59
|
"@types/node": "^25.2.3",
|
|
60
60
|
"cac": "^6.7.14",
|
|
61
61
|
"electron": "^40.4.1",
|