@bonsae/nrg 0.21.2 → 0.22.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/LICENSE +21 -0
- package/README.md +2 -3
- package/package.json +14 -9
- package/schemas/labels.schema.json +15 -5
- package/server/index.cjs +2 -1358
- package/test/client/component/index.js +41 -224
- package/test/client/component/setup.js +201 -1475
- package/test/client/e2e/config.js +12 -0
- package/test/client/e2e/index.js +419 -199
- package/test/client/unit/index.js +19 -32
- package/test/client/unit/setup.js +28 -21
- package/test/server/integration/index.js +2 -26
- package/test/server/unit/index.js +2 -184
- package/types/client.d.ts +1 -266
- package/types/server.d.ts +1 -900
- package/types/test-client-component.d.ts +7 -143
- package/types/test-client-e2e.d.ts +0 -6
- package/types/test-client-unit.d.ts +11 -105
- package/types/test-server-integration.d.ts +73 -49
- package/types/test-server-unit.d.ts +26 -2
- package/types/vite.d.ts +2 -0
- package/vite/index.js +378 -150
- package/server/resources/nrg-client.js +0 -7493
- package/test/client/component/nrg.css +0 -1
- package/types/shims/brands.d.ts +0 -32
- package/types/shims/client/form/components/node-red-config-input.vue.d.ts +0 -125
- package/types/shims/client/form/components/node-red-editor-input.vue.d.ts +0 -124
- package/types/shims/client/form/components/node-red-input-label.vue.d.ts +0 -34
- package/types/shims/client/form/components/node-red-input.vue.d.ts +0 -123
- package/types/shims/client/form/components/node-red-json-schema-form.vue.d.ts +0 -772
- package/types/shims/client/form/components/node-red-select-input.vue.d.ts +0 -132
- package/types/shims/client/form/components/node-red-toggle.vue.d.ts +0 -36
- package/types/shims/client/form/components/node-red-typed-input.vue.d.ts +0 -151
- package/types/shims/client/globals.d.ts +0 -320
- package/types/shims/client/types.d.ts +0 -227
- package/types/shims/components.d.ts +0 -23
- package/types/shims/constants.d.ts +0 -4
- package/types/shims/schema-options.d.ts +0 -24
- package/types/shims/shims-vue.d.ts +0 -5
- package/types/shims/typebox.d.ts +0 -10
package/test/client/e2e/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// src/test/client/e2e/index.ts
|
|
2
|
-
import
|
|
3
|
-
import
|
|
2
|
+
import fs15 from "fs";
|
|
3
|
+
import path14 from "path";
|
|
4
4
|
|
|
5
5
|
// src/test/client/e2e/environment.ts
|
|
6
|
-
import
|
|
7
|
-
import
|
|
6
|
+
import fs14 from "fs";
|
|
7
|
+
import path13 from "path";
|
|
8
8
|
|
|
9
9
|
// src/vite/server/build.ts
|
|
10
10
|
import { build as viteBuild } from "vite";
|
|
@@ -115,6 +115,26 @@ import dts from "vite-plugin-dts";
|
|
|
115
115
|
import fs from "fs";
|
|
116
116
|
import path from "path";
|
|
117
117
|
import ts from "typescript";
|
|
118
|
+
var RUNTIME_TYPE_REWRITES = {
|
|
119
|
+
"@bonsae/nrg/server": "@bonsae/nrg-runtime/server",
|
|
120
|
+
"@bonsae/nrg/client": "@bonsae/nrg-runtime/client"
|
|
121
|
+
};
|
|
122
|
+
function rewriteRuntimeTypeImports(outDir, entryNames) {
|
|
123
|
+
for (const name of entryNames) {
|
|
124
|
+
const dtsPath = path.join(outDir, `${name}.d.ts`);
|
|
125
|
+
if (!fs.existsSync(dtsPath)) continue;
|
|
126
|
+
const original = fs.readFileSync(dtsPath, "utf-8");
|
|
127
|
+
let rewritten = original;
|
|
128
|
+
for (const [from, to] of Object.entries(RUNTIME_TYPE_REWRITES)) {
|
|
129
|
+
const escaped = from.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
130
|
+
const re = new RegExp(`(['"])${escaped}\\1`, "g");
|
|
131
|
+
rewritten = rewritten.replace(re, `$1${to}$1`);
|
|
132
|
+
}
|
|
133
|
+
if (rewritten !== original) {
|
|
134
|
+
fs.writeFileSync(dtsPath, rewritten);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
118
138
|
function collectTsFiles(dir) {
|
|
119
139
|
if (!fs.existsSync(dir)) return [];
|
|
120
140
|
return fs.readdirSync(dir, { withFileTypes: true }).flatMap((dirent) => {
|
|
@@ -489,18 +509,23 @@ ${reexports}
|
|
|
489
509
|
}
|
|
490
510
|
|
|
491
511
|
// src/vite/server/plugins/output-wrapper.ts
|
|
492
|
-
function
|
|
512
|
+
function nrgServerSpecifier(isDev) {
|
|
513
|
+
return isDev ? "@bonsae/nrg/server" : "@bonsae/nrg-runtime/server";
|
|
514
|
+
}
|
|
515
|
+
function cjsWrapper(isDev = false) {
|
|
516
|
+
const serverSpecifier = nrgServerSpecifier(isDev);
|
|
493
517
|
return {
|
|
494
518
|
name: "vite-plugin-node-red:server:cjs-wrapper",
|
|
495
519
|
renderChunk(code, chunk, outputOptions) {
|
|
496
520
|
if (!chunk.isEntry || outputOptions.format !== "cjs") return null;
|
|
497
|
-
const footer = `(function(){var _exp=module.exports&&module.exports.__esModule?module.exports.default:module.exports;if(_exp&&typeof _exp==="object"&&Array.isArray(_exp.nodes)){var _nrg=require(
|
|
521
|
+
const footer = `(function(){var _exp=module.exports&&module.exports.__esModule?module.exports.default:module.exports;if(_exp&&typeof _exp==="object"&&Array.isArray(_exp.nodes)){var _nrg=require(${JSON.stringify(serverSpecifier)});module.exports=_nrg.registerTypes(_exp.nodes);}else if(typeof _exp==="function"&&Array.isArray(_exp.nodes)){module.exports=_exp;_exp.nodes.forEach(function(cls){if(cls&&cls.type){_exp[cls.type.replace(/(?:^|[-_])(\\w)/g,function(_,c){return c.toUpperCase();})] = cls;}});}})();`;
|
|
498
522
|
return { code: `${code}
|
|
499
523
|
${footer}`, map: null };
|
|
500
524
|
}
|
|
501
525
|
};
|
|
502
526
|
}
|
|
503
|
-
function esmWrapper() {
|
|
527
|
+
function esmWrapper(isDev = false) {
|
|
528
|
+
const serverSpecifier = nrgServerSpecifier(isDev);
|
|
504
529
|
return {
|
|
505
530
|
name: "vite-plugin-node-red:server:esm-wrapper",
|
|
506
531
|
renderChunk(code, chunk, outputOptions) {
|
|
@@ -526,7 +551,9 @@ function esmWrapper() {
|
|
|
526
551
|
`import { dirname as __nrgDirname } from "path";`,
|
|
527
552
|
`var __filename = __nrgFileURLToPath(import.meta.url);`,
|
|
528
553
|
`var __dirname = __nrgDirname(__filename);`,
|
|
529
|
-
`import { registerTypes as __nrgRegisterTypes } from
|
|
554
|
+
`import { registerTypes as __nrgRegisterTypes } from ${JSON.stringify(
|
|
555
|
+
serverSpecifier
|
|
556
|
+
)};`,
|
|
530
557
|
``
|
|
531
558
|
].join("\n");
|
|
532
559
|
const replacement = [
|
|
@@ -550,6 +577,12 @@ var nodeBuiltins = /* @__PURE__ */ new Set([
|
|
|
550
577
|
...builtinModules,
|
|
551
578
|
...builtinModules.map((m) => `node:${m}`)
|
|
552
579
|
]);
|
|
580
|
+
var RUNTIME_REWRITES = {
|
|
581
|
+
"@bonsae/nrg/server": "@bonsae/nrg-runtime/server"
|
|
582
|
+
};
|
|
583
|
+
var RUNTIME_VERSION_SOURCE = {
|
|
584
|
+
"@bonsae/nrg-runtime": "@bonsae/nrg"
|
|
585
|
+
};
|
|
553
586
|
function buildTypesPath(entryName) {
|
|
554
587
|
return `./${entryName}.d.ts`;
|
|
555
588
|
}
|
|
@@ -606,7 +639,8 @@ function packageJsonGenerator(options) {
|
|
|
606
639
|
bundled = [],
|
|
607
640
|
types = false,
|
|
608
641
|
entryNames = [],
|
|
609
|
-
format = "cjs"
|
|
642
|
+
format = "cjs",
|
|
643
|
+
isDev = false
|
|
610
644
|
} = options;
|
|
611
645
|
const trackedDependencies = /* @__PURE__ */ new Set();
|
|
612
646
|
return {
|
|
@@ -624,12 +658,13 @@ function packageJsonGenerator(options) {
|
|
|
624
658
|
if (nodeBuiltins.has(source)) {
|
|
625
659
|
return { id: source, external: true };
|
|
626
660
|
}
|
|
627
|
-
const
|
|
661
|
+
const resolved = isDev ? source : RUNTIME_REWRITES[source] ?? source;
|
|
662
|
+
const packageName = resolved.startsWith("@") ? resolved.split("/").slice(0, 2).join("/") : resolved.split("/")[0];
|
|
628
663
|
if (bundled.includes(packageName)) {
|
|
629
664
|
return null;
|
|
630
665
|
}
|
|
631
666
|
trackedDependencies.add(packageName);
|
|
632
|
-
return { id:
|
|
667
|
+
return { id: resolved, external: true };
|
|
633
668
|
}
|
|
634
669
|
},
|
|
635
670
|
closeBundle() {
|
|
@@ -642,14 +677,19 @@ function packageJsonGenerator(options) {
|
|
|
642
677
|
fs2.readFileSync(rootPackageJsonPath, "utf-8")
|
|
643
678
|
);
|
|
644
679
|
const sourceDeps = rootPackageJson.dependencies ?? {};
|
|
680
|
+
const devDeps = rootPackageJson.devDependencies ?? {};
|
|
645
681
|
const peerDeps = rootPackageJson.peerDependencies ?? {};
|
|
646
682
|
let distDependencies = {};
|
|
647
683
|
for (const dep of trackedDependencies) {
|
|
648
684
|
if (peerDeps[dep]) {
|
|
649
685
|
continue;
|
|
650
686
|
}
|
|
687
|
+
const versionSource = RUNTIME_VERSION_SOURCE[dep];
|
|
688
|
+
const sourceVersion = versionSource ? sourceDeps[versionSource] ?? devDeps[versionSource] : void 0;
|
|
651
689
|
if (sourceDeps[dep]) {
|
|
652
690
|
distDependencies[dep] = sourceDeps[dep];
|
|
691
|
+
} else if (sourceVersion) {
|
|
692
|
+
distDependencies[dep] = sourceVersion;
|
|
653
693
|
} else {
|
|
654
694
|
const dependencyPackageJsonPath = path2.resolve(
|
|
655
695
|
`./node_modules/${dep}/package.json`
|
|
@@ -736,9 +776,10 @@ async function build(serverOpts, buildContext) {
|
|
|
736
776
|
bundled,
|
|
737
777
|
types: types && !buildContext.isDev,
|
|
738
778
|
entryNames: Object.keys(entryPoints),
|
|
739
|
-
format
|
|
779
|
+
format,
|
|
780
|
+
isDev: buildContext.isDev
|
|
740
781
|
}),
|
|
741
|
-
isEsm ? esmWrapper() : cjsWrapper()
|
|
782
|
+
isEsm ? esmWrapper(buildContext.isDev) : cjsWrapper(buildContext.isDev)
|
|
742
783
|
];
|
|
743
784
|
if (types && !buildContext.isDev) {
|
|
744
785
|
plugins.push(
|
|
@@ -780,6 +821,9 @@ async function build(serverOpts, buildContext) {
|
|
|
780
821
|
};
|
|
781
822
|
try {
|
|
782
823
|
await viteBuild(config);
|
|
824
|
+
if (types && !buildContext.isDev) {
|
|
825
|
+
rewriteRuntimeTypeImports(buildContext.outDir, Object.keys(entryPoints));
|
|
826
|
+
}
|
|
783
827
|
if (isEsm) {
|
|
784
828
|
const bridgeCode = `'use strict';
|
|
785
829
|
// CJS bridge \u2014 auto-generated by @bonsae/nrg/vite
|
|
@@ -806,12 +850,13 @@ module.exports = function (RED) {
|
|
|
806
850
|
// src/vite/client/build.ts
|
|
807
851
|
import { build as viteBuild2 } from "vite";
|
|
808
852
|
import vue from "@vitejs/plugin-vue";
|
|
809
|
-
import
|
|
810
|
-
import
|
|
853
|
+
import fs10 from "fs";
|
|
854
|
+
import path10 from "path";
|
|
855
|
+
import crypto from "crypto";
|
|
811
856
|
|
|
812
857
|
// src/vite/client/plugins/help-generator.ts
|
|
813
|
-
import
|
|
814
|
-
import
|
|
858
|
+
import fs5 from "fs";
|
|
859
|
+
import path5 from "path";
|
|
815
860
|
import { pathToFileURL } from "url";
|
|
816
861
|
import { createRequire } from "module";
|
|
817
862
|
|
|
@@ -1042,8 +1087,127 @@ function getHelpTranslations(lang) {
|
|
|
1042
1087
|
return translations[lang] ?? translations["en-US"];
|
|
1043
1088
|
}
|
|
1044
1089
|
|
|
1090
|
+
// src/vite/client/plugins/unsafe-types.ts
|
|
1091
|
+
import ts2 from "typescript";
|
|
1092
|
+
import fs4 from "fs";
|
|
1093
|
+
import path4 from "path";
|
|
1094
|
+
var NRG_SERVER_MODULE = "@bonsae/nrg/server";
|
|
1095
|
+
function normalizeType(text) {
|
|
1096
|
+
return text.replace(/\s+/g, " ").trim();
|
|
1097
|
+
}
|
|
1098
|
+
function resolveImports(sf) {
|
|
1099
|
+
const defineSchema = /* @__PURE__ */ new Set();
|
|
1100
|
+
const schemaType = /* @__PURE__ */ new Set();
|
|
1101
|
+
sf.forEachChild((node) => {
|
|
1102
|
+
if (!ts2.isImportDeclaration(node) || !ts2.isStringLiteral(node.moduleSpecifier) || node.moduleSpecifier.text !== NRG_SERVER_MODULE || !node.importClause?.namedBindings || !ts2.isNamedImports(node.importClause.namedBindings)) {
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
for (const el of node.importClause.namedBindings.elements) {
|
|
1106
|
+
const imported = (el.propertyName ?? el.name).text;
|
|
1107
|
+
const local = el.name.text;
|
|
1108
|
+
if (imported === "defineSchema") defineSchema.add(local);
|
|
1109
|
+
if (imported === "SchemaType") schemaType.add(local);
|
|
1110
|
+
}
|
|
1111
|
+
});
|
|
1112
|
+
return { defineSchema, schemaType };
|
|
1113
|
+
}
|
|
1114
|
+
function staticPropName(name) {
|
|
1115
|
+
if (ts2.isIdentifier(name) || ts2.isStringLiteralLike(name)) return name.text;
|
|
1116
|
+
return void 0;
|
|
1117
|
+
}
|
|
1118
|
+
function unsafeTypeArg(node, sf, schemaType) {
|
|
1119
|
+
if (!ts2.isCallExpression(node) || !ts2.isPropertyAccessExpression(node.expression) || !ts2.isIdentifier(node.expression.expression) || !schemaType.has(node.expression.expression.text)) {
|
|
1120
|
+
return void 0;
|
|
1121
|
+
}
|
|
1122
|
+
const method = node.expression.name.text;
|
|
1123
|
+
if (method === "Unsafe" && node.typeArguments?.length) {
|
|
1124
|
+
return normalizeType(node.typeArguments[0].getText(sf));
|
|
1125
|
+
}
|
|
1126
|
+
if (method === "Array" && node.arguments.length) {
|
|
1127
|
+
const inner = unsafeTypeArg(node.arguments[0], sf, schemaType);
|
|
1128
|
+
if (inner) return `${inner}[]`;
|
|
1129
|
+
}
|
|
1130
|
+
return void 0;
|
|
1131
|
+
}
|
|
1132
|
+
function readSchemaCall(call, sf, schemaType) {
|
|
1133
|
+
const [propsArg, optsArg] = call.arguments;
|
|
1134
|
+
if (!propsArg || !optsArg || !ts2.isObjectLiteralExpression(propsArg) || !ts2.isObjectLiteralExpression(optsArg)) {
|
|
1135
|
+
return void 0;
|
|
1136
|
+
}
|
|
1137
|
+
let id;
|
|
1138
|
+
for (const p of optsArg.properties) {
|
|
1139
|
+
if (ts2.isPropertyAssignment(p) && staticPropName(p.name) === "$id" && ts2.isStringLiteralLike(p.initializer)) {
|
|
1140
|
+
id = p.initializer.text;
|
|
1141
|
+
}
|
|
1142
|
+
}
|
|
1143
|
+
if (!id) return void 0;
|
|
1144
|
+
const props = {};
|
|
1145
|
+
for (const p of propsArg.properties) {
|
|
1146
|
+
if (!ts2.isPropertyAssignment(p)) continue;
|
|
1147
|
+
const key = staticPropName(p.name);
|
|
1148
|
+
if (key === void 0) continue;
|
|
1149
|
+
const type = unsafeTypeArg(p.initializer, sf, schemaType);
|
|
1150
|
+
if (type) props[key] = type;
|
|
1151
|
+
}
|
|
1152
|
+
return { id, props };
|
|
1153
|
+
}
|
|
1154
|
+
function extractUnsafeTypesFromSource(fileName, code) {
|
|
1155
|
+
const out = /* @__PURE__ */ new Map();
|
|
1156
|
+
const sf = ts2.createSourceFile(fileName, code, ts2.ScriptTarget.Latest, true);
|
|
1157
|
+
const { defineSchema, schemaType } = resolveImports(sf);
|
|
1158
|
+
if (defineSchema.size === 0 || schemaType.size === 0) return out;
|
|
1159
|
+
const visit = (node) => {
|
|
1160
|
+
if (ts2.isCallExpression(node) && ts2.isIdentifier(node.expression) && defineSchema.has(node.expression.text)) {
|
|
1161
|
+
const result = readSchemaCall(node, sf, schemaType);
|
|
1162
|
+
if (result && Object.keys(result.props).length > 0) {
|
|
1163
|
+
if (out.has(result.id)) {
|
|
1164
|
+
throw new Error(
|
|
1165
|
+
`Duplicate schema $id "${result.id}" in ${fileName} \u2014 $id must be unique`
|
|
1166
|
+
);
|
|
1167
|
+
}
|
|
1168
|
+
out.set(result.id, result.props);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
ts2.forEachChild(node, visit);
|
|
1172
|
+
};
|
|
1173
|
+
visit(sf);
|
|
1174
|
+
return out;
|
|
1175
|
+
}
|
|
1176
|
+
function collectTsFiles2(dir) {
|
|
1177
|
+
const out = [];
|
|
1178
|
+
if (!fs4.existsSync(dir)) return out;
|
|
1179
|
+
for (const entry of fs4.readdirSync(dir, { withFileTypes: true })) {
|
|
1180
|
+
const full = path4.join(dir, entry.name);
|
|
1181
|
+
if (entry.isDirectory()) {
|
|
1182
|
+
if (entry.name === "node_modules") continue;
|
|
1183
|
+
out.push(...collectTsFiles2(full));
|
|
1184
|
+
} else if (entry.name.endsWith(".ts") && !entry.name.endsWith(".d.ts") && !entry.name.endsWith(".test.ts") && !entry.name.endsWith(".spec.ts")) {
|
|
1185
|
+
out.push(full);
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
return out;
|
|
1189
|
+
}
|
|
1190
|
+
function extractUnsafeTypes(srcDir) {
|
|
1191
|
+
const merged = /* @__PURE__ */ new Map();
|
|
1192
|
+
for (const file of collectTsFiles2(srcDir).sort()) {
|
|
1193
|
+
const perFile = extractUnsafeTypesFromSource(
|
|
1194
|
+
file,
|
|
1195
|
+
fs4.readFileSync(file, "utf-8")
|
|
1196
|
+
);
|
|
1197
|
+
for (const [id, props] of perFile) {
|
|
1198
|
+
if (merged.has(id)) {
|
|
1199
|
+
throw new Error(
|
|
1200
|
+
`Duplicate schema $id "${id}" across ${srcDir} \u2014 $id must be unique`
|
|
1201
|
+
);
|
|
1202
|
+
}
|
|
1203
|
+
merged.set(id, props);
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
return merged;
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1045
1209
|
// src/vite/client/plugins/help-generator.ts
|
|
1046
|
-
function buildPropertyRow(name, schema, required, label) {
|
|
1210
|
+
function buildPropertyRow(name, schema, required, label, parsedType) {
|
|
1047
1211
|
let type = "";
|
|
1048
1212
|
if (schema["x-nrg-node-type"]) {
|
|
1049
1213
|
type = `NodeRef \u2192 ${schema["x-nrg-node-type"]}`;
|
|
@@ -1051,6 +1215,8 @@ function buildPropertyRow(name, schema, required, label) {
|
|
|
1051
1215
|
type = "TypedInput";
|
|
1052
1216
|
} else if (schema.type) {
|
|
1053
1217
|
type = String(schema.type);
|
|
1218
|
+
} else if (parsedType) {
|
|
1219
|
+
type = parsedType;
|
|
1054
1220
|
}
|
|
1055
1221
|
if (schema.enum) type += ` (${schema.enum.join(", ")})`;
|
|
1056
1222
|
const constraints = [];
|
|
@@ -1086,16 +1252,19 @@ function generateSchemaSection(options) {
|
|
|
1086
1252
|
t,
|
|
1087
1253
|
labels,
|
|
1088
1254
|
heading = "###",
|
|
1089
|
-
includeDefault = true
|
|
1255
|
+
includeDefault = true,
|
|
1256
|
+
unsafeTypes
|
|
1090
1257
|
} = options;
|
|
1091
1258
|
if (!schema?.properties) return "";
|
|
1259
|
+
const parsed = unsafeTypes?.get(schema.$id);
|
|
1092
1260
|
const required = new Set(schema.required ?? []);
|
|
1093
1261
|
const rows = Object.entries(schema.properties).filter(([key]) => !SKIP_FIELDS.has(key)).map(
|
|
1094
1262
|
([key, propSchema]) => buildPropertyRow(
|
|
1095
1263
|
key,
|
|
1096
1264
|
propSchema,
|
|
1097
1265
|
required.has(key),
|
|
1098
|
-
labels?.[key]
|
|
1266
|
+
labels?.[key],
|
|
1267
|
+
parsed?.[key]
|
|
1099
1268
|
)
|
|
1100
1269
|
);
|
|
1101
1270
|
if (rows.length === 0) return "";
|
|
@@ -1133,9 +1302,9 @@ ${table}
|
|
|
1133
1302
|
`;
|
|
1134
1303
|
}
|
|
1135
1304
|
function loadNodeLabels(labelPath) {
|
|
1136
|
-
if (!
|
|
1305
|
+
if (!fs5.existsSync(labelPath)) return {};
|
|
1137
1306
|
try {
|
|
1138
|
-
const raw = JSON.parse(
|
|
1307
|
+
const raw = JSON.parse(fs5.readFileSync(labelPath, "utf-8"));
|
|
1139
1308
|
return {
|
|
1140
1309
|
description: raw.description,
|
|
1141
1310
|
configs: raw.configs,
|
|
@@ -1147,7 +1316,7 @@ function loadNodeLabels(labelPath) {
|
|
|
1147
1316
|
return {};
|
|
1148
1317
|
}
|
|
1149
1318
|
}
|
|
1150
|
-
function generateHelpDoc(nodeClass, labels, t) {
|
|
1319
|
+
function generateHelpDoc(nodeClass, labels, t, unsafeTypes) {
|
|
1151
1320
|
const lines = [];
|
|
1152
1321
|
if (labels.description) {
|
|
1153
1322
|
lines.push(`<p>${labels.description}</p>`);
|
|
@@ -1156,14 +1325,16 @@ function generateHelpDoc(nodeClass, labels, t) {
|
|
|
1156
1325
|
title: t.sections.properties,
|
|
1157
1326
|
schema: nodeClass.configSchema,
|
|
1158
1327
|
t,
|
|
1159
|
-
labels: labels.configs
|
|
1328
|
+
labels: labels.configs,
|
|
1329
|
+
unsafeTypes
|
|
1160
1330
|
});
|
|
1161
1331
|
if (configSection) lines.push(configSection);
|
|
1162
1332
|
const credsSection = generateSchemaSection({
|
|
1163
1333
|
title: t.sections.credentials,
|
|
1164
1334
|
schema: nodeClass.credentialsSchema,
|
|
1165
1335
|
t,
|
|
1166
|
-
labels: labels.credentials
|
|
1336
|
+
labels: labels.credentials,
|
|
1337
|
+
unsafeTypes
|
|
1167
1338
|
});
|
|
1168
1339
|
if (credsSection) lines.push(credsSection);
|
|
1169
1340
|
if (nodeClass.inputSchema) {
|
|
@@ -1172,7 +1343,8 @@ function generateHelpDoc(nodeClass, labels, t) {
|
|
|
1172
1343
|
schema: nodeClass.inputSchema,
|
|
1173
1344
|
t,
|
|
1174
1345
|
labels: labels.input,
|
|
1175
|
-
includeDefault: false
|
|
1346
|
+
includeDefault: false,
|
|
1347
|
+
unsafeTypes
|
|
1176
1348
|
});
|
|
1177
1349
|
if (inputSection) lines.push(inputSection);
|
|
1178
1350
|
}
|
|
@@ -1189,7 +1361,8 @@ function generateHelpDoc(nodeClass, labels, t) {
|
|
|
1189
1361
|
t,
|
|
1190
1362
|
labels: portPropLabels,
|
|
1191
1363
|
heading: "####",
|
|
1192
|
-
includeDefault: false
|
|
1364
|
+
includeDefault: false,
|
|
1365
|
+
unsafeTypes
|
|
1193
1366
|
});
|
|
1194
1367
|
if (section) portSections.push(section);
|
|
1195
1368
|
});
|
|
@@ -1209,7 +1382,8 @@ ${portSections.join("\n")}`
|
|
|
1209
1382
|
t,
|
|
1210
1383
|
labels: portPropLabels,
|
|
1211
1384
|
heading: "####",
|
|
1212
|
-
includeDefault: false
|
|
1385
|
+
includeDefault: false,
|
|
1386
|
+
unsafeTypes
|
|
1213
1387
|
});
|
|
1214
1388
|
if (section) portSections.push(section);
|
|
1215
1389
|
}
|
|
@@ -1226,7 +1400,8 @@ ${portSections.join("\n")}`
|
|
|
1226
1400
|
schema: os3,
|
|
1227
1401
|
t,
|
|
1228
1402
|
labels: outputPropLabels,
|
|
1229
|
-
includeDefault: false
|
|
1403
|
+
includeDefault: false,
|
|
1404
|
+
unsafeTypes
|
|
1230
1405
|
});
|
|
1231
1406
|
if (section) lines.push(section);
|
|
1232
1407
|
}
|
|
@@ -1234,26 +1409,26 @@ ${portSections.join("\n")}`
|
|
|
1234
1409
|
return lines.join("\n").trim();
|
|
1235
1410
|
}
|
|
1236
1411
|
function discoverLanguages(labelsDir, nodeType) {
|
|
1237
|
-
const nodeLabelsDir =
|
|
1238
|
-
if (!
|
|
1239
|
-
return
|
|
1412
|
+
const nodeLabelsDir = path5.join(labelsDir, nodeType);
|
|
1413
|
+
if (!fs5.existsSync(nodeLabelsDir)) return [];
|
|
1414
|
+
return fs5.readdirSync(nodeLabelsDir).filter((f) => f.endsWith(".json")).map((f) => path5.basename(f, ".json"));
|
|
1240
1415
|
}
|
|
1241
1416
|
function helpGenerator(options) {
|
|
1242
|
-
const { outDir, localesOutDir, docsDir, labelsDir } = options;
|
|
1417
|
+
const { outDir, localesOutDir, docsDir, labelsDir, srcDir } = options;
|
|
1243
1418
|
return {
|
|
1244
1419
|
name: "vite-plugin-node-red:client:help-generator",
|
|
1245
1420
|
apply: "build",
|
|
1246
1421
|
enforce: "post",
|
|
1247
1422
|
async closeBundle() {
|
|
1248
|
-
const esmPath =
|
|
1249
|
-
const cjsPath =
|
|
1423
|
+
const esmPath = path5.resolve(outDir, "index.mjs");
|
|
1424
|
+
const cjsPath = path5.resolve(outDir, "index.js");
|
|
1250
1425
|
let packageFn;
|
|
1251
1426
|
try {
|
|
1252
|
-
if (
|
|
1427
|
+
if (fs5.existsSync(esmPath)) {
|
|
1253
1428
|
const fileUrl = pathToFileURL(esmPath).href + `?t=${Date.now()}`;
|
|
1254
1429
|
const mod = await import(fileUrl);
|
|
1255
1430
|
packageFn = mod?.default ?? mod;
|
|
1256
|
-
} else if (
|
|
1431
|
+
} else if (fs5.existsSync(cjsPath)) {
|
|
1257
1432
|
const require2 = createRequire(import.meta.url);
|
|
1258
1433
|
delete require2.cache[cjsPath];
|
|
1259
1434
|
const rawMod = require2(cjsPath);
|
|
@@ -1263,6 +1438,7 @@ function helpGenerator(options) {
|
|
|
1263
1438
|
return;
|
|
1264
1439
|
}
|
|
1265
1440
|
const nodeClasses = packageFn?.nodes ?? [];
|
|
1441
|
+
const unsafeTypes = srcDir ? extractUnsafeTypes(srcDir) : void 0;
|
|
1266
1442
|
const helpByLang = /* @__PURE__ */ new Map();
|
|
1267
1443
|
for (const NodeClass of nodeClasses) {
|
|
1268
1444
|
const type = NodeClass.type;
|
|
@@ -1270,13 +1446,13 @@ function helpGenerator(options) {
|
|
|
1270
1446
|
const languages = discoverLanguages(labelsDir, type);
|
|
1271
1447
|
if (!languages.includes("en-US")) languages.push("en-US");
|
|
1272
1448
|
for (const lang of languages) {
|
|
1273
|
-
const manualMd =
|
|
1274
|
-
const manualHtml =
|
|
1275
|
-
if (
|
|
1276
|
-
const labelPath =
|
|
1449
|
+
const manualMd = path5.join(docsDir, type, `${lang}.md`);
|
|
1450
|
+
const manualHtml = path5.join(docsDir, type, `${lang}.html`);
|
|
1451
|
+
if (fs5.existsSync(manualMd) || fs5.existsSync(manualHtml)) continue;
|
|
1452
|
+
const labelPath = path5.join(labelsDir, type, `${lang}.json`);
|
|
1277
1453
|
const labels = loadNodeLabels(labelPath);
|
|
1278
1454
|
const t = getHelpTranslations(lang);
|
|
1279
|
-
const content = generateHelpDoc(NodeClass, labels, t);
|
|
1455
|
+
const content = generateHelpDoc(NodeClass, labels, t, unsafeTypes);
|
|
1280
1456
|
if (!content) continue;
|
|
1281
1457
|
if (!helpByLang.has(lang)) helpByLang.set(lang, []);
|
|
1282
1458
|
helpByLang.get(lang).push(
|
|
@@ -1287,11 +1463,11 @@ ${content}
|
|
|
1287
1463
|
}
|
|
1288
1464
|
}
|
|
1289
1465
|
for (const [lang, scripts] of helpByLang) {
|
|
1290
|
-
const langDir =
|
|
1291
|
-
|
|
1292
|
-
const indexPath =
|
|
1293
|
-
const existing =
|
|
1294
|
-
|
|
1466
|
+
const langDir = path5.join(localesOutDir, lang);
|
|
1467
|
+
fs5.mkdirSync(langDir, { recursive: true });
|
|
1468
|
+
const indexPath = path5.join(langDir, "index.html");
|
|
1469
|
+
const existing = fs5.existsSync(indexPath) ? fs5.readFileSync(indexPath, "utf-8") : "";
|
|
1470
|
+
fs5.writeFileSync(
|
|
1295
1471
|
indexPath,
|
|
1296
1472
|
existing + (existing ? "\n" : "") + scripts.join("\n"),
|
|
1297
1473
|
"utf-8"
|
|
@@ -1303,8 +1479,8 @@ ${content}
|
|
|
1303
1479
|
|
|
1304
1480
|
// src/vite/client/plugins/html-generator.ts
|
|
1305
1481
|
import mime from "mime-types";
|
|
1306
|
-
import
|
|
1307
|
-
import
|
|
1482
|
+
import fs6 from "fs";
|
|
1483
|
+
import path6 from "path";
|
|
1308
1484
|
function htmlGenerator(options) {
|
|
1309
1485
|
const { packageName, licensePath } = options;
|
|
1310
1486
|
return {
|
|
@@ -1314,7 +1490,7 @@ function htmlGenerator(options) {
|
|
|
1314
1490
|
generateBundle(_, bundle) {
|
|
1315
1491
|
const resourcesTags = Object.keys(bundle).map((fileName) => {
|
|
1316
1492
|
const asset = bundle[fileName];
|
|
1317
|
-
const srcPath =
|
|
1493
|
+
const srcPath = path6.join(
|
|
1318
1494
|
"resources",
|
|
1319
1495
|
packageName,
|
|
1320
1496
|
fileName.replace(/^resources\/?/, "")
|
|
@@ -1342,8 +1518,8 @@ function htmlGenerator(options) {
|
|
|
1342
1518
|
return null;
|
|
1343
1519
|
}
|
|
1344
1520
|
}).filter(Boolean).join("\n");
|
|
1345
|
-
const licenseBanner = licensePath &&
|
|
1346
|
-
${
|
|
1521
|
+
const licenseBanner = licensePath && fs6.existsSync(licensePath) ? `<!--
|
|
1522
|
+
${fs6.readFileSync(licensePath, "utf-8")}
|
|
1347
1523
|
-->` : "";
|
|
1348
1524
|
this.emitFile({
|
|
1349
1525
|
type: "asset",
|
|
@@ -1356,8 +1532,8 @@ ${resourcesTags}`
|
|
|
1356
1532
|
}
|
|
1357
1533
|
|
|
1358
1534
|
// src/vite/client/plugins/locales-generator.ts
|
|
1359
|
-
import
|
|
1360
|
-
import
|
|
1535
|
+
import fs7 from "fs";
|
|
1536
|
+
import path7 from "path";
|
|
1361
1537
|
import { merge } from "es-toolkit";
|
|
1362
1538
|
function localesGenerator(options) {
|
|
1363
1539
|
const { outDir, docsDir, labelsDir } = options;
|
|
@@ -1740,17 +1916,17 @@ Supported: ${languages.join(", ")}`
|
|
|
1740
1916
|
}
|
|
1741
1917
|
function forEachFile(baseDir, fileExtensions, processFile) {
|
|
1742
1918
|
const langMap = /* @__PURE__ */ new Map();
|
|
1743
|
-
if (!
|
|
1744
|
-
const nodeDirs =
|
|
1919
|
+
if (!fs7.existsSync(baseDir)) return langMap;
|
|
1920
|
+
const nodeDirs = fs7.readdirSync(baseDir, { withFileTypes: true }).filter((d) => d.isDirectory());
|
|
1745
1921
|
for (const nodeDir of nodeDirs) {
|
|
1746
1922
|
const nodeType = nodeDir.name;
|
|
1747
|
-
const nodePath =
|
|
1748
|
-
const files =
|
|
1923
|
+
const nodePath = path7.join(baseDir, nodeType);
|
|
1924
|
+
const files = fs7.readdirSync(nodePath);
|
|
1749
1925
|
for (const file of files) {
|
|
1750
|
-
const ext =
|
|
1926
|
+
const ext = path7.extname(file);
|
|
1751
1927
|
if (!fileExtensions.includes(ext)) continue;
|
|
1752
|
-
const lang =
|
|
1753
|
-
const filePath =
|
|
1928
|
+
const lang = path7.basename(file, ext);
|
|
1929
|
+
const filePath = path7.join(nodePath, file);
|
|
1754
1930
|
validateLanguage(lang, filePath);
|
|
1755
1931
|
const value = processFile({ ext, filePath, nodeType });
|
|
1756
1932
|
if (value == null) continue;
|
|
@@ -1768,10 +1944,10 @@ Supported: ${languages.join(", ")}`
|
|
|
1768
1944
|
}
|
|
1769
1945
|
function writeOutput(langMap, fileName, serialize) {
|
|
1770
1946
|
for (const [lang, data] of langMap.entries()) {
|
|
1771
|
-
const langOutDir =
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1947
|
+
const langOutDir = path7.join(outDir, lang);
|
|
1948
|
+
fs7.mkdirSync(langOutDir, { recursive: true });
|
|
1949
|
+
fs7.writeFileSync(
|
|
1950
|
+
path7.join(langOutDir, fileName),
|
|
1775
1951
|
serialize(data),
|
|
1776
1952
|
"utf-8"
|
|
1777
1953
|
);
|
|
@@ -1783,7 +1959,7 @@ Supported: ${languages.join(", ")}`
|
|
|
1783
1959
|
({ ext, filePath, nodeType }) => {
|
|
1784
1960
|
const type = ext === ".html" ? "text/html" : ext === ".md" ? "text/markdown" : null;
|
|
1785
1961
|
if (!type) return null;
|
|
1786
|
-
const content =
|
|
1962
|
+
const content = fs7.readFileSync(filePath, "utf-8");
|
|
1787
1963
|
return [
|
|
1788
1964
|
`<script type="${type}" data-help-name="${nodeType}">
|
|
1789
1965
|
${content}
|
|
@@ -1800,7 +1976,7 @@ ${content}
|
|
|
1800
1976
|
labelsDir,
|
|
1801
1977
|
[".json"],
|
|
1802
1978
|
({ filePath, nodeType }) => {
|
|
1803
|
-
const parsed = JSON.parse(
|
|
1979
|
+
const parsed = JSON.parse(fs7.readFileSync(filePath, "utf-8"));
|
|
1804
1980
|
if (parsed[nodeType] && typeof parsed[nodeType] === "object") {
|
|
1805
1981
|
console.warn(
|
|
1806
1982
|
`[locales] Warning: "${filePath}" uses nested format (root key "${nodeType}"). Label files should be flat \u2014 the node type is added automatically. See https://bonsaedev.github.io/nrg/guide/building-and-running`
|
|
@@ -1850,8 +2026,8 @@ function minifier() {
|
|
|
1850
2026
|
// src/vite/client/plugins/node-definitions-inliner.ts
|
|
1851
2027
|
import { createRequire as createRequire2 } from "module";
|
|
1852
2028
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
1853
|
-
import
|
|
1854
|
-
import
|
|
2029
|
+
import path8 from "path";
|
|
2030
|
+
import fs8 from "fs";
|
|
1855
2031
|
import mime2 from "mime-types";
|
|
1856
2032
|
var VIRTUAL_ID = "virtual:nrg/node-definitions";
|
|
1857
2033
|
var RESOLVED_ID = "\0" + VIRTUAL_ID;
|
|
@@ -1882,17 +2058,68 @@ function getCredentialsFromSchema(schema) {
|
|
|
1882
2058
|
return result;
|
|
1883
2059
|
}
|
|
1884
2060
|
function resolveIcon(iconsDir, type) {
|
|
1885
|
-
if (!
|
|
1886
|
-
return
|
|
1887
|
-
if (
|
|
2061
|
+
if (!fs8.existsSync(iconsDir)) return void 0;
|
|
2062
|
+
return fs8.readdirSync(iconsDir).find((f) => {
|
|
2063
|
+
if (path8.basename(f, path8.extname(f)) !== type) return false;
|
|
1888
2064
|
const mimeType = mime2.lookup(f);
|
|
1889
2065
|
return mimeType !== false && mimeType.startsWith("image/");
|
|
1890
2066
|
});
|
|
1891
2067
|
}
|
|
1892
|
-
|
|
2068
|
+
var RUNTIME_SPECIFIER = "@bonsae/nrg-runtime/server";
|
|
2069
|
+
var RUNTIME_SPECIFIER_RE = /(['"])@bonsae\/nrg-runtime\/server\1/g;
|
|
2070
|
+
function resolveRuntimeServer(serverOutDir) {
|
|
2071
|
+
const roots = [path8.join(serverOutDir, "index.js"), import.meta.url];
|
|
2072
|
+
for (const root of roots) {
|
|
2073
|
+
try {
|
|
2074
|
+
return createRequire2(root).resolve(RUNTIME_SPECIFIER);
|
|
2075
|
+
} catch {
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
return void 0;
|
|
2079
|
+
}
|
|
2080
|
+
async function loadServerPackageExport(serverOutDir) {
|
|
2081
|
+
const esmEntryPath = path8.resolve(serverOutDir, "index.mjs");
|
|
2082
|
+
const cjsEntryPath = path8.resolve(serverOutDir, "index.js");
|
|
2083
|
+
const isEsm = fs8.existsSync(esmEntryPath);
|
|
2084
|
+
const entryPath = isEsm ? esmEntryPath : fs8.existsSync(cjsEntryPath) ? cjsEntryPath : void 0;
|
|
2085
|
+
if (!entryPath) return void 0;
|
|
2086
|
+
const code = fs8.readFileSync(entryPath, "utf-8");
|
|
2087
|
+
const runtimeServer = code.includes(RUNTIME_SPECIFIER) ? resolveRuntimeServer(serverOutDir) : void 0;
|
|
2088
|
+
let tempPath;
|
|
2089
|
+
let loadPath = entryPath;
|
|
2090
|
+
if (runtimeServer) {
|
|
2091
|
+
const replacement = isEsm ? JSON.stringify(pathToFileURL2(runtimeServer).href) : JSON.stringify(runtimeServer);
|
|
2092
|
+
const rewritten = code.replace(RUNTIME_SPECIFIER_RE, replacement);
|
|
2093
|
+
tempPath = path8.resolve(
|
|
2094
|
+
serverOutDir,
|
|
2095
|
+
`.nrg-server-${Date.now()}${isEsm ? ".mjs" : ".cjs"}`
|
|
2096
|
+
);
|
|
2097
|
+
fs8.writeFileSync(tempPath, rewritten);
|
|
2098
|
+
loadPath = tempPath;
|
|
2099
|
+
}
|
|
2100
|
+
const require2 = createRequire2(import.meta.url);
|
|
2101
|
+
try {
|
|
2102
|
+
if (isEsm) {
|
|
2103
|
+
const fileUrl = pathToFileURL2(loadPath).href + `?t=${Date.now()}`;
|
|
2104
|
+
const mod = await import(fileUrl);
|
|
2105
|
+
return mod?.default ?? mod;
|
|
2106
|
+
}
|
|
2107
|
+
delete require2.cache[loadPath];
|
|
2108
|
+
const rawMod = require2(loadPath);
|
|
2109
|
+
return rawMod?.default ?? rawMod;
|
|
2110
|
+
} finally {
|
|
2111
|
+
if (tempPath) {
|
|
2112
|
+
try {
|
|
2113
|
+
delete require2.cache[tempPath];
|
|
2114
|
+
fs8.rmSync(tempPath);
|
|
2115
|
+
} catch {
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
function nodeDefinitionsInliner(serverOutDir, entryPath, iconsDir, componentsDir, nodesDir, hasUserEntry = true, cacheDir = path8.resolve("node_modules", ".nrg", "client")) {
|
|
1893
2121
|
let _nodeTypes = [];
|
|
1894
2122
|
let _definitions = {};
|
|
1895
|
-
const cacheDir = path7.resolve("node_modules", ".nrg", "client");
|
|
1896
2123
|
return {
|
|
1897
2124
|
name: "vite-plugin-node-red:client:node-definitions-inliner",
|
|
1898
2125
|
enforce: "pre",
|
|
@@ -1901,19 +2128,7 @@ function nodeDefinitionsInliner(serverOutDir, entryPath, iconsDir, componentsDir
|
|
|
1901
2128
|
async buildStart() {
|
|
1902
2129
|
_nodeTypes = [];
|
|
1903
2130
|
_definitions = {};
|
|
1904
|
-
const
|
|
1905
|
-
const cjsEntryPath = path7.resolve(serverOutDir, "index.js");
|
|
1906
|
-
let packageFn;
|
|
1907
|
-
if (fs7.existsSync(esmEntryPath)) {
|
|
1908
|
-
const fileUrl = pathToFileURL2(esmEntryPath).href + `?t=${Date.now()}`;
|
|
1909
|
-
const mod = await import(fileUrl);
|
|
1910
|
-
packageFn = mod?.default ?? mod;
|
|
1911
|
-
} else if (fs7.existsSync(cjsEntryPath)) {
|
|
1912
|
-
const require2 = createRequire2(import.meta.url);
|
|
1913
|
-
delete require2.cache[cjsEntryPath];
|
|
1914
|
-
const rawMod = require2(cjsEntryPath);
|
|
1915
|
-
packageFn = rawMod?.default ?? rawMod;
|
|
1916
|
-
}
|
|
2131
|
+
const packageFn = await loadServerPackageExport(serverOutDir);
|
|
1917
2132
|
const nodeClasses = packageFn?.nodes ?? [];
|
|
1918
2133
|
for (const NodeClass of nodeClasses) {
|
|
1919
2134
|
const type = NodeClass.type;
|
|
@@ -1952,14 +2167,14 @@ function nodeDefinitionsInliner(serverOutDir, entryPath, iconsDir, componentsDir
|
|
|
1952
2167
|
};
|
|
1953
2168
|
}
|
|
1954
2169
|
if (!hasUserEntry) {
|
|
1955
|
-
const nodesCache =
|
|
1956
|
-
if (
|
|
1957
|
-
|
|
2170
|
+
const nodesCache = path8.resolve(cacheDir, "nodes");
|
|
2171
|
+
if (fs8.existsSync(nodesCache)) {
|
|
2172
|
+
fs8.rmSync(nodesCache, { recursive: true });
|
|
1958
2173
|
}
|
|
1959
|
-
|
|
2174
|
+
fs8.mkdirSync(nodesCache, { recursive: true });
|
|
1960
2175
|
for (const type of _nodeTypes) {
|
|
1961
|
-
const userTsPath = nodesDir ?
|
|
1962
|
-
if (userTsPath &&
|
|
2176
|
+
const userTsPath = nodesDir ? path8.resolve(nodesDir, `${type}.ts`) : null;
|
|
2177
|
+
if (userTsPath && fs8.existsSync(userTsPath)) continue;
|
|
1963
2178
|
const content = [
|
|
1964
2179
|
`// auto-generated by nrg`,
|
|
1965
2180
|
`import { defineNode } from "@bonsae/nrg/client";`,
|
|
@@ -1969,13 +2184,13 @@ function nodeDefinitionsInliner(serverOutDir, entryPath, iconsDir, componentsDir
|
|
|
1969
2184
|
`});`,
|
|
1970
2185
|
``
|
|
1971
2186
|
].join("\n");
|
|
1972
|
-
|
|
2187
|
+
fs8.writeFileSync(path8.resolve(nodesCache, `${type}.ts`), content);
|
|
1973
2188
|
}
|
|
1974
2189
|
const entryContent = generateEntryCode("");
|
|
1975
|
-
|
|
2190
|
+
fs8.mkdirSync(path8.dirname(path8.resolve(cacheDir, "index.ts")), {
|
|
1976
2191
|
recursive: true
|
|
1977
2192
|
});
|
|
1978
|
-
|
|
2193
|
+
fs8.writeFileSync(path8.resolve(cacheDir, "index.ts"), entryContent);
|
|
1979
2194
|
}
|
|
1980
2195
|
},
|
|
1981
2196
|
resolveId(id) {
|
|
@@ -1998,12 +2213,12 @@ function nodeDefinitionsInliner(serverOutDir, entryPath, iconsDir, componentsDir
|
|
|
1998
2213
|
const nrgImports = /* @__PURE__ */ new Set(["__setSchemas"]);
|
|
1999
2214
|
const lines = [`import __nrgSchemas from "${VIRTUAL_ID}";`];
|
|
2000
2215
|
const postLines = [`__setSchemas(__nrgSchemas);`];
|
|
2001
|
-
if (componentsDir &&
|
|
2216
|
+
if (componentsDir && fs8.existsSync(componentsDir)) {
|
|
2002
2217
|
const formImports = [];
|
|
2003
2218
|
const formEntries = [];
|
|
2004
2219
|
for (const type of _nodeTypes) {
|
|
2005
|
-
const componentPath =
|
|
2006
|
-
if (
|
|
2220
|
+
const componentPath = path8.resolve(componentsDir, `${type}.vue`);
|
|
2221
|
+
if (fs8.existsSync(componentPath)) {
|
|
2007
2222
|
const varName = `__nrgForm_${type.replace(/-/g, "_")}`;
|
|
2008
2223
|
formImports.push(
|
|
2009
2224
|
`import ${varName} from ${JSON.stringify(componentPath)};`
|
|
@@ -2018,12 +2233,12 @@ function nodeDefinitionsInliner(serverOutDir, entryPath, iconsDir, componentsDir
|
|
|
2018
2233
|
}
|
|
2019
2234
|
}
|
|
2020
2235
|
if (!hasUserEntry) {
|
|
2021
|
-
const nodesCache =
|
|
2236
|
+
const nodesCache = path8.resolve(cacheDir, "nodes");
|
|
2022
2237
|
const defVarNames = [];
|
|
2023
2238
|
for (const type of _nodeTypes) {
|
|
2024
2239
|
const varName = `__nrgNodeDef_${type.replace(/-/g, "_")}`;
|
|
2025
|
-
const userTsPath = nodesDir ?
|
|
2026
|
-
const tsPath = userTsPath &&
|
|
2240
|
+
const userTsPath = nodesDir ? path8.resolve(nodesDir, `${type}.ts`) : null;
|
|
2241
|
+
const tsPath = userTsPath && fs8.existsSync(userTsPath) ? userTsPath : path8.resolve(nodesCache, `${type}.ts`);
|
|
2027
2242
|
lines.push(`import ${varName} from ${JSON.stringify(tsPath)};`);
|
|
2028
2243
|
defVarNames.push(varName);
|
|
2029
2244
|
}
|
|
@@ -2041,8 +2256,8 @@ function nodeDefinitionsInliner(serverOutDir, entryPath, iconsDir, componentsDir
|
|
|
2041
2256
|
}
|
|
2042
2257
|
|
|
2043
2258
|
// src/vite/client/plugins/static-copy.ts
|
|
2044
|
-
import
|
|
2045
|
-
import
|
|
2259
|
+
import fs9 from "fs";
|
|
2260
|
+
import path9 from "path";
|
|
2046
2261
|
function staticCopy(options) {
|
|
2047
2262
|
const { targets } = options;
|
|
2048
2263
|
return {
|
|
@@ -2051,23 +2266,23 @@ function staticCopy(options) {
|
|
|
2051
2266
|
enforce: "post",
|
|
2052
2267
|
closeBundle() {
|
|
2053
2268
|
for (const { src, dest } of targets) {
|
|
2054
|
-
if (!
|
|
2055
|
-
|
|
2056
|
-
const stat =
|
|
2269
|
+
if (!fs9.existsSync(src)) continue;
|
|
2270
|
+
fs9.mkdirSync(dest, { recursive: true });
|
|
2271
|
+
const stat = fs9.statSync(src);
|
|
2057
2272
|
if (stat.isDirectory()) {
|
|
2058
|
-
const files =
|
|
2273
|
+
const files = fs9.readdirSync(src);
|
|
2059
2274
|
for (const file of files) {
|
|
2060
|
-
const srcFile =
|
|
2061
|
-
const destFile =
|
|
2062
|
-
const fileStat =
|
|
2275
|
+
const srcFile = path9.join(src, file);
|
|
2276
|
+
const destFile = path9.join(dest, file);
|
|
2277
|
+
const fileStat = fs9.statSync(srcFile);
|
|
2063
2278
|
if (fileStat.isDirectory()) {
|
|
2064
|
-
|
|
2279
|
+
fs9.cpSync(srcFile, destFile, { recursive: true });
|
|
2065
2280
|
} else {
|
|
2066
|
-
|
|
2281
|
+
fs9.copyFileSync(srcFile, destFile);
|
|
2067
2282
|
}
|
|
2068
2283
|
}
|
|
2069
2284
|
} else {
|
|
2070
|
-
|
|
2285
|
+
fs9.copyFileSync(src, dest);
|
|
2071
2286
|
}
|
|
2072
2287
|
}
|
|
2073
2288
|
}
|
|
@@ -2075,6 +2290,11 @@ function staticCopy(options) {
|
|
|
2075
2290
|
}
|
|
2076
2291
|
|
|
2077
2292
|
// src/vite/client/build.ts
|
|
2293
|
+
function cacheKeyFor(outDir) {
|
|
2294
|
+
const abs = path10.resolve(outDir);
|
|
2295
|
+
const hash = crypto.createHash("sha1").update(abs).digest("hex").slice(0, 8);
|
|
2296
|
+
return `${path10.basename(abs) || "client"}-${hash}`;
|
|
2297
|
+
}
|
|
2078
2298
|
async function build2(clientBuildOptions, buildContext) {
|
|
2079
2299
|
const {
|
|
2080
2300
|
srcDir = "./client",
|
|
@@ -2088,74 +2308,81 @@ async function build2(clientBuildOptions, buildContext) {
|
|
|
2088
2308
|
globals = {},
|
|
2089
2309
|
manualChunks
|
|
2090
2310
|
} = clientBuildOptions;
|
|
2091
|
-
const
|
|
2311
|
+
const cacheDir = path10.resolve(
|
|
2312
|
+
"node_modules",
|
|
2313
|
+
".nrg",
|
|
2314
|
+
"client",
|
|
2315
|
+
cacheKeyFor(buildContext.outDir)
|
|
2316
|
+
);
|
|
2317
|
+
const physicalEntryPath = path10.resolve(srcDir, entry);
|
|
2092
2318
|
let entryPath;
|
|
2093
2319
|
let generatedEntry = false;
|
|
2094
|
-
if (
|
|
2320
|
+
if (fs10.existsSync(physicalEntryPath)) {
|
|
2095
2321
|
entryPath = physicalEntryPath;
|
|
2096
2322
|
} else {
|
|
2097
|
-
const
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
fs9.mkdirSync(cacheDir, { recursive: true });
|
|
2323
|
+
const cachedEntryPath = path10.resolve(cacheDir, entry);
|
|
2324
|
+
if (!fs10.existsSync(cacheDir)) {
|
|
2325
|
+
fs10.mkdirSync(cacheDir, { recursive: true });
|
|
2101
2326
|
}
|
|
2102
|
-
|
|
2327
|
+
fs10.writeFileSync(cachedEntryPath, "// auto-generated entry\n");
|
|
2103
2328
|
entryPath = cachedEntryPath;
|
|
2104
2329
|
generatedEntry = true;
|
|
2105
2330
|
}
|
|
2106
|
-
const iconsDir =
|
|
2107
|
-
staticDirs.icons ??
|
|
2331
|
+
const iconsDir = path10.resolve(
|
|
2332
|
+
staticDirs.icons ?? path10.join(path10.dirname(path10.resolve(srcDir)), "icons")
|
|
2108
2333
|
);
|
|
2109
2334
|
const plugins = [
|
|
2110
2335
|
vue(),
|
|
2111
2336
|
nodeDefinitionsInliner(
|
|
2112
2337
|
buildContext.outDir,
|
|
2113
2338
|
entryPath,
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
!generatedEntry
|
|
2339
|
+
fs10.existsSync(iconsDir) ? iconsDir : void 0,
|
|
2340
|
+
path10.resolve(srcDir, "components"),
|
|
2341
|
+
path10.resolve(srcDir, "nodes"),
|
|
2342
|
+
!generatedEntry,
|
|
2343
|
+
cacheDir
|
|
2118
2344
|
)
|
|
2119
2345
|
];
|
|
2120
2346
|
plugins.push(
|
|
2121
2347
|
htmlGenerator({
|
|
2122
2348
|
packageName: buildContext.packageName,
|
|
2123
|
-
licensePath: licensePath ?
|
|
2349
|
+
licensePath: licensePath ? path10.resolve(licensePath) : void 0
|
|
2124
2350
|
})
|
|
2125
2351
|
);
|
|
2126
2352
|
if (locales) {
|
|
2127
2353
|
const { docsDir = "./locales/docs", labelsDir = "./locales/labels" } = locales;
|
|
2128
|
-
const localesOutDir =
|
|
2354
|
+
const localesOutDir = path10.join(buildContext.outDir, "locales");
|
|
2129
2355
|
plugins.push(
|
|
2130
2356
|
localesGenerator({
|
|
2131
2357
|
outDir: localesOutDir,
|
|
2132
|
-
docsDir:
|
|
2133
|
-
labelsDir:
|
|
2358
|
+
docsDir: path10.resolve(docsDir),
|
|
2359
|
+
labelsDir: path10.resolve(labelsDir)
|
|
2134
2360
|
})
|
|
2135
2361
|
);
|
|
2136
2362
|
plugins.push(
|
|
2137
2363
|
helpGenerator({
|
|
2138
2364
|
outDir: buildContext.outDir,
|
|
2139
2365
|
localesOutDir,
|
|
2140
|
-
docsDir:
|
|
2141
|
-
labelsDir:
|
|
2366
|
+
docsDir: path10.resolve(docsDir),
|
|
2367
|
+
labelsDir: path10.resolve(labelsDir),
|
|
2368
|
+
srcDir: buildContext.serverSrcDir
|
|
2142
2369
|
})
|
|
2143
2370
|
);
|
|
2144
2371
|
}
|
|
2145
2372
|
const copyTargets = [];
|
|
2146
|
-
const publicDir =
|
|
2147
|
-
staticDirs.public ??
|
|
2373
|
+
const publicDir = path10.resolve(
|
|
2374
|
+
staticDirs.public ?? path10.join(srcDir, "public")
|
|
2148
2375
|
);
|
|
2149
|
-
if (
|
|
2376
|
+
if (fs10.existsSync(publicDir)) {
|
|
2150
2377
|
copyTargets.push({
|
|
2151
2378
|
src: publicDir,
|
|
2152
|
-
dest:
|
|
2379
|
+
dest: path10.join(buildContext.outDir, "resources")
|
|
2153
2380
|
});
|
|
2154
2381
|
}
|
|
2155
|
-
if (
|
|
2382
|
+
if (fs10.existsSync(iconsDir)) {
|
|
2156
2383
|
copyTargets.push({
|
|
2157
2384
|
src: iconsDir,
|
|
2158
|
-
dest:
|
|
2385
|
+
dest: path10.join(buildContext.outDir, "icons")
|
|
2159
2386
|
});
|
|
2160
2387
|
}
|
|
2161
2388
|
if (copyTargets.length > 0) {
|
|
@@ -2183,10 +2410,10 @@ async function build2(clientBuildOptions, buildContext) {
|
|
|
2183
2410
|
configFile: false,
|
|
2184
2411
|
logLevel: "warn",
|
|
2185
2412
|
base: `/resources/${buildContext.packageName}`,
|
|
2186
|
-
publicDir:
|
|
2413
|
+
publicDir: path10.resolve(srcDir, "public"),
|
|
2187
2414
|
resolve: {
|
|
2188
2415
|
alias: {
|
|
2189
|
-
"@":
|
|
2416
|
+
"@": path10.resolve(srcDir)
|
|
2190
2417
|
}
|
|
2191
2418
|
},
|
|
2192
2419
|
plugins,
|
|
@@ -2240,15 +2467,15 @@ async function build2(clientBuildOptions, buildContext) {
|
|
|
2240
2467
|
throw new BuildError("client", error);
|
|
2241
2468
|
} finally {
|
|
2242
2469
|
if (generatedEntry) {
|
|
2243
|
-
if (
|
|
2244
|
-
|
|
2470
|
+
if (fs10.existsSync(entryPath)) {
|
|
2471
|
+
fs10.unlinkSync(entryPath);
|
|
2245
2472
|
}
|
|
2246
2473
|
}
|
|
2247
2474
|
}
|
|
2248
2475
|
}
|
|
2249
2476
|
|
|
2250
2477
|
// src/vite/node-red-launcher/index.ts
|
|
2251
|
-
import
|
|
2478
|
+
import fs13 from "fs";
|
|
2252
2479
|
|
|
2253
2480
|
// src/vite/async-utils.ts
|
|
2254
2481
|
function withTimeout(promise, ms, fallback) {
|
|
@@ -2289,22 +2516,22 @@ async function retry(fn, options = {}) {
|
|
|
2289
2516
|
import { exec } from "child_process";
|
|
2290
2517
|
import { randomUUID } from "crypto";
|
|
2291
2518
|
import { createRequire as createRequire3 } from "module";
|
|
2292
|
-
import
|
|
2519
|
+
import fs11 from "fs";
|
|
2293
2520
|
import os from "os";
|
|
2294
|
-
import
|
|
2521
|
+
import path11 from "path";
|
|
2295
2522
|
function getNodeRedCommand(version) {
|
|
2296
2523
|
return version ? `node-red@${version}` : "node-red";
|
|
2297
2524
|
}
|
|
2298
2525
|
function resolveNodeRedFromLocalNodeModules() {
|
|
2299
2526
|
try {
|
|
2300
|
-
const require_ = createRequire3(
|
|
2527
|
+
const require_ = createRequire3(path11.join(process.cwd(), "package.json"));
|
|
2301
2528
|
const pkgJsonPath = require_.resolve("node-red/package.json");
|
|
2302
|
-
const pkgDir =
|
|
2303
|
-
const pkg = JSON.parse(
|
|
2529
|
+
const pkgDir = path11.dirname(pkgJsonPath);
|
|
2530
|
+
const pkg = JSON.parse(fs11.readFileSync(pkgJsonPath, "utf-8"));
|
|
2304
2531
|
const bin = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.["node-red"];
|
|
2305
2532
|
if (!bin) return null;
|
|
2306
|
-
const entry =
|
|
2307
|
-
return
|
|
2533
|
+
const entry = path11.resolve(pkgDir, bin);
|
|
2534
|
+
return fs11.existsSync(entry) ? entry : null;
|
|
2308
2535
|
} catch {
|
|
2309
2536
|
return null;
|
|
2310
2537
|
}
|
|
@@ -2329,11 +2556,11 @@ async function resolveNodeRed(options) {
|
|
|
2329
2556
|
logger2.info(
|
|
2330
2557
|
hasExplicitVersion ? `Using configured version (${version}), downloading via npx...` : `Not found locally, downloading via npx (this may take a while)...`
|
|
2331
2558
|
);
|
|
2332
|
-
const resolverScript =
|
|
2559
|
+
const resolverScript = path11.join(
|
|
2333
2560
|
os.tmpdir(),
|
|
2334
2561
|
`nrg-resolve-node-red-${process.pid}-${randomUUID()}.cjs`
|
|
2335
2562
|
);
|
|
2336
|
-
|
|
2563
|
+
fs11.writeFileSync(
|
|
2337
2564
|
resolverScript,
|
|
2338
2565
|
`const fs = require("fs");
|
|
2339
2566
|
const path = require("path");
|
|
@@ -2367,7 +2594,7 @@ for (const d of dirs) {
|
|
|
2367
2594
|
);
|
|
2368
2595
|
});
|
|
2369
2596
|
const entryPoint = stdout.trim();
|
|
2370
|
-
if (!entryPoint || !
|
|
2597
|
+
if (!entryPoint || !fs11.existsSync(entryPoint)) {
|
|
2371
2598
|
throw new NodeRedStartError(
|
|
2372
2599
|
new Error(
|
|
2373
2600
|
`Could not resolve node-red entry point: ${entryPoint || "(empty)"}`
|
|
@@ -2378,7 +2605,7 @@ for (const d of dirs) {
|
|
|
2378
2605
|
return entryPoint;
|
|
2379
2606
|
} finally {
|
|
2380
2607
|
try {
|
|
2381
|
-
|
|
2608
|
+
fs11.unlinkSync(resolverScript);
|
|
2382
2609
|
} catch {
|
|
2383
2610
|
}
|
|
2384
2611
|
}
|
|
@@ -2386,28 +2613,28 @@ for (const d of dirs) {
|
|
|
2386
2613
|
|
|
2387
2614
|
// src/vite/node-red-launcher/settings.ts
|
|
2388
2615
|
import { builtinModules as builtinModules2 } from "module";
|
|
2389
|
-
import
|
|
2616
|
+
import fs12 from "fs";
|
|
2390
2617
|
import os2 from "os";
|
|
2391
|
-
import
|
|
2618
|
+
import path12 from "path";
|
|
2392
2619
|
import { pathToFileURL as pathToFileURL3 } from "url";
|
|
2393
2620
|
import { build as esbuild } from "esbuild";
|
|
2394
2621
|
function findUserRuntimeSettingsFilepath(settingsFilepath, logger2) {
|
|
2395
2622
|
if (settingsFilepath) {
|
|
2396
|
-
const resolved2 =
|
|
2397
|
-
if (
|
|
2623
|
+
const resolved2 = path12.resolve(settingsFilepath);
|
|
2624
|
+
if (fs12.existsSync(resolved2)) {
|
|
2398
2625
|
return resolved2;
|
|
2399
2626
|
}
|
|
2400
2627
|
logger2.warn(`Settings file not found: ${settingsFilepath}`);
|
|
2401
2628
|
return null;
|
|
2402
2629
|
}
|
|
2403
|
-
const resolved =
|
|
2404
|
-
if (
|
|
2630
|
+
const resolved = path12.resolve("node-red.settings.ts");
|
|
2631
|
+
if (fs12.existsSync(resolved)) {
|
|
2405
2632
|
return resolved;
|
|
2406
2633
|
}
|
|
2407
2634
|
return null;
|
|
2408
2635
|
}
|
|
2409
2636
|
async function compileRuntimeSettingsFile(runtimeSettingsFilepath, port) {
|
|
2410
|
-
const compiledRuntimeSettingsFilepath =
|
|
2637
|
+
const compiledRuntimeSettingsFilepath = path12.join(
|
|
2411
2638
|
os2.tmpdir(),
|
|
2412
2639
|
`node-red.settings.${process.pid}-${port}.cjs`
|
|
2413
2640
|
);
|
|
@@ -2415,8 +2642,8 @@ async function compileRuntimeSettingsFile(runtimeSettingsFilepath, port) {
|
|
|
2415
2642
|
...builtinModules2,
|
|
2416
2643
|
...builtinModules2.map((m) => `node:${m}`)
|
|
2417
2644
|
];
|
|
2418
|
-
const settingsDir =
|
|
2419
|
-
const settingsFile = runtimeSettingsFilepath.split(
|
|
2645
|
+
const settingsDir = path12.dirname(runtimeSettingsFilepath).split(path12.sep).join("/");
|
|
2646
|
+
const settingsFile = runtimeSettingsFilepath.split(path12.sep).join("/");
|
|
2420
2647
|
await esbuild({
|
|
2421
2648
|
entryPoints: [runtimeSettingsFilepath],
|
|
2422
2649
|
outfile: compiledRuntimeSettingsFilepath,
|
|
@@ -2448,14 +2675,14 @@ async function generateRuntimeSettings(options) {
|
|
|
2448
2675
|
);
|
|
2449
2676
|
tempFiles.push(compiledRuntimeSettingsFilepath);
|
|
2450
2677
|
}
|
|
2451
|
-
const normalizedOutDir =
|
|
2452
|
-
const cwd = process.cwd().split(
|
|
2453
|
-
const userDir =
|
|
2678
|
+
const normalizedOutDir = path12.resolve(outDir).split(path12.sep).join("/");
|
|
2679
|
+
const cwd = process.cwd().split(path12.sep).join("/");
|
|
2680
|
+
const userDir = path12.resolve(cwd, ".node-red").split(path12.sep).join("/");
|
|
2454
2681
|
const userDirLiteral = JSON.stringify(userDir);
|
|
2455
2682
|
const outDirLiteral = JSON.stringify(normalizedOutDir);
|
|
2456
2683
|
const finalRuntimeSettingsFile = compiledRuntimeSettingsFilepath ? `
|
|
2457
2684
|
const compiledRuntimeSettings = require(${JSON.stringify(
|
|
2458
|
-
compiledRuntimeSettingsFilepath.split(
|
|
2685
|
+
compiledRuntimeSettingsFilepath.split(path12.sep).join("/")
|
|
2459
2686
|
)});
|
|
2460
2687
|
const settings = compiledRuntimeSettings.default || compiledRuntimeSettings;
|
|
2461
2688
|
settings.uiPort = ${port};
|
|
@@ -2487,11 +2714,11 @@ const settings = {
|
|
|
2487
2714
|
};
|
|
2488
2715
|
module.exports = settings;
|
|
2489
2716
|
`;
|
|
2490
|
-
const finalRuntimeSettingsFilepath =
|
|
2717
|
+
const finalRuntimeSettingsFilepath = path12.join(
|
|
2491
2718
|
os2.tmpdir(),
|
|
2492
2719
|
`node-red-settings-final-${process.pid}-${port}.cjs`
|
|
2493
2720
|
);
|
|
2494
|
-
|
|
2721
|
+
fs12.writeFileSync(finalRuntimeSettingsFilepath, finalRuntimeSettingsFile);
|
|
2495
2722
|
tempFiles.push(finalRuntimeSettingsFilepath);
|
|
2496
2723
|
return { filepath: finalRuntimeSettingsFilepath, tempFiles };
|
|
2497
2724
|
}
|
|
@@ -2716,7 +2943,7 @@ var NodeRedLauncher = class {
|
|
|
2716
2943
|
preferredPort: this.preferredPort,
|
|
2717
2944
|
logger: this.logger
|
|
2718
2945
|
});
|
|
2719
|
-
if (!this.nodeRedEntryPoint || !
|
|
2946
|
+
if (!this.nodeRedEntryPoint || !fs13.existsSync(this.nodeRedEntryPoint)) {
|
|
2720
2947
|
this.nodeRedEntryPoint = await resolveNodeRed({
|
|
2721
2948
|
version: this.options.runtime?.version,
|
|
2722
2949
|
logger: this.logger
|
|
@@ -2790,7 +3017,7 @@ var NodeRedLauncher = class {
|
|
|
2790
3017
|
cleanup() {
|
|
2791
3018
|
for (const file of this.tempFiles) {
|
|
2792
3019
|
try {
|
|
2793
|
-
|
|
3020
|
+
fs13.unlinkSync(file);
|
|
2794
3021
|
} catch {
|
|
2795
3022
|
}
|
|
2796
3023
|
}
|
|
@@ -2810,10 +3037,10 @@ var NodeRedTestEnvironment = class {
|
|
|
2810
3037
|
options;
|
|
2811
3038
|
constructor(options) {
|
|
2812
3039
|
this.options = options;
|
|
2813
|
-
this.projectDir =
|
|
2814
|
-
this.outDir =
|
|
2815
|
-
this.nodeRedDir =
|
|
2816
|
-
this.installedPkgDir =
|
|
3040
|
+
this.projectDir = path13.resolve(options.projectDir ?? process.cwd());
|
|
3041
|
+
this.outDir = path13.join(this.projectDir, "dist-e2e");
|
|
3042
|
+
this.nodeRedDir = path13.join(this.projectDir, ".node-red");
|
|
3043
|
+
this.installedPkgDir = path13.join(
|
|
2817
3044
|
this.nodeRedDir,
|
|
2818
3045
|
"node_modules",
|
|
2819
3046
|
options.packageName
|
|
@@ -2825,15 +3052,15 @@ var NodeRedTestEnvironment = class {
|
|
|
2825
3052
|
async setup() {
|
|
2826
3053
|
this.originalCwd = process.cwd();
|
|
2827
3054
|
process.chdir(this.projectDir);
|
|
2828
|
-
if (
|
|
2829
|
-
|
|
3055
|
+
if (fs14.existsSync(this.outDir)) fs14.rmSync(this.outDir, { recursive: true });
|
|
3056
|
+
fs14.mkdirSync(this.outDir, { recursive: true });
|
|
2830
3057
|
const buildContext = {
|
|
2831
3058
|
outDir: this.outDir,
|
|
2832
3059
|
packageName: this.options.packageName,
|
|
2833
3060
|
isDev: false
|
|
2834
3061
|
};
|
|
2835
3062
|
const serverOpts = {
|
|
2836
|
-
srcDir:
|
|
3063
|
+
srcDir: path13.join(this.projectDir, "src/server"),
|
|
2837
3064
|
entry: "index.ts",
|
|
2838
3065
|
format: "esm",
|
|
2839
3066
|
bundled: [],
|
|
@@ -2843,7 +3070,7 @@ var NodeRedTestEnvironment = class {
|
|
|
2843
3070
|
};
|
|
2844
3071
|
await build(serverOpts, buildContext);
|
|
2845
3072
|
const clientOpts = {
|
|
2846
|
-
srcDir:
|
|
3073
|
+
srcDir: path13.join(this.projectDir, "src/client"),
|
|
2847
3074
|
entry: "index.ts",
|
|
2848
3075
|
name: this.options.clientName ?? "NodeRedNodes",
|
|
2849
3076
|
format: "es",
|
|
@@ -2852,18 +3079,18 @@ var NodeRedTestEnvironment = class {
|
|
|
2852
3079
|
...this.options.client
|
|
2853
3080
|
};
|
|
2854
3081
|
await build2(clientOpts, buildContext);
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
3082
|
+
fs14.mkdirSync(this.installedPkgDir, { recursive: true });
|
|
3083
|
+
fs14.cpSync(this.outDir, this.installedPkgDir, { recursive: true });
|
|
3084
|
+
fs14.mkdirSync(this.nodeRedDir, { recursive: true });
|
|
3085
|
+
fs14.writeFileSync(
|
|
3086
|
+
path13.join(this.nodeRedDir, ".config.runtime.json"),
|
|
2860
3087
|
JSON.stringify({ telemetryEnabled: false })
|
|
2861
3088
|
);
|
|
2862
3089
|
const launcherOpts = {
|
|
2863
3090
|
runtime: { port: this.options.port ?? 1881 }
|
|
2864
3091
|
};
|
|
2865
3092
|
if (this.options.settingsFile) {
|
|
2866
|
-
launcherOpts.runtime.settingsFilepath =
|
|
3093
|
+
launcherOpts.runtime.settingsFilepath = path13.resolve(
|
|
2867
3094
|
this.projectDir,
|
|
2868
3095
|
this.options.settingsFile
|
|
2869
3096
|
);
|
|
@@ -2898,25 +3125,19 @@ var NodeRedTestEnvironment = class {
|
|
|
2898
3125
|
this.launcher.cleanup();
|
|
2899
3126
|
this.launcher = null;
|
|
2900
3127
|
}
|
|
2901
|
-
if (
|
|
2902
|
-
if (
|
|
2903
|
-
|
|
3128
|
+
if (fs14.existsSync(this.outDir)) fs14.rmSync(this.outDir, { recursive: true });
|
|
3129
|
+
if (fs14.existsSync(this.nodeRedDir)) {
|
|
3130
|
+
fs14.rmSync(this.nodeRedDir, { recursive: true });
|
|
2904
3131
|
}
|
|
2905
3132
|
this.port = null;
|
|
2906
3133
|
}
|
|
2907
3134
|
};
|
|
2908
3135
|
|
|
2909
3136
|
// src/test/client/e2e/index.ts
|
|
2910
|
-
var defaultConfig = {
|
|
2911
|
-
testTimeout: 6e4,
|
|
2912
|
-
hookTimeout: 12e4,
|
|
2913
|
-
globalSetup: ["@bonsae/nrg/test/client/e2e"],
|
|
2914
|
-
include: ["tests/client/e2e/**/*.test.ts"]
|
|
2915
|
-
};
|
|
2916
3137
|
var _env = null;
|
|
2917
3138
|
async function setup(options) {
|
|
2918
3139
|
const packageName = JSON.parse(
|
|
2919
|
-
|
|
3140
|
+
fs15.readFileSync(path14.join(process.cwd(), "package.json"), "utf-8")
|
|
2920
3141
|
).name;
|
|
2921
3142
|
_env = new NodeRedTestEnvironment({
|
|
2922
3143
|
packageName,
|
|
@@ -2948,8 +3169,8 @@ var NodeRedEditor = class {
|
|
|
2948
3169
|
errors = [];
|
|
2949
3170
|
screenshotDir;
|
|
2950
3171
|
async screenshot(name) {
|
|
2951
|
-
|
|
2952
|
-
const filePath =
|
|
3172
|
+
fs15.mkdirSync(this.screenshotDir, { recursive: true });
|
|
3173
|
+
const filePath = path14.join(this.screenshotDir, `${name}.png`);
|
|
2953
3174
|
await this.page.screenshot({ path: filePath, fullPage: true });
|
|
2954
3175
|
return filePath;
|
|
2955
3176
|
}
|
|
@@ -3353,7 +3574,6 @@ export {
|
|
|
3353
3574
|
NodeRedEditor,
|
|
3354
3575
|
NodeRedField,
|
|
3355
3576
|
NodeRedTestEnvironment,
|
|
3356
|
-
defaultConfig,
|
|
3357
3577
|
setup,
|
|
3358
3578
|
teardown
|
|
3359
3579
|
};
|