@bonsae/create-nrg 0.6.1 → 0.7.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/README.md CHANGED
@@ -55,11 +55,12 @@ my-project/
55
55
  │ ├── nodes/<node>.ts
56
56
  │ ├── schemas/<node>.ts
57
57
  │ └── tsconfig.json
58
- ├── locales/
59
- ├── labels/<node>/en-US.json
60
- └── docs/<node>/en-US.md
61
- ├── icons/
62
- └── examples/
58
+ └── resources/
59
+ ├── locales/
60
+ ├── labels/<node>/en-US.json
61
+ │ └── docs/<node>/en-US.md
62
+ ├── icons/
63
+ └── examples/
63
64
  ```
64
65
 
65
66
  ## License
package/index.js CHANGED
@@ -112,7 +112,13 @@ async function main() {
112
112
  const nodeCategory = project.nodeCategory;
113
113
  const nodeColor = project.nodeColor;
114
114
  const hasInputs = project.hasInputs;
115
+ // Validate here too: the --outputs flag path bypasses the prompt's validator,
116
+ // so a non-numeric/negative flag would otherwise scaffold a node with 0 ports.
115
117
  const nodeOutputs = parseInt(project.nodeOutputs, 10);
118
+ if (Number.isNaN(nodeOutputs) || nodeOutputs < 0) {
119
+ p.cancel("--outputs must be an integer >= 0.");
120
+ process.exit(1);
121
+ }
116
122
  const projectDir = path.resolve(process.cwd(), dashCase(projectName));
117
123
  if (fs.existsSync(projectDir)) {
118
124
  p.cancel(`Directory "${dashCase(projectName)}" already exists.`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bonsae/create-nrg",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "description": "Scaffold a new NRG project for Node-RED",
5
5
  "author": "Allan Oricil <allanoricil@duck.com>",
6
6
  "license": "MIT",
@@ -32,7 +32,7 @@
32
32
  "bonsae"
33
33
  ],
34
34
  "scripts": {
35
- "build": "tsc && node -e \"const fs=require('fs');fs.cpSync('src/templates','dist/templates',{recursive:true});for(const f of['package.json','README.md','LICENSE'])fs.copyFileSync(f,'dist/'+f)\"",
35
+ "build": "tsc && node -e \"const fs=require('fs');fs.rmSync('dist/templates',{recursive:true,force:true});fs.cpSync('src/templates','dist/templates',{recursive:true});for(const f of['package.json','README.md','LICENSE'])fs.copyFileSync(f,'dist/'+f)\"",
36
36
  "dev": "tsc --watch",
37
37
  "validate": "pnpm validate:lint && pnpm validate:format",
38
38
  "validate:lint": "eslint src/",
package/scaffold.js CHANGED
@@ -72,6 +72,6 @@ export function scaffoldProject(destDir, templatesDir, options) {
72
72
  renderTemplateFile(path.join(nodeTemplatesDir, "server-node.ts.hbs"), path.join(srcDir, "server", "nodes", `${dashCaseNodeName}.ts`), vars);
73
73
  renderTemplateFile(path.join(nodeTemplatesDir, "schema.ts.hbs"), path.join(srcDir, "server", "schemas", `${dashCaseNodeName}.ts`), vars);
74
74
  renderTemplateFile(path.join(nodeTemplatesDir, "server-index.ts.hbs"), path.join(srcDir, "server", "index.ts"), vars);
75
- renderTemplateFile(path.join(nodeTemplatesDir, "labels.json.hbs"), path.join(srcDir, "locales", "labels", dashCaseNodeName, "en-US.json"), vars);
76
- renderTemplateFile(path.join(nodeTemplatesDir, "docs.md.hbs"), path.join(srcDir, "locales", "docs", dashCaseNodeName, "en-US.md"), vars);
75
+ renderTemplateFile(path.join(nodeTemplatesDir, "labels.json.hbs"), path.join(srcDir, "resources", "locales", "labels", dashCaseNodeName, "en-US.json"), vars);
76
+ renderTemplateFile(path.join(nodeTemplatesDir, "docs.md.hbs"), path.join(srcDir, "resources", "locales", "docs", dashCaseNodeName, "en-US.md"), vars);
77
77
  }
@@ -1,6 +1,7 @@
1
1
  .DS_Store
2
2
  *.log
3
3
  dist
4
+ .nrg
4
5
  build
5
6
  node_modules
6
7
  coverage
@@ -3,6 +3,7 @@ import eslintConfigPrettier from "eslint-config-prettier";
3
3
  import eslintPluginVue from "eslint-plugin-vue";
4
4
  import globals from "globals";
5
5
  import typescriptEslint from "typescript-eslint";
6
+ import { nrgConventions } from "@bonsae/nrg/eslint";
6
7
 
7
8
  export default typescriptEslint.config(
8
9
  {
@@ -34,5 +35,42 @@ export default typescriptEslint.config(
34
35
  ],
35
36
  },
36
37
  },
38
+ // Boundary: browser/client code must never VALUE-import the node runtime. The
39
+ // server (io-node, node:async_hooks, and anything under src/server/**) is
40
+ // server-only. Schemas reach the client as serialized data — the nrg vite
41
+ // plugin in production, the @bonsae/nrg/test/client/component/schemas node
42
+ // globalSetup in component tests — and as types via `import type` (erased).
43
+ {
44
+ files: ["src/client/**/*.ts", "tests/client/**/*.ts"],
45
+ plugins: { "@typescript-eslint": typescriptEslint.plugin },
46
+ languageOptions: { parser: typescriptEslint.parser },
47
+ rules: {
48
+ "@typescript-eslint/no-restricted-imports": [
49
+ "error",
50
+ {
51
+ paths: [
52
+ {
53
+ name: "@bonsae/nrg/server",
54
+ allowTypeImports: true,
55
+ message:
56
+ "Browser/client code must not import the node runtime. Use `import type` for schema types; in tests, name the node type via createNode({ type }) — the schemas globalSetup provides serialized schemas.",
57
+ },
58
+ ],
59
+ patterns: [
60
+ {
61
+ group: ["**/server/**"],
62
+ allowTypeImports: true,
63
+ message:
64
+ "Browser/client code must not value-import server modules — they pull in the node runtime. Use `import type`, or createNode({ type }) in tests.",
65
+ },
66
+ ],
67
+ },
68
+ ],
69
+ },
70
+ },
71
+ // nrg node conventions (shared from the toolkit so they can't drift): a node's
72
+ // static `type` must match its filename in src/server/nodes — the type string
73
+ // keys the node's schema, component, icon and locale folder.
74
+ nrgConventions,
37
75
  eslintConfigPrettier,
38
76
  );
@@ -16,7 +16,6 @@
16
16
  "scripts": {
17
17
  "debug": "node --inspect-brk ./node_modules/vite/bin/vite.js --mode development",
18
18
  "dev": "vite --mode development",
19
- "build:dev": "vite build --mode development",
20
19
  "build": "vite build --mode production",
21
20
  "validate": "pnpm validate:tsc && pnpm validate:lint && pnpm validate:format",
22
21
  "validate:tsc": "tsc -p src/server/tsconfig.json --noEmit",
@@ -42,10 +41,9 @@
42
41
  "prettier --write"
43
42
  ]
44
43
  },
45
- "dependencies": {
46
- "@bonsae/nrg": "latest"
47
- },
44
+ "dependencies": {},
48
45
  "devDependencies": {
46
+ "@bonsae/nrg": "latest",
49
47
  "@commitlint/cli": "^20.5.0",
50
48
  "@commitlint/config-conventional": "^20.5.0",
51
49
  "@eslint/js": "^9.27.0",
@@ -0,0 +1,8 @@
1
+ # resources
2
+
3
+ Drop resource folders here and the build handles each by name — no config needed:
4
+
5
+ - `icons/` — node icons (`{type}.svg/.png`); inlined into the node definitions.
6
+ - `locales/labels/{node}/{lang}.json` — editor labels & descriptions (i18n).
7
+ - `locales/docs/{node}/{lang}.md|.html` — manual help for the Node-RED info panel.
8
+ - any other folder (e.g. `examples/`) — copied verbatim to `dist/<folder>`.