ddd-ts-kit 0.17.0 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.fr.md +10 -12
- package/README.md +9 -10
- package/dist/affected/reach-of.js +1 -1
- package/dist/affected/reach-of.js.map +1 -1
- package/dist/check/catalogue/architecture-rules.d.ts.map +1 -1
- package/dist/check/catalogue/architecture-rules.js +2 -0
- package/dist/check/catalogue/architecture-rules.js.map +1 -1
- package/dist/check/declarations/declared-event-handlers.d.ts +4 -9
- package/dist/check/declarations/declared-event-handlers.d.ts.map +1 -1
- package/dist/check/declarations/declared-event-handlers.js +5 -5
- package/dist/check/declarations/declared-event-handlers.js.map +1 -1
- package/dist/check/declarations/option-of.d.ts +0 -2
- package/dist/check/declarations/option-of.d.ts.map +1 -1
- package/dist/check/declarations/option-of.js +1 -7
- package/dist/check/declarations/option-of.js.map +1 -1
- package/dist/check/explain/authz-docs.d.ts.map +1 -1
- package/dist/check/explain/authz-docs.js +14 -1
- package/dist/check/explain/authz-docs.js.map +1 -1
- package/dist/check/explain/events-docs.d.ts.map +1 -1
- package/dist/check/explain/events-docs.js +31 -11
- package/dist/check/explain/events-docs.js.map +1 -1
- package/dist/check/explain/ports-docs.d.ts.map +1 -1
- package/dist/check/explain/ports-docs.js +11 -9
- package/dist/check/explain/ports-docs.js.map +1 -1
- package/dist/check/explain/scheduling-docs.d.ts.map +1 -1
- package/dist/check/explain/scheduling-docs.js +10 -5
- package/dist/check/explain/scheduling-docs.js.map +1 -1
- package/dist/check/explain/wiring-docs.js +4 -4
- package/dist/check/explain/wiring-docs.js.map +1 -1
- package/dist/check/fixtures/authz-policy-fixtures.d.ts +3 -0
- package/dist/check/fixtures/authz-policy-fixtures.d.ts.map +1 -0
- package/dist/check/fixtures/authz-policy-fixtures.js +97 -0
- package/dist/check/fixtures/authz-policy-fixtures.js.map +1 -0
- package/dist/check/fixtures/declarations-fixtures.d.ts.map +1 -1
- package/dist/check/fixtures/declarations-fixtures.js +2 -42
- package/dist/check/fixtures/declarations-fixtures.js.map +1 -1
- package/dist/check/fixtures/declared.d.ts.map +1 -1
- package/dist/check/fixtures/declared.js +3 -3
- package/dist/check/fixtures/declared.js.map +1 -1
- package/dist/check/fixtures/domain-events-fixtures.js +1 -1
- package/dist/check/fixtures/domain-events-fixtures.js.map +1 -1
- package/dist/check/fixtures/fixtures.d.ts.map +1 -1
- package/dist/check/fixtures/fixtures.js +2 -0
- package/dist/check/fixtures/fixtures.js.map +1 -1
- package/dist/check/rules/authz-policy-asked.d.ts +3 -0
- package/dist/check/rules/authz-policy-asked.d.ts.map +1 -0
- package/dist/check/rules/authz-policy-asked.js +184 -0
- package/dist/check/rules/authz-policy-asked.js.map +1 -0
- package/dist/check/rules/declarations-role-declared.d.ts.map +1 -1
- package/dist/check/rules/declarations-role-declared.js +4 -35
- package/dist/check/rules/declarations-role-declared.js.map +1 -1
- package/dist/check/rules/events-consumer-idempotent.js +3 -3
- package/dist/check/rules/events-consumer-idempotent.js.map +1 -1
- package/dist/generate/emit.d.ts.map +1 -1
- package/dist/generate/emit.js +2 -14
- package/dist/generate/emit.js.map +1 -1
- package/dist/generate/kinds/ask-policy-in-generated-use-case.d.ts +9 -0
- package/dist/generate/kinds/ask-policy-in-generated-use-case.d.ts.map +1 -0
- package/dist/generate/kinds/ask-policy-in-generated-use-case.js +102 -0
- package/dist/generate/kinds/ask-policy-in-generated-use-case.js.map +1 -0
- package/dist/generate/kinds/assert-declares-its-name.d.ts +9 -0
- package/dist/generate/kinds/assert-declares-its-name.d.ts.map +1 -0
- package/dist/generate/kinds/assert-declares-its-name.js +16 -0
- package/dist/generate/kinds/assert-declares-its-name.js.map +1 -0
- package/dist/generate/kinds/command-context.d.ts +12 -0
- package/dist/generate/kinds/command-context.d.ts.map +1 -0
- package/dist/generate/kinds/command-context.js +18 -0
- package/dist/generate/kinds/command-context.js.map +1 -0
- package/dist/generate/kinds/command-kind.d.ts.map +1 -1
- package/dist/generate/kinds/command-kind.js +7 -24
- package/dist/generate/kinds/command-kind.js.map +1 -1
- package/dist/generate/kinds/command-outputs.d.ts +6 -0
- package/dist/generate/kinds/command-outputs.d.ts.map +1 -0
- package/dist/generate/kinds/command-outputs.js +13 -0
- package/dist/generate/kinds/command-outputs.js.map +1 -0
- package/dist/generate/kinds/declares-its-name.d.ts +5 -0
- package/dist/generate/kinds/declares-its-name.d.ts.map +1 -0
- package/dist/generate/kinds/declares-its-name.js +7 -0
- package/dist/generate/kinds/declares-its-name.js.map +1 -0
- package/dist/generate/kinds/event-file-of.d.ts +5 -0
- package/dist/generate/kinds/event-file-of.d.ts.map +1 -0
- package/dist/generate/kinds/event-file-of.js +5 -0
- package/dist/generate/kinds/event-file-of.js.map +1 -0
- package/dist/generate/kinds/event-handler-kind.d.ts.map +1 -1
- package/dist/generate/kinds/event-handler-kind.js +2 -0
- package/dist/generate/kinds/event-handler-kind.js.map +1 -1
- package/dist/generate/kinds/event-name-reference.d.ts +4 -3
- package/dist/generate/kinds/event-name-reference.d.ts.map +1 -1
- package/dist/generate/kinds/event-name-reference.js +6 -6
- package/dist/generate/kinds/event-name-reference.js.map +1 -1
- package/dist/generate/kinds/integration-event-kind.d.ts.map +1 -1
- package/dist/generate/kinds/integration-event-kind.js +2 -0
- package/dist/generate/kinds/integration-event-kind.js.map +1 -1
- package/dist/generate/kinds/policy-kind.d.ts.map +1 -1
- package/dist/generate/kinds/policy-kind.js +2 -0
- package/dist/generate/kinds/policy-kind.js.map +1 -1
- package/dist/generate/kinds/query-context.d.ts +9 -0
- package/dist/generate/kinds/query-context.d.ts.map +1 -0
- package/dist/generate/kinds/query-context.js +27 -0
- package/dist/generate/kinds/query-context.js.map +1 -0
- package/dist/generate/kinds/query-kind.d.ts.map +1 -1
- package/dist/generate/kinds/query-kind.js +16 -52
- package/dist/generate/kinds/query-kind.js.map +1 -1
- package/dist/generate/kinds/query-outputs.d.ts +8 -0
- package/dist/generate/kinds/query-outputs.d.ts.map +1 -0
- package/dist/generate/kinds/query-outputs.js +20 -0
- package/dist/generate/kinds/query-outputs.js.map +1 -0
- package/dist/generate/kinds/reader-file.d.ts +8 -0
- package/dist/generate/kinds/reader-file.d.ts.map +1 -0
- package/dist/generate/kinds/reader-file.js +9 -0
- package/dist/generate/kinds/reader-file.js.map +1 -0
- package/dist/generate/mark-policy-questions.d.ts +10 -0
- package/dist/generate/mark-policy-questions.d.ts.map +1 -0
- package/dist/generate/mark-policy-questions.js +76 -0
- package/dist/generate/mark-policy-questions.js.map +1 -0
- package/dist/generate/permission-pattern.d.ts +4 -0
- package/dist/generate/permission-pattern.d.ts.map +1 -0
- package/dist/generate/permission-pattern.js +7 -0
- package/dist/generate/permission-pattern.js.map +1 -0
- package/dist/generate/refined-by-policy.d.ts +4 -0
- package/dist/generate/refined-by-policy.d.ts.map +1 -0
- package/dist/generate/refined-by-policy.js +9 -0
- package/dist/generate/refined-by-policy.js.map +1 -0
- package/dist/generate/rendered.d.ts +5 -0
- package/dist/generate/rendered.d.ts.map +1 -0
- package/dist/generate/rendered.js +18 -0
- package/dist/generate/rendered.js.map +1 -0
- package/dist/generate/wire.d.ts.map +1 -1
- package/dist/generate/wire.js +3 -25
- package/dist/generate/wire.js.map +1 -1
- package/dist/generate/wirings.d.ts +8 -0
- package/dist/generate/wirings.d.ts.map +1 -0
- package/dist/generate/wirings.js +28 -0
- package/dist/generate/wirings.js.map +1 -0
- package/dist/init/copilot-instruction.d.ts +6 -0
- package/dist/init/copilot-instruction.d.ts.map +1 -0
- package/dist/init/copilot-instruction.js +15 -0
- package/dist/init/copilot-instruction.js.map +1 -0
- package/dist/init/files/guidance-files.d.ts +1 -0
- package/dist/init/files/guidance-files.d.ts.map +1 -1
- package/dist/init/files/guidance-files.js +4 -3
- package/dist/init/files/guidance-files.js.map +1 -1
- package/dist/init/files/layer-rules.d.ts +3 -0
- package/dist/init/files/layer-rules.d.ts.map +1 -0
- package/dist/init/files/layer-rules.js +11 -0
- package/dist/init/files/layer-rules.js.map +1 -0
- package/dist/init/files/pipeline-files.d.ts.map +1 -1
- package/dist/init/files/pipeline-files.js +2 -0
- package/dist/init/files/pipeline-files.js.map +1 -1
- package/dist/init/json-object.d.ts +3 -0
- package/dist/init/json-object.d.ts.map +1 -0
- package/dist/init/json-object.js +12 -0
- package/dist/init/json-object.js.map +1 -0
- package/dist/init/manifest/versions.js +24 -24
- package/dist/init/run-init.d.ts.map +1 -1
- package/dist/init/run-init.js +4 -0
- package/dist/init/run-init.js.map +1 -1
- package/dist/init/write-agent-settings.d.ts.map +1 -1
- package/dist/init/write-agent-settings.js +3 -10
- package/dist/init/write-agent-settings.js.map +1 -1
- package/dist/init/write-copilot-instructions.d.ts +7 -0
- package/dist/init/write-copilot-instructions.d.ts.map +1 -0
- package/dist/init/write-copilot-instructions.js +16 -0
- package/dist/init/write-copilot-instructions.js.map +1 -0
- package/dist/init/write-copilot-settings.d.ts +8 -0
- package/dist/init/write-copilot-settings.d.ts.map +1 -0
- package/dist/init/write-copilot-settings.js +36 -0
- package/dist/init/write-copilot-settings.js.map +1 -0
- package/dist/markers/index.d.ts +1 -0
- package/dist/markers/index.d.ts.map +1 -1
- package/dist/markers/index.js +1 -0
- package/dist/markers/index.js.map +1 -1
- package/dist/markers/replace-in-region.d.ts +10 -0
- package/dist/markers/replace-in-region.d.ts.map +1 -0
- package/dist/markers/replace-in-region.js +30 -0
- package/dist/markers/replace-in-region.js.map +1 -0
- package/dist/sdk/agent-instruction.d.ts +1 -1
- package/dist/sdk/agent-instruction.js +1 -1
- package/dist/sdk/instruct-agents.d.ts +1 -1
- package/dist/sdk/instruct-agents.d.ts.map +1 -1
- package/dist/sdk/instruct-agents.js +12 -8
- package/dist/sdk/instruct-agents.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +24 -3
- package/templates/command/handler.declared.ts.tpl +29 -0
- package/templates/command/handler.spec.buses.ts.tpl +24 -1
- package/templates/command/handler.ts.tpl +29 -0
- package/templates/command/wiring.manual.tpl +2 -2
- package/templates/command/wiring.tsyringe.tpl +5 -2
- package/templates/event-handler/event-handler.declared.ts.tpl +1 -1
- package/templates/init/AGENTS.md.tpl +46 -0
- package/templates/init/CLAUDE.md.tpl +2 -45
- package/templates/init/README.md.tpl +1 -1
- package/templates/init/rules/application.md.tpl +1 -1
- package/templates/integration-event/publisher.declared.ts.tpl +1 -1
- package/templates/pipeline/github/workflows/copilot-setup-steps.yml +26 -0
- package/templates/pipeline/package-scripts.json +1 -1
- package/templates/presets/identity/context/application/integration/publishers/account-deactivated.publisher.ts.tpl +1 -1
- package/templates/presets/identity/context/application/integration/publishers/delegation-granted.publisher.ts.tpl +1 -1
- package/templates/presets/identity/context/application/integration/publishers/delegation-revoked.publisher.ts.tpl +1 -1
- package/templates/presets/identity/context/application/integration/publishers/member-joined.publisher.ts.tpl +1 -1
- package/templates/presets/identity/context/application/integration/publishers/member-removed.publisher.ts.tpl +1 -1
- package/templates/presets/identity/context/application/integration/publishers/member-role-changed.publisher.ts.tpl +1 -1
- package/templates/presets/identity/context/application/integration/publishers/organisation-opened.publisher.ts.tpl +1 -1
- package/templates/query/handler.declared.ts.tpl +19 -0
- package/templates/query/handler.spec.buses.ts.tpl +21 -0
- package/templates/query/handler.ts.tpl +19 -0
- package/templates/query/wiring.manual.tpl +1 -1
- package/templates/query/wiring.tsyringe.tpl +4 -1
package/README.fr.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[English](README.md) · **Français**
|
|
2
|
-
<!-- translation-of: README.md sha256:
|
|
2
|
+
<!-- translation-of: README.md sha256:bed804ca4ed40c91 -->
|
|
3
3
|
|
|
4
4
|
# ddd-ts-kit
|
|
5
5
|
|
|
@@ -520,10 +520,11 @@ choix sont enregistrés sous `stack` dans la configuration, `docsUi`, `ci` et `l
|
|
|
520
520
|
| `knip.json` | code mort : les points d'entrée sont `main.ts` et `apps/*/main.ts`, les scripts, les *specs* et les *fakes*, les fichiers de module dans le style explicite, les fichiers de rôle sous discovery (*jobs* et *publishers* compris) |
|
|
521
521
|
| `vitest.config.ts` | projets unitaires et d'intégration, les seuils de couverture lus dans `ddd-ts-kit.config.json` (`governedCoverage`), par contexte et par couche, dans le mode des décorateurs standard `decorators()` de `@ddd-ts-kit/testing/vitest`, qui compile les fichiers contenant un décorateur avec le compilateur du projet (Vitest ne transforme pas les décorateurs standard ; il transforme lui-même les anciens, si bien qu'un projet avec `experimentalDecorators` ne reçoit pas de *plugin*), et sous `--assembly discovery` `server.deps.inline: ['@ddd-ts-kit/di']` |
|
|
522
522
|
| `lefthook.yml`, `commitlint.config.mjs` | *hooks* pre-commit (ESLint, la vérification du format et `check` sur les fichiers indexés, `check --commit-size --staged`, qui ne bloque jamais), pre-push (types, tests unitaires) et commit-msg (`npm run hooks:install`), *commits* conventionnels |
|
|
523
|
-
| `--ci github` | `.github/workflows/ci.yml`, `pr-title.yml`, `.github/dependabot.yml`, `.github/branch-protection.md`, `renovate.json` ; `codeql.yml` avec `--ci-extras codeql` |
|
|
523
|
+
| `--ci github` | `.github/workflows/ci.yml`, `pr-title.yml`, `copilot-setup-steps.yml` (Node et les dépendances, installés avant le démarrage de l'agent cloud de Copilot), `.github/dependabot.yml`, `.github/branch-protection.md`, `renovate.json` ; `codeql.yml` avec `--ci-extras codeql` |
|
|
524
524
|
| `--ci gitlab` | `.gitlab-ci.yml` (les constats d'architecture comme rapport Code Quality au moyen de `check --format gitlab`), `.gitlab/merge-request-settings.md`, `renovate.json` |
|
|
525
|
-
| `README.md`, `CLAUDE.md`, `.claude/rules/*.md` | comment le lancer ; un guide léger (commandes, comment lire moins, la carte des règles, fichiers générés, note sur le compilateur, les *skills* du *plugin* : `/ddd-ts-kit:start`, `glossary`, `use-case`, `document`, `quality-gate`) et les invariants dans sept fichiers de règles, `domain.md`, `application.md`, `published-language.md`, `infrastructure.md`, `presentation.md`, `platform.md` et `tests.md`, chacun délimité par un frontmatter `paths` |
|
|
526
|
-
| `.
|
|
525
|
+
| `README.md`, `AGENTS.md`, `CLAUDE.md`, `.claude/rules/*.md`, `.github/instructions/*.instructions.md` | comment le lancer ; un guide léger dans `AGENTS.md`, que lisent Codex, Copilot et la plupart des agents de code et qu'importe `CLAUDE.md` (commandes, comment lire moins, la carte des règles, fichiers générés, note sur le compilateur, les *skills* du *plugin* : `/ddd-ts-kit:start`, `glossary`, `use-case`, `document`, `quality-gate`) et les invariants dans sept fichiers de règles, `domain.md`, `application.md`, `published-language.md`, `infrastructure.md`, `presentation.md`, `platform.md` et `tests.md`, chacun délimité par un frontmatter `paths`, et les mêmes sept pour GitHub Copilot, chacun délimité par `applyTo` |
|
|
526
|
+
| `.github/copilot/settings.json` | le *plugin* du kit, déclaré pour GitHub Copilot (`extraKnownMarketplaces`, `enabledPlugins`) : son agent cloud l'installe, la CLI Copilot et VS Code le recommandent ; un fichier existant garde ce qu'il contient et reçoit les deux entrées |
|
|
527
|
+
| `.claude/settings.json` | des permissions seulement : les vérifications et les générateurs s'exécutent sans demander, les fichiers `.env` sont illisibles (`.env.example` reste lisible), les trois documents générés ne sont pas modifiés à la main, `git push`, `npm publish` et toute modification des fichiers qui portent les règles et le *pipeline* (`ddd-ts-kit.config.json`, `eslint.config.mjs`, `biome.json`, `.dependency-cruiser.cjs`, `knip.json`, `lefthook.yml`, `.gitlab-ci.yml`, `.github/workflows/**`, `.claude/settings.json`, `.github/copilot/settings.json`) demandent d'abord |
|
|
527
528
|
| `.gitignore` | `node_modules`, `dist`, `coverage`, `.env`, `*.tsbuildinfo` et `.ddd-ts-kit/`, où écrit `worker-scope` |
|
|
528
529
|
|
|
529
530
|
`--ci both` écrit les deux *pipelines*, `--ci none` aucun (et pas de `renovate.json`). Les
|
|
@@ -678,7 +679,7 @@ Next, in this order: the language of the context first, then the business decisi
|
|
|
678
679
|
avec `@Repository(<UseCase>Reader)` ; `integration-handler` écrit
|
|
679
680
|
`@IntegrationEventHandler(definition, { consumer })` et est refusé quand l'amont ne déclare pas
|
|
680
681
|
l'événement ; `event-handler` et le *publisher* de `integration-event` écrivent
|
|
681
|
-
`@DomainEventHandler(Event
|
|
682
|
+
`@DomainEventHandler(Event)`, rattaché au `eventName` que déclare la classe d'événement (le *publisher* avec
|
|
682
683
|
`[IntegrationEventPublisher, IdGenerator]`), et tous deux sont trouvés comme n'importe quel
|
|
683
684
|
fichier de rôle : la racine de composition ne liste aucun *publisher* ; `job` écrit
|
|
684
685
|
`@Scheduled('<context>.<name>', schedule)` ; `policy` écrit une classe avec
|
|
@@ -1107,7 +1108,8 @@ est utilisée quand le clone l'a). Chaque chemin modifié atteint quelque chose
|
|
|
1107
1108
|
puisque leur code peut lire son langage publié ; un chemin sous son seul `test/` atteint ce
|
|
1108
1109
|
contexte seul, puisqu'aucun autre contexte ne peut importer ses tests ;
|
|
1109
1110
|
- un document n'atteint rien qui s'exécute : un fichier Markdown à la racine, tout ce qui est
|
|
1110
|
-
sous `docs/`, `openapi/` ou `.
|
|
1111
|
+
sous `docs/`, `openapi/`, `.claude/`, `.github/instructions/` ou `.github/copilot/` (la porte des
|
|
1112
|
+
documents tourne toujours) ;
|
|
1111
1113
|
- tout le reste atteint tout : la plateforme, le noyau partagé, `main.ts`, la configuration, le
|
|
1112
1114
|
lockfile, le *pipeline*, un répertoire de `src/contexts/` que la configuration ne déclare pas.
|
|
1113
1115
|
|
|
@@ -1306,7 +1308,7 @@ règle.
|
|
|
1306
1308
|
| `event-sourcing/upcaster-required` | un `defineStoredEvent` dont `encode` ne nomme aucun type, ou un type non déclaré dans le fichier, ou un type qu'il atteint et que le fichier ne déclare pas ; une version au-dessus de 1 sans *upcaster* depuis chaque version inférieure ; une version en dessous de la dernière enregistrée dans `stored-events.lock.json`, ou une version enregistrée dont la forme a changé. `ddd-ts-kit docs --stored-events` enregistre les nouvelles versions et n'en réécrit jamais une ; `docs --check` échoue tant qu'une version déclarée n'est pas enregistrée |
|
|
1307
1309
|
| `context/extractable` | un fichier de module qui importe un autre contexte hors de son langage publié ; une persistance qui importe l'infrastructure d'un autre contexte ou nomme son schéma ; un gestionnaire qui importe le *repository* d'un autre contexte ; `export let` ou un `new Map`, `Set`, `WeakMap` exporté au niveau du module ; `deployable: true` sans `apps/<context>/main.ts` ; dans le style déclaré, un fichier de rôle qui importe quoi que ce soit d'un fichier de port d'un autre contexte |
|
|
1308
1310
|
| `governance/recorded-deviation` | un commentaire `ddd-ts-kit-disable` ou `eslint-disable` dont la raison ne nomme aucun `ADR-<number>` avec un fichier `docs/adr/<number>-*.md` ; une règle mise à `off` (ou à `warn` en dessous de sa valeur par défaut), un répertoire supplémentaire, un *package* autorisé supplémentaire, un `guard` autre que `enforce` ou `stack.events` hors de l'outbox, sans entrée `deviations` `{ what, adr, reason }` qui pointe vers un enregistrement existant |
|
|
1309
|
-
| `declarations/role-declared` | style déclaré seulement : un fichier de rôle (autre que `*.command.ts` et `*.query.ts`, tenus par `authz/declared` ; `*.job.ts` sous `application/scheduling/` avec `@Scheduled` et `*.publisher.ts` avec `@DomainEventHandler` sont des rôles) qui n'exporte aucune classe portant le décorateur de son suffixe et de son dossier, ou une classe qui en porte une autre ; une classe déclarée dans un fichier qui n'est pas un fichier de rôle ; une option `consumer` ou `name` manquante, vide, une variable, une concaténation ou un template literal avec une substitution ;
|
|
1311
|
+
| `declarations/role-declared` | style déclaré seulement : un fichier de rôle (autre que `*.command.ts` et `*.query.ts`, tenus par `authz/declared` ; `*.job.ts` sous `application/scheduling/` avec `@Scheduled` et `*.publisher.ts` avec `@DomainEventHandler` sont des rôles) qui n'exporte aucune classe portant le décorateur de son suffixe et de son dossier, ou une classe qui en porte une autre ; une classe déclarée dans un fichier qui n'est pas un fichier de rôle ; une option `consumer` ou `name` manquante, vide, une variable, une concaténation ou un template literal avec une substitution ; tout décorateur de déclaration sur une classe sous `domain/` |
|
|
1310
1312
|
| `declarations/barrel-current` | style déclaré seulement : avec `stack.assembly: barrel`, un `<context>.declarations.ts` manquant ou qui diffère d'un `export *` par fichier de rôle trié par chemin, suivi d'un `injected(Class, [Tokens])` par classe dont le constructeur reçoit quelque chose (lu depuis les signatures, avec leurs imports) ; avec `discovery`, un barrel qui existe encore, et un `<context>.dependencies.ts` qui diffère de ces instructions `injected` (son absence est acceptée tant qu'il n'en contiendrait aucune). Le message nomme le fichier de rôle manquant ou la classe dont la liste est périmée. Elle a besoin de l'arbre, c'est pourquoi `check-file` ne l'exécute pas |
|
|
1311
1313
|
| `declarations/constructor-injection` | style déclaré seulement, dans un fichier de rôle : sur une classe dont le décorateur ne liste rien, un paramètre de constructeur optionnel, qui a une valeur par défaut, est un paramètre du reste ou est déstructuré, n'a pas de type, ou est typé par autre chose qu'un nom de classe (arguments de type mis à part) : une union, une intersection, un tableau, un nom qualifié, un type du langage, une interface, un alias de type, une enum ou une classe non exportée du fichier ou du fichier du projet d'où elle est importée ; une classe qui hérite son constructeur d'une classe que le projet ne sait pas lire. Sous `stack.dependencies: signature`, un décorateur qui porte une liste alors que le constructeur peut être lu : une liste qui le répète, une qui en diffère |
|
|
1312
1314
|
| `ports/abstract-class` | dans un fichier de port (`domain/repositories/*.repository.ts`, `application/ports/*.port.ts`) : une classe qui n'est pas `abstract` ; un membre qui n'est pas une méthode ou une propriété abstraite (`static readonly tokenKey = '<text>'` mis à part) : un constructeur, un corps, un initialiseur, un membre `private`, `protected` ou `#` ; une `interface` exportée (un alias `type`, une forme de données, n'est pas signalé) |
|
|
@@ -1412,11 +1414,7 @@ exactement comme le chemin relatif vers le même fichier.
|
|
|
1412
1414
|
et les espaces de noms). Les options `consumer` et `name` ne sont lues que dans un littéral
|
|
1413
1415
|
d'objet écrit dans l'appel du décorateur : gardées dans une variable, étalées ou construites par
|
|
1414
1416
|
une fonction, elles sont signalées comme n'étant pas une chaîne littérale.
|
|
1415
|
-
- `
|
|
1416
|
-
le corps de la classe d'événement, trouvée par un import direct relatif ou par alias : un nom
|
|
1417
|
-
posé dans un constructeur, un accesseur ou une classe de base, ou un événement atteint par un
|
|
1418
|
-
barrel, n'est pas comparé. `authz/declared` suit un import direct du message depuis un fichier
|
|
1419
|
-
de module.
|
|
1417
|
+
- `authz/declared` suit un import direct du message depuis un fichier de module.
|
|
1420
1418
|
- `context/extractable` reconnaît un port à son fichier (`domain/repositories/*.repository.ts`,
|
|
1421
1419
|
`application/ports/*.port.ts`) : un port d'un autre contexte atteint par un réexport n'est pas
|
|
1422
1420
|
vu.
|
package/README.md
CHANGED
|
@@ -504,10 +504,11 @@ config, `docsUi`, `ci` and `logger` included.
|
|
|
504
504
|
| `knip.json` | dead code: entry points are `main.ts` and `apps/*/main.ts`, the scripts, the specs and the fakes, the module files in the explicit style, the role files under discovery (jobs and publishers included) |
|
|
505
505
|
| `vitest.config.ts` | unit and integration projects, the coverage thresholds read from `ddd-ts-kit.config.json` (`governedCoverage`), per context and layer, in the standard decorator mode `decorators()` of `@ddd-ts-kit/testing/vitest`, which compiles the files holding a decorator with the compiler of the project (Vitest does not lower standard decorators; it lowers legacy ones itself, so a project with `experimentalDecorators` gets no plugin), and under `--assembly discovery` `server.deps.inline: ['@ddd-ts-kit/di']` |
|
|
506
506
|
| `lefthook.yml`, `commitlint.config.mjs` | pre-commit (ESLint, the format check and `check` on the staged files, `check --commit-size --staged`, which never blocks), pre-push (types, unit tests) and commit-msg hooks (`npm run hooks:install`), conventional commits |
|
|
507
|
-
| `--ci github` | `.github/workflows/ci.yml`, `pr-title.yml`, `.github/dependabot.yml`, `.github/branch-protection.md`, `renovate.json`; `codeql.yml` with `--ci-extras codeql` |
|
|
507
|
+
| `--ci github` | `.github/workflows/ci.yml`, `pr-title.yml`, `copilot-setup-steps.yml` (Node and the dependencies, installed before the Copilot cloud agent starts), `.github/dependabot.yml`, `.github/branch-protection.md`, `renovate.json`; `codeql.yml` with `--ci-extras codeql` |
|
|
508
508
|
| `--ci gitlab` | `.gitlab-ci.yml` (architecture findings as a Code Quality report through `check --format gitlab`), `.gitlab/merge-request-settings.md`, `renovate.json` |
|
|
509
|
-
| `README.md`, `CLAUDE.md`, `.claude/rules/*.md` | how to run it; a slim guide (commands, how to read less, the map of the rules, generated files, compiler note, the skills of the plugin: `/ddd-ts-kit:start`, `glossary`, `use-case`, `document`, `quality-gate`) and the invariants in seven rule files, `domain.md`, `application.md`, `published-language.md`, `infrastructure.md`, `presentation.md`, `platform.md` and `tests.md`, each scoped by a `paths` frontmatter |
|
|
510
|
-
| `.
|
|
509
|
+
| `README.md`, `AGENTS.md`, `CLAUDE.md`, `.claude/rules/*.md`, `.github/instructions/*.instructions.md` | how to run it; a slim guide in `AGENTS.md`, which Codex, Copilot and most coding agents read and `CLAUDE.md` imports (commands, how to read less, the map of the rules, generated files, compiler note, the skills of the plugin: `/ddd-ts-kit:start`, `glossary`, `use-case`, `document`, `quality-gate`) and the invariants in seven rule files, `domain.md`, `application.md`, `published-language.md`, `infrastructure.md`, `presentation.md`, `platform.md` and `tests.md`, each scoped by a `paths` frontmatter, and the same seven for GitHub Copilot, each scoped by `applyTo` |
|
|
510
|
+
| `.github/copilot/settings.json` | the plugin of the kit, declared for GitHub Copilot (`extraKnownMarketplaces`, `enabledPlugins`): its cloud agent installs it, the Copilot CLI and VS Code recommend it; an existing file keeps what it holds and gains the two entries |
|
|
511
|
+
| `.claude/settings.json` | permissions only: the checks and generators run without asking, `.env` files are unreadable (`.env.example` stays readable), the three generated documents are not edited by hand, `git push`, `npm publish` and any edit of the files that hold the rules and the pipeline (`ddd-ts-kit.config.json`, `eslint.config.mjs`, `biome.json`, `.dependency-cruiser.cjs`, `knip.json`, `lefthook.yml`, `.gitlab-ci.yml`, `.github/workflows/**`, `.claude/settings.json`, `.github/copilot/settings.json`) ask first |
|
|
511
512
|
| `.gitignore` | `node_modules`, `dist`, `coverage`, `.env`, `*.tsbuildinfo` and `.ddd-ts-kit/`, where `worker-scope` writes |
|
|
512
513
|
|
|
513
514
|
`--ci both` writes the two pipelines, `--ci none` neither (and no `renovate.json`). The pipeline
|
|
@@ -658,7 +659,7 @@ Next, in this order: the language of the context first, then the business decisi
|
|
|
658
659
|
`@Repository(<UseCase>Reader)`; `integration-handler` writes
|
|
659
660
|
`@IntegrationEventHandler(definition, { consumer })` and is refused when the
|
|
660
661
|
upstream does not declare the event; `event-handler` and the publisher of `integration-event`
|
|
661
|
-
write `@DomainEventHandler(Event
|
|
662
|
+
write `@DomainEventHandler(Event)`, attached under the `eventName` the event class declares (the publisher with
|
|
662
663
|
`[IntegrationEventPublisher, IdGenerator]`), and both are found like any role file: the
|
|
663
664
|
composition root lists no publisher; `job` writes `@Scheduled('<context>.<name>', schedule)`;
|
|
664
665
|
`policy` writes a class with `@Policy(permission, { name })` and registers nothing; `gateway`
|
|
@@ -1056,7 +1057,8 @@ Each changed path reaches something:
|
|
|
1056
1057
|
their code may read its published language; a path under its `test/` alone reaches that
|
|
1057
1058
|
context alone, since no other context may import its tests;
|
|
1058
1059
|
- a document reaches nothing that runs: a Markdown file at the root, anything under `docs/`,
|
|
1059
|
-
`openapi/` or `.
|
|
1060
|
+
`openapi/`, `.claude/`, `.github/instructions/` or `.github/copilot/` (the documents gate
|
|
1061
|
+
always runs);
|
|
1060
1062
|
- anything else reaches everything: the platform, the shared kernel, `main.ts`, the config, the
|
|
1061
1063
|
lockfile, the pipeline, a directory of `src/contexts/` the config does not declare.
|
|
1062
1064
|
|
|
@@ -1249,7 +1251,7 @@ const due = handler.isDueNow(new Reminder(new Date('2026-03-01T09:00:00Z'))); //
|
|
|
1249
1251
|
| `event-sourcing/upcaster-required` | a `defineStoredEvent` whose `encode` names no type, or a type not declared in the file, or a type it reaches that the file does not declare; a version above 1 without an upcaster from each version below; a version below the last one recorded in `stored-events.lock.json`, or a recorded version whose shape changed. `ddd-ts-kit docs --stored-events` records new versions and never rewrites one; `docs --check` fails while a declared version is unrecorded |
|
|
1250
1252
|
| `context/extractable` | a module file importing another context outside its published language; persistence importing another context's infrastructure or naming its schema; a handler importing another context's repository; `export let` or an exported `new Map`, `Set`, `WeakMap` at module level; `deployable: true` without `apps/<context>/main.ts`; in the declared style, a role file importing anything of a port file of another context |
|
|
1251
1253
|
| `governance/recorded-deviation` | a `ddd-ts-kit-disable` or `eslint-disable` comment whose reason names no `ADR-<number>` with a file `docs/adr/<number>-*.md`; a rule set to `off` (or to `warn` below its default), an extra directory, an extra allowed package, a `guard` other than `enforce` or `stack.events` off the outbox, without a `deviations` entry `{ what, adr, reason }` pointing to an existing record |
|
|
1252
|
-
| `declarations/role-declared` | declared style only: a role file (other than `*.command.ts` and `*.query.ts`, held by `authz/declared`; `*.job.ts` under `application/scheduling/` with `@Scheduled` and `*.publisher.ts` with `@DomainEventHandler` are roles) exporting no class with the decorator of its suffix and folder, or one carrying another declaration; a declared class in a file that is not a role file; a `consumer` or `name` option that is missing, empty, a variable, a concatenation or a template with a substitution;
|
|
1254
|
+
| `declarations/role-declared` | declared style only: a role file (other than `*.command.ts` and `*.query.ts`, held by `authz/declared`; `*.job.ts` under `application/scheduling/` with `@Scheduled` and `*.publisher.ts` with `@DomainEventHandler` are roles) exporting no class with the decorator of its suffix and folder, or one carrying another declaration; a declared class in a file that is not a role file; a `consumer` or `name` option that is missing, empty, a variable, a concatenation or a template with a substitution; any declaration decorator on a class under `domain/` |
|
|
1253
1255
|
| `declarations/barrel-current` | declared style only: with `stack.assembly: barrel`, a missing `<context>.declarations.ts` or one that differs from one `export *` per role file sorted by path followed by one `injected(Class, [Tokens])` per class whose constructor takes something (read from the signatures, with their imports); with `discovery`, a barrel that still exists, and a `<context>.dependencies.ts` that differs from those `injected` statements (absent is accepted while it would hold none). The message names the missing role file or the class whose list is stale. It needs the tree, so `check-file` does not run it |
|
|
1254
1256
|
| `declarations/constructor-injection` | declared style only, in a role file: on a class whose decorator lists nothing, a constructor parameter that is optional, has a default value, is a rest parameter or is destructured, has no type, or is typed by anything but one class name (type arguments aside): a union, an intersection, an array, a qualified name, a type of the language, an interface, a type alias, an enum or an unexported class of the file or of the file of the project it is imported from; a class that inherits its constructor from a class the project cannot read. Under `stack.dependencies: signature`, a decorator that carries a list although the constructor can be read: one that repeats it, one that differs |
|
|
1255
1257
|
| `ports/abstract-class` | in a port file (`domain/repositories/*.repository.ts`, `application/ports/*.port.ts`): a class that is not `abstract`; a member that is not an abstract method or property (`static readonly tokenKey = '<text>'` apart): a constructor, a body, an initializer, a `private`, `protected` or `#` member; an exported `interface` (a `type` alias, a data shape, is not reported) |
|
|
@@ -1343,10 +1345,7 @@ import is judged by every boundary rule exactly as the relative path to the same
|
|
|
1343
1345
|
and namespaces). The `consumer` and `name` options are read only in an object literal written in
|
|
1344
1346
|
the decorator call: held in a variable, spread or built by a function, they are reported as not
|
|
1345
1347
|
being a string literal.
|
|
1346
|
-
- `
|
|
1347
|
-
body of the event class, found through a direct relative or alias import: a name set in a
|
|
1348
|
-
constructor, a getter or a base class, or an event reached through a barrel, is not compared.
|
|
1349
|
-
`authz/declared` follows one direct import of the message from a module file.
|
|
1348
|
+
- `authz/declared` follows one direct import of the message from a module file.
|
|
1350
1349
|
- `context/extractable` tells a port by its file (`domain/repositories/*.repository.ts`,
|
|
1351
1350
|
`application/ports/*.port.ts`): a port of another context reached through a re-export is not seen.
|
|
1352
1351
|
- `composition/only-in-module` reports every `.include(` of a file importing `@ddd-ts-kit/di`
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Written for people and agents, never loaded by a spec, a build or a tool of the pipeline other than the documents gate, which always runs. */
|
|
2
|
-
const DOCUMENT_DIRECTORIES = ['docs/', 'openapi/', '.claude/'];
|
|
2
|
+
const DOCUMENT_DIRECTORIES = ['docs/', 'openapi/', '.claude/', '.github/instructions/', '.github/copilot/'];
|
|
3
3
|
/**
|
|
4
4
|
* What a changed path, relative to the project root, reaches. A path under a declared context
|
|
5
5
|
* reaches that context; a document reaches nothing; anything else (the shared kernel, the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reach-of.js","sourceRoot":"","sources":["../../src/affected/reach-of.ts"],"names":[],"mappings":"AAGA,iJAAiJ;AACjJ,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"reach-of.js","sourceRoot":"","sources":["../../src/affected/reach-of.ts"],"names":[],"mappings":"AAGA,iJAAiJ;AACjJ,MAAM,oBAAoB,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,uBAAuB,EAAE,kBAAkB,CAAC,CAAC;AAE5G;;;;;GAKG;AACH,MAAM,UAAU,OAAO,CAAC,MAAc,EAAE,IAAY;IAClD,MAAM,QAAQ,GAAG,GAAG,MAAM,CAAC,WAAW,GAAG,CAAC;IAE1C,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,OAAO,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,6BAA6B,EAAE,CAAC;AAC9E,CAAC;AAED,SAAS,YAAY,CAAC,MAAc,EAAE,MAAc;IAClD,MAAM,CAAC,OAAO,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAElD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,SAAS,EAAE,CAAC;QAChE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,iCAAiC,EAAE,CAAC;IAC1G,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC;AACrE,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAEnC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;AAClH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"architecture-rules.d.ts","sourceRoot":"","sources":["../../../src/check/catalogue/architecture-rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"architecture-rules.d.ts","sourceRoot":"","sources":["../../../src/check/catalogue/architecture-rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAmF7C,gHAAgH;AAChH,eAAO,MAAM,kBAAkB,EAAE,SAAS,IAAI,EAkF7C,CAAC"}
|
|
@@ -3,6 +3,7 @@ import { authzActorExplicit } from '../rules/authz-actor-explicit.js';
|
|
|
3
3
|
import { authzFieldsBySchema } from '../rules/authz-fields-by-schema.js';
|
|
4
4
|
import { authzDeclared } from '../rules/authz-declared.js';
|
|
5
5
|
import { authzInApplication } from '../rules/authz-in-application.js';
|
|
6
|
+
import { authzPolicyAsked } from '../rules/authz-policy-asked.js';
|
|
6
7
|
import { cleanBlankLines } from '../rules/clean-blank-lines.js';
|
|
7
8
|
import { cleanBraces } from '../rules/clean-braces.js';
|
|
8
9
|
import { cleanFileSize } from '../rules/clean-file-size.js';
|
|
@@ -134,6 +135,7 @@ export const ARCHITECTURE_RULES = [
|
|
|
134
135
|
authzInApplication,
|
|
135
136
|
authzActorExplicit,
|
|
136
137
|
authzFieldsBySchema,
|
|
138
|
+
authzPolicyAsked,
|
|
137
139
|
aspectsOutsideIn,
|
|
138
140
|
tracingPlatformOnly,
|
|
139
141
|
tenancyScopedStatement,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"architecture-rules.js","sourceRoot":"","sources":["../../../src/check/catalogue/architecture-rules.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"architecture-rules.js","sourceRoot":"","sources":["../../../src/check/catalogue/architecture-rules.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,16 +4,11 @@ export interface DeclaredEventHandler {
|
|
|
4
4
|
readonly className: string;
|
|
5
5
|
/** Line of the decorator. */
|
|
6
6
|
readonly line: number;
|
|
7
|
-
/** The first argument: the definition of
|
|
7
|
+
/** The first argument: the definition of the integration event. */
|
|
8
8
|
readonly event: string;
|
|
9
|
-
/** The `consumer` of `@IntegrationEventHandler
|
|
9
|
+
/** The `consumer` of `@IntegrationEventHandler`; undefined when the options hold no such key. */
|
|
10
10
|
readonly name: OptionValue | undefined;
|
|
11
11
|
}
|
|
12
|
-
declare
|
|
13
|
-
|
|
14
|
-
readonly DomainEventHandler: 'name';
|
|
15
|
-
};
|
|
16
|
-
/** The classes of a source that declare themselves handlers of an event, with the name their decorator gives. */
|
|
17
|
-
export declare function declaredEventHandlers(scan: Scan, decorator: keyof typeof NAME_KEYS): DeclaredEventHandler[];
|
|
18
|
-
export {};
|
|
12
|
+
/** The classes of a source that declare themselves handlers of an integration event, with the consumer name their decorator gives. */
|
|
13
|
+
export declare function declaredEventHandlers(scan: Scan): DeclaredEventHandler[];
|
|
19
14
|
//# sourceMappingURL=declared-event-handlers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"declared-event-handlers.d.ts","sourceRoot":"","sources":["../../../src/check/declarations/declared-event-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE5D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,
|
|
1
|
+
{"version":3,"file":"declared-event-handlers.d.ts","sourceRoot":"","sources":["../../../src/check/declarations/declared-event-handlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAG5C,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE5D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,6BAA6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,mEAAmE;IACnE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,iGAAiG;IACjG,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS,CAAC;CACxC;AAID,sIAAsI;AACtI,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,IAAI,GAAG,oBAAoB,EAAE,CAWxE"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { argumentsOf } from './arguments-of.js';
|
|
2
2
|
import { classesOf } from './classes-of.js';
|
|
3
3
|
import { optionOf } from './option-of.js';
|
|
4
|
-
const
|
|
5
|
-
/** The classes of a source that declare themselves handlers of an event, with the name their decorator gives. */
|
|
6
|
-
export function declaredEventHandlers(scan
|
|
4
|
+
const DECORATOR = 'IntegrationEventHandler';
|
|
5
|
+
/** The classes of a source that declare themselves handlers of an integration event, with the consumer name their decorator gives. */
|
|
6
|
+
export function declaredEventHandlers(scan) {
|
|
7
7
|
return classesOf(scan).flatMap((declared) => declared.decorations
|
|
8
|
-
.filter(({ name }) => name ===
|
|
8
|
+
.filter(({ name }) => name === DECORATOR)
|
|
9
9
|
.map((decoration) => ({
|
|
10
10
|
className: declared.name,
|
|
11
11
|
line: decoration.line,
|
|
12
12
|
event: argumentsOf(scan, decoration)[0]?.code ?? '',
|
|
13
|
-
name: optionOf(scan, decoration,
|
|
13
|
+
name: optionOf(scan, decoration, 'consumer'),
|
|
14
14
|
})));
|
|
15
15
|
}
|
|
16
16
|
//# sourceMappingURL=declared-event-handlers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"declared-event-handlers.js","sourceRoot":"","sources":["../../../src/check/declarations/declared-event-handlers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAoB,MAAM,gBAAgB,CAAC;AAY5D,MAAM,SAAS,GAAG,
|
|
1
|
+
{"version":3,"file":"declared-event-handlers.js","sourceRoot":"","sources":["../../../src/check/declarations/declared-event-handlers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAoB,MAAM,gBAAgB,CAAC;AAY5D,MAAM,SAAS,GAAG,yBAAyB,CAAC;AAE5C,sIAAsI;AACtI,MAAM,UAAU,qBAAqB,CAAC,IAAU;IAC9C,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC1C,QAAQ,CAAC,WAAW;SACjB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC;SACxC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACpB,SAAS,EAAE,QAAQ,CAAC,IAAI;QACxB,IAAI,EAAE,UAAU,CAAC,IAAI;QACrB,KAAK,EAAE,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE;QACnD,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,UAAU,CAAC;KAC7C,CAAC,CAAC,CACN,CAAC;AACJ,CAAC"}
|
|
@@ -4,8 +4,6 @@ import type { Decoration } from './decoration.js';
|
|
|
4
4
|
export interface OptionValue {
|
|
5
5
|
/** Undefined when the value is a variable, a template with substitutions, a concatenation or a shorthand. */
|
|
6
6
|
readonly literal: string | undefined;
|
|
7
|
-
/** The value when it reads a member of a name, `InvoiceIssued.eventName`; undefined otherwise. */
|
|
8
|
-
readonly reference?: string;
|
|
9
7
|
readonly line: number;
|
|
10
8
|
}
|
|
11
9
|
/** The value of `key` in an options object given directly to the decorator, or undefined when no such key is written. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"option-of.d.ts","sourceRoot":"","sources":["../../../src/check/declarations/option-of.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,2CAA2C;AAC3C,MAAM,WAAW,WAAW;IAC1B,6GAA6G;IAC7G,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,
|
|
1
|
+
{"version":3,"file":"option-of.d.ts","sourceRoot":"","sources":["../../../src/check/declarations/option-of.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,2CAA2C;AAC3C,MAAM,WAAW,WAAW;IAC1B,6GAA6G;IAC7G,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,yHAAyH;AACzH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAmBjG"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
const MEMBER = /^\s*([A-Za-z_$][\w$]*\.[A-Za-z_$][\w$]*)\s*[,}]/;
|
|
2
1
|
/** The value of `key` in an options object given directly to the decorator, or undefined when no such key is written. */
|
|
3
2
|
export function optionOf(scan, decoration, key) {
|
|
4
3
|
const { code } = scan;
|
|
@@ -11,12 +10,7 @@ export function optionOf(scan, decoration, key) {
|
|
|
11
10
|
const valueStart = match.index + match[0].length;
|
|
12
11
|
const literal = scan.strings.find((candidate) => candidate.start === valueStart);
|
|
13
12
|
const complete = literal !== undefined && /^\s*[,}]/.test(code.slice(literal.end, decoration.close + 1));
|
|
14
|
-
|
|
15
|
-
return {
|
|
16
|
-
literal: complete ? literal.value : undefined,
|
|
17
|
-
line: scan.lineAt(match.index),
|
|
18
|
-
...(reference === undefined ? {} : { reference }),
|
|
19
|
-
};
|
|
13
|
+
return { literal: complete ? literal.value : undefined, line: scan.lineAt(match.index) };
|
|
20
14
|
}
|
|
21
15
|
return undefined;
|
|
22
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"option-of.js","sourceRoot":"","sources":["../../../src/check/declarations/option-of.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"option-of.js","sourceRoot":"","sources":["../../../src/check/declarations/option-of.ts"],"names":[],"mappings":"AAUA,yHAAyH;AACzH,MAAM,UAAU,QAAQ,CAAC,IAAU,EAAE,UAAsB,EAAE,GAAW;IACtE,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC;IACtB,MAAM,OAAO,GAAG,IAAI,MAAM,CAAC,eAAe,GAAG,wBAAwB,EAAE,GAAG,CAAC,CAAC;IAE5E,OAAO,CAAC,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC;IAEpC,KAAK,IAAI,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAClH,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YAClE,SAAS;QACX,CAAC;QAED,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QACjD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC;QACjF,MAAM,QAAQ,GAAG,OAAO,KAAK,SAAS,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;QAEzG,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;IAC3F,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,mGAAmG;AACnG,SAAS,cAAc,CAAC,MAAc;IACpC,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,KAAa,EAAU,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;IAE5G,OAAO,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;AAC3E,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authz-docs.d.ts","sourceRoot":"","sources":["../../../src/check/explain/authz-docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"authz-docs.d.ts","sourceRoot":"","sources":["../../../src/check/explain/authz-docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqExD,CAAC"}
|
|
@@ -27,11 +27,24 @@ await this.access.authorize(command.actor, billingPermissions['invoice.void'], i
|
|
|
27
27
|
// application/authorization/only-issuer-voids.policy.ts
|
|
28
28
|
@Policy(billingPermissions['invoice.void'], { name: 'billing.only-issuer-voids' })
|
|
29
29
|
export class OnlyIssuerVoidsPolicy {}`,
|
|
30
|
+
},
|
|
31
|
+
'authz/policy-asked': {
|
|
32
|
+
why: 'The bus checks the permission of a use case before its handler runs, with the identifier of the element at most: it cannot read the element. A policy is the part of the right that needs the element (only the issuer, not after closing), and it is evaluated only when the handler asks Access once the element is loaded. A handler that forgets to ask leaves the policy declared, tested and never applied, and nothing at run time says so. Judged: for every permission refined by a policy (@Policy or definePolicy in application/authorization/), the handlers in the folder of each command or query that requires it (@Requires, .requires(...) or requires(X, ...)) call authorize, decide or decideOn and name that permission in their code. The TODO(domain) the generator leaves in such a handler, naming the permission, is accepted: `ddd-ts-kit todo` lists it, and until it is done the authorization module refuses the result of the handler at run time (PolicyNotAskedError).',
|
|
33
|
+
bad: `// application/authorization/only-issuer-voids.policy.ts
|
|
34
|
+
@Policy(billingPermissions['invoice.void'], { name: 'billing.only-issuer-voids' })
|
|
35
|
+
export class OnlyIssuerVoidsPolicy {}
|
|
36
|
+
// application/commands/void-invoice/void-invoice.handler.ts
|
|
37
|
+
const invoice = await this.invoices.get(command.invoiceId);
|
|
38
|
+
invoice.void(this.clock.now());`,
|
|
39
|
+
good: `// application/commands/void-invoice/void-invoice.handler.ts
|
|
40
|
+
const invoice = await this.invoices.get(command.invoiceId);
|
|
41
|
+
await this.access.authorize(command.actor, billingPermissions['invoice.void'], invoice);
|
|
42
|
+
invoice.void(this.clock.now());`,
|
|
30
43
|
},
|
|
31
44
|
'authz/actor-explicit': {
|
|
32
45
|
why: 'A handler that reads "the current user" from an ambient context depends on something no signature shows: a consumer or a job that forgot to set it fails at run time, and a test has to set a global. With the actor as data of the command, the use case says who acts, and any caller can send it. The ExecutionScope port (and ActorContext, a view of it) is named and read by infrastructure and the platform alone, as a type or as a value in a dependency list, for audit columns, tenant scoping and correlation: stampCreation, stampUpdate and tenantScopeOf belong in a repository adapter.',
|
|
33
46
|
bad: `// application/commands/void-invoice/void-invoice.handler.ts
|
|
34
|
-
|
|
47
|
+
constructor(private readonly invoices: InvoiceRepository, private readonly scope: ExecutionScope) {}
|
|
35
48
|
const actor = this.actors.require();
|
|
36
49
|
const { tenantId } = this.scope.require();
|
|
37
50
|
const stamp = stampCreation(this.scope, this.clock);`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authz-docs.js","sourceRoot":"","sources":["../../../src/check/explain/authz-docs.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAsC;IAC3D,gBAAgB,EAAE;QAChB,GAAG,EAAE,mvBAAmvB;QACxvB,GAAG,EAAE;;;mEAG0D;QAC/D,IAAI,EAAE;;;;;mEAKyD;KAChE;IACD,sBAAsB,EAAE;QACtB,GAAG,EAAE,q0BAAq0B;QAC10B,GAAG,EAAE;;;;;4DAKmD;QACxD,IAAI,EAAE;;;;;;sCAM4B;KACnC;IACD,sBAAsB,EAAE;QACtB,GAAG,EAAE,ykBAAykB;QAC9kB,GAAG,EAAE;;;;qDAI4C;QACjD,IAAI,EAAE;;;;;2GAKiG;KACxG;IACD,wBAAwB,EAAE;QACxB,GAAG,EAAE,i1BAAi1B;QACt1B,GAAG,EAAE;;+FAEsF;QAC3F,IAAI,EAAE;;;;;IAKN;KACD;CACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"authz-docs.js","sourceRoot":"","sources":["../../../src/check/explain/authz-docs.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAsC;IAC3D,gBAAgB,EAAE;QAChB,GAAG,EAAE,mvBAAmvB;QACxvB,GAAG,EAAE;;;mEAG0D;QAC/D,IAAI,EAAE;;;;;mEAKyD;KAChE;IACD,sBAAsB,EAAE;QACtB,GAAG,EAAE,q0BAAq0B;QAC10B,GAAG,EAAE;;;;;4DAKmD;QACxD,IAAI,EAAE;;;;;;sCAM4B;KACnC;IACD,oBAAoB,EAAE;QACpB,GAAG,EAAE,08BAA08B;QAC/8B,GAAG,EAAE;;;;;gCAKuB;QAC5B,IAAI,EAAE;;;gCAGsB;KAC7B;IACD,sBAAsB,EAAE;QACtB,GAAG,EAAE,ykBAAykB;QAC9kB,GAAG,EAAE;;;;qDAI4C;QACjD,IAAI,EAAE;;;;;2GAKiG;KACxG;IACD,wBAAwB,EAAE;QACxB,GAAG,EAAE,i1BAAi1B;QACt1B,GAAG,EAAE;;+FAEsF;QAC3F,IAAI,EAAE;;;;;IAKN;KACD;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events-docs.d.ts","sourceRoot":"","sources":["../../../src/check/explain/events-docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"events-docs.d.ts","sourceRoot":"","sources":["../../../src/check/explain/events-docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA6FzD,CAAC"}
|
|
@@ -29,23 +29,27 @@ eventPublisher: new OutboxPublisher(persistence.outbox),`,
|
|
|
29
29
|
bad: `// billing.module.ts
|
|
30
30
|
subscriber.subscribe('catalog.product.listed', (event) => productListedHandler.handle(event));
|
|
31
31
|
// application/integration/handlers/product-listed.integration-handler.ts
|
|
32
|
-
@IntegrationEventHandler(productListedV1, { consumer: CONSUMER_NAME }
|
|
32
|
+
@IntegrationEventHandler(productListedV1, { consumer: CONSUMER_NAME })`,
|
|
33
33
|
good: `// billing.module.ts
|
|
34
34
|
builder.on(productListedV1, { consumer: 'billing.product-listed' }).handledBy(ProductListedHandler, [CommandBus]);
|
|
35
35
|
// or, wired by hand
|
|
36
36
|
consume(productListedV1, { consumer: 'billing.product-listed', processed, unitOfWork }, (event) => productListedHandler.handle(event));
|
|
37
37
|
// or declared on the class
|
|
38
|
-
@IntegrationEventHandler(productListedV1, { consumer: 'billing.product-listed' }
|
|
39
|
-
export class ProductListedHandler {
|
|
38
|
+
@IntegrationEventHandler(productListedV1, { consumer: 'billing.product-listed' })
|
|
39
|
+
export class ProductListedHandler {
|
|
40
|
+
constructor(private readonly commands: CommandBus) {}
|
|
41
|
+
}`,
|
|
40
42
|
},
|
|
41
43
|
'domain-events/dispatched-on-save': {
|
|
42
44
|
why: 'Domain events leave with the save. Once a repository method that was handed an aggregate resolves, the events the aggregate recorded are dispatched in order, inside the unit of work of the command, so their handlers and the outbox commit or roll back with the state. A handler that pulls the events and dispatches them itself announces them twice or outside the transaction, and a repository adapter that dispatches mixes persistence with wiring. Reported: a call to pullEvents() in application/ or infrastructure/ of a context, and DomainEventDispatcher imported, listed as a dependency or received by a constructor in application/commands, application/queries and a repository adapter. The module file, the tests, the platform and main.ts are left alone.',
|
|
43
45
|
bad: `// application/commands/issue-invoice/issue-invoice.handler.ts
|
|
44
|
-
@CommandHandler(IssueInvoiceCommand
|
|
46
|
+
@CommandHandler(IssueInvoiceCommand)
|
|
47
|
+
constructor(private readonly invoices: InvoiceRepository, private readonly dispatcher: DomainEventDispatcher) {}
|
|
45
48
|
await this.invoices.save(invoice);
|
|
46
49
|
await this.dispatcher.dispatch(invoice.pullEvents());`,
|
|
47
50
|
good: `// application/commands/issue-invoice/issue-invoice.handler.ts
|
|
48
|
-
@CommandHandler(IssueInvoiceCommand
|
|
51
|
+
@CommandHandler(IssueInvoiceCommand)
|
|
52
|
+
constructor(private readonly invoices: InvoiceRepository) {}
|
|
49
53
|
await this.invoices.save(invoice);
|
|
50
54
|
// a removal that announces an event takes the aggregate
|
|
51
55
|
await this.invoices.remove(invoice);`,
|
|
@@ -54,13 +58,24 @@ await this.invoices.remove(invoice);`,
|
|
|
54
58
|
why: "An effect of a domain event exists only if the state change that recorded the event is committed. A handler that runs before the commit runs inside the transaction, and the commit can still fail after it ran (a deferred constraint, a serialization failure, a lost connection): that is safe only when the rollback undoes everything the handler did, so a before-commit handler has transactional effects only. Judged: every production class of application/event-handlers/*.event-handler.ts and application/integration/publishers/*.publisher.ts, and any class carrying @DomainEventHandler. Its phase is after-commit when its decorator says phase: 'after-commit', or, without a decorator, when every .on(..) of <context>.module.ts whose callback mentions it has a third argument holding phase: 'after-commit'; otherwise it is before-commit. Its dependencies are the names of its dependency list, of .toClass(Handler, [..]) and the types of its constructor parameters, resolved through the imports. Before the commit it may depend on the domain/ of its context, on the kernel ports except Cache, CachePurger, Lock, RateLimiter, JobScheduler and EventBus (CacheInvalidation is allowed: the purge it asks for commits with the work), on @ddd-ts-kit/auth, on application helpers of its context, and on a port of application/ports/ only when it is a persistence port: at least one production class implements it under infrastructure/persistence/ and none anywhere else under infrastructure/. Refused: those five kernel ports, any other port of application/ports/, anything of infrastructure/, of another context, of the platform or of another package. An after-commit handler is refused IntegrationEventPublisher alone: after the commit nothing makes the outbox row atomic with a state change, so it sends a command instead.",
|
|
55
59
|
bad: `// application/event-handlers/invoice-issued.event-handler.ts
|
|
56
60
|
// Mailer is implemented under infrastructure/external/: the mail leaves even when the commit fails
|
|
57
|
-
@DomainEventHandler(InvoiceIssued
|
|
61
|
+
@DomainEventHandler(InvoiceIssued)
|
|
62
|
+
constructor(
|
|
63
|
+
private readonly invoiceRepository: InvoiceRepository,
|
|
64
|
+
private readonly mailer: Mailer,
|
|
65
|
+
private readonly cache: Cache,
|
|
66
|
+
) {}
|
|
58
67
|
// after the commit the outbox row would be written in no transaction
|
|
59
|
-
@DomainEventHandler(InvoiceIssued, {
|
|
68
|
+
@DomainEventHandler(InvoiceIssued, { phase: 'after-commit' })
|
|
69
|
+
constructor(private readonly integrationEventPublisher: IntegrationEventPublisher) {}`,
|
|
60
70
|
good: `// application/event-handlers/invoice-issued.event-handler.ts: repositories, persistence ports, buses
|
|
61
|
-
@DomainEventHandler(InvoiceIssued
|
|
71
|
+
@DomainEventHandler(InvoiceIssued)
|
|
72
|
+
constructor(
|
|
73
|
+
private readonly invoiceRepository: InvoiceRepository,
|
|
74
|
+
private readonly commandBus: CommandBus,
|
|
75
|
+
) {}
|
|
62
76
|
// an effect that may be lost on a crash runs after the commit, at most once
|
|
63
|
-
@DomainEventHandler(InvoiceIssued, {
|
|
77
|
+
@DomainEventHandler(InvoiceIssued, { phase: 'after-commit' })
|
|
78
|
+
constructor(private readonly cache: Cache) {}
|
|
64
79
|
// explicit style, in billing.module.ts
|
|
65
80
|
platform.domainEvents.on('billing.invoice.issued', async (event) => {
|
|
66
81
|
if (event instanceof InvoiceIssued) {
|
|
@@ -68,8 +83,13 @@ platform.domainEvents.on('billing.invoice.issued', async (event) => {
|
|
|
68
83
|
}
|
|
69
84
|
}, { phase: 'after-commit' });
|
|
70
85
|
// an effect that must not be lost: a publisher writes to the outbox, the handler of that event does the work
|
|
71
|
-
@DomainEventHandler(InvoiceIssued
|
|
72
|
-
export class InvoiceIssuedPublisher {
|
|
86
|
+
@DomainEventHandler(InvoiceIssued)
|
|
87
|
+
export class InvoiceIssuedPublisher {
|
|
88
|
+
constructor(
|
|
89
|
+
private readonly integrationEventPublisher: IntegrationEventPublisher,
|
|
90
|
+
private readonly idGenerator: IdGenerator,
|
|
91
|
+
) {}
|
|
92
|
+
}`,
|
|
73
93
|
},
|
|
74
94
|
};
|
|
75
95
|
//# sourceMappingURL=events-docs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events-docs.js","sourceRoot":"","sources":["../../../src/check/explain/events-docs.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAsC;IAC5D,oBAAoB,EAAE;QACpB,GAAG,EAAE,2LAA2L;QAChM,GAAG,EAAE,kCAAkC;QACvC,IAAI,EAAE,2CAA2C;KAClD;IACD,sCAAsC,EAAE;QACtC,GAAG,EAAE,2UAA2U;QAChV,GAAG,EAAE;uEAC8D;QACnE,IAAI,EAAE;;;IAGN;KACD;IACD,wBAAwB,EAAE;QACxB,GAAG,EAAE,wVAAwV;QAC7V,GAAG,EAAE;;;qDAG4C;QACjD,IAAI,EAAE;;;yDAG+C;KACtD;IACD,4BAA4B,EAAE;QAC5B,GAAG,EAAE,mlBAAmlB;QACxlB,GAAG,EAAE;;;
|
|
1
|
+
{"version":3,"file":"events-docs.js","sourceRoot":"","sources":["../../../src/check/explain/events-docs.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAsC;IAC5D,oBAAoB,EAAE;QACpB,GAAG,EAAE,2LAA2L;QAChM,GAAG,EAAE,kCAAkC;QACvC,IAAI,EAAE,2CAA2C;KAClD;IACD,sCAAsC,EAAE;QACtC,GAAG,EAAE,2UAA2U;QAChV,GAAG,EAAE;uEAC8D;QACnE,IAAI,EAAE;;;IAGN;KACD;IACD,wBAAwB,EAAE;QACxB,GAAG,EAAE,wVAAwV;QAC7V,GAAG,EAAE;;;qDAG4C;QACjD,IAAI,EAAE;;;yDAG+C;KACtD;IACD,4BAA4B,EAAE;QAC5B,GAAG,EAAE,mlBAAmlB;QACxlB,GAAG,EAAE;;;uEAG8D;QACnE,IAAI,EAAE;;;;;;;;EAQR;KACC;IACD,kCAAkC,EAAE;QAClC,GAAG,EAAE,svBAAsvB;QAC3vB,GAAG,EAAE;;;;sDAI6C;QAClD,IAAI,EAAE;;;;;qCAK2B;KAClC;IACD,2CAA2C,EAAE;QAC3C,GAAG,EAAE,uxDAAuxD;QAC5xD,GAAG,EAAE;;;;;;;;;;sFAU6E;QAClF,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;EAsBR;KACC;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ports-docs.d.ts","sourceRoot":"","sources":["../../../src/check/explain/ports-docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"ports-docs.d.ts","sourceRoot":"","sources":["../../../src/check/explain/ports-docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA4ExD,CAAC"}
|
|
@@ -17,12 +17,12 @@ export abstract class InvoiceRepository extends Repository<Invoice> {}`,
|
|
|
17
17
|
'ports/implements-never-extends': {
|
|
18
18
|
why: 'An adapter says which contract it honours with `implements`, and the compiler holds it to that contract. Extending the port instead would inherit from a class that holds nothing, make the adapter a second port for the container, and is refused when the binding is registered. The rule reads the class behind @Repository, @Gateway and @Adapter, the class given to bind(P).toClass(C) or rebind(P).toClass(C), and every class of infrastructure/ that extends a class of a port file. A class bound to itself is no port and is left alone.',
|
|
19
19
|
bad: `// infrastructure/persistence/knex-invoice.repository.ts
|
|
20
|
-
@Repository(InvoiceRepository
|
|
20
|
+
@Repository(InvoiceRepository)
|
|
21
21
|
export class KnexInvoiceRepository extends InvoiceRepository {}
|
|
22
22
|
// billing.module.ts
|
|
23
23
|
builder.bind(PaymentGateway).toClass(StripePaymentGateway, [PaymentSettings]); // class StripePaymentGateway {}`,
|
|
24
24
|
good: `// infrastructure/persistence/knex-invoice.repository.ts
|
|
25
|
-
@Repository(InvoiceRepository
|
|
25
|
+
@Repository(InvoiceRepository)
|
|
26
26
|
export class KnexInvoiceRepository implements InvoiceRepository {}
|
|
27
27
|
// infrastructure/external/stripe-payment.gateway.ts
|
|
28
28
|
export class StripePaymentGateway implements PaymentGateway {}`,
|
|
@@ -31,15 +31,15 @@ export class StripePaymentGateway implements PaymentGateway {}`,
|
|
|
31
31
|
why: 'The abstract class of a port is its injection token: it names the dependency, carries its type and lets the compiler check a dependency list against a constructor. A constant beside it (a token() call, a Symbol, a string, an UPPER_SNAKE_CASE name in a list) is a second name for the same thing that nothing ties to the type, and a file of tokens is one more place to keep in step with the ports. There is one way to name a dependency: the class.',
|
|
32
32
|
bad: `// application/ports/billing.ports.ts
|
|
33
33
|
export const INVOICE_REPOSITORY = token<InvoiceRepository>('billing.InvoiceRepository');
|
|
34
|
-
//
|
|
35
|
-
|
|
36
|
-
// billing.module.ts
|
|
34
|
+
// billing.module.ts, explicit style
|
|
35
|
+
builder.command(IssueInvoiceCommand).handledBy(IssueInvoiceHandler, [INVOICE_REPOSITORY, CLOCK]);
|
|
37
36
|
builder.bind(Symbol.for('billing.PaymentGateway')).toClass(StripePaymentGateway, []);`,
|
|
38
37
|
good: `// domain/repositories/invoice.repository.ts
|
|
39
38
|
export abstract class InvoiceRepository extends Repository<Invoice> {}
|
|
40
39
|
// application/commands/issue-invoice/issue-invoice.handler.ts
|
|
41
|
-
@CommandHandler(IssueInvoiceCommand
|
|
42
|
-
|
|
40
|
+
@CommandHandler(IssueInvoiceCommand)
|
|
41
|
+
constructor(private readonly invoices: InvoiceRepository, private readonly clock: Clock) {}
|
|
42
|
+
// billing.module.ts, explicit style
|
|
43
43
|
builder.bind(PaymentGateway).toClass(StripePaymentGateway, [PaymentSettings]);`,
|
|
44
44
|
},
|
|
45
45
|
'ports/no-concrete-dependency': {
|
|
@@ -66,11 +66,13 @@ export class IssueInvoiceHandler {
|
|
|
66
66
|
bad: `import type { InvoiceRepository } from '@/contexts/billing/domain/repositories/invoice.repository';
|
|
67
67
|
import { type Clock } from '@ddd-ts-kit/kernel';
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
// billing.module.ts, explicit style
|
|
70
|
+
builder.command(IssueInvoiceCommand).handledBy(IssueInvoiceHandler, [InvoiceRepository, Clock]);`,
|
|
70
71
|
good: `import { Clock } from '@ddd-ts-kit/kernel';
|
|
71
72
|
import { InvoiceRepository } from '@/contexts/billing/domain/repositories/invoice.repository';
|
|
72
73
|
|
|
73
|
-
|
|
74
|
+
// billing.module.ts, explicit style
|
|
75
|
+
builder.command(IssueInvoiceCommand).handledBy(IssueInvoiceHandler, [InvoiceRepository, Clock]);`,
|
|
74
76
|
},
|
|
75
77
|
};
|
|
76
78
|
//# sourceMappingURL=ports-docs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ports-docs.js","sourceRoot":"","sources":["../../../src/check/explain/ports-docs.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAsC;IAC3D,sBAAsB,EAAE;QACtB,GAAG,EAAE,kmBAAkmB;QACvmB,GAAG,EAAE;;;;;EAKP;QACE,IAAI,EAAE;;;;;uEAK6D;KACpE;IACD,gCAAgC,EAAE;QAChC,GAAG,EAAE,shBAAshB;QAC3hB,GAAG,EAAE;;;;kHAIyG;QAC9G,IAAI,EAAE;;;;+DAIqD;KAC5D;IACD,yBAAyB,EAAE;QACzB,GAAG,EAAE,+bAA+b;QACpc,GAAG,EAAE
|
|
1
|
+
{"version":3,"file":"ports-docs.js","sourceRoot":"","sources":["../../../src/check/explain/ports-docs.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,UAAU,GAAsC;IAC3D,sBAAsB,EAAE;QACtB,GAAG,EAAE,kmBAAkmB;QACvmB,GAAG,EAAE;;;;;EAKP;QACE,IAAI,EAAE;;;;;uEAK6D;KACpE;IACD,gCAAgC,EAAE;QAChC,GAAG,EAAE,shBAAshB;QAC3hB,GAAG,EAAE;;;;kHAIyG;QAC9G,IAAI,EAAE;;;;+DAIqD;KAC5D;IACD,yBAAyB,EAAE;QACzB,GAAG,EAAE,+bAA+b;QACpc,GAAG,EAAE;;;;sFAI6E;QAClF,IAAI,EAAE;;;;;;+EAMqE;KAC5E;IACD,8BAA8B,EAAE;QAC9B,GAAG,EAAE,omBAAomB;QACzmB,GAAG,EAAE;;;;;;;;qGAQ4F;QACjG,IAAI,EAAE;;;;;;EAMR;KACC;IACD,oBAAoB,EAAE;QACpB,GAAG,EAAE,4WAA4W;QACjX,GAAG,EAAE;;;;iGAIwF;QAC7F,IAAI,EAAE;;;;iGAIuF;KAC9F;CACF,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduling-docs.d.ts","sourceRoot":"","sources":["../../../src/check/explain/scheduling-docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"scheduling-docs.d.ts","sourceRoot":"","sources":["../../../src/check/explain/scheduling-docs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwC7D,CAAC"}
|
|
@@ -4,8 +4,13 @@ export const SCHEDULING_DOCS = {
|
|
|
4
4
|
bad: `// application/scheduling/send-reminders.job.ts
|
|
5
5
|
import { Invoice } from '@/contexts/billing/domain/aggregates/invoice.aggregate';
|
|
6
6
|
|
|
7
|
-
@Scheduled('billing.send-reminders', { every: '15m' }
|
|
7
|
+
@Scheduled('billing.send-reminders', { every: '15m' })
|
|
8
8
|
export class SendRemindersJob {
|
|
9
|
+
constructor(
|
|
10
|
+
private readonly invoices: InvoiceRepository,
|
|
11
|
+
private readonly mailer: Mailer,
|
|
12
|
+
) {}
|
|
13
|
+
|
|
9
14
|
async run(): Promise<void> {
|
|
10
15
|
for (const invoice of await this.invoices.findOverdue()) {
|
|
11
16
|
await this.mailer.remind(invoice);
|
|
@@ -13,7 +18,7 @@ export class SendRemindersJob {
|
|
|
13
18
|
}
|
|
14
19
|
}`,
|
|
15
20
|
good: `// application/scheduling/send-reminders.job.ts
|
|
16
|
-
@Scheduled('billing.send-reminders', { every: '15m' }
|
|
21
|
+
@Scheduled('billing.send-reminders', { every: '15m' })
|
|
17
22
|
export class SendRemindersJob implements ScheduledJob {
|
|
18
23
|
constructor(private readonly commands: CommandBus) {}
|
|
19
24
|
|
|
@@ -24,12 +29,12 @@ export class SendRemindersJob implements ScheduledJob {
|
|
|
24
29
|
},
|
|
25
30
|
'scheduling/job-name': {
|
|
26
31
|
why: 'The name of a job is its identity everywhere a run leaves a trace: the scheduler and its lock, the settings that enable or reschedule it, the logs, the metrics and the audit trail, where the job is the system actor of the command it sends. It is written once as a string literal, `<context>.<job-name>` in lower-case kebab-case, so that it survives the renaming of a class and tells which context owns the job. Two jobs under one name share a lock and overwrite each other, so a name is unique in the project.',
|
|
27
|
-
bad: `@Scheduled(JOB_NAME, { every: '15m' }
|
|
28
|
-
@Scheduled('SendReminders', { every: '15m' }
|
|
32
|
+
bad: `@Scheduled(JOB_NAME, { every: '15m' })
|
|
33
|
+
@Scheduled('SendReminders', { every: '15m' })
|
|
29
34
|
// in contexts/billing
|
|
30
35
|
builder.job('shipping.send-reminders', { every: '15m' }).handledBy(SendRemindersJob, [CommandBus]);
|
|
31
36
|
new SendRemindersCommand(systemActor('billing.reminders'), execution.scheduledAt);`,
|
|
32
|
-
good: `@Scheduled('billing.send-reminders', { every: '15m' }
|
|
37
|
+
good: `@Scheduled('billing.send-reminders', { every: '15m' })
|
|
33
38
|
builder.job('billing.send-reminders', { every: '15m' }).handledBy(SendRemindersJob, [CommandBus]);
|
|
34
39
|
new SendRemindersCommand(systemActor('billing.send-reminders'), execution.scheduledAt);`,
|
|
35
40
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scheduling-docs.js","sourceRoot":"","sources":["../../../src/check/explain/scheduling-docs.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAsC;IAChE,kCAAkC,EAAE;QAClC,GAAG,EAAE,2dAA2d;QAChe,GAAG,EAAE
|
|
1
|
+
{"version":3,"file":"scheduling-docs.js","sourceRoot":"","sources":["../../../src/check/explain/scheduling-docs.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAsC;IAChE,kCAAkC,EAAE;QAClC,GAAG,EAAE,2dAA2d;QAChe,GAAG,EAAE;;;;;;;;;;;;;;;EAeP;QACE,IAAI,EAAE;;;;;;;;EAQR;KACC;IACD,qBAAqB,EAAE;QACrB,GAAG,EAAE,+fAA+f;QACpgB,GAAG,EAAE;;;;mFAI0E;QAC/E,IAAI,EAAE;;wFAE8E;KACrF;CACF,CAAC"}
|