@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 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 { nodeRed } from "@bonsae/nrg/vite";
39
+ import { nrg } from "@bonsae/nrg/vite";
40
40
 
41
41
  export default defineConfig({
42
- plugins: [nodeRed()],
42
+ plugins: [nrg()],
43
43
  });
44
44
  ```
45
45
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bonsae/nrg",
3
- "version": "0.19.0",
3
+ "version": "0.19.1",
4
4
  "description": "NRG framework — build Node-RED nodes with Vue 3, TypeScript, and JSON Schema",
5
5
  "author": "Allan Oricil <allanoricil@duck.com>",
6
6
  "license": "MIT",
@@ -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, httpAdminRoot, logger: logger2 } = options;
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
- ${httpAdminRootAssignment}if(!settings.userDir){
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}],${httpAdminRootEntry}
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, slug = "") {
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, editor path slug). */
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, httpAdminRoot, logger: logger2 } = options;
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
- ${httpAdminRootAssignment}if(!settings.userDir){
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}],${httpAdminRootEntry}
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, slug = "") {
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[proxyKey];
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}${basePath}`)}`
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
- [proxyKey]: {
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({