@pjts/eslint-style-rules 0.0.8 → 0.0.9
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/LICENSE +21 -0
- package/README.md +38 -8
- package/dist/index.js +35 -4
- package/dist/index.js.map +1 -1
- package/dist/lib/ast.d.ts +27 -13
- package/dist/lib/ast.js +33 -7
- package/dist/lib/ast.js.map +1 -1
- package/dist/lib/db.d.ts +5 -4
- package/dist/lib/db.js +2 -2
- package/dist/lib/db.js.map +1 -1
- package/dist/lib/rule.d.ts +8 -6
- package/dist/lib/rule.js +3 -3
- package/dist/lib/rule.js.map +1 -1
- package/dist/lib/types.d.ts +69 -0
- package/dist/lib/types.js +270 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/wiring.d.ts +5 -3
- package/dist/lib/wiring.js +8 -4
- package/dist/lib/wiring.js.map +1 -1
- package/dist/rules/app-class-suffix.d.ts +1 -1
- package/dist/rules/app-class-suffix.js +1 -1
- package/dist/rules/app-class-suffix.js.map +1 -1
- package/dist/rules/app-service-endpoints.d.ts +3 -1
- package/dist/rules/app-service-endpoints.js +9 -8
- package/dist/rules/app-service-endpoints.js.map +1 -1
- package/dist/rules/auth-access.d.ts +2 -2
- package/dist/rules/auth-access.js +11 -10
- package/dist/rules/auth-access.js.map +1 -1
- package/dist/rules/config-provider-only.d.ts +1 -1
- package/dist/rules/config-provider-only.js +5 -3
- package/dist/rules/config-provider-only.js.map +1 -1
- package/dist/rules/db-client-dependency.d.ts +1 -1
- package/dist/rules/db-client-dependency.js +11 -7
- package/dist/rules/db-client-dependency.js.map +1 -1
- package/dist/rules/db-writes-in-repositories.d.ts +1 -1
- package/dist/rules/db-writes-in-repositories.js +12 -8
- package/dist/rules/db-writes-in-repositories.js.map +1 -1
- package/dist/rules/decorated-class-contract.d.ts +1 -1
- package/dist/rules/decorated-class-contract.js +1 -1
- package/dist/rules/decorated-class-contract.js.map +1 -1
- package/dist/rules/domain-primitive-params.d.ts +17 -0
- package/dist/rules/domain-primitive-params.js +116 -0
- package/dist/rules/domain-primitive-params.js.map +1 -0
- package/dist/rules/entity-constructor-data.d.ts +1 -1
- package/dist/rules/entity-constructor-data.js +4 -3
- package/dist/rules/entity-constructor-data.js.map +1 -1
- package/dist/rules/event-sourced-aggregate.d.ts +2 -2
- package/dist/rules/event-sourced-aggregate.js +8 -8
- package/dist/rules/event-sourced-aggregate.js.map +1 -1
- package/dist/rules/find-one-naming.d.ts +3 -2
- package/dist/rules/find-one-naming.js +35 -8
- package/dist/rules/find-one-naming.js.map +1 -1
- package/dist/rules/implements-ports-only.d.ts +10 -0
- package/dist/rules/implements-ports-only.js +74 -0
- package/dist/rules/implements-ports-only.js.map +1 -0
- package/dist/rules/import-only-in.d.ts +1 -1
- package/dist/rules/import-only-in.js +7 -3
- package/dist/rules/import-only-in.js.map +1 -1
- package/dist/rules/knex-first.d.ts +2 -1
- package/dist/rules/knex-first.js +11 -4
- package/dist/rules/knex-first.js.map +1 -1
- package/dist/rules/message-file.d.ts +1 -1
- package/dist/rules/message-file.js +3 -2
- package/dist/rules/message-file.js.map +1 -1
- package/dist/rules/message-handler.d.ts +1 -1
- package/dist/rules/message-handler.js +7 -6
- package/dist/rules/message-handler.js.map +1 -1
- package/dist/rules/message-name-reference.d.ts +2 -1
- package/dist/rules/message-name-reference.js +24 -5
- package/dist/rules/message-name-reference.js.map +1 -1
- package/dist/rules/message-names.d.ts +1 -1
- package/dist/rules/message-names.js +2 -2
- package/dist/rules/message-names.js.map +1 -1
- package/dist/rules/module-layout.d.ts +1 -1
- package/dist/rules/module-layout.js +1 -1
- package/dist/rules/module-layout.js.map +1 -1
- package/dist/rules/module-service-getters.d.ts +1 -1
- package/dist/rules/module-service-getters.js +11 -9
- package/dist/rules/module-service-getters.js.map +1 -1
- package/dist/rules/module-shape.d.ts +1 -1
- package/dist/rules/module-shape.js +6 -7
- package/dist/rules/module-shape.js.map +1 -1
- package/dist/rules/no-async-in-domain.d.ts +1 -1
- package/dist/rules/no-async-in-domain.js +2 -2
- package/dist/rules/no-async-in-domain.js.map +1 -1
- package/dist/rules/no-duplicate-sdk-types.d.ts +1 -1
- package/dist/rules/no-duplicate-sdk-types.js +1 -1
- package/dist/rules/no-duplicate-sdk-types.js.map +1 -1
- package/dist/rules/no-entity-assembly-in-app.d.ts +4 -2
- package/dist/rules/no-entity-assembly-in-app.js +24 -8
- package/dist/rules/no-entity-assembly-in-app.js.map +1 -1
- package/dist/rules/no-entity-mutation-outside-domain.d.ts +1 -1
- package/dist/rules/no-entity-mutation-outside-domain.js +1 -1
- package/dist/rules/no-entity-mutation-outside-domain.js.map +1 -1
- package/dist/rules/no-manual-wiring.d.ts +1 -1
- package/dist/rules/no-manual-wiring.js +5 -2
- package/dist/rules/no-manual-wiring.js.map +1 -1
- package/dist/rules/no-message-construction-outside-domain.d.ts +1 -1
- package/dist/rules/no-message-construction-outside-domain.js +1 -1
- package/dist/rules/no-message-construction-outside-domain.js.map +1 -1
- package/dist/rules/no-reconstitute.d.ts +1 -1
- package/dist/rules/no-reconstitute.js +1 -1
- package/dist/rules/no-reconstitute.js.map +1 -1
- package/dist/rules/one-class-per-file.d.ts +7 -0
- package/dist/rules/one-class-per-file.js +55 -0
- package/dist/rules/one-class-per-file.js.map +1 -0
- package/dist/rules/port-file.d.ts +1 -1
- package/dist/rules/port-file.js +3 -2
- package/dist/rules/port-file.js.map +1 -1
- package/dist/rules/port-has-adapters.d.ts +1 -1
- package/dist/rules/port-has-adapters.js +1 -1
- package/dist/rules/port-has-adapters.js.map +1 -1
- package/dist/rules/repository-naming.d.ts +1 -1
- package/dist/rules/repository-naming.js +2 -2
- package/dist/rules/repository-naming.js.map +1 -1
- package/dist/rules/repository-return-types.d.ts +10 -0
- package/dist/rules/repository-return-types.js +67 -0
- package/dist/rules/repository-return-types.js.map +1 -0
- package/dist/rules/repository-serialization.d.ts +13 -3
- package/dist/rules/repository-serialization.js +108 -12
- package/dist/rules/repository-serialization.js.map +1 -1
- package/dist/rules/return-entities.d.ts +1 -1
- package/dist/rules/return-entities.js +3 -3
- package/dist/rules/return-entities.js.map +1 -1
- package/dist/rules/save-contract.d.ts +5 -3
- package/dist/rules/save-contract.js +18 -5
- package/dist/rules/save-contract.js.map +1 -1
- package/dist/rules/subclass-declares-constructor.d.ts +1 -1
- package/dist/rules/subclass-declares-constructor.js +1 -1
- package/dist/rules/subclass-declares-constructor.js.map +1 -1
- package/dist/rules/test-location.d.ts +1 -1
- package/dist/rules/test-location.js +1 -1
- package/dist/rules/test-location.js.map +1 -1
- package/dist/rules/throw-app-error.d.ts +1 -1
- package/dist/rules/throw-app-error.js +4 -3
- package/dist/rules/throw-app-error.js.map +1 -1
- package/dist/rules/trackable-repository.d.ts +1 -1
- package/dist/rules/trackable-repository.js +4 -4
- package/dist/rules/trackable-repository.js.map +1 -1
- package/dist/rules/unique-class-names.d.ts +1 -1
- package/dist/rules/unique-class-names.js +5 -4
- package/dist/rules/unique-class-names.js.map +1 -1
- package/package.json +18 -6
package/dist/rules/port-file.js
CHANGED
|
@@ -8,6 +8,7 @@ const PORT_NAME = /Port$/;
|
|
|
8
8
|
const TYPE_ONLY = new Set(['TSInterfaceDeclaration', 'TSTypeAliasDeclaration', 'ImportDeclaration', 'ExportAllDeclaration']);
|
|
9
9
|
/** The declaration behind a top-level statement (`export interface X` → `interface X`). */
|
|
10
10
|
const declarationOf = (statement) => statement.type === 'ExportNamedDeclaration' || statement.type === 'ExportDefaultDeclaration' ? statement.declaration : statement;
|
|
11
|
+
const RUNTIME_KINDS = { ClassDeclaration: 'class', FunctionDeclaration: 'function', VariableDeclaration: 'value', TSEnumDeclaration: 'enum' };
|
|
11
12
|
/**
|
|
12
13
|
* Ports live one per file in `src/modules/<module>/app/ports/<Name>Port.ts`, each declared as an
|
|
13
14
|
* exported interface named exactly like the file. Supporting types (DTO-ish interfaces the port
|
|
@@ -18,7 +19,7 @@ const declarationOf = (statement) => statement.type === 'ExportNamedDeclaration'
|
|
|
18
19
|
exports.default = (0, rule_1.defineRule)({
|
|
19
20
|
meta: {
|
|
20
21
|
type: 'suggestion',
|
|
21
|
-
docs: { description: 'Enforce the location, shape and naming of port files' },
|
|
22
|
+
docs: { description: 'Enforce the location, shape and naming of port files', url: 'https://github.com/PiotrJozefow/pjx/tree/master/modules/eslint-style-rules#port-file' },
|
|
22
23
|
messages: {
|
|
23
24
|
fileName: 'Port files are named "<Name>Port.ts" — "{{file}}.ts" is not.',
|
|
24
25
|
missing: '"{{file}}.ts" must declare `export interface {{file}}`.',
|
|
@@ -57,7 +58,7 @@ exports.default = (0, rule_1.defineRule)({
|
|
|
57
58
|
if (!declaration)
|
|
58
59
|
continue;
|
|
59
60
|
if (!TYPE_ONLY.has(declaration.type) && declaration.type !== 'TSModuleDeclaration') {
|
|
60
|
-
const kind =
|
|
61
|
+
const kind = RUNTIME_KINDS[declaration.type] ?? 'statement';
|
|
61
62
|
if (declaration.id?.name === file) {
|
|
62
63
|
// `export abstract class XPort` — the port itself, declared with the wrong construct.
|
|
63
64
|
found = true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port-file.js","sourceRoot":"","sources":["../../src/rules/port-file.ts"],"names":[],"mappings":";;;AAAA,kEAA6B;
|
|
1
|
+
{"version":3,"file":"port-file.js","sourceRoot":"","sources":["../../src/rules/port-file.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
* winning over the adapters it wraps, and adapters behind `@Adapter({ profile })` left to the profile.
|
|
7
7
|
* Reads sibling files, so editors only re-check it when the port file itself is re-linted.
|
|
8
8
|
*/
|
|
9
|
-
declare const _default: import("eslint").
|
|
9
|
+
declare const _default: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<string, any[], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
|
|
10
10
|
export default _default;
|
|
@@ -14,7 +14,7 @@ const wiring_1 = require("../lib/wiring");
|
|
|
14
14
|
exports.default = (0, rule_1.defineRule)({
|
|
15
15
|
meta: {
|
|
16
16
|
type: 'suggestion',
|
|
17
|
-
docs: { description: 'Require every port to have exactly one adapter per storage profile' },
|
|
17
|
+
docs: { description: 'Require every port to have exactly one adapter per storage profile', url: 'https://github.com/PiotrJozefow/pjx/tree/master/modules/eslint-style-rules#port-has-adapters' },
|
|
18
18
|
messages: {
|
|
19
19
|
missing: 'Port "{{port}}" has no adapter under src/modules or src/common (expected e.g. Pg{{base}} implementing it).',
|
|
20
20
|
ambiguous: 'Port "{{port}}" has {{count}} adapters in storage "{{storage}}": {{names}} — keep one, make one a composite taking {{port}}[], or mark them with @Adapter({ profile }).',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port-has-adapters.js","sourceRoot":"","sources":["../../src/rules/port-has-adapters.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"port-has-adapters.js","sourceRoot":"","sources":["../../src/rules/port-has-adapters.ts"],"names":[],"mappings":";;AACA,oCAA4C;AAC5C,sCAAyC;AACzC,0CAAkF;AAElF;;;;;;;GAOG;AACH,kBAAe,IAAA,iBAAU,EAAC;IACxB,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,EAAE,WAAW,EAAE,oEAAoE,EAAE,GAAG,EAAE,8FAA8F,EAAE;QAChM,QAAQ,EAAE;YACR,OAAO,EAAE,4GAA4G;YACrH,SAAS,EAAE,yKAAyK;YACpL,UAAU,EAAE,iEAAiE;SAC9E;QACD,MAAM,EAAE,CAAC;gBACP,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;gBACtE,oBAAoB,EAAE,KAAK;aAC5B,CAAC;KACH;IACD,MAAM,CAAC,OAAO;QACZ,MAAM,QAAQ,GAAa,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC5E,MAAM,QAAQ,GAAG,IAAA,oBAAc,EAAC,OAAO,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,IAAA,gBAAO,EAAC,OAAO,CAAC,CAAC;QAC7B,IAAI,CAAC,QAAQ,IAAI,CAAC,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO;YAAE,OAAO,EAAE,CAAC;QAC/F,OAAO;YACL,yCAAyC,CAAC,IAAqC;gBAC7E,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;gBAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBACvC,MAAM,OAAO,GAAG,IAAA,oBAAW,EAAC,GAAG,CAAC,CAAC;gBACjC,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACzJ,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC9B,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;oBAC9E,OAAO;gBACT,CAAC;gBACD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;oBAC/B,MAAM,UAAU,GAAG,IAAA,qBAAY,EAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;oBACxD,MAAM,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAA,sBAAa,EAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;oBACxE,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC1B,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;wBAChI,OAAO;oBACT,CAAC;oBACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACrD,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;wBAC1K,OAAO;oBACT,CAAC;gBACH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -15,5 +15,5 @@
|
|
|
15
15
|
* `imports` entries are `module`, `module#ImportedName` or `scope/*`.
|
|
16
16
|
* requireImplementationFolder (default true), fileNameMatchesClass (default true)
|
|
17
17
|
*/
|
|
18
|
-
declare const _default: import("eslint").
|
|
18
|
+
declare const _default: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<string, any[], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
|
|
19
19
|
export default _default;
|
|
@@ -24,7 +24,7 @@ const rule_1 = require("../lib/rule");
|
|
|
24
24
|
exports.default = (0, rule_1.defineRule)({
|
|
25
25
|
meta: {
|
|
26
26
|
type: 'suggestion',
|
|
27
|
-
docs: { description: 'Tie repository class names to their storage folder, imports and file name' },
|
|
27
|
+
docs: { description: 'Tie repository class names to their storage folder, imports and file name', url: 'https://github.com/PiotrJozefow/pjx/tree/master/modules/eslint-style-rules#repository-naming' },
|
|
28
28
|
messages: {
|
|
29
29
|
folder: 'Repository "{{name}}" must live in infrastructure/repositories/<{{storages}}>/ (combine with "+" for several).',
|
|
30
30
|
unknownStorage: 'Unknown storage "{{segment}}" in "{{folder}}/" — known: {{storages}}.',
|
|
@@ -71,7 +71,7 @@ exports.default = (0, rule_1.defineRule)({
|
|
|
71
71
|
return {
|
|
72
72
|
ImportDeclaration(node) {
|
|
73
73
|
const source = node.source.value;
|
|
74
|
-
const importedNames = node.specifiers.map((s) => s.imported
|
|
74
|
+
const importedNames = node.specifiers.map((s) => (s.type === 'ImportSpecifier' ? (s.imported.type === 'Identifier' ? s.imported.name : s.imported.value) : s.local.name));
|
|
75
75
|
for (const key of keys) {
|
|
76
76
|
const spec = (storages[key].imports ?? []).find((candidate) => matches(candidate, source, importedNames));
|
|
77
77
|
if (spec && !detected.has(key))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository-naming.js","sourceRoot":"","sources":["../../src/rules/repository-naming.ts"],"names":[],"mappings":";;;AAAA,kEAA6B;
|
|
1
|
+
{"version":3,"file":"repository-naming.js","sourceRoot":"","sources":["../../src/rules/repository-naming.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repositories hand out domain classes only. Public methods of `…Repository` classes and the method
|
|
3
|
+
* signatures of `…RepositoryPort` interfaces return `Promise<Entity | ValueObject | DomainPrimitive |
|
|
4
|
+
* UpdateResult | X[] | X | null | void>` — never a primitive, a literal, an inline object, a plain
|
|
5
|
+
* interface / type alias / enum (`…Record`, `…Row`) or `any`. `Promise<>`, arrays and `| null` /
|
|
6
|
+
* `| undefined` are unwrapped; the rest is the same type classification as `domain-primitive-params`.
|
|
7
|
+
* A public repository method without a return type is reported too.
|
|
8
|
+
*/
|
|
9
|
+
declare const _default: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<string, any[], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
|
|
10
|
+
export default _default;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ast_1 = require("../lib/ast");
|
|
4
|
+
const rule_1 = require("../lib/rule");
|
|
5
|
+
const types_1 = require("../lib/types");
|
|
6
|
+
/**
|
|
7
|
+
* Repositories hand out domain classes only. Public methods of `…Repository` classes and the method
|
|
8
|
+
* signatures of `…RepositoryPort` interfaces return `Promise<Entity | ValueObject | DomainPrimitive |
|
|
9
|
+
* UpdateResult | X[] | X | null | void>` — never a primitive, a literal, an inline object, a plain
|
|
10
|
+
* interface / type alias / enum (`…Record`, `…Row`) or `any`. `Promise<>`, arrays and `| null` /
|
|
11
|
+
* `| undefined` are unwrapped; the rest is the same type classification as `domain-primitive-params`.
|
|
12
|
+
* A public repository method without a return type is reported too.
|
|
13
|
+
*/
|
|
14
|
+
exports.default = (0, rule_1.defineRule)({
|
|
15
|
+
meta: {
|
|
16
|
+
type: 'suggestion',
|
|
17
|
+
docs: { description: 'Require repositories and repository ports to return domain classes', url: 'https://github.com/PiotrJozefow/pjx/tree/master/modules/eslint-style-rules#repository-return-types' },
|
|
18
|
+
messages: {
|
|
19
|
+
plain: '"{{method}}" returns `{{type}}`: repositories return domain classes (entities, value objects, domain primitives, UpdateResult), arrays of them, null or void.',
|
|
20
|
+
missing: 'Public repository method "{{method}}": declare the return type.',
|
|
21
|
+
},
|
|
22
|
+
schema: [{
|
|
23
|
+
type: 'object',
|
|
24
|
+
properties: { ...types_1.typePolicySchema, classPattern: { type: 'string' }, interfacePattern: { type: 'string' } },
|
|
25
|
+
additionalProperties: false,
|
|
26
|
+
}],
|
|
27
|
+
},
|
|
28
|
+
create(context) {
|
|
29
|
+
const options = context.options[0] ?? {};
|
|
30
|
+
const classPattern = new RegExp(options.classPattern ?? 'Repository$');
|
|
31
|
+
const interfacePattern = new RegExp(options.interfacePattern ?? 'RepositoryPort$');
|
|
32
|
+
const classifier = (0, types_1.createTypeClassifier)(context, (0, types_1.typePolicy)(options, { allowTypeSuffixes: [], checkAny: true }));
|
|
33
|
+
const check = (node, method, returnType) => {
|
|
34
|
+
if (!returnType) {
|
|
35
|
+
context.report({ node: node.key, messageId: 'missing', data: { method } });
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const type = classifier.plainReason(returnType.typeAnnotation);
|
|
39
|
+
if (type)
|
|
40
|
+
context.report({ node: returnType, messageId: 'plain', data: { method, type } });
|
|
41
|
+
};
|
|
42
|
+
return {
|
|
43
|
+
'ClassDeclaration[id]'(classNode) {
|
|
44
|
+
if (!classPattern.test(classNode.id.name))
|
|
45
|
+
return;
|
|
46
|
+
for (const member of classNode.body.body) {
|
|
47
|
+
if (member.type !== 'MethodDefinition' && member.type !== 'TSAbstractMethodDefinition')
|
|
48
|
+
continue;
|
|
49
|
+
if (member.kind !== 'method' || member.static || member.computed)
|
|
50
|
+
continue;
|
|
51
|
+
if (member.accessibility === 'private' || member.accessibility === 'protected' || member.key.type === 'PrivateIdentifier')
|
|
52
|
+
continue;
|
|
53
|
+
check(member, (0, ast_1.memberName)(member), member.value.returnType);
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
'TSInterfaceDeclaration'(interfaceNode) {
|
|
57
|
+
if (!interfacePattern.test(interfaceNode.id.name))
|
|
58
|
+
return;
|
|
59
|
+
for (const member of interfaceNode.body.body) {
|
|
60
|
+
if (member.type === 'TSMethodSignature' && !member.computed)
|
|
61
|
+
check(member, (0, ast_1.memberName)(member), member.returnType);
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
//# sourceMappingURL=repository-return-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository-return-types.js","sourceRoot":"","sources":["../../src/rules/repository-return-types.ts"],"names":[],"mappings":";;AACA,oCAAwC;AACxC,sCAAyC;AACzC,wCAAkF;AAElF;;;;;;;GAOG;AACH,kBAAe,IAAA,iBAAU,EAAC;IACxB,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,EAAE,WAAW,EAAE,oEAAoE,EAAE,GAAG,EAAE,oGAAoG,EAAE;QACtM,QAAQ,EAAE;YACR,KAAK,EAAE,+JAA+J;YACtK,OAAO,EAAE,iEAAiE;SAC3E;QACD,MAAM,EAAE,CAAC;gBACP,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,EAAE,GAAG,wBAAgB,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,gBAAgB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;gBAC3G,oBAAoB,EAAE,KAAK;aAC5B,CAAC;KACH;IACD,MAAM,CAAC,OAAO;QACZ,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,IAAI,aAAa,CAAC,CAAC;QACvE,MAAM,gBAAgB,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,IAAI,iBAAiB,CAAC,CAAC;QACnF,MAAM,UAAU,GAAG,IAAA,4BAAoB,EAAC,OAAO,EAAE,IAAA,kBAAU,EAAC,OAAO,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAEjH,MAAM,KAAK,GAAG,CAAC,IAAkG,EAAE,MAAqB,EAAE,UAAiD,EAAE,EAAE;YAC7L,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;gBAC3E,OAAO;YACT,CAAC;YACD,MAAM,IAAI,GAAG,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;YAC/D,IAAI,IAAI;gBAAE,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7F,CAAC,CAAC;QAEF,OAAO;YACL,sBAAsB,CAAC,SAAkE;gBACvF,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC;oBAAE,OAAO;gBAClD,KAAK,MAAM,MAAM,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;oBACzC,IAAI,MAAM,CAAC,IAAI,KAAK,kBAAkB,IAAI,MAAM,CAAC,IAAI,KAAK,4BAA4B;wBAAE,SAAS;oBACjG,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ;wBAAE,SAAS;oBAC3E,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS,IAAI,MAAM,CAAC,aAAa,KAAK,WAAW,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,mBAAmB;wBAAE,SAAS;oBACpI,KAAK,CAAC,MAAM,EAAE,IAAA,gBAAU,EAAC,MAAM,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBAC7D,CAAC;YACH,CAAC;YACD,wBAAwB,CAAC,aAAa;gBACpC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,IAAI,CAAC;oBAAE,OAAO;gBAC1D,KAAK,MAAM,MAAM,IAAI,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;oBAC7C,IAAI,MAAM,CAAC,IAAI,KAAK,mBAAmB,IAAI,CAAC,MAAM,CAAC,QAAQ;wBAAE,KAAK,CAAC,MAAM,EAAE,IAAA,gBAAU,EAAC,MAAM,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;gBACpH,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* (
|
|
2
|
+
* Persistence repositories map rows through `deserialize` (record → domain class, returning
|
|
3
|
+
* `new X(...)`) and write through `serialize` (domain class → record) — each required only for the
|
|
4
|
+
* direction the repository uses:
|
|
5
|
+
*
|
|
6
|
+
* - `deserialize` when a public method declares a return type other than `void` / `UpdateResult`
|
|
7
|
+
* (`ignoreReturnTypes`), `Promise<>` unwrapped — it hands out something built from rows;
|
|
8
|
+
* - `serialize` when a public method takes a class-typed parameter that is not a domain primitive
|
|
9
|
+
* (a class declared outside `…/values/`) and the class writes (`writeMethods`: insert / upsert / update).
|
|
10
|
+
*
|
|
11
|
+
* A guarded column update returning `UpdateResult` needs neither. `serialize…` / `deserialize…`
|
|
12
|
+
* variants satisfy the requirement. Other mapper names (`toDomain`, `toRow`, `fromRow`, `mapRow`, …)
|
|
13
|
+
* are always reported.
|
|
4
14
|
*/
|
|
5
|
-
declare const _default: import("eslint").
|
|
15
|
+
declare const _default: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<string, any[], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
|
|
6
16
|
export default _default;
|
|
@@ -2,45 +2,141 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const ast_1 = require("../lib/ast");
|
|
4
4
|
const rule_1 = require("../lib/rule");
|
|
5
|
+
const types_1 = require("../lib/types");
|
|
5
6
|
const LEGACY_MAPPERS = /^(toDomain|toEntity|toRecord|toRow|fromRow|fromRecord|mapRow|mapRecord|rowTo\w+|recordTo\w+)$/;
|
|
6
7
|
/**
|
|
7
|
-
*
|
|
8
|
-
* (
|
|
8
|
+
* Persistence repositories map rows through `deserialize` (record → domain class, returning
|
|
9
|
+
* `new X(...)`) and write through `serialize` (domain class → record) — each required only for the
|
|
10
|
+
* direction the repository uses:
|
|
11
|
+
*
|
|
12
|
+
* - `deserialize` when a public method declares a return type other than `void` / `UpdateResult`
|
|
13
|
+
* (`ignoreReturnTypes`), `Promise<>` unwrapped — it hands out something built from rows;
|
|
14
|
+
* - `serialize` when a public method takes a class-typed parameter that is not a domain primitive
|
|
15
|
+
* (a class declared outside `…/values/`) and the class writes (`writeMethods`: insert / upsert / update).
|
|
16
|
+
*
|
|
17
|
+
* A guarded column update returning `UpdateResult` needs neither. `serialize…` / `deserialize…`
|
|
18
|
+
* variants satisfy the requirement. Other mapper names (`toDomain`, `toRow`, `fromRow`, `mapRow`, …)
|
|
19
|
+
* are always reported.
|
|
9
20
|
*/
|
|
10
21
|
exports.default = (0, rule_1.defineRule)({
|
|
11
22
|
meta: {
|
|
12
23
|
type: 'suggestion',
|
|
13
|
-
|
|
24
|
+
hasSuggestions: true,
|
|
25
|
+
docs: { description: 'Require serialize/deserialize mapping methods on persistence repositories', url: 'https://github.com/PiotrJozefow/pjx/tree/master/modules/eslint-style-rules#repository-serialization' },
|
|
14
26
|
messages: {
|
|
15
|
-
missing: '"{{name}}" must define `{{method}}
|
|
27
|
+
missing: '"{{name}}" must define `{{method}}` — {{reason}}.',
|
|
16
28
|
legacy: 'Rename `{{method}}` to `serialize` / `deserialize`.',
|
|
29
|
+
rename: 'Rename to `{{name}}`.',
|
|
17
30
|
constructor: '`deserialize` must return `new <Entity>({...})`.',
|
|
18
31
|
},
|
|
19
32
|
schema: [{
|
|
20
33
|
type: 'object',
|
|
21
|
-
properties: {
|
|
34
|
+
properties: {
|
|
35
|
+
classPattern: { type: 'string' },
|
|
36
|
+
ignoreReturnTypes: { type: 'array', items: { type: 'string' } },
|
|
37
|
+
writeMethods: { type: 'array', items: { type: 'string' } },
|
|
38
|
+
valuesFolder: { type: 'string' },
|
|
39
|
+
pathAliases: { type: 'object', additionalProperties: { type: 'string' } },
|
|
40
|
+
},
|
|
22
41
|
additionalProperties: false,
|
|
23
42
|
}],
|
|
24
43
|
},
|
|
25
44
|
create(context) {
|
|
26
|
-
const
|
|
45
|
+
const options = context.options[0] ?? {};
|
|
46
|
+
const classPattern = new RegExp(options.classPattern ?? '^Pg\\w*Repository$');
|
|
47
|
+
const ignoreReturnTypes = options.ignoreReturnTypes ?? ['UpdateResult'];
|
|
48
|
+
const writeMethods = new Set(options.writeMethods ?? ['insert', 'upsert', 'update']);
|
|
49
|
+
const valuesFolder = options.valuesFolder ?? 'values';
|
|
50
|
+
const classifier = (0, types_1.createTypeClassifier)(context, (0, types_1.typePolicy)({ pathAliases: options.pathAliases ?? types_1.DEFAULT_PATH_ALIASES }));
|
|
51
|
+
const unwrap = (type) => {
|
|
52
|
+
let current = type;
|
|
53
|
+
while (current?.type === 'TSTypeReference' && current.typeName.name === 'Promise')
|
|
54
|
+
current = current.typeArguments?.params?.[0];
|
|
55
|
+
return current;
|
|
56
|
+
};
|
|
57
|
+
const isIgnoredReturn = (type) => {
|
|
58
|
+
const inner = unwrap(type);
|
|
59
|
+
if (!inner)
|
|
60
|
+
return true;
|
|
61
|
+
if (inner.type === 'TSVoidKeyword' || inner.type === 'TSUndefinedKeyword')
|
|
62
|
+
return true;
|
|
63
|
+
if (inner.type === 'TSUnionType')
|
|
64
|
+
return inner.types.every(isIgnoredReturn);
|
|
65
|
+
return inner.type === 'TSTypeReference' && ignoreReturnTypes.includes(inner.typeName.name);
|
|
66
|
+
};
|
|
67
|
+
const isEntityType = (type) => {
|
|
68
|
+
if (!type)
|
|
69
|
+
return false;
|
|
70
|
+
if (type.type === 'TSArrayType')
|
|
71
|
+
return isEntityType(type.elementType);
|
|
72
|
+
if (type.type === 'TSUnionType')
|
|
73
|
+
return type.types.some(isEntityType);
|
|
74
|
+
if (type.type !== 'TSTypeReference' || type.typeName.type !== 'Identifier')
|
|
75
|
+
return false;
|
|
76
|
+
if (['Array', 'ReadonlyArray', 'Readonly'].includes(type.typeName.name))
|
|
77
|
+
return isEntityType(type.typeArguments?.params?.[0]);
|
|
78
|
+
const declaration = classifier.resolve(type.typeName.name);
|
|
79
|
+
return declaration?.kind === 'class' && !declaration.index.file.split('/').slice(0, -1).includes(valuesFolder) && !classifier.isAllowedLocation(declaration.index.file);
|
|
80
|
+
};
|
|
81
|
+
const paramType = (raw) => {
|
|
82
|
+
const param = raw.type === 'TSParameterProperty' ? raw.parameter : raw;
|
|
83
|
+
const binding = param.type === 'AssignmentPattern' ? param.left : param;
|
|
84
|
+
return (param.typeAnnotation ?? binding.typeAnnotation)?.typeAnnotation;
|
|
85
|
+
};
|
|
86
|
+
const writes = (classNode) => {
|
|
87
|
+
let found = false;
|
|
88
|
+
const visit = (node) => {
|
|
89
|
+
if (found || !node || typeof node.type !== 'string')
|
|
90
|
+
return;
|
|
91
|
+
if (node.type === 'CallExpression' && node.callee.type === 'MemberExpression' && !node.callee.computed && writeMethods.has(node.callee.property.name)) {
|
|
92
|
+
found = true;
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
for (const key of Object.keys(node)) {
|
|
96
|
+
if (key === 'parent')
|
|
97
|
+
continue;
|
|
98
|
+
const value = node[key];
|
|
99
|
+
if (Array.isArray(value))
|
|
100
|
+
value.forEach(visit);
|
|
101
|
+
else if (value && typeof value.type === 'string')
|
|
102
|
+
visit(value);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
visit(classNode.body);
|
|
106
|
+
return found;
|
|
107
|
+
};
|
|
108
|
+
const hasMapper = (classNode, prefix) => (0, ast_1.methods)(classNode).some((method) => new RegExp(`^${prefix}([A-Z]\\w*)?$`).test((0, ast_1.memberName)(method) ?? ''));
|
|
27
109
|
return {
|
|
28
110
|
'ClassDeclaration[id]'(node) {
|
|
29
111
|
const name = node.id.name;
|
|
30
112
|
if (!classPattern.test(name))
|
|
31
113
|
return;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
114
|
+
const publicMethods = (0, ast_1.methods)(node).filter((method) => method.kind === 'method' && !method.static && method.accessibility !== 'private' && method.accessibility !== 'protected' && method.key.type !== 'PrivateIdentifier');
|
|
115
|
+
const reader = publicMethods.find((method) => method.value.returnType && !isIgnoredReturn(method.value.returnType.typeAnnotation));
|
|
116
|
+
if (reader && !hasMapper(node, 'deserialize')) {
|
|
117
|
+
context.report({ node: node.id, messageId: 'missing', data: { name, method: 'deserialize', reason: `\`${(0, ast_1.memberName)(reader)}\` returns what it reads` } });
|
|
118
|
+
}
|
|
119
|
+
const writer = writes(node) && publicMethods.find((method) => method.value.params.some((param) => isEntityType(paramType(param))));
|
|
120
|
+
if (writer && !hasMapper(node, 'serialize')) {
|
|
121
|
+
context.report({ node: node.id, messageId: 'missing', data: { name, method: 'serialize', reason: `\`${(0, ast_1.memberName)(writer)}\` writes a domain class` } });
|
|
35
122
|
}
|
|
36
123
|
for (const method of (0, ast_1.methods)(node)) {
|
|
37
|
-
|
|
38
|
-
|
|
124
|
+
const legacy = (0, ast_1.memberName)(method) ?? '';
|
|
125
|
+
if (LEGACY_MAPPERS.test(legacy)) {
|
|
126
|
+
// toDomain/toEntity/fromRow/fromRecord/mapRow/mapRecord/rowTo*/recordTo* build an entity; toRecord/toRow build a record.
|
|
127
|
+
const replacement = /^(toRecord|toRow)$/.test(legacy) ? 'serialize' : 'deserialize';
|
|
128
|
+
const taken = (0, ast_1.findMethod)(node, replacement) !== undefined;
|
|
129
|
+
context.report({
|
|
130
|
+
node: method.key,
|
|
131
|
+
messageId: 'legacy',
|
|
132
|
+
data: { method: legacy },
|
|
133
|
+
suggest: taken ? [] : [{ messageId: 'rename', data: { name: replacement }, fix: (fixer) => fixer.replaceText(method.key, replacement) }],
|
|
134
|
+
});
|
|
39
135
|
}
|
|
40
136
|
}
|
|
41
137
|
const deserialize = (0, ast_1.findMethod)(node, 'deserialize');
|
|
42
138
|
const returned = deserialize?.value.body?.body.filter((statement) => statement.type === 'ReturnStatement') ?? [];
|
|
43
|
-
if (returned.some((statement) => statement.argument?.type !== 'NewExpression')) {
|
|
139
|
+
if (deserialize && returned.some((statement) => statement.type === 'ReturnStatement' && statement.argument?.type !== 'NewExpression')) {
|
|
44
140
|
context.report({ node: deserialize.key, messageId: 'constructor' });
|
|
45
141
|
}
|
|
46
142
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repository-serialization.js","sourceRoot":"","sources":["../../src/rules/repository-serialization.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"repository-serialization.js","sourceRoot":"","sources":["../../src/rules/repository-serialization.ts"],"names":[],"mappings":";;AACA,oCAA6E;AAC7E,sCAAyC;AACzC,wCAAsF;AAEtF,MAAM,cAAc,GAAG,+FAA+F,CAAC;AAEvH;;;;;;;;;;;;;GAaG;AACH,kBAAe,IAAA,iBAAU,EAAC;IACxB,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,cAAc,EAAE,IAAI;QACpB,IAAI,EAAE,EAAE,WAAW,EAAE,2EAA2E,EAAE,GAAG,EAAE,qGAAqG,EAAE;QAC9M,QAAQ,EAAE;YACR,OAAO,EAAE,mDAAmD;YAC5D,MAAM,EAAE,qDAAqD;YAC7D,MAAM,EAAE,uBAAuB;YAC/B,WAAW,EAAE,kDAAkD;SAChE;QACD,MAAM,EAAE,CAAC;gBACP,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBAChC,iBAAiB,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;oBAC/D,YAAY,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;oBAC1D,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBAChC,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,oBAAoB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;iBAC1E;gBACD,oBAAoB,EAAE,KAAK;aAC5B,CAAC;KACH;IACD,MAAM,CAAC,OAAO;QACZ,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACzC,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,IAAI,oBAAoB,CAAC,CAAC;QAC9E,MAAM,iBAAiB,GAAa,OAAO,CAAC,iBAAiB,IAAI,CAAC,cAAc,CAAC,CAAC;QAClF,MAAM,YAAY,GAAG,IAAI,GAAG,CAAS,OAAO,CAAC,YAAY,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC7F,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,QAAQ,CAAC;QACtD,MAAM,UAAU,GAAG,IAAA,4BAAoB,EAAC,OAAO,EAAE,IAAA,kBAAU,EAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,4BAAoB,EAAE,CAAC,CAAC,CAAC;QAE3H,MAAM,MAAM,GAAG,CAAC,IAAS,EAAO,EAAE;YAChC,IAAI,OAAO,GAAG,IAAI,CAAC;YACnB,OAAO,OAAO,EAAE,IAAI,KAAK,iBAAiB,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS;gBAAE,OAAO,GAAG,OAAO,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;YAChI,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC;QACF,MAAM,eAAe,GAAG,CAAC,IAAS,EAAW,EAAE;YAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;YAC3B,IAAI,CAAC,KAAK;gBAAE,OAAO,IAAI,CAAC;YACxB,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB;gBAAE,OAAO,IAAI,CAAC;YACvF,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa;gBAAE,OAAO,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;YAC5E,OAAO,KAAK,CAAC,IAAI,KAAK,iBAAiB,IAAI,iBAAiB,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC7F,CAAC,CAAC;QACF,MAAM,YAAY,GAAG,CAAC,IAAS,EAAW,EAAE;YAC1C,IAAI,CAAC,IAAI;gBAAE,OAAO,KAAK,CAAC;YACxB,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa;gBAAE,OAAO,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YACvE,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa;gBAAE,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACtE,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY;gBAAE,OAAO,KAAK,CAAC;YACzF,IAAI,CAAC,OAAO,EAAE,eAAe,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,OAAO,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9H,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3D,OAAO,WAAW,EAAE,IAAI,KAAK,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1K,CAAC,CAAC;QACF,MAAM,SAAS,GAAG,CAAC,GAAQ,EAAE,EAAE;YAC7B,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,KAAK,qBAAqB,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;YACvE,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,mBAAmB,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;YACxE,OAAO,CAAC,KAAK,CAAC,cAAc,IAAI,OAAO,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;QAC1E,CAAC,CAAC;QACF,MAAM,MAAM,GAAG,CAAC,SAAoB,EAAE,EAAE;YACtC,IAAI,KAAK,GAAG,KAAK,CAAC;YAClB,MAAM,KAAK,GAAG,CAAC,IAAS,EAAE,EAAE;gBAC1B,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;oBAAE,OAAO;gBAC5D,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAgB,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtJ,KAAK,GAAG,IAAI,CAAC;oBACb,OAAO;gBACT,CAAC;gBACD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBACpC,IAAI,GAAG,KAAK,QAAQ;wBAAE,SAAS;oBAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;oBACxB,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;wBAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;yBAC1C,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;wBAAE,KAAK,CAAC,KAAK,CAAC,CAAC;gBACjE,CAAC;YACH,CAAC,CAAC;YACF,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YACtB,OAAO,KAAK,CAAC;QACf,CAAC,CAAC;QACF,MAAM,SAAS,GAAG,CAAC,SAAoB,EAAE,MAAc,EAAE,EAAE,CAAC,IAAA,aAAO,EAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,IAAI,MAAM,eAAe,CAAC,CAAC,IAAI,CAAC,IAAA,gBAAU,EAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAEtK,OAAO;YACL,sBAAsB,CAAC,IAA6D;gBAClF,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;gBAC1B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;oBAAE,OAAO;gBAErC,MAAM,aAAa,GAAG,IAAA,aAAO,EAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CACpD,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS,IAAI,MAAM,CAAC,aAAa,KAAK,WAAW,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,mBAAmB,CAAC,CAAC;gBACvK,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,CAAC;gBACnI,IAAI,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,CAAC;oBAC9C,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,IAAA,gBAAU,EAAC,MAAM,CAAC,0BAA0B,EAAE,EAAE,CAAC,CAAC;gBAC5J,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnI,IAAI,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,CAAC;oBAC5C,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,IAAA,gBAAU,EAAC,MAAM,CAAC,0BAA0B,EAAE,EAAE,CAAC,CAAC;gBAC1J,CAAC;gBACD,KAAK,MAAM,MAAM,IAAI,IAAA,aAAO,EAAC,IAAI,CAAC,EAAE,CAAC;oBACnC,MAAM,MAAM,GAAG,IAAA,gBAAU,EAAC,MAAM,CAAC,IAAI,EAAE,CAAC;oBACxC,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;wBAChC,yHAAyH;wBACzH,MAAM,WAAW,GAAG,oBAAoB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC;wBACpF,MAAM,KAAK,GAAG,IAAA,gBAAU,EAAC,IAAI,EAAE,WAAW,CAAC,KAAK,SAAS,CAAC;wBAC1D,OAAO,CAAC,MAAM,CAAC;4BACb,IAAI,EAAE,MAAM,CAAC,GAAG;4BAChB,SAAS,EAAE,QAAQ;4BACnB,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE;4BACxB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC;yBACzI,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBACD,MAAM,WAAW,GAAG,IAAA,gBAAU,EAAC,IAAI,EAAE,aAAa,CAAC,CAAC;gBACpD,MAAM,QAAQ,GAAG,WAAW,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,iBAAiB,CAAC,IAAI,EAAE,CAAC;gBACjH,IAAI,WAAW,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,iBAAiB,IAAI,SAAS,CAAC,QAAQ,EAAE,IAAI,KAAK,eAAe,CAAC,EAAE,CAAC;oBACtI,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC;gBACtE,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
* service methods return domain entities (`Promise<Task>`); the framework serializes them
|
|
3
3
|
* through `toJSON`, so the app layer never calls it nor declares response-DTO return types.
|
|
4
4
|
*/
|
|
5
|
-
declare const _default: import("eslint").
|
|
5
|
+
declare const _default: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<string, any[], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
|
|
6
6
|
export default _default;
|
|
@@ -9,7 +9,7 @@ const rule_1 = require("../lib/rule");
|
|
|
9
9
|
exports.default = (0, rule_1.defineRule)({
|
|
10
10
|
meta: {
|
|
11
11
|
type: 'suggestion',
|
|
12
|
-
docs: { description: 'Forbid hand-serialization and response-DTO return types in the app layer' },
|
|
12
|
+
docs: { description: 'Forbid hand-serialization and response-DTO return types in the app layer', url: 'https://github.com/PiotrJozefow/pjx/tree/master/modules/eslint-style-rules#return-entities' },
|
|
13
13
|
messages: {
|
|
14
14
|
toJSON: 'Return the entity — the framework serializes it via toJSON.',
|
|
15
15
|
responseType: 'Return the domain entity, not "{{type}}".',
|
|
@@ -27,8 +27,8 @@ exports.default = (0, rule_1.defineRule)({
|
|
|
27
27
|
'MethodDefinition[kind="method"][accessibility!="private"] > FunctionExpression'(fn) {
|
|
28
28
|
const inner = (0, ast_1.promiseTypeArgument)(fn.returnType);
|
|
29
29
|
const type = inner?.type === 'TSArrayType' ? inner.elementType : inner;
|
|
30
|
-
const name = type?.type === 'TSTypeReference' ? type.typeName.name : null;
|
|
31
|
-
if (name && responseType.test(name)) {
|
|
30
|
+
const name = type?.type === 'TSTypeReference' && type.typeName.type === 'Identifier' ? type.typeName.name : null;
|
|
31
|
+
if (name && responseType.test(name) && fn.returnType) {
|
|
32
32
|
context.report({ node: fn.returnType, messageId: 'responseType', data: { type: name } });
|
|
33
33
|
}
|
|
34
34
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"return-entities.js","sourceRoot":"","sources":["../../src/rules/return-entities.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"return-entities.js","sourceRoot":"","sources":["../../src/rules/return-entities.ts"],"names":[],"mappings":";;AACA,oCAAiD;AACjD,sCAAyC;AAEzC;;;GAGG;AACH,kBAAe,IAAA,iBAAU,EAAC;IACxB,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,EAAE,WAAW,EAAE,0EAA0E,EAAE,GAAG,EAAE,4FAA4F,EAAE;QACpM,QAAQ,EAAE;YACR,MAAM,EAAE,6DAA6D;YACrE,YAAY,EAAE,2CAA2C;SAC1D;QACD,MAAM,EAAE,CAAC;gBACP,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,EAAE,mBAAmB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;gBACvD,oBAAoB,EAAE,KAAK;aAC5B,CAAC;KACH;IACD,MAAM,CAAC,OAAO;QACZ,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,mBAAmB,IAAI,mCAAmC,CAAC,CAAC;QAChH,OAAO;YACL,mEAAmE,EAAE,CAAC,IAA6B,EAAE,EAAE,CACrG,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;YAC/C,gFAAgF,CAAC,EAA+B;gBAC9G,MAAM,KAAK,GAAG,IAAA,yBAAmB,EAAC,EAAE,CAAC,UAAU,CAAC,CAAC;gBACjD,MAAM,IAAI,GAAG,KAAK,EAAE,IAAI,KAAK,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC;gBACvE,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,KAAK,iBAAiB,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBACjH,IAAI,IAAI,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,UAAU,EAAE,CAAC;oBACrD,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC,UAAU,EAAE,SAAS,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC3F,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* respond from the domain entity, never from what `repo.save()` returned.
|
|
3
|
-
* `save` signatures are `Promise<void
|
|
4
|
-
*
|
|
3
|
+
* `save` signatures are `Promise<void>` — on `…RepositoryPort` interfaces and on repositories (classes
|
|
4
|
+
* named `…Repository` or implementing a `…RepositoryPort`, never `@AppService` endpoints named
|
|
5
|
+
* `save`); a genuine `RETURNING` case is documented with
|
|
6
|
+
* `// eslint-disable-next-line pjts/save-contract -- RETURNING <column>`.
|
|
5
7
|
*/
|
|
6
|
-
declare const _default: import("eslint").
|
|
8
|
+
declare const _default: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<string, any[], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
|
|
7
9
|
export default _default;
|
|
@@ -4,13 +4,15 @@ const ast_1 = require("../lib/ast");
|
|
|
4
4
|
const rule_1 = require("../lib/rule");
|
|
5
5
|
/**
|
|
6
6
|
* respond from the domain entity, never from what `repo.save()` returned.
|
|
7
|
-
* `save` signatures are `Promise<void
|
|
8
|
-
*
|
|
7
|
+
* `save` signatures are `Promise<void>` — on `…RepositoryPort` interfaces and on repositories (classes
|
|
8
|
+
* named `…Repository` or implementing a `…RepositoryPort`, never `@AppService` endpoints named
|
|
9
|
+
* `save`); a genuine `RETURNING` case is documented with
|
|
10
|
+
* `// eslint-disable-next-line pjts/save-contract -- RETURNING <column>`.
|
|
9
11
|
*/
|
|
10
12
|
exports.default = (0, rule_1.defineRule)({
|
|
11
13
|
meta: {
|
|
12
14
|
type: 'suggestion',
|
|
13
|
-
docs: { description: 'Enforce the repository save() contract' },
|
|
15
|
+
docs: { description: 'Enforce the repository save() contract', url: 'https://github.com/PiotrJozefow/pjx/tree/master/modules/eslint-style-rules#save-contract' },
|
|
14
16
|
messages: {
|
|
15
17
|
usedResult: 'Respond from the entity itself, not from save()\'s return value.',
|
|
16
18
|
signature: '`save` must return Promise<void> unless the SQL uses RETURNING.',
|
|
@@ -33,8 +35,19 @@ exports.default = (0, rule_1.defineRule)({
|
|
|
33
35
|
if (isSaveCall(node.argument))
|
|
34
36
|
context.report({ node, messageId: 'usedResult' });
|
|
35
37
|
},
|
|
36
|
-
'TSMethodSignature[key.name="save"]': (node) =>
|
|
37
|
-
|
|
38
|
+
'TSMethodSignature[key.name="save"]': (node) => {
|
|
39
|
+
const owner = node.parent?.parent;
|
|
40
|
+
if (owner?.type === 'TSInterfaceDeclaration' && /RepositoryPort$/.test(owner.id.name))
|
|
41
|
+
checkSignature(node.key, node.returnType);
|
|
42
|
+
},
|
|
43
|
+
'MethodDefinition[key.name="save"]': (node) => {
|
|
44
|
+
const owner = node.parent?.parent;
|
|
45
|
+
if (!owner || (owner.type !== 'ClassDeclaration' && owner.type !== 'ClassExpression') || (0, ast_1.decoratorNames)(owner).includes('AppService'))
|
|
46
|
+
return;
|
|
47
|
+
const implementsRepositoryPort = (owner.implements ?? []).some((clause) => /RepositoryPort$/.test(context.sourceCode.getText(clause.expression)));
|
|
48
|
+
if (/Repository$/.test(owner.id?.name ?? '') || implementsRepositoryPort)
|
|
49
|
+
checkSignature(node.key, node.value.returnType);
|
|
50
|
+
},
|
|
38
51
|
};
|
|
39
52
|
},
|
|
40
53
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"save-contract.js","sourceRoot":"","sources":["../../src/rules/save-contract.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"save-contract.js","sourceRoot":"","sources":["../../src/rules/save-contract.ts"],"names":[],"mappings":";;AACA,oCAAgG;AAChG,sCAAyC;AAEzC;;;;;;GAMG;AACH,kBAAe,IAAA,iBAAU,EAAC;IACxB,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,EAAE,WAAW,EAAE,wCAAwC,EAAE,GAAG,EAAE,0FAA0F,EAAE;QAChK,QAAQ,EAAE;YACR,UAAU,EAAE,kEAAkE;YAC9E,SAAS,EAAE,iEAAiE;SAC7E;QACD,MAAM,EAAE,EAAE;KACX;IACD,MAAM,CAAC,OAAO;QACZ,MAAM,UAAU,GAAG,CAAC,IAAsC,EAAE,EAAE,CAAC,IAAA,sBAAgB,EAAC,IAAA,iBAAW,EAAC,IAAI,CAAC,CAAC,KAAK,MAAM,CAAC;QAC9G,MAAM,cAAc,GAAG,CAAC,GAAkB,EAAE,UAAiD,EAAE,EAAE;YAC/F,MAAM,KAAK,GAAG,IAAA,yBAAmB,EAAC,UAAU,CAAC,CAAC;YAC9C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,EAAE,IAAI,KAAK,eAAe;gBAAE,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,CAAC;QACpH,CAAC,CAAC;QACF,OAAO;YACL,kBAAkB,CAAC,IAAiC;gBAClD,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;oBAAE,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;YAC/E,CAAC;YACD,eAAe,CAAC,IAA8B;gBAC5C,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC;oBAAE,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;YACnF,CAAC;YACD,oCAAoC,EAAE,CAAC,IAAgC,EAAE,EAAE;gBACzE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;gBAClC,IAAI,KAAK,EAAE,IAAI,KAAK,wBAAwB,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC;oBAAE,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YACnI,CAAC;YACD,mCAAmC,EAAE,CAAC,IAA+B,EAAE,EAAE;gBACvE,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;gBAClC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,kBAAkB,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,CAAC,IAAI,IAAA,oBAAc,EAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;oBAAE,OAAO;gBAC9I,MAAM,wBAAwB,GAAG,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAClJ,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,IAAI,wBAAwB;oBAAE,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC5H,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* constructor: the wiring is derived from constructor signatures, and an inherited signature hides
|
|
4
4
|
* which dependencies the subclass really takes (and lets several subclasses share one ambiguous port).
|
|
5
5
|
*/
|
|
6
|
-
declare const _default: import("eslint").
|
|
6
|
+
declare const _default: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<string, any[], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
|
|
7
7
|
export default _default;
|
|
@@ -9,7 +9,7 @@ const rule_1 = require("../lib/rule");
|
|
|
9
9
|
exports.default = (0, rule_1.defineRule)({
|
|
10
10
|
meta: {
|
|
11
11
|
type: 'suggestion',
|
|
12
|
-
docs: { description: 'Subclasses in app/ and infrastructure/ declare their own constructor' },
|
|
12
|
+
docs: { description: 'Subclasses in app/ and infrastructure/ declare their own constructor', url: 'https://github.com/PiotrJozefow/pjx/tree/master/modules/eslint-style-rules#subclass-declares-constructor' },
|
|
13
13
|
messages: { missing: '{{name}} extends {{base}} but declares no constructor; declare the dependencies it takes (the wiring is derived from them).' },
|
|
14
14
|
schema: [{
|
|
15
15
|
type: 'object',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subclass-declares-constructor.js","sourceRoot":"","sources":["../../src/rules/subclass-declares-constructor.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"subclass-declares-constructor.js","sourceRoot":"","sources":["../../src/rules/subclass-declares-constructor.ts"],"names":[],"mappings":";;AACA,sCAAyC;AAEzC;;;;GAIG;AACH,kBAAe,IAAA,iBAAU,EAAC;IACxB,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,EAAE,WAAW,EAAE,sEAAsE,EAAE,GAAG,EAAE,0GAA0G,EAAE;QAC9M,QAAQ,EAAE,EAAE,OAAO,EAAE,6HAA6H,EAAE;QACpJ,MAAM,EAAE,CAAC;gBACP,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;gBACzE,oBAAoB,EAAE,KAAK;aAC5B,CAAC;KACH;IACD,MAAM,CAAC,OAAO;QACZ,4CAA4C;QAC5C,MAAM,WAAW,GAAa,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,EAAE,CAAC,CAAC,CAAC;QACpF,OAAO;YACL,8BAA8B,CAAC,IAA+B;gBAC5D,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,UAAW,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAC9E,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC;oBAAE,OAAO;gBACnE,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,kBAAkB,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC;gBAC5H,IAAI,CAAC,cAAc;oBAAE,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YACvI,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
|
|
@@ -10,5 +10,5 @@
|
|
|
10
10
|
* Checked as: the first segment of the test's file name is a source file in the same directory.
|
|
11
11
|
* When it isn't, the rule searches the source root (the nearest `src/`) to suggest where it belongs.
|
|
12
12
|
*/
|
|
13
|
-
declare const _default: import("eslint").
|
|
13
|
+
declare const _default: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<string, any[], unknown, import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
|
|
14
14
|
export default _default;
|
|
@@ -44,7 +44,7 @@ const indexOf = (root) => {
|
|
|
44
44
|
exports.default = (0, rule_1.defineRule)({
|
|
45
45
|
meta: {
|
|
46
46
|
type: 'suggestion',
|
|
47
|
-
docs: { description: 'Require tests to sit next to, and be named after, the file they test' },
|
|
47
|
+
docs: { description: 'Require tests to sit next to, and be named after, the file they test', url: 'https://github.com/PiotrJozefow/pjx/tree/master/modules/eslint-style-rules#test-location' },
|
|
48
48
|
messages: {
|
|
49
49
|
folder: 'Tests sit next to the code they test — move to {{target}}.',
|
|
50
50
|
name: 'Test files are named "<TestedFile>.<optional-suffix>.test.ts" — "{{file}}" has more than one suffix.',
|