@ddd-ts-kit/eslint-plugin 0.1.1 → 0.2.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 (83) hide show
  1. package/README.md +3 -1
  2. package/dist/project/config.d.ts +4 -0
  3. package/dist/project/config.d.ts.map +1 -1
  4. package/dist/project/is-judged.d.ts +5 -0
  5. package/dist/project/is-judged.d.ts.map +1 -0
  6. package/dist/project/is-judged.js +7 -0
  7. package/dist/project/is-judged.js.map +1 -0
  8. package/dist/project/parse-config.d.ts.map +1 -1
  9. package/dist/project/parse-config.js +4 -0
  10. package/dist/project/parse-config.js.map +1 -1
  11. package/dist/project/resolve-import.d.ts.map +1 -1
  12. package/dist/project/resolve-import.js +4 -1
  13. package/dist/project/resolve-import.js.map +1 -1
  14. package/dist/project/specifier-suffix.d.ts +6 -0
  15. package/dist/project/specifier-suffix.d.ts.map +1 -0
  16. package/dist/project/specifier-suffix.js +8 -0
  17. package/dist/project/specifier-suffix.js.map +1 -0
  18. package/dist/project/to-alias.d.ts +3 -2
  19. package/dist/project/to-alias.d.ts.map +1 -1
  20. package/dist/project/to-alias.js +4 -3
  21. package/dist/project/to-alias.js.map +1 -1
  22. package/dist/rules/clean-one-export-per-file.js +7 -3
  23. package/dist/rules/clean-one-export-per-file.js.map +1 -1
  24. package/dist/rules/declarations-constructor-injection.d.ts +5 -0
  25. package/dist/rules/declarations-constructor-injection.d.ts.map +1 -0
  26. package/dist/rules/declarations-constructor-injection.js +80 -0
  27. package/dist/rules/declarations-constructor-injection.js.map +1 -0
  28. package/dist/rules/imports-alias-only.d.ts.map +1 -1
  29. package/dist/rules/imports-alias-only.js +7 -9
  30. package/dist/rules/imports-alias-only.js.map +1 -1
  31. package/dist/rules/imports-extension.d.ts +5 -0
  32. package/dist/rules/imports-extension.d.ts.map +1 -0
  33. package/dist/rules/imports-extension.js +45 -0
  34. package/dist/rules/imports-extension.js.map +1 -0
  35. package/dist/rules/ports-no-concrete-dependency.d.ts +3 -1
  36. package/dist/rules/ports-no-concrete-dependency.d.ts.map +1 -1
  37. package/dist/rules/ports-no-concrete-dependency.js +51 -3
  38. package/dist/rules/ports-no-concrete-dependency.js.map +1 -1
  39. package/dist/rules/rules.d.ts.map +1 -1
  40. package/dist/rules/rules.js +4 -0
  41. package/dist/rules/rules.js.map +1 -1
  42. package/dist/support/declarations/declared-roles.d.ts.map +1 -1
  43. package/dist/support/declarations/declared-roles.js +1 -0
  44. package/dist/support/declarations/declared-roles.js.map +1 -1
  45. package/dist/support/injection/language-types.d.ts +3 -0
  46. package/dist/support/injection/language-types.d.ts.map +1 -0
  47. package/dist/support/injection/language-types.js +20 -0
  48. package/dist/support/injection/language-types.js.map +1 -0
  49. package/dist/support/injection/not-classes.d.ts +4 -0
  50. package/dist/support/injection/not-classes.d.ts.map +1 -0
  51. package/dist/support/injection/not-classes.js +20 -0
  52. package/dist/support/injection/not-classes.js.map +1 -0
  53. package/dist/support/injection/parameter-reading.d.ts +9 -0
  54. package/dist/support/injection/parameter-reading.d.ts.map +1 -0
  55. package/dist/support/injection/parameter-reading.js +2 -0
  56. package/dist/support/injection/parameter-reading.js.map +1 -0
  57. package/dist/support/injection/read-parameter.d.ts +9 -0
  58. package/dist/support/injection/read-parameter.d.ts.map +1 -0
  59. package/dist/support/injection/read-parameter.js +41 -0
  60. package/dist/support/injection/read-parameter.js.map +1 -0
  61. package/dist/support/injection/written-name.d.ts +4 -0
  62. package/dist/support/injection/written-name.d.ts.map +1 -0
  63. package/dist/support/injection/written-name.js +13 -0
  64. package/dist/support/injection/written-name.js.map +1 -0
  65. package/dist/version.d.ts +1 -1
  66. package/dist/version.js +1 -1
  67. package/docs/rules/clean-one-export-per-file.md +1 -1
  68. package/docs/rules/context-declared-relationship.md +2 -2
  69. package/docs/rules/context-extractable.md +3 -3
  70. package/docs/rules/context-published-language-is-a-contract.md +1 -1
  71. package/docs/rules/context-published-language-only.md +2 -2
  72. package/docs/rules/declarations-constructor-injection.md +89 -0
  73. package/docs/rules/declarations-role-declared.md +15 -9
  74. package/docs/rules/domain-events-transactional-before-commit.md +1 -1
  75. package/docs/rules/imports-alias-only.md +10 -9
  76. package/docs/rules/imports-extension.md +83 -0
  77. package/docs/rules/layer-application-inward.md +3 -3
  78. package/docs/rules/layer-domain-purity.md +3 -3
  79. package/docs/rules/layer-infrastructure-no-presentation.md +2 -2
  80. package/docs/rules/layer-presentation-no-infrastructure.md +2 -2
  81. package/docs/rules/ports-no-concrete-dependency.md +4 -3
  82. package/docs/rules/test-no-mocks.md +1 -1
  83. package/package.json +1 -1
@@ -1,24 +1,72 @@
1
- import { defineRule } from '../support/rule/define-rule.js';
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils';
2
+ import { constructorOf } from '../support/classes/constructor-of.js';
3
+ import { ACCESS_DECORATORS } from '../support/declarations/access-decorators.js';
4
+ import { declarationReader } from '../support/declarations/declaration-reader.js';
5
+ import { declaredRoleOf } from '../support/declarations/declared-role-of.js';
6
+ import { isDeclaredStyle } from '../support/declarations/is-declared-style.js';
2
7
  import { dependencyListListener } from '../support/ports/dependency-list-listener.js';
