@bonsae/nrg 0.13.1 → 0.15.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/vite/index.js CHANGED
@@ -88,7 +88,9 @@ function mergeOptions(defaults, overrides) {
88
88
  for (const key of Object.keys(overrides)) {
89
89
  const overrideVal = overrides[key];
90
90
  const defaultVal = defaults[key];
91
- if (overrideVal !== void 0 && !Array.isArray(overrideVal) && !Array.isArray(defaultVal) && typeof overrideVal === "object" && typeof defaultVal === "object" && overrideVal !== null && defaultVal !== null) {
91
+ if (overrideVal !== void 0 && Array.isArray(overrideVal) && Array.isArray(defaultVal)) {
92
+ result[key] = [.../* @__PURE__ */ new Set([...defaultVal, ...overrideVal])];
93
+ } else if (overrideVal !== void 0 && !Array.isArray(overrideVal) && !Array.isArray(defaultVal) && typeof overrideVal === "object" && typeof defaultVal === "object" && overrideVal !== null && defaultVal !== null) {
92
94
  result[key] = mergeOptions(
93
95
  defaultVal,
94
96
  overrideVal
@@ -105,7 +107,7 @@ import { spawn } from "child_process";
105
107
  import getPort from "get-port";
106
108
  import detect from "detect-port";
107
109
  import { builtinModules } from "module";
108
- import treeKill2 from "tree-kill";
110
+ import treeKill from "tree-kill";
109
111
  import fs2 from "fs";
110
112
  import os from "os";
111
113
  import path2 from "path";
@@ -290,7 +292,7 @@ var NodeRedLauncher = class {
290
292
  return "node-red";
291
293
  }
292
294
  findRuntimeSettingsFilepath() {
293
- const runtimeSettingsFilepath = this.options.runtime.settingsFilepath;
295
+ const runtimeSettingsFilepath = this.options.runtime?.settingsFilepath;
294
296
  if (runtimeSettingsFilepath) {
295
297
  const resolved2 = path2.resolve(runtimeSettingsFilepath);
296
298
  if (fs2.existsSync(resolved2)) {
@@ -426,7 +428,7 @@ module.exports = settings;
426
428
  }
427
429
  if (line.includes("Started flows") || line.includes("Server now running")) {
428
430
  this.isReady = true;
429
- resolve();
431
+ resolve(void 0);
430
432
  }
431
433
  }
432
434
  });
@@ -451,7 +453,7 @@ module.exports = settings;
451
453
  )
452
454
  );
453
455
  }
454
- resolve();
456
+ resolve(void 0);
455
457
  });
