@conformetry/configuration 0.0.38 → 0.0.40

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 CHANGED
@@ -1,3 +1,33 @@
1
+ ## 0.0.40 (2026-10-18)
2
+
3
+ ### 🚀 Features
4
+
5
+ - ⚠️ **conformetry:** ✨ expose the filesystem and configuration directory to hooks ([#1695](https://github.com/organizzolini/codebase/pull/1695), [#1679](https://github.com/organizzolini/codebase/issues/1679))
6
+
7
+ ### ⚠️ Breaking Changes
8
+
9
+ - **conformetry:** ✨ expose the filesystem and configuration directory to hooks ([#1695](https://github.com/organizzolini/codebase/pull/1695), [#1679](https://github.com/organizzolini/codebase/issues/1679))
10
+ `GenerationService.runGenerator` in the published
11
+ `@conformetry/generation` now requires `configurationDirectoryPath`, so
12
+ an embedder calling it must pass the absolute directory of its
13
+ configuration file; the title carries `!` so the squash releases it as
14
+ such.
15
+ - This is stacked on #1693.
16
+
17
+ ### 🧱 Updated Dependencies
18
+
19
+ - Updated conformetry-core to 0.0.39
20
+
21
+ ## 0.0.39 (2026-10-18)
22
+
23
+ ### 🚀 Features
24
+
25
+ - **conformetry:** ✨ run configured generator hooks from the command line ([#1693](https://github.com/organizzolini/codebase/pull/1693), [#1675](https://github.com/organizzolini/codebase/issues/1675))
26
+
27
+ ### 🧱 Updated Dependencies
28
+
29
+ - Updated conformetry-core to 0.0.38
30
+
1
31
  ## 0.0.38 (2026-10-18)
2
32
 
3
33
  ### 🧱 Updated Dependencies
package/README.md CHANGED
@@ -61,6 +61,7 @@ export default conformetryConfiguration;
61
61
  | `inputs` | | The values it substitutes, as JSON Schema fragments |
62
62
  | `instances` | | Where this generator's output already lives |
63
63
  | `description` | | Shown when a host lists or prompts for generators |
64
+ | `hooks` | | `preGenerate` and `postGenerate` functions run around the render; see [`@conformetry/generation`](../conformetry-generation/README.md) |
64
65
 
65
66
  Both `inputs` and `instances` may be omitted. A generator with neither renders
66
67
  a fixed template nobody validates, which is legal.
@@ -81,6 +82,10 @@ problem in one pass:
81
82
  - **A key the schema does not declare.** The generator object is strict, so a
82
83
  misspelled field — or `aliases`, which was removed outright — is rejected
83
84
  rather than stripped and left reading as though it took effect.
85
+ - **A hook that is not a function, or an unknown key under `hooks`.** A
86
+ string or object where a function was meant is named by its hook, and
87
+ `hooks` is strict for the same reason the generator is: a misspelt hook name
88
+ would otherwise be stripped and the hook silently never run.
84
89
 
85
90
  ## Instances
86
91
 
@@ -248,6 +253,7 @@ asserting that these paths _are_ instances:
248
253
  | `ConfigurationPathRequiredError` | Thrown by `ConfigurationService.requireConfigurationPath` for an absent or blank path, naming the flag or option the caller passed as the surface |
249
254
  | `ConformetryConfiguration` | The loaded configuration type — author your config as this |
250
255
  | `ConformetryInstanceGroup`, `ConformetryGeneratorDefinition` | Field-level types for the above |
256
+ | `GeneratorHook`, `GeneratorHookContext`, `GeneratorHooks` | The hook types, re-exported from `@conformetry/core` so a config file can type its hooks from this package |
251
257
 
252
258
  **One service and one module, and no other collaborator** — the same pair
253
259
  `@callidescope/configuration`, `@codependix/configuration` and
@@ -292,10 +298,10 @@ Call stacks traced through `projects/ic-suite/conformetry/conformetry-configurat
292
298
 
293
299
  | Measure | Value |
294
300
  | --- | --- |
295
- | Callables | 183 |
301
+ | Callables | 186 |
296
302
  | Files | 38 |
297
- | Calls traced | 167 |
298
- | Call stacks | 5 |
303
+ | Calls traced | 169 |
304
+ | Call stacks | 6 |
299
305
  | Deepest stack | 10 |
300
306
  | Stacks through recursion | 0 |
301
307
  | Unfollowable calls | 7 |
@@ -369,7 +375,7 @@ What this project is judged against, as declared in its own `callidescope.config
369
375
  ```
370
376
 
371
377
  <details>
372
- <summary>2 more call stacks</summary>
378
+ <summary>3 more call stacks</summary>
373
379
 
374
380
  **4. `assertNoCollisions`** — depth ≥ 3 · orphan-root
375
381
 
@@ -392,6 +398,14 @@ What this project is judged against, as declared in its own `callidescope.config
392
398
  ↳ Derives the case variants every template can reference from one name.
393
399
  ```
394
400
 
401
+ **6. `generatorHookSchema`** — depth 2 · orphan-root
402
+
403
+ ```text
404
+ 🚀 generatorHookSchema(hookName: string): z.ZodType<GeneratorHook> [projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.constants.ts:71]
405
+ ↳ A hook as a config file declares it: a function, and nothing narrower.
406
+ └─> custom(…)(value: unknown): value is Function [projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.constants.ts:72]
407
+ ```
408
+
395
409
  </details>
396
410
 
397
411
  ### Breadth
@@ -403,7 +417,7 @@ What this project is judged against, as declared in its own `callidescope.config
403
417
  | `InputPromptingService.promptForInput` | 4 | `InputPromptingService.assertCanPrompt`, `InputSchemaService.readEnumValues`, `InputPromptingService.map(…)`, `InputSchemaService.readPromptMessage` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/input/input-prompting.service.ts:90` |
404
418
 
405
419
  <details>
406
- <summary>102 more callables</summary>
420
+ <summary>104 more callables</summary>
407
421
 
408
422
  | Callable | Breadth | Calls directly | Location |
409
423
  | --- | --- | --- | --- |
@@ -412,7 +426,7 @@ What this project is judged against, as declared in its own `callidescope.config
412
426
  | `InstanceDiscoveryService.resolveInventoriedInstances` | 4 | `InstanceDiscoveryService.takeInventory`, `InstanceDiscoveryService.map(…)`, `InstanceDiscoveryService.filter(…)`, `InstanceDiscoveryService.map(…)` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery.service.ts:219` |
413
427
  | `InstanceDiscoveryService.resolveInventoriedTemplates` | 4 | `InstanceDiscoveryService.takeInventory`, `InstanceDiscoveryService.filter(…)`, `InstanceDiscoveryService.map(…)`, `InstanceDiscoveryService.filter(…)` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery.service.ts:244` |
414
428
  | `InstanceDiscoveryService.takeInventory` | 4 | `TemplateDiscoveryService.collectTemplates`, `InstanceDiscoveryService.findInstances`, `InstanceDiscoveryService.readInventoryGlobs`, `InstanceDiscoveryService.map(…)` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery.service.ts:283` |
415
- | `ConfigurationService.loadConformetryConfiguration` | 4 | `ConfigurationService.resolveConfigurationPath`, `UnknownConfigurationFileTypeError.constructor`, `ConfigurationService.loadConfigurationModule`, `ConfigurationService.map(…)` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:244` |
429
+ | `ConfigurationService.loadConformetryConfiguration` | 4 | `ConfigurationService.resolveConfigurationPath`, `UnknownConfigurationFileTypeError.constructor`, `ConfigurationService.loadConfigurationModule`, `ConfigurationService.map(…)` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:237` |
416
430
  | `assertNoCollisions` | 3 | `findDuplicates`, `findUnusableNames`, `findReservedNames` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.utilities.ts:28` |
417
431
  | `findReservedNames` | 3 | `map(…)`, `filter(…)`, `map(…)` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.utilities.ts:97` |
418
432
  | `findUnusableNames` | 3 | `map(…)`, `filter(…)`, `map(…)` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.utilities.ts:112` |
@@ -435,6 +449,7 @@ What this project is judged against, as declared in its own `callidescope.config
435
449
  | `InstanceDiscoveryMatchingService.map(…)` | 2 | `InstanceDiscoveryMatchingService.fillPlaceholders`, `TemplateDiscoveryService.countMatchingFiles` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery-matching.service.ts:186` |
436
450
  | `missingInputError` | 1 | `InputError.constructor` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.constants.ts:55` |
437
451
  | `missingDirectoryError` | 1 | `InputError.constructor` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/input/input.constants.ts:70` |
452
+ | `generatorHookSchema` | 1 | `custom(…)` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.constants.ts:71` |
438
453
  | `InputOptionsService.resolvePropertyName` | 1 | `InputOptionsService.find(…)` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/input/input-options.service.ts:100` |
439
454
  | `InputOptionsService.collectGeneratorInputs` | 1 | `InputOptionsService.collectOneInput` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/input/input-options.service.ts:120` |
440
455
  | `InputSchemaService.readSchemaProperty` | 1 | `InputSchemaService.find(…)` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/input/input-schema.service.ts:26` |
@@ -485,30 +500,31 @@ What this project is judged against, as declared in its own `callidescope.config
485
500
  | `InstanceDiscoveryService.map(…)` | 1 | `InstanceDiscoveryService.flatMap(…)` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery.service.ts:256` |
486
501
  | `InstanceDiscoveryService.flatMap(…)` | 1 | `InstanceDiscoveryService.find(…)` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery.service.ts:257` |
487
502
  | `InstanceDiscoveryService.map(…)` | 1 | `InstanceDiscoveryService.weighInstance` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/instance-discovery/instance-discovery.service.ts:295` |
488
- | `ConfigurationService.loadConfigurationModule` | 1 | `ConfigurationService.loadJsonConfiguration` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:136` |
489
- | `ConfigurationService.resolveConfigurationPath` | 1 | `ConfigurationService.findWorkspaceRoot` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:175` |
490
- | `ConfigurationService.buildNameSubstitutions` | 1 | `RenderingService.buildNameSubstitutions` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:203` |
491
- | `ConfigurationService.collectTemplate` | 1 | `TemplateDiscoveryService.collectTemplate` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:208` |
492
- | `ConfigurationService.collectTemplates` | 1 | `TemplateDiscoveryService.collectTemplates` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:215` |
493
- | `ConfigurationService.findInstances` | 1 | `InstanceDiscoveryService.findInstances` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:223` |
494
- | `ConfigurationService.isAtTerminal` | 1 | `InputPromptingService.isAtTerminal` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:228` |
495
- | `ConfigurationService.isProjectScoped` | 1 | `InstanceGroupService.isProjectScoped` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:233` |
496
- | `ConfigurationService.map(…)` | 1 | `ConfigurationService.applyGeneratorDefaults` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:260` |
497
- | `ConfigurationService.matchInstances` | 1 | `InstanceDiscoveryService.matchInstances` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:264` |
498
- | `ConfigurationService.parseCommaDelimitedOption` | 1 | `InputService.parseCommaDelimitedOption` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:272` |
499
- | `ConfigurationService.parseOptionalOption` | 1 | `InputService.parseOptionalOption` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:279` |
500
- | `ConfigurationService.parseThresholdOption` | 1 | `InputService.parseThresholdOption` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:284` |
501
- | `ConfigurationService.prepareDocuments` | 1 | `InstanceDiscoveryService.prepareDocuments` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:292` |
502
- | `ConfigurationService.promptForTemplate` | 1 | `InputPromptingService.promptForTemplate` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:299` |
503
- | `ConfigurationService.promptForTemplates` | 1 | `InputPromptingService.promptForTemplates` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:306` |
504
- | `ConfigurationService.readWorkspaceGroups` | 1 | `InstanceDiscoveryService.readWorkspaceGroups` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:313` |
505
- | `ConfigurationService.renderContent` | 1 | `RenderingService.renderContent` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:320` |
506
- | `ConfigurationService.renderPath` | 1 | `RenderingService.renderPath` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:327` |
507
- | `ConfigurationService.requireConfigurationPath` | 1 | `ConfigurationPathRequiredError.constructor` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:342` |
508
- | `ConfigurationService.resolveGeneratorInputs` | 1 | `InputService.resolveGeneratorInputs` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:356` |
509
- | `ConfigurationService.resolveInstanceFiles` | 1 | `InstanceDiscoveryService.resolveInstanceFiles` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:363` |
510
- | `ConfigurationService.resolveInventoriedInstances` | 1 | `InstanceDiscoveryService.resolveInventoriedInstances` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:368` |
511
- | `ConfigurationService.resolveInventoriedTemplates` | 1 | `InstanceDiscoveryService.resolveInventoriedTemplates` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:375` |
503
+ | `ConfigurationService.applyGeneratorDefaults` | 1 | `ConfigurationService.applyHookDefaults` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:89` |
504
+ | `ConfigurationService.loadConfigurationModule` | 1 | `ConfigurationService.loadJsonConfiguration` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:157` |
505
+ | `ConfigurationService.buildNameSubstitutions` | 1 | `RenderingService.buildNameSubstitutions` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:196` |
506
+ | `ConfigurationService.collectTemplate` | 1 | `TemplateDiscoveryService.collectTemplate` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:201` |
507
+ | `ConfigurationService.collectTemplates` | 1 | `TemplateDiscoveryService.collectTemplates` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:208` |
508
+ | `ConfigurationService.findInstances` | 1 | `InstanceDiscoveryService.findInstances` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:216` |
509
+ | `ConfigurationService.isAtTerminal` | 1 | `InputPromptingService.isAtTerminal` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:221` |
510
+ | `ConfigurationService.isProjectScoped` | 1 | `InstanceGroupService.isProjectScoped` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:226` |
511
+ | `ConfigurationService.map(…)` | 1 | `ConfigurationService.applyGeneratorDefaults` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:253` |
512
+ | `ConfigurationService.matchInstances` | 1 | `InstanceDiscoveryService.matchInstances` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:257` |
513
+ | `ConfigurationService.parseCommaDelimitedOption` | 1 | `InputService.parseCommaDelimitedOption` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:265` |
514
+ | `ConfigurationService.parseOptionalOption` | 1 | `InputService.parseOptionalOption` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:272` |
515
+ | `ConfigurationService.parseThresholdOption` | 1 | `InputService.parseThresholdOption` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:277` |
516
+ | `ConfigurationService.prepareDocuments` | 1 | `InstanceDiscoveryService.prepareDocuments` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:285` |
517
+ | `ConfigurationService.promptForTemplate` | 1 | `InputPromptingService.promptForTemplate` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:292` |
518
+ | `ConfigurationService.promptForTemplates` | 1 | `InputPromptingService.promptForTemplates` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:299` |
519
+ | `ConfigurationService.readWorkspaceGroups` | 1 | `InstanceDiscoveryService.readWorkspaceGroups` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:306` |
520
+ | `ConfigurationService.renderContent` | 1 | `RenderingService.renderContent` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:313` |
521
+ | `ConfigurationService.renderPath` | 1 | `RenderingService.renderPath` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:320` |
522
+ | `ConfigurationService.requireConfigurationPath` | 1 | `ConfigurationPathRequiredError.constructor` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:335` |
523
+ | `ConfigurationService.resolveConfigurationPath` | 1 | `ConfigurationService.findWorkspaceRoot` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:356` |
524
+ | `ConfigurationService.resolveGeneratorInputs` | 1 | `InputService.resolveGeneratorInputs` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:382` |
525
+ | `ConfigurationService.resolveInstanceFiles` | 1 | `InstanceDiscoveryService.resolveInstanceFiles` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:389` |
526
+ | `ConfigurationService.resolveInventoriedInstances` | 1 | `InstanceDiscoveryService.resolveInventoriedInstances` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:394` |
527
+ | `ConfigurationService.resolveInventoriedTemplates` | 1 | `InstanceDiscoveryService.resolveInventoriedTemplates` | `projects/ic-suite/conformetry/conformetry-configuration/src/modules/configuration/configuration.service.ts:401` |
512
528
 
513
529
  </details>
514
530
  <!-- callidescope:end -->
@@ -749,14 +765,14 @@ graph LR
749
765
 
750
766
  ### Project
751
767
 
752
- ![Lines of Code](https://img.shields.io/badge/Lines_of_Code-6721-22c55e?style=flat-square)
753
- ![Repository Size](https://img.shields.io/badge/Repository_Size-233.04_kB-6b7280?style=flat-square)
768
+ ![Lines of Code](https://img.shields.io/badge/Lines_of_Code-6873-22c55e?style=flat-square)
769
+ ![Repository Size](https://img.shields.io/badge/Repository_Size-239.77_kB-6b7280?style=flat-square)
754
770
  ![Folders](https://img.shields.io/badge/Folders-9-4a4a4a?style=flat-square)
755
771
  ![Source Files](https://img.shields.io/badge/Source_Files-55-3178c6?style=flat-square)
756
772
 
757
773
  ### Measured Targets
758
774
 
759
- ![Compiled JavaScript Size](https://img.shields.io/badge/Compiled_JavaScript_Size-8.22_kB_gzip-6b7280?style=flat-square)
775
+ ![Compiled JavaScript Size](https://img.shields.io/badge/Compiled_JavaScript_Size-8.35_kB_gzip-6b7280?style=flat-square)
760
776
 
761
777
  ### TypeScript
762
778
 
@@ -765,7 +781,7 @@ graph LR
765
781
  ![Generic Declarations](https://img.shields.io/badge/Generic_Declarations-2-0369a1?style=flat-square)
766
782
  ![Enums](https://img.shields.io/badge/Enums-0-f97316?style=flat-square)
767
783
  ![Decorators](https://img.shields.io/badge/Decorators-17-db2777?style=flat-square)
768
- ![Doc Comments](https://img.shields.io/badge/Doc_Comments-187-6366f1?style=flat-square)
784
+ ![Doc Comments](https://img.shields.io/badge/Doc_Comments-189-6366f1?style=flat-square)
769
785
  ![Static Methods](https://img.shields.io/badge/Static_Methods-0-166534?style=flat-square)
770
786
 
771
787
  ### JavaScript
@@ -774,15 +790,15 @@ graph LR
774
790
  ![Test Files](https://img.shields.io/badge/Test_Files-15-10b981?style=flat-square)
775
791
  ![External Packages](https://img.shields.io/badge/External_Packages-17-8b5cf6?style=flat-square)
776
792
  ![Classes](https://img.shields.io/badge/Classes-21-7c3aed?style=flat-square)
777
- ![Functions](https://img.shields.io/badge/Functions-355-16a34a?style=flat-square)
778
- ![Methods](https://img.shields.io/badge/Methods-147-15803d?style=flat-square)
779
- ![Sync Functions](https://img.shields.io/badge/Sync_Functions-404-4ade80?style=flat-square)
780
- ![Async Functions](https://img.shields.io/badge/Async_Functions-98-059669?style=flat-square)
781
- ![Constants](https://img.shields.io/badge/Constants-328-dc2626?style=flat-square)
782
- ![Imports](https://img.shields.io/badge/Imports-216-0284c7?style=flat-square)
793
+ ![Functions](https://img.shields.io/badge/Functions-368-16a34a?style=flat-square)
794
+ ![Methods](https://img.shields.io/badge/Methods-148-15803d?style=flat-square)
795
+ ![Sync Functions](https://img.shields.io/badge/Sync_Functions-409-4ade80?style=flat-square)
796
+ ![Async Functions](https://img.shields.io/badge/Async_Functions-107-059669?style=flat-square)
797
+ ![Constants](https://img.shields.io/badge/Constants-336-dc2626?style=flat-square)
798
+ ![Imports](https://img.shields.io/badge/Imports-220-0284c7?style=flat-square)
783
799
  ![Exported Symbols](https://img.shields.io/badge/Exported_Symbols-66-ea580c?style=flat-square)
784
- ![Comments](https://img.shields.io/badge/Comments-339-64748b?style=flat-square)
785
- ![Comment Lines](https://img.shields.io/badge/Comment_Lines-936-475569?style=flat-square)
800
+ ![Comments](https://img.shields.io/badge/Comments-336-64748b?style=flat-square)
801
+ ![Comment Lines](https://img.shields.io/badge/Comment_Lines-944-475569?style=flat-square)
786
802
  ![TODO Comments](https://img.shields.io/badge/TODO_Comments-0-ca8a04?style=flat-square)
787
803
 
788
804
  ### Python
@@ -938,23 +954,23 @@ graph LR
938
954
  ### Markdown
939
955
 
940
956
  ![Markdown Files](https://img.shields.io/badge/Markdown_Files-2-083fa1?style=flat-square)
941
- ![Markdown Lines](https://img.shields.io/badge/Markdown_Lines-449-1f6feb?style=flat-square)
957
+ ![Markdown Lines](https://img.shields.io/badge/Markdown_Lines-479-1f6feb?style=flat-square)
942
958
  ![H1](https://img.shields.io/badge/H1-1-7c3aed?style=flat-square)
943
- ![H2](https://img.shields.io/badge/H2-41-8b5cf6?style=flat-square)
944
- ![H3](https://img.shields.io/badge/H3-52-a78bfa?style=flat-square)
959
+ ![H2](https://img.shields.io/badge/H2-43-8b5cf6?style=flat-square)
960
+ ![H3](https://img.shields.io/badge/H3-57-a78bfa?style=flat-square)
945
961
  ![H4](https://img.shields.io/badge/H4-0-c4b5fd?style=flat-square)
946
962
  ![H5](https://img.shields.io/badge/H5-0-ddd6fe?style=flat-square)
947
963
  ![H6](https://img.shields.io/badge/H6-0-ede9fe?style=flat-square)
948
- ![Paragraphs](https://img.shields.io/badge/Paragraphs-85-64748b?style=flat-square)
949
- ![Lists](https://img.shields.io/badge/Lists-46-16a34a?style=flat-square)
950
- ![List Items](https://img.shields.io/badge/List_Items-65-22c55e?style=flat-square)
964
+ ![Paragraphs](https://img.shields.io/badge/Paragraphs-91-64748b?style=flat-square)
965
+ ![Lists](https://img.shields.io/badge/Lists-52-16a34a?style=flat-square)
966
+ ![List Items](https://img.shields.io/badge/List_Items-71-22c55e?style=flat-square)
951
967
  ![Task List Items](https://img.shields.io/badge/Task_List_Items-0-4ade80?style=flat-square)
952
968
  ![Tables](https://img.shields.io/badge/Tables-2-0284c7?style=flat-square)
953
969
  ![Table Rows](https://img.shields.io/badge/Table_Rows-10-0ea5e9?style=flat-square)
954
- ![Links](https://img.shields.io/badge/Links-15-059669?style=flat-square)
970
+ ![Links](https://img.shields.io/badge/Links-21-059669?style=flat-square)
955
971
  ![Images](https://img.shields.io/badge/Images-0-10b981?style=flat-square)
956
972
  ![Code Blocks](https://img.shields.io/badge/Code_Blocks-11-dc2626?style=flat-square)
957
- ![Inline Code](https://img.shields.io/badge/Inline_Code-72-ef4444?style=flat-square)
973
+ ![Inline Code](https://img.shields.io/badge/Inline_Code-76-ef4444?style=flat-square)
958
974
  ![Block Quotes](https://img.shields.io/badge/Block_Quotes-0-ca8a04?style=flat-square)
959
975
  ![Thematic Breaks](https://img.shields.io/badge/Thematic_Breaks-0-a16207?style=flat-square)
960
976
  <!-- codometer:end -->
@@ -1,3 +1,6 @@
1
+ import { GeneratorHook } from '@conformetry/core';
2
+ import { GeneratorHookContext } from '@conformetry/core';
3
+ import { GeneratorHooks } from '@conformetry/core';
1
4
  import { InventoriedInstance } from '@conformetry/core';
2
5
  import { InventoriedPairing } from '@conformetry/core';
3
6
  import { InventoriedTemplate } from '@conformetry/core';
@@ -88,6 +91,11 @@ export declare class ConfigurationService {
88
91
  * template nobody validates — so both default to empty rather than failing.
89
92
  */
90
93
  private applyGeneratorDefaults;
94
+ /**
95
+ * Drops the hooks a generator left unset, rather than carrying them as
96
+ * explicit `undefined`, so what a host forwards is exactly what was declared.
97
+ */
98
+ private applyHookDefaults;
91
99
  /**
92
100
  * Walks upward from the process cwd looking for the workspace manifest.
93
101
  *
@@ -99,10 +107,6 @@ export declare class ConfigurationService {
99
107
  private loadConfigurationModule;
100
108
  /** Reads a JSON or JSONC config file. */
101
109
  private loadJsonConfiguration;
102
- /**
103
- * Resolves a config path against the cwd, falling back to the workspace root.
104
- */
105
- private resolveConfigurationPath;
106
110
  /** Derives the case variants every template can reference from one name. */
107
111
  buildNameSubstitutions(name: string): Substitutions;
108
112
  /** Reads one template folder. */
@@ -162,6 +166,15 @@ export declare class ConfigurationService {
162
166
  * Throws `ConfigurationPathRequiredError` for an absent or blank value.
163
167
  */
164
168
  requireConfigurationPath(value: string | undefined, surface: string): string;
169
+ /**
170
+ * Resolves a config path to the absolute file `loadConformetryConfiguration`
171
+ * reads: against the cwd first, then the workspace root.
172
+ *
173
+ * Public because the directory a hook builds its paths from is that file's
174
+ * parent, and only this resolution knows which file was read. A host that
175
+ * worked it out from the flag alone would miss the workspace-root fallback.
176
+ */
177
+ resolveConfigurationPath(configurationPath: string): Promise<string>;
165
178
  /** Resolves generator inputs from raw command-line arguments. */
166
179
  resolveGeneratorInputs(args: ResolveGeneratorInputsArguments): Promise<Record<string, string>>;
167
180
  /** Lists every file a matched instance's template requires it to have. */
@@ -183,6 +196,13 @@ export declare type ConformetryConfiguration = ConformetryGeneratorDefinition[];
183
196
  /** One generator, with the template it renders and the instances it governs. */
184
197
  export declare interface ConformetryGeneratorDefinition {
185
198
  description?: string;
199
+ /**
200
+ * Functions run around generation: `preGenerate` before anything is written,
201
+ * `postGenerate` after the template is rendered. Optional, and left off the
202
+ * loaded definition when a generator declares none, so a host forwards
203
+ * exactly what the configuration said.
204
+ */
205
+ hooks?: GeneratorHooks;
186
206
  /**
187
207
  * The values this generator substitutes, as JSON Schema fragments. Named for
188
208
  * what the implementation calls them everywhere else — a generator takes
@@ -290,6 +310,12 @@ export declare interface FindInstancesArguments {
290
310
  readonly workingDirectory: string;
291
311
  }
292
312
 
313
+ export { GeneratorHook }
314
+
315
+ export { GeneratorHookContext }
316
+
317
+ export { GeneratorHooks }
318
+
293
319
  /**
294
320
  * Thrown when a command line cannot be turned into a run.
295
321
  *
package/dist/src/index.js CHANGED
@@ -103,8 +103,12 @@ var ConfigurationPathRequiredError = class extends Error {
103
103
  e.null(),
104
104
  e.array(y),
105
105
  e.record(e.string(), y)
106
- ])), b = e.array(e.strictObject({
106
+ ])), generatorHookSchema = (t) => e.custom((e) => typeof e == "function", { message: `The ${t} hook must be a function` }), b = e.array(e.strictObject({
107
107
  description: e.string().optional(),
108
+ hooks: e.strictObject({
109
+ postGenerate: generatorHookSchema("postGenerate").optional(),
110
+ preGenerate: generatorHookSchema("preGenerate").optional()
111
+ }).optional(),
108
112
  inputs: e.record(e.string(), e.record(e.string(), y)).optional(),
109
113
  instances: e.array(e.object({
110
114
  exclude: e.array(e.string()).optional(),
@@ -901,6 +905,7 @@ var V = class ConfigurationService {
901
905
  applyGeneratorDefaults(e) {
902
906
  return {
903
907
  ...e.description === void 0 ? {} : { description: e.description },
908
+ ...e.hooks === void 0 ? {} : { hooks: this.applyHookDefaults(e.hooks) },
904
909
  inputs: e.inputs ?? {},
905
910
  instances: e.instances ?? [],
906
911
  name: e.name,
@@ -908,6 +913,12 @@ var V = class ConfigurationService {
908
913
  ...e.threshold === void 0 ? {} : { threshold: e.threshold }
909
914
  };
910
915
  }
916
+ applyHookDefaults(e) {
917
+ return {
918
+ ...e.postGenerate === void 0 ? {} : { postGenerate: e.postGenerate },
919
+ ...e.preGenerate === void 0 ? {} : { preGenerate: e.preGenerate }
920
+ };
921
+ }
911
922
  async findWorkspaceRoot() {
912
923
  let e = t.resolve(process.cwd());
913
924
  for (;;) try {
@@ -929,14 +940,6 @@ var V = class ConfigurationService {
929
940
  let t = await d(e.configurationPath, "utf8");
930
941
  return e.extension === ".jsonc" ? m(t) : JSON.parse(t);
931
942
  }
932
- async resolveConfigurationPath(e) {
933
- let n = t.resolve(e);
934
- if (c(n)) return n;
935
- let r = await this.findWorkspaceRoot();
936
- if (r === void 0) return n;
937
- let i = t.resolve(r, e);
938
- return c(i) ? i : n;
939
- }
940
943
  buildNameSubstitutions(e) {
941
944
  return this.renderingService.buildNameSubstitutions(e);
942
945
  }
@@ -999,6 +1002,14 @@ var V = class ConfigurationService {
999
1002
  if (n === void 0 || n === "") throw new ConfigurationPathRequiredError(t);
1000
1003
  return n;
1001
1004
  }
1005
+ async resolveConfigurationPath(e) {
1006
+ let n = t.resolve(e);
1007
+ if (c(n)) return n;
1008
+ let r = await this.findWorkspaceRoot();
1009
+ if (r === void 0) return n;
1010
+ let i = t.resolve(r, e);
1011
+ return c(i) ? i : n;
1012
+ }
1002
1013
  async resolveGeneratorInputs(e) {
1003
1014
  return this.inputService.resolveGeneratorInputs(e);
1004
1015
  }
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "url": "https://github.com/organizzolini/codebase/issues"
5
5
  },
6
6
  "dependencies": {
7
- "@conformetry/core": "0.0.37",
7
+ "@conformetry/core": "0.0.39",
8
8
  "@nestjs/common": "^11.1.21 || ^12.0.1",
9
9
  "jiti": "^2.7.0",
10
10
  "jsonc-parser": "^3.3.1",
@@ -67,5 +67,5 @@
67
67
  "strict": true
68
68
  },
69
69
  "types": "./dist/src/index.d.ts",
70
- "version": "0.0.38"
70
+ "version": "0.0.40"
71
71
  }