@bonsae/nrg 0.19.0 → 0.19.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/README.md +2 -2
- package/package.json +1 -1
- package/test/client/e2e/index.js +4 -17
- package/types/vite.d.ts +1 -14
- package/vite/index.js +34 -87
package/README.md
CHANGED
|
@@ -36,10 +36,10 @@ Installing `node-red` as a dev dependency is recommended for fast, reliable dev
|
|
|
36
36
|
|
|
37
37
|
```typescript
|
|
38
38
|
import { defineConfig } from "vite";
|
|
39
|
-
import {
|
|
39
|
+
import { nrg } from "@bonsae/nrg/vite";
|
|
40
40
|
|
|
41
41
|
export default defineConfig({
|
|
42
|
-
plugins: [
|
|
42
|
+
plugins: [nrg()],
|
|
43
43
|
});
|
|
44
44
|
```
|
|
45
45
|
|
package/package.json
CHANGED
package/test/client/e2e/index.js
CHANGED
|
@@ -2191,7 +2191,7 @@ async function compileRuntimeSettingsFile(runtimeSettingsFilepath, port) {
|
|
|
2191
2191
|
return compiledRuntimeSettingsFilepath;
|
|
2192
2192
|
}
|
|
2193
2193
|
async function generateRuntimeSettings(options) {
|
|
2194
|
-
const { outDir, port, settingsFilepath,
|
|
2194
|
+
const { outDir, port, settingsFilepath, logger: logger2 } = options;
|
|
2195
2195
|
const tempFiles = [];
|
|
2196
2196
|
const userRuntimeSettingsFilepath = findUserRuntimeSettingsFilepath(
|
|
2197
2197
|
settingsFilepath,
|
|
@@ -2210,17 +2210,13 @@ async function generateRuntimeSettings(options) {
|
|
|
2210
2210
|
const userDir = path11.resolve(cwd, ".node-red").split(path11.sep).join("/");
|
|
2211
2211
|
const userDirLiteral = JSON.stringify(userDir);
|
|
2212
2212
|
const outDirLiteral = JSON.stringify(normalizedOutDir);
|
|
2213
|
-
const httpAdminRootAssignment = httpAdminRoot ? `settings.httpAdminRoot = ${JSON.stringify(httpAdminRoot)};
|
|
2214
|
-
` : "";
|
|
2215
|
-
const httpAdminRootEntry = httpAdminRoot ? `
|
|
2216
|
-
httpAdminRoot: ${JSON.stringify(httpAdminRoot)},` : "";
|
|
2217
2213
|
const finalRuntimeSettingsFile = compiledRuntimeSettingsFilepath ? `
|
|
2218
2214
|
const compiledRuntimeSettings = require(${JSON.stringify(
|
|
2219
2215
|
compiledRuntimeSettingsFilepath.split(path11.sep).join("/")
|
|
2220
2216
|
)});
|
|
2221
2217
|
const settings = compiledRuntimeSettings.default || compiledRuntimeSettings;
|
|
2222
2218
|
settings.uiPort = ${port};
|
|
2223
|
-
|
|
2219
|
+
if(!settings.userDir){
|
|
2224
2220
|
settings.userDir = ${userDirLiteral};
|
|
2225
2221
|
}
|
|
2226
2222
|
settings.nodesDir = settings.nodesDir || [];
|
|
@@ -2242,7 +2238,7 @@ const settings = {
|
|
|
2242
2238
|
uiPort: ${port},
|
|
2243
2239
|
userDir: ${userDirLiteral},
|
|
2244
2240
|
flowFile: "flows.json",
|
|
2245
|
-
nodesDir: [${outDirLiteral}]
|
|
2241
|
+
nodesDir: [${outDirLiteral}],
|
|
2246
2242
|
// the welcome tour overlay intercepts pointer events \u2014 fatal for e2e
|
|
2247
2243
|
editorTheme: { tours: false },
|
|
2248
2244
|
};
|
|
@@ -2396,12 +2392,10 @@ var NodeRedLauncher = class {
|
|
|
2396
2392
|
port = null;
|
|
2397
2393
|
outDir;
|
|
2398
2394
|
options;
|
|
2399
|
-
_slug;
|
|
2400
2395
|
logger;
|
|
2401
|
-
constructor(outDir, options
|
|
2396
|
+
constructor(outDir, options) {
|
|
2402
2397
|
this.outDir = outDir;
|
|
2403
2398
|
this.options = options;
|
|
2404
|
-
this._slug = slug;
|
|
2405
2399
|
this.logger = new Logger({
|
|
2406
2400
|
name: "vite-plugin-node-red",
|
|
2407
2401
|
prefix: "node-red"
|
|
@@ -2410,12 +2404,6 @@ var NodeRedLauncher = class {
|
|
|
2410
2404
|
get preferredPort() {
|
|
2411
2405
|
return this.options.runtime?.port ?? 1880;
|
|
2412
2406
|
}
|
|
2413
|
-
get slug() {
|
|
2414
|
-
return this._slug;
|
|
2415
|
-
}
|
|
2416
|
-
get basePath() {
|
|
2417
|
-
return this._slug ? `/${this._slug}/` : "/";
|
|
2418
|
-
}
|
|
2419
2407
|
get restartDelay() {
|
|
2420
2408
|
return this.options.restartDelay ?? 1e3;
|
|
2421
2409
|
}
|
|
@@ -2496,7 +2484,6 @@ var NodeRedLauncher = class {
|
|
|
2496
2484
|
outDir: this.outDir,
|
|
2497
2485
|
port: this.port,
|
|
2498
2486
|
settingsFilepath: this.options.runtime?.settingsFilepath,
|
|
2499
|
-
httpAdminRoot: this._slug ? this.basePath : void 0,
|
|
2500
2487
|
logger: this.logger
|
|
2501
2488
|
});
|
|
2502
2489
|
for (const file of settings.tempFiles) {
|
package/types/vite.d.ts
CHANGED
|
@@ -80,15 +80,6 @@ export interface NodeRedLauncherOptions {
|
|
|
80
80
|
export interface ServerOptions {
|
|
81
81
|
/** Options for the Node-RED dev server launcher. */
|
|
82
82
|
nodeRed?: NodeRedLauncherOptions;
|
|
83
|
-
/**
|
|
84
|
-
* URL-safe path slug the dev server mounts the Node-RED editor under, so
|
|
85
|
-
* several `nrg dev` instances can be told apart by path (e.g. behind a
|
|
86
|
-
* shared reverse proxy) — the editor is served at
|
|
87
|
-
* `http://host:port/<slug>/`. Must match `/^[a-z0-9]+(?:-[a-z0-9]+)*$/`;
|
|
88
|
-
* an invalid value is rejected rather than rewritten.
|
|
89
|
-
* @default the slugified project folder name
|
|
90
|
-
*/
|
|
91
|
-
slug?: string;
|
|
92
83
|
}
|
|
93
84
|
/**
|
|
94
85
|
* Options for building the distributable Node-RED package.
|
|
@@ -111,7 +102,7 @@ export interface BuildOptions {
|
|
|
111
102
|
* `build` for the production bundle.
|
|
112
103
|
*/
|
|
113
104
|
export interface NrgPluginOptions {
|
|
114
|
-
/** Dev server options (Node-RED launcher
|
|
105
|
+
/** Dev server options (Node-RED launcher). */
|
|
115
106
|
server?: ServerOptions;
|
|
116
107
|
/** Production build options (output dir, server/client bundles, copies). */
|
|
117
108
|
build?: BuildOptions;
|
|
@@ -177,10 +168,6 @@ export interface NodeRedLauncher {
|
|
|
177
168
|
cleanup(): void;
|
|
178
169
|
flushLogs(): void;
|
|
179
170
|
readonly preferredPort: number;
|
|
180
|
-
/** URL-safe path slug the editor is mounted under (empty for root). */
|
|
181
|
-
readonly slug: string;
|
|
182
|
-
/** Path prefix derived from the slug — `/<slug>/`, or `/` when no slug. */
|
|
183
|
-
readonly basePath: string;
|
|
184
171
|
readonly restartDelay: number;
|
|
185
172
|
readonly pid: number | null;
|
|
186
173
|
}
|
package/vite/index.js
CHANGED
|
@@ -52,40 +52,6 @@ var DEFAULT_EXTRA_FILES_COPY_TARGETS = [
|
|
|
52
52
|
// src/vite/utils.ts
|
|
53
53
|
import fs from "fs";
|
|
54
54
|
import path from "path";
|
|
55
|
-
|
|
56
|
-
// src/vite/errors.ts
|
|
57
|
-
var PluginError = class extends Error {
|
|
58
|
-
constructor(message, code, cause) {
|
|
59
|
-
super(message);
|
|
60
|
-
this.code = code;
|
|
61
|
-
this.cause = cause;
|
|
62
|
-
this.name = "PluginError";
|
|
63
|
-
}
|
|
64
|
-
};
|
|
65
|
-
var NodeRedStartError = class extends PluginError {
|
|
66
|
-
constructor(cause) {
|
|
67
|
-
super("Failed to start Node-RED", "NODE_RED_START_FAILED", cause);
|
|
68
|
-
this.name = "NodeRedStartError";
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
var BuildError = class extends PluginError {
|
|
72
|
-
constructor(phase, cause) {
|
|
73
|
-
super(
|
|
74
|
-
`Failed to build ${phase}`,
|
|
75
|
-
`BUILD_${phase.toUpperCase()}_FAILED`,
|
|
76
|
-
cause
|
|
77
|
-
);
|
|
78
|
-
this.name = "BuildError";
|
|
79
|
-
}
|
|
80
|
-
};
|
|
81
|
-
var ConfigError = class extends PluginError {
|
|
82
|
-
constructor(message) {
|
|
83
|
-
super(message, "CONFIG_INVALID");
|
|
84
|
-
this.name = "ConfigError";
|
|
85
|
-
}
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
// src/vite/utils.ts
|
|
89
55
|
function cleanDir(dir) {
|
|
90
56
|
if (fs.existsSync(dir)) {
|
|
91
57
|
fs.rmSync(dir, { recursive: true });
|
|
@@ -120,23 +86,6 @@ function getPackageName() {
|
|
|
120
86
|
}
|
|
121
87
|
return "node-red-nodes";
|
|
122
88
|
}
|
|
123
|
-
var SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
124
|
-
function slugify(input) {
|
|
125
|
-
return input.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
126
|
-
}
|
|
127
|
-
function resolveSlug(userSlug) {
|
|
128
|
-
if (userSlug !== void 0) {
|
|
129
|
-
const trimmed = userSlug.trim();
|
|
130
|
-
if (!SLUG_PATTERN.test(trimmed)) {
|
|
131
|
-
const suggestion = slugify(trimmed);
|
|
132
|
-
throw new ConfigError(
|
|
133
|
-
`Invalid dev server slug ${JSON.stringify(userSlug)}. A slug must be URL-safe: lowercase letters, digits and single hyphens (matching ${String(SLUG_PATTERN)}).` + (suggestion ? ` Did you mean ${JSON.stringify(suggestion)}?` : "")
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
return trimmed;
|
|
137
|
-
}
|
|
138
|
-
return slugify(path.basename(process.cwd())) || "app";
|
|
139
|
-
}
|
|
140
89
|
function mergeOptions(defaults, overrides) {
|
|
141
90
|
if (!overrides) return { ...defaults };
|
|
142
91
|
const result = { ...defaults };
|
|
@@ -202,6 +151,32 @@ async function retry(fn, options = {}) {
|
|
|
202
151
|
throw lastError;
|
|
203
152
|
}
|
|
204
153
|
|
|
154
|
+
// src/vite/errors.ts
|
|
155
|
+
var PluginError = class extends Error {
|
|
156
|
+
constructor(message, code, cause) {
|
|
157
|
+
super(message);
|
|
158
|
+
this.code = code;
|
|
159
|
+
this.cause = cause;
|
|
160
|
+
this.name = "PluginError";
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
var NodeRedStartError = class extends PluginError {
|
|
164
|
+
constructor(cause) {
|
|
165
|
+
super("Failed to start Node-RED", "NODE_RED_START_FAILED", cause);
|
|
166
|
+
this.name = "NodeRedStartError";
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
var BuildError = class extends PluginError {
|
|
170
|
+
constructor(phase, cause) {
|
|
171
|
+
super(
|
|
172
|
+
`Failed to build ${phase}`,
|
|
173
|
+
`BUILD_${phase.toUpperCase()}_FAILED`,
|
|
174
|
+
cause
|
|
175
|
+
);
|
|
176
|
+
this.name = "BuildError";
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
205
180
|
// src/vite/logger.ts
|
|
206
181
|
import * as clackLogger from "@clack/prompts";
|
|
207
182
|
var color = {
|
|
@@ -424,7 +399,7 @@ async function compileRuntimeSettingsFile(runtimeSettingsFilepath, port) {
|
|
|
424
399
|
return compiledRuntimeSettingsFilepath;
|
|
425
400
|
}
|
|
426
401
|
async function generateRuntimeSettings(options) {
|
|
427
|
-
const { outDir, port, settingsFilepath,
|
|
402
|
+
const { outDir, port, settingsFilepath, logger: logger2 } = options;
|
|
428
403
|
const tempFiles = [];
|
|
429
404
|
const userRuntimeSettingsFilepath = findUserRuntimeSettingsFilepath(
|
|
430
405
|
settingsFilepath,
|
|
@@ -443,17 +418,13 @@ async function generateRuntimeSettings(options) {
|
|
|
443
418
|
const userDir = path3.resolve(cwd, ".node-red").split(path3.sep).join("/");
|
|
444
419
|
const userDirLiteral = JSON.stringify(userDir);
|
|
445
420
|
const outDirLiteral = JSON.stringify(normalizedOutDir);
|
|
446
|
-
const httpAdminRootAssignment = httpAdminRoot ? `settings.httpAdminRoot = ${JSON.stringify(httpAdminRoot)};
|
|
447
|
-
` : "";
|
|
448
|
-
const httpAdminRootEntry = httpAdminRoot ? `
|
|
449
|
-
httpAdminRoot: ${JSON.stringify(httpAdminRoot)},` : "";
|
|
450
421
|
const finalRuntimeSettingsFile = compiledRuntimeSettingsFilepath ? `
|
|
451
422
|
const compiledRuntimeSettings = require(${JSON.stringify(
|
|
452
423
|
compiledRuntimeSettingsFilepath.split(path3.sep).join("/")
|
|
453
424
|
)});
|
|
454
425
|
const settings = compiledRuntimeSettings.default || compiledRuntimeSettings;
|
|
455
426
|
settings.uiPort = ${port};
|
|
456
|
-
|
|
427
|
+
if(!settings.userDir){
|
|
457
428
|
settings.userDir = ${userDirLiteral};
|
|
458
429
|
}
|
|
459
430
|
settings.nodesDir = settings.nodesDir || [];
|
|
@@ -475,7 +446,7 @@ const settings = {
|
|
|
475
446
|
uiPort: ${port},
|
|
476
447
|
userDir: ${userDirLiteral},
|
|
477
448
|
flowFile: "flows.json",
|
|
478
|
-
nodesDir: [${outDirLiteral}]
|
|
449
|
+
nodesDir: [${outDirLiteral}],
|
|
479
450
|
// the welcome tour overlay intercepts pointer events \u2014 fatal for e2e
|
|
480
451
|
editorTheme: { tours: false },
|
|
481
452
|
};
|
|
@@ -629,12 +600,10 @@ var NodeRedLauncher = class {
|
|
|
629
600
|
port = null;
|
|
630
601
|
outDir;
|
|
631
602
|
options;
|
|
632
|
-
_slug;
|
|
633
603
|
logger;
|
|
634
|
-
constructor(outDir, options
|
|
604
|
+
constructor(outDir, options) {
|
|
635
605
|
this.outDir = outDir;
|
|
636
606
|
this.options = options;
|
|
637
|
-
this._slug = slug;
|
|
638
607
|
this.logger = new Logger({
|
|
639
608
|
name: "vite-plugin-node-red",
|
|
640
609
|
prefix: "node-red"
|
|
@@ -643,12 +612,6 @@ var NodeRedLauncher = class {
|
|
|
643
612
|
get preferredPort() {
|
|
644
613
|
return this.options.runtime?.port ?? 1880;
|
|
645
614
|
}
|
|
646
|
-
get slug() {
|
|
647
|
-
return this._slug;
|
|
648
|
-
}
|
|
649
|
-
get basePath() {
|
|
650
|
-
return this._slug ? `/${this._slug}/` : "/";
|
|
651
|
-
}
|
|
652
615
|
get restartDelay() {
|
|
653
616
|
return this.options.restartDelay ?? 1e3;
|
|
654
617
|
}
|
|
@@ -729,7 +692,6 @@ var NodeRedLauncher = class {
|
|
|
729
692
|
outDir: this.outDir,
|
|
730
693
|
port: this.port,
|
|
731
694
|
settingsFilepath: this.options.runtime?.settingsFilepath,
|
|
732
|
-
httpAdminRoot: this._slug ? this.basePath : void 0,
|
|
733
695
|
logger: this.logger
|
|
734
696
|
});
|
|
735
697
|
for (const file of settings.tempFiles) {
|
|
@@ -2720,8 +2682,6 @@ function serverPlugin(options) {
|
|
|
2720
2682
|
extraFilesCopyTargets,
|
|
2721
2683
|
buildContext
|
|
2722
2684
|
} = options;
|
|
2723
|
-
const { slug, basePath } = nodeRedLauncher;
|
|
2724
|
-
const proxyKey = slug ? `^/${slug}(?:/|\\?|$)` : "^/.*";
|
|
2725
2685
|
let nodeRedPort;
|
|
2726
2686
|
let initialStartDone = false;
|
|
2727
2687
|
let isStarting = false;
|
|
@@ -2761,7 +2721,7 @@ function serverPlugin(options) {
|
|
|
2761
2721
|
logger.stopSpinner("Node-RED started");
|
|
2762
2722
|
const proxyConfig = server.config.server.proxy;
|
|
2763
2723
|
if (proxyConfig && typeof proxyConfig === "object") {
|
|
2764
|
-
const rule = proxyConfig[
|
|
2724
|
+
const rule = proxyConfig["^/.*"];
|
|
2765
2725
|
if (rule && typeof rule === "object") {
|
|
2766
2726
|
rule.target = `http://127.0.0.1:${nodeRedPort}`;
|
|
2767
2727
|
}
|
|
@@ -2786,7 +2746,7 @@ function serverPlugin(options) {
|
|
|
2786
2746
|
const printServerUrls = (vitePort, nodeRedPorts) => {
|
|
2787
2747
|
console.log();
|
|
2788
2748
|
console.log(
|
|
2789
|
-
` ${color2.cyan("Vite")} ${color2.dim("\u279C")} ${color2.cyan(`http://127.0.0.1:${vitePort}
|
|
2749
|
+
` ${color2.cyan("Vite")} ${color2.dim("\u279C")} ${color2.cyan(`http://127.0.0.1:${vitePort}/`)}`
|
|
2790
2750
|
);
|
|
2791
2751
|
if (nodeRedPorts.actual != nodeRedPorts.preferred) {
|
|
2792
2752
|
console.log(
|
|
@@ -2808,7 +2768,7 @@ function serverPlugin(options) {
|
|
|
2808
2768
|
server: {
|
|
2809
2769
|
host: "127.0.0.1",
|
|
2810
2770
|
proxy: {
|
|
2811
|
-
|
|
2771
|
+
"^/.*": {
|
|
2812
2772
|
target: `http://127.0.0.1:${nodeRedLauncher.preferredPort}`,
|
|
2813
2773
|
changeOrigin: true,
|
|
2814
2774
|
ws: true,
|
|
@@ -2851,17 +2811,6 @@ function serverPlugin(options) {
|
|
|
2851
2811
|
},
|
|
2852
2812
|
async configureServer(viteServer) {
|
|
2853
2813
|
server = viteServer;
|
|
2854
|
-
if (slug) {
|
|
2855
|
-
server.middlewares.use((req, res, next) => {
|
|
2856
|
-
if (req.url === "/" || req.url === "") {
|
|
2857
|
-
res.statusCode = 302;
|
|
2858
|
-
res.setHeader("Location", basePath);
|
|
2859
|
-
res.end();
|
|
2860
|
-
return;
|
|
2861
|
-
}
|
|
2862
|
-
next();
|
|
2863
|
-
});
|
|
2864
|
-
}
|
|
2865
2814
|
logger.intro();
|
|
2866
2815
|
await start2(true);
|
|
2867
2816
|
initialStartDone = true;
|
|
@@ -3004,11 +2953,9 @@ function nrg(options = {}) {
|
|
|
3004
2953
|
packageName: getPackageName(),
|
|
3005
2954
|
isDev: process.env.NODE_ENV === "development"
|
|
3006
2955
|
};
|
|
3007
|
-
const slug = resolveSlug(server.slug);
|
|
3008
2956
|
const nodeRedLauncher = new NodeRedLauncher(
|
|
3009
2957
|
resolvedOutDir,
|
|
3010
|
-
nodeRedLauncherOptions
|
|
3011
|
-
slug
|
|
2958
|
+
nodeRedLauncherOptions
|
|
3012
2959
|
);
|
|
3013
2960
|
return [
|
|
3014
2961
|
serverPlugin({
|