@pjts/eslint-style-rules 0.0.4 → 0.0.6

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 CHANGED
@@ -106,15 +106,20 @@ exception is an inline disable with a reason:
106
106
  | Rule | What it checks |
107
107
  |---|---|
108
108
  | `module-layout` | only `rootFiles` at a module root (`<Module>Module.ts`, `<Module>MessageHandlers.ts`, `index.ts`); allowed top-level and `app/` subfolders; required entries exist |
109
- | `module-service-getters` | a `…Module`'s public getters return only `new X(...)` of a class from its own `./app/`, named `x` (camelCase) |
109
+ | `module-shape` | `…Module` = `@HttpModule` + `static readonly services`, `…MessageHandlers` = `@MessageHandlers` + `static readonly handlers`, `…Workers` = `@Workers` + `static readonly workers`; entries are classes from the module's own `./app/`; static methods with a return type are config providers; nothing else (no context, fields, getters, setters) |
110
+ | `module-service-getters` | (legacy, not in `configs.ddd`) a hand-wired `…Module`'s public getters return only `new X(...)` of a class from its own `./app/`, named `x` (camelCase) |
111
+ | `unique-class-names` | a class name is declared once under `src/modules/**` + `src/common/**` — class names key the wiring and the route registry |
112
+ | `subclass-declares-constructor` | app and infrastructure classes that `extends` something declare their own constructor (`ignoreBases` for `RepositoryBase` & co.) |
110
113
  | `port-file` | ports live in `app/ports/<Name>Port.ts`, one exported interface per file named like it; only types; no `…Port` elsewhere |
111
- | `port-has-adapters` | every `XRepositoryPort` has at least one implementation in the module's infrastructure |
114
+ | `port-has-adapters` | every `XPort` in `app/ports/` resolves to exactly one adapter per storage profile the way the container does: `implements` anywhere under `src/modules/**` / `src/common/**` (a prefixed `…XRepository` counts for repository ports), `pg` vs `memory` storage, a composite taking `XPort[]` wins, `@Adapter({ profile })` adapters are left to the profile |
112
115
  | `test-location` | `<TestedFile>.<optional-suffix>.test.ts` sits next to `<TestedFile>.ts`; no `__tests__/` |
113
116
 
114
117
  ### Cross-cutting
115
118
 
116
119
  | Rule | What it checks |
117
120
  |---|---|
121
+ | `no-manual-wiring` | no `new X(...)` of an app class (`…Service/View/Handler` from an `app/` path), an adapter (`infrastructure/` path, `Pg…`, `InMemory…`), a module/group class or an application-provided infra class (`JetStreamMessagePublisher`, …) — outside `domain/`, `testing/`, `deployments/`, tests |
122
+ | `config-provider-only` | `config.pick/pickMaybe/has` only in static config methods of a `…Module`/`…MessageHandlers`/`…Workers` class, under `common/config/` or `deployments/` (`allow`, `moduleStaticMethods`) |
118
123
  | `throw-app-error` | only `throw AppError.x(...)` / `throw new AppError(...)` from `@pjts/core`; rethrowing the caught error is allowed |
119
124
  | `import-only-in` | a package is imported only under given path fragments (`uuid` → `/domain/`) |
120
125
  | `no-duplicate-sdk-types` | frontend: no local type named like one in the generated client's `types.d.ts` |
