bahlint 28.58.6934

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 (420) hide show
  1. package/LICENSE +19 -0
  2. package/README.md +370 -0
  3. package/bin/eslint.js +195 -0
  4. package/conf/ecma-version.js +16 -0
  5. package/conf/globals.js +169 -0
  6. package/conf/replacements.json +26 -0
  7. package/conf/rule-type-list.json +91 -0
  8. package/lib/api.js +39 -0
  9. package/lib/cli-engine/formatters/formatters-meta.json +22 -0
  10. package/lib/cli-engine/formatters/gasoline.js +168 -0
  11. package/lib/cli-engine/formatters/html.js +359 -0
  12. package/lib/cli-engine/formatters/json-with-metadata.js +16 -0
  13. package/lib/cli-engine/formatters/json.js +13 -0
  14. package/lib/cli-engine/formatters/stylish.js +153 -0
  15. package/lib/cli-engine/hash.js +35 -0
  16. package/lib/cli-engine/lint-result-cache.js +220 -0
  17. package/lib/cli.js +607 -0
  18. package/lib/config/config-loader.js +683 -0
  19. package/lib/config/config.js +674 -0
  20. package/lib/config/default-config.js +78 -0
  21. package/lib/config/flat-config-array.js +217 -0
  22. package/lib/config/flat-config-schema.js +598 -0
  23. package/lib/config-api.js +12 -0
  24. package/lib/eslint/eslint-helpers.js +1462 -0
  25. package/lib/eslint/eslint.js +1364 -0
  26. package/lib/eslint/index.js +7 -0
  27. package/lib/eslint/worker.js +173 -0
  28. package/lib/languages/js/index.js +336 -0
  29. package/lib/languages/js/source-code/index.js +7 -0
  30. package/lib/languages/js/source-code/source-code.js +1178 -0
  31. package/lib/languages/js/source-code/token-store/backward-token-comment-cursor.js +61 -0
  32. package/lib/languages/js/source-code/token-store/backward-token-cursor.js +57 -0
  33. package/lib/languages/js/source-code/token-store/cursor.js +76 -0
  34. package/lib/languages/js/source-code/token-store/cursors.js +120 -0
  35. package/lib/languages/js/source-code/token-store/decorative-cursor.js +38 -0
  36. package/lib/languages/js/source-code/token-store/filter-cursor.js +42 -0
  37. package/lib/languages/js/source-code/token-store/forward-token-comment-cursor.js +65 -0
  38. package/lib/languages/js/source-code/token-store/forward-token-cursor.js +62 -0
  39. package/lib/languages/js/source-code/token-store/index.js +695 -0
  40. package/lib/languages/js/source-code/token-store/limit-cursor.js +39 -0
  41. package/lib/languages/js/source-code/token-store/padded-token-cursor.js +45 -0
  42. package/lib/languages/js/source-code/token-store/skip-cursor.js +41 -0
  43. package/lib/languages/js/source-code/token-store/utils.js +131 -0
  44. package/lib/languages/js/validate-language-options.js +196 -0
  45. package/lib/linter/apply-disable-directives.js +583 -0
  46. package/lib/linter/code-path-analysis/code-path-analyzer.js +828 -0
  47. package/lib/linter/code-path-analysis/code-path-segment.js +262 -0
  48. package/lib/linter/code-path-analysis/code-path-state.js +2370 -0
  49. package/lib/linter/code-path-analysis/code-path.js +332 -0
  50. package/lib/linter/code-path-analysis/debug-helpers.js +223 -0
  51. package/lib/linter/code-path-analysis/fork-context.js +374 -0
  52. package/lib/linter/code-path-analysis/id-generator.js +44 -0
  53. package/lib/linter/esquery.js +332 -0
  54. package/lib/linter/file-context.js +88 -0
  55. package/lib/linter/file-report.js +604 -0
  56. package/lib/linter/index.js +11 -0
  57. package/lib/linter/interpolate.js +50 -0
  58. package/lib/linter/linter.js +1614 -0
  59. package/lib/linter/rule-fixer.js +199 -0
  60. package/lib/linter/source-code-fixer.js +154 -0
  61. package/lib/linter/source-code-traverser.js +333 -0
  62. package/lib/linter/source-code-visitor.js +81 -0
  63. package/lib/linter/timing.js +209 -0
  64. package/lib/linter/vfile.js +115 -0
  65. package/lib/options.js +416 -0
  66. package/lib/rule-tester/index.js +7 -0
  67. package/lib/rule-tester/rule-tester.js +1817 -0
  68. package/lib/rules/accessor-pairs.js +420 -0
  69. package/lib/rules/array-bracket-newline.js +291 -0
  70. package/lib/rules/array-bracket-spacing.js +301 -0
  71. package/lib/rules/array-callback-return.js +493 -0
  72. package/lib/rules/array-element-newline.js +374 -0
  73. package/lib/rules/arrow-body-style.js +418 -0
  74. package/lib/rules/arrow-parens.js +237 -0
  75. package/lib/rules/arrow-spacing.js +188 -0
  76. package/lib/rules/block-scoped-var.js +137 -0
  77. package/lib/rules/block-spacing.js +202 -0
  78. package/lib/rules/brace-style.js +278 -0
  79. package/lib/rules/callback-return.js +216 -0
  80. package/lib/rules/camelcase.js +422 -0
  81. package/lib/rules/capitalized-comments.js +325 -0
  82. package/lib/rules/class-methods-use-this.js +250 -0
  83. package/lib/rules/comma-dangle.js +424 -0
  84. package/lib/rules/comma-spacing.js +205 -0
  85. package/lib/rules/comma-style.js +391 -0
  86. package/lib/rules/complexity.js +201 -0
  87. package/lib/rules/computed-property-spacing.js +251 -0
  88. package/lib/rules/consistent-return.js +221 -0
  89. package/lib/rules/consistent-this.js +179 -0
  90. package/lib/rules/constructor-super.js +453 -0
  91. package/lib/rules/curly.js +425 -0
  92. package/lib/rules/default-case-last.js +51 -0
  93. package/lib/rules/default-case.js +103 -0
  94. package/lib/rules/default-param-last.js +78 -0
  95. package/lib/rules/dot-location.js +138 -0
  96. package/lib/rules/dot-notation.js +216 -0
  97. package/lib/rules/eol-last.js +135 -0
  98. package/lib/rules/eqeqeq.js +210 -0
  99. package/lib/rules/for-direction.js +168 -0
  100. package/lib/rules/func-call-spacing.js +281 -0
  101. package/lib/rules/func-name-matching.js +338 -0
  102. package/lib/rules/func-names.js +194 -0
  103. package/lib/rules/func-style.js +221 -0
  104. package/lib/rules/function-call-argument-newline.js +166 -0
  105. package/lib/rules/function-paren-newline.js +368 -0
  106. package/lib/rules/generator-star-spacing.js +246 -0
  107. package/lib/rules/getter-return.js +242 -0
  108. package/lib/rules/global-require.js +117 -0
  109. package/lib/rules/grouped-accessor-pairs.js +268 -0
  110. package/lib/rules/guard-for-in.js +85 -0
  111. package/lib/rules/handle-callback-err.js +122 -0
  112. package/lib/rules/id-blacklist.js +241 -0
  113. package/lib/rules/id-denylist.js +223 -0
  114. package/lib/rules/id-length.js +217 -0
  115. package/lib/rules/id-match.js +363 -0
  116. package/lib/rules/implicit-arrow-linebreak.js +125 -0
  117. package/lib/rules/indent-legacy.js +1369 -0
  118. package/lib/rules/indent.js +2334 -0
  119. package/lib/rules/index.js +332 -0
  120. package/lib/rules/init-declarations.js +172 -0
  121. package/lib/rules/jsx-quotes.js +128 -0
  122. package/lib/rules/key-spacing.js +822 -0
  123. package/lib/rules/keyword-spacing.js +701 -0
  124. package/lib/rules/line-comment-position.js +157 -0
  125. package/lib/rules/linebreak-style.js +135 -0
  126. package/lib/rules/lines-around-comment.js +581 -0
  127. package/lib/rules/lines-around-directive.js +249 -0
  128. package/lib/rules/lines-between-class-members.js +358 -0
  129. package/lib/rules/logical-assignment-operators.js +688 -0
  130. package/lib/rules/max-classes-per-file.js +90 -0
  131. package/lib/rules/max-depth.js +159 -0
  132. package/lib/rules/max-len.js +497 -0
  133. package/lib/rules/max-lines-per-function.js +238 -0
  134. package/lib/rules/max-lines.js +189 -0
  135. package/lib/rules/max-nested-callbacks.js +115 -0
  136. package/lib/rules/max-params.js +148 -0
  137. package/lib/rules/max-statements-per-line.js +224 -0
  138. package/lib/rules/max-statements.js +188 -0
  139. package/lib/rules/multiline-comment-style.js +652 -0
  140. package/lib/rules/multiline-ternary.js +257 -0
  141. package/lib/rules/new-cap.js +277 -0
  142. package/lib/rules/new-parens.js +120 -0
  143. package/lib/rules/newline-after-var.js +307 -0
  144. package/lib/rules/newline-before-return.js +242 -0
  145. package/lib/rules/newline-per-chained-call.js +159 -0
  146. package/lib/rules/no-alert.js +149 -0
  147. package/lib/rules/no-array-constructor.js +195 -0
  148. package/lib/rules/no-async-promise-executor.js +45 -0
  149. package/lib/rules/no-await-in-loop.js +115 -0
  150. package/lib/rules/no-bitwise.js +145 -0
  151. package/lib/rules/no-buffer-constructor.js +74 -0
  152. package/lib/rules/no-caller.js +52 -0
  153. package/lib/rules/no-case-declarations.js +80 -0
  154. package/lib/rules/no-catch-shadow.js +96 -0
  155. package/lib/rules/no-class-assign.js +66 -0
  156. package/lib/rules/no-compare-neg-zero.js +74 -0
  157. package/lib/rules/no-cond-assign.js +175 -0
  158. package/lib/rules/no-confusing-arrow.js +127 -0
  159. package/lib/rules/no-console.js +221 -0
  160. package/lib/rules/no-const-assign.js +73 -0
  161. package/lib/rules/no-constant-binary-expression.js +603 -0
  162. package/lib/rules/no-constant-condition.js +177 -0
  163. package/lib/rules/no-constructor-return.js +62 -0
  164. package/lib/rules/no-continue.js +38 -0
  165. package/lib/rules/no-control-regex.js +142 -0
  166. package/lib/rules/no-debugger.js +41 -0
  167. package/lib/rules/no-delete-var.js +42 -0
  168. package/lib/rules/no-div-regex.js +60 -0
  169. package/lib/rules/no-dupe-args.js +92 -0
  170. package/lib/rules/no-dupe-class-members.js +117 -0
  171. package/lib/rules/no-dupe-else-if.js +145 -0
  172. package/lib/rules/no-dupe-keys.js +165 -0
  173. package/lib/rules/no-duplicate-case.js +78 -0
  174. package/lib/rules/no-duplicate-imports.js +368 -0
  175. package/lib/rules/no-else-return.js +450 -0
  176. package/lib/rules/no-empty-character-class.js +83 -0
  177. package/lib/rules/no-empty-function.js +236 -0
  178. package/lib/rules/no-empty-pattern.js +85 -0
  179. package/lib/rules/no-empty-static-block.js +73 -0
  180. package/lib/rules/no-empty.js +153 -0
  181. package/lib/rules/no-eq-null.js +51 -0
  182. package/lib/rules/no-eval.js +295 -0
  183. package/lib/rules/no-ex-assign.js +57 -0
  184. package/lib/rules/no-extend-native.js +180 -0
  185. package/lib/rules/no-extra-bind.js +224 -0
  186. package/lib/rules/no-extra-boolean-cast.js +420 -0
  187. package/lib/rules/no-extra-label.js +169 -0
  188. package/lib/rules/no-extra-parens.js +1669 -0
  189. package/lib/rules/no-extra-semi.js +167 -0
  190. package/lib/rules/no-fallthrough.js +260 -0
  191. package/lib/rules/no-floating-decimal.js +99 -0
  192. package/lib/rules/no-func-assign.js +77 -0
  193. package/lib/rules/no-global-assign.js +101 -0
  194. package/lib/rules/no-implicit-coercion.js +468 -0
  195. package/lib/rules/no-implicit-globals.js +187 -0
  196. package/lib/rules/no-implied-eval.js +170 -0
  197. package/lib/rules/no-import-assign.js +227 -0
  198. package/lib/rules/no-inline-comments.js +115 -0
  199. package/lib/rules/no-inner-declarations.js +147 -0
  200. package/lib/rules/no-invalid-regexp.js +244 -0
  201. package/lib/rules/no-invalid-this.js +178 -0
  202. package/lib/rules/no-irregular-whitespace.js +292 -0
  203. package/lib/rules/no-iterator.js +48 -0
  204. package/lib/rules/no-label-var.js +78 -0
  205. package/lib/rules/no-labels.js +156 -0
  206. package/lib/rules/no-lone-blocks.js +140 -0
  207. package/lib/rules/no-lonely-if.js +126 -0
  208. package/lib/rules/no-loop-func.js +267 -0
  209. package/lib/rules/no-loss-of-precision.js +249 -0
  210. package/lib/rules/no-magic-numbers.js +365 -0
  211. package/lib/rules/no-misleading-character-class.js +595 -0
  212. package/lib/rules/no-mixed-operators.js +253 -0
  213. package/lib/rules/no-mixed-requires.js +267 -0
  214. package/lib/rules/no-mixed-spaces-and-tabs.js +148 -0
  215. package/lib/rules/no-multi-assign.js +66 -0
  216. package/lib/rules/no-multi-spaces.js +179 -0
  217. package/lib/rules/no-multi-str.js +67 -0
  218. package/lib/rules/no-multiple-empty-lines.js +210 -0
  219. package/lib/rules/no-native-reassign.js +114 -0
  220. package/lib/rules/no-negated-condition.js +100 -0
  221. package/lib/rules/no-negated-in-lhs.js +59 -0
  222. package/lib/rules/no-nested-ternary.js +46 -0
  223. package/lib/rules/no-new-func.js +96 -0
  224. package/lib/rules/no-new-native-nonconstructor.js +70 -0
  225. package/lib/rules/no-new-object.js +76 -0
  226. package/lib/rules/no-new-require.js +67 -0
  227. package/lib/rules/no-new-symbol.js +74 -0
  228. package/lib/rules/no-new-wrappers.js +62 -0
  229. package/lib/rules/no-new.js +42 -0
  230. package/lib/rules/no-nonoctal-decimal-escape.js +176 -0
  231. package/lib/rules/no-obj-calls.js +99 -0
  232. package/lib/rules/no-object-constructor.js +124 -0
  233. package/lib/rules/no-octal-escape.js +53 -0
  234. package/lib/rules/no-octal.js +42 -0
  235. package/lib/rules/no-param-reassign.js +248 -0
  236. package/lib/rules/no-path-concat.js +79 -0
  237. package/lib/rules/no-plusplus.js +102 -0
  238. package/lib/rules/no-process-env.js +68 -0
  239. package/lib/rules/no-process-exit.js +67 -0
  240. package/lib/rules/no-promise-executor-return.js +264 -0
  241. package/lib/rules/no-proto.js +45 -0
  242. package/lib/rules/no-prototype-builtins.js +181 -0
  243. package/lib/rules/no-redeclare.js +173 -0
  244. package/lib/rules/no-regex-spaces.js +219 -0
  245. package/lib/rules/no-restricted-exports.js +227 -0
  246. package/lib/rules/no-restricted-globals.js +266 -0
  247. package/lib/rules/no-restricted-imports.js +892 -0
  248. package/lib/rules/no-restricted-modules.js +249 -0
  249. package/lib/rules/no-restricted-properties.js +233 -0
  250. package/lib/rules/no-restricted-syntax.js +74 -0
  251. package/lib/rules/no-return-assign.js +87 -0
  252. package/lib/rules/no-return-await.js +162 -0
  253. package/lib/rules/no-script-url.js +68 -0
  254. package/lib/rules/no-self-assign.js +186 -0
  255. package/lib/rules/no-self-compare.js +77 -0
  256. package/lib/rules/no-sequences.js +158 -0
  257. package/lib/rules/no-setter-return.js +224 -0
  258. package/lib/rules/no-shadow-restricted-names.js +113 -0
  259. package/lib/rules/no-shadow.js +624 -0
  260. package/lib/rules/no-spaced-func.js +105 -0
  261. package/lib/rules/no-sparse-arrays.js +68 -0
  262. package/lib/rules/no-sync.js +81 -0
  263. package/lib/rules/no-tabs.js +110 -0
  264. package/lib/rules/no-template-curly-in-string.js +45 -0
  265. package/lib/rules/no-ternary.js +38 -0
  266. package/lib/rules/no-this-before-super.js +365 -0
  267. package/lib/rules/no-throw-literal.js +46 -0
  268. package/lib/rules/no-trailing-spaces.js +227 -0
  269. package/lib/rules/no-unassigned-vars.js +80 -0
  270. package/lib/rules/no-undef-init.js +101 -0
  271. package/lib/rules/no-undef.js +84 -0
  272. package/lib/rules/no-undefined.js +85 -0
  273. package/lib/rules/no-underscore-dangle.js +383 -0
  274. package/lib/rules/no-unexpected-multiline.js +130 -0
  275. package/lib/rules/no-unmodified-loop-condition.js +360 -0
  276. package/lib/rules/no-unneeded-ternary.js +232 -0
  277. package/lib/rules/no-unreachable-loop.js +190 -0
  278. package/lib/rules/no-unreachable.js +300 -0
  279. package/lib/rules/no-unsafe-finally.js +119 -0
  280. package/lib/rules/no-unsafe-negation.js +152 -0
  281. package/lib/rules/no-unsafe-optional-chaining.js +221 -0
  282. package/lib/rules/no-unused-expressions.js +227 -0
  283. package/lib/rules/no-unused-labels.js +158 -0
  284. package/lib/rules/no-unused-private-class-members.js +219 -0
  285. package/lib/rules/no-unused-vars.js +1739 -0
  286. package/lib/rules/no-use-before-define.js +446 -0
  287. package/lib/rules/no-useless-assignment.js +657 -0
  288. package/lib/rules/no-useless-backreference.js +263 -0
  289. package/lib/rules/no-useless-call.js +95 -0
  290. package/lib/rules/no-useless-catch.js +57 -0
  291. package/lib/rules/no-useless-computed-key.js +204 -0
  292. package/lib/rules/no-useless-concat.js +121 -0
  293. package/lib/rules/no-useless-constructor.js +262 -0
  294. package/lib/rules/no-useless-escape.js +406 -0
  295. package/lib/rules/no-useless-rename.js +202 -0
  296. package/lib/rules/no-useless-return.js +401 -0
  297. package/lib/rules/no-var.js +367 -0
  298. package/lib/rules/no-void.js +69 -0
  299. package/lib/rules/no-warning-comments.js +209 -0
  300. package/lib/rules/no-whitespace-before-property.js +150 -0
  301. package/lib/rules/no-with.js +37 -0
  302. package/lib/rules/nonblock-statement-body-position.js +164 -0
  303. package/lib/rules/object-curly-newline.js +383 -0
  304. package/lib/rules/object-curly-spacing.js +369 -0
  305. package/lib/rules/object-property-newline.js +151 -0
  306. package/lib/rules/object-shorthand.js +652 -0
  307. package/lib/rules/one-var-declaration-per-line.js +117 -0
  308. package/lib/rules/one-var.js +717 -0
  309. package/lib/rules/operator-assignment.js +270 -0
  310. package/lib/rules/operator-linebreak.js +315 -0
  311. package/lib/rules/padded-blocks.js +366 -0
  312. package/lib/rules/padding-line-between-statements.js +612 -0
  313. package/lib/rules/prefer-arrow-callback.js +437 -0
  314. package/lib/rules/prefer-const.js +546 -0
  315. package/lib/rules/prefer-destructuring.js +332 -0
  316. package/lib/rules/prefer-exponentiation-operator.js +235 -0
  317. package/lib/rules/prefer-named-capture-group.js +197 -0
  318. package/lib/rules/prefer-numeric-literals.js +157 -0
  319. package/lib/rules/prefer-object-has-own.js +148 -0
  320. package/lib/rules/prefer-object-spread.js +319 -0
  321. package/lib/rules/prefer-promise-reject-errors.js +154 -0
  322. package/lib/rules/prefer-reflect.js +150 -0
  323. package/lib/rules/prefer-regex-literals.js +605 -0
  324. package/lib/rules/prefer-rest-params.js +117 -0
  325. package/lib/rules/prefer-spread.js +91 -0
  326. package/lib/rules/prefer-template.js +347 -0
  327. package/lib/rules/preserve-caught-error.js +535 -0
  328. package/lib/rules/quote-props.js +394 -0
  329. package/lib/rules/quotes.js +416 -0
  330. package/lib/rules/radix.js +193 -0
  331. package/lib/rules/require-atomic-updates.js +365 -0
  332. package/lib/rules/require-await.js +184 -0
  333. package/lib/rules/require-unicode-regexp.js +317 -0
  334. package/lib/rules/require-yield.js +86 -0
  335. package/lib/rules/rest-spread-spacing.js +150 -0
  336. package/lib/rules/semi-spacing.js +297 -0
  337. package/lib/rules/semi-style.js +218 -0
  338. package/lib/rules/semi.js +476 -0
  339. package/lib/rules/sort-imports.js +319 -0
  340. package/lib/rules/sort-keys.js +268 -0
  341. package/lib/rules/sort-vars.js +140 -0
  342. package/lib/rules/space-before-blocks.js +232 -0
  343. package/lib/rules/space-before-function-paren.js +202 -0
  344. package/lib/rules/space-in-parens.js +374 -0
  345. package/lib/rules/space-infix-ops.js +249 -0
  346. package/lib/rules/space-unary-ops.js +400 -0
  347. package/lib/rules/spaced-comment.js +447 -0
  348. package/lib/rules/strict.js +314 -0
  349. package/lib/rules/switch-colon-spacing.js +158 -0
  350. package/lib/rules/symbol-description.js +70 -0
  351. package/lib/rules/template-curly-spacing.js +168 -0
  352. package/lib/rules/template-tag-spacing.js +121 -0
  353. package/lib/rules/unicode-bom.js +73 -0
  354. package/lib/rules/use-isnan.js +268 -0
  355. package/lib/rules/utils/ast-utils.js +2828 -0
  356. package/lib/rules/utils/char-source.js +247 -0
  357. package/lib/rules/utils/fix-tracker.js +125 -0
  358. package/lib/rules/utils/keywords.js +67 -0
  359. package/lib/rules/utils/lazy-loading-rule-map.js +118 -0
  360. package/lib/rules/utils/regular-expressions.js +58 -0
  361. package/lib/rules/utils/unicode/index.js +16 -0
  362. package/lib/rules/utils/unicode/is-combining-character.js +13 -0
  363. package/lib/rules/utils/unicode/is-emoji-modifier.js +13 -0
  364. package/lib/rules/utils/unicode/is-regional-indicator-symbol.js +13 -0
  365. package/lib/rules/utils/unicode/is-surrogate-pair.js +14 -0
  366. package/lib/rules/valid-typeof.js +171 -0
  367. package/lib/rules/vars-on-top.js +165 -0
  368. package/lib/rules/wrap-iife.js +238 -0
  369. package/lib/rules/wrap-regex.js +91 -0
  370. package/lib/rules/yield-star-spacing.js +158 -0
  371. package/lib/rules/yoda.js +362 -0
  372. package/lib/services/parser-service.js +64 -0
  373. package/lib/services/processor-service.js +100 -0
  374. package/lib/services/suppressions-service.js +302 -0
  375. package/lib/services/warning-service.js +87 -0
  376. package/lib/shared/ajv.js +34 -0
  377. package/lib/shared/assert.js +21 -0
  378. package/lib/shared/ast-utils.js +30 -0
  379. package/lib/shared/deep-merge-arrays.js +62 -0
  380. package/lib/shared/directives.js +16 -0
  381. package/lib/shared/flags.js +89 -0
  382. package/lib/shared/logging.js +38 -0
  383. package/lib/shared/naming.js +109 -0
  384. package/lib/shared/option-utils.js +63 -0
  385. package/lib/shared/relative-module-resolver.js +28 -0
  386. package/lib/shared/runtime-info.js +177 -0
  387. package/lib/shared/serialization.js +78 -0
  388. package/lib/shared/severity.js +49 -0
  389. package/lib/shared/stats.js +30 -0
  390. package/lib/shared/string-utils.js +58 -0
  391. package/lib/shared/text-table.js +68 -0
  392. package/lib/shared/translate-cli-options.js +223 -0
  393. package/lib/shared/traverser.js +202 -0
  394. package/lib/types/config-api.d.ts +12 -0
  395. package/lib/types/index.d.ts +1482 -0
  396. package/lib/types/rules.d.ts +5603 -0
  397. package/lib/types/universal.d.ts +6 -0
  398. package/lib/types/use-at-your-own-risk.d.ts +34 -0
  399. package/lib/universal.js +10 -0
  400. package/lib/unsupported-api.js +26 -0
  401. package/messages/all-files-ignored.js +16 -0
  402. package/messages/all-matched-files-ignored.js +21 -0
  403. package/messages/config-file-missing.js +16 -0
  404. package/messages/config-plugin-missing.js +14 -0
  405. package/messages/config-serialize-function.js +30 -0
  406. package/messages/eslintrc-incompat.js +117 -0
  407. package/messages/eslintrc-plugins.js +27 -0
  408. package/messages/extend-config-missing.js +13 -0
  409. package/messages/failed-to-read-json.js +11 -0
  410. package/messages/file-not-found.js +10 -0
  411. package/messages/invalid-rule-options.js +17 -0
  412. package/messages/invalid-rule-severity.js +13 -0
  413. package/messages/no-config-found.js +15 -0
  414. package/messages/plugin-conflict.js +22 -0
  415. package/messages/plugin-invalid.js +16 -0
  416. package/messages/plugin-missing.js +19 -0
  417. package/messages/print-config-with-directory-path.js +8 -0
  418. package/messages/shared.js +23 -0
  419. package/messages/whitespace-found.js +11 -0
  420. package/package.json +220 -0
