@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.
- package/README.md +3 -1
- package/dist/project/config.d.ts +4 -0
- package/dist/project/config.d.ts.map +1 -1
- package/dist/project/is-judged.d.ts +5 -0
- package/dist/project/is-judged.d.ts.map +1 -0
- package/dist/project/is-judged.js +7 -0
- package/dist/project/is-judged.js.map +1 -0
- package/dist/project/parse-config.d.ts.map +1 -1
- package/dist/project/parse-config.js +4 -0
- package/dist/project/parse-config.js.map +1 -1
- package/dist/project/resolve-import.d.ts.map +1 -1
- package/dist/project/resolve-import.js +4 -1
- package/dist/project/resolve-import.js.map +1 -1
- package/dist/project/specifier-suffix.d.ts +6 -0
- package/dist/project/specifier-suffix.d.ts.map +1 -0
- package/dist/project/specifier-suffix.js +8 -0
- package/dist/project/specifier-suffix.js.map +1 -0
- package/dist/project/to-alias.d.ts +3 -2
- package/dist/project/to-alias.d.ts.map +1 -1
- package/dist/project/to-alias.js +4 -3
- package/dist/project/to-alias.js.map +1 -1
- package/dist/rules/clean-one-export-per-file.js +7 -3
- package/dist/rules/clean-one-export-per-file.js.map +1 -1
- package/dist/rules/declarations-constructor-injection.d.ts +5 -0
- package/dist/rules/declarations-constructor-injection.d.ts.map +1 -0
- package/dist/rules/declarations-constructor-injection.js +80 -0
- package/dist/rules/declarations-constructor-injection.js.map +1 -0
- package/dist/rules/imports-alias-only.d.ts.map +1 -1
- package/dist/rules/imports-alias-only.js +7 -9
- package/dist/rules/imports-alias-only.js.map +1 -1
- package/dist/rules/imports-extension.d.ts +5 -0
- package/dist/rules/imports-extension.d.ts.map +1 -0
- package/dist/rules/imports-extension.js +45 -0
- package/dist/rules/imports-extension.js.map +1 -0
- package/dist/rules/ports-no-concrete-dependency.d.ts +3 -1
- package/dist/rules/ports-no-concrete-dependency.d.ts.map +1 -1
- package/dist/rules/ports-no-concrete-dependency.js +51 -3
- package/dist/rules/ports-no-concrete-dependency.js.map +1 -1
- package/dist/rules/rules.d.ts.map +1 -1
- package/dist/rules/rules.js +4 -0
- package/dist/rules/rules.js.map +1 -1
- package/dist/support/declarations/declared-roles.d.ts.map +1 -1
- package/dist/support/declarations/declared-roles.js +1 -0
- package/dist/support/declarations/declared-roles.js.map +1 -1
- package/dist/support/injection/language-types.d.ts +3 -0
- package/dist/support/injection/language-types.d.ts.map +1 -0
- package/dist/support/injection/language-types.js +20 -0
- package/dist/support/injection/language-types.js.map +1 -0
- package/dist/support/injection/not-classes.d.ts +4 -0
- package/dist/support/injection/not-classes.d.ts.map +1 -0
- package/dist/support/injection/not-classes.js +20 -0
- package/dist/support/injection/not-classes.js.map +1 -0
- package/dist/support/injection/parameter-reading.d.ts +9 -0
- package/dist/support/injection/parameter-reading.d.ts.map +1 -0
- package/dist/support/injection/parameter-reading.js +2 -0
- package/dist/support/injection/parameter-reading.js.map +1 -0
- package/dist/support/injection/read-parameter.d.ts +9 -0
- package/dist/support/injection/read-parameter.d.ts.map +1 -0
- package/dist/support/injection/read-parameter.js +41 -0
- package/dist/support/injection/read-parameter.js.map +1 -0
- package/dist/support/injection/written-name.d.ts +4 -0
- package/dist/support/injection/written-name.d.ts.map +1 -0
- package/dist/support/injection/written-name.js +13 -0
- package/dist/support/injection/written-name.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/rules/clean-one-export-per-file.md +1 -1
- package/docs/rules/context-declared-relationship.md +2 -2
- package/docs/rules/context-extractable.md +3 -3
- package/docs/rules/context-published-language-is-a-contract.md +1 -1
- package/docs/rules/context-published-language-only.md +2 -2
- package/docs/rules/declarations-constructor-injection.md +89 -0
- package/docs/rules/declarations-role-declared.md +15 -9
- package/docs/rules/domain-events-transactional-before-commit.md +1 -1
- package/docs/rules/imports-alias-only.md +10 -9
- package/docs/rules/imports-extension.md +83 -0
- package/docs/rules/layer-application-inward.md +3 -3
- package/docs/rules/layer-domain-purity.md +3 -3
- package/docs/rules/layer-infrastructure-no-presentation.md +2 -2
- package/docs/rules/layer-presentation-no-infrastructure.md +2 -2
- package/docs/rules/ports-no-concrete-dependency.md +4 -3
- package/docs/rules/test-no-mocks.md +1 -1
- package/package.json +1 -1
|
@@ -1,24 +1,72 @@
|
|
|
1
|
-
import {
|
|
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
|
|
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
|
-
|
|
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":"
|
|
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;
|
|
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"}
|
package/dist/rules/rules.js
CHANGED
|
@@ -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]));
|
package/dist/rules/rules.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/rules/rules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAgB,MAAM,4BAA4B,CAAC;AAClE,OAAO,EAAE,iCAAiC,EAAE,MAAM,2CAA2C,CAAC;AAC9F,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EACL,2BAA2B,EAC3B,mCAAmC,EACnC,4BAA4B,GAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,4BAA4B,EAAE,MAAM,qCAAqC,CAAC;AACnF,OAAO,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AACrF,OAAO,EAAE,qCAAqC,EAAE,MAAM,gDAAgD,CAAC;AACvG,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AACtF,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,iCAAiC,EAAE,iCAAiC,EAAE,MAAM,qBAAqB,CAAC;AAC3G,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,uCAAuC,CAAC;AACrF,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE,MAAM,GAAG,GAAG;IACV,iBAAiB;IACjB,sBAAsB;IACtB,iCAAiC;IACjC,iCAAiC;IACjC,4BAA4B;IAC5B,2BAA2B;IAC3B,mCAAmC;IACnC,mBAAmB;IACnB,yBAAyB;IACzB,mBAAmB;IACnB,aAAa;IACb,iBAAiB;IACjB,oBAAoB;IACpB,mBAAmB;IACnB,uBAAuB;IACvB,mBAAmB;IACnB,kBAAkB;IAClB,kBAAkB;IAClB,qBAAqB;IACrB,aAAa;IACb,4BAA4B;IAC5B,6BAA6B;IAC7B,oBAAoB;IACpB,uBAAuB;IACvB,iCAAiC;IACjC,4BAA4B;IAC5B,qCAAqC;IACrC,WAAW;IACX,gBAAgB;IAChB,oBAAoB;IACpB,wBAAwB;IACxB,kBAAkB;IAClB,aAAa;IACb,kBAAkB;IAClB,kBAAkB;IAClB,gBAAgB;IAChB,mBAAmB;IACnB,2BAA2B;IAC3B,2BAA2B;IAC3B,wBAAwB;IACxB,kBAAkB;IAClB,2BAA2B;IAC3B,oBAAoB;IACpB,yBAAyB;IACzB,gBAAgB;IAChB,4BAA4B;IAC5B,iBAAiB;IACjB,gBAAgB;CACjB,CAAC;AAEF,+HAA+H;AAC/H,MAAM,CAAC,MAAM,KAAK,GAAsC,MAAM,CAAC,WAAW,CACxE,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAC7C,CAAC"}
|
|
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,
|
|
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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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
|
+
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
|
+
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
70
|
+
import type { InvoiceRepository } from '@/contexts/billing/domain/repositories/invoice.repository';
|
|
70
71
|
|
|
71
|
-
@CommandHandler(IssueInvoiceCommand
|
|
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
|
|
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
|
|
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
|
-
-
|
|
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.
|