package/dist/index.js CHANGED
@@ -20,6 +20,11 @@ const import_only_in_1 = tslib_1.__importDefault(require("./rules/import-only-in
20
20
  const knex_first_1 = tslib_1.__importDefault(require("./rules/knex-first"));
21
21
  const module_layout_1 = tslib_1.__importDefault(require("./rules/module-layout"));
22
22
  const module_service_getters_1 = tslib_1.__importDefault(require("./rules/module-service-getters"));
23
+ const module_shape_1 = tslib_1.__importDefault(require("./rules/module-shape"));
24
+ const no_manual_wiring_1 = tslib_1.__importDefault(require("./rules/no-manual-wiring"));
25
+ const config_provider_only_1 = tslib_1.__importDefault(require("./rules/config-provider-only"));
26
+ const unique_class_names_1 = tslib_1.__importDefault(require("./rules/unique-class-names"));
27
+ const subclass_declares_constructor_1 = tslib_1.__importDefault(require("./rules/subclass-declares-constructor"));
23
28
  const no_async_in_domain_1 = tslib_1.__importDefault(require("./rules/no-async-in-domain"));
24
29
  const no_duplicate_sdk_types_1 = tslib_1.__importDefault(require("./rules/no-duplicate-sdk-types"));
25
30
  const no_entity_assembly_in_app_1 = tslib_1.__importDefault(require("./rules/no-entity-assembly-in-app"));
@@ -53,6 +58,11 @@ const rules = {
53
58
  'knex-first': knex_first_1.default,
54
59
  'module-layout': module_layout_1.default,
55
60
  'module-service-getters': module_service_getters_1.default,
61
+ 'module-shape': module_shape_1.default,
62
+ 'no-manual-wiring': no_manual_wiring_1.default,
63
+ 'config-provider-only': config_provider_only_1.default,
64
+ 'unique-class-names': unique_class_names_1.default,
65
+ 'subclass-declares-constructor': subclass_declares_constructor_1.default,
56
66
  'no-async-in-domain': no_async_in_domain_1.default,
57
67
  'no-duplicate-sdk-types': no_duplicate_sdk_types_1.default,
58
68
  'no-entity-assembly-in-app': no_entity_assembly_in_app_1.default,
@@ -106,6 +116,10 @@ const createDddConfig = (options = {}) => {
106
116
  // Only …Pg…Repository classes depend on the client, and only they write through it.
107
117
  'pjts/db-client-dependency': 'error',
108
118
  'pjts/db-writes-in-repositories': 'error',
119
+ // Environment is read in module static config methods and common/config/ only.
120
+ 'pjts/config-provider-only': 'error',
121
+ // Class names key the generated wiring and the route registry.
122
+ 'pjts/unique-class-names': 'error',
109
123
  // Every thrown error is an AppError (rethrowing a caught error unchanged is fine).
110
124
  'pjts/throw-app-error': 'error',
111
125
  // Identities are minted by the domain.
@@ -119,6 +133,12 @@ const createDddConfig = (options = {}) => {
119
133
  ...(authAccess ? { 'pjts/auth-access': ['error', authAccess] } : {}),
120
134
  },
121
135
  },
136
+ {
137
+ // Nobody builds app classes, adapters or modules by hand: the IoC container does, from the wiring.
138
+ files: [`${src}/**/*.ts`],
139
+ ignores: [...exclude, `${module}/domain/**`, `${module}/testing/**`, `${src}/testing/**`],
140
+ rules: { 'pjts/no-manual-wiring': 'error' },
141
+ },
122
142
  // ── Messages: one per file, MessageNames in step ──────────────────────────
123
143
  {
124
144
  files: [`${messages}/*.ts`],
@@ -132,17 +152,18 @@ const createDddConfig = (options = {}) => {
132
152
  folders: ['app', 'domain', 'infrastructure', 'testing'],
133
153
  subfolders: { app: ['dto', 'ports'] },
134
154
  required: ['app', 'index.ts'],
135
- // The module's MessageHandlerBase composition root sits next to its HTTP module.
136
- rootFiles: ['{Module}Module.ts', '{Module}MessageHandlers.ts', 'index.ts'],
155
+ // The module's handler and worker groups sit next to its HTTP module.
156
+ rootFiles: ['{Module}Module.ts', '{Module}MessageHandlers.ts', '{Module}Workers.ts', 'index.ts'],
137
157
  }],
138
158
  // Ports: app/ports/<Name>Port.ts, one exported interface named like the file; `…Port` nowhere else.
139
159
  'pjts/port-file': 'error',
140
160
  },
141
161
  },
142
162
  {
143
- // Modules expose their own app-layer classes — and nothing else — as camelCase getters.
144
- files: [`${module}/*Module.ts`],
145
- rules: { 'pjts/module-service-getters': ['error', { suffixes: ['Service', 'View', 'Handler'] }] },
163
+ // Modules and groups are declarations: @HttpModule + static services, @MessageHandlers + static
164
+ // handlers, @Workers + static workers, static config methods — no context, getters or setters.
165
+ files: [`${module}/*Module.ts`, `${module}/*MessageHandlers.ts`, `${module}/*Workers.ts`],
166
+ rules: { 'pjts/module-shape': 'error' },
146
167
  },
147
168
  // ── Domain layer: pure, synchronous, no I/O ───────────────────────────────
148
169
  {
@@ -193,6 +214,11 @@ const createDddConfig = (options = {}) => {
193
214
  files: [`${module}/app/ports/*.ts`],
194
215
  rules: { 'pjts/port-has-adapters': 'error' },
195
216
  },
217
+ {
218
+ // Subclasses declare the dependencies they take; the wiring is derived from constructors.
219
+ files: [`${module}/app/*.ts`, `${module}/infrastructure/**/*.ts`],
220
+ rules: { 'pjts/subclass-declares-constructor': ['error', { ignoreBases: ['RepositoryBase', 'TransactionalRepositoryBase', 'OutboxRepository', 'KnexViewBase'] }] },
221
+ },
196
222
  {
197
223
  files: [`${module}/app/**/*.ts`, `${module}/infrastructure/**/*.ts`],
198
224
  rules: { 'pjts/save-contract': 'error' },
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AACA,wFAAsD;AACtD,8EAA6C;AAC7C,sGAAoE;AACpE,gFAA+C;AAC/C,sFAAqD;AACrD,oGAAkE;AAClE,kFAAiD;AACjD,0HAAsF;AACtF,oIAAgG;AAChG,gGAA+D;AAC/D,kGAAgE;AAChE,gGAA8D;AAC9D,0GAAuE;AACvE,wGAAsE;AACtE,sGAAoE;AACpE,sFAAoD;AACpD,oFAAkD;AAClD,4EAA2C;AAC3C,kFAAiD;AACjD,oGAAkE;AAClE,gFAA+C;AAC/C,wFAAsD;AACtD,gGAA8D;AAC9D,4FAA0D;AAC1D,kHAAgF;AAChF,4FAAyD;AACzD,oGAAiE;AACjE,0GAAsE;AACtE,sFAAqD;AACrD,0EAAyC;AACzC,0FAAwD;AACxD,0FAAyD;AACzD,wGAAuE;AACvE,sFAAqD;AACrD,kFAAiD;AACjD,kFAAiD;AACjD,sFAAoD;AAEpD,MAAM,KAAK,GAAG;IACZ,aAAa,EAAE,qBAAU;IACzB,yBAAyB,EAAE,iCAAqB;IAChD,cAAc,EAAE,sBAAW;IAC3B,iBAAiB,EAAE,yBAAc;IACjC,wBAAwB,EAAE,gCAAoB;IAC9C,eAAe,EAAE,uBAAY;IAC7B,mCAAmC,EAAE,2CAA6B;IAClE,wCAAwC,EAAE,gDAAkC;IAC5E,sBAAsB,EAAE,8BAAmB;IAC3C,kBAAkB,EAAE,0BAAc;IAClC,uBAAuB,EAAE,+BAAmB;IAC5C,sBAAsB,EAAE,8BAAkB;IAC1C,2BAA2B,EAAE,mCAAsB;IACnD,0BAA0B,EAAE,kCAAsB;IAClD,yBAAyB,EAAE,iCAAqB;IAChD,iBAAiB,EAAE,yBAAa;IAChC,gBAAgB,EAAE,wBAAY;IAC9B,YAAY,EAAE,oBAAS;IACvB,eAAe,EAAE,uBAAY;IAC7B,wBAAwB,EAAE,gCAAoB;IAC9C,cAAc,EAAE,sBAAW;IAC3B,kBAAkB,EAAE,0BAAc;IAClC,sBAAsB,EAAE,8BAAkB;IAC1C,oBAAoB,EAAE,4BAAgB;IACtC,+BAA+B,EAAE,uCAA2B;IAC5D,oBAAoB,EAAE,4BAAe;IACrC,wBAAwB,EAAE,gCAAmB;IAC7C,2BAA2B,EAAE,mCAAqB;IAClD,iBAAiB,EAAE,yBAAc;IACjC,WAAW,EAAE,mBAAQ;IACrB,mBAAmB,EAAE,2BAAe;IACpC,mBAAmB,EAAE,2BAAgB;IACrC,0BAA0B,EAAE,kCAAuB;IACnD,iBAAiB,EAAE,yBAAc;IACjC,eAAe,EAAE,uBAAY;IAC7B,eAAe,EAAE,uBAAY;IAC7B,iBAAiB,EAAE,yBAAa;CACjC,CAAC;AAsBF;;;GAGG;AACH,MAAM,eAAe,GAAG,CAAC,UAA4B,EAAE,EAAmB,EAAE;IAC1E,+EAA+E;IAC/E,MAAM,QAAQ,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAC9C,MAAM,EACJ,GAAG,GAAG,KAAK,EACX,OAAO,GAAG,aAAa,EACvB,OAAO,GAAG,CAAC,GAAG,GAAG,6BAA6B,EAAE,GAAG,GAAG,iBAAiB,CAAC,EACxE,SAAS,GAAG,CAAC,UAAU,EAAE,IAAI,GAAG,iBAAiB,CAAC,EAClD,QAAQ,GAAG,GAAG,GAAG,kBAAkB,EACnC,UAAU,GAAG,KAAK,EAClB,QAAQ,GAAG;QACT,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,8BAA8B,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAC7E,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE;QACzD,MAAM,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE;KAC/B,GACF,GAAG,OAAO,CAAC;IACZ,MAAM,MAAM,GAAG,GAAG,OAAO,IAAI,CAAC;IAC9B,MAAM,oBAAoB,GAAG,EAAE,KAAK,EAAE,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,EAAE,OAAO,EAAE,uDAAuD,EAAE,CAAC;IAExJ,OAAO;QACL;YACE,KAAK,EAAE,CAAC,GAAG,GAAG,UAAU,CAAC;YACzB,eAAe,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE;YAC5C,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,oBAAoB,EAAE,QAAQ,CAAC,MAAM,EAAE;YAChE,KAAK,EAAE;gBACL,sBAAsB,EAAE,OAAO;gBAC/B,+FAA+F;gBAC/F,4BAA4B,EAAE,OAAO;gBACrC,sFAAsF;gBACtF,oCAAoC,EAAE,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,CAAC,EAAE,CAAC;aAC3H;SACF;QACD;YACE,0FAA0F;YAC1F,KAAK,EAAE,CAAC,GAAG,MAAM,kBAAkB,CAAC;YACpC,KAAK,EAAE,EAAE,oCAAoC,EAAE,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,aAAa,EAAE,OAAO,EAAE,eAAe,EAAE,iBAAiB,CAAC,EAAE,CAAC,EAAE;SACtI;QAED,6EAA6E;QAC7E;YACE,KAAK,EAAE,CAAC,GAAG,GAAG,UAAU,CAAC;YACzB,OAAO,EAAE,OAAO;YAChB,KAAK,EAAE;gBACL,oFAAoF;gBACpF,2BAA2B,EAAE,OAAO;gBACpC,gCAAgC,EAAE,OAAO;gBACzC,+EAA+E;gBAC/E,2BAA2B,EAAE,OAAO;gBACpC,+DAA+D;gBAC/D,yBAAyB,EAAE,OAAO;gBAClC,mFAAmF;gBACnF,sBAAsB,EAAE,OAAO;gBAC/B,uCAAuC;gBACvC,qBAAqB,EAAE,CAAC,OAAO,EAAE;wBAC/B,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,2FAA2F,EAAE,EAAE;qBAC7I,CAAC;gBACF,oDAAoD;gBACpD,6BAA6B,EAAE,OAAO;gBACtC,iGAAiG;gBACjG,6CAA6C,EAAE,OAAO;gBACtD,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACrE;SACF;QAED;YACE,mGAAmG;YACnG,KAAK,EAAE,CAAC,GAAG,GAAG,UAAU,CAAC;YACzB,OAAO,EAAE,CAAC,GAAG,OAAO,EAAE,GAAG,MAAM,YAAY,EAAE,GAAG,MAAM,aAAa,EAAE,GAAG,GAAG,aAAa,CAAC;YACzF,KAAK,EAAE,EAAE,uBAAuB,EAAE,OAAO,EAAE;SAC5C;QAED,6EAA6E;QAC7E;YACE,KAAK,EAAE,CAAC,GAAG,QAAQ,OAAO,CAAC;YAC3B,KAAK,EAAE,EAAE,mBAAmB,EAAE,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE;SACvE;QAED,6EAA6E;QAC7E;YACE,KAAK,EAAE,CAAC,GAAG,MAAM,UAAU,CAAC;YAC5B,KAAK,EAAE;gBACL,oBAAoB,EAAE,CAAC,OAAO,EAAE;wBAC9B,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,SAAS,CAAC;wBACvD,UAAU,EAAE,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,EAAE;wBACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;wBAC7B,sEAAsE;wBACtE,SAAS,EAAE,CAAC,mBAAmB,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,UAAU,CAAC;qBACjG,CAAC;gBACF,oGAAoG;gBACpG,gBAAgB,EAAE,OAAO;aAC1B;SACF;QACD;YACE,gGAAgG;YAChG,+FAA+F;YAC/F,KAAK,EAAE,CAAC,GAAG,MAAM,aAAa,EAAE,GAAG,MAAM,sBAAsB,EAAE,GAAG,MAAM,cAAc,CAAC;YACzF,KAAK,EAAE,EAAE,mBAAmB,EAAE,OAAO,EAAE;SACxC;QAED,6EAA6E;QAC7E;YACE,KAAK,EAAE,CAAC,GAAG,MAAM,iBAAiB,CAAC;YACnC,KAAK,EAAE;gBACL,yBAAyB,EAAE,CAAC,OAAO,EAAE,EAAE,cAAc,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACpE,+BAA+B,EAAE,CAAC,OAAO,EAAE;wBACzC,SAAS,EAAE,EAAE,qBAAqB,EAAE,CAAC,QAAQ,CAAC,EAAE,qBAAqB,EAAE,CAAC,QAAQ,CAAC,EAAE,qBAAqB,EAAE,CAAC,QAAQ,CAAC,EAAE;qBACvH,CAAC;gBACF,8BAA8B,EAAE,OAAO;gBACvC,8FAA8F;gBAC9F,8BAA8B,EAAE,OAAO;gBACvC,uBAAuB,EAAE,CAAC,OAAO,EAAE;wBACjC,QAAQ,EAAE;4BACR,EAAE,KAAK,EAAE,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,EAAE,OAAO,EAAE,+CAA+C,EAAE;4BAClH,2GAA2G;4BAC3G,EAAE,KAAK,EAAE,0EAA0E,EAAE,OAAO,EAAE,6CAA6C,EAAE;4BAC7I,8FAA8F;4BAC9F,gGAAgG;4BAChG,EAAE,KAAK,EAAE,6BAA6B,EAAE,OAAO,EAAE,4CAA4C,EAAE;yBAChG;qBACF,CAAC;aACH;SACF;QACD;YACE,6DAA6D;YAC7D,KAAK,EAAE,CAAC,GAAG,MAAM,wBAAwB,EAAE,GAAG,MAAM,0BAA0B,EAAE,GAAG,MAAM,wBAAwB,CAAC;YAClH,KAAK,EAAE,EAAE,8BAA8B,EAAE,KAAK,EAAE;SACjD;QAED,6EAA6E;QAC7E;YACE,KAAK,EAAE,CAAC,GAAG,MAAM,WAAW,CAAC;YAC7B,OAAO,EAAE,CAAC,aAAa,CAAC;YACxB,KAAK,EAAE;gBACL,+GAA+G;gBAC/G,uBAAuB,EAAE,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC;gBACzF,sBAAsB,EAAE,OAAO;gBAC/B,gCAAgC,EAAE,OAAO;gBACzC,sBAAsB,EAAE,OAAO;gBAC/B,wFAAwF;gBACxF,sBAAsB,EAAE,OAAO;gBAC/B,0FAA0F;gBAC1F,wCAAwC,EAAE,OAAO;gBACjD,uBAAuB,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC;aACzE;SACF;QACD;YACE,KAAK,EAAE,CAAC,GAAG,MAAM,iBAAiB,CAAC;YACnC,KAAK,EAAE,EAAE,wBAAwB,EAAE,OAAO,EAAE;SAC7C;QACD;YACE,0FAA0F;YAC1F,KAAK,EAAE,CAAC,GAAG,MAAM,WAAW,EAAE,GAAG,MAAM,yBAAyB,CAAC;YACjE,KAAK,EAAE,EAAE,oCAAoC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,CAAC,gBAAgB,EAAE,6BAA6B,EAAE,kBAAkB,EAAE,cAAc,CAAC,EAAE,CAAC,EAAE;SACnK;QACD;YACE,KAAK,EAAE,CAAC,GAAG,MAAM,cAAc,EAAE,GAAG,MAAM,yBAAyB,CAAC;YACpE,KAAK,EAAE,EAAE,oBAAoB,EAAE,OAAO,EAAE;SACzC;QAED,6EAA6E;QAC7E;YACE,KAAK,EAAE,CAAC,GAAG,MAAM,yBAAyB,CAAC;YAC3C,KAAK,EAAE;gBACL,8GAA8G;gBAC9G,wBAAwB,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,2BAA2B,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC;gBAChH,+BAA+B,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,oBAAoB,EAAE,CAAC;gBAClF,iBAAiB,EAAE,OAAO;gBAC1B,mGAAmG;gBACnG,2BAA2B,EAAE,OAAO;aACrC;SACF;QAED,8EAA8E;QAC9E;YACE,KAAK,EAAE,CAAC,GAAG,GAAG,eAAe,CAAC;YAC9B,KAAK,EAAE;gBACL,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;gBAChF,oCAAoC,EAAE,KAAK;gBAC3C,uBAAuB,EAAE,KAAK;gBAC9B,oBAAoB,EAAE,OAAO;aAC9B;SACF;KACiB,CAAC;AACvB,CAAC,CAAC;AAEF,MAAM,MAAM,GAAG;IACb,IAAI,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE;IAC1C,KAAK;IACL,OAAO,EAAE,EAAqC;IAC9C,eAAe;CAChB,CAAC;AAEF,+FAA+F;AAC/F,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;AAEjG,iBAAS,MAA+G,CAAC"}
@@ -0,0 +1,28 @@
1
+ /** `<…>/src/<rest>` → the `src` directory of the file being linted, or null. */
2
+ export declare const srcRoot: (context: any) => string | null;
3
+ export interface ScannedClass {
4
+ name: string;
5
+ file: string;
6
+ implements: Set<string>;
7
+ /** `pg`, `memory`, `pg-nats`, … from the folder, else from the `Pg`/`InMemory` prefix. */
8
+ storage?: string;
9
+ /** `@Adapter({ profile: 'x' })` */
10
+ profile?: string;
11
+ /** Constructor parameter types written as `T[]` / `Array<T>`. */
12
+ arrayParams: Set<string>;
13
+ }
14
+ /**
15
+ * Every class declared under `<src>/modules/**` and `<src>/common/**` (tests excluded), read once per
16
+ * lint run with regexes — enough for names, `implements`, storage, profile and array constructor params.
17
+ */
18
+ export declare const scanClasses: (src: string) => ScannedClass[];
19
+ /** Test hook: forget scanned trees so a test can add files and re-scan. */
20
+ export declare const resetScans: () => void;
21
+ /**
22
+ * Adapters of `port` that the container would consider under `storage` with no active profile — the
23
+ * same rules as `@pjts/container`'s `candidatesOf`: the other storage world is dropped, an adapter of the
24
+ * active world outranks a storage-less one (composites stay), and a port whose adapters all live in the
25
+ * other world keeps them.
26
+ */
27
+ export declare const candidatesOf: (classes: ScannedClass[], port: string, storage: string) => ScannedClass[];
28
+ export declare const isCompositeOf: (cls: ScannedClass, port: string) => boolean;
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isCompositeOf = exports.candidatesOf = exports.resetScans = exports.scanClasses = exports.srcRoot = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
6
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
7
+ const ast_1 = require("./ast");
8
+ /** `<…>/src/<rest>` → the `src` directory of the file being linted, or null. */
9
+ const srcRoot = (context) => {
10
+ const file = (0, ast_1.filePath)(context);
11
+ const index = file.lastIndexOf('/src/');
12
+ return index === -1 ? null : file.slice(0, index + 4);
13
+ };
14
+ exports.srcRoot = srcRoot;
15
+ const STORAGE_FOLDERS = { pg: 'pg', 'pg+nats': 'pg-nats', 'pg-nats': 'pg-nats', redis: 'redis', s3: 's3', 'in-memory': 'memory', memory: 'memory' };
16
+ const storageOf = (file, name) => {
17
+ const segments = file.split('/');
18
+ const infrastructure = segments.indexOf('infrastructure');
19
+ if (infrastructure !== -1) {
20
+ for (const segment of segments.slice(infrastructure + 1, -1)) {
21
+ if (STORAGE_FOLDERS[segment])
22
+ return STORAGE_FOLDERS[segment];
23
+ }
24
+ }
25
+ if (/^InMemory[A-Z]/.test(name))
26
+ return 'memory';
27
+ if (/^Pg[A-Z]/.test(name))
28
+ return 'pg';
29
+ return undefined;
30
+ };
31
+ const scans = new Map();
32
+ /**
33
+ * Every class declared under `<src>/modules/**` and `<src>/common/**` (tests excluded), read once per
34
+ * lint run with regexes — enough for names, `implements`, storage, profile and array constructor params.
35
+ */
36
+ const scanClasses = (src) => {
37
+ const cached = scans.get(src);
38
+ if (cached)
39
+ return cached;
40
+ const classes = [];
41
+ const walk = (current) => {
42
+ if (!node_fs_1.default.existsSync(current))
43
+ return;
44
+ for (const entry of node_fs_1.default.readdirSync(current, { withFileTypes: true })) {
45
+ const full = node_path_1.default.join(current, entry.name);
46
+ if (entry.isDirectory()) {
47
+ // test doubles under testing/ are not adapters (the wiring generator skips them too)
48
+ if (!/^(__tests?__|test|testing|node_modules)$/.test(entry.name))
49
+ walk(full);
50
+ }
51
+ else if (/\.ts$/.test(entry.name) && !/\.(test|spec|d)\.ts$/.test(entry.name)) {
52
+ const source = node_fs_1.default.readFileSync(full, 'utf8');
53
+ const file = full.split(node_path_1.default.sep).join('/');
54
+ for (const match of source.matchAll(/(?:@Adapter\(\s*\{[^}]*profile\s*:\s*['"`]([\w-]+)['"`][^}]*\}\s*\)\s*)?(?:export\s+)?(?:abstract\s+)?class\s+(\w+)([^{]*)\{/g)) {
55
+ const [, profile, name, header] = match;
56
+ const implemented = header.match(/\bimplements\s+([\w\s,<>.]+)/)?.[1] ?? '';
57
+ const body = source.slice(match.index + match[0].length);
58
+ const constructorParams = body.match(/constructor\s*\(([^)]*)\)/)?.[1] ?? '';
59
+ const arrayParams = new Set();
60
+ for (const array of constructorParams.matchAll(/:\s*(?:readonly\s+)?(\w+)\[\]|:\s*(?:Readonly)?Array<\s*(\w+)\s*>/g)) {
61
+ arrayParams.add(array[1] ?? array[2]);
62
+ }
63
+ classes.push({
64
+ name,
65
+ file,
66
+ implements: new Set((implemented.match(/\b[A-Z]\w*/g) ?? []).filter((word) => word !== 'implements')),
67
+ storage: storageOf(file, name),
68
+ profile,
69
+ arrayParams,
70
+ });
71
+ }
72
+ }
73
+ }
74
+ };
75
+ walk(node_path_1.default.join(src, 'modules'));
76
+ walk(node_path_1.default.join(src, 'common'));
77
+ scans.set(src, classes);
78
+ return classes;
79
+ };
80
+ exports.scanClasses = scanClasses;
81
+ /** Test hook: forget scanned trees so a test can add files and re-scan. */
82
+ const resetScans = () => scans.clear();
83
+ exports.resetScans = resetScans;
84
+ const isMemory = (storage) => storage === 'memory';
85
+ /**
86
+ * Adapters of `port` that the container would consider under `storage` with no active profile — the
87
+ * same rules as `@pjts/container`'s `candidatesOf`: the other storage world is dropped, an adapter of the
88
+ * active world outranks a storage-less one (composites stay), and a port whose adapters all live in the
89
+ * other world keeps them.
90
+ */
91
+ const candidatesOf = (classes, port, storage) => {
92
+ const active = classes.filter((cls) => cls.implements.has(port) && cls.profile === undefined);
93
+ const inStorage = active.filter((cls) => cls.storage === undefined || isMemory(cls.storage) === isMemory(storage));
94
+ const specific = inStorage.filter((cls) => cls.storage !== undefined || (0, exports.isCompositeOf)(cls, port));
95
+ const preferred = specific.some((cls) => cls.storage !== undefined) ? specific : inStorage;
96
+ return preferred.length > 0 ? preferred : active;
97
+ };
98
+ exports.candidatesOf = candidatesOf;
99
+ const isCompositeOf = (cls, port) => cls.implements.has(port) && cls.arrayParams.has(port);
100
+ exports.isCompositeOf = isCompositeOf;
101
+ //# sourceMappingURL=wiring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wiring.js","sourceRoot":"","sources":["../../src/lib/wiring.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Environment is read in exactly two kinds of places: static config methods of a module class
3
+ * (`static calendarFeedConfig(): CalendarFeedConfig`) and the shared `common/config/` providers (plus
4
+ * the entry file under `deployments/`). Everywhere else a class declares the `…Config` object it needs
5
+ * as a constructor parameter.
6
+ */
7
+ declare const _default: import("eslint").Rule.RuleModule;
8
+ export default _default;
@@ -0,0 +1,59 @@
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
+ /**
6
+ * Environment is read in exactly two kinds of places: static config methods of a module class
7
+ * (`static calendarFeedConfig(): CalendarFeedConfig`) and the shared `common/config/` providers (plus
8
+ * the entry file under `deployments/`). Everywhere else a class declares the `…Config` object it needs
9
+ * as a constructor parameter.
10
+ */
11
+ exports.default = (0, rule_1.defineRule)({
12
+ meta: {
13
+ type: 'suggestion',
14
+ docs: { description: 'config.pick / pickMaybe / has only in config providers' },
15
+ messages: {
16
+ outside: '`{{object}}.{{method}}(...)` is allowed only in {{where}} — declare the `…Config` object as a constructor dependency instead.',
17
+ },
18
+ schema: [{
19
+ type: 'object',
20
+ properties: {
21
+ configNames: { type: 'array', items: { type: 'string' } },
22
+ methods: { type: 'array', items: { type: 'string' } },
23
+ allow: { type: 'array', items: { type: 'string' } },
24
+ moduleStaticMethods: { type: 'boolean' },
25
+ },
26
+ additionalProperties: false,
27
+ }],
28
+ },
29
+ create(context) {
30
+ const configNames = context.options[0]?.configNames ?? ['config'];
31
+ const methods = context.options[0]?.methods ?? ['pick', 'pickMaybe', 'has'];
32
+ const allow = context.options[0]?.allow ?? ['/common/config/', '/deployments/'];
33
+ const moduleStaticMethods = context.options[0]?.moduleStaticMethods ?? true;
34
+ const file = (0, ast_1.filePath)(context);
35
+ if (allow.some((fragment) => file.includes(fragment)))
36
+ return {};
37
+ const where = [moduleStaticMethods ? 'static config methods of a module class' : null, ...allow.map((fragment) => fragment.replace(/^\//, ''))]
38
+ .filter(Boolean)
39
+ .join(', ');
40
+ const inModuleStaticMethod = (node) => {
41
+ const ancestors = context.sourceCode.getAncestors(node);
42
+ const method = ancestors.find((ancestor) => ancestor.type === 'MethodDefinition');
43
+ const cls = ancestors.find((ancestor) => ancestor.type === 'ClassDeclaration');
44
+ return !!method && method.static && method.kind === 'method' && /(Module|MessageHandlers|Workers)$/.test(cls?.id?.name ?? '');
45
+ };
46
+ return {
47
+ 'CallExpression[callee.type="MemberExpression"][callee.object.type="Identifier"]'(node) {
48
+ const object = node.callee.object.name;
49
+ const method = node.callee.property?.name;
50
+ if (!configNames.includes(object) || !methods.includes(method))
51
+ return;
52
+ if (moduleStaticMethods && inModuleStaticMethod(node))
53
+ return;
54
+ context.report({ node, messageId: 'outside', data: { object, method, where } });
55
+ },
56
+ };
57
+ },
58
+ });
59
+ //# sourceMappingURL=config-provider-only.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-provider-only.js","sourceRoot":"","sources":["../../src/rules/config-provider-only.ts"],"names":[],"mappings":";;AAAA,oCAAsC;AACtC,sCAAyC;AAEzC;;;;;GAKG;AACH,kBAAe,IAAA,iBAAU,EAAC;IACxB,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,EAAE,WAAW,EAAE,wDAAwD,EAAE;QAC/E,QAAQ,EAAE;YACR,OAAO,EAAE,+HAA+H;SACzI;QACD,MAAM,EAAE,CAAC;gBACP,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,WAAW,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;oBACzD,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;oBACrD,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;oBACnD,mBAAmB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;iBACzC;gBACD,oBAAoB,EAAE,KAAK;aAC5B,CAAC;KACH;IACD,MAAM,CAAC,OAAO;QACZ,MAAM,WAAW,GAAa,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC5E,MAAM,OAAO,GAAa,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;QACtF,MAAM,KAAK,GAAa,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC;QAC1F,MAAM,mBAAmB,GAAY,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,mBAAmB,IAAI,IAAI,CAAC;QACrF,MAAM,IAAI,GAAG,IAAA,cAAQ,EAAC,OAAO,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAAE,OAAO,EAAE,CAAC;QACjE,MAAM,KAAK,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,yCAAyC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;aAC5I,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,MAAM,oBAAoB,GAAG,CAAC,IAAI,EAAW,EAAE;YAC7C,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAU,CAAC;YACjE,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC;YAClF,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC;YAC/E,OAAO,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,mCAAmC,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;QAChI,CAAC,CAAC;QAEF,OAAO;YACL,iFAAiF,CAAC,IAAI;gBACpF,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;gBACvC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC;gBAC1C,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;oBAAE,OAAO;gBACvE,IAAI,mBAAmB,IAAI,oBAAoB,CAAC,IAAI,CAAC;oBAAE,OAAO;gBAC9D,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YAClF,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Module, message-handler and worker group classes are declarations, not factories:
3
+ *
4
+ * @HttpModule('/v1')
5
+ * export class CalendarModule {
6
+ * static readonly services = [CalendarEventService, CalendarView]
7
+ * static calendarFeedConfig(): CalendarFeedConfig { … } // config provider (optional)
8
+ * }
9
+ *
10
+ * - `…Module` carries `@HttpModule` and `static readonly services`; `…MessageHandlers` carries
11
+ * `@MessageHandlers` and `static readonly handlers`; `…Workers` carries `@Workers` and `static readonly workers`;
12
+ * - every list entry is a class imported from the module's own `./app/…` (not `./app/dto`, `./app/ports`);
13
+ * - nothing else: no constructor, fields, getters, setters or instance methods (that was manual wiring);
14
+ * static methods with an explicit return type are config providers and are allowed unless
15
+ * `configProviders: false`.
16
+ */
17
+ declare const _default: import("eslint").Rule.RuleModule;
18
+ export default _default;
@@ -0,0 +1,111 @@
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
+ /**
6
+ * Module, message-handler and worker group classes are declarations, not factories:
7
+ *
8
+ * @HttpModule('/v1')
9
+ * export class CalendarModule {
10
+ * static readonly services = [CalendarEventService, CalendarView]
11
+ * static calendarFeedConfig(): CalendarFeedConfig { … } // config provider (optional)
12
+ * }
13
+ *
14
+ * - `…Module` carries `@HttpModule` and `static readonly services`; `…MessageHandlers` carries
15
+ * `@MessageHandlers` and `static readonly handlers`; `…Workers` carries `@Workers` and `static readonly workers`;
16
+ * - every list entry is a class imported from the module's own `./app/…` (not `./app/dto`, `./app/ports`);
17
+ * - nothing else: no constructor, fields, getters, setters or instance methods (that was manual wiring);
18
+ * static methods with an explicit return type are config providers and are allowed unless
19
+ * `configProviders: false`.
20
+ */
21
+ exports.default = (0, rule_1.defineRule)({
22
+ meta: {
23
+ type: 'suggestion',
24
+ docs: { description: 'Module and group classes declare their services, handlers or workers statically and nothing else' },
25
+ messages: {
26
+ decorator: '{{name}} must be decorated with @{{decorator}}.',
27
+ list: '{{name}} must declare `static readonly {{key}} = [...]` as an array literal of class names.',
28
+ notApp: '"{{entry}}" in {{name}}.{{key}} must be a class imported from ./app/ — {{what}}.',
29
+ member: '{{name}} may only declare `static readonly {{key}}`{{extra}}; found {{what}}. Wiring is derived by the container.',
30
+ configReturn: 'Static method {{name}}.{{method}}() must declare the config type it returns.',
31
+ },
32
+ schema: [{
33
+ type: 'object',
34
+ properties: { configProviders: { type: 'boolean' } },
35
+ additionalProperties: false,
36
+ }],
37
+ },
38
+ create(context) {
39
+ const configProviders = context.options[0]?.configProviders ?? true;
40
+ const imports = new Map();
41
+ const isAppSource = (source) => /^\.\/app(\/|$)/.test(source) && !/^\.\/app\/(dto|ports)(\/|$)/.test(source);
42
+ const kinds = [
43
+ { suffix: /Module$/, decorator: 'HttpModule', key: 'services' },
44
+ { suffix: /MessageHandlers$/, decorator: 'MessageHandlers', key: 'handlers' },
45
+ { suffix: /Workers$/, decorator: 'Workers', key: 'workers' },
46
+ ];
47
+ const describe = (member) => {
48
+ if (member.type === 'MethodDefinition') {
49
+ if (member.kind === 'constructor')
50
+ return 'a constructor';
51
+ if (member.kind === 'get' || member.kind === 'set')
52
+ return `${member.kind}ter \`${(0, ast_1.memberName)(member)}\``;
53
+ return `${member.static ? 'static ' : ''}method \`${(0, ast_1.memberName)(member)}\``;
54
+ }
55
+ return `${member.static ? 'static ' : ''}field \`${(0, ast_1.memberName)(member)}\``;
56
+ };
57
+ return {
58
+ ImportDeclaration(node) {
59
+ if (node.importKind === 'type')
60
+ return;
61
+ for (const specifier of node.specifiers) {
62
+ if (specifier.importKind !== 'type')
63
+ imports.set(specifier.local.name, node.source.value);
64
+ }
65
+ },
66
+ ClassDeclaration(node) {
67
+ const name = node.id?.name;
68
+ const kind = name && kinds.find((candidate) => candidate.suffix.test(name));
69
+ if (!kind)
70
+ return;
71
+ const extra = configProviders ? ' and static config methods' : '';
72
+ if (!(0, ast_1.decoratorNames)(node).includes(kind.decorator)) {
73
+ context.report({ node: node.id, messageId: 'decorator', data: { name, decorator: kind.decorator } });
74
+ }
75
+ const list = node.body.body.find((member) => member.type === 'PropertyDefinition' && member.static && (0, ast_1.memberName)(member) === kind.key);
76
+ if (!list || list.value?.type !== 'ArrayExpression') {
77
+ context.report({ node: list ?? node.id, messageId: 'list', data: { name, key: kind.key } });
78
+ }
79
+ else {
80
+ for (const element of list.value.elements) {
81
+ if (element?.type !== 'Identifier') {
82
+ context.report({ node: element ?? list, messageId: 'notApp', data: { entry: element ? context.sourceCode.getText(element) : 'hole', name, key: kind.key, what: 'it is not a class name' } });
83
+ continue;
84
+ }
85
+ const source = imports.get(element.name);
86
+ if (!source || !isAppSource(source)) {
87
+ context.report({
88
+ node: element,
89
+ messageId: 'notApp',
90
+ data: { entry: element.name, name, key: kind.key, what: source ? `it comes from '${source}'` : 'it is not imported from ./app/' },
91
+ });
92
+ }
93
+ }
94
+ }
95
+ for (const member of node.body.body) {
96
+ if (member === list)
97
+ continue;
98
+ const isStaticMethod = member.type === 'MethodDefinition' && member.static && member.kind === 'method';
99
+ if (configProviders && isStaticMethod) {
100
+ if (!member.value.returnType) {
101
+ context.report({ node: member.key, messageId: 'configReturn', data: { name, method: (0, ast_1.memberName)(member) } });
102
+ }
103
+ continue;
104
+ }
105
+ context.report({ node: member.key ?? member, messageId: 'member', data: { name, key: kind.key, extra, what: describe(member) } });
106
+ }
107
+ },
108
+ };
109
+ },
110
+ });
111
+ //# sourceMappingURL=module-shape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-shape.js","sourceRoot":"","sources":["../../src/rules/module-shape.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Nobody constructs application classes, adapters or modules by hand — the IoC container does, from the
3
+ * generated wiring. `new X(...)` is reported when X is:
4
+ * - a value imported from an `app/` path (not `app/dto`, `app/ports`) whose name ends with a use-case suffix;
5
+ * - a value imported from an `infrastructure` path, or named `Pg…` / `InMemory…`;
6
+ * - a class named `…Module`, `…MessageHandlers` or `…Workers`;
7
+ * - one of the infrastructure classes the application itself provides (`JetStreamMessagePublisher`, …).
8
+ * Apply it outside `domain/`, `testing/`, `deployments/` and tests.
9
+ */
10
+ declare const _default: import("eslint").Rule.RuleModule;
11
+ export default _default;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const rule_1 = require("../lib/rule");
4
+ /**
5
+ * Nobody constructs application classes, adapters or modules by hand — the IoC container does, from the
6
+ * generated wiring. `new X(...)` is reported when X is:
7
+ * - a value imported from an `app/` path (not `app/dto`, `app/ports`) whose name ends with a use-case suffix;
8
+ * - a value imported from an `infrastructure` path, or named `Pg…` / `InMemory…`;
9
+ * - a class named `…Module`, `…MessageHandlers` or `…Workers`;
10
+ * - one of the infrastructure classes the application itself provides (`JetStreamMessagePublisher`, …).
11
+ * Apply it outside `domain/`, `testing/`, `deployments/` and tests.
12
+ */
13
+ exports.default = (0, rule_1.defineRule)({
14
+ meta: {
15
+ type: 'suggestion',
16
+ docs: { description: 'No hand-built application classes, adapters or modules — the container builds them' },
17
+ messages: {
18
+ wiring: '`new {{name}}(...)` is manual wiring ({{why}}): declare {{name}} as a constructor dependency and let the container build it.',
19
+ },
20
+ schema: [{
21
+ type: 'object',
22
+ properties: {
23
+ suffixes: { type: 'array', items: { type: 'string' } },
24
+ infraClasses: { type: 'array', items: { type: 'string' } },
25
+ },
26
+ additionalProperties: false,
27
+ }],
28
+ },
29
+ create(context) {
30
+ const suffixes = context.options[0]?.suffixes ?? ['Service', 'View', 'Handler'];
31
+ const infraClasses = context.options[0]?.infraClasses ?? ['JetStreamMessagePublisher', 'JetStreamMessageSubscriber', 'RedisMessageDeduplicator', 'MessageRepeater'];
32
+ const imports = new Map();
33
+ const isApp = (source) => /(^|\/)app(\/|$)/.test(source) && !/(^|\/)app\/(dto|ports)(\/|$)/.test(source);
34
+ const isInfrastructure = (source) => /(^|\/)infrastructure(\/|$)/.test(source);
35
+ const why = (name) => {
36
+ const source = imports.get(name);
37
+ if (/(Module|MessageHandlers|Workers)$/.test(name))
38
+ return 'module and group classes are declarations';
39
+ if (source && isApp(source) && suffixes.some((suffix) => name.endsWith(suffix)))
40
+ return `${name} is an application class from '${source}'`;
41
+ if (source && isInfrastructure(source))
42
+ return `${name} is an adapter from '${source}'`;
43
+ if (/^(Pg|InMemory)[A-Z]/.test(name))
44
+ return `${name} is an adapter`;
45
+ if (infraClasses.includes(name))
46
+ return `${name} is provided by the application`;
47
+ return null;
48
+ };
49
+ return {
50
+ ImportDeclaration(node) {
51
+ if (node.importKind === 'type')
52
+ return;
53
+ for (const specifier of node.specifiers) {
54
+ if (specifier.importKind !== 'type')
55
+ imports.set(specifier.local.name, node.source.value);
56
+ }
57
+ },
58
+ 'NewExpression[callee.type="Identifier"]'(node) {
59
+ const name = node.callee.name;
60
+ const reason = why(name);
61
+ if (reason)
62
+ context.report({ node, messageId: 'wiring', data: { name, why: reason } });
63
+ },
64
+ };
65
+ },
66
+ });
67
+ //# sourceMappingURL=no-manual-wiring.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-manual-wiring.js","sourceRoot":"","sources":["../../src/rules/no-manual-wiring.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
1
  /**
2
- * Every `<X>RepositoryPort` declared in `app/ports/` has at least one implementation in the module's
3
- * `infrastructure/`: a class that `implements` the port, or a prefixed `…<X>Repository`
4
- * (`PgXRepository`, `PgNatsXRepository`, `InMemoryXRepository`, …). Which prefix is right for its
5
- * folder is `repository-naming`'s job.
2
+ * Every `<X>Port` declared in `app/ports/` resolves to exactly one adapter per storage profile, the
3
+ * way the IoC container resolves it: a class anywhere under `src/modules/**` or `src/common/**` that
4
+ * `implements` the port (for repository ports a prefixed `…<X>Repository` also counts), filtered by
5
+ * storage (`pg` vs `memory` folders / prefixes), with a composite (`implements T`, takes `T[]`)
6
+ * winning over the adapters it wraps, and adapters behind `@Adapter({ profile })` left to the profile.
6
7
  * Reads sibling files, so editors only re-check it when the port file itself is re-linted.
7
8
  */
8
9
  declare const _default: import("eslint").Rule.RuleModule;
@@ -1,60 +1,59 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const tslib_1 = require("tslib");
4
- const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
5
- const node_path_1 = tslib_1.__importDefault(require("node:path"));
6
3
  const ast_1 = require("../lib/ast");
7
4
  const rule_1 = require("../lib/rule");
8
- /** infrastructure dir → [{ name, implements: Set<string> }] for every class declared in it (per lint run). */
9
- const infrastructureClasses = new Map();
10
- const classesIn = (dir) => {
11
- if (!infrastructureClasses.has(dir)) {
12
- const classes = [];
13
- const walk = (current) => {
14
- if (!node_fs_1.default.existsSync(current))
15
- return;
16
- for (const entry of node_fs_1.default.readdirSync(current, { withFileTypes: true })) {
17
- const full = node_path_1.default.join(current, entry.name);
18
- if (entry.isDirectory())
19
- walk(full);
20
- else if (/\.ts$/.test(entry.name) && !/\.test\.ts$/.test(entry.name)) {
21
- for (const match of node_fs_1.default.readFileSync(full, 'utf8').matchAll(/\bclass\s+(\w+)([^{]*)\{/g)) {
22
- const implemented = match[2].match(/\bimplements\s+([\w\s,<>.]+)/)?.[1] ?? '';
23
- classes.push({ name: match[1], implements: new Set(implemented.match(/\w+/g) ?? []) });
24
- }
25
- }
26
- }
27
- };
28
- walk(dir);
29
- infrastructureClasses.set(dir, classes);
30
- }
31
- return infrastructureClasses.get(dir);
32
- };
5
+ const wiring_1 = require("../lib/wiring");
33
6
  /**
34
- * Every `<X>RepositoryPort` declared in `app/ports/` has at least one implementation in the module's
35
- * `infrastructure/`: a class that `implements` the port, or a prefixed `…<X>Repository`
36
- * (`PgXRepository`, `PgNatsXRepository`, `InMemoryXRepository`, …). Which prefix is right for its
37
- * folder is `repository-naming`'s job.
7
+ * Every `<X>Port` declared in `app/ports/` resolves to exactly one adapter per storage profile, the
8
+ * way the IoC container resolves it: a class anywhere under `src/modules/**` or `src/common/**` that
9
+ * `implements` the port (for repository ports a prefixed `…<X>Repository` also counts), filtered by
10
+ * storage (`pg` vs `memory` folders / prefixes), with a composite (`implements T`, takes `T[]`)
11
+ * winning over the adapters it wraps, and adapters behind `@Adapter({ profile })` left to the profile.
38
12
  * Reads sibling files, so editors only re-check it when the port file itself is re-linted.
39
13
  */
40
14
  exports.default = (0, rule_1.defineRule)({
41
15
  meta: {
42
16
  type: 'suggestion',
43
- docs: { description: 'Require every repository port to have at least one infrastructure implementation' },
44
- messages: { missing: 'Port "{{port}}" has no implementation in {{module}}/infrastructure/ (expected e.g. Pg{{base}}).' },
45
- schema: [],
17
+ docs: { description: 'Require every port to have exactly one adapter per storage profile' },
18
+ messages: {
19
+ missing: 'Port "{{port}}" has no adapter under src/modules or src/common (expected e.g. Pg{{base}} implementing it).',
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 }).',
21
+ composites: 'Port "{{port}}" has more than one composite adapter: {{names}}.',
22
+ },
23
+ schema: [{
24
+ type: 'object',
25
+ properties: { storages: { type: 'array', items: { type: 'string' } } },
26
+ additionalProperties: false,
27
+ }],
46
28
  },
47
29
  create(context) {
30
+ const storages = context.options[0]?.storages ?? ['pg', 'memory'];
48
31
  const location = (0, ast_1.moduleLocation)(context);
49
- if (!location || location.rest[0] !== 'app' || location.rest[1] !== 'ports')
32
+ const src = (0, wiring_1.srcRoot)(context);
33
+ if (!location || !src || location.rest[0] !== 'app' || location.rest[1] !== 'ports')
50
34
  return {};
51
35
  return {
52
- 'TSInterfaceDeclaration[id.name=/RepositoryPort$/]'(node) {
36
+ 'TSInterfaceDeclaration[id.name=/Port$/]'(node) {
53
37
  const port = node.id.name;
54
38
  const base = port.replace(/Port$/, '');
55
- const implemented = classesIn(node_path_1.default.join(location.root, 'infrastructure')).some((cls) => cls.implements.has(port) || (cls.name !== base && cls.name.endsWith(base) && /^[A-Z]/.test(cls.name)));
56
- if (!implemented)
57
- context.report({ node: node.id, messageId: 'missing', data: { port, base, module: location.module } });
39
+ const classes = (0, wiring_1.scanClasses)(src);
40
+ const implementers = classes.filter((cls) => cls.implements.has(port) || (/RepositoryPort$/.test(port) && cls.name !== base && cls.name.endsWith(base)));
41
+ if (implementers.length === 0) {
42
+ context.report({ node: node.id, messageId: 'missing', data: { port, base } });
43
+ return;
44
+ }
45
+ for (const storage of storages) {
46
+ const candidates = (0, wiring_1.candidatesOf)(classes, port, storage);
47
+ const composites = candidates.filter((cls) => (0, wiring_1.isCompositeOf)(cls, port));
48
+ if (composites.length > 1) {
49
+ context.report({ node: node.id, messageId: 'composites', data: { port, names: composites.map((cls) => cls.name).join(', ') } });
50
+ return;
51
+ }
52
+ if (composites.length === 0 && candidates.length > 1) {
53
+ context.report({ node: node.id, messageId: 'ambiguous', data: { port, storage, count: String(candidates.length), names: candidates.map((cls) => cls.name).join(', ') } });
54
+ return;
55
+ }
56
+ }
58
57
  },
59
58
  };
60
59
  },
@@ -1 +1 @@
1
- {"version":3,"file":"port-has-adapters.js","sourceRoot":"","sources":["../../src/rules/port-has-adapters.ts"],"names":[],"mappings":";;;AAAA,8DAAyB;AACzB,kEAA6B;AAC7B,oCAA4C;AAC5C,sCAAyC;AAEzC,8GAA8G;AAC9G,MAAM,qBAAqB,GAAG,IAAI,GAAG,EAAE,CAAC;AAExC,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,EAAE;IACxB,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;QACpC,MAAM,OAAO,GAAU,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,EAAE;YACvB,IAAI,CAAC,iBAAE,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,OAAO;YACpC,KAAK,MAAM,KAAK,IAAI,iBAAE,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;gBACrE,MAAM,IAAI,GAAG,mBAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC5C,IAAI,KAAK,CAAC,WAAW,EAAE;oBAAE,IAAI,CAAC,IAAI,CAAC,CAAC;qBAC/B,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;oBACrE,KAAK,MAAM,KAAK,IAAI,iBAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,2BAA2B,CAAC,EAAE,CAAC;wBACxF,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,8BAA8B,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;wBAC9E,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,GAAG,CAAC,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;oBACzF,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,qBAAqB,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,qBAAqB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACxC,CAAC,CAAC;AAEF;;;;;;GAMG;AACH,kBAAe,IAAA,iBAAU,EAAC;IACxB,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,EAAE,WAAW,EAAE,kFAAkF,EAAE;QACzG,QAAQ,EAAE,EAAE,OAAO,EAAE,iGAAiG,EAAE;QACxH,MAAM,EAAE,EAAE;KACX;IACD,MAAM,CAAC,OAAO;QACZ,MAAM,QAAQ,GAAG,IAAA,oBAAc,EAAC,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO;YAAE,OAAO,EAAE,CAAC;QACvF,OAAO;YACL,mDAAmD,CAAC,IAAI;gBACtD,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;gBAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBACvC,MAAM,WAAW,GAAG,SAAS,CAAC,mBAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAC5E,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAC/G,CAAC;gBACF,IAAI,CAAC,WAAW;oBAAE,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;YAC3H,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
1
+ {"version":3,"file":"port-has-adapters.js","sourceRoot":"","sources":["../../src/rules/port-has-adapters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Application services, adapters, handlers and workers that extend a class declare their own
3
+ * constructor: the wiring is derived from constructor signatures, and an inherited signature hides
4
+ * which dependencies the subclass really takes (and lets several subclasses share one ambiguous port).
5
+ */
6
+ declare const _default: import("eslint").Rule.RuleModule;
7
+ export default _default;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const rule_1 = require("../lib/rule");
4
+ /**
5
+ * Application services, adapters, handlers and workers that extend a class declare their own
6
+ * constructor: the wiring is derived from constructor signatures, and an inherited signature hides
7
+ * which dependencies the subclass really takes (and lets several subclasses share one ambiguous port).
8
+ */
9
+ exports.default = (0, rule_1.defineRule)({
10
+ meta: {
11
+ type: 'suggestion',
12
+ docs: { description: 'Subclasses in app/ and infrastructure/ declare their own constructor' },
13
+ messages: { missing: '{{name}} extends {{base}} but declares no constructor; declare the dependencies it takes (the wiring is derived from them).' },
14
+ schema: [{
15
+ type: 'object',
16
+ properties: { ignoreBases: { type: 'array', items: { type: 'string' } } },
17
+ additionalProperties: false,
18
+ }],
19
+ },
20
+ create(context) {
21
+ // Error subclasses are thrown, never wired.
22
+ const ignoreBases = ['Error', ...(context.options[0]?.ignoreBases ?? [])];
23
+ return {
24
+ 'ClassDeclaration[superClass]'(node) {
25
+ const base = context.sourceCode.getText(node.superClass).replace(/<.*$/, '');
26
+ if (ignoreBases.includes(base) || (node.abstract ?? false))
27
+ return;
28
+ const hasConstructor = node.body.body.some((member) => member.type === 'MethodDefinition' && member.kind === 'constructor');
29
+ if (!hasConstructor)
30
+ context.report({ node: node.id ?? node, messageId: 'missing', data: { name: node.id?.name ?? 'class', base } });
31
+ },
32
+ };
33
+ },
34
+ });
35
+ //# sourceMappingURL=subclass-declares-constructor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subclass-declares-constructor.js","sourceRoot":"","sources":["../../src/rules/subclass-declares-constructor.ts"],"names":[],"mappings":";;AAAA,sCAAyC;AAEzC;;;;GAIG;AACH,kBAAe,IAAA,iBAAU,EAAC;IACxB,IAAI,EAAE;QACJ,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,EAAE,WAAW,EAAE,sEAAsE,EAAE;QAC7F,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,IAAI;gBACjC,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAC7E,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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Class names are the keys of the generated wiring and of the HTTP route registry, so they are unique
3
+ * per repository (ubiquitous language). Reads every class declared under `src/modules/**` and
4
+ * `src/common/**` once per lint run.
5
+ */
6
+ declare const _default: import("eslint").Rule.RuleModule;
7
+ export default _default;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
5
+ const ast_1 = require("../lib/ast");
6
+ const rule_1 = require("../lib/rule");
7
+ const wiring_1 = require("../lib/wiring");
8
+ const UNWIRED_DECORATORS = ['Dto', 'StringDomainPrimitive', 'NumberDomainPrimitive', 'ObjectDomainPrimitive', 'StringArrayDomainPrimitive', 'NullBoolDomainPrimitive'];
9
+ /**
10
+ * Class names are the keys of the generated wiring and of the HTTP route registry, so they are unique
11
+ * per repository (ubiquitous language). Reads every class declared under `src/modules/**` and
12
+ * `src/common/**` once per lint run.
13
+ */
14
+ exports.default = (0, rule_1.defineRule)({
15
+ meta: {
16
+ type: 'problem',
17
+ docs: { description: 'Class names are unique across the repository' },
18
+ messages: { duplicate: 'Class "{{name}}" is also declared in {{other}}; class names must be unique per repository.' },
19
+ schema: [],
20
+ },
21
+ create(context) {
22
+ const src = (0, wiring_1.srcRoot)(context);
23
+ if (!src)
24
+ return {};
25
+ const file = (0, ast_1.filePath)(context);
26
+ return {
27
+ ClassDeclaration(node) {
28
+ if (!node.id)
29
+ return;
30
+ // DTOs, domain primitives and domain classes are never wired; two modules may each have a DocumentIdDto.
31
+ const decorators = (node.decorators ?? []).map((d) => (d.expression.type === 'CallExpression' ? d.expression.callee : d.expression)).map((e) => e.name);
32
+ if (/\/(domain|dto)\//.test(file) || decorators.some((name) => UNWIRED_DECORATORS.includes(name)))
33
+ return;
34
+ const other = (0, wiring_1.scanClasses)(src).find((cls) => cls.name === node.id.name && cls.file !== file);
35
+ if (other)
36
+ context.report({ node: node.id, messageId: 'duplicate', data: { name: node.id.name, other: node_path_1.default.relative(src, other.file) } });
37
+ },
38
+ };
39
+ },
40
+ });
41
+ //# sourceMappingURL=unique-class-names.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unique-class-names.js","sourceRoot":"","sources":["../../src/rules/unique-class-names.ts"],"names":[],"mappings":";;;AAAA,kEAA6B;AAC7B,oCAAsC;AACtC,sCAAyC;AACzC,0CAAqD;AAErD,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,yBAAyB,CAAC,CAAC;AAEvK;;;;GAIG;AACH,kBAAe,IAAA,iBAAU,EAAC;IACxB,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,EAAE,WAAW,EAAE,8CAA8C,EAAE;QACrE,QAAQ,EAAE,EAAE,SAAS,EAAE,4FAA4F,EAAE;QACrH,MAAM,EAAE,EAAE;KACX;IACD,MAAM,CAAC,OAAO;QACZ,MAAM,GAAG,GAAG,IAAA,gBAAO,EAAC,OAAO,CAAC,CAAC;QAC7B,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,GAAG,IAAA,cAAQ,EAAC,OAAO,CAAC,CAAC;QAC/B,OAAO;YACL,gBAAgB,CAAC,IAAI;gBACnB,IAAI,CAAC,IAAI,CAAC,EAAE;oBAAE,OAAO;gBACrB,yGAAyG;gBACzG,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBACxJ,IAAI,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;oBAAE,OAAO;gBAC1G,MAAM,KAAK,GAAG,IAAA,oBAAW,EAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;gBAC7F,IAAI,KAAK;oBAAE,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,mBAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;YAC5I,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pjts/eslint-style-rules",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "Piotr Józefów DDD utility package — ESLint rules and flat-config preset enforcing the pjts DDD layout and conventions",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",