@bonsae/nrg 0.6.0 → 0.6.2
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 +5 -5
- package/package.json +14 -75
- package/{build/server → server}/index.cjs +1 -1
- package/{src/core/client → shims}/components.d.ts +2 -0
- package/{src/tsconfig → tsconfig}/client.json +3 -3
- package/types/client.d.ts +37 -0
- package/types/index.d.ts +211 -0
- package/types/server.d.ts +2293 -0
- package/types/vite.d.ts +12 -0
- package/{build/vite → vite}/index.js +95 -0
- package/build/vite/utils.js +0 -56
- package/src/core/client/app.vue +0 -185
- package/src/core/client/components/node-red-config-input.vue +0 -79
- package/src/core/client/components/node-red-editor-input.vue +0 -307
- package/src/core/client/components/node-red-input-label.vue +0 -53
- package/src/core/client/components/node-red-input.vue +0 -93
- package/src/core/client/components/node-red-json-schema-form.vue +0 -444
- package/src/core/client/components/node-red-select-input.vue +0 -108
- package/src/core/client/components/node-red-toggle.vue +0 -115
- package/src/core/client/components/node-red-typed-input.vue +0 -158
- package/src/core/client/index.ts +0 -500
- package/src/core/client/tsconfig.json +0 -18
- package/src/core/constants.ts +0 -18
- package/src/core/errors.ts +0 -9
- package/src/core/server/api/index.ts +0 -1
- package/src/core/server/api/serve-nrg-resources.ts +0 -54
- package/src/core/server/index.ts +0 -190
- package/src/core/server/nodes/config-node.ts +0 -67
- package/src/core/server/nodes/factories.ts +0 -133
- package/src/core/server/nodes/index.ts +0 -5
- package/src/core/server/nodes/io-node.ts +0 -179
- package/src/core/server/nodes/node.ts +0 -259
- package/src/core/server/nodes/types/config-node.ts +0 -28
- package/src/core/server/nodes/types/factories.ts +0 -115
- package/src/core/server/nodes/types/index.ts +0 -4
- package/src/core/server/nodes/types/io-node.ts +0 -40
- package/src/core/server/nodes/types/node.ts +0 -41
- package/src/core/server/nodes/utils.ts +0 -106
- package/src/core/server/schemas/base.ts +0 -66
- package/src/core/server/schemas/index.ts +0 -3
- package/src/core/server/schemas/type.ts +0 -95
- package/src/core/server/schemas/types/index.ts +0 -82
- package/src/core/server/tsconfig.json +0 -17
- package/src/core/server/types/index.ts +0 -220
- package/src/core/server/utils.ts +0 -56
- package/src/core/server/validator.ts +0 -36
- package/src/core/validator.ts +0 -222
- package/src/index.ts +0 -2
- package/src/types.ts +0 -189
- package/src/utils.ts +0 -20
- package/src/vite/async-utils.ts +0 -61
- package/src/vite/client/build.ts +0 -227
- package/src/vite/client/index.ts +0 -1
- package/src/vite/client/plugins/html-generator.ts +0 -75
- package/src/vite/client/plugins/index.ts +0 -5
- package/src/vite/client/plugins/locales-generator.ts +0 -126
- package/src/vite/client/plugins/minifier.ts +0 -23
- package/src/vite/client/plugins/node-definitions-inliner.ts +0 -275
- package/src/vite/client/plugins/static-copy.ts +0 -43
- package/src/vite/defaults.ts +0 -77
- package/src/vite/errors.ts +0 -37
- package/src/vite/index.ts +0 -2
- package/src/vite/logger.ts +0 -94
- package/src/vite/node-red-launcher.ts +0 -344
- package/src/vite/plugin.ts +0 -61
- package/src/vite/plugins/build.ts +0 -85
- package/src/vite/plugins/index.ts +0 -2
- package/src/vite/plugins/server.ts +0 -267
- package/src/vite/server/build.ts +0 -124
- package/src/vite/server/index.ts +0 -1
- package/src/vite/server/plugins/index.ts +0 -3
- package/src/vite/server/plugins/output-wrapper.ts +0 -109
- package/src/vite/server/plugins/package-json-generator.ts +0 -203
- package/src/vite/server/plugins/type-generator.ts +0 -285
- package/src/vite/types.ts +0 -174
- package/src/vite/utils.ts +0 -72
- /package/{build/index.js → index.js} +0 -0
- /package/{build/server → server}/resources/nrg-client.js +0 -0
- /package/{build/server → server}/resources/vue.esm-browser.js +0 -0
- /package/{build/server → server}/resources/vue.esm-browser.prod.js +0 -0
- /package/{src/core/client → shims}/globals.d.ts +0 -0
- /package/{src/core/client → shims}/shims-vue.d.ts +0 -0
- /package/{src/tsconfig → tsconfig}/base.json +0 -0
- /package/{src/tsconfig → tsconfig}/server.json +0 -0
|
@@ -1,344 +0,0 @@
|
|
|
1
|
-
import type { ChildProcess } from "child_process";
|
|
2
|
-
import { spawn } from "child_process";
|
|
3
|
-
import getPort from "get-port";
|
|
4
|
-
import detect from "detect-port";
|
|
5
|
-
import { builtinModules } from "module";
|
|
6
|
-
import treeKill from "tree-kill";
|
|
7
|
-
import fs from "fs";
|
|
8
|
-
import os from "os";
|
|
9
|
-
import path from "path";
|
|
10
|
-
import { build as esbuild } from "esbuild";
|
|
11
|
-
import { withTimeout, retry } from "./async-utils";
|
|
12
|
-
import { NodeRedStartError } from "./errors";
|
|
13
|
-
import { Logger } from "./logger";
|
|
14
|
-
import type { Logger, NodeRedLauncherOptions } from "./types";
|
|
15
|
-
|
|
16
|
-
class NodeRedLauncher {
|
|
17
|
-
private compiledRuntimeSettingsFilepath: string | null = null;
|
|
18
|
-
private process: ChildProcess | null = null;
|
|
19
|
-
private bufferedLogs: string[] = [];
|
|
20
|
-
private isReady: boolean = false;
|
|
21
|
-
private port: number | null = null;
|
|
22
|
-
|
|
23
|
-
private readonly outDir: string;
|
|
24
|
-
private readonly options: NodeRedLauncherOptions;
|
|
25
|
-
private readonly logger: Logger;
|
|
26
|
-
|
|
27
|
-
constructor(outDir: string, options: NodeRedLauncherOptions) {
|
|
28
|
-
this.outDir = outDir;
|
|
29
|
-
this.options = options;
|
|
30
|
-
this.logger = new Logger({
|
|
31
|
-
name: "vite-plugin-node-red",
|
|
32
|
-
prefix: "node-red",
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
get preferredPort(): number {
|
|
37
|
-
return this.options.runtime?.port ?? 1880;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
get restartDelay(): number {
|
|
41
|
-
return this.options.restartDelay ?? 1000;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
get pid(): number | null {
|
|
45
|
-
return this.process?.pid ?? null;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
get nodeRedCommand(): string {
|
|
49
|
-
const version = this.options.runtime?.version;
|
|
50
|
-
if (version === "latest") {
|
|
51
|
-
return "node-red@latest";
|
|
52
|
-
}
|
|
53
|
-
if (version) {
|
|
54
|
-
return `node-red@${version}`;
|
|
55
|
-
}
|
|
56
|
-
return "node-red";
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
private findRuntimeSettingsFilepath(): string | null {
|
|
60
|
-
const runtimeSettingsFilepath = this.options.runtime.settingsFilepath;
|
|
61
|
-
if (runtimeSettingsFilepath) {
|
|
62
|
-
const resolved = path.resolve(runtimeSettingsFilepath);
|
|
63
|
-
if (fs.existsSync(resolved)) {
|
|
64
|
-
return resolved;
|
|
65
|
-
}
|
|
66
|
-
this.logger.warn(`Settings file not found: ${runtimeSettingsFilepath}`);
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const resolved = path.resolve("node-red.settings.ts");
|
|
71
|
-
if (fs.existsSync(resolved)) {
|
|
72
|
-
return resolved;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
private async compileRuntimeSettingsFile(
|
|
79
|
-
runtimeSettingsFilepath: string,
|
|
80
|
-
): Promise<string> {
|
|
81
|
-
const compiledRuntimeSettingsFilepath = path.join(
|
|
82
|
-
os.tmpdir(),
|
|
83
|
-
`node-red.settings.${process.pid}.cjs`,
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
// NOTE: I need to include "node:" modules which are a new common standard
|
|
87
|
-
const nodeBuiltins = [
|
|
88
|
-
...builtinModules,
|
|
89
|
-
...builtinModules.map((m) => `node:${m}`),
|
|
90
|
-
];
|
|
91
|
-
|
|
92
|
-
const settingsDir = path
|
|
93
|
-
.dirname(runtimeSettingsFilepath)
|
|
94
|
-
.split(path.sep)
|
|
95
|
-
.join("/");
|
|
96
|
-
const settingsFile = runtimeSettingsFilepath.split(path.sep).join("/");
|
|
97
|
-
|
|
98
|
-
// NOTE: im hardcoding node18 because it doesn't really matter
|
|
99
|
-
await esbuild({
|
|
100
|
-
entryPoints: [runtimeSettingsFilepath],
|
|
101
|
-
outfile: compiledRuntimeSettingsFilepath,
|
|
102
|
-
format: "cjs",
|
|
103
|
-
platform: "node",
|
|
104
|
-
target: "node18",
|
|
105
|
-
bundle: true,
|
|
106
|
-
define: {
|
|
107
|
-
"import.meta.dirname": JSON.stringify(settingsDir),
|
|
108
|
-
"import.meta.filename": JSON.stringify(settingsFile),
|
|
109
|
-
"import.meta.url": JSON.stringify(`file://${settingsFile}`),
|
|
110
|
-
},
|
|
111
|
-
external: [...nodeBuiltins, "node-red", "@node-red/*"],
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
this.compiledRuntimeSettingsFilepath = compiledRuntimeSettingsFilepath;
|
|
115
|
-
return compiledRuntimeSettingsFilepath;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
private async generateRuntimeSettingsFile(): Promise<string> {
|
|
119
|
-
const userRuntimeSettingsFilepath = this.findRuntimeSettingsFilepath();
|
|
120
|
-
let compiledRuntimeSettingsFilepath: string | null = null;
|
|
121
|
-
if (userRuntimeSettingsFilepath) {
|
|
122
|
-
compiledRuntimeSettingsFilepath = await this.compileRuntimeSettingsFile(
|
|
123
|
-
userRuntimeSettingsFilepath,
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const outDir = path.resolve(this.outDir).split(path.sep).join("/");
|
|
128
|
-
const cwd = process.cwd().split(path.sep).join("/");
|
|
129
|
-
const userDir = path.resolve(cwd, ".node-red");
|
|
130
|
-
const finalRuntimeSettingsFile = compiledRuntimeSettingsFilepath
|
|
131
|
-
? `
|
|
132
|
-
const compiledRuntimeSettings = require("${compiledRuntimeSettingsFilepath
|
|
133
|
-
.split(path.sep)
|
|
134
|
-
.join("/")}");
|
|
135
|
-
const settings = compiledRuntimeSettings.default || compiledRuntimeSettings;
|
|
136
|
-
settings.uiPort = ${this.port};
|
|
137
|
-
if(!settings.userDir){
|
|
138
|
-
settings.userDir = "${userDir}";
|
|
139
|
-
}
|
|
140
|
-
settings.nodesDir = settings.nodesDir || [];
|
|
141
|
-
if (!settings.nodesDir.includes("${outDir}")) {
|
|
142
|
-
settings.nodesDir.push("${outDir}");
|
|
143
|
-
}
|
|
144
|
-
if(!settings.flowFile){
|
|
145
|
-
settings.flowFile = "flows.json";
|
|
146
|
-
}
|
|
147
|
-
module.exports = settings;
|
|
148
|
-
`
|
|
149
|
-
: `
|
|
150
|
-
const settings = {
|
|
151
|
-
uiPort: ${this.port},
|
|
152
|
-
userDir: "${userDir}",
|
|
153
|
-
flowFile: "flows.json",
|
|
154
|
-
nodesDir: ["${outDir}"],
|
|
155
|
-
};
|
|
156
|
-
module.exports = settings;
|
|
157
|
-
`;
|
|
158
|
-
|
|
159
|
-
const finalRuntimeSettingsFilepath = path.join(
|
|
160
|
-
os.tmpdir(),
|
|
161
|
-
`node-red-settings-final-${process.pid}.cjs`,
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
fs.writeFileSync(finalRuntimeSettingsFilepath, finalRuntimeSettingsFile);
|
|
165
|
-
this.compiledRuntimeSettingsFilepath = finalRuntimeSettingsFilepath;
|
|
166
|
-
return finalRuntimeSettingsFilepath;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
private log(line: string): void {
|
|
170
|
-
if (line.includes("Server now running at")) {
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
this.logger.raw(line);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
async start(): Promise<number> {
|
|
177
|
-
this.port = await getPort({ port: this.preferredPort });
|
|
178
|
-
|
|
179
|
-
const startProcess = (): Promise => {
|
|
180
|
-
// eslint-disable-next-line no-async-promise-executor
|
|
181
|
-
return new Promise(async (resolve, reject) => {
|
|
182
|
-
try {
|
|
183
|
-
const settingsPath = await this.generateRuntimeSettingsFile();
|
|
184
|
-
const args = this.options.args ?? [];
|
|
185
|
-
|
|
186
|
-
this.bufferedLogs = [];
|
|
187
|
-
this.isReady = false;
|
|
188
|
-
|
|
189
|
-
this.process = spawn(
|
|
190
|
-
"npx",
|
|
191
|
-
[this.nodeRedCommand, "-s", settingsPath, ...args],
|
|
192
|
-
{
|
|
193
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
194
|
-
shell: true,
|
|
195
|
-
},
|
|
196
|
-
);
|
|
197
|
-
|
|
198
|
-
this.process.stdout?.on("data", (data) => {
|
|
199
|
-
const lines = data.toString().split("\n").filter(Boolean);
|
|
200
|
-
|
|
201
|
-
for (const line of lines) {
|
|
202
|
-
if (this.isReady) {
|
|
203
|
-
this.log(line);
|
|
204
|
-
} else {
|
|
205
|
-
this.bufferedLogs.push(line);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
if (
|
|
209
|
-
line.includes("Started flows") ||
|
|
210
|
-
line.includes("Server now running")
|
|
211
|
-
) {
|
|
212
|
-
this.isReady = true;
|
|
213
|
-
resolve();
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
this.process.stderr?.on("data", (data) => {
|
|
219
|
-
const lines = data.toString().split("\n").filter(Boolean);
|
|
220
|
-
|
|
221
|
-
for (const line of lines) {
|
|
222
|
-
if (this.isReady) {
|
|
223
|
-
this.logger.error(`${line}`);
|
|
224
|
-
} else {
|
|
225
|
-
this.bufferedLogs.push(line);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
this.process.on("error", (error) => {
|
|
231
|
-
reject(new NodeRedStartError(error));
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
this.process.on("exit", (code) => {
|
|
235
|
-
if (!this.isReady && code !== 0 && code !== null) {
|
|
236
|
-
reject(
|
|
237
|
-
new NodeRedStartError(
|
|
238
|
-
new Error(`Process exited with code ${code}`),
|
|
239
|
-
),
|
|
240
|
-
);
|
|
241
|
-
}
|
|
242
|
-
resolve();
|
|
243
|
-
});
|
|
244
|
-
} catch (error) {
|
|
245
|
-
reject(new NodeRedStartError(error as Error));
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
try {
|
|
251
|
-
await retry(startProcess, { attempts: 3, delay: 100 });
|
|
252
|
-
return this.port;
|
|
253
|
-
} catch (error) {
|
|
254
|
-
if (this.process) {
|
|
255
|
-
const pid = this.process.pid;
|
|
256
|
-
if (pid) {
|
|
257
|
-
treeKill(pid, "SIGKILL");
|
|
258
|
-
}
|
|
259
|
-
this.process = null;
|
|
260
|
-
}
|
|
261
|
-
throw new NodeRedStartError(error as Error);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
async stop(skipPortUsageCheck: boolean = false): Promise<void> {
|
|
266
|
-
if (!this.process) return;
|
|
267
|
-
|
|
268
|
-
const pid = this.process.pid;
|
|
269
|
-
const currentPort = this.port;
|
|
270
|
-
|
|
271
|
-
if (!pid) {
|
|
272
|
-
this.process = null;
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
const stopProcess = new Promise<void>((resolve) => {
|
|
277
|
-
this.process!.once("exit", () => {
|
|
278
|
-
this.process = null;
|
|
279
|
-
resolve();
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
treeKill(pid, "SIGTERM", (error) => {
|
|
283
|
-
if (error) {
|
|
284
|
-
try {
|
|
285
|
-
process.kill(pid, "SIGTERM");
|
|
286
|
-
} catch {
|
|
287
|
-
this.process = null;
|
|
288
|
-
resolve();
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
});
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
try {
|
|
295
|
-
await withTimeout(stopProcess, 10000);
|
|
296
|
-
} catch {
|
|
297
|
-
this.logger.warn("Graceful shutdown timed out, force killing...");
|
|
298
|
-
await new Promise<void>((resolve) => {
|
|
299
|
-
treeKill(pid, "SIGKILL", () => {
|
|
300
|
-
this.process = null;
|
|
301
|
-
resolve();
|
|
302
|
-
});
|
|
303
|
-
});
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
if (!skipPortUsageCheck && currentPort) {
|
|
307
|
-
const checkPortUsage = async (): Promise<void> => {
|
|
308
|
-
const availablePort = await detect(currentPort);
|
|
309
|
-
if (availablePort !== currentPort) {
|
|
310
|
-
throw new Error("Port still in use");
|
|
311
|
-
}
|
|
312
|
-
};
|
|
313
|
-
|
|
314
|
-
try {
|
|
315
|
-
await retry(checkPortUsage, { attempts: 5, delay: 100 });
|
|
316
|
-
} catch {
|
|
317
|
-
this.logger.warn(
|
|
318
|
-
`Port ${currentPort} may still be in use. If restart fails, try again in a few seconds.`,
|
|
319
|
-
);
|
|
320
|
-
}
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
this.port = null;
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
flushLogs(): void {
|
|
327
|
-
for (const line of this.bufferedLogs) {
|
|
328
|
-
this.log(line);
|
|
329
|
-
}
|
|
330
|
-
this.bufferedLogs = [];
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
cleanup(): void {
|
|
334
|
-
if (
|
|
335
|
-
this.compiledRuntimeSettingsFilepath &&
|
|
336
|
-
fs.existsSync(this.compiledRuntimeSettingsFilepath)
|
|
337
|
-
) {
|
|
338
|
-
fs.unlinkSync(this.compiledRuntimeSettingsFilepath);
|
|
339
|
-
this.compiledRuntimeSettingsFilepath = null;
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
export { NodeRedLauncher };
|
package/src/vite/plugin.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from "vite";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import type { NodeRedPluginOptions } from "./types";
|
|
4
|
-
import {
|
|
5
|
-
DEFAULT_CLIENT_BUILD_OPTIONS,
|
|
6
|
-
DEFAULT_SERVER_BUILD_OPTIONS,
|
|
7
|
-
DEFAULT_NODE_RED_LAUNCHER_OPTIONS,
|
|
8
|
-
DEFAULT_EXTRA_FILES_COPY_TARGETS,
|
|
9
|
-
DEFAULT_OUTPUT_DIR,
|
|
10
|
-
} from "./defaults";
|
|
11
|
-
import { getPackageName, mergeOptions } from "./utils";
|
|
12
|
-
import { NodeRedLauncher } from "./node-red-launcher";
|
|
13
|
-
import { serverPlugin, buildPlugin } from "./plugins";
|
|
14
|
-
|
|
15
|
-
function nodeRed(options: NodeRedPluginOptions = {}): Plugin[] {
|
|
16
|
-
const { outDir = DEFAULT_OUTPUT_DIR } = options;
|
|
17
|
-
|
|
18
|
-
const clientBuildOptions = mergeOptions(
|
|
19
|
-
DEFAULT_CLIENT_BUILD_OPTIONS,
|
|
20
|
-
options.clientBuildOptions,
|
|
21
|
-
);
|
|
22
|
-
const serverBuildOptions = mergeOptions(
|
|
23
|
-
DEFAULT_SERVER_BUILD_OPTIONS,
|
|
24
|
-
options.serverBuildOptions,
|
|
25
|
-
);
|
|
26
|
-
const nodeRedLauncherOptions = mergeOptions(
|
|
27
|
-
DEFAULT_NODE_RED_LAUNCHER_OPTIONS,
|
|
28
|
-
options.nodeRedLauncherOptions,
|
|
29
|
-
);
|
|
30
|
-
const extraFilesCopyTargets =
|
|
31
|
-
options.extraFilesCopyTargets ?? DEFAULT_EXTRA_FILES_COPY_TARGETS;
|
|
32
|
-
|
|
33
|
-
const resolvedOutDir = path.resolve(outDir);
|
|
34
|
-
const buildContext = {
|
|
35
|
-
outDir: resolvedOutDir,
|
|
36
|
-
packageName: getPackageName(),
|
|
37
|
-
isDev: process.env.NODE_ENV === "development",
|
|
38
|
-
};
|
|
39
|
-
const nodeRedLauncher = new NodeRedLauncher(
|
|
40
|
-
resolvedOutDir,
|
|
41
|
-
nodeRedLauncherOptions,
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
return [
|
|
45
|
-
serverPlugin({
|
|
46
|
-
nodeRedLauncher,
|
|
47
|
-
serverBuildOptions,
|
|
48
|
-
clientBuildOptions,
|
|
49
|
-
extraFilesCopyTargets,
|
|
50
|
-
buildContext,
|
|
51
|
-
}),
|
|
52
|
-
buildPlugin({
|
|
53
|
-
serverBuildOptions,
|
|
54
|
-
clientBuildOptions,
|
|
55
|
-
extraFilesCopyTargets,
|
|
56
|
-
buildContext,
|
|
57
|
-
}),
|
|
58
|
-
];
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export { nodeRed };
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from "vite";
|
|
2
|
-
import { execSync } from "child_process";
|
|
3
|
-
import fs from "fs";
|
|
4
|
-
import path from "path";
|
|
5
|
-
import { BuildError } from "../errors";
|
|
6
|
-
import { logger } from "../logger";
|
|
7
|
-
import type { BuildPluginOptions } from "../types";
|
|
8
|
-
import { build as buildServer } from "../server";
|
|
9
|
-
import { build as buildClient } from "../client";
|
|
10
|
-
import { cleanDir, copyFiles } from "../utils";
|
|
11
|
-
|
|
12
|
-
function buildPlugin(options: BuildPluginOptions): Plugin {
|
|
13
|
-
const {
|
|
14
|
-
serverBuildOptions,
|
|
15
|
-
clientBuildOptions,
|
|
16
|
-
extraFilesCopyTargets,
|
|
17
|
-
buildContext,
|
|
18
|
-
} = options;
|
|
19
|
-
|
|
20
|
-
return {
|
|
21
|
-
name: "vite-plugin-node-red:build",
|
|
22
|
-
apply: "build",
|
|
23
|
-
|
|
24
|
-
async buildStart() {
|
|
25
|
-
try {
|
|
26
|
-
logger.intro();
|
|
27
|
-
|
|
28
|
-
logger.startSpinner("Type checking");
|
|
29
|
-
const serverTsconfig = path.resolve(
|
|
30
|
-
serverBuildOptions.srcDir ?? "./src/server",
|
|
31
|
-
"tsconfig.json",
|
|
32
|
-
);
|
|
33
|
-
const clientTsconfig = path.resolve(
|
|
34
|
-
clientBuildOptions.srcDir ?? "./src/client",
|
|
35
|
-
"tsconfig.json",
|
|
36
|
-
);
|
|
37
|
-
const tsconfigsToCheck = [serverTsconfig, clientTsconfig].filter((p) =>
|
|
38
|
-
fs.existsSync(p),
|
|
39
|
-
);
|
|
40
|
-
try {
|
|
41
|
-
for (const tsconfig of tsconfigsToCheck) {
|
|
42
|
-
execSync(`npx tsc -p ${tsconfig} --noEmit`, {
|
|
43
|
-
stdio: ["inherit", "pipe", "pipe"],
|
|
44
|
-
encoding: "utf-8",
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
logger.stopSpinner("Type checked");
|
|
48
|
-
} catch (e: any) {
|
|
49
|
-
logger.stopSpinner("Type check failed");
|
|
50
|
-
const output = (e.stdout || "") + (e.stderr || "");
|
|
51
|
-
if (output) {
|
|
52
|
-
console.error(output);
|
|
53
|
-
}
|
|
54
|
-
throw new BuildError("type-check", e);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
logger.startSpinner("Cleaning");
|
|
58
|
-
cleanDir(buildContext.outDir);
|
|
59
|
-
logger.stopSpinner("Cleaned");
|
|
60
|
-
|
|
61
|
-
logger.startSpinner("Building");
|
|
62
|
-
await buildServer(serverBuildOptions, buildContext);
|
|
63
|
-
await buildClient(clientBuildOptions, buildContext);
|
|
64
|
-
logger.stopSpinner("Built");
|
|
65
|
-
|
|
66
|
-
if (extraFilesCopyTargets.length) {
|
|
67
|
-
logger.startSpinner("Copying extra files");
|
|
68
|
-
copyFiles(extraFilesCopyTargets, buildContext.outDir);
|
|
69
|
-
logger.stopSpinner("Copied extra files");
|
|
70
|
-
}
|
|
71
|
-
logger.success("Success");
|
|
72
|
-
process.exit(0);
|
|
73
|
-
} catch (error) {
|
|
74
|
-
if (error instanceof BuildError) {
|
|
75
|
-
logger.error(`Build failed: ${error.message}`, error.cause);
|
|
76
|
-
} else {
|
|
77
|
-
logger.error("Unexpected error during build", error as Error);
|
|
78
|
-
}
|
|
79
|
-
process.exit(1);
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export { buildPlugin };
|