@bonsae/nrg 0.27.0 → 0.28.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/eslint/index.js +48 -0
- package/package.json +2 -1
- package/test/client/e2e/index.js +16 -19
- package/types/test-client-e2e.d.ts +2 -15
- package/types/vite.d.ts +8 -17
- package/vite/index.js +35 -42
package/eslint/index.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// src/eslint/index.ts
|
|
2
|
+
var nodeTypeMatchesFilename = {
|
|
3
|
+
meta: {
|
|
4
|
+
type: "problem",
|
|
5
|
+
docs: {
|
|
6
|
+
description: "require a node's static `type` to equal its filename in server/nodes"
|
|
7
|
+
},
|
|
8
|
+
schema: [],
|
|
9
|
+
messages: {
|
|
10
|
+
mismatch: `Node static type "{{type}}" must match the filename "{{expected}}.ts" \u2014 the type string keys the node's schema, component, icon and locale folder.`
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
create(context) {
|
|
14
|
+
const match = /[\\/]server[\\/]nodes[\\/]([^\\/]+)\.ts$/.exec(
|
|
15
|
+
context.filename
|
|
16
|
+
);
|
|
17
|
+
if (!match) return {};
|
|
18
|
+
const expected = match[1];
|
|
19
|
+
return {
|
|
20
|
+
"PropertyDefinition[static=true]"(node) {
|
|
21
|
+
if (node.key?.type === "Identifier" && node.key.name === "type" && node.value?.type === "Literal" && typeof node.value.value === "string" && node.value.value !== expected) {
|
|
22
|
+
context.report({
|
|
23
|
+
node: node.value,
|
|
24
|
+
messageId: "mismatch",
|
|
25
|
+
data: { type: node.value.value, expected }
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var plugin = {
|
|
33
|
+
meta: { name: "@bonsae/nrg" },
|
|
34
|
+
rules: { "node-type-matches-filename": nodeTypeMatchesFilename }
|
|
35
|
+
};
|
|
36
|
+
var nrgConventions = {
|
|
37
|
+
plugins: { "@bonsae/nrg": plugin },
|
|
38
|
+
rules: {
|
|
39
|
+
"@bonsae/nrg/node-type-matches-filename": "error"
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
var index_default = nrgConventions;
|
|
43
|
+
export {
|
|
44
|
+
index_default as default,
|
|
45
|
+
nodeTypeMatchesFilename,
|
|
46
|
+
nrgConventions,
|
|
47
|
+
plugin
|
|
48
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bonsae/nrg",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.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",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"types": "./types/vite.d.ts",
|
|
51
51
|
"default": "./vite/index.js"
|
|
52
52
|
},
|
|
53
|
+
"./eslint": "./eslint/index.js",
|
|
53
54
|
"./test/server/unit": {
|
|
54
55
|
"types": "./types/test-server-unit.d.ts",
|
|
55
56
|
"default": "./test/server/unit/index.js"
|
package/test/client/e2e/index.js
CHANGED
|
@@ -2306,12 +2306,12 @@ async function build2(clientBuildOptions, buildContext) {
|
|
|
2306
2306
|
name = "NodeRedNodes",
|
|
2307
2307
|
format = "es",
|
|
2308
2308
|
licensePath = "./LICENSE",
|
|
2309
|
-
|
|
2310
|
-
staticDirs = {},
|
|
2309
|
+
publicDir,
|
|
2311
2310
|
external = [],
|
|
2312
2311
|
globals = {},
|
|
2313
2312
|
manualChunks
|
|
2314
2313
|
} = clientBuildOptions;
|
|
2314
|
+
const resourcesDir = buildContext.resourcesDir;
|
|
2315
2315
|
const cacheDir = path10.resolve(
|
|
2316
2316
|
"node_modules",
|
|
2317
2317
|
".nrg",
|
|
@@ -2332,9 +2332,7 @@ async function build2(clientBuildOptions, buildContext) {
|
|
|
2332
2332
|
entryPath = cachedEntryPath;
|
|
2333
2333
|
generatedEntry = true;
|
|
2334
2334
|
}
|
|
2335
|
-
const iconsDir = path10.
|
|
2336
|
-
staticDirs.icons ?? path10.join(path10.dirname(path10.resolve(srcDir)), "icons")
|
|
2337
|
-
);
|
|
2335
|
+
const iconsDir = path10.join(resourcesDir, "icons");
|
|
2338
2336
|
const plugins = [
|
|
2339
2337
|
vue(),
|
|
2340
2338
|
nodeDefinitionsInliner(
|
|
@@ -2353,33 +2351,31 @@ async function build2(clientBuildOptions, buildContext) {
|
|
|
2353
2351
|
licensePath: licensePath ? path10.resolve(licensePath) : void 0
|
|
2354
2352
|
})
|
|
2355
2353
|
);
|
|
2356
|
-
|
|
2357
|
-
|
|
2354
|
+
const localesDir = path10.join(resourcesDir, "locales");
|
|
2355
|
+
if (fs10.existsSync(localesDir)) {
|
|
2356
|
+
const docsDir = path10.join(localesDir, "docs");
|
|
2357
|
+
const labelsDir = path10.join(localesDir, "labels");
|
|
2358
2358
|
const localesOutDir = path10.join(buildContext.outDir, "locales");
|
|
2359
2359
|
plugins.push(
|
|
2360
|
-
localesGenerator({
|
|
2361
|
-
outDir: localesOutDir,
|
|
2362
|
-
docsDir: path10.resolve(docsDir),
|
|
2363
|
-
labelsDir: path10.resolve(labelsDir)
|
|
2364
|
-
})
|
|
2360
|
+
localesGenerator({ outDir: localesOutDir, docsDir, labelsDir })
|
|
2365
2361
|
);
|
|
2366
2362
|
plugins.push(
|
|
2367
2363
|
helpGenerator({
|
|
2368
2364
|
outDir: buildContext.outDir,
|
|
2369
2365
|
localesOutDir,
|
|
2370
|
-
docsDir
|
|
2371
|
-
labelsDir
|
|
2366
|
+
docsDir,
|
|
2367
|
+
labelsDir,
|
|
2372
2368
|
srcDir: buildContext.serverSrcDir
|
|
2373
2369
|
})
|
|
2374
2370
|
);
|
|
2375
2371
|
}
|
|
2376
2372
|
const copyTargets = [];
|
|
2377
|
-
const
|
|
2378
|
-
|
|
2373
|
+
const resolvedPublicDir = path10.resolve(
|
|
2374
|
+
publicDir ?? path10.join(srcDir, "public")
|
|
2379
2375
|
);
|
|
2380
|
-
if (fs10.existsSync(
|
|
2376
|
+
if (fs10.existsSync(resolvedPublicDir)) {
|
|
2381
2377
|
copyTargets.push({
|
|
2382
|
-
src:
|
|
2378
|
+
src: resolvedPublicDir,
|
|
2383
2379
|
dest: path10.join(buildContext.outDir, "resources")
|
|
2384
2380
|
});
|
|
2385
2381
|
}
|
|
@@ -3061,7 +3057,8 @@ var NodeRedTestEnvironment = class {
|
|
|
3061
3057
|
const buildContext = {
|
|
3062
3058
|
outDir: this.outDir,
|
|
3063
3059
|
packageName: this.options.packageName,
|
|
3064
|
-
isDev: false
|
|
3060
|
+
isDev: false,
|
|
3061
|
+
resourcesDir: path13.join(this.projectDir, "src/resources")
|
|
3065
3062
|
};
|
|
3066
3063
|
const serverOpts = {
|
|
3067
3064
|
srcDir: path13.join(this.projectDir, "src/server"),
|
|
@@ -19,15 +19,8 @@ interface ClientBuildOptions {
|
|
|
19
19
|
base?: string;
|
|
20
20
|
/** Path to LICENSE file to include in the HTML output. @default "./LICENSE" */
|
|
21
21
|
licensePath?: string;
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
/** Directories for static assets (icons, public files). */
|
|
25
|
-
staticDirs?: {
|
|
26
|
-
/** Directory containing node icons ({type}.png). @default "./src/icons" */
|
|
27
|
-
icons?: string;
|
|
28
|
-
/** Directory for public static files copied to dist/resources/. @default "./src/client/public" */
|
|
29
|
-
public?: string;
|
|
30
|
-
};
|
|
22
|
+
/** Directory for the editor's public static files, copied to dist/resources/. @default "./src/client/public" */
|
|
23
|
+
publicDir?: string;
|
|
31
24
|
/** Modules to treat as external (not bundled). @default ["jquery", "node-red", "vue", "@bonsae/nrg/client"] */
|
|
32
25
|
external?: string[];
|
|
33
26
|
/** Global variable mappings for external modules. */
|
|
@@ -35,12 +28,6 @@ interface ClientBuildOptions {
|
|
|
35
28
|
/** Custom chunk splitting function for Rollup. */
|
|
36
29
|
manualChunks?: (id: string) => string | undefined;
|
|
37
30
|
}
|
|
38
|
-
interface LocalesOptions {
|
|
39
|
-
/** Directory containing documentation files ({type}/{lang}.md or .html). @default "./src/locales/docs" */
|
|
40
|
-
docsDir?: string;
|
|
41
|
-
/** Directory containing label files ({type}/{lang}.json). @default "./src/locales/labels" */
|
|
42
|
-
labelsDir?: string;
|
|
43
|
-
}
|
|
44
31
|
interface ServerBuildOptions {
|
|
45
32
|
/** Source directory for server code. @default "./src/server" */
|
|
46
33
|
srcDir?: string;
|
package/types/vite.d.ts
CHANGED
|
@@ -6,6 +6,12 @@ export interface BuildContext {
|
|
|
6
6
|
isDev: boolean;
|
|
7
7
|
/** Resolved server source dir, scanned to recover `Unsafe<T>()` types for docs. */
|
|
8
8
|
serverSrcDir?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Resolved resources dir (default ./src/resources). Its convention subfolders
|
|
11
|
+
* are auto-handled: `icons/` and `locales/{docs,labels}/` run their pipelines,
|
|
12
|
+
* every other folder is copied verbatim to `dist/<name>`. @default ./src/resources
|
|
13
|
+
*/
|
|
14
|
+
resourcesDir: string;
|
|
9
15
|
}
|
|
10
16
|
export interface BuildPluginOptions {
|
|
11
17
|
serverBuildOptions: ServerBuildOptions;
|
|
@@ -30,15 +36,8 @@ export interface ClientBuildOptions {
|
|
|
30
36
|
base?: string;
|
|
31
37
|
/** Path to LICENSE file to include in the HTML output. @default "./LICENSE" */
|
|
32
38
|
licensePath?: string;
|
|
33
|
-
/**
|
|
34
|
-
|
|
35
|
-
/** Directories for static assets (icons, public files). */
|
|
36
|
-
staticDirs?: {
|
|
37
|
-
/** Directory containing node icons ({type}.png). @default "./src/icons" */
|
|
38
|
-
icons?: string;
|
|
39
|
-
/** Directory for public static files copied to dist/resources/. @default "./src/client/public" */
|
|
40
|
-
public?: string;
|
|
41
|
-
};
|
|
39
|
+
/** Directory for the editor's public static files, copied to dist/resources/. @default "./src/client/public" */
|
|
40
|
+
publicDir?: string;
|
|
42
41
|
/** Modules to treat as external (not bundled). @default ["jquery", "node-red", "vue", "@bonsae/nrg/client"] */
|
|
43
42
|
external?: string[];
|
|
44
43
|
/** Global variable mappings for external modules. */
|
|
@@ -52,12 +51,6 @@ export interface CopyTarget {
|
|
|
52
51
|
/** Destination path relative to the output directory. */
|
|
53
52
|
dest: string;
|
|
54
53
|
}
|
|
55
|
-
export interface LocalesOptions {
|
|
56
|
-
/** Directory containing documentation files ({type}/{lang}.md or .html). @default "./src/locales/docs" */
|
|
57
|
-
docsDir?: string;
|
|
58
|
-
/** Directory containing label files ({type}/{lang}.json). @default "./src/locales/labels" */
|
|
59
|
-
labelsDir?: string;
|
|
60
|
-
}
|
|
61
54
|
export interface LoggerOptions {
|
|
62
55
|
name: string;
|
|
63
56
|
prefix?: string;
|
|
@@ -93,8 +86,6 @@ export interface BuildOptions {
|
|
|
93
86
|
server?: ServerBuildOptions;
|
|
94
87
|
/** Options for building the client-side editor UI. */
|
|
95
88
|
client?: ClientBuildOptions;
|
|
96
|
-
/** Extra files to copy into the output directory (e.g., LICENSE, README). */
|
|
97
|
-
extraFilesCopyTargets?: CopyTarget[];
|
|
98
89
|
}
|
|
99
90
|
/**
|
|
100
91
|
* Options for the `nrg()` Vite plugin.
|
package/vite/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import path15 from "path";
|
|
|
3
3
|
|
|
4
4
|
// src/vite/defaults.ts
|
|
5
5
|
var DEFAULT_OUTPUT_DIR = "./dist";
|
|
6
|
+
var DEFAULT_RESOURCES_DIR = "./src/resources";
|
|
6
7
|
var DEFAULT_CLIENT_BUILD_OPTIONS = {
|
|
7
8
|
srcDir: "./src/client",
|
|
8
9
|
entry: "index.ts",
|
|
@@ -16,14 +17,7 @@ var DEFAULT_CLIENT_BUILD_OPTIONS = {
|
|
|
16
17
|
"node-red": "RED",
|
|
17
18
|
vue: "Vue"
|
|
18
19
|
},
|
|
19
|
-
|
|
20
|
-
docsDir: "./src/locales/docs",
|
|
21
|
-
labelsDir: "./src/locales/labels"
|
|
22
|
-
},
|
|
23
|
-
staticDirs: {
|
|
24
|
-
icons: "./src/icons",
|
|
25
|
-
public: "./src/client/public"
|
|
26
|
-
}
|
|
20
|
+
publicDir: "./src/client/public"
|
|
27
21
|
};
|
|
28
22
|
var DEFAULT_SERVER_BUILD_OPTIONS = {
|
|
29
23
|
srcDir: "./src/server",
|
|
@@ -45,8 +39,7 @@ var DEFAULT_NODE_RED_LAUNCHER_OPTIONS = {
|
|
|
45
39
|
};
|
|
46
40
|
var DEFAULT_EXTRA_FILES_COPY_TARGETS = [
|
|
47
41
|
{ src: "./LICENSE", dest: "LICENSE" },
|
|
48
|
-
{ src: "./README.md", dest: "README.md" }
|
|
49
|
-
{ src: "./src/examples", dest: "examples" }
|
|
42
|
+
{ src: "./README.md", dest: "README.md" }
|
|
50
43
|
];
|
|
51
44
|
|
|
52
45
|
// src/vite/utils.ts
|
|
@@ -74,6 +67,16 @@ function copyFiles(targets, outDir) {
|
|
|
74
67
|
}
|
|
75
68
|
}
|
|
76
69
|
}
|
|
70
|
+
var RESOURCE_PIPELINE_FOLDERS = /* @__PURE__ */ new Set(["icons", "locales"]);
|
|
71
|
+
function discoverResourceCopyTargets(resourcesDir) {
|
|
72
|
+
if (!fs.existsSync(resourcesDir)) return [];
|
|
73
|
+
return fs.readdirSync(resourcesDir, { withFileTypes: true }).filter(
|
|
74
|
+
(entry) => entry.isDirectory() && !RESOURCE_PIPELINE_FOLDERS.has(entry.name)
|
|
75
|
+
).map((entry) => ({
|
|
76
|
+
src: path.join(resourcesDir, entry.name),
|
|
77
|
+
dest: entry.name
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
77
80
|
function getPackageName() {
|
|
78
81
|
const pkgPath = path.resolve("./package.json");
|
|
79
82
|
if (fs.existsSync(pkgPath)) {
|
|
@@ -2963,12 +2966,12 @@ async function build2(clientBuildOptions, buildContext) {
|
|
|
2963
2966
|
name = "NodeRedNodes",
|
|
2964
2967
|
format = "es",
|
|
2965
2968
|
licensePath = "./LICENSE",
|
|
2966
|
-
|
|
2967
|
-
staticDirs = {},
|
|
2969
|
+
publicDir,
|
|
2968
2970
|
external = [],
|
|
2969
2971
|
globals = {},
|
|
2970
2972
|
manualChunks
|
|
2971
2973
|
} = clientBuildOptions;
|
|
2974
|
+
const resourcesDir = buildContext.resourcesDir;
|
|
2972
2975
|
const cacheDir = path13.resolve(
|
|
2973
2976
|
"node_modules",
|
|
2974
2977
|
".nrg",
|
|
@@ -2989,9 +2992,7 @@ async function build2(clientBuildOptions, buildContext) {
|
|
|
2989
2992
|
entryPath = cachedEntryPath;
|
|
2990
2993
|
generatedEntry = true;
|
|
2991
2994
|
}
|
|
2992
|
-
const iconsDir = path13.
|
|
2993
|
-
staticDirs.icons ?? path13.join(path13.dirname(path13.resolve(srcDir)), "icons")
|
|
2994
|
-
);
|
|
2995
|
+
const iconsDir = path13.join(resourcesDir, "icons");
|
|
2995
2996
|
const plugins = [
|
|
2996
2997
|
vue(),
|
|
2997
2998
|
nodeDefinitionsInliner(
|
|
@@ -3010,33 +3011,31 @@ async function build2(clientBuildOptions, buildContext) {
|
|
|
3010
3011
|
licensePath: licensePath ? path13.resolve(licensePath) : void 0
|
|
3011
3012
|
})
|
|
3012
3013
|
);
|
|
3013
|
-
|
|
3014
|
-
|
|
3014
|
+
const localesDir = path13.join(resourcesDir, "locales");
|
|
3015
|
+
if (fs14.existsSync(localesDir)) {
|
|
3016
|
+
const docsDir = path13.join(localesDir, "docs");
|
|
3017
|
+
const labelsDir = path13.join(localesDir, "labels");
|
|
3015
3018
|
const localesOutDir = path13.join(buildContext.outDir, "locales");
|
|
3016
3019
|
plugins.push(
|
|
3017
|
-
localesGenerator({
|
|
3018
|
-
outDir: localesOutDir,
|
|
3019
|
-
docsDir: path13.resolve(docsDir),
|
|
3020
|
-
labelsDir: path13.resolve(labelsDir)
|
|
3021
|
-
})
|
|
3020
|
+
localesGenerator({ outDir: localesOutDir, docsDir, labelsDir })
|
|
3022
3021
|
);
|
|
3023
3022
|
plugins.push(
|
|
3024
3023
|
helpGenerator({
|
|
3025
3024
|
outDir: buildContext.outDir,
|
|
3026
3025
|
localesOutDir,
|
|
3027
|
-
docsDir
|
|
3028
|
-
labelsDir
|
|
3026
|
+
docsDir,
|
|
3027
|
+
labelsDir,
|
|
3029
3028
|
srcDir: buildContext.serverSrcDir
|
|
3030
3029
|
})
|
|
3031
3030
|
);
|
|
3032
3031
|
}
|
|
3033
3032
|
const copyTargets = [];
|
|
3034
|
-
const
|
|
3035
|
-
|
|
3033
|
+
const resolvedPublicDir = path13.resolve(
|
|
3034
|
+
publicDir ?? path13.join(srcDir, "public")
|
|
3036
3035
|
);
|
|
3037
|
-
if (fs14.existsSync(
|
|
3036
|
+
if (fs14.existsSync(resolvedPublicDir)) {
|
|
3038
3037
|
copyTargets.push({
|
|
3039
|
-
src:
|
|
3038
|
+
src: resolvedPublicDir,
|
|
3040
3039
|
dest: path13.join(buildContext.outDir, "resources")
|
|
3041
3040
|
});
|
|
3042
3041
|
}
|
|
@@ -3294,21 +3293,10 @@ function serverPlugin(options) {
|
|
|
3294
3293
|
const clientSrcDir = path14.resolve(
|
|
3295
3294
|
clientBuildOptions.srcDir ?? "./client"
|
|
3296
3295
|
);
|
|
3297
|
-
const localesDocsDir = path14.resolve(
|
|
3298
|
-
clientBuildOptions.locales?.docsDir ?? "./locales/docs"
|
|
3299
|
-
);
|
|
3300
|
-
const localesLabelsDir = path14.resolve(
|
|
3301
|
-
clientBuildOptions.locales?.labelsDir ?? "./locales/labels"
|
|
3302
|
-
);
|
|
3303
|
-
const iconsDir = path14.resolve(
|
|
3304
|
-
clientBuildOptions.staticDirs?.icons ?? path14.join(path14.dirname(clientSrcDir), "icons")
|
|
3305
|
-
);
|
|
3306
3296
|
const watchPaths = [
|
|
3307
3297
|
serverSrcDir,
|
|
3308
3298
|
clientSrcDir,
|
|
3309
|
-
|
|
3310
|
-
localesLabelsDir,
|
|
3311
|
-
iconsDir
|
|
3299
|
+
buildContext.resourcesDir
|
|
3312
3300
|
];
|
|
3313
3301
|
watcher = chokidar.watch(watchPaths, {
|
|
3314
3302
|
ignoreInitial: true,
|
|
@@ -3414,13 +3402,18 @@ function nrg(options = {}) {
|
|
|
3414
3402
|
DEFAULT_NODE_RED_LAUNCHER_OPTIONS,
|
|
3415
3403
|
server.nodeRed
|
|
3416
3404
|
);
|
|
3417
|
-
const
|
|
3405
|
+
const resourcesDir = path15.resolve(DEFAULT_RESOURCES_DIR);
|
|
3406
|
+
const extraFilesCopyTargets = [
|
|
3407
|
+
...DEFAULT_EXTRA_FILES_COPY_TARGETS,
|
|
3408
|
+
...discoverResourceCopyTargets(resourcesDir)
|
|
3409
|
+
];
|
|
3418
3410
|
const resolvedOutDir = path15.resolve(outDir);
|
|
3419
3411
|
const buildContext = {
|
|
3420
3412
|
outDir: resolvedOutDir,
|
|
3421
3413
|
packageName: getPackageName(),
|
|
3422
3414
|
isDev: process.env.NODE_ENV === "development",
|
|
3423
|
-
serverSrcDir: path15.resolve(serverBuildOptions.srcDir ?? "./server")
|
|
3415
|
+
serverSrcDir: path15.resolve(serverBuildOptions.srcDir ?? "./server"),
|
|
3416
|
+
resourcesDir
|
|
3424
3417
|
};
|
|
3425
3418
|
const nodeRedLauncher = new NodeRedLauncher(
|
|
3426
3419
|
resolvedOutDir,
|