@codometer/configuration 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/README.md ADDED
@@ -0,0 +1,900 @@
1
+ # ⏲️ Codometer Configuration
2
+
3
+ **The configuration reference for [Codometer](../codometer-cli/README.md).**
4
+
5
+ `@codometer/configuration` reads a repository's `codometer.config.ts` and hands
6
+ back a fully defaulted configuration object. It is the only package that knows
7
+ anything about a particular repository; `@codometer/cli` measures whatever the
8
+ configuration describes.
9
+
10
+ ```bash
11
+ npm install --save-dev @codometer/configuration
12
+ ```
13
+
14
+ Install it directly when you are typing a configuration file. `@codometer/cli`
15
+ already depends on it.
16
+
17
+ ## Configuration File
18
+
19
+ Any of `codometer.config.{ts,mts,cts,js,mjs,cjs,json,jsonc}` is read from the
20
+ directory being measured, or from any directory above it. `format` is the one
21
+ field every configuration must set — there is no code-level fallback for it —
22
+ and every other field is optional.
23
+
24
+ ```ts
25
+ import { type CodometerConfiguration } from "@codometer/configuration";
26
+
27
+ const codometerConfiguration: CodometerConfiguration = {
28
+ // Which report shape this run produces. Required; no default.
29
+ format: "markdown",
30
+ // Appended to the built-in exclusions (node_modules, dist, build, coverage,
31
+ // .nx), matched against repository-relative paths with `path.matchesGlob`.
32
+ exclude: ["notepads/**", "**/templates/**"],
33
+ // Ignore files in gitignore syntax, whose patterns exclude as well.
34
+ excludeFrom: ["configuration/.codometerignore"],
35
+ // Named sets of files measured alongside the codebase itself. The built-in
36
+ // `codebase` whole-tree scan is always present unless one of these entries
37
+ // replaces it by name.
38
+ inputs: [
39
+ {
40
+ analyses: ["size"],
41
+ compression: "gzip",
42
+ include: ["dist/**/*.js", "!dist/**/*.map.js"],
43
+ name: "compiled",
44
+ },
45
+ ],
46
+ // Target an unqualified limit path belongs to.
47
+ defaultInput: "codebase",
48
+ // How high each measured metric may go.
49
+ limits: [
50
+ { metric: "compiled.size", value: "8 KB" },
51
+ { metric: "typescript.interfaces", severity: "warn", value: 500 },
52
+ ],
53
+ // Destinations the measured statistics are written to.
54
+ outputs: [
55
+ { indentation: 2, path: "output/codometer.json", type: "json" },
56
+ {
57
+ description: "Measured on every push.",
58
+ // Named something other than the defaults on purpose: a file holding the
59
+ // default start marker anywhere — a document like this one, explaining
60
+ // it — reads as already carrying the block, and gets no block of its own.
61
+ endMarker: "<!-- STATISTICS_END -->",
62
+ path: "README.md",
63
+ startMarker: "<!-- STATISTICS_START -->",
64
+ type: "markdown",
65
+ },
66
+ ],
67
+ // Interpreter used for Python analysis; defaults to `python3`.
68
+ python: { command: "uv run python" },
69
+ };
70
+
71
+ export default codometerConfiguration;
72
+ ```
73
+
74
+ Output paths are resolved relative to the process's working directory, not to
75
+ the configuration file, so a configuration kept in a `configuration/` folder
76
+ still writes to the repository root.
77
+
78
+ ## Resolution
79
+
80
+ The search starts at the directory being measured and walks upward, taking the
81
+ first configuration file it finds. **The nearest one wins outright**: nothing
82
+ from a further ancestor is folded into it. Merging the two would leave a limit
83
+ that never applied looking exactly like one that did, and telling them apart
84
+ would mean knowing which of several files each field came from.
85
+
86
+ So a folder carrying no configuration file of its own is measured by the
87
+ nearest ancestor that does, and a folder that writes one is measured by that
88
+ alone. A configuration file is always read as a plain object — one exported as
89
+ a function is not recognized, and falls back to an empty configuration, the
90
+ same way a file exporting `42` does.
91
+
92
+ ## What Gets Measured
93
+
94
+ Discovery walks the directory itself and reads every `.gitignore` it passes, so
95
+ **`.gitignore` is already in force**: a build directory or a virtual environment
96
+ is pruned where its ignore file names it, and no exclusion has to name it again.
97
+ Git is never invoked, so a directory that is not a repository at all is measured
98
+ the same way as one that is, and what is measured is the working tree rather
99
+ than the index — a file that exists and is not ignored counts, whether or not it
100
+ has been committed yet. What the two exclusion options are for is the opposite
101
+ case: files that are kept but that nobody wrote.
102
+
103
+ | Option | Syntax | Use it for |
104
+ | ------ | ------ | ---------- |
105
+ | `exclude` | Globs, matched with `path.matchesGlob` | A handful of paths named inline, appended to the built-in defaults |
106
+ | `excludeFrom` | Paths to ignore files, in gitignore syntax | Lockfiles, vendored bundles, generated documentation — the list a repository would rather keep in a file |
107
+
108
+ `excludeFrom` files are read as gitignore syntax and matched natively, so
109
+ negations, anchoring, and directory patterns behave exactly as they do in a
110
+ `.gitignore`, and pointing codometer at a file another tool already reads gives
111
+ the same answer that tool gets. Matching is case-sensitive on every platform,
112
+ deliberately: git takes that from whichever filesystem it finds itself on, and a
113
+ measurement that disagrees with itself between a laptop and CI is worse than a
114
+ strict one.
115
+
116
+ One caution when reusing an existing ignore file: most are written for one
117
+ tool's concerns, not for measurement. A `.prettierignore` typically ignores all
118
+ markdown because a markdown linter handles it — point codometer at that and the
119
+ prose metrics vanish. A dedicated `.codometerignore` is usually the better
120
+ answer.
121
+
122
+ ## Inputs
123
+
124
+ An **input** is a named set of files, declared by include and exclude globs,
125
+ together with the analyses run over it. `inputs` is an array — replacing what
126
+ used to be called `targets` — and one entry is always there whether or not a
127
+ configuration declares any: the built-in `codebase` scan, which measures
128
+ everything the ignore files leave behind and runs `language` analysis over it.
129
+
130
+ ```ts
131
+ inputs: [
132
+ {
133
+ analyses: ["size"],
134
+ compression: "gzip",
135
+ exclude: ["dist/vendor/**"],
136
+ include: ["dist/**/*.js", "!dist/**/*.map.js"],
137
+ name: "compiled",
138
+ },
139
+ ],
140
+ ```
141
+
142
+ | Field | Required | Default | Meaning |
143
+ | ----- | -------- | ------- | ------- |
144
+ | `name` | yes | — | What the input is called. Two inputs may not share one |
145
+ | `include` | yes | — | Globs that add files. At least one must add rather than remove |
146
+ | `exclude` | no | none | Globs that remove files |
147
+ | `analyses` | yes | — | `language`, `size`, or both. At least one |
148
+ | `compression` | no | `gzip` | `gzip`, `brotli`, or `none` for the bytes on disk |
149
+ | `directory` | no | `.` | Where the input's globs start, relative to the process's working directory |
150
+
151
+ `language` runs the same analyzers the codebase gets. `size` compresses each
152
+ matched file **on its own** and sums the results — never all of them together,
153
+ which would find matches across file boundaries and report a total no client
154
+ ever receives. Gzip compresses at level 9 and brotli at quality 11, both stated
155
+ explicitly rather than left to a library default.
156
+
157
+ A `!` prefix in `include` removes files instead of adding them. Negations are
158
+ collected into one set applied to the whole input rather than in the order
159
+ they were written, so rearranging the array cannot change which files the
160
+ input holds. A `!` in `exclude` is rejected: that list already removes files,
161
+ so there is nothing there to negate.
162
+
163
+ Ignore files are not consulted for a declared input. That is deliberate, and it
164
+ is what lets one measure compiled output — a directory every `.gitignore`
165
+ claims, which is exactly why no ignore rule may reach it. A file an input
166
+ matched but cannot be read fails the run rather than counting as zero bytes: a
167
+ total quietly short by one file is worse than no total at all.
168
+
169
+ ### Replacing The Built-In Codebase Input
170
+
171
+ Declaring an input named `codebase` replaces the built-in whole-tree scan
172
+ rather than adding beside it:
173
+
174
+ ```ts
175
+ inputs: [
176
+ { analyses: ["language", "size"], compression: "none", include: ["**/*"], name: "codebase" },
177
+ ],
178
+ ```
179
+
180
+ Only its `compression` and `analyses` are read. **Its `include` and `exclude`
181
+ globs are not consulted at all** — the whole-tree scan is discovered by
182
+ walking the repository's ignore files rather than by matching globs, so the
183
+ `include: ["**/*"]` above is a placeholder, and narrowing it to `src/**` would
184
+ not narrow anything. To measure a subset of the tree, declare an input under
185
+ some other name.
186
+
187
+ This is the only way to measure the whole tree under a different compression
188
+ or set of analyses than the built-in entry runs.
189
+
190
+ ## Limits
191
+
192
+ A **limit** is how high one measured metric may go. Any metric can carry one — a
193
+ compressed size, a line count, a counter for one of the conventions below — and
194
+ a metric nothing limits is measured and reported exactly as before, gated by
195
+ nothing.
196
+
197
+ ```ts
198
+ defaultInput: "codebase",
199
+ limits: [
200
+ { metric: "Compiled JavaScript.size", value: "8 KB" },
201
+ { label: "Interfaces", metric: "typescript.interfaces", value: 500 },
202
+ { metric: "linesOfCode", severity: "warn", value: 100_000 },
203
+ ],
204
+ ```
205
+
206
+ | Field | Required | Default | Meaning |
207
+ | ----- | -------- | ------- | ------- |
208
+ | `metric` | yes | — | Dotted path of the metric this limits |
209
+ | `value` | yes | — | How high the metric may go, as a number or a string with a unit |
210
+ | `severity` | no | `fail` | `fail` stops the run on a breach; `warn` reports it |
211
+ | `label` | no | the path | What to call the limit in a report |
212
+
213
+ A metric is addressed by the input's name followed by its path within that
214
+ input — `codebase.typescript.interfaces`, `codebase.markdown.files`,
215
+ `Compiled JavaScript.size`. Every input carries `files`, an input running size
216
+ analysis carries `size`, and one running language analysis carries every
217
+ counter the codebase measurement lists, with configured counters under `custom.<label>`.
218
+ Set `defaultInput` and a path naming no input is read as that input's.
219
+
220
+ Where a `defaultInput` is set, a path is read as that input's whenever no
221
+ input name prefixes it — so with `defaultInput: "codebase"` and an input
222
+ called `typescript`, `typescript.interfaces` is the codebase's, because the
223
+ `typescript` input has no `interfaces` metric of its own to compete with it.
224
+ Write the input name in full wherever an input and a metric group share one.
225
+
226
+ **Ambiguity is refused, never resolved.** A path that could name two metrics —
227
+ an input called `markdown` beside the codebase's own `markdown.files` — fails
228
+ the run naming both readings, as does a path naming none, or one naming a
229
+ metric from an analysis the input never ran. A limit that quietly bound to the
230
+ wrong metric would look exactly like one that works.
231
+
232
+ A value written as a string carries a **decimal** unit whose trailing `b` is
233
+ required: `"8 KB"` is 8000 bytes and `"1 MB"` is 1000000, while `"8 K"` is not
234
+ a size and is refused rather than read as anything. A value nothing can read
235
+ fails the run instead of being taken as zero.
236
+
237
+ An input that matched **no files** fails the run if and only if a limit is
238
+ written against it. Declaring a limit asserts the files are there, so an empty
239
+ match is a glob that stopped matching or a build that never ran — while an
240
+ input nobody limited simply measured zero, which is unremarkable.
241
+
242
+ ## Custom Statistics
243
+
244
+ A repository that names files by convention has a vocabulary no language
245
+ analyzer knows about. The top-level `custom` array is what **measures** these
246
+ counters, regardless of whether — or where — any output renders them:
247
+
248
+ ```ts
249
+ custom: [
250
+ { label: "Service Files", patterns: ["**/*.service.ts"] },
251
+ { label: "Unit Tests", patterns: ["**/*.unit.test.ts"] },
252
+ { color: "16a34a", label: "Migrations", patterns: ["**/migrations/*.sql"] },
253
+ ],
254
+ ```
255
+
256
+ Each entry becomes one badge, in the order it was configured, everywhere it is
257
+ selected. Globs are matched against repository-relative paths with
258
+ `path.matchesGlob` over the same discovered files everything else measures, so
259
+ exclusions apply. A file matching several of one entry's globs counts once.
260
+ `color` is a shields.io hexadecimal triplet; entries that omit it take the next
261
+ color from a built-in palette, cycling so a counter's color stays the same
262
+ between runs.
263
+
264
+ A counter selects what it counts with one of three fields — `patterns`,
265
+ `symbols`, or `comment` — and needs at least one of them, or it is rejected as
266
+ counting nothing.
267
+
268
+ An output's own `custom` array is a separate, later concern: it **selects**,
269
+ by label, which of the top-level counters that destination renders — it never
270
+ declares a counter of its own. A JSON report and a markdown report may still
271
+ select entirely different labels:
272
+
273
+ ```ts
274
+ custom: [
275
+ { label: "Service Files", patterns: ["**/*.service.ts"] },
276
+ { label: "Unit Tests", patterns: ["**/*.unit.test.ts"] },
277
+ ],
278
+ outputs: [
279
+ { custom: ["Service Files"], path: "codometer-report.json", type: "json" },
280
+ { custom: ["Unit Tests"], path: "README.md", type: "markdown" },
281
+ ],
282
+ ```
283
+
284
+ A label an output selects that the top-level `custom` never declared is
285
+ refused when the configuration loads — selection cannot conjure a counter that
286
+ was never measured. A counter the top level declares but no output selects is
287
+ still measured and still gates a limit; it simply renders nowhere.
288
+
289
+ ### Counting Declarations
290
+
291
+ `symbols` counts declarations in TypeScript and JavaScript sources instead of
292
+ files. It asks for one or more `kinds`, optionally narrowed to declarations
293
+ carrying every named modifier:
294
+
295
+ ```ts
296
+ custom: [
297
+ {
298
+ group: "typescript",
299
+ label: "Static Methods",
300
+ symbols: { kinds: ["method"], modifiers: ["static"] },
301
+ },
302
+ { label: "Abstract Classes", symbols: { kinds: ["class"], modifiers: ["abstract"] } },
303
+ ],
304
+ ```
305
+
306
+ `kinds` are `class`, `enum`, `function`, `getter`, `interface`, `method`,
307
+ `property`, and `setter`. `modifiers` are `abstract`, `async`, `export`,
308
+ `override`, `private`, `protected`, `public`, `readonly`, and `static`.
309
+
310
+ Both are read literally, from the syntax. A callable written as a class member
311
+ is a `method`; one written anywhere else is a `function`, arrow functions
312
+ included. A class field holding an arrow function is a `property`, and the
313
+ arrow carries none of the field's modifiers — so a `static build = () => {}` is
314
+ found by asking for static properties, not static methods. `public` matches
315
+ members annotated `public`, not members that are public by omission, and
316
+ `private` does not match a `#name` field, which carries no modifier at all.
317
+
318
+ A symbol counter may also carry `patterns`, which then narrows _which files are
319
+ searched_ rather than being what is counted — `patterns: ["packages/**"]` with
320
+ a `symbols` matcher counts declarations in `packages/`. Counting happens during
321
+ the walk the TypeScript analyzer already makes, so any number of these costs
322
+ one pass over the sources.
323
+
324
+ ### Selecting A Comment Budget
325
+
326
+ `comment` selects a comment budget for a counter to measure, rather than
327
+ counting files or declarations:
328
+
329
+ ```ts
330
+ custom: [
331
+ { comment: { language: "yaml", maximumWords: 128 }, label: "YAML Comment Budget" },
332
+ { comment: { kind: "class", maximumLines: 24 }, label: "Class Comment Budget" },
333
+ ],
334
+ ```
335
+
336
+ | Field | Required | Default | Meaning |
337
+ | ----- | -------- | ------- | ------- |
338
+ | `language` | no | every language with comments | Narrows the budget to one of `css`, `hcl`, `python`, `shell`, `sql`, `toml`, `typescript`, `yaml` |
339
+ | `kind` | no | a plain comment block | Narrows to a documented declaration's JSDoc-style comment for this declaration kind |
340
+ | `maximumCharacters` | no | — | How many characters a block may hold, markers and newlines and all |
341
+ | `maximumLines` | no | — | How many lines a block may span |
342
+ | `maximumWords` | no | — | How many words of prose a block may hold, once markers are stripped |
343
+ | `severity` | no | `fail` | `fail` stops the run on a breach; `warn` reports it |
344
+
345
+ Its `value` is a count — how many blocks broke the selector's own
346
+ `maximumCharacters`/`maximumLines`/`maximumWords` — and its `instances` names
347
+ each breaching block's `file` and 1-indexed `line`, plus how much it measured.
348
+ A block that stayed within budget contributes to neither.
349
+
350
+ An entry with none of `patterns`, `symbols`, or `comment` is rejected rather
351
+ than reported as a permanent zero.
352
+
353
+ ### Where A Counter Renders
354
+
355
+ `group` names the badge group a counter is rendered into, after that group's
356
+ built-in badges. It defaults to `conventions` — a group that exists only for
357
+ these counters and is omitted entirely when none belong to it. Any rendered
358
+ group may be named instead: `css`, `hcl`, `json`, `jupyter`, `markdown`,
359
+ `python`, `repository`, `shell`, `sql`, `toml`, `typescript`, or `yaml`. A name
360
+ outside that set fails the configuration rather than rendering nowhere.
361
+
362
+ The default palette runs per group over the top-level `custom` array, so
363
+ adding a counter to one group never recolors the badges of another. A
364
+ counter's color is settled once there — an output selecting it back out by
365
+ label renders whichever color that resolution gave it, rather than cycling
366
+ its own palette.
367
+
368
+ ## Outputs
369
+
370
+ `outputs` is an array of typed destinations, replacing what used to be one
371
+ fixed-key `output` object. Declare as many as you like, including more than one
372
+ of a kind:
373
+
374
+ ```ts
375
+ outputs: [
376
+ { indentation: 2, path: "output/codometer.json", type: "json" },
377
+ { path: "README.md", type: "markdown" },
378
+ ],
379
+ ```
380
+
381
+ A JSON entry needs `path`; `indentation` defaults to `2`. A markdown entry
382
+ needs a `path`, a `write` function, or both — a destination naming neither is
383
+ rejected when the configuration loads.
384
+
385
+ ### Writing Markdown
386
+
387
+ The default markdown report is a `description` paragraph followed by shields.io
388
+ badges under one `###` heading per language, spliced between two anchor
389
+ markers. `write` is the whole of the customizable behavior — it both decides
390
+ what the report says and where it lands, replacing what used to be two
391
+ separate `render` and `write` callbacks:
392
+
393
+ ```ts
394
+ {
395
+ path: "README.md",
396
+ type: "markdown",
397
+ write: ({ anchors, renderBadges, statistics }) =>
398
+ anchors.syncAnchoredBlock({
399
+ content: `Lines of code: ${statistics.linesOfCode}\n\n${renderBadges()}`,
400
+ }),
401
+ }
402
+ ```
403
+
404
+ | Argument | Meaning |
405
+ | -------- | ------- |
406
+ | `description` | The configured description, for a writer that wants to place it itself |
407
+ | `renderBadges()` | The built-in badge rendering of these same statistics — call it to build the default content, or to add to it |
408
+ | `statistics` | The measured statistics |
409
+ | `check` | True when nothing may be written and the file is only being inspected |
410
+ | `path` | The configured path, resolved against the process's working directory |
411
+ | `anchors` | The marker mechanics, so choosing a different file does not mean reimplementing the splice |
412
+
413
+ | Anchor helper | Does |
414
+ | ------------- | ---- |
415
+ | `anchors.syncAnchoredBlock({ content?, path? })` | Splices the block into a file, appending when the markers are absent and creating the file when it is missing. In check mode it compares instead of writing and returns whether the file is current. |
416
+ | `anchors.wrapInAnchors(content?)` | Returns the content wrapped in the markers, for a writer placing it somewhere itself. |
417
+ | `anchors.startMarker` / `anchors.endMarker` | The configured markers. |
418
+
419
+ Leaving `write` unset keeps the built-in rendering and writing. A `write`
420
+ function returns `false` to report its destination as stale, which is what
421
+ fails a `--check` run; anything else counts as up to date.
422
+
423
+ ## Exports
424
+
425
+ `ConfigurationService` and `ConfigurationModule`, plus the
426
+ `CodometerConfiguration` type you author your config as and the resolved shapes
427
+ the CLI reads.
428
+
429
+ ## Test
430
+
431
+ ```bash
432
+ nx run codometer-configuration:vitest
433
+ ```
434
+
435
+ ## License
436
+
437
+ MIT — see [LICENSE](../../LICENSE).
438
+
439
+ ## 👔 Conformetry
440
+
441
+ This project was generated from the [nestjs-service-project](../../configuration/conformetry-templates/nestjs-service-project) conformetry template.
442
+
443
+ <!-- callidescope:start -->
444
+
445
+ ## 🔭 Callidescope
446
+
447
+ Call stacks traced through `packages/ic-suite/codometer/codometer-configuration`, deepest first. Each frame shows what it takes, what it returns, and what its documentation says.
448
+
449
+ | Measure | Value |
450
+ | --- | --- |
451
+ | Callables | 73 |
452
+ | Files | 19 |
453
+ | Calls traced | 68 |
454
+ | Call stacks | 6 |
455
+ | Deepest stack | 3 |
456
+ | Stacks through recursion | 0 |
457
+ | Unfollowable calls | 0 |
458
+
459
+ ### Limits
460
+
461
+ What this project is judged against, as declared in its own `callidescope.config.ts`.
462
+
463
+ | Limit | Value |
464
+ | --- | --- |
465
+ | `maximumDepth` | 9 |
466
+ | `maximumBreadth` | 7 |
467
+
468
+ ### Call stacks (depth)
469
+
470
+ **1. `superRefine(…)`** — depth 3 · orphan-root
471
+
472
+ ```text
473
+ 🚀 superRefine(…)(…): void [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:209]
474
+ └─> find(…)(…): boolean [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:211]
475
+ └─> findIndex(…)(…): boolean [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:212]
476
+ ```
477
+
478
+ **2. `callbackSchema`** — depth 2 · orphan-root
479
+
480
+ ```text
481
+ 🚀 callbackSchema<CallbackType>(): z.ZodType<CallbackType> [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:36]
482
+ ↳ Accepts a configured callback.
483
+ └─> custom(…)(value: unknown): value is Function [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:37]
484
+ ```
485
+
486
+ **3. `superRefine(…)`** — depth 2 · orphan-root
487
+
488
+ ```text
489
+ 🚀 superRefine(…)(…): void [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:107]
490
+ └─> some(…)(pattern: string): boolean [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:109]
491
+ ```
492
+
493
+ <details>
494
+ <summary>3 more call stacks</summary>
495
+
496
+ **4. `refine(…)`** — depth 2 · orphan-root
497
+
498
+ ```text
499
+ 🚀 refine(…)(…): boolean [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:166]
500
+ └─> map(…)(…): string [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:167]
501
+ ```
502
+
503
+ **5. `refine(…)`** — depth 2 · orphan-root
504
+
505
+ ```text
506
+ 🚀 refine(…)(…): boolean [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:182]
507
+ └─> map(…)(…): string [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:183]
508
+ ```
509
+
510
+ **6. `superRefine(…)`** — depth 2 · orphan-root
511
+
512
+ ```text
513
+ 🚀 superRefine(…)(…): void [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:227]
514
+ └─> map(…)(…): string [packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:229]
515
+ ```
516
+
517
+ </details>
518
+
519
+ ### Breadth
520
+
521
+ | Callable | Breadth | Calls directly | Location |
522
+ | --- | --- | --- | --- |
523
+ | `ConfigurationFlagsService.readCheckNames` | 4 | `ConfigurationFlagsService.describeAcceptedCheckNames`, `ConfigurationFlagsService.filter(…)`, `ConfigurationFlagsService.map(…)`, `ConfigurationFlagsService.validateCheckNames` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:57` |
524
+ | `ConfigurationLoaderService.load` | 4 | `ConfigurationLoaderService.findConfigurationFile`, `ConfigurationLoaderService.resolveConfigurationPath`, `UnknownConfigurationFileTypeError.constructor`, `ConfigurationLoaderService.loadConfigurationModule` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-loader.service.ts:190` |
525
+ | `ConfigurationResolverService.resolveConfiguration` | 4 | `ConfigurationResolverService.resolveCustomStatistics`, `ConfigurationResolverService.resolveInputs`, `ConfigurationResolverService.resolveLimits`, `ConfigurationResolverService.resolveOutputs` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:336` |
526
+
527
+ <details>
528
+ <summary>40 more callables</summary>
529
+
530
+ | Callable | Breadth | Calls directly | Location |
531
+ | --- | --- | --- | --- |
532
+ | `ConfigurationResolverService.resolveInput` | 3 | `ConfigurationResolverService.map(…)`, `ConfigurationResolverService.filter(…)`, `ConfigurationResolverService.filter(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:196` |
533
+ | `ConfigurationService.loadConfigurationFile` | 3 | `ConfigurationLoaderService.load`, `ConfigurationService.resolveConfiguration`, `ConfigurationService.parseConfiguration` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:85` |
534
+ | `ConfigurationFlagsService.resolveFormat` | 2 | `ConfigurationFlagsService.find(…)`, `ConfigurationFlagsService.map(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:154` |
535
+ | `ConfigurationLoaderService.loadConfigurationModule` | 2 | `ConfigurationLoaderService.loadJsonConfiguration`, `ConfigurationLoaderService.readDefaultExport` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-loader.service.ts:105` |
536
+ | `ConfigurationLoaderService.resolveConfigurationPath` | 2 | `ConfigurationLoaderService.findRepositoryRoot`, `ConfigurationFileNotFoundError.constructor` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-loader.service.ts:156` |
537
+ | `ConfigurationResolverService.parseLimitValue` | 2 | `ConfigurationResolverService.parseLimitValueText`, `InvalidLimitValueError.constructor` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:94` |
538
+ | `ConfigurationResolverService.resolveInputs` | 2 | `ConfigurationResolverService.some(…)`, `ConfigurationResolverService.map(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:224` |
539
+ | `ConfigurationResolverService.map(…)` | 2 | `ConfigurationResolverService.resolveJsonOutput`, `ConfigurationResolverService.resolveMarkdownOutput` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:292` |
540
+ | `ConfigurationResolverService.selectCustomStatistics` | 2 | `ConfigurationResolverService.map(…)`, `ConfigurationResolverService.flatMap(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:308` |
541
+ | `callbackSchema` | 1 | `custom(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:36` |
542
+ | `superRefine(…)` | 1 | `some(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:107` |
543
+ | `refine(…)` | 1 | `map(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:166` |
544
+ | `refine(…)` | 1 | `map(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:182` |
545
+ | `superRefine(…)` | 1 | `find(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:209` |
546
+ | `find(…)` | 1 | `findIndex(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:211` |
547
+ | `superRefine(…)` | 1 | `map(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-schema.constants.ts:227` |
548
+ | `ConfigurationFlagsService.describeAcceptedCheckNames` | 1 | `ConfigurationFlagsService.map(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:46` |
549
+ | `ConfigurationFlagsService.validateCheckNames` | 1 | `ConfigurationFlagsService.describeAcceptedCheckNames` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:89` |
550
+ | `ConfigurationFlagsService.parseDefaultedOption` | 1 | `ConfigurationFlagsService.parseOptionalOption` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:115` |
551
+ | `ConfigurationFlagsService.parseDirectoryOption` | 1 | `ConfigurationFlagsService.parseDefaultedOption` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:126` |
552
+ | `ConfigurationFlagsService.selectMode` | 1 | `ConfigurationFlagsService.readCheckNames` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-flags.service.ts:184` |
553
+ | `ConfigurationLoaderService.findRepositoryRoot` | 1 | `ConfigurationLoaderService.some(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-loader.service.ts:81` |
554
+ | `ConfigurationResolverService.parseConfigurationInternal` | 1 | `InvalidConfigurationError.constructor` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:75` |
555
+ | `ConfigurationResolverService.parseLimitValueText` | 1 | `InvalidLimitValueError.constructor` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:114` |
556
+ | `ConfigurationResolverService.resolveCustomStatistics` | 1 | `ConfigurationResolverService.map(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:150` |
557
+ | `ConfigurationResolverService.map(…)` | 1 | `ConfigurationResolverService.resolveInput` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:235` |
558
+ | `ConfigurationResolverService.resolveJsonOutput` | 1 | `ConfigurationResolverService.selectCustomStatistics` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:239` |
559
+ | `ConfigurationResolverService.resolveLimits` | 1 | `ConfigurationResolverService.map(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:258` |
560
+ | `ConfigurationResolverService.map(…)` | 1 | `ConfigurationResolverService.parseLimitValue` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:261` |
561
+ | `ConfigurationResolverService.resolveMarkdownOutput` | 1 | `ConfigurationResolverService.selectCustomStatistics` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:270` |
562
+ | `ConfigurationResolverService.resolveOutputs` | 1 | `ConfigurationResolverService.map(…)` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:288` |
563
+ | `ConfigurationResolverService.parseConfiguration` | 1 | `ConfigurationResolverService.parseConfigurationInternal` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration-resolver.service.ts:326` |
564
+ | `ConfigurationService.loadConfiguration` | 1 | `ConfigurationService.loadConfigurationFile` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:68` |
565
+ | `ConfigurationService.parseConfiguration` | 1 | `ConfigurationResolverService.parseConfiguration` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:110` |
566
+ | `ConfigurationService.parseDefaultedOption` | 1 | `ConfigurationFlagsService.parseDefaultedOption` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:115` |
567
+ | `ConfigurationService.parseDirectoryOption` | 1 | `ConfigurationFlagsService.parseDirectoryOption` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:120` |
568
+ | `ConfigurationService.parseOptionalOption` | 1 | `ConfigurationFlagsService.parseOptionalOption` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:125` |
569
+ | `ConfigurationService.resolveConfiguration` | 1 | `ConfigurationResolverService.resolveConfiguration` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:130` |
570
+ | `ConfigurationService.resolveFormat` | 1 | `ConfigurationFlagsService.resolveFormat` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:139` |
571
+ | `ConfigurationService.selectMode` | 1 | `ConfigurationFlagsService.selectMode` | `packages/ic-suite/codometer/codometer-configuration/src/modules/configuration/configuration.service.ts:152` |
572
+
573
+ </details>
574
+ <!-- callidescope:end -->
575
+
576
+ ## 🕸️ Codependix
577
+
578
+ 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`.
579
+
580
+ ### Nx Neighborhood
581
+
582
+ <!-- codependix:start name="codependix-nx-projects" -->
583
+ ```mermaid
584
+ graph LR
585
+ codometer_cli["codometer-cli"]
586
+ codometer_configuration["codometer-configuration"]
587
+ codometer_core["codometer-core"]
588
+ codometer_examples["codometer-examples"]
589
+ codometer_languages["codometer-languages"]
590
+ codometer_measurement["codometer-measurement"]
591
+ codometer_output["codometer-output"]
592
+ codometer_cli --> codometer_configuration
593
+ codometer_configuration --> codometer_core
594
+ codometer_examples --> codometer_configuration
595
+ codometer_languages --> codometer_configuration
596
+ codometer_measurement --> codometer_configuration
597
+ codometer_output --> codometer_configuration
598
+ classDef subject fill:#7c3aed,color:#fff,stroke:#4c1d95,stroke-width:2px
599
+ class codometer_configuration subject
600
+ ```
601
+ <!-- codependix:end name="codependix-nx-projects" -->
602
+
603
+ ### NestJS Module Graph
604
+
605
+ <!-- codependix:start name="codependix-nestjs-modules" -->
606
+ ```mermaid
607
+ flowchart LR
608
+ ConfigurationModule
609
+ ```
610
+ <!-- codependix:end name="codependix-nestjs-modules" -->
611
+
612
+ ### File Imports
613
+
614
+ <!-- codependix:start name="codependix-file-imports" -->
615
+ ```mermaid
616
+ graph LR
617
+ file_callidescope_config_ts["callidescope.config.ts"]
618
+ file_codependix_config_ts["codependix.config.ts"]
619
+ file_codometer_config_ts["codometer.config.ts"]
620
+ file_eslint_config_ts["eslint.config.ts"]
621
+ file_src_index_ts["src/index.ts"]
622
+ file_src_index_unit_test_ts["src/index.unit.test.ts"]
623
+ file_src_modules_configuration_configuration_flags_constants_ts["src/modules/configuration/configuration-flags.constants.ts"]
624
+ file_src_modules_configuration_configuration_flags_service_ts["src/modules/configuration/configuration-flags.service.ts"]
625
+ file_src_modules_configuration_configuration_flags_service_unit_test_ts["src/modules/configuration/configuration-flags.service.unit.test.ts"]
626
+ file_src_modules_configuration_configuration_loader_service_ts["src/modules/configuration/configuration-loader.service.ts"]
627
+ file_src_modules_configuration_configuration_loader_service_unit_test_ts["src/modules/configuration/configuration-loader.service.unit.test.ts"]
628
+ file_src_modules_configuration_configuration_loader_types_ts["src/modules/configuration/configuration-loader.types.ts"]
629
+ file_src_modules_configuration_configuration_resolver_service_ts["src/modules/configuration/configuration-resolver.service.ts"]
630
+ file_src_modules_configuration_configuration_resolver_service_unit_test_ts["src/modules/configuration/configuration-resolver.service.unit.test.ts"]
631
+ file_src_modules_configuration_configuration_schema_constants_ts["src/modules/configuration/configuration-schema.constants.ts"]
632
+ file_src_modules_configuration_configuration_constants_ts["src/modules/configuration/configuration.constants.ts"]
633
+ file_src_modules_configuration_configuration_module_ts["src/modules/configuration/configuration.module.ts"]
634
+ file_src_modules_configuration_configuration_module_unit_test_ts["src/modules/configuration/configuration.module.unit.test.ts"]
635
+ file_src_modules_configuration_configuration_service_ts["src/modules/configuration/configuration.service.ts"]
636
+ file_src_modules_configuration_configuration_service_unit_test_ts["src/modules/configuration/configuration.service.unit.test.ts"]
637
+ file_src_modules_configuration_configuration_types_ts["src/modules/configuration/configuration.types.ts"]
638
+ file_src_modules_configuration_output_types_ts["src/modules/configuration/output.types.ts"]
639
+ file_src_modules_configuration_resolved_types_ts["src/modules/configuration/resolved.types.ts"]
640
+ file_testing_mocks_ts["testing/mocks.ts"]
641
+ file_testing_setup_ts["testing/setup.ts"]
642
+ file_vite_config_ts["vite.config.ts"]
643
+ file_vitest_config_ts["vitest.config.ts"]
644
+ file_src_index_unit_test_ts --> file_src_index_ts
645
+ file_src_modules_configuration_configuration_flags_service_ts --> file_src_modules_configuration_configuration_flags_constants_ts
646
+ file_src_modules_configuration_configuration_flags_service_ts --> file_src_modules_configuration_configuration_types_ts
647
+ file_src_modules_configuration_configuration_flags_service_unit_test_ts --> file_src_modules_configuration_configuration_flags_service_ts
648
+ file_src_modules_configuration_configuration_flags_service_unit_test_ts --> file_src_modules_configuration_configuration_types_ts
649
+ file_src_modules_configuration_configuration_loader_service_ts --> file_src_modules_configuration_configuration_loader_types_ts
650
+ file_src_modules_configuration_configuration_loader_service_ts --> file_src_modules_configuration_configuration_constants_ts
651
+ file_src_modules_configuration_configuration_loader_service_ts --> file_src_modules_configuration_configuration_types_ts
652
+ file_src_modules_configuration_configuration_loader_service_unit_test_ts --> file_src_modules_configuration_configuration_loader_service_ts
653
+ file_src_modules_configuration_configuration_resolver_service_ts --> file_src_modules_configuration_configuration_schema_constants_ts
654
+ file_src_modules_configuration_configuration_resolver_service_ts --> file_src_modules_configuration_configuration_constants_ts
655
+ file_src_modules_configuration_configuration_resolver_service_ts --> file_src_modules_configuration_configuration_types_ts
656
+ file_src_modules_configuration_configuration_resolver_service_ts --> file_src_modules_configuration_resolved_types_ts
657
+ file_src_modules_configuration_configuration_resolver_service_unit_test_ts --> file_src_modules_configuration_configuration_resolver_service_ts
658
+ file_src_modules_configuration_configuration_schema_constants_ts --> file_src_modules_configuration_configuration_constants_ts
659
+ file_src_modules_configuration_configuration_schema_constants_ts --> file_src_modules_configuration_output_types_ts
660
+ file_src_modules_configuration_configuration_constants_ts --> file_src_modules_configuration_configuration_types_ts
661
+ file_src_modules_configuration_configuration_module_ts --> file_src_modules_configuration_configuration_flags_service_ts
662
+ file_src_modules_configuration_configuration_module_ts --> file_src_modules_configuration_configuration_loader_service_ts
663
+ file_src_modules_configuration_configuration_module_ts --> file_src_modules_configuration_configuration_resolver_service_ts
664
+ file_src_modules_configuration_configuration_module_ts --> file_src_modules_configuration_configuration_service_ts
665
+ file_src_modules_configuration_configuration_module_unit_test_ts --> file_src_modules_configuration_configuration_loader_service_ts
666
+ file_src_modules_configuration_configuration_module_unit_test_ts --> file_src_modules_configuration_configuration_module_ts
667
+ file_src_modules_configuration_configuration_module_unit_test_ts --> file_src_modules_configuration_configuration_service_ts
668
+ file_src_modules_configuration_configuration_service_ts --> file_src_modules_configuration_configuration_flags_service_ts
669
+ file_src_modules_configuration_configuration_service_ts --> file_src_modules_configuration_configuration_loader_service_ts
670
+ file_src_modules_configuration_configuration_service_ts --> file_src_modules_configuration_configuration_resolver_service_ts
671
+ file_src_modules_configuration_configuration_service_ts --> file_src_modules_configuration_configuration_types_ts
672
+ file_src_modules_configuration_configuration_service_ts --> file_src_modules_configuration_resolved_types_ts
673
+ file_src_modules_configuration_configuration_service_unit_test_ts --> file_src_modules_configuration_configuration_flags_service_ts
674
+ file_src_modules_configuration_configuration_service_unit_test_ts --> file_src_modules_configuration_configuration_loader_service_ts
675
+ file_src_modules_configuration_configuration_service_unit_test_ts --> file_src_modules_configuration_configuration_resolver_service_ts
676
+ file_src_modules_configuration_configuration_service_unit_test_ts --> file_src_modules_configuration_configuration_constants_ts
677
+ file_src_modules_configuration_configuration_service_unit_test_ts --> file_src_modules_configuration_configuration_service_ts
678
+ file_src_modules_configuration_configuration_service_unit_test_ts --> file_src_modules_configuration_configuration_types_ts
679
+ file_src_modules_configuration_configuration_types_ts --> file_src_modules_configuration_configuration_flags_constants_ts
680
+ file_src_modules_configuration_configuration_types_ts --> file_src_modules_configuration_output_types_ts
681
+ file_src_modules_configuration_resolved_types_ts --> file_src_modules_configuration_configuration_types_ts
682
+ file_src_modules_configuration_resolved_types_ts --> file_src_modules_configuration_output_types_ts
683
+ ```
684
+ <!-- codependix:end name="codependix-file-imports" -->
685
+
686
+ <!-- codometer:start -->
687
+
688
+ ## ⏲️ Codometer
689
+
690
+ ### Project
691
+
692
+ ![Lines of Code](https://img.shields.io/badge/Lines_of_Code-4302-22c55e?style=flat-square)
693
+ ![Repository Size](https://img.shields.io/badge/Repository_Size-154.28_kB-6b7280?style=flat-square)
694
+ ![Folders](https://img.shields.io/badge/Folders-4-4a4a4a?style=flat-square)
695
+ ![Source Files](https://img.shields.io/badge/Source_Files-27-3178c6?style=flat-square)
696
+
697
+ ### Measured Targets
698
+
699
+ ![Compiled JavaScript Size](https://img.shields.io/badge/Compiled_JavaScript_Size-5.36_kB_gzip-6b7280?style=flat-square)
700
+
701
+ ### TypeScript
702
+
703
+ ![TypeScript Files](https://img.shields.io/badge/TypeScript_Files-27-3178c6?style=flat-square)
704
+ ![Interfaces](https://img.shields.io/badge/Interfaces-26-0ea5e9?style=flat-square)
705
+ ![Generic Declarations](https://img.shields.io/badge/Generic_Declarations-1-0369a1?style=flat-square)
706
+ ![Enums](https://img.shields.io/badge/Enums-0-f97316?style=flat-square)
707
+ ![Decorators](https://img.shields.io/badge/Decorators-5-db2777?style=flat-square)
708
+ ![Doc Comments](https://img.shields.io/badge/Doc_Comments-161-6366f1?style=flat-square)
709
+ ![Static Methods](https://img.shields.io/badge/Static_Methods-0-166534?style=flat-square)
710
+
711
+ ### JavaScript
712
+
713
+ ![JavaScript Files](https://img.shields.io/badge/JavaScript_Files-0-f7df1e?style=flat-square)
714
+ ![Test Files](https://img.shields.io/badge/Test_Files-6-10b981?style=flat-square)
715
+ ![External Packages](https://img.shields.io/badge/External_Packages-12-8b5cf6?style=flat-square)
716
+ ![Classes](https://img.shields.io/badge/Classes-5-7c3aed?style=flat-square)
717
+ ![Functions](https://img.shields.io/badge/Functions-173-16a34a?style=flat-square)
718
+ ![Methods](https://img.shields.io/badge/Methods-53-15803d?style=flat-square)
719
+ ![Sync Functions](https://img.shields.io/badge/Sync_Functions-149-4ade80?style=flat-square)
720
+ ![Async Functions](https://img.shields.io/badge/Async_Functions-77-059669?style=flat-square)
721
+ ![Constants](https://img.shields.io/badge/Constants-241-dc2626?style=flat-square)
722
+ ![Imports](https://img.shields.io/badge/Imports-93-0284c7?style=flat-square)
723
+ ![Exported Symbols](https://img.shields.io/badge/Exported_Symbols-74-ea580c?style=flat-square)
724
+ ![Comments](https://img.shields.io/badge/Comments-317-64748b?style=flat-square)
725
+ ![Comment Lines](https://img.shields.io/badge/Comment_Lines-900-475569?style=flat-square)
726
+ ![TODO Comments](https://img.shields.io/badge/TODO_Comments-0-ca8a04?style=flat-square)
727
+
728
+ ### Python
729
+
730
+ ![Python Files](https://img.shields.io/badge/Python_Files-0-3776ab?style=flat-square)
731
+ ![Python Lines](https://img.shields.io/badge/Python_Lines-0-4b8bbe?style=flat-square)
732
+ ![Python Classes](https://img.shields.io/badge/Python_Classes-0-7c3aed?style=flat-square)
733
+ ![Python Functions](https://img.shields.io/badge/Python_Functions-0-16a34a?style=flat-square)
734
+ ![Python Protocols](https://img.shields.io/badge/Python_Protocols-0-0ea5e9?style=flat-square)
735
+ ![Python Constants](https://img.shields.io/badge/Python_Constants-0-dc2626?style=flat-square)
736
+ ![Python Imports](https://img.shields.io/badge/Python_Imports-0-0284c7?style=flat-square)
737
+ ![Python Decorators](https://img.shields.io/badge/Python_Decorators-0-db2777?style=flat-square)
738
+ ![Docstrings](https://img.shields.io/badge/Docstrings-0-6366f1?style=flat-square)
739
+ ![Docstring Lines](https://img.shields.io/badge/Docstring_Lines-0-818cf8?style=flat-square)
740
+ ![Python Comments](https://img.shields.io/badge/Python_Comments-0-64748b?style=flat-square)
741
+ ![Python Comment Lines](https://img.shields.io/badge/Python_Comment_Lines-0-475569?style=flat-square)
742
+
743
+ ### JSON
744
+
745
+ ![JSON Files](https://img.shields.io/badge/JSON_Files-4-a16207?style=flat-square)
746
+ ![JSON Lines](https://img.shields.io/badge/JSON_Lines-165-ca8a04?style=flat-square)
747
+ ![JSON Objects](https://img.shields.io/badge/JSON_Objects-38-7c3aed?style=flat-square)
748
+ ![JSON Arrays](https://img.shields.io/badge/JSON_Arrays-13-8b5cf6?style=flat-square)
749
+ ![JSON Properties](https://img.shields.io/badge/JSON_Properties-103-0284c7?style=flat-square)
750
+ ![JSON Strings](https://img.shields.io/badge/JSON_Strings-90-16a34a?style=flat-square)
751
+ ![JSON Numbers](https://img.shields.io/badge/JSON_Numbers-1-059669?style=flat-square)
752
+ ![JSON Booleans](https://img.shields.io/badge/JSON_Booleans-7-0ea5e9?style=flat-square)
753
+ ![JSON Nulls](https://img.shields.io/badge/JSON_Nulls-0-64748b?style=flat-square)
754
+ ![JSON Items](https://img.shields.io/badge/JSON_Items-42-475569?style=flat-square)
755
+ ![JSON Nodes](https://img.shields.io/badge/JSON_Nodes-149-dc2626?style=flat-square)
756
+ ![JSON Max Depth](https://img.shields.io/badge/JSON_Max_Depth-5-ea580c?style=flat-square)
757
+
758
+ ### YAML
759
+
760
+ ![YAML Files](https://img.shields.io/badge/YAML_Files-0-cb171e?style=flat-square)
761
+ ![YAML Lines](https://img.shields.io/badge/YAML_Lines-0-e34c26?style=flat-square)
762
+ ![YAML Documents](https://img.shields.io/badge/YAML_Documents-0-f97316?style=flat-square)
763
+ ![YAML Mappings](https://img.shields.io/badge/YAML_Mappings-0-7c3aed?style=flat-square)
764
+ ![YAML Sequences](https://img.shields.io/badge/YAML_Sequences-0-8b5cf6?style=flat-square)
765
+ ![YAML Keys](https://img.shields.io/badge/YAML_Keys-0-0284c7?style=flat-square)
766
+ ![YAML Scalars](https://img.shields.io/badge/YAML_Scalars-0-16a34a?style=flat-square)
767
+ ![YAML Anchors](https://img.shields.io/badge/YAML_Anchors-0-059669?style=flat-square)
768
+ ![YAML Aliases](https://img.shields.io/badge/YAML_Aliases-0-10b981?style=flat-square)
769
+ ![YAML Comments](https://img.shields.io/badge/YAML_Comments-0-64748b?style=flat-square)
770
+ ![YAML Max Depth](https://img.shields.io/badge/YAML_Max_Depth-0-ea580c?style=flat-square)
771
+
772
+ ### TOML
773
+
774
+ ![TOML Files](https://img.shields.io/badge/TOML_Files-0-9c4221?style=flat-square)
775
+ ![TOML Lines](https://img.shields.io/badge/TOML_Lines-0-b45309?style=flat-square)
776
+ ![TOML Tables](https://img.shields.io/badge/TOML_Tables-0-7c3aed?style=flat-square)
777
+ ![TOML Array Tables](https://img.shields.io/badge/TOML_Array_Tables-0-8b5cf6?style=flat-square)
778
+ ![TOML Keys](https://img.shields.io/badge/TOML_Keys-0-0284c7?style=flat-square)
779
+ ![TOML Arrays](https://img.shields.io/badge/TOML_Arrays-0-16a34a?style=flat-square)
780
+ ![TOML Comments](https://img.shields.io/badge/TOML_Comments-0-64748b?style=flat-square)
781
+
782
+ ### Shell
783
+
784
+ ![Shell Files](https://img.shields.io/badge/Shell_Files-0-89e051?style=flat-square)
785
+ ![Shell Lines](https://img.shields.io/badge/Shell_Lines-0-4eaa25?style=flat-square)
786
+ ![Shell Functions](https://img.shields.io/badge/Shell_Functions-0-16a34a?style=flat-square)
787
+ ![Shell Variables](https://img.shields.io/badge/Shell_Variables-0-0284c7?style=flat-square)
788
+ ![Shell Exports](https://img.shields.io/badge/Shell_Exports-0-ea580c?style=flat-square)
789
+ ![Shell Conditionals](https://img.shields.io/badge/Shell_Conditionals-0-7c3aed?style=flat-square)
790
+ ![Shell Loops](https://img.shields.io/badge/Shell_Loops-0-8b5cf6?style=flat-square)
791
+ ![Shell Pipelines](https://img.shields.io/badge/Shell_Pipelines-0-059669?style=flat-square)
792
+ ![Shebangs](https://img.shields.io/badge/Shebangs-0-6b7280?style=flat-square)
793
+ ![Shell Comments](https://img.shields.io/badge/Shell_Comments-0-64748b?style=flat-square)
794
+ ![Shell Comment Lines](https://img.shields.io/badge/Shell_Comment_Lines-0-475569?style=flat-square)
795
+
796
+ ### SQL
797
+
798
+ ![SQL Files](https://img.shields.io/badge/SQL_Files-0-e38c00?style=flat-square)
799
+ ![SQL Lines](https://img.shields.io/badge/SQL_Lines-0-f29111?style=flat-square)
800
+ ![SQL Statements](https://img.shields.io/badge/SQL_Statements-0-7c3aed?style=flat-square)
801
+ ![SQL Selects](https://img.shields.io/badge/SQL_Selects-0-16a34a?style=flat-square)
802
+ ![SQL Inserts](https://img.shields.io/badge/SQL_Inserts-0-22c55e?style=flat-square)
803
+ ![SQL Updates](https://img.shields.io/badge/SQL_Updates-0-0ea5e9?style=flat-square)
804
+ ![SQL Deletes](https://img.shields.io/badge/SQL_Deletes-0-dc2626?style=flat-square)
805
+ ![SQL Creates](https://img.shields.io/badge/SQL_Creates-0-0284c7?style=flat-square)
806
+ ![SQL Joins](https://img.shields.io/badge/SQL_Joins-0-8b5cf6?style=flat-square)
807
+ ![SQL CTEs](https://img.shields.io/badge/SQL_CTEs-0-059669?style=flat-square)
808
+ ![SQL Comments](https://img.shields.io/badge/SQL_Comments-0-64748b?style=flat-square)
809
+
810
+ ### HCL
811
+
812
+ ![HCL Files](https://img.shields.io/badge/HCL_Files-0-844fba?style=flat-square)
813
+ ![HCL Lines](https://img.shields.io/badge/HCL_Lines-0-a78bfa?style=flat-square)
814
+ ![HCL Blocks](https://img.shields.io/badge/HCL_Blocks-0-7c3aed?style=flat-square)
815
+ ![HCL Resources](https://img.shields.io/badge/HCL_Resources-0-0284c7?style=flat-square)
816
+ ![HCL Variables](https://img.shields.io/badge/HCL_Variables-0-16a34a?style=flat-square)
817
+ ![HCL Outputs](https://img.shields.io/badge/HCL_Outputs-0-059669?style=flat-square)
818
+ ![HCL Attributes](https://img.shields.io/badge/HCL_Attributes-0-0ea5e9?style=flat-square)
819
+ ![HCL Interpolations](https://img.shields.io/badge/HCL_Interpolations-0-db2777?style=flat-square)
820
+ ![HCL Comments](https://img.shields.io/badge/HCL_Comments-0-64748b?style=flat-square)
821
+
822
+ ### CSS
823
+
824
+ ![CSS Files](https://img.shields.io/badge/CSS_Files-0-264de4?style=flat-square)
825
+ ![CSS Lines](https://img.shields.io/badge/CSS_Lines-0-2965f1?style=flat-square)
826
+ ![CSS Rules](https://img.shields.io/badge/CSS_Rules-0-7c3aed?style=flat-square)
827
+ ![CSS Selectors](https://img.shields.io/badge/CSS_Selectors-0-8b5cf6?style=flat-square)
828
+ ![CSS Declarations](https://img.shields.io/badge/CSS_Declarations-0-0284c7?style=flat-square)
829
+ ![CSS At Rules](https://img.shields.io/badge/CSS_At_Rules-0-f97316?style=flat-square)
830
+ ![CSS Media Queries](https://img.shields.io/badge/CSS_Media_Queries-0-ea580c?style=flat-square)
831
+ ![CSS Custom Properties](https://img.shields.io/badge/CSS_Custom_Properties-0-16a34a?style=flat-square)
832
+ ![CSS Comments](https://img.shields.io/badge/CSS_Comments-0-64748b?style=flat-square)
833
+
834
+ ### Conventions
835
+
836
+ ![Module Files](https://img.shields.io/badge/Module_Files-1-7c3aed?style=flat-square)
837
+ ![Service Files](https://img.shields.io/badge/Service_Files-4-0284c7?style=flat-square)
838
+ ![Command Files](https://img.shields.io/badge/Command_Files-0-16a34a?style=flat-square)
839
+ ![Constants Files](https://img.shields.io/badge/Constants_Files-3-ea580c?style=flat-square)
840
+ ![Types Files](https://img.shields.io/badge/Types_Files-4-db2777?style=flat-square)
841
+ ![Utilities Files](https://img.shields.io/badge/Utilities_Files-0-0ea5e9?style=flat-square)
842
+ ![TypeORM Entities](https://img.shields.io/badge/TypeORM_Entities-0-059669?style=flat-square)
843
+ ![Unit Tests](https://img.shields.io/badge/Unit_Tests-6-ca8a04?style=flat-square)
844
+ ![Integration Tests](https://img.shields.io/badge/Integration_Tests-0-7c3aed?style=flat-square)
845
+ ![End To End Tests](https://img.shields.io/badge/End_To_End_Tests-0-0284c7?style=flat-square)
846
+ ![CSS Comment Budget](https://img.shields.io/badge/CSS_Comment_Budget-0-16a34a?style=flat-square)
847
+ ![HCL Comment Budget](https://img.shields.io/badge/HCL_Comment_Budget-0-ea580c?style=flat-square)
848
+ ![Python Comment Budget](https://img.shields.io/badge/Python_Comment_Budget-0-db2777?style=flat-square)
849
+ ![SQL Comment Budget](https://img.shields.io/badge/SQL_Comment_Budget-0-0ea5e9?style=flat-square)
850
+ ![TOML Comment Budget](https://img.shields.io/badge/TOML_Comment_Budget-0-059669?style=flat-square)
851
+ ![TypeScript Comment Budget](https://img.shields.io/badge/TypeScript_Comment_Budget-0-ca8a04?style=flat-square)
852
+ ![YAML Comment Budget](https://img.shields.io/badge/YAML_Comment_Budget-0-7c3aed?style=flat-square)
853
+ ![Shell Comment Budget](https://img.shields.io/badge/Shell_Comment_Budget-0-0284c7?style=flat-square)
854
+
855
+ ### Jupyter
856
+
857
+ ![Notebooks](https://img.shields.io/badge/Notebooks-0-f37626?style=flat-square)
858
+ ![Notebook Cells](https://img.shields.io/badge/Notebook_Cells-0-e8a33d?style=flat-square)
859
+ ![Code Cells](https://img.shields.io/badge/Code_Cells-0-3776ab?style=flat-square)
860
+ ![Markdown Cells](https://img.shields.io/badge/Markdown_Cells-0-083fa1?style=flat-square)
861
+ ![Raw Cells](https://img.shields.io/badge/Raw_Cells-0-9ca3af?style=flat-square)
862
+ ![Executed Cells](https://img.shields.io/badge/Executed_Cells-0-16a34a?style=flat-square)
863
+ ![Cell Outputs](https://img.shields.io/badge/Cell_Outputs-0-059669?style=flat-square)
864
+ ![Notebook Code Lines](https://img.shields.io/badge/Notebook_Code_Lines-0-4b8bbe?style=flat-square)
865
+ ![Notebook Classes](https://img.shields.io/badge/Notebook_Classes-0-7c3aed?style=flat-square)
866
+ ![Notebook Functions](https://img.shields.io/badge/Notebook_Functions-0-22c55e?style=flat-square)
867
+ ![Notebook Imports](https://img.shields.io/badge/Notebook_Imports-0-0284c7?style=flat-square)
868
+ ![Notebook Decorators](https://img.shields.io/badge/Notebook_Decorators-0-db2777?style=flat-square)
869
+ ![Notebook Prose Lines](https://img.shields.io/badge/Notebook_Prose_Lines-0-1f6feb?style=flat-square)
870
+ ![Notebook Headings](https://img.shields.io/badge/Notebook_Headings-0-a78bfa?style=flat-square)
871
+ ![Notebook Links](https://img.shields.io/badge/Notebook_Links-0-10b981?style=flat-square)
872
+ ![Notebook Images](https://img.shields.io/badge/Notebook_Images-0-34d399?style=flat-square)
873
+ ![Notebook Code Blocks](https://img.shields.io/badge/Notebook_Code_Blocks-0-dc2626?style=flat-square)
874
+ ![Notebook Properties](https://img.shields.io/badge/Notebook_Properties-0-ca8a04?style=flat-square)
875
+ ![Notebook Nodes](https://img.shields.io/badge/Notebook_Nodes-0-a16207?style=flat-square)
876
+ ![Notebook Max Depth](https://img.shields.io/badge/Notebook_Max_Depth-0-ea580c?style=flat-square)
877
+
878
+ ### Markdown
879
+
880
+ ![Markdown Files](https://img.shields.io/badge/Markdown_Files-1-083fa1?style=flat-square)
881
+ ![Markdown Lines](https://img.shields.io/badge/Markdown_Lines-222-1f6feb?style=flat-square)
882
+ ![H1](https://img.shields.io/badge/H1-1-7c3aed?style=flat-square)
883
+ ![H2](https://img.shields.io/badge/H2-7-8b5cf6?style=flat-square)
884
+ ![H3](https://img.shields.io/badge/H3-12-a78bfa?style=flat-square)
885
+ ![H4](https://img.shields.io/badge/H4-0-c4b5fd?style=flat-square)
886
+ ![H5](https://img.shields.io/badge/H5-0-ddd6fe?style=flat-square)
887
+ ![H6](https://img.shields.io/badge/H6-0-ede9fe?style=flat-square)
888
+ ![Paragraphs](https://img.shields.io/badge/Paragraphs-45-64748b?style=flat-square)
889
+ ![Lists](https://img.shields.io/badge/Lists-6-16a34a?style=flat-square)
890
+ ![List Items](https://img.shields.io/badge/List_Items-25-22c55e?style=flat-square)
891
+ ![Task List Items](https://img.shields.io/badge/Task_List_Items-0-4ade80?style=flat-square)
892
+ ![Tables](https://img.shields.io/badge/Tables-2-0284c7?style=flat-square)
893
+ ![Table Rows](https://img.shields.io/badge/Table_Rows-10-0ea5e9?style=flat-square)
894
+ ![Links](https://img.shields.io/badge/Links-9-059669?style=flat-square)
895
+ ![Images](https://img.shields.io/badge/Images-0-10b981?style=flat-square)
896
+ ![Code Blocks](https://img.shields.io/badge/Code_Blocks-11-dc2626?style=flat-square)
897
+ ![Inline Code](https://img.shields.io/badge/Inline_Code-73-ef4444?style=flat-square)
898
+ ![Block Quotes](https://img.shields.io/badge/Block_Quotes-0-ca8a04?style=flat-square)
899
+ ![Thematic Breaks](https://img.shields.io/badge/Thematic_Breaks-0-a16207?style=flat-square)
900
+ <!-- codometer:end -->