@thethracian/oxlint-config 0.2.1 → 0.3.1

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 (279) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +124 -18
  3. package/dist/codemod-fix/cli.d.ts +3 -0
  4. package/dist/codemod-fix/cli.d.ts.map +1 -0
  5. package/dist/codemod-fix/cli.js +22 -0
  6. package/dist/codemod-fix/cli.js.map +1 -0
  7. package/dist/codemod-fix/index.d.ts +44 -0
  8. package/dist/codemod-fix/index.d.ts.map +1 -0
  9. package/dist/codemod-fix/index.js +110 -0
  10. package/dist/codemod-fix/index.js.map +1 -0
  11. package/dist/codemods/arrow-body-style.d.ts +7 -0
  12. package/dist/codemods/arrow-body-style.d.ts.map +1 -0
  13. package/dist/codemods/arrow-body-style.js +106 -0
  14. package/dist/codemods/arrow-body-style.js.map +1 -0
  15. package/dist/codemods/comment-format.d.ts +24 -0
  16. package/dist/codemods/comment-format.d.ts.map +1 -0
  17. package/dist/codemods/comment-format.js +100 -0
  18. package/dist/codemods/comment-format.js.map +1 -0
  19. package/dist/codemods/explicit-return-types.d.ts +7 -0
  20. package/dist/codemods/explicit-return-types.d.ts.map +1 -0
  21. package/dist/codemods/explicit-return-types.js +350 -0
  22. package/dist/codemods/explicit-return-types.js.map +1 -0
  23. package/dist/codemods/format-file-header.d.ts +7 -0
  24. package/dist/codemods/format-file-header.d.ts.map +1 -0
  25. package/dist/codemods/format-file-header.js +163 -0
  26. package/dist/codemods/format-file-header.js.map +1 -0
  27. package/dist/codemods/format-jsdoc-comments.d.ts +7 -0
  28. package/dist/codemods/format-jsdoc-comments.d.ts.map +1 -0
  29. package/dist/codemods/format-jsdoc-comments.js +129 -0
  30. package/dist/codemods/format-jsdoc-comments.js.map +1 -0
  31. package/dist/codemods/function-declarations.d.ts +7 -0
  32. package/dist/codemods/function-declarations.d.ts.map +1 -0
  33. package/dist/codemods/function-declarations.js +202 -0
  34. package/dist/codemods/function-declarations.js.map +1 -0
  35. package/dist/codemods/inline-export-lists.d.ts +7 -0
  36. package/dist/codemods/inline-export-lists.d.ts.map +1 -0
  37. package/dist/codemods/inline-export-lists.js +168 -0
  38. package/dist/codemods/inline-export-lists.js.map +1 -0
  39. package/dist/codemods/internal-export-docs.d.ts +7 -0
  40. package/dist/codemods/internal-export-docs.d.ts.map +1 -0
  41. package/dist/codemods/internal-export-docs.js +93 -0
  42. package/dist/codemods/internal-export-docs.js.map +1 -0
  43. package/dist/codemods/no-ternary-branch-initializers.d.ts +14 -0
  44. package/dist/codemods/no-ternary-branch-initializers.d.ts.map +1 -0
  45. package/dist/codemods/no-ternary-branch-initializers.js +240 -0
  46. package/dist/codemods/no-ternary-branch-initializers.js.map +1 -0
  47. package/dist/codemods/no-ternary-variable-initializers.d.ts +14 -0
  48. package/dist/codemods/no-ternary-variable-initializers.d.ts.map +1 -0
  49. package/dist/codemods/no-ternary-variable-initializers.js +235 -0
  50. package/dist/codemods/no-ternary-variable-initializers.js.map +1 -0
  51. package/dist/codemods/no-ternary.d.ts +7 -0
  52. package/dist/codemods/no-ternary.d.ts.map +1 -0
  53. package/dist/codemods/no-ternary.js +215 -0
  54. package/dist/codemods/no-ternary.js.map +1 -0
  55. package/dist/codemods/rename-acronyms.d.ts +8 -0
  56. package/dist/codemods/rename-acronyms.d.ts.map +1 -0
  57. package/dist/codemods/rename-acronyms.js +193 -0
  58. package/dist/codemods/rename-acronyms.js.map +1 -0
  59. package/dist/codemods/run.d.ts +2 -0
  60. package/dist/codemods/run.d.ts.map +1 -0
  61. package/dist/codemods/run.js +14 -0
  62. package/dist/codemods/run.js.map +1 -0
  63. package/dist/codemods/sort-imports.d.ts +7 -0
  64. package/dist/codemods/sort-imports.d.ts.map +1 -0
  65. package/dist/codemods/sort-imports.js +235 -0
  66. package/dist/codemods/sort-imports.js.map +1 -0
  67. package/dist/index.d.ts +30 -96
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +156 -94
  70. package/dist/index.js.map +1 -1
  71. package/dist/rules/acronym-case.d.ts +7 -3
  72. package/dist/rules/acronym-case.d.ts.map +1 -1
  73. package/dist/rules/acronym-case.js +129 -118
  74. package/dist/rules/acronym-case.js.map +1 -1
  75. package/dist/rules/acronyms-1.d.ts +3 -0
  76. package/dist/rules/acronyms-1.d.ts.map +1 -0
  77. package/dist/rules/acronyms-1.js +407 -0
  78. package/dist/rules/acronyms-1.js.map +1 -0
  79. package/dist/rules/acronyms-2.d.ts +3 -0
  80. package/dist/rules/acronyms-2.d.ts.map +1 -0
  81. package/dist/rules/acronyms-2.js +407 -0
  82. package/dist/rules/acronyms-2.js.map +1 -0
  83. package/dist/rules/acronyms-3.d.ts +3 -0
  84. package/dist/rules/acronyms-3.d.ts.map +1 -0
  85. package/dist/rules/acronyms-3.js +407 -0
  86. package/dist/rules/acronyms-3.js.map +1 -0
  87. package/dist/rules/acronyms-4.d.ts +3 -0
  88. package/dist/rules/acronyms-4.d.ts.map +1 -0
  89. package/dist/rules/acronyms-4.js +377 -0
  90. package/dist/rules/acronyms-4.js.map +1 -0
  91. package/dist/rules/acronyms.d.ts +1 -8
  92. package/dist/rules/acronyms.d.ts.map +1 -1
  93. package/dist/rules/acronyms.js +14 -1578
  94. package/dist/rules/acronyms.js.map +1 -1
  95. package/dist/rules/boolean-prefix.d.ts +11 -2
  96. package/dist/rules/boolean-prefix.d.ts.map +1 -1
  97. package/dist/rules/boolean-prefix.js +95 -59
  98. package/dist/rules/boolean-prefix.js.map +1 -1
  99. package/dist/rules/camel-case-identifiers.d.ts +3 -4
  100. package/dist/rules/camel-case-identifiers.d.ts.map +1 -1
  101. package/dist/rules/camel-case-identifiers.js +59 -40
  102. package/dist/rules/camel-case-identifiers.js.map +1 -1
  103. package/dist/rules/char-class.d.ts +26 -13
  104. package/dist/rules/char-class.d.ts.map +1 -1
  105. package/dist/rules/char-class.js +56 -24
  106. package/dist/rules/char-class.js.map +1 -1
  107. package/dist/rules/diagnostic-guidance.d.ts +91 -0
  108. package/dist/rules/diagnostic-guidance.d.ts.map +1 -0
  109. package/dist/rules/diagnostic-guidance.js +243 -0
  110. package/dist/rules/diagnostic-guidance.js.map +1 -0
  111. package/dist/rules/effect-default-ast.d.ts +89 -0
  112. package/dist/rules/effect-default-ast.d.ts.map +1 -0
  113. package/dist/rules/effect-default-ast.js +208 -0
  114. package/dist/rules/effect-default-ast.js.map +1 -0
  115. package/dist/rules/effect-default-compat-rules.d.ts +76 -0
  116. package/dist/rules/effect-default-compat-rules.d.ts.map +1 -0
  117. package/dist/rules/effect-default-compat-rules.js +270 -0
  118. package/dist/rules/effect-default-compat-rules.js.map +1 -0
  119. package/dist/rules/effect-default-env-rules.d.ts +60 -0
  120. package/dist/rules/effect-default-env-rules.d.ts.map +1 -0
  121. package/dist/rules/effect-default-env-rules.js +259 -0
  122. package/dist/rules/effect-default-env-rules.js.map +1 -0
  123. package/dist/rules/effect-default-fiber-helpers.d.ts +13 -0
  124. package/dist/rules/effect-default-fiber-helpers.d.ts.map +1 -0
  125. package/dist/rules/effect-default-fiber-helpers.js +76 -0
  126. package/dist/rules/effect-default-fiber-helpers.js.map +1 -0
  127. package/dist/rules/effect-default-floating-helpers.d.ts +7 -0
  128. package/dist/rules/effect-default-floating-helpers.d.ts.map +1 -0
  129. package/dist/rules/effect-default-floating-helpers.js +113 -0
  130. package/dist/rules/effect-default-floating-helpers.js.map +1 -0
  131. package/dist/rules/effect-default-helpers.d.ts +8 -32
  132. package/dist/rules/effect-default-helpers.d.ts.map +1 -1
  133. package/dist/rules/effect-default-helpers.js +11 -535
  134. package/dist/rules/effect-default-helpers.js.map +1 -1
  135. package/dist/rules/effect-default-resource-helpers.d.ts +18 -4
  136. package/dist/rules/effect-default-resource-helpers.d.ts.map +1 -1
  137. package/dist/rules/effect-default-resource-helpers.js +30 -13
  138. package/dist/rules/effect-default-resource-helpers.js.map +1 -1
  139. package/dist/rules/effect-default-safety-helpers.d.ts +43 -0
  140. package/dist/rules/effect-default-safety-helpers.d.ts.map +1 -0
  141. package/dist/rules/effect-default-safety-helpers.js +126 -0
  142. package/dist/rules/effect-default-safety-helpers.js.map +1 -0
  143. package/dist/rules/effect-default-scan-helpers.d.ts +43 -0
  144. package/dist/rules/effect-default-scan-helpers.d.ts.map +1 -0
  145. package/dist/rules/effect-default-scan-helpers.js +141 -0
  146. package/dist/rules/effect-default-scan-helpers.js.map +1 -0
  147. package/dist/rules/effect-default-schema-helpers.d.ts +37 -0
  148. package/dist/rules/effect-default-schema-helpers.d.ts.map +1 -0
  149. package/dist/rules/effect-default-schema-helpers.js +104 -0
  150. package/dist/rules/effect-default-schema-helpers.js.map +1 -0
  151. package/dist/rules/effect-default-test-helpers.d.ts +18 -4
  152. package/dist/rules/effect-default-test-helpers.d.ts.map +1 -1
  153. package/dist/rules/effect-default-test-helpers.js +41 -20
  154. package/dist/rules/effect-default-test-helpers.js.map +1 -1
  155. package/dist/rules/effect-default-workflow-helpers.d.ts +91 -0
  156. package/dist/rules/effect-default-workflow-helpers.d.ts.map +1 -0
  157. package/dist/rules/effect-default-workflow-helpers.js +247 -0
  158. package/dist/rules/effect-default-workflow-helpers.js.map +1 -0
  159. package/dist/rules/effect-default.d.ts +1 -1
  160. package/dist/rules/effect-default.d.ts.map +1 -1
  161. package/dist/rules/effect-default.js +105 -680
  162. package/dist/rules/effect-default.js.map +1 -1
  163. package/dist/rules/effect-exported-declarations.d.ts +19 -0
  164. package/dist/rules/effect-exported-declarations.d.ts.map +1 -0
  165. package/dist/rules/effect-exported-declarations.js +237 -0
  166. package/dist/rules/effect-exported-declarations.js.map +1 -0
  167. package/dist/rules/effect-path-options.d.ts +49 -11
  168. package/dist/rules/effect-path-options.d.ts.map +1 -1
  169. package/dist/rules/effect-path-options.js +85 -52
  170. package/dist/rules/effect-path-options.js.map +1 -1
  171. package/dist/rules/effect-rule-aliases.d.ts +55 -0
  172. package/dist/rules/effect-rule-aliases.d.ts.map +1 -0
  173. package/dist/rules/effect-rule-aliases.js +278 -0
  174. package/dist/rules/effect-rule-aliases.js.map +1 -0
  175. package/dist/rules/effect-rule-core.d.ts +38 -24
  176. package/dist/rules/effect-rule-core.d.ts.map +1 -1
  177. package/dist/rules/effect-rule-core.js +157 -344
  178. package/dist/rules/effect-rule-core.js.map +1 -1
  179. package/dist/rules/effect-rule-names.d.ts +12 -3
  180. package/dist/rules/effect-rule-names.d.ts.map +1 -1
  181. package/dist/rules/effect-rule-names.js +15 -3
  182. package/dist/rules/effect-rule-names.js.map +1 -1
  183. package/dist/rules/effect-source-comments.d.ts +7 -0
  184. package/dist/rules/effect-source-comments.d.ts.map +1 -0
  185. package/dist/rules/effect-source-comments.js +227 -0
  186. package/dist/rules/effect-source-comments.js.map +1 -0
  187. package/dist/rules/effect-source-helpers.d.ts +4 -9
  188. package/dist/rules/effect-source-helpers.d.ts.map +1 -1
  189. package/dist/rules/effect-source-helpers.js +7 -358
  190. package/dist/rules/effect-source-helpers.js.map +1 -1
  191. package/dist/rules/effect-source-navigation.d.ts +25 -0
  192. package/dist/rules/effect-source-navigation.d.ts.map +1 -0
  193. package/dist/rules/effect-source-navigation.js +244 -0
  194. package/dist/rules/effect-source-navigation.js.map +1 -0
  195. package/dist/rules/effect-source-scan.d.ts +30 -7
  196. package/dist/rules/effect-source-scan.d.ts.map +1 -1
  197. package/dist/rules/effect-source-scan.js +372 -300
  198. package/dist/rules/effect-source-scan.js.map +1 -1
  199. package/dist/rules/effect-strict-ast-specs.d.ts +8 -0
  200. package/dist/rules/effect-strict-ast-specs.d.ts.map +1 -0
  201. package/dist/rules/effect-strict-ast-specs.js +166 -0
  202. package/dist/rules/effect-strict-ast-specs.js.map +1 -0
  203. package/dist/rules/effect-strict-boundary-helpers.d.ts +25 -0
  204. package/dist/rules/effect-strict-boundary-helpers.d.ts.map +1 -0
  205. package/dist/rules/effect-strict-boundary-helpers.js +127 -0
  206. package/dist/rules/effect-strict-boundary-helpers.js.map +1 -0
  207. package/dist/rules/effect-strict-core-specs.d.ts +8 -0
  208. package/dist/rules/effect-strict-core-specs.d.ts.map +1 -0
  209. package/dist/rules/effect-strict-core-specs.js +334 -0
  210. package/dist/rules/effect-strict-core-specs.js.map +1 -0
  211. package/dist/rules/effect-strict-external-helpers.d.ts +25 -0
  212. package/dist/rules/effect-strict-external-helpers.d.ts.map +1 -0
  213. package/dist/rules/effect-strict-external-helpers.js +87 -0
  214. package/dist/rules/effect-strict-external-helpers.js.map +1 -0
  215. package/dist/rules/effect-strict-helpers.d.ts +75 -33
  216. package/dist/rules/effect-strict-helpers.d.ts.map +1 -1
  217. package/dist/rules/effect-strict-helpers.js +93 -384
  218. package/dist/rules/effect-strict-helpers.js.map +1 -1
  219. package/dist/rules/effect-strict-internals.d.ts +198 -0
  220. package/dist/rules/effect-strict-internals.d.ts.map +1 -0
  221. package/dist/rules/effect-strict-internals.js +477 -0
  222. package/dist/rules/effect-strict-internals.js.map +1 -0
  223. package/dist/rules/effect-strict-segment-helpers.d.ts +79 -0
  224. package/dist/rules/effect-strict-segment-helpers.d.ts.map +1 -0
  225. package/dist/rules/effect-strict-segment-helpers.js +308 -0
  226. package/dist/rules/effect-strict-segment-helpers.js.map +1 -0
  227. package/dist/rules/effect-strict.d.ts +1 -1
  228. package/dist/rules/effect-strict.d.ts.map +1 -1
  229. package/dist/rules/effect-strict.js +10 -725
  230. package/dist/rules/effect-strict.js.map +1 -1
  231. package/dist/rules/max-import-depth.d.ts +2 -2
  232. package/dist/rules/max-import-depth.d.ts.map +1 -1
  233. package/dist/rules/max-import-depth.js +52 -17
  234. package/dist/rules/max-import-depth.js.map +1 -1
  235. package/dist/rules/max-line-length.d.ts +9 -2
  236. package/dist/rules/max-line-length.d.ts.map +1 -1
  237. package/dist/rules/max-line-length.js +52 -15
  238. package/dist/rules/max-line-length.js.map +1 -1
  239. package/dist/rules/no-commented-out-code.d.ts +3 -7
  240. package/dist/rules/no-commented-out-code.d.ts.map +1 -1
  241. package/dist/rules/no-commented-out-code.js +157 -102
  242. package/dist/rules/no-commented-out-code.js.map +1 -1
  243. package/dist/rules/pascal-case-types.d.ts +1 -1
  244. package/dist/rules/pascal-case-types.d.ts.map +1 -1
  245. package/dist/rules/pascal-case-types.js +65 -46
  246. package/dist/rules/pascal-case-types.js.map +1 -1
  247. package/dist/rules/plugin-commented-out-code-rule.d.ts +32 -0
  248. package/dist/rules/plugin-commented-out-code-rule.d.ts.map +1 -0
  249. package/dist/rules/plugin-commented-out-code-rule.js +135 -0
  250. package/dist/rules/plugin-commented-out-code-rule.js.map +1 -0
  251. package/dist/rules/plugin.d.ts +5 -0
  252. package/dist/rules/plugin.d.ts.map +1 -1
  253. package/dist/rules/plugin.js +168 -154
  254. package/dist/rules/plugin.js.map +1 -1
  255. package/dist/rules/private-underscore.d.ts +1 -1
  256. package/dist/rules/private-underscore.d.ts.map +1 -1
  257. package/dist/rules/private-underscore.js +11 -4
  258. package/dist/rules/private-underscore.js.map +1 -1
  259. package/dist/rules/require-file-doc.d.ts +5 -6
  260. package/dist/rules/require-file-doc.d.ts.map +1 -1
  261. package/dist/rules/require-file-doc.js +127 -78
  262. package/dist/rules/require-file-doc.js.map +1 -1
  263. package/dist/rules/require-function-doc-ignored-text.d.ts +7 -0
  264. package/dist/rules/require-function-doc-ignored-text.d.ts.map +1 -0
  265. package/dist/rules/require-function-doc-ignored-text.js +67 -0
  266. package/dist/rules/require-function-doc-ignored-text.js.map +1 -0
  267. package/dist/rules/require-function-doc-local-exports.d.ts +7 -0
  268. package/dist/rules/require-function-doc-local-exports.d.ts.map +1 -0
  269. package/dist/rules/require-function-doc-local-exports.js +114 -0
  270. package/dist/rules/require-function-doc-local-exports.js.map +1 -0
  271. package/dist/rules/require-function-doc.d.ts +3 -18
  272. package/dist/rules/require-function-doc.d.ts.map +1 -1
  273. package/dist/rules/require-function-doc.js +396 -221
  274. package/dist/rules/require-function-doc.js.map +1 -1
  275. package/dist/rules/source-cache.d.ts +13 -5
  276. package/dist/rules/source-cache.d.ts.map +1 -1
  277. package/dist/rules/source-cache.js +35 -22
  278. package/dist/rules/source-cache.js.map +1 -1
  279. package/package.json +10 -2
