Skip to content

Commit 79c6b60

Browse files
authored
feat: Add @n8n/node-cli package with an empty create command (#17620)
1 parent 53594a9 commit 79c6b60

File tree

13 files changed

+268
-0
lines changed

13 files changed

+268
-0
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# @n8n/create-node
2+
3+
Scaffold a new community n8n node
4+
5+
## Usage
6+
7+
```bash
8+
npm create @n8n/node
9+
# or
10+
pnpm create @n8n/node
11+
# or
12+
yarn create @n8n/node
13+
```
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/usr/bin/env node
2+
3+
import { spawnSync } from 'node:child_process';
4+
import { createRequire } from 'node:module';
5+
import path from 'node:path';
6+
7+
const require = createRequire(import.meta.url);
8+
9+
const cliBin = require.resolve('@n8n/node-cli/bin/n8n-node.js');
10+
11+
const result = spawnSync('node', [cliBin, 'create', ...process.argv.slice(2)], {
12+
stdio: 'inherit',
13+
});
14+
15+
process.exit(result.status ?? 1);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"private": true,
3+
"type": "module",
4+
"name": "@n8n/create-node",
5+
"version": "0.1.0",
6+
"description": "Official CLI to create new community nodes for n8n",
7+
"bin": {
8+
"create-n8n-node": "./bin/create.js"
9+
},
10+
"files": [
11+
"bin",
12+
"dist"
13+
],
14+
"scripts": {
15+
"publish:dry": "pnpm run build && pnpm pub --dry-run",
16+
"start": "./bin/create.js"
17+
},
18+
"repository": {
19+
"type": "git",
20+
"url": "https://github.com/n8n-io/n8n"
21+
},
22+
"dependencies": {
23+
"@n8n/node-cli": "workspace:*"
24+
}
25+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"extends": "@n8n/typescript-config/modern/tsconfig.json",
3+
"compilerOptions": {
4+
"baseUrl": ".",
5+
"rootDir": "src",
6+
"outDir": "dist",
7+
"types": ["vite/client", "vitest/globals"],
8+
"isolatedModules": true
9+
},
10+
"include": ["src/**/*.ts"]
11+
}

packages/@n8n/node-cli/README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# @n8n/node-cli
2+
3+
Official CLI for developing community nodes for [n8n](https://n8n.io).
4+
5+
## Features
6+
7+
- 🔧 Scaffold new nodes
8+
- More coming soon
9+
10+
## Installation
11+
12+
Run directly via `npx`:
13+
14+
```bash
15+
npx n8n-node create
16+
```
17+
18+
Or install globally:
19+
20+
```bash
21+
npm install -g @n8n/node-cli
22+
n8n-node create
23+
```
24+
25+
## Commands
26+
27+
## Create a node
28+
29+
```bash
30+
n8n-node create # Scaffold a new node
31+
```
32+
33+
## Related
34+
35+
`@n8n/create-node`: Lightweight wrapper to support `npm create @n8n/node`
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env node
2+
3+
import { execute } from '@oclif/core';
4+
5+
await execute({ dir: import.meta.url });
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { defineConfig } from 'eslint/config';
2+
import { nodeConfig } from '@n8n/eslint-config/node';
3+
4+
export default defineConfig(nodeConfig, {
5+
files: ['./src/commands/*.ts'],
6+
rules: { 'import-x/no-default-export': 'off' },
7+
});
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"private": true,
3+
"type": "module",
4+
"name": "@n8n/node-cli",
5+
"version": "0.1.0",
6+
"description": "Official CLI for developing community nodes for n8n",
7+
"bin": {
8+
"n8n-node": "./bin/n8n-node.js"
9+
},
10+
"files": [
11+
"bin",
12+
"dist"
13+
],
14+
"scripts": {
15+
"clean": "rimraf dist .turbo",
16+
"typecheck": "tsc --noEmit",
17+
"dev": "tsc -w",
18+
"format": "biome format --write src",
19+
"format:check": "biome ci src",
20+
"lint": "eslint src --quiet",
21+
"lintfix": "eslint src --fix",
22+
"build": "tsc",
23+
"publish:dry": "pnpm run build && pnpm pub --dry-run",
24+
"test": "vitest run",
25+
"test:dev": "vitest --silent=false",
26+
"start": "./bin/n8n-node.js"
27+
},
28+
"repository": {
29+
"type": "git",
30+
"url": "https://github.com/n8n-io/n8n"
31+
},
32+
"oclif": {
33+
"bin": "n8n-node",
34+
"commands": "./dist/commands",
35+
"topicSeparator": " "
36+
},
37+
"dependencies": {
38+
"@oclif/core": "^4.5.2",
39+
"prompts": "^2.4.2"
40+
},
41+
"devDependencies": {
42+
"@n8n/typescript-config": "workspace:*",
43+
"@n8n/vitest-config": "workspace:*",
44+
"@oclif/test": "^4.1.13"
45+
}
46+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { runCommand } from '@oclif/test';
2+
3+
describe('n8n-node create', () => {
4+
it('should print correct output', async () => {
5+
const { stdout } = await runCommand('create -f', { root: import.meta.dirname });
6+
expect(stdout).toEqual('hello from commands/create.ts (force=true)\n');
7+
});
8+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Command, Flags } from '@oclif/core';
2+
3+
export default class Create extends Command {
4+
static override description = 'Create a new n8n community node';
5+
static override examples = ['<%= config.bin %> <%= command.id %>'];
6+
static override flags = {
7+
// flag with no value (-f, --force)
8+
force: Flags.boolean({ char: 'f' }),
9+
};
10+
11+
async run(): Promise<void> {
12+
const { flags } = await this.parse(Create);
13+
14+
const force = flags.force;
15+
this.log(`hello from commands/create.ts (force=${force})`);
16+
}
17+
}

0 commit comments

Comments
 (0)