456
458
  } catch (error) {
457
459
  reject(new NodeRedStartError(error));
@@ -465,7 +467,7 @@ module.exports = settings;
465
467
  if (this.process) {
466
468
  const pid = this.process.pid;
467
469
  if (pid) {
468
- treeKill2(pid, "SIGKILL");
470
+ treeKill(pid, "SIGKILL");
469
471
  }
470
472
  this.process = null;
471
473
  }
@@ -483,15 +485,15 @@ module.exports = settings;
483
485
  const stopProcess = new Promise((resolve) => {
484
486
  this.process.once("exit", () => {
485
487
  this.process = null;
486
- resolve();
488
+ resolve(void 0);
487
489
  });
488
- treeKill2(pid, "SIGTERM", (error) => {
490
+ treeKill(pid, "SIGTERM", (error) => {
489
491
  if (error) {
490
492
  try {
491
493
  process.kill(pid, "SIGTERM");
492
494
  } catch {
493
495
  this.process = null;
494
- resolve();
496
+ resolve(void 0);
495
497
  }
496
498
  }
497
499
  });
@@ -501,9 +503,9 @@ module.exports = settings;
501
503
  } catch {
502
504
  this.logger.warn("Graceful shutdown timed out, force killing...");
503
505
  await new Promise((resolve) => {
504
- treeKill2(pid, "SIGKILL", () => {
506
+ treeKill(pid, "SIGKILL", () => {
505
507
  this.process = null;
506
- resolve();
508
+ resolve(void 0);
507
509
  });
508
510
  });
509
511
  }
@@ -522,7 +524,7 @@ module.exports = settings;
522
524
  );
523
525
  if (pid) {
524
526
  await new Promise((resolve) => {
525
- treeKill2(pid, "SIGKILL", () => resolve());
527
+ treeKill(pid, "SIGKILL", () => resolve());
526
528
  });
527
529
  await new Promise((resolve) => setTimeout(resolve, 1e3));
528
530
  }
@@ -546,6 +548,7 @@ module.exports = settings;
546
548
 
547
549
  // src/vite/plugins/server.ts
548
550
  import chokidar from "chokidar";
551
+ import treeKill2 from "tree-kill";
549
552
  import path12 from "path";
550
553
 
551
554
  // src/vite/server/build.ts
@@ -658,18 +661,34 @@ function getSchemaReferences(filePath) {
658
661
  }
659
662
  }
660
663
  const schemaRefs = /* @__PURE__ */ new Map();
661
- function extractIdentifiers(node) {
664
+ const recordPortNames = /* @__PURE__ */ new Map();
665
+ let outputsSchemaIsRecord = false;
666
+ function extractIdentifiers(node, propName) {
662
667
  if (ts.isIdentifier(node)) return [node.text];
663
668
  if (ts.isArrayLiteralExpression(node)) {
664
669
  return node.elements.filter(ts.isIdentifier).map((el) => el.text);
665
670
  }
671
+ if (ts.isObjectLiteralExpression(node) && propName === "outputsSchema") {
672
+ const ids = [];
673
+ outputsSchemaIsRecord = true;
674
+ for (const prop of node.properties) {
675
+ if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.initializer)) {
676
+ const portName = ts.isIdentifier(prop.name) ? prop.name.text : ts.isStringLiteral(prop.name) ? prop.name.text : void 0;
677
+ if (portName) {
678
+ ids.push(prop.initializer.text);
679
+ recordPortNames.set(prop.initializer.text, portName);
680
+ }
681
+ }
682
+ }
683
+ return ids;
684
+ }
666
685
  return [];
667
686
  }
668
687
  for (const stmt of source.statements) {
669
688
  if (ts.isClassDeclaration(stmt)) {
670
689
  for (const member of stmt.members) {
671
690
  if (ts.isPropertyDeclaration(member) && ts.isIdentifier(member.name) && member.name.text in SCHEMA_PROP_SEMANTICS && member.initializer) {
672
- const ids = extractIdentifiers(member.initializer);
691
+ const ids = extractIdentifiers(member.initializer, member.name.text);
673
692
  if (ids.length > 0) {
674
693
  schemaRefs.set(member.name.text, ids);
675
694
  }
@@ -683,7 +702,7 @@ function getSchemaReferences(filePath) {
683
702
  if (arg && ts.isObjectLiteralExpression(arg)) {
684
703
  for (const prop of arg.properties) {
685
704
  if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name) && prop.name.text in SCHEMA_PROP_SEMANTICS) {
686
- const ids = extractIdentifiers(prop.initializer);
705
+ const ids = extractIdentifiers(prop.initializer, prop.name.text);
687
706
  if (ids.length > 0) {
688
707
  schemaRefs.set(prop.name.text, ids);
689
708
  }
@@ -696,21 +715,57 @@ function getSchemaReferences(filePath) {
696
715
  const result = [];
697
716
  for (const [propName, identifiers] of schemaRefs) {
698
717
  const semanticName = SCHEMA_PROP_SEMANTICS[propName];
699
- const isArray = identifiers.length > 1;
718
+ const isArray = identifiers.length > 1 && !outputsSchemaIsRecord;
719
+ const isRecord = propName === "outputsSchema" && outputsSchemaIsRecord;
700
720
  for (const identifier of identifiers) {
701
721
  const importSource = importMap.get(identifier);
702
722
  if (importSource) {
703
723
  result.push({
704
724
  localName: identifier,
705
- semanticName: isArray ? identifier : semanticName,
725
+ semanticName: isArray || isRecord ? identifier : semanticName,
706
726
  importSource,
707
- tupleProp: isArray ? semanticName : void 0
727
+ tupleProp: isArray || isRecord ? semanticName : void 0,
728
+ recordPortName: isRecord ? recordPortNames.get(identifier) : void 0
708
729
  });
709
730
  }
710
731
  }
711
732
  }
712
733
  return result;
713
734
  }
735
+ function getFactoryInfo(filePath) {
736
+ const content = fs3.readFileSync(filePath, "utf-8");
737
+ const source = ts.createSourceFile(
738
+ filePath,
739
+ content,
740
+ ts.ScriptTarget.ESNext,
741
+ true
742
+ );
743
+ for (const stmt of source.statements) {
744
+ if (ts.isExportAssignment(stmt) && stmt.expression && ts.isCallExpression(stmt.expression)) {
745
+ const callee = stmt.expression.expression;
746
+ if (ts.isIdentifier(callee)) {
747
+ if (callee.text === "defineIONode" || callee.text === "defineConfigNode") {
748
+ return { factoryName: callee.text };
749
+ }
750
+ }
751
+ }
752
+ }
753
+ return null;
754
+ }
755
+ function buildTypeArg(schemaMap, semanticName, portNameMap) {
756
+ const names = schemaMap.get(semanticName);
757
+ if (!names || names.length === 0) return "any";
758
+ if (names.length === 1 && !portNameMap?.has(names[0]))
759
+ return `Infer<typeof ${names[0]}>`;
760
+ if (portNameMap && names.some((n) => portNameMap.has(n))) {
761
+ const entries = names.map((n) => {
762
+ const portName = portNameMap.get(n);
763
+ return portName ? `${portName}: Infer<typeof ${n}>` : null;
764
+ }).filter(Boolean);
765
+ return `{ ${entries.join(", ")} }`;
766
+ }
767
+ return `[${names.map((n) => `Infer<typeof ${n}>`).join(", ")}]`;
768
+ }
714
769
  function buildNodeReexports(srcDir, entryFile) {
715
770
  const nodesDir = path3.join(srcDir, "nodes");
716
771
  const nodeFiles = collectTsFiles(nodesDir);
@@ -719,15 +774,78 @@ function buildNodeReexports(srcDir, entryFile) {
719
774
  const relPath = rel.startsWith(".") ? rel : `./${rel}`;
720
775
  const specifier = relPath.replace(/\.ts$/, "");
721
776
  const ns = toPascalCase(path3.basename(file, ".ts"));
722
- const lines = [`export { default as ${ns} } from "${specifier}";`];
723
- const typePairs = getNodeTypeExports(file);
724
- if (typePairs.length > 0) {
725
- const prefixed = typePairs.map(
726
- ({ localName, semanticName }) => `${localName} as ${ns}${semanticName}`
727
- ).join(", ");
728
- lines.push(`export type { ${prefixed} } from "${specifier}";`);
729
- }
730
777
  const schemaRefs = getSchemaReferences(file);
778
+ const factoryInfo = getFactoryInfo(file);
779
+ const lines = [];
780
+ if (factoryInfo) {
781
+ const interfaceName = factoryInfo.factoryName === "defineIONode" ? "IIONode" : "IConfigNode";
782
+ lines.push(`import _${ns} from "${specifier}";`);
783
+ const schemaMap = /* @__PURE__ */ new Map();
784
+ const portNameMap = /* @__PURE__ */ new Map();
785
+ for (const ref of schemaRefs) {
786
+ const key = ref.tupleProp ?? ref.semanticName;
787
+ if (!schemaMap.has(key)) schemaMap.set(key, []);
788
+ schemaMap.get(key).push(ref.localName);
789
+ if (ref.recordPortName) {
790
+ portNameMap.set(ref.localName, ref.recordPortName);
791
+ }
792
+ }
793
+ const hasSchemas = schemaMap.size > 0;
794
+ const hasRecordOutputs = portNameMap.size > 0;
795
+ const nrgImports = ["NodeConstructor", interfaceName];
796
+ if (hasSchemas) nrgImports.push("Infer");
797
+ lines.push(
798
+ `import type { ${nrgImports.join(", ")} } from "@bonsae/nrg/server";`
799
+ );
800
+ if (hasSchemas) {
801
+ const bySource2 = /* @__PURE__ */ new Map();
802
+ for (const ref of schemaRefs) {
803
+ const resolvedSource = path3.relative(
804
+ path3.dirname(entryFile),
805
+ path3.resolve(path3.dirname(file), ref.importSource)
806
+ ).replace(/\\/g, "/");
807
+ const sourceSpecifier = resolvedSource.startsWith(".") ? resolvedSource : `./${resolvedSource}`;
808
+ if (!bySource2.has(sourceSpecifier))
809
+ bySource2.set(sourceSpecifier, []);
810
+ const list = bySource2.get(sourceSpecifier);
811
+ if (!list.includes(ref.localName)) list.push(ref.localName);
812
+ }
813
+ for (const [source, names] of bySource2) {
814
+ lines.push(`import type { ${names.join(", ")} } from "${source}";`);
815
+ }
816
+ }
817
+ let typeArgs;
818
+ if (factoryInfo.factoryName === "defineIONode") {
819
+ const outputsArg = buildTypeArg(
820
+ schemaMap,
821
+ "OutputsSchema",
822
+ portNameMap.size > 0 ? portNameMap : void 0
823
+ );
824
+ typeArgs = [
825
+ buildTypeArg(schemaMap, "ConfigSchema"),
826
+ buildTypeArg(schemaMap, "CredentialsSchema"),
827
+ buildTypeArg(schemaMap, "InputSchema"),
828
+ outputsArg
829
+ ].join(", ");
830
+ } else {
831
+ typeArgs = [
832
+ buildTypeArg(schemaMap, "ConfigSchema"),
833
+ buildTypeArg(schemaMap, "CredentialsSchema")
834
+ ].join(", ");
835
+ }
836
+ lines.push(
837
+ `export const ${ns}: NodeConstructor<${interfaceName}<${typeArgs}>> = _${ns};`
838
+ );
839
+ } else {
840
+ lines.push(`export { default as ${ns} } from "${specifier}";`);
841
+ const typePairs = getNodeTypeExports(file);
842
+ if (typePairs.length > 0) {
843
+ const prefixed = typePairs.map(
844
+ ({ localName, semanticName }) => `${localName} as ${ns}${semanticName}`
845
+ ).join(", ");
846
+ lines.push(`export type { ${prefixed} } from "${specifier}";`);
847
+ }
848
+ }
731
849
  const bySource = /* @__PURE__ */ new Map();
732
850
  for (const ref of schemaRefs) {
733
851
  const resolvedSource = path3.relative(
@@ -1038,10 +1156,10 @@ async function build(serverOpts, buildContext) {
1038
1156
  srcDir = "./server",
1039
1157
  entry = "index.ts",
1040
1158
  format = "esm",
1159
+ external = [],
1041
1160
  bundled = [],
1042
1161
  types = true,
1043
- nodeTarget = "node22",
1044
- plugins: userPlugins = []
1162
+ nodeTarget = "node22"
1045
1163
  } = serverOpts;
1046
1164
  const entries = Array.isArray(entry) ? entry : [entry];
1047
1165
  const resolvedSrcDir = path5.resolve(srcDir);
@@ -1066,8 +1184,7 @@ async function build(serverOpts, buildContext) {
1066
1184
  entryNames: Object.keys(entryPoints),
1067
1185
  format
1068
1186
  }),
1069
- isEsm ? esmWrapper() : cjsWrapper(),
1070
- ...userPlugins
1187
+ isEsm ? esmWrapper() : cjsWrapper()
1071
1188
  ];
1072
1189
  if (types && !buildContext.isDev) {
1073
1190
  plugins.push(
@@ -1092,6 +1209,7 @@ async function build(serverOpts, buildContext) {
1092
1209
  formats: [isEsm ? "es" : "cjs"]
1093
1210
  },
1094
1211
  rollupOptions: {
1212
+ external,
1095
1213
  output: {
1096
1214
  entryFileNames: isEsm ? "[name].mjs" : "[name].js",
1097
1215
  exports: isEsm ? void 0 : "auto",
@@ -1504,9 +1622,10 @@ function generateHelpDoc(nodeClass, labels, t) {
1504
1622
  if (inputSection) lines.push(inputSection);
1505
1623
  }
1506
1624
  if (nodeClass.outputsSchema) {
1507
- if (Array.isArray(nodeClass.outputsSchema)) {
1625
+ const os2 = nodeClass.outputsSchema;
1626
+ if (Array.isArray(os2)) {
1508
1627
  const portSections = [];
1509
- nodeClass.outputsSchema.forEach((schema, i) => {
1628
+ os2.forEach((schema, i) => {
1510
1629
  const title = `${t.sections.port} ${i + 1}`;
1511
1630
  const portPropLabels = labels.outputs?.[i];
1512
1631
  const section = generateSchemaSection({
@@ -1522,6 +1641,26 @@ function generateHelpDoc(nodeClass, labels, t) {
1522
1641
  if (portSections.length) {
1523
1642
  lines.push(
1524
1643
  `<h3>${t.sections.outputs}</h3>
1644
+ ${portSections.join("\n")}`
1645
+ );
1646
+ }
1647
+ } else if (!("type" in os2 || "properties" in os2)) {
1648
+ const portSections = [];
1649
+ for (const [portName, schema] of Object.entries(os2)) {
1650
+ const portPropLabels = labels.outputs?.[portName];
1651
+ const section = generateSchemaSection({
1652
+ title: portName,
1653
+ schema,
1654
+ t,
1655
+ labels: portPropLabels,
1656
+ heading: "####",
1657
+ includeDefault: false
1658
+ });
1659
+ if (section) portSections.push(section);
1660
+ }
1661
+ if (portSections.length) {
1662
+ lines.push(
1663
+ `<h3>${t.sections.outputs}</h3>
1525
1664
  ${portSections.join("\n")}`
1526
1665
  );
1527
1666
  }
@@ -1529,7 +1668,7 @@ ${portSections.join("\n")}`
1529
1668
  const outputPropLabels = labels.outputs?.[0];
1530
1669
  const section = generateSchemaSection({
1531
1670
  title: t.sections.output,
1532
- schema: nodeClass.outputsSchema,
1671
+ schema: os2,
1533
1672
  t,
1534
1673
  labels: outputPropLabels,
1535
1674
  includeDefault: false
@@ -1664,6 +1803,7 @@ ${resourcesTags}`
1664
1803
  // src/vite/client/plugins/locales-generator.ts
1665
1804
  import fs8 from "fs";
1666
1805
  import path8 from "path";
1806
+ import { merge } from "es-toolkit";
1667
1807
  function localesGenerator(options) {
1668
1808
  const { outDir, docsDir, labelsDir } = options;
1669
1809
  const languages = [
@@ -1678,6 +1818,108 @@ function localesGenerator(options) {
1678
1818
  "zh-CN",
1679
1819
  "zh-TW"
1680
1820
  ];
1821
+ const frameworkLabels = {
1822
+ "en-US": {
1823
+ configs: { name: "Name" },
1824
+ toggles: {
1825
+ validateInput: "Validate Input",
1826
+ validateOutput: "Validate Output",
1827
+ errorPort: "Error Port",
1828
+ completePort: "Complete Port",
1829
+ statusPort: "Status Port"
1830
+ }
1831
+ },
1832
+ de: {
1833
+ configs: { name: "Name" },
1834
+ toggles: {
1835
+ validateInput: "Eingabe validieren",
1836
+ validateOutput: "Ausgabe validieren",
1837
+ errorPort: "Fehler-Port",
1838
+ completePort: "Abschluss-Port",
1839
+ statusPort: "Status-Port"
1840
+ }
1841
+ },
1842
+ "es-ES": {
1843
+ configs: { name: "Nombre" },
1844
+ toggles: {
1845
+ validateInput: "Validar entrada",
1846
+ validateOutput: "Validar salida",
1847
+ errorPort: "Puerto de error",
1848
+ completePort: "Puerto de completado",
1849
+ statusPort: "Puerto de estado"
1850
+ }
1851
+ },
1852
+ fr: {
1853
+ configs: { name: "Nom" },
1854
+ toggles: {
1855
+ validateInput: "Valider l'entr\xE9e",
1856
+ validateOutput: "Valider la sortie",
1857
+ errorPort: "Port d'erreur",
1858
+ completePort: "Port de compl\xE9tion",
1859
+ statusPort: "Port de statut"
1860
+ }
1861
+ },
1862
+ ko: {
1863
+ configs: { name: "\uC774\uB984" },
1864
+ toggles: {
1865
+ validateInput: "\uC785\uB825 \uAC80\uC99D",
1866
+ validateOutput: "\uCD9C\uB825 \uAC80\uC99D",
1867
+ errorPort: "\uC624\uB958 \uD3EC\uD2B8",
1868
+ completePort: "\uC644\uB8CC \uD3EC\uD2B8",
1869
+ statusPort: "\uC0C1\uD0DC \uD3EC\uD2B8"
1870
+ }
1871
+ },
1872
+ "pt-BR": {
1873
+ configs: { name: "Nome" },
1874
+ toggles: {
1875
+ validateInput: "Validar Entrada",
1876
+ validateOutput: "Validar Sa\xEDda",
1877
+ errorPort: "Porta de Erro",
1878
+ completePort: "Porta de Conclus\xE3o",
1879
+ statusPort: "Porta de Status"
1880
+ }
1881
+ },
1882
+ ru: {
1883
+ configs: { name: "\u0418\u043C\u044F" },
1884
+ toggles: {
1885
+ validateInput: "\u041F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u044C \u0432\u0445\u043E\u0434",
1886
+ validateOutput: "\u041F\u0440\u043E\u0432\u0435\u0440\u0438\u0442\u044C \u0432\u044B\u0445\u043E\u0434",
1887
+ errorPort: "\u041F\u043E\u0440\u0442 \u043E\u0448\u0438\u0431\u043A\u0438",
1888
+ completePort: "\u041F\u043E\u0440\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0438\u044F",
1889
+ statusPort: "\u041F\u043E\u0440\u0442 \u0441\u0442\u0430\u0442\u0443\u0441\u0430"
1890
+ }
1891
+ },
1892
+ ja: {
1893
+ configs: { name: "\u540D\u524D" },
1894
+ toggles: {
1895
+ validateInput: "\u5165\u529B\u691C\u8A3C",
1896
+ validateOutput: "\u51FA\u529B\u691C\u8A3C",
1897
+ errorPort: "\u30A8\u30E9\u30FC\u30DD\u30FC\u30C8",
1898
+ completePort: "\u5B8C\u4E86\u30DD\u30FC\u30C8",
1899
+ statusPort: "\u30B9\u30C6\u30FC\u30BF\u30B9\u30DD\u30FC\u30C8"
1900
+ }
1901
+ },
1902
+ "zh-CN": {
1903
+ configs: { name: "\u540D\u79F0" },
1904
+ toggles: {
1905
+ validateInput: "\u9A8C\u8BC1\u8F93\u5165",
1906
+ validateOutput: "\u9A8C\u8BC1\u8F93\u51FA",
1907
+ errorPort: "\u9519\u8BEF\u7AEF\u53E3",
1908
+ completePort: "\u5B8C\u6210\u7AEF\u53E3",
1909
+ statusPort: "\u72B6\u6001\u7AEF\u53E3"
1910
+ }
1911
+ },
1912
+ "zh-TW": {
1913
+ configs: { name: "\u540D\u7A31" },
1914
+ toggles: {
1915
+ validateInput: "\u9A57\u8B49\u8F38\u5165",
1916
+ validateOutput: "\u9A57\u8B49\u8F38\u51FA",
1917
+ errorPort: "\u932F\u8AA4\u7AEF\u53E3",
1918
+ completePort: "\u5B8C\u6210\u7AEF\u53E3",
1919
+ statusPort: "\u72C0\u614B\u7AEF\u53E3"
1920
+ }
1921
+ }
1922
+ };
1681
1923
  return {
1682
1924
  name: "vite-plugin-node-red:client:locales-generator",
1683
1925
  apply: "build",
@@ -1762,6 +2004,15 @@ ${content}
1762
2004
  return parsed;
1763
2005
  }
1764
2006
  );
2007
+ for (const [lang, nodeTypes] of labelLangs.entries()) {
2008
+ const defaults = frameworkLabels[lang] ?? frameworkLabels["en-US"];
2009
+ for (const nodeType of Object.keys(nodeTypes)) {
2010
+ nodeTypes[nodeType] = merge(
2011
+ structuredClone(defaults),
2012
+ nodeTypes[nodeType]
2013
+ );
2014
+ }
2015
+ }
1765
2016
  writeOutput(
1766
2017
  labelLangs,
1767
2018
  "index.json",
@@ -2025,10 +2276,9 @@ async function build2(clientBuildOptions, buildContext) {
2025
2276
  licensePath = "./LICENSE",
2026
2277
  locales,
2027
2278
  staticDirs = {},
2028
- external = ["jquery", "node-red", "vue"],
2029
- globals = { jquery: "$", "node-red": "RED", vue: "Vue" },
2030
- manualChunks,
2031
- plugins: userPlugins = []
2279
+ external = [],
2280
+ globals = {},
2281
+ manualChunks
2032
2282
  } = clientBuildOptions;
2033
2283
  const physicalEntryPath = path11.resolve(srcDir, entry);
2034
2284
  let entryPath;
@@ -2057,8 +2307,7 @@ async function build2(clientBuildOptions, buildContext) {
2057
2307
  path11.resolve(srcDir, "components"),
2058
2308
  path11.resolve(srcDir, "nodes"),
2059
2309
  !generatedEntry
2060
- ),
2061
- ...userPlugins
2310
+ )
2062
2311
  ];
2063
2312
  plugins.push(
2064
2313
  htmlGenerator({
@@ -2385,7 +2634,7 @@ function serverPlugin(options) {
2385
2634
  const pid = nodeRedLauncher.pid;
2386
2635
  if (pid) {
2387
2636
  try {
2388
- treeKill(pid, "SIGKILL");
2637
+ treeKill2(pid, "SIGKILL");
2389
2638
  } catch {
2390
2639
  }
2391
2640
  }