@luma-layered-ts/eslint-plugin 1.0.1 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.d.ts CHANGED
@@ -1,11 +1,21 @@
1
1
  import type { TSESLint } from "@typescript-eslint/utils";
2
2
  export declare const rules: {
3
- server: TSESLint.RuleModule<"importViolation" | "encodedGlobal" | "ioGlobal" | "schemaBoundary" | "encodedMethod", [{
3
+ server: TSESLint.RuleModule<"importViolation" | "importNonLayer" | "encodedGlobal" | "ioGlobal" | "schemaBoundary" | "encodedMethod", [{
4
4
  [x: string]: never;
5
5
  }], unknown, TSESLint.RuleListener> & {
6
6
  name: string;
7
7
  };
8
- react: TSESLint.RuleModule<"importViolation" | "encodedGlobal" | "schemaBoundary" | "encodedMethod" | "componentParseMethod", [{
8
+ react: TSESLint.RuleModule<"importViolation" | "importNonLayer" | "encodedGlobal" | "schemaBoundary" | "encodedMethod" | "componentParseMethod", [{
9
+ [x: string]: never;
10
+ }], unknown, TSESLint.RuleListener> & {
11
+ name: string;
12
+ };
13
+ next: TSESLint.RuleModule<"importViolation" | "importNonLayer" | "encodedGlobal" | "schemaBoundary" | "encodedMethod", [{
14
+ [x: string]: never;
15
+ }], unknown, TSESLint.RuleListener> & {
16
+ name: string;
17
+ };
18
+ "require-layer": TSESLint.RuleModule<"noLayer", [{
9
19
  [x: string]: never;
10
20
  }], unknown, TSESLint.RuleListener> & {
11
21
  name: string;
@@ -16,12 +26,55 @@ export declare const configs: {
16
26
  plugins: {
17
27
  "@luma-layered-ts": {
18
28
  rules: {
19
- server: TSESLint.RuleModule<"importViolation" | "encodedGlobal" | "ioGlobal" | "schemaBoundary" | "encodedMethod", [{
29
+ server: TSESLint.RuleModule<"importViolation" | "importNonLayer" | "encodedGlobal" | "ioGlobal" | "schemaBoundary" | "encodedMethod", [{
30
+ [x: string]: never;
31
+ }], unknown, TSESLint.RuleListener> & {
32
+ name: string;
33
+ };
34
+ react: TSESLint.RuleModule<"importViolation" | "importNonLayer" | "encodedGlobal" | "schemaBoundary" | "encodedMethod" | "componentParseMethod", [{
35
+ [x: string]: never;
36
+ }], unknown, TSESLint.RuleListener> & {
37
+ name: string;
38
+ };
39
+ next: TSESLint.RuleModule<"importViolation" | "importNonLayer" | "encodedGlobal" | "schemaBoundary" | "encodedMethod", [{
40
+ [x: string]: never;
41
+ }], unknown, TSESLint.RuleListener> & {
42
+ name: string;
43
+ };
44
+ "require-layer": TSESLint.RuleModule<"noLayer", [{
45
+ [x: string]: never;
46
+ }], unknown, TSESLint.RuleListener> & {
47
+ name: string;
48
+ };
49
+ };
50
+ };
51
+ };
52
+ rules: {
53
+ "@luma-layered-ts/server": "error";
54
+ "@luma-layered-ts/react": "error";
55
+ "@luma-layered-ts/require-layer": "error";
56
+ };
57
+ };
58
+ "recommended-next": {
59
+ plugins: {
60
+ "@luma-layered-ts": {
61
+ rules: {
62
+ server: TSESLint.RuleModule<"importViolation" | "importNonLayer" | "encodedGlobal" | "ioGlobal" | "schemaBoundary" | "encodedMethod", [{
63
+ [x: string]: never;
64
+ }], unknown, TSESLint.RuleListener> & {
65
+ name: string;
66
+ };
67
+ react: TSESLint.RuleModule<"importViolation" | "importNonLayer" | "encodedGlobal" | "schemaBoundary" | "encodedMethod" | "componentParseMethod", [{
68
+ [x: string]: never;
69
+ }], unknown, TSESLint.RuleListener> & {
70
+ name: string;
71
+ };
72
+ next: TSESLint.RuleModule<"importViolation" | "importNonLayer" | "encodedGlobal" | "schemaBoundary" | "encodedMethod", [{
20
73
  [x: string]: never;
21
74
  }], unknown, TSESLint.RuleListener> & {
22
75
  name: string;
23
76
  };
24
- react: TSESLint.RuleModule<"importViolation" | "encodedGlobal" | "schemaBoundary" | "encodedMethod" | "componentParseMethod", [{
77
+ "require-layer": TSESLint.RuleModule<"noLayer", [{
25
78
  [x: string]: never;
26
79
  }], unknown, TSESLint.RuleListener> & {
27
80
  name: string;
@@ -32,6 +85,8 @@ export declare const configs: {
32
85
  rules: {
33
86
  "@luma-layered-ts/server": "error";
34
87
  "@luma-layered-ts/react": "error";
88
+ "@luma-layered-ts/next": "error";
89
+ "@luma-layered-ts/require-layer": "error";
35
90
  };
36
91
  };
37
92
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEzD,eAAO,MAAM,KAAK;;;;;;;;;;;CAGjB,CAAC;AAMF,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;CAUnB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEzD,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;CAKjB,CAAC;AAMF,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsBnB,CAAC"}
package/lib/index.js CHANGED
@@ -6,9 +6,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.configs = exports.rules = void 0;
7
7
  const server_1 = __importDefault(require("./rules/server"));
8
8
  const react_1 = __importDefault(require("./rules/react"));
9
+ const next_1 = __importDefault(require("./rules/next"));
10
+ const require_layer_1 = __importDefault(require("./rules/require-layer"));
9
11
  exports.rules = {
10
12
  server: server_1.default,
11
13
  react: react_1.default,
14
+ next: next_1.default,
15
+ "require-layer": require_layer_1.default,
12
16
  };
13
17
  const plugin = {
14
18
  rules: exports.rules,
@@ -21,6 +25,18 @@ exports.configs = {
21
25
  rules: {
22
26
  "@luma-layered-ts/server": "error",
23
27
  "@luma-layered-ts/react": "error",
28
+ "@luma-layered-ts/require-layer": "error",
29
+ },
30
+ },
31
+ "recommended-next": {
32
+ plugins: {
33
+ "@luma-layered-ts": plugin,
34
+ },
35
+ rules: {
36
+ "@luma-layered-ts/server": "error",
37
+ "@luma-layered-ts/react": "error",
38
+ "@luma-layered-ts/next": "error",
39
+ "@luma-layered-ts/require-layer": "error",
24
40
  },
25
41
  },
26
42
  };
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,4DAAoC;AACpC,0DAAkC;AAGrB,QAAA,KAAK,GAAG;IACnB,MAAM,EAAN,gBAAM;IACN,KAAK,EAAL,eAAK;CACN,CAAC;AAEF,MAAM,MAAM,GAAG;IACb,KAAK,EAAL,aAAK;CAC2B,CAAC;AAEtB,QAAA,OAAO,GAAG;IACrB,WAAW,EAAE;QACX,OAAO,EAAE;YACP,kBAAkB,EAAE,MAAM;SAC3B;QACD,KAAK,EAAE;YACL,yBAAyB,EAAE,OAAO;YAClC,wBAAwB,EAAE,OAAO;SAClC;KACmC;CACvC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;AAAA,4DAAoC;AACpC,0DAAkC;AAClC,wDAAgC;AAChC,0EAAiD;AAGpC,QAAA,KAAK,GAAG;IACnB,MAAM,EAAN,gBAAM;IACN,KAAK,EAAL,eAAK;IACL,IAAI,EAAJ,cAAI;IACJ,eAAe,EAAE,uBAAY;CAC9B,CAAC;AAEF,MAAM,MAAM,GAAG;IACb,KAAK,EAAL,aAAK;CAC2B,CAAC;AAEtB,QAAA,OAAO,GAAG;IACrB,WAAW,EAAE;QACX,OAAO,EAAE;YACP,kBAAkB,EAAE,MAAM;SAC3B;QACD,KAAK,EAAE;YACL,yBAAyB,EAAE,OAAO;YAClC,wBAAwB,EAAE,OAAO;YACjC,gCAAgC,EAAE,OAAO;SAC1C;KACmC;IACtC,kBAAkB,EAAE;QAClB,OAAO,EAAE;YACP,kBAAkB,EAAE,MAAM;SAC3B;QACD,KAAK,EAAE;YACL,yBAAyB,EAAE,OAAO;YAClC,wBAAwB,EAAE,OAAO;YACjC,uBAAuB,EAAE,OAAO;YAChC,gCAAgC,EAAE,OAAO;SAC1C;KACmC;CACvC,CAAC"}
package/lib/layers.d.ts CHANGED
@@ -1,8 +1,10 @@
1
- export declare const LAYER_NAMES: readonly ["core", "service", "adapter", "infra", "ui/hooks", "ui/components", "ui/pages"];
1
+ export declare const LAYER_NAMES: readonly ["core", "service", "adapter", "infra", "ui/hooks", "ui/components", "ui/pages", "app/api", "app/pages"];
2
2
  export type LayerName = (typeof LAYER_NAMES)[number];
3
+ export declare function isTestFile(filePath: string): boolean;
3
4
  export declare function getLayerFromPath(filePath: string): LayerName | null;
4
5
  export declare function getLayerFromImport(importPath: string): LayerName | null;
5
6
  export declare function canImport(from: LayerName, to: LayerName): boolean;
7
+ export declare function isNonLayerAliasImport(importPath: string): boolean;
6
8
  export declare const ENCODING_GLOBALS: Set<string>;
7
9
  export declare const IO_GLOBALS: Set<string>;
8
10
  export declare const SCHEMA_BOUNDARY_METHODS: Set<string>;
@@ -1 +1 @@
1
- {"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../src/layers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,2FAQd,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAarD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAMnE;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAcvE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAGjE;AAKD,eAAO,MAAM,gBAAgB,aAU3B,CAAC;AAGH,eAAO,MAAM,UAAU,aAMrB,CAAC;AAGH,eAAO,MAAM,uBAAuB,aAWlC,CAAC;AAGH,eAAO,MAAM,6BAA6B,aAyBxC,CAAC"}
1
+ {"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../src/layers.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,WAAW,mHAUd,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAkBrD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAUnE;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAmBvE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAGjE;AAID,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAEjE;AAKD,eAAO,MAAM,gBAAgB,aAc3B,CAAC;AAGH,eAAO,MAAM,UAAU,aAOrB,CAAC;AAGH,eAAO,MAAM,uBAAuB,aAWlC,CAAC;AAKH,eAAO,MAAM,6BAA6B,aAqBxC,CAAC"}
package/lib/layers.js CHANGED
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.STRING_INTERPRETATION_METHODS = exports.SCHEMA_BOUNDARY_METHODS = exports.IO_GLOBALS = exports.ENCODING_GLOBALS = exports.LAYER_NAMES = void 0;
4
+ exports.isTestFile = isTestFile;
4
5
  exports.getLayerFromPath = getLayerFromPath;
5
6
  exports.getLayerFromImport = getLayerFromImport;
6
7
  exports.canImport = canImport;
8
+ exports.isNonLayerAliasImport = isNonLayerAliasImport;
7
9
  exports.LAYER_NAMES = [
8
10
  "core",
9
11
  "service",
@@ -12,6 +14,8 @@ exports.LAYER_NAMES = [
12
14
  "ui/hooks",
13
15
  "ui/components",
14
16
  "ui/pages",
17
+ "app/api",
18
+ "app/pages",
15
19
  ];
16
20
  // import行列: 各レイヤがimport可能なレイヤ (自身は常に可)
17
21
  const allowedImports = {
@@ -22,15 +26,33 @@ const allowedImports = {
22
26
  "ui/hooks": ["core", "service"],
23
27
  "ui/components": ["core", "ui/hooks"],
24
28
  "ui/pages": ["core", "service", "ui/hooks", "ui/components"],
29
+ // app/ layers are wiring roots (entry points) — not importable by other layers
30
+ "app/api": ["core", "service", "adapter", "infra"],
31
+ "app/pages": ["core", "service", "ui/hooks", "ui/components", "ui/pages"],
25
32
  };
33
+ // Test and story files are excluded from layer constraint checks.
34
+ // They need freedom to import across layers for fixtures and mocking.
35
+ function isTestFile(filePath) {
36
+ return /\.(test|spec|stories)\.[^/]+$/.test(filePath);
37
+ }
26
38
  function getLayerFromPath(filePath) {
39
+ // Check app/api before app/pages (more specific first)
40
+ if (filePath.match(/\/src\/app\/api\//))
41
+ return "app/api";
42
+ if (filePath.match(/\/src\/app\//))
43
+ return "app/pages";
27
44
  const match = filePath.match(/\/src\/(ui\/(?:hooks|components|pages)|core|service|adapter|infra)\//);
28
45
  if (!match)
29
46
  return null;
30
47
  return match[1];
31
48
  }
32
49
  function getLayerFromImport(importPath) {
50
+ // app/ layers are entry points — they should not be imported by other modules.
51
+ // Check only the standard layers for import resolution.
33
52
  for (const layer of exports.LAYER_NAMES) {
53
+ // Skip app/ layers in import resolution — they are not importable
54
+ if (layer === "app/api" || layer === "app/pages")
55
+ continue;
34
56
  if (importPath.includes(`/${layer}/`) ||
35
57
  importPath.startsWith(`${layer}/`) ||
36
58
  importPath === layer) {
@@ -47,10 +69,19 @@ function canImport(from, to) {
47
69
  return true;
48
70
  return allowedImports[from].includes(to);
49
71
  }
72
+ // Detect project-internal imports via path alias that should resolve to a layer but don't.
73
+ // Only checks @/ alias imports — relative imports (./ ../) are assumed same-layer.
74
+ function isNonLayerAliasImport(importPath) {
75
+ return importPath.startsWith("@/");
76
+ }
50
77
  // --- Encoded representation restrictions ---
51
78
  // Globals that interact with encoded representations (serialization, parsing)
52
79
  exports.ENCODING_GLOBALS = new Set([
53
80
  "JSON",
81
+ "String",
82
+ "Number",
83
+ "Date",
84
+ "Temporal",
54
85
  "parseInt",
55
86
  "parseFloat",
56
87
  "encodeURIComponent",
@@ -67,6 +98,7 @@ exports.IO_GLOBALS = new Set([
67
98
  "Response",
68
99
  "Headers",
69
100
  "FormData",
101
+ "process",
70
102
  ]);
71
103
  // Schema boundary methods (decode/encode = canonical ↔ encoded conversion)
72
104
  exports.SCHEMA_BOUNDARY_METHODS = new Set([
@@ -81,7 +113,9 @@ exports.SCHEMA_BOUNDARY_METHODS = new Set([
81
113
  "encodeUnknownSync",
82
114
  "encodePromise",
83
115
  ]);
84
- // String interpretation methods (structural access, pattern matching, content inspection)
116
+ // String interpretation methods (structural access, pattern matching, content inspection).
117
+ // Excludes includes/indexOf/lastIndexOf/slice — these exist on Array too and cause
118
+ // false positives without type information.
85
119
  exports.STRING_INTERPRETATION_METHODS = new Set([
86
120
  "split",
87
121
  "match",
@@ -89,12 +123,8 @@ exports.STRING_INTERPRETATION_METHODS = new Set([
89
123
  "replace",
90
124
  "replaceAll",
91
125
  "search",
92
- "includes",
93
126
  "startsWith",
94
127
  "endsWith",
95
- "indexOf",
96
- "lastIndexOf",
97
- "slice",
98
128
  "substring",
99
129
  "charAt",
100
130
  "charCodeAt",
package/lib/layers.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"layers.js","sourceRoot":"","sources":["../src/layers.ts"],"names":[],"mappings":";;;AAuBA,4CAMC;AAED,gDAcC;AAED,8BAGC;AAlDY,QAAA,WAAW,GAAG;IACzB,MAAM;IACN,SAAS;IACT,SAAS;IACT,OAAO;IACP,UAAU;IACV,eAAe;IACf,UAAU;CACF,CAAC;AAIX,uCAAuC;AACvC,MAAM,cAAc,GAA4C;IAC9D,IAAI,EAAE,EAAE;IACR,OAAO,EAAE,CAAC,MAAM,CAAC;IACjB,OAAO,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;IAC5B,KAAK,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC;IACrC,UAAU,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;IAC/B,eAAe,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC;IACrC,UAAU,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,CAAC;CAC7D,CAAC;AAEF,SAAgB,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAC1B,sEAAsE,CACvE,CAAC;IACF,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,OAAO,KAAK,CAAC,CAAC,CAAc,CAAC;AAC/B,CAAC;AAED,SAAgB,kBAAkB,CAAC,UAAkB;IACnD,KAAK,MAAM,KAAK,IAAI,mBAAW,EAAE,CAAC;QAChC,IACE,UAAU,CAAC,QAAQ,CAAC,IAAI,KAAK,GAAG,CAAC;YACjC,UAAU,CAAC,UAAU,CAAC,GAAG,KAAK,GAAG,CAAC;YAClC,UAAU,KAAK,KAAK,EACpB,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,UAAU,CAAC,UAAU,CAAC,KAAK,KAAK,GAAG,CAAC,IAAI,UAAU,KAAK,KAAK,KAAK,EAAE,EAAE,CAAC;YACxE,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAgB,SAAS,CAAC,IAAe,EAAE,EAAa;IACtD,IAAI,IAAI,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAC7B,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,8CAA8C;AAE9C,8EAA8E;AACjE,QAAA,gBAAgB,GAAG,IAAI,GAAG,CAAC;IACtC,MAAM;IACN,UAAU;IACV,YAAY;IACZ,oBAAoB;IACpB,oBAAoB;IACpB,WAAW;IACX,WAAW;IACX,MAAM;IACN,MAAM;CACP,CAAC,CAAC;AAEH,sBAAsB;AACT,QAAA,UAAU,GAAG,IAAI,GAAG,CAAC;IAChC,OAAO;IACP,SAAS;IACT,UAAU;IACV,SAAS;IACT,UAAU;CACX,CAAC,CAAC;AAEH,2EAA2E;AAC9D,QAAA,uBAAuB,GAAG,IAAI,GAAG,CAAC;IAC7C,QAAQ;IACR,YAAY;IACZ,eAAe;IACf,mBAAmB;IACnB,eAAe;IACf,QAAQ;IACR,YAAY;IACZ,eAAe;IACf,mBAAmB;IACnB,eAAe;CAChB,CAAC,CAAC;AAEH,0FAA0F;AAC7E,QAAA,6BAA6B,GAAG,IAAI,GAAG,CAAC;IACnD,OAAO;IACP,OAAO;IACP,UAAU;IACV,SAAS;IACT,YAAY;IACZ,QAAQ;IACR,UAAU;IACV,YAAY;IACZ,UAAU;IACV,SAAS;IACT,aAAa;IACb,OAAO;IACP,WAAW;IACX,QAAQ;IACR,YAAY;IACZ,aAAa;IACb,WAAW;IACX,UAAU;IACV,QAAQ;IACR,QAAQ;IACR,eAAe;IACf,MAAM;IACN,WAAW;IACX,SAAS;CACV,CAAC,CAAC"}
1
+ {"version":3,"file":"layers.js","sourceRoot":"","sources":["../src/layers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ type Options = Record<string, never>;
2
+ type MessageId = "importViolation" | "importNonLayer" | "encodedGlobal" | "schemaBoundary" | "encodedMethod";
3
+ declare const _default: import("@typescript-eslint/utils/dist/ts-eslint/Rule.js").RuleModule<MessageId, [Options], unknown, import("@typescript-eslint/utils/dist/ts-eslint/Rule.js").RuleListener> & {
4
+ name: string;
5
+ };
6
+ export default _default;
7
+ //# sourceMappingURL=next.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../../src/rules/next.ts"],"names":[],"mappings":"AAcA,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAKrC,KAAK,SAAS,GACV,iBAAiB,GACjB,gBAAgB,GAChB,eAAe,GACf,gBAAgB,GAChB,eAAe,CAAC;;;;AAEpB,wBAwKG"}
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const utils_1 = require("@typescript-eslint/utils");
4
+ const create_rule_js_1 = require("../create-rule.js");
5
+ const layers_js_1 = require("../layers.js");
6
+ const defaultOptions = {};
7
+ const NEXT_LAYERS = new Set(["app/api", "app/pages"]);
8
+ exports.default = (0, create_rule_js_1.createRule)({
9
+ name: "next",
10
+ meta: {
11
+ type: "problem",
12
+ docs: {
13
+ description: "Enforce layered architecture for Next.js app router files. app/api/ has server wiring root constraints (import matrix only). app/ pages/layouts have ui/pages-equivalent constraints.",
14
+ },
15
+ messages: {
16
+ importViolation: "'{{fromLayer}}' cannot import from '{{toLayer}}'.",
17
+ importNonLayer: "Import '{{importPath}}' does not resolve to a recognized layer. Move the target into a layer directory.",
18
+ encodedGlobal: "'{{name}}' is an encoded representation API. Not allowed in '{{layer}}'. Use canonical types (Effect.ts) instead.",
19
+ schemaBoundary: "Schema.{{method}}() crosses the canonical/encoded boundary. Not allowed in '{{layer}}'. Decoding belongs in adapter.",
20
+ encodedMethod: "'.{{method}}()' interprets encoded representation. Not allowed in '{{layer}}'.",
21
+ },
22
+ schema: [],
23
+ },
24
+ defaultOptions: [defaultOptions],
25
+ create(context) {
26
+ const filePath = context.filename;
27
+ if ((0, layers_js_1.isTestFile)(filePath))
28
+ return {};
29
+ const layer = (0, layers_js_1.getLayerFromPath)(filePath);
30
+ if (!layer || !NEXT_LAYERS.has(layer))
31
+ return {};
32
+ const isApiRoute = layer === "app/api";
33
+ function checkImport(importPath, node) {
34
+ const toLayer = (0, layers_js_1.getLayerFromImport)(importPath);
35
+ if (!toLayer) {
36
+ if ((0, layers_js_1.isNonLayerAliasImport)(importPath)) {
37
+ context.report({
38
+ node,
39
+ messageId: "importNonLayer",
40
+ data: { importPath },
41
+ });
42
+ }
43
+ return;
44
+ }
45
+ if (!(0, layers_js_1.canImport)(layer, toLayer)) {
46
+ context.report({
47
+ node,
48
+ messageId: "importViolation",
49
+ data: { fromLayer: layer, toLayer },
50
+ });
51
+ }
52
+ }
53
+ // app/api: import matrix only (server-side wiring root)
54
+ if (isApiRoute) {
55
+ return {
56
+ ImportDeclaration(node) {
57
+ checkImport(node.source.value, node);
58
+ },
59
+ ImportExpression(node) {
60
+ if (node.source.type === utils_1.AST_NODE_TYPES.Literal &&
61
+ typeof node.source.value === "string") {
62
+ checkImport(node.source.value, node);
63
+ }
64
+ },
65
+ TSExternalModuleReference(node) {
66
+ if (node.expression.type === utils_1.AST_NODE_TYPES.Literal &&
67
+ typeof node.expression.value === "string") {
68
+ checkImport(node.expression.value, node);
69
+ }
70
+ },
71
+ };
72
+ }
73
+ // app/pages: same constraints as ui/pages
74
+ return {
75
+ ImportDeclaration(node) {
76
+ checkImport(node.source.value, node);
77
+ },
78
+ ImportExpression(node) {
79
+ if (node.source.type === utils_1.AST_NODE_TYPES.Literal &&
80
+ typeof node.source.value === "string") {
81
+ checkImport(node.source.value, node);
82
+ }
83
+ },
84
+ TSExternalModuleReference(node) {
85
+ if (node.expression.type === utils_1.AST_NODE_TYPES.Literal &&
86
+ typeof node.expression.value === "string") {
87
+ checkImport(node.expression.value, node);
88
+ }
89
+ },
90
+ // Encoding globals
91
+ Identifier(node) {
92
+ if (!layers_js_1.ENCODING_GLOBALS.has(node.name))
93
+ return;
94
+ if (node.parent?.type === utils_1.AST_NODE_TYPES.MemberExpression &&
95
+ node.parent.property === node &&
96
+ !node.parent.computed) {
97
+ return;
98
+ }
99
+ if (isInTypeContext(node))
100
+ return;
101
+ context.report({
102
+ node,
103
+ messageId: "encodedGlobal",
104
+ data: { name: node.name, layer },
105
+ });
106
+ },
107
+ // Schema boundary + string interpretation
108
+ CallExpression(node) {
109
+ if (node.callee.type !== utils_1.AST_NODE_TYPES.MemberExpression ||
110
+ node.callee.property.type !== utils_1.AST_NODE_TYPES.Identifier) {
111
+ return;
112
+ }
113
+ const method = node.callee.property.name;
114
+ if (layers_js_1.SCHEMA_BOUNDARY_METHODS.has(method)) {
115
+ context.report({
116
+ node,
117
+ messageId: "schemaBoundary",
118
+ data: { method, layer },
119
+ });
120
+ return;
121
+ }
122
+ if (method === "toString")
123
+ return;
124
+ if (layers_js_1.STRING_INTERPRETATION_METHODS.has(method)) {
125
+ context.report({
126
+ node,
127
+ messageId: "encodedMethod",
128
+ data: { method, layer },
129
+ });
130
+ }
131
+ },
132
+ };
133
+ function isInTypeContext(node) {
134
+ let current = node.parent;
135
+ while (current) {
136
+ if (current.type.startsWith("TS") &&
137
+ current.type !== utils_1.AST_NODE_TYPES.TSAsExpression &&
138
+ current.type !== utils_1.AST_NODE_TYPES.TSSatisfiesExpression) {
139
+ return true;
140
+ }
141
+ current = current.parent;
142
+ }
143
+ return false;
144
+ }
145
+ },
146
+ });
147
+ //# sourceMappingURL=next.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.js","sourceRoot":"","sources":["../../src/rules/next.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  type Options = Record<string, never>;
2
- type MessageId = "importViolation" | "encodedGlobal" | "schemaBoundary" | "encodedMethod" | "componentParseMethod";
2
+ type MessageId = "importViolation" | "importNonLayer" | "encodedGlobal" | "schemaBoundary" | "encodedMethod" | "componentParseMethod";
3
3
  declare const _default: import("@typescript-eslint/utils/dist/ts-eslint/Rule.js").RuleModule<MessageId, [Options], unknown, import("@typescript-eslint/utils/dist/ts-eslint/Rule.js").RuleListener> & {
4
4
  name: string;
5
5
  };
@@ -1 +1 @@
1
- {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/rules/react.ts"],"names":[],"mappings":"AAYA,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAQrC,KAAK,SAAS,GACV,iBAAiB,GACjB,eAAe,GACf,gBAAgB,GAChB,eAAe,GACf,sBAAsB,CAAC;;;;AAE3B,wBAqJG"}
1
+ {"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/rules/react.ts"],"names":[],"mappings":"AAcA,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAQrC,KAAK,SAAS,GACV,iBAAiB,GACjB,gBAAgB,GAChB,eAAe,GACf,gBAAgB,GAChB,eAAe,GACf,sBAAsB,CAAC;;;;AAE3B,wBAiKG"}
@@ -16,6 +16,7 @@ exports.default = (0, create_rule_js_1.createRule)({
16
16
  },
17
17
  messages: {
18
18
  importViolation: "'{{fromLayer}}' cannot import from '{{toLayer}}'.",
19
+ importNonLayer: "Import '{{importPath}}' does not resolve to a recognized layer. Move the target into a layer directory.",
19
20
  encodedGlobal: "'{{name}}' is an encoded representation API. Not allowed in '{{layer}}'. Use canonical types (Effect.ts) instead.",
20
21
  schemaBoundary: "Schema.{{method}}() crosses the canonical/encoded boundary. Not allowed in '{{layer}}'. Decoding belongs in adapter.",
21
22
  encodedMethod: "'.{{method}}()' interprets encoded representation. Not allowed in '{{layer}}'.",
@@ -26,14 +27,24 @@ exports.default = (0, create_rule_js_1.createRule)({
26
27
  defaultOptions: [defaultOptions],
27
28
  create(context) {
28
29
  const filePath = context.filename;
30
+ if ((0, layers_js_1.isTestFile)(filePath))
31
+ return {};
29
32
  const layer = (0, layers_js_1.getLayerFromPath)(filePath);
30
33
  if (!layer || !UI_LAYERS.has(layer))
31
34
  return {};
32
35
  const isComponent = layer === "ui/components";
33
36
  function checkImport(importPath, node) {
34
37
  const toLayer = (0, layers_js_1.getLayerFromImport)(importPath);
35
- if (!toLayer)
38
+ if (!toLayer) {
39
+ if ((0, layers_js_1.isNonLayerAliasImport)(importPath)) {
40
+ context.report({
41
+ node,
42
+ messageId: "importNonLayer",
43
+ data: { importPath },
44
+ });
45
+ }
36
46
  return;
47
+ }
37
48
  if (!(0, layers_js_1.canImport)(layer, toLayer)) {
38
49
  context.report({
39
50
  node,
@@ -1 +1 @@
1
- {"version":3,"file":"react.js","sourceRoot":"","sources":["../../src/rules/react.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"react.js","sourceRoot":"","sources":["../../src/rules/react.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ type Options = Record<string, never>;
2
+ declare const _default: import("@typescript-eslint/utils/dist/ts-eslint/Rule.js").RuleModule<"noLayer", [Options], unknown, import("@typescript-eslint/utils/dist/ts-eslint/Rule.js").RuleListener> & {
3
+ name: string;
4
+ };
5
+ export default _default;
6
+ //# sourceMappingURL=require-layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-layer.d.ts","sourceRoot":"","sources":["../../src/rules/require-layer.ts"],"names":[],"mappings":"AAGA,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;;;;AAKrC,wBAwCG"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const create_rule_js_1 = require("../create-rule.js");
4
+ const layers_js_1 = require("../layers.js");
5
+ const defaultOptions = {};
6
+ exports.default = (0, create_rule_js_1.createRule)({
7
+ name: "require-layer",
8
+ meta: {
9
+ type: "problem",
10
+ docs: {
11
+ description: "Require all source files under src/ to belong to a recognized layer directory. Files outside layer directories bypass all layer constraint checks.",
12
+ },
13
+ messages: {
14
+ noLayer: "This file is not in a recognized layer directory (src/{core,service,adapter,infra,ui/{hooks,components,pages},app/}). Move it to the appropriate layer so that import and encoding constraints are enforced.",
15
+ },
16
+ schema: [],
17
+ },
18
+ defaultOptions: [defaultOptions],
19
+ create(context) {
20
+ const filePath = context.filename;
21
+ // Only check files under src/
22
+ if (!filePath.match(/\/src\//))
23
+ return {};
24
+ // Skip test files (they need cross-layer imports for fixtures)
25
+ if ((0, layers_js_1.isTestFile)(filePath))
26
+ return {};
27
+ // Skip src/main.ts (composition root)
28
+ if (filePath.match(/\/src\/main\.[^/]+$/))
29
+ return {};
30
+ const layer = (0, layers_js_1.getLayerFromPath)(filePath);
31
+ if (layer)
32
+ return {};
33
+ // File is under src/ but not in any layer — report on Program node
34
+ return {
35
+ Program(node) {
36
+ context.report({
37
+ node,
38
+ messageId: "noLayer",
39
+ });
40
+ },
41
+ };
42
+ },
43
+ });
44
+ //# sourceMappingURL=require-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"require-layer.js","sourceRoot":"","sources":["../../src/rules/require-layer.ts"],"names":[],"mappings":";;AAAA,sDAA+C;AAC/C,4CAA4D;AAG5D,MAAM,cAAc,GAAY,EAAE,CAAC;AAInC,kBAAe,IAAA,2BAAU,EAAuB;IAC9C,IAAI,EAAE,eAAe;IACrB,IAAI,EAAE;QACJ,IAAI,EAAE,SAAS;QACf,IAAI,EAAE;YACJ,WAAW,EACT,oJAAoJ;SACvJ;QACD,QAAQ,EAAE;YACR,OAAO,EACL,8MAA8M;SACjN;QACD,MAAM,EAAE,EAAE;KACX;IACD,cAAc,EAAE,CAAC,cAAc,CAAC;IAChC,MAAM,CAAC,OAAO;QACZ,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;QAElC,8BAA8B;QAC9B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC;YAAE,OAAO,EAAE,CAAC;QAE1C,+DAA+D;QAC/D,IAAI,IAAA,sBAAU,EAAC,QAAQ,CAAC;YAAE,OAAO,EAAE,CAAC;QAEpC,sCAAsC;QACtC,IAAI,QAAQ,CAAC,KAAK,CAAC,qBAAqB,CAAC;YAAE,OAAO,EAAE,CAAC;QAErD,MAAM,KAAK,GAAG,IAAA,4BAAgB,EAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,KAAK;YAAE,OAAO,EAAE,CAAC;QAErB,mEAAmE;QACnE,OAAO;YACL,OAAO,CAAC,IAAI;gBACV,OAAO,CAAC,MAAM,CAAC;oBACb,IAAI;oBACJ,SAAS,EAAE,SAAS;iBACrB,CAAC,CAAC;YACL,CAAC;SACF,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -1,5 +1,5 @@
1
1
  type Options = Record<string, never>;
2
- type MessageId = "importViolation" | "encodedGlobal" | "ioGlobal" | "schemaBoundary" | "encodedMethod";
2
+ type MessageId = "importViolation" | "importNonLayer" | "encodedGlobal" | "ioGlobal" | "schemaBoundary" | "encodedMethod";
3
3
  declare const _default: import("@typescript-eslint/utils/dist/ts-eslint/Rule.js").RuleModule<MessageId, [Options], unknown, import("@typescript-eslint/utils/dist/ts-eslint/Rule.js").RuleListener> & {
4
4
  name: string;
5
5
  };
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/rules/server.ts"],"names":[],"mappings":"AAaA,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAWrC,KAAK,SAAS,GACV,iBAAiB,GACjB,eAAe,GACf,UAAU,GACV,gBAAgB,GAChB,eAAe,CAAC;;;;AAEpB,wBAkJG"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/rules/server.ts"],"names":[],"mappings":"AAeA,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAWrC,KAAK,SAAS,GACV,iBAAiB,GACjB,gBAAgB,GAChB,eAAe,GACf,UAAU,GACV,gBAAgB,GAChB,eAAe,CAAC;;;;AAEpB,wBA8JG"}
@@ -20,6 +20,7 @@ exports.default = (0, create_rule_js_1.createRule)({
20
20
  },
21
21
  messages: {
22
22
  importViolation: "'{{fromLayer}}' cannot import from '{{toLayer}}'.",
23
+ importNonLayer: "Import '{{importPath}}' does not resolve to a recognized layer. Move the target into a layer directory.",
23
24
  encodedGlobal: "'{{name}}' is an encoded representation API. Not allowed in '{{layer}}'. Use canonical types (Effect.ts) instead.",
24
25
  ioGlobal: "'{{name}}' is an IO boundary API. Not allowed in '{{layer}}'. IO belongs in infra.",
25
26
  schemaBoundary: "Schema.{{method}}() crosses the canonical/encoded boundary. Only allowed in adapter/infra. Current layer: '{{layer}}'.",
@@ -30,14 +31,24 @@ exports.default = (0, create_rule_js_1.createRule)({
30
31
  defaultOptions: [defaultOptions],
31
32
  create(context) {
32
33
  const filePath = context.filename;
34
+ if ((0, layers_js_1.isTestFile)(filePath))
35
+ return {};
33
36
  const layer = (0, layers_js_1.getLayerFromPath)(filePath);
34
37
  if (!layer || !SERVER_LAYERS.has(layer))
35
38
  return {};
36
39
  const isInner = INNER_LAYERS.has(layer);
37
40
  function checkImport(importPath, node) {
38
41
  const toLayer = (0, layers_js_1.getLayerFromImport)(importPath);
39
- if (!toLayer)
42
+ if (!toLayer) {
43
+ if ((0, layers_js_1.isNonLayerAliasImport)(importPath)) {
44
+ context.report({
45
+ node,
46
+ messageId: "importNonLayer",
47
+ data: { importPath },
48
+ });
49
+ }
40
50
  return;
51
+ }
41
52
  if (!(0, layers_js_1.canImport)(layer, toLayer)) {
42
53
  context.report({
43
54
  node,
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/rules/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/rules/server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luma-layered-ts/eslint-plugin",
3
- "version": "1.0.1",
3
+ "version": "1.2.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },