You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: switch to n8n-node lint (full ESLint community-nodes rules) (#147)
* fix: guard against a missing dependencies field in npm registry response
data.dependencies was typed as always present, but if the registry
response ever omitted it, accessing ["n8n-workflow"] would throw a raw
TypeError instead of the descriptive error this code is meant to give.
* feat: switch to n8n-node lint (full ESLint community-nodes rules)
oxlint + eslint-plugin-n8n-nodes-base only checked a narrow subset of
n8n's community-node rules and missed real issues: no dependencies
field validation, no auth-pattern checks, weaker type-safety
enforcement. Switch to n8n-node lint (matching n8n-nodes-actual),
which runs the official @n8n/eslint-plugin-community-nodes rules
alongside TypeScript ESLint and eslint-plugin-import-x.
Uses configWithoutCloudSupport (n8n.strict: false) rather than the
strict-mode default, since the cloud-only restricted-imports/globals
rules fire broadly on tests/ and scripts/ tooling that never ships to
n8n Cloud - same choice n8n-nodes-actual already made.
Fixes surfaced by the switch:
- package.json declared "dependencies" (eventsource, form-data), which
community nodes must not do (they'd get bundled into the host n8n
instance). Both are genuinely needed at runtime, so vendor them via
an esbuild post-build step (scripts/bundle-vendor-deps.mjs) that
inlines just those two packages into the two compiled files that use
them, leaving n8n-workflow and local imports as normal requires.
Verified the resulting dist/ has zero remaining requires for either
package, and validated end-to-end via the full docker-compose
pipeline (real n8n + PocketBase, including the expired-token
isolated-process test) with the bundled build.
- 3 no-http-request-with-manual-auth findings in LoadOptions.ts are
suppressed, not reverted: this project deliberately moved off
httpRequestWithAuthentication (commit 8003c58) because n8n doesn't
reliably invoke a credential's authenticate hook on scheduled
executions, and the credential type no longer even declares one.
- RequestBodyFunctions.ts now throws NodeOperationError instead of a
plain Error when rethrowing a JSON parse failure.
- PocketbaseTrigger.node.ts gained a subtitle and properly typed its
EventSource handlers instead of using `any`.
- Reordered PocketbaseHttp's operation options alphabetically
(cosmetic only - default is set explicitly, unaffected by order).
- Replaced no-explicit-any across test files with real types (or a
justified inline suppression for the one test that deliberately
feeds malformed input to check a runtime guard).
- no-console is scoped off for scripts/ (CLI tooling) and the one
integration spec that intentionally logs live e2e diagnostics.
* test: assert NodeOperationError type, not just message, for invalid JSON body
The message-only assertion would still pass if the parse-failure path
regressed to throwing a plain Error again.
* fix: use NodeOperationError consistently across all three parseBodyJson throw sites
Only the JSON.parse catch-block rethrow was upgraded; the two
validation throws still used a plain Error despite node being
available as a parameter now, giving inconsistent error surfacing
for what are all "invalid body JSON" failures in the same helper.
Copy file name to clipboardExpand all lines: nodes/Common/LoadOptions.ts
+4-1Lines changed: 4 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -38,6 +38,7 @@ async function loadPocketBaseFields(
38
38
credentials.usernameasstring,
39
39
credentials.passwordasstring,
40
40
);
41
+
// eslint-disable-next-line @n8n/community-nodes/no-http-request-with-manual-auth -- httpRequestWithAuthentication relies on the credential's `authenticate` property, which this project deliberately removed (see commit 8003c58): n8n doesn't reliably invoke it during scheduled executions, causing 403s once the stored JWT expired. fetchPocketbaseToken replaces it with a reliable, cache-aware token fetch.
@@ -16,6 +17,7 @@ export class PocketbaseTrigger implements INodeType {
16
17
group: ["trigger"],
17
18
version: 1,
18
19
description: "Handle Pocketbase events via SSE (Beta)",
20
+
subtitle: '={{$parameter["collection"]}}',
19
21
defaults: {
20
22
name: "Pocketbase Trigger",
21
23
},
@@ -29,15 +31,15 @@ export class PocketbaseTrigger implements INodeType {
29
31
],
30
32
properties: [
31
33
{
32
-
displayName: "Collection Name",
34
+
displayName: 'Collection Name or ID',
33
35
name: "collection",
34
36
type: "options",
35
37
typeOptions: {
36
38
loadOptionsMethod: "getCollections",
37
39
},
38
40
default: "",
39
41
required: true,
40
-
description: "The name of the collection to watch for changes",
42
+
description: 'The name of the collection to watch for changes. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
41
43
},
42
44
{
43
45
displayName: "Events",
@@ -62,6 +64,7 @@ export class PocketbaseTrigger implements INodeType {
62
64
description: "The events to trigger the node",
63
65
},
64
66
],
67
+
usableAsTool: true,
65
68
};
66
69
67
70
methods={
@@ -108,7 +111,7 @@ function subscribeToPocketbaseSSE(
108
111
constMAX_RECONNECT_ATTEMPTS=50;
109
112
letconsecutiveFailures=0;
110
113
111
-
constonConnect=async(e: any)=>{
114
+
constonConnect=async(e: MessageEvent)=>{
112
115
try{
113
116
constdata=JSON.parse(e.dataasstring);
114
117
constclientId=data.clientId;
@@ -143,7 +146,7 @@ function subscribeToPocketbaseSSE(
143
146
}
144
147
};
145
148
146
-
constonError=(error: any)=>{
149
+
constonError=(error: EventSourceErrorEvent)=>{
147
150
if(stabilityTimer){
148
151
clearTimeout(stabilityTimer);
149
152
stabilityTimer=null;
@@ -153,12 +156,17 @@ function subscribeToPocketbaseSSE(
0 commit comments