@codometer/core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +335 -0
- package/dist/src/index.d.ts +511 -0
- package/dist/src/index.js +82 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Jimmy Paolini
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
# @codometer/core
|
|
2
|
+
|
|
3
|
+
The contracts leaf of the codometer toolchain. It holds what a measurement
|
|
4
|
+
**produces** β the per-language statistics groups, the report vocabulary a
|
|
5
|
+
consumer joins across runs, and the errors a configuration is refused with β
|
|
6
|
+
and nothing that runs.
|
|
7
|
+
|
|
8
|
+
No service and no NestJS module lives here, which is what makes it a leaf every
|
|
9
|
+
other codometer package may reach without dragging a container behind it. The
|
|
10
|
+
test that decides whether a declaration belongs here is sharp: a type the tool
|
|
11
|
+
produces is core, and a value somebody writes in `codometer.config.ts` is
|
|
12
|
+
configuration.
|
|
13
|
+
|
|
14
|
+
## Test
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
nx run codometer-core:vitest
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## π Conformetry
|
|
21
|
+
|
|
22
|
+
This project was generated from the [nestjs-service-project](../../configuration/conformetry-templates/nestjs-service-project) conformetry template.
|
|
23
|
+
|
|
24
|
+
## πΈοΈ Codependix
|
|
25
|
+
|
|
26
|
+
Dependency graphs exported by [codependix](https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/codependix/codependix-cli), regenerated by `nx run codebase:codependix:write`.
|
|
27
|
+
|
|
28
|
+
### Nx Neighborhood
|
|
29
|
+
|
|
30
|
+
<!-- codependix:start name="codependix-nx-projects" -->
|
|
31
|
+
```mermaid
|
|
32
|
+
graph LR
|
|
33
|
+
codometer_cli["codometer-cli"]
|
|
34
|
+
codometer_configuration["codometer-configuration"]
|
|
35
|
+
codometer_core["codometer-core"]
|
|
36
|
+
codometer_examples["codometer-examples"]
|
|
37
|
+
codometer_languages["codometer-languages"]
|
|
38
|
+
codometer_measurement["codometer-measurement"]
|
|
39
|
+
codometer_output["codometer-output"]
|
|
40
|
+
codometer_cli --> codometer_core
|
|
41
|
+
codometer_configuration --> codometer_core
|
|
42
|
+
codometer_examples --> codometer_core
|
|
43
|
+
codometer_languages --> codometer_core
|
|
44
|
+
codometer_measurement --> codometer_core
|
|
45
|
+
codometer_output --> codometer_core
|
|
46
|
+
classDef subject fill:#7c3aed,color:#fff,stroke:#4c1d95,stroke-width:2px
|
|
47
|
+
class codometer_core subject
|
|
48
|
+
```
|
|
49
|
+
<!-- codependix:end name="codependix-nx-projects" -->
|
|
50
|
+
|
|
51
|
+
### NestJS Module Graph
|
|
52
|
+
|
|
53
|
+
<!-- codependix:start name="codependix-nestjs-modules" -->
|
|
54
|
+
```mermaid
|
|
55
|
+
flowchart LR
|
|
56
|
+
CodometerCoreModule
|
|
57
|
+
```
|
|
58
|
+
<!-- codependix:end name="codependix-nestjs-modules" -->
|
|
59
|
+
|
|
60
|
+
### File Imports
|
|
61
|
+
|
|
62
|
+
<!-- codependix:start name="codependix-file-imports" -->
|
|
63
|
+
```mermaid
|
|
64
|
+
graph LR
|
|
65
|
+
file_callidescope_config_ts["callidescope.config.ts"]
|
|
66
|
+
file_codependix_config_ts["codependix.config.ts"]
|
|
67
|
+
file_codometer_config_ts["codometer.config.ts"]
|
|
68
|
+
file_eslint_config_ts["eslint.config.ts"]
|
|
69
|
+
file_src_index_ts["src/index.ts"]
|
|
70
|
+
file_src_index_unit_test_ts["src/index.unit.test.ts"]
|
|
71
|
+
file_src_modules_codometer_core_codometer_core_constants_ts["src/modules/codometer-core/codometer-core.constants.ts"]
|
|
72
|
+
file_src_modules_codometer_core_codometer_core_module_ts["src/modules/codometer-core/codometer-core.module.ts"]
|
|
73
|
+
file_src_modules_codometer_core_codometer_core_service_ts["src/modules/codometer-core/codometer-core.service.ts"]
|
|
74
|
+
file_src_modules_codometer_core_codometer_core_service_unit_test_ts["src/modules/codometer-core/codometer-core.service.unit.test.ts"]
|
|
75
|
+
file_src_modules_codometer_core_codometer_core_types_ts["src/modules/codometer-core/codometer-core.types.ts"]
|
|
76
|
+
file_testing_mocks_ts["testing/mocks.ts"]
|
|
77
|
+
file_testing_setup_ts["testing/setup.ts"]
|
|
78
|
+
file_vite_config_ts["vite.config.ts"]
|
|
79
|
+
file_vitest_config_ts["vitest.config.ts"]
|
|
80
|
+
file_src_index_unit_test_ts --> file_src_index_ts
|
|
81
|
+
file_src_modules_codometer_core_codometer_core_constants_ts --> file_src_modules_codometer_core_codometer_core_types_ts
|
|
82
|
+
file_src_modules_codometer_core_codometer_core_module_ts --> file_src_modules_codometer_core_codometer_core_service_ts
|
|
83
|
+
file_src_modules_codometer_core_codometer_core_service_unit_test_ts --> file_src_modules_codometer_core_codometer_core_service_ts
|
|
84
|
+
```
|
|
85
|
+
<!-- codependix:end name="codependix-file-imports" -->
|
|
86
|
+
|
|
87
|
+
<!-- callidescope:start -->
|
|
88
|
+
|
|
89
|
+
## π Callidescope
|
|
90
|
+
|
|
91
|
+
Call stacks traced through `packages/ic-suite/codometer/codometer-core`, deepest first. Each frame shows what it takes, what it returns, and what its documentation says.
|
|
92
|
+
|
|
93
|
+
| Measure | Value |
|
|
94
|
+
| --- | --- |
|
|
95
|
+
| Callables | 5 |
|
|
96
|
+
| Files | 11 |
|
|
97
|
+
| Calls traced | 0 |
|
|
98
|
+
| Call stacks | 0 |
|
|
99
|
+
| Deepest stack | 0 |
|
|
100
|
+
| Stacks through recursion | 0 |
|
|
101
|
+
| Unfollowable calls | 4 |
|
|
102
|
+
|
|
103
|
+
### Limits
|
|
104
|
+
|
|
105
|
+
What this project is judged against, as declared in its own `callidescope.config.ts`.
|
|
106
|
+
|
|
107
|
+
| Limit | Value |
|
|
108
|
+
| --- | --- |
|
|
109
|
+
| `maximumDepth` | 1 |
|
|
110
|
+
| `maximumBreadth` | 1 |
|
|
111
|
+
|
|
112
|
+
### Call stacks (depth)
|
|
113
|
+
|
|
114
|
+
None.
|
|
115
|
+
|
|
116
|
+
### Breadth
|
|
117
|
+
|
|
118
|
+
None.
|
|
119
|
+
<!-- callidescope:end -->
|
|
120
|
+
|
|
121
|
+
<!-- codometer:start -->
|
|
122
|
+
|
|
123
|
+
## β²οΈ Codometer
|
|
124
|
+
|
|
125
|
+
### Project
|
|
126
|
+
|
|
127
|
+