3
8
  import { importedBindings } from '../support/ports/imported-bindings.js';
9
+ import { defineRule } from '../support/rule/define-rule.js';
4
10
  export const portsNoConcreteDependency = defineRule({
5
11
  id: 'ports/no-concrete-dependency',
6
12
  type: 'problem',
7
13
  recommended: 'error',
8
- description: 'A dependency list names ports, never the class that implements one: nothing imported from infrastructure/ or from test/fakes/.',
14
+ description: 'A dependency is named by its port, never by the class that implements one: nothing imported from infrastructure/ or from test/fakes/ in a dependency list, nor as the type of a constructor parameter of a declared class.',
9
15
  messages: {
10
16
  concrete: '{{name}} is named in a dependency list but comes from {{where}}: a list names ports, never what implements them. Name the port (the abstract class of domain/repositories or application/ports that {{name}} implements) and let the declaration of the adapter, the module file or a `fake(Port, ..)` of the test say which class stands behind it.',
17
+ typed: '{{name}} types a constructor parameter of a declared class but comes from {{where}}: a parameter is typed by a port, never by what implements it. Type it by the port (the abstract class of domain/repositories or application/ports that {{name}} implements): the adapter, or a `fake(Port, ..)` of the test, is bound to that port at the composition root.',
11
18
  },
12
19
  create({ file, sourceCode, report }) {
13
20
  const imported = importedBindings(file, sourceCode.ast);
14
- return dependencyListListener(sourceCode.ast, (dependency) => {
21
+ const lists = dependencyListListener(sourceCode.ast, (dependency) => {
15
22
  const where = concretePlace(imported.get(dependency.name)?.target);
16
23
  if (where !== undefined) {
17
24
  report({ node: dependency, messageId: 'concrete', data: { name: dependency.name, where } });
18
25
  }
19
26
  });
27
+ const judgeClass = signatureJudge(file, sourceCode.ast, { imported, report });
28
+ return {
29
+ ...lists,
30
+ ClassDeclaration(node) {
31
+ lists.ClassDeclaration?.(node);
32
+ judgeClass(node);
33
+ },
34
+ ClassExpression(node) {
35
+ lists.ClassExpression?.(node);
36
+ judgeClass(node);
37
+ },
38
+ };
20
39
  },
21
40
  });
41
+ /** A declared class that lists nothing states its dependencies in its constructor: its parameter types are the list. */
42
+ function signatureJudge(file, program, { imported, report }) {
43
+ if (file.isTest || !isDeclaredStyle(file) || declaredRoleOf(file) === undefined) {
44
+ return () => undefined;
45
+ }
46
+ const declarationsOf = declarationReader(program);
47
+ return (node) => {
48
+ const [declaration] = declarationsOf(node).filter(({ name }) => !ACCESS_DECORATORS.has(name));
49
+ if (declaration === undefined || declaration.arguments.at(-1)?.type === AST_NODE_TYPES.ArrayExpression) {
50
+ return;
51
+ }
52
+ for (const type of parameterTypes(constructorOf(node.body))) {
53
+ const where = concretePlace(imported.get(type.name)?.target);
54
+ if (where !== undefined) {
55
+ report({ node: type, messageId: 'typed', data: { name: type.name, where } });
56
+ }
57
+ }
58
+ };
59
+ }
60
+ /** The class name each parameter of a constructor is typed by, when it is typed by one. */
61
+ function parameterTypes(written) {
62
+ return (written?.value.params ?? []).flatMap((node) => {
63
+ const parameter = node.type === AST_NODE_TYPES.TSParameterProperty ? node.parameter : node;
64
+ const type = parameter.type === AST_NODE_TYPES.Identifier ? parameter.typeAnnotation?.typeAnnotation : undefined;
65
+ return type?.type === AST_NODE_TYPES.TSTypeReference && type.typeName.type === AST_NODE_TYPES.Identifier
66
+ ? [type.typeName]
67
+ : [];
68
+ });
69
+ }
22
70
  function concretePlace(target) {
23
71
  if (target?.kind !== 'file' || target.location.area !== 'context') {
24
72
  return undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"ports-no-concrete-dependency.js","sourceRoot":"","sources":["../../src/rules/ports-no-concrete-dependency.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,8CAA8C,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAE,MAAM,uCAAuC,CAAC;AAEzE,MAAM,CAAC,MAAM,yBAAyB,GAAG,UAAU,CAAa;IAC9D,EAAE,EAAE,8BAA8B;IAClC,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,OAAO;IACpB,WAAW,EACT,gIAAgI;IAClI,QAAQ,EAAE;QACR,QAAQ,EACN,sVAAsV;KACzV;IACD,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE;QACjC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC;QAExD,OAAO,sBAAsB,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,EAAE;YAC3D,MAAM,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;YAEnE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YAC9F,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC,CAAC;AAEH,SAAS,aAAa,CAAC,MAAgC;IACrD,IAAI,MAAM,EAAE,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAClE,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC;IAE1C,IAAI,KAAK,KAAK,gBAAgB,EAAE,CAAC;QAC/B,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED,OAAO,KAAK,KAAK,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;AAC/E,CAAC"}
1
+ {"version":3,"file":"ports-no-concrete-dependency.js","sourceRoot":"","sources":["../../src/rules/ports-no-concrete-dependency.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/rules/rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAoGlE,+HAA+H;AAC/H,eAAO,MAAM,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEnD,CAAC"}
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/rules/rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAwGlE,+HAA+H;AAC/H,eAAO,MAAM,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEnD,CAAC"}
@@ -17,6 +17,7 @@ import { cleanOneExportPerFile } from './clean-one-export-per-file.js';
17
17
  import { cleanStepdown } from './clean-stepdown.js';
18
18
  import { contextExtractable } from './context-extractable.js';
19
19
  import { contextDeclaredRelationship, contextPublishedLanguageIsAContract, contextPublishedLanguageOnly, } from './context-boundaries.js';
20
+ import { declarationsConstructorInjection } from './declarations-constructor-injection.js';
20
21
  import { declarationsRoleDeclared } from './declarations-role-declared.js';
21
22
  import { domainAggregateEncapsulation } from './domain-aggregate-encapsulation.js';
22
23
  import { domainEventsDispatchedOnSave } from './domain-events-dispatched-on-save.js';
@@ -28,6 +29,7 @@ import { eventsNameFormat } from './events-name-format.js';
28
29
  import { eventsOutboxRequired } from './events-outbox-required.js';
29
30
  import { governanceRecordedDeviation } from './governance-recorded-deviation.js';
30
31
  import { importsAliasOnly } from './imports-alias-only.js';
32
+ import { importsExtension } from './imports-extension.js';
31
33
  import { layerApplicationInward } from './layer-application-inward.js';
32
34
  import { layerDomainPurity } from './layer-domain-purity.js';
33
35
  import { layerInfrastructureNoPresentation, layerPresentationNoInfrastructure } from './layer-sideways.js';
@@ -83,6 +85,7 @@ const ALL = [
83
85
  standardNoParallelInterface,
84
86
  governanceRecordedDeviation,
85
87
  declarationsRoleDeclared,
88
+ declarationsConstructorInjection,
86
89
  portsAbstractClass,
87
90
  portsImplementsNeverExtends,
88
91
  portsNoTokenConstant,
@@ -91,6 +94,7 @@ const ALL = [
91
94
  schedulingJobTriggersUseCase,
92
95
  schedulingJobName,
93
96
  importsAliasOnly,
97
+ importsExtension,
94
98
  ];
95
99
  /** Keyed by ESLint name: the id of docs/ARCHITECTURE.md with its slash replaced by a dash, or the name of a companion rule. */
96
100
  export const rules = Object.fromEntries(ALL.map((rule) => [docsOf(rule).name, rule]));
@@ -1 +1 @@
1
- {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/rules/rules.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/rules/rules.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"declared-roles.d.ts","sourceRoot":"","sources":["../../../src/support/declarations/declared-roles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,uFAAuF;AACvF,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EAiBjD,CAAC"}
1
+ {"version":3,"file":"declared-roles.d.ts","sourceRoot":"","sources":["../../../src/support/declarations/declared-roles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,uFAAuF;AACvF,eAAO,MAAM,cAAc,EAAE,SAAS,YAAY,EAkBjD,CAAC"}
@@ -13,6 +13,7 @@ export const DECLARED_ROLES = [
13
13
  { suffix: 'publisher', folders: ['application/integration/publishers'], decorators: ['DomainEventHandler'] },
14
14
  { suffix: 'policy', folders: ['application/authorization'], decorators: ['Policy'] },
15
15
  { suffix: 'job', folders: ['application/scheduling'], decorators: ['Scheduled'] },
16
+ { suffix: 'projection', folders: ['application/projections'], decorators: ['Projection'] },
16
17
  { suffix: 'repository', folders: ['infrastructure/persistence'], decorators: ['Repository'] },
17
18
  { suffix: 'gateway', folders: ['infrastructure'], decorators: ['Gateway'] },
18
19
  { suffix: 'adapter', folders: ['infrastructure'], decorators: ['Adapter'] },
@@ -1 +1 @@
1
- {"version":3,"file":"declared-roles.js","sourceRoot":"","sources":["../../../src/support/declarations/declared-roles.ts"],"names":[],"mappings":"AAEA,uFAAuF;AACvF,MAAM,CAAC,MAAM,cAAc,GAA4B;IACrD,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,sBAAsB,CAAC,EAAE,UAAU,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE;IAC5F,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,qBAAqB,CAAC,EAAE,UAAU,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE;IACzF,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,sBAAsB,CAAC,EAAE,UAAU,EAAE,CAAC,gBAAgB,CAAC,EAAE;IACxF,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,qBAAqB,CAAC,EAAE,UAAU,EAAE,CAAC,cAAc,CAAC,EAAE;IACrF;QACE,MAAM,EAAE,qBAAqB;QAC7B,OAAO,EAAE,CAAC,kCAAkC,CAAC;QAC7C,UAAU,EAAE,CAAC,yBAAyB,CAAC;KACxC;IACD,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,4BAA4B,CAAC,EAAE,UAAU,EAAE,CAAC,oBAAoB,CAAC,EAAE;IACxG,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,oCAAoC,CAAC,EAAE,UAAU,EAAE,CAAC,oBAAoB,CAAC,EAAE;IAC5G,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,2BAA2B,CAAC,EAAE,UAAU,EAAE,CAAC,QAAQ,CAAC,EAAE;IACpF,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,wBAAwB,CAAC,EAAE,UAAU,EAAE,CAAC,WAAW,CAAC,EAAE;IACjF,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,4BAA4B,CAAC,EAAE,UAAU,EAAE,CAAC,YAAY,CAAC,EAAE;IAC7F,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,gBAAgB,CAAC,EAAE,UAAU,EAAE,CAAC,SAAS,CAAC,EAAE;IAC3E,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,gBAAgB,CAAC,EAAE,UAAU,EAAE,CAAC,SAAS,CAAC,EAAE;CAC5E,CAAC"}
1
+ {"version":3,"file":"declared-roles.js","sourceRoot":"","sources":["../../../src/support/declarations/declared-roles.ts"],"names":[],"mappings":"AAEA,uFAAuF;AACvF,MAAM,CAAC,MAAM,cAAc,GAA4B;IACrD,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,sBAAsB,CAAC,EAAE,UAAU,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE;IAC5F,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,qBAAqB,CAAC,EAAE,UAAU,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE;IACzF,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,sBAAsB,CAAC,EAAE,UAAU,EAAE,CAAC,gBAAgB,CAAC,EAAE;IACxF,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,qBAAqB,CAAC,EAAE,UAAU,EAAE,CAAC,cAAc,CAAC,EAAE;IACrF;QACE,MAAM,EAAE,qBAAqB;QAC7B,OAAO,EAAE,CAAC,kCAAkC,CAAC;QAC7C,UAAU,EAAE,CAAC,yBAAyB,CAAC;KACxC;IACD,EAAE,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,CAAC,4BAA4B,CAAC,EAAE,UAAU,EAAE,CAAC,oBAAoB,CAAC,EAAE;IACxG,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC,oCAAoC,CAAC,EAAE,UAAU,EAAE,CAAC,oBAAoB,CAAC,EAAE;IAC5G,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,2BAA2B,CAAC,EAAE,UAAU,EAAE,CAAC,QAAQ,CAAC,EAAE;IACpF,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,wBAAwB,CAAC,EAAE,UAAU,EAAE,CAAC,WAAW,CAAC,EAAE;IACjF,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,yBAAyB,CAAC,EAAE,UAAU,EAAE,CAAC,YAAY,CAAC,EAAE;IAC1F,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,4BAA4B,CAAC,EAAE,UAAU,EAAE,CAAC,YAAY,CAAC,EAAE;IAC7F,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,gBAAgB,CAAC,EAAE,UAAU,EAAE,CAAC,SAAS,CAAC,EAAE;IAC3E,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,gBAAgB,CAAC,EAAE,UAAU,EAAE,CAAC,SAAS,CAAC,EAAE;CAC5E,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Types of the language and of its standard library: they exist for every program, so they name no dependency of one. */
2
+ export declare const LANGUAGE_TYPES: ReadonlySet<string>;
3
+ //# sourceMappingURL=language-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language-types.d.ts","sourceRoot":"","sources":["../../../src/support/injection/language-types.ts"],"names":[],"mappings":"AAAA,0HAA0H;AAC1H,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CAiB7C,CAAC"}
@@ -0,0 +1,20 @@
1
+ /** Types of the language and of its standard library: they exist for every program, so they name no dependency of one. */
2
+ export const LANGUAGE_TYPES = new Set([
3
+ 'Date',
4
+ 'Map',
5
+ 'Set',
6
+ 'Array',
7
+ 'ReadonlyArray',
8
+ 'Record',
9
+ 'Promise',
10
+ 'Function',
11
+ 'RegExp',
12
+ 'Error',
13
+ 'URL',
14
+ 'Buffer',
15
+ 'Partial',
16
+ 'Readonly',
17
+ 'Pick',
18
+ 'Omit',
19
+ ]);
20
+ //# sourceMappingURL=language-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"language-types.js","sourceRoot":"","sources":["../../../src/support/injection/language-types.ts"],"names":[],"mappings":"AAAA,0HAA0H;AAC1H,MAAM,CAAC,MAAM,cAAc,GAAwB,IAAI,GAAG,CAAC;IACzD,MAAM;IACN,KAAK;IACL,KAAK;IACL,OAAO;IACP,eAAe;IACf,QAAQ;IACR,SAAS;IACT,UAAU;IACV,QAAQ;IACR,OAAO;IACP,KAAK;IACL,QAAQ;IACR,SAAS;IACT,UAAU;IACV,MAAM;IACN,MAAM;CACP,CAAC,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type TSESTree } from '@typescript-eslint/utils';
2
+ /** The names a program declares at its top level as an interface, a type alias or an enum, with what each is. */
3
+ export declare function notClasses(program: TSESTree.Program): ReadonlyMap<string, string>;
4
+ //# sourceMappingURL=not-classes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"not-classes.d.ts","sourceRoot":"","sources":["../../../src/support/injection/not-classes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAQzE,iHAAiH;AACjH,wBAAgB,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAejF"}
@@ -0,0 +1,20 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils';
2
+ const KINDS = {
3
+ [AST_NODE_TYPES.TSInterfaceDeclaration]: 'an interface',
4
+ [AST_NODE_TYPES.TSTypeAliasDeclaration]: 'a type alias',
5
+ [AST_NODE_TYPES.TSEnumDeclaration]: 'an enum',
6
+ };
7
+ /** The names a program declares at its top level as an interface, a type alias or an enum, with what each is. */
8
+ export function notClasses(program) {
9
+ const declared = program.body.flatMap((statement) => {
10
+ const declaration = statement.type === AST_NODE_TYPES.ExportNamedDeclaration && statement.declaration !== null
11
+ ? statement.declaration
12
+ : statement;
13
+ const what = KINDS[declaration.type];
14
+ return what !== undefined && 'id' in declaration && declaration.id?.type === AST_NODE_TYPES.Identifier
15
+ ? [[declaration.id.name, what]]
16
+ : [];
17
+ });
18
+ return new Map(declared);
19
+ }
20
+ //# sourceMappingURL=not-classes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"not-classes.js","sourceRoot":"","sources":["../../../src/support/injection/not-classes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,MAAM,0BAA0B,CAAC;AAEzE,MAAM,KAAK,GAAsD;IAC/D,CAAC,cAAc,CAAC,sBAAsB,CAAC,EAAE,cAAc;IACvD,CAAC,cAAc,CAAC,sBAAsB,CAAC,EAAE,cAAc;IACvD,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAE,SAAS;CAC9C,CAAC;AAEF,iHAAiH;AACjH,MAAM,UAAU,UAAU,CAAC,OAAyB;IAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,SAAS,EAAsB,EAAE;QACtE,MAAM,WAAW,GACf,SAAS,CAAC,IAAI,KAAK,cAAc,CAAC,sBAAsB,IAAI,SAAS,CAAC,WAAW,KAAK,IAAI;YACxF,CAAC,CAAC,SAAS,CAAC,WAAW;YACvB,CAAC,CAAC,SAAS,CAAC;QAEhB,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAErC,OAAO,IAAI,KAAK,SAAS,IAAI,IAAI,IAAI,WAAW,IAAI,WAAW,CAAC,EAAE,EAAE,IAAI,KAAK,cAAc,CAAC,UAAU;YACpG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC/B,CAAC,CAAC,EAAE,CAAC;IACT,CAAC,CAAC,CAAC;IAEH,OAAO,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,9 @@
1
+ /** What a constructor parameter says of a dependency: the class that types it, or why it names none. */
2
+ export type ParameterReading = {
3
+ readonly token: string;
4
+ readonly flaw?: undefined;
5
+ } | {
6
+ readonly flaw: string;
7
+ readonly token?: undefined;
8
+ };
9
+ //# sourceMappingURL=parameter-reading.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameter-reading.d.ts","sourceRoot":"","sources":["../../../src/support/injection/parameter-reading.ts"],"names":[],"mappings":"AAAA,wGAAwG;AACxG,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=parameter-reading.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parameter-reading.js","sourceRoot":"","sources":["../../../src/support/injection/parameter-reading.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import { type TSESTree } from '@typescript-eslint/utils';
2
+ import type { ParameterReading } from './parameter-reading.js';
3
+ /**
4
+ * Reads one constructor parameter of a declared class. `notClasses` are the names the file
5
+ * declares as an interface, a type alias or an enum: what another file declares is read by
6
+ * `ddd-ts-kit check`, which sees the project.
7
+ */
8
+ export declare function readParameter(node: TSESTree.Parameter, notClasses: ReadonlyMap<string, string>): ParameterReading;
9
+ //# sourceMappingURL=read-parameter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-parameter.d.ts","sourceRoot":"","sources":["../../../src/support/injection/read-parameter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAI/D;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,gBAAgB,CAoBjH"}
@@ -0,0 +1,41 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils';
2
+ import { LANGUAGE_TYPES } from './language-types.js';
3
+ const ALWAYS_GIVEN = 'the composition root gives every parameter a value, always';
4
+ /**
5
+ * Reads one constructor parameter of a declared class. `notClasses` are the names the file
6
+ * declares as an interface, a type alias or an enum: what another file declares is read by
7
+ * `ddd-ts-kit check`, which sees the project.
8
+ */
9
+ export function readParameter(node, notClasses) {
10
+ const parameter = node.type === AST_NODE_TYPES.TSParameterProperty ? node.parameter : node;
11
+ if (parameter.type === AST_NODE_TYPES.RestElement) {
12
+ return { flaw: `is a rest parameter: ${ALWAYS_GIVEN}` };
13
+ }
14
+ if (parameter.type === AST_NODE_TYPES.AssignmentPattern) {
15
+ return { flaw: `has a default value: ${ALWAYS_GIVEN}` };
16
+ }
17
+ if (parameter.type !== AST_NODE_TYPES.Identifier) {
18
+ return { flaw: `is destructured: ${ALWAYS_GIVEN}` };
19
+ }
20
+ if (parameter.optional) {
21
+ return { flaw: `is optional: ${ALWAYS_GIVEN}` };
22
+ }
23
+ return typed(parameter.typeAnnotation?.typeAnnotation, notClasses);
24
+ }
25
+ function typed(type, notClasses) {
26
+ if (type === undefined) {
27
+ return { flaw: 'has no type' };
28
+ }
29
+ if (type.type !== AST_NODE_TYPES.TSTypeReference || type.typeName.type !== AST_NODE_TYPES.Identifier) {
30
+ return { flaw: 'is typed by something that names no single class' };
31
+ }
32
+ const { name } = type.typeName;
33
+ const what = notClasses.get(name);
34
+ if (what !== undefined) {
35
+ return { flaw: `is typed \`${name}\`, ${what}: only a class exists at run time and can be an injection token` };
36
+ }
37
+ return LANGUAGE_TYPES.has(name)
38
+ ? { flaw: `is typed \`${name}\`, a type of the language: it names nothing the composition root binds` }
39
+ : { token: name };
40
+ }
41
+ //# sourceMappingURL=read-parameter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-parameter.js","sourceRoot":"","sources":["../../../src/support/injection/read-parameter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAGrD,MAAM,YAAY,GAAG,4DAA4D,CAAC;AAElF;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,IAAwB,EAAE,UAAuC;IAC7F,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IAE3F,IAAI,SAAS,CAAC,IAAI,KAAK,cAAc,CAAC,WAAW,EAAE,CAAC;QAClD,OAAO,EAAE,IAAI,EAAE,wBAAwB,YAAY,EAAE,EAAE,CAAC;IAC1D,CAAC;IAED,IAAI,SAAS,CAAC,IAAI,KAAK,cAAc,CAAC,iBAAiB,EAAE,CAAC;QACxD,OAAO,EAAE,IAAI,EAAE,wBAAwB,YAAY,EAAE,EAAE,CAAC;IAC1D,CAAC;IAED,IAAI,SAAS,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU,EAAE,CAAC;QACjD,OAAO,EAAE,IAAI,EAAE,oBAAoB,YAAY,EAAE,EAAE,CAAC;IACtD,CAAC;IAED,IAAI,SAAS,CAAC,QAAQ,EAAE,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,gBAAgB,YAAY,EAAE,EAAE,CAAC;IAClD,CAAC;IAED,OAAO,KAAK,CAAC,SAAS,CAAC,cAAc,EAAE,cAAc,EAAE,UAAU,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,KAAK,CAAC,IAAmC,EAAE,UAAuC;IACzF,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;IACjC,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,eAAe,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU,EAAE,CAAC;QACrG,OAAO,EAAE,IAAI,EAAE,kDAAkD,EAAE,CAAC;IACtE,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;IAC/B,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAElC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,cAAc,IAAI,OAAO,IAAI,iEAAiE,EAAE,CAAC;IAClH,CAAC;IAED,OAAO,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC;QAC7B,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,IAAI,yEAAyE,EAAE;QACvG,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type TSESTree } from '@typescript-eslint/utils';
2
+ /** The name a constructor parameter is written under, or its source shape when it has none. */
3
+ export declare function writtenName(node: TSESTree.Parameter): string;
4
+ //# sourceMappingURL=written-name.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"written-name.d.ts","sourceRoot":"","sources":["../../../src/support/injection/written-name.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEzE,+FAA+F;AAC/F,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,SAAS,GAAG,MAAM,CAW5D"}
@@ -0,0 +1,13 @@
1
+ import { AST_NODE_TYPES } from '@typescript-eslint/utils';
2
+ /** The name a constructor parameter is written under, or its source shape when it has none. */
3
+ export function writtenName(node) {
4
+ const parameter = node.type === AST_NODE_TYPES.TSParameterProperty ? node.parameter : node;
5
+ const target = parameter.type === AST_NODE_TYPES.AssignmentPattern ? parameter.left : parameter;
6
+ if (target.type === AST_NODE_TYPES.Identifier) {
7
+ return target.name;
8
+ }
9
+ return target.type === AST_NODE_TYPES.RestElement && target.argument.type === AST_NODE_TYPES.Identifier
10
+ ? target.argument.name
11
+ : 'the destructured one';
12
+ }
13
+ //# sourceMappingURL=written-name.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"written-name.js","sourceRoot":"","sources":["../../../src/support/injection/written-name.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAiB,MAAM,0BAA0B,CAAC;AAEzE,+FAA+F;AAC/F,MAAM,UAAU,WAAW,CAAC,IAAwB;IAClD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,KAAK,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3F,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,KAAK,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IAEhG,IAAI,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU,EAAE,CAAC;QAC9C,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,KAAK,cAAc,CAAC,WAAW,IAAI,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,cAAc,CAAC,UAAU;QACrG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI;QACtB,CAAC,CAAC,sBAAsB,CAAC;AAC7B,CAAC"}
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.1.1";
1
+ export declare const VERSION = "0.2.0";
2
2
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = '0.1.1';
1
+ export const VERSION = '0.2.0';
2
2
  //# sourceMappingURL=version.js.map
@@ -42,7 +42,7 @@ export function retry(options: RetryOptions): Aspect {}
42
42
  export class RabbitMqEventBus {}
43
43
 
44
44
  // src/platform/index.ts
45
- export { retry, type RetryOptions } from '@/platform/retry.js';
45
+ export { retry, type RetryOptions } from '@/platform/retry';
46
46
  ```
47
47
 
48
48
  ## Details
@@ -17,14 +17,14 @@ Incorrect:
17
17
  ```ts
18
18
  // ddd-ts-kit.config.json: "shipping": { "upstreams": [] }
19
19
  // src/contexts/shipping/application/integration/handlers/billing-invoice-issued.integration-handler.ts
20
- import type { InvoiceIssuedV1 } from '@/contexts/billing/published-language/index.js';
20
+ import type { InvoiceIssuedV1 } from '@/contexts/billing/published-language/index';
21
21
  ```
22
22
 
23
23
  Correct:
24
24
 
25
25
  ```ts
26
26
  // ddd-ts-kit.config.json: "shipping": { "upstreams": [{ "context": "billing", "relationship": "published-language" }] }
27
- import type { InvoiceIssuedV1 } from '@/contexts/billing/published-language/index.js';
27
+ import type { InvoiceIssuedV1 } from '@/contexts/billing/published-language/index';
28
28
  ```
29
29
 
30
30
  ## Details
@@ -41,11 +41,11 @@ export function remember(currency: string, rate: number): void {
41
41
  }
42
42
 
43
43
  // billing/billing.module.ts
44
- import { ProductReader } from '@/contexts/catalog/application/ports/product-reader.port.js';
44
+ import { ProductReader } from '@/contexts/catalog/application/ports/product-reader.port';
45
45
  builder.query(GetPrice).public().handledBy(GetPriceHandler, [ProductReader]);
46
46
 
47
47
  // declared style: billing/application/queries/get-price/get-price.handler.ts
48
- import { ProductReader } from '@/contexts/catalog/application/ports/product-reader.port.js';
48
+ import { ProductReader } from '@/contexts/catalog/application/ports/product-reader.port';
49
49
 
50
50
  @QueryHandler(GetPriceQuery, [ProductReader])
51
51
  export class GetPriceHandler {}
@@ -62,7 +62,7 @@ builder.bind(PriceSource).toClass(InProcessPriceSource, [QueryBus]).as('gateway'
62
62
  builder.query(GetPrice).public().handledBy(GetPriceHandler, [PriceSource]);
63
63
 
64
64
  // declared style: the port is one of billing, its gateway calls catalog
65
- import { PriceCatalog } from '@/contexts/billing/application/ports/price-catalog.port.js';
65
+ import { PriceCatalog } from '@/contexts/billing/application/ports/price-catalog.port';
66
66
 
67
67
  @QueryHandler(GetPriceQuery, [PriceCatalog])
68
68
  export class GetPriceHandler {}
@@ -16,7 +16,7 @@ Incorrect:
16
16
 
17
17
  ```ts
18
18
  // src/contexts/billing/published-language/invoice-issued.v1.integration-event.ts
19
- import type { Invoice } from '@/contexts/billing/domain/aggregates/invoice.aggregate.js';
19
+ import type { Invoice } from '@/contexts/billing/domain/aggregates/invoice.aggregate';
20
20
  ```
21
21
 
22
22
  Correct:
@@ -16,13 +16,13 @@ Incorrect:
16
16
 
17
17
  ```ts
18
18
  // src/contexts/billing/application/...
19
- import { Product } from '@/contexts/catalog/domain/aggregates/product.aggregate.js';
19
+ import { Product } from '@/contexts/catalog/domain/aggregates/product.aggregate';
20
20
  ```
21
21
 
22
22
  Correct:
23
23
 
24
24
  ```ts
25
- import type { ProductListedV1 } from '@/contexts/catalog/published-language/index.js';
25
+ import type { ProductListedV1 } from '@/contexts/catalog/published-language/index';
26
26
  ```
27
27
 
28
28
  ## Details
@@ -0,0 +1,89 @@
1
+ # ddd-ts-kit/declarations-constructor-injection
2
+
3
+ Architecture id: `declarations/constructor-injection`. Default severity: `error` in `recommended`, `error` in `strict`.
4
+
5
+ Applies to: every role file of a context in a declared-style project (`stack.style: "declared"` in `ddd-ts-kit.config.json`), tests excluded. Nothing is reported in an explicit-style project, where the module file lists what each class is given.
6
+
7
+ ## Why
8
+
9
+ The constructor signature is the one statement of what a declared class depends on. `ddd-ts-kit docs` reads it and writes, in the generated file of the context, the list the composition root injects: nothing is repeated in the decorator, and nothing can disagree with the constructor. That only works when each parameter names exactly one injection token, and a token is a class: an interface, a type alias or a primitive is erased by the compiler; a union names two things; an optional or defaulted parameter says the container might give nothing, and it always gives a value.
10
+
11
+ The compiler is not asked for the types at run time. `emitDecoratorMetadata` exists only with legacy decorators compiled by `tsc` or by swc with its option: standard decorators have none, `tsx` and esbuild emit none, and a port imported with `import type` is recorded as `Object`.
12
+
13
+ ## Reported
14
+
15
+ On the class of a role file that carries a declaration decorator other than `@Requires` and `@Public`, when the decorator lists no dependency:
16
+
17
+ - a constructor parameter that is optional, has a default value, is a rest parameter or is destructured
18
+ - a constructor parameter without a type, or typed by anything but one class name, type arguments aside (`Cache<Session>` names `Cache`): a union, an intersection, an array, a function, a literal, an object type, a qualified name
19
+ - a constructor parameter typed by a type of the language (`string`, `number`, `Date`, `Map`...) or by an interface, a type alias or an enum the file declares
20
+
21
+ Under `"stack.dependencies": "signature"`, when the decorator carries a list and the class writes its constructor (or extends nothing):
22
+
23
+ - a list that names what the constructor is typed by, in order: it is redundant, and the fix removes it
24
+ - a list that differs from the constructor: it wins at run time, so the signature lies; no fix
25
+
26
+ Incorrect:
27
+
28
+ ```ts
29
+ @CommandHandler(IssueInvoiceCommand)
30
+ export class IssueInvoiceHandler implements CommandHandler<IssueInvoiceCommand> {
31
+ constructor(
32
+ private readonly invoices: InvoiceRepository | undefined,
33
+ private readonly retries = 3,
34
+ private readonly currency: string,
35
+ ) {}
36
+ }
37
+
38
+ // "stack.dependencies": "signature"
39
+ @CommandHandler(IssueInvoiceCommand, [InvoiceRepository, Clock])
40
+ export class IssueInvoiceHandler implements CommandHandler<IssueInvoiceCommand> {
41
+ constructor(
42
+ private readonly invoices: InvoiceRepository,
43
+ private readonly clock: Clock,
44
+ ) {}
45
+ }
46
+ ```
47
+
48
+ Correct:
49
+
50
+ ```ts
51
+ import type { Clock } from '@ddd-ts-kit/kernel';
52
+ import { CommandHandler } from '@ddd-ts-kit/kernel/declarations';
53
+ import type { InvoiceSettings } from '@/contexts/billing/application/ports/invoice-settings.port';
54
+ import type { InvoiceRepository } from '@/contexts/billing/domain/repositories/invoice.repository';
55
+
56
+ @CommandHandler(IssueInvoiceCommand)
57
+ export class IssueInvoiceHandler implements CommandHandler<IssueInvoiceCommand> {
58
+ constructor(
59
+ private readonly invoices: InvoiceRepository,
60
+ private readonly settings: InvoiceSettings, // an abstract class with readonly members, bound to a value in the platform
61
+ private readonly clock: Clock,
62
+ ) {}
63
+ }
64
+ ```
65
+
66
+ ## Details
67
+
68
+ A parameter decorator of another library and the modifiers `public`, `private`, `protected`, `readonly` and `override` are looked through. A class that writes no constructor and extends nothing takes nothing.
69
+
70
+ The fix of a redundant list removes the list and the comma before it: `@CommandHandler(IssueInvoiceCommand, [InvoiceRepository, Clock])` becomes `@CommandHandler(IssueInvoiceCommand)`. It is the codemod that moves a project to `"stack.dependencies": "signature"`: set the key, run `eslint --fix`, then `ddd-ts-kit docs`, which registers in the generated file of each context what the constructors take. A port that now only types a parameter may be imported with `import type`, which `@typescript-eslint/consistent-type-imports` fixes in a project compiled without `emitDecoratorMetadata`.
71
+
72
+ A project whose config does not say, or says `"stack.dependencies": "listed"`, lists its dependencies in its decorators as 0.1 did: its lists are never reported, and a class of it that lists nothing is held to the same rules about its parameters.
73
+
74
+ ## Options
75
+
76
+ None.
77
+
78
+ `rules."declarations/constructor-injection"` in `ddd-ts-kit.config.json` set to `off` silences the rule, and `// ddd-ts-kit-disable-next-line declarations/constructor-injection -- <reason>` silences one line, exactly as for `ddd-ts-kit check`.
79
+
80
+ ## Limits
81
+
82
+ - An interface, a type alias or an enum imported from another file is not known to be one here: `ddd-ts-kit check` reads the imported file of the project and reports it. A name imported from a package is trusted, and the compiler judges the generated file, which imports it as a value.
83
+ - A class that inherits its constructor is not judged here: `ddd-ts-kit check` follows the base class through the project and reports one it cannot read (a class of a package).
84
+ - That the generated file registers the list of the current constructor is `declarations/barrel-current` of `ddd-ts-kit check`: it is a fact of the project, not of one file.
85
+ - That a parameter is typed by a port and not by an adapter or a fake is `layer/application-inward` and `ports/no-concrete-dependency`.
86
+
87
+ ## With the CLI checker
88
+
89
+ `ddd-ts-kit check` reports the same id from the text of the files, across files, and stays the fast edit-time guard. This rule is the authority on what one file shows, and the only one that fixes.
@@ -22,7 +22,7 @@ On any class of `application/`, `infrastructure/`, `presentation/` or the contex
22
22
 
23
23
  Under `domain/`:
24
24
 
25
- - a class carrying any declaration decorator: `Requires`, `Public`, `CommandHandler`, `QueryHandler`, `IntegrationEventHandler`, `DomainEventHandler`, `Scheduled`, `Repository`, `Gateway`, `Adapter`, `Policy`
25
+ - a class carrying any declaration decorator: `Requires`, `Public`, `CommandHandler`, `QueryHandler`, `IntegrationEventHandler`, `DomainEventHandler`, `Scheduled`, `Projection`, `Repository`, `Gateway`, `Adapter`, `Policy`
26
26
 
27
27
  | File, relative to the context | Exported class carries |
28
28
  |---|---|
@@ -33,6 +33,7 @@ Under `domain/`:
33
33
  | `application/integration/publishers/**/*.publisher.ts` | `@DomainEventHandler` |
34
34
  | `application/authorization/**/*.policy.ts` | `@Policy` |
35
35
  | `application/scheduling/**/*.job.ts` | `@Scheduled` |
36
+ | `application/projections/**/*.projection.ts` | `@Projection` |
36
37
  | `infrastructure/persistence/**/*.repository.ts` | `@Repository` |
37
38
  | `infrastructure/**/*.gateway.ts` | `@Gateway` |
38
39
  | `infrastructure/**/*.adapter.ts` | `@Adapter` |
@@ -44,7 +45,7 @@ Incorrect:
44
45
  export class IssueInvoiceHandler {}
45
46
 
46
47
  // application/queries/search-invoices/search-invoices.handler.ts
47
- @CommandHandler(SearchInvoicesQuery, [InvoiceReader])
48
+ @CommandHandler(SearchInvoicesQuery)
48
49
  export class SearchInvoicesHandler {}
49
50
 
50
51
  // application/authorization/only-issuer-voids.policy.ts
@@ -64,12 +65,17 @@ Correct:
64
65
 
65
66
  ```ts
66
67
  // application/commands/issue-invoice/issue-invoice.handler.ts
67
- import { Clock } from '@ddd-ts-kit/kernel';
68
+ import type { Clock } from '@ddd-ts-kit/kernel';
68
69
  import { CommandHandler } from '@ddd-ts-kit/kernel/declarations';
69
- import { InvoiceRepository } from '@/contexts/billing/domain/repositories/invoice.repository.js';
70
+ import type { InvoiceRepository } from '@/contexts/billing/domain/repositories/invoice.repository';
70
71
 
71
- @CommandHandler(IssueInvoiceCommand, [InvoiceRepository, Clock])
72
- export class IssueInvoiceHandler implements CommandHandler<IssueInvoiceCommand> {}
72
+ @CommandHandler(IssueInvoiceCommand)
73
+ export class IssueInvoiceHandler implements CommandHandler<IssueInvoiceCommand> {
74
+ constructor(
75
+ private readonly invoices: InvoiceRepository,
76
+ private readonly clock: Clock,
77
+ ) {}
78
+ }
73
79
 
74
80
  // application/authorization/only-issuer-voids.policy.ts
75
81
  @Policy(billingPermissions['invoice.void'], { name: 'billing.only-issuer-voids' })
@@ -82,7 +88,7 @@ export class InvoiceIssuedEventHandler {}
82
88
 
83
89
  ## Details
84
90
 
85
- A decorator counts when its name is one of the ten declaration decorators and that name is imported from `@ddd-ts-kit/kernel/declarations` in the file: `{ Repository }`, an alias `{ Repository as Repo }`, or a namespace `declarations.Repository`. A home-made decorator of the same name, or one of another package (`@Retry` of `@ddd-ts-kit/aspects/decorators`), is ignored.
91
+ A decorator counts when its name is one of the twelve declaration decorators and that name is imported from `@ddd-ts-kit/kernel/declarations` in the file: `{ Repository }`, an alias `{ Repository as Repo }`, or a namespace `declarations.Repository`. A home-made decorator of the same name, or one of another package (`@Retry` of `@ddd-ts-kit/aspects/decorators`), is ignored.
86
92
 
87
93
  The role of a file is read from its suffix and its folder, as the generator writes them. A class is exported inline, by `export { A }` or by `export default A`. When a class carries another declaration decorator, only that is reported: fixing it also answers the missing one.
88
94
 
@@ -96,9 +102,9 @@ None.
96
102
 
97
103
  ## Limits
98
104
 
99
- - An event class reached through a barrel (`@/contexts/billing/domain/events/index.js`), a renaming export, a default import or a namespace is not followed: its name is not compared. `ddd-ts-kit check` resolves the same import in the project.
105
+ - An event class reached through a barrel (`@/contexts/billing/domain/events/index`), a renaming export, a default import or a namespace is not followed: its name is not compared. `ddd-ts-kit check` resolves the same import in the project.
100
106
  - A decorator applied through a variable (`const declare = Repository(InvoiceRepository); @declare class ...`) is not recognised.
101
- - That the dependency list matches the constructor and that a handler handles its message is checked by the compiler, not here; that an adapter implements its port is `ports/implements-never-extends`, and where a job lives and what it is named are `scheduling/job-triggers-use-case` and `scheduling/job-name`.
107
+ - What a class is given is `declarations/constructor-injection`; that a list matches the constructor and that a handler handles its message is checked by the compiler, not here; that an adapter implements its port is `ports/implements-never-extends`, and where a job lives and what it is named are `scheduling/job-triggers-use-case` and `scheduling/job-name`.
102
108
  - That each role file holds a single declared class is `naming/one-concept-per-file` of `ddd-ts-kit check`.
103
109
  - That the generated barrel `<context>.declarations.ts` lists every role file is `declarations/barrel-current` of `ddd-ts-kit check`: it is a fact of the project, not of one file.
104
110
  - A role file written outside the folders of the table is not known to be one: `naming/suffix` and `tree/closed` of `ddd-ts-kit check` hold the tree.