ddd-ts-kit 0.2.0 → 0.3.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.
Files changed (232) hide show
  1. package/README.md +55 -2
  2. package/dist/check/catalogue/architecture-rules.d.ts.map +1 -1
  3. package/dist/check/catalogue/architecture-rules.js +4 -0
  4. package/dist/check/catalogue/architecture-rules.js.map +1 -1
  5. package/dist/check/catalogue/eslint-only-rules.d.ts.map +1 -1
  6. package/dist/check/catalogue/eslint-only-rules.js +12 -0
  7. package/dist/check/catalogue/eslint-only-rules.js.map +1 -1
  8. package/dist/check/errors/builds-through-factories.d.ts +4 -0
  9. package/dist/check/errors/builds-through-factories.d.ts.map +1 -0
  10. package/dist/check/errors/builds-through-factories.js +5 -0
  11. package/dist/check/errors/builds-through-factories.js.map +1 -0
  12. package/dist/check/errors/error-code.d.ts +6 -0
  13. package/dist/check/errors/error-code.d.ts.map +1 -0
  14. package/dist/check/errors/error-code.js +2 -0
  15. package/dist/check/errors/error-code.js.map +1 -0
  16. package/dist/check/errors/error-codes.d.ts +8 -0
  17. package/dist/check/errors/error-codes.d.ts.map +1 -0
  18. package/dist/check/errors/error-codes.js +21 -0
  19. package/dist/check/errors/error-codes.js.map +1 -0
  20. package/dist/check/errors/kit-error-codes.d.ts +3 -0
  21. package/dist/check/errors/kit-error-codes.d.ts.map +1 -0
  22. package/dist/check/errors/kit-error-codes.js +17 -0
  23. package/dist/check/errors/kit-error-codes.js.map +1 -0
  24. package/dist/check/explain/errors-docs.d.ts +3 -0
  25. package/dist/check/explain/errors-docs.d.ts.map +1 -0
  26. package/dist/check/explain/errors-docs.js +30 -0
  27. package/dist/check/explain/errors-docs.js.map +1 -0
  28. package/dist/check/explain/rule-docs.d.ts.map +1 -1
  29. package/dist/check/explain/rule-docs.js +2 -0
  30. package/dist/check/explain/rule-docs.js.map +1 -1
  31. package/dist/check/fixtures/errors-fixtures.d.ts +3 -0
  32. package/dist/check/fixtures/errors-fixtures.d.ts.map +1 -0
  33. package/dist/check/fixtures/errors-fixtures.js +126 -0
  34. package/dist/check/fixtures/errors-fixtures.js.map +1 -0
  35. package/dist/check/fixtures/fixtures.d.ts.map +1 -1
  36. package/dist/check/fixtures/fixtures.js +2 -0
  37. package/dist/check/fixtures/fixtures.js.map +1 -1
  38. package/dist/check/rules/errors-code-unique.d.ts +3 -0
  39. package/dist/check/rules/errors-code-unique.d.ts.map +1 -0
  40. package/dist/check/rules/errors-code-unique.js +34 -0
  41. package/dist/check/rules/errors-code-unique.js.map +1 -0
  42. package/dist/check/rules/errors-known-code.d.ts +3 -0
  43. package/dist/check/rules/errors-known-code.d.ts.map +1 -0
  44. package/dist/check/rules/errors-known-code.js +51 -0
  45. package/dist/check/rules/errors-known-code.js.map +1 -0
  46. package/dist/check/rules/language-glossary-term.d.ts.map +1 -1
  47. package/dist/check/rules/language-glossary-term.js +7 -5
  48. package/dist/check/rules/language-glossary-term.js.map +1 -1
  49. package/dist/commands/error-factories.d.ts +7 -0
  50. package/dist/commands/error-factories.d.ts.map +1 -0
  51. package/dist/commands/error-factories.js +65 -0
  52. package/dist/commands/error-factories.js.map +1 -0
  53. package/dist/commands/init.d.ts.map +1 -1
  54. package/dist/commands/init.js +1 -0
  55. package/dist/commands/init.js.map +1 -1
  56. package/dist/config/index.d.ts +1 -1
  57. package/dist/config/index.d.ts.map +1 -1
  58. package/dist/config/index.js +1 -1
  59. package/dist/config/index.js.map +1 -1
  60. package/dist/config/parse-stack.d.ts.map +1 -1
  61. package/dist/config/parse-stack.js +2 -1
  62. package/dist/config/parse-stack.js.map +1 -1
  63. package/dist/config/stack.d.ts +9 -0
  64. package/dist/config/stack.d.ts.map +1 -1
  65. package/dist/config/stack.js +1 -0
  66. package/dist/config/stack.js.map +1 -1
  67. package/dist/describe/context-description.d.ts +12 -0
  68. package/dist/describe/context-description.d.ts.map +1 -1
  69. package/dist/describe/describe-context.d.ts.map +1 -1
  70. package/dist/describe/describe-context.js +2 -0
  71. package/dist/describe/describe-context.js.map +1 -1
  72. package/dist/describe/format-description.d.ts.map +1 -1
  73. package/dist/describe/format-description.js +5 -0
  74. package/dist/describe/format-description.js.map +1 -1
  75. package/dist/describe/read-errors.d.ts +8 -0
  76. package/dist/describe/read-errors.d.ts.map +1 -0
  77. package/dist/describe/read-errors.js +52 -0
  78. package/dist/describe/read-errors.js.map +1 -0
  79. package/dist/describe/reference-lines.js +14 -1
  80. package/dist/describe/reference-lines.js.map +1 -1
  81. package/dist/generate/errors/add-factory.d.ts +13 -0
  82. package/dist/generate/errors/add-factory.d.ts.map +1 -0
  83. package/dist/generate/errors/add-factory.js +30 -0
  84. package/dist/generate/errors/add-factory.js.map +1 -0
  85. package/dist/generate/errors/add-spec-case.d.ts +6 -0
  86. package/dist/generate/errors/add-spec-case.d.ts.map +1 -0
  87. package/dist/generate/errors/add-spec-case.js +26 -0
  88. package/dist/generate/errors/add-spec-case.js.map +1 -0
  89. package/dist/generate/errors/class-body.d.ts +8 -0
  90. package/dist/generate/errors/class-body.d.ts.map +1 -0
  91. package/dist/generate/errors/class-body.js +11 -0
  92. package/dist/generate/errors/class-body.js.map +1 -0
  93. package/dist/generate/errors/codes-of-context.d.ts +4 -0
  94. package/dist/generate/errors/codes-of-context.d.ts.map +1 -0
  95. package/dist/generate/errors/codes-of-context.js +17 -0
  96. package/dist/generate/errors/codes-of-context.js.map +1 -0
  97. package/dist/generate/errors/refusal-code.d.ts +13 -0
  98. package/dist/generate/errors/refusal-code.d.ts.map +1 -0
  99. package/dist/generate/errors/refusal-code.js +19 -0
  100. package/dist/generate/errors/refusal-code.js.map +1 -0
  101. package/dist/generate/errors/refusal-name.d.ts +4 -0
  102. package/dist/generate/errors/refusal-name.d.ts.map +1 -0
  103. package/dist/generate/errors/refusal-name.js +15 -0
  104. package/dist/generate/errors/refusal-name.js.map +1 -0
  105. package/dist/generate/errors/static-methods.d.ts +10 -0
  106. package/dist/generate/errors/static-methods.d.ts.map +1 -0
  107. package/dist/generate/errors/static-methods.js +13 -0
  108. package/dist/generate/errors/static-methods.js.map +1 -0
  109. package/dist/generate/errors/vague-refusal-names.d.ts +3 -0
  110. package/dist/generate/errors/vague-refusal-names.d.ts.map +1 -0
  111. package/dist/generate/errors/vague-refusal-names.js +15 -0
  112. package/dist/generate/errors/vague-refusal-names.js.map +1 -0
  113. package/dist/generate/kinds/domain-error-kind.d.ts.map +1 -1
  114. package/dist/generate/kinds/domain-error-kind.js +4 -1
  115. package/dist/generate/kinds/domain-error-kind.js.map +1 -1
  116. package/dist/generate/kinds/error-kind.d.ts +3 -0
  117. package/dist/generate/kinds/error-kind.d.ts.map +1 -0
  118. package/dist/generate/kinds/error-kind.js +75 -0
  119. package/dist/generate/kinds/error-kind.js.map +1 -0
  120. package/dist/generate/kinds.d.ts.map +1 -1
  121. package/dist/generate/kinds.js +2 -0
  122. package/dist/generate/kinds.js.map +1 -1
  123. package/dist/init/manifest/versions.js +23 -23
  124. package/dist/init/stack/resolve-stack.d.ts.map +1 -1
  125. package/dist/init/stack/resolve-stack.js +3 -1
  126. package/dist/init/stack/resolve-stack.js.map +1 -1
  127. package/dist/init/stack/stack-options.d.ts +1 -0
  128. package/dist/init/stack/stack-options.d.ts.map +1 -1
  129. package/dist/refusals/apply-plan.d.ts +17 -0
  130. package/dist/refusals/apply-plan.d.ts.map +1 -0
  131. package/dist/refusals/apply-plan.js +118 -0
  132. package/dist/refusals/apply-plan.js.map +1 -0
  133. package/dist/refusals/factory-name-for.d.ts +7 -0
  134. package/dist/refusals/factory-name-for.d.ts.map +1 -0
  135. package/dist/refusals/factory-name-for.js +16 -0
  136. package/dist/refusals/factory-name-for.js.map +1 -0
  137. package/dist/refusals/legacy-error.d.ts +21 -0
  138. package/dist/refusals/legacy-error.d.ts.map +1 -0
  139. package/dist/refusals/legacy-error.js +2 -0
  140. package/dist/refusals/legacy-error.js.map +1 -0
  141. package/dist/refusals/legacy-errors.d.ts +6 -0
  142. package/dist/refusals/legacy-errors.d.ts.map +1 -0
  143. package/dist/refusals/legacy-errors.js +16 -0
  144. package/dist/refusals/legacy-errors.js.map +1 -0
  145. package/dist/refusals/migration-draft.d.ts +15 -0
  146. package/dist/refusals/migration-draft.d.ts.map +1 -0
  147. package/dist/refusals/migration-draft.js +41 -0
  148. package/dist/refusals/migration-draft.js.map +1 -0
  149. package/dist/refusals/migration-plan.d.ts +6 -0
  150. package/dist/refusals/migration-plan.d.ts.map +1 -0
  151. package/dist/refusals/migration-plan.js +2 -0
  152. package/dist/refusals/migration-plan.js.map +1 -0
  153. package/dist/refusals/move.d.ts +15 -0
  154. package/dist/refusals/move.d.ts.map +1 -0
  155. package/dist/refusals/move.js +2 -0
  156. package/dist/refusals/move.js.map +1 -0
  157. package/dist/refusals/nested-cases.d.ts +3 -0
  158. package/dist/refusals/nested-cases.d.ts.map +1 -0
  159. package/dist/refusals/nested-cases.js +9 -0
  160. package/dist/refusals/nested-cases.js.map +1 -0
  161. package/dist/refusals/plan-file.d.ts +3 -0
  162. package/dist/refusals/plan-file.d.ts.map +1 -0
  163. package/dist/refusals/plan-file.js +3 -0
  164. package/dist/refusals/plan-file.js.map +1 -0
  165. package/dist/refusals/planned-factory.d.ts +11 -0
  166. package/dist/refusals/planned-factory.d.ts.map +1 -0
  167. package/dist/refusals/planned-factory.js +2 -0
  168. package/dist/refusals/planned-factory.js.map +1 -0
  169. package/dist/refusals/planned-move.d.ts +8 -0
  170. package/dist/refusals/planned-move.d.ts.map +1 -0
  171. package/dist/refusals/planned-move.js +2 -0
  172. package/dist/refusals/planned-move.js.map +1 -0
  173. package/dist/refusals/project-sources.d.ts +5 -0
  174. package/dist/refusals/project-sources.d.ts.map +1 -0
  175. package/dist/refusals/project-sources.js +13 -0
  176. package/dist/refusals/project-sources.js.map +1 -0
  177. package/dist/refusals/propose-plan.d.ts +16 -0
  178. package/dist/refusals/propose-plan.d.ts.map +1 -0
  179. package/dist/refusals/propose-plan.js +39 -0
  180. package/dist/refusals/propose-plan.js.map +1 -0
  181. package/dist/refusals/read-legacy-error.d.ts +9 -0
  182. package/dist/refusals/read-legacy-error.d.ts.map +1 -0
  183. package/dist/refusals/read-legacy-error.js +75 -0
  184. package/dist/refusals/read-legacy-error.js.map +1 -0
  185. package/dist/refusals/read-plan.d.ts +4 -0
  186. package/dist/refusals/read-plan.d.ts.map +1 -0
  187. package/dist/refusals/read-plan.js +43 -0
  188. package/dist/refusals/read-plan.js.map +1 -0
  189. package/dist/refusals/render-factory.d.ts +5 -0
  190. package/dist/refusals/render-factory.d.ts.map +1 -0
  191. package/dist/refusals/render-factory.js +14 -0
  192. package/dist/refusals/render-factory.js.map +1 -0
  193. package/dist/refusals/replace-in-code.d.ts +16 -0
  194. package/dist/refusals/replace-in-code.d.ts.map +1 -0
  195. package/dist/refusals/replace-in-code.js +20 -0
  196. package/dist/refusals/replace-in-code.js.map +1 -0
  197. package/dist/refusals/rewrite-usages.d.ts +6 -0
  198. package/dist/refusals/rewrite-usages.d.ts.map +1 -0
  199. package/dist/refusals/rewrite-usages.js +80 -0
  200. package/dist/refusals/rewrite-usages.js.map +1 -0
  201. package/dist/refusals/spec-parts.d.ts +8 -0
  202. package/dist/refusals/spec-parts.d.ts.map +1 -0
  203. package/dist/refusals/spec-parts.js +14 -0
  204. package/dist/refusals/spec-parts.js.map +1 -0
  205. package/dist/run.d.ts.map +1 -1
  206. package/dist/run.js +7 -1
  207. package/dist/run.js.map +1 -1
  208. package/dist/stack/stack-vars.d.ts.map +1 -1
  209. package/dist/stack/stack-vars.js +2 -1
  210. package/dist/stack/stack-vars.js.map +1 -1
  211. package/dist/version.d.ts +1 -1
  212. package/dist/version.js +1 -1
  213. package/package.json +2 -2
  214. package/templates/aggregate/aggregate.ts.tpl +5 -0
  215. package/templates/command/handler.declared.ts.tpl +5 -0
  216. package/templates/command/handler.ts.tpl +5 -0
  217. package/templates/docs/openapi.json.tpl +5 -0
  218. package/templates/entity/entity.ts.tpl +5 -0
  219. package/templates/error/case.spec.ts.tpl +8 -0
  220. package/templates/error/concept-error.spec.ts.tpl +7 -0
  221. package/templates/error/concept-error.ts.tpl +5 -0
  222. package/templates/error/factory.ts.tpl +4 -0
  223. package/templates/init/jest.config.js.tpl +7 -0
  224. package/templates/init/rules/domain.md.tpl +11 -0
  225. package/templates/init/rules/presentation.md.tpl +5 -0
  226. package/templates/pipeline/package-scripts.json +1 -1
  227. package/templates/route/route.class-validator.ts.tpl +1 -1
  228. package/templates/route/route.none.ts.tpl +1 -1
  229. package/templates/route/route.search.ts.tpl +1 -1
  230. package/templates/route/route.standard-schema.ts.tpl +1 -1
  231. package/templates/route/route.zod.ts.tpl +1 -1
  232. package/templates/value-object/value-object.ts.tpl +5 -0
