@replikanti/flowlint-core 0.10.0 → 0.12.1
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 +2 -1
- package/dist/index.d.mts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +49 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +49 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @replikanti/flowlint-core
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
5
|
Core static analysis engine for [n8n](https://n8n.io) workflows. This package contains the parser, rules engine, and default rule definitions.
|
|
6
6
|
|
|
@@ -70,6 +70,7 @@ This package includes 14 built-in rules:
|
|
|
70
70
|
| R12 | Unhandled error path | must |
|
|
71
71
|
| R13 | Webhook acknowledgment | must |
|
|
72
72
|
| R14 | Retry-After compliance | should |
|
|
73
|
+
| R15 | Error handler set in settings | must |
|
|
73
74
|
|
|
74
75
|
## License
|
|
75
76
|
|
package/dist/index.d.mts
CHANGED
|
@@ -56,6 +56,9 @@ interface RetryAfterComplianceConfig {
|
|
|
56
56
|
suggest_exponential_backoff?: boolean;
|
|
57
57
|
suggest_jitter?: boolean;
|
|
58
58
|
}
|
|
59
|
+
interface ErrorHandlerSetInSettingsConfig {
|
|
60
|
+
enabled: boolean;
|
|
61
|
+
}
|
|
59
62
|
interface RulesConfig {
|
|
60
63
|
rate_limit_retry: RateLimitRetryConfig;
|
|
61
64
|
error_handling: ErrorHandlingConfig;
|
|
@@ -71,6 +74,7 @@ interface RulesConfig {
|
|
|
71
74
|
config_literals: ConfigLiteralsConfig;
|
|
72
75
|
webhook_acknowledgment: WebhookAcknowledgmentConfig;
|
|
73
76
|
retry_after_compliance: RetryAfterComplianceConfig;
|
|
77
|
+
error_handler_set_in_settings: ErrorHandlerSetInSettingsConfig;
|
|
74
78
|
}
|
|
75
79
|
interface FilesConfig {
|
|
76
80
|
include: string[];
|
|
@@ -168,7 +172,7 @@ type RuleContext = {
|
|
|
168
172
|
cfg: FlowLintConfig;
|
|
169
173
|
nodeLines?: Record<string, number>;
|
|
170
174
|
};
|
|
171
|
-
declare function runAllRules(graph: Graph, ctx: RuleContext): Finding[];
|
|
175
|
+
declare function runAllRules(graph: Graph, ctx: RuleContext, extraRules?: RuleRunner[]): Finding[];
|
|
172
176
|
|
|
173
177
|
interface RuleMetadata {
|
|
174
178
|
id: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -56,6 +56,9 @@ interface RetryAfterComplianceConfig {
|
|
|
56
56
|
suggest_exponential_backoff?: boolean;
|
|
57
57
|
suggest_jitter?: boolean;
|
|
58
58
|
}
|
|
59
|
+
interface ErrorHandlerSetInSettingsConfig {
|
|
60
|
+
enabled: boolean;
|
|
61
|
+
}
|
|
59
62
|
interface RulesConfig {
|
|
60
63
|
rate_limit_retry: RateLimitRetryConfig;
|
|
61
64
|
error_handling: ErrorHandlingConfig;
|
|
@@ -71,6 +74,7 @@ interface RulesConfig {
|
|
|
71
74
|
config_literals: ConfigLiteralsConfig;
|
|
72
75
|
webhook_acknowledgment: WebhookAcknowledgmentConfig;
|
|
73
76
|
retry_after_compliance: RetryAfterComplianceConfig;
|
|
77
|
+
error_handler_set_in_settings: ErrorHandlerSetInSettingsConfig;
|
|
74
78
|
}
|
|
75
79
|
interface FilesConfig {
|
|
76
80
|
include: string[];
|
|
@@ -168,7 +172,7 @@ type RuleContext = {
|
|
|
168
172
|
cfg: FlowLintConfig;
|
|
169
173
|
nodeLines?: Record<string, number>;
|
|
170
174
|
};
|
|
171
|
-
declare function runAllRules(graph: Graph, ctx: RuleContext): Finding[];
|
|
175
|
+
declare function runAllRules(graph: Graph, ctx: RuleContext, extraRules?: RuleRunner[]): Finding[];
|
|
172
176
|
|
|
173
177
|
interface RuleMetadata {
|
|
174
178
|
id: string;
|
package/dist/index.js
CHANGED
|
@@ -401,6 +401,11 @@ function findAllUpstreamNodes(graph, startNodeId) {
|
|
|
401
401
|
}
|
|
402
402
|
return visited;
|
|
403
403
|
}
|
|
404
|
+
function isMainWorkflow(graph) {
|
|
405
|
+
return graph.nodes.some(
|
|
406
|
+
(node) => /trigger|webhook|schedule|form|\bstart\b/i.test(node.type) && !/executeworkflow/i.test(node.type) && !/manualTrigger/i.test(node.type)
|
|
407
|
+
);
|
|
408
|
+
}
|
|
404
409
|
var EXAMPLES_BASE_URL = "https://github.com/Replikanti/flowlint-examples/tree/main";
|
|
405
410
|
function getExampleLink(ruleId) {
|
|
406
411
|
return `${EXAMPLES_BASE_URL}/${ruleId}`;
|
|
@@ -615,7 +620,8 @@ function parseN8n(doc) {
|
|
|
615
620
|
edges,
|
|
616
621
|
meta: {
|
|
617
622
|
credentials: !!parsed.credentials,
|
|
618
|
-
nodeLines: Object.fromEntries(nodeLines)
|
|
623
|
+
nodeLines: Object.fromEntries(nodeLines),
|
|
624
|
+
settings: parsed.settings
|
|
619
625
|
}
|
|
620
626
|
};
|
|
621
627
|
}
|
|
@@ -1159,6 +1165,40 @@ var r14RetryAfterCompliance = createNodeRule(metadata14.id, metadata14.name, (no
|
|
|
1159
1165
|
};
|
|
1160
1166
|
});
|
|
1161
1167
|
|
|
1168
|
+
// src/rules/lib/r15-error-handler-set-in-settings.ts
|
|
1169
|
+
var metadata15 = {
|
|
1170
|
+
id: "R15",
|
|
1171
|
+
name: "error_handler_set_in_settings",
|
|
1172
|
+
severity: "must",
|
|
1173
|
+
description: "Ensures main workflows have an error handler workflow configured in settings",
|
|
1174
|
+
details: "Main workflows (triggered by webhook, schedule, form, etc.) should have settings.errorWorkflow set to receive error notifications. Sub-workflows (Execute Workflow Trigger) are excluded from this check."
|
|
1175
|
+
};
|
|
1176
|
+
function getWorkflowSettings(meta) {
|
|
1177
|
+
const settings = meta.settings;
|
|
1178
|
+
if (settings != null && typeof settings === "object" && !Array.isArray(settings)) {
|
|
1179
|
+
return settings;
|
|
1180
|
+
}
|
|
1181
|
+
return void 0;
|
|
1182
|
+
}
|
|
1183
|
+
function r15ErrorHandlerSetInSettings(graph, ctx) {
|
|
1184
|
+
const cfg = ctx.cfg.rules.error_handler_set_in_settings;
|
|
1185
|
+
if (!cfg?.enabled) return [];
|
|
1186
|
+
if (!isMainWorkflow(graph)) return [];
|
|
1187
|
+
const settings = getWorkflowSettings(graph.meta);
|
|
1188
|
+
if (settings?.errorWorkflow && typeof settings.errorWorkflow === "string" && settings.errorWorkflow.trim().length > 0) {
|
|
1189
|
+
return [];
|
|
1190
|
+
}
|
|
1191
|
+
return [
|
|
1192
|
+
{
|
|
1193
|
+
rule: metadata15.id,
|
|
1194
|
+
severity: metadata15.severity,
|
|
1195
|
+
path: ctx.path,
|
|
1196
|
+
message: "Main workflow does not have an error handler workflow configured in settings",
|
|
1197
|
+
raw_details: "Set settings.errorWorkflow to a valid workflow ID so that runtime errors trigger a notification workflow."
|
|
1198
|
+
}
|
|
1199
|
+
];
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1162
1202
|
// src/rules/index.ts
|
|
1163
1203
|
var rules = [
|
|
1164
1204
|
r1Retry,
|
|
@@ -1174,10 +1214,11 @@ var rules = [
|
|
|
1174
1214
|
r11DeprecatedNodes,
|
|
1175
1215
|
r12UnhandledErrorPath,
|
|
1176
1216
|
r13WebhookAcknowledgment,
|
|
1177
|
-
r14RetryAfterCompliance
|
|
1217
|
+
r14RetryAfterCompliance,
|
|
1218
|
+
r15ErrorHandlerSetInSettings
|
|
1178
1219
|
];
|
|
1179
|
-
function runAllRules(graph, ctx) {
|
|
1180
|
-
return rules.flatMap((rule) => rule(graph, ctx));
|
|
1220
|
+
function runAllRules(graph, ctx, extraRules = []) {
|
|
1221
|
+
return [...rules, ...extraRules].flatMap((rule) => rule(graph, ctx));
|
|
1181
1222
|
}
|
|
1182
1223
|
|
|
1183
1224
|
// src/rules/metadata.ts
|
|
@@ -1195,7 +1236,8 @@ var RULES_METADATA = [
|
|
|
1195
1236
|
metadata11,
|
|
1196
1237
|
metadata12,
|
|
1197
1238
|
metadata13,
|
|
1198
|
-
metadata14
|
|
1239
|
+
metadata14,
|
|
1240
|
+
metadata15
|
|
1199
1241
|
];
|
|
1200
1242
|
|
|
1201
1243
|
// src/config/default-config.ts
|
|
@@ -1263,7 +1305,8 @@ var defaultConfig = {
|
|
|
1263
1305
|
enabled: true,
|
|
1264
1306
|
suggest_exponential_backoff: true,
|
|
1265
1307
|
suggest_jitter: true
|
|
1266
|
-
}
|
|
1308
|
+
},
|
|
1309
|
+
error_handler_set_in_settings: { enabled: true }
|
|
1267
1310
|
}
|
|
1268
1311
|
};
|
|
1269
1312
|
|