@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,285 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from "vite";
|
|
2
|
-
import dts from "vite-plugin-dts";
|
|
3
|
-
import fs from "fs";
|
|
4
|
-
import path from "path";
|
|
5
|
-
import ts from "typescript";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Recursively collect all .ts files under a directory, excluding .d.ts files.
|
|
9
|
-
*/
|
|
10
|
-
function collectTsFiles(dir: string): string[] {
|
|
11
|
-
if (!fs.existsSync(dir)) return [];
|
|
12
|
-
return fs.readdirSync(dir, { withFileTypes: true }).flatMap((dirent) => {
|
|
13
|
-
const full = path.join(dir, dirent.name);
|
|
14
|
-
if (dirent.isDirectory()) return collectTsFiles(full);
|
|
15
|
-
if (
|
|
16
|
-
dirent.isFile() &&
|
|
17
|
-
dirent.name.endsWith(".ts") &&
|
|
18
|
-
!dirent.name.endsWith(".d.ts")
|
|
19
|
-
)
|
|
20
|
-
return [full];
|
|
21
|
-
return [];
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Convert a file basename (without extension) to PascalCase.
|
|
27
|
-
* E.g. "your-node" → "YourNode", "remote_server" → "RemoteServer"
|
|
28
|
-
*/
|
|
29
|
-
function toPascalCase(name: string): string {
|
|
30
|
-
return name
|
|
31
|
-
.split(/[-_]/)
|
|
32
|
-
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
33
|
-
.join("");
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Positional semantic names for each framework base class.
|
|
38
|
-
* Position i in the generic corresponds to the i-th semantic slot.
|
|
39
|
-
* Users can name their types anything — the position determines meaning.
|
|
40
|
-
*/
|
|
41
|
-
const BASE_CLASS_SLOTS: Record<string, string[]> = {
|
|
42
|
-
IONode: ["Config", "Credentials", "Input", "Output", "Settings"],
|
|
43
|
-
ConfigNode: ["Config", "Credentials", "Settings"],
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Parse a node source file and return `{ localName, semanticName }` pairs for
|
|
48
|
-
* types that should be exported from the package.
|
|
49
|
-
*
|
|
50
|
-
* The semantic name is derived from the generic POSITION in the base class, so
|
|
51
|
-
* a user can name their types anything:
|
|
52
|
-
*
|
|
53
|
-
* export default class MyNode extends IONode<Bananas, MyCreds, …>
|
|
54
|
-
* export type Bananas = { … } → exported as {Ns}Config (position 0)
|
|
55
|
-
* export type MyCreds = { … } → exported as {Ns}Credentials (position 1)
|
|
56
|
-
*
|
|
57
|
-
* Only types that appear as generic args AND are exported from the file are
|
|
58
|
-
* included, so unrelated helper types are never leaked.
|
|
59
|
-
*/
|
|
60
|
-
function getNodeTypeExports(
|
|
61
|
-
filePath: string,
|
|
62
|
-
): Array<{ localName: string; semanticName: string }> {
|
|
63
|
-
const content = fs.readFileSync(filePath, "utf-8");
|
|
64
|
-
const source = ts.createSourceFile(
|
|
65
|
-
filePath,
|
|
66
|
-
content,
|
|
67
|
-
ts.ScriptTarget.ESNext,
|
|
68
|
-
/* setParentNodes */ true,
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
const hasModifier = (node: ts.HasModifiers, kind: ts.SyntaxKind) =>
|
|
72
|
-
(node.modifiers ?? []).some((m) => m.kind === kind);
|
|
73
|
-
|
|
74
|
-
// Collect names of exported type aliases and interfaces.
|
|
75
|
-
const exportedTypeNames = new Set<string>();
|
|
76
|
-
for (const stmt of source.statements) {
|
|
77
|
-
if (
|
|
78
|
-
ts.isTypeAliasDeclaration(stmt) &&
|
|
79
|
-
hasModifier(stmt, ts.SyntaxKind.ExportKeyword)
|
|
80
|
-
) {
|
|
81
|
-
exportedTypeNames.add(stmt.name.text);
|
|
82
|
-
}
|
|
83
|
-
if (
|
|
84
|
-
ts.isInterfaceDeclaration(stmt) &&
|
|
85
|
-
hasModifier(stmt, ts.SyntaxKind.ExportKeyword)
|
|
86
|
-
) {
|
|
87
|
-
exportedTypeNames.add(stmt.name.text);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (exportedTypeNames.size === 0) return [];
|
|
92
|
-
|
|
93
|
-
// Find `export default class … extends BaseClass<T0, T1, …>` and extract
|
|
94
|
-
// the base class name and its generic type argument names by position.
|
|
95
|
-
let baseClassName = "";
|
|
96
|
-
const genericArgNames: string[] = [];
|
|
97
|
-
|
|
98
|
-
for (const stmt of source.statements) {
|
|
99
|
-
if (
|
|
100
|
-
!ts.isClassDeclaration(stmt) ||
|
|
101
|
-
!hasModifier(stmt, ts.SyntaxKind.DefaultKeyword)
|
|
102
|
-
) {
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
for (const clause of stmt.heritageClauses ?? []) {
|
|
106
|
-
if (clause.token !== ts.SyntaxKind.ExtendsKeyword) continue;
|
|
107
|
-
for (const type of clause.types) {
|
|
108
|
-
if (ts.isIdentifier(type.expression)) {
|
|
109
|
-
baseClassName = type.expression.text;
|
|
110
|
-
}
|
|
111
|
-
for (const arg of type.typeArguments ?? []) {
|
|
112
|
-
if (ts.isTypeReferenceNode(arg) && ts.isIdentifier(arg.typeName)) {
|
|
113
|
-
genericArgNames.push(arg.typeName.text);
|
|
114
|
-
} else {
|
|
115
|
-
// Unknown / complex type arg — push empty string to preserve positions.
|
|
116
|
-
genericArgNames.push("");
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
break;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const slots = BASE_CLASS_SLOTS[baseClassName];
|
|
125
|
-
if (!slots) return [];
|
|
126
|
-
|
|
127
|
-
// Build pairs: for each position, if the arg is exported AND we have a
|
|
128
|
-
// semantic name for that slot, include it.
|
|
129
|
-
const result: Array<{ localName: string; semanticName: string }> = [];
|
|
130
|
-
for (let i = 0; i < genericArgNames.length; i++) {
|
|
131
|
-
const localName = genericArgNames[i];
|
|
132
|
-
const semanticName = slots[i];
|
|
133
|
-
if (localName && semanticName && exportedTypeNames.has(localName)) {
|
|
134
|
-
result.push({ localName, semanticName });
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
return result;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Build re-export statements for every file in {srcDir}/nodes/, relative to
|
|
142
|
-
* the given entry file path.
|
|
143
|
-
*
|
|
144
|
-
* Per node file two kinds of statements are generated:
|
|
145
|
-
*
|
|
146
|
-
* // 1. Class re-export — so api-extractor includes the class declaration
|
|
147
|
-
* // in the bundled .d.ts, enabling `import { YourNode }`, `instanceof`,
|
|
148
|
-
* // type assertions `as YourNode`, and `resolveTypedInput<YourNode>()`.
|
|
149
|
-
* export { default as YourNode } from "./nodes/your-node";
|
|
150
|
-
*
|
|
151
|
-
* // 2. Type-only exports — one per exported type alias/interface, prefixed
|
|
152
|
-
* // with the namespace name to avoid collisions across node files.
|
|
153
|
-
* // Enables `import type { YourNodeConfig, YourNodeCredentials }`.
|
|
154
|
-
* export type { Config as YourNodeConfig, Credentials as YourNodeCredentials,
|
|
155
|
-
* Input as YourNodeInput, Output as YourNodeOutput,
|
|
156
|
-
* Settings as YourNodeSettings } from "./nodes/your-node";
|
|
157
|
-
*
|
|
158
|
-
* These statements are appended in memory to the entry file content served to
|
|
159
|
-
* the TypeScript compiler via a `ts.sys.readFile` patch, so api-extractor
|
|
160
|
-
* includes them in the final bundled `.d.ts` without touching any source file.
|
|
161
|
-
* Runtime class values are exposed by `cjsDefaultExportPlugin` dynamically
|
|
162
|
-
* via the `nodes` array on the package function.
|
|
163
|
-
*/
|
|
164
|
-
function buildNodeReexports(srcDir: string, entryFile: string): string {
|
|
165
|
-
const nodesDir = path.join(srcDir, "nodes");
|
|
166
|
-
const nodeFiles = collectTsFiles(nodesDir);
|
|
167
|
-
return nodeFiles
|
|
168
|
-
.map((file) => {
|
|
169
|
-
const rel = path
|
|
170
|
-
.relative(path.dirname(entryFile), file)
|
|
171
|
-
.replace(/\\/g, "/");
|
|
172
|
-
const relPath = rel.startsWith(".") ? rel : `./${rel}`;
|
|
173
|
-
const specifier = relPath.replace(/\.ts$/, "");
|
|
174
|
-
const ns = toPascalCase(path.basename(file, ".ts"));
|
|
175
|
-
|
|
176
|
-
const lines = [`export { default as ${ns} } from "${specifier}";`];
|
|
177
|
-
|
|
178
|
-
const typePairs = getNodeTypeExports(file);
|
|
179
|
-
if (typePairs.length > 0) {
|
|
180
|
-
const prefixed = typePairs
|
|
181
|
-
.map(
|
|
182
|
-
({ localName, semanticName }) =>
|
|
183
|
-
`${localName} as ${ns}${semanticName}`,
|
|
184
|
-
)
|
|
185
|
-
.join(", ");
|
|
186
|
-
lines.push(`export type { ${prefixed} } from "${specifier}";`);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
return lines.join("\n");
|
|
190
|
-
})
|
|
191
|
-
.join("\n");
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
function typeGenerator(options: {
|
|
195
|
-
srcDir: string;
|
|
196
|
-
outDir: string;
|
|
197
|
-
/** Absolute paths of entry files (values from the entryPoints record). */
|
|
198
|
-
entryFiles: string[];
|
|
199
|
-
}): Plugin[] {
|
|
200
|
-
const { srcDir, outDir, entryFiles } = options;
|
|
201
|
-
|
|
202
|
-
// Prefer the server-specific tsconfig (inside srcDir) over the root one.
|
|
203
|
-
// The root tsconfig typically only includes vite.config.ts, while the server
|
|
204
|
-
// tsconfig includes the actual source files needed for declaration emit.
|
|
205
|
-
const serverTsconfig = path.resolve(srcDir, "tsconfig.json");
|
|
206
|
-
const rootTsconfig = path.resolve("tsconfig.json");
|
|
207
|
-
const userTsconfig = fs.existsSync(serverTsconfig)
|
|
208
|
-
? serverTsconfig
|
|
209
|
-
: rootTsconfig;
|
|
210
|
-
// Exclude the user's client dir (sibling of srcDir), any nested client dirs,
|
|
211
|
-
// and the vite/ build-tooling dir — none of these should appear in the
|
|
212
|
-
// published type declarations.
|
|
213
|
-
const clientDir = path.relative(
|
|
214
|
-
process.cwd(),
|
|
215
|
-
path.join(path.dirname(srcDir), "client"),
|
|
216
|
-
);
|
|
217
|
-
|
|
218
|
-
// Absolute resolved path → augmented source content (in-memory only).
|
|
219
|
-
const augmentedContents = new Map<string, string>();
|
|
220
|
-
// Original ts.sys.readFile — restored in closeBundle.
|
|
221
|
-
let origReadFile: typeof ts.sys.readFile | null = null;
|
|
222
|
-
|
|
223
|
-
const nodeTypeExporter: Plugin = {
|
|
224
|
-
name: "vite-plugin-node-red:server:type-exporter",
|
|
225
|
-
enforce: "pre",
|
|
226
|
-
buildStart() {
|
|
227
|
-
augmentedContents.clear();
|
|
228
|
-
for (const entryFile of entryFiles) {
|
|
229
|
-
const reexports = buildNodeReexports(srcDir, entryFile);
|
|
230
|
-
if (!reexports) continue;
|
|
231
|
-
const original = fs.readFileSync(entryFile, "utf-8");
|
|
232
|
-
augmentedContents.set(
|
|
233
|
-
path.resolve(entryFile),
|
|
234
|
-
`${original}\n${reexports}\n`,
|
|
235
|
-
);
|
|
236
|
-
}
|
|
237
|
-
if (augmentedContents.size === 0) return;
|
|
238
|
-
origReadFile = ts.sys.readFile.bind(ts.sys);
|
|
239
|
-
ts.sys.readFile = (fileName, encoding) => {
|
|
240
|
-
const resolved = path.resolve(fileName);
|
|
241
|
-
return (
|
|
242
|
-
augmentedContents.get(resolved) ?? origReadFile!(fileName, encoding)
|
|
243
|
-
);
|
|
244
|
-
};
|
|
245
|
-
},
|
|
246
|
-
closeBundle() {
|
|
247
|
-
if (origReadFile) {
|
|
248
|
-
ts.sys.readFile = origReadFile;
|
|
249
|
-
origReadFile = null;
|
|
250
|
-
}
|
|
251
|
-
augmentedContents.clear();
|
|
252
|
-
},
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
return [
|
|
256
|
-
nodeTypeExporter,
|
|
257
|
-
dts({
|
|
258
|
-
rollupTypes: true,
|
|
259
|
-
rollupOptions: {
|
|
260
|
-
messageCallback(message) {
|
|
261
|
-
if (message.messageId === "console-preamble") {
|
|
262
|
-
message.logLevel = "none";
|
|
263
|
-
}
|
|
264
|
-
},
|
|
265
|
-
},
|
|
266
|
-
outDir,
|
|
267
|
-
...(fs.existsSync(userTsconfig) && { tsconfigPath: userTsconfig }),
|
|
268
|
-
compilerOptions: {
|
|
269
|
-
noEmit: false,
|
|
270
|
-
declaration: true,
|
|
271
|
-
emitDeclarationOnly: true,
|
|
272
|
-
noCheck: true,
|
|
273
|
-
},
|
|
274
|
-
exclude: [
|
|
275
|
-
`${clientDir}/**`,
|
|
276
|
-
"**/client/**",
|
|
277
|
-
"vite/**",
|
|
278
|
-
"node_modules/**",
|
|
279
|
-
"dist/**",
|
|
280
|
-
],
|
|
281
|
-
}),
|
|
282
|
-
].flat();
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
export { typeGenerator };
|
package/src/vite/types.ts
DELETED
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from "vite";
|
|
2
|
-
import type { NodeRedLauncher } from "./node-red-launcher";
|
|
3
|
-
|
|
4
|
-
interface BuildContext {
|
|
5
|
-
outDir: string;
|
|
6
|
-
packageName: string;
|
|
7
|
-
isDev: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
interface BuildPluginOptions {
|
|
11
|
-
serverBuildOptions: ServerBuildOptions;
|
|
12
|
-
clientBuildOptions: ClientBuildOptions;
|
|
13
|
-
extraFilesCopyTargets: CopyTarget[];
|
|
14
|
-
buildContext: BuildContext;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface ClientBuildOptions {
|
|
18
|
-
/** Source directory for client code. @default "./src/client" */
|
|
19
|
-
srcDir?: string;
|
|
20
|
-
/** Entry filename relative to srcDir. @default "index.ts" */
|
|
21
|
-
entry?: string;
|
|
22
|
-
/** Subdirectory name for node definition files. @default "nodes" */
|
|
23
|
-
nodesSubdir?: string;
|
|
24
|
-
/** Pattern to match node definition files. */
|
|
25
|
-
nodeFilePattern?: RegExp;
|
|
26
|
-
/** Global variable name for the UMD/IIFE bundle. @default "NodeRedNodes" */
|
|
27
|
-
name?: string;
|
|
28
|
-
/** Output format for the client bundle. @default "es" */
|
|
29
|
-
format?: "es" | "iife" | "umd";
|
|
30
|
-
/** Base public path for serving resources. */
|
|
31
|
-
base?: string;
|
|
32
|
-
/** Path to LICENSE file to include in the HTML output. @default "./LICENSE" */
|
|
33
|
-
licensePath?: string;
|
|
34
|
-
/** Internationalization options for labels and docs. */
|
|
35
|
-
locales?: LocalesOptions;
|
|
36
|
-
/** Directories for static assets (icons, public files). */
|
|
37
|
-
staticDirs?: {
|
|
38
|
-
/** Directory containing node icons ({type}.png). @default "./src/icons" */
|
|
39
|
-
icons?: string;
|
|
40
|
-
/** Directory for public static files copied to dist/resources/. @default "./src/client/public" */
|
|
41
|
-
public?: string;
|
|
42
|
-
};
|
|
43
|
-
/** Modules to treat as external (not bundled). @default ["jquery", "node-red", "vue", "@bonsae/nrg/client"] */
|
|
44
|
-
external?: string[];
|
|
45
|
-
/** Global variable mappings for external modules. */
|
|
46
|
-
globals?: Record<string, string>;
|
|
47
|
-
/** Custom chunk splitting function for Rollup. */
|
|
48
|
-
manualChunks?: (id: string) => string | undefined;
|
|
49
|
-
/** Additional Vite plugins for the client build. */
|
|
50
|
-
plugins: Plugin[];
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
interface CopyTarget {
|
|
54
|
-
/** Source file or directory path. */
|
|
55
|
-
src: string;
|
|
56
|
-
/** Destination path relative to the output directory. */
|
|
57
|
-
dest: string;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
interface LocalesOptions {
|
|
61
|
-
/** Directory containing documentation files ({type}/{lang}.md or .html). @default "./src/locales/docs" */
|
|
62
|
-
docsDir?: string;
|
|
63
|
-
/** Directory containing label files ({type}/{lang}.json). @default "./src/locales/labels" */
|
|
64
|
-
labelsDir?: string;
|
|
65
|
-
/** Supported languages. @default ["en-US", "de", "es-ES", "fr", "ko", "pt-BR", "ru", "ja", "zh-CN", "zh-TW"] */
|
|
66
|
-
languages?: string[];
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
interface LoggerOptions {
|
|
70
|
-
name: string;
|
|
71
|
-
prefix?: string;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
interface NodeRedLauncherOptions {
|
|
75
|
-
runtime?: {
|
|
76
|
-
/** Port for Node-RED to listen on. @default 1880 */
|
|
77
|
-
port?: number;
|
|
78
|
-
/** Path to the Node-RED settings file (TypeScript supported). @default "./node-red.settings.ts" */
|
|
79
|
-
settingsFilepath?: string;
|
|
80
|
-
/** Node-RED version to install for the dev server. @default "latest" */
|
|
81
|
-
version?: string;
|
|
82
|
-
};
|
|
83
|
-
/** Delay in ms before restarting Node-RED after a file change. @default 1000 */
|
|
84
|
-
restartDelay?: number;
|
|
85
|
-
/** Additional CLI arguments passed to the Node-RED process. */
|
|
86
|
-
args?: string[];
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Options for the `nodeRed()` Vite plugin.
|
|
91
|
-
*
|
|
92
|
-
* All options are optional — defaults work for the standard `src/` directory layout.
|
|
93
|
-
*/
|
|
94
|
-
interface NodeRedPluginOptions {
|
|
95
|
-
/** Output directory for the built Node-RED package. @default "./dist" */
|
|
96
|
-
outDir?: string;
|
|
97
|
-
/** Options for building the client-side editor UI. */
|
|
98
|
-
clientBuildOptions?: ClientBuildOptions;
|
|
99
|
-
/** Options for building the server-side node runtime. */
|
|
100
|
-
serverBuildOptions?: ServerBuildOptions;
|
|
101
|
-
/** Options for the Node-RED dev server launcher. */
|
|
102
|
-
nodeRedLauncherOptions?: NodeRedLauncherOptions;
|
|
103
|
-
/** Extra files to copy into the output directory (e.g., LICENSE, README). */
|
|
104
|
-
extraFilesCopyTargets?: CopyTarget[];
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
interface PackageJson {
|
|
108
|
-
name: string;
|
|
109
|
-
version: string;
|
|
110
|
-
description?: string;
|
|
111
|
-
type?: "commonjs" | "module";
|
|
112
|
-
main?: string;
|
|
113
|
-
types?: string;
|
|
114
|
-
exports?: Record<string, unknown>;
|
|
115
|
-
scripts?: Record<string, string>;
|
|
116
|
-
dependencies?: Record<string, string>;
|
|
117
|
-
devDependencies?: Record<string, string>;
|
|
118
|
-
peerDependencies?: Record<string, string>;
|
|
119
|
-
optionalDependencies?: Record<string, string>;
|
|
120
|
-
keywords?: string[];
|
|
121
|
-
author?: string | { name: string; email?: string; url?: string };
|
|
122
|
-
license?: string;
|
|
123
|
-
repository?: string | { type: string; url: string };
|
|
124
|
-
bugs?: string | { url: string; email?: string };
|
|
125
|
-
homepage?: string;
|
|
126
|
-
engines?: Record<string, string>;
|
|
127
|
-
files?: string[];
|
|
128
|
-
private?: boolean;
|
|
129
|
-
publishConfig?: Record<string, unknown>;
|
|
130
|
-
"node-red"?: {
|
|
131
|
-
nodes?: Record<string, string>;
|
|
132
|
-
version?: string;
|
|
133
|
-
};
|
|
134
|
-
[key: string]: unknown;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
interface ServerBuildOptions {
|
|
138
|
-
/** Source directory for server code. @default "./src/server" */
|
|
139
|
-
srcDir?: string;
|
|
140
|
-
/** Entry filename relative to srcDir. @default "index.ts" */
|
|
141
|
-
entry?: string;
|
|
142
|
-
/** Output format. "esm" builds to .mjs with a CJS bridge for Node-RED. @default "esm" */
|
|
143
|
-
format?: "cjs" | "esm";
|
|
144
|
-
/** Dependencies to bundle into the output instead of keeping as external. @default [] */
|
|
145
|
-
bundled?: string[];
|
|
146
|
-
/** Generate rolled-up .d.ts type declarations (production only). @default true */
|
|
147
|
-
types?: boolean;
|
|
148
|
-
/** esbuild target for the server bundle. @default "node22" */
|
|
149
|
-
nodeTarget?: string;
|
|
150
|
-
/** Additional Vite plugins for the server build. */
|
|
151
|
-
plugins: Plugin[];
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
interface ServerPluginOptions {
|
|
155
|
-
nodeRedLauncher: NodeRedLauncher;
|
|
156
|
-
serverBuildOptions: ServerBuildOptions;
|
|
157
|
-
clientBuildOptions: ClientBuildOptions;
|
|
158
|
-
extraFilesCopyTargets: CopyTarget[];
|
|
159
|
-
buildContext: BuildContext;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
export {
|
|
163
|
-
BuildContext,
|
|
164
|
-
BuildPluginOptions,
|
|
165
|
-
ClientBuildOptions,
|
|
166
|
-
CopyTarget,
|
|
167
|
-
LocalesOptions,
|
|
168
|
-
LoggerOptions,
|
|
169
|
-
NodeRedLauncherOptions,
|
|
170
|
-
NodeRedPluginOptions,
|
|
171
|
-
PackageJson,
|
|
172
|
-
ServerBuildOptions,
|
|
173
|
-
ServerPluginOptions,
|
|
174
|
-
};
|
package/src/vite/utils.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import type { 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
|
-
export { cleanDir, copyFiles, getPackageName, mergeOptions };
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|