@@ -328,6 +328,11 @@
328
328
  }
329
329
  }
330
330
  },
331
+ "facts": {
332
+ "type": "object",
333
+ "description": "The facts of the refusal its code exposes, by name. Absent when it exposes none.",
334
+ "additionalProperties": true
335
+ },
331
336
  "requestId": {
332
337
  "type": "string"
333
338
  }
@@ -13,7 +13,12 @@ export class {{name.pascal}} extends Entity<string> {
13
13
  }
14
14
 
15
15
  static create(id: string, state: {{name.pascal}}State): {{name.pascal}} {
16
+ {{#if refusals.factories}}
17
+ // TODO(domain): check the invariants {{name.pascal}} guards on its own and throw a refusal of the error class of its aggregate when one is violated (`ddd-ts-kit generate error {{context.kebab}} <Concept> <refusal>`); invariants spanning several entities belong to the aggregate root.
18
+ {{/if}}
19
+ {{#if refusals.classes}}
16
20
  // TODO(domain): check the invariants {{name.pascal}} guards on its own and throw a DomainError of ../errors when one is violated; invariants spanning several entities belong to the aggregate root.
21
+ {{/if}}
17
22
  return new {{name.pascal}}(id, state);
18
23
  }
19
24
 
@@ -0,0 +1,8 @@
1
+ it('refuses "{{refusal.words}}" with the code {{error.code}}', () => {
2
+ const error = {{name.pascal}}Error.{{refusal.camel}}();
3
+
4
+ expect(error).toBeInstanceOf(DomainError);
5
+ expect(error.code).toBe('{{error.code}}');
6
+ expect(error.message).toBe('{{refusal.title}}.');
7
+ expect(error.facts).toEqual({});
8
+ });
@@ -0,0 +1,7 @@
1
+ import { describe, expect, it } from '{{tests.module}}';
2
+ import { DomainError } from '@ddd-ts-kit/kernel';
3
+ import { {{name.pascal}}Error } from '{{alias.context}}/domain/errors/{{name.kebab}}.error{{alias.ext}}';
4
+
5
+ describe('{{name.pascal}}Error', () => {
6
+ {{error.case}}
7
+ });
@@ -0,0 +1,5 @@
1
+ import { ConceptError } from '@ddd-ts-kit/kernel';
2
+
3
+ export class {{name.pascal}}Error extends ConceptError {
4
+ {{error.factory}}
5
+ }
@@ -0,0 +1,4 @@
1
+ static {{refusal.camel}}() {
2
+ // TODO(domain): take as parameters the facts that explain this refusal (which {{context.words}} rule, which value), give them as the third argument and write a message a domain expert would recognise; a fact reaches the client only when named: `.exposing('<fact>')`. The code is the stable contract.
3
+ return {{name.pascal}}Error.refusal('{{error.code}}', '{{refusal.title}}.');
4
+ }
@@ -16,7 +16,14 @@ export default {
16
16
  {
17
17
  jsc: {
18
18
  parser: { syntax: 'typescript', decorators: true },
19
+ {{#if decorators.legacy}}
20
+ // A library of the stack only has legacy decorators: the whole program is compiled in that mode, with the metadata it reads.
19
21
  transform: { legacyDecorator: true, decoratorMetadata: true },
22
+ {{/if}}
23
+ {{#if decorators.standard}}
24
+ // Standard decorators, as `tsc` emits them for this project: no `experimentalDecorators` in tsconfig.json.
25
+ transform: { decoratorVersion: '2022-03' },
26
+ {{/if}}
20
27
  target: 'es2022',
21
28
  },
22
29
  },
@@ -10,9 +10,20 @@ paths:
10
10
  - Names come from the glossary of `CONTEXT.md`, written first (`language/glossary-term`); no `Manager`, `Helper`, `Data`, `Info`, `Model` (`language/no-technical-name`).
11
11
  - Aggregate: private constructor, `create` for birth, `rehydrate` for loading, state changed by methods named after the business intention, no setter, no public mutable property (`domain/aggregate-encapsulation`). One aggregate per transaction; another one is referenced by its id.
12
12
  - Value objects are immutable, validated in `create`, compared with `equals` (`domain/value-object-immutability`). An email, an amount, a period are types, not strings.
13
+ {{#if refusals.factories}}
14
+ - A violated invariant throws a refusal built by a static factory of the error class of its concept, never `new` and never a bare `Error`: `throw InvoiceError.alreadyIssued(this.id)` (`errors/through-factory`, `domain/no-generic-error`). One class per concept of the glossary in `domain/errors/`, extending `ConceptError`, no constructor (`errors/constructor-not-public`); a factory is named after the refusal and its code says the same words (`errors/factory-name`), one code per refusal of the context (`errors/code-unique`).
15
+ - A factory takes the facts of the refusal as typed parameters and gives them to `refusal(code, message, facts)`. Facts are private: one reaches a client only when the factory names it, `.exposing('<fact>')`, and never when it identifies a person. A value object returns its refusals in the `Result` of `create`: `err(PersonError.invalidEmail(raw))`.
16
+ {{/if}}
17
+ {{#if refusals.classes}}
13
18
  - A violated invariant throws a `DomainError` of `domain/errors/` with a stable `code`, never a bare `Error` (`domain/no-generic-error`).
19
+ {{/if}}
14
20
  - Domain events are named in the past tense, `<context>.<aggregate>.<fact>` (`events/name-format`), and recorded by the aggregate (`this.record(...)`). They leave with the save: nothing here dispatches them.
15
21
  - A repository here is a port: an abstract class extending the kernel `Repository<Aggregate>`, abstract members only (`ports/abstract-class`). A domain service is stateless.
16
22
  - Time and identifiers come in as parameters (`purity/*`); nothing here knows the acting user or its rights (`authz/in-application`).
17
23
  - One concept per file, with the suffix of its role: `.aggregate.ts`, `.entity.ts`, `.vo.ts`, `.event.ts`, `.error.ts`, `.repository.ts`, `.service.ts` (`naming/suffix`, `naming/one-concept-per-file`).
24
+ {{#if refusals.factories}}
25
+ - The language first, with `/ddd-ts-kit:glossary`. Then create with `npx ddd-ts-kit generate aggregate|entity|value-object|domain-event|domain-service|repository ... --json`, a refusal with `npx ddd-ts-kit generate error <context> <Concept> <refusal> --json` (it adds the factory to the class of the concept, and its case to the spec), and fill the `TODO(domain)` places it lists.
26
+ {{/if}}
27
+ {{#if refusals.classes}}
18
28
  - The language first, with `/ddd-ts-kit:glossary`. Then create with `npx ddd-ts-kit generate aggregate|entity|value-object|domain-event|domain-error|domain-service|repository ... --json` and fill the `TODO(domain)` places it lists.
29
+ {{/if}}
@@ -10,7 +10,12 @@ paths:
10
10
  - A route validates the shape of the input, builds a command or a query with the actor, executes it through `CommandBus` or `QueryBus` (never a handler class) and maps the answer. Nothing else.
11
11
  - Imports `application/` (and domain types for mapping), never `infrastructure/` (`layer/presentation-no-infrastructure`).
12
12
  - Input shape is validated here with the schema library of the project, behind the `Schema` port. Business rules are not validated here.
13
+ {{#if refusals.factories}}
14
+ - Every route declares its `security`, or `security: false`, and the codes of the refusals it can answer in `errors`, as their factories set them (`errors/known-code`); the mapping from code to status lives in one place, the error mapper. A client reads the `code`, and under `facts` only what a factory exposed.
15
+ {{/if}}
16
+ {{#if refusals.classes}}
13
17
  - Every route declares its `security`, or `security: false`, and the `DomainError` codes it can answer in `errors`; the mapping from code to status lives in one place, the error mapper.
18
+ {{/if}}
14
19
  - No role or ownership test here (`authz/in-application`): the bus asks for the permission, a policy decides on loaded state.
15
20
  - Request and response types are presentation types (`*.dto.ts`): never an aggregate, never a row.
16
21
  - Never put the message of an unexpected failure in a response or a log.
@@ -23,7 +23,7 @@
23
23
  "@biomejs/biome": "2.5.15",
24
24
  "@commitlint/cli": "^21.2.3",
25
25
  "@commitlint/config-conventional": "^21.2.3",
26
- "@ddd-ts-kit/eslint-plugin": "^0.2.0",
26
+ "@ddd-ts-kit/eslint-plugin": "^0.3.0",
27
27
  "@eslint/js": "^10.0.1",
28
28
  "@typescript/native": "npm:typescript@~7.0.2",
29
29
  "@vitest/coverage-v8": "5.0.3",
@@ -42,7 +42,7 @@ export function {{name.camel}}Route({{route.bus}}: {{route.busType}}): Route {
42
42
  {{#if route.isQuery}}
43
43
  responses: { {{route.status}}: { description: 'The answer.', body: answer } },
44
44
  {{/if}}
45
- // TODO(domain): list the codes of the DomainErrors "{{name.words}}" can raise, so that they appear in the contract with their status.
45
+ // TODO(domain): list the codes of the refusals "{{name.words}}" can raise, as their factories set them, so that they appear in the contract with their status (`errors/known-code`).
46
46
  errors: [{{route.errorCodes}}],
47
47
  security: {{route.security}},
48
48
  },
@@ -61,7 +61,7 @@ export function {{name.camel}}Route({{route.bus}}: {{route.busType}}): Route {
61
61
  {{#if route.isQuery}}
62
62
  responses: { {{route.status}}: { description: 'The answer.', body: answer } },
63
63
  {{/if}}
64
- // TODO(domain): list the codes of the DomainErrors "{{name.words}}" can raise, so that they appear in the contract with their status.
64
+ // TODO(domain): list the codes of the refusals "{{name.words}}" can raise, as their factories set them, so that they appear in the contract with their status (`errors/known-code`).
65
65
  errors: [{{route.errorCodes}}],
66
66
  security: {{route.security}},
67
67
  },
@@ -62,7 +62,7 @@ export function {{name.camel}}Route(queries: QueryBus): Route {
62
62
  tags: ['{{context.kebab}}'],
63
63
  request: { query },
64
64
  responses: { 200: { description: 'One page of the search.', body: pageSchemaOf(line) } },
65
- // TODO(domain): list the codes of the DomainErrors "{{name.words}}" can raise, so that they appear in the contract with their status.
65
+ // TODO(domain): list the codes of the refusals "{{name.words}}" can raise, as their factories set them, so that they appear in the contract with their status (`errors/known-code`).
66
66
  errors: ['UNAUTHORIZED', 'FORBIDDEN'],
67
67
  security: {{route.security}},
68
68
  },
@@ -70,7 +70,7 @@ export function {{name.camel}}Route({{route.bus}}: {{route.busType}}): Route {
70
70
  {{#if route.isQuery}}
71
71
  responses: { {{route.status}}: { description: 'The answer.', body: answer } },
72
72
  {{/if}}
73
- // TODO(domain): list the codes of the DomainErrors "{{name.words}}" can raise, so that they appear in the contract with their status.
73
+ // TODO(domain): list the codes of the refusals "{{name.words}}" can raise, as their factories set them, so that they appear in the contract with their status (`errors/known-code`).
74
74
  errors: [{{route.errorCodes}}],
75
75
  security: {{route.security}},
76
76
  },
@@ -52,7 +52,7 @@ export function {{name.camel}}Route({{route.bus}}: {{route.busType}}): Route {
52
52
  {{#if route.isQuery}}
53
53
  responses: { {{route.status}}: { description: 'The answer.', body: answer } },
54
54
  {{/if}}
55
- // TODO(domain): list the codes of the DomainErrors "{{name.words}}" can raise, so that they appear in the contract with their status.
55
+ // TODO(domain): list the codes of the refusals "{{name.words}}" can raise, as their factories set them, so that they appear in the contract with their status (`errors/known-code`).
56
56
  errors: [{{route.errorCodes}}],
57
57
  security: {{route.security}},
58
58
  },
@@ -10,7 +10,12 @@ export class {{name.pascal}} extends ValueObject<{{name.pascal}}Props> {
10
10
  }
11
11
 
12
12
  static create(value: string): Result<{{name.pascal}}, InvariantViolation> {
13
+ {{#if refusals.factories}}
14
+ // TODO(domain): replace `value: string` by the real components of {{name.pascal}}, normalize them and check every validity rule; return `err(...)` with a refusal of the concept this value describes, for example `<Concept>Error.invalid{{name.pascal}}(value)` (`ddd-ts-kit generate error {{context.kebab}} <Concept> invalid{{name.pascal}}`), instead of InvariantViolation.
15
+ {{/if}}
16
+ {{#if refusals.classes}}
13
17
  // TODO(domain): replace `value: string` by the real components of {{name.pascal}}, normalize them and check every validity rule; return `err(...)` with a dedicated error (`ddd-ts-kit generate domain-error {{context.kebab}} Invalid{{name.pascal}}`) instead of InvariantViolation.
18
+ {{/if}}
14
19
  if (value.trim().length === 0) {
15
20
  return err(new InvariantViolation('{{name.title}} must not be empty.'));
16
21
  }