|
|
128
|
+

|
|
129
|
+

|
|
130
|
+

|
|
131
|
+
|
|
132
|
+
### Measured Targets
|
|
133
|
+
|
|
134
|
+

|
|
135
|
+
|
|
136
|
+
### TypeScript
|
|
137
|
+
|
|
138
|
+

|
|
139
|
+

|
|
140
|
+

|
|
141
|
+

|
|
142
|
+

|
|
143
|
+

|
|
144
|
+

|
|
145
|
+
|
|
146
|
+
### JavaScript
|
|
147
|
+
|
|
148
|
+

|
|
149
|
+

|
|
150
|
+

|
|
151
|
+

|
|
152
|
+

|
|
153
|
+

|
|
154
|
+

|
|
155
|
+

|
|
156
|
+

|
|
157
|
+

|
|
158
|
+

|
|
159
|
+

|
|
160
|
+

|
|
161
|
+

|
|
162
|
+
|
|
163
|
+
### Python
|
|
164
|
+
|
|
165
|
+

|
|
166
|
+

|
|
167
|
+

|
|
168
|
+

|
|
169
|
+

|
|
170
|
+

|
|
171
|
+

|
|
172
|
+

|
|
173
|
+

|
|
174
|
+

|
|
175
|
+

|
|
176
|
+

|
|
177
|
+
|
|
178
|
+
### JSON
|
|
179
|
+
|
|
180
|
+

|
|
181
|
+

|
|
182
|
+

|
|
183
|
+

|
|
184
|
+

|
|
185
|
+

|
|
186
|
+

|
|
187
|
+

|
|
188
|
+

|
|
189
|
+

|
|
190
|
+

|
|
191
|
+

|
|
192
|
+
|
|
193
|
+
### YAML
|
|
194
|
+
|
|
195
|
+

|
|
196
|
+

|
|
197
|
+

|
|
198
|
+

|
|
199
|
+

|
|
200
|
+

|
|
201
|
+

|
|
202
|
+

|
|
203
|
+

|
|
204
|
+

|
|
205
|
+

|
|
206
|
+
|
|
207
|
+
### TOML
|
|
208
|
+
|
|
209
|
+

|
|
210
|
+

|
|
211
|
+

|
|
212
|
+

|
|
213
|
+

|
|
214
|
+

|
|
215
|
+

|
|
216
|
+
|
|
217
|
+
### Shell
|
|
218
|
+
|
|
219
|
+

|
|
220
|
+

|
|
221
|
+

|
|
222
|
+

|
|
223
|
+

|
|
224
|
+

|
|
225
|
+

|
|
226
|
+

|
|
227
|
+

|
|
228
|
+

|
|
229
|
+

|
|
230
|
+
|
|
231
|
+
### SQL
|
|
232
|
+
|
|
233
|
+

|
|
234
|
+

|
|
235
|
+

|
|
236
|
+

|
|
237
|
+

|
|
238
|
+

|
|
239
|
+

|
|
240
|
+

|
|
241
|
+

|
|
242
|
+

|
|
243
|
+

|
|
244
|
+
|
|
245
|
+
### HCL
|
|
246
|
+
|
|
247
|
+

|
|
248
|
+

|
|
249
|
+

|
|
250
|
+

|
|
251
|
+

|
|
252
|
+