@@ -0,0 +1,109 @@
1
+ /**
2
+ * @fileoverview Common helpers for naming of plugins, formatters and configs
3
+ */
4
+
5
+ "use strict";
6
+
7
+ const NAMESPACE_REGEX = /^@.*\//u;
8
+
9
+ /**
10
+ * Brings package name to correct format based on prefix
11
+ * @param {string} name The name of the package.
12
+ * @param {string} prefix Can be either "eslint-plugin", "eslint-config" or "eslint-formatter"
13
+ * @returns {string} Normalized name of the package
14
+ * @private
15
+ */
16
+ function normalizePackageName(name, prefix) {
17
+ let normalizedName = name;
18
+
19
+ /**
20
+ * On Windows, name can come in with Windows slashes instead of Unix slashes.
21
+ * Normalize to Unix first to avoid errors later on.
22
+ * https://github.com/eslint/eslint/issues/5644
23
+ */
24
+ if (normalizedName.includes("\\")) {
25
+ normalizedName = normalizedName.replace(/\\/gu, "/");
26
+ }
27
+
28
+ if (normalizedName.charAt(0) === "@") {
29
+ /**
30
+ * it's a scoped package
31
+ * package name is the prefix, or just a username
32
+ */
33
+ const scopedPackageShortcutRegex = new RegExp(
34
+ `^(@[^/]+)(?:/(?:${prefix})?)?$`,
35
+ "u",
36
+ ),
37
+ scopedPackageNameRegex = new RegExp(`^${prefix}(-|$)`, "u");
38
+
39
+ if (scopedPackageShortcutRegex.test(normalizedName)) {
40
+ normalizedName = normalizedName.replace(
41
+ scopedPackageShortcutRegex,
42
+ `$1/${prefix}`,
43
+ );
44
+ } else if (!scopedPackageNameRegex.test(normalizedName.split("/")[1])) {
45
+ /**
46
+ * for scoped packages, insert the prefix after the first / unless
47
+ * the path is already @scope/eslint or @scope/eslint-xxx-yyy
48
+ */
49
+ normalizedName = normalizedName.replace(
50
+ /^@([^/]+)\/(.*)$/u,
51
+ `@$1/${prefix}-$2`,
52
+ );
53
+ }
54
+ } else if (!normalizedName.startsWith(`${prefix}-`)) {
55
+ normalizedName = `${prefix}-${normalizedName}`;
56
+ }
57
+
58
+ return normalizedName;
59
+ }
60
+
61
+ /**
62
+ * Removes the prefix from a fullname.
63
+ * @param {string} fullname The term which may have the prefix.
64
+ * @param {string} prefix The prefix to remove.
65
+ * @returns {string} The term without prefix.
66
+ */
67
+ function getShorthandName(fullname, prefix) {
68
+ if (fullname[0] === "@") {
69
+ let matchResult = new RegExp(`^(@[^/]+)/${prefix}$`, "u").exec(
70
+ fullname,
71
+ );
72
+
73
+ if (matchResult) {
74
+ return matchResult[1];
75
+ }
76
+
77
+ matchResult = new RegExp(`^(@[^/]+)/${prefix}-(.+)$`, "u").exec(
78
+ fullname,
79
+ );
80
+ if (matchResult) {
81
+ return `${matchResult[1]}/${matchResult[2]}`;
82
+ }
83
+ } else if (fullname.startsWith(`${prefix}-`)) {
84
+ return fullname.slice(prefix.length + 1);
85
+ }
86
+
87
+ return fullname;
88
+ }
89
+
90
+ /**
91
+ * Gets the scope (namespace) of a term.
92
+ * @param {string} term The term which may have the namespace.
93
+ * @returns {string} The namespace of the term if it has one.
94
+ */
95
+ function getNamespaceFromTerm(term) {
96
+ const match = term.match(NAMESPACE_REGEX);
97
+
98
+ return match ? match[0] : "";
99
+ }
100
+
101
+ //------------------------------------------------------------------------------
102
+ // Public Interface
103
+ //------------------------------------------------------------------------------
104
+
105
+ module.exports = {
106
+ normalizePackageName,
107
+ getShorthandName,
108
+ getNamespaceFromTerm,
109
+ };
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @fileoverview Utilities to operate on option objects.
3
+ * @author Josh Goldberg
4
+ */
5
+
6
+ "use strict";
7
+
8
+ /**
9
+ * Determines whether any of input's properties are different
10
+ * from values that already exist in original.
11
+ * @template T
12
+ * @param {Partial<T>} input New value.
13
+ * @param {T} original Original value.
14
+ * @returns {boolean} Whether input includes an explicit difference.
15
+ */
16
+ function containsDifferentProperty(input, original) {
17
+ if (input === original) {
18
+ return false;
19
+ }
20
+
21
+ if (
22
+ typeof input !== typeof original ||
23
+ Array.isArray(input) !== Array.isArray(original)
24
+ ) {
25
+ return true;
26
+ }
27
+
28
+ if (Array.isArray(input)) {
29
+ return (
30
+ input.length !== original.length ||
31
+ input.some((value, i) =>
32
+ containsDifferentProperty(value, original[i]),
33
+ )
34
+ );
35
+ }
36
+
37
+ if (typeof input === "object") {
38
+ if (input === null || original === null) {
39
+ return true;
40
+ }
41
+
42
+ const inputKeys = Object.keys(input);
43
+ const originalKeys = Object.keys(original);
44
+
45
+ return (
46
+ inputKeys.length !== originalKeys.length ||
47
+ inputKeys.some(
48
+ inputKey =>
49
+ !Object.hasOwn(original, inputKey) ||
50
+ containsDifferentProperty(
51
+ input[inputKey],
52
+ original[inputKey],
53
+ ),
54
+ )
55
+ );
56
+ }
57
+
58
+ return true;
59
+ }
60
+
61
+ module.exports = {
62
+ containsDifferentProperty,
63
+ };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Utility for resolving a module relative to another module
3
+ * @author Teddy Katz
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const Module = require("node:module");
9
+
10
+ /*
11
+ * `Module.createRequire` is added in v12.2.0. It supports URL as well.
12
+ * We only support the case where the argument is a filepath, not a URL.
13
+ */
14
+ const createRequire = Module.createRequire;
15
+
16
+ /**
17
+ * Resolves a Node module relative to another module
18
+ * @param {string} moduleName The name of a Node module, or a path to a Node module.
19
+ * @param {string} relativeToPath An absolute path indicating the module that `moduleName` should be resolved relative to. This must be
20
+ * a file rather than a directory, but the file need not actually exist.
21
+ * @returns {string} The absolute path that would result from calling `require.resolve(moduleName)` in a file located at `relativeToPath`
22
+ * @throws {Error} When the module cannot be resolved.
23
+ */
24
+ function resolve(moduleName, relativeToPath) {
25
+ return createRequire(relativeToPath).resolve(moduleName);
26
+ }
27
+
28
+ exports.resolve = resolve;
@@ -0,0 +1,177 @@
1
+ /**
2
+ * @fileoverview Utility to get information about the execution environment.
3
+ * @author Kai Cataldo
4
+ */
5
+
6
+ "use strict";
7
+
8
+ //------------------------------------------------------------------------------
9
+ // Requirements
10
+ //------------------------------------------------------------------------------
11
+
12
+ const path = require("node:path");
13
+ const spawn = require("cross-spawn");
14
+ const os = require("node:os");
15
+ const log = require("../shared/logging");
16
+ const packageJson = require("../../package.json");
17
+
18
+ //------------------------------------------------------------------------------
19
+ // Helpers
20
+ //------------------------------------------------------------------------------
21
+
22
+ /**
23
+ * Generates and returns execution environment information.
24
+ * @returns {string} A string that contains execution environment information.
25
+ */
26
+ function environment() {
27
+ const cache = new Map();
28
+
29
+ /**
30
+ * Checks if a path is a child of a directory.
31
+ * @param {string} parentPath The parent path to check.
32
+ * @param {string} childPath The path to check.
33
+ * @returns {boolean} Whether or not the given path is a child of a directory.
34
+ */
35
+ function isChildOfDirectory(parentPath, childPath) {
36
+ return !path.relative(parentPath, childPath).startsWith("..");
37
+ }
38
+
39
+ /**
40
+ * Synchronously executes a shell command and formats the result.
41
+ * @param {string} cmd The command to execute.
42
+ * @param {Array} args The arguments to be executed with the command.
43
+ * @throws {Error} As may be collected by `cross-spawn.sync`.
44
+ * @returns {string} The version returned by the command.
45
+ */
46
+ function execCommand(cmd, args) {
47
+ const key = [cmd, ...args].join(" ");
48
+
49
+ if (cache.has(key)) {
50
+ return cache.get(key);
51
+ }
52
+
53
+ const process = spawn.sync(cmd, args, { encoding: "utf8" });
54
+
55
+ if (process.error) {
56
+ throw process.error;
57
+ }
58
+
59
+ const result = process.stdout.trim();
60
+
61
+ cache.set(key, result);
62
+ return result;
63
+ }
64
+
65
+ /**
66
+ * Normalizes a version number.
67
+ * @param {string} versionStr The string to normalize.
68
+ * @returns {string} The normalized version number.
69
+ */
70
+ function normalizeVersionStr(versionStr) {
71
+ return versionStr.startsWith("v") ? versionStr : `v${versionStr}`;
72
+ }
73
+
74
+ /**
75
+ * Gets bin version.
76
+ * @param {string} bin The bin to check.
77
+ * @throws {Error} As may be collected by `cross-spawn.sync`.
78
+ * @returns {string} The normalized version returned by the command.
79
+ */
80
+ function getBinVersion(bin) {
81
+ const binArgs = ["--version"];
82
+
83
+ try {
84
+ return normalizeVersionStr(execCommand(bin, binArgs));
85
+ } catch (e) {
86
+ log.error(
87
+ `Error finding ${bin} version running the command \`${bin} ${binArgs.join(" ")}\``,
88
+ );
89
+ throw e;
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Gets installed npm package version.
95
+ * @param {string} pkg The package to check.
96
+ * @param {boolean} global Whether to check globally or not.
97
+ * @throws {Error} As may be collected by `cross-spawn.sync`.
98
+ * @returns {string} The normalized version returned by the command.
99
+ */
100
+ function getNpmPackageVersion(pkg, { global = false } = {}) {
101
+ const npmBinArgs = ["bin", "-g"];
102
+ const npmLsArgs = ["ls", "--depth=0", "--json", pkg];
103
+
104
+ if (global) {
105
+ npmLsArgs.push("-g");
106
+ }
107
+
108
+ try {
109
+ const parsedStdout = JSON.parse(execCommand("npm", npmLsArgs));
110
+
111
+ /*
112
+ * Checking globally returns an empty JSON object, while local checks
113
+ * include the name and version of the local project.
114
+ */
115
+ if (
116
+ Object.keys(parsedStdout).length === 0 ||
117
+ !(parsedStdout.dependencies && parsedStdout.dependencies.eslint)
118
+ ) {
119
+ return "Not found";
120
+ }
121
+
122
+ const [, processBinPath] = process.argv;
123
+ let npmBinPath;
124
+
125
+ try {
126
+ npmBinPath = execCommand("npm", npmBinArgs);
127
+ } catch (e) {
128
+ log.error(
129
+ `Error finding npm binary path when running command \`npm ${npmBinArgs.join(" ")}\``,
130
+ );
131
+ throw e;
132
+ }
133
+
134
+ const isGlobal = isChildOfDirectory(npmBinPath, processBinPath);
135
+ let pkgVersion = parsedStdout.dependencies.eslint.version;
136
+
137
+ if ((global && isGlobal) || (!global && !isGlobal)) {
138
+ pkgVersion += " (Currently used)";
139
+ }
140
+
141
+ return normalizeVersionStr(pkgVersion);
142
+ } catch (e) {
143
+ log.error(
144
+ `Error finding ${pkg} version running the command \`npm ${npmLsArgs.join(" ")}\``,
145
+ );
146
+ throw e;
147
+ }
148
+ }
149
+
150
+ return [
151
+ "Environment Info:",
152
+ "",
153
+ `Node version: ${process.version}`,
154
+ `npm version: ${getBinVersion("npm")}`,
155
+ `Local ESLint version: ${getNpmPackageVersion("eslint", { global: false })}`,
156
+ `Global ESLint version: ${getNpmPackageVersion("eslint", { global: true })}`,
157
+ `Operating System: ${os.platform()} ${os.release()}`,
158
+ ].join("\n");
159
+ }
160
+
161
+ /**
162
+ * Returns version of currently executing ESLint.
163
+ * @returns {string} The version from the currently executing ESLint's package.json.
164
+ */
165
+ function version() {
166
+ return `v${packageJson.version}`;
167
+ }
168
+
169
+ //------------------------------------------------------------------------------
170
+ // Public Interface
171
+ //------------------------------------------------------------------------------
172
+
173
+ module.exports = {
174
+ __esModule: true, // Indicate intent for imports, remove ambiguity for Knip (see: https://github.com/eslint/eslint/pull/18005#discussion_r1484422616)
175
+ environment,
176
+ version,
177
+ };
@@ -0,0 +1,78 @@
1
+ /**
2
+ * @fileoverview Serialization utils.
3
+ * @author Bryan Mishkin
4
+ */
5
+
6
+ "use strict";
7
+
8
+ /**
9
+ * Check if a value is a primitive or plain object created by the Object constructor.
10
+ * @param {any} val the value to check
11
+ * @returns {boolean} true if so
12
+ * @private
13
+ */
14
+ function isSerializablePrimitiveOrPlainObject(val) {
15
+ return (
16
+ val === null ||
17
+ typeof val === "string" ||
18
+ typeof val === "boolean" ||
19
+ typeof val === "number" ||
20
+ (typeof val === "object" && val.constructor === Object) ||
21
+ Array.isArray(val)
22
+ );
23
+ }
24
+
25
+ /**
26
+ * Check if a value is serializable.
27
+ * Functions or objects like RegExp cannot be serialized by JSON.stringify().
28
+ * Inspired by: https://stackoverflow.com/questions/30579940/reliable-way-to-check-if-objects-is-serializable-in-javascript
29
+ * @param {any} val The value
30
+ * @param {Set<Object>} seenObjects Objects already seen in this path from the root object.
31
+ * @returns {boolean} `true` if the value is serializable
32
+ */
33
+ function isSerializable(val, seenObjects = new Set()) {
34
+ if (!isSerializablePrimitiveOrPlainObject(val)) {
35
+ return false;
36
+ }
37
+ if (typeof val === "object" && val !== null) {
38
+ if (seenObjects.has(val)) {
39
+ /*
40
+ * Since this is a depth-first traversal, encountering
41
+ * the same object again means there is a circular reference.
42
+ * Objects with circular references are not serializable.
43
+ */
44
+ return false;
45
+ }
46
+ for (const property in val) {
47
+ if (Object.hasOwn(val, property)) {
48
+ if (!isSerializablePrimitiveOrPlainObject(val[property])) {
49
+ return false;
50
+ }
51
+ if (
52
+ typeof val[property] === "object" &&
53
+ val[property] !== null
54
+ ) {
55
+ if (
56
+ /*
57
+ * We're creating a new Set of seen objects because we want to
58
+ * ensure that `val` doesn't appear again in this path, but it can appear
59
+ * in other paths. This allows for reusing objects in the graph, as long as
60
+ * there are no cycles.
61
+ */
62
+ !isSerializable(
63
+ val[property],
64
+ new Set([...seenObjects, val]),
65
+ )
66
+ ) {
67
+ return false;
68
+ }
69
+ }
70
+ }
71
+ }
72
+ }
73
+ return true;
74
+ }
75
+
76
+ module.exports = {
77
+ isSerializable,
78
+ };
@@ -0,0 +1,49 @@
1
+ /**
2
+ * @fileoverview Helpers for severity values (e.g. normalizing different types).
3
+ * @author Bryan Mishkin
4
+ */
5
+
6
+ "use strict";
7
+
8
+ /**
9
+ * Convert severity value of different types to a string.
10
+ * @param {string|number} severity severity value
11
+ * @throws error if severity is invalid
12
+ * @returns {string} severity string
13
+ */
14
+ function normalizeSeverityToString(severity) {
15
+ if ([2, "2", "error"].includes(severity)) {
16
+ return "error";
17
+ }
18
+ if ([1, "1", "warn"].includes(severity)) {
19
+ return "warn";
20
+ }
21
+ if ([0, "0", "off"].includes(severity)) {
22
+ return "off";
23
+ }
24
+ throw new Error(`Invalid severity value: ${severity}`);
25
+ }
26
+
27
+ /**
28
+ * Convert severity value of different types to a number.
29
+ * @param {string|number} severity severity value
30
+ * @throws error if severity is invalid
31
+ * @returns {number} severity number
32
+ */
33
+ function normalizeSeverityToNumber(severity) {
34
+ if ([2, "2", "error"].includes(severity)) {
35
+ return 2;
36
+ }
37
+ if ([1, "1", "warn"].includes(severity)) {
38
+ return 1;
39
+ }
40
+ if ([0, "0", "off"].includes(severity)) {
41
+ return 0;
42
+ }
43
+ throw new Error(`Invalid severity value: ${severity}`);
44
+ }
45
+
46
+ module.exports = {
47
+ normalizeSeverityToString,
48
+ normalizeSeverityToNumber,
49
+ };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @fileoverview Provides helper functions to start/stop the time measurements
3
+ * that are provided by the ESLint 'stats' option.
4
+ * @author Mara Kiefer <http://github.com/mnkiefer>
5
+ */
6
+ "use strict";
7
+
8
+ /**
9
+ * Start time measurement
10
+ * @returns {[number, number]} t variable for tracking time
11
+ */
12
+ function startTime() {
13
+ return process.hrtime();
14
+ }
15
+
16
+ /**
17
+ * End time measurement
18
+ * @param {[number, number]} t Variable for tracking time
19
+ * @returns {number} The measured time in milliseconds
20
+ */
21
+ function endTime(t) {
22
+ const time = process.hrtime(t);
23
+
24
+ return time[0] * 1e3 + time[1] / 1e6;
25
+ }
26
+
27
+ module.exports = {
28
+ startTime,
29
+ endTime,
30
+ };
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @fileoverview Utilities to operate on strings.
3
+ * @author Stephen Wade
4
+ */
5
+
6
+ "use strict";
7
+
8
+ //------------------------------------------------------------------------------
9
+ // Helpers
10
+ //------------------------------------------------------------------------------
11
+
12
+ // eslint-disable-next-line no-control-regex -- intentionally including control characters
13
+ const ASCII_REGEX = /^[\u0000-\u007f]*$/u;
14
+
15
+ /** @type {Intl.Segmenter | undefined} */
16
+ let segmenter;
17
+
18
+ //------------------------------------------------------------------------------
19
+ // Public Interface
20
+ //------------------------------------------------------------------------------
21
+
22
+ /**
23
+ * Converts the first letter of a string to uppercase.
24
+ * @param {string} string The string to operate on
25
+ * @returns {string} The converted string
26
+ */
27
+ function upperCaseFirst(string) {
28
+ if (string.length <= 1) {
29
+ return string.toUpperCase();
30
+ }
31
+ return string[0].toUpperCase() + string.slice(1);
32
+ }
33
+
34
+ /**
35
+ * Counts graphemes in a given string.
36
+ * @param {string} value A string to count graphemes.
37
+ * @returns {number} The number of graphemes in `value`.
38
+ */
39
+ function getGraphemeCount(value) {
40
+ if (ASCII_REGEX.test(value)) {
41
+ return value.length;
42
+ }
43
+
44
+ segmenter ??= new Intl.Segmenter("en-US"); // en-US locale should be supported everywhere
45
+ let graphemeCount = 0;
46
+
47
+ // eslint-disable-next-line no-unused-vars -- for-of needs a variable
48
+ for (const unused of segmenter.segment(value)) {
49
+ graphemeCount++;
50
+ }
51
+
52
+ return graphemeCount;
53
+ }
54
+
55
+ module.exports = {
56
+ upperCaseFirst,
57
+ getGraphemeCount,
58
+ };
@@ -0,0 +1,68 @@
1
+ /**
2
+ * @fileoverview Optimized version of the `text-table` npm module to improve performance by replacing inefficient regex-based
3
+ * whitespace trimming with a modern built-in method.
4
+ *
5
+ * This modification addresses a performance issue reported in https://github.com/eslint/eslint/issues/18709
6
+ *
7
+ * The `text-table` module is published under the MIT License. For the original source, refer to:
8
+ * https://www.npmjs.com/package/text-table.
9
+ */
10
+
11
+ /*
12
+ *
13
+ * This software is released under the MIT license:
14
+ *
15
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
16
+ * this software and associated documentation files (the "Software"), to deal in
17
+ * the Software without restriction, including without limitation the rights to
18
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
19
+ * the Software, and to permit persons to whom the Software is furnished to do so,
20
+ * subject to the following conditions:
21
+ *
22
+ * The above copyright notice and this permission notice shall be included in all
23
+ * copies or substantial portions of the Software.
24
+ *
25
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
27
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
28
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
29
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
+ */
32
+
33
+ "use strict";
34
+
35
+ module.exports = function (rows_, opts) {
36
+ const hsep = " ";
37
+ const align = opts.align;
38
+ const stringLength = opts.stringLength;
39
+
40
+ const sizes = rows_.reduce((acc, row) => {
41
+ row.forEach((c, ix) => {
42
+ const n = stringLength(c);
43
+
44
+ if (!acc[ix] || n > acc[ix]) {
45
+ acc[ix] = n;
46
+ }
47
+ });
48
+ return acc;
49
+ }, []);
50
+
51
+ return rows_
52
+ .map(row =>
53
+ row
54
+ .map((c, ix) => {
55
+ const n = sizes[ix] - stringLength(c) || 0;
56
+ const s = Array(Math.max(n + 1, 1)).join(" ");
57
+
58
+ if (align[ix] === "r") {
59
+ return s + c;
60
+ }
61
+
62
+ return c + s;
63
+ })
64
+ .join(hsep)
65
+ .trimEnd(),
66
+ )
67
+ .join("\n");
68
+ };