@bonsae/nrg 0.10.1 → 0.11.1

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/types/server.d.ts CHANGED
@@ -2146,12 +2146,8 @@ export type ConfigNodeContext = {
2146
2146
  export declare abstract class IONode<TConfig = any, TCredentials = any, TInput = any, TOutput = any, TSettings = any> extends Node$1<TConfig, TCredentials, TSettings> {
2147
2147
  static readonly align?: "left" | "right";
2148
2148
  static readonly color: HexColor;
2149
- static readonly labelStyle?: "node_label" | "node_label_italic" | string;
2150
- static readonly paletteLabel?: string;
2151
2149
  static readonly inputs?: number;
2152
2150
  static readonly outputs?: number;
2153
- static readonly inputLabels?: string | string[];
2154
- static readonly outputLabels?: string | string[];
2155
2151
  static readonly inputSchema?: Schema;
2156
2152
  static readonly outputsSchema?: Schema | Schema[];
2157
2153
  static readonly validateInput: boolean;
@@ -2207,11 +2203,7 @@ export interface IONodeDefinition<TConfigSchema extends TSchema | undefined = un
2207
2203
  color?: HexColor;
2208
2204
  inputs?: 0 | 1;
2209
2205
  outputs?: number;
2210
- paletteLabel?: string;
2211
- inputLabels?: string | string[];
2212
- outputLabels?: string | string[];
2213
2206
  align?: "left" | "right";
2214
- labelStyle?: string;
2215
2207
  configSchema?: TConfigSchema;
2216
2208
  credentialsSchema?: TCredsSchema;
2217
2209
  settingsSchema?: TSettingsSchema;
package/vite/index.js CHANGED
@@ -383,7 +383,24 @@ module.exports = settings;
383
383
  this.logger.raw(line);
384
384
  }
385
385
  async start() {
386
- this.port = await getPort({ port: this.preferredPort });
386
+ const available = await detect(this.preferredPort);
387
+ if (available === this.preferredPort) {
388
+ this.port = this.preferredPort;
389
+ } else {
390
+ this.logger.warn(
391
+ `Port ${this.preferredPort} is still in use, waiting...`
392
+ );
393
+ await new Promise((resolve) => setTimeout(resolve, 2e3));
394
+ const retryAvailable = await detect(this.preferredPort);
395
+ if (retryAvailable === this.preferredPort) {
396
+ this.port = this.preferredPort;
397
+ } else {
398
+ this.logger.warn(
399
+ `Port ${this.preferredPort} still occupied, using port ${retryAvailable}`
400
+ );
401
+ this.port = await getPort({ port: this.preferredPort });
402
+ }
403
+ }
387
404
  const startProcess = () => {
388
405
  return new Promise(async (resolve, reject) => {
389
406
  try {
@@ -498,11 +515,17 @@ module.exports = settings;
498
515
  }
499
516
  };
500
517
  try {
501
- await retry(checkPortUsage, { attempts: 5, delay: 100 });
518
+ await retry(checkPortUsage, { attempts: 10, delay: 300 });
502
519
  } catch {
503
520
  this.logger.warn(
504
- `Port ${currentPort} may still be in use. If restart fails, try again in a few seconds.`
521
+ `Port ${currentPort} still in use after stop. Force killing...`
505
522
  );
523
+ if (pid) {
524
+ await new Promise((resolve) => {
525
+ treeKill2(pid, "SIGKILL", () => resolve());
526
+ });
527
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
528
+ }
506
529
  }
507
530
  }
508
531
  this.port = null;
@@ -1118,6 +1141,235 @@ import fs6 from "fs";
1118
1141
  import path6 from "path";
1119
1142
  import { pathToFileURL } from "url";
1120
1143
  import { createRequire } from "module";
1144
+
1145
+ // src/vite/client/plugins/help-i18n.ts
1146
+ var translations = {
1147
+ "en-US": {
1148
+ sections: {
1149
+ properties: "Properties",
1150
+ credentials: "Credentials",
1151
+ input: "Input",
1152
+ output: "Output",
1153
+ outputs: "Outputs",
1154
+ port: "Port"
1155
+ },
1156
+ columns: {
1157
+ property: "Property",
1158
+ label: "Label",
1159
+ type: "Type",
1160
+ required: "Required",
1161
+ default: "Default",
1162
+ description: "Description"
1163
+ },
1164
+ values: {
1165
+ yes: "Yes",
1166
+ no: "No"
1167
+ }
1168
+ },
1169
+ de: {
1170
+ sections: {
1171
+ properties: "Eigenschaften",
1172
+ credentials: "Zugangsdaten",
1173
+ input: "Eingang",
1174
+ output: "Ausgang",
1175
+ outputs: "Ausg\xE4nge",
1176
+ port: "Port"
1177
+ },
1178
+ columns: {
1179
+ property: "Eigenschaft",
1180
+ label: "Bezeichnung",
1181
+ type: "Typ",
1182
+ required: "Erforderlich",
1183
+ default: "Standard",
1184
+ description: "Beschreibung"
1185
+ },
1186
+ values: {
1187
+ yes: "Ja",
1188
+ no: "Nein"
1189
+ }
1190
+ },
1191
+ "es-ES": {
1192
+ sections: {
1193
+ properties: "Propiedades",
1194
+ credentials: "Credenciales",
1195
+ input: "Entrada",
1196
+ output: "Salida",
1197
+ outputs: "Salidas",
1198
+ port: "Puerto"
1199
+ },
1200
+ columns: {
1201
+ property: "Propiedad",
1202
+ label: "Etiqueta",
1203
+ type: "Tipo",
1204
+ required: "Requerido",
1205
+ default: "Predeterminado",
1206
+ description: "Descripci\xF3n"
1207
+ },
1208
+ values: {
1209
+ yes: "S\xED",
1210
+ no: "No"
1211
+ }
1212
+ },
1213
+ fr: {
1214
+ sections: {
1215
+ properties: "Propri\xE9t\xE9s",
1216
+ credentials: "Identifiants",
1217
+ input: "Entr\xE9e",
1218
+ output: "Sortie",
1219
+ outputs: "Sorties",
1220
+ port: "Port"
1221
+ },
1222
+ columns: {
1223
+ property: "Propri\xE9t\xE9",
1224
+ label: "Libell\xE9",
1225
+ type: "Type",
1226
+ required: "Requis",
1227
+ default: "Par d\xE9faut",
1228
+ description: "Description"
1229
+ },
1230
+ values: {
1231
+ yes: "Oui",
1232
+ no: "Non"
1233
+ }
1234
+ },
1235
+ ko: {
1236
+ sections: {
1237
+ properties: "\uC18D\uC131",
1238
+ credentials: "\uC790\uACA9 \uC99D\uBA85",
1239
+ input: "\uC785\uB825",
1240
+ output: "\uCD9C\uB825",
1241
+ outputs: "\uCD9C\uB825",
1242
+ port: "\uD3EC\uD2B8"
1243
+ },
1244
+ columns: {
1245
+ property: "\uC18D\uC131",
1246
+ label: "\uB77C\uBCA8",
1247
+ type: "\uC720\uD615",
1248
+ required: "\uD544\uC218",
1249
+ default: "\uAE30\uBCF8\uAC12",
1250
+ description: "\uC124\uBA85"
1251
+ },
1252
+ values: {
1253
+ yes: "\uC608",
1254
+ no: "\uC544\uB2C8\uC624"
1255
+ }
1256
+ },
1257
+ "pt-BR": {
1258
+ sections: {
1259
+ properties: "Propriedades",
1260
+ credentials: "Credenciais",
1261
+ input: "Entrada",
1262
+ output: "Sa\xEDda",
1263
+ outputs: "Sa\xEDdas",
1264
+ port: "Porta"
1265
+ },
1266
+ columns: {
1267
+ property: "Propriedade",
1268
+ label: "R\xF3tulo",
1269
+ type: "Tipo",
1270
+ required: "Obrigat\xF3rio",
1271
+ default: "Padr\xE3o",
1272
+ description: "Descri\xE7\xE3o"
1273
+ },
1274
+ values: {
1275
+ yes: "Sim",
1276
+ no: "N\xE3o"
1277
+ }
1278
+ },
1279
+ ru: {
1280
+ sections: {
1281
+ properties: "\u0421\u0432\u043E\u0439\u0441\u0442\u0432\u0430",
1282
+ credentials: "\u0423\u0447\u0451\u0442\u043D\u044B\u0435 \u0434\u0430\u043D\u043D\u044B\u0435",
1283
+ input: "\u0412\u0445\u043E\u0434",
1284
+ output: "\u0412\u044B\u0445\u043E\u0434",
1285
+ outputs: "\u0412\u044B\u0445\u043E\u0434\u044B",
1286
+ port: "\u041F\u043E\u0440\u0442"
1287
+ },
1288
+ columns: {
1289
+ property: "\u0421\u0432\u043E\u0439\u0441\u0442\u0432\u043E",
1290
+ label: "\u041C\u0435\u0442\u043A\u0430",
1291
+ type: "\u0422\u0438\u043F",
1292
+ required: "\u041E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u043E",
1293
+ default: "\u041F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E",
1294
+ description: "\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435"
1295
+ },
1296
+ values: {
1297
+ yes: "\u0414\u0430",
1298
+ no: "\u041D\u0435\u0442"
1299
+ }
1300
+ },
1301
+ ja: {
1302
+ sections: {
1303
+ properties: "\u30D7\u30ED\u30D1\u30C6\u30A3",
1304
+ credentials: "\u8A8D\u8A3C\u60C5\u5831",
1305
+ input: "\u5165\u529B",
1306
+ output: "\u51FA\u529B",
1307
+ outputs: "\u51FA\u529B",
1308
+ port: "\u30DD\u30FC\u30C8"
1309
+ },
1310
+ columns: {
1311
+ property: "\u30D7\u30ED\u30D1\u30C6\u30A3",
1312
+ label: "\u30E9\u30D9\u30EB",
1313
+ type: "\u578B",
1314
+ required: "\u5FC5\u9808",
1315
+ default: "\u30C7\u30D5\u30A9\u30EB\u30C8",
1316
+ description: "\u8AAC\u660E"
1317
+ },
1318
+ values: {
1319
+ yes: "\u306F\u3044",
1320
+ no: "\u3044\u3044\u3048"
1321
+ }
1322
+ },
1323
+ "zh-CN": {
1324
+ sections: {
1325
+ properties: "\u5C5E\u6027",
1326
+ credentials: "\u51ED\u8BC1",
1327
+ input: "\u8F93\u5165",
1328
+ output: "\u8F93\u51FA",
1329
+ outputs: "\u8F93\u51FA",
1330
+ port: "\u7AEF\u53E3"
1331
+ },
1332
+ columns: {
1333
+ property: "\u5C5E\u6027",
1334
+ label: "\u6807\u7B7E",
1335
+ type: "\u7C7B\u578B",
1336
+ required: "\u5FC5\u586B",
1337
+ default: "\u9ED8\u8BA4\u503C",
1338
+ description: "\u63CF\u8FF0"
1339
+ },
1340
+ values: {
1341
+ yes: "\u662F",
1342
+ no: "\u5426"
1343
+ }
1344
+ },
1345
+ "zh-TW": {
1346
+ sections: {
1347
+ properties: "\u5C6C\u6027",
1348
+ credentials: "\u6191\u8B49",
1349
+ input: "\u8F38\u5165",
1350
+ output: "\u8F38\u51FA",
1351
+ outputs: "\u8F38\u51FA",
1352
+ port: "\u57E0"
1353
+ },
1354
+ columns: {
1355
+ property: "\u5C6C\u6027",
1356
+ label: "\u6A19\u7C64",
1357
+ type: "\u985E\u578B",
1358
+ required: "\u5FC5\u586B",
1359
+ default: "\u9810\u8A2D\u503C",
1360
+ description: "\u63CF\u8FF0"
1361
+ },
1362
+ values: {
1363
+ yes: "\u662F",
1364
+ no: "\u5426"
1365
+ }
1366
+ }
1367
+ };
1368
+ function getHelpTranslations(lang) {
1369
+ return translations[lang] ?? translations["en-US"];
1370
+ }
1371
+
1372
+ // src/vite/client/plugins/help-generator.ts
1121
1373
  function buildPropertyRow(name, schema, required, label) {
1122
1374
  let type = "";
1123
1375
  if (schema["x-nrg-node-type"]) {
@@ -1154,7 +1406,15 @@ var SKIP_FIELDS = /* @__PURE__ */ new Set([
1154
1406
  "g",
1155
1407
  "_users"
1156
1408
  ]);
1157
- function generateSchemaSection(title, schema, labels, heading = "###") {
1409
+ function generateSchemaSection(options) {
1410
+ const {
1411
+ title,
1412
+ schema,
1413
+ t,
1414
+ labels,
1415
+ heading = "###",
1416
+ includeDefault = true
1417
+ } = options;
1158
1418
  if (!schema?.properties) return "";
1159
1419
  const required = new Set(schema.required ?? []);
1160
1420
  const rows = Object.entries(schema.properties).filter(([key]) => !SKIP_FIELDS.has(key)).map(
@@ -1167,10 +1427,24 @@ function generateSchemaSection(title, schema, labels, heading = "###") {
1167
1427
  );
1168
1428
  if (rows.length === 0) return "";
1169
1429
  const hasLabels = rows.some((r) => r.label);
1170
- const headerCells = hasLabels ? '<th>Property</th><th>Label</th><th>Type</th><th>Required</th><th>Default</th><th style="width:35%">Description</th>' : '<th>Property</th><th>Type</th><th>Required</th><th>Default</th><th style="width:40%">Description</th>';
1171
- const tableRows = rows.map(
1172
- (r) => hasLabels ? `<tr><td>${r.name}</td><td>${r.label}</td><td>${r.type}</td><td>${r.required ? "Yes" : "No"}</td><td>${r.defaultVal ? `<code>${r.defaultVal}</code>` : ""}</td><td>${r.description}</td></tr>` : `<tr><td>${r.name}</td><td>${r.type}</td><td>${r.required ? "Yes" : "No"}</td><td>${r.defaultVal ? `<code>${r.defaultVal}</code>` : ""}</td><td>${r.description}</td></tr>`
1173
- ).join("\n");
1430
+ const c = t.columns;
1431
+ const v = t.values;
1432
+ let headerCells;
1433
+ let rowFn;
1434
+ if (hasLabels && includeDefault) {
1435
+ headerCells = `<th>${c.label}</th><th>${c.property}</th><th>${c.type}</th><th>${c.required}</th><th>${c.default}</th><th style="width:35%">${c.description}</th>`;
1436
+ rowFn = (r) => `<tr><td>${r.label}</td><td>${r.name}</td><td>${r.type}</td><td>${r.required ? v.yes : v.no}</td><td>${r.defaultVal ? `<code>${r.defaultVal}</code>` : ""}</td><td>${r.description}</td></tr>`;
1437
+ } else if (hasLabels) {
1438
+ headerCells = `<th>${c.label}</th><th>${c.property}</th><th>${c.type}</th><th>${c.required}</th><th style="width:35%">${c.description}</th>`;
1439
+ rowFn = (r) => `<tr><td>${r.label}</td><td>${r.name}</td><td>${r.type}</td><td>${r.required ? v.yes : v.no}</td><td>${r.description}</td></tr>`;
1440
+ } else if (includeDefault) {
1441
+ headerCells = `<th>${c.property}</th><th>${c.type}</th><th>${c.required}</th><th>${c.default}</th><th style="width:40%">${c.description}</th>`;
1442
+ rowFn = (r) => `<tr><td>${r.name}</td><td>${r.type}</td><td>${r.required ? v.yes : v.no}</td><td>${r.defaultVal ? `<code>${r.defaultVal}</code>` : ""}</td><td>${r.description}</td></tr>`;
1443
+ } else {
1444
+ headerCells = `<th>${c.property}</th><th>${c.type}</th><th>${c.required}</th><th style="width:40%">${c.description}</th>`;
1445
+ rowFn = (r) => `<tr><td>${r.name}</td><td>${r.type}</td><td>${r.required ? v.yes : v.no}</td><td>${r.description}</td></tr>`;
1446
+ }
1447
+ const tableRows = rows.map(rowFn).join("\n");
1174
1448
  const table = `<div style="overflow-x:auto">
1175
1449
  <table width="100%" style="min-width:500px">
1176
1450
  <thead><tr>${headerCells}</tr></thead>
@@ -1179,8 +1453,9 @@ ${tableRows}
1179
1453
  </tbody>
1180
1454
  </table>
1181
1455
  </div>`;
1182
- return `${heading} ${title}
1183
-
1456
+ const headingLevel = heading.length;
1457
+ const tag = `h${headingLevel}`;
1458
+ return `<${tag}>${title}</${tag}>
1184
1459
  ${table}
1185
1460
  `;
1186
1461
  }
@@ -1199,65 +1474,66 @@ function loadNodeLabels(labelPath) {
1199
1474
  return {};
1200
1475
  }
1201
1476
  }
1202
- function generateHelpDoc(nodeClass, labels) {
1477
+ function generateHelpDoc(nodeClass, labels, t) {
1203
1478
  const lines = [];
1204
1479
  if (labels.description) {
1205
- lines.push(labels.description);
1206
- lines.push("");
1480
+ lines.push(`<p>${labels.description}</p>`);
1207
1481
  }
1208
- const configSection = generateSchemaSection(
1209
- "Properties",
1210
- nodeClass.configSchema,
1211
- labels.configs
1212
- );
1482
+ const configSection = generateSchemaSection({
1483
+ title: t.sections.properties,
1484
+ schema: nodeClass.configSchema,
1485
+ t,
1486
+ labels: labels.configs
1487
+ });
1213
1488
  if (configSection) lines.push(configSection);
1214
- const credsSection = generateSchemaSection(
1215
- "Credentials",
1216
- nodeClass.credentialsSchema,
1217
- labels.credentials
1218
- );
1489
+ const credsSection = generateSchemaSection({
1490
+ title: t.sections.credentials,
1491
+ schema: nodeClass.credentialsSchema,
1492
+ t,
1493
+ labels: labels.credentials
1494
+ });
1219
1495
  if (credsSection) lines.push(credsSection);
1220
1496
  if (nodeClass.inputSchema) {
1221
- const inputLabels = nodeClass.inputLabels;
1222
- const inputLabel = typeof inputLabels === "string" ? inputLabels : Array.isArray(inputLabels) ? inputLabels[0] : void 0;
1223
- const inputTitle = inputLabel ? `Input (${inputLabel})` : "Input";
1224
- const inputSection = generateSchemaSection(
1225
- inputTitle,
1226
- nodeClass.inputSchema,
1227
- labels.input
1228
- );
1497
+ const inputSection = generateSchemaSection({
1498
+ title: t.sections.input,
1499
+ schema: nodeClass.inputSchema,
1500
+ t,
1501
+ labels: labels.input,
1502
+ includeDefault: false
1503
+ });
1229
1504
  if (inputSection) lines.push(inputSection);
1230
1505
  }
1231
1506
  if (nodeClass.outputsSchema) {
1232
- const outputLabels = nodeClass.outputLabels;
1233
1507
  if (Array.isArray(nodeClass.outputsSchema)) {
1234
1508
  const portSections = [];
1235
1509
  nodeClass.outputsSchema.forEach((schema, i) => {
1236
- const portLabel = Array.isArray(outputLabels) ? outputLabels[i] : void 0;
1237
- const title = portLabel ? `Port ${i + 1} \u2014 ${portLabel}` : `Port ${i + 1}`;
1510
+ const title = `${t.sections.port} ${i + 1}`;
1238
1511
  const portPropLabels = labels.outputs?.[i];
1239
- const section = generateSchemaSection(
1512
+ const section = generateSchemaSection({
1240
1513
  title,
1241
1514
  schema,
1242
- portPropLabels,
1243
- "####"
1244
- );
1515
+ t,
1516
+ labels: portPropLabels,
1517
+ heading: "####",
1518
+ includeDefault: false
1519
+ });
1245
1520
  if (section) portSections.push(section);
1246
1521
  });
1247
1522
  if (portSections.length) {
1248
- lines.push(`### Outputs
1249
-
1250
- ${portSections.join("\n")}`);
1523
+ lines.push(
1524
+ `<h3>${t.sections.outputs}</h3>
1525
+ ${portSections.join("\n")}`
1526
+ );
1251
1527
  }
1252
1528
  } else {
1253
- const label = typeof outputLabels === "string" ? outputLabels : Array.isArray(outputLabels) ? outputLabels[0] : void 0;
1254
- const title = label ? `Output (${label})` : "Output";
1255
1529
  const outputPropLabels = labels.outputs?.[0];
1256
- const section = generateSchemaSection(
1257
- title,
1258
- nodeClass.outputsSchema,
1259
- outputPropLabels
1260
- );
1530
+ const section = generateSchemaSection({
1531
+ title: t.sections.output,
1532
+ schema: nodeClass.outputsSchema,
1533
+ t,
1534
+ labels: outputPropLabels,
1535
+ includeDefault: false
1536
+ });
1261
1537
  if (section) lines.push(section);
1262
1538
  }
1263
1539
  }
@@ -1305,11 +1581,12 @@ function helpGenerator(options) {
1305
1581
  if (fs6.existsSync(manualMd) || fs6.existsSync(manualHtml)) continue;
1306
1582
  const labelPath = path6.join(labelsDir, type, `${lang}.json`);
1307
1583
  const labels = loadNodeLabels(labelPath);
1308
- const content = generateHelpDoc(NodeClass, labels);
1584
+ const t = getHelpTranslations(lang);
1585
+ const content = generateHelpDoc(NodeClass, labels, t);
1309
1586
  if (!content) continue;
1310
1587
  if (!helpByLang.has(lang)) helpByLang.set(lang, []);
1311
1588
  helpByLang.get(lang).push(
1312
- `<script type="text/markdown" data-help-name="${type}">
1589
+ `<script type="text/html" data-help-name="${type}">
1313
1590
  ${content}
1314
1591
  </script>`
1315
1592
  );
@@ -1609,12 +1886,8 @@ function nodeDefinitionsInliner(serverOutDir, entryPath, iconsDir, componentsDir
1609
1886
  align: NodeClass.align,
1610
1887
  color: NodeClass.color,
1611
1888
  icon: iconsDir ? resolveIcon(iconsDir, type) : void 0,
1612
- labelStyle: NodeClass.labelStyle,
1613
- paletteLabel: NodeClass.paletteLabel,
1614
1889
  inputs: NodeClass.inputs,
1615
1890
  outputs: NodeClass.outputs,
1616
- inputLabels: NodeClass.inputLabels,
1617
- outputLabels: NodeClass.outputLabels,
1618
1891
  inputSchema,
1619
1892
  outputsSchema
1620
1893
  };
@@ -2020,10 +2293,14 @@ function serverPlugin(options) {
2020
2293
  changeOrigin: true,
2021
2294
  ws: true,
2022
2295
  configure: (proxy) => {
2023
- proxy.on("error", () => {
2296
+ proxy.on("error", (_err, _req, res) => {
2024
2297
  if (nodeRedPort) {
2025
2298
  proxy.options.target = `http://127.0.0.1:${nodeRedPort}`;
2026
2299
  }
2300
+ if (res && !res.headersSent && "writeHead" in res) {
2301
+ res.writeHead(502);
2302
+ res.end();
2303
+ }
2027
2304
  });
2028
2305
  }
2029
2306
  }
@@ -2038,7 +2315,11 @@ function serverPlugin(options) {
2038
2315
  info: () => {
2039
2316
  },
2040
2317
  warn: console.warn,
2041
- error: console.error,
2318
+ error: (...args) => {
2319
+ const msg = args.map(String).join(" ");
2320
+ if (isStarting && msg.includes("ECONNREFUSED")) return;
2321
+ console.error(...args);
2322
+ },
2042
2323
  warnOnce: () => {
2043
2324
  },
2044
2325
  hasWarned: false,