|
|
253
|
+

|
|
254
|
+

|
|
255
|
+

|
|
256
|
+
|
|
257
|
+
### CSS
|
|
258
|
+
|
|
259
|
+

|
|
260
|
+

|
|
261
|
+

|
|
262
|
+

|
|
263
|
+

|
|
264
|
+

|
|
265
|
+

|
|
266
|
+

|
|
267
|
+

|
|
268
|
+
|
|
269
|
+
### Conventions
|
|
270
|
+
|
|
271
|
+

|
|
272
|
+

|
|
273
|
+

|
|
274
|
+

|
|
275
|
+

|
|
276
|
+

|
|
277
|
+

|
|
278
|
+

|
|
279
|
+

|
|
280
|
+

|
|
281
|
+

|
|
282
|
+

|
|
283
|
+

|
|
284
|
+

|
|
285
|
+

|
|
286
|
+

|
|
287
|
+

|
|
288
|
+

|
|
289
|
+
|
|
290
|
+
### Jupyter
|
|
291
|
+
|
|
292
|
+

|
|
293
|
+

|
|
294
|
+

|
|
295
|
+

|
|
296
|
+

|
|
297
|
+

|
|
298
|
+

|
|
299
|
+

|
|
300
|
+

|
|
301
|
+

|
|
302
|
+

|
|
303
|
+

|
|
304
|
+

|
|
305
|
+

|
|
306
|
+

|
|
307
|
+

|
|
308
|
+

|
|
309
|
+

|
|
310
|
+

|
|
311
|
+

|
|
312
|
+
|
|
313
|
+
### Markdown
|
|
314
|
+
|
|
315
|
+

|
|
316
|
+

|
|
317
|
+

|
|
318
|
+

|
|
319
|
+

|
|
320
|
+

|
|
321
|
+

|
|
322
|
+

|
|
323
|
+

|
|
324
|
+

|
|
325
|
+

|
|
326
|
+

|
|
327
|
+

|
|
328
|
+

|
|
329
|
+

|
|
330
|
+

|
|
331
|
+

|
|
332
|
+

|
|
333
|
+

|
|
334
|
+

