@zukhruf/eslint 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +138 -0
  3. package/dist/authoring/ast.d.ts +10 -0
  4. package/dist/authoring/ast.d.ts.map +1 -0
  5. package/dist/authoring/ast.js +22 -0
  6. package/dist/authoring/ast.js.map +1 -0
  7. package/dist/authoring/import-ban.d.ts +14 -0
  8. package/dist/authoring/import-ban.d.ts.map +1 -0
  9. package/dist/authoring/import-ban.js +32 -0
  10. package/dist/authoring/import-ban.js.map +1 -0
  11. package/dist/authoring/path-scope.d.ts +12 -0
  12. package/dist/authoring/path-scope.d.ts.map +1 -0
  13. package/dist/authoring/path-scope.js +28 -0
  14. package/dist/authoring/path-scope.js.map +1 -0
  15. package/dist/authoring/rule-module.d.ts +14 -0
  16. package/dist/authoring/rule-module.d.ts.map +1 -0
  17. package/dist/authoring/rule-module.js +23 -0
  18. package/dist/authoring/rule-module.js.map +1 -0
  19. package/dist/authoring/scoped-rule.d.ts +8 -0
  20. package/dist/authoring/scoped-rule.d.ts.map +1 -0
  21. package/dist/authoring/scoped-rule.js +12 -0
  22. package/dist/authoring/scoped-rule.js.map +1 -0
  23. package/dist/authoring/selector-rule.d.ts +17 -0
  24. package/dist/authoring/selector-rule.d.ts.map +1 -0
  25. package/dist/authoring/selector-rule.js +23 -0
  26. package/dist/authoring/selector-rule.js.map +1 -0
  27. package/dist/base/config.d.ts +8 -0
  28. package/dist/base/config.d.ts.map +1 -0
  29. package/dist/base/config.js +122 -0
  30. package/dist/base/config.js.map +1 -0
  31. package/dist/base/options.d.ts +23 -0
  32. package/dist/base/options.d.ts.map +1 -0
  33. package/dist/base/options.js +22 -0
  34. package/dist/base/options.js.map +1 -0
  35. package/dist/concept.d.ts +16 -0
  36. package/dist/concept.d.ts.map +1 -0
  37. package/dist/concept.js +5 -0
  38. package/dist/concept.js.map +1 -0
  39. package/dist/diagnostics/config.d.ts +4 -0
  40. package/dist/diagnostics/config.d.ts.map +1 -0
  41. package/dist/diagnostics/config.js +25 -0
  42. package/dist/diagnostics/config.js.map +1 -0
  43. package/dist/diagnostics/consistent-event-name.d.ts +4 -0
  44. package/dist/diagnostics/consistent-event-name.d.ts.map +1 -0
  45. package/dist/diagnostics/consistent-event-name.js +72 -0
  46. package/dist/diagnostics/consistent-event-name.js.map +1 -0
  47. package/dist/diagnostics/no-fabricated-fallback.d.ts +4 -0
  48. package/dist/diagnostics/no-fabricated-fallback.d.ts.map +1 -0
  49. package/dist/diagnostics/no-fabricated-fallback.js +116 -0
  50. package/dist/diagnostics/no-fabricated-fallback.js.map +1 -0
  51. package/dist/diagnostics/no-hardcoded-id-shape.d.ts +4 -0
  52. package/dist/diagnostics/no-hardcoded-id-shape.d.ts.map +1 -0
  53. package/dist/diagnostics/no-hardcoded-id-shape.js +73 -0
  54. package/dist/diagnostics/no-hardcoded-id-shape.js.map +1 -0
  55. package/dist/environment/config.d.ts +7 -0
  56. package/dist/environment/config.d.ts.map +1 -0
  57. package/dist/environment/config.js +28 -0
  58. package/dist/environment/config.js.map +1 -0
  59. package/dist/environment/no-default-for-path-env.d.ts +10 -0
  60. package/dist/environment/no-default-for-path-env.d.ts.map +1 -0
  61. package/dist/environment/no-default-for-path-env.js +124 -0
  62. package/dist/environment/no-default-for-path-env.js.map +1 -0
  63. package/dist/environment/no-single-env-read-wrapper.d.ts +10 -0
  64. package/dist/environment/no-single-env-read-wrapper.d.ts.map +1 -0
  65. package/dist/environment/no-single-env-read-wrapper.js +76 -0
  66. package/dist/environment/no-single-env-read-wrapper.js.map +1 -0
  67. package/dist/environment/no-undeclared-process-env.d.ts +11 -0
  68. package/dist/environment/no-undeclared-process-env.d.ts.map +1 -0
  69. package/dist/environment/no-undeclared-process-env.js +195 -0
  70. package/dist/environment/no-undeclared-process-env.js.map +1 -0
  71. package/dist/files.d.ts +16 -0
  72. package/dist/files.d.ts.map +1 -0
  73. package/dist/files.js +27 -0
  74. package/dist/files.js.map +1 -0
  75. package/dist/hono/config.d.ts +3 -0
  76. package/dist/hono/config.d.ts.map +1 -0
  77. package/dist/hono/config.js +18 -0
  78. package/dist/hono/config.js.map +1 -0
  79. package/dist/hono/no-untyped-empty-json.d.ts +8 -0
  80. package/dist/hono/no-untyped-empty-json.d.ts.map +1 -0
  81. package/dist/hono/no-untyped-empty-json.js +14 -0
  82. package/dist/hono/no-untyped-empty-json.js.map +1 -0
  83. package/dist/imports/no-deepagents-agent.d.ts +3 -0
  84. package/dist/imports/no-deepagents-agent.d.ts.map +1 -0
  85. package/dist/imports/no-deepagents-agent.js +7 -0
  86. package/dist/imports/no-deepagents-agent.js.map +1 -0
  87. package/dist/imports/no-playwright-test.d.ts +3 -0
  88. package/dist/imports/no-playwright-test.d.ts.map +1 -0
  89. package/dist/imports/no-playwright-test.js +7 -0
  90. package/dist/imports/no-playwright-test.js.map +1 -0
  91. package/dist/imports/no-state-managers.d.ts +3 -0
  92. package/dist/imports/no-state-managers.d.ts.map +1 -0
  93. package/dist/imports/no-state-managers.js +15 -0
  94. package/dist/imports/no-state-managers.js.map +1 -0
  95. package/dist/index.d.ts +3 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +3 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/island/island-scope.d.ts +10 -0
  100. package/dist/island/island-scope.d.ts.map +1 -0
  101. package/dist/island/island-scope.js +21 -0
  102. package/dist/island/island-scope.js.map +1 -0
  103. package/dist/island/no-console.d.ts +9 -0
  104. package/dist/island/no-console.d.ts.map +1 -0
  105. package/dist/island/no-console.js +39 -0
  106. package/dist/island/no-console.js.map +1 -0
  107. package/dist/island/no-generic-port.d.ts +8 -0
  108. package/dist/island/no-generic-port.d.ts.map +1 -0
  109. package/dist/island/no-generic-port.js +14 -0
  110. package/dist/island/no-generic-port.js.map +1 -0
  111. package/dist/island/no-process-env.d.ts +3 -0
  112. package/dist/island/no-process-env.d.ts.map +1 -0
  113. package/dist/island/no-process-env.js +10 -0
  114. package/dist/island/no-process-env.js.map +1 -0
  115. package/dist/island/plugin.d.ts +25 -0
  116. package/dist/island/plugin.d.ts.map +1 -0
  117. package/dist/island/plugin.js +67 -0
  118. package/dist/island/plugin.js.map +1 -0
  119. package/dist/language/no-enum.d.ts +3 -0
  120. package/dist/language/no-enum.d.ts.map +1 -0
  121. package/dist/language/no-enum.js +7 -0
  122. package/dist/language/no-enum.js.map +1 -0
  123. package/dist/nx-policy/dependency-policy.d.ts +30 -0
  124. package/dist/nx-policy/dependency-policy.d.ts.map +1 -0
  125. package/dist/nx-policy/dependency-policy.js +31 -0
  126. package/dist/nx-policy/dependency-policy.js.map +1 -0
  127. package/dist/nx-policy/island-constraint.d.ts +10 -0
  128. package/dist/nx-policy/island-constraint.d.ts.map +1 -0
  129. package/dist/nx-policy/island-constraint.js +15 -0
  130. package/dist/nx-policy/island-constraint.js.map +1 -0
  131. package/dist/nx-policy/module-boundaries.d.ts +29 -0
  132. package/dist/nx-policy/module-boundaries.d.ts.map +1 -0
  133. package/dist/nx-policy/module-boundaries.js +20 -0
  134. package/dist/nx-policy/module-boundaries.js.map +1 -0
  135. package/dist/nx-project/config.d.ts +4 -0
  136. package/dist/nx-project/config.d.ts.map +1 -0
  137. package/dist/nx-project/config.js +20 -0
  138. package/dist/nx-project/config.js.map +1 -0
  139. package/dist/nx-project/no-missing-asset-input.d.ts +9 -0
  140. package/dist/nx-project/no-missing-asset-input.d.ts.map +1 -0
  141. package/dist/nx-project/no-missing-asset-input.js +209 -0
  142. package/dist/nx-project/no-missing-asset-input.js.map +1 -0
  143. package/dist/nx.d.ts +5 -0
  144. package/dist/nx.d.ts.map +1 -0
  145. package/dist/nx.js +5 -0
  146. package/dist/nx.js.map +1 -0
  147. package/dist/packaged-app/config.d.ts +4 -0
  148. package/dist/packaged-app/config.d.ts.map +1 -0
  149. package/dist/packaged-app/config.js +19 -0
  150. package/dist/packaged-app/config.js.map +1 -0
  151. package/dist/packaged-app/no-bare-spawn.d.ts +4 -0
  152. package/dist/packaged-app/no-bare-spawn.d.ts.map +1 -0
  153. package/dist/packaged-app/no-bare-spawn.js +175 -0
  154. package/dist/packaged-app/no-bare-spawn.js.map +1 -0
  155. package/dist/plugin.d.ts +14 -0
  156. package/dist/plugin.d.ts.map +1 -0
  157. package/dist/plugin.js +48 -0
  158. package/dist/plugin.js.map +1 -0
  159. package/dist/pulumi/config.d.ts +3 -0
  160. package/dist/pulumi/config.d.ts.map +1 -0
  161. package/dist/pulumi/config.js +17 -0
  162. package/dist/pulumi/config.js.map +1 -0
  163. package/dist/pulumi/require-server-replace-guard.d.ts +4 -0
  164. package/dist/pulumi/require-server-replace-guard.d.ts.map +1 -0
  165. package/dist/pulumi/require-server-replace-guard.js +120 -0
  166. package/dist/pulumi/require-server-replace-guard.js.map +1 -0
  167. package/dist/react/config.d.ts +4 -0
  168. package/dist/react/config.d.ts.map +1 -0
  169. package/dist/react/config.js +13 -0
  170. package/dist/react/config.js.map +1 -0
  171. package/dist/react/require-combobox-popover-modal.d.ts +10 -0
  172. package/dist/react/require-combobox-popover-modal.d.ts.map +1 -0
  173. package/dist/react/require-combobox-popover-modal.js +101 -0
  174. package/dist/react/require-combobox-popover-modal.js.map +1 -0
  175. package/dist/react-router/config.d.ts +3 -0
  176. package/dist/react-router/config.d.ts.map +1 -0
  177. package/dist/react-router/config.js +34 -0
  178. package/dist/react-router/config.js.map +1 -0
  179. package/dist/react-router/no-internal-anchor.d.ts +8 -0
  180. package/dist/react-router/no-internal-anchor.d.ts.map +1 -0
  181. package/dist/react-router/no-internal-anchor.js +14 -0
  182. package/dist/react-router/no-internal-anchor.js.map +1 -0
  183. package/dist/react-router/no-raw-route-path.d.ts +9 -0
  184. package/dist/react-router/no-raw-route-path.d.ts.map +1 -0
  185. package/dist/react-router/no-raw-route-path.js +17 -0
  186. package/dist/react-router/no-raw-route-path.js.map +1 -0
  187. package/dist/react-router/require-loader-data-type-argument.d.ts +10 -0
  188. package/dist/react-router/require-loader-data-type-argument.d.ts.map +1 -0
  189. package/dist/react-router/require-loader-data-type-argument.js +16 -0
  190. package/dist/react-router/require-loader-data-type-argument.js.map +1 -0
  191. package/dist/tailwind/class-name-check.d.ts +12 -0
  192. package/dist/tailwind/class-name-check.d.ts.map +1 -0
  193. package/dist/tailwind/class-name-check.js +16 -0
  194. package/dist/tailwind/class-name-check.js.map +1 -0
  195. package/dist/tailwind/config.d.ts +3 -0
  196. package/dist/tailwind/config.d.ts.map +1 -0
  197. package/dist/tailwind/config.js +18 -0
  198. package/dist/tailwind/config.js.map +1 -0
  199. package/dist/tailwind/no-arbitrary-z-index.d.ts +3 -0
  200. package/dist/tailwind/no-arbitrary-z-index.d.ts.map +1 -0
  201. package/dist/tailwind/no-arbitrary-z-index.js +7 -0
  202. package/dist/tailwind/no-arbitrary-z-index.js.map +1 -0
  203. package/dist/tailwind/no-h-screen.d.ts +3 -0
  204. package/dist/tailwind/no-h-screen.d.ts.map +1 -0
  205. package/dist/tailwind/no-h-screen.js +7 -0
  206. package/dist/tailwind/no-h-screen.js.map +1 -0
  207. package/dist/tailwind/no-will-change.d.ts +3 -0
  208. package/dist/tailwind/no-will-change.d.ts.map +1 -0
  209. package/dist/tailwind/no-will-change.js +7 -0
  210. package/dist/tailwind/no-will-change.js.map +1 -0
  211. package/dist/test-files/config.d.ts +3 -0
  212. package/dist/test-files/config.d.ts.map +1 -0
  213. package/dist/test-files/config.js +16 -0
  214. package/dist/test-files/config.js.map +1 -0
  215. package/dist/test-files/no-test-lifecycle-hooks.d.ts +3 -0
  216. package/dist/test-files/no-test-lifecycle-hooks.d.ts.map +1 -0
  217. package/dist/test-files/no-test-lifecycle-hooks.js +9 -0
  218. package/dist/test-files/no-test-lifecycle-hooks.js.map +1 -0
  219. package/dist/test-files/require-msw-error-on-unhandled-request.d.ts +10 -0
  220. package/dist/test-files/require-msw-error-on-unhandled-request.d.ts.map +1 -0
  221. package/dist/test-files/require-msw-error-on-unhandled-request.js +16 -0
  222. package/dist/test-files/require-msw-error-on-unhandled-request.js.map +1 -0
  223. package/dist/workspace/project-manifest.d.ts +14 -0
  224. package/dist/workspace/project-manifest.d.ts.map +1 -0
  225. package/dist/workspace/project-manifest.js +45 -0
  226. package/dist/workspace/project-manifest.js.map +1 -0
  227. package/dist/workspace/workspace-root.d.ts +12 -0
  228. package/dist/workspace/workspace-root.d.ts.map +1 -0
  229. package/dist/workspace/workspace-root.js +46 -0
  230. package/dist/workspace/workspace-root.js.map +1 -0
  231. package/package.json +67 -0
