@coinagerie/vocabulary 0.0.0-stage → 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/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ ## 0.0.1 (2026-11-04)
2
+
3
+ ### 🚀 Features
4
+
5
+ - **coinagerie:** 📦️ publish coinagerie to npm ([#2088](https://github.com/organizzolini/codebase/pull/2088), [#1793](https://github.com/organizzolini/codebase/issues/1793))
6
+ - **configuration,coinagerie:** ✨ adopt coinagerie with a root glossary ([#1888](https://github.com/organizzolini/codebase/pull/1888), [#1785](https://github.com/organizzolini/codebase/issues/1785))
7
+ - **coinagerie:** ✨ fold word forms and exclude configured words ([#1882](https://github.com/organizzolini/codebase/pull/1882), [#1762](https://github.com/organizzolini/codebase/issues/1762))
8
+ - **coinagerie:** ✨ build a markdown glossary from typescript ([#1875](https://github.com/organizzolini/codebase/pull/1875), [#1755](https://github.com/organizzolini/codebase/issues/1755))
9
+
10
+ ### 🧱 Updated Dependencies
11
+
12
+ - Updated coinagerie-configuration to 0.0.1
13
+ - Updated coinagerie-languages to 0.0.1
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 CHANGED
@@ -1,3 +1,532 @@
1
- # Temporary Holding Version
1
+ # @coinagerie/vocabulary
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ [![npm](https://img.shields.io/npm/v/@coinagerie/vocabulary?logo=npm&label=npm)](https://www.npmjs.com/package/@coinagerie/vocabulary)
4
+
5
+ File discovery, word splitting, folding, and exclusion: the part of coinagerie that turns a codebase into a sorted list of headwords.
6
+
7
+ ```bash
8
+ npm install @coinagerie/vocabulary
9
+ ```
10
+
11
+ ## Test
12
+
13
+ ```bash
14
+ nx run coinagerie-vocabulary:vitest
15
+ ```
16
+
17
+ ## 👔 Conformetry
18
+
19
+ This project was generated from the [nestjs-service-project](../../configuration/conformetry-templates/nestjs-service-project) conformetry template.
20
+
21
+ <!-- coinagerie:start -->
22
+
23
+ ## 🪙 Coinagerie
24
+
25
+ The words this package uses that the root glossary does not define, regenerated with `nx run coinagerie-vocabulary:coinagerie-check:write`.
26
+
27
+ - **absolute**:
28
+ - **after**:
29
+ - **ancestor**:
30
+ - **aspect**:
31
+ - **breadth**:
32
+ - **bug**:
33
+ - **bundle**:
34
+ - **chunk**:
35
+ - **clear**:
36
+ - **compile**:
37
+ - **compiler**:
38
+ - **configure**:
39
+ - **console**:
40
+ - **constant**:
41
+ - **controller**:
42
+ - **debug**:
43
+ - **decorator**:
44
+ - **deep**:
45
+ - **define**:
46
+ - **describe**:
47
+ - **discover**:
48
+ - **discovery**:
49
+ - **dist**:
50
+ - **doc**:
51
+ - **each**:
52
+ - **entry**:
53
+ - **equal**:
54
+ - **experimental**:
55
+ - **extname**:
56
+ - **fake**:
57
+ - **flat**:
58
+ - **force**:
59
+ - **gitkeep**:
60
+ - **glossary**:
61
+ - **guide**:
62
+ - **headword**:
63
+ - **homepage**:
64
+ - **identifier**:
65
+ - **ignorecase**:
66
+ - **implementation**:
67
+ - **injectable**:
68
+ - **keep**:
69
+ - **least**:
70
+ - **length**:
71
+ - **link**:
72
+ - **logo**:
73
+ - **lower**:
74
+ - **lowercase**:
75
+ - **mark**:
76
+ - **maximum**:
77
+ - **md**:
78
+ - **meta**:
79
+ - **mkdtemp**:
80
+ - **mock**:
81
+ - **one**:
82
+ - **other**:
83
+ - **own**:
84
+ - **part**:
85
+ - **partial**:
86
+ - **phase**:
87
+ - **png**:
88
+ - **posix**:
89
+ - **promise**:
90
+ - **publish**:
91
+ - **readdir**:
92
+ - **real**:
93
+ - **recursive**:
94
+ - **relative**:
95
+ - **reload**:
96
+ - **resolution**:
97
+ - **scoped**:
98
+ - **segment**:
99
+ - **sep**:
100
+ - **separator**:
101
+ - **singular**:
102
+ - **slice**:
103
+ - **some**:
104
+ - **sort**:
105
+ - **split**:
106
+ - **spy**:
107
+ - **strict**:
108
+ - **symbolic**:
109
+ - **symlink**:
110
+ - **synthetic**:
111
+ - **temporary**:
112
+ - **term**:
113
+ - **thing**:
114
+ - **timer**:
115
+ - **tmpdir**:
116
+ - **tokenizer**:
117
+ - **unignored**:
118
+ - **unmock**:
119
+ - **vendor**:
120
+ - **verb**:
121
+ - **verdict**:
122
+ - **vi**:
123
+ - **vocabulary**:
124
+ - **walk**:
125
+
126
+ <!-- coinagerie:end -->
127
+
128
+ <!-- callidescope:start -->
129
+
130
+ ## 🔭 Callidescope
131
+
132
+ Call stacks traced through `projects/ic-suite/coinagerie/coinagerie-vocabulary`, deepest first. Each frame shows what it takes, what it returns, and what its documentation says.
133
+
134
+ | Measure | Value |
135
+ | --- | --- |
136
+ | Callables | 39 |
137
+ | Files | 25 |
138
+ | Calls traced | 41 |
139
+ | Call stacks | 0 |
140
+ | Deepest stack | 0 |
141
+ | Stacks through recursion | 0 |
142
+ | Unfollowable calls | 1 |
143
+
144
+ ### Limits
145
+
146
+ What this project is judged against, as declared in its own `callidescope.config.ts`.
147
+
148
+ | Limit | Value |
149
+ | --- | --- |
150
+ | `maximumDepth` | 7 |
151
+ | `maximumBreadth` | 7 |
152
+
153
+ ### Call stacks (depth)
154
+
155
+ None.
156
+
157
+ ### Breadth
158
+
159
+ | Callable | Breadth | Calls directly | Location |
160
+ | --- | --- | --- | --- |
161
+ | `DiscoveryService.discover` | 7 | `DiscoveryService.findRepositoryRoot`, `DiscoveryService.map(…)`, `DiscoveryService.filter(…)`, `DiscoveryService.map(…)`, `DiscoveryService.filter(…)`, `DiscoveryService.walk`, `DiscoveryService.readAncestorScopes` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/discovery/discovery.service.ts:152` |
162
+ | `VocabularyService.collect` | 5 | `DiscoveryService.discover`, `VocabularyService.map(…)`, `VocabularyService.excludedHeadwords`, `VocabularyService.collectFile`, `FoldingService.headword` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/vocabulary/vocabulary.service.ts:95` |
163
+ | `DiscoveryService.walk` | 4 | `DiscoveryService.toPosix`, `IgnoreRulesService.readScope`, `DiscoveryService.flatMap(…)`, `DiscoveryService.filter(…)` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/discovery/discovery.service.ts:107` |
164
+
165
+ <details>
166
+ <summary>15 more callables</summary>
167
+
168
+ | Callable | Breadth | Calls directly | Location |
169
+ | --- | --- | --- | --- |
170
+ | `DiscoveryService.readAncestorScopes` | 3 | `DiscoveryService.filter(…)`, `DiscoveryService.toPosix`, `DiscoveryService.flatMap(…)` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/discovery/discovery.service.ts:78` |
171
+ | `DiscoveryService.flatMap(…)` | 3 | `IgnoreRulesService.isIgnored`, `DiscoveryService.isExcludedFolder`, `DiscoveryService.walk` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/discovery/discovery.service.ts:122` |
172
+ | `WordsService.splitIdentifier` | 3 | `WordsService.filter(…)`, `WordsService.map(…)`, `WordsService.flatMap(…)` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/words/words.service.ts:43` |
173
+ | `VocabularyService.collectFile` | 3 | `WordsService.splitPath`, `LanguagesService.tokenizerFor`, `VocabularyService.flatMap(…)` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/vocabulary/vocabulary.service.ts:42` |
174
+ | `DiscoveryService.isExcludedFolder` | 2 | `DiscoveryService.toPosix`, `DiscoveryService.some(…)` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/discovery/discovery.service.ts:56` |
175
+ | `DiscoveryService.isSelected` | 2 | `DiscoveryService.some(…)`, `DiscoveryService.some(…)` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/discovery/discovery.service.ts:67` |
176
+ | `IgnoreRulesService.isIgnored` | 1 | `IgnoreRulesService.toScopedPath` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/discovery/ignore-rules.service.ts:49` |
177
+ | `DiscoveryService.flatMap(…)` | 1 | `IgnoreRulesService.readScope` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/discovery/discovery.service.ts:86` |
178
+ | `DiscoveryService.map(…)` | 1 | `DiscoveryService.toPosix` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/discovery/discovery.service.ts:163` |
179
+ | `DiscoveryService.filter(…)` | 1 | `DiscoveryService.isSelected` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/discovery/discovery.service.ts:166` |
180
+ | `FoldingService.headword` | 1 | `FoldingService.fold` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/folding/folding.service.ts:49` |
181
+ | `WordsService.filter(…)` | 1 | `WordsService.isTerm` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/words/words.service.ts:48` |
182
+ | `WordsService.splitPath` | 1 | `WordsService.splitIdentifier` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/words/words.service.ts:56` |
183
+ | `VocabularyService.flatMap(…)` | 1 | `WordsService.splitIdentifier` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/vocabulary/vocabulary.service.ts:57` |
184
+ | `VocabularyService.excludedHeadwords` | 1 | `FoldingService.headword` | `projects/ic-suite/coinagerie/coinagerie-vocabulary/src/modules/vocabulary/vocabulary.service.ts:70` |
185
+
186
+ </details>
187
+ <!-- callidescope:end -->
188
+
189
+ ## 🕸️ Codependix
190
+
191
+ Dependency graphs exported by [codependix](https://github.com/Organizzolini/codebase/tree/main/projects/ic-suite/codependix/codependix-cli), regenerated by `nx run configuration:codependix:write`.
192
+
193
+ ### Nx Neighborhood
194
+
195
+ <!-- codependix:start name="codependix-nx-projects" -->
196
+ ```mermaid
197
+ graph LR
198
+ coinagerie_cli["coinagerie-cli"]
199
+ coinagerie_configuration["coinagerie-configuration"]
200
+ coinagerie_languages["coinagerie-languages"]
201
+ coinagerie_vocabulary["coinagerie-vocabulary"]
202
+ coinagerie_cli --> coinagerie_vocabulary
203
+ coinagerie_vocabulary --> coinagerie_configuration
204
+ coinagerie_vocabulary --> coinagerie_languages
205
+ classDef subject fill:#7c3aed,color:#fff,stroke:#4c1d95,stroke-width:2px
206
+ class coinagerie_vocabulary subject
207
+ ```
208
+ <!-- codependix:end name="codependix-nx-projects" -->
209
+
210
+ ### NestJS Module Graph
211
+
212
+ <!-- codependix:start name="codependix-nestjs-modules" -->
213
+ ```mermaid
214
+ flowchart LR
215
+ CssModule
216
+ DiscoveryModule
217
+ FoldingModule
218
+ HclModule
219
+ JsonModule
220
+ LanguagesModule
221
+ PythonModule
222
+ ScannerModule
223
+ ShellModule
224
+ SqlModule
225
+ TomlModule
226
+ TypescriptModule
227
+ VocabularyModule
228
+ WordsModule
229
+ YamlModule
230
+ CssModule --> ScannerModule
231
+ HclModule --> ScannerModule
232
+ JsonModule --> ScannerModule
233
+ LanguagesModule --> CssModule
234
+ LanguagesModule --> HclModule
235
+ LanguagesModule --> JsonModule
236
+ LanguagesModule --> PythonModule
237
+ LanguagesModule --> ShellModule
238
+ LanguagesModule --> SqlModule
239
+ LanguagesModule --> TomlModule
240
+ LanguagesModule --> TypescriptModule
241
+ LanguagesModule --> YamlModule
242
+ PythonModule --> ScannerModule
243
+ ShellModule --> ScannerModule
244
+ SqlModule --> ScannerModule
245
+ TomlModule --> ScannerModule
246
+ VocabularyModule --> DiscoveryModule
247
+ VocabularyModule --> FoldingModule
248
+ VocabularyModule --> LanguagesModule
249
+ VocabularyModule --> WordsModule
250
+ ```
251
+ <!-- codependix:end name="codependix-nestjs-modules" -->
252
+
253
+ ### File Imports
254
+
255
+ <!-- codependix:start name="codependix-file-imports" -->
256
+ ```mermaid
257
+ graph LR
258
+ file_callidescope_config_ts["callidescope.config.ts"]
259
+ file_codependix_config_ts["codependix.config.ts"]
260
+ file_codometer_config_ts["codometer.config.ts"]
261
+ file_coinagerie_config_ts["coinagerie.config.ts"]
262
+ file_eslint_config_ts["eslint.config.ts"]
263
+ file_src_index_ts["src/index.ts"]
264
+ file_src_index_unit_test_ts["src/index.unit.test.ts"]
265
+ file_src_modules_discovery_discovery_constants_ts["src/modules/discovery/discovery.constants.ts"]
266
+ file_src_modules_discovery_discovery_module_ts["src/modules/discovery/discovery.module.ts"]
267
+ file_src_modules_discovery_discovery_service_ts["src/modules/discovery/discovery.service.ts"]
268
+ file_src_modules_discovery_discovery_service_unit_test_ts["src/modules/discovery/discovery.service.unit.test.ts"]
269
+ file_src_modules_discovery_discovery_types_ts["src/modules/discovery/discovery.types.ts"]
270
+ file_src_modules_discovery_ignore_rules_service_ts["src/modules/discovery/ignore-rules.service.ts"]
271
+ file_src_modules_discovery_ignore_rules_service_unit_test_ts["src/modules/discovery/ignore-rules.service.unit.test.ts"]
272
+ file_src_modules_folding_folding_constants_ts["src/modules/folding/folding.constants.ts"]
273
+ file_src_modules_folding_folding_module_ts["src/modules/folding/folding.module.ts"]
274
+ file_src_modules_folding_folding_service_ts["src/modules/folding/folding.service.ts"]
275
+ file_src_modules_folding_folding_service_unit_test_ts["src/modules/folding/folding.service.unit.test.ts"]
276
+ file_src_modules_folding_folding_types_ts["src/modules/folding/folding.types.ts"]
277
+ file_src_modules_vocabulary_vocabulary_constants_ts["src/modules/vocabulary/vocabulary.constants.ts"]
278
+ file_src_modules_vocabulary_vocabulary_module_ts["src/modules/vocabulary/vocabulary.module.ts"]
279
+ file_src_modules_vocabulary_vocabulary_service_ts["src/modules/vocabulary/vocabulary.service.ts"]
280
+ file_src_modules_vocabulary_vocabulary_service_unit_test_ts["src/modules/vocabulary/vocabulary.service.unit.test.ts"]
281
+ file_src_modules_vocabulary_vocabulary_types_ts["src/modules/vocabulary/vocabulary.types.ts"]
282
+ file_src_modules_words_words_constants_ts["src/modules/words/words.constants.ts"]
283
+ file_src_modules_words_words_module_ts["src/modules/words/words.module.ts"]
284
+ file_src_modules_words_words_service_ts["src/modules/words/words.service.ts"]
285
+ file_src_modules_words_words_service_unit_test_ts["src/modules/words/words.service.unit.test.ts"]
286
+ file_src_modules_words_words_types_ts["src/modules/words/words.types.ts"]
287
+ file_testing_mocks_ts["testing/mocks.ts"]
288
+ file_testing_setup_ts["testing/setup.ts"]
289
+ file_vite_config_ts["vite.config.ts"]
290
+ file_vitest_config_ts["vitest.config.ts"]
291
+ file_src_index_unit_test_ts --> file_src_index_ts
292
+ file_src_modules_discovery_discovery_module_ts --> file_src_modules_discovery_discovery_service_ts
293
+ file_src_modules_discovery_discovery_module_ts --> file_src_modules_discovery_ignore_rules_service_ts
294
+ file_src_modules_discovery_discovery_service_ts --> file_src_modules_discovery_discovery_constants_ts
295
+ file_src_modules_discovery_discovery_service_ts --> file_src_modules_discovery_discovery_types_ts
296
+ file_src_modules_discovery_discovery_service_ts --> file_src_modules_discovery_ignore_rules_service_ts
297
+ file_src_modules_discovery_discovery_service_unit_test_ts --> file_src_modules_discovery_discovery_service_ts
298
+ file_src_modules_discovery_discovery_service_unit_test_ts --> file_src_modules_discovery_ignore_rules_service_ts
299
+ file_src_modules_discovery_ignore_rules_service_ts --> file_src_modules_discovery_discovery_types_ts
300
+ file_src_modules_discovery_ignore_rules_service_unit_test_ts --> file_src_modules_discovery_discovery_types_ts
301
+ file_src_modules_discovery_ignore_rules_service_unit_test_ts --> file_src_modules_discovery_ignore_rules_service_ts
302
+ file_src_modules_folding_folding_module_ts --> file_src_modules_folding_folding_service_ts
303
+ file_src_modules_folding_folding_service_ts --> file_src_modules_words_words_constants_ts
304
+ file_src_modules_folding_folding_service_unit_test_ts --> file_src_modules_folding_folding_service_ts
305
+ file_src_modules_vocabulary_vocabulary_module_ts --> file_src_modules_discovery_discovery_module_ts
306
+ file_src_modules_vocabulary_vocabulary_module_ts --> file_src_modules_folding_folding_module_ts
307
+ file_src_modules_vocabulary_vocabulary_module_ts --> file_src_modules_vocabulary_vocabulary_service_ts
308
+ file_src_modules_vocabulary_vocabulary_module_ts --> file_src_modules_words_words_module_ts
309
+ file_src_modules_vocabulary_vocabulary_service_ts --> file_src_modules_discovery_discovery_service_ts
310
+ file_src_modules_vocabulary_vocabulary_service_ts --> file_src_modules_folding_folding_service_ts
311
+ file_src_modules_vocabulary_vocabulary_service_ts --> file_src_modules_words_words_service_ts
312
+ file_src_modules_vocabulary_vocabulary_service_unit_test_ts --> file_src_modules_discovery_discovery_module_ts
313
+ file_src_modules_vocabulary_vocabulary_service_unit_test_ts --> file_src_modules_folding_folding_module_ts
314
+ file_src_modules_vocabulary_vocabulary_service_unit_test_ts --> file_src_modules_vocabulary_vocabulary_service_ts
315
+ file_src_modules_vocabulary_vocabulary_service_unit_test_ts --> file_src_modules_words_words_module_ts
316
+ file_src_modules_words_words_module_ts --> file_src_modules_words_words_service_ts
317
+ file_src_modules_words_words_service_ts --> file_src_modules_words_words_constants_ts
318
+ file_src_modules_words_words_service_unit_test_ts --> file_src_modules_words_words_service_ts
319
+ ```
320
+ <!-- codependix:end name="codependix-file-imports" -->
321
+
322
+ <!-- codometer:start -->
323
+
324
+ ## ⏲️ Codometer
325
+
326
+ ### Project
327
+
328
+ ![Lines of Code](https://img.shields.io/badge/Lines_of_Code-1576-22c55e?style=flat-square)
329
+ ![Repository Size](https://img.shields.io/badge/Repository_Size-58.91_kB-6b7280?style=flat-square)
330
+ ![Folders](https://img.shields.io/badge/Folders-7-4a4a4a?style=flat-square)
331
+ ![Source Files](https://img.shields.io/badge/Source_Files-33-3178c6?style=flat-square)
332
+
333
+ ### TypeScript
334
+
335
+ ![TypeScript Files](https://img.shields.io/badge/TypeScript_Files-33-3178c6?style=flat-square)
336
+ ![Interfaces](https://img.shields.io/badge/Interfaces-4-0ea5e9?style=flat-square)
337
+ ![Generic Declarations](https://img.shields.io/badge/Generic_Declarations-0-0369a1?style=flat-square)
338
+ ![Enums](https://img.shields.io/badge/Enums-0-f97316?style=flat-square)
339
+ ![Decorators](https://img.shields.io/badge/Decorators-9-db2777?style=flat-square)
340
+ ![Doc Comments](https://img.shields.io/badge/Doc_Comments-45-6366f1?style=flat-square)
341
+ ![Static Methods](https://img.shields.io/badge/Static_Methods-0-166534?style=flat-square)
342
+
343
+ ### JavaScript
344
+
345
+ ![JavaScript Files](https://img.shields.io/badge/JavaScript_Files-0-f7df1e?style=flat-square)
346
+ ![Test Files](https://img.shields.io/badge/Test_Files-6-10b981?style=flat-square)
347
+ ![External Packages](https://img.shields.io/badge/External_Packages-13-8b5cf6?style=flat-square)
348
+ ![Classes](https://img.shields.io/badge/Classes-9-7c3aed?style=flat-square)
349
+ ![Functions](https://img.shields.io/badge/Functions-78-16a34a?style=flat-square)
350
+ ![Methods](https://img.shields.io/badge/Methods-34-15803d?style=flat-square)
351
+ ![Sync Functions](https://img.shields.io/badge/Sync_Functions-94-4ade80?style=flat-square)
352
+ ![Async Functions](https://img.shields.io/badge/Async_Functions-18-059669?style=flat-square)
353
+ ![Constants](https://img.shields.io/badge/Constants-53-dc2626?style=flat-square)
354
+ ![Imports](https://img.shields.io/badge/Imports-89-0284c7?style=flat-square)
355
+ ![Exported Symbols](https://img.shields.io/badge/Exported_Symbols-21-ea580c?style=flat-square)
356
+ ![Comments](https://img.shields.io/badge/Comments-93-64748b?style=flat-square)
357
+ ![Comment Lines](https://img.shields.io/badge/Comment_Lines-205-475569?style=flat-square)
358
+ ![TODO Comments](https://img.shields.io/badge/TODO_Comments-0-ca8a04?style=flat-square)
359
+
360
+ ### Python
361
+
362
+ ![Python Files](https://img.shields.io/badge/Python_Files-0-3776ab?style=flat-square)
363
+ ![Python Lines](https://img.shields.io/badge/Python_Lines-0-4b8bbe?style=flat-square)
364
+ ![Python Classes](https://img.shields.io/badge/Python_Classes-0-7c3aed?style=flat-square)
365
+ ![Python Functions](https://img.shields.io/badge/Python_Functions-0-16a34a?style=flat-square)
366
+ ![Python Protocols](https://img.shields.io/badge/Python_Protocols-0-0ea5e9?style=flat-square)
367
+ ![Python Constants](https://img.shields.io/badge/Python_Constants-0-dc2626?style=flat-square)
368
+ ![Python Imports](https://img.shields.io/badge/Python_Imports-0-0284c7?style=flat-square)
369
+ ![Python Decorators](https://img.shields.io/badge/Python_Decorators-0-db2777?style=flat-square)
370
+ ![Docstrings](https://img.shields.io/badge/Docstrings-0-6366f1?style=flat-square)
371
+ ![Docstring Lines](https://img.shields.io/badge/Docstring_Lines-0-818cf8?style=flat-square)
372
+ ![Python Comments](https://img.shields.io/badge/Python_Comments-0-64748b?style=flat-square)
373
+ ![Python Comment Lines](https://img.shields.io/badge/Python_Comment_Lines-0-475569?style=flat-square)
374
+
375
+ ### JSON
376
+
377
+ ![JSON Files](https://img.shields.io/badge/JSON_Files-4-a16207?style=flat-square)
378
+ ![JSON Lines](https://img.shields.io/badge/JSON_Lines-159-ca8a04?style=flat-square)
379
+ ![JSON Objects](https://img.shields.io/badge/JSON_Objects-37-7c3aed?style=flat-square)
380
+ ![JSON Arrays](https://img.shields.io/badge/JSON_Arrays-12-8b5cf6?style=flat-square)
381
+ ![JSON Properties](https://img.shields.io/badge/JSON_Properties-98-0284c7?style=flat-square)
382
+ ![JSON Strings](https://img.shields.io/badge/JSON_Strings-88-16a34a?style=flat-square)
383
+ ![JSON Numbers](https://img.shields.io/badge/JSON_Numbers-1-059669?style=flat-square)
384
+ ![JSON Booleans](https://img.shields.io/badge/JSON_Booleans-6-0ea5e9?style=flat-square)
385
+ ![JSON Nulls](https://img.shields.io/badge/JSON_Nulls-0-64748b?style=flat-square)
386
+ ![JSON Items](https://img.shields.io/badge/JSON_Items-42-475569?style=flat-square)
387
+ ![JSON Nodes](https://img.shields.io/badge/JSON_Nodes-144-dc2626?style=flat-square)
388
+ ![JSON Max Depth](https://img.shields.io/badge/JSON_Max_Depth-5-ea580c?style=flat-square)
389
+
390
+ ### YAML
391
+
392
+ ![YAML Files](https://img.shields.io/badge/YAML_Files-0-cb171e?style=flat-square)
393
+ ![YAML Lines](https://img.shields.io/badge/YAML_Lines-0-e34c26?style=flat-square)
394
+ ![YAML Documents](https://img.shields.io/badge/YAML_Documents-0-f97316?style=flat-square)
395
+ ![YAML Mappings](https://img.shields.io/badge/YAML_Mappings-0-7c3aed?style=flat-square)
396
+ ![YAML Sequences](https://img.shields.io/badge/YAML_Sequences-0-8b5cf6?style=flat-square)
397
+ ![YAML Keys](https://img.shields.io/badge/YAML_Keys-0-0284c7?style=flat-square)
398
+ ![YAML Scalars](https://img.shields.io/badge/YAML_Scalars-0-16a34a?style=flat-square)
399
+ ![YAML Anchors](https://img.shields.io/badge/YAML_Anchors-0-059669?style=flat-square)
400
+ ![YAML Aliases](https://img.shields.io/badge/YAML_Aliases-0-10b981?style=flat-square)
401
+ ![YAML Comments](https://img.shields.io/badge/YAML_Comments-0-64748b?style=flat-square)
402
+ ![YAML Max Depth](https://img.shields.io/badge/YAML_Max_Depth-0-ea580c?style=flat-square)
403
+
404
+ ### TOML
405
+
406
+ ![TOML Files](https://img.shields.io/badge/TOML_Files-0-9c4221?style=flat-square)
407
+ ![TOML Lines](https://img.shields.io/badge/TOML_Lines-0-b45309?style=flat-square)
408
+ ![TOML Tables](https://img.shields.io/badge/TOML_Tables-0-7c3aed?style=flat-square)
409
+ ![TOML Array Tables](https://img.shields.io/badge/TOML_Array_Tables-0-8b5cf6?style=flat-square)
410
+ ![TOML Keys](https://img.shields.io/badge/TOML_Keys-0-0284c7?style=flat-square)
411
+ ![TOML Arrays](https://img.shields.io/badge/TOML_Arrays-0-16a34a?style=flat-square)
412
+ ![TOML Comments](https://img.shields.io/badge/TOML_Comments-0-64748b?style=flat-square)
413
+
414
+ ### Shell
415
+
416
+ ![Shell Files](https://img.shields.io/badge/Shell_Files-0-89e051?style=flat-square)
417
+ ![Shell Lines](https://img.shields.io/badge/Shell_Lines-0-4eaa25?style=flat-square)
418
+ ![Shell Functions](https://img.shields.io/badge/Shell_Functions-0-16a34a?style=flat-square)
419
+ ![Shell Variables](https://img.shields.io/badge/Shell_Variables-0-0284c7?style=flat-square)
420
+ ![Shell Exports](https://img.shields.io/badge/Shell_Exports-0-ea580c?style=flat-square)
421
+ ![Shell Conditionals](https://img.shields.io/badge/Shell_Conditionals-0-7c3aed?style=flat-square)
422
+ ![Shell Loops](https://img.shields.io/badge/Shell_Loops-0-8b5cf6?style=flat-square)
423
+ ![Shell Pipelines](https://img.shields.io/badge/Shell_Pipelines-0-059669?style=flat-square)
424
+ ![Shebangs](https://img.shields.io/badge/Shebangs-0-6b7280?style=flat-square)
425
+ ![Shell Comments](https://img.shields.io/badge/Shell_Comments-0-64748b?style=flat-square)
426
+ ![Shell Comment Lines](https://img.shields.io/badge/Shell_Comment_Lines-0-475569?style=flat-square)
427
+
428
+ ### SQL
429
+
430
+ ![SQL Files](https://img.shields.io/badge/SQL_Files-0-e38c00?style=flat-square)
431
+ ![SQL Lines](https://img.shields.io/badge/SQL_Lines-0-f29111?style=flat-square)
432
+ ![SQL Statements](https://img.shields.io/badge/SQL_Statements-0-7c3aed?style=flat-square)
433
+ ![SQL Selects](https://img.shields.io/badge/SQL_Selects-0-16a34a?style=flat-square)
434
+ ![SQL Inserts](https://img.shields.io/badge/SQL_Inserts-0-22c55e?style=flat-square)
435
+ ![SQL Updates](https://img.shields.io/badge/SQL_Updates-0-0ea5e9?style=flat-square)
436
+ ![SQL Deletes](https://img.shields.io/badge/SQL_Deletes-0-dc2626?style=flat-square)
437
+ ![SQL Creates](https://img.shields.io/badge/SQL_Creates-0-0284c7?style=flat-square)
438
+ ![SQL Joins](https://img.shields.io/badge/SQL_Joins-0-8b5cf6?style=flat-square)
439
+ ![SQL CTEs](https://img.shields.io/badge/SQL_CTEs-0-059669?style=flat-square)
440
+ ![SQL Comments](https://img.shields.io/badge/SQL_Comments-0-64748b?style=flat-square)
441
+
442
+ ### HCL
443
+
444
+ ![HCL Files](https://img.shields.io/badge/HCL_Files-0-844fba?style=flat-square)
445
+ ![HCL Lines](https://img.shields.io/badge/HCL_Lines-0-a78bfa?style=flat-square)
446
+ ![HCL Blocks](https://img.shields.io/badge/HCL_Blocks-0-7c3aed?style=flat-square)
447
+ ![HCL Resources](https://img.shields.io/badge/HCL_Resources-0-0284c7?style=flat-square)
448
+ ![HCL Variables](https://img.shields.io/badge/HCL_Variables-0-16a34a?style=flat-square)
449
+ ![HCL Outputs](https://img.shields.io/badge/HCL_Outputs-0-059669?style=flat-square)
450
+ ![HCL Attributes](https://img.shields.io/badge/HCL_Attributes-0-0ea5e9?style=flat-square)
451
+ ![HCL Interpolations](https://img.shields.io/badge/HCL_Interpolations-0-db2777?style=flat-square)
452
+ ![HCL Comments](https://img.shields.io/badge/HCL_Comments-0-64748b?style=flat-square)
453
+
454
+ ### CSS
455
+
456
+ ![CSS Files](https://img.shields.io/badge/CSS_Files-0-264de4?style=flat-square)
457
+ ![CSS Lines](https://img.shields.io/badge/CSS_Lines-0-2965f1?style=flat-square)
458
+ ![CSS Rules](https://img.shields.io/badge/CSS_Rules-0-7c3aed?style=flat-square)
459
+ ![CSS Selectors](https://img.shields.io/badge/CSS_Selectors-0-8b5cf6?style=flat-square)
460
+ ![CSS Declarations](https://img.shields.io/badge/CSS_Declarations-0-0284c7?style=flat-square)
461
+ ![CSS At Rules](https://img.shields.io/badge/CSS_At_Rules-0-f97316?style=flat-square)
462
+ ![CSS Media Queries](https://img.shields.io/badge/CSS_Media_Queries-0-ea580c?style=flat-square)
463
+ ![CSS Custom Properties](https://img.shields.io/badge/CSS_Custom_Properties-0-16a34a?style=flat-square)
464
+ ![CSS Comments](https://img.shields.io/badge/CSS_Comments-0-64748b?style=flat-square)
465
+
466
+ ### Conventions
467
+
468
+ ![Module Files](https://img.shields.io/badge/Module_Files-4-7c3aed?style=flat-square)
469
+ ![Service Files](https://img.shields.io/badge/Service_Files-5-0284c7?style=flat-square)
470
+ ![Command Files](https://img.shields.io/badge/Command_Files-0-16a34a?style=flat-square)
471
+ ![Constants Files](https://img.shields.io/badge/Constants_Files-4-ea580c?style=flat-square)
472
+ ![Types Files](https://img.shields.io/badge/Types_Files-4-db2777?style=flat-square)
473
+ ![Utilities Files](https://img.shields.io/badge/Utilities_Files-0-0ea5e9?style=flat-square)
474
+ ![TypeORM Entities](https://img.shields.io/badge/TypeORM_Entities-0-059669?style=flat-square)
475
+ ![Unit Tests](https://img.shields.io/badge/Unit_Tests-6-ca8a04?style=flat-square)
476
+ ![Integration Tests](https://img.shields.io/badge/Integration_Tests-0-7c3aed?style=flat-square)
477
+ ![End To End Tests](https://img.shields.io/badge/End_To_End_Tests-0-0284c7?style=flat-square)
478
+ ![CSS Comment Budget](https://img.shields.io/badge/CSS_Comment_Budget-0-16a34a?style=flat-square)
479
+ ![HCL Comment Budget](https://img.shields.io/badge/HCL_Comment_Budget-0-ea580c?style=flat-square)
480
+ ![Python Comment Budget](https://img.shields.io/badge/Python_Comment_Budget-0-db2777?style=flat-square)
481
+ ![SQL Comment Budget](https://img.shields.io/badge/SQL_Comment_Budget-0-0ea5e9?style=flat-square)
482
+ ![TOML Comment Budget](https://img.shields.io/badge/TOML_Comment_Budget-0-059669?style=flat-square)
483
+ ![TypeScript Comment Budget](https://img.shields.io/badge/TypeScript_Comment_Budget-0-ca8a04?style=flat-square)
484
+ ![YAML Comment Budget](https://img.shields.io/badge/YAML_Comment_Budget-0-7c3aed?style=flat-square)
485
+ ![Shell Comment Budget](https://img.shields.io/badge/Shell_Comment_Budget-0-0284c7?style=flat-square)
486
+
487
+ ### Jupyter
488
+
489
+ ![Notebooks](https://img.shields.io/badge/Notebooks-0-f37626?style=flat-square)
490
+ ![Notebook Cells](https://img.shields.io/badge/Notebook_Cells-0-e8a33d?style=flat-square)
491
+ ![Code Cells](https://img.shields.io/badge/Code_Cells-0-3776ab?style=flat-square)
492
+ ![Markdown Cells](https://img.shields.io/badge/Markdown_Cells-0-083fa1?style=flat-square)
493
+ ![Raw Cells](https://img.shields.io/badge/Raw_Cells-0-9ca3af?style=flat-square)
494
+ ![Executed Cells](https://img.shields.io/badge/Executed_Cells-0-16a34a?style=flat-square)
495
+ ![Cell Outputs](https://img.shields.io/badge/Cell_Outputs-0-059669?style=flat-square)
496
+ ![Notebook Code Lines](https://img.shields.io/badge/Notebook_Code_Lines-0-4b8bbe?style=flat-square)
497
+ ![Notebook Classes](https://img.shields.io/badge/Notebook_Classes-0-7c3aed?style=flat-square)
498
+ ![Notebook Functions](https://img.shields.io/badge/Notebook_Functions-0-22c55e?style=flat-square)
499
+ ![Notebook Imports](https://img.shields.io/badge/Notebook_Imports-0-0284c7?style=flat-square)
500
+ ![Notebook Decorators](https://img.shields.io/badge/Notebook_Decorators-0-db2777?style=flat-square)
501
+ ![Notebook Prose Lines](https://img.shields.io/badge/Notebook_Prose_Lines-0-1f6feb?style=flat-square)
502
+ ![Notebook Headings](https://img.shields.io/badge/Notebook_Headings-0-a78bfa?style=flat-square)
503
+ ![Notebook Links](https://img.shields.io/badge/Notebook_Links-0-10b981?style=flat-square)
504
+ ![Notebook Images](https://img.shields.io/badge/Notebook_Images-0-34d399?style=flat-square)
505
+ ![Notebook Code Blocks](https://img.shields.io/badge/Notebook_Code_Blocks-0-dc2626?style=flat-square)
506
+ ![Notebook Properties](https://img.shields.io/badge/Notebook_Properties-0-ca8a04?style=flat-square)
507
+ ![Notebook Nodes](https://img.shields.io/badge/Notebook_Nodes-0-a16207?style=flat-square)
508
+ ![Notebook Max Depth](https://img.shields.io/badge/Notebook_Max_Depth-0-ea580c?style=flat-square)
509
+
510
+ ### Markdown
511
+
512
+ ![Markdown Files](https://img.shields.io/badge/Markdown_Files-2-083fa1?style=flat-square)
513
+ ![Markdown Lines](https://img.shields.io/badge/Markdown_Lines-235-1f6feb?style=flat-square)
514
+ ![H1](https://img.shields.io/badge/H1-1-7c3aed?style=flat-square)
515
+ ![H2](https://img.shields.io/badge/H2-8-8b5cf6?style=flat-square)
516
+ ![H3](https://img.shields.io/badge/H3-14-a78bfa?style=flat-square)
517
+ ![H4](https://img.shields.io/badge/H4-0-c4b5fd?style=flat-square)
518
+ ![H5](https://img.shields.io/badge/H5-0-ddd6fe?style=flat-square)
519
+ ![H6](https://img.shields.io/badge/H6-0-ede9fe?style=flat-square)
520
+ ![Paragraphs](https://img.shields.io/badge/Paragraphs-51-64748b?style=flat-square)
521
+ ![Lists](https://img.shields.io/badge/Lists-8-16a34a?style=flat-square)
522
+ ![List Items](https://img.shields.io/badge/List_Items-31-22c55e?style=flat-square)
523
+ ![Task List Items](https://img.shields.io/badge/Task_List_Items-0-4ade80?style=flat-square)
524
+ ![Tables](https://img.shields.io/badge/Tables-2-0284c7?style=flat-square)
525
+ ![Table Rows](https://img.shields.io/badge/Table_Rows-10-0ea5e9?style=flat-square)
526
+ ![Links](https://img.shields.io/badge/Links-17-059669?style=flat-square)
527
+ ![Images](https://img.shields.io/badge/Images-0-10b981?style=flat-square)
528
+ ![Code Blocks](https://img.shields.io/badge/Code_Blocks-11-dc2626?style=flat-square)
529
+ ![Inline Code](https://img.shields.io/badge/Inline_Code-72-ef4444?style=flat-square)
530
+ ![Block Quotes](https://img.shields.io/badge/Block_Quotes-0-ca8a04?style=flat-square)
531
+ ![Thematic Breaks](https://img.shields.io/badge/Thematic_Breaks-0-a16207?style=flat-square)
532
+ <!-- codometer:end -->
@@ -0,0 +1,215 @@
1
+ import { Ignore } from 'ignore';
2
+ import { LanguagesService } from '@coinagerie/languages';
3
+ import { ResolvedCoinagerieConfiguration } from '@coinagerie/configuration';
4
+
5
+ /** What `discover` is asked to list. */
6
+ export declare interface DiscoverArguments {
7
+ /** The absolute root the run scans. */
8
+ directory: string;
9
+ /** Globs, relative to the root, naming files to leave out. */
10
+ exclude: string[];
11
+ /** Globs, relative to the root, naming the files to keep. */
12
+ include: string[];
13
+ /** Absolute paths always left out: the files the run writes. */
14
+ skip: string[];
15
+ }
16
+
17
+ /**
18
+ * Provides file discovery. `IgnoreRulesService` is a provider rather than an
19
+ * export: it is how discovery reads `.gitignore`, and nothing else needs it.
20
+ */
21
+ export declare class DiscoveryModule {
22
+ }
23
+
24
+ /**
25
+ * Lists the files a run scans.
26
+ *
27
+ * Every `.gitignore` git would honor is honored — those inside the root, and
28
+ * those above it up to the repository root — and then the configuration's
29
+ * own `include` and `exclude.paths` globs decide among what is left.
30
+ */
31
+ export declare class DiscoveryService {
32
+ private readonly ignoreRulesService;
33
+ constructor(ignoreRulesService: IgnoreRulesService);
34
+ /**
35
+ * The nearest folder at or above the root holding a `.git` entry, or the
36
+ * root itself outside any repository. A worktree's `.git` is a file, which
37
+ * counts the same.
38
+ */
39
+ private findRepositoryRoot;
40
+ /**
41
+ * Whether an `exclude.paths` glob names a folder outright, which excludes
42
+ * everything in it — so `exclude: ["dist"]` reads the way a `.gitignore`
43
+ * line does, and the folder is never walked.
44
+ */
45
+ private isExcludedFolder;
46
+ /** Whether the configuration's globs keep a root-relative file. */
47
+ private isSelected;
48
+ /**
49
+ * The ignore files of every folder from the repository root down to, but
50
+ * not including, the scan root — whose own file the walk reads.
51
+ */
52
+ private readAncestorScopes;
53
+ /** A path with forward slashes, which is what every glob is written in. */
54
+ private toPosix;
55
+ /**
56
+ * Every file under one folder that no ignore file claims, as absolute
57
+ * paths. Symbolic links are skipped rather than followed, so nothing is
58
+ * read twice and a link to an ancestor cannot loop.
59
+ */
60
+ private walk;
61
+ /**
62
+ * Every file the run scans, relative to the root, sorted so the same tree
63
+ * yields the same list on every machine.
64
+ */
65
+ discover(args: DiscoverArguments): string[];
66
+ }
67
+
68
+ /** Provides the folding of word forms into headwords. */
69
+ export declare class FoldingModule {
70
+ }
71
+
72
+ /**
73
+ * Folds the surface forms of a word into one headword, so the glossary lists
74
+ * a term once however the code inflects it.
75
+ *
76
+ * Plurals fold into their singular and inflected verbs into their lemma:
77
+ * `aspects` into `aspect`, `configured` and `configuring` into `configure`.
78
+ * Derivational families stay apart, so `configuration` keeps its own entry —
79
+ * unless the configuration's own `fold` merges them.
80
+ */
81
+ export declare class FoldingService {
82
+ constructor();
83
+ /**
84
+ * The headword a lowercase word folds into: its singular, then its lemma.
85
+ *
86
+ * A fold that would leave a single letter (`ts` into `t`) is refused, since
87
+ * one-letter words are not terms.
88
+ */
89
+ fold(word: string): string;
90
+ /**
91
+ * The headword a word is listed under: folded into its singular and lemma,
92
+ * then through the configuration's own `fold` when it has one. A fault in
93
+ * that function surfaces as an `InvalidConfigurationError` naming the file.
94
+ */
95
+ headword(word: string, configuration: ResolvedCoinagerieConfiguration): string;
96
+ }
97
+
98
+ /**
99
+ * Reads `.gitignore` files and judges paths against them, without git.
100
+ *
101
+ * Reading the syntax here rather than asking git is what lets a run scan a
102
+ * folder that is not a repository at all.
103
+ */
104
+ declare class IgnoreRulesService {
105
+ constructor();
106
+ /** A path as a scope sees it, or `undefined` when it lies outside the scope. */
107
+ private toScopedPath;
108
+ /**
109
+ * Whether the scopes ignore a repository-relative path, the innermost
110
+ * deciding — which is how a nested `!pattern` re-includes a file its parent
111
+ * ignored. A folder is judged with a trailing slash.
112
+ */
113
+ isIgnored(scopes: IgnoreScope[], relativePath: string): boolean;
114
+ /**
115
+ * Reads one ignore file, or `undefined` when it does not exist.
116
+ *
117
+ * Case-sensitive on every platform, so the same file ignores the same paths
118
+ * on a developer's machine and in CI.
119
+ */
120
+ readScope(args: ReadIgnoreScopeArguments): IgnoreScope | undefined;
121
+ }
122
+
123
+ /**
124
+ * The rules of one `.gitignore`, and the folder they were written in.
125
+ *
126
+ * `base` is relative to the repository root, `""` for the root itself; the
127
+ * patterns only ever see paths relative to it.
128
+ */
129
+ declare interface IgnoreScope {
130
+ base: string;
131
+ matcher: Ignore;
132
+ }
133
+
134
+ /** Where to read one ignore file from, and the folder it governs. */
135
+ declare interface ReadIgnoreScopeArguments {
136
+ base: string;
137
+ filePath: string;
138
+ }
139
+
140
+ /**
141
+ * Provides the vocabulary pipeline, wired to discovery, the language
142
+ * tokenizers, word splitting, folding, and exclusion.
143
+ */
144
+ export declare class VocabularyModule {
145
+ }
146
+
147
+ /**
148
+ * The coinagerie pipeline: from a configuration to the sorted list of every
149
+ * word the code uses.
150
+ *
151
+ * Discovers the files, splits every path into words, tokenizes every file a
152
+ * language claims and splits its identifiers into words, folds each word into
153
+ * its headword, leaves out the headwords the configuration excludes, then
154
+ * de-duplicates and sorts. A fault in the configuration's `fold` aborts the
155
+ * run, naming the configuration file. A file no language claims still
156
+ * contributes its path.
157
+ */
158
+ export declare class VocabularyService {
159
+ private readonly discoveryService;
160
+ private readonly foldingService;
161
+ private readonly languagesService;
162
+ private readonly wordsService;
163
+ constructor(discoveryService: DiscoveryService, foldingService: FoldingService, languagesService: LanguagesService, wordsService: WordsService);
164
+ /** The words of one file: its path's, then its identifiers'. */
165
+ private collectFile;
166
+ /**
167
+ * The headwords the configuration leaves out.
168
+ *
169
+ * Its words are folded the way the code's are, so exclusion compares
170
+ * headwords: excluding `service` covers `services`, and excluding
171
+ * `implements` covers the `implement` it folds into.
172
+ */
173
+ private excludedHeadwords;
174
+ /**
175
+ * Every word the configured files use, sorted and de-duplicated.
176
+ *
177
+ * The files a configuration writes a glossary to are left out, so a run
178
+ * never reads its own output back as vocabulary.
179
+ */
180
+ collect(configuration: ResolvedCoinagerieConfiguration): Promise<string[]>;
181
+ }
182
+
183
+ /**
184
+ * Provides the splitting and normalizing of identifiers and paths into
185
+ * words.
186
+ */
187
+ export declare class WordsModule {
188
+ }
189
+
190
+ /**
191
+ * Splits names into the words a glossary lists.
192
+ *
193
+ * A word leaves here lowercase, at least two characters long, and not a bare
194
+ * number. It is not yet folded: `aspects` and `aspect` are still two words.
195
+ */
196
+ export declare class WordsService {
197
+ constructor();
198
+ /** Whether a lowercase word is a term rather than noise. */
199
+ private isTerm;
200
+ /**
201
+ * The words of one identifier, in the order written, repeats kept.
202
+ *
203
+ * Splits on every separator, then on case changes, keeping acronym runs
204
+ * together: `XMLHttpRequest` is `xml`, `http`, and `request`.
205
+ */
206
+ splitIdentifier(raw: string): string[];
207
+ /**
208
+ * The words of a relative file path: every folder name, and the file name
209
+ * with only its final extension removed, so `glossary.service.ts`
210
+ * contributes `glossary` and `service`.
211
+ */
212
+ splitPath(relativePath: string): string[];
213
+ }
214
+
215
+ export { }
@@ -0,0 +1,212 @@
1
+ import { Injectable as e, Module as t } from "@nestjs/common";
2
+ import { existsSync as n, readFileSync as r, readdirSync as i } from "node:fs";
3
+ import a from "node:path";
4
+ import o from "ignore";
5
+ import s from "pluralize";
6
+ import c from "wink-lemmatizer";
7
+ import { LanguagesModule as l, LanguagesService as u } from "@coinagerie/languages";
8
+ import { readFile as d } from "node:fs/promises";
9
+ // \0rolldown/runtime.js
10
+ var f = ".gitignore";
11
+ // \0@oxc-project+runtime@0.155.0/helpers/esm/decorateMetadata.js
12
+ function __decorateMetadata(e, t) {
13
+ if (typeof Reflect == "object" && typeof Reflect.metadata == "function") return Reflect.metadata(e, t);
14
+ }
15
+ // \0@oxc-project+runtime@0.155.0/helpers/esm/decorate.js
16
+ function __decorate(e, t, n, r) {
17
+ var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
18
+ if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
19
+ 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);
20
+ return i > 3 && a && Object.defineProperty(t, n, a), a;
21
+ }
22
+ // src/modules/discovery/ignore-rules.service.ts
23
+ var p = class IgnoreRulesService {
24
+ constructor() {}
25
+ toScopedPath(e, t) {
26
+ if (e.base === "") return t;
27
+ let n = `${e.base}/`;
28
+ return t.startsWith(n) ? t.slice(n.length) : void 0;
29
+ }
30
+ isIgnored(e, t) {
31
+ let n = !1;
32
+ for (let r of e) {
33
+ let e = this.toScopedPath(r, t);
34
+ if (e === void 0) continue;
35
+ let i = r.matcher.test(e);
36
+ (i.ignored || i.unignored) && (n = i.ignored);
37
+ }
38
+ return n;
39
+ }
40
+ readScope(e) {
41
+ if (n(e.filePath)) return {
42
+ base: e.base,
43
+ matcher: o({ ignorecase: !1 }).add(r(e.filePath, "utf8"))
44
+ };
45
+ }
46
+ };
47
+ p = __decorate([e(), __decorateMetadata("design:paramtypes", [])], p);
48
+ // src/modules/discovery/discovery.service.ts
49
+ var m = class DiscoveryService {
50
+ ignoreRulesService;
51
+ constructor(e) {
52
+ this.ignoreRulesService = e;
53
+ }
54
+ findRepositoryRoot(e) {
55
+ for (let t = e;; t = a.dirname(t)) {
56
+ if (n(a.join(t, ".git"))) return t;
57
+ if (a.dirname(t) === t) return e;
58
+ }
59
+ }
60
+ isExcludedFolder(e, t) {
61
+ let n = this.toPosix(a.relative(e.discover.directory, t));
62
+ return e.discover.exclude.some((e) => a.matchesGlob(n, e));
63
+ }
64
+ isSelected(e, t) {
65
+ return e.include.some((e) => a.matchesGlob(t, e)) && !e.exclude.some((e) => a.matchesGlob(t, e));
66
+ }
67
+ readAncestorScopes(e, t) {
68
+ let n = this.toPosix(a.relative(e, t)).split("/").filter((e) => e !== "");
69
+ return n.flatMap((t, r) => {
70
+ let i = n.slice(0, r).join("/"), o = this.ignoreRulesService.readScope({
71
+ base: i,
72
+ filePath: a.join(e, i, f)
73
+ });
74
+ return o === void 0 ? [] : [o];
75
+ });
76
+ }
77
+ toPosix(e) {
78
+ return e.split(a.sep).join("/");
79
+ }
80
+ walk(e) {
81
+ let t = this.toPosix(a.relative(e.repositoryRoot, e.absoluteDirectory)), n = this.ignoreRulesService.readScope({
82
+ base: t,
83
+ filePath: a.join(e.absoluteDirectory, f)
84
+ }), r = n === void 0 ? e.scopes : [...e.scopes, n];
85
+ return i(e.absoluteDirectory, { withFileTypes: !0 }).filter((e) => !e.isSymbolicLink() && e.name !== ".git").flatMap((n) => {
86
+ let i = a.join(e.absoluteDirectory, n.name), o = t === "" ? n.name : `${t}/${n.name}`, s = n.isDirectory();
87
+ return this.ignoreRulesService.isIgnored(r, s ? `${o}/` : o) ? [] : s ? this.isExcludedFolder(e, i) ? [] : this.walk({
88
+ ...e,
89
+ absoluteDirectory: i,
90
+ scopes: r
91
+ }) : [i];
92
+ });
93
+ }
94
+ discover(e) {
95
+ let t = this.findRepositoryRoot(e.directory), n = new Set(e.skip.map((e) => a.resolve(e)));
96
+ return this.walk({
97
+ absoluteDirectory: e.directory,
98
+ discover: e,
99
+ repositoryRoot: t,
100
+ scopes: this.readAncestorScopes(t, e.directory)
101
+ }).filter((e) => !n.has(e)).map((t) => this.toPosix(a.relative(e.directory, t))).filter((t) => this.isSelected(e, t)).toSorted();
102
+ }
103
+ };
104
+ m = __decorate([e(), __decorateMetadata("design:paramtypes", [p === void 0 ? Object : p])], m);
105
+ // src/modules/discovery/discovery.module.ts
106
+ var h = class DiscoveryModule {};
107
+ h = __decorate([t({
108
+ controllers: [],
109
+ exports: [m],
110
+ imports: [],
111
+ providers: [m, p]
112
+ })], h);
113
+ // src/modules/words/words.constants.ts
114
+ var g = /[^\p{L}\p{M}\p{N}]+/u, _ = /\p{Lu}+(?![\p{Ll}\p{Lo}\p{Lm}])\p{N}*|\p{Lu}?[\p{Ll}\p{Lo}\p{Lm}\p{M}]+\p{N}*|\p{N}+[\p{Ll}\p{Lo}\p{Lm}\p{M}]*/gu, v = /^\p{N}+$/u, y = /^.{2,}$/su, b = class FoldingService {
115
+ constructor() {}
116
+ fold(e) {
117
+ let t = c.verb(s.singular(e));
118
+ return y.test(t) ? t : e;
119
+ }
120
+ headword(e, t) {
121
+ let n = this.fold(e);
122
+ return t.fold === void 0 ? n : t.fold(n);
123
+ }
124
+ };
125
+ b = __decorate([e(), __decorateMetadata("design:paramtypes", [])], b);
126
+ // src/modules/folding/folding.module.ts
127
+ var x = class FoldingModule {};
128
+ x = __decorate([t({
129
+ controllers: [],
130
+ exports: [b],
131
+ imports: [],
132
+ providers: [b]
133
+ })], x);
134
+ // src/modules/words/words.service.ts
135
+ var S = class WordsService {
136
+ constructor() {}
137
+ isTerm(e) {
138
+ return y.test(e) && !v.test(e);
139
+ }
140
+ splitIdentifier(e) {
141
+ return e.split(g).flatMap((e) => e.match(_) ?? []).map((e) => e.toLowerCase()).filter((e) => this.isTerm(e));
142
+ }
143
+ splitPath(e) {
144
+ return this.splitIdentifier(e.slice(0, e.length - a.extname(e).length));
145
+ }
146
+ };
147
+ S = __decorate([e(), __decorateMetadata("design:paramtypes", [])], S);
148
+ // src/modules/words/words.module.ts
149
+ var C = class WordsModule {};
150
+ C = __decorate([t({
151
+ controllers: [],
152
+ exports: [S],
153
+ imports: [],
154
+ providers: [S]
155
+ })], C);
156
+ // src/modules/vocabulary/vocabulary.service.ts
157
+ var w = class VocabularyService {
158
+ discoveryService;
159
+ foldingService;
160
+ languagesService;
161
+ wordsService;
162
+ constructor(e, t, n, r) {
163
+ this.discoveryService = e, this.foldingService = t, this.languagesService = n, this.wordsService = r;
164
+ }
165
+ async collectFile(e, t) {
166
+ let n = this.wordsService.splitPath(t), r = this.languagesService.tokenizerFor(t);
167
+ if (r === void 0) return n;
168
+ let i = await d(a.join(e, t), "utf8");
169
+ return [...n, ...r(i, t).flatMap((e) => this.wordsService.splitIdentifier(e))];
170
+ }
171
+ excludedHeadwords(e) {
172
+ let t = /* @__PURE__ */ new Set();
173
+ for (let n of e.exclude.words) {
174
+ let r = n.toLowerCase();
175
+ t.add(r), t.add(this.foldingService.headword(r, e));
176
+ }
177
+ return t;
178
+ }
179
+ async collect(e) {
180
+ let t = this.discoveryService.discover({
181
+ directory: e.directory,
182
+ exclude: e.exclude.paths,
183
+ include: e.include,
184
+ skip: e.outputs.map((e) => e.path)
185
+ }), n = this.excludedHeadwords(e), r = /* @__PURE__ */ new Set(), i = /* @__PURE__ */ new Map();
186
+ for (let a of t) for (let t of await this.collectFile(e.directory, a)) {
187
+ let a = i.get(t) ?? this.foldingService.headword(t, e);
188
+ i.set(t, a), n.has(a) || r.add(a);
189
+ }
190
+ return [...r].toSorted();
191
+ }
192
+ };
193
+ w = __decorate([e(), __decorateMetadata("design:paramtypes", [
194
+ m === void 0 ? Object : m,
195
+ b === void 0 ? Object : b,
196
+ u === void 0 ? Object : u,
197
+ S === void 0 ? Object : S
198
+ ])], w);
199
+ // src/modules/vocabulary/vocabulary.module.ts
200
+ var T = class VocabularyModule {};
201
+ T = __decorate([t({
202
+ controllers: [],
203
+ exports: [w],
204
+ imports: [
205
+ h,
206
+ x,
207
+ l,
208
+ C
209
+ ],
210
+ providers: [w]
211
+ })], T);
212
+ export { h as DiscoveryModule, m as DiscoveryService, x as FoldingModule, b as FoldingService, T as VocabularyModule, w as VocabularyService, C as WordsModule, S as WordsService };
package/package.json CHANGED
@@ -1,6 +1,65 @@
1
1
  {
2
+ "author": "Jimmy Paolini",
3
+ "bugs": {
4
+ "url": "https://github.com/organizzolini/codebase/issues"
5
+ },
6
+ "dependencies": {
7
+ "@coinagerie/configuration": "0.0.1",
8
+ "@coinagerie/languages": "0.0.1",
9
+ "@nestjs/common": "^11.1.21 || ^12.0.1",
10
+ "ignore": "7.0.14",
11
+ "pluralize": "^8.0.0",
12
+ "reflect-metadata": "^0.2.2",
13
+ "wink-lemmatizer": "^3.0.4"
14
+ },
15
+ "description": "File discovery, word splitting, folding, and exclusion that turn a codebase into a sorted list of headwords",
16
+ "devDependencies": {
17
+ "@golevelup/ts-vitest": "^4.0.0",
18
+ "@nestjs/testing": "^12.0.1",
19
+ "@nx/eslint-plugin": "^24.0.0",
20
+ "@swc/helpers": "^0.5.21",
21
+ "@types/node": "^26.5.1",
22
+ "@types/pluralize": "^0.0.33",
23
+ "@vitest/coverage-v8": "^5.0.0",
24
+ "vitest": "^5.0.0"
25
+ },
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/src/index.d.ts",
29
+ "default": "./dist/src/index.js"
30
+ },
31
+ "./package.json": "./package.json"
32
+ },
33
+ "files": [
34
+ "CHANGELOG.md",
35
+ "dist",
36
+ "LICENSE",
37
+ "README.md"
38
+ ],
39
+ "homepage": "https://github.com/organizzolini/codebase/tree/main/projects/ic-suite/coinagerie/coinagerie-vocabulary#readme",
40
+ "keywords": [
41
+ "coinagerie",
42
+ "glossary",
43
+ "vocabulary",
44
+ "words"
45
+ ],
46
+ "license": "MIT",
47
+ "main": "./dist/src/index.js",
2
48
  "name": "@coinagerie/vocabulary",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
49
+ "publishConfig": {
50
+ "access": "public",
51
+ "registry": "https://registry.npmjs.org"
52
+ },
53
+ "repository": {
54
+ "directory": "projects/ic-suite/coinagerie/coinagerie-vocabulary",
55
+ "type": "git",
56
+ "url": "git+https://github.com/organizzolini/codebase.git"
57
+ },
58
+ "type": "module",
59
+ "typeCoverage": {
60
+ "atLeast": 100,
61
+ "strict": true
62
+ },
63
+ "types": "./dist/src/index.d.ts",
64
+ "version": "0.0.1"
6
65
  }