flowlint 0.5.1 → 0.6.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 +45 -355
- package/dist/cli.js +163 -21
- package/dist/cli.js.map +1 -1
- package/package.json +52 -57
- package/dist/cli.d.ts +0 -8
- package/dist/commands/init.d.ts +0 -8
- package/dist/commands/init.js +0 -34
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/scan.d.ts +0 -11
- package/dist/commands/scan.js +0 -104
- package/dist/commands/scan.js.map +0 -1
- package/dist/packages/config/flowlint-config.d.ts +0 -73
- package/dist/packages/config/flowlint-config.js +0 -120
- package/dist/packages/config/flowlint-config.js.map +0 -1
- package/dist/packages/config/index.d.ts +0 -4
- package/dist/packages/config/index.js +0 -21
- package/dist/packages/config/index.js.map +0 -1
- package/dist/packages/github/client.d.ts +0 -2
- package/dist/packages/github/client.js +0 -94
- package/dist/packages/github/client.js.map +0 -1
- package/dist/packages/logger/index.d.ts +0 -11
- package/dist/packages/logger/index.js +0 -40
- package/dist/packages/logger/index.js.map +0 -1
- package/dist/packages/observability/collectors.d.ts +0 -40
- package/dist/packages/observability/collectors.js +0 -75
- package/dist/packages/observability/collectors.js.map +0 -1
- package/dist/packages/observability/index.d.ts +0 -10
- package/dist/packages/observability/index.js +0 -35
- package/dist/packages/observability/index.js.map +0 -1
- package/dist/packages/observability/metrics.d.ts +0 -119
- package/dist/packages/observability/metrics.js +0 -194
- package/dist/packages/observability/metrics.js.map +0 -1
- package/dist/packages/observability/middleware.d.ts +0 -32
- package/dist/packages/observability/middleware.js +0 -58
- package/dist/packages/observability/middleware.js.map +0 -1
- package/dist/packages/review/analysis-engine.d.ts +0 -19
- package/dist/packages/review/analysis-engine.js +0 -111
- package/dist/packages/review/analysis-engine.js.map +0 -1
- package/dist/packages/review/index.d.ts +0 -12
- package/dist/packages/review/index.js +0 -29
- package/dist/packages/review/index.js.map +0 -1
- package/dist/packages/review/parser-n8n.d.ts +0 -2
- package/dist/packages/review/parser-n8n.js +0 -122
- package/dist/packages/review/parser-n8n.js.map +0 -1
- package/dist/packages/review/providers/github.d.ts +0 -62
- package/dist/packages/review/providers/github.js +0 -275
- package/dist/packages/review/providers/github.js.map +0 -1
- package/dist/packages/review/providers.d.ts +0 -106
- package/dist/packages/review/providers.js +0 -12
- package/dist/packages/review/providers.js.map +0 -1
- package/dist/packages/review/reporter.d.ts +0 -17
- package/dist/packages/review/reporter.js +0 -59
- package/dist/packages/review/reporter.js.map +0 -1
- package/dist/packages/review/rules/index.d.ts +0 -9
- package/dist/packages/review/rules/index.js +0 -415
- package/dist/packages/review/rules/index.js.map +0 -1
- package/dist/packages/review/rules/rule-utils.d.ts +0 -36
- package/dist/packages/review/rules/rule-utils.js +0 -75
- package/dist/packages/review/rules/rule-utils.js.map +0 -1
- package/dist/packages/review/schemas/index.d.ts +0 -17
- package/dist/packages/review/schemas/index.js +0 -167
- package/dist/packages/review/schemas/index.js.map +0 -1
- package/dist/packages/review/schemas/n8n-workflow.schema.json +0 -177
- package/dist/packages/review/sniffer.d.ts +0 -15
- package/dist/packages/review/sniffer.js +0 -47
- package/dist/packages/review/sniffer.js.map +0 -1
- package/dist/packages/review/types.d.ts +0 -40
- package/dist/packages/review/types.js +0 -3
- package/dist/packages/review/types.js.map +0 -1
- package/dist/packages/review/utils/findings.d.ts +0 -23
- package/dist/packages/review/utils/findings.js +0 -34
- package/dist/packages/review/utils/findings.js.map +0 -1
- package/dist/packages/review/utils/merge.d.ts +0 -12
- package/dist/packages/review/utils/merge.js +0 -40
- package/dist/packages/review/utils/merge.js.map +0 -1
- package/dist/packages/review/utils.d.ts +0 -60
- package/dist/packages/review/utils.js +0 -214
- package/dist/packages/review/utils.js.map +0 -1
- package/dist/packages/tracing/github-tracer.d.ts +0 -38
- package/dist/packages/tracing/github-tracer.js +0 -79
- package/dist/packages/tracing/github-tracer.js.map +0 -1
- package/dist/packages/tracing/index.d.ts +0 -81
- package/dist/packages/tracing/index.js +0 -240
- package/dist/packages/tracing/index.js.map +0 -1
- package/dist/packages/tracing/tracer.d.ts +0 -30
- package/dist/packages/tracing/tracer.js +0 -141
- package/dist/packages/tracing/tracer.js.map +0 -1
- package/dist/providers/local-config-provider.d.ts +0 -11
- package/dist/providers/local-config-provider.js +0 -39
- package/dist/providers/local-config-provider.js.map +0 -1
- package/dist/providers/local-file-source.d.ts +0 -13
- package/dist/providers/local-file-source.js +0 -47
- package/dist/providers/local-file-source.js.map +0 -1
- package/dist/reporters/console-reporter.d.ts +0 -8
- package/dist/reporters/console-reporter.js +0 -75
- package/dist/reporters/console-reporter.js.map +0 -1
- package/dist/reporters/github-actions-reporter.d.ts +0 -30
- package/dist/reporters/github-actions-reporter.js +0 -104
- package/dist/reporters/github-actions-reporter.js.map +0 -1
- package/dist/reporters/json-reporter.d.ts +0 -14
- package/dist/reporters/json-reporter.js +0 -57
- package/dist/reporters/json-reporter.js.map +0 -1
- package/dist/reporters/junit-reporter.d.ts +0 -25
- package/dist/reporters/junit-reporter.js +0 -142
- package/dist/reporters/junit-reporter.js.map +0 -1
- package/dist/reporters/sarif-reporter.d.ts +0 -21
- package/dist/reporters/sarif-reporter.js +0 -125
- package/dist/reporters/sarif-reporter.js.map +0 -1
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import type { Graph, Finding, NodeRef, FindingSeverity } from '../types';
|
|
2
|
-
import type { FlowLintConfig } from '../../config/flowlint-config';
|
|
3
|
-
type Rule = string;
|
|
4
|
-
type RuleContext = {
|
|
5
|
-
path: string;
|
|
6
|
-
cfg: FlowLintConfig;
|
|
7
|
-
nodeLines?: Record<string, number>;
|
|
8
|
-
};
|
|
9
|
-
type RuleRunner = (graph: Graph, ctx: RuleContext) => Finding[];
|
|
10
|
-
type NodeRuleLogic = (node: NodeRef, graph: Graph, ctx: RuleContext) => Finding | Finding[] | null;
|
|
11
|
-
/**
|
|
12
|
-
* A higher-order function to create a rule that iterates over each node in the graph.
|
|
13
|
-
* It abstracts the boilerplate of checking if the rule is enabled and iterating through nodes.
|
|
14
|
-
*
|
|
15
|
-
* @param ruleId - The ID of the rule (e.g., 'R1').
|
|
16
|
-
* @param configKey - The key in the FlowLintConfig rules object.
|
|
17
|
-
* @param logic - The function containing the core logic to be executed for each node.
|
|
18
|
-
* @returns A RuleRunner function.
|
|
19
|
-
*/
|
|
20
|
-
export declare function createNodeRule(ruleId: Rule, configKey: keyof FlowLintConfig['rules'], logic: NodeRuleLogic): RuleRunner;
|
|
21
|
-
type HardcodedStringRuleOptions = {
|
|
22
|
-
ruleId: Rule;
|
|
23
|
-
severity: FindingSeverity;
|
|
24
|
-
configKey: 'secrets' | 'config_literals';
|
|
25
|
-
messageFn: (node: NodeRef, value: string) => string;
|
|
26
|
-
details: string;
|
|
27
|
-
};
|
|
28
|
-
/**
|
|
29
|
-
* Creates a rule that checks for hardcoded strings in node parameters based on a denylist of regex patterns.
|
|
30
|
-
* This is used to create R4 (Secrets) and R9 (Config Literals).
|
|
31
|
-
*
|
|
32
|
-
* @param options - The configuration for the hardcoded string rule.
|
|
33
|
-
* @returns A RuleRunner function.
|
|
34
|
-
*/
|
|
35
|
-
export declare function createHardcodedStringRule({ ruleId, severity, configKey, messageFn, details, }: HardcodedStringRuleOptions): RuleRunner;
|
|
36
|
-
export {};
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createNodeRule = createNodeRule;
|
|
4
|
-
exports.createHardcodedStringRule = createHardcodedStringRule;
|
|
5
|
-
const utils_1 = require("../utils");
|
|
6
|
-
/**
|
|
7
|
-
* A higher-order function to create a rule that iterates over each node in the graph.
|
|
8
|
-
* It abstracts the boilerplate of checking if the rule is enabled and iterating through nodes.
|
|
9
|
-
*
|
|
10
|
-
* @param ruleId - The ID of the rule (e.g., 'R1').
|
|
11
|
-
* @param configKey - The key in the FlowLintConfig rules object.
|
|
12
|
-
* @param logic - The function containing the core logic to be executed for each node.
|
|
13
|
-
* @returns A RuleRunner function.
|
|
14
|
-
*/
|
|
15
|
-
function createNodeRule(ruleId, configKey, logic) {
|
|
16
|
-
return (graph, ctx) => {
|
|
17
|
-
const ruleConfig = ctx.cfg.rules[configKey];
|
|
18
|
-
if (!ruleConfig?.enabled) {
|
|
19
|
-
return [];
|
|
20
|
-
}
|
|
21
|
-
const findings = [];
|
|
22
|
-
for (const node of graph.nodes) {
|
|
23
|
-
const result = logic(node, graph, ctx);
|
|
24
|
-
if (result) {
|
|
25
|
-
if (Array.isArray(result)) {
|
|
26
|
-
findings.push(...result);
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
findings.push(result);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return findings;
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Creates a rule that checks for hardcoded strings in node parameters based on a denylist of regex patterns.
|
|
38
|
-
* This is used to create R4 (Secrets) and R9 (Config Literals).
|
|
39
|
-
*
|
|
40
|
-
* @param options - The configuration for the hardcoded string rule.
|
|
41
|
-
* @returns A RuleRunner function.
|
|
42
|
-
*/
|
|
43
|
-
function createHardcodedStringRule({ ruleId, severity, configKey, messageFn, details, }) {
|
|
44
|
-
const logic = (node, graph, ctx) => {
|
|
45
|
-
const cfg = ctx.cfg.rules[configKey];
|
|
46
|
-
if (!cfg.denylist_regex?.length) {
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
const regexes = cfg.denylist_regex.map((pattern) => (0, utils_1.toRegex)(pattern));
|
|
50
|
-
const findings = [];
|
|
51
|
-
const strings = (0, utils_1.collectStrings)(node.params);
|
|
52
|
-
for (const value of strings) {
|
|
53
|
-
// Ignore expressions and empty strings
|
|
54
|
-
if (!value || value.includes('{{')) {
|
|
55
|
-
continue;
|
|
56
|
-
}
|
|
57
|
-
if (regexes.some((regex) => regex.test(value))) {
|
|
58
|
-
findings.push({
|
|
59
|
-
rule: ruleId,
|
|
60
|
-
severity,
|
|
61
|
-
path: ctx.path,
|
|
62
|
-
message: messageFn(node, value),
|
|
63
|
-
nodeId: node.id,
|
|
64
|
-
line: ctx.nodeLines?.[node.id],
|
|
65
|
-
raw_details: details,
|
|
66
|
-
});
|
|
67
|
-
// Only report one finding per node to avoid noise
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return findings;
|
|
72
|
-
};
|
|
73
|
-
return createNodeRule(ruleId, configKey, logic);
|
|
74
|
-
}
|
|
75
|
-
//# sourceMappingURL=rule-utils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rule-utils.js","sourceRoot":"","sources":["../../../../packages/review/rules/rule-utils.ts"],"names":[],"mappings":";;AAkBA,wCAwBC;AAiBD,8DAyCC;AAlGD,oCAAmD;AAOnD;;;;;;;;GAQG;AACH,SAAgB,cAAc,CAC5B,MAAY,EACZ,SAAwC,EACxC,KAAoB;IAEpB,OAAO,CAAC,KAAY,EAAE,GAAgB,EAAa,EAAE;QACnD,MAAM,UAAU,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAA0B,CAAC;QACrE,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;YACzB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;YACvC,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC1B,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACN,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACxB,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC;AAUD;;;;;;GAMG;AACH,SAAgB,yBAAyB,CAAC,EACxC,MAAM,EACN,QAAQ,EACR,SAAS,EACT,SAAS,EACT,OAAO,GACoB;IAC3B,MAAM,KAAK,GAAkB,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAChD,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QACrC,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAA,eAAO,EAAC,OAAO,CAAC,CAAC,CAAC;QAEtE,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAA,sBAAc,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE5C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,uCAAuC;YACvC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnC,SAAS;YACX,CAAC;YAED,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;gBAC/C,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,MAAM;oBACZ,QAAQ;oBACR,IAAI,EAAE,GAAG,CAAC,IAAI;oBACd,OAAO,EAAE,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC;oBAC/B,MAAM,EAAE,IAAI,CAAC,EAAE;oBACf,IAAI,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC9B,WAAW,EAAE,OAAO;iBACrB,CAAC,CAAC;gBACH,kDAAkD;gBAClD,MAAM;YACR,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export declare class ValidationError extends Error {
|
|
2
|
-
errors: Array<{
|
|
3
|
-
path: string;
|
|
4
|
-
message: string;
|
|
5
|
-
suggestion?: string;
|
|
6
|
-
}>;
|
|
7
|
-
constructor(errors: Array<{
|
|
8
|
-
path: string;
|
|
9
|
-
message: string;
|
|
10
|
-
suggestion?: string;
|
|
11
|
-
}>);
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* Validate n8n workflow structure
|
|
15
|
-
* Throws ValidationError with detailed messages if validation fails
|
|
16
|
-
*/
|
|
17
|
-
export declare function validateN8nWorkflow(data: any): void;
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.ValidationError = void 0;
|
|
7
|
-
exports.validateN8nWorkflow = validateN8nWorkflow;
|
|
8
|
-
const ajv_1 = __importDefault(require("ajv"));
|
|
9
|
-
const ajv_formats_1 = __importDefault(require("ajv-formats"));
|
|
10
|
-
const n8n_workflow_schema_json_1 = __importDefault(require("./n8n-workflow.schema.json"));
|
|
11
|
-
const utils_1 = require("../utils");
|
|
12
|
-
// Custom error class for validation failures
|
|
13
|
-
class ValidationError extends Error {
|
|
14
|
-
constructor(errors) {
|
|
15
|
-
super(`Workflow validation failed: ${errors.length} error(s)`);
|
|
16
|
-
this.errors = errors;
|
|
17
|
-
this.name = 'ValidationError';
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
exports.ValidationError = ValidationError;
|
|
21
|
-
// Dummy validator that always passes
|
|
22
|
-
const createDummyValidator = () => {
|
|
23
|
-
const v = () => true;
|
|
24
|
-
v.errors = [];
|
|
25
|
-
return v;
|
|
26
|
-
};
|
|
27
|
-
// Singleton instance
|
|
28
|
-
let validatorInstance = null;
|
|
29
|
-
function getValidator() {
|
|
30
|
-
if (validatorInstance)
|
|
31
|
-
return validatorInstance;
|
|
32
|
-
// Detect Node.js environment safely
|
|
33
|
-
// Use optional chaining to satisfy SonarQube
|
|
34
|
-
const isNode = typeof process !== 'undefined' && process?.versions?.node != null;
|
|
35
|
-
if (isNode) {
|
|
36
|
-
try {
|
|
37
|
-
const ajv = new ajv_1.default({
|
|
38
|
-
allErrors: true,
|
|
39
|
-
strict: false,
|
|
40
|
-
verbose: true,
|
|
41
|
-
code: { source: true, es5: true }
|
|
42
|
-
});
|
|
43
|
-
(0, ajv_formats_1.default)(ajv);
|
|
44
|
-
validatorInstance = ajv.compile(n8n_workflow_schema_json_1.default);
|
|
45
|
-
}
|
|
46
|
-
catch (error) {
|
|
47
|
-
// Fallback to dummy validator if compilation fails (e.g. due to strict CSP in some environments)
|
|
48
|
-
console.warn('Failed to compile JSON schema validator, falling back to dummy validator:', error);
|
|
49
|
-
validatorInstance = createDummyValidator();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
validatorInstance = createDummyValidator();
|
|
54
|
-
}
|
|
55
|
-
return validatorInstance;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Throws a ValidationError if the provided set contains items.
|
|
59
|
-
* Centralizes the pattern of checking validation results and throwing errors.
|
|
60
|
-
*
|
|
61
|
-
* @param items - Set of items that represent validation failures
|
|
62
|
-
* @param config - Configuration for building error messages
|
|
63
|
-
* @throws ValidationError if items set is not empty
|
|
64
|
-
*/
|
|
65
|
-
function throwIfInvalid(items, config) {
|
|
66
|
-
if (items.size > 0) {
|
|
67
|
-
const errors = (0, utils_1.buildValidationErrors)(items, config);
|
|
68
|
-
throw new ValidationError(errors);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Check for duplicate node IDs in the workflow
|
|
73
|
-
*/
|
|
74
|
-
function checkDuplicateNodeIds(data) {
|
|
75
|
-
if (!Array.isArray(data.nodes))
|
|
76
|
-
return;
|
|
77
|
-
const seen = new Set();
|
|
78
|
-
const duplicates = new Set();
|
|
79
|
-
for (const node of data.nodes) {
|
|
80
|
-
if (node.id && seen.has(node.id)) {
|
|
81
|
-
duplicates.add(node.id);
|
|
82
|
-
}
|
|
83
|
-
if (node.id) {
|
|
84
|
-
seen.add(node.id);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
throwIfInvalid(duplicates, {
|
|
88
|
-
path: 'nodes[].id',
|
|
89
|
-
messageTemplate: (id) => `Duplicate node ID: "${id}"`,
|
|
90
|
-
suggestionTemplate: (id) => `Each node must have a unique ID. Remove or rename the duplicate node with ID "${id}".`,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Check for orphaned connections (references to non-existent nodes)
|
|
95
|
-
*/
|
|
96
|
-
function checkOrphanedConnections(data) {
|
|
97
|
-
if (!data.connections || !Array.isArray(data.nodes))
|
|
98
|
-
return;
|
|
99
|
-
const nodeIds = new Set();
|
|
100
|
-
const nodeNames = new Set();
|
|
101
|
-
// Collect all node IDs and names
|
|
102
|
-
for (const node of data.nodes) {
|
|
103
|
-
if (node.id)
|
|
104
|
-
nodeIds.add(node.id);
|
|
105
|
-
if (node.name)
|
|
106
|
-
nodeNames.add(node.name);
|
|
107
|
-
}
|
|
108
|
-
const orphanedRefs = new Set();
|
|
109
|
-
// Check all connection targets
|
|
110
|
-
Object.entries(data.connections).forEach(([sourceId, channels]) => {
|
|
111
|
-
// Check if source exists
|
|
112
|
-
if (!nodeIds.has(sourceId) && !nodeNames.has(sourceId)) {
|
|
113
|
-
orphanedRefs.add(sourceId);
|
|
114
|
-
}
|
|
115
|
-
// Check targets
|
|
116
|
-
if (typeof channels === 'object' && channels !== null) {
|
|
117
|
-
Object.values(channels).forEach((connArray) => {
|
|
118
|
-
const flatConnections = (0, utils_1.flattenConnections)(connArray);
|
|
119
|
-
flatConnections.forEach((conn) => {
|
|
120
|
-
if (conn?.node) {
|
|
121
|
-
if (!nodeIds.has(conn.node) && !nodeNames.has(conn.node)) {
|
|
122
|
-
orphanedRefs.add(conn.node);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
});
|
|
129
|
-
throwIfInvalid(orphanedRefs, {
|
|
130
|
-
path: 'connections',
|
|
131
|
-
messageTemplate: (ref) => `Orphaned connection reference: "${ref}"`,
|
|
132
|
-
suggestionTemplate: (ref) => `Connection references node "${ref}" which does not exist. Add the missing node or remove the invalid connection.`,
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Validate n8n workflow structure
|
|
137
|
-
* Throws ValidationError with detailed messages if validation fails
|
|
138
|
-
*/
|
|
139
|
-
function validateN8nWorkflow(data) {
|
|
140
|
-
const validate = getValidator();
|
|
141
|
-
// Basic schema validation
|
|
142
|
-
if (!validate(data)) {
|
|
143
|
-
const errors = (validate.errors || []).map((err) => {
|
|
144
|
-
const path = err.instancePath || err.schemaPath;
|
|
145
|
-
const message = err.message || 'Validation error';
|
|
146
|
-
let suggestion = '';
|
|
147
|
-
// Provide helpful suggestions based on error type
|
|
148
|
-
if (err.keyword === 'required') {
|
|
149
|
-
const missing = err.params?.missingProperty;
|
|
150
|
-
suggestion = `Add the required field "${missing}" to the workflow.`;
|
|
151
|
-
}
|
|
152
|
-
else if (err.keyword === 'type') {
|
|
153
|
-
const expected = err.params?.type;
|
|
154
|
-
suggestion = `The field should be of type "${expected}".`;
|
|
155
|
-
}
|
|
156
|
-
else if (err.keyword === 'minLength') {
|
|
157
|
-
suggestion = 'This field cannot be empty.';
|
|
158
|
-
}
|
|
159
|
-
return { path, message, suggestion };
|
|
160
|
-
});
|
|
161
|
-
throw new ValidationError(errors);
|
|
162
|
-
}
|
|
163
|
-
// Additional custom validations
|
|
164
|
-
checkDuplicateNodeIds(data);
|
|
165
|
-
checkOrphanedConnections(data);
|
|
166
|
-
}
|
|
167
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../packages/review/schemas/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"$id": "https://flowlint.dev/schemas/n8n-workflow.json",
|
|
4
|
-
"title": "n8n Workflow Schema",
|
|
5
|
-
"description": "JSON Schema for n8n workflow files (v1.x)",
|
|
6
|
-
"type": "object",
|
|
7
|
-
"required": ["nodes", "connections"],
|
|
8
|
-
"properties": {
|
|
9
|
-
"name": {
|
|
10
|
-
"type": "string",
|
|
11
|
-
"description": "Workflow name"
|
|
12
|
-
},
|
|
13
|
-
"nodes": {
|
|
14
|
-
"type": "array",
|
|
15
|
-
"description": "Array of workflow nodes",
|
|
16
|
-
"items": {
|
|
17
|
-
"type": "object",
|
|
18
|
-
"required": ["type", "name"],
|
|
19
|
-
"properties": {
|
|
20
|
-
"id": {
|
|
21
|
-
"type": "string",
|
|
22
|
-
"minLength": 1,
|
|
23
|
-
"description": "Unique node identifier"
|
|
24
|
-
},
|
|
25
|
-
"type": {
|
|
26
|
-
"type": "string",
|
|
27
|
-
"minLength": 1,
|
|
28
|
-
"description": "Node type (e.g., n8n-nodes-base.httpRequest)"
|
|
29
|
-
},
|
|
30
|
-
"name": {
|
|
31
|
-
"type": "string",
|
|
32
|
-
"minLength": 1,
|
|
33
|
-
"description": "Human-readable node name"
|
|
34
|
-
},
|
|
35
|
-
"parameters": {
|
|
36
|
-
"type": "object",
|
|
37
|
-
"description": "Node-specific configuration parameters"
|
|
38
|
-
},
|
|
39
|
-
"credentials": {
|
|
40
|
-
"type": "object",
|
|
41
|
-
"description": "Credential references for this node"
|
|
42
|
-
},
|
|
43
|
-
"position": {
|
|
44
|
-
"type": "array",
|
|
45
|
-
"description": "X,Y coordinates for UI placement",
|
|
46
|
-
"items": {
|
|
47
|
-
"type": "number"
|
|
48
|
-
},
|
|
49
|
-
"minItems": 2,
|
|
50
|
-
"maxItems": 2
|
|
51
|
-
},
|
|
52
|
-
"continueOnFail": {
|
|
53
|
-
"type": "boolean",
|
|
54
|
-
"description": "Whether to continue execution on node failure"
|
|
55
|
-
},
|
|
56
|
-
"disabled": {
|
|
57
|
-
"type": "boolean",
|
|
58
|
-
"description": "Whether the node is disabled"
|
|
59
|
-
},
|
|
60
|
-
"notesInFlow": {
|
|
61
|
-
"type": "boolean"
|
|
62
|
-
},
|
|
63
|
-
"notes": {
|
|
64
|
-
"type": "string"
|
|
65
|
-
},
|
|
66
|
-
"typeVersion": {
|
|
67
|
-
"type": "number",
|
|
68
|
-
"description": "Version of the node type"
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
"additionalProperties": true
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
"connections": {
|
|
75
|
-
"type": "object",
|
|
76
|
-
"description": "Map of node connections (source node ID -> connection details)",
|
|
77
|
-
"patternProperties": {
|
|
78
|
-
"^.*$": {
|
|
79
|
-
"type": "object",
|
|
80
|
-
"description": "Connection channels for a source node",
|
|
81
|
-
"patternProperties": {
|
|
82
|
-
"^(main|error|timeout|.*?)$": {
|
|
83
|
-
"description": "Connection array for this channel",
|
|
84
|
-
"oneOf": [
|
|
85
|
-
{
|
|
86
|
-
"type": "array",
|
|
87
|
-
"items": {
|
|
88
|
-
"type": "object",
|
|
89
|
-
"required": ["node"],
|
|
90
|
-
"properties": {
|
|
91
|
-
"node": {
|
|
92
|
-
"type": "string",
|
|
93
|
-
"description": "Target node ID or name"
|
|
94
|
-
},
|
|
95
|
-
"type": {
|
|
96
|
-
"type": "string",
|
|
97
|
-
"description": "Connection type"
|
|
98
|
-
},
|
|
99
|
-
"index": {
|
|
100
|
-
"type": "number",
|
|
101
|
-
"description": "Output index"
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
{
|
|
107
|
-
"type": "array",
|
|
108
|
-
"items": {
|
|
109
|
-
"type": "array",
|
|
110
|
-
"items": {
|
|
111
|
-
"type": "object",
|
|
112
|
-
"required": ["node"],
|
|
113
|
-
"properties": {
|
|
114
|
-
"node": {
|
|
115
|
-
"type": "string"
|
|
116
|
-
},
|
|
117
|
-
"type": {
|
|
118
|
-
"type": "string"
|
|
119
|
-
},
|
|
120
|
-
"index": {
|
|
121
|
-
"type": "number"
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
]
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
"active": {
|
|
134
|
-
"type": "boolean",
|
|
135
|
-
"description": "Whether the workflow is active"
|
|
136
|
-
},
|
|
137
|
-
"settings": {
|
|
138
|
-
"type": "object",
|
|
139
|
-
"description": "Workflow settings"
|
|
140
|
-
},
|
|
141
|
-
"tags": {
|
|
142
|
-
"type": "array",
|
|
143
|
-
"description": "Workflow tags",
|
|
144
|
-
"items": {
|
|
145
|
-
"oneOf": [
|
|
146
|
-
{ "type": "string" },
|
|
147
|
-
{
|
|
148
|
-
"type": "object",
|
|
149
|
-
"required": ["name"],
|
|
150
|
-
"properties": {
|
|
151
|
-
"id": { "type": "string" },
|
|
152
|
-
"name": { "type": "string" }
|
|
153
|
-
},
|
|
154
|
-
"additionalProperties": true
|
|
155
|
-
}
|
|
156
|
-
]
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
"pinData": {
|
|
160
|
-
"type": "object",
|
|
161
|
-
"description": "Pinned execution data for testing"
|
|
162
|
-
},
|
|
163
|
-
"versionId": {
|
|
164
|
-
"type": "string",
|
|
165
|
-
"description": "Workflow version identifier"
|
|
166
|
-
},
|
|
167
|
-
"id": {
|
|
168
|
-
"type": ["string", "number"],
|
|
169
|
-
"description": "Workflow ID"
|
|
170
|
-
},
|
|
171
|
-
"meta": {
|
|
172
|
-
"type": "object",
|
|
173
|
-
"description": "Metadata"
|
|
174
|
-
}
|
|
175
|
-
},
|
|
176
|
-
"additionalProperties": true
|
|
177
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { Octokit } from 'octokit';
|
|
2
|
-
import type { PRFile } from './types';
|
|
3
|
-
export type GlobSet = {
|
|
4
|
-
include: string[];
|
|
5
|
-
ignore: string[];
|
|
6
|
-
};
|
|
7
|
-
export declare function pickTargets(files: PRFile[], globs: GlobSet): PRFile[];
|
|
8
|
-
export type FetchResult = {
|
|
9
|
-
contents: Map<string, string>;
|
|
10
|
-
errors: Array<{
|
|
11
|
-
filename: string;
|
|
12
|
-
error: string;
|
|
13
|
-
}>;
|
|
14
|
-
};
|
|
15
|
-
export declare function fetchRawFiles(gh: Octokit, repoFull: string, targets: PRFile[]): Promise<FetchResult>;
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.pickTargets = pickTargets;
|
|
7
|
-
exports.fetchRawFiles = fetchRawFiles;
|
|
8
|
-
const logger_1 = require("../logger");
|
|
9
|
-
const micromatch_1 = __importDefault(require("micromatch"));
|
|
10
|
-
function pickTargets(files, globs) {
|
|
11
|
-
return files
|
|
12
|
-
.filter((file) => file.status !== 'removed')
|
|
13
|
-
.filter((file) => {
|
|
14
|
-
const normalized = file.filename.replace(/\\/g, '/');
|
|
15
|
-
const included = micromatch_1.default.isMatch(normalized, globs.include, { dot: true });
|
|
16
|
-
const ignored = micromatch_1.default.isMatch(normalized, globs.ignore, { dot: true });
|
|
17
|
-
return included && !ignored;
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
async function fetchRawFiles(gh, repoFull, targets) {
|
|
21
|
-
const [owner, repo] = repoFull.split('/');
|
|
22
|
-
const contents = new Map();
|
|
23
|
-
const errors = [];
|
|
24
|
-
for (const file of targets) {
|
|
25
|
-
if (!file.sha) {
|
|
26
|
-
errors.push({ filename: file.filename, error: 'Missing SHA (file may be removed)' });
|
|
27
|
-
continue;
|
|
28
|
-
}
|
|
29
|
-
try {
|
|
30
|
-
const { data: blob } = await gh.request('GET /repos/{owner}/{repo}/git/blobs/{file_sha}', {
|
|
31
|
-
owner,
|
|
32
|
-
repo,
|
|
33
|
-
file_sha: file.sha,
|
|
34
|
-
});
|
|
35
|
-
const raw = Buffer.from(blob.content, 'base64').toString('utf8');
|
|
36
|
-
contents.set(file.filename, raw);
|
|
37
|
-
}
|
|
38
|
-
catch (error) {
|
|
39
|
-
// Handle transient errors (404, timeouts, rate limits) gracefully
|
|
40
|
-
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
41
|
-
logger_1.logger.warn({ filename: file.filename, error: errorMsg }, 'failed to fetch file');
|
|
42
|
-
errors.push({ filename: file.filename, error: errorMsg });
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return { contents, errors };
|
|
46
|
-
}
|
|
47
|
-
//# sourceMappingURL=sniffer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sniffer.js","sourceRoot":"","sources":["../../../packages/review/sniffer.ts"],"names":[],"mappings":";;;;;AAOA,kCASC;AAOD,sCAgCC;AArDD,sCAAmC;AACnC,4DAAoC;AAIpC,SAAgB,WAAW,CAAC,KAAe,EAAE,KAAc;IACzD,OAAO,KAAK;SACT,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC;SAC3C,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACf,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,oBAAU,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9E,MAAM,OAAO,GAAG,oBAAU,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5E,OAAO,QAAQ,IAAI,CAAC,OAAO,CAAC;IAC9B,CAAC,CAAC,CAAC;AACP,CAAC;AAOM,KAAK,UAAU,aAAa,CACjC,EAAW,EACX,QAAgB,EAChB,OAAiB;IAEjB,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,MAAM,MAAM,GAA+C,EAAE,CAAC;IAE9D,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,mCAAmC,EAAE,CAAC,CAAC;YACrF,SAAS;QACX,CAAC;QAED,IAAI,CAAC;YACH,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,gDAAgD,EAAE;gBACxF,KAAK;gBACL,IAAI;gBACJ,QAAQ,EAAE,IAAI,CAAC,GAAG;aACnB,CAAC,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACjE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,kEAAkE;YAClE,MAAM,QAAQ,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACxE,eAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,sBAAsB,CAAC,CAAC;YAClF,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AAC9B,CAAC"}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
export type PRFile = {
|
|
2
|
-
filename: string;
|
|
3
|
-
status: string;
|
|
4
|
-
sha?: string;
|
|
5
|
-
patch?: string;
|
|
6
|
-
};
|
|
7
|
-
export type FindingSeverity = 'must' | 'should' | 'nit';
|
|
8
|
-
export type Finding = {
|
|
9
|
-
rule: string;
|
|
10
|
-
severity: FindingSeverity;
|
|
11
|
-
path: string;
|
|
12
|
-
message: string;
|
|
13
|
-
raw_details?: string;
|
|
14
|
-
nodeId?: string;
|
|
15
|
-
line?: number;
|
|
16
|
-
documentationUrl?: string;
|
|
17
|
-
};
|
|
18
|
-
export type NodeRef = {
|
|
19
|
-
id: string;
|
|
20
|
-
type: string;
|
|
21
|
-
name?: string;
|
|
22
|
-
params?: Record<string, unknown>;
|
|
23
|
-
cred?: Record<string, unknown>;
|
|
24
|
-
flags?: {
|
|
25
|
-
continueOnFail?: boolean;
|
|
26
|
-
retryOnFail?: boolean | string;
|
|
27
|
-
waitBetweenTries?: number | string;
|
|
28
|
-
maxTries?: number | string;
|
|
29
|
-
};
|
|
30
|
-
};
|
|
31
|
-
export type Edge = {
|
|
32
|
-
from: string;
|
|
33
|
-
to: string;
|
|
34
|
-
on?: 'success' | 'error' | 'timeout';
|
|
35
|
-
};
|
|
36
|
-
export type Graph = {
|
|
37
|
-
nodes: NodeRef[];
|
|
38
|
-
edges: Edge[];
|
|
39
|
-
meta: Record<string, unknown>;
|
|
40
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../packages/review/types.ts"],"names":[],"mappings":""}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Findings utilities
|
|
3
|
-
* Shared logic for processing and analyzing findings across both review engine and CLI
|
|
4
|
-
*/
|
|
5
|
-
import type { Finding } from '../types';
|
|
6
|
-
export interface FindingsSummary {
|
|
7
|
-
must: number;
|
|
8
|
-
should: number;
|
|
9
|
-
nit: number;
|
|
10
|
-
total: number;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Count findings by severity level
|
|
14
|
-
*/
|
|
15
|
-
export declare function countFindingsBySeverity(findings: Finding[]): FindingsSummary;
|
|
16
|
-
/**
|
|
17
|
-
* Get severity order for sorting
|
|
18
|
-
*/
|
|
19
|
-
export declare function getSeverityOrder(): Record<string, number>;
|
|
20
|
-
/**
|
|
21
|
-
* Sort findings by severity
|
|
22
|
-
*/
|
|
23
|
-
export declare function sortFindingsBySeverity(findings: Finding[]): Finding[];
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Findings utilities
|
|
4
|
-
* Shared logic for processing and analyzing findings across both review engine and CLI
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.countFindingsBySeverity = countFindingsBySeverity;
|
|
8
|
-
exports.getSeverityOrder = getSeverityOrder;
|
|
9
|
-
exports.sortFindingsBySeverity = sortFindingsBySeverity;
|
|
10
|
-
/**
|
|
11
|
-
* Count findings by severity level
|
|
12
|
-
*/
|
|
13
|
-
function countFindingsBySeverity(findings) {
|
|
14
|
-
return {
|
|
15
|
-
must: findings.filter((f) => f.severity === 'must').length,
|
|
16
|
-
should: findings.filter((f) => f.severity === 'should').length,
|
|
17
|
-
nit: findings.filter((f) => f.severity === 'nit').length,
|
|
18
|
-
total: findings.length,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Get severity order for sorting
|
|
23
|
-
*/
|
|
24
|
-
function getSeverityOrder() {
|
|
25
|
-
return { must: 0, should: 1, nit: 2 };
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Sort findings by severity
|
|
29
|
-
*/
|
|
30
|
-
function sortFindingsBySeverity(findings) {
|
|
31
|
-
const order = getSeverityOrder();
|
|
32
|
-
return [...findings].sort((a, b) => order[a.severity] - order[b.severity]);
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=findings.js.map
|