@@ -0,0 +1,14 @@
1
+ import { selectorRule } from "../authoring/selector-rule.js";
2
+ /**
3
+ * A port the host implements (a requester, a store) returns `unknown`, and
4
+ * each consumer narrows it where it reads it. A generic response forces every
5
+ * test stub to assert into T or to return `any`.
6
+ */
7
+ export default selectorRule({
8
+ description: 'Disallow ports (interfaces and function types) whose methods are generic in their response',
9
+ selectors: [
10
+ ':matches(TSInterfaceDeclaration, TSTypeAliasDeclaration) :matches(TSMethodSignature, TSFunctionType, TSCallSignatureDeclaration)[typeParameters]',
11
+ ],
12
+ message: 'A port must not be generic in its response. Return unknown and narrow at the call site.',
13
+ });
14
+ //# sourceMappingURL=no-generic-port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-generic-port.js","sourceRoot":"","sources":["../../src/island/no-generic-port.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D;;;;GAIG;AACH,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,4FAA4F;IAC9F,SAAS,EAAE;QACT,kJAAkJ;KACnJ;IACD,OAAO,EACL,yFAAyF;CAC5F,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("eslint").Rule.RuleModule;
2
+ export default _default;
3
+ //# sourceMappingURL=no-process-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-process-env.d.ts","sourceRoot":"","sources":["../../src/island/no-process-env.ts"],"names":[],"mappings":";AAEA,wBAQG"}
@@ -0,0 +1,10 @@
1
+ import { selectorRule } from "../authoring/selector-rule.js";
2
+ export default selectorRule({
3
+ description: 'Disallow reading process.env in library code',
4
+ selectors: [
5
+ "MemberExpression[object.name='process']:matches([computed=false][property.name='env'], [computed=true][property.value='env'])",
6
+ "VariableDeclarator[init.name='process'] > ObjectPattern > Property[key.name='env']",
7
+ ],
8
+ message: 'Library code must not read process.env. Take the value as an option the library types; the host reads its environment.',
9
+ });
10
+ //# sourceMappingURL=no-process-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-process-env.js","sourceRoot":"","sources":["../../src/island/no-process-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,eAAe,YAAY,CAAC;IAC1B,WAAW,EAAE,8CAA8C;IAC3D,SAAS,EAAE;QACT,+HAA+H;QAC/H,oFAAoF;KACrF;IACD,OAAO,EACL,wHAAwH;CAC3H,CAAC,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { Linter } from 'eslint';
2
+ /**
3
+ * Islands: Nx projects tagged `layer:island`, written as if published to npm.
4
+ * An island depends only on other islands, never on a host's runtime; a port it
5
+ * declares returns `unknown` rather than a generic; its package.json declares
6
+ * every package its shipped code imports. Library code (every island, plus the
7
+ * globs in `settings.island.libraries`) never reads process.env or writes to
8
+ * console: the host reads its environment and passes values in.
9
+ */
10
+ declare const plugin: {
11
+ meta: {
12
+ name: string;
13
+ namespace: string;
14
+ };
15
+ rules: {
16
+ 'no-generic-port': import("eslint").Rule.RuleModule;
17
+ 'no-explicit-any': import("eslint").Rule.RuleModule;
18
+ 'dependency-checks': import("eslint").Rule.RuleModule;
19
+ 'no-process-env': import("eslint").Rule.RuleModule;
20
+ 'no-console': import("eslint").Rule.RuleModule;
21
+ };
22
+ configs: Record<string, Linter.Config<import("@eslint/core", { with: { "resolution-mode": "require" } }).RulesConfig>[]>;
23
+ };
24
+ export default plugin;
25
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/island/plugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAmC7C;;;;;;;GAOG;AACH,QAAA,MAAM,MAAM;;;;;;;;;;;;;CAIa,CAAC;AAkC1B,eAAe,MAAM,CAAC"}
@@ -0,0 +1,67 @@
1
+ import nx from '@nx/eslint-plugin';
2
+ import * as jsonc from 'jsonc-eslint-parser';
3
+ import tseslint from 'typescript-eslint';
4
+ import { ruleOf } from "../authoring/rule-module.js";
5
+ import { scopedRule } from "../authoring/scoped-rule.js";
6
+ import { CONFIG_FILES, PACKAGE_JSON, SCRIPTS, TESTS, TYPESCRIPT, } from "../files.js";
7
+ import { dependencyPolicy } from "../nx-policy/dependency-policy.js";
8
+ import { inIsland, inLibrary } from "./island-scope.js";
9
+ import noConsole from "./no-console.js";
10
+ import noGenericPort from "./no-generic-port.js";
11
+ import noProcessEnv from "./no-process-env.js";
12
+ // Each check has its own `island/*` key, so a repo's own no-explicit-any,
13
+ // no-console or dependency-checks settings never replace it. typescript-eslint's
14
+ // and Nx's rules are reused through their plugins' public `rules` maps.
15
+ const rules = {
16
+ 'no-generic-port': scopedRule(noGenericPort, inIsland),
17
+ 'no-explicit-any': scopedRule(ruleOf(tseslint.plugin, 'no-explicit-any'), inIsland),
18
+ 'dependency-checks': scopedRule(ruleOf(nx, 'dependency-checks'), inIsland),
19
+ 'no-process-env': scopedRule(noProcessEnv, inLibrary),
20
+ 'no-console': scopedRule(noConsole, inLibrary),
21
+ };
22
+ const configs = {};
23
+ /**
24
+ * Islands: Nx projects tagged `layer:island`, written as if published to npm.
25
+ * An island depends only on other islands, never on a host's runtime; a port it
26
+ * declares returns `unknown` rather than a generic; its package.json declares
27
+ * every package its shipped code imports. Library code (every island, plus the
28
+ * globs in `settings.island.libraries`) never reads process.env or writes to
29
+ * console: the host reads its environment and passes values in.
30
+ */
31
+ const plugin = {
32
+ meta: { name: '@zukhruf/eslint/nx', namespace: 'island' },
33
+ rules,
34
+ configs,
35
+ };
36
+ const plugins = { island: plugin };
37
+ configs['recommended'] = [
38
+ {
39
+ name: 'island/recommended/ports',
40
+ files: TYPESCRIPT,
41
+ ignores: TESTS,
42
+ plugins,
43
+ rules: {
44
+ 'island/no-generic-port': 'error',
45
+ 'island/no-explicit-any': 'error',
46
+ },
47
+ },
48
+ {
49
+ name: 'island/recommended/library',
50
+ files: TYPESCRIPT,
51
+ ignores: [...TESTS, ...SCRIPTS, ...CONFIG_FILES],
52
+ plugins,
53
+ rules: {
54
+ 'island/no-process-env': 'error',
55
+ 'island/no-console': 'error',
56
+ },
57
+ },
58
+ {
59
+ name: 'island/recommended/dependencies',
60
+ files: PACKAGE_JSON,
61
+ languageOptions: { parser: jsonc },
62
+ plugins,
63
+ rules: { 'island/dependency-checks': ['error', dependencyPolicy()] },
64
+ },
65
+ ];
66
+ export default plugin;
67
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/island/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEnC,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAC;AAC7C,OAAO,QAAQ,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,OAAO,EACP,KAAK,EACL,UAAU,GACX,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,SAAS,MAAM,iBAAiB,CAAC;AACxC,OAAO,aAAa,MAAM,sBAAsB,CAAC;AACjD,OAAO,YAAY,MAAM,qBAAqB,CAAC;AAE/C,0EAA0E;AAC1E,iFAAiF;AACjF,wEAAwE;AACxE,MAAM,KAAK,GAAG;IACZ,iBAAiB,EAAE,UAAU,CAAC,aAAa,EAAE,QAAQ,CAAC;IACtD,iBAAiB,EAAE,UAAU,CAC3B,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC1C,QAAQ,CACT;IACD,mBAAmB,EAAE,UAAU,CAAC,MAAM,CAAC,EAAE,EAAE,mBAAmB,CAAC,EAAE,QAAQ,CAAC;IAC1E,gBAAgB,EAAE,UAAU,CAAC,YAAY,EAAE,SAAS,CAAC;IACrD,YAAY,EAAE,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC;CAC/C,CAAC;AAEF,MAAM,OAAO,GAAoC,EAAE,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,MAAM,GAAG;IACb,IAAI,EAAE,EAAE,IAAI,EAAE,oBAAoB,EAAE,SAAS,EAAE,QAAQ,EAAE;IACzD,KAAK;IACL,OAAO;CACgB,CAAC;AAE1B,MAAM,OAAO,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAEnC,OAAO,CAAC,aAAa,CAAC,GAAG;IACvB;QACE,IAAI,EAAE,0BAA0B;QAChC,KAAK,EAAE,UAAU;QACjB,OAAO,EAAE,KAAK;QACd,OAAO;QACP,KAAK,EAAE;YACL,wBAAwB,EAAE,OAAO;YACjC,wBAAwB,EAAE,OAAO;SAClC;KACF;IACD;QACE,IAAI,EAAE,4BAA4B;QAClC,KAAK,EAAE,UAAU;QACjB,OAAO,EAAE,CAAC,GAAG,KAAK,EAAE,GAAG,OAAO,EAAE,GAAG,YAAY,CAAC;QAChD,OAAO;QACP,KAAK,EAAE;YACL,uBAAuB,EAAE,OAAO;YAChC,mBAAmB,EAAE,OAAO;SAC7B;KACF;IACD;QACE,IAAI,EAAE,iCAAiC;QACvC,KAAK,EAAE,YAAY;QACnB,eAAe,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QAClC,OAAO;QACP,KAAK,EAAE,EAAE,0BAA0B,EAAE,CAAC,OAAO,EAAE,gBAAgB,EAAE,CAAC,EAAE;KACrE;CACF,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -0,0 +1,3 @@
1
+ declare const _default: import("eslint").Rule.RuleModule;
2
+ export default _default;
3
+ //# sourceMappingURL=no-enum.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-enum.d.ts","sourceRoot":"","sources":["../../src/language/no-enum.ts"],"names":[],"mappings":";AAEA,wBAMG"}
@@ -0,0 +1,7 @@
1
+ import { selectorRule } from "../authoring/selector-rule.js";
2
+ export default selectorRule({
3
+ description: 'Disallow TypeScript enums, which Node cannot run with types stripped',
4
+ selectors: ['TSEnumDeclaration'],
5
+ message: 'No TS enums — they need a runtime transform and break Node strip-only `.ts` execution (tsc/bundlers hide it). Use a `const` object + a union type instead.',
6
+ });
7
+ //# sourceMappingURL=no-enum.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-enum.js","sourceRoot":"","sources":["../../src/language/no-enum.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAE7D,eAAe,YAAY,CAAC;IAC1B,WAAW,EACT,sEAAsE;IACxE,SAAS,EAAE,CAAC,mBAAmB,CAAC;IAChC,OAAO,EACL,4JAA4J;CAC/J,CAAC,CAAC"}
@@ -0,0 +1,30 @@
1
+ export interface DependencyPolicyOptions {
2
+ ignoredFiles?: string[];
3
+ ignoredDependencies?: string[];
4
+ includeTransitiveDependencies?: boolean;
5
+ checkMissingDependencies?: boolean;
6
+ checkObsoleteDependencies?: boolean;
7
+ checkVersionMismatches?: boolean;
8
+ buildTargets?: string[];
9
+ }
10
+ /**
11
+ * Options for `@nx/dependency-checks`: a package declares every package its
12
+ * shipped code imports, and only its direct imports. Obsolete dependencies are
13
+ * not checked: the check sees static imports only, so it would flag a package
14
+ * loaded through a dynamic import(), a CSS `@source` or a CLI.
15
+ *
16
+ * A project's `ignoredFiles` and `ignoredDependencies` are appended to the
17
+ * policy. Setting the rule with only those arrays would let the rule's own
18
+ * defaults fill in the rest — obsolete-dependency checks on, test files counted
19
+ * as shipped — which is how per-project configs silently lost the policy.
20
+ */
21
+ export declare function dependencyPolicy({ ignoredFiles, ignoredDependencies, ...overrides }?: DependencyPolicyOptions): {
22
+ ignoredFiles: string[];
23
+ ignoredDependencies: string[];
24
+ includeTransitiveDependencies: boolean;
25
+ checkMissingDependencies: boolean;
26
+ checkObsoleteDependencies: boolean;
27
+ checkVersionMismatches: boolean;
28
+ buildTargets?: string[];
29
+ };
30
+ //# sourceMappingURL=dependency-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-policy.d.ts","sourceRoot":"","sources":["../../src/nx-policy/dependency-policy.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACtC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAYD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,YAAiB,EACjB,mBAAwB,EACxB,GAAG,SAAS,EACb,GAAE,uBAA4B;;;mCAhCG,OAAO;8BACZ,OAAO;+BACN,OAAO;4BACV,OAAO;mBACjB,MAAM,EAAE;EAsCxB"}
@@ -0,0 +1,31 @@
1
+ const TESTS = '**/*.{test,spec}.{ts,tsx,mts,cts}';
2
+ // Test and build-tool files never ship, so their imports are not dependencies.
3
+ const NEVER_SHIPPED = [
4
+ `{projectRoot}/${TESTS}`,
5
+ '{projectRoot}/**/{tests,test,e2e,__tests__,__mocks__}/**',
6
+ '{projectRoot}/**/test-setup.{ts,tsx,mts,cts}',
7
+ '{projectRoot}/*.config.{js,cjs,mjs,ts,mts,cts}',
8
+ ];
9
+ /**
10
+ * Options for `@nx/dependency-checks`: a package declares every package its
11
+ * shipped code imports, and only its direct imports. Obsolete dependencies are
12
+ * not checked: the check sees static imports only, so it would flag a package
13
+ * loaded through a dynamic import(), a CSS `@source` or a CLI.
14
+ *
15
+ * A project's `ignoredFiles` and `ignoredDependencies` are appended to the
16
+ * policy. Setting the rule with only those arrays would let the rule's own
17
+ * defaults fill in the rest — obsolete-dependency checks on, test files counted
18
+ * as shipped — which is how per-project configs silently lost the policy.
19
+ */
20
+ export function dependencyPolicy({ ignoredFiles = [], ignoredDependencies = [], ...overrides } = {}) {
21
+ return {
22
+ includeTransitiveDependencies: false,
23
+ checkMissingDependencies: true,
24
+ checkObsoleteDependencies: false,
25
+ checkVersionMismatches: true,
26
+ ...overrides,
27
+ ignoredFiles: [...NEVER_SHIPPED, ...ignoredFiles],
28
+ ignoredDependencies: [...ignoredDependencies],
29
+ };
30
+ }
31
+ //# sourceMappingURL=dependency-policy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-policy.js","sourceRoot":"","sources":["../../src/nx-policy/dependency-policy.ts"],"names":[],"mappings":"AAUA,MAAM,KAAK,GAAG,mCAAmC,CAAC;AAElD,+EAA+E;AAC/E,MAAM,aAAa,GAAG;IACpB,iBAAiB,KAAK,EAAE;IACxB,0DAA0D;IAC1D,8CAA8C;IAC9C,gDAAgD;CACjD,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,YAAY,GAAG,EAAE,EACjB,mBAAmB,GAAG,EAAE,EACxB,GAAG,SAAS,KACe,EAAE;IAC7B,OAAO;QACL,6BAA6B,EAAE,KAAK;QACpC,wBAAwB,EAAE,IAAI;QAC9B,yBAAyB,EAAE,KAAK;QAChC,sBAAsB,EAAE,IAAI;QAC5B,GAAG,SAAS;QACZ,YAAY,EAAE,CAAC,GAAG,aAAa,EAAE,GAAG,YAAY,CAAC;QACjD,mBAAmB,EAAE,CAAC,GAAG,mBAAmB,CAAC;KAC9C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { DepConstraint } from './module-boundaries.ts';
2
+ /** The Nx tag that makes a project an island. */
3
+ export declare const ISLAND_TAG = "layer:island";
4
+ /**
5
+ * The `@nx/enforce-module-boundaries` constraint for islands: an island depends
6
+ * only on other islands and never imports a host's runtime (`hostRuntimes`,
7
+ * e.g. `['electron', 'hono', 'hono/*']`).
8
+ */
9
+ export declare function islandConstraint(hostRuntimes: readonly string[]): DepConstraint;
10
+ //# sourceMappingURL=island-constraint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"island-constraint.d.ts","sourceRoot":"","sources":["../../src/nx-policy/island-constraint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,iDAAiD;AACjD,eAAO,MAAM,UAAU,iBAAiB,CAAC;AAEzC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,SAAS,MAAM,EAAE,GAC9B,aAAa,CAMf"}
@@ -0,0 +1,15 @@
1
+ /** The Nx tag that makes a project an island. */
2
+ export const ISLAND_TAG = 'layer:island';
3
+ /**
4
+ * The `@nx/enforce-module-boundaries` constraint for islands: an island depends
5
+ * only on other islands and never imports a host's runtime (`hostRuntimes`,
6
+ * e.g. `['electron', 'hono', 'hono/*']`).
7
+ */
8
+ export function islandConstraint(hostRuntimes) {
9
+ return {
10
+ sourceTag: ISLAND_TAG,
11
+ onlyDependOnLibsWithTags: [ISLAND_TAG],
12
+ bannedExternalImports: [...hostRuntimes],
13
+ };
14
+ }
15
+ //# sourceMappingURL=island-constraint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"island-constraint.js","sourceRoot":"","sources":["../../src/nx-policy/island-constraint.ts"],"names":[],"mappings":"AAEA,iDAAiD;AACjD,MAAM,CAAC,MAAM,UAAU,GAAG,cAAc,CAAC;AAEzC;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,YAA+B;IAE/B,OAAO;QACL,SAAS,EAAE,UAAU;QACrB,wBAAwB,EAAE,CAAC,UAAU,CAAC;QACtC,qBAAqB,EAAE,CAAC,GAAG,YAAY,CAAC;KACzC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,29 @@
1
+ export interface DepConstraint {
2
+ sourceTag: string;
3
+ onlyDependOnLibsWithTags?: string[];
4
+ notDependOnLibsWithTags?: string[];
5
+ bannedExternalImports?: string[];
6
+ allowedExternalImports?: string[];
7
+ }
8
+ export interface ModuleBoundaryOptions {
9
+ /** Import paths exempt from every constraint, as regexes. */
10
+ allow?: string[];
11
+ depConstraints?: DepConstraint[];
12
+ checkDynamicDependenciesExceptions?: string[];
13
+ banTransitiveDependencies?: boolean;
14
+ enforceBuildableLibDependency?: boolean;
15
+ }
16
+ /**
17
+ * Options for `@nx/enforce-module-boundaries`: the shared ones, with the
18
+ * repo's own `allow` entries and constraints appended rather than replacing
19
+ * them. Setting the rule with only the repo's constraints would drop the rest,
20
+ * the way partial `dependency-checks` options dropped the shared policy.
21
+ */
22
+ export declare function moduleBoundaries({ allow, depConstraints, ...rest }?: ModuleBoundaryOptions): {
23
+ allow: string[];
24
+ depConstraints: DepConstraint[];
25
+ checkDynamicDependenciesExceptions?: string[];
26
+ banTransitiveDependencies?: boolean;
27
+ enforceBuildableLibDependency: boolean;
28
+ };
29
+ //# sourceMappingURL=module-boundaries.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-boundaries.d.ts","sourceRoot":"","sources":["../../src/nx-policy/module-boundaries.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC;IACpC,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,qBAAqB;IACpC,6DAA6D;IAC7D,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,CAAC,EAAE,aAAa,EAAE,CAAC;IACjC,kCAAkC,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9C,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC;AAKD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAU,EACV,cAAmB,EACnB,GAAG,IAAI,EACR,GAAE,qBAA0B;;;yCAlBU,MAAM,EAAE;gCACjB,OAAO;mCACH,OAAO;EA0BxC"}
@@ -0,0 +1,20 @@
1
+ // ESLint configs import presets across project boundaries by design.
2
+ const ESLINT_CONFIG_FILES = '^.*/eslint(\\.base)?\\.config\\.[cm]?js$';
3
+ /**
4
+ * Options for `@nx/enforce-module-boundaries`: the shared ones, with the
5
+ * repo's own `allow` entries and constraints appended rather than replacing
6
+ * them. Setting the rule with only the repo's constraints would drop the rest,
7
+ * the way partial `dependency-checks` options dropped the shared policy.
8
+ */
9
+ export function moduleBoundaries({ allow = [], depConstraints = [], ...rest } = {}) {
10
+ return {
11
+ enforceBuildableLibDependency: true,
12
+ ...rest,
13
+ allow: [ESLINT_CONFIG_FILES, ...allow],
14
+ depConstraints: [
15
+ { sourceTag: '*', onlyDependOnLibsWithTags: ['*'] },
16
+ ...depConstraints,
17
+ ],
18
+ };
19
+ }
20
+ //# sourceMappingURL=module-boundaries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"module-boundaries.js","sourceRoot":"","sources":["../../src/nx-policy/module-boundaries.ts"],"names":[],"mappings":"AAiBA,qEAAqE;AACrE,MAAM,mBAAmB,GAAG,0CAA0C,CAAC;AAEvE;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,KAAK,GAAG,EAAE,EACV,cAAc,GAAG,EAAE,EACnB,GAAG,IAAI,KACkB,EAAE;IAC3B,OAAO;QACL,6BAA6B,EAAE,IAAI;QACnC,GAAG,IAAI;QACP,KAAK,EAAE,CAAC,mBAAmB,EAAE,GAAG,KAAK,CAAC;QACtC,cAAc,EAAE;YACd,EAAE,SAAS,EAAE,GAAG,EAAE,wBAAwB,EAAE,CAAC,GAAG,CAAC,EAAE;YACnD,GAAG,cAAc;SAClB;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { type Concept } from '../concept.ts';
2
+ /** Nx project.json files: target options that Nx reads without complaint when they are wrong. */
3
+ export declare const nxProjectJson: Concept;
4
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/nx-project/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,OAAO,EAAU,MAAM,eAAe,CAAC;AAMrD,iGAAiG;AACjG,eAAO,MAAM,aAAa,EAAE,OAY3B,CAAC"}
@@ -0,0 +1,20 @@
1
+ import * as jsonc from 'jsonc-eslint-parser';
2
+ import { enable } from "../concept.js";
3
+ import { PROJECT_JSON } from "../files.js";
4
+ import noMissingAssetInput from "./no-missing-asset-input.js";
5
+ const rules = { 'no-missing-asset-input': noMissingAssetInput };
6
+ /** Nx project.json files: target options that Nx reads without complaint when they are wrong. */
7
+ export const nxProjectJson = {
8
+ name: 'nx-project-json',
9
+ rules,
10
+ config: (plugins) => [
11
+ {
12
+ name: 'zukhruf/nx-project-json',
13
+ files: PROJECT_JSON,
14
+ languageOptions: { parser: jsonc },
15
+ plugins,
16
+ rules: enable(rules),
17
+ },
18
+ ],
19
+ };
20
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/nx-project/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,qBAAqB,CAAC;AAE7C,OAAO,EAAgB,MAAM,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,mBAAmB,MAAM,6BAA6B,CAAC;AAE9D,MAAM,KAAK,GAAG,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,CAAC;AAEhE,iGAAiG;AACjG,MAAM,CAAC,MAAM,aAAa,GAAY;IACpC,IAAI,EAAE,iBAAiB;IACvB,KAAK;IACL,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;QACnB;YACE,IAAI,EAAE,yBAAyB;YAC/B,KAAK,EAAE,YAAY;YACnB,eAAe,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;YAClC,OAAO;YACP,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC;SACrB;KACF;CACF,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { Rule } from 'eslint';
2
+ /**
3
+ * Nx copies a target's `assets` with a silent glob: an input that does not
4
+ * exist, or one the root ignore files drop, copies nothing while the build
5
+ * stays green, and the artifact ships without it.
6
+ */
7
+ declare const rule: Rule.RuleModule;
8
+ export default rule;
9
+ //# sourceMappingURL=no-missing-asset-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-missing-asset-input.d.ts","sourceRoot":"","sources":["../../src/nx-project/no-missing-asset-input.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAsEnC;;;;GAIG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAqKhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,209 @@
1
+ import { existsSync, readFileSync, statSync } from 'node:fs';
2
+ import { dirname, join, posix, relative, resolve, sep } from 'node:path';
3
+ import ignore, {} from 'ignore';
4
+ import { isType } from "../authoring/ast.js";
5
+ import { workspaceRootOf } from "../workspace/workspace-root.js";
6
+ function keyName(property) {
7
+ const key = property['key'];
8
+ if (isType(key, 'JSONLiteral') && typeof key['value'] === 'string') {
9
+ return key['value'];
10
+ }
11
+ if (isType(key, 'JSONIdentifier') && typeof key['name'] === 'string') {
12
+ return key['name'];
13
+ }
14
+ return undefined;
15
+ }
16
+ function stringValue(node) {
17
+ return isType(node, 'JSONLiteral') && typeof node['value'] === 'string'
18
+ ? node['value']
19
+ : undefined;
20
+ }
21
+ const GLOB_MAGIC = /[*?[\]{}!]/;
22
+ // The leading magic-free directory of a glob pattern — 'packages/x/**' → 'packages/x'.
23
+ function staticBase(pattern) {
24
+ const segments = pattern.split('/');
25
+ const literal = [];
26
+ for (const segment of segments) {
27
+ if (GLOB_MAGIC.test(segment)) {
28
+ break;
29
+ }
30
+ literal.push(segment);
31
+ }
32
+ return literal.join('/');
33
+ }
34
+ function isDirectory(path) {
35
+ return existsSync(path) && statSync(path).isDirectory();
36
+ }
37
+ // Nx executors generally receive workspace-root asset inputs, while Nx's Vite
38
+ // copy plugin receives project-root inputs and remaps them before
39
+ // CopyAssetsHandler runs, so both roots are tried.
40
+ function assetRoots(workspaceRoot, filename) {
41
+ const projectRoot = dirname(filename);
42
+ if (projectRoot === workspaceRoot) {
43
+ return [workspaceRoot];
44
+ }
45
+ return [workspaceRoot, projectRoot];
46
+ }
47
+ // Nx's CopyAssetsHandler reads only the ROOT .gitignore and .nxignore
48
+ // (node_modules/@nx/js/dist/src/utils/assets/copy-assets-handler.js:47-48) and
49
+ // skips every matched file (:152), so an ignored asset builds green and ships
50
+ // nothing. Nested .gitignore files are not read there, so they do not count here.
51
+ // Only the @nx/js tsc/swc executors accept includeIgnoredFiles; this rule does
52
+ // not honor that opt-out.
53
+ function rootIgnoreFiles(workspaceRoot) {
54
+ return ['.gitignore', '.nxignore']
55
+ .filter((file) => existsSync(join(workspaceRoot, file)))
56
+ .map((file) => ({
57
+ file,
58
+ matcher: ignore().add(readFileSync(join(workspaceRoot, file), 'utf8')),
59
+ }));
60
+ }
61
+ /**
62
+ * Nx copies a target's `assets` with a silent glob: an input that does not
63
+ * exist, or one the root ignore files drop, copies nothing while the build
64
+ * stays green, and the artifact ships without it.
65
+ */
66
+ const rule = {
67
+ meta: {
68
+ type: 'problem',
69
+ docs: {
70
+ description: "Disallow target asset entries whose input path does not exist — Nx's asset copy is a silent glob, so a dead path ships nothing while the build stays green",
71
+ },
72
+ messages: {
73
+ missingInput: 'Asset input "{{path}}" is not a directory from the workspace root or project root. The executor globs it silently — a dead input copies nothing and the build stays green. Fix the path or delete the entry.',
74
+ missingPattern: 'Asset pattern "{{pattern}}" matches nothing: "{{base}}" does not exist relative to the workspace root or project root. Fix the path or delete the entry.',
75
+ ignoredAsset: 'Asset "{{path}}" is matched by the root {{file}}, and Nx\'s asset copy skips root-ignored files — the build stays green and ships without it. Ignore it from a .gitignore inside the project instead, or stop ignoring it.',
76
+ },
77
+ schema: [],
78
+ },
79
+ create(context) {
80
+ const filename = context.physicalFilename;
81
+ const workspaceRoot = workspaceRootOf(dirname(filename));
82
+ if (!workspaceRoot) {
83
+ return {};
84
+ }
85
+ const roots = assetRoots(workspaceRoot, filename);
86
+ const ignoreFiles = rootIgnoreFiles(workspaceRoot);
87
+ // Nx globs from the workspace root, so a root that resolves the path above
88
+ // it (a project-root `../..` read from the workspace root) is never Nx's.
89
+ const rootResolving = (path, exists) => roots.find((root) => {
90
+ const absolute = resolve(root, path);
91
+ return (!relative(workspaceRoot, absolute).startsWith('..') &&
92
+ exists(absolute));
93
+ });
94
+ // A magic-free pattern names one path; a glob is probed at its static base
95
+ // directory, which is ignored only when every file it can match is dropped.
96
+ const reportIfIgnored = (node, root, pattern) => {
97
+ const base = staticBase(pattern);
98
+ // `ignore` takes a workspace-relative path with `/` separators.
99
+ const directory = relative(workspaceRoot, resolve(root, base))
100
+ .split(sep)
101
+ .join('/');
102
+ // No ignore file can drop the workspace root itself.
103
+ if (directory === '') {
104
+ return;
105
+ }
106
+ const fromWorkspace = directory + (base === pattern ? '' : '/');
107
+ const matched = ignoreFiles.find(({ matcher }) => matcher.ignores(fromWorkspace));
108
+ if (matched) {
109
+ context.report({
110
+ node,
111
+ messageId: 'ignoredAsset',
112
+ data: { path: fromWorkspace, file: matched.file },
113
+ });
114
+ }
115
+ };
116
+ function underTargets(node) {
117
+ return context.sourceCode
118
+ .getAncestors(node)
119
+ .some((ancestor) => isType(ancestor, 'JSONProperty') && keyName(ancestor) === 'targets');
120
+ }
121
+ function checkStringEntry(element) {
122
+ const pattern = stringValue(element);
123
+ if (pattern === undefined) {
124
+ return;
125
+ }
126
+ const normalized = pattern.replace(/^\.\//, '');
127
+ const base = staticBase(normalized);
128
+ if (base === '') {
129
+ return;
130
+ }
131
+ const baseRoot = rootResolving(base, existsSync);
132
+ if (!baseRoot) {
133
+ context.report({
134
+ node: element,
135
+ messageId: 'missingPattern',
136
+ data: { pattern, base },
137
+ });
138
+ return;
139
+ }
140
+ reportIfIgnored(element, baseRoot, normalized);
141
+ }
142
+ function checkObjectEntry(element) {
143
+ const properties = element['properties'];
144
+ if (!Array.isArray(properties)) {
145
+ return;
146
+ }
147
+ const fields = new Map();
148
+ for (const property of properties) {
149
+ if (isType(property, 'JSONProperty')) {
150
+ const key = keyName(property);
151
+ if (key !== undefined) {
152
+ fields.set(key, property['value']);
153
+ }
154
+ }
155
+ }
156
+ const value = fields.get('input');
157
+ if (!isType(value, 'JSONLiteral')) {
158
+ return;
159
+ }
160
+ const input = stringValue(value);
161
+ if (input === undefined) {
162
+ return;
163
+ }
164
+ const inputRoot = rootResolving(input, isDirectory);
165
+ if (!inputRoot) {
166
+ context.report({
167
+ node: value,
168
+ messageId: 'missingInput',
169
+ data: { path: input },
170
+ });
171
+ return;
172
+ }
173
+ const glob = stringValue(fields.get('glob'));
174
+ if (glob !== undefined) {
175
+ // A glob is a `/`-separated pattern on every OS; path.join would
176
+ // write backslashes on Windows, which staticBase never splits.
177
+ reportIfIgnored(element, inputRoot, posix.join(input, glob));
178
+ }
179
+ }
180
+ return {
181
+ JSONProperty(node) {
182
+ if (!isType(node, 'JSONProperty')) {
183
+ return;
184
+ }
185
+ if (keyName(node) !== 'assets' || !underTargets(node)) {
186
+ return;
187
+ }
188
+ const value = node['value'];
189
+ if (!isType(value, 'JSONArrayExpression')) {
190
+ return;
191
+ }
192
+ const elements = value['elements'];
193
+ if (!Array.isArray(elements)) {
194
+ return;
195
+ }
196
+ for (const element of elements) {
197
+ if (isType(element, 'JSONLiteral')) {
198
+ checkStringEntry(element);
199
+ }
200
+ else if (isType(element, 'JSONObjectExpression')) {
201
+ checkObjectEntry(element);
202
+ }
203
+ }
204
+ },
205
+ };
206
+ },
207
+ };
208
+ export default rule;
209
+ //# sourceMappingURL=no-missing-asset-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-missing-asset-input.js","sourceRoot":"","sources":["../../src/nx-project/no-missing-asset-input.ts"],"names":[],"mappings":"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"}
package/dist/nx.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export { default } from './island/plugin.ts';
2
+ export { dependencyPolicy, type DependencyPolicyOptions, } from './nx-policy/dependency-policy.ts';
3
+ export { ISLAND_TAG, islandConstraint } from './nx-policy/island-constraint.ts';
4
+ export { type DepConstraint, moduleBoundaries, type ModuleBoundaryOptions, } from './nx-policy/module-boundaries.ts';
5
+ //# sourceMappingURL=nx.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nx.d.ts","sourceRoot":"","sources":["../src/nx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EACL,gBAAgB,EAChB,KAAK,uBAAuB,GAC7B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAChF,OAAO,EACL,KAAK,aAAa,EAClB,gBAAgB,EAChB,KAAK,qBAAqB,GAC3B,MAAM,kCAAkC,CAAC"}
package/dist/nx.js ADDED
@@ -0,0 +1,5 @@
1
+ export { default } from "./island/plugin.js";
2
+ export { dependencyPolicy, } from "./nx-policy/dependency-policy.js";
3
+ export { ISLAND_TAG, islandConstraint } from "./nx-policy/island-constraint.js";
4
+ export { moduleBoundaries, } from "./nx-policy/module-boundaries.js";
5
+ //# sourceMappingURL=nx.js.map
package/dist/nx.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nx.js","sourceRoot":"","sources":["../src/nx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EACL,gBAAgB,GAEjB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAChF,OAAO,EAEL,gBAAgB,GAEjB,MAAM,kCAAkC,CAAC"}