|
|
335
|
+
<!-- codometer:end -->
|
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aggregated code statistics produced by the measurement pipeline,
|
|
3
|
+
* grouped by the language each counter was measured from.
|
|
4
|
+
*
|
|
5
|
+
* This is the shape every configured callback is handed, which is why it lives
|
|
6
|
+
* beside the configuration types rather than in the CLI that produces it: a
|
|
7
|
+
* `codometer.config.ts` has to be able to name it.
|
|
8
|
+
*/
|
|
9
|
+
export declare interface CodeStatisticsResult {
|
|
10
|
+
css: CssStatistics;
|
|
11
|
+
custom: CustomStatisticResult[];
|
|
12
|
+
folders: number;
|
|
13
|
+
hcl: HclStatistics;
|
|
14
|
+
javascript: JavascriptStatistics;
|
|
15
|
+
json: JsonStatistics;
|
|
16
|
+
jupyter: JupyterStatistics;
|
|
17
|
+
linesOfCode: number;
|
|
18
|
+
markdown: MarkdownStatistics;
|
|
19
|
+
python: PythonStatistics;
|
|
20
|
+
/**
|
|
21
|
+
* Byte-precise total of this target's files, uncompressed.
|
|
22
|
+
*
|
|
23
|
+
* Produced by the same size analysis a declared target's `size` metric
|
|
24
|
+
* uses β with `none` as its compression β rather than a rounded stat sum,
|
|
25
|
+
* so the workspace headline moves by the byte instead of by the whole
|
|
26
|
+
* binary unit and stays comparable with every other size in the workspace,
|
|
27
|
+
* which are all decimal.
|
|
28
|
+
*/
|
|
29
|
+
repositoryBytes: number;
|
|
30
|
+
shell: ShellStatistics;
|
|
31
|
+
sourceFiles: number;
|
|
32
|
+
sql: SqlStatistics;
|
|
33
|
+
toml: TomlStatistics;
|
|
34
|
+
typescript: TypescriptStatistics;
|
|
35
|
+
yaml: YamlStatistics;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Severities a limit may declare for the breach it would report. */
|
|
39
|
+
export declare const CODOMETER_SEVERITIES: readonly ["fail", "warn"];
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Badge groups a configured counter may be rendered into.
|
|
43
|
+
*
|
|
44
|
+
* Accepted by name rather than as free text so a misspelled group fails the
|
|
45
|
+
* configuration instead of silently rendering the badge nowhere.
|
|
46
|
+
*/
|
|
47
|
+
export declare const CODOMETER_STATISTIC_GROUPS: readonly ["conventions", "css", "hcl", "json", "jupyter", "markdown", "python", "repository", "shell", "sql", "toml", "typescript", "yaml"];
|
|
48
|
+
|
|
49
|
+
/** Declaration kinds a symbol counter, or a `comment` selector, may ask for. */
|
|
50
|
+
export declare const CODOMETER_SYMBOL_KINDS: readonly ["class", "enum", "function", "getter", "interface", "method", "property", "setter"];
|
|
51
|
+
|
|
52
|
+
/** Modifiers a symbol counter may require of a declaration. */
|
|
53
|
+
export declare const CODOMETER_SYMBOL_MODIFIERS: readonly ["abstract", "async", "export", "override", "private", "protected", "public", "readonly", "static"];
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* TODO: Document the codometerCore module.
|
|
57
|
+
*/
|
|
58
|
+
export declare class CodometerCoreModule {
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* TODO: Document the codometerCore service.
|
|
63
|
+
*/
|
|
64
|
+
export declare class CodometerCoreService {
|
|
65
|
+
constructor();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Everything one run measured, and everything it could not.
|
|
70
|
+
*
|
|
71
|
+
* Codometer's own shape rather than any other tool's. What a consumer needs is
|
|
72
|
+
* every metric's value alongside whatever limits it, and a name it can join a
|
|
73
|
+
* previous run's report on; nothing here is inferred from a field's absence.
|
|
74
|
+
*/
|
|
75
|
+
export declare interface CodometerReport {
|
|
76
|
+
/**
|
|
77
|
+
* Whatever the run could not do, named. Empty on an ordinary run.
|
|
78
|
+
*
|
|
79
|
+
* Present in the report rather than only on the console so that a consumer
|
|
80
|
+
* reading the file can tell a metric nobody measured from one that measured
|
|
81
|
+
* zero.
|
|
82
|
+
*/
|
|
83
|
+
failures: ReportFailure[];
|
|
84
|
+
targets: ReportTarget[];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* What a breach costs.
|
|
89
|
+
*
|
|
90
|
+
* `fail` is a gate and `warn` is a report β the difference between a limit
|
|
91
|
+
* that stops a change and one that only says the metric passed it. Both are
|
|
92
|
+
* reported identically; only the consequence differs.
|
|
93
|
+
*/
|
|
94
|
+
export declare type CodometerSeverity = "fail" | "warn";
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* A badge group a configured counter can be rendered into.
|
|
98
|
+
*
|
|
99
|
+
* Every group the report renders, plus `conventions` β the group that exists
|
|
100
|
+
* for these counters and appears only when at least one is configured.
|
|
101
|
+
*/
|
|
102
|
+
export declare type CodometerStatisticGroup = "conventions" | "css" | "hcl" | "json" | "jupyter" | "markdown" | "python" | "repository" | "shell" | "sql" | "toml" | "typescript" | "yaml";
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* A kind of declaration a symbol counter can ask for.
|
|
106
|
+
*
|
|
107
|
+
* `function` covers every callable written outside a class body β function
|
|
108
|
+
* declarations, function expressions, and arrow functions alike β while a
|
|
109
|
+
* callable written as a class member is a `method`, a `getter`, or a
|
|
110
|
+
* `setter`. A class field holding an arrow function is a `property`: the
|
|
111
|
+
* arrow carries none of the field's modifiers, so a static one is found by
|
|
112
|
+
* asking for static properties rather than static methods.
|
|
113
|
+
*/
|
|
114
|
+
export declare type CodometerSymbolKind = "class" | "enum" | "function" | "getter" | "interface" | "method" | "property" | "setter";
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* A modifier a counted declaration must carry.
|
|
118
|
+
*
|
|
119
|
+
* Read literally, from the syntax: `public` matches members annotated
|
|
120
|
+
* `public` and not members that are public by omission, and `private`
|
|
121
|
+
* likewise does not match a `#name` field, which carries no modifier.
|
|
122
|
+
*/
|
|
123
|
+
export declare type CodometerSymbolModifier = "abstract" | "async" | "export" | "override" | "private" | "protected" | "public" | "readonly" | "static";
|
|
124
|
+
|
|
125
|
+
/** Raised when an explicitly named configuration file does not exist. */
|
|
126
|
+
export declare class ConfigurationFileNotFoundError extends Error {
|
|
127
|
+
constructor(filePath: string);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Structural statistics specific to CSS stylesheets.
|
|
132
|
+
*/
|
|
133
|
+
export declare interface CssStatistics {
|
|
134
|
+
atRules: number;
|
|
135
|
+
comments: number;
|
|
136
|
+
customProperties: number;
|
|
137
|
+
declarations: number;
|
|
138
|
+
files: number;
|
|
139
|
+
lines: number;
|
|
140
|
+
mediaQueries: number;
|
|
141
|
+
rules: number;
|
|
142
|
+
selectors: number;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* What one configured counter found.
|
|
147
|
+
*
|
|
148
|
+
* `count` is files for a counter matching paths and declarations for one
|
|
149
|
+
* matching symbols, which is why it is not called either.
|
|
150
|
+
*/
|
|
151
|
+
export declare interface CustomStatisticResult {
|
|
152
|
+
color: string;
|
|
153
|
+
count: number;
|
|
154
|
+
group: CodometerStatisticGroup;
|
|
155
|
+
/**
|
|
156
|
+
* Where each measured instance was found, for a selector that measures
|
|
157
|
+
* per-instance rather than only counting matches.
|
|
158
|
+
*
|
|
159
|
+
* Left unset by a counter that only counts β `patterns`, `symbols` β since
|
|
160
|
+
* neither measures anything beyond a match. A `comment` selector populates
|
|
161
|
+
* it with every block that broke its budget.
|
|
162
|
+
*/
|
|
163
|
+
instances?: CustomStatisticResultInstance[] | undefined;
|
|
164
|
+
label: string;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** One measured occurrence a per-instance selector found. */
|
|
168
|
+
export declare interface CustomStatisticResultInstance {
|
|
169
|
+
file: string;
|
|
170
|
+
/** 1-indexed line the measured thing starts on. */
|
|
171
|
+
line: number;
|
|
172
|
+
measured: number;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Statistics specific to HCL, the Terraform configuration language.
|
|
177
|
+
*/
|
|
178
|
+
export declare interface HclStatistics {
|
|
179
|
+
attributes: number;
|
|
180
|
+
blocks: number;
|
|
181
|
+
comments: number;
|
|
182
|
+
files: number;
|
|
183
|
+
interpolations: number;
|
|
184
|
+
lines: number;
|
|
185
|
+
outputs: number;
|
|
186
|
+
resources: number;
|
|
187
|
+
variables: number;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Raised when a configuration does not satisfy the schema.
|
|
192
|
+
*
|
|
193
|
+
* Written out rather than letting a `ZodError` reach a caller, whose own
|
|
194
|
+
* message is the JSON dump of its issue list β a wall of `invalid_value`
|
|
195
|
+
* objects where a sentence saying what to write would do.
|
|
196
|
+
*/
|
|
197
|
+
export declare class InvalidConfigurationError extends Error {
|
|
198
|
+
constructor(issues: string);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Raised when a limit's value cannot be read as a number of anything.
|
|
203
|
+
*
|
|
204
|
+
* Loud rather than lenient. A value nobody can read has no defensible reading:
|
|
205
|
+
* taken as zero it gates every metric at nothing, and ignored it gates
|
|
206
|
+
* nothing at all. Both look like a working limit from the outside.
|
|
207
|
+
*/
|
|
208
|
+
export declare class InvalidLimitValueError extends Error {
|
|
209
|
+
constructor(metric: string, value: string);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** Code statistics specific to JavaScript source files. */
|
|
213
|
+
export declare interface JavascriptStatistics {
|
|
214
|
+
asyncFunctions: number;
|
|
215
|
+
classes: number;
|
|
216
|
+
commentLines: number;
|
|
217
|
+
comments: number;
|
|
218
|
+
constants: number;
|
|
219
|
+
exported: number;
|
|
220
|
+
externalPackages: number;
|
|
221
|
+
files: number;
|
|
222
|
+
functions: number;
|
|
223
|
+
imports: number;
|
|
224
|
+
methods: number;
|
|
225
|
+
syncFunctions: number;
|
|
226
|
+
testFiles: number;
|
|
227
|
+
todos: number;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** Code statistics specific to JSON, JSONC, and JSONL files. */
|
|
231
|
+
export declare interface JsonStatistics {
|
|
232
|
+
arrays: number;
|
|
233
|
+
booleans: number;
|
|
234
|
+
files: number;
|
|
235
|
+
items: number;
|
|
236
|
+
lines: number;
|
|
237
|
+
maxDepth: number;
|
|
238
|
+
nulls: number;
|
|
239
|
+
numbers: number;
|
|
240
|
+
objects: number;
|
|
241
|
+
properties: number;
|
|
242
|
+
strings: number;
|
|
243
|
+
totalNodes: number;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Statistics specific to Jupyter notebooks.
|
|
248
|
+
*
|
|
249
|
+
* A notebook is three languages in one file, so the counters come from three
|
|
250
|
+
* analyzers: the notebook document itself is JSON, its code cells are Python,
|
|
251
|
+
* and its markdown cells are prose. Cell and output counts are the notebook's
|
|
252
|
+
* own, belonging to no single language.
|
|
253
|
+
*/
|
|
254
|
+
export declare interface JupyterStatistics {
|
|
255
|
+
cells: number;
|
|
256
|
+
classes: number;
|
|
257
|
+
codeBlocks: number;
|
|
258
|
+
codeCells: number;
|
|
259
|
+
codeLines: number;
|
|
260
|
+
decorators: number;
|
|
261
|
+
executedCells: number;
|
|
262
|
+
files: number;
|
|
263
|
+
functions: number;
|
|
264
|
+
headings: number;
|
|
265
|
+
images: number;
|
|
266
|
+
imports: number;
|
|
267
|
+
links: number;
|
|
268
|
+
markdownCells: number;
|
|
269
|
+
markdownLines: number;
|
|
270
|
+
maxDepth: number;
|
|
271
|
+
outputs: number;
|
|
272
|
+
properties: number;
|
|
273
|
+
rawCells: number;
|
|
274
|
+
totalNodes: number;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** Structural statistics specific to markdown documents. */
|
|
278
|
+
export declare interface MarkdownStatistics {
|
|
279
|
+
blockQuotes: number;
|
|
280
|
+
codeBlocks: number;
|
|
281
|
+
files: number;
|
|
282
|
+
headingLevel1: number;
|
|
283
|
+
headingLevel2: number;
|
|
284
|
+
headingLevel3: number;
|
|
285
|
+
headingLevel4: number;
|
|
286
|
+
headingLevel5: number;
|
|
287
|
+
headingLevel6: number;
|
|
288
|
+
images: number;
|
|
289
|
+
inlineCode: number;
|
|
290
|
+
lines: number;
|
|
291
|
+
links: number;
|
|
292
|
+
listItems: number;
|
|
293
|
+
lists: number;
|
|
294
|
+
paragraphs: number;
|
|
295
|
+
tableRows: number;
|
|
296
|
+
tables: number;
|
|
297
|
+
taskListItems: number;
|
|
298
|
+
thematicBreaks: number;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* What a metric's number counts.
|
|
303
|
+
*
|
|
304
|
+
* Only bytes are called out. Every other metric counts things, and a count has
|
|
305
|
+
* no unit to get wrong.
|
|
306
|
+
*/
|
|
307
|
+
export declare type MetricUnit = "bytes" | null;
|
|
308
|
+
|
|
309
|
+
/** Code statistics specific to Python source files. */
|
|
310
|
+
export declare interface PythonStatistics {
|
|
311
|
+
classes: number;
|
|
312
|
+
commentLines: number;
|
|
313
|
+
comments: number;
|
|
314
|
+
constants: number;
|
|
315
|
+
decorators: number;
|
|
316
|
+
docstringLines: number;
|
|
317
|
+
docstrings: number;
|
|
318
|
+
files: number;
|
|
319
|
+
functions: number;
|
|
320
|
+
imports: number;
|
|
321
|
+
lines: number;
|
|
322
|
+
protocols: number;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Something the run could not do, and what it was trying to do it to.
|
|
327
|
+
*
|
|
328
|
+
* Declared beside the measurement that produces it rather than beside the
|
|
329
|
+
* report that renders it, so the dependency between the two runs one way. The
|
|
330
|
+
* name says where it surfaces: `CodometerReport.failures` is what a consumer
|
|
331
|
+
* reads it from.
|
|
332
|
+
*/
|
|
333
|
+
export declare interface ReportFailure {
|
|
334
|
+
/** Which part of the run it failed in. */
|
|
335
|
+
kind: ReportFailureKind;
|
|
336
|
+
reason: string;
|
|
337
|
+
/** An input's name for an input failure, a limit's written path for a limit. */
|
|
338
|
+
subject: string;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Which part of a run a failure belongs to.
|
|
343
|
+
*
|
|
344
|
+
* `input` is a set of files that could not be measured; `limit` is a declared
|
|
345
|
+
* limit that could not be held against anything. Neither is a breach, and a
|
|
346
|
+
* consumer that treats them as one reports a passing gate for a metric nobody
|
|
347
|
+
* ever measured.
|
|
348
|
+
*/
|
|
349
|
+
export declare type ReportFailureKind = "input" | "limit";
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* The limit declared on one metric, and whether the metric cleared it.
|
|
353
|
+
*
|
|
354
|
+
* A limit that held is written out exactly like one that did not, so a
|
|
355
|
+
* consumer can render the headroom rather than only the failures.
|
|
356
|
+
*/
|
|
357
|
+
export declare interface ReportLimit {
|
|
358
|
+
breached: boolean;
|
|
359
|
+
/** Stays `null` when none was written; a renderer falls back to the path. */
|
|
360
|
+
label: null | string;
|
|
361
|
+
severity: CodometerSeverity;
|
|
362
|
+
value: number;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/** One measured number, and whatever limits it. */
|
|
366
|
+
export declare interface ReportMetric {
|
|
367
|
+
/**
|
|
368
|
+
* Where each measured instance was found, for a metric a per-instance
|
|
369
|
+
* selector produced β a `comment` selector today, and any future selector
|
|
370
|
+
* that measures more than a count.
|
|
371
|
+
*
|
|
372
|
+
* Stays `null` for a metric that only counts, so a consumer can tell "no
|
|
373
|
+
* instance was found" from "this metric never tracks instances" without
|
|
374
|
+
* reading the configuration that produced it β the same reasoning
|
|
375
|
+
* `ReportLimit.label` already follows for a limit nobody named.
|
|
376
|
+
*/
|
|
377
|
+
instances: CustomStatisticResultInstance[] | null;
|
|
378
|
+
/**
|
|
379
|
+
* Every limit declared on the metric, in the order they were written.
|
|
380
|
+
*
|
|
381
|
+
* A list because the configuration accepts more than one limit on a single
|
|
382
|
+
* metric on purpose β a `warn` short of a `fail` is how a repository sees a
|
|
383
|
+
* number coming before it stops a change β and the gate already enforces all
|
|
384
|
+
* of them. A single field could only carry the last one written, which made
|
|
385
|
+
* the report unable to say what the gate was actually enforcing.
|
|
386
|
+
*
|
|
387
|
+
* Stays an empty array where nothing limits the metric, never absent.
|
|
388
|
+
*/
|
|
389
|
+
limits: ReportLimit[];
|
|
390
|
+
/**
|
|
391
|
+
* The metric's name across runs: its target's name, then its path.
|
|
392
|
+
*
|
|
393
|
+
* Stable by construction β both halves are written in the configuration β
|
|
394
|
+
* which is what lets a consumer join this run's report against the last
|
|
395
|
+
* one's instead of reading every metric as removed and re-added.
|
|
396
|
+
*/
|
|
397
|
+
name: string;
|
|
398
|
+
/** The metric's path within its target, with no target name on the front. */
|
|
399
|
+
path: string;
|
|
400
|
+
/**
|
|
401
|
+
* `bytes` where the value counts bytes, `null` for a plain count.
|
|
402
|
+
*
|
|
403
|
+
* Bytes are raw and decimal: a renderer showing kilobytes divides by 1000.
|
|
404
|
+
*/
|
|
405
|
+
unit: MetricUnit;
|
|
406
|
+
value: number;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/** One target's metrics, and whether its globs claimed anything at all. */
|
|
410
|
+
export declare interface ReportTarget {
|
|
411
|
+
/**
|
|
412
|
+
* True when the target's globs matched no files.
|
|
413
|
+
*
|
|
414
|
+
* Said outright rather than left to be read off a missing limit or a zero,
|
|
415
|
+
* because a target that matched nothing passes every limit written against
|
|
416
|
+
* it while measuring nothing at all.
|
|
417
|
+
*/
|
|
418
|
+
empty: boolean;
|
|
419
|
+
/** How many files the target's globs claimed. */
|
|
420
|
+
files: number;
|
|
421
|
+
metrics: ReportMetric[];
|
|
422
|
+
name: string;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Statistics specific to shell scripts.
|
|
427
|
+
*
|
|
428
|
+
* Counted with patterns rather than a parser: shell has no portable syntax
|
|
429
|
+
* tree available without a native dependency, so these are the constructs a
|
|
430
|
+
* reader recognizes on sight rather than everything the language admits.
|
|
431
|
+
*/
|
|
432
|
+
export declare interface ShellStatistics {
|
|
433
|
+
commentLines: number;
|
|
434
|
+
comments: number;
|
|
435
|
+
conditionals: number;
|
|
436
|
+
exports: number;
|
|
437
|
+
files: number;
|
|
438
|
+
functions: number;
|
|
439
|
+
lines: number;
|
|
440
|
+
loops: number;
|
|
441
|
+
pipelines: number;
|
|
442
|
+
shebangs: number;
|
|
443
|
+
variables: number;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Statistics specific to SQL scripts.
|
|
448
|
+
*/
|
|
449
|
+
export declare interface SqlStatistics {
|
|
450
|
+
comments: number;
|
|
451
|
+
commonTableExpressions: number;
|
|
452
|
+
creates: number;
|
|
453
|
+
deletes: number;
|
|
454
|
+
files: number;
|
|
455
|
+
inserts: number;
|
|
456
|
+
joins: number;
|
|
457
|
+
lines: number;
|
|
458
|
+
selects: number;
|
|
459
|
+
statements: number;
|
|
460
|
+
updates: number;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
/**
|
|
464
|
+
* Structural statistics specific to TOML documents.
|
|
465
|
+
*/
|
|
466
|
+
export declare interface TomlStatistics {
|
|
467
|
+
arrays: number;
|
|
468
|
+
arrayTables: number;
|
|
469
|
+
comments: number;
|
|
470
|
+
files: number;
|
|
471
|
+
keys: number;
|
|
472
|
+
lines: number;
|
|
473
|
+
tables: number;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/** Code statistics specific to TypeScript source files. */
|
|
477
|
+
export declare interface TypescriptStatistics {
|
|
478
|
+
decorators: number;
|
|
479
|
+
docComments: number;
|
|
480
|
+
enums: number;
|
|
481
|
+
files: number;
|
|
482
|
+
genericDeclarations: number;
|
|
483
|
+
interfaces: number;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/** Raised when the configuration path points to an unsupported file type. */
|
|
487
|
+
export declare class UnknownConfigurationFileTypeError extends Error {
|
|
488
|
+
constructor(filePath: string);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Structural statistics specific to YAML documents.
|
|
493
|
+
*
|
|
494
|
+
* A YAML file is a stream rather than a single value: one file can hold
|
|
495
|
+
* several documents, which is why `documents` is counted apart from `files`.
|
|
496
|
+
*/
|
|
497
|
+
export declare interface YamlStatistics {
|
|
498
|
+
aliases: number;
|
|
499
|
+
anchors: number;
|
|
500
|
+
comments: number;
|
|
501
|
+
documents: number;
|
|
502
|
+
files: number;
|
|
503
|
+
keys: number;
|
|
504
|
+
lines: number;
|
|
505
|
+
mappings: number;
|
|
506
|
+
maxDepth: number;
|
|
507
|
+
scalars: number;
|
|
508
|
+
sequences: number;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
export { }
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Injectable as e, Module as t } from "@nestjs/common";
|
|
2
|
+
//#region packages/ic-suite/codometer/codometer-core/src/modules/codometer-core/codometer-core.constants.ts
|
|
3
|
+
var n = class extends Error {
|
|
4
|
+
constructor(e) {
|
|
5
|
+
super(`Configuration file not found: ${e}`), this.name = "ConfigurationFileNotFoundError";
|
|
6
|
+
}
|
|
7
|
+
}, r = class extends Error {
|
|
8
|
+
constructor(e) {
|
|
9
|
+
super(`Cannot read the codometer configuration.\n${e}`), this.name = "InvalidConfigurationError";
|
|
10
|
+
}
|
|
11
|
+
}, i = class extends Error {
|
|
12
|
+
constructor(e, t) {
|
|
13
|
+
super(`Cannot read the limit on "${e}" from "${t}". Write a number, or a string carrying a decimal unit β "8 KB" is 8000 bytes and "1 MB" is 1000000. The trailing "b" is required, so "8 K" is not a size.`), this.name = "InvalidLimitValueError";
|
|
14
|
+
}
|
|
15
|
+
}, a = class extends Error {
|
|
16
|
+
constructor(e) {
|
|
17
|
+
super(`Unsupported configuration file type: ${e}`), this.name = "UnknownConfigurationFileTypeError";
|
|
18
|
+
}
|
|
19
|
+
}, o = [
|
|
20
|
+
"conventions",
|
|
21
|
+
"css",
|
|
22
|
+
"hcl",
|
|
23
|
+
"json",
|
|
24
|
+
"jupyter",
|
|
25
|
+
"markdown",
|
|
26
|
+
"python",
|
|
27
|
+
"repository",
|
|
28
|
+
"shell",
|
|
29
|
+
"sql",
|
|
30
|
+
"toml",
|
|
31
|
+
"typescript",
|
|
32
|
+
"yaml"
|
|
33
|
+
], s = ["fail", "warn"], c = [
|
|
34
|
+
"class",
|
|
35
|
+
"enum",
|
|
36
|
+
"function",
|
|
37
|
+
"getter",
|
|
38
|
+
"interface",
|
|
39
|
+
"method",
|
|
40
|
+
"property",
|
|
41
|
+
"setter"
|
|
42
|
+
], l = [
|
|
43
|
+
"abstract",
|
|
44
|
+
"async",
|
|
45
|
+
"export",
|
|
46
|
+
"override",
|
|
47
|
+
"private",
|
|
48
|
+
"protected",
|
|
49
|
+
"public",
|
|
50
|
+
"readonly",
|
|
51
|
+
"static"
|
|
52
|
+
];
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region \0@oxc-project+runtime@0.151.0/helpers/esm/decorateMetadata.js
|
|
55
|
+
function u(e, t) {
|
|
56
|
+
if (typeof Reflect == "object" && typeof Reflect.metadata == "function") return Reflect.metadata(e, t);
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
//#region \0@oxc-project+runtime@0.151.0/helpers/esm/decorate.js
|
|
60
|
+
function d(e, t, n, r) {
|
|
61
|
+
var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
|
|
62
|
+
if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
|
|
63
|
+
else for (var s = e.length - 1; s >= 0; s--) (o = e[s]) && (a = (i < 3 ? o(a) : i > 3 ? o(t, n, a) : o(t, n)) || a);
|
|
64
|
+
return i > 3 && a && Object.defineProperty(t, n, a), a;
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region packages/ic-suite/codometer/codometer-core/src/modules/codometer-core/codometer-core.service.ts
|
|
68
|
+
var f = class {
|
|
69
|
+
constructor() {}
|
|
70
|
+
};
|
|
71
|
+
f = d([e(), u("design:paramtypes", [])], f);
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region packages/ic-suite/codometer/codometer-core/src/modules/codometer-core/codometer-core.module.ts
|
|
74
|
+
var p = class {};
|
|
75
|
+
p = d([t({
|
|
76
|
+
controllers: [],
|
|
77
|
+
exports: [f],
|
|
78
|
+
imports: [],
|
|
79
|
+
providers: [f]
|
|
80
|
+
})], p);
|
|
81
|
+
//#endregion
|
|
82
|
+
export { s as CODOMETER_SEVERITIES, o as CODOMETER_STATISTIC_GROUPS, c as CODOMETER_SYMBOL_KINDS, l as CODOMETER_SYMBOL_MODIFIERS, p as CodometerCoreModule, f as CodometerCoreService, n as ConfigurationFileNotFoundError, r as InvalidConfigurationError, i as InvalidLimitValueError, a as UnknownConfigurationFileTypeError };
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"author": "Jimmy Paolini",
|
|
3
|
+
"bugs": {
|
|
4
|
+
"url": "https://github.com/Organizzolini/codebase/issues"
|
|
5
|
+
},
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"@nestjs/common": "^11.1.21 || ^12.0.1",
|
|
8
|
+
"reflect-metadata": "^0.2.2"
|
|
9
|
+
},
|
|
10
|
+
"description": "Core domain models, metrics contracts, and report shapes for the Codometer measurement toolchain",
|
|
11
|
+
"devDependencies": {
|
|
12
|
+
"@golevelup/ts-vitest": "^4.0.0",
|
|
13
|
+
"@nestjs/testing": "^12.0.1",
|
|
14
|
+
"@nx/eslint-plugin": "^23.0.0",
|
|
15
|
+
"@swc/helpers": "^0.5.21",
|
|
16
|
+
"@types/node": "^26.5.1",
|
|
17
|
+
"@vitest/coverage-v8": "^5.0.0",
|
|
18
|
+
"vitest": "^5.0.0"
|
|
19
|
+
},
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./dist/src/index.d.ts",
|
|
23
|
+
"default": "./dist/src/index.js"
|
|
24
|
+
},
|
|
25
|
+
"./package.json": "./package.json"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"LICENSE",
|
|
30
|
+
"README.md"
|
|
31
|
+
],
|
|
32
|
+
"homepage": "https://github.com/Organizzolini/codebase/tree/main/packages/ic-suite/codometer/codometer-core#readme",
|
|
33
|
+
"keywords": [
|
|
34
|
+
"code-statistics",
|
|
35
|
+
"codometer",
|
|
36
|
+
"contracts",
|
|
37
|
+
"measurement",
|
|
38
|
+
"metrics",
|
|
39
|
+
"types"
|
|
40
|
+
],
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"main": "./dist/src/index.js",
|
|
43
|
+
"name": "@codometer/core",
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public",
|
|
46
|
+
"registry": "https://registry.npmjs.org"
|
|
47
|
+
},
|
|
48
|
+
"repository": {
|
|
49
|
+
"directory": "packages/ic-suite/codometer/codometer-core",
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "git+https://github.com/Organizzolini/codebase.git"
|
|
52
|
+
},
|
|
53
|
+
"type": "module",
|
|
54
|
+
"typeCoverage": {
|
|
55
|
+
"atLeast": 100,
|
|
56
|
+
"strict": true
|
|
57
|
+
},
|
|
58
|
+
"types": "./dist/src/index.d.ts",
|
|
59
|
+
"version": "0.0.1"
|
|
60
|
+
}
|