@lucasacoutinho/archer 0.2.0 → 0.3.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 +145 -387
- package/dist/analyzer/Analyzer.d.ts +17 -0
- package/dist/analyzer/Analyzer.d.ts.map +1 -0
- package/dist/analyzer/Analyzer.js +15 -0
- package/dist/analyzer/Analyzer.js.map +1 -0
- package/dist/analyzer/bindings.d.ts +26 -0
- package/dist/analyzer/bindings.d.ts.map +1 -0
- package/dist/analyzer/bindings.js +61 -0
- package/dist/analyzer/bindings.js.map +1 -0
- package/dist/analyzer/errors.d.ts +34 -0
- package/dist/analyzer/errors.d.ts.map +1 -0
- package/dist/analyzer/errors.js +20 -0
- package/dist/analyzer/errors.js.map +1 -0
- package/dist/analyzer/graph-file.d.ts +13 -0
- package/dist/analyzer/graph-file.d.ts.map +1 -0
- package/dist/analyzer/graph-file.js +22 -0
- package/dist/analyzer/graph-file.js.map +1 -0
- package/dist/analyzer/paths.d.ts +12 -0
- package/dist/analyzer/paths.d.ts.map +1 -0
- package/dist/analyzer/paths.js +26 -0
- package/dist/analyzer/paths.js.map +1 -0
- package/dist/analyzer/server-exit.d.ts +19 -0
- package/dist/analyzer/server-exit.d.ts.map +1 -0
- package/dist/analyzer/server-exit.js +70 -0
- package/dist/analyzer/server-exit.js.map +1 -0
- package/dist/analyzer/source.d.ts +29 -0
- package/dist/analyzer/source.d.ts.map +1 -0
- package/dist/analyzer/source.js +58 -0
- package/dist/analyzer/source.js.map +1 -0
- package/dist/analyzer/syntax.d.ts +29 -0
- package/dist/analyzer/syntax.d.ts.map +1 -0
- package/dist/analyzer/syntax.js +226 -0
- package/dist/analyzer/syntax.js.map +1 -0
- package/dist/analyzer/targets.d.ts +26 -0
- package/dist/analyzer/targets.d.ts.map +1 -0
- package/dist/analyzer/targets.js +84 -0
- package/dist/analyzer/targets.js.map +1 -0
- package/dist/analyzer/typescript.d.ts +5 -0
- package/dist/analyzer/typescript.d.ts.map +1 -0
- package/dist/analyzer/typescript.js +221 -0
- package/dist/analyzer/typescript.js.map +1 -0
- package/dist/analyzer/workspace.d.ts +24 -0
- package/dist/analyzer/workspace.d.ts.map +1 -0
- package/dist/analyzer/workspace.js +9 -0
- package/dist/analyzer/workspace.js.map +1 -0
- package/dist/cli/explain.d.ts +3 -0
- package/dist/cli/explain.d.ts.map +1 -0
- package/dist/cli/explain.js +21 -0
- package/dist/cli/explain.js.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.d.ts.map +1 -0
- package/dist/cli/main.js +159 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/config/input.d.ts +59 -0
- package/dist/config/input.d.ts.map +1 -0
- package/dist/config/input.js +115 -0
- package/dist/config/input.js.map +1 -0
- package/dist/config/rules.d.ts +94 -0
- package/dist/config/rules.d.ts.map +1 -0
- package/dist/config/rules.js +130 -0
- package/dist/config/rules.js.map +1 -0
- package/dist/core/baseline.d.ts +16 -0
- package/dist/core/baseline.d.ts.map +1 -0
- package/dist/core/baseline.js +25 -0
- package/dist/core/baseline.js.map +1 -0
- package/dist/core/check.d.ts +16 -0
- package/dist/core/check.d.ts.map +1 -0
- package/dist/core/check.js +271 -0
- package/dist/core/check.js.map +1 -0
- package/dist/core/config.d.ts +72 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +78 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/fingerprint.d.ts +54 -0
- package/dist/core/fingerprint.d.ts.map +1 -0
- package/dist/core/fingerprint.js +182 -0
- package/dist/core/fingerprint.js.map +1 -0
- package/dist/core/keys.d.ts +10 -0
- package/dist/core/keys.d.ts.map +1 -0
- package/dist/core/keys.js +16 -0
- package/dist/core/keys.js.map +1 -0
- package/dist/core/lower.d.ts +13 -0
- package/dist/core/lower.d.ts.map +1 -0
- package/dist/core/lower.js +82 -0
- package/dist/core/lower.js.map +1 -0
- package/dist/core/model.d.ts +155 -0
- package/dist/core/model.d.ts.map +1 -0
- package/dist/core/model.js +116 -0
- package/dist/core/model.js.map +1 -0
- package/dist/core/pattern.d.ts +13 -0
- package/dist/core/pattern.d.ts.map +1 -0
- package/dist/core/pattern.js +29 -0
- package/dist/core/pattern.js.map +1 -0
- package/dist/core/reach.d.ts +10 -0
- package/dist/core/reach.d.ts.map +1 -0
- package/dist/core/reach.js +81 -0
- package/dist/core/reach.js.map +1 -0
- package/dist/core/rule.d.ts +200 -0
- package/dist/core/rule.d.ts.map +1 -0
- package/dist/core/rule.js +162 -0
- package/dist/core/rule.js.map +1 -0
- package/dist/core/selector.d.ts +7 -0
- package/dist/core/selector.d.ts.map +1 -0
- package/dist/core/selector.js +27 -0
- package/dist/core/selector.js.map +1 -0
- package/dist/core/structural.d.ts +10 -0
- package/dist/core/structural.d.ts.map +1 -0
- package/dist/core/structural.js +24 -0
- package/dist/core/structural.js.map +1 -0
- package/dist/core/text.d.ts +26 -0
- package/dist/core/text.d.ts.map +1 -0
- package/dist/core/text.js +144 -0
- package/dist/core/text.js.map +1 -0
- package/dist/effect.d.ts +19 -0
- package/dist/effect.d.ts.map +1 -0
- package/dist/effect.js +21 -0
- package/dist/effect.js.map +1 -0
- package/dist/index.d.ts +24 -44
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +59 -52
- package/dist/index.js.map +1 -0
- package/dist/report/agent.d.ts +3 -0
- package/dist/report/agent.d.ts.map +1 -0
- package/dist/report/agent.js +35 -0
- package/dist/report/agent.js.map +1 -0
- package/dist/report/dot.d.ts +4 -0
- package/dist/report/dot.d.ts.map +1 -0
- package/dist/report/dot.js +15 -0
- package/dist/report/dot.js.map +1 -0
- package/dist/report/github.d.ts +3 -0
- package/dist/report/github.d.ts.map +1 -0
- package/dist/report/github.js +18 -0
- package/dist/report/github.js.map +1 -0
- package/dist/report/json.d.ts +3 -0
- package/dist/report/json.d.ts.map +1 -0
- package/dist/report/json.js +4 -0
- package/dist/report/json.js.map +1 -0
- package/dist/report/message.d.ts +20 -0
- package/dist/report/message.d.ts.map +1 -0
- package/dist/report/message.js +73 -0
- package/dist/report/message.js.map +1 -0
- package/dist/report/pretty.d.ts +8 -0
- package/dist/report/pretty.d.ts.map +1 -0
- package/dist/report/pretty.js +89 -0
- package/dist/report/pretty.js.map +1 -0
- package/dist/report/render.d.ts +9 -0
- package/dist/report/render.d.ts.map +1 -0
- package/dist/report/render.js +10 -0
- package/dist/report/render.js.map +1 -0
- package/dist/report/report.d.ts +44 -0
- package/dist/report/report.d.ts.map +1 -0
- package/dist/report/report.js +49 -0
- package/dist/report/report.js.map +1 -0
- package/dist/report/sarif.d.ts +3 -0
- package/dist/report/sarif.d.ts.map +1 -0
- package/dist/report/sarif.js +68 -0
- package/dist/report/sarif.js.map +1 -0
- package/dist/run.d.ts +49 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +87 -0
- package/dist/run.js.map +1 -0
- package/dist/shell/baseline-file.d.ts +20 -0
- package/dist/shell/baseline-file.d.ts.map +1 -0
- package/dist/shell/baseline-file.js +46 -0
- package/dist/shell/baseline-file.js.map +1 -0
- package/dist/shell/load-config.d.ts +19 -0
- package/dist/shell/load-config.d.ts.map +1 -0
- package/dist/shell/load-config.js +39 -0
- package/dist/shell/load-config.js.map +1 -0
- package/package.json +29 -177
- package/skills/archer/SKILL.md +127 -45
- package/skills/archer/agents/openai.yaml +2 -2
- package/skills/archer/references/rules.md +267 -54
- package/dist/bun/plugin.cjs +0 -85
- package/dist/bun/plugin.d.cts +0 -7
- package/dist/bun/plugin.d.ts +0 -7
- package/dist/bun/plugin.js +0 -11
- package/dist/bun.cjs +0 -2238
- package/dist/bun.d.cts +0 -13
- package/dist/bun.d.ts +0 -13
- package/dist/bun.js +0 -28
- package/dist/chunk-2AKMBLHG.js +0 -2165
- package/dist/chunk-67YEOTXP.js +0 -25
- package/dist/chunk-IDVLHNL2.js +0 -46
- package/dist/chunk-ZZ6TR4PO.js +0 -201
- package/dist/cli.js +0 -2643
- package/dist/index.cjs +0 -2484
- package/dist/index.d.cts +0 -45
- package/dist/jest/plugin.cjs +0 -85
- package/dist/jest/plugin.d.cts +0 -7
- package/dist/jest/plugin.d.ts +0 -7
- package/dist/jest/plugin.js +0 -11
- package/dist/jest.cjs +0 -2237
- package/dist/jest.d.cts +0 -13
- package/dist/jest.d.ts +0 -13
- package/dist/jest.js +0 -27
- package/dist/matchers-Cqnbsyxe.d.cts +0 -11
- package/dist/matchers-Cqnbsyxe.d.ts +0 -11
- package/dist/node.cjs +0 -2237
- package/dist/node.d.cts +0 -13
- package/dist/node.d.ts +0 -13
- package/dist/node.js +0 -27
- package/dist/reporters-BbAXMpuW.d.cts +0 -6
- package/dist/reporters-xh-HQneS.d.ts +0 -6
- package/dist/suite-BwnPDCvU.d.cts +0 -337
- package/dist/suite-BwnPDCvU.d.ts +0 -337
- package/dist/vitest/plugin.cjs +0 -85
- package/dist/vitest/plugin.d.cts +0 -7
- package/dist/vitest/plugin.d.ts +0 -7
- package/dist/vitest/plugin.js +0 -11
- package/dist/vitest.cjs +0 -2531
- package/dist/vitest.d.cts +0 -37
- package/dist/vitest.d.ts +0 -37
- package/dist/vitest.js +0 -139
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import type { Applied } from "../core/baseline.ts";
|
|
3
|
+
import { Fingerprint } from "../core/fingerprint.ts";
|
|
4
|
+
import type { Graph } from "../core/model.ts";
|
|
5
|
+
import { Severity, Violation } from "../core/rule.ts";
|
|
6
|
+
/** What reporters need about a rule that the checked policy does not carry. */
|
|
7
|
+
export interface RuleInfo {
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly severity: Severity;
|
|
10
|
+
readonly reason?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const RuleInfo: Schema.Codec<RuleInfo>;
|
|
13
|
+
export interface Report {
|
|
14
|
+
/** Violations the baseline does not accept, in check order (O1). */
|
|
15
|
+
readonly violations: ReadonlyArray<Violation>;
|
|
16
|
+
readonly suppressed: number;
|
|
17
|
+
readonly stale: ReadonlyArray<Fingerprint>;
|
|
18
|
+
readonly emptySubjects: ReadonlyArray<string>;
|
|
19
|
+
/** Dependency rules whose object names files by a glob but selects none: usually a mistyped path. */
|
|
20
|
+
readonly emptyObjects: ReadonlyArray<string>;
|
|
21
|
+
readonly rules: ReadonlyArray<RuleInfo>;
|
|
22
|
+
readonly counts: {
|
|
23
|
+
readonly error: number;
|
|
24
|
+
readonly warning: number;
|
|
25
|
+
readonly info: number;
|
|
26
|
+
};
|
|
27
|
+
readonly stats: {
|
|
28
|
+
readonly files: number;
|
|
29
|
+
readonly dependencies: number;
|
|
30
|
+
};
|
|
31
|
+
readonly verdict: "pass" | "fail";
|
|
32
|
+
}
|
|
33
|
+
export declare const Report: Schema.Codec<Report>;
|
|
34
|
+
/** Port of `Archer.Spec.fails`. */
|
|
35
|
+
export declare const fails: (failOnWarnings: boolean, kept: ReadonlyArray<Violation>) => boolean;
|
|
36
|
+
export declare const makeReport: (input: {
|
|
37
|
+
readonly applied: Applied;
|
|
38
|
+
readonly emptySubjects: ReadonlyArray<string>;
|
|
39
|
+
readonly emptyObjects: ReadonlyArray<string>;
|
|
40
|
+
readonly rules: ReadonlyArray<RuleInfo>;
|
|
41
|
+
readonly graph: Graph;
|
|
42
|
+
readonly failOnWarnings: boolean;
|
|
43
|
+
}) => Report;
|
|
44
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/report/report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC/B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAErD,+EAA+E;AAC/E,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAI1C,CAAA;AAEF,MAAM,WAAW,MAAM;IACrB,oEAAoE;IACpE,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,CAAA;IAC1C,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC7C,qGAAqG;IACrG,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC5C,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5F,QAAQ,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAA;IACzE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;CAClC;AAED,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAkBtC,CAAA;AAEF,mCAAmC;AACnC,eAAO,MAAM,KAAK,mBAAoB,OAAO,QAAQ,aAAa,CAAC,SAAS,CAAC,KAAG,OACkC,CAAA;AAKlH,eAAO,MAAM,UAAU,UAAW;IAChC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC7C,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IAC5C,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAA;IACvC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAA;CACjC,KAAG,MAiBF,CAAA"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import { Fingerprint } from "../core/fingerprint.js";
|
|
3
|
+
import { Severity, Violation } from "../core/rule.js";
|
|
4
|
+
export const RuleInfo = Schema.Struct({
|
|
5
|
+
id: Schema.String,
|
|
6
|
+
severity: Severity,
|
|
7
|
+
reason: Schema.optionalKey(Schema.String),
|
|
8
|
+
});
|
|
9
|
+
export const Report = Schema.Struct({
|
|
10
|
+
/** Violations the baseline does not accept, in check order (O1). */
|
|
11
|
+
violations: Schema.Array(Violation),
|
|
12
|
+
suppressed: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
13
|
+
stale: Schema.Array(Fingerprint),
|
|
14
|
+
emptySubjects: Schema.Array(Schema.String),
|
|
15
|
+
emptyObjects: Schema.Array(Schema.String),
|
|
16
|
+
rules: Schema.Array(RuleInfo),
|
|
17
|
+
counts: Schema.Struct({
|
|
18
|
+
error: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
19
|
+
warning: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
20
|
+
info: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
21
|
+
}),
|
|
22
|
+
stats: Schema.Struct({
|
|
23
|
+
files: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
24
|
+
dependencies: Schema.Int.check(Schema.isGreaterThanOrEqualTo(0)),
|
|
25
|
+
}),
|
|
26
|
+
verdict: Schema.Literals(["pass", "fail"]),
|
|
27
|
+
});
|
|
28
|
+
/** Port of `Archer.Spec.fails`. */
|
|
29
|
+
export const fails = (failOnWarnings, kept) => kept.some((violation) => violation.severity === "error" || (failOnWarnings && violation.severity === "warning"));
|
|
30
|
+
const count = (violations, severity) => violations.filter((violation) => violation.severity === severity).length;
|
|
31
|
+
export const makeReport = (input) => ({
|
|
32
|
+
violations: input.applied.kept,
|
|
33
|
+
suppressed: input.applied.suppressed.length,
|
|
34
|
+
stale: input.applied.stale,
|
|
35
|
+
emptySubjects: input.emptySubjects,
|
|
36
|
+
emptyObjects: input.emptyObjects,
|
|
37
|
+
rules: input.rules,
|
|
38
|
+
counts: {
|
|
39
|
+
error: count(input.applied.kept, "error"),
|
|
40
|
+
warning: count(input.applied.kept, "warning"),
|
|
41
|
+
info: count(input.applied.kept, "info"),
|
|
42
|
+
},
|
|
43
|
+
stats: {
|
|
44
|
+
files: input.graph.files.length,
|
|
45
|
+
dependencies: input.graph.files.reduce((total, file) => total + file.dependencies.length, 0),
|
|
46
|
+
},
|
|
47
|
+
verdict: fails(input.failOnWarnings, input.applied.kept) ? "fail" : "pass",
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/report/report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif.d.ts","sourceRoot":"","sources":["../../src/report/sarif.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAiDzC,eAAO,MAAM,KAAK,WAAY,MAAM,KAAG,MAkDtC,CAAA"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Match } from "effect";
|
|
2
|
+
import { encode, fingerprint } from "../core/fingerprint.js";
|
|
3
|
+
import { describe, importText, pathText, standalone } from "./message.js";
|
|
4
|
+
const level = (severity) => Match.value(severity).pipe(Match.when("error", () => "error"), Match.when("warning", () => "warning"), Match.when("info", () => "note"), Match.exhaustive);
|
|
5
|
+
const physicalLocation = (path, region) => ({
|
|
6
|
+
artifactLocation: { uri: path, uriBaseId: "%SRCROOT%" },
|
|
7
|
+
...(region === undefined ? {} : { region: { startLine: region.line, startColumn: region.column } }),
|
|
8
|
+
});
|
|
9
|
+
const codeFlows = (edges) => edges.length === 0
|
|
10
|
+
? []
|
|
11
|
+
: [
|
|
12
|
+
{
|
|
13
|
+
threadFlows: [
|
|
14
|
+
{
|
|
15
|
+
locations: edges.map((edge) => ({
|
|
16
|
+
location: {
|
|
17
|
+
physicalLocation: physicalLocation(pathText(edge.source), edge.dependency.location),
|
|
18
|
+
message: { text: importText(edge) },
|
|
19
|
+
},
|
|
20
|
+
})),
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
];
|
|
25
|
+
export const sarif = (report) => {
|
|
26
|
+
const results = report.violations.map((violation) => {
|
|
27
|
+
const description = describe(violation, report.rules);
|
|
28
|
+
const { location } = description;
|
|
29
|
+
const ruleIndex = report.rules.findIndex((rule) => rule.id === violation.ruleId);
|
|
30
|
+
const flows = Match.value(violation.evidence).pipe(Match.tag("Walk", "Cycle", ({ edges }) => codeFlows(edges)), Match.orElse(() => []));
|
|
31
|
+
return {
|
|
32
|
+
ruleId: violation.ruleId,
|
|
33
|
+
...(ruleIndex < 0 ? {} : { ruleIndex }),
|
|
34
|
+
level: level(violation.severity),
|
|
35
|
+
message: { text: standalone(violation, description) },
|
|
36
|
+
locations: [
|
|
37
|
+
{
|
|
38
|
+
physicalLocation: location === undefined
|
|
39
|
+
? physicalLocation(pathText(violation.subject))
|
|
40
|
+
: physicalLocation(location.path, location),
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
partialFingerprints: { archer: encode(fingerprint(violation)) },
|
|
44
|
+
...(flows.length === 0 ? {} : { codeFlows: flows }),
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
return JSON.stringify({
|
|
48
|
+
$schema: "https://json.schemastore.org/sarif-2.1.0.json",
|
|
49
|
+
version: "2.1.0",
|
|
50
|
+
runs: [
|
|
51
|
+
{
|
|
52
|
+
tool: {
|
|
53
|
+
driver: {
|
|
54
|
+
name: "Archer",
|
|
55
|
+
informationUri: "https://github.com/lucasacoutinho/archer",
|
|
56
|
+
rules: report.rules.map((rule) => ({
|
|
57
|
+
id: rule.id,
|
|
58
|
+
shortDescription: { text: rule.reason ?? rule.id },
|
|
59
|
+
defaultConfiguration: { level: level(rule.severity) },
|
|
60
|
+
})),
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
results,
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
}, undefined, 2);
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=sarif.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sarif.js","sourceRoot":"","sources":["../../src/report/sarif.ts"],"names":[],"mappings":"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"}
|
package/dist/run.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Effect, FileSystem, Path, Result, Schema } from "effect";
|
|
2
|
+
import { Analyzer } from "./analyzer/Analyzer.ts";
|
|
3
|
+
import type { AnalysisError } from "./analyzer/errors.ts";
|
|
4
|
+
import { ConfigError } from "./core/config.ts";
|
|
5
|
+
import type { Graph } from "./core/model.ts";
|
|
6
|
+
import { type ArcherConfig, ConfigInvalid } from "./config/input.ts";
|
|
7
|
+
import { type Report } from "./report/report.ts";
|
|
8
|
+
import { type BaselineError } from "./shell/baseline-file.ts";
|
|
9
|
+
import { type ConfigLoadError } from "./shell/load-config.ts";
|
|
10
|
+
export type BaselineMode = "apply" | "ignore" | "record" | "prune";
|
|
11
|
+
export interface RunOptions {
|
|
12
|
+
/** A configuration, or the path of a configuration file. Without it, the first `archer.config.*` in `cwd`. */
|
|
13
|
+
readonly config?: ArcherConfig | string;
|
|
14
|
+
readonly cwd?: string;
|
|
15
|
+
readonly baseline?: BaselineMode;
|
|
16
|
+
}
|
|
17
|
+
export interface RunResult {
|
|
18
|
+
readonly report: Report;
|
|
19
|
+
readonly graph: Graph;
|
|
20
|
+
readonly root: string;
|
|
21
|
+
}
|
|
22
|
+
declare const ConfigNotFound_base: Schema.Class<ConfigNotFound, Schema.TaggedStruct<"ConfigNotFound", {
|
|
23
|
+
readonly searched: Schema.$Array<Schema.String>;
|
|
24
|
+
}>, import("effect/Cause").YieldableError & {
|
|
25
|
+
readonly brand: unique symbol;
|
|
26
|
+
}>;
|
|
27
|
+
export declare class ConfigNotFound extends ConfigNotFound_base {
|
|
28
|
+
}
|
|
29
|
+
declare const ConfigRejected_base: Schema.Class<ConfigRejected, Schema.TaggedStruct<"ConfigRejected", {
|
|
30
|
+
readonly error: Schema.Codec<ConfigError, ConfigError, never, never>;
|
|
31
|
+
}>, import("effect/Cause").YieldableError & {
|
|
32
|
+
readonly brand: unique symbol;
|
|
33
|
+
}>;
|
|
34
|
+
export declare class ConfigRejected extends ConfigRejected_base {
|
|
35
|
+
}
|
|
36
|
+
export type RunError = ConfigNotFound | ConfigLoadError | ConfigInvalid | ConfigRejected | AnalysisError | BaselineError;
|
|
37
|
+
export interface WorkspaceLocation {
|
|
38
|
+
/** The directory the analysis reads. */
|
|
39
|
+
readonly root: string;
|
|
40
|
+
/** The configuration file, when the configuration came from one. */
|
|
41
|
+
readonly configFile: string | undefined;
|
|
42
|
+
}
|
|
43
|
+
/** Where a run would analyze, without analyzing: what a watcher needs to watch. */
|
|
44
|
+
export declare const locateWorkspace: (options: RunOptions) => Effect.Effect<WorkspaceLocation, ConfigNotFound | ConfigLoadError | ConfigInvalid, FileSystem.FileSystem | Path.Path>;
|
|
45
|
+
/** Decode, lower, and check: the pure part of a run, for a graph built by the caller. */
|
|
46
|
+
export declare const checkGraph: (input: ArcherConfig, graph: Graph) => Result.Result<Report, ConfigInvalid | ConfigRejected>;
|
|
47
|
+
export declare const run: (options?: RunOptions) => Effect.Effect<RunResult, RunError, Analyzer | FileSystem.FileSystem | Path.Path>;
|
|
48
|
+
export {};
|
|
49
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAS,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGzD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,KAAK,EAAY,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAGtD,OAAO,EAAE,KAAK,YAAY,EAAsB,aAAa,EAAuB,MAAM,mBAAmB,CAAA;AAC7G,OAAO,EAAc,KAAK,MAAM,EAAiB,MAAM,oBAAoB,CAAA;AAC3E,OAAO,EAAE,KAAK,aAAa,EAA+B,MAAM,0BAA0B,CAAA;AAC1F,OAAO,EAAmB,KAAK,eAAe,EAAgB,MAAM,wBAAwB,CAAA;AAE5F,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAA;AAElE,MAAM,WAAW,UAAU;IACzB,8GAA8G;IAC9G,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,CAAA;IACvC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAA;CACjC;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;;;;oBAEwF,OAAO,MAAM;;AAAtG,qBAAa,cAAe,SAAQ,mBAGnC;CAAG;;;;oBAEqF,OAAO,MAAM;;AAAtG,qBAAa,cAAe,SAAQ,mBAGnC;CAAG;AAEJ,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG,eAAe,GAAG,aAAa,GAAG,cAAc,GAAG,aAAa,GAAG,aAAa,CAAA;AAoCxH,MAAM,WAAW,iBAAiB;IAChC,wCAAwC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,oEAAoE;IACpE,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;CACxC;AAED,mFAAmF;AACnF,eAAO,MAAM,eAAe,EAAE,CAC5B,OAAO,EAAE,UAAU,KAChB,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,cAAc,GAAG,eAAe,GAAG,aAAa,EAAE,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAKrH,CAAA;AAeJ,yFAAyF;AACzF,eAAO,MAAM,UAAU,UACd,YAAY,SACZ,KAAK,KACX,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,cAAc,CAcpD,CAAA;AAEH,eAAO,MAAM,GAAG,EAAE,CAChB,OAAO,CAAC,EAAE,UAAU,KACjB,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAuClF,CAAA"}
|
package/dist/run.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { Effect, FileSystem, Match, Path, Result, Schema } from "effect";
|
|
2
|
+
import { Analyzer } from "./analyzer/Analyzer.js";
|
|
3
|
+
import { apply, record } from "./core/baseline.js";
|
|
4
|
+
import { check, emptyObjects, emptySubjects } from "./core/check.js";
|
|
5
|
+
import { ConfigError } from "./core/config.js";
|
|
6
|
+
import { structuralKey } from "./core/structural.js";
|
|
7
|
+
import { lower } from "./core/lower.js";
|
|
8
|
+
import { ConfigInvalid, decodeConfiguration } from "./config/input.js";
|
|
9
|
+
import { makeReport } from "./report/report.js";
|
|
10
|
+
import { readBaseline, writeBaseline } from "./shell/baseline-file.js";
|
|
11
|
+
import { configFileNames, importConfig } from "./shell/load-config.js";
|
|
12
|
+
export class ConfigNotFound extends Schema.TaggedError()("ConfigNotFound", { searched: Schema.Array(Schema.String) }) {
|
|
13
|
+
}
|
|
14
|
+
export class ConfigRejected extends Schema.TaggedError()("ConfigRejected", { error: ConfigError }) {
|
|
15
|
+
}
|
|
16
|
+
const locate = Effect.fn("locateConfig")(function* (cwd, config) {
|
|
17
|
+
const fs = yield* FileSystem.FileSystem;
|
|
18
|
+
const path = yield* Path.Path;
|
|
19
|
+
const candidates = config === undefined ? configFileNames.map((name) => path.join(cwd, name)) : [path.resolve(cwd, config)];
|
|
20
|
+
for (const candidate of candidates) {
|
|
21
|
+
if (yield* fs.exists(candidate).pipe(Effect.orElseSucceed(() => false))) {
|
|
22
|
+
return candidate;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return yield* new ConfigNotFound({ searched: candidates });
|
|
26
|
+
});
|
|
27
|
+
const load = Effect.fn("loadConfig")(function* (options) {
|
|
28
|
+
const path = yield* Path.Path;
|
|
29
|
+
const cwd = path.resolve(options.cwd ?? ".");
|
|
30
|
+
if (typeof options.config === "object") {
|
|
31
|
+
return { configuration: yield* decode(options.config), base: cwd, file: undefined };
|
|
32
|
+
}
|
|
33
|
+
const file = yield* locate(cwd, options.config);
|
|
34
|
+
return { configuration: yield* decode(yield* importConfig(file)), base: path.dirname(file), file };
|
|
35
|
+
});
|
|
36
|
+
/** Where a run would analyze, without analyzing: what a watcher needs to watch. */
|
|
37
|
+
export const locateWorkspace = Effect.fn("locateWorkspace")(function* (options) {
|
|
38
|
+
const path = yield* Path.Path;
|
|
39
|
+
const { configuration, base, file } = yield* load(options);
|
|
40
|
+
return { root: path.resolve(base, configuration.root), configFile: file };
|
|
41
|
+
});
|
|
42
|
+
const decode = (input) => Effect.fromResult(decodeConfiguration(input));
|
|
43
|
+
const customRules = (configuration) => (name, graph, subject) => configuration.custom.get(name)?.({ graph, subject: subject.join("/") }) ?? [];
|
|
44
|
+
/** User rules carry their reason; layer and public-API rules come from lowering. */
|
|
45
|
+
const ruleInfo = (configuration, policy) => {
|
|
46
|
+
const described = new Map(configuration.rules.map((rule) => [rule.id, rule]));
|
|
47
|
+
return policy.map((rule) => described.get(rule.id) ?? { id: rule.id, severity: rule.severity });
|
|
48
|
+
};
|
|
49
|
+
/** Decode, lower, and check: the pure part of a run, for a graph built by the caller. */
|
|
50
|
+
export const checkGraph = (input, graph) => Result.flatMap(decodeConfiguration(input), (configuration) => Result.mapBoth(lower(configuration.config), {
|
|
51
|
+
onFailure: (error) => new ConfigRejected({ error }),
|
|
52
|
+
onSuccess: (policy) => makeReport({
|
|
53
|
+
applied: apply([], check(customRules(configuration), policy, graph)),
|
|
54
|
+
emptySubjects: emptySubjects(policy, graph),
|
|
55
|
+
emptyObjects: emptyObjects(policy, graph),
|
|
56
|
+
rules: ruleInfo(configuration, policy),
|
|
57
|
+
graph,
|
|
58
|
+
failOnWarnings: configuration.failOnWarnings,
|
|
59
|
+
}),
|
|
60
|
+
}));
|
|
61
|
+
export const run = Effect.fn("run")(function* (options = {}) {
|
|
62
|
+
const path = yield* Path.Path;
|
|
63
|
+
const analyzer = yield* Analyzer;
|
|
64
|
+
const { configuration, base } = yield* load(options);
|
|
65
|
+
const policy = yield* Effect.fromResult(lower(configuration.config)).pipe(Effect.mapError((error) => new ConfigRejected({ error })));
|
|
66
|
+
const root = path.resolve(base, configuration.root);
|
|
67
|
+
const graph = yield* analyzer.analyze({ root, projects: configuration.projects });
|
|
68
|
+
const violations = check(customRules(configuration), policy, graph);
|
|
69
|
+
const baselineFile = configuration.baseline === undefined ? undefined : path.resolve(root, configuration.baseline);
|
|
70
|
+
const current = record(violations);
|
|
71
|
+
const baseline = baselineFile === undefined
|
|
72
|
+
? []
|
|
73
|
+
: yield* Match.value(options.baseline ?? "apply").pipe(Match.when("ignore", () => Effect.succeed([])), Match.when("apply", () => readBaseline(baselineFile)), Match.when("record", () => writeBaseline(baselineFile, current).pipe(Effect.as(current))), Match.when("prune", () => readBaseline(baselineFile).pipe(Effect.map((stored) => {
|
|
74
|
+
const live = new Set(current.map(structuralKey));
|
|
75
|
+
return stored.filter((entry) => live.has(structuralKey(entry)));
|
|
76
|
+
}), Effect.tap((kept) => writeBaseline(baselineFile, kept)))), Match.exhaustive);
|
|
77
|
+
const report = makeReport({
|
|
78
|
+
applied: apply(baseline, violations),
|
|
79
|
+
emptySubjects: emptySubjects(policy, graph),
|
|
80
|
+
emptyObjects: emptyObjects(policy, graph),
|
|
81
|
+
rules: ruleInfo(configuration, policy),
|
|
82
|
+
graph,
|
|
83
|
+
failOnWarnings: configuration.failOnWarnings,
|
|
84
|
+
});
|
|
85
|
+
return { report, graph, root };
|
|
86
|
+
});
|
|
87
|
+
//# sourceMappingURL=run.js.map
|
package/dist/run.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAEjD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAGpD,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAyC,aAAa,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAA;AAC7G,OAAO,EAAE,UAAU,EAA8B,MAAM,oBAAoB,CAAA;AAC3E,OAAO,EAAsB,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC1F,OAAO,EAAE,eAAe,EAAwB,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAiB5F,MAAM,OAAO,cAAe,SAAQ,MAAM,CAAC,WAAW,EAAqD,CACzG,gBAAgB,EAChB,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAC1C;CAAG;AAEJ,MAAM,OAAO,cAAe,SAAQ,MAAM,CAAC,WAAW,EAAqD,CACzG,gBAAgB,EAChB,EAAE,KAAK,EAAE,WAAW,EAAE,CACvB;CAAG;AAIJ,MAAM,MAAM,GAGoE,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,EAAE,GAAW,EAAE,MAA0B;IAC1J,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAA;IACvC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAA;IAC7B,MAAM,UAAU,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAA;IAC3H,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACxE,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,IAAI,cAAc,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAA;AAC5D,CAAC,CAAC,CAAA;AAQF,MAAM,IAAI,GAGR,MAAM,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAmB;IACtD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAA;IAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAA;IAC5C,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;IACrF,CAAC;IACD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IAC/C,OAAO,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAA;AACpG,CAAC,CAAC,CAAA;AASF,mFAAmF;AACnF,MAAM,CAAC,MAAM,eAAe,GAG1B,MAAM,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAmB;IACzD,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAA;IAC7B,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC1D,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAA;AAC3E,CAAC,CAAC,CAAA;AAEJ,MAAM,MAAM,GAAG,CAAC,KAAc,EAA+C,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAA;AAE7H,MAAM,WAAW,GACf,CAAC,aAA4B,EAAe,EAAE,CAC9C,CAAC,IAAY,EAAE,KAAY,EAAE,OAAiB,EAAyB,EAAE,CACvE,aAAa,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAA;AAEjF,oFAAoF;AACpF,MAAM,QAAQ,GAAG,CAAC,aAA4B,EAAE,MAAc,EAAmB,EAAE;IACjF,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;IAC7E,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAA;AACjG,CAAC,CAAA;AAED,yFAAyF;AACzF,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,KAAmB,EACnB,KAAY,EAC2C,EAAE,CACzD,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC,aAAa,EAAE,EAAE,CAC3D,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE;IAC1C,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC;IACnD,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CACpB,UAAU,CAAC;QACT,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QACpE,aAAa,EAAE,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC;QAC3C,YAAY,EAAE,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC;QACzC,KAAK,EAAE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QACtC,KAAK;QACL,cAAc,EAAE,aAAa,CAAC,cAAc;KAC7C,CAAC;CACL,CAAC,CACH,CAAA;AAEH,MAAM,CAAC,MAAM,GAAG,GAEwE,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAe,EAAE;IAC1I,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAA;IAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAA;IAChC,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACpD,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CACvE,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAC1D,CAAA;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,CAAA;IACnD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAA;IACjF,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;IACnE,MAAM,YAAY,GAAG,aAAa,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAA;IAClH,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,CAAA;IAClC,MAAM,QAAQ,GACZ,YAAY,KAAK,SAAS;QACxB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,IAAI,CAClD,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAC9C,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,EACrD,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EACzF,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CACvB,YAAY,CAAC,YAAY,CAAC,CAAC,IAAI,CAC7B,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YACpB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAA;YAChD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;QACjE,CAAC,CAAC,EACF,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,CACxD,CACF,EACD,KAAK,CAAC,UAAU,CACjB,CAAA;IACP,MAAM,MAAM,GAAG,UAAU,CAAC;QACxB,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,UAAU,CAAC;QACpC,aAAa,EAAE,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC;QAC3C,YAAY,EAAE,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC;QACzC,KAAK,EAAE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QACtC,KAAK;QACL,cAAc,EAAE,aAAa,CAAC,cAAc;KAC7C,CAAC,CAAA;IACF,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAsB,CAAA;AACpD,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Effect, FileSystem, Path, Schema } from "effect";
|
|
2
|
+
import { type Fingerprint } from "../core/fingerprint.ts";
|
|
3
|
+
export declare const header: string;
|
|
4
|
+
declare const BaselineError_base: Schema.Class<BaselineError, Schema.TaggedStruct<"BaselineError", {
|
|
5
|
+
readonly path: Schema.String;
|
|
6
|
+
readonly reason: Schema.Literals<readonly ["Unreadable", "UnsupportedHeader", "MalformedLine", "Unwritable"]>;
|
|
7
|
+
readonly line: Schema.optionalKey<Schema.Int>;
|
|
8
|
+
}>, import("effect/Cause").YieldableError & {
|
|
9
|
+
readonly brand: unique symbol;
|
|
10
|
+
}>;
|
|
11
|
+
export declare class BaselineError extends BaselineError_base {
|
|
12
|
+
}
|
|
13
|
+
export declare const parseBaseline: (path: string, text: string) => Effect.Effect<Array<Fingerprint>, BaselineError>;
|
|
14
|
+
export declare const formatBaseline: (entries: ReadonlyArray<Fingerprint>) => string;
|
|
15
|
+
/** A missing file is an empty baseline, so a project can adopt Archer before recording one. */
|
|
16
|
+
export declare const readBaseline: (path: string) => Effect.Effect<Array<Fingerprint>, BaselineError, FileSystem.FileSystem>;
|
|
17
|
+
/** Writes through a sibling temporary file and a rename, so a reader never sees half a baseline. */
|
|
18
|
+
export declare const writeBaseline: (path: string, entries: ReadonlyArray<Fingerprint>) => Effect.Effect<void, BaselineError, FileSystem.FileSystem | Path.Path>;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=baseline-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline-file.d.ts","sourceRoot":"","sources":["../../src/shell/baseline-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAU,IAAI,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACjE,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,wBAAwB,CAAA;AAEzE,eAAO,MAAM,MAAM,EAAE,MAA4B,CAAA;;;;;;oBAEsC,OAAO,MAAM;;AAApG,qBAAa,aAAc,SAAQ,kBAIjC;CAAG;AAEL,eAAO,MAAM,aAAa,SAAU,MAAM,QAAQ,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,aAAa,CAiBzG,CAAA;AAED,eAAO,MAAM,cAAc,YAAa,aAAa,CAAC,WAAW,CAAC,KAAG,MACjB,CAAA;AAEpD,+FAA+F;AAC/F,eAAO,MAAM,YAAY,EAAE,CACzB,IAAI,EAAE,MAAM,KACT,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,aAAa,EAAE,UAAU,CAAC,UAAU,CAQzE,CAAA;AAEF,oGAAoG;AACpG,eAAO,MAAM,aAAa,EAAE,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,aAAa,CAAC,WAAW,CAAC,KAChC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,aAAa,EAAE,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CASvE,CAAA"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Effect, FileSystem, Option, Path, Schema } from "effect";
|
|
2
|
+
import { decode, encode } from "../core/fingerprint.js";
|
|
3
|
+
export const header = "archer-baseline 1";
|
|
4
|
+
export class BaselineError extends Schema.TaggedError()("BaselineError", {
|
|
5
|
+
path: Schema.String,
|
|
6
|
+
reason: Schema.Literals(["Unreadable", "UnsupportedHeader", "MalformedLine", "Unwritable"]),
|
|
7
|
+
line: Schema.optionalKey(Schema.Int),
|
|
8
|
+
}) {
|
|
9
|
+
}
|
|
10
|
+
export const parseBaseline = (path, text) => {
|
|
11
|
+
const [first, ...rest] = text.split("\n");
|
|
12
|
+
if (first !== header) {
|
|
13
|
+
return Effect.fail(new BaselineError({ path, reason: "UnsupportedHeader", line: 1 }));
|
|
14
|
+
}
|
|
15
|
+
const entries = [];
|
|
16
|
+
for (const [index, line] of rest.entries()) {
|
|
17
|
+
if (line === "") {
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const entry = decode(line);
|
|
21
|
+
if (Option.isNone(entry)) {
|
|
22
|
+
return Effect.fail(new BaselineError({ path, reason: "MalformedLine", line: index + 2 }));
|
|
23
|
+
}
|
|
24
|
+
entries.push(entry.value);
|
|
25
|
+
}
|
|
26
|
+
return Effect.succeed(entries);
|
|
27
|
+
};
|
|
28
|
+
export const formatBaseline = (entries) => [header, ...entries.map(encode)].join("\n") + "\n";
|
|
29
|
+
/** A missing file is an empty baseline, so a project can adopt Archer before recording one. */
|
|
30
|
+
export const readBaseline = Effect.fn("readBaseline")(function* (path) {
|
|
31
|
+
const fs = yield* FileSystem.FileSystem;
|
|
32
|
+
const exists = yield* fs.exists(path).pipe(Effect.mapError(() => new BaselineError({ path, reason: "Unreadable" })));
|
|
33
|
+
if (!exists) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
const text = yield* fs.readFileString(path).pipe(Effect.mapError(() => new BaselineError({ path, reason: "Unreadable" })));
|
|
37
|
+
return yield* parseBaseline(path, text);
|
|
38
|
+
});
|
|
39
|
+
/** Writes through a sibling temporary file and a rename, so a reader never sees half a baseline. */
|
|
40
|
+
export const writeBaseline = Effect.fn("writeBaseline")(function* (path, entries) {
|
|
41
|
+
const fs = yield* FileSystem.FileSystem;
|
|
42
|
+
const paths = yield* Path.Path;
|
|
43
|
+
const temporary = paths.join(paths.dirname(path), `.${paths.basename(path)}.tmp`);
|
|
44
|
+
yield* fs.makeDirectory(paths.dirname(path), { recursive: true }).pipe(Effect.andThen(fs.writeFileString(temporary, formatBaseline(entries))), Effect.andThen(fs.rename(temporary, path)), Effect.mapError(() => new BaselineError({ path, reason: "Unwritable" })));
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=baseline-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline-file.js","sourceRoot":"","sources":["../../src/shell/baseline-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Effect, Schema } from "effect";
|
|
2
|
+
declare const ConfigLoadError_base: Schema.Class<ConfigLoadError, Schema.TaggedStruct<"ConfigLoadError", {
|
|
3
|
+
readonly path: Schema.String;
|
|
4
|
+
readonly cause: Schema.Defect;
|
|
5
|
+
}>, import("effect/Cause").YieldableError & {
|
|
6
|
+
readonly brand: unique symbol;
|
|
7
|
+
}>;
|
|
8
|
+
export declare class ConfigLoadError extends ConfigLoadError_base {
|
|
9
|
+
}
|
|
10
|
+
export declare const configFileNames: ReadonlyArray<string>;
|
|
11
|
+
/**
|
|
12
|
+
* A changed configuration file loads as a new module instance, so a watcher
|
|
13
|
+
* sees its edits. Node never frees a module instance, so an unchanged file
|
|
14
|
+
* reuses the last one instead of leaking a copy per call. Modules the
|
|
15
|
+
* configuration imports stay cached by Node.
|
|
16
|
+
*/
|
|
17
|
+
export declare const importConfig: (absolutePath: string) => Effect.Effect<unknown, ConfigLoadError>;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=load-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-config.d.ts","sourceRoot":"","sources":["../../src/shell/load-config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;;;;;oBAEoD,OAAO,MAAM;;AAAxG,qBAAa,eAAgB,SAAQ,oBAGpC;CAAG;AAEJ,eAAO,MAAM,eAAe,EAAE,aAAa,CAAC,MAAM,CAAsF,CAAA;AAWxI;;;;;GAKG;AACH,eAAO,MAAM,YAAY,iBAAkB,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,eAAe,CAgBtF,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
2
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
3
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
4
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
5
|
+
});
|
|
6
|
+
}
|
|
7
|
+
return path;
|
|
8
|
+
};
|
|
9
|
+
import { readFile } from "node:fs/promises";
|
|
10
|
+
import { pathToFileURL } from "node:url";
|
|
11
|
+
import { Effect, Schema } from "effect";
|
|
12
|
+
export class ConfigLoadError extends Schema.TaggedError()("ConfigLoadError", { path: Schema.String, cause: Schema.Defect() }) {
|
|
13
|
+
}
|
|
14
|
+
export const configFileNames = ["archer.config.ts", "archer.config.mts", "archer.config.js", "archer.config.mjs"];
|
|
15
|
+
let generation = 0;
|
|
16
|
+
const loaded = new Map();
|
|
17
|
+
/**
|
|
18
|
+
* A changed configuration file loads as a new module instance, so a watcher
|
|
19
|
+
* sees its edits. Node never frees a module instance, so an unchanged file
|
|
20
|
+
* reuses the last one instead of leaking a copy per call. Modules the
|
|
21
|
+
* configuration imports stay cached by Node.
|
|
22
|
+
*/
|
|
23
|
+
export const importConfig = (absolutePath) => Effect.tryPromise({
|
|
24
|
+
try: async () => {
|
|
25
|
+
const source = await readFile(absolutePath, "utf8");
|
|
26
|
+
const previous = loaded.get(absolutePath);
|
|
27
|
+
if (previous !== undefined && previous.source === source) {
|
|
28
|
+
return previous.value;
|
|
29
|
+
}
|
|
30
|
+
generation += 1;
|
|
31
|
+
const url = new URL(pathToFileURL(absolutePath));
|
|
32
|
+
url.searchParams.set("archer", String(generation));
|
|
33
|
+
const module = await import(__rewriteRelativeImportExtension(url.href));
|
|
34
|
+
loaded.set(absolutePath, { source, value: module.default });
|
|
35
|
+
return module.default;
|
|
36
|
+
},
|
|
37
|
+
catch: (cause) => new ConfigLoadError({ path: absolutePath, cause }),
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=load-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-config.js","sourceRoot":"","sources":["../../src/shell/load-config.ts"],"names":[],"mappings":";;;;;;;;AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEvC,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,WAAW,EAAsD,CAC3G,iBAAiB,EACjB,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,CAChD;CAAG;AAEJ,MAAM,CAAC,MAAM,eAAe,GAA0B,CAAC,kBAAkB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,CAAC,CAAA;AAOxI,IAAI,UAAU,GAAW,CAAC,CAAA;AAE1B,MAAM,MAAM,GAAwB,IAAI,GAAG,EAAkB,CAAA;AAE7D;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,YAAoB,EAA2C,EAAE,CAC5F,MAAM,CAAC,UAAU,CAAC;IAChB,GAAG,EAAE,KAAK,IAAsB,EAAE;QAChC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAA;QACnD,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QACzC,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YACzD,OAAO,QAAQ,CAAC,KAAK,CAAA;QACvB,CAAC;QACD,UAAU,IAAI,CAAC,CAAA;QACf,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,CAAA;QAChD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAA;QAClD,MAAM,MAAM,GAAmC,MAAM,MAAM,kCAAC,GAAG,CAAC,IAAI,EAAC,CAAA;QACrE,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAA;QAC3D,OAAO,MAAM,CAAC,OAAO,CAAA;IACvB,CAAC;IACD,KAAK,EAAE,CAAC,KAAc,EAAmB,EAAE,CAAC,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;CAC/F,CAAC,CAAA"}
|