@codometer/measurement 0.0.77 → 0.0.79
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/CHANGELOG.md +24 -0
- package/dist/src/index.d.ts +106 -458
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,27 @@
|
|
|
1
|
+
## 0.0.79 (2026-11-11)
|
|
2
|
+
|
|
3
|
+
### 🚀 Features
|
|
4
|
+
|
|
5
|
+
- **codometer:** ✨ tighten the comment budgets and shorten every comment over them ([#2262](https://github.com/organizzolini/codebase/pull/2262), [#2261](https://github.com/organizzolini/codebase/issues/2261))
|
|
6
|
+
|
|
7
|
+
### 🧱 Updated Dependencies
|
|
8
|
+
|
|
9
|
+
- Updated codometer-configuration to 0.0.79
|
|
10
|
+
- Updated codometer-languages to 0.0.79
|
|
11
|
+
- Updated codometer-core to 0.0.79
|
|
12
|
+
|
|
13
|
+
## 0.0.78 (2026-11-10)
|
|
14
|
+
|
|
15
|
+
### 🚀 Features
|
|
16
|
+
|
|
17
|
+
- **codometer:** ✨ gate JSDoc on every declaration kind and shorten long comments ([#2227](https://github.com/organizzolini/codebase/pull/2227), [#2226](https://github.com/organizzolini/codebase/issues/2226))
|
|
18
|
+
|
|
19
|
+
### 🧱 Updated Dependencies
|
|
20
|
+
|
|
21
|
+
- Updated codometer-configuration to 0.0.78
|
|
22
|
+
- Updated codometer-languages to 0.0.78
|
|
23
|
+
- Updated codometer-core to 0.0.78
|
|
24
|
+
|
|
1
25
|
## 0.0.77 (2026-11-10)
|
|
2
26
|
|
|
3
27
|
### 🧱 Updated Dependencies
|
package/dist/src/index.d.ts
CHANGED
|
@@ -32,14 +32,9 @@ declare interface CreateIgnoreScopeArguments {
|
|
|
32
32
|
/** Input to the custom statistics step. */
|
|
33
33
|
export declare interface CustomizationInput {
|
|
34
34
|
/**
|
|
35
|
-
*
|
|
36
|
-
* statistic's label.
|
|
35
|
+
* Each `comment` counter's measurements, keyed by its statistic's label.
|
|
37
36
|
*
|
|
38
|
-
*
|
|
39
|
-
* merging the two results back together by label — the languages package
|
|
40
|
-
* measures a counter naming a declaration kind and one naming a language
|
|
41
|
-
* through two different calls, but a label belongs to exactly one custom
|
|
42
|
-
* statistic either way.
|
|
37
|
+
* Merged by label from both measurers, since a label names exactly one statistic.
|
|
43
38
|
*/
|
|
44
39
|
commentCounts: Record<string, CommentMeasurement[]>;
|
|
45
40
|
/** Every file of the target being counted over. */
|
|
@@ -56,50 +51,26 @@ export declare class CustomizationModule {
|
|
|
56
51
|
}
|
|
57
52
|
|
|
58
53
|
/**
|
|
59
|
-
* Counts the conventions a repository holds itself to.
|
|
54
|
+
* Counts the conventions a repository holds itself to. Which counters apply comes from configuration, not this package.
|
|
60
55
|
*
|
|
61
|
-
*
|
|
62
|
-
* `*.service.ts` means, or whether a static method is something to keep an
|
|
63
|
-
* eye on, is not — which is why these counters come from the configuration
|
|
64
|
-
* rather than from this package.
|
|
65
|
-
*
|
|
66
|
-
* A counter measures files by path, declarations by shape, or a comment
|
|
67
|
-
* budget by length. The file half is done here; the declaration half is
|
|
68
|
-
* tallied by the TypeScript analyzer during the walk it already makes, and
|
|
69
|
-
* the comment half by `@codometer/languages`' comment services — both arrive
|
|
70
|
-
* here as counts to be labelled.
|
|
56
|
+
* Files are measured here; declaration and comment counts arrive from `@codometer/languages`.
|
|
71
57
|
*/
|
|
72
58
|
export declare class CustomizationService {
|
|
73
59
|
constructor();
|
|
74
60
|
/** Turn a `comment`-selector statistic's own breaches into its result. */
|
|
75
61
|
private buildCommentResult;
|
|
76
62
|
/**
|
|
77
|
-
* Counts the
|
|
78
|
-
*
|
|
79
|
-
* A file matching several globs of the same counter is one file, not
|
|
80
|
-
* several: the counter asks how many files there are, not how many times
|
|
81
|
-
* they matched.
|
|
63
|
+
* Counts the files claimed by at least one glob; a file matching several globs counts once.
|
|
82
64
|
*/
|
|
83
65
|
private countMatches;
|
|
84
66
|
/** Count every configured statistic over the discovered files. */
|
|
85
67
|
analyze({ commentCounts, files, statistics, symbolCounts, }: CustomizationInput): CustomStatisticResult[];
|
|
86
68
|
/**
|
|
87
|
-
*
|
|
88
|
-
* measure.
|
|
89
|
-
*
|
|
90
|
-
* Handed to those services rather than measured again here: a `comment`
|
|
91
|
-
* selector names a language or a documentable kind, and turning that into a
|
|
92
|
-
* budget is this package's business, not the tokenizer's. One list, mirroring
|
|
93
|
-
* the selector field for field — which counter a given measurer takes is
|
|
94
|
-
* decided by each measurer, which selects from the list by reading `kind`.
|
|
69
|
+
* Picks the counters `@codometer/languages`' comment services measure. Each measurer selects its own by `kind`.
|
|
95
70
|
*/
|
|
96
71
|
buildCommentCounters(statistics: CustomizationInput["statistics"]): CommentCounter[];
|
|
97
72
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
* Handed to that analyzer rather than parsed again here: it already walks
|
|
101
|
-
* every source file, and a second walk would double the slowest part of a
|
|
102
|
-
* run to learn what the first one passed straight over.
|
|
73
|
+
* Picks the counters the TypeScript analyzer tallies during its existing walk, rather than walking files again.
|
|
103
74
|
*/
|
|
104
75
|
buildSymbolCounters(statistics: CustomizationInput["statistics"]): TypescriptSymbolCounter[];
|
|
105
76
|
}
|
|
@@ -143,91 +114,45 @@ export declare class DiscoveryService {
|
|
|
143
114
|
private readonly logger;
|
|
144
115
|
constructor(ignoreRulesService: IgnoreRulesService, logger: LoggerService);
|
|
145
116
|
/**
|
|
146
|
-
* Folds a directory's
|
|
147
|
-
*
|
|
148
|
-
* Appended last so its patterns outrank the ones above it, which is how git
|
|
149
|
-
* resolves a nested ignore file: the closest one to the file wins.
|
|
117
|
+
* Folds a directory's `.gitignore` into the rule sets in force, appended last so its patterns outrank the ones above.
|
|
150
118
|
*/
|
|
151
119
|
private applyDirectoryIgnoreFile;
|
|
152
120
|
/** Selects the discovered files whose extension belongs to a category. */
|
|
153
121
|
private filterByExtension;
|
|
154
122
|
/**
|
|
155
|
-
* Whether any exclusion glob claims the
|
|
156
|
-
*
|
|
157
|
-
* Matched with `path.matchesGlob` rather than by substring, so a glob naming
|
|
158
|
-
* a `dist` directory removes build output and leaves a `redistribute`
|
|
159
|
-
* directory alone.
|
|
123
|
+
* Whether any exclusion glob claims the path. Matched by glob, not substring, so a `dist` glob leaves `redistribute` alone.
|
|
160
124
|
*/
|
|
161
125
|
private isExcluded;
|
|
162
126
|
/**
|
|
163
|
-
* Whether every file beneath
|
|
164
|
-
*
|
|
165
|
-
* A pattern ending in `/**` claims every descendant without exception, so a
|
|
166
|
-
* directory matching the pattern with that suffix removed cannot contribute
|
|
167
|
-
* a single file and never has to be read. This is a shortcut and not a rule
|
|
168
|
-
* of its own: the same files would be dropped one by one afterwards either
|
|
169
|
-
* way. It matters in a directory with no `.gitignore` to prune
|
|
170
|
-
* `node_modules`, where reading it dwarfs reading the codebase.
|
|
127
|
+
* Whether a `/**` glob excludes every file beneath the directory, so the walk can skip reading it. Matters for an unignored `node_modules`.
|
|
171
128
|
*/
|
|
172
129
|
private isExhaustivelyExcluded;
|
|
173
130
|
/**
|
|
174
|
-
* Whether either set
|
|
175
|
-
*
|
|
176
|
-
* The two sets are answered independently and the answers combined, rather
|
|
177
|
-
* than merged into one set. A configured ignore file subtracts from what the
|
|
178
|
-
* repository's own `.gitignore` files leave behind, exactly as the two git
|
|
179
|
-
* invocations this replaced did; a negation in one cannot resurrect a file
|
|
180
|
-
* the other removed.
|
|
131
|
+
* Whether either ignore rule set claims the path. Checked separately, so a negation in one cannot resurrect a file the other removed.
|
|
181
132
|
*/
|
|
182
133
|
private isIgnoredPath;
|
|
183
134
|
/**
|
|
184
|
-
* Lists every measurable file
|
|
185
|
-
*
|
|
186
|
-
* Sorted because the walk visits directories in whatever order the
|
|
187
|
-
* filesystem reports them, and every consumer downstream deserves the same
|
|
188
|
-
* list from the same tree on any machine.
|
|
135
|
+
* Lists every measurable file under the working directory, sorted so every consumer sees the same order on any machine.
|
|
189
136
|
*/
|
|
190
137
|
private listDiscoveredFiles;
|
|
191
138
|
/**
|
|
192
|
-
* Reads a directory's entries, or none when
|
|
193
|
-
*
|
|
194
|
-
* A directory can vanish or refuse to open partway through a walk — one
|
|
195
|
-
* being cleaned up by another process, a mount the caller has no permission
|
|
196
|
-
* on. Shelling out to git never failed for either reason, so letting one
|
|
197
|
-
* unreadable directory abort the whole measurement would be a regression:
|
|
198
|
-
* warn, skip it, and keep counting the rest.
|
|
139
|
+
* Reads a directory's entries, or none when it cannot be read, so one vanished directory does not abort the walk.
|
|
199
140
|
*/
|
|
200
141
|
private readDirectoryEntries;
|
|
201
142
|
/**
|
|
202
|
-
* Reads the configured ignore files
|
|
203
|
-
*
|
|
204
|
-
* A missing file is a warning rather than a failure: a repository that has
|
|
205
|
-
* renamed its ignore file should hear about it, but a report is still worth
|
|
206
|
-
* more than a crash.
|
|
143
|
+
* Reads the configured ignore files as rules anchored at the root. A missing file only warns, since a report beats a crash.
|
|
207
144
|
*/
|
|
208
145
|
private readExcludeFromScopes;
|
|
209
146
|
/**
|
|
210
|
-
* Collects every measurable file under one directory.
|
|
211
|
-
*
|
|
212
|
-
* Walked directory by directory rather than matched by a single recursive
|
|
213
|
-
* glob, because an ignored directory then costs one decision instead of an
|
|
214
|
-
* enumeration: `node_modules/` is pruned where it is named, not discovered
|
|
215
|
-
* in full and thrown away.
|
|
147
|
+
* Collects every measurable file under one directory. Walking directory by directory prunes ignored trees such as `node_modules/` at their root.
|
|
216
148
|
*/
|
|
217
149
|
private walkDirectory;
|
|
218
150
|
/**
|
|
219
|
-
* Descends into
|
|
220
|
-
*
|
|
221
|
-
* The trailing slash is what makes a `coverage/` pattern claim the directory
|
|
222
|
-
* itself: without it the pattern only ever matches a file of that name.
|
|
151
|
+
* Descends into a subdirectory unless nothing there counts. The trailing slash lets a `coverage/` pattern claim the directory itself.
|
|
223
152
|
*/
|
|
224
153
|
private walkSubdirectory;
|
|
225
154
|
/**
|
|
226
|
-
* Sorts
|
|
227
|
-
*
|
|
228
|
-
* Separate from the walk so that any target's files can be categorized, not
|
|
229
|
-
* only the ones this service found itself: a target naming its files by glob
|
|
230
|
-
* is analyzed by the same language analyzers as the codebase around it.
|
|
155
|
+
* Sorts file paths into analyzer categories. Separate from the walk, so any target's files can be categorized.
|
|
231
156
|
*/
|
|
232
157
|
categorize(files: string[]): DiscoveryResult;
|
|
233
158
|
/** Returns categorized file path lists for the given codebase root. */
|
|
@@ -241,25 +166,18 @@ declare interface DuplicateTargetFinding {
|
|
|
241
166
|
}
|
|
242
167
|
|
|
243
168
|
/**
|
|
244
|
-
* Raised when a target carrying a limit matched no files
|
|
169
|
+
* Raised when a target carrying a limit matched no files.
|
|
245
170
|
*
|
|
246
|
-
*
|
|
247
|
-
*
|
|
248
|
-
*
|
|
249
|
-
*
|
|
171
|
+
* A limit asserts its files exist, so an empty match means a stale glob or a
|
|
172
|
+
* build that never ran, and a zero would pass every limit.
|
|
173
|
+
*
|
|
174
|
+
* Targets nobody limited are left alone.
|
|
250
175
|
*/
|
|
251
176
|
export declare class EmptyTargetError extends Error {
|
|
252
177
|
constructor(target: string, metric: string);
|
|
253
178
|
}
|
|
254
179
|
|
|
255
|
-
/**
|
|
256
|
-
* What one limit found once it was pointed at its metric.
|
|
257
|
-
*
|
|
258
|
-
* A breach is one of these carrying `breached`, and it reports everything a
|
|
259
|
-
* breach has to: which metric, held to what, and what the metric actually
|
|
260
|
-
* measured. A limit that held is reported the same way, so a report can show
|
|
261
|
-
* the headroom rather than only the failures.
|
|
262
|
-
*/
|
|
180
|
+
/** One limit's result against its metric; a breach sets `breached`. */
|
|
263
181
|
export declare interface EvaluatedLimit {
|
|
264
182
|
/** Whether the measured value came out above the limit. */
|
|
265
183
|
breached: boolean;
|
|
@@ -280,61 +198,29 @@ declare interface EvaluateLimitsArguments {
|
|
|
280
198
|
}
|
|
281
199
|
|
|
282
200
|
/**
|
|
283
|
-
* Reads and applies gitignore-syntax rule sets without invoking git.
|
|
284
|
-
*
|
|
285
|
-
* Codometer used to hand this problem to `git ls-files`, which meant it could
|
|
286
|
-
* only measure a directory that was a git repository. Reading the syntax here
|
|
287
|
-
* is what lets it measure any directory at all, and it is the only reading of
|
|
288
|
-
* that syntax in the tool — there is no git fast path to disagree with.
|
|
201
|
+
* Reads and applies gitignore-syntax rule sets without invoking git, so any directory can be measured. It is the only reader of that syntax.
|
|
289
202
|
*/
|
|
290
203
|
declare class IgnoreRulesService {
|
|
291
204
|
constructor();
|
|
292
205
|
/**
|
|
293
|
-
* The path a rule set
|
|
294
|
-
*
|
|
295
|
-
* A rule set anchored at `projects/affirmancy` matches its patterns
|
|
296
|
-
* against `output/one.md`, not against the full path, because that is what
|
|
297
|
-
* the patterns in that directory's ignore file were written against.
|
|
206
|
+
* The path relative to a rule set's directory, or nothing when it lies outside. Patterns match against this, not the full path.
|
|
298
207
|
*/
|
|
299
208
|
private toScopedPath;
|
|
300
209
|
/**
|
|
301
|
-
* Builds a rule set from patterns
|
|
302
|
-
*
|
|
303
|
-
* Case-sensitive on every platform, deliberately. Git decides that from the
|
|
304
|
-
* filesystem it happens to be on, so the same ignore file can claim a
|
|
305
|
-
* different set of files on a developer's Mac and on Linux CI. A measurement
|
|
306
|
-
* that disagrees with itself between machines is worse than a strict one.
|
|
210
|
+
* Builds a rule set from patterns in hand. Always case-sensitive, so one ignore file claims the same files on every platform.
|
|
307
211
|
*/
|
|
308
212
|
createScope(args: CreateIgnoreScopeArguments): IgnoreScope;
|
|
309
213
|
/**
|
|
310
|
-
* Whether the rule sets ignore a path, the innermost
|
|
311
|
-
*
|
|
312
|
-
* gitignore resolution is nested rather than additive: a rule set in a
|
|
313
|
-
* subdirectory overrides the one above it, which is what lets a `!pattern`
|
|
314
|
-
* re-include a file its parent excluded. Reading the scopes outermost first
|
|
315
|
-
* and keeping the last decision reproduces that ordering.
|
|
316
|
-
*
|
|
317
|
-
* A directory is passed with a trailing slash, so a `build/` pattern claims
|
|
318
|
-
* the directory rather than only a file that happens to be named `build`.
|
|
214
|
+
* Whether the rule sets ignore a path, the innermost deciding. Scopes apply outermost first, so a nested `!pattern` can re-include a file.
|
|
319
215
|
*/
|
|
320
216
|
isIgnored(scopes: readonly IgnoreScope[], relativePath: string): boolean;
|
|
321
217
|
/**
|
|
322
|
-
* Reads a rule set
|
|
323
|
-
*
|
|
324
|
-
* Returns nothing when the file is absent, so a configured ignore file that
|
|
325
|
-
* was renamed is reported by the caller rather than silently behaving as an
|
|
326
|
-
* empty one.
|
|
218
|
+
* Reads a rule set from a gitignore-syntax file, or nothing when it is absent so the caller can report it.
|
|
327
219
|
*/
|
|
328
220
|
readScope(args: ReadIgnoreScopeArguments): IgnoreScope | undefined;
|
|
329
221
|
}
|
|
330
222
|
|
|
331
|
-
/**
|
|
332
|
-
* A gitignore-syntax rule set together with the directory it is anchored to.
|
|
333
|
-
*
|
|
334
|
-
* The directory matters because gitignore patterns are relative to the file
|
|
335
|
-
* they were written in: `/output` in a project's own ignore file claims that
|
|
336
|
-
* project's `output`, not the one at the repository root.
|
|
337
|
-
*/
|
|
223
|
+
/** `.gitignore` rules and the directory their patterns are relative to. */
|
|
338
224
|
declare interface IgnoreScope {
|
|
339
225
|
/** Directory the patterns are relative to, `/`-separated from the walk root. `""` is the root itself. */
|
|
340
226
|
directory: string;
|
|
@@ -344,12 +230,7 @@ declare interface IgnoreScope {
|
|
|
344
230
|
/** What a directory entry counts as while an input's tree is walked. */
|
|
345
231
|
export declare type InputEntryKind = "directory" | "file" | "other";
|
|
346
232
|
|
|
347
|
-
/**
|
|
348
|
-
* What every analysis declared for one input reported over its files.
|
|
349
|
-
*
|
|
350
|
-
* An analysis an input did not ask for reports `undefined` rather than a zero,
|
|
351
|
-
* so an input nobody measured the size of is never mistaken for an empty one.
|
|
352
|
-
*/
|
|
233
|
+
/** One input's analysis results; skipped ones are `undefined`, not zero. */
|
|
353
234
|
export declare interface InputMeasurement {
|
|
354
235
|
/** How many files the input's globs claimed. */
|
|
355
236
|
files: number;
|
|
@@ -359,14 +240,9 @@ export declare interface InputMeasurement {
|
|
|
359
240
|
}
|
|
360
241
|
|
|
361
242
|
/**
|
|
362
|
-
* Raised when an input
|
|
243
|
+
* Raised when an input reaches beyond the repository holding it.
|
|
363
244
|
*
|
|
364
|
-
* An input may
|
|
365
|
-
* project reaches build output written above it — but not out of the
|
|
366
|
-
* repository holding both. Beyond that boundary a configuration file could
|
|
367
|
-
* read any file on the machine and report its size, which is not a measurement
|
|
368
|
-
* anybody asked for and is exactly what a tool published as a shared action
|
|
369
|
-
* must not be able to do.
|
|
245
|
+
* An input may leave the measured folder, but reading outside the repository would let a shared action measure any file on the machine.
|
|
370
246
|
*/
|
|
371
247
|
export declare class InputOutsideRepositoryError extends Error {
|
|
372
248
|
constructor(input: string, directory: string, boundary: string);
|
|
@@ -389,56 +265,31 @@ export declare class InputsService {
|
|
|
389
265
|
private readonly logger;
|
|
390
266
|
constructor(logger: LoggerService);
|
|
391
267
|
/**
|
|
392
|
-
* Whether a directory can hold anything the input's globs claim.
|
|
393
|
-
*
|
|
394
|
-
* A hidden directory is only entered when a glob spells it out. That is what
|
|
395
|
-
* every glob library means by excluding dot files, and it is also what stops
|
|
396
|
-
* an input over the whole tree from reading the repository's git database.
|
|
268
|
+
* Whether a directory can hold anything the input's globs claim. A hidden directory is entered only when a glob names it.
|
|
397
269
|
*/
|
|
398
270
|
private canDescend;
|
|
399
271
|
/**
|
|
400
|
-
* The furthest
|
|
401
|
-
*
|
|
402
|
-
* The repository holding the measured directory, or that directory itself
|
|
403
|
-
* when nothing above it looks like one. Found by marker rather than by
|
|
404
|
-
* asking git, which is never invoked here, and generic to every repository —
|
|
405
|
-
* it says where measuring stops, not how any tree beneath it is arranged.
|
|
272
|
+
* The furthest an input may reach: the repository above the measured directory, found by marker files, or the directory itself.
|
|
406
273
|
*/
|
|
407
274
|
private findBoundary;
|
|
408
275
|
/** Whether the last segment of a path starts with a dot. */
|
|
409
276
|
private isHidden;
|
|
410
277
|
/**
|
|
411
|
-
* Whether a symbolic link points at a file.
|
|
412
|
-
*
|
|
413
|
-
* Links are followed, as every glob library does. Only to files, though: a
|
|
414
|
-
* link pointing back at one of its own ancestors would otherwise be walked
|
|
415
|
-
* until the stack ran out.
|
|
278
|
+
* Whether a symbolic link points at a file. Links are followed only to files, so a link back to an ancestor cannot recurse.
|
|
416
279
|
*/
|
|
417
280
|
private isLinkedFile;
|
|
418
281
|
/**
|
|
419
|
-
* Whether the input claims a file.
|
|
420
|
-
*
|
|
421
|
-
* Both lists are answered in full rather than in order, so where a pattern
|
|
422
|
-
* sits within either of them cannot change the answer.
|
|
282
|
+
* Whether the input claims a file. Both lists are answered in full, so pattern order cannot change the answer.
|
|
423
283
|
*/
|
|
424
284
|
private isMatched;
|
|
425
285
|
/** Whether the directory is on the way down to a glob's literal prefix. */
|
|
426
286
|
private leadsToBase;
|
|
427
287
|
/**
|
|
428
|
-
* Reads a directory's entries, or none when
|
|
429
|
-
*
|
|
430
|
-
* An input naming a directory that was never built is an ordinary state
|
|
431
|
-
* rather than a failure — it holds no files, and what that means is decided
|
|
432
|
-
* by whoever asked for the measurement.
|
|
288
|
+
* Reads a directory's entries, or none when it cannot be read. An input naming a directory not yet built simply holds no files.
|
|
433
289
|
*/
|
|
434
290
|
private readEntries;
|
|
435
291
|
/**
|
|
436
|
-
* The
|
|
437
|
-
*
|
|
438
|
-
* Empty when the input starts where the run does. Otherwise it is the walk
|
|
439
|
-
* root written relative to the measured directory — `../../dist` and the
|
|
440
|
-
* like — so that every path leaving this service is relative to the same
|
|
441
|
-
* directory whether or not the input reached outside it.
|
|
292
|
+
* The prefix every matched path carries, relative to the measured directory. Empty when the input starts where the run does.
|
|
442
293
|
*/
|
|
443
294
|
private readInputPrefix;
|
|
444
295
|
/** What a directory entry counts as, once any link has been followed. */
|
|
@@ -448,52 +299,25 @@ export declare class InputsService {
|
|
|
448
299
|
/** Whether a directory is the boundary or sits somewhere beneath it. */
|
|
449
300
|
private sitsInsideBoundary;
|
|
450
301
|
/**
|
|
451
|
-
* The literal path prefix of a glob, up to its first magic character.
|
|
452
|
-
*
|
|
453
|
-
* `dist/projects/common/observability/**` can only match inside `dist/projects/common/observability`, so
|
|
454
|
-
* that is the only branch of the tree worth reading — the difference between
|
|
455
|
-
* measuring one build directory and enumerating every dependency to find it.
|
|
302
|
+
* The literal path prefix of a glob, up to its first magic character. Only that branch of the tree needs reading.
|
|
456
303
|
*/
|
|
457
304
|
private toIncludeBase;
|
|
458
305
|
/** Collects every file one directory of the input's tree contributes. */
|
|
459
306
|
private walk;
|
|
460
307
|
/**
|
|
461
|
-
* Lists the files an input holds, sorted, relative to the measured directory.
|
|
462
|
-
*
|
|
463
|
-
* The walk starts at the input's own directory, which is the measured one
|
|
464
|
-
* unless the input named a way out of it. Where a repository builds is a
|
|
465
|
-
* convention its configuration states and this service is told, never one
|
|
466
|
-
* inferred here from a project's position — but the reach is bounded: a
|
|
467
|
-
* directory landing outside the repository fails the input by name rather
|
|
468
|
-
* than measuring whatever it found there.
|
|
469
|
-
*
|
|
470
|
-
* Sorted because the walk visits directories in whatever order the
|
|
471
|
-
* filesystem reports them, and a size is a sum of every file either way —
|
|
472
|
-
* but a list nobody can predict is one nobody can compare.
|
|
308
|
+
* Lists the files an input holds, sorted, relative to the measured directory. The walk may reach outside it, but never beyond the repository.
|
|
473
309
|
*/
|
|
474
310
|
matchFiles(args: MatchInputFilesArguments): string[];
|
|
475
311
|
}
|
|
476
312
|
|
|
477
|
-
/**
|
|
478
|
-
* One limit that could not be held against anything.
|
|
479
|
-
*
|
|
480
|
-
* Collected rather than thrown. A configuration carrying three limits that
|
|
481
|
-
* bind to nothing is three mistakes to fix, and reporting only the first turns
|
|
482
|
-
* one repair into three runs.
|
|
483
|
-
*/
|
|
313
|
+
/** A limit that bound to nothing, collected rather than thrown. */
|
|
484
314
|
declare interface LimitFailure {
|
|
485
315
|
/** The dotted path exactly as the limit was written. */
|
|
486
316
|
metric: string;
|
|
487
317
|
reason: string;
|
|
488
318
|
}
|
|
489
319
|
|
|
490
|
-
/**
|
|
491
|
-
* What every declared limit found, alongside the ones that bound to nothing.
|
|
492
|
-
*
|
|
493
|
-
* Both lists are always present. A limit that could not be bound is neither a
|
|
494
|
-
* breach nor a pass, and reporting it as either would be a gate whose verdict
|
|
495
|
-
* nobody could trust.
|
|
496
|
-
*/
|
|
320
|
+
/** Every limit's result, with unbound limits neither breached nor passed. */
|
|
497
321
|
declare interface LimitsEvaluation {
|
|
498
322
|
failures: LimitFailure[];
|
|
499
323
|
limits: EvaluatedLimit[];
|
|
@@ -508,10 +332,9 @@ export declare class LimitsModule {
|
|
|
508
332
|
/**
|
|
509
333
|
* Holds measured metrics to the limits declared against them.
|
|
510
334
|
*
|
|
511
|
-
* Every metric is addressable
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
* worth is the caller's to say.
|
|
335
|
+
* Every metric is addressable by a dotted path of target and metric name.
|
|
336
|
+
* Nothing here decides what a breach costs: it reports which limits were
|
|
337
|
+
* exceeded and by how much; the caller decides the rest.
|
|
515
338
|
*/
|
|
516
339
|
export declare class LimitsService {
|
|
517
340
|
constructor();
|
|
@@ -524,56 +347,24 @@ export declare class LimitsService {
|
|
|
524
347
|
/** Names every measured target, for an error that has to list them. */
|
|
525
348
|
private describeTargets;
|
|
526
349
|
/**
|
|
527
|
-
* Every metric a written path could mean.
|
|
528
|
-
*
|
|
529
|
-
* Each target is asked whether the path starts with its name, rather than
|
|
530
|
-
* the path being split at its first dot: a target's name may hold a dot of
|
|
531
|
-
* its own, and so may the metric path that follows it. Whatever the shapes
|
|
532
|
-
* involved, every reading is collected and none of them is preferred.
|
|
350
|
+
* Every metric a written path could mean. Targets match by name prefix, never by splitting at the first dot.
|
|
533
351
|
*/
|
|
534
352
|
private findCandidates;
|
|
535
353
|
/**
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
* A default target that was never measured is refused rather than ignored:
|
|
539
|
-
* ignoring it would turn every unqualified path in the configuration into an
|
|
540
|
-
* unresolvable one, and report the paths instead of the reason.
|
|
354
|
+
* The path read as the default target's metric, if one is set. An unmeasured default is refused, not ignored.
|
|
541
355
|
*/
|
|
542
356
|
private findDefaultCandidate;
|
|
543
357
|
/**
|
|
544
|
-
* Points one written path at exactly one measured metric.
|
|
545
|
-
*
|
|
546
|
-
* Ambiguity is refused rather than settled by a rule about which reading
|
|
547
|
-
* wins. Any such rule would be invisible in the configuration file, and a
|
|
548
|
-
* limit holding a metric nobody meant to limit reads exactly like one that
|
|
549
|
-
* works.
|
|
358
|
+
* Points one written path at exactly one measured metric. Ambiguity is refused, never settled by a hidden rule.
|
|
550
359
|
*/
|
|
551
360
|
private resolve;
|
|
552
361
|
/**
|
|
553
|
-
* Holds every declared limit against
|
|
554
|
-
*
|
|
555
|
-
* Returns what each limit found rather than a verdict. Severity is carried
|
|
556
|
-
* through untouched: whether a breach stops the run is a decision about the
|
|
557
|
-
* run, not about the measurement.
|
|
558
|
-
*
|
|
559
|
-
* A limit that binds to nothing joins `failures` and the rest are evaluated
|
|
560
|
-
* anyway, so one run names every path in a configuration that binds to
|
|
561
|
-
* nothing instead of the first one and nothing after it.
|
|
362
|
+
* Holds every declared limit against its metric, returning what each found. Unbound limits are collected, not thrown.
|
|
562
363
|
*/
|
|
563
364
|
evaluate(args: EvaluateLimitsArguments): LimitsEvaluation;
|
|
564
365
|
}
|
|
565
366
|
|
|
566
|
-
/**
|
|
567
|
-
* Structured values that belong beside a log line rather than inside it.
|
|
568
|
-
*
|
|
569
|
-
* Counts, percentages, and durations are the values that change on every
|
|
570
|
-
* occurrence, so they are carried as fields: the message stays constant and
|
|
571
|
-
* groupable in telemetry, and the numbers stay queryable instead of having to
|
|
572
|
-
* be parsed back out of prose.
|
|
573
|
-
*
|
|
574
|
-
* The named members are the recurring ones; the index signature keeps the
|
|
575
|
-
* argument open for whatever a given call site needs to attach.
|
|
576
|
-
*/
|
|
367
|
+
/** Values beside the log line, kept as queryable fields. */
|
|
577
368
|
declare interface LogData {
|
|
578
369
|
[key: string]: unknown;
|
|
579
370
|
/** How many things the operation handled. */
|
|
@@ -587,20 +378,10 @@ declare interface LogData {
|
|
|
587
378
|
}
|
|
588
379
|
|
|
589
380
|
/**
|
|
590
|
-
* Transient
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
-
* Messages follow one grammar: an emoji naming the subject, a verb in present
|
|
596
|
-
* progressive or past tense, then the object. Values that vary per call —
|
|
597
|
-
* counts, percentages, durations — go in the `data` argument rather than the
|
|
598
|
-
* message, so the message stays constant enough for telemetry to group on.
|
|
599
|
-
*
|
|
600
|
-
* ```ts
|
|
601
|
-
* this.logger.info("📥 Downloading CSEL sources", undefined, { total: 428 });
|
|
602
|
-
* this.logger.info("📥 Downloaded CSEL sources", undefined, { count: 412 });
|
|
603
|
-
* ```
|
|
381
|
+
* Transient logger, so each injecting class gets its own instance. Consumers
|
|
382
|
+
* call `setContext(ClassName.name)`. Backed by pino: JSON in production,
|
|
383
|
+
* pretty-printed in development. Messages start with an emoji naming the subject,
|
|
384
|
+
* then a present or past-tense verb. Varying values such as counts go in `data`.
|
|
604
385
|
*/
|
|
605
386
|
declare @Injectable({ scope: Scope.TRANSIENT })
|
|
606
387
|
class LoggerService
|
|
@@ -618,12 +399,7 @@ implements LoggerServiceContract
|
|
|
618
399
|
private static readonly isProduction =
|
|
619
400
|
process.env["NODE_ENV"] === "production";
|
|
620
401
|
|
|
621
|
-
/**
|
|
622
|
-
* Built on first use, not when this file is evaluated.
|
|
623
|
-
*
|
|
624
|
-
* A destination fixed at import time could only ever be chosen by this
|
|
625
|
-
* package, since every consumer's own code runs after its imports.
|
|
626
|
-
*/
|
|
402
|
+
/** Built lazily, so `logToStandardError` can still set the destination. */
|
|
627
403
|
private static rootLogger: pino.Logger | undefined;
|
|
628
404
|
|
|
629
405
|
/** Whether lines go to standard error instead of standard output. */
|
|
@@ -666,18 +442,8 @@ implements LoggerServiceContract
|
|
|
666
442
|
}
|
|
667
443
|
|
|
668
444
|
/**
|
|
669
|
-
* Sends
|
|
670
|
-
*
|
|
671
|
-
* For a command-line application whose standard output *is* its result. A log
|
|
672
|
-
* line sharing that stream is not a diagnostic beside the data, it is a
|
|
673
|
-
* corruption of it. Call it before anything logs — the first statement of the
|
|
674
|
-
* application's bootstrap.
|
|
675
|
-
*
|
|
676
|
-
* A call after the first line warns and changes nothing: the destination is
|
|
677
|
-
* fixed when the pino instance is built, and tearing down a transport
|
|
678
|
-
* somebody is writing through would be worse than refusing. The warning is
|
|
679
|
-
* the point — silently leaving the lines on standard output is how a caller
|
|
680
|
-
* would ship a corrupted pipe without ever being told.
|
|
445
|
+
* Sends later lines to standard error, for a command whose stdout is its
|
|
446
|
+
* result. Call it first; later calls warn and change nothing.
|
|
681
447
|
*/
|
|
682
448
|
static logToStandardError(): void {
|
|
683
449
|
if (LoggerService.rootLogger !== undefined) {
|
|
@@ -691,10 +457,8 @@ implements LoggerServiceContract
|
|
|
691
457
|
}
|
|
692
458
|
|
|
693
459
|
/**
|
|
694
|
-
* Fails a malformed message in development,
|
|
695
|
-
*
|
|
696
|
-
* A logger that throws in production turns an observability call into an
|
|
697
|
-
* outage, so the check runs only where a developer is present to fix it.
|
|
460
|
+
* Fails a malformed message in development only, since a throw in production
|
|
461
|
+
* would turn logging into an outage.
|
|
698
462
|
*/
|
|
699
463
|
private assertConventionalMessage(args: {
|
|
700
464
|
context: string | undefined;
|
|
@@ -754,11 +518,8 @@ implements LoggerServiceContract
|
|
|
754
518
|
}
|
|
755
519
|
|
|
756
520
|
/**
|
|
757
|
-
* Whether a word is a
|
|
758
|
-
*
|
|
759
|
-
* Present progressive means the operation is under way; past means it
|
|
760
|
-
* finished. Regular morphology covers both, so a new verb needs no
|
|
761
|
-
* registration anywhere — only irregular pasts are enumerated.
|
|
521
|
+
* Whether a word is a present-progressive or past-tense verb. Only irregular
|
|
522
|
+
* pasts need listing; regular morphology covers the rest.
|
|
762
523
|
*/
|
|
763
524
|
private isConventionalVerb(word: string): boolean {
|
|
764
525
|
const lowercased = word.toLowerCase();
|
|
@@ -834,11 +595,8 @@ implements LoggerServiceContract
|
|
|
834
595
|
}
|
|
835
596
|
|
|
836
597
|
/**
|
|
837
|
-
* Logs
|
|
838
|
-
*
|
|
839
|
-
* `ConsoleLogger.error` spends a third slot on a context string that the
|
|
840
|
-
* other levels do not have, so this one accepts either: a string keeps
|
|
841
|
-
* NestJS's meaning, an object is structured data like everywhere else.
|
|
598
|
+
* Logs at the `error` level. The second argument is a stack, the third a
|
|
599
|
+
* context string or structured data.
|
|
842
600
|
*/
|
|
843
601
|
override error(
|
|
844
602
|
message: unknown,
|
|
@@ -869,12 +627,8 @@ implements LoggerServiceContract
|
|
|
869
627
|
}
|
|
870
628
|
|
|
871
629
|
/**
|
|
872
|
-
* Logs
|
|
873
|
-
*
|
|
874
|
-
* NestJS and `nest-commander` call this method directly as part of the
|
|
875
|
-
* framework's own `LoggerService` contract, so it must keep working
|
|
876
|
-
* exactly as before. Application code should call `info` instead — the
|
|
877
|
-
* same behavior under a name that says what level it logs at.
|
|
630
|
+
* Logs at the `info` level, as NestJS and `nest-commander` call it.
|
|
631
|
+
* Application code should call `info` instead.
|
|
878
632
|
*/
|
|
879
633
|
override log(message: unknown, context?: string, data?: LogData): void {
|
|
880
634
|
this.info(message, context, data);
|
|
@@ -905,7 +659,7 @@ implements LoggerServiceContract
|
|
|
905
659
|
}
|
|
906
660
|
}
|
|
907
661
|
|
|
908
|
-
/**
|
|
662
|
+
/** Public logger shape, for test doubles without the service. */
|
|
909
663
|
declare interface LoggerServiceContract extends ConsoleLogger {
|
|
910
664
|
/** Normalizes unknown errors into a stable message and timestamped log line. */
|
|
911
665
|
buildErrorLogEntry(
|
|
@@ -934,21 +688,13 @@ export declare interface MeasureArguments {
|
|
|
934
688
|
/**
|
|
935
689
|
* Files codometer writes itself, relative to the measured directory.
|
|
936
690
|
*
|
|
937
|
-
* Never measured,
|
|
938
|
-
* measured a different tree depending on its flags could not tell a stale
|
|
939
|
-
* report from a report written by a differently-flagged run.
|
|
691
|
+
* Never measured, so flags never change what is measured.
|
|
940
692
|
*/
|
|
941
693
|
outputPaths: readonly string[];
|
|
942
694
|
workingDirectory: string;
|
|
943
695
|
}
|
|
944
696
|
|
|
945
|
-
/**
|
|
946
|
-
* What one target measured, as the limits layer reads it.
|
|
947
|
-
*
|
|
948
|
-
* Declared here rather than imported from the measurement pipeline: gating a
|
|
949
|
-
* number needs the number and its target's name, and nothing about how either
|
|
950
|
-
* was produced.
|
|
951
|
-
*/
|
|
697
|
+
/** One target's measurements, as the limits layer reads them. */
|
|
952
698
|
declare interface MeasuredTarget {
|
|
953
699
|
files: number;
|
|
954
700
|
language: CodeStatisticsResult | undefined;
|
|
@@ -956,21 +702,12 @@ declare interface MeasuredTarget {
|
|
|
956
702
|
size: SizeResult | undefined;
|
|
957
703
|
}
|
|
958
704
|
|
|
959
|
-
/**
|
|
960
|
-
* Everything one run measured, input by input.
|
|
961
|
-
*
|
|
962
|
-
* `statistics` is the `codebase` input's own language metrics, which is the
|
|
963
|
-
* report every consumer renders today. It is the same object that input
|
|
964
|
-
* carries, held out separately so nothing downstream has to know which input
|
|
965
|
-
* it came from.
|
|
966
|
-
*/
|
|
705
|
+
/** Everything one run measured, input by input; `statistics` stands apart. */
|
|
967
706
|
export declare interface MeasurementResult {
|
|
968
707
|
/**
|
|
969
|
-
*
|
|
708
|
+
* What the run could not do, collected rather than thrown.
|
|
970
709
|
*
|
|
971
|
-
*
|
|
972
|
-
* recorded here and stepped over, so one run names every one of them instead
|
|
973
|
-
* of stopping at the first and hiding the rest behind it.
|
|
710
|
+
* One run names every failure rather than stopping at the first.
|
|
974
711
|
*/
|
|
975
712
|
failures: ReportFailure[];
|
|
976
713
|
/** Every metric each measured input counted, addressable by dotted path. */
|
|
@@ -978,24 +715,18 @@ export declare interface MeasurementResult {
|
|
|
978
715
|
/** Every input measured, in the order `inputs` declared them. */
|
|
979
716
|
inputs: InputMeasurement[];
|
|
980
717
|
/**
|
|
981
|
-
* What every declared limit found, in
|
|
718
|
+
* What every declared limit found, in declaration order.
|
|
982
719
|
*
|
|
983
|
-
* Empty when
|
|
984
|
-
* no limit is measured and reported like every other, and gated by nothing.
|
|
720
|
+
* Empty when none is declared, which is the ordinary case.
|
|
985
721
|
*/
|
|
986
722
|
limits: EvaluatedLimit[];
|
|
987
723
|
statistics: CodeStatisticsResult;
|
|
988
724
|
}
|
|
989
725
|
|
|
990
726
|
/**
|
|
991
|
-
* Wires every analyzer a measurement run joins, and the service that joins
|
|
992
|
-
* them.
|
|
727
|
+
* Wires every analyzer a measurement run joins, and the service that joins them.
|
|
993
728
|
*
|
|
994
|
-
*
|
|
995
|
-
* files, the language and size analyzers count them, the custom counters add
|
|
996
|
-
* whatever a configuration declared, and the limits layer holds the result to
|
|
997
|
-
* what the configuration gates. None of the five imports another, which is why
|
|
998
|
-
* the join lives here rather than inside one of them.
|
|
729
|
+
* Discovery, language, size, custom counters, and limits; none imports another, so the join lives here.
|
|
999
730
|
*/
|
|
1000
731
|
export declare class MeasureModule {
|
|
1001
732
|
}
|
|
@@ -1003,12 +734,7 @@ export declare class MeasureModule {
|
|
|
1003
734
|
/**
|
|
1004
735
|
* Aggregates every analyzer's report into a single set of statistics.
|
|
1005
736
|
*
|
|
1006
|
-
* The one place the
|
|
1007
|
-
* meet. None of the four imports another, so joining them has to happen
|
|
1008
|
-
* somewhere, and a call-stack trace reports that join as module spread against
|
|
1009
|
-
* `measureInput` and `analyzeFiles` — the two methods that personally name
|
|
1010
|
-
* three of the four. That is the arrangement working, not drifting: pushing the
|
|
1011
|
-
* join down into one of the analyzers is what would couple them to each other.
|
|
737
|
+
* The one place the analyzers meet. None imports another, so the join lives here.
|
|
1012
738
|
*/
|
|
1013
739
|
export declare class MeasureService {
|
|
1014
740
|
private readonly discoveryService;
|
|
@@ -1020,17 +746,7 @@ export declare class MeasureService {
|
|
|
1020
746
|
private readonly metricIndexService;
|
|
1021
747
|
constructor(discoveryService: DiscoveryService, languagesService: LanguagesService, customizationService: CustomizationService, inputsService: InputsService, sizeService: SizeService, limitsService: LimitsService, metricIndexService: MetricIndexService);
|
|
1022
748
|
/**
|
|
1023
|
-
*
|
|
1024
|
-
*
|
|
1025
|
-
* Three analyzers, not one: the language analyzers, the size analyzer that
|
|
1026
|
-
* produces the headline byte total, and the custom counters a configuration
|
|
1027
|
-
* declares. Named for the file set rather than for any of the three, because
|
|
1028
|
-
* this sits directly above `LanguagesService.analyze` in every measurement
|
|
1029
|
-
* stack — named for a language it reads there as a forwarding layer instead
|
|
1030
|
-
* of as the place all three are joined.
|
|
1031
|
-
*
|
|
1032
|
-
* Takes the files it is given rather than finding them, so the codebase and
|
|
1033
|
-
* an input naming compiled output are counted by exactly the same analyzers.
|
|
749
|
+
* Runs every analyzer over one file set and shapes the result. Takes the files it is given, so codebase and input are counted identically.
|
|
1034
750
|
*/
|
|
1035
751
|
private analyzeFiles;
|
|
1036
752
|
/** Project the TypeScript analyzer's counters onto the JavaScript group. */
|
|
@@ -1040,22 +756,11 @@ export declare class MeasureService {
|
|
|
1040
756
|
/** Reads whatever an input's measurement threw as a printable sentence. */
|
|
1041
757
|
private describeFailure;
|
|
1042
758
|
/**
|
|
1043
|
-
* Discovers one input's files, minus
|
|
1044
|
-
*
|
|
1045
|
-
* The built-in `codebase` input is discovered by whatever its ignore files
|
|
1046
|
-
* leave behind rather than by matching its own `include`/`exclude` globs —
|
|
1047
|
-
* those stay placeholders for that one input, exactly as
|
|
1048
|
-
* `@codometer/configuration` documents. Every other input's files are
|
|
1049
|
-
* whatever its globs claim.
|
|
759
|
+
* Discovers one input's files, minus codometer's own outputs. The built-in `codebase` input uses its ignore files, not its globs.
|
|
1050
760
|
*/
|
|
1051
761
|
private discoverInputFiles;
|
|
1052
762
|
/**
|
|
1053
|
-
* Drops
|
|
1054
|
-
*
|
|
1055
|
-
* Codometer's reports are made of what it measured, so measuring them makes
|
|
1056
|
-
* every report an input to the next one: a badge block changes the markdown
|
|
1057
|
-
* counters, which changes the badges. Removing them is what makes a second
|
|
1058
|
-
* run over an untouched tree produce the same bytes as the first.
|
|
763
|
+
* Drops codometer's own report files from measured ones, so a second run over an untouched tree yields the same bytes.
|
|
1059
764
|
*/
|
|
1060
765
|
private excludeOutputPaths;
|
|
1061
766
|
/**
|
|
@@ -1063,11 +768,7 @@ export declare class MeasureService {
|
|
|
1063
768
|
*/
|
|
1064
769
|
private getFolderCount;
|
|
1065
770
|
/**
|
|
1066
|
-
*
|
|
1067
|
-
*
|
|
1068
|
-
* An analysis nobody asked for is not run at all. Compressing a source tree
|
|
1069
|
-
* to answer a question nobody put costs more than every other analysis put
|
|
1070
|
-
* together.
|
|
771
|
+
* Measures one declared input with only the analyses it asked for. An analysis nobody requested is never run.
|
|
1071
772
|
*/
|
|
1072
773
|
private measureInput;
|
|
1073
774
|
/** Restates the limits layer's failures in the report's own vocabulary. */
|
|
@@ -1075,14 +776,7 @@ export declare class MeasureService {
|
|
|
1075
776
|
/** Whether an input asked for one of the analyses. */
|
|
1076
777
|
private runsAnalysis;
|
|
1077
778
|
/**
|
|
1078
|
-
*
|
|
1079
|
-
*
|
|
1080
|
-
* The built-in `codebase` input is not special-cased here — resolution
|
|
1081
|
-
* already prepends it unless a configuration replaces it by name, so this
|
|
1082
|
-
* simply measures whichever inputs it was handed, in the order given. An
|
|
1083
|
-
* input that cannot be measured — a glob pointing at a directory that
|
|
1084
|
-
* vanished, a file that will not open — is recorded and stepped over, so one
|
|
1085
|
-
* unreadable file never takes the whole run with it.
|
|
779
|
+
* Measures every declared input in declaration order. A failing input is recorded and skipped, so one bad file cannot end the run.
|
|
1086
780
|
*/
|
|
1087
781
|
measure(args: MeasureArguments): MeasurementResult;
|
|
1088
782
|
}
|
|
@@ -1097,62 +791,39 @@ declare interface MetricIndexResult {
|
|
|
1097
791
|
/**
|
|
1098
792
|
* Makes every measured number addressable by a dotted path.
|
|
1099
793
|
*
|
|
1100
|
-
*
|
|
1101
|
-
*
|
|
1102
|
-
*
|
|
1103
|
-
* way, so the naming lives here rather than in either caller.
|
|
794
|
+
* One index answers both which metric a limit targets and which metrics the
|
|
795
|
+
* report lists. Both need every number named the same way, so the naming lives
|
|
796
|
+
* here, not in either caller.
|
|
1104
797
|
*/
|
|
1105
798
|
export declare class MetricIndexService {
|
|
1106
799
|
constructor();
|
|
1107
800
|
/**
|
|
1108
|
-
* Records one metric,
|
|
1109
|
-
*
|
|
1110
|
-
* Two counters sharing a path is a configuration mistake rather than a
|
|
1111
|
-
* measurement one — two statistics with the same label — and it is caught
|
|
1112
|
-
* here so that a limit addressing that path is refused instead of being
|
|
1113
|
-
* given whichever counter was indexed first.
|
|
801
|
+
* Records one metric. A path already answered is marked ambiguous, so a limit addressing it is refused rather than given the first counter.
|
|
1114
802
|
*/
|
|
1115
803
|
private addMetric;
|
|
1116
804
|
/**
|
|
1117
|
-
* Indexes every metric one target measured, by
|
|
1118
|
-
*
|
|
1119
|
-
* An analysis the target never ran contributes nothing, so a limit written
|
|
1120
|
-
* against it is refused rather than being compared against a zero the target
|
|
1121
|
-
* never reported.
|
|
805
|
+
* Indexes every metric one target measured, by path. An analysis the target never ran is refused, not compared as zero.
|
|
1122
806
|
*/
|
|
1123
807
|
private buildTargetIndex;
|
|
1124
808
|
/**
|
|
1125
|
-
* Explains a name two measured targets both answered to.
|
|
1126
|
-
*
|
|
1127
|
-
* Written where the collision is found rather than raised as an error: the
|
|
1128
|
-
* run carries on with the first target of that name, and this is what the
|
|
1129
|
-
* report says about the one it had to drop.
|
|
809
|
+
* Explains a name two measured targets both answered to. The second target is dropped; the run continues with the first.
|
|
1130
810
|
*/
|
|
1131
811
|
private describeDuplicate;
|
|
1132
812
|
/** Indexes a group of counters, descending into the nested ones. */
|
|
1133
813
|
private indexCounters;
|
|
1134
814
|
/**
|
|
1135
|
-
* Indexes everything language analysis counted.
|
|
1136
|
-
*
|
|
1137
|
-
* Configured counters are indexed under a prefix rather than beside the
|
|
1138
|
-
* built-in ones, so a counter labelled `files` cannot take the path the file
|
|
1139
|
-
* count already answers to.
|
|
815
|
+
* Indexes everything language analysis counted. Configured counters sit under a prefix, so a counter named `files` cannot shadow the file count.
|
|
1140
816
|
*/
|
|
1141
817
|
private indexLanguage;
|
|
1142
818
|
/** Whether a statistics entry holds counters of its own. */
|
|
1143
819
|
private isCounterGroup;
|
|
1144
820
|
/**
|
|
1145
|
-
* Indexes every measured target
|
|
1146
|
-
*
|
|
1147
|
-
* A repeated name is collected rather than thrown, so a run reports every
|
|
1148
|
-
* naming collision it found instead of the first one. The later target is
|
|
1149
|
-
* dropped: a metric is addressed by its target's name, so a name answering
|
|
1150
|
-
* to two targets can address neither.
|
|
821
|
+
* Indexes every measured target by name. A repeated name is collected rather than thrown, and the later target is dropped.
|
|
1151
822
|
*/
|
|
1152
823
|
index(targets: readonly MeasuredTarget[]): MetricIndexResult;
|
|
1153
824
|
}
|
|
1154
825
|
|
|
1155
|
-
/**
|
|
826
|
+
/** Message split into emoji and the prose telemetry stores. */
|
|
1156
827
|
declare interface ParsedLogMessage {
|
|
1157
828
|
emoji: string | undefined;
|
|
1158
829
|
text: string;
|
|
@@ -1175,9 +846,7 @@ export declare interface SizeResult {
|
|
|
1175
846
|
/**
|
|
1176
847
|
* Total bytes the target's files occupy under the chosen compression.
|
|
1177
848
|
*
|
|
1178
|
-
* A sum of separately compressed files
|
|
1179
|
-
* them: a browser fetches each file on its own, so compressing them together
|
|
1180
|
-
* would report a number no client ever receives.
|
|
849
|
+
* A sum of separately compressed files, as browsers fetch them.
|
|
1181
850
|
*/
|
|
1182
851
|
bytes: number;
|
|
1183
852
|
compression: CodometerCompression;
|
|
@@ -1189,28 +858,15 @@ export declare class SizeService {
|
|
|
1189
858
|
private readonly logger;
|
|
1190
859
|
constructor(logger: LoggerService);
|
|
1191
860
|
/**
|
|
1192
|
-
* Compresses one file's contents and
|
|
1193
|
-
*
|
|
1194
|
-
* Written as a lookup rather than a switch so that a compression added to
|
|
1195
|
-
* the configuration without an implementation here fails to compile, instead
|
|
1196
|
-
* of falling through to whichever branch happened to be last.
|
|
861
|
+
* Compresses one file's contents and returns the byte count. A lookup, not a switch, so a missing compressor fails to compile.
|
|
1197
862
|
*/
|
|
1198
863
|
private compress;
|
|
1199
864
|
/**
|
|
1200
|
-
* Measures one file, or fails the run.
|
|
1201
|
-
*
|
|
1202
|
-
* A file can vanish between being matched and being read — a build running
|
|
1203
|
-
* beside the measurement is enough. Skipping it would report a total short
|
|
1204
|
-
* by that file while still counting it, which is a number that looks
|
|
1205
|
-
* consistent and lets a real breach through. Failing is the lesser harm.
|
|
865
|
+
* Measures one file, or fails the run. Skipping a vanished file would understate the total, so failing is the lesser harm.
|
|
1206
866
|
*/
|
|
1207
867
|
private measureFile;
|
|
1208
868
|
/**
|
|
1209
|
-
* Measures every file of a target and sums the results.
|
|
1210
|
-
*
|
|
1211
|
-
* Each file is compressed on its own. Compressing them together would let
|
|
1212
|
-
* one file's dictionary shrink the next, reporting a total smaller than
|
|
1213
|
-
* anything that will ever be transferred.
|
|
869
|
+
* Measures every file of a target and sums the results. Each file is compressed alone, since shared compression would shrink later files.
|
|
1214
870
|
*/
|
|
1215
871
|
analyze(args: AnalyzeSizeArguments): SizeResult;
|
|
1216
872
|
}
|
|
@@ -1220,20 +876,14 @@ export declare interface TargetMetricIndex {
|
|
|
1220
876
|
/**
|
|
1221
877
|
* Paths more than one metric answers to, which no limit may address.
|
|
1222
878
|
*
|
|
1223
|
-
* Two
|
|
1224
|
-
* metric would be a defensible binding, which is exactly why neither is.
|
|
879
|
+
* Two counters sharing a label cause this.
|
|
1225
880
|
*/
|
|
1226
881
|
ambiguous: Set<string>;
|
|
1227
882
|
files: number;
|
|
1228
883
|
/**
|
|
1229
|
-
*
|
|
1230
|
-
* same dotted path `metrics` uses.
|
|
884
|
+
* Per-instance measurements of each metric, keyed by its dotted path.
|
|
1231
885
|
*
|
|
1232
|
-
*
|
|
1233
|
-
* `comment` selector today, and any future selector that measures more
|
|
1234
|
-
* than a count. A metric with no entry counted matches and nothing more,
|
|
1235
|
-
* so a consumer reading this map can tell the two apart without reading
|
|
1236
|
-
* the configuration that produced either.
|
|
886
|
+
* Present only for metrics a per-instance selector produced.
|
|
1237
887
|
*/
|
|
1238
888
|
instances: Map<string, CustomStatisticResultInstance[]>;
|
|
1239
889
|
metrics: Map<string, number>;
|
|
@@ -1242,10 +892,9 @@ export declare interface TargetMetricIndex {
|
|
|
1242
892
|
/**
|
|
1243
893
|
* Raised when a limit's dotted path does not name exactly one metric.
|
|
1244
894
|
*
|
|
1245
|
-
*
|
|
1246
|
-
*
|
|
1247
|
-
*
|
|
1248
|
-
* nobody would ever discover was wrong.
|
|
895
|
+
* A path naming nothing gates nothing while looking like a gate. A path naming
|
|
896
|
+
* several would have to pick one, and a limit quietly holding the wrong metric
|
|
897
|
+
* would never be discovered.
|
|
1249
898
|
*/
|
|
1250
899
|
export declare class UnboundMetricError extends Error {
|
|
1251
900
|
constructor(path: string, reason: string);
|
|
@@ -1254,11 +903,11 @@ export declare class UnboundMetricError extends Error {
|
|
|
1254
903
|
/**
|
|
1255
904
|
* Raised when a file a target matched cannot be read.
|
|
1256
905
|
*
|
|
1257
|
-
* Louder than
|
|
1258
|
-
*
|
|
1259
|
-
*
|
|
1260
|
-
*
|
|
1261
|
-
* breach pass.
|
|
906
|
+
* Louder than discovery's directory tolerance, on purpose: an unreadable
|
|
907
|
+
* directory narrows the measurement, while an unreadable matched file makes the
|
|
908
|
+
* total wrong.
|
|
909
|
+
*
|
|
910
|
+
* Quietly short by one file, a number would let a breach pass.
|
|
1262
911
|
*/
|
|
1263
912
|
export declare class UnreadableTargetFileError extends Error {
|
|
1264
913
|
constructor(filePath: string, reason: string);
|
|
@@ -1281,8 +930,7 @@ export declare interface WalkInputArguments {
|
|
|
1281
930
|
/**
|
|
1282
931
|
* The literal path prefix of each include glob.
|
|
1283
932
|
*
|
|
1284
|
-
* A
|
|
1285
|
-
* leading to a prefix nor sitting inside one holds nothing the input wants.
|
|
933
|
+
* A directory holding nothing under that prefix can be skipped.
|
|
1286
934
|
*/
|
|
1287
935
|
includeBases: readonly string[];
|
|
1288
936
|
input: ResolvedCodometerInput;
|
package/package.json
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
"url": "https://github.com/organizzolini/codebase/issues"
|
|
5
5
|
},
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@codometer/configuration": "0.0.
|
|
8
|
-
"@codometer/core": "0.0.
|
|
9
|
-
"@codometer/languages": "0.0.
|
|
7
|
+
"@codometer/configuration": "0.0.79",
|
|
8
|
+
"@codometer/core": "0.0.79",
|
|
9
|
+
"@codometer/languages": "0.0.79",
|
|
10
10
|
"@nestjs/common": "^11.1.21 || ^12.0.1",
|
|
11
11
|
"ignore": "7.0.14",
|
|
12
12
|
"pino": "^10.3.1",
|
|
@@ -64,5 +64,5 @@
|
|
|
64
64
|
"strict": true
|
|
65
65
|
},
|
|
66
66
|
"types": "./dist/src/index.d.ts",
|
|
67
|
-
"version": "0.0.
|
|
67
|
+
"version": "0.0.79"
|
|
68
68
|
}
|