@conformetry/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 +426 -0
- package/dist/src/index.d.ts +242 -0
- package/dist/src/index.js +30 -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,426 @@
|
|
|
1
|
+
# 👔 Conformetry Core
|
|
2
|
+
|
|
3
|
+
The shared contract every other [Conformetry](../conformetry-cli/README.md)
|
|
4
|
+
package builds on. It is the contracts leaf of the five-layer spine — `core <-
|
|
5
|
+
configuration <- analysis <- output <- cli` — so it declares types and holds
|
|
6
|
+
nothing executable: no service, no NestJS module, no dependency on anything
|
|
7
|
+
else in the conformetry graph. Importing a result type from here therefore
|
|
8
|
+
drags nothing behind it.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install --save-dev @conformetry/core
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## What it owns
|
|
15
|
+
|
|
16
|
+
| File | Responsibility |
|
|
17
|
+
| ---- | -------------- |
|
|
18
|
+
| `lib/differences.types.ts` | The structured `ConformetryDifference` shape, and the language and category unions that discriminate it |
|
|
19
|
+
| `lib/inventory.types.ts` | What discovery found, as the output layer renders it: templates, instances, and the pairings between them |
|
|
20
|
+
| `lib/runner.types.ts` | The `ConformetryLanguageValidator` contract and the document, payload, and result shapes it is spoken in |
|
|
21
|
+
| `lib/scoring.types.ts` | `InstanceScore`: how well one matched instance honours the template it matched |
|
|
22
|
+
|
|
23
|
+
The behavior these types describe lives above them. The difference and scoring
|
|
24
|
+
primitives, the file-existence pass, and every per-format validator are in
|
|
25
|
+
[`@conformetry/languages`](../conformetry-languages/README.md); the validator
|
|
26
|
+
envelope is in [`@conformetry/validation`](../conformetry-validation/README.md);
|
|
27
|
+
rendering is in [`@conformetry/output`](../conformetry-output/README.md).
|
|
28
|
+
|
|
29
|
+
"Language" here means a validator for one file format — TypeScript, JSON,
|
|
30
|
+
markdown, Python. The word "plugin" is reserved for the Nx plugin in
|
|
31
|
+
[`@conformetry/nx`](../conformetry-nx/README.md), and is deliberately not used
|
|
32
|
+
for these.
|
|
33
|
+
|
|
34
|
+
## Writing a language validator
|
|
35
|
+
|
|
36
|
+
A validator supplies a descriptor and a single-document comparison. Extension
|
|
37
|
+
filtering, grouping differences under their file, and assembling the result are
|
|
38
|
+
handled once by `RunnerService` in `@conformetry/validation`, so a language
|
|
39
|
+
package contains only its comparison logic:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
@Injectable()
|
|
43
|
+
export class ExampleValidatorService implements ConformetryLanguageValidator {
|
|
44
|
+
public readonly descriptor = EXAMPLE_VALIDATOR_DESCRIPTOR;
|
|
45
|
+
|
|
46
|
+
public validateDocument(
|
|
47
|
+
document: PreparedValidationDocument,
|
|
48
|
+
): DocumentValidationResult {
|
|
49
|
+
// compare document.renderedTemplate against document.instance
|
|
50
|
+
return { differences, totalWeight };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Weight and score
|
|
56
|
+
|
|
57
|
+
A validator reports how much the template asked for alongside what it found.
|
|
58
|
+
`totalWeight` counts every requirement the comparison weighed — conforming ones
|
|
59
|
+
included, because leaving them out would score an instance only against the
|
|
60
|
+
parts of itself that are already wrong.
|
|
61
|
+
|
|
62
|
+
Each difference may carry a `weight`, defaulting to 1. It says how many
|
|
63
|
+
requirements that one finding stands in for: a validator reports a missing
|
|
64
|
+
class once, however many members it held, so weighing the finding by its
|
|
65
|
+
subtree is what keeps deleting a class from costing the same as deleting an
|
|
66
|
+
import. No per-kind weight table is needed — a class is worth more because it
|
|
67
|
+
contains more.
|
|
68
|
+
|
|
69
|
+
```text
|
|
70
|
+
score = (totalWeight - sum(difference.weight ?? 1)) / totalWeight
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`ScoringService`, in `@conformetry/languages`, owns that arithmetic, including
|
|
74
|
+
the two cases worth getting right once: the default weight of a finding that
|
|
75
|
+
declares none, and an empty template whose denominator is zero and which
|
|
76
|
+
therefore conforms perfectly.
|
|
77
|
+
|
|
78
|
+
[`@conformetry/validation`](../conformetry-validation/README.md) drives the
|
|
79
|
+
registered validators; they are never responsible for discovering files or
|
|
80
|
+
loading configuration.
|
|
81
|
+
|
|
82
|
+
## Structured differences
|
|
83
|
+
|
|
84
|
+
Differences carry the location on both sides — instance and template — along
|
|
85
|
+
with the expected value and a concrete `fix`. That last field is the point:
|
|
86
|
+
reports are meant to be actionable by whoever, or whatever, has to make the
|
|
87
|
+
file conform. Prefer populating `instanceLine`/`templateLine` (or
|
|
88
|
+
`instancePath` for document formats) over folding a location into the message.
|
|
89
|
+
|
|
90
|
+
## Exports
|
|
91
|
+
|
|
92
|
+
Types only: `ConformetryDifference`, `ConformetryDifferenceLanguage`,
|
|
93
|
+
`ConformetryDifferenceType`, `ConformetryLanguageValidator`,
|
|
94
|
+
`DocumentValidationResult`, `InstanceScore`, `InventoriedInstance`,
|
|
95
|
+
`InventoriedPairing`, `InventoriedTemplate`, `LanguageValidatorDescriptor`,
|
|
96
|
+
`LanguageValidatorResult`, `PreparedValidationDocument`,
|
|
97
|
+
`PreparedValidationPayload`, and `ValidationFileResult`.
|
|
98
|
+
|
|
99
|
+
## Test
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
nx run conformetry-core:vitest
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
One test, and it asserts the property that makes this package a leaf: the
|
|
106
|
+
module contributes nothing at runtime, so importing a result type from here
|
|
107
|
+
cannot drag a service or a NestJS module behind it. Exporting one value fails
|
|
108
|
+
it.
|
|
109
|
+
|
|
110
|
+
## License
|
|
111
|
+
|
|
112
|
+
MIT — see [LICENSE](../../../../LICENSE).
|
|
113
|
+
|
|
114
|
+
## 👔 Conformetry
|
|
115
|
+
|
|
116
|
+
This project was generated from the [nestjs-service-project](../../../../configuration/conformetry-templates/nestjs-service-project) conformetry template.
|
|
117
|
+
|
|
118
|
+
<!-- callidescope:start -->
|
|
119
|
+
|
|
120
|
+
## 🔭 Callidescope
|
|
121
|
+
|
|
122
|
+
Call stacks traced through `packages/ic-suite/conformetry/conformetry-core`, deepest first. Each frame shows what it takes, what it returns, and what its documentation says.
|
|
123
|
+
|
|
124
|
+
| Measure | Value |
|
|
125
|
+
| --- | --- |
|
|
126
|
+
| Callables | 1 |
|
|
127
|
+
| Files | 11 |
|
|
128
|
+
| Calls traced | 0 |
|
|
129
|
+
| Call stacks | 0 |
|
|
130
|
+
| Deepest stack | 0 |
|
|
131
|
+
| Stacks through recursion | 0 |
|
|
132
|
+
| Unfollowable calls | 0 |
|
|
133
|
+
|
|
134
|
+
### Limits
|
|
135
|
+
|
|
136
|
+
What this project is judged against, as declared in its own `callidescope.config.ts`.
|
|
137
|
+
|
|
138
|
+
| Limit | Value |
|
|
139
|
+
| --- | --- |
|
|
140
|
+
| `maximumDepth` | 1 |
|
|
141
|
+
| `maximumBreadth` | 1 |
|
|
142
|
+
|
|
143
|
+
### Call stacks (depth)
|
|
144
|
+
|
|
145
|
+
None.
|
|
146
|
+
|
|
147
|
+
### Breadth
|
|
148
|
+
|
|
149
|
+
None.
|
|
150
|
+
<!-- callidescope:end -->
|
|
151
|
+
|
|
152
|
+
## 🕸️ Codependix
|
|
153
|
+
|
|
154
|
+
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`.
|
|
155
|
+
|
|
156
|
+
### Nx Neighborhood
|
|
157
|
+
|
|
158
|
+
<!-- codependix:start name="codependix-nx-projects" -->
|
|
159
|
+
```mermaid
|
|
160
|
+
graph LR
|
|
161
|
+
conformetry_cli["conformetry-cli"]
|
|
162
|
+
conformetry_configuration["conformetry-configuration"]
|
|
163
|
+
conformetry_core["conformetry-core"]
|
|
164
|
+
conformetry_languages["conformetry-languages"]
|
|
165
|
+
conformetry_output["conformetry-output"]
|
|
166
|
+
conformetry_validation["conformetry-validation"]
|
|
167
|
+
conformetry_cli --> conformetry_core
|
|
168
|
+
conformetry_configuration --> conformetry_core
|
|
169
|
+
conformetry_languages --> conformetry_core
|
|
170
|
+
conformetry_output --> conformetry_core
|
|
171
|
+
conformetry_validation --> conformetry_core
|
|
172
|
+
classDef subject fill:#7c3aed,color:#fff,stroke:#4c1d95,stroke-width:2px
|
|
173
|
+
class conformetry_core subject
|
|
174
|
+
```
|
|
175
|
+
<!-- codependix:end name="codependix-nx-projects" -->
|
|
176
|
+
|
|
177
|
+
### NestJS Module Graph
|
|
178
|
+
|
|
179
|
+
<!-- codependix:start name="codependix-nestjs-modules" -->
|
|
180
|
+
```mermaid
|
|
181
|
+
flowchart LR
|
|
182
|
+
ConformetryCoreModule
|
|
183
|
+
```
|
|
184
|
+
<!-- codependix:end name="codependix-nestjs-modules" -->
|
|
185
|
+
|
|
186
|
+
### File Imports
|
|
187
|
+
|
|
188
|
+
<!-- codependix:start name="codependix-file-imports" -->
|
|
189
|
+
```mermaid
|
|
190
|
+
graph LR
|
|
191
|
+
file_callidescope_config_ts["callidescope.config.ts"]
|
|
192
|
+
file_codependix_config_ts["codependix.config.ts"]
|
|
193
|
+
file_codometer_config_ts["codometer.config.ts"]
|
|
194
|
+
file_eslint_config_ts["eslint.config.ts"]
|
|
195
|
+
file_src_index_ts["src/index.ts"]
|
|
196
|
+
file_src_index_unit_test_ts["src/index.unit.test.ts"]
|
|
197
|
+
file_src_modules_conformetry_core_conformetry_core_constants_ts["src/modules/conformetry-core/conformetry-core.constants.ts"]
|
|
198
|
+
file_src_modules_conformetry_core_conformetry_core_module_ts["src/modules/conformetry-core/conformetry-core.module.ts"]
|
|
199
|
+
file_src_modules_conformetry_core_conformetry_core_service_ts["src/modules/conformetry-core/conformetry-core.service.ts"]
|
|
200
|
+
file_src_modules_conformetry_core_conformetry_core_service_unit_test_ts["src/modules/conformetry-core/conformetry-core.service.unit.test.ts"]
|
|
201
|
+
file_src_modules_conformetry_core_conformetry_core_types_ts["src/modules/conformetry-core/conformetry-core.types.ts"]
|
|
202
|
+
file_testing_mocks_ts["testing/mocks.ts"]
|
|
203
|
+
file_testing_setup_ts["testing/setup.ts"]
|
|
204
|
+
file_vite_config_ts["vite.config.ts"]
|
|
205
|
+
file_vitest_config_ts["vitest.config.ts"]
|
|
206
|
+
file_src_index_unit_test_ts --> file_src_index_ts
|
|
207
|
+
file_src_modules_conformetry_core_conformetry_core_module_ts --> file_src_modules_conformetry_core_conformetry_core_service_ts
|
|
208
|
+
file_src_modules_conformetry_core_conformetry_core_service_unit_test_ts --> file_src_modules_conformetry_core_conformetry_core_service_ts
|
|
209
|
+
```
|
|
210
|
+
<!-- codependix:end name="codependix-file-imports" -->
|
|
211
|
+
|
|
212
|
+
<!-- codometer:start -->
|
|
213
|
+
|
|
214
|
+
## ⏲️ Codometer
|
|
215
|
+
|
|
216
|
+
### Project
|
|
217
|
+
|
|
218
|
+

|
|
219
|
+

|
|
220
|
+

|
|
221
|
+

|
|
222
|
+
|
|
223
|
+
### Measured Targets
|
|
224
|
+
|
|
225
|
+

|
|
226
|
+
|
|
227
|
+
### TypeScript
|
|
228
|
+
|
|
229
|
+

|
|
230
|
+

|
|
231
|
+

|
|
232
|
+

|
|
233
|
+

|
|
234
|
+

|
|
235
|
+

|
|
236
|
+
|
|
237
|
+
### JavaScript
|
|
238
|
+
|
|
239
|
+

|
|
240
|
+

|
|
241
|
+

|
|
242
|
+

|
|
243
|
+

|
|
244
|
+

|
|
245
|
+

|
|
246
|
+

|
|
247
|
+

|
|
248
|
+

|
|
249
|
+

|
|
250
|
+

|
|
251
|
+

|
|
252
|
+

|
|
253
|
+
|
|
254
|
+
### Python
|
|
255
|
+
|
|
256
|
+

|
|
257
|
+

|
|
258
|
+

|
|
259
|
+

|
|
260
|
+

|
|
261
|
+

|
|
262
|
+

|
|
263
|
+

|
|
264
|
+

|
|
265
|
+

|
|
266
|
+

|
|
267
|
+

|
|
268
|
+
|
|
269
|
+
### JSON
|
|
270
|
+
|
|
271
|
+

|
|
272
|
+

|
|
273
|
+

|
|
274
|
+

|
|
275
|
+

|
|
276
|
+

|
|
277
|
+

|
|
278
|
+

|
|
279
|
+

|
|
280
|
+

|
|
281
|
+

|
|
282
|
+

|
|
283
|
+
|
|
284
|
+
### YAML
|
|
285
|
+
|
|
286
|
+

|
|
287
|
+

|
|
288
|
+

|
|
289
|
+

|
|
290
|
+

|
|
291
|
+

|
|
292
|
+

|
|
293
|
+

|
|
294
|
+

|
|
295
|
+

|
|
296
|
+

|
|
297
|
+
|
|
298
|
+
### TOML
|
|
299
|
+
|
|
300
|
+

|
|
301
|
+

|
|
302
|
+

|
|
303
|
+

|
|
304
|
+

|
|
305
|
+

|
|
306
|
+

|
|
307
|
+
|
|
308
|
+
### Shell
|
|
309
|
+
|
|
310
|
+

|
|
311
|
+

|
|
312
|
+

|
|
313
|
+

|
|
314
|
+

|
|
315
|
+

|
|
316
|
+

|
|
317
|
+

|
|
318
|
+

|
|
319
|
+

|
|
320
|
+

|
|
321
|
+
|
|
322
|
+
### SQL
|
|
323
|
+
|
|
324
|
+

|
|
325
|
+

|
|
326
|
+

|
|
327
|
+

|
|
328
|
+

|
|
329
|
+

|
|
330
|
+

|
|
331
|
+

|
|
332
|
+

|
|
333
|
+

|
|
334
|
+

|
|
335
|
+
|
|
336
|
+
### HCL
|
|
337
|
+
|
|
338
|
+

|
|
339
|
+

|
|
340
|
+

|
|
341
|
+

|
|
342
|
+

|
|
343
|
+

|
|
344
|
+

|
|
345
|
+

|
|
346
|
+

|
|
347
|
+
|
|
348
|
+
### CSS
|
|
349
|
+
|
|
350
|
+

|
|
351
|
+

|
|
352
|
+

|
|
353
|
+

|
|
354
|
+

|
|
355
|
+

|
|
356
|
+

|
|
357
|
+

|
|
358
|
+

|
|
359
|
+
|
|
360
|
+
### Conventions
|
|
361
|
+
|
|
362
|
+

|
|
363
|
+

|
|
364
|
+

|
|
365
|
+

|
|
366
|
+

|
|
367
|
+

|
|
368
|
+

|
|
369
|
+

|
|
370
|
+

|
|
371
|
+

|
|
372
|
+

|
|
373
|
+

|
|
374
|
+

|
|
375
|
+

|
|
376
|
+

|
|
377
|
+

|
|
378
|
+

|
|
379
|
+

|
|
380
|
+
|
|
381
|
+
### Jupyter
|
|
382
|
+
|
|
383
|
+

|
|
384
|
+

|
|
385
|
+

|
|
386
|
+

|
|
387
|
+

|
|
388
|
+

|
|
389
|
+

|
|
390
|
+

|
|
391
|
+

|
|
392
|
+

|
|
393
|
+

|
|
394
|
+

|
|
395
|
+

|
|
396
|
+

|
|
397
|
+

|
|
398
|
+

|
|
399
|
+

|
|
400
|
+

|
|
401
|
+

|
|
402
|
+

|
|
403
|
+
|
|
404
|
+
### Markdown
|
|
405
|
+
|
|
406
|
+

|
|
407
|
+

|
|
408
|
+

|
|
409
|
+

|
|
410
|
+

|
|
411
|
+

|
|
412
|
+

|
|
413
|
+

|
|
414
|
+

|
|
415
|
+

|
|
416
|
+

|
|
417
|
+

|
|
418
|
+

|
|
419
|
+

|
|
420
|
+

|
|
421
|
+

|
|
422
|
+

|
|
423
|
+

|
|
424
|
+

|
|
425
|
+

|
|
426
|
+
<!-- codometer:end -->
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TODO: Document the conformetryCore module.
|
|
3
|
+
*/
|
|
4
|
+
export declare class ConformetryCoreModule {
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* TODO: Document the conformetryCore service.
|
|
9
|
+
*/
|
|
10
|
+
export declare class ConformetryCoreService {
|
|
11
|
+
constructor();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* A structured conformance error produced by any validator.
|
|
16
|
+
*
|
|
17
|
+
* Two discriminating fields identify the error category:
|
|
18
|
+
* - `differenceType` — what kind of element is missing
|
|
19
|
+
* - `language` — which validator / file format produced the error.
|
|
20
|
+
*
|
|
21
|
+
* All differences represent a *missing* or *mismatched* element; there is no
|
|
22
|
+
* separate action field. Consumers render these through `ReportingService`
|
|
23
|
+
* rather than formatting them ad hoc, so every validator reports identically.
|
|
24
|
+
*/
|
|
25
|
+
export declare interface ConformetryDifference {
|
|
26
|
+
/** Actual value found in the instance (populated for value-mismatch differences). */
|
|
27
|
+
readonly actual?: string;
|
|
28
|
+
/** Category of missing element. */
|
|
29
|
+
readonly differenceType: ConformetryDifferenceType;
|
|
30
|
+
/** Snippet of the template content that should be present in the instance. */
|
|
31
|
+
readonly expected?: string;
|
|
32
|
+
/** One-line actionable suggestion for the reader (human or coding agent). */
|
|
33
|
+
readonly fix: string;
|
|
34
|
+
/** 1-based column number in the instance file where the error was detected. */
|
|
35
|
+
readonly instanceColumn?: number;
|
|
36
|
+
/** 1-based line number in the instance file where the error was detected. */
|
|
37
|
+
readonly instanceLine?: number;
|
|
38
|
+
/** JSON dot-notation path in the instance document, e.g. `"scripts.build[0]"`. */
|
|
39
|
+
readonly instancePath?: string;
|
|
40
|
+
/**
|
|
41
|
+
* File format of the validator that produced this error.
|
|
42
|
+
* Absent for `"file"` and `"directory"` differences.
|
|
43
|
+
*/
|
|
44
|
+
readonly language?: ConformetryDifferenceLanguage;
|
|
45
|
+
/** Short human-readable description of what is missing. */
|
|
46
|
+
readonly message: string;
|
|
47
|
+
/** 1-based column number in the rendered template that defines the requirement. */
|
|
48
|
+
readonly templateColumn?: number;
|
|
49
|
+
/** 1-based line number in the rendered template that defines the requirement. */
|
|
50
|
+
readonly templateLine?: number;
|
|
51
|
+
/** JSON dot-notation path in the template document. */
|
|
52
|
+
readonly templatePath?: string;
|
|
53
|
+
/**
|
|
54
|
+
* How many template requirements this one finding accounts for.
|
|
55
|
+
*
|
|
56
|
+
* A validator reports a missing element once, however much of the template
|
|
57
|
+
* that element contained: deleting a class is one error, not one per member.
|
|
58
|
+
* The weight restores the proportion — a missing class stands in for its
|
|
59
|
+
* whole subtree, a missing import stands only for itself — so an instance's
|
|
60
|
+
* score reflects how much of the template is actually absent.
|
|
61
|
+
*
|
|
62
|
+
* Defaults to 1 when absent, which is right for any leaf requirement.
|
|
63
|
+
*/
|
|
64
|
+
readonly weight?: number;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* The language / file format processed by the validator that produced the
|
|
69
|
+
* error. Absent for `"file"` and `"directory"` differences, which are language
|
|
70
|
+
* agnostic and raised by the file-existence pass.
|
|
71
|
+
*/
|
|
72
|
+
export declare type ConformetryDifferenceLanguage = "javascript" | "json" | "markdown" | "python" | "text" | "typescript";
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Category of the element that caused the conformance failure.
|
|
76
|
+
*
|
|
77
|
+
* `"instance"` is the odd one out: it does not name a missing element inside a
|
|
78
|
+
* file but a directory or file the caller declared to be generated code, which
|
|
79
|
+
* conformetry could not attribute to any single template.
|
|
80
|
+
*/
|
|
81
|
+
export declare type ConformetryDifferenceType = "code" | "comment" | "directory" | "file" | "instance";
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* A validator for one language or file format.
|
|
85
|
+
*
|
|
86
|
+
* Implementations supply only their descriptor and a single-document
|
|
87
|
+
* comparison. Extension filtering, result grouping, and result assembly are
|
|
88
|
+
* handled once by `RunnerService`, so no validator repeats that envelope.
|
|
89
|
+
*
|
|
90
|
+
* Not to be confused with an Nx plugin — this is the contract between
|
|
91
|
+
* `conformetry-validation` and the Language modules in `conformetry-languages`,
|
|
92
|
+
* such as its TypeScript module.
|
|
93
|
+
*/
|
|
94
|
+
export declare interface ConformetryLanguageValidator {
|
|
95
|
+
readonly descriptor: LanguageValidatorDescriptor;
|
|
96
|
+
/**
|
|
97
|
+
* Compares one already-rendered template against its instance and returns
|
|
98
|
+
* every difference, plus how much was asked of the instance. Called only for
|
|
99
|
+
* documents whose extension this validator claims, so implementations never
|
|
100
|
+
* need to re-check the extension.
|
|
101
|
+
*/
|
|
102
|
+
validateDocument(document: PreparedValidationDocument): DocumentValidationResult;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* What comparing one document produced: the differences, and the size of the
|
|
107
|
+
* requirement the comparison weighed them against.
|
|
108
|
+
*
|
|
109
|
+
* The total is reported even when nothing is wrong. A conforming document is
|
|
110
|
+
* still evidence — it is the part of the instance that *did* honour its
|
|
111
|
+
* template — and leaving it out of the denominator would score an instance
|
|
112
|
+
* only against the files it got wrong.
|
|
113
|
+
*/
|
|
114
|
+
export declare interface DocumentValidationResult {
|
|
115
|
+
readonly differences: ConformetryDifference[];
|
|
116
|
+
/** Combined weight of the template requirements this document imposes. */
|
|
117
|
+
readonly totalWeight: number;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* How well one matched instance honours the template it was matched to.
|
|
122
|
+
*
|
|
123
|
+
* Lives in core rather than beside the orchestrator because reporting renders
|
|
124
|
+
* it and the orchestrator produces it, and a shape shared by two layers is
|
|
125
|
+
* exactly what the leaf package is for.
|
|
126
|
+
*/
|
|
127
|
+
export declare interface InstanceScore {
|
|
128
|
+
/** Combined weight of the requirements this instance failed. */
|
|
129
|
+
readonly failedWeight: number;
|
|
130
|
+
readonly instancePath: string;
|
|
131
|
+
/** Whether the score reached the threshold that applies to this instance. */
|
|
132
|
+
readonly ok: boolean;
|
|
133
|
+
/** Share of the template's requirements honoured, from 0 to 1. */
|
|
134
|
+
readonly score: number;
|
|
135
|
+
readonly templateName: string;
|
|
136
|
+
/** The threshold that applied, after resolving every level. */
|
|
137
|
+
readonly threshold: number;
|
|
138
|
+
/** Combined weight of the requirements that were checked. */
|
|
139
|
+
readonly totalWeight: number;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* One instance found on disk, paired with the templates that explain it.
|
|
144
|
+
*
|
|
145
|
+
* Lives in core for the same reason [[InstanceScore]] does: discovery produces
|
|
146
|
+
* it and the output layer renders it, so the shape belongs to neither side.
|
|
147
|
+
*/
|
|
148
|
+
export declare interface InventoriedInstance {
|
|
149
|
+
/** Where the instance is, including its name stem. */
|
|
150
|
+
readonly path: string;
|
|
151
|
+
/** Templates that explain this instance, best fit first. */
|
|
152
|
+
readonly templates: InventoriedPairing[];
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* How well one template and one instance fit each other.
|
|
157
|
+
*
|
|
158
|
+
* The ratio is file overlap, not conformance: it says how much of a template's
|
|
159
|
+
* structure an instance has, never how faithfully those files honour it.
|
|
160
|
+
*/
|
|
161
|
+
export declare interface InventoriedPairing {
|
|
162
|
+
readonly matchedFileCount: number;
|
|
163
|
+
/** Share of the template's files the instance already has, 0 to 1. */
|
|
164
|
+
readonly matchRatio: number;
|
|
165
|
+
/** The other side of the pairing — a template name or an instance path. */
|
|
166
|
+
readonly name: string;
|
|
167
|
+
readonly templateFileCount: number;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** One declared template, paired with the instances it explains. */
|
|
171
|
+
export declare interface InventoriedTemplate {
|
|
172
|
+
readonly description: string;
|
|
173
|
+
/** Instances this template explains, empty when nothing matched it. */
|
|
174
|
+
readonly instances: InventoriedPairing[];
|
|
175
|
+
readonly name: string;
|
|
176
|
+
readonly templatePath: string;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Identifies a language validator and declares which files it claims. */
|
|
180
|
+
export declare interface LanguageValidatorDescriptor {
|
|
181
|
+
/** Human-readable summary shown in CLI help and reports. */
|
|
182
|
+
readonly description?: string;
|
|
183
|
+
/** Extensions this validator claims, including the leading dot. */
|
|
184
|
+
readonly fileExtensions: readonly string[];
|
|
185
|
+
/** Stable identifier, also usable as a `--languages` filter value. */
|
|
186
|
+
readonly name: string;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/** Outcome of running one language validator over a document set. */
|
|
190
|
+
export declare interface LanguageValidatorResult {
|
|
191
|
+
readonly checkedPaths: string[];
|
|
192
|
+
readonly fileResults: ValidationFileResult[];
|
|
193
|
+
readonly languageName: string;
|
|
194
|
+
readonly ok: boolean;
|
|
195
|
+
/**
|
|
196
|
+
* Combined weight of every document this validator claimed, conforming ones
|
|
197
|
+
* included — see `DocumentValidationResult.totalWeight`.
|
|
198
|
+
*/
|
|
199
|
+
readonly totalWeight: number;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* A template file paired with the instance file it governs, with the template
|
|
204
|
+
* already rendered against the project's substitutions. Producing these is
|
|
205
|
+
* `conformetry-configuration`'s job; validators only compare them.
|
|
206
|
+
*
|
|
207
|
+
* A document exists only when both sides are present on disk — missing files
|
|
208
|
+
* are reported by the file-existence pass before validators ever run.
|
|
209
|
+
*/
|
|
210
|
+
export declare interface PreparedValidationDocument {
|
|
211
|
+
/** Basename of the instance file, used to pick a parser. */
|
|
212
|
+
readonly filename: string;
|
|
213
|
+
/** Verbatim contents of the instance file. */
|
|
214
|
+
readonly instance: string;
|
|
215
|
+
/** Absolute path to the instance file, used in error messages. */
|
|
216
|
+
readonly instanceFilePath: string;
|
|
217
|
+
/** Template contents after substitutions have been applied. */
|
|
218
|
+
readonly renderedTemplate: string;
|
|
219
|
+
/** Absolute path to the source template, used in error messages. */
|
|
220
|
+
readonly templateFilePath: string;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/** The document pairs discovered for one validation run. */
|
|
224
|
+
export declare interface PreparedValidationPayload {
|
|
225
|
+
readonly checkedPaths: string[];
|
|
226
|
+
readonly documents: PreparedValidationDocument[];
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Every error found in one instance file, kept grouped by file so reports can
|
|
231
|
+
* print a per-file heading with its originating template.
|
|
232
|
+
*/
|
|
233
|
+
export declare interface ValidationFileResult {
|
|
234
|
+
readonly differences: ConformetryDifference[];
|
|
235
|
+
readonly filename: string;
|
|
236
|
+
readonly instanceFilePath: string;
|
|
237
|
+
readonly templateFilePath: string;
|
|
238
|
+
/** Combined weight of the template requirements checked in this file. */
|
|
239
|
+
readonly totalWeight: number;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export { }
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Injectable as e, Module as t } from "@nestjs/common";
|
|
2
|
+
//#region \0@oxc-project+runtime@0.151.0/helpers/esm/decorateMetadata.js
|
|
3
|
+
function n(e, t) {
|
|
4
|
+
if (typeof Reflect == "object" && typeof Reflect.metadata == "function") return Reflect.metadata(e, t);
|
|
5
|
+
}
|
|
6
|
+
//#endregion
|
|
7
|
+
//#region \0@oxc-project+runtime@0.151.0/helpers/esm/decorate.js
|
|
8
|
+
function r(e, t, n, r) {
|
|
9
|
+
var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
|
|
10
|
+
if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
|
|
11
|
+
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);
|
|
12
|
+
return i > 3 && a && Object.defineProperty(t, n, a), a;
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region packages/ic-suite/conformetry/conformetry-core/src/modules/conformetry-core/conformetry-core.service.ts
|
|
16
|
+
var i = class {
|
|
17
|
+
constructor() {}
|
|
18
|
+
};
|
|
19
|
+
i = r([e(), n("design:paramtypes", [])], i);
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region packages/ic-suite/conformetry/conformetry-core/src/modules/conformetry-core/conformetry-core.module.ts
|
|
22
|
+
var a = class {};
|
|
23
|
+
a = r([t({
|
|
24
|
+
controllers: [],
|
|
25
|
+
exports: [i],
|
|
26
|
+
imports: [],
|
|
27
|
+
providers: [i]
|
|
28
|
+
})], a);
|
|
29
|
+
//#endregion
|
|
30
|
+
export { a as ConformetryCoreModule, i as ConformetryCoreService };
|
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 types and structured contracts for the Conformetry code generation and conformance 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/conformetry/conformetry-core#readme",
|
|
33
|
+
"keywords": [
|
|
34
|
+
"code-generation",
|
|
35
|
+
"conformance",
|
|
36
|
+
"conformetry",
|
|
37
|
+
"contracts",
|
|
38
|
+
"templates",
|
|
39
|
+
"types"
|
|
40
|
+
],
|
|
41
|
+
"license": "MIT",
|
|
42
|
+
"main": "./dist/src/index.js",
|
|
43
|
+
"name": "@conformetry/core",
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public",
|
|
46
|
+
"registry": "https://registry.npmjs.org"
|
|
47
|
+
},
|
|
48
|
+
"repository": {
|
|
49
|
+
"directory": "packages/ic-suite/conformetry/conformetry-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
|
+
}
|