@bonsae/nrg 0.1.0
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 +130 -0
- package/build/server/index.cjs +910 -0
- package/build/server/resources/nrg-client.js +6530 -0
- package/build/server/resources/vue.esm-browser.prod.js +13 -0
- package/build/vite/index.js +1893 -0
- package/build/vite/utils.js +60 -0
- package/package.json +110 -0
- package/src/core/client/api/index.ts +17 -0
- package/src/core/client/app.vue +201 -0
- package/src/core/client/components/node-red-config-input.vue +57 -0
- package/src/core/client/components/node-red-editor-input.vue +283 -0
- package/src/core/client/components/node-red-input.vue +71 -0
- package/src/core/client/components/node-red-json-schema-form.vue +369 -0
- package/src/core/client/components/node-red-select-input.vue +86 -0
- package/src/core/client/components/node-red-typed-input.vue +130 -0
- package/src/core/client/components.d.ts +18 -0
- package/src/core/client/globals.d.ts +17 -0
- package/src/core/client/index.ts +504 -0
- package/src/core/client/shims-vue.d.ts +5 -0
- package/src/core/client/tsconfig.json +18 -0
- package/src/core/client/virtual.d.ts +5 -0
- package/src/core/constants.ts +18 -0
- package/src/core/server/index.ts +209 -0
- package/src/core/server/nodes/config-node.ts +67 -0
- package/src/core/server/nodes/index.ts +4 -0
- package/src/core/server/nodes/io-node.ts +178 -0
- package/src/core/server/nodes/node.ts +255 -0
- package/src/core/server/nodes/types/config-node.ts +28 -0
- package/src/core/server/nodes/types/index.ts +3 -0
- package/src/core/server/nodes/types/io-node.ts +37 -0
- package/src/core/server/nodes/types/node.ts +41 -0
- package/src/core/server/nodes/utils.ts +83 -0
- package/src/core/server/schemas/base.ts +66 -0
- package/src/core/server/schemas/index.ts +3 -0
- package/src/core/server/schemas/type.ts +95 -0
- package/src/core/server/schemas/types/index.ts +73 -0
- package/src/core/server/tsconfig.json +17 -0
- package/src/core/server/types/index.ts +73 -0
- package/src/core/server/utils.ts +56 -0
- package/src/core/server/validator.ts +32 -0
- package/src/core/validator.ts +222 -0
- package/src/tsconfig/base.json +23 -0
- package/src/tsconfig/client.json +11 -0
- package/src/tsconfig/server.json +6 -0
- package/src/vite/async-utils.ts +61 -0
- package/src/vite/client/build.ts +223 -0
- package/src/vite/client/index.ts +1 -0
- package/src/vite/client/plugins/html-generator.ts +75 -0
- package/src/vite/client/plugins/index.ts +5 -0
- package/src/vite/client/plugins/locales-generator.ts +126 -0
- package/src/vite/client/plugins/minifier.ts +22 -0
- package/src/vite/client/plugins/node-definitions-inliner.ts +224 -0
- package/src/vite/client/plugins/static-copy.ts +43 -0
- package/src/vite/defaults.ts +77 -0
- package/src/vite/errors.ts +37 -0
- package/src/vite/index.ts +3 -0
- package/src/vite/logger.ts +94 -0
- package/src/vite/node-red-launcher.ts +344 -0
- package/src/vite/plugin.ts +61 -0
- package/src/vite/plugins/build.ts +73 -0
- package/src/vite/plugins/index.ts +2 -0
- package/src/vite/plugins/server.ts +267 -0
- package/src/vite/server/build.ts +124 -0
- package/src/vite/server/index.ts +1 -0
- package/src/vite/server/plugins/index.ts +3 -0
- package/src/vite/server/plugins/output-wrapper.ts +109 -0
- package/src/vite/server/plugins/package-json-generator.ts +203 -0
- package/src/vite/server/plugins/type-generator.ts +285 -0
- package/src/vite/types.ts +369 -0
- package/src/vite/utils.ts +103 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
import type { Plugin } from "vite";
|
|
2
|
+
import type { NodeRedLauncher } from "./node-red-launcher";
|
|
3
|
+
import type { Http2ServerRequest } from "http2";
|
|
4
|
+
|
|
5
|
+
interface BuildContext {
|
|
6
|
+
outDir: string;
|
|
7
|
+
packageName: string;
|
|
8
|
+
isDev: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface BuildPluginOptions {
|
|
12
|
+
serverBuildOptions: ServerBuildOptions;
|
|
13
|
+
clientBuildOptions: ClientBuildOptions;
|
|
14
|
+
extraFilesCopyTargets: CopyTarget[];
|
|
15
|
+
buildContext: BuildContext;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface ClientBuildOptions {
|
|
19
|
+
/** Source directory for client code. @default "./src/client" */
|
|
20
|
+
srcDir?: string;
|
|
21
|
+
/** Entry filename relative to srcDir. @default "index.ts" */
|
|
22
|
+
entry?: string;
|
|
23
|
+
/** Subdirectory name for node definition files. @default "nodes" */
|
|
24
|
+
nodesSubdir?: string;
|
|
25
|
+
/** Pattern to match node definition files. */
|
|
26
|
+
nodeFilePattern?: RegExp;
|
|
27
|
+
/** Global variable name for the UMD/IIFE bundle. @default "NodeRedNodes" */
|
|
28
|
+
name?: string;
|
|
29
|
+
/** Output format for the client bundle. @default "es" */
|
|
30
|
+
format?: "es" | "iife" | "umd";
|
|
31
|
+
/** Base public path for serving resources. */
|
|
32
|
+
base?: string;
|
|
33
|
+
/** Path to LICENSE file to include in the HTML output. @default "./LICENSE" */
|
|
34
|
+
licensePath?: string;
|
|
35
|
+
/** Internationalization options for labels and docs. */
|
|
36
|
+
locales?: LocalesOptions;
|
|
37
|
+
/** Directories for static assets (icons, public files). */
|
|
38
|
+
staticDirs?: {
|
|
39
|
+
/** Directory containing node icons ({type}.png). @default "./src/icons" */
|
|
40
|
+
icons?: string;
|
|
41
|
+
/** Directory for public static files copied to dist/resources/. @default "./src/client/public" */
|
|
42
|
+
public?: string;
|
|
43
|
+
};
|
|
44
|
+
/** Modules to treat as external (not bundled). @default ["jquery", "node-red", "vue", "@bonsae/nrg/client"] */
|
|
45
|
+
external?: string[];
|
|
46
|
+
/** Global variable mappings for external modules. */
|
|
47
|
+
globals?: Record<string, string>;
|
|
48
|
+
/** Custom chunk splitting function for Rollup. */
|
|
49
|
+
manualChunks?: (id: string) => string | undefined;
|
|
50
|
+
/** Additional Vite plugins for the client build. */
|
|
51
|
+
plugins: Plugin[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface CopyTarget {
|
|
55
|
+
/** Source file or directory path. */
|
|
56
|
+
src: string;
|
|
57
|
+
/** Destination path relative to the output directory. */
|
|
58
|
+
dest: string;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface LocalesOptions {
|
|
62
|
+
/** Directory containing documentation files ({type}/{lang}.md or .html). @default "./src/locales/docs" */
|
|
63
|
+
docsDir?: string;
|
|
64
|
+
/** Directory containing label files ({type}/{lang}.json). @default "./src/locales/labels" */
|
|
65
|
+
labelsDir?: string;
|
|
66
|
+
/** Supported languages. @default ["en-US", "de", "es-ES", "fr", "ko", "pt-BR", "ru", "ja", "zh-CN", "zh-TW"] */
|
|
67
|
+
languages?: string[];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
interface LoggerOptions {
|
|
71
|
+
name: string;
|
|
72
|
+
prefix?: string;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
interface NodeRedLauncherOptions {
|
|
76
|
+
runtime?: {
|
|
77
|
+
/** Port for Node-RED to listen on. @default 1880 */
|
|
78
|
+
port?: number;
|
|
79
|
+
/** Path to the Node-RED settings file (TypeScript supported). @default "./node-red.settings.ts" */
|
|
80
|
+
settingsFilepath?: string;
|
|
81
|
+
/** Node-RED version to install for the dev server. @default "latest" */
|
|
82
|
+
version?: string;
|
|
83
|
+
};
|
|
84
|
+
/** Delay in ms before restarting Node-RED after a file change. @default 1000 */
|
|
85
|
+
restartDelay?: number;
|
|
86
|
+
/** Additional CLI arguments passed to the Node-RED process. */
|
|
87
|
+
args?: string[];
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Options for the `nodeRed()` Vite plugin.
|
|
92
|
+
*
|
|
93
|
+
* All options are optional — defaults work for the standard `src/` directory layout.
|
|
94
|
+
*/
|
|
95
|
+
interface NodeRedPluginOptions {
|
|
96
|
+
/** Output directory for the built Node-RED package. @default "./dist" */
|
|
97
|
+
outDir?: string;
|
|
98
|
+
/** Options for building the client-side editor UI. */
|
|
99
|
+
clientBuildOptions?: ClientBuildOptions;
|
|
100
|
+
/** Options for building the server-side node runtime. */
|
|
101
|
+
serverBuildOptions?: ServerBuildOptions;
|
|
102
|
+
/** Options for the Node-RED dev server launcher. */
|
|
103
|
+
nodeRedLauncherOptions?: NodeRedLauncherOptions;
|
|
104
|
+
/** Extra files to copy into the output directory (e.g., LICENSE, README). */
|
|
105
|
+
extraFilesCopyTargets?: CopyTarget[];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
interface NodeRedRuntimeSettings {
|
|
109
|
+
// NOTE: commented out because the preferred port must be set using NodeRedLauncherOptions.runtime.port
|
|
110
|
+
// uiPort?: number;
|
|
111
|
+
// NOTE: commented out because the plugin set it to 127.0.0.1
|
|
112
|
+
// uiHost?: string;
|
|
113
|
+
userDir?: string;
|
|
114
|
+
nodesDir?: string | string[];
|
|
115
|
+
flowFile?: string;
|
|
116
|
+
flowFilePretty?: boolean;
|
|
117
|
+
credentialSecret?: string | false;
|
|
118
|
+
requireHttps?: boolean;
|
|
119
|
+
https?:
|
|
120
|
+
| { key: string; cert: string }
|
|
121
|
+
| (() =>
|
|
122
|
+
| Promise<{ key: string; cert: string }>
|
|
123
|
+
| { key: string; cert: string });
|
|
124
|
+
httpsRefreshInterval?: number;
|
|
125
|
+
httpAdminRoot?: string;
|
|
126
|
+
httpNodeRoot?: string;
|
|
127
|
+
httpNodeCors?: { origin: string; methods: string };
|
|
128
|
+
httpStatic?: string | { path: string; root: string }[];
|
|
129
|
+
httpStaticRoot?: string;
|
|
130
|
+
httpAdminMiddleware?: (req: unknown, res: unknown, next: () => void) => void;
|
|
131
|
+
httpNodeMiddleware?: (req: unknown, res: unknown, next: () => void) => void;
|
|
132
|
+
httpServerOptions?: Record<string, unknown>;
|
|
133
|
+
adminAuth?: {
|
|
134
|
+
type?: "credentials" | "strategy";
|
|
135
|
+
users?: {
|
|
136
|
+
username: string;
|
|
137
|
+
password: string;
|
|
138
|
+
permissions?: string | string[];
|
|
139
|
+
}[];
|
|
140
|
+
default?: {
|
|
141
|
+
permissions?: string | string[];
|
|
142
|
+
};
|
|
143
|
+
tokens?: (
|
|
144
|
+
token: string,
|
|
145
|
+
) => Promise<{ user: string; permissions: string | string[] } | null>;
|
|
146
|
+
tokenHeader: "string";
|
|
147
|
+
sessionExpiryTime?: number;
|
|
148
|
+
[key: string]: unknown;
|
|
149
|
+
};
|
|
150
|
+
httpNodeAuth?: {
|
|
151
|
+
user?: string;
|
|
152
|
+
pass?: string;
|
|
153
|
+
};
|
|
154
|
+
httpStaticAuth?: {
|
|
155
|
+
user?: string;
|
|
156
|
+
pass?: string;
|
|
157
|
+
};
|
|
158
|
+
lang?:
|
|
159
|
+
| "en-US"
|
|
160
|
+
| "de"
|
|
161
|
+
| "es-ES"
|
|
162
|
+
| "fr"
|
|
163
|
+
| "ko"
|
|
164
|
+
| "pt-BR"
|
|
165
|
+
| "ru"
|
|
166
|
+
| "ja"
|
|
167
|
+
| "zh-CN"
|
|
168
|
+
| "zh-TW";
|
|
169
|
+
diagnostics?: {
|
|
170
|
+
enabled?: boolean;
|
|
171
|
+
ui?: boolean;
|
|
172
|
+
};
|
|
173
|
+
runtimeState?: {
|
|
174
|
+
enabled?: boolean;
|
|
175
|
+
ui?: boolean;
|
|
176
|
+
};
|
|
177
|
+
disableEditor?: boolean;
|
|
178
|
+
editorTheme?: {
|
|
179
|
+
page?: {
|
|
180
|
+
title?: string;
|
|
181
|
+
favicon?: string;
|
|
182
|
+
css?: string | string[];
|
|
183
|
+
scripts?: string | string[];
|
|
184
|
+
};
|
|
185
|
+
header?: {
|
|
186
|
+
title?: string;
|
|
187
|
+
image?: string;
|
|
188
|
+
url?: string;
|
|
189
|
+
};
|
|
190
|
+
deployButton?: {
|
|
191
|
+
type?: "simple" | "default";
|
|
192
|
+
label?: string;
|
|
193
|
+
icon?: string;
|
|
194
|
+
};
|
|
195
|
+
menu?: {
|
|
196
|
+
"menu-item-import-library"?: boolean;
|
|
197
|
+
"menu-item-export-library"?: boolean;
|
|
198
|
+
"menu-item-keyboard-shortcuts"?: boolean;
|
|
199
|
+
"menu-item-help"?: {
|
|
200
|
+
label?: string;
|
|
201
|
+
url?: string;
|
|
202
|
+
};
|
|
203
|
+
[menuItem: string]:
|
|
204
|
+
| boolean
|
|
205
|
+
| { label?: string; url?: string }
|
|
206
|
+
| undefined;
|
|
207
|
+
};
|
|
208
|
+
userMenu?: boolean;
|
|
209
|
+
login?: {
|
|
210
|
+
image?: string;
|
|
211
|
+
};
|
|
212
|
+
logout?: {
|
|
213
|
+
redirect?: string;
|
|
214
|
+
};
|
|
215
|
+
palette?: {
|
|
216
|
+
catalogues?: string[];
|
|
217
|
+
categories?: string[];
|
|
218
|
+
theme?: { category: string; type: string; color: string }[];
|
|
219
|
+
};
|
|
220
|
+
projects?: {
|
|
221
|
+
enabled?: boolean;
|
|
222
|
+
workflow?: {
|
|
223
|
+
mode: "manual" | "auto";
|
|
224
|
+
};
|
|
225
|
+
};
|
|
226
|
+
codeEditor?: {
|
|
227
|
+
lib?: "monaco" | "ace";
|
|
228
|
+
// TODO: add monaco option types
|
|
229
|
+
options?: Record<string, unknown>;
|
|
230
|
+
};
|
|
231
|
+
mermaid?: {
|
|
232
|
+
theme?: string;
|
|
233
|
+
};
|
|
234
|
+
tours?: boolean;
|
|
235
|
+
theme?: string;
|
|
236
|
+
[key: string]: unknown;
|
|
237
|
+
};
|
|
238
|
+
contextStorage?: {
|
|
239
|
+
default?: {
|
|
240
|
+
module?: "memory" | "localfilesystem" | object;
|
|
241
|
+
config?: Record<string, unknown>;
|
|
242
|
+
};
|
|
243
|
+
[store: string]:
|
|
244
|
+
| {
|
|
245
|
+
module?: "memory" | "localfilesystem" | object;
|
|
246
|
+
config?: Record<string, unknown>;
|
|
247
|
+
}
|
|
248
|
+
| undefined;
|
|
249
|
+
};
|
|
250
|
+
exportGlobalContextKeys?: boolean;
|
|
251
|
+
logging?: {
|
|
252
|
+
console?: {
|
|
253
|
+
level?: "fatal" | "error" | "warn" | "info" | "debug" | "trace" | "off";
|
|
254
|
+
metrics?: boolean;
|
|
255
|
+
audit?: boolean;
|
|
256
|
+
};
|
|
257
|
+
};
|
|
258
|
+
fileWorkingDirectory?: string;
|
|
259
|
+
functionExternalModules?: boolean;
|
|
260
|
+
functionGlobalContext?: Record<string, unknown>;
|
|
261
|
+
nodeMessageBufferMaxLength?: number;
|
|
262
|
+
functionTimeout?: number;
|
|
263
|
+
externalModules?: {
|
|
264
|
+
autoInstall?: boolean;
|
|
265
|
+
autoInstallRetry?: number;
|
|
266
|
+
palette?: {
|
|
267
|
+
allowInstall?: boolean;
|
|
268
|
+
allowUpdate?: boolean;
|
|
269
|
+
allowUpload?: boolean;
|
|
270
|
+
allowList?: string[];
|
|
271
|
+
denyList?: string[];
|
|
272
|
+
allowUpdateList?: string[];
|
|
273
|
+
denyUpdateList?: string[];
|
|
274
|
+
};
|
|
275
|
+
modules?: {
|
|
276
|
+
allowInstall?: boolean;
|
|
277
|
+
allowList?: string[];
|
|
278
|
+
denyList?: string[];
|
|
279
|
+
};
|
|
280
|
+
};
|
|
281
|
+
execMaxBufferSize?: number;
|
|
282
|
+
debugMaxLength?: number;
|
|
283
|
+
debugUseColors?: boolean;
|
|
284
|
+
httpRequestTimeout?: number;
|
|
285
|
+
mqttReconnectTime?: number;
|
|
286
|
+
serialReconnectTime?: number;
|
|
287
|
+
socketReconnectTime?: number;
|
|
288
|
+
socketTimeout?: number;
|
|
289
|
+
tcpMsgQueueSize?: number;
|
|
290
|
+
inboundWebSocketTimeout?: number;
|
|
291
|
+
tlsConfigDisableLocalFiles?: boolean;
|
|
292
|
+
webSocketNodeVerifyClient?: (info: {
|
|
293
|
+
origin: string;
|
|
294
|
+
req: Http2ServerRequest;
|
|
295
|
+
secure: boolean;
|
|
296
|
+
}) => boolean;
|
|
297
|
+
apiMaxLength?: string;
|
|
298
|
+
[key: string]: unknown;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
interface PackageJson {
|
|
302
|
+
name: string;
|
|
303
|
+
version: string;
|
|
304
|
+
description?: string;
|
|
305
|
+
type?: "commonjs" | "module";
|
|
306
|
+
main?: string;
|
|
307
|
+
types?: string;
|
|
308
|
+
exports?: Record<string, unknown>;
|
|
309
|
+
scripts?: Record<string, string>;
|
|
310
|
+
dependencies?: Record<string, string>;
|
|
311
|
+
devDependencies?: Record<string, string>;
|
|
312
|
+
peerDependencies?: Record<string, string>;
|
|
313
|
+
optionalDependencies?: Record<string, string>;
|
|
314
|
+
keywords?: string[];
|
|
315
|
+
author?: string | { name: string; email?: string; url?: string };
|
|
316
|
+
license?: string;
|
|
317
|
+
repository?: string | { type: string; url: string };
|
|
318
|
+
bugs?: string | { url: string; email?: string };
|
|
319
|
+
homepage?: string;
|
|
320
|
+
engines?: Record<string, string>;
|
|
321
|
+
files?: string[];
|
|
322
|
+
private?: boolean;
|
|
323
|
+
publishConfig?: Record<string, unknown>;
|
|
324
|
+
"node-red"?: {
|
|
325
|
+
nodes?: Record<string, string>;
|
|
326
|
+
version?: string;
|
|
327
|
+
};
|
|
328
|
+
[key: string]: unknown;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
interface ServerBuildOptions {
|
|
332
|
+
/** Source directory for server code. @default "./src/server" */
|
|
333
|
+
srcDir?: string;
|
|
334
|
+
/** Entry filename relative to srcDir. @default "index.ts" */
|
|
335
|
+
entry?: string;
|
|
336
|
+
/** Output format. "esm" builds to .mjs with a CJS bridge for Node-RED. @default "esm" */
|
|
337
|
+
format?: "cjs" | "esm";
|
|
338
|
+
/** Dependencies to bundle into the output instead of keeping as external. @default [] */
|
|
339
|
+
bundled?: string[];
|
|
340
|
+
/** Generate rolled-up .d.ts type declarations (production only). @default true */
|
|
341
|
+
types?: boolean;
|
|
342
|
+
/** esbuild target for the server bundle. @default "node22" */
|
|
343
|
+
nodeTarget?: string;
|
|
344
|
+
/** Additional Vite plugins for the server build. */
|
|
345
|
+
plugins: Plugin[];
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
interface ServerPluginOptions {
|
|
349
|
+
nodeRedLauncher: NodeRedLauncher;
|
|
350
|
+
serverBuildOptions: ServerBuildOptions;
|
|
351
|
+
clientBuildOptions: ClientBuildOptions;
|
|
352
|
+
extraFilesCopyTargets: CopyTarget[];
|
|
353
|
+
buildContext: BuildContext;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export {
|
|
357
|
+
BuildContext,
|
|
358
|
+
BuildPluginOptions,
|
|
359
|
+
ClientBuildOptions,
|
|
360
|
+
CopyTarget,
|
|
361
|
+
LocalesOptions,
|
|
362
|
+
LoggerOptions,
|
|
363
|
+
NodeRedLauncherOptions,
|
|
364
|
+
NodeRedPluginOptions,
|
|
365
|
+
NodeRedRuntimeSettings,
|
|
366
|
+
PackageJson,
|
|
367
|
+
ServerBuildOptions,
|
|
368
|
+
ServerPluginOptions,
|
|
369
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import type { NodeRedRuntimeSettings, PackageJson } from "./types";
|
|
4
|
+
|
|
5
|
+
function cleanDir(dir: string) {
|
|
6
|
+
if (fs.existsSync(dir)) {
|
|
7
|
+
fs.rmSync(dir, { recursive: true });
|
|
8
|
+
}
|
|
9
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function copyFiles(targets: CopyTarget[], outDir: string): void {
|
|
13
|
+
for (const { src, dest } of targets) {
|
|
14
|
+
const srcPath = path.resolve(src);
|
|
15
|
+
const destPath = path.join(outDir, dest);
|
|
16
|
+
|
|
17
|
+
if (!fs.existsSync(srcPath)) {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const stat = fs.statSync(srcPath);
|
|
22
|
+
|
|
23
|
+
if (stat.isDirectory()) {
|
|
24
|
+
fs.cpSync(srcPath, destPath, { recursive: true });
|
|
25
|
+
} else {
|
|
26
|
+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
27
|
+
fs.copyFileSync(srcPath, destPath);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getPackageName(): string {
|
|
33
|
+
const pkgPath = path.resolve("./package.json");
|
|
34
|
+
if (fs.existsSync(pkgPath)) {
|
|
35
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8")) as PackageJson;
|
|
36
|
+
return pkg.name;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return "node-red-nodes";
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function mergeOptions<T extends Record<string, unknown>>(
|
|
43
|
+
defaults: T,
|
|
44
|
+
overrides?: Partial<T>,
|
|
45
|
+
): T {
|
|
46
|
+
if (!overrides) return { ...defaults };
|
|
47
|
+
|
|
48
|
+
const result = { ...defaults };
|
|
49
|
+
for (const key of Object.keys(overrides) as (keyof T)[]) {
|
|
50
|
+
const overrideVal = overrides[key];
|
|
51
|
+
const defaultVal = defaults[key];
|
|
52
|
+
if (
|
|
53
|
+
overrideVal !== undefined &&
|
|
54
|
+
!Array.isArray(overrideVal) &&
|
|
55
|
+
!Array.isArray(defaultVal) &&
|
|
56
|
+
typeof overrideVal === "object" &&
|
|
57
|
+
typeof defaultVal === "object" &&
|
|
58
|
+
overrideVal !== null &&
|
|
59
|
+
defaultVal !== null
|
|
60
|
+
) {
|
|
61
|
+
result[key] = mergeOptions(
|
|
62
|
+
defaultVal as Record<string, unknown>,
|
|
63
|
+
overrideVal as Record<string, unknown>,
|
|
64
|
+
) as T[keyof T];
|
|
65
|
+
} else if (overrideVal !== undefined) {
|
|
66
|
+
result[key] = overrideVal as T[keyof T];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Define Node-RED runtime settings with full type support.
|
|
74
|
+
*
|
|
75
|
+
* Note: All paths should be absolute. Use `import.meta.dirname` or `__dirname` to resolve relative paths.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* import { defineRuntimeSettings } from "./vite/utils";
|
|
80
|
+
* import path from "path";
|
|
81
|
+
*
|
|
82
|
+
* const __dirname = import.meta.dirname;
|
|
83
|
+
*
|
|
84
|
+
* export default defineRuntimeSettings({
|
|
85
|
+
* userDir: path.resolve(__dirname, ".node-red"),
|
|
86
|
+
* flowFile: "flows.json",
|
|
87
|
+
* httpStatic: path.resolve(__dirname, "public"),
|
|
88
|
+
* });
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
function defineRuntimeSettings(
|
|
92
|
+
settings: NodeRedRuntimeSettings,
|
|
93
|
+
): NodeRedRuntimeSettings {
|
|
94
|
+
return settings;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export {
|
|
98
|
+
cleanDir,
|
|
99
|
+
copyFiles,
|
|
100
|
+
defineRuntimeSettings,
|
|
101
|
+
getPackageName,
|
|
102
|
+
mergeOptions,
|
|
103
|
+
};
|