@ddd-ts-kit/eslint-plugin 0.0.0-stage → 0.1.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 +292 -2
- package/dist/ddd-ts-kit.d.ts +5 -0
- package/dist/ddd-ts-kit.d.ts.map +1 -0
- package/dist/ddd-ts-kit.js +7 -0
- package/dist/ddd-ts-kit.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin.d.ts +11 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +30 -0
- package/dist/plugin.js.map +1 -0
- package/dist/presets/braces-rules.d.ts +11 -0
- package/dist/presets/braces-rules.d.ts.map +1 -0
- package/dist/presets/braces-rules.js +10 -0
- package/dist/presets/braces-rules.js.map +1 -0
- package/dist/presets/create-ddd-ts-kit.d.ts +21 -0
- package/dist/presets/create-ddd-ts-kit.d.ts.map +1 -0
- package/dist/presets/create-ddd-ts-kit.js +123 -0
- package/dist/presets/create-ddd-ts-kit.js.map +1 -0
- package/dist/presets/flat-rules.d.ts +3 -0
- package/dist/presets/flat-rules.d.ts.map +1 -0
- package/dist/presets/flat-rules.js +2 -0
- package/dist/presets/flat-rules.js.map +1 -0
- package/dist/presets/layout-rules.d.ts +11 -0
- package/dist/presets/layout-rules.d.ts.map +1 -0
- package/dist/presets/layout-rules.js +33 -0
- package/dist/presets/layout-rules.js.map +1 -0
- package/dist/presets/plugin-rule-levels.d.ts +4 -0
- package/dist/presets/plugin-rule-levels.d.ts.map +1 -0
- package/dist/presets/plugin-rule-levels.js +13 -0
- package/dist/presets/plugin-rule-levels.js.map +1 -0
- package/dist/presets/standard-rule-sets.d.ts +12 -0
- package/dist/presets/standard-rule-sets.d.ts.map +1 -0
- package/dist/presets/standard-rule-sets.js +15 -0
- package/dist/presets/standard-rule-sets.js.map +1 -0
- package/dist/presets/standard-rules.d.ts +24 -0
- package/dist/presets/standard-rules.d.ts.map +1 -0
- package/dist/presets/standard-rules.js +88 -0
- package/dist/presets/standard-rules.js.map +1 -0
- package/dist/project/alias-root.d.ts +8 -0
- package/dist/project/alias-root.d.ts.map +1 -0
- package/dist/project/alias-root.js +2 -0
- package/dist/project/alias-root.js.map +1 -0
- package/dist/project/alias-roots.d.ts +9 -0
- package/dist/project/alias-roots.d.ts.map +1 -0
- package/dist/project/alias-roots.js +17 -0
- package/dist/project/alias-roots.js.map +1 -0
- package/dist/project/config-file.d.ts +2 -0
- package/dist/project/config-file.d.ts.map +1 -0
- package/dist/project/config-file.js +2 -0
- package/dist/project/config-file.js.map +1 -0
- package/dist/project/config.d.ts +53 -0
- package/dist/project/config.d.ts.map +1 -0
- package/dist/project/config.js +2 -0
- package/dist/project/config.js.map +1 -0
- package/dist/project/configured-severity.d.ts +3 -0
- package/dist/project/configured-severity.d.ts.map +1 -0
- package/dist/project/configured-severity.js +5 -0
- package/dist/project/configured-severity.js.map +1 -0
- package/dist/project/describe-linted-file.d.ts +4 -0
- package/dist/project/describe-linted-file.d.ts.map +1 -0
- package/dist/project/describe-linted-file.js +38 -0
- package/dist/project/describe-linted-file.js.map +1 -0
- package/dist/project/find-project.d.ts +4 -0
- package/dist/project/find-project.d.ts.map +1 -0
- package/dist/project/find-project.js +37 -0
- package/dist/project/find-project.js.map +1 -0
- package/dist/project/is-record.d.ts +2 -0
- package/dist/project/is-record.d.ts.map +1 -0
- package/dist/project/is-record.js +4 -0
- package/dist/project/is-record.js.map +1 -0
- package/dist/project/is-test-file.d.ts +3 -0
- package/dist/project/is-test-file.d.ts.map +1 -0
- package/dist/project/is-test-file.js +4 -0
- package/dist/project/is-test-file.js.map +1 -0
- package/dist/project/layer.d.ts +2 -0
- package/dist/project/layer.d.ts.map +1 -0
- package/dist/project/layer.js +2 -0
- package/dist/project/layer.js.map +1 -0
- package/dist/project/lint-host.d.ts +6 -0
- package/dist/project/lint-host.d.ts.map +1 -0
- package/dist/project/lint-host.js +2 -0
- package/dist/project/lint-host.js.map +1 -0
- package/dist/project/linted-file.d.ts +13 -0
- package/dist/project/linted-file.d.ts.map +1 -0
- package/dist/project/linted-file.js +2 -0
- package/dist/project/linted-file.js.map +1 -0
- package/dist/project/locate.d.ts +5 -0
- package/dist/project/locate.d.ts.map +1 -0
- package/dist/project/locate.js +47 -0
- package/dist/project/locate.js.map +1 -0
- package/dist/project/location.d.ts +11 -0
- package/dist/project/location.d.ts.map +1 -0
- package/dist/project/location.js +2 -0
- package/dist/project/location.js.map +1 -0
- package/dist/project/parse-allowed-file.d.ts +4 -0
- package/dist/project/parse-allowed-file.d.ts.map +1 -0
- package/dist/project/parse-allowed-file.js +11 -0
- package/dist/project/parse-allowed-file.js.map +1 -0
- package/dist/project/parse-config.d.ts +10 -0
- package/dist/project/parse-config.d.ts.map +1 -0
- package/dist/project/parse-config.js +113 -0
- package/dist/project/parse-config.js.map +1 -0
- package/dist/project/plugin-settings.d.ts +8 -0
- package/dist/project/plugin-settings.d.ts.map +1 -0
- package/dist/project/plugin-settings.js +2 -0
- package/dist/project/plugin-settings.js.map +1 -0
- package/dist/project/posix.d.ts +2 -0
- package/dist/project/posix.d.ts.map +1 -0
- package/dist/project/posix.js +4 -0
- package/dist/project/posix.js.map +1 -0
- package/dist/project/resolve-import.d.ts +15 -0
- package/dist/project/resolve-import.d.ts.map +1 -0
- package/dist/project/resolve-import.js +32 -0
- package/dist/project/resolve-import.js.map +1 -0
- package/dist/project/to-alias.d.ts +7 -0
- package/dist/project/to-alias.d.ts.map +1 -0
- package/dist/project/to-alias.js +13 -0
- package/dist/project/to-alias.js.map +1 -0
- package/dist/project/to-posix.d.ts +2 -0
- package/dist/project/to-posix.d.ts.map +1 -0
- package/dist/project/to-posix.js +5 -0
- package/dist/project/to-posix.js.map +1 -0
- package/dist/rules/application-command-query-separation.d.ts +6 -0
- package/dist/rules/application-command-query-separation.d.ts.map +1 -0
- package/dist/rules/application-command-query-separation.js +49 -0
- package/dist/rules/application-command-query-separation.js.map +1 -0
- package/dist/rules/application-handler-shape.d.ts +4 -0
- package/dist/rules/application-handler-shape.d.ts.map +1 -0
- package/dist/rules/application-handler-shape.js +51 -0
- package/dist/rules/application-handler-shape.js.map +1 -0
- package/dist/rules/aspects-outside-in.d.ts +2 -0
- package/dist/rules/aspects-outside-in.d.ts.map +1 -0
- package/dist/rules/aspects-outside-in.js +45 -0
- package/dist/rules/aspects-outside-in.js.map +1 -0
- package/dist/rules/authz-actor-explicit.d.ts +5 -0
- package/dist/rules/authz-actor-explicit.d.ts.map +1 -0
- package/dist/rules/authz-actor-explicit.js +106 -0
- package/dist/rules/authz-actor-explicit.js.map +1 -0
- package/dist/rules/authz-declared.d.ts +5 -0
- package/dist/rules/authz-declared.d.ts.map +1 -0
- package/dist/rules/authz-declared.js +167 -0
- package/dist/rules/authz-declared.js.map +1 -0
- package/dist/rules/authz-in-application.d.ts +5 -0
- package/dist/rules/authz-in-application.d.ts.map +1 -0
- package/dist/rules/authz-in-application.js +202 -0
- package/dist/rules/authz-in-application.js.map +1 -0
- package/dist/rules/clean-file-size.d.ts +2 -0
- package/dist/rules/clean-file-size.d.ts.map +1 -0
- package/dist/rules/clean-file-size.js +25 -0
- package/dist/rules/clean-file-size.js.map +1 -0
- package/dist/rules/clean-function-ceiling.d.ts +6 -0
- package/dist/rules/clean-function-ceiling.d.ts.map +1 -0
- package/dist/rules/clean-function-ceiling.js +32 -0
- package/dist/rules/clean-function-ceiling.js.map +1 -0
- package/dist/rules/clean-function-size.d.ts +7 -0
- package/dist/rules/clean-function-size.d.ts.map +1 -0
- package/dist/rules/clean-function-size.js +70 -0
- package/dist/rules/clean-function-size.js.map +1 -0
- package/dist/rules/clean-no-commented-out-code.d.ts +3 -0
- package/dist/rules/clean-no-commented-out-code.d.ts.map +1 -0
- package/dist/rules/clean-no-commented-out-code.js +60 -0
- package/dist/rules/clean-no-commented-out-code.js.map +1 -0
- package/dist/rules/clean-no-escape-hatch.d.ts +15 -0
- package/dist/rules/clean-no-escape-hatch.d.ts.map +1 -0
- package/dist/rules/clean-no-escape-hatch.js +116 -0
- package/dist/rules/clean-no-escape-hatch.js.map +1 -0
- package/dist/rules/clean-no-flag-argument.d.ts +2 -0
- package/dist/rules/clean-no-flag-argument.d.ts.map +1 -0
- package/dist/rules/clean-no-flag-argument.js +80 -0
- package/dist/rules/clean-no-flag-argument.js.map +1 -0
- package/dist/rules/clean-no-hash-private.d.ts +2 -0
- package/dist/rules/clean-no-hash-private.d.ts.map +1 -0
- package/dist/rules/clean-no-hash-private.js +36 -0
- package/dist/rules/clean-no-hash-private.js.map +1 -0
- package/dist/rules/clean-no-noise-comment.d.ts +5 -0
- package/dist/rules/clean-no-noise-comment.d.ts.map +1 -0
- package/dist/rules/clean-no-noise-comment.js +187 -0
- package/dist/rules/clean-no-noise-comment.js.map +1 -0
- package/dist/rules/clean-one-export-per-file.d.ts +10 -0
- package/dist/rules/clean-one-export-per-file.d.ts.map +1 -0
- package/dist/rules/clean-one-export-per-file.js +124 -0
- package/dist/rules/clean-one-export-per-file.js.map +1 -0
- package/dist/rules/clean-stepdown.d.ts +3 -0
- package/dist/rules/clean-stepdown.d.ts.map +1 -0
- package/dist/rules/clean-stepdown.js +33 -0
- package/dist/rules/clean-stepdown.js.map +1 -0
- package/dist/rules/context-boundaries.d.ts +4 -0
- package/dist/rules/context-boundaries.d.ts.map +1 -0
- package/dist/rules/context-boundaries.js +87 -0
- package/dist/rules/context-boundaries.js.map +1 -0
- package/dist/rules/context-extractable.d.ts +5 -0
- package/dist/rules/context-extractable.d.ts.map +1 -0
- package/dist/rules/context-extractable.js +242 -0
- package/dist/rules/context-extractable.js.map +1 -0
- package/dist/rules/declarations-role-declared.d.ts +5 -0
- package/dist/rules/declarations-role-declared.d.ts.map +1 -0
- package/dist/rules/declarations-role-declared.js +142 -0
- package/dist/rules/declarations-role-declared.js.map +1 -0
- package/dist/rules/domain-aggregate-encapsulation.d.ts +4 -0
- package/dist/rules/domain-aggregate-encapsulation.d.ts.map +1 -0
- package/dist/rules/domain-aggregate-encapsulation.js +93 -0
- package/dist/rules/domain-aggregate-encapsulation.js.map +1 -0
- package/dist/rules/domain-events-dispatched-on-save.d.ts +3 -0
- package/dist/rules/domain-events-dispatched-on-save.d.ts.map +1 -0
- package/dist/rules/domain-events-dispatched-on-save.js +87 -0
- package/dist/rules/domain-events-dispatched-on-save.js.map +1 -0
- package/dist/rules/domain-events-transactional-before-commit.d.ts +4 -0
- package/dist/rules/domain-events-transactional-before-commit.d.ts.map +1 -0
- package/dist/rules/domain-events-transactional-before-commit.js +121 -0
- package/dist/rules/domain-events-transactional-before-commit.js.map +1 -0
- package/dist/rules/domain-no-generic-error.d.ts +2 -0
- package/dist/rules/domain-no-generic-error.d.ts.map +1 -0
- package/dist/rules/domain-no-generic-error.js +32 -0
- package/dist/rules/domain-no-generic-error.js.map +1 -0
- package/dist/rules/domain-value-object-immutability.d.ts +4 -0
- package/dist/rules/domain-value-object-immutability.d.ts.map +1 -0
- package/dist/rules/domain-value-object-immutability.js +77 -0
- package/dist/rules/domain-value-object-immutability.js.map +1 -0
- package/dist/rules/events-consumer-idempotent.d.ts +5 -0
- package/dist/rules/events-consumer-idempotent.d.ts.map +1 -0
- package/dist/rules/events-consumer-idempotent.js +115 -0
- package/dist/rules/events-consumer-idempotent.js.map +1 -0
- package/dist/rules/events-name-format.d.ts +2 -0
- package/dist/rules/events-name-format.d.ts.map +1 -0
- package/dist/rules/events-name-format.js +53 -0
- package/dist/rules/events-name-format.js.map +1 -0
- package/dist/rules/events-outbox-required.d.ts +7 -0
- package/dist/rules/events-outbox-required.d.ts.map +1 -0
- package/dist/rules/events-outbox-required.js +82 -0
- package/dist/rules/events-outbox-required.js.map +1 -0
- package/dist/rules/governance-recorded-deviation.d.ts +2 -0
- package/dist/rules/governance-recorded-deviation.d.ts.map +1 -0
- package/dist/rules/governance-recorded-deviation.js +73 -0
- package/dist/rules/governance-recorded-deviation.js.map +1 -0
- package/dist/rules/imports-alias-only.d.ts +5 -0
- package/dist/rules/imports-alias-only.d.ts.map +1 -0
- package/dist/rules/imports-alias-only.js +63 -0
- package/dist/rules/imports-alias-only.js.map +1 -0
- package/dist/rules/layer-application-inward.d.ts +2 -0
- package/dist/rules/layer-application-inward.d.ts.map +1 -0
- package/dist/rules/layer-application-inward.js +66 -0
- package/dist/rules/layer-application-inward.js.map +1 -0
- package/dist/rules/layer-domain-purity.d.ts +4 -0
- package/dist/rules/layer-domain-purity.d.ts.map +1 -0
- package/dist/rules/layer-domain-purity.js +75 -0
- package/dist/rules/layer-domain-purity.js.map +1 -0
- package/dist/rules/layer-sideways.d.ts +3 -0
- package/dist/rules/layer-sideways.d.ts.map +1 -0
- package/dist/rules/layer-sideways.js +42 -0
- package/dist/rules/layer-sideways.js.map +1 -0
- package/dist/rules/ports-abstract-class.d.ts +2 -0
- package/dist/rules/ports-abstract-class.d.ts.map +1 -0
- package/dist/rules/ports-abstract-class.js +74 -0
- package/dist/rules/ports-abstract-class.js.map +1 -0
- package/dist/rules/ports-implements-never-extends.d.ts +5 -0
- package/dist/rules/ports-implements-never-extends.d.ts.map +1 -0
- package/dist/rules/ports-implements-never-extends.js +81 -0
- package/dist/rules/ports-implements-never-extends.js.map +1 -0
- package/dist/rules/ports-no-concrete-dependency.d.ts +2 -0
- package/dist/rules/ports-no-concrete-dependency.d.ts.map +1 -0
- package/dist/rules/ports-no-concrete-dependency.js +32 -0
- package/dist/rules/ports-no-concrete-dependency.js.map +1 -0
- package/dist/rules/ports-no-token-constant.d.ts +5 -0
- package/dist/rules/ports-no-token-constant.d.ts.map +1 -0
- package/dist/rules/ports-no-token-constant.js +109 -0
- package/dist/rules/ports-no-token-constant.js.map +1 -0
- package/dist/rules/ports-value-import.d.ts +3 -0
- package/dist/rules/ports-value-import.d.ts.map +1 -0
- package/dist/rules/ports-value-import.js +60 -0
- package/dist/rules/ports-value-import.js.map +1 -0
- package/dist/rules/purity.d.ts +4 -0
- package/dist/rules/purity.d.ts.map +1 -0
- package/dist/rules/purity.js +65 -0
- package/dist/rules/purity.js.map +1 -0
- package/dist/rules/rules.d.ts +4 -0
- package/dist/rules/rules.d.ts.map +1 -0
- package/dist/rules/rules.js +97 -0
- package/dist/rules/rules.js.map +1 -0
- package/dist/rules/scheduling-job-name.d.ts +5 -0
- package/dist/rules/scheduling-job-name.d.ts.map +1 -0
- package/dist/rules/scheduling-job-name.js +98 -0
- package/dist/rules/scheduling-job-name.js.map +1 -0
- package/dist/rules/scheduling-job-triggers-use-case.d.ts +5 -0
- package/dist/rules/scheduling-job-triggers-use-case.d.ts.map +1 -0
- package/dist/rules/scheduling-job-triggers-use-case.js +129 -0
- package/dist/rules/scheduling-job-triggers-use-case.js.map +1 -0
- package/dist/rules/standard-no-parallel-interface.d.ts +2 -0
- package/dist/rules/standard-no-parallel-interface.d.ts.map +1 -0
- package/dist/rules/standard-no-parallel-interface.js +57 -0
- package/dist/rules/standard-no-parallel-interface.js.map +1 -0
- package/dist/rules/test-no-mocks.d.ts +2 -0
- package/dist/rules/test-no-mocks.d.ts.map +1 -0
- package/dist/rules/test-no-mocks.js +50 -0
- package/dist/rules/test-no-mocks.js.map +1 -0
- package/dist/rules/tracing-platform-only.d.ts +2 -0
- package/dist/rules/tracing-platform-only.d.ts.map +1 -0
- package/dist/rules/tracing-platform-only.js +52 -0
- package/dist/rules/tracing-platform-only.js.map +1 -0
- package/dist/support/ancestors.d.ts +4 -0
- package/dist/support/ancestors.d.ts.map +1 -0
- package/dist/support/ancestors.js +7 -0
- package/dist/support/ancestors.js.map +1 -0
- package/dist/support/calls/accessed-name.d.ts +4 -0
- package/dist/support/calls/accessed-name.d.ts.map +1 -0
- package/dist/support/calls/accessed-name.js +14 -0
- package/dist/support/calls/accessed-name.js.map +1 -0
- package/dist/support/calls/callee-name.d.ts +4 -0
- package/dist/support/calls/callee-name.d.ts.map +1 -0
- package/dist/support/calls/callee-name.js +11 -0
- package/dist/support/calls/callee-name.js.map +1 -0
- package/dist/support/calls/has-spread.d.ts +4 -0
- package/dist/support/calls/has-spread.d.ts.map +1 -0
- package/dist/support/calls/has-spread.js +6 -0
- package/dist/support/calls/has-spread.js.map +1 -0
- package/dist/support/calls/method-chain.d.ts +8 -0
- package/dist/support/calls/method-chain.d.ts.map +1 -0
- package/dist/support/calls/method-chain.js +13 -0
- package/dist/support/calls/method-chain.js.map +1 -0
- package/dist/support/calls/missing-keys.d.ts +7 -0
- package/dist/support/calls/missing-keys.d.ts.map +1 -0
- package/dist/support/calls/missing-keys.js +28 -0
- package/dist/support/calls/missing-keys.js.map +1 -0
- package/dist/support/calls/property-of.d.ts +3 -0
- package/dist/support/calls/property-of.d.ts.map +1 -0
- package/dist/support/calls/property-of.js +8 -0
- package/dist/support/calls/property-of.js.map +1 -0
- package/dist/support/classes/class-finder.d.ts +18 -0
- package/dist/support/classes/class-finder.d.ts.map +1 -0
- package/dist/support/classes/class-finder.js +76 -0
- package/dist/support/classes/class-finder.js.map +1 -0
- package/dist/support/classes/class-name.d.ts +4 -0
- package/dist/support/classes/class-name.d.ts.map +1 -0
- package/dist/support/classes/class-name.js +4 -0
- package/dist/support/classes/class-name.js.map +1 -0
- package/dist/support/classes/constructor-of.d.ts +3 -0
- package/dist/support/classes/constructor-of.d.ts.map +1 -0
- package/dist/support/classes/constructor-of.js +5 -0
- package/dist/support/classes/constructor-of.js.map +1 -0
- package/dist/support/classes/enclosing-member.d.ts +8 -0
- package/dist/support/classes/enclosing-member.d.ts.map +1 -0
- package/dist/support/classes/enclosing-member.js +15 -0
- package/dist/support/classes/enclosing-member.js.map +1 -0
- package/dist/support/classes/exported-classes.d.ts +4 -0
- package/dist/support/classes/exported-classes.d.ts.map +1 -0
- package/dist/support/classes/exported-classes.js +22 -0
- package/dist/support/classes/exported-classes.js.map +1 -0
- package/dist/support/classes/is-callable.d.ts +4 -0
- package/dist/support/classes/is-callable.d.ts.map +1 -0
- package/dist/support/classes/is-callable.js +10 -0
- package/dist/support/classes/is-callable.js.map +1 -0
- package/dist/support/classes/is-constructor.d.ts +3 -0
- package/dist/support/classes/is-constructor.d.ts.map +1 -0
- package/dist/support/classes/is-constructor.js +5 -0
- package/dist/support/classes/is-constructor.js.map +1 -0
- package/dist/support/classes/is-function.d.ts +3 -0
- package/dist/support/classes/is-function.d.ts.map +1 -0
- package/dist/support/classes/is-function.js +5 -0
- package/dist/support/classes/is-function.js.map +1 -0
- package/dist/support/classes/is-inline-export.d.ts +3 -0
- package/dist/support/classes/is-inline-export.d.ts.map +1 -0
- package/dist/support/classes/is-inline-export.js +6 -0
- package/dist/support/classes/is-inline-export.js.map +1 -0
- package/dist/support/classes/is-keyed.d.ts +5 -0
- package/dist/support/classes/is-keyed.d.ts.map +1 -0
- package/dist/support/classes/is-keyed.js +5 -0
- package/dist/support/classes/is-keyed.js.map +1 -0
- package/dist/support/classes/key-name.d.ts +3 -0
- package/dist/support/classes/key-name.d.ts.map +1 -0
- package/dist/support/classes/key-name.js +11 -0
- package/dist/support/classes/key-name.js.map +1 -0
- package/dist/support/classes/member-name.d.ts +4 -0
- package/dist/support/classes/member-name.d.ts.map +1 -0
- package/dist/support/classes/member-name.js +7 -0
- package/dist/support/classes/member-name.js.map +1 -0
- package/dist/support/classes/top-level-classes.d.ts +4 -0
- package/dist/support/classes/top-level-classes.d.ts.map +1 -0
- package/dist/support/classes/top-level-classes.js +10 -0
- package/dist/support/classes/top-level-classes.js.map +1 -0
- package/dist/support/classes/visibility-of.d.ts +4 -0
- package/dist/support/classes/visibility-of.d.ts.map +1 -0
- package/dist/support/classes/visibility-of.js +12 -0
- package/dist/support/classes/visibility-of.js.map +1 -0
- package/dist/support/comments/comment-lines.d.ts +15 -0
- package/dist/support/comments/comment-lines.d.ts.map +1 -0
- package/dist/support/comments/comment-lines.js +47 -0
- package/dist/support/comments/comment-lines.js.map +1 -0
- package/dist/support/comments/is-commented-out-code.d.ts +6 -0
- package/dist/support/comments/is-commented-out-code.d.ts.map +1 -0
- package/dist/support/comments/is-commented-out-code.js +108 -0
- package/dist/support/comments/is-commented-out-code.js.map +1 -0
- package/dist/support/comments/is-directive.d.ts +3 -0
- package/dist/support/comments/is-directive.d.ts.map +1 -0
- package/dist/support/comments/is-directive.js +6 -0
- package/dist/support/comments/is-directive.js.map +1 -0
- package/dist/support/comments/is-fragment.d.ts +3 -0
- package/dist/support/comments/is-fragment.d.ts.map +1 -0
- package/dist/support/comments/is-fragment.js +18 -0
- package/dist/support/comments/is-fragment.js.map +1 -0
- package/dist/support/comments/is-jsdoc.d.ts +3 -0
- package/dist/support/comments/is-jsdoc.d.ts.map +1 -0
- package/dist/support/comments/is-jsdoc.js +5 -0
- package/dist/support/comments/is-jsdoc.js.map +1 -0
- package/dist/support/comments/prose-opening.d.ts +3 -0
- package/dist/support/comments/prose-opening.d.ts.map +1 -0
- package/dist/support/comments/prose-opening.js +3 -0
- package/dist/support/comments/prose-opening.js.map +1 -0
- package/dist/support/comments/reads-as-prose.d.ts +3 -0
- package/dist/support/comments/reads-as-prose.d.ts.map +1 -0
- package/dist/support/comments/reads-as-prose.js +7 -0
- package/dist/support/comments/reads-as-prose.js.map +1 -0
- package/dist/support/declarations/access-decorators.d.ts +3 -0
- package/dist/support/declarations/access-decorators.d.ts.map +1 -0
- package/dist/support/declarations/access-decorators.js +3 -0
- package/dist/support/declarations/access-decorators.js.map +1 -0
- package/dist/support/declarations/declaration-reader.d.ts +19 -0
- package/dist/support/declarations/declaration-reader.d.ts.map +1 -0
- package/dist/support/declarations/declaration-reader.js +46 -0
- package/dist/support/declarations/declaration-reader.js.map +1 -0
- package/dist/support/declarations/declared-role-of.d.ts +5 -0
- package/dist/support/declarations/declared-role-of.d.ts.map +1 -0
- package/dist/support/declarations/declared-role-of.js +12 -0
- package/dist/support/declarations/declared-role-of.js.map +1 -0
- package/dist/support/declarations/declared-role.d.ts +9 -0
- package/dist/support/declarations/declared-role.d.ts.map +1 -0
- package/dist/support/declarations/declared-role.js +2 -0
- package/dist/support/declarations/declared-role.js.map +1 -0
- package/dist/support/declarations/declared-roles.d.ts +4 -0
- package/dist/support/declarations/declared-roles.d.ts.map +1 -0
- package/dist/support/declarations/declared-roles.js +20 -0
- package/dist/support/declarations/declared-roles.js.map +1 -0
- package/dist/support/declarations/is-declared-style.d.ts +3 -0
- package/dist/support/declarations/is-declared-style.d.ts.map +1 -0
- package/dist/support/declarations/is-declared-style.js +4 -0
- package/dist/support/declarations/is-declared-style.js.map +1 -0
- package/dist/support/declarations/written-name.d.ts +11 -0
- package/dist/support/declarations/written-name.d.ts.map +1 -0
- package/dist/support/declarations/written-name.js +22 -0
- package/dist/support/declarations/written-name.js.map +1 -0
- package/dist/support/declarations/written-names.d.ts +3 -0
- package/dist/support/declarations/written-names.d.ts.map +1 -0
- package/dist/support/declarations/written-names.js +7 -0
- package/dist/support/declarations/written-names.js.map +1 -0
- package/dist/support/descendants.d.ts +4 -0
- package/dist/support/descendants.d.ts.map +1 -0
- package/dist/support/descendants.js +21 -0
- package/dist/support/descendants.js.map +1 -0
- package/dist/support/exports/derived-forms-of.d.ts +8 -0
- package/dist/support/exports/derived-forms-of.d.ts.map +1 -0
- package/dist/support/exports/derived-forms-of.js +23 -0
- package/dist/support/exports/derived-forms-of.js.map +1 -0
- package/dist/support/exports/explain-exports.d.ts +11 -0
- package/dist/support/exports/explain-exports.d.ts.map +1 -0
- package/dist/support/exports/explain-exports.js +60 -0
- package/dist/support/exports/explain-exports.js.map +1 -0
- package/dist/support/exports/export-explanation.d.ts +9 -0
- package/dist/support/exports/export-explanation.d.ts.map +1 -0
- package/dist/support/exports/export-explanation.js +2 -0
- package/dist/support/exports/export-explanation.js.map +1 -0
- package/dist/support/exports/is-named-after.d.ts +8 -0
- package/dist/support/exports/is-named-after.d.ts.map +1 -0
- package/dist/support/exports/is-named-after.js +16 -0
- package/dist/support/exports/is-named-after.js.map +1 -0
- package/dist/support/exports/module-shape-of.d.ts +4 -0
- package/dist/support/exports/module-shape-of.d.ts.map +1 -0
- package/dist/support/exports/module-shape-of.js +11 -0
- package/dist/support/exports/module-shape-of.js.map +1 -0
- package/dist/support/exports/module-shape.d.ts +10 -0
- package/dist/support/exports/module-shape.d.ts.map +1 -0
- package/dist/support/exports/module-shape.js +2 -0
- package/dist/support/exports/module-shape.js.map +1 -0
- package/dist/support/exports/shares-private-state.d.ts +11 -0
- package/dist/support/exports/shares-private-state.d.ts.map +1 -0
- package/dist/support/exports/shares-private-state.js +36 -0
- package/dist/support/exports/shares-private-state.js.map +1 -0
- package/dist/support/exports/signature-of.d.ts +8 -0
- package/dist/support/exports/signature-of.d.ts.map +1 -0
- package/dist/support/exports/signature-of.js +44 -0
- package/dist/support/exports/signature-of.js.map +1 -0
- package/dist/support/exports/top-level-declaration.d.ts +10 -0
- package/dist/support/exports/top-level-declaration.d.ts.map +1 -0
- package/dist/support/exports/top-level-declaration.js +2 -0
- package/dist/support/exports/top-level-declaration.js.map +1 -0
- package/dist/support/exports/top-level-declarations.d.ts +5 -0
- package/dist/support/exports/top-level-declarations.d.ts.map +1 -0
- package/dist/support/exports/top-level-declarations.js +48 -0
- package/dist/support/exports/top-level-declarations.js.map +1 -0
- package/dist/support/exports/type-closure.d.ts +5 -0
- package/dist/support/exports/type-closure.d.ts.map +1 -0
- package/dist/support/exports/type-closure.js +18 -0
- package/dist/support/exports/type-closure.js.map +1 -0
- package/dist/support/exports/type-family-of.d.ts +8 -0
- package/dist/support/exports/type-family-of.d.ts.map +1 -0
- package/dist/support/exports/type-family-of.js +43 -0
- package/dist/support/exports/type-family-of.js.map +1 -0
- package/dist/support/exports/type-names-in.d.ts +4 -0
- package/dist/support/exports/type-names-in.d.ts.map +1 -0
- package/dist/support/exports/type-names-in.js +21 -0
- package/dist/support/exports/type-names-in.js.map +1 -0
- package/dist/support/functions/code-lines.d.ts +5 -0
- package/dist/support/functions/code-lines.d.ts.map +1 -0
- package/dist/support/functions/code-lines.js +14 -0
- package/dist/support/functions/code-lines.js.map +1 -0
- package/dist/support/functions/described-function.d.ts +11 -0
- package/dist/support/functions/described-function.d.ts.map +1 -0
- package/dist/support/functions/described-function.js +9 -0
- package/dist/support/functions/described-function.js.map +1 -0
- package/dist/support/functions/function-node.d.ts +3 -0
- package/dist/support/functions/function-node.d.ts.map +1 -0
- package/dist/support/functions/function-node.js +2 -0
- package/dist/support/functions/function-node.js.map +1 -0
- package/dist/support/glob-matcher.d.ts +3 -0
- package/dist/support/glob-matcher.d.ts.map +1 -0
- package/dist/support/glob-matcher.js +8 -0
- package/dist/support/glob-matcher.js.map +1 -0
- package/dist/support/globals/ambient-name.d.ts +8 -0
- package/dist/support/globals/ambient-name.d.ts.map +1 -0
- package/dist/support/globals/ambient-name.js +26 -0
- package/dist/support/globals/ambient-name.js.map +1 -0
- package/dist/support/globals/property-name.d.ts +3 -0
- package/dist/support/globals/property-name.d.ts.map +1 -0
- package/dist/support/globals/property-name.js +10 -0
- package/dist/support/globals/property-name.js.map +1 -0
- package/dist/support/hash-private-fix.d.ts +12 -0
- package/dist/support/hash-private-fix.d.ts.map +1 -0
- package/dist/support/hash-private-fix.js +52 -0
- package/dist/support/hash-private-fix.js.map +1 -0
- package/dist/support/imports/describe-target.d.ts +3 -0
- package/dist/support/imports/describe-target.d.ts.map +1 -0
- package/dist/support/imports/describe-target.js +11 -0
- package/dist/support/imports/describe-target.js.map +1 -0
- package/dist/support/imports/import-listener.d.ts +23 -0
- package/dist/support/imports/import-listener.d.ts.map +1 -0
- package/dist/support/imports/import-listener.js +43 -0
- package/dist/support/imports/import-listener.js.map +1 -0
- package/dist/support/imports/in-context.d.ts +4 -0
- package/dist/support/imports/in-context.d.ts.map +1 -0
- package/dist/support/imports/in-context.js +4 -0
- package/dist/support/imports/in-context.js.map +1 -0
- package/dist/support/imports/in-layer.d.ts +5 -0
- package/dist/support/imports/in-layer.d.ts.map +1 -0
- package/dist/support/imports/in-layer.js +4 -0
- package/dist/support/imports/in-layer.js.map +1 -0
- package/dist/support/imports/in-source-root.d.ts +4 -0
- package/dist/support/imports/in-source-root.d.ts.map +1 -0
- package/dist/support/imports/in-source-root.js +5 -0
- package/dist/support/imports/in-source-root.js.map +1 -0
- package/dist/support/imports/inner-layer.d.ts +4 -0
- package/dist/support/imports/inner-layer.d.ts.map +1 -0
- package/dist/support/imports/inner-layer.js +9 -0
- package/dist/support/imports/inner-layer.js.map +1 -0
- package/dist/support/imports/static-string.d.ts +3 -0
- package/dist/support/imports/static-string.d.ts.map +1 -0
- package/dist/support/imports/static-string.js +11 -0
- package/dist/support/imports/static-string.js.map +1 -0
- package/dist/support/kebab-case.d.ts +7 -0
- package/dist/support/kebab-case.d.ts.map +1 -0
- package/dist/support/kebab-case.js +13 -0
- package/dist/support/kebab-case.js.map +1 -0
- package/dist/support/members/parameter-name.d.ts +3 -0
- package/dist/support/members/parameter-name.d.ts.map +1 -0
- package/dist/support/members/parameter-name.js +7 -0
- package/dist/support/members/parameter-name.js.map +1 -0
- package/dist/support/members/parameter-properties.d.ts +4 -0
- package/dist/support/members/parameter-properties.d.ts.map +1 -0
- package/dist/support/members/parameter-properties.js +6 -0
- package/dist/support/members/parameter-properties.js.map +1 -0
- package/dist/support/members/starts-at-this.d.ts +4 -0
- package/dist/support/members/starts-at-this.d.ts.map +1 -0
- package/dist/support/members/starts-at-this.js +10 -0
- package/dist/support/members/starts-at-this.js.map +1 -0
- package/dist/support/outside-concerns/outside-concern-message.d.ts +3 -0
- package/dist/support/outside-concerns/outside-concern-message.d.ts.map +1 -0
- package/dist/support/outside-concerns/outside-concern-message.js +3 -0
- package/dist/support/outside-concerns/outside-concern-message.js.map +1 -0
- package/dist/support/outside-concerns/outside-concern.d.ts +13 -0
- package/dist/support/outside-concerns/outside-concern.d.ts.map +1 -0
- package/dist/support/outside-concerns/outside-concern.js +31 -0
- package/dist/support/outside-concerns/outside-concern.js.map +1 -0
- package/dist/support/ports/binding-call-reader.d.ts +10 -0
- package/dist/support/ports/binding-call-reader.d.ts.map +1 -0
- package/dist/support/ports/binding-call-reader.js +25 -0
- package/dist/support/ports/binding-call-reader.js.map +1 -0
- package/dist/support/ports/dependency-list-listener.d.ts +10 -0
- package/dist/support/ports/dependency-list-listener.d.ts.map +1 -0
- package/dist/support/ports/dependency-list-listener.js +37 -0
- package/dist/support/ports/dependency-list-listener.js.map +1 -0
- package/dist/support/ports/imported-binding.d.ts +11 -0
- package/dist/support/ports/imported-binding.d.ts.map +1 -0
- package/dist/support/ports/imported-binding.js +2 -0
- package/dist/support/ports/imported-binding.js.map +1 -0
- package/dist/support/ports/imported-bindings.d.ts +6 -0
- package/dist/support/ports/imported-bindings.d.ts.map +1 -0
- package/dist/support/ports/imported-bindings.js +19 -0
- package/dist/support/ports/imported-bindings.js.map +1 -0
- package/dist/support/ports/is-port-file.d.ts +4 -0
- package/dist/support/ports/is-port-file.d.ts.map +1 -0
- package/dist/support/ports/is-port-file.js +13 -0
- package/dist/support/ports/is-port-file.js.map +1 -0
- package/dist/support/purity-rule.d.ts +19 -0
- package/dist/support/purity-rule.d.ts.map +1 -0
- package/dist/support/purity-rule.js +74 -0
- package/dist/support/purity-rule.js.map +1 -0
- package/dist/support/rule/define-rule.d.ts +30 -0
- package/dist/support/rule/define-rule.d.ts.map +1 -0
- package/dist/support/rule/define-rule.js +51 -0
- package/dist/support/rule/define-rule.js.map +1 -0
- package/dist/support/rule/docs-of.d.ts +6 -0
- package/dist/support/rule/docs-of.d.ts.map +1 -0
- package/dist/support/rule/docs-of.js +9 -0
- package/dist/support/rule/docs-of.js.map +1 -0
- package/dist/support/rule/rule-docs.d.ts +9 -0
- package/dist/support/rule/rule-docs.d.ts.map +1 -0
- package/dist/support/rule/rule-docs.js +2 -0
- package/dist/support/rule/rule-docs.js.map +1 -0
- package/dist/support/scheduling/is-job-file.d.ts +4 -0
- package/dist/support/scheduling/is-job-file.d.ts.map +1 -0
- package/dist/support/scheduling/is-job-file.js +11 -0
- package/dist/support/scheduling/is-job-file.js.map +1 -0
- package/dist/support/scheduling/registered-job.d.ts +11 -0
- package/dist/support/scheduling/registered-job.d.ts.map +1 -0
- package/dist/support/scheduling/registered-job.js +17 -0
- package/dist/support/scheduling/registered-job.js.map +1 -0
- package/dist/support/standard-interfaces/boundary-names.d.ts +3 -0
- package/dist/support/standard-interfaces/boundary-names.d.ts.map +1 -0
- package/dist/support/standard-interfaces/boundary-names.js +3 -0
- package/dist/support/standard-interfaces/boundary-names.js.map +1 -0
- package/dist/support/standard-interfaces/parallel-names.d.ts +4 -0
- package/dist/support/standard-interfaces/parallel-names.d.ts.map +1 -0
- package/dist/support/standard-interfaces/parallel-names.js +76 -0
- package/dist/support/standard-interfaces/parallel-names.js.map +1 -0
- package/dist/support/standard-interfaces/standard-names-in.d.ts +3 -0
- package/dist/support/standard-interfaces/standard-names-in.d.ts.map +1 -0
- package/dist/support/standard-interfaces/standard-names-in.js +5 -0
- package/dist/support/standard-interfaces/standard-names-in.js.map +1 -0
- package/dist/support/stepdown/call-graph.d.ts +8 -0
- package/dist/support/stepdown/call-graph.d.ts.map +1 -0
- package/dist/support/stepdown/call-graph.js +27 -0
- package/dist/support/stepdown/call-graph.js.map +1 -0
- package/dist/support/stepdown/member-use.d.ts +7 -0
- package/dist/support/stepdown/member-use.d.ts.map +1 -0
- package/dist/support/stepdown/member-use.js +2 -0
- package/dist/support/stepdown/member-use.js.map +1 -0
- package/dist/support/stepdown/member-uses.d.ts +9 -0
- package/dist/support/stepdown/member-uses.d.ts.map +1 -0
- package/dist/support/stepdown/member-uses.js +27 -0
- package/dist/support/stepdown/member-uses.js.map +1 -0
- package/dist/support/stepdown/misplaced-functions.d.ts +11 -0
- package/dist/support/stepdown/misplaced-functions.d.ts.map +1 -0
- package/dist/support/stepdown/misplaced-functions.js +80 -0
- package/dist/support/stepdown/misplaced-functions.js.map +1 -0
- package/dist/support/stepdown/misplaced-members.d.ts +10 -0
- package/dist/support/stepdown/misplaced-members.d.ts.map +1 -0
- package/dist/support/stepdown/misplaced-members.js +73 -0
- package/dist/support/stepdown/misplaced-members.js.map +1 -0
- package/dist/support/suppressions/shares-line-with-code.d.ts +3 -0
- package/dist/support/suppressions/shares-line-with-code.d.ts.map +1 -0
- package/dist/support/suppressions/shares-line-with-code.js +5 -0
- package/dist/support/suppressions/shares-line-with-code.js.map +1 -0
- package/dist/support/suppressions/suppressed-lines.d.ts +4 -0
- package/dist/support/suppressions/suppressed-lines.d.ts.map +1 -0
- package/dist/support/suppressions/suppressed-lines.js +17 -0
- package/dist/support/suppressions/suppressed-lines.js.map +1 -0
- package/dist/support/types/declared-type-name.d.ts +6 -0
- package/dist/support/types/declared-type-name.d.ts.map +1 -0
- package/dist/support/types/declared-type-name.js +33 -0
- package/dist/support/types/declared-type-name.js.map +1 -0
- package/dist/support/types/parameter-binding.d.ts +4 -0
- package/dist/support/types/parameter-binding.d.ts.map +1 -0
- package/dist/support/types/parameter-binding.js +7 -0
- package/dist/support/types/parameter-binding.js.map +1 -0
- package/dist/support/types/parameter-type-name.d.ts +3 -0
- package/dist/support/types/parameter-type-name.d.ts.map +1 -0
- package/dist/support/types/parameter-type-name.js +6 -0
- package/dist/support/types/parameter-type-name.js.map +1 -0
- package/dist/support/types/type-reference-name.d.ts +4 -0
- package/dist/support/types/type-reference-name.d.ts.map +1 -0
- package/dist/support/types/type-reference-name.js +14 -0
- package/dist/support/types/type-reference-name.js.map +1 -0
- package/dist/support/words/same-word.d.ts +3 -0
- package/dist/support/words/same-word.d.ts.map +1 -0
- package/dist/support/words/same-word.js +75 -0
- package/dist/support/words/same-word.js.map +1 -0
- package/dist/support/words/split-words.d.ts +3 -0
- package/dist/support/words/split-words.d.ts.map +1 -0
- package/dist/support/words/split-words.js +12 -0
- package/dist/support/words/split-words.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +2 -0
- package/dist/version.js.map +1 -0
- package/docs/rules/application-command-query-separation.md +54 -0
- package/docs/rules/application-handler-shape.md +52 -0
- package/docs/rules/aspects-outside-in.md +54 -0
- package/docs/rules/authz-actor-explicit.md +70 -0
- package/docs/rules/authz-declared.md +87 -0
- package/docs/rules/authz-in-application.md +88 -0
- package/docs/rules/clean-blank-lines.md +87 -0
- package/docs/rules/clean-braces.md +61 -0
- package/docs/rules/clean-file-size.md +43 -0
- package/docs/rules/clean-formatted.md +32 -0
- package/docs/rules/clean-function-ceiling.md +53 -0
- package/docs/rules/clean-function-size.md +45 -0
- package/docs/rules/clean-no-commented-out-code.md +48 -0
- package/docs/rules/clean-no-escape-hatch.md +80 -0
- package/docs/rules/clean-no-flag-argument.md +50 -0
- package/docs/rules/clean-no-hash-private.md +63 -0
- package/docs/rules/clean-no-noise-comment.md +55 -0
- package/docs/rules/clean-one-export-per-file.md +88 -0
- package/docs/rules/clean-stepdown.md +60 -0
- package/docs/rules/context-declared-relationship.md +49 -0
- package/docs/rules/context-extractable.md +109 -0
- package/docs/rules/context-published-language-is-a-contract.md +47 -0
- package/docs/rules/context-published-language-only.md +47 -0
- package/docs/rules/declarations-role-declared.md +109 -0
- package/docs/rules/domain-aggregate-encapsulation.md +63 -0
- package/docs/rules/domain-events-dispatched-on-save.md +83 -0
- package/docs/rules/domain-events-transactional-before-commit.md +92 -0
- package/docs/rules/domain-no-generic-error.md +40 -0
- package/docs/rules/domain-value-object-immutability.md +52 -0
- package/docs/rules/events-consumer-idempotent.md +68 -0
- package/docs/rules/events-name-format.md +50 -0
- package/docs/rules/events-outbox-required.md +57 -0
- package/docs/rules/governance-recorded-deviation.md +55 -0
- package/docs/rules/imports-alias-only.md +73 -0
- package/docs/rules/layer-application-inward.md +62 -0
- package/docs/rules/layer-domain-purity.md +60 -0
- package/docs/rules/layer-infrastructure-no-presentation.md +46 -0
- package/docs/rules/layer-presentation-no-infrastructure.md +46 -0
- package/docs/rules/ports-abstract-class.md +70 -0
- package/docs/rules/ports-implements-never-extends.md +53 -0
- package/docs/rules/ports-no-concrete-dependency.md +52 -0
- package/docs/rules/ports-no-token-constant.md +57 -0
- package/docs/rules/ports-value-import.md +55 -0
- package/docs/rules/purity-no-ambient-randomness.md +43 -0
- package/docs/rules/purity-no-environment.md +45 -0
- package/docs/rules/purity-no-system-clock.md +49 -0
- package/docs/rules/scheduling-job-name.md +57 -0
- package/docs/rules/scheduling-job-triggers-use-case.md +71 -0
- package/docs/rules/standard-no-parallel-interface.md +95 -0
- package/docs/rules/test-no-mocks.md +47 -0
- package/docs/rules/tracing-platform-only.md +65 -0
- package/package.json +56 -4
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# ddd-ts-kit/application-command-query-separation
|
|
2
|
+
|
|
3
|
+
Architecture id: `application/command-query-separation` (added by this plugin). Default severity: `warn` in `recommended`, `error` in `strict`.
|
|
4
|
+
|
|
5
|
+
Applies to: files under `application/queries/` of a context, tests excluded.
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
A query answers and never changes state: it can then be retried, cached and run on a replica. A query that saves is a command with a return value.
|
|
10
|
+
|
|
11
|
+
## Reported
|
|
12
|
+
|
|
13
|
+
- a call of `save`, `delete` or `publish` on something held by the handler (`this.invoices.save(...)`, `this.#bus.publish(...)`)
|
|
14
|
+
|
|
15
|
+
Incorrect:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
export class SearchInvoicesHandler {
|
|
19
|
+
async execute(query: SearchInvoicesQuery): Promise<SearchInvoicesResult> {
|
|
20
|
+
await this.audit.save(query);
|
|
21
|
+
return this.reader.read(query);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Correct:
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
export class SearchInvoicesHandler {
|
|
30
|
+
async execute(query: SearchInvoicesQuery): Promise<SearchInvoicesResult> {
|
|
31
|
+
return this.reader.read(query);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Details
|
|
37
|
+
|
|
38
|
+
Pragmatic by design: the rule matches method names on dependencies reached through `this`. A local `Set` whose `delete` is called is not reported.
|
|
39
|
+
|
|
40
|
+
## Options
|
|
41
|
+
|
|
42
|
+
`[{ "mutators": ["save", "delete", "publish"] }]` replaces the list of method names.
|
|
43
|
+
|
|
44
|
+
`rules."application/command-query-separation"` in `ddd-ts-kit.config.json` set to `off` silences the rule, and `// ddd-ts-kit-disable-next-line application/command-query-separation -- <reason>` silences one line, exactly as for `ddd-ts-kit check`.
|
|
45
|
+
|
|
46
|
+
## Limits
|
|
47
|
+
|
|
48
|
+
- A mutation behind another name (`upsert`, `record`) needs the `mutators` option.
|
|
49
|
+
- A dependency passed as an argument instead of injected is not followed.
|
|
50
|
+
- The other half of the principle, a command returning more than an identifier, is left to review.
|
|
51
|
+
|
|
52
|
+
## With the CLI checker
|
|
53
|
+
|
|
54
|
+
New with this plugin: the CLI checker has no equivalent, because the shape of a class needs a syntax tree.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# ddd-ts-kit/application-handler-shape
|
|
2
|
+
|
|
3
|
+
Architecture id: `application/handler-shape` (added by this plugin). Default severity: `error` in `recommended`, `error` in `strict`.
|
|
4
|
+
|
|
5
|
+
Applies to: `*.handler.ts` under `application/` of a context.
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
A handler is one use case: one class, called by the bus through `execute`. A second public method is a second use case hiding in the first, or a business decision that belongs to the domain.
|
|
10
|
+
|
|
11
|
+
## Reported
|
|
12
|
+
|
|
13
|
+
- a handler file that exports no class
|
|
14
|
+
- a second exported class
|
|
15
|
+
- a handler class without a public `execute`
|
|
16
|
+
- any other public method or function property, static ones included
|
|
17
|
+
|
|
18
|
+
Incorrect:
|
|
19
|
+
|
|
20
|
+
```ts
|
|
21
|
+
export class IssueInvoiceHandler {
|
|
22
|
+
async handle(command: IssueInvoiceCommand): Promise<string> {}
|
|
23
|
+
computeTotal(): number {}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Correct:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
export class IssueInvoiceHandler implements CommandHandler<IssueInvoiceCommand> {
|
|
31
|
+
async execute(command: IssueInvoiceCommand): Promise<string> {}
|
|
32
|
+
private total(): number {}
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Details
|
|
37
|
+
|
|
38
|
+
Types, interfaces and constants exported next to the class are allowed. `*.event-handler.ts` files are not handlers of the bus and are not judged.
|
|
39
|
+
|
|
40
|
+
## Options
|
|
41
|
+
|
|
42
|
+
None.
|
|
43
|
+
|
|
44
|
+
`rules."application/handler-shape"` in `ddd-ts-kit.config.json` set to `off` silences the rule, and `// ddd-ts-kit-disable-next-line application/handler-shape -- <reason>` silences one line, exactly as for `ddd-ts-kit check`.
|
|
45
|
+
|
|
46
|
+
## Limits
|
|
47
|
+
|
|
48
|
+
- The signature of `execute` is not checked against the command or query type: the compiler does it through `CommandHandler<T>` and `QueryHandler<T>`.
|
|
49
|
+
|
|
50
|
+
## With the CLI checker
|
|
51
|
+
|
|
52
|
+
New with this plugin: the CLI checker has no equivalent, because the shape of a class needs a syntax tree.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# ddd-ts-kit/aspects-outside-in
|
|
2
|
+
|
|
3
|
+
Architecture id: `aspects/outside-in`. Default severity: `error` in `recommended`, `error` in `strict`.
|
|
4
|
+
|
|
5
|
+
Applies to: every production file under the source root, except `infrastructure/` of a context and the platform directory; `domain/` and `application/` are left to the layer rules.
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
Logging, metrics, retry, timeout, circuit breaking and caching are applied from outside the code they wrap: the policy of a whole application is read in one place, the composition root, and changes without touching a class. The decorator form is the exception, kept for an adapter whose policy is part of what the adapter is (a client of a provider that documents its own retry and timeout rules). On a route, in a module file, in a published language or in the shared kernel, a decorator hides a policy where nobody looks for one.
|
|
10
|
+
|
|
11
|
+
## Reported
|
|
12
|
+
|
|
13
|
+
- an import of `@ddd-ts-kit/aspects/decorators` in `presentation/`, in `<context>.module.ts`, in `published-language/`, in any other production file of a context outside `infrastructure/`, in the shared kernel, in `main.ts` and in any other source under the source root (`apps/<context>/main.ts` included)
|
|
14
|
+
|
|
15
|
+
Incorrect:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
// src/contexts/billing/presentation/http/issue-invoice.route.ts
|
|
19
|
+
import { Retry } from '@ddd-ts-kit/aspects/decorators';
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Correct:
|
|
23
|
+
|
|
24
|
+
```ts
|
|
25
|
+
// src/contexts/billing/billing.module.ts
|
|
26
|
+
import { retry, timeout } from '@ddd-ts-kit/aspects';
|
|
27
|
+
|
|
28
|
+
builder.bind(PaymentGateway).toClass(StripePaymentGateway, [PaymentSettings]).with(retry({ attempts: 3 }), timeout(2000));
|
|
29
|
+
|
|
30
|
+
// src/contexts/billing/infrastructure/external/stripe-payment.gateway.ts
|
|
31
|
+
import { Retry } from '@ddd-ts-kit/aspects/decorators';
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Details
|
|
35
|
+
|
|
36
|
+
Only the `/decorators` entry is judged: the wrappers of `@ddd-ts-kit/aspects` (`retry`, `timeout`, `aspects`, the bus middlewares) are what a module file and `main.ts` are expected to import. Static imports, type-only imports, `export ... from`, dynamic `import()` and `require()` are all read.
|
|
37
|
+
|
|
38
|
+
In `domain/` and `application/` every entry of `@ddd-ts-kit/aspects` is already refused by `layer-domain-purity` and `layer-application-inward`: this rule stays silent there, so that one import gives one report. Tests and files outside the source root (scripts, config files) are not judged.
|
|
39
|
+
|
|
40
|
+
## Options
|
|
41
|
+
|
|
42
|
+
None. `platformDir` and `sourceRoot` of `ddd-ts-kit.config.json` say where the platform and the sources are.
|
|
43
|
+
|
|
44
|
+
`rules."aspects/outside-in"` in `ddd-ts-kit.config.json` set to `off` silences the rule, and `// ddd-ts-kit-disable-next-line aspects/outside-in -- <reason>` silences one line, exactly as for `ddd-ts-kit check`.
|
|
45
|
+
|
|
46
|
+
## Limits
|
|
47
|
+
|
|
48
|
+
- A decorator re-exported by a file of `infrastructure/` or of the platform and imported from there is not followed.
|
|
49
|
+
- A home-made decorator built on `weave` or on an aspect of the root entry is not recognised.
|
|
50
|
+
- With `layer/domain-purity` or `layer/application-inward` set to `off`, nothing reports the decorators in that layer.
|
|
51
|
+
|
|
52
|
+
## With the CLI checker
|
|
53
|
+
|
|
54
|
+
`ddd-ts-kit check` reports the same id from the import specifiers it reads in the text of the files, with the same exemptions. This rule is the authority.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# ddd-ts-kit/authz-actor-explicit
|
|
2
|
+
|
|
3
|
+
Architecture id: `authz/actor-explicit`. Default severity: `error` in `recommended`, `error` in `strict`.
|
|
4
|
+
|
|
5
|
+
Applies to: `domain/` and `application/` of a context, tests excluded.
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
A use case that reads "the current actor" from the air works behind an HTTP request and nowhere else: an integration event handler, a scheduled job and a test have to set a global first, and forget. The actor is data of the command or the query, like every other input. The `ExecutionScope` opened at the boundary (and `ActorContext`, a view of it) exists for code that is not handed the context: infrastructure and the platform read it for audit columns, tenant scoping and correlation.
|
|
10
|
+
|
|
11
|
+
## Reported
|
|
12
|
+
|
|
13
|
+
- an import of `ActorContext`, `ExecutionScope`, `AsyncLocalStorageExecutionScope`, `ScopedActorContext` or `AsyncLocalStorage`, from any module, as a type or as a value: the port class is also its injection token, so a value import is the one a dependency list would name
|
|
14
|
+
- the same names reached through a namespace (`kernel.ExecutionScope`, `hooks.AsyncLocalStorage`)
|
|
15
|
+
- a constructor parameter typed `ActorContext` or `ExecutionScope`
|
|
16
|
+
- a call of `.current()` or `.require()` without argument on a receiver declared with one of these types, or, when the file does not show its declaration, named `actors`, `scope`, `scopes`, `...actorContext` or `...executionScope`
|
|
17
|
+
- an import of the infrastructure helpers `stampCreation`, `stampUpdate` or `tenantScopeOf`, and their use through an imported namespace (`kernel.stampCreation`)
|
|
18
|
+
|
|
19
|
+
Incorrect:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { stampCreation, type ExecutionScope } from '@ddd-ts-kit/kernel';
|
|
23
|
+
|
|
24
|
+
export class VoidInvoiceHandler {
|
|
25
|
+
constructor(private readonly invoices: InvoiceRepository, private readonly scope: ExecutionScope) {}
|
|
26
|
+
|
|
27
|
+
async execute(command: VoidInvoice): Promise<void> {
|
|
28
|
+
const { actor } = this.scope.require();
|
|
29
|
+
const stamp = stampCreation(this.scope, this.clock);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Correct:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
export class VoidInvoiceHandler {
|
|
38
|
+
constructor(private readonly invoices: InvoiceRepository, private readonly access: Access) {}
|
|
39
|
+
|
|
40
|
+
async execute(command: VoidInvoice): Promise<void> {
|
|
41
|
+
await this.access.authorize(command.actor, billingPermissions['invoice.void'], invoice);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// infrastructure/persistence/drizzle-invoice.repository.ts
|
|
46
|
+
const row = { ...toRow(invoice), ...stampCreation(this.scope, this.clock), ...tenantScopeOf(this.scope) };
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Details
|
|
50
|
+
|
|
51
|
+
`infrastructure/` and the platform may read the `ExecutionScope` and the `ActorContext` for audit columns, tenant scoping, log fields and the correlation id, and the module binds `ActorContext` and `ExecutionScope`: none of them is judged. Tests are not judged either, so `FixedExecutionScope` and `FixedActorContext` stay available to them. An import, the constructor parameter it types and the read are three reports, one per line to change.
|
|
52
|
+
|
|
53
|
+
The type of a receiver is read from its declaration in the same file (a parameter, a variable, a property, a parameter property): no type information is needed. A receiver named `scope` and declared with another type (`AccessScope`, a concept of the domain) is not reported.
|
|
54
|
+
|
|
55
|
+
## Options
|
|
56
|
+
|
|
57
|
+
None.
|
|
58
|
+
|
|
59
|
+
`rules."authz/actor-explicit"` in `ddd-ts-kit.config.json` set to `off` silences the rule, and `// ddd-ts-kit-disable-next-line authz/actor-explicit -- <reason>` silences one line, exactly as for `ddd-ts-kit check`.
|
|
60
|
+
|
|
61
|
+
## Limits
|
|
62
|
+
|
|
63
|
+
- An ambient context reached under another name (a port of the project wrapping `ExecutionScope`, a module-level variable) is not seen.
|
|
64
|
+
- A re-export through a file of the context that renames the port is not followed.
|
|
65
|
+
- A receiver named `scope` whose declaration is not in the file (a destructured dependency, a property of a base class) is judged by its name: a concept of the domain called `scope` with a `current()` or `require()` method of its own is reported. Annotate the declaration, or record the suppression.
|
|
66
|
+
- A method of the project named `stampCreation`, `stampUpdate` or `tenantScopeOf` is not reported; a helper imported under these names from another module than the kernel is.
|
|
67
|
+
|
|
68
|
+
## With the CLI checker
|
|
69
|
+
|
|
70
|
+
`ddd-ts-kit check` reports the same id from the text of the files and stays the fast edit-time guard: it knows no declared type, so it reports `.current()` and `.require()` on anything named `scope`, `scopes` or `...executionScope`, and a helper only when the file imports it under its own name. This rule is the authority.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# ddd-ts-kit/authz-declared
|
|
2
|
+
|
|
3
|
+
Architecture id: `authz/declared`. Default severity: `error` in `recommended`, `error` in `strict`.
|
|
4
|
+
|
|
5
|
+
Applies to: the module file of a context for registrations, every production file for routes and messages, and in a declared-style project (`stack.style: "declared"`) the `*.command.ts` and `*.query.ts` files under `application/commands` and `application/queries`; tests excluded.
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
Nothing is reachable by default. A use case or a route that says nothing about who may call it is open by accident, and the accident is found in production. Saying "public" is a decision; saying nothing is not.
|
|
10
|
+
|
|
11
|
+
## Reported
|
|
12
|
+
|
|
13
|
+
- in `<context>.module.ts`: a chain `<builder>.command(X)` or `<builder>.query(X)` that reaches `.handledBy(...)` or `.handledByFactory(...)` with neither `.requires(...)` nor `.public()`, unless the class `X` is seen to carry `@Requires(...)` or `@Public()`
|
|
14
|
+
- in a declared-style project: an exported class of a `*.command.ts` or `*.query.ts` file under `application/commands` or `application/queries` that carries neither `@Requires(...)` nor `@Public()` of `@ddd-ts-kit/kernel/declarations`
|
|
15
|
+
- a `defineRoute({...})` whose spec has no `security` property, or `security: undefined`
|
|
16
|
+
- a `defineRoute({...})` whose spec has `security: []`
|
|
17
|
+
- a class extending `AuthorizedCommand` or `AuthorizedQuery` whose constructor does not pass one of its own parameters as first argument of `super(...)`
|
|
18
|
+
|
|
19
|
+
Incorrect:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
builder.command(VoidInvoice).handledBy(VoidInvoiceHandler, [INVOICES]);
|
|
23
|
+
|
|
24
|
+
defineRoute({ method: 'POST', path: '/invoices/:id/void', operationId: 'voidInvoice', responses }, handler);
|
|
25
|
+
|
|
26
|
+
export class VoidInvoice extends AuthorizedCommand {
|
|
27
|
+
constructor(readonly invoiceId: string) {
|
|
28
|
+
super(systemActor('billing'));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// declared style: application/commands/issue-invoice/issue-invoice.command.ts
|
|
33
|
+
export class IssueInvoiceCommand extends AuthorizedCommand<string> {}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Correct:
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
builder.command(VoidInvoice).requires(billingPermissions['invoice.void']).handledBy(VoidInvoiceHandler, [INVOICES]);
|
|
40
|
+
builder.query(GetCatalog).public().handledBy(GetCatalogHandler, [CATALOG]);
|
|
41
|
+
|
|
42
|
+
defineRoute({ method: 'POST', path: '/invoices/:id/void', operationId: 'voidInvoice', responses, security: ['bearer'] }, handler);
|
|
43
|
+
defineRoute({ method: 'GET', path: '/catalog', operationId: 'getCatalog', responses, security: false }, handler);
|
|
44
|
+
|
|
45
|
+
export class VoidInvoice extends AuthorizedCommand {
|
|
46
|
+
constructor(actor: Actor, readonly invoiceId: string) {
|
|
47
|
+
super(actor);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// declared style: application/commands/issue-invoice/issue-invoice.command.ts
|
|
52
|
+
import { Requires } from '@ddd-ts-kit/kernel/declarations';
|
|
53
|
+
|
|
54
|
+
@Requires(billingPermissions['invoice.issue'])
|
|
55
|
+
export class IssueInvoiceCommand extends AuthorizedCommand<string> {}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Details
|
|
59
|
+
|
|
60
|
+
The route type of `@ddd-ts-kit/http` enforces `security` already: `defineRoute` does not compile without it and refuses an empty list. This rule stays as the lint-level net for a route definition built loosely: a spec typed `any` or cast, a JavaScript file, a wrapper that widens the type.
|
|
61
|
+
|
|
62
|
+
`@Requires(...)` or `@Public()` on the message class is the declaration, in any project: a module that registers a decorated message without `.requires(...)` or `.public()` is not reported. The class is in view when it is declared in the module file or imported by name from a source of the project that exists on disk, which is then parsed (syntax only). A decorator counts when its name is imported from `@ddd-ts-kit/kernel/declarations` in the file of the class, under an alias (`{ Requires as Needs }`) or a namespace (`declarations.Requires`) too; a home-made `Requires` does not.
|
|
63
|
+
|
|
64
|
+
An explicit-style project is judged on its registrations only: a message file without a decorator is not reported there.
|
|
65
|
+
|
|
66
|
+
The registration is recognised by its shape, whatever the builder is called. `super(input.actor)` is accepted when `input` is a constructor parameter. A class without a constructor inherits the one of `AuthorizedCommand`, which takes the actor.
|
|
67
|
+
|
|
68
|
+
## Options
|
|
69
|
+
|
|
70
|
+
None.
|
|
71
|
+
|
|
72
|
+
`rules."authz/declared"` in `ddd-ts-kit.config.json` set to `off` silences the rule, and `// ddd-ts-kit-disable-next-line authz/declared -- <reason>` silences one line, exactly as for `ddd-ts-kit check`.
|
|
73
|
+
|
|
74
|
+
## Limits
|
|
75
|
+
|
|
76
|
+
- A registered message reached through a barrel, a renaming export, a default import or a namespace is not followed to its class: its decorator is not seen and the registration is reported.
|
|
77
|
+
- In a declared-style project that keeps a `<context>.module.ts`, a message registered there with `.requires(...)` and written without a decorator is still reported in its own file: put the decorator on the class.
|
|
78
|
+
- A `*.command.ts` or `*.query.ts` file that exports no class is not reported here.
|
|
79
|
+
- A registration split over statements (`const target = builder.command(X); target.handledBy(H);`) is not followed.
|
|
80
|
+
- A wiring written by hand with `AuthorizationMap.of(requires(...), publicUseCase(...))` is not read: `authorizationMiddleware` refuses an undeclared use case at run time, and `createApplication({ authorization: 'required' })` at start.
|
|
81
|
+
- A message extending plain `Command` or `Query` while its registration calls `.requires(...)` spans two files and is not seen here; the compiler refuses it, since `requires` only exists for a message that carries an actor.
|
|
82
|
+
- A route spec that is not an object literal, or that spreads another object, is not judged.
|
|
83
|
+
- That the scheme named in `security` exists, and that the permission is the right one, is not checked.
|
|
84
|
+
|
|
85
|
+
## With the CLI checker
|
|
86
|
+
|
|
87
|
+
`ddd-ts-kit check` reports the same id from the text of the files and stays the fast edit-time guard. This rule is the authority.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# ddd-ts-kit/authz-in-application
|
|
2
|
+
|
|
3
|
+
Architecture id: `authz/in-application`. Default severity: `error` in `recommended`, `error` in `strict`.
|
|
4
|
+
|
|
5
|
+
Applies to: `presentation/`, `infrastructure/` and `domain/` of a context, tests excluded.
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
A permission decided in three places is decided in none. A role test in a route is skipped by the integration event handler that sends the same command; a refusal in a repository cannot be audited; an aggregate that knows roles cannot change authorization model. One place decides: the application layer, through the `Authorizer` port.
|
|
10
|
+
|
|
11
|
+
## Reported
|
|
12
|
+
|
|
13
|
+
In `presentation/`:
|
|
14
|
+
|
|
15
|
+
- a read of `.roles`, `.permissions` or `.isAdmin` on anything
|
|
16
|
+
- a comparison of a member named `role` with a string (`===`, `!==`, `==`, `!=`), and a `switch` on it
|
|
17
|
+
- an import from `@ddd-ts-kit/auth` (any entry) of anything but the request glue (`actorOf`, `sessionOf`, `resolveSession`, `SessionAuthenticator`, `bearerCredential`, `inActorContext`, `principalResolver`, `HeaderValues`), the codes `FORBIDDEN` and `UNAUTHORIZED` and the error classes (the `Access` port included)
|
|
18
|
+
- in a declared-style project (`stack.style: "declared"`): an import of `Requires`, `Public` or `Policy` from `@ddd-ts-kit/kernel/declarations`
|
|
19
|
+
|
|
20
|
+
In `infrastructure/`:
|
|
21
|
+
|
|
22
|
+
- a call to `.authorize(...)`, `.decide(...)` or `.check(...)` on something named `access` or `...authorizer...`, or declared with the type `Access` or `...Authorizer`
|
|
23
|
+
- `new ForbiddenError(...)`
|
|
24
|
+
- in a declared-style project: an import of `Requires`, `Public` or `Policy` from `@ddd-ts-kit/kernel/declarations`, or of the ports `Access` or `PolicyAccess` from `@ddd-ts-kit/auth` (any entry), as a type or as a value
|
|
25
|
+
|
|
26
|
+
In `domain/`:
|
|
27
|
+
|
|
28
|
+
- any import from `@ddd-ts-kit/auth`
|
|
29
|
+
- an import of `Actor`, `Actored`, `ActorContext`, `Session` or `ExecutionContext` from `@ddd-ts-kit/kernel`
|
|
30
|
+
- a read of `.roles` or `.permissions` on anything but `this`
|
|
31
|
+
|
|
32
|
+
Incorrect:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
// presentation/http/void-invoice.route.ts
|
|
36
|
+
if (!context.principal.roles.includes('controller')) {
|
|
37
|
+
return { status: 403 };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// infrastructure/persistence/drizzle-invoice.repository.ts
|
|
41
|
+
await this.access.authorize(actor, billingPermissions['invoice.read'], row);
|
|
42
|
+
|
|
43
|
+
// domain/aggregates/invoice.aggregate.ts
|
|
44
|
+
void(by: Actor): void {
|
|
45
|
+
if (!by.roles.includes('controller')) {
|
|
46
|
+
throw new NotAllowedError();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Correct:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
// presentation/http/void-invoice.route.ts
|
|
55
|
+
await commandBus.execute(new VoidInvoice(actorOf(context.principal), params.invoiceId));
|
|
56
|
+
|
|
57
|
+
// application/commands/void-invoice/void-invoice.handler.ts
|
|
58
|
+
await this.access.authorize(command.actor, billingPermissions['invoice.void'], invoice);
|
|
59
|
+
invoice.void(command.actor.id, this.clock.now());
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Details
|
|
63
|
+
|
|
64
|
+
The type of a receiver is read from its declaration in the same file (a parameter, a variable, a property, a parameter property): no type information is needed. A class of `infrastructure/` that `implements` an `...Authorizer` is an adapter of the port (a cache, a remote service) and may delegate to another authorizer.
|
|
65
|
+
|
|
66
|
+
`application/` is where access is declared and decided: `Requires`, `Public` and `Policy` of `@ddd-ts-kit/kernel/declarations` and the `Access` port of `@ddd-ts-kit/auth` are imported there freely, in both styles. In `domain/` of a declared-style project the whole declarations entry is refused by `layer-domain-purity`, so this rule does not report it a second time. The other names of the declarations entry (`Repository`, `CLOCK`, ...) are not the concern of this rule. An explicit-style project is judged as before: these imports are not reported outside `application/`.
|
|
67
|
+
|
|
68
|
+
In `domain/`, `this.roles` and `this.state.roles` are not reported: a context whose subject is access itself (identity, membership) models roles as state.
|
|
69
|
+
|
|
70
|
+
## Options
|
|
71
|
+
|
|
72
|
+
None.
|
|
73
|
+
|
|
74
|
+
`rules."authz/in-application"` in `ddd-ts-kit.config.json` set to `off` silences the rule, and `// ddd-ts-kit-disable-next-line authz/in-application -- <reason>` silences one line, exactly as for `ddd-ts-kit check`.
|
|
75
|
+
|
|
76
|
+
## Limits
|
|
77
|
+
|
|
78
|
+
- `Requires`, `Public` or `Policy` reached through a namespace import of the declarations entry (`import * as declarations`) is not reported in `presentation/` and `infrastructure/`.
|
|
79
|
+
- The names are the signal. A route of an administration API whose body legitimately carries `roles` or `permissions` (grant a role to a member) is reported when it reads them: destructure the body (`const { roles } = body`) or record the deviation.
|
|
80
|
+
- A role test written without a member named `role` or `roles` (`isAdmin(user)`, `['admin'].includes(kind)`) is not seen.
|
|
81
|
+
- `.check(...)` on an authorizer held under another name and typed in another file is not seen.
|
|
82
|
+
- An ownership test (`row.ownerId !== actor.id`) is not recognised as such in any layer; in `infrastructure/` only the refusal that follows (`new ForbiddenError`) is.
|
|
83
|
+
- `Authenticator` is not on the allow-list of `presentation/`: the principal is resolved once by the server (`principalResolver`), not by each route. `SessionAuthenticator` is, for the boundary that resolves a whole session with `resolveSession`.
|
|
84
|
+
- A `Session` or an `ExecutionContext` declared by the project itself, or imported from another module than the kernel, is not reported in `domain/`.
|
|
85
|
+
|
|
86
|
+
## With the CLI checker
|
|
87
|
+
|
|
88
|
+
`ddd-ts-kit check` reports the same id from the text of the files and stays the fast edit-time guard. This rule is the authority.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# clean/blank-lines (layout)
|
|
2
|
+
|
|
3
|
+
Architecture id: `clean/blank-lines`. Default severity: `error` in `recommended`, `error` in `strict`. Fixable with `--fix`.
|
|
4
|
+
|
|
5
|
+
Applies to: every linted TypeScript file.
|
|
6
|
+
|
|
7
|
+
Not a rule of this plugin: two rules of [`@stylistic/eslint-plugin`](https://eslint.style) hold it, configured by the presets and exported as `standardRules.layout`.
|
|
8
|
+
|
|
9
|
+
## Why
|
|
10
|
+
|
|
11
|
+
A function reads as paragraphs: what it declares, what it decides, what it answers. A blank line before every `return` and between the logical blocks makes those paragraphs visible, and makes a block that has grown too many of them look like what it is, a function to split.
|
|
12
|
+
|
|
13
|
+
## Reported
|
|
14
|
+
|
|
15
|
+
- a `return` that is not alone in its block and has no blank line before it
|
|
16
|
+
- no blank line after a group of declarations (`const`, `let`), or around an `if`, a `for`, a `while`, a `do`, a `try`, a `switch` or a block
|
|
17
|
+
- no blank line around a statement or a declaration written on several lines
|
|
18
|
+
- no blank line before or after a method of a class
|
|
19
|
+
|
|
20
|
+
Incorrect:
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
function total(lines: readonly Line[]): number {
|
|
24
|
+
const amounts = lines.map((line) => line.amount);
|
|
25
|
+
if (amounts.length === 0) {
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
return amounts.reduce((sum, amount) => sum + amount, 0);
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Correct:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
function total(lines: readonly Line[]): number {
|
|
36
|
+
const amounts = lines.map((line) => line.amount);
|
|
37
|
+
|
|
38
|
+
if (amounts.length === 0) {
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return amounts.reduce((sum, amount) => sum + amount, 0);
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Details
|
|
47
|
+
|
|
48
|
+
What may stay together: consecutive one-line declarations; consecutive `case` labels; consecutive fields of a class, and consecutive abstract signatures of a port; the overloads of a method.
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
'@stylistic/padding-line-between-statements': [level,
|
|
52
|
+
{ blankLine: 'always', prev: '*', next: 'return' },
|
|
53
|
+
{ blankLine: 'always', prev: ['const', 'let', 'var'], next: '*' },
|
|
54
|
+
{ blankLine: 'any', prev: ['const', 'let', 'var'], next: ['const', 'let', 'var'] },
|
|
55
|
+
{ blankLine: 'always', prev: '*', next: ['if', 'for', 'while', 'do', 'try', 'switch', 'block-like'] },
|
|
56
|
+
{ blankLine: 'always', prev: ['if', 'for', 'while', 'do', 'try', 'switch', 'block-like'], next: '*' },
|
|
57
|
+
{ blankLine: 'always', prev: '*', next: ['multiline-const', 'multiline-let', 'multiline-var', 'multiline-expression'] },
|
|
58
|
+
{ blankLine: 'always', prev: ['multiline-const', 'multiline-let', 'multiline-var', 'multiline-expression'], next: '*' },
|
|
59
|
+
{ blankLine: 'any', prev: ['case', 'default'], next: ['case', 'default'] },
|
|
60
|
+
],
|
|
61
|
+
'@stylistic/lines-between-class-members': [level, { enforce: [
|
|
62
|
+
{ blankLine: 'always', prev: '*', next: 'method' },
|
|
63
|
+
{ blankLine: 'always', prev: 'method', next: '*' },
|
|
64
|
+
] }, { exceptAfterOverload: true }],
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`dddTsKit()` and the two presets register the plugin under `@stylistic` and enable the two rules. A blank line right after `{` or right before `}`, two blank lines in a row and a blank line at an end of a file are removed by the formatter ([`clean/formatted`](clean-formatted.md)), not reported here. In a config composed by hand:
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
import stylistic from '@stylistic/eslint-plugin';
|
|
71
|
+
import { standardRules } from '@ddd-ts-kit/eslint-plugin';
|
|
72
|
+
|
|
73
|
+
export default [{ files: ['**/*.ts'], plugins: { '@stylistic': stylistic }, rules: standardRules.layout }];
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Options
|
|
77
|
+
|
|
78
|
+
None. `rules."clean/blank-lines"` in `ddd-ts-kit.config.json` gives the two rules their severity in `dddTsKit()`: `error` (default), `warn`, or `off`, which leaves them out. The `ddd-ts-kit-disable-next-line` comment does not reach these rules: they are not rules of this plugin, and both are fixed by `eslint --fix --fix-type layout`.
|
|
79
|
+
|
|
80
|
+
## Limits
|
|
81
|
+
|
|
82
|
+
- The rules judge blank lines, not line breaks, indentation or line length: the formatter of the project does, and keeps the blank lines it finds.
|
|
83
|
+
- A blank line required on both sides of a multiline statement applies inside a group of declarations too: a `const` written on several lines is set apart from the one-line `const` around it.
|
|
84
|
+
|
|
85
|
+
## With the CLI checker
|
|
86
|
+
|
|
87
|
+
`ddd-ts-kit check` holds the cheap part only, as an approximation: a `return` glued to the statement above it, and a padded block of statements. It leaves the braces that hold no statement alone: an object literal, a type literal, an interface, an enum, a destructuring pattern, a list of imports or exports. These rules are the authority.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# clean/braces (layout)
|
|
2
|
+
|
|
3
|
+
Architecture id: `clean/braces`. Default severity: `error` in `recommended`, `error` in `strict`. Fixable with `--fix`.
|
|
4
|
+
|
|
5
|
+
Applies to: every linted TypeScript file, and in `dddTsKit()` every linted `.js`, `.mjs` and `.cjs` file.
|
|
6
|
+
|
|
7
|
+
Not a rule of this plugin: `curly` of ESLint holds it, configured by the presets and exported as `standardRules.braces`.
|
|
8
|
+
|
|
9
|
+
## Why
|
|
10
|
+
|
|
11
|
+
A branch written between braces, its body on its own lines, is visible at a glance, and a statement added to it later cannot silently fall outside it.
|
|
12
|
+
|
|
13
|
+
## Reported
|
|
14
|
+
|
|
15
|
+
- an `if`, an `else`, a `for`, a `for..of`, a `for..in`, a `while` or a `do` whose body is not a block
|
|
16
|
+
|
|
17
|
+
Incorrect:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
if (wrapped.has(repository)) return repository;
|
|
21
|
+
|
|
22
|
+
for (const step of steps) await step();
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Correct:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
if (wrapped.has(repository)) {
|
|
29
|
+
return repository;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
for (const step of steps) {
|
|
33
|
+
await step();
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Details
|
|
38
|
+
|
|
39
|
+
```js
|
|
40
|
+
curly: [level, 'all'],
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Not judged: a ternary, an arrow function returning an expression, `??` and `&&` expressions, a one-line object literal. An `else if` chain stays `} else if (...) {` on the line of the closing brace.
|
|
44
|
+
|
|
45
|
+
`curly` adds the braces; where they go is the work of the formatter ([`clean/formatted`](clean-formatted.md)), which always breaks a block that holds a statement: `if (a) { return b; }` on one line does not survive `npm run format`, and `npm run format:check` refuses it. That is why `@stylistic/brace-style` is not enabled: it would only repeat what the formatter decides.
|
|
46
|
+
|
|
47
|
+
In a config composed by hand:
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
import { standardRules } from '@ddd-ts-kit/eslint-plugin';
|
|
51
|
+
|
|
52
|
+
export default [{ files: ['**/*.ts'], rules: standardRules.braces }];
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Options
|
|
56
|
+
|
|
57
|
+
None. `rules."clean/braces"` in `ddd-ts-kit.config.json` gives `curly` its severity in `dddTsKit()`: `error` (default), `warn`, or `off`, which leaves it out. The `ddd-ts-kit-disable-next-line` comment does not reach it: it is not a rule of this plugin.
|
|
58
|
+
|
|
59
|
+
## With the CLI checker
|
|
60
|
+
|
|
61
|
+
`ddd-ts-kit check` holds the same thing on text, as an approximation: a body without braces, a body on the line of its braces, an `else` on a line of its own. This rule and the formatter are the authority.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# ddd-ts-kit/clean-file-size
|
|
2
|
+
|
|
3
|
+
Architecture id: `clean/file-size`. Default severity: `error` in `recommended`, `error` in `strict`.
|
|
4
|
+
|
|
5
|
+
Applies to: every linted file, tests included.
|
|
6
|
+
|
|
7
|
+
## Why
|
|
8
|
+
|
|
9
|
+
A file that does not fit in one sitting holds more than one responsibility: two classes that grew together, a function and the helpers of another one, a spec that tests three behaviours. The limit is a signal to split by responsibility, not a number to reach.
|
|
10
|
+
|
|
11
|
+
## Reported
|
|
12
|
+
|
|
13
|
+
- a file of more than 350 lines: every physical line counts, comments and blank lines included; a final newline adds none
|
|
14
|
+
|
|
15
|
+
Incorrect:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
// invoice.aggregate.spec.ts: 600 lines, issuing, paying and voiding in one file
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Correct:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
// invoice-issuing.spec.ts, invoice-payment.spec.ts, invoice-voiding.spec.ts: one behaviour each
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Details
|
|
28
|
+
|
|
29
|
+
The finding is reported once, on line 351. Declaration files (`*.d.ts`) and any file under a directory named `generated` are exempt: nobody reads them in one sitting, and nobody writes them.
|
|
30
|
+
|
|
31
|
+
## Options
|
|
32
|
+
|
|
33
|
+
None: the limit is 350 lines and is not configurable.
|
|
34
|
+
|
|
35
|
+
`rules."clean/file-size"` in `ddd-ts-kit.config.json` set to `off` silences the rule, and `// ddd-ts-kit-disable-next-line clean/file-size -- <reason>` silences one line, exactly as for `ddd-ts-kit check`.
|
|
36
|
+
|
|
37
|
+
## Limits
|
|
38
|
+
|
|
39
|
+
- The rule says that a file is too long, not where to cut it: split by responsibility, and name each file after what it holds (`clean/one-export-per-file`).
|
|
40
|
+
|
|
41
|
+
## With the CLI checker
|
|
42
|
+
|
|
43
|
+
`ddd-ts-kit check` reports the same id with the same count. Both tools agree.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# clean/formatted (layout)
|
|
2
|
+
|
|
3
|
+
Architecture id: `clean/formatted`. No severity: a file is formatted or it is not. Fixable with `npm run format`.
|
|
4
|
+
|
|
5
|
+
Applies to: every TypeScript, JavaScript and JSON file of the project.
|
|
6
|
+
|
|
7
|
+
Not a rule of this plugin, and not a rule of ESLint: the formatter of the project, [Biome](https://biomejs.dev), holds it with the `biome.json` that `ddd-ts-kit init` writes.
|
|
8
|
+
|
|
9
|
+
## Why
|
|
10
|
+
|
|
11
|
+
One way to lay out a file leaves nothing to discuss in a review and nothing to decide while writing: a line is at most 120 columns wide, and a diff shows what changed, never how somebody likes their line breaks.
|
|
12
|
+
|
|
13
|
+
## Checked
|
|
14
|
+
|
|
15
|
+
- `npm run format:check` (`biome format .`) reports nothing to change; it runs on staged files before a commit, in `npm run verify` and in the lint job of the pipeline
|
|
16
|
+
- `npm run format` (`biome format --write .`) settles it
|
|
17
|
+
|
|
18
|
+
The settings: line width 120, two spaces, LF, single quotes, trailing commas, semicolons, parentheses around the parameter of an arrow function. The linter and the import organiser of Biome are off: ESLint with this plugin is the only linter, and the formatter never reorders an import.
|
|
19
|
+
|
|
20
|
+
## With ESLint
|
|
21
|
+
|
|
22
|
+
The presets enable no rule that decides where a token goes, so the two never fight: `biome format --write` then `eslint --fix` then `biome format` reports nothing to change. What ESLint keeps is what a formatter does not decide: the blank lines between statements ([`clean/blank-lines`](clean-blank-lines.md)) and the braces of a branch ([`clean/braces`](clean-braces.md)).
|
|
23
|
+
|
|
24
|
+
## Limits
|
|
25
|
+
|
|
26
|
+
- Markdown and YAML are not formatted.
|
|
27
|
+
- Generated artifacts compared byte for byte by their own check (`openapi/*.json`, `asyncapi.json`, `.dependency-cruiser.cjs`) and build outputs are left out in `biome.json`.
|
|
28
|
+
- A string literal, a URL or a regular expression longer than 120 columns stays on its line: a formatter does not cut a token.
|
|
29
|
+
|
|
30
|
+
## With the CLI checker
|
|
31
|
+
|
|
32
|
+
`ddd-ts-kit rules` lists the id and `ddd-ts-kit explain clean/formatted` says who decides; `ddd-ts-kit check` judges nothing here.
|