@goodbones/campaigns 0.1.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/LICENSE +21 -0
- package/build/dts/core/campaign-state.d.ts +38 -0
- package/build/dts/core/campaign-state.d.ts.map +1 -0
- package/build/dts/core/campaigns.d.ts +196 -0
- package/build/dts/core/campaigns.d.ts.map +1 -0
- package/build/dts/core/ledger.d.ts +173 -0
- package/build/dts/core/ledger.d.ts.map +1 -0
- package/build/dts/core/phases.d.ts +26 -0
- package/build/dts/core/phases.d.ts.map +1 -0
- package/build/dts/core/sectors.d.ts +52 -0
- package/build/dts/core/sectors.d.ts.map +1 -0
- package/build/dts/domain/config.d.ts +985 -0
- package/build/dts/domain/config.d.ts.map +1 -0
- package/build/dts/domain/report.d.ts +16 -0
- package/build/dts/domain/report.d.ts.map +1 -0
- package/build/dts/host/campaigns.d.ts +195 -0
- package/build/dts/host/campaigns.d.ts.map +1 -0
- package/build/dts/host/diff.d.ts +31 -0
- package/build/dts/host/diff.d.ts.map +1 -0
- package/build/dts/index.d.ts +17 -0
- package/build/dts/index.d.ts.map +1 -0
- package/build/dts/infrastructure/campaign-functions.d.ts +7 -0
- package/build/dts/infrastructure/campaign-functions.d.ts.map +1 -0
- package/build/dts/infrastructure/report-source-fake.d.ts +4 -0
- package/build/dts/infrastructure/report-source-fake.d.ts.map +1 -0
- package/build/dts/infrastructure/report-source-live.d.ts +3 -0
- package/build/dts/infrastructure/report-source-live.d.ts.map +1 -0
- package/build/dts/load/decode.d.ts +7 -0
- package/build/dts/load/decode.d.ts.map +1 -0
- package/build/dts/load/extension.d.ts +25 -0
- package/build/dts/load/extension.d.ts.map +1 -0
- package/build/dts/manifest/lower.d.ts +14 -0
- package/build/dts/manifest/lower.d.ts.map +1 -0
- package/build/dts/manifest/spec.d.ts +515 -0
- package/build/dts/manifest/spec.d.ts.map +1 -0
- package/build/dts/ports/campaign-predicate.d.ts +23 -0
- package/build/dts/ports/campaign-predicate.d.ts.map +1 -0
- package/build/dts/ports/report-source.d.ts +14 -0
- package/build/dts/ports/report-source.d.ts.map +1 -0
- package/build/dts/testing.d.ts +2 -0
- package/build/dts/testing.d.ts.map +1 -0
- package/build/esm/core/campaign-state.js +140 -0
- package/build/esm/core/campaign-state.js.map +1 -0
- package/build/esm/core/campaigns.js +954 -0
- package/build/esm/core/campaigns.js.map +1 -0
- package/build/esm/core/ledger.js +519 -0
- package/build/esm/core/ledger.js.map +1 -0
- package/build/esm/core/phases.js +87 -0
- package/build/esm/core/phases.js.map +1 -0
- package/build/esm/core/sectors.js +313 -0
- package/build/esm/core/sectors.js.map +1 -0
- package/build/esm/domain/config.js +245 -0
- package/build/esm/domain/config.js.map +1 -0
- package/build/esm/domain/report.js +168 -0
- package/build/esm/domain/report.js.map +1 -0
- package/build/esm/host/campaigns.js +1159 -0
- package/build/esm/host/campaigns.js.map +1 -0
- package/build/esm/host/diff.js +156 -0
- package/build/esm/host/diff.js.map +1 -0
- package/build/esm/index.js +27 -0
- package/build/esm/index.js.map +1 -0
- package/build/esm/infrastructure/campaign-functions.js +67 -0
- package/build/esm/infrastructure/campaign-functions.js.map +1 -0
- package/build/esm/infrastructure/report-source-fake.js +6 -0
- package/build/esm/infrastructure/report-source-fake.js.map +1 -0
- package/build/esm/infrastructure/report-source-live.js +165 -0
- package/build/esm/infrastructure/report-source-live.js.map +1 -0
- package/build/esm/load/decode.js +60 -0
- package/build/esm/load/decode.js.map +1 -0
- package/build/esm/load/extension.js +326 -0
- package/build/esm/load/extension.js.map +1 -0
- package/build/esm/manifest/lower.js +488 -0
- package/build/esm/manifest/lower.js.map +1 -0
- package/build/esm/manifest/spec.js +296 -0
- package/build/esm/manifest/spec.js.map +1 -0
- package/build/esm/ports/campaign-predicate.js +2 -0
- package/build/esm/ports/campaign-predicate.js.map +1 -0
- package/build/esm/ports/report-source.js +7 -0
- package/build/esm/ports/report-source.js.map +1 -0
- package/build/esm/testing.js +5 -0
- package/build/esm/testing.js.map +1 -0
- package/package.json +65 -0
- package/src/core/campaign-state.ts +227 -0
- package/src/core/campaigns.ts +1319 -0
- package/src/core/ledger.ts +675 -0
- package/src/core/phases.ts +138 -0
- package/src/core/sectors.ts +399 -0
- package/src/domain/config.ts +314 -0
- package/src/domain/report.ts +203 -0
- package/src/host/campaigns.ts +1664 -0
- package/src/host/diff.ts +203 -0
- package/src/index.ts +256 -0
- package/src/infrastructure/campaign-functions.ts +99 -0
- package/src/infrastructure/report-source-fake.ts +10 -0
- package/src/infrastructure/report-source-live.ts +193 -0
- package/src/load/decode.ts +81 -0
- package/src/load/extension.ts +466 -0
- package/src/manifest/lower.ts +615 -0
- package/src/manifest/spec.ts +364 -0
- package/src/ports/campaign-predicate.ts +29 -0
- package/src/ports/report-source.ts +35 -0
- package/src/testing.ts +4 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { BindingKind, DeclarationKind, ImportProbeTarget, MemberSubject, PatternList, } from "@goodbones/core";
|
|
2
|
+
import * as Schema from "effect/Schema";
|
|
3
|
+
// The lowered vocabulary of the campaigns family — what the manifest's
|
|
4
|
+
// `campaigns` map becomes once its globs are resolved, and what the
|
|
5
|
+
// evaluators in `core/` compile. It reaches into @goodbones/core only for
|
|
6
|
+
// the pattern primitives the other families already speak: an import's
|
|
7
|
+
// probe target, a binding kind, a declaration kind, a member subject.
|
|
8
|
+
// A campaign: one multi-step refactor, tracked as an object in the
|
|
9
|
+
// repository. Where a rule says what may never happen, a campaign names what
|
|
10
|
+
// the code is moving away from — as `objectives`, each a detector with a
|
|
11
|
+
// ledger that only shrinks on its own — over `sectors` the code declares
|
|
12
|
+
// through a `perimeter`, through an ordered sequence of `phases` toward an
|
|
13
|
+
// end. Lowered from the manifest's `campaigns` map with its globs resolved;
|
|
14
|
+
// the detector below is what the evaluator compiles.
|
|
15
|
+
// What one holdout is: a whole file, a named declaration in it, one matched
|
|
16
|
+
// expression, or the sector itself (for a presence objective — the sector is
|
|
17
|
+
// the holdout while nothing in it matches). The first three are the unit a
|
|
18
|
+
// per-file detector answers at; the unit decides what a term from another
|
|
19
|
+
// level means (a file-level term in a declaration objective is a filter; a
|
|
20
|
+
// declaration-level term in a file objective is existential) and what the
|
|
21
|
+
// fingerprint anchors on.
|
|
22
|
+
export const CampaignUnit = Schema.Literals(["file", "declaration", "match"]);
|
|
23
|
+
export const Holdout = Schema.Literals(["file", "declaration", "match", "sector"]);
|
|
24
|
+
// The detector's leaf terms. Every pattern is a regular-expression source,
|
|
25
|
+
// as everywhere else in this config; the manifest writes globs and lowering
|
|
26
|
+
// translates them. Each term answers at one level — `path`, `imports`,
|
|
27
|
+
// `requires`, `content` and a boolean `fn` about the file; `exports` and
|
|
28
|
+
// `members` about a declaration; `syntax` and a listing `fn` about a match.
|
|
29
|
+
const PathTerm = Schema.Struct({
|
|
30
|
+
file: PatternList,
|
|
31
|
+
fileNot: Schema.optionalKey(PatternList),
|
|
32
|
+
// With `convention`: which capture group of `file` holds the name being
|
|
33
|
+
// judged, and the shape it must have for the term to hold.
|
|
34
|
+
subject: Schema.optionalKey(Schema.Finite),
|
|
35
|
+
convention: Schema.optionalKey(Schema.String),
|
|
36
|
+
});
|
|
37
|
+
const ImportsTerm = Schema.Struct({
|
|
38
|
+
// Where an edge of the file must resolve to: a path pattern, a package
|
|
39
|
+
// name, or a builtin. Holds when at least one edge does.
|
|
40
|
+
resolves: ImportProbeTarget,
|
|
41
|
+
// Names that must be pulled across that edge; omit for any binding.
|
|
42
|
+
symbols: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
43
|
+
});
|
|
44
|
+
const ExportsTerm = Schema.Struct({
|
|
45
|
+
name: Schema.optionalKey(PatternList),
|
|
46
|
+
kinds: Schema.optionalKey(Schema.Array(BindingKind)),
|
|
47
|
+
declares: Schema.optionalKey(Schema.Array(DeclarationKind)),
|
|
48
|
+
reexport: Schema.optionalKey(Schema.Boolean),
|
|
49
|
+
});
|
|
50
|
+
const MembersTerm = Schema.Struct({
|
|
51
|
+
subject: MemberSubject,
|
|
52
|
+
name: Schema.optionalKey(PatternList),
|
|
53
|
+
in: Schema.optionalKey(PatternList),
|
|
54
|
+
declares: Schema.optionalKey(Schema.Array(DeclarationKind)),
|
|
55
|
+
});
|
|
56
|
+
const ContentTerm = Schema.Struct({ regex: Schema.String });
|
|
57
|
+
// How a metavariable of a syntax rule is narrowed: by the text it captured,
|
|
58
|
+
// or by what the identifier at its root is bound to — the module it was
|
|
59
|
+
// imported from and the name it was imported as.
|
|
60
|
+
const BindingNarrowing = Schema.Struct({
|
|
61
|
+
resolves: ImportProbeTarget,
|
|
62
|
+
member: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
63
|
+
});
|
|
64
|
+
const CaptureNarrowing = Schema.Struct({
|
|
65
|
+
regex: Schema.optionalKey(Schema.String),
|
|
66
|
+
binding: Schema.optionalKey(BindingNarrowing),
|
|
67
|
+
});
|
|
68
|
+
const SyntaxTerm = Schema.Struct({
|
|
69
|
+
// The engine's rule object, carried opaquely: the matcher validates it.
|
|
70
|
+
rule: Schema.Unknown,
|
|
71
|
+
where: Schema.optionalKey(Schema.Record(Schema.String, CaptureNarrowing)),
|
|
72
|
+
});
|
|
73
|
+
// A pattern no parser of ours sees, reported by another program: a type
|
|
74
|
+
// error, another linter's finding. Exactly one of `command` (run from the
|
|
75
|
+
// repository root, once per process) and `file` (written by an earlier
|
|
76
|
+
// step), each a list — the manifest's one string lowered to a list of one —
|
|
77
|
+
// read as one report. Each diagnostic on a file is a match anchored on the
|
|
78
|
+
// declaration at its position, keyed by its code and a hash of its message.
|
|
79
|
+
export const ReportFormat = Schema.Literals(["tsc", "eslint", "oxlint", "regex"]);
|
|
80
|
+
const ReportTerm = Schema.Struct({
|
|
81
|
+
command: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
82
|
+
file: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
83
|
+
format: ReportFormat,
|
|
84
|
+
// `regex` only: named groups `file`, `line`, and optionally `column`,
|
|
85
|
+
// `code`, `message`.
|
|
86
|
+
pattern: Schema.optionalKey(Schema.String),
|
|
87
|
+
// The codes the term speaks to; omit for every one.
|
|
88
|
+
codes: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
89
|
+
codesNot: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
90
|
+
});
|
|
91
|
+
const DetectorRef = Schema.suspend(() => Detector);
|
|
92
|
+
export const Detector = Schema.Union([
|
|
93
|
+
Schema.Struct({ all: Schema.Array(DetectorRef) }),
|
|
94
|
+
Schema.Struct({ any: Schema.Array(DetectorRef) }),
|
|
95
|
+
Schema.Struct({ not: DetectorRef }),
|
|
96
|
+
Schema.Struct({ path: PathTerm }),
|
|
97
|
+
Schema.Struct({ imports: ImportsTerm }),
|
|
98
|
+
Schema.Struct({ exports: ExportsTerm }),
|
|
99
|
+
Schema.Struct({ members: MembersTerm }),
|
|
100
|
+
Schema.Struct({ requires: Schema.Array(Schema.String) }),
|
|
101
|
+
Schema.Struct({ content: ContentTerm }),
|
|
102
|
+
Schema.Struct({ syntax: SyntaxTerm }),
|
|
103
|
+
Schema.Struct({ report: ReportTerm }),
|
|
104
|
+
Schema.Struct({ fn: Schema.String }),
|
|
105
|
+
]);
|
|
106
|
+
// A term quantified over the sector's files rather than answered by one.
|
|
107
|
+
// `has` takes an ordinary detector and holds when at least one file (or
|
|
108
|
+
// declaration, or match) in the sector satisfies it — a presence, whose
|
|
109
|
+
// holdout is the sector until something matches. `oneRoot` holds when every
|
|
110
|
+
// file of the sector sits under the root its perimeter was found at, which
|
|
111
|
+
// is what an `endState` needs; `oneHost` when every file matches the host.
|
|
112
|
+
// Each needs the sector's file list and nothing else, so the CLI reports
|
|
113
|
+
// them and the plugin, which sees one file, reads only their effect on the
|
|
114
|
+
// sector's phase through the ledger.
|
|
115
|
+
export const SectorTerm = Schema.Union([
|
|
116
|
+
Schema.Struct({ has: Detector }),
|
|
117
|
+
Schema.Struct({ oneRoot: Schema.Literal(true) }),
|
|
118
|
+
Schema.Struct({ oneHost: PatternList }),
|
|
119
|
+
]);
|
|
120
|
+
// One diagnostic a probe stands in for, positions one-based as a tool
|
|
121
|
+
// prints them.
|
|
122
|
+
export const ProbeDiagnostic = Schema.Struct({
|
|
123
|
+
line: Schema.Finite,
|
|
124
|
+
column: Schema.optionalKey(Schema.Finite),
|
|
125
|
+
code: Schema.optionalKey(Schema.String),
|
|
126
|
+
message: Schema.optionalKey(Schema.String),
|
|
127
|
+
});
|
|
128
|
+
// A source an objective is proven against: the path it would have, its text
|
|
129
|
+
// when a term needs one, the target of each of its edges (in place of the live
|
|
130
|
+
// resolver), the files beside it (in place of the file system) and the
|
|
131
|
+
// diagnostics reported on it (in place of the report source).
|
|
132
|
+
export const CampaignProbe = Schema.Struct({
|
|
133
|
+
path: Schema.String,
|
|
134
|
+
source: Schema.optionalKey(Schema.String),
|
|
135
|
+
edges: Schema.optionalKey(Schema.Record(Schema.String, ImportProbeTarget)),
|
|
136
|
+
files: Schema.optionalKey(Schema.Array(Schema.String)),
|
|
137
|
+
report: Schema.optionalKey(Schema.Array(ProbeDiagnostic)),
|
|
138
|
+
});
|
|
139
|
+
export const CampaignProbes = Schema.Struct({
|
|
140
|
+
fires: Schema.Array(CampaignProbe),
|
|
141
|
+
ignores: Schema.Array(CampaignProbe),
|
|
142
|
+
});
|
|
143
|
+
// An objective: a detector, a granularity, probes, and a ledger that only
|
|
144
|
+
// shrinks on its own. Owned by one campaign; named by at most one phase (an
|
|
145
|
+
// objective no phase names is in window in every phase). Exactly one of
|
|
146
|
+
// `match` (a per-file detector, evaluated by both hosts) and `sector` (a
|
|
147
|
+
// term over the sector's files, evaluated by the CLI) — or, for the
|
|
148
|
+
// objectives an `endState` expands into, `endState` naming the family.
|
|
149
|
+
export const ObjectiveRule = Schema.Struct({
|
|
150
|
+
// `campaign/<campaign>/<objective>`, the rule name a violation carries.
|
|
151
|
+
name: Schema.String,
|
|
152
|
+
id: Schema.String,
|
|
153
|
+
campaign: Schema.String,
|
|
154
|
+
// The `how`: what a reader at a holdout does about it.
|
|
155
|
+
message: Schema.String,
|
|
156
|
+
why: Schema.optionalKey(Schema.String),
|
|
157
|
+
holdout: Holdout,
|
|
158
|
+
match: Schema.optionalKey(Detector),
|
|
159
|
+
sector: Schema.optionalKey(SectorTerm),
|
|
160
|
+
endState: Schema.optionalKey(Schema.Struct({
|
|
161
|
+
phase: Schema.String,
|
|
162
|
+
family: Schema.Literals(["imports", "exports", "members", "surface", "structure"]),
|
|
163
|
+
})),
|
|
164
|
+
// The phase at which the objective stops counting, exclusive; absent, it
|
|
165
|
+
// counts to the end.
|
|
166
|
+
until: Schema.optionalKey(Schema.String),
|
|
167
|
+
probes: CampaignProbes,
|
|
168
|
+
});
|
|
169
|
+
// How a sector is recognized. The name is the sector's identity. A `marker`
|
|
170
|
+
// is a file that names the sector (and may list the globs it owns); `glob`
|
|
171
|
+
// is one sector per match; `match` one sector per detector match, keyed by
|
|
172
|
+
// its anchor; `file` one sector per file, keyed by the path without its
|
|
173
|
+
// extension; `nx` reads the workspace's projects. A campaign with none has
|
|
174
|
+
// one implicit sector, the scope.
|
|
175
|
+
export const PerimeterRule = Schema.Union([
|
|
176
|
+
Schema.Struct({ kind: Schema.Literal("file") }),
|
|
177
|
+
Schema.Struct({ kind: Schema.Literal("nx") }),
|
|
178
|
+
Schema.Struct({ kind: Schema.Literal("glob"), glob: PatternList }),
|
|
179
|
+
Schema.Struct({
|
|
180
|
+
kind: Schema.Literal("marker"),
|
|
181
|
+
marker: PatternList,
|
|
182
|
+
probes: Schema.optionalKey(Schema.Struct({ fires: PatternList, ignores: PatternList })),
|
|
183
|
+
}),
|
|
184
|
+
Schema.Struct({
|
|
185
|
+
kind: Schema.Literal("match"),
|
|
186
|
+
match: Detector,
|
|
187
|
+
unit: Schema.Literals(["declaration", "match"]),
|
|
188
|
+
probes: CampaignProbes,
|
|
189
|
+
}),
|
|
190
|
+
]);
|
|
191
|
+
// What a touched sector owes beyond the nudge. A strict ladder: the ledger
|
|
192
|
+
// records growth with a reason under `advise`; `ratchet` refuses it in a
|
|
193
|
+
// touched sector; `paydown` adds that a diff editing a holdout-bearing
|
|
194
|
+
// declaration must leave the sector with fewer holdouts.
|
|
195
|
+
export const OnTouch = Schema.Literals(["advise", "ratchet", "paydown"]);
|
|
196
|
+
// A dated receipt for a change to a defined phase, which authorizes the next
|
|
197
|
+
// `clear` to re-baseline the sectors in that phase's window.
|
|
198
|
+
export const PhaseConcession = Schema.Struct({
|
|
199
|
+
reason: Schema.String,
|
|
200
|
+
at: Schema.String,
|
|
201
|
+
by: Schema.optionalKey(Schema.String),
|
|
202
|
+
});
|
|
203
|
+
// A phase: a named, ordered group of objectives. Defined when it names one
|
|
204
|
+
// (or is attested, or carries an end state); open when it has only an
|
|
205
|
+
// intent, and then it is last. `hash` is the phase's definition — its
|
|
206
|
+
// position, its objectives and their detectors — so a change to a defined
|
|
207
|
+
// phase is visible against the plan the ledger recorded.
|
|
208
|
+
export const PhaseRule = Schema.Struct({
|
|
209
|
+
id: Schema.String,
|
|
210
|
+
intent: Schema.optionalKey(Schema.String),
|
|
211
|
+
objectives: Schema.Array(Schema.String),
|
|
212
|
+
attested: Schema.Boolean,
|
|
213
|
+
onTouch: Schema.optionalKey(OnTouch),
|
|
214
|
+
// The sector-relative node tree, carried as written; expanded per sector
|
|
215
|
+
// by the host that evaluates it.
|
|
216
|
+
endState: Schema.optionalKey(Schema.Unknown),
|
|
217
|
+
concessions: Schema.Array(PhaseConcession),
|
|
218
|
+
hash: Schema.String,
|
|
219
|
+
});
|
|
220
|
+
export const CampaignRule = Schema.Struct({
|
|
221
|
+
// `campaign/<id>`.
|
|
222
|
+
name: Schema.String,
|
|
223
|
+
id: Schema.String,
|
|
224
|
+
title: Schema.optionalKey(Schema.String),
|
|
225
|
+
why: Schema.optionalKey(Schema.String),
|
|
226
|
+
owner: Schema.optionalKey(Schema.String),
|
|
227
|
+
scope: PatternList,
|
|
228
|
+
// Extensions the campaign widens the walk to, beyond the packs' — a
|
|
229
|
+
// JavaScript half a TypeScript pack does not visit.
|
|
230
|
+
extensions: Schema.Array(Schema.String),
|
|
231
|
+
// What the remainder of the scope counts as; absent, everything no sector
|
|
232
|
+
// claims is legacy.
|
|
233
|
+
legacy: Schema.optionalKey(PatternList),
|
|
234
|
+
perimeter: Schema.optionalKey(PerimeterRule),
|
|
235
|
+
onTouch: Schema.optionalKey(OnTouch),
|
|
236
|
+
phases: Schema.Array(PhaseRule),
|
|
237
|
+
objectives: Schema.Array(ObjectiveRule),
|
|
238
|
+
// Milliseconds without progress after which the campaign is stalled;
|
|
239
|
+
// absent, it never is.
|
|
240
|
+
staleAfter: Schema.optionalKey(Schema.Finite),
|
|
241
|
+
// What `check` demands once every count is zero: keep the campaign as a
|
|
242
|
+
// guard against recurrence, or remove it from the manifest.
|
|
243
|
+
onComplete: Schema.Literals(["keep", "remove"]),
|
|
244
|
+
});
|
|
245
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/domain/config.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,aAAa,EACb,WAAW,GACZ,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,uEAAuE;AACvE,oEAAoE;AACpE,0EAA0E;AAC1E,uEAAuE;AACvE,sEAAsE;AAEtE,mEAAmE;AACnE,6EAA6E;AAC7E,yEAAyE;AACzE,yEAAyE;AACzE,2EAA2E;AAC3E,4EAA4E;AAC5E,qDAAqD;AAErD,4EAA4E;AAC5E,6EAA6E;AAC7E,2EAA2E;AAC3E,0EAA0E;AAC1E,2EAA2E;AAC3E,0EAA0E;AAC1E,0BAA0B;AAC1B,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC;AAC9E,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEnF,2EAA2E;AAC3E,4EAA4E;AAC5E,uEAAuE;AACvE,yEAAyE;AACzE,4EAA4E;AAC5E,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;IAC7B,IAAI,EAAE,WAAW;IACjB,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC;IACxC,wEAAwE;IACxE,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;CAC9C,CAAC,CAAC;AAGH,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IAChC,uEAAuE;IACvE,yDAAyD;IACzD,QAAQ,EAAE,iBAAiB;IAC3B,oEAAoE;IACpE,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;CACzD,CAAC,CAAC;AAGH,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IACpD,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAC3D,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC;CAC7C,CAAC,CAAC;AAGH,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC;IAChC,OAAO,EAAE,aAAa;IACtB,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC;IACrC,EAAE,EAAE,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC;IACnC,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;CAC5D,CAAC,CAAC;AAGH,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;AAG5D,4EAA4E;AAC5E,wEAAwE;AACxE,iDAAiD;AACjD,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC;IACrC,QAAQ,EAAE,iBAAiB;IAC3B,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;CACxD,CAAC,CAAC;AAEH,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC;IACrC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IACxC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC;CAC9C,CAAC,CAAC;AAEH,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IAC/B,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC,OAAO;IACpB,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;CAC1E,CAAC,CAAC;AAGH,wEAAwE;AACxE,0EAA0E;AAC1E,uEAAuE;AACvE,4EAA4E;AAC5E,2EAA2E;AAC3E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;AAElF,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACxD,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrD,MAAM,EAAE,YAAY;IACpB,sEAAsE;IACtE,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IAC1C,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtD,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;CAC1D,CAAC,CAAC;AAkBH,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,GAA2B,EAAE,CAAC,QAAQ,CAAC,CAAC;AAE3E,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC;IACnC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;IACjD,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;IACjD,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;IACnC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjC,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IACvC,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IACvC,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IACvC,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;IACxD,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IACvC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IACrC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IACrC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;CACrC,CAAC,CAAC;AAEH,yEAAyE;AACzE,wEAAwE;AACxE,wEAAwE;AACxE,4EAA4E;AAC5E,2EAA2E;AAC3E,2EAA2E;AAC3E,yEAAyE;AACzE,2EAA2E;AAC3E,qCAAqC;AACrC,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC;IACrC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;IAChC,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;IAChD,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;CACxC,CAAC,CAAC;AAGH,sEAAsE;AACtE,eAAe;AACf,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IACzC,IAAI,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;CAC3C,CAAC,CAAC;AAEH,4EAA4E;AAC5E,+EAA+E;AAC/E,uEAAuE;AACvE,8DAA8D;AAC9D,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC;IACzC,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IACzC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC1E,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtD,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;CAC1D,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;CACrC,CAAC,CAAC;AAEH,0EAA0E;AAC1E,4EAA4E;AAC5E,wEAAwE;AACxE,yEAAyE;AACzE,oEAAoE;AACpE,uEAAuE;AACvE,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC;IACzC,wEAAwE;IACxE,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,EAAE,EAAE,MAAM,CAAC,MAAM;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM;IACvB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,GAAG,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IACtC,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC;IACtC,QAAQ,EAAE,MAAM,CAAC,WAAW,CAC1B,MAAM,CAAC,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC,MAAM;QACpB,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;KACnF,CAAC,CACH;IACD,yEAAyE;IACzE,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IACxC,MAAM,EAAE,cAAc;CACvB,CAAC,CAAC;AAEH,4EAA4E;AAC5E,2EAA2E;AAC3E,2EAA2E;AAC3E,wEAAwE;AACxE,2EAA2E;AAC3E,kCAAkC;AAClC,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC;IACxC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;IAC/C,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;IAC7C,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAClE,MAAM,CAAC,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC9B,MAAM,EAAE,WAAW;QACnB,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC;KACxF,CAAC;IACF,MAAM,CAAC,MAAM,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;QAC7B,KAAK,EAAE,QAAQ;QACf,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;QAC/C,MAAM,EAAE,cAAc;KACvB,CAAC;CACH,CAAC,CAAC;AAGH,2EAA2E;AAC3E,yEAAyE;AACzE,uEAAuE;AACvE,yDAAyD;AACzD,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;AAGzE,6EAA6E;AAC7E,6DAA6D;AAC7D,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC;IAC3C,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC,MAAM;IACjB,EAAE,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;CACtC,CAAC,CAAC;AAEH,2EAA2E;AAC3E,sEAAsE;AACtE,sEAAsE;AACtE,0EAA0E;AAC1E,yDAAyD;AACzD,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC;IACrC,EAAE,EAAE,MAAM,CAAC,MAAM;IACjB,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IACzC,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;IACvC,QAAQ,EAAE,MAAM,CAAC,OAAO;IACxB,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC;IACpC,yEAAyE;IACzE,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC;IAC5C,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,eAAe,CAAC;IAC1C,IAAI,EAAE,MAAM,CAAC,MAAM;CACpB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC;IACxC,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC,MAAM;IACnB,EAAE,EAAE,MAAM,CAAC,MAAM;IACjB,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IACxC,GAAG,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IACtC,KAAK,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IACxC,KAAK,EAAE,WAAW;IAClB,oEAAoE;IACpE,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;IACvC,0EAA0E;IAC1E,oBAAoB;IACpB,MAAM,EAAE,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC,WAAW,CAAC,aAAa,CAAC;IAC5C,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC;IACpC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC;IACvC,qEAAqE;IACrE,uBAAuB;IACvB,UAAU,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC;IAC7C,wEAAwE;IACxE,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CAChD,CAAC,CAAC"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
// A campaign's `report` term names a pattern no parser of ours sees: a type
|
|
2
|
+
// error, a lint finding from another tool, anything a program prints one
|
|
3
|
+
// line per occurrence. This is the vocabulary such a report is read into —
|
|
4
|
+
// a diagnostic with a file, a position, a code and a message — and the
|
|
5
|
+
// readers for the formats a report comes in. Pure: text in, diagnostics out.
|
|
6
|
+
// Running the command or reading the file is the report source's business.
|
|
7
|
+
const relativeTo = (repoRoot, file) => {
|
|
8
|
+
const slashed = file.replaceAll("\\", "/");
|
|
9
|
+
const root = repoRoot.replaceAll("\\", "/").replace(/\/$/, "");
|
|
10
|
+
const relative = slashed === root
|
|
11
|
+
? ""
|
|
12
|
+
: slashed.startsWith(`${root}/`)
|
|
13
|
+
? slashed.slice(root.length + 1)
|
|
14
|
+
: slashed;
|
|
15
|
+
return relative.replace(/^\.\//, "");
|
|
16
|
+
};
|
|
17
|
+
const oneBased = (value, fallback = 1) => {
|
|
18
|
+
const parsed = Number(value);
|
|
19
|
+
return Number.isFinite(parsed) && parsed >= 1 ? parsed - 1 : fallback - 1;
|
|
20
|
+
};
|
|
21
|
+
const firstLine = (message) => message.split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
22
|
+
// `src/a.ts(12,5): error TS2551: Property 'x' does not exist…`, one per
|
|
23
|
+
// line, with the continuation lines tsc indents beneath a message ignored —
|
|
24
|
+
// the first line is the message.
|
|
25
|
+
const TSC_LINE = /^(.+?)\((\d+),(\d+)\): error (TS\d+): (.*)$/;
|
|
26
|
+
const parseTsc = (text, options) => {
|
|
27
|
+
const found = [];
|
|
28
|
+
for (const line of text.split(/\r?\n/)) {
|
|
29
|
+
const match = TSC_LINE.exec(line);
|
|
30
|
+
if (match === null)
|
|
31
|
+
continue;
|
|
32
|
+
const [, file = "", row, column, code = "", message = ""] = match;
|
|
33
|
+
found.push({
|
|
34
|
+
file: relativeTo(options.repoRoot, file),
|
|
35
|
+
line: oneBased(row),
|
|
36
|
+
column: oneBased(column),
|
|
37
|
+
code,
|
|
38
|
+
message: firstLine(message),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
return found;
|
|
42
|
+
};
|
|
43
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
44
|
+
const asString = (value) => (typeof value === "string" ? value : "");
|
|
45
|
+
const asNumber = (value) => typeof value === "number" && Number.isFinite(value) ? value : undefined;
|
|
46
|
+
const parseJson = (text, format) => {
|
|
47
|
+
try {
|
|
48
|
+
return JSON.parse(text);
|
|
49
|
+
}
|
|
50
|
+
catch (cause) {
|
|
51
|
+
throw new Error(`a ${format} report is JSON, and this one does not parse: ${String(cause)}`);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
// `eslint --format json`: one object per file with its messages. A message
|
|
55
|
+
// with no `ruleId` (a parse error) carries the code `""`.
|
|
56
|
+
const parseEslint = (text, options) => {
|
|
57
|
+
const parsed = parseJson(text, "eslint");
|
|
58
|
+
if (!Array.isArray(parsed))
|
|
59
|
+
throw new Error("an eslint report is a JSON array of files");
|
|
60
|
+
const found = [];
|
|
61
|
+
for (const entry of parsed) {
|
|
62
|
+
if (!isRecord(entry) || !Array.isArray(entry.messages))
|
|
63
|
+
continue;
|
|
64
|
+
const file = relativeTo(options.repoRoot, asString(entry.filePath));
|
|
65
|
+
for (const message of entry.messages) {
|
|
66
|
+
if (!isRecord(message))
|
|
67
|
+
continue;
|
|
68
|
+
found.push({
|
|
69
|
+
file,
|
|
70
|
+
line: (asNumber(message.line) ?? 1) - 1,
|
|
71
|
+
column: (asNumber(message.column) ?? 1) - 1,
|
|
72
|
+
code: asString(message.ruleId),
|
|
73
|
+
message: firstLine(asString(message.message)),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return found;
|
|
78
|
+
};
|
|
79
|
+
// `oxlint --format json`: `{ diagnostics: [{ filename, code, message,
|
|
80
|
+
// labels: [{ span: { line, column } }] }] }`, positions one-based.
|
|
81
|
+
const parseOxlint = (text, options) => {
|
|
82
|
+
const parsed = parseJson(text, "oxlint");
|
|
83
|
+
if (!isRecord(parsed) || !Array.isArray(parsed.diagnostics)) {
|
|
84
|
+
throw new Error("an oxlint report is a JSON object with a `diagnostics` array");
|
|
85
|
+
}
|
|
86
|
+
const found = [];
|
|
87
|
+
for (const entry of parsed.diagnostics) {
|
|
88
|
+
if (!isRecord(entry))
|
|
89
|
+
continue;
|
|
90
|
+
const labels = Array.isArray(entry.labels) ? entry.labels : [];
|
|
91
|
+
const label = labels[0];
|
|
92
|
+
const span = isRecord(label) && isRecord(label.span) ? label.span : {};
|
|
93
|
+
found.push({
|
|
94
|
+
file: relativeTo(options.repoRoot, asString(entry.filename)),
|
|
95
|
+
line: (asNumber(span.line) ?? 1) - 1,
|
|
96
|
+
column: (asNumber(span.column) ?? 1) - 1,
|
|
97
|
+
code: asString(entry.code),
|
|
98
|
+
message: firstLine(asString(entry.message)),
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return found;
|
|
102
|
+
};
|
|
103
|
+
const parseRegex = (text, options) => {
|
|
104
|
+
if (options.pattern === undefined) {
|
|
105
|
+
throw new Error("a `regex` report needs a `pattern` with named groups `file` and `line`");
|
|
106
|
+
}
|
|
107
|
+
const pattern = new RegExp(options.pattern);
|
|
108
|
+
const found = [];
|
|
109
|
+
for (const line of text.split(/\r?\n/)) {
|
|
110
|
+
const match = pattern.exec(line);
|
|
111
|
+
if (match === null)
|
|
112
|
+
continue;
|
|
113
|
+
const groups = match.groups ?? {};
|
|
114
|
+
if (groups.file === undefined)
|
|
115
|
+
continue;
|
|
116
|
+
found.push({
|
|
117
|
+
file: relativeTo(options.repoRoot, groups.file),
|
|
118
|
+
line: oneBased(groups.line),
|
|
119
|
+
column: oneBased(groups.column),
|
|
120
|
+
code: groups.code ?? "",
|
|
121
|
+
message: firstLine(groups.message ?? ""),
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return found;
|
|
125
|
+
};
|
|
126
|
+
export const parseReport = (format, text, options) => {
|
|
127
|
+
switch (format) {
|
|
128
|
+
case "tsc":
|
|
129
|
+
return parseTsc(text, options);
|
|
130
|
+
case "eslint":
|
|
131
|
+
return parseEslint(text, options);
|
|
132
|
+
case "oxlint":
|
|
133
|
+
return parseOxlint(text, options);
|
|
134
|
+
case "regex":
|
|
135
|
+
return parseRegex(text, options);
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
// One report from several outputs. A tool that takes one project at a time
|
|
139
|
+
// is run once per project, and a project's program includes the files of
|
|
140
|
+
// the projects it references, so one diagnostic is printed under several
|
|
141
|
+
// runs; it is one diagnostic. Kept once, at its first appearance, when
|
|
142
|
+
// identical in file, position, code and message.
|
|
143
|
+
export const uniqueDiagnostics = (diagnostics) => {
|
|
144
|
+
const seen = new Set();
|
|
145
|
+
const kept = [];
|
|
146
|
+
for (const one of diagnostics) {
|
|
147
|
+
const key = JSON.stringify([one.file, one.line, one.column, one.code, one.message]);
|
|
148
|
+
if (seen.has(key))
|
|
149
|
+
continue;
|
|
150
|
+
seen.add(key);
|
|
151
|
+
kept.push(one);
|
|
152
|
+
}
|
|
153
|
+
return kept;
|
|
154
|
+
};
|
|
155
|
+
// The diagnostics indexed by file, which is how a per-file evaluator asks
|
|
156
|
+
// for them.
|
|
157
|
+
export const indexByFile = (diagnostics) => {
|
|
158
|
+
const byFile = new Map();
|
|
159
|
+
for (const one of diagnostics) {
|
|
160
|
+
const found = byFile.get(one.file);
|
|
161
|
+
if (found === undefined)
|
|
162
|
+
byFile.set(one.file, [one]);
|
|
163
|
+
else
|
|
164
|
+
found.push(one);
|
|
165
|
+
}
|
|
166
|
+
return byFile;
|
|
167
|
+
};
|
|
168
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../../../src/domain/report.ts"],"names":[],"mappings":"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"}
|