@bonsae/nrg 0.1.0 → 0.2.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/build/server/index.cjs +12 -1
- package/build/server/resources/nrg-client.js +9 -3
- package/build/vite/index.js +86 -57
- package/package.json +4 -1
- package/src/core/client/components/node-red-json-schema-form.vue +10 -0
- package/src/core/server/schemas/type.ts +16 -2
- package/src/vite/client/build.ts +1 -1
- package/src/vite/client/plugins/minifier.ts +9 -8
- package/src/vite/client/plugins/node-definitions-inliner.ts +107 -56
package/build/server/index.cjs
CHANGED
|
@@ -661,13 +661,24 @@ function NodeRef(nodeClass, options) {
|
|
|
661
661
|
};
|
|
662
662
|
}
|
|
663
663
|
function TypedInput(options) {
|
|
664
|
+
const { types, ...rest } = options ?? {};
|
|
664
665
|
return {
|
|
665
666
|
...TypedInputSchema,
|
|
666
|
-
...
|
|
667
|
+
...rest,
|
|
668
|
+
...types ? { "x-typed-types": types } : {},
|
|
667
669
|
[import_typebox.Kind]: "TypedInput"
|
|
668
670
|
};
|
|
669
671
|
}
|
|
672
|
+
var _OriginalString = import_typebox.Type.String.bind(import_typebox.Type);
|
|
673
|
+
function StringWithLang(options) {
|
|
674
|
+
const { lang, ...rest } = options ?? {};
|
|
675
|
+
return _OriginalString({
|
|
676
|
+
...rest,
|
|
677
|
+
...lang ? { "x-editor-language": lang } : {}
|
|
678
|
+
});
|
|
679
|
+
}
|
|
670
680
|
var SchemaType = Object.assign({}, import_typebox.Type, {
|
|
681
|
+
String: StringWithLang,
|
|
671
682
|
NodeRef,
|
|
672
683
|
TypedInput
|
|
673
684
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(){var s=document.createElement("style");s.textContent="[data-v-e5c98949] .node-red-vue-input-error-message{color:var(--red-ui-text-color-error)}[data-v-e5c98949] .nrg-label{display:inline-block;width:100%;cursor:default}[data-v-e5c98949] .form-row input[type=text],[data-v-e5c98949] .form-row input[type=number],[data-v-e5c98949] .form-row input[type=password]{height:34px;padding:0 8px;box-sizing:border-box}.container[data-v-508cfdb8]{position:relative}.expand-button[data-v-508cfdb8]{position:absolute;top:-23px;right:0;z-index:10;transition:color .3s ease;cursor:pointer}.nrg-required[data-v-
|
|
1
|
+
(function(){var s=document.createElement("style");s.textContent="[data-v-e5c98949] .node-red-vue-input-error-message{color:var(--red-ui-text-color-error)}[data-v-e5c98949] .nrg-label{display:inline-block;width:100%;cursor:default}[data-v-e5c98949] .form-row input[type=text],[data-v-e5c98949] .form-row input[type=number],[data-v-e5c98949] .form-row input[type=password]{height:34px;padding:0 8px;box-sizing:border-box}.container[data-v-508cfdb8]{position:relative}.expand-button[data-v-508cfdb8]{position:absolute;top:-23px;right:0;z-index:10;transition:color .3s ease;cursor:pointer}.nrg-required[data-v-2a313890]{color:var(--red-ui-text-color-error);margin-left:2px}\n";document.head.appendChild(s);})();
|
|
2
2
|
import { defineComponent as je, resolveComponent as qe, openBlock as te, createElementBlock as re, Fragment as Ke, createElementVNode as ue, createCommentVNode as ge, createVNode as Vn, toDisplayString as Pe, withDirectives as ws, vShow as bs, renderList as fr, createTextVNode as pr, createBlock as ze, createApp as Es } from "/nrg/assets/vue.esm-browser.prod.js";
|
|
3
3
|
function Ss() {
|
|
4
4
|
}
|
|
@@ -6168,7 +6168,13 @@ function Dn(e, t, r) {
|
|
|
6168
6168
|
language: t["x-editor-language"]
|
|
6169
6169
|
} : { key: e, label: s, inputType: "text", required: r, htmlType: "text" };
|
|
6170
6170
|
default:
|
|
6171
|
-
return {
|
|
6171
|
+
return t["x-editor-language"] ? {
|
|
6172
|
+
key: e,
|
|
6173
|
+
label: s,
|
|
6174
|
+
inputType: "editor",
|
|
6175
|
+
required: r,
|
|
6176
|
+
language: t["x-editor-language"]
|
|
6177
|
+
} : {
|
|
6172
6178
|
key: e,
|
|
6173
6179
|
label: s,
|
|
6174
6180
|
inputType: "text",
|
|
@@ -6348,7 +6354,7 @@ function Bo(e, t, r, s, m, o) {
|
|
|
6348
6354
|
))
|
|
6349
6355
|
]);
|
|
6350
6356
|
}
|
|
6351
|
-
const Mn = /* @__PURE__ */ Ie(zo, [["render", Bo], ["__scopeId", "data-v-
|
|
6357
|
+
const Mn = /* @__PURE__ */ Ie(zo, [["render", Bo], ["__scopeId", "data-v-2a313890"]]), gs = {}, sr = {};
|
|
6352
6358
|
function Qo(e) {
|
|
6353
6359
|
Object.assign(gs, e);
|
|
6354
6360
|
}
|
package/build/vite/index.js
CHANGED
|
@@ -1183,14 +1183,15 @@ function minifier() {
|
|
|
1183
1183
|
return {
|
|
1184
1184
|
name: "vite-plugin-node-red:client:minifier",
|
|
1185
1185
|
apply: "build",
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1186
|
+
async generateBundle(_options, bundle) {
|
|
1187
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
1188
|
+
if (chunk.type === "chunk" && fileName.endsWith(".js")) {
|
|
1189
|
+
const result = await transform(chunk.code, {
|
|
1190
|
+
minify: true
|
|
1191
|
+
});
|
|
1192
|
+
chunk.code = result.code;
|
|
1193
|
+
chunk.map = null;
|
|
1192
1194
|
}
|
|
1193
|
-
return code;
|
|
1194
1195
|
}
|
|
1195
1196
|
}
|
|
1196
1197
|
};
|
|
@@ -1204,8 +1205,6 @@ import fs8 from "fs";
|
|
|
1204
1205
|
import mime2 from "mime-types";
|
|
1205
1206
|
var VIRTUAL_ID = "virtual:nrg/node-definitions";
|
|
1206
1207
|
var RESOLVED_ID = "\0" + VIRTUAL_ID;
|
|
1207
|
-
var VIRTUAL_ENTRY_ID = "virtual:nrg/client-entry";
|
|
1208
|
-
var RESOLVED_ENTRY_ID = "\0" + VIRTUAL_ENTRY_ID;
|
|
1209
1208
|
var SKIP_DEFAULTS = /* @__PURE__ */ new Set(["x", "y", "z", "g", "wires", "type", "id"]);
|
|
1210
1209
|
function getDefaultsFromSchema(schema) {
|
|
1211
1210
|
if (!schema?.properties) return void 0;
|
|
@@ -1243,6 +1242,7 @@ function resolveIcon(iconsDir, type) {
|
|
|
1243
1242
|
function nodeDefinitionsInliner(serverOutDir, entryPath, iconsDir, componentsDir, nodesDir, hasUserEntry = true) {
|
|
1244
1243
|
let _nodeTypes = [];
|
|
1245
1244
|
let _definitions = {};
|
|
1245
|
+
const cacheDir = path8.resolve("node_modules", ".nrg", "client");
|
|
1246
1246
|
return {
|
|
1247
1247
|
name: "vite-plugin-node-red:client:node-definitions-inliner",
|
|
1248
1248
|
enforce: "pre",
|
|
@@ -1302,64 +1302,93 @@ function nodeDefinitionsInliner(serverOutDir, entryPath, iconsDir, componentsDir
|
|
|
1302
1302
|
outputsSchema
|
|
1303
1303
|
};
|
|
1304
1304
|
}
|
|
1305
|
+
if (!hasUserEntry) {
|
|
1306
|
+
const nodesCache = path8.resolve(cacheDir, "nodes");
|
|
1307
|
+
if (fs8.existsSync(nodesCache)) {
|
|
1308
|
+
fs8.rmSync(nodesCache, { recursive: true });
|
|
1309
|
+
}
|
|
1310
|
+
fs8.mkdirSync(nodesCache, { recursive: true });
|
|
1311
|
+
for (const type of _nodeTypes) {
|
|
1312
|
+
const userTsPath = nodesDir ? path8.resolve(nodesDir, `${type}.ts`) : null;
|
|
1313
|
+
if (userTsPath && fs8.existsSync(userTsPath)) continue;
|
|
1314
|
+
const content = [
|
|
1315
|
+
`// auto-generated by nrg`,
|
|
1316
|
+
`import { defineNode } from "@bonsae/nrg/client";`,
|
|
1317
|
+
``,
|
|
1318
|
+
`export default defineNode({`,
|
|
1319
|
+
` type: ${JSON.stringify(type)},`,
|
|
1320
|
+
`});`,
|
|
1321
|
+
``
|
|
1322
|
+
].join("\n");
|
|
1323
|
+
fs8.writeFileSync(path8.resolve(nodesCache, `${type}.ts`), content);
|
|
1324
|
+
}
|
|
1325
|
+
const entryContent = generateEntryCode("");
|
|
1326
|
+
fs8.mkdirSync(path8.dirname(path8.resolve(cacheDir, "index.ts")), {
|
|
1327
|
+
recursive: true
|
|
1328
|
+
});
|
|
1329
|
+
fs8.writeFileSync(path8.resolve(cacheDir, "index.ts"), entryContent);
|
|
1330
|
+
}
|
|
1305
1331
|
},
|
|
1306
1332
|
resolveId(id) {
|
|
1307
1333
|
if (id === VIRTUAL_ID) return RESOLVED_ID;
|
|
1308
|
-
if (id === VIRTUAL_ENTRY_ID) return RESOLVED_ENTRY_ID;
|
|
1309
1334
|
},
|
|
1310
1335
|
load(id) {
|
|
1311
|
-
if (id ===
|
|
1312
|
-
|
|
1313
|
-
|
|
1336
|
+
if (id === RESOLVED_ID)
|
|
1337
|
+
return `export default ${JSON.stringify(_definitions)};`;
|
|
1338
|
+
if (!hasUserEntry && id === entryPath) {
|
|
1339
|
+
return generateEntryCode("");
|
|
1340
|
+
}
|
|
1314
1341
|
},
|
|
1315
1342
|
transform(code, id) {
|
|
1316
|
-
if (id !== entryPath
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
postLines.push(`__setForms({ ${formEntries.join(", ")} });`);
|
|
1343
|
+
if (id !== entryPath) return;
|
|
1344
|
+
if (!hasUserEntry) return;
|
|
1345
|
+
return { code: generateEntryCode(code), map: null };
|
|
1346
|
+
}
|
|
1347
|
+
};
|
|
1348
|
+
function generateEntryCode(userCode) {
|
|
1349
|
+
const nrgImports = /* @__PURE__ */ new Set(["__setSchemas"]);
|
|
1350
|
+
const lines = [`import __nrgSchemas from "${VIRTUAL_ID}";`];
|
|
1351
|
+
const postLines = [`__setSchemas(__nrgSchemas);`];
|
|
1352
|
+
if (componentsDir && fs8.existsSync(componentsDir)) {
|
|
1353
|
+
const formImports = [];
|
|
1354
|
+
const formEntries = [];
|
|
1355
|
+
for (const type of _nodeTypes) {
|
|
1356
|
+
const componentPath = path8.resolve(componentsDir, `${type}.vue`);
|
|
1357
|
+
if (fs8.existsSync(componentPath)) {
|
|
1358
|
+
const varName = `__nrgForm_${type.replace(/-/g, "_")}`;
|
|
1359
|
+
formImports.push(
|
|
1360
|
+
`import ${varName} from ${JSON.stringify(componentPath)};`
|
|
1361
|
+
);
|
|
1362
|
+
formEntries.push(`${JSON.stringify(type)}: ${varName}`);
|
|
1337
1363
|
}
|
|
1338
1364
|
}
|
|
1339
|
-
if (
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
const tsPath = nodesDir ? path8.resolve(nodesDir, `${type}.ts`) : null;
|
|
1344
|
-
if (tsPath && fs8.existsSync(tsPath)) {
|
|
1345
|
-
lines.push(`import ${varName} from ${JSON.stringify(tsPath)};`);
|
|
1346
|
-
} else {
|
|
1347
|
-
lines.push(`const ${varName} = { type: ${JSON.stringify(type)} };`);
|
|
1348
|
-
}
|
|
1349
|
-
defVarNames.push(varName);
|
|
1350
|
-
}
|
|
1351
|
-
if (defVarNames.length > 0) {
|
|
1352
|
-
nrgImports.add("registerTypes");
|
|
1353
|
-
postLines.push(`registerTypes([${defVarNames.join(", ")}]);`);
|
|
1354
|
-
}
|
|
1365
|
+
if (formImports.length > 0) {
|
|
1366
|
+
lines.push(...formImports);
|
|
1367
|
+
nrgImports.add("__setForms");
|
|
1368
|
+
postLines.push(`__setForms({ ${formEntries.join(", ")} });`);
|
|
1355
1369
|
}
|
|
1356
|
-
const importLine = `import { ${[...nrgImports].join(", ")} } from "@bonsae/nrg/client";`;
|
|
1357
|
-
lines.splice(1, 0, importLine);
|
|
1358
|
-
lines.push(...postLines);
|
|
1359
|
-
lines.push("");
|
|
1360
|
-
return { code: lines.join("\n") + code, map: null };
|
|
1361
1370
|
}
|
|
1362
|
-
|
|
1371
|
+
if (!hasUserEntry) {
|
|
1372
|
+
const nodesCache = path8.resolve(cacheDir, "nodes");
|
|
1373
|
+
const defVarNames = [];
|
|
1374
|
+
for (const type of _nodeTypes) {
|
|
1375
|
+
const varName = `__nrgNodeDef_${type.replace(/-/g, "_")}`;
|
|
1376
|
+
const userTsPath = nodesDir ? path8.resolve(nodesDir, `${type}.ts`) : null;
|
|
1377
|
+
const tsPath = userTsPath && fs8.existsSync(userTsPath) ? userTsPath : path8.resolve(nodesCache, `${type}.ts`);
|
|
1378
|
+
lines.push(`import ${varName} from ${JSON.stringify(tsPath)};`);
|
|
1379
|
+
defVarNames.push(varName);
|
|
1380
|
+
}
|
|
1381
|
+
if (defVarNames.length > 0) {
|
|
1382
|
+
nrgImports.add("registerTypes");
|
|
1383
|
+
postLines.push(`registerTypes([${defVarNames.join(", ")}]);`);
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
const importLine = `import { ${[...nrgImports].join(", ")} } from "@bonsae/nrg/client";`;
|
|
1387
|
+
lines.splice(1, 0, importLine);
|
|
1388
|
+
lines.push(...postLines);
|
|
1389
|
+
lines.push("");
|
|
1390
|
+
return lines.join("\n") + userCode;
|
|
1391
|
+
}
|
|
1363
1392
|
}
|
|
1364
1393
|
|
|
1365
1394
|
// src/vite/client/plugins/static-copy.ts
|
|
@@ -1525,7 +1554,7 @@ async function build2(clientBuildOptions, buildContext) {
|
|
|
1525
1554
|
build: {
|
|
1526
1555
|
outDir: buildContext.outDir,
|
|
1527
1556
|
emptyOutDir: false,
|
|
1528
|
-
sourcemap: buildContext.isDev ? "inline" :
|
|
1557
|
+
sourcemap: buildContext.isDev ? "inline" : false,
|
|
1529
1558
|
minify: !buildContext.isDev && format !== "es",
|
|
1530
1559
|
copyPublicDir: false,
|
|
1531
1560
|
lib: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bonsae/nrg",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "NRG framework — build Node-RED nodes with Vue 3, TypeScript, and JSON Schema",
|
|
5
5
|
"author": "Allan Oricil <allanoricil@duck.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -23,6 +23,9 @@
|
|
|
23
23
|
"lint:fix": "eslint src/ --fix",
|
|
24
24
|
"format": "prettier --write \"src/**/*.{ts,vue,json}\"",
|
|
25
25
|
"format:check": "prettier --check \"src/**/*.{ts,vue,json}\"",
|
|
26
|
+
"docs:dev": "pnpm --dir docs dev",
|
|
27
|
+
"docs:build": "pnpm --dir docs build",
|
|
28
|
+
"docs:preview": "pnpm --dir docs preview",
|
|
26
29
|
"prepare": "husky"
|
|
27
30
|
},
|
|
28
31
|
"files": [
|
|
@@ -291,6 +291,16 @@ function buildField(
|
|
|
291
291
|
return { key, label, inputType: "text", required, htmlType: "text" };
|
|
292
292
|
|
|
293
293
|
default:
|
|
294
|
+
// string with editor language → code editor
|
|
295
|
+
if (schema["x-editor-language"]) {
|
|
296
|
+
return {
|
|
297
|
+
key,
|
|
298
|
+
label,
|
|
299
|
+
inputType: "editor",
|
|
300
|
+
required,
|
|
301
|
+
language: schema["x-editor-language"],
|
|
302
|
+
};
|
|
303
|
+
}
|
|
294
304
|
// string (or untyped)
|
|
295
305
|
return {
|
|
296
306
|
key,
|
|
@@ -26,15 +26,29 @@ function NodeRef<T extends new (...args: any[]) => any>(
|
|
|
26
26
|
} as unknown as TNodeRef<InstanceType<T>>;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
function TypedInput(
|
|
29
|
+
function TypedInput(
|
|
30
|
+
options?: SchemaOptions & { types?: string[] },
|
|
31
|
+
): TTypedInput {
|
|
32
|
+
const { types, ...rest } = options ?? {};
|
|
30
33
|
return {
|
|
31
34
|
...TypedInputSchema,
|
|
32
|
-
...
|
|
35
|
+
...rest,
|
|
36
|
+
...(types ? { "x-typed-types": types } : {}),
|
|
33
37
|
[Kind]: "TypedInput",
|
|
34
38
|
} as unknown as TTypedInput;
|
|
35
39
|
}
|
|
36
40
|
|
|
41
|
+
const _OriginalString = BaseType.String.bind(BaseType);
|
|
42
|
+
function StringWithLang(options?: SchemaOptions & { lang?: string }) {
|
|
43
|
+
const { lang, ...rest } = options ?? {};
|
|
44
|
+
return _OriginalString({
|
|
45
|
+
...rest,
|
|
46
|
+
...(lang ? { "x-editor-language": lang } : {}),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
37
50
|
const SchemaType = Object.assign({}, BaseType, {
|
|
51
|
+
String: StringWithLang,
|
|
38
52
|
NodeRef,
|
|
39
53
|
TypedInput,
|
|
40
54
|
});
|
package/src/vite/client/build.ts
CHANGED
|
@@ -173,7 +173,7 @@ async function build(
|
|
|
173
173
|
build: {
|
|
174
174
|
outDir: buildContext.outDir,
|
|
175
175
|
emptyOutDir: false,
|
|
176
|
-
sourcemap: buildContext.isDev ? "inline" :
|
|
176
|
+
sourcemap: buildContext.isDev ? "inline" : false,
|
|
177
177
|
minify: !buildContext.isDev && format !== "es",
|
|
178
178
|
copyPublicDir: false,
|
|
179
179
|
lib: {
|
|
@@ -6,15 +6,16 @@ function minifier(): Plugin {
|
|
|
6
6
|
name: "vite-plugin-node-red:client:minifier",
|
|
7
7
|
apply: "build",
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
async generateBundle(_options, bundle) {
|
|
10
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
11
|
+
if (chunk.type === "chunk" && fileName.endsWith(".js")) {
|
|
12
|
+
const result = await transform(chunk.code, {
|
|
13
|
+
minify: true,
|
|
14
|
+
});
|
|
15
|
+
chunk.code = result.code;
|
|
16
|
+
chunk.map = null as any;
|
|
15
17
|
}
|
|
16
|
-
|
|
17
|
-
},
|
|
18
|
+
}
|
|
18
19
|
},
|
|
19
20
|
};
|
|
20
21
|
}
|
|
@@ -8,9 +8,6 @@ import mime from "mime-types";
|
|
|
8
8
|
const VIRTUAL_ID = "virtual:nrg/node-definitions";
|
|
9
9
|
const RESOLVED_ID = "\0" + VIRTUAL_ID;
|
|
10
10
|
|
|
11
|
-
const VIRTUAL_ENTRY_ID = "virtual:nrg/client-entry";
|
|
12
|
-
const RESOLVED_ENTRY_ID = "\0" + VIRTUAL_ENTRY_ID;
|
|
13
|
-
|
|
14
11
|
const SKIP_DEFAULTS = new Set(["x", "y", "z", "g", "wires", "type", "id"]);
|
|
15
12
|
|
|
16
13
|
function getDefaultsFromSchema(
|
|
@@ -77,6 +74,8 @@ function nodeDefinitionsInliner(
|
|
|
77
74
|
): Plugin {
|
|
78
75
|
let _nodeTypes: string[] = [];
|
|
79
76
|
let _definitions: Record<string, any> = {};
|
|
77
|
+
// Cache directory for generated files (inside node_modules, gitignored)
|
|
78
|
+
const cacheDir = path.resolve("node_modules", ".nrg", "client");
|
|
80
79
|
|
|
81
80
|
return {
|
|
82
81
|
name: "vite-plugin-node-red:client:node-definitions-inliner",
|
|
@@ -145,80 +144,132 @@ function nodeDefinitionsInliner(
|
|
|
145
144
|
outputsSchema,
|
|
146
145
|
};
|
|
147
146
|
}
|
|
147
|
+
|
|
148
|
+
// When no user entry, generate node definition files in cache
|
|
149
|
+
// so they appear as separate files in browser devtools.
|
|
150
|
+
if (!hasUserEntry) {
|
|
151
|
+
const nodesCache = path.resolve(cacheDir, "nodes");
|
|
152
|
+
if (fs.existsSync(nodesCache)) {
|
|
153
|
+
fs.rmSync(nodesCache, { recursive: true });
|
|
154
|
+
}
|
|
155
|
+
fs.mkdirSync(nodesCache, { recursive: true });
|
|
156
|
+
|
|
157
|
+
for (const type of _nodeTypes) {
|
|
158
|
+
// Skip if user has a physical node definition file
|
|
159
|
+
const userTsPath = nodesDir
|
|
160
|
+
? path.resolve(nodesDir, `${type}.ts`)
|
|
161
|
+
: null;
|
|
162
|
+
if (userTsPath && fs.existsSync(userTsPath)) continue;
|
|
163
|
+
|
|
164
|
+
const content = [
|
|
165
|
+
`// auto-generated by nrg`,
|
|
166
|
+
`import { defineNode } from "@bonsae/nrg/client";`,
|
|
167
|
+
``,
|
|
168
|
+
`export default defineNode({`,
|
|
169
|
+
` type: ${JSON.stringify(type)},`,
|
|
170
|
+
`});`,
|
|
171
|
+
``,
|
|
172
|
+
].join("\n");
|
|
173
|
+
fs.writeFileSync(path.resolve(nodesCache, `${type}.ts`), content);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Also write the entry file to cache
|
|
177
|
+
const entryContent = generateEntryCode("");
|
|
178
|
+
fs.mkdirSync(path.dirname(path.resolve(cacheDir, "index.ts")), {
|
|
179
|
+
recursive: true,
|
|
180
|
+
});
|
|
181
|
+
fs.writeFileSync(path.resolve(cacheDir, "index.ts"), entryContent);
|
|
182
|
+
}
|
|
148
183
|
},
|
|
149
184
|
|
|
150
185
|
resolveId(id) {
|
|
151
186
|
if (id === VIRTUAL_ID) return RESOLVED_ID;
|
|
152
|
-
if (id === VIRTUAL_ENTRY_ID) return RESOLVED_ENTRY_ID;
|
|
153
187
|
},
|
|
154
188
|
|
|
155
189
|
load(id) {
|
|
156
|
-
if (id ===
|
|
157
|
-
|
|
158
|
-
|
|
190
|
+
if (id === RESOLVED_ID)
|
|
191
|
+
return `export default ${JSON.stringify(_definitions)};`;
|
|
192
|
+
|
|
193
|
+
// For auto-generated entries, return the generated code directly
|
|
194
|
+
// so the browser devtools shows the actual source instead of the
|
|
195
|
+
// placeholder comment on disk.
|
|
196
|
+
if (!hasUserEntry && id === entryPath) {
|
|
197
|
+
return generateEntryCode("");
|
|
198
|
+
}
|
|
159
199
|
},
|
|
160
200
|
|
|
161
201
|
transform(code, id) {
|
|
162
|
-
if (id !== entryPath
|
|
202
|
+
if (id !== entryPath) return;
|
|
203
|
+
// When the user provides their own entry, prepend the generated
|
|
204
|
+
// code to their source. For auto-generated entries, the load hook
|
|
205
|
+
// already returned the full code.
|
|
206
|
+
if (!hasUserEntry) return;
|
|
163
207
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
208
|
+
return { code: generateEntryCode(code), map: null };
|
|
209
|
+
},
|
|
210
|
+
};
|
|
167
211
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
212
|
+
function generateEntryCode(userCode: string): string {
|
|
213
|
+
const nrgImports = new Set<string>(["__setSchemas"]);
|
|
214
|
+
const lines = [`import __nrgSchemas from "${VIRTUAL_ID}";`];
|
|
215
|
+
const postLines: string[] = [`__setSchemas(__nrgSchemas);`];
|
|
172
216
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
formImports.push(
|
|
178
|
-
`import ${varName} from ${JSON.stringify(componentPath)};`,
|
|
179
|
-
);
|
|
180
|
-
formEntries.push(`${JSON.stringify(type)}: ${varName}`);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
217
|
+
// Auto-detect form components by convention: {componentsDir}/{type}.vue
|
|
218
|
+
if (componentsDir && fs.existsSync(componentsDir)) {
|
|
219
|
+
const formImports: string[] = [];
|
|
220
|
+
const formEntries: string[] = [];
|
|
183
221
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
222
|
+
for (const type of _nodeTypes) {
|
|
223
|
+
const componentPath = path.resolve(componentsDir, `${type}.vue`);
|
|
224
|
+
if (fs.existsSync(componentPath)) {
|
|
225
|
+
const varName = `__nrgForm_${type.replace(/-/g, "_")}`;
|
|
226
|
+
formImports.push(
|
|
227
|
+
`import ${varName} from ${JSON.stringify(componentPath)};`,
|
|
228
|
+
);
|
|
229
|
+
formEntries.push(`${JSON.stringify(type)}: ${varName}`);
|
|
188
230
|
}
|
|
189
231
|
}
|
|
190
232
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
const tsPath = nodesDir ? path.resolve(nodesDir, `${type}.ts`) : null;
|
|
198
|
-
|
|
199
|
-
if (tsPath && fs.existsSync(tsPath)) {
|
|
200
|
-
lines.push(`import ${varName} from ${JSON.stringify(tsPath)};`);
|
|
201
|
-
} else {
|
|
202
|
-
lines.push(`const ${varName} = { type: ${JSON.stringify(type)} };`);
|
|
203
|
-
}
|
|
204
|
-
defVarNames.push(varName);
|
|
205
|
-
}
|
|
233
|
+
if (formImports.length > 0) {
|
|
234
|
+
lines.push(...formImports);
|
|
235
|
+
nrgImports.add("__setForms");
|
|
236
|
+
postLines.push(`__setForms({ ${formEntries.join(", ")} });`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
206
239
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
240
|
+
// Auto-register only when no user entry was provided.
|
|
241
|
+
if (!hasUserEntry) {
|
|
242
|
+
const nodesCache = path.resolve(cacheDir, "nodes");
|
|
243
|
+
const defVarNames: string[] = [];
|
|
244
|
+
|
|
245
|
+
for (const type of _nodeTypes) {
|
|
246
|
+
const varName = `__nrgNodeDef_${type.replace(/-/g, "_")}`;
|
|
247
|
+
// Use physical file if user has one, otherwise use cached generated file
|
|
248
|
+
const userTsPath = nodesDir
|
|
249
|
+
? path.resolve(nodesDir, `${type}.ts`)
|
|
250
|
+
: null;
|
|
251
|
+
const tsPath =
|
|
252
|
+
userTsPath && fs.existsSync(userTsPath)
|
|
253
|
+
? userTsPath
|
|
254
|
+
: path.resolve(nodesCache, `${type}.ts`);
|
|
255
|
+
lines.push(`import ${varName} from ${JSON.stringify(tsPath)};`);
|
|
256
|
+
defVarNames.push(varName);
|
|
211
257
|
}
|
|
212
258
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
259
|
+
if (defVarNames.length > 0) {
|
|
260
|
+
nrgImports.add("registerTypes");
|
|
261
|
+
postLines.push(`registerTypes([${defVarNames.join(", ")}]);`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
216
264
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
265
|
+
// Build the @bonsae/nrg/client import line
|
|
266
|
+
const importLine = `import { ${[...nrgImports].join(", ")} } from "@bonsae/nrg/client";`;
|
|
267
|
+
lines.splice(1, 0, importLine);
|
|
268
|
+
|
|
269
|
+
lines.push(...postLines);
|
|
270
|
+
lines.push("");
|
|
271
|
+
return lines.join("\n") + userCode;
|
|
272
|
+
}
|
|
222
273
|
}
|
|
223
274
|
|
|
224
275
|
export { nodeDefinitionsInliner };
|