@@ -1,18 +1,20 @@
1
- import { stripComments, stripCommentsAndStrings } from './effect-source-helpers.js';
1
+ /* -------------------------------------------------------------------------- */
2
+ /* Core runtime for source-backed and AST-backed Effect lint rules. */
3
+ /* -------------------------------------------------------------------------- */
4
+ import { canonicalizeEffectAPIAliases } from './effect-rule-aliases.js';
5
+ import { effectDiagnosticMessage } from './diagnostic-guidance.js';
2
6
  import { readCachedSource } from './source-cache.js';
7
+ import { stripCommentsAndStrings } from './effect-source-helpers.js';
3
8
  const LINE_START_CACHE_MAX = 256;
4
9
  const TOKEN_GATE_CACHE_MAX = 512;
10
+ const CHAR_CODE_NEWLINE = 10;
5
11
  const lineStartCache = new Map();
6
12
  const globalPatternCache = new WeakMap();
7
13
  const tokenGateCache = new WeakMap();
8
14
  const sourceTokenPresenceCache = new Map();
9
- function readSource(context) {
10
- return readCachedSource(context);
11
- }
12
- function isCodeAt(strippedSource, index) {
13
- return strippedSource[index]?.trim() !== '';
14
- }
15
- function hasPattern(source, patterns) {
15
+ const readSource = (context) => readCachedSource(context);
16
+ const isCodeAt = (strippedSource, index) => strippedSource[index]?.trim() !== '';
17
+ const hasPattern = (source, patterns) => {
16
18
  let strippedSource = undefined;
17
19
  return patterns.some((pattern) => {
18
20
  for (const match of source.matchAll(toGlobalRegExp(pattern))) {
@@ -23,41 +25,50 @@ function hasPattern(source, patterns) {
23
25
  }
24
26
  return false;
25
27
  });
26
- }
27
- function toGlobalRegExp(pattern) {
28
+ };
29
+ const toGlobalRegExp = (pattern) => {
28
30
  const cachedPattern = globalPatternCache.get(pattern);
29
31
  if (cachedPattern !== undefined) {
30
32
  return cachedPattern;
31
33
  }
32
- const globalPattern = new RegExp(pattern.source, pattern.flags.includes('g') ? pattern.flags : `${pattern.flags}g`);
34
+ let { flags } = pattern;
35
+ if (!flags.includes('g')) {
36
+ flags = `${flags}g`;
37
+ }
38
+ const globalPattern = new RegExp(pattern.source, flags);
33
39
  globalPatternCache.set(pattern, globalPattern);
34
40
  return globalPattern;
35
- }
36
- function cachedLineStarts(source) {
37
- return lineStartCache.get(source);
38
- }
39
- function lineStartsFor(source) {
40
- const cachedStarts = cachedLineStarts(source);
41
- if (cachedStarts !== undefined) {
42
- return cachedStarts;
41
+ };
42
+ const cachedLineStarts = (source) => lineStartCache.get(source);
43
+ const evictFirstLineStart = () => {
44
+ if (lineStartCache.size < LINE_START_CACHE_MAX) {
45
+ return;
46
+ }
47
+ const firstKey = lineStartCache.keys().next().value;
48
+ if (firstKey !== undefined) {
49
+ lineStartCache.delete(firstKey);
43
50
  }
51
+ };
52
+ const computeLineStarts = (source) => {
44
53
  const starts = [0];
45
54
  for (let position = 0; position < source.length; position++) {
46
- if (source.charCodeAt(position) === 10) {
55
+ if (source.charCodeAt(position) === CHAR_CODE_NEWLINE) {
47
56
  starts.push(position + 1);
48
57
  }
49
58
  }
50
- if (lineStartCache.size >= LINE_START_CACHE_MAX) {
51
- const firstKey = lineStartCache.keys().next().value;
52
- if (firstKey !== undefined) {
53
- lineStartCache.delete(firstKey);
54
- }
59
+ return starts;
60
+ };
61
+ const lineStartsFor = (source) => {
62
+ const cachedStarts = cachedLineStarts(source);
63
+ if (cachedStarts !== undefined) {
64
+ return cachedStarts;
55
65
  }
66
+ const starts = computeLineStarts(source);
67
+ evictFirstLineStart();
56
68
  lineStartCache.set(source, starts);
57
69
  return starts;
58
- }
59
- function locFromIndex(source, index) {
60
- const starts = lineStartsFor(source);
70
+ };
71
+ const lineIndexFor = (starts, index) => {
61
72
  let low = 0;
62
73
  let high = starts.length - 1;
63
74
  while (low <= high) {
@@ -70,50 +81,57 @@ function locFromIndex(source, index) {
70
81
  high = middle - 1;
71
82
  }
72
83
  }
73
- const lineIndex = Math.max(0, high);
84
+ return Math.max(0, high);
85
+ };
86
+ const locFromIndex = (source, index) => {
87
+ const starts = lineStartsFor(source);
88
+ const lineIndex = lineIndexFor(starts, index);
74
89
  const lineStart = starts[lineIndex] ?? 0;
75
90
  const line = lineIndex + 1;
76
91
  return { column: index - lineStart, line };
77
- }
78
- function firstPatternLoc(source, patterns) {
92
+ };
93
+ const firstPatternLOC = (source, patterns) => {
79
94
  let strippedSource = undefined;
80
95
  for (const pattern of patterns) {
81
96
  for (const match of source.matchAll(toGlobalRegExp(pattern))) {
82
97
  strippedSource ??= stripCommentsAndStrings(source);
83
- if (!isCodeAt(strippedSource, match.index)) {
84
- continue;
98
+ if (isCodeAt(strippedSource, match.index)) {
99
+ return locFromIndex(source, match.index);
85
100
  }
86
- return locFromIndex(source, match.index);
87
101
  }
88
102
  }
89
103
  return undefined;
90
- }
91
- function reportPatternMatches(input) {
104
+ };
105
+ const reportPatternMatches = (input) => {
92
106
  const { context, node, source, spec } = input;
107
+ const message = effectDiagnosticMessage(spec.name, spec.message);
93
108
  if (!spec.countPatterns) {
94
109
  context.report({
95
- loc: firstPatternLoc(source, spec.patterns ?? []),
96
- message: spec.message,
110
+ loc: firstPatternLOC(source, spec.patterns ?? []),
111
+ message,
97
112
  node,
98
113
  });
99
114
  return;
100
115
  }
116
+ reportCountedPatternMatches(input, message);
117
+ };
118
+ const reportCountedPatternMatches = (input, message) => {
119
+ const { context, node, source, spec } = input;
101
120
  let strippedSource = undefined;
102
- for (const pattern of spec.countPatterns) {
121
+ for (const pattern of spec.countPatterns ?? []) {
103
122
  for (const match of source.matchAll(toGlobalRegExp(pattern))) {
104
123
  strippedSource ??= stripCommentsAndStrings(source);
105
- if (!isCodeAt(strippedSource, match.index)) {
106
- continue;
124
+ if (isCodeAt(strippedSource, match.index)) {
125
+ context.report({
126
+ loc: locFromIndex(source, match.index),
127
+ message,
128
+ node,
129
+ });
107
130
  }
108
- context.report({
109
- loc: locFromIndex(source, match.index),
110
- message: spec.message,
111
- node,
112
- });
113
131
  }
114
132
  }
115
- }
116
- function checkResultIndex(result) {
133
+ };
134
+ const checkResultIndex = (result) => {
117
135
  if (typeof result === 'number') {
118
136
  return result;
119
137
  }
@@ -121,11 +139,14 @@ function checkResultIndex(result) {
121
139
  return result.index;
122
140
  }
123
141
  return undefined;
124
- }
125
- function isCheckViolation(result) {
126
- return typeof result === 'boolean' ? result : true;
127
- }
128
- function cachedSourceTokenPresence(source) {
142
+ };
143
+ const isCheckViolation = (result) => {
144
+ if (typeof result === 'boolean') {
145
+ return result;
146
+ }
147
+ return true;
148
+ };
149
+ const cachedSourceTokenPresence = (source) => {
129
150
  let tokenPresence = sourceTokenPresenceCache.get(source);
130
151
  if (tokenPresence !== undefined) {
131
152
  return tokenPresence;
@@ -139,8 +160,8 @@ function cachedSourceTokenPresence(source) {
139
160
  tokenPresence = new Map();
140
161
  sourceTokenPresenceCache.set(source, tokenPresence);
141
162
  return tokenPresence;
142
- }
143
- function hasTokenInSourceCached(source, token) {
163
+ };
164
+ const hasTokenInSourceCached = (source, token) => {
144
165
  const tokenPresence = cachedSourceTokenPresence(source);
145
166
  const cachedValue = tokenPresence.get(token);
146
167
  if (cachedValue !== undefined) {
@@ -149,14 +170,10 @@ function hasTokenInSourceCached(source, token) {
149
170
  const hasToken = source.includes(token);
150
171
  tokenPresence.set(token, hasToken);
151
172
  return hasToken;
152
- }
153
- function hasAnyToken(source, tokens) {
154
- return tokens.some((token) => hasTokenInSourceCached(source, token));
155
- }
156
- function cachedTokenGate(source, tokens) {
157
- return tokenGateCache.get(tokens)?.get(source);
158
- }
159
- function cacheTokenGate(source, tokens, hasToken) {
173
+ };
174
+ const hasAnyToken = (source, tokens) => tokens.some((token) => hasTokenInSourceCached(source, token));
175
+ const cachedTokenGate = (source, tokens) => tokenGateCache.get(tokens)?.get(source);
176
+ const cacheTokenGate = (source, tokens, hasToken) => {
160
177
  let sourceCache = tokenGateCache.get(tokens);
161
178
  if (!sourceCache) {
162
179
  sourceCache = new Map();
@@ -170,77 +187,96 @@ function cacheTokenGate(source, tokens, hasToken) {
170
187
  }
171
188
  sourceCache.set(source, hasToken);
172
189
  return hasToken;
173
- }
174
- function hasAnyTokenCached(source, tokens) {
190
+ };
191
+ const hasAnyTokenCached = (source, tokens) => {
175
192
  const cachedValue = cachedTokenGate(source, tokens);
176
193
  if (cachedValue !== undefined) {
177
194
  return cachedValue;
178
195
  }
179
196
  return cacheTokenGate(source, tokens, hasAnyToken(source, tokens));
180
- }
181
- function hasEveryTokenGroup(source, tokenGroups) {
182
- return tokenGroups.every((group) => hasAnyTokenCached(source, group));
183
- }
184
- function shouldSkipSource(source, requiredTokens, requiredTokenGroups) {
185
- return (source === '' ||
186
- Boolean(requiredTokens && !hasAnyTokenCached(source, requiredTokens)) ||
187
- Boolean(requiredTokenGroups && !hasEveryTokenGroup(source, requiredTokenGroups)));
188
- }
189
- function runProgramRule(input) {
197
+ };
198
+ const hasEveryTokenGroup = (source, tokenGroups) => tokenGroups.every((group) => hasAnyTokenCached(source, group));
199
+ const shouldSkipSource = (source, requiredTokens, requiredTokenGroups) => source === '' ||
200
+ Boolean(requiredTokens && !hasAnyTokenCached(source, requiredTokens)) ||
201
+ Boolean(requiredTokenGroups && !hasEveryTokenGroup(source, requiredTokenGroups));
202
+ const checkResultLOC = (source, spec, checkResult) => {
203
+ const index = checkResultIndex(checkResult);
204
+ if (index !== undefined) {
205
+ return locFromIndex(source, index);
206
+ }
207
+ return firstPatternLOC(source, spec.patterns ?? []);
208
+ };
209
+ const reportCheckResult = (context, node, source, spec, checkResult) => {
210
+ context.report({
211
+ loc: checkResultLOC(source, spec, checkResult),
212
+ message: effectDiagnosticMessage(spec.name, spec.message),
213
+ node,
214
+ });
215
+ };
216
+ const guidedContext = (context, spec) => ({
217
+ get filename() {
218
+ return context.filename;
219
+ },
220
+ get options() {
221
+ return context.options;
222
+ },
223
+ report(descriptor) {
224
+ context.report({
225
+ ...descriptor,
226
+ message: effectDiagnosticMessage(spec.name, descriptor.message),
227
+ });
228
+ },
229
+ get sourceCode() {
230
+ return context.sourceCode;
231
+ },
232
+ });
233
+ const runProgramRule = (input) => {
190
234
  const { context, node, source, spec } = input;
191
- const canonicalSource = canonicalizeEffectApiAliases(source);
235
+ const canonicalSource = canonicalizeEffectAPIAliases(source);
192
236
  const checkResult = spec.check?.(canonicalSource, context);
193
237
  if (checkResult !== undefined) {
194
238
  if (!isCheckViolation(checkResult)) {
195
239
  return;
196
240
  }
197
- const index = checkResultIndex(checkResult);
198
- context.report({
199
- loc: index === undefined
200
- ? firstPatternLoc(canonicalSource, spec.patterns ?? [])
201
- : locFromIndex(canonicalSource, index),
202
- message: spec.message,
203
- node,
204
- });
241
+ reportCheckResult(context, node, canonicalSource, spec, checkResult);
205
242
  return;
206
243
  }
207
244
  if (hasPattern(canonicalSource, spec.patterns ?? [])) {
208
245
  reportPatternMatches({ context, node, source: canonicalSource, spec });
209
246
  }
210
- }
211
- function makeProgramOnlyRule(spec, options) {
247
+ };
248
+ const makeProgramOnlyRule = (spec, options) => {
212
249
  const requiredTokens = spec.tokens ?? options.defaultTokens;
213
250
  const requiredTokenGroups = spec.tokenGroups;
214
- const rule = makeAstCapableRule(spec, options);
251
+ const rule = makeASTCapableRule(spec, options);
215
252
  return {
216
253
  ...rule,
217
254
  createOnce(context) {
218
255
  let source = '';
219
256
  let isSkipped = true;
220
257
  return {
221
- before() {
222
- source = readSource(context);
223
- isSkipped = shouldSkipSource(source, requiredTokens, requiredTokenGroups);
224
- return isSkipped ? false : undefined;
225
- },
226
258
  Program(node) {
227
259
  if (isSkipped) {
228
260
  return;
229
261
  }
230
262
  runProgramRule({ context, node, source, spec });
231
263
  },
264
+ before() {
265
+ source = readSource(context);
266
+ isSkipped = shouldSkipSource(source, requiredTokens, requiredTokenGroups);
267
+ if (isSkipped) {
268
+ return false;
269
+ }
270
+ return undefined;
271
+ },
232
272
  };
233
273
  },
234
274
  };
235
- }
236
- function makeAstCapableRule(spec, options) {
275
+ };
276
+ const makeASTCapableRule = (spec, options) => {
237
277
  const requiredTokens = spec.tokens ?? options.defaultTokens;
238
278
  const requiredTokenGroups = spec.tokenGroups;
239
279
  const rule = {
240
- meta: {
241
- schema: options.schema,
242
- type: 'problem',
243
- },
244
280
  create(context) {
245
281
  const source = readSource(context);
246
282
  if (shouldSkipSource(source, requiredTokens, requiredTokenGroups)) {
@@ -248,7 +284,8 @@ function makeAstCapableRule(spec, options) {
248
284
  Program() { },
249
285
  };
250
286
  }
251
- const astVisitors = spec.ast?.(context, source) ?? {};
287
+ const astContext = guidedContext(context, spec);
288
+ const astVisitors = spec.ast?.(astContext, source) ?? {};
252
289
  return {
253
290
  ...astVisitors,
254
291
  Program(node) {
@@ -259,251 +296,27 @@ function makeAstCapableRule(spec, options) {
259
296
  },
260
297
  };
261
298
  },
299
+ meta: {
300
+ docs: {
301
+ description: effectDiagnosticMessage(spec.name, spec.message),
302
+ },
303
+ schema: options.schema,
304
+ type: 'problem',
305
+ },
262
306
  };
263
307
  return rule;
264
- }
265
- function makeProgramRule(spec, options) {
266
- return spec.ast ? makeAstCapableRule(spec, options) : makeProgramOnlyRule(spec, options);
267
- }
268
- function makeRules(specs, options = {}) {
269
- return Object.fromEntries(specs.map((spec) => [spec.name, makeProgramRule(spec, options)]));
270
- }
271
- function hasEffectSignal(source) {
272
- const cachedValue = cachedBoolean(effectSignalCache, source);
273
- if (cachedValue !== undefined) {
274
- return cachedValue;
275
- }
276
- if (!source.includes('Effect') && !source.includes('effect')) {
277
- return cacheBoolean(effectSignalCache, source, false);
278
- }
279
- const codeOnly = stripCommentsAndStrings(source);
280
- return cacheBoolean(effectSignalCache, source, hasEffectValueImport(source) ||
281
- effectImportAliases(source).some((alias) => new RegExp(`\\b${escapeRegExp(alias)}\\.`, 'u').test(codeOnly)));
282
- }
283
- const runtimeCallPattern = /\b(?:Effect\.(?:runPromise|runPromiseExit|runSync|runSyncExit|runFork)|[A-Za-z_$][\w$]*Runtime\.runMain)\s*\(/;
284
- const boundaryFilePattern = /(?:^|\/)src\/(?:main|server|cli)\.ts$|\.entry\.ts$/;
285
- const testFilePattern = /\.(?:test|spec)\.tsx?$/;
286
- const ALIAS_CACHE_MAX = 256;
287
- const BOOLEAN_CACHE_MAX = 512;
288
- const effectAliasCache = new Map();
289
- const runtimeFunctionAliasCache = new Map();
290
- const canonicalSourceCache = new Map();
291
- const effectSignalCache = new Map();
292
- const runtimeCallCache = new Map();
293
- function cachedAliases(cache, source) {
294
- return cache.get(source);
295
- }
296
- function cacheAliases(cache, source, value) {
297
- if (cache.size >= ALIAS_CACHE_MAX) {
298
- const firstKey = cache.keys().next().value;
299
- if (firstKey !== undefined) {
300
- cache.delete(firstKey);
301
- }
302
- }
303
- cache.set(source, value);
304
- return value;
305
- }
306
- function cachedBoolean(cache, source) {
307
- return cache.get(source);
308
- }
309
- function cacheBoolean(cache, source, value) {
310
- if (cache.size >= BOOLEAN_CACHE_MAX) {
311
- const firstKey = cache.keys().next().value;
312
- if (firstKey !== undefined) {
313
- cache.delete(firstKey);
314
- }
315
- }
316
- cache.set(source, value);
317
- return value;
318
- }
319
- function escapeRegExp(value) {
320
- return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
321
- }
322
- function hasLocalEffectBinding(source) {
323
- return /\b(?:const|let|var|function|class|namespace)\s+Effect\b/.test(stripCommentsAndStrings(source));
324
- }
325
- function importSpecifierNames(specifier) {
326
- const trimmed = specifier.trim();
327
- if (trimmed.startsWith('type ')) {
328
- return undefined;
329
- }
330
- const parts = trimmed.split(/\s+as\s+/);
331
- const importedName = parts[0]?.trim();
332
- const localName = parts[1]?.trim() ?? importedName;
333
- return importedName && localName ? { importedName, localName } : undefined;
334
- }
335
- function hasAnyEffectImport(source) {
336
- return /(?:^|\n)\s*import(?:\s+type)?(?:[\s\S]*?\s+from\s*)?['"](?:effect(?:\/[^'"]+)?|@effect\/[^'"]+)['"]/.test(stripComments(source));
337
- }
338
- function hasEffectValueImport(source) {
339
- const commentFreeSource = stripComments(source);
340
- for (const match of commentFreeSource.matchAll(/(?:^|\n)\s*import\s+(?!type\b)\s*{([^}]+)}\s*from\s*['"]effect['"]/g)) {
341
- if (match[1]
342
- .split(',')
343
- .some((specifier) => importSpecifierNames(specifier)?.importedName === 'Effect')) {
344
- return true;
345
- }
346
- }
347
- return (/(?:^|\n)\s*import\s+(?!type\b)\*\s+as\s+[A-Za-z_$][\w$]*\s+from\s*['"]effect(?:\/Effect)?['"]/.test(commentFreeSource) || effectFunctionAliases(source, 'Effect').length > 0);
348
- }
349
- function effectImportAliases(source) {
350
- const cachedValue = cachedAliases(effectAliasCache, source);
351
- if (cachedValue) {
352
- return cachedValue;
353
- }
354
- const aliases = new Set();
355
- const commentFreeSource = stripComments(source);
356
- for (const match of commentFreeSource.matchAll(/(?:^|\n)\s*import\s+(?!type\b)\s*{([^}]+)}\s*from\s*['"]effect['"]/g)) {
357
- for (const specifier of match[1].split(',')) {
358
- const names = importSpecifierNames(specifier);
359
- if (!names) {
360
- continue;
361
- }
362
- if (names.importedName === 'Effect') {
363
- aliases.add('Effect');
364
- aliases.add(names.localName);
365
- }
366
- }
367
- }
368
- for (const match of commentFreeSource.matchAll(/(?:^|\n)\s*import\s+(?!type\b)\*\s+as\s+([A-Za-z_$][\w$]*)\s+from\s*['"]effect(?:\/Effect)?['"]/g)) {
369
- aliases.add('Effect');
370
- aliases.add(match[1]);
371
- }
372
- if (aliases.size === 0 && !hasAnyEffectImport(source) && !hasLocalEffectBinding(source)) {
373
- aliases.add('Effect');
374
- }
375
- return cacheAliases(effectAliasCache, source, [...aliases]);
376
- }
377
- function effectApiAliases(source, apiName) {
378
- const aliases = new Set();
379
- const commentFreeSource = stripComments(source);
380
- for (const match of commentFreeSource.matchAll(/(?:^|\n)\s*import\s+(?!type\b)\s*{([^}]+)}\s*from\s*['"]effect['"]/g)) {
381
- for (const specifier of match[1].split(',')) {
382
- const names = importSpecifierNames(specifier);
383
- if (names?.importedName === apiName) {
384
- aliases.add(names.localName);
385
- }
386
- }
387
- }
388
- for (const match of commentFreeSource.matchAll(new RegExp(`(?:^|\\n)\\s*import\\s+(?!type\\b)\\*\\s+as\\s+([A-Za-z_$][\\w$]*)\\s+from\\s*['"]effect/${escapeRegExp(apiName)}['"]`, 'g'))) {
389
- aliases.add(match[1]);
390
- }
391
- if (aliases.size === 0 && !hasAnyEffectImport(source)) {
392
- aliases.add(apiName);
393
- }
394
- return [...aliases];
395
- }
396
- function effectFunctionAliases(source, moduleName, functionName) {
397
- const aliases = new Set();
398
- const commentFreeSource = stripComments(source);
399
- for (const match of commentFreeSource.matchAll(new RegExp(`(?:^|\\n)\\s*import\\s+(?!type\\b)\\s*{([^}]+)}\\s*from\\s*['"]effect/${escapeRegExp(moduleName)}['"]`, 'g'))) {
400
- for (const specifier of match[1].split(',')) {
401
- const names = importSpecifierNames(specifier);
402
- if (names && (!functionName || names.importedName === functionName)) {
403
- aliases.add(names.localName);
404
- }
405
- }
406
- }
407
- return [...aliases];
408
- }
409
- function canonicalImportAliases(source) {
410
- const aliases = new Map();
411
- const commentFreeSource = stripComments(source);
412
- const canonicalNames = new Set([
413
- 'Config',
414
- 'Context',
415
- 'Effect',
416
- 'Fiber',
417
- 'Layer',
418
- 'Queue',
419
- 'Schedule',
420
- 'Schema',
421
- 'Scope',
422
- 'Stream',
423
- 'TestClock',
424
- ]);
425
- for (const match of commentFreeSource.matchAll(/(?:^|\n)\s*import\s+(?!type\b)\s*{([^}]+)}\s*from\s*['"]effect['"]/g)) {
426
- for (const specifier of match[1].split(',')) {
427
- const names = importSpecifierNames(specifier);
428
- const importedName = names?.importedName;
429
- const localName = names?.localName;
430
- if (importedName &&
431
- localName &&
432
- canonicalNames.has(importedName) &&
433
- localName !== importedName) {
434
- aliases.set(localName, importedName);
435
- }
436
- }
437
- }
438
- for (const match of commentFreeSource.matchAll(/(?:^|\n)\s*import\s+(?!type\b)\*\s+as\s+([A-Za-z_$][\w$]*)\s+from\s*['"]effect\/([A-Za-z]+)['"]/g)) {
439
- const [, localName, moduleName] = match;
440
- if (canonicalNames.has(moduleName) && localName !== moduleName) {
441
- aliases.set(localName, moduleName);
442
- }
443
- }
444
- return aliases;
445
- }
446
- function canonicalizeEffectApiAliases(source) {
447
- const cachedValue = canonicalSourceCache.get(source);
448
- if (cachedValue !== undefined) {
449
- return cachedValue;
450
- }
451
- let canonicalSource = source;
452
- for (const [localName, canonicalName] of canonicalImportAliases(source)) {
453
- canonicalSource = canonicalSource.replace(new RegExp(`\\b${escapeRegExp(localName)}\\.`, 'g'), `${canonicalName}.`);
454
- }
455
- if (canonicalSourceCache.size >= ALIAS_CACHE_MAX) {
456
- const firstKey = canonicalSourceCache.keys().next().value;
457
- if (firstKey !== undefined) {
458
- canonicalSourceCache.delete(firstKey);
459
- }
460
- }
461
- canonicalSourceCache.set(source, canonicalSource);
462
- return canonicalSource;
463
- }
464
- function effectRuntimeFunctionAliases(source) {
465
- const cachedValue = cachedAliases(runtimeFunctionAliasCache, source);
466
- if (cachedValue) {
467
- return cachedValue;
468
- }
469
- const aliases = new Set();
470
- const runtimeNames = new Set([
471
- 'runFork',
472
- 'runPromise',
473
- 'runPromiseExit',
474
- 'runSync',
475
- 'runSyncExit',
476
- ]);
477
- const commentFreeSource = stripComments(source);
478
- for (const match of commentFreeSource.matchAll(/(?:^|\n)\s*import\s*{([^}]+)}\s*from\s*['"]effect\/Effect['"]/g)) {
479
- for (const specifier of match[1].split(',')) {
480
- const names = importSpecifierNames(specifier);
481
- const importedName = names?.importedName;
482
- const localName = names?.localName;
483
- if (importedName && localName && runtimeNames.has(importedName)) {
484
- aliases.add(localName);
485
- }
486
- }
487
- }
488
- return cacheAliases(runtimeFunctionAliasCache, source, [...aliases]);
489
- }
490
- function hasRuntimeCall(source) {
491
- const cachedValue = cachedBoolean(runtimeCallCache, source);
492
- if (cachedValue !== undefined) {
493
- return cachedValue;
494
- }
495
- const code = stripCommentsAndStrings(source);
496
- if (runtimeCallPattern.test(code)) {
497
- return cacheBoolean(runtimeCallCache, source, true);
498
- }
499
- return cacheBoolean(runtimeCallCache, source, effectImportAliases(source).some((alias) => new RegExp(`\\b${alias}\\.(?:runPromise|runPromiseExit|runSync|runSyncExit|runFork)\\s*\\(`).test(code)) ||
500
- effectRuntimeFunctionAliases(source).some((alias) => new RegExp(`\\b${alias}\\s*\\(`).test(code)));
501
- }
502
- function isBoundaryFile(filename) {
503
- return Boolean(filename && boundaryFilePattern.test(filename));
504
- }
505
- function isTestFile(filename) {
506
- return Boolean(filename && testFilePattern.test(filename));
507
- }
508
- export { hasEffectSignal, effectApiAliases, effectFunctionAliases, effectImportAliases, hasRuntimeCall, isBoundaryFile, isTestFile, makeRules, runtimeCallPattern, };
308
+ };
309
+ const makeProgramRule = (spec, options) => {
310
+ if (spec.ast) {
311
+ return makeASTCapableRule(spec, options);
312
+ }
313
+ return makeProgramOnlyRule(spec, options);
314
+ };
315
+ /**
316
+ * Internal helper exported for package-local composition.
317
+ *
318
+ * @internal
319
+ */
320
+ export const makeRules = (specs, options = {}) => Object.fromEntries(specs.map((spec) => [spec.name, makeProgramRule(spec, options)]));
321
+ export { effectAPIAliases, effectFunctionAliases, effectImportAliases, hasEffectSignal, hasRuntimeCall, isBoundaryFile, isTestFile, runtimeCallPattern, } from './effect-rule-aliases.js';
509
322
  //# sourceMappingURL=effect-rule-core.js.map