gurkencheck 0.0.9 → 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 (334) hide show
  1. package/README.md +30 -11
  2. package/dist/config-parser.d.ts +15 -1
  3. package/dist/config-parser.js +58 -12
  4. package/dist/config-verifier.d.ts +0 -1
  5. package/dist/config-verifier.js +71 -3
  6. package/dist/diagnostics.d.ts +0 -1
  7. package/dist/diagnostics.js +0 -1
  8. package/dist/exit-codes.d.ts +0 -1
  9. package/dist/exit-codes.js +0 -1
  10. package/dist/feature-finder.d.ts +0 -1
  11. package/dist/feature-finder.js +29 -11
  12. package/dist/formatters/index.d.ts +0 -1
  13. package/dist/formatters/index.js +2 -3
  14. package/dist/formatters/json.d.ts +0 -1
  15. package/dist/formatters/json.js +0 -1
  16. package/dist/formatters/junit.d.ts +1 -13
  17. package/dist/formatters/junit.js +36 -11
  18. package/dist/formatters/sarif.d.ts +0 -1
  19. package/dist/formatters/sarif.js +25 -7
  20. package/dist/formatters/stylish.d.ts +0 -1
  21. package/dist/formatters/stylish.js +0 -1
  22. package/dist/formatters/tap.d.ts +0 -1
  23. package/dist/formatters/tap.js +37 -5
  24. package/dist/gherkin/dialects.d.ts +0 -1
  25. package/dist/gherkin/dialects.js +0 -1
  26. package/dist/gherkin/keywords.d.ts +6 -3
  27. package/dist/gherkin/keywords.js +10 -4
  28. package/dist/gherkin/parse.d.ts +0 -1
  29. package/dist/gherkin/parse.js +19 -7
  30. package/dist/gherkin/traverse.d.ts +0 -1
  31. package/dist/gherkin/traverse.js +0 -1
  32. package/dist/gherkin/variables.d.ts +12 -1
  33. package/dist/gherkin/variables.js +24 -6
  34. package/dist/index.d.ts +1 -2
  35. package/dist/index.js +1 -2
  36. package/dist/linter.d.ts +0 -1
  37. package/dist/linter.js +1 -2
  38. package/dist/logger.d.ts +0 -1
  39. package/dist/logger.js +0 -1
  40. package/dist/main.d.ts +0 -1
  41. package/dist/main.js +78 -27
  42. package/dist/presets.d.ts +2 -2
  43. package/dist/presets.js +0 -5
  44. package/dist/rules/allowed-tags.d.ts +0 -1
  45. package/dist/rules/allowed-tags.js +2 -1
  46. package/dist/rules/background-setup-only.d.ts +0 -1
  47. package/dist/rules/background-setup-only.js +0 -1
  48. package/dist/rules/file-name.d.ts +0 -1
  49. package/dist/rules/file-name.js +10 -1
  50. package/dist/rules/indentation.d.ts +0 -1
  51. package/dist/rules/indentation.js +24 -10
  52. package/dist/rules/index.d.ts +0 -1
  53. package/dist/rules/index.js +0 -1
  54. package/dist/rules/keywords-in-logical-order.d.ts +0 -1
  55. package/dist/rules/keywords-in-logical-order.js +0 -1
  56. package/dist/rules/max-scenarios-per-file.d.ts +0 -1
  57. package/dist/rules/max-scenarios-per-file.js +0 -1
  58. package/dist/rules/name-length.d.ts +0 -1
  59. package/dist/rules/name-length.js +5 -3
  60. package/dist/rules/new-line-at-eof.d.ts +0 -1
  61. package/dist/rules/new-line-at-eof.js +10 -2
  62. package/dist/rules/no-background-only-scenario.d.ts +0 -1
  63. package/dist/rules/no-background-only-scenario.js +0 -1
  64. package/dist/rules/no-dupe-feature-names.d.ts +0 -1
  65. package/dist/rules/no-dupe-feature-names.js +5 -1
  66. package/dist/rules/no-dupe-file-names.d.ts +0 -1
  67. package/dist/rules/no-dupe-file-names.js +0 -1
  68. package/dist/rules/no-dupe-scenario-names.d.ts +0 -1
  69. package/dist/rules/no-dupe-scenario-names.js +4 -1
  70. package/dist/rules/no-duplicate-tags.d.ts +0 -1
  71. package/dist/rules/no-duplicate-tags.js +0 -1
  72. package/dist/rules/no-empty-background.d.ts +0 -1
  73. package/dist/rules/no-empty-background.js +0 -1
  74. package/dist/rules/no-empty-file.d.ts +0 -1
  75. package/dist/rules/no-empty-file.js +0 -1
  76. package/dist/rules/no-examples-in-scenarios.d.ts +0 -1
  77. package/dist/rules/no-examples-in-scenarios.js +0 -1
  78. package/dist/rules/no-files-without-scenarios.d.ts +0 -1
  79. package/dist/rules/no-files-without-scenarios.js +0 -1
  80. package/dist/rules/no-homogenous-tags.d.ts +0 -1
  81. package/dist/rules/no-homogenous-tags.js +0 -1
  82. package/dist/rules/no-multiple-empty-lines.d.ts +0 -1
  83. package/dist/rules/no-multiple-empty-lines.js +2 -3
  84. package/dist/rules/no-partially-commented-tag-lines.d.ts +0 -1
  85. package/dist/rules/no-partially-commented-tag-lines.js +7 -5
  86. package/dist/rules/no-restricted-patterns.d.ts +0 -1
  87. package/dist/rules/no-restricted-patterns.js +64 -19
  88. package/dist/rules/no-restricted-tags.d.ts +0 -1
  89. package/dist/rules/no-restricted-tags.js +2 -1
  90. package/dist/rules/no-scenario-outlines-without-examples.d.ts +0 -1
  91. package/dist/rules/no-scenario-outlines-without-examples.js +0 -1
  92. package/dist/rules/no-scenarios-without-then.d.ts +0 -1
  93. package/dist/rules/no-scenarios-without-then.js +0 -1
  94. package/dist/rules/no-scenarios-without-when.d.ts +0 -1
  95. package/dist/rules/no-scenarios-without-when.js +0 -1
  96. package/dist/rules/no-superfluous-tags.d.ts +0 -1
  97. package/dist/rules/no-superfluous-tags.js +0 -1
  98. package/dist/rules/no-trailing-spaces.d.ts +0 -1
  99. package/dist/rules/no-trailing-spaces.js +13 -4
  100. package/dist/rules/no-undeclared-variables.d.ts +0 -1
  101. package/dist/rules/no-undeclared-variables.js +12 -11
  102. package/dist/rules/no-unnamed-features.d.ts +0 -1
  103. package/dist/rules/no-unnamed-features.js +0 -1
  104. package/dist/rules/no-unnamed-scenarios.d.ts +0 -1
  105. package/dist/rules/no-unnamed-scenarios.js +0 -1
  106. package/dist/rules/no-unused-variables.d.ts +0 -1
  107. package/dist/rules/no-unused-variables.js +0 -1
  108. package/dist/rules/one-space-between-tags.d.ts +0 -1
  109. package/dist/rules/one-space-between-tags.js +3 -2
  110. package/dist/rules/only-one-when.d.ts +0 -1
  111. package/dist/rules/only-one-when.js +5 -5
  112. package/dist/rules/required-tags.d.ts +0 -1
  113. package/dist/rules/required-tags.js +13 -3
  114. package/dist/rules/scenario-size.d.ts +0 -1
  115. package/dist/rules/scenario-size.js +0 -1
  116. package/dist/rules/use-and.d.ts +0 -1
  117. package/dist/rules/use-and.js +2 -2
  118. package/dist/rules.d.ts +0 -1
  119. package/dist/rules.js +49 -4
  120. package/dist/stats/collect.d.ts +0 -1
  121. package/dist/stats/collect.js +0 -1
  122. package/dist/stats/command.d.ts +0 -1
  123. package/dist/stats/command.js +24 -7
  124. package/dist/stats/format/index.d.ts +0 -1
  125. package/dist/stats/format/index.js +0 -1
  126. package/dist/stats/format/json.d.ts +0 -1
  127. package/dist/stats/format/json.js +0 -1
  128. package/dist/stats/format/markdown.d.ts +0 -1
  129. package/dist/stats/format/markdown.js +24 -6
  130. package/dist/stats/format/shared.d.ts +0 -1
  131. package/dist/stats/format/shared.js +0 -1
  132. package/dist/stats/format/text.d.ts +0 -1
  133. package/dist/stats/format/text.js +0 -1
  134. package/dist/stats/index.d.ts +0 -1
  135. package/dist/stats/index.js +0 -1
  136. package/dist/stats/normalise.d.ts +0 -1
  137. package/dist/stats/normalise.js +27 -14
  138. package/dist/stats/similar.d.ts +0 -1
  139. package/dist/stats/similar.js +0 -1
  140. package/dist/stats/types.d.ts +0 -1
  141. package/dist/stats/types.js +0 -1
  142. package/dist/suppressions.d.ts +6 -3
  143. package/dist/suppressions.js +36 -30
  144. package/dist/types.d.ts +7 -1
  145. package/dist/types.js +0 -1
  146. package/dist/util/case.d.ts +2 -2
  147. package/dist/util/case.js +17 -3
  148. package/dist/util/collections.d.ts +0 -1
  149. package/dist/util/collections.js +0 -1
  150. package/dist/util/glob.d.ts +9 -3
  151. package/dist/util/glob.js +115 -27
  152. package/dist/util/json.d.ts +0 -1
  153. package/dist/util/json.js +0 -1
  154. package/dist/util/lines.d.ts +6 -4
  155. package/dist/util/lines.js +22 -4
  156. package/dist/util/location.d.ts +8 -1
  157. package/dist/util/location.js +10 -1
  158. package/dist/util/patterns.d.ts +9 -0
  159. package/dist/util/patterns.js +21 -0
  160. package/dist/util/resolve.d.ts +6 -0
  161. package/dist/util/resolve.js +101 -0
  162. package/dist/util/stream.d.ts +0 -1
  163. package/dist/util/stream.js +3 -2
  164. package/dist/util/xml.d.ts +0 -1
  165. package/dist/util/xml.js +17 -3
  166. package/dist/version.d.ts +0 -1
  167. package/dist/version.js +0 -1
  168. package/dist/watch.d.ts +11 -1
  169. package/dist/watch.js +38 -3
  170. package/package.json +6 -2
  171. package/dist/config-parser.d.ts.map +0 -1
  172. package/dist/config-parser.js.map +0 -1
  173. package/dist/config-verifier.d.ts.map +0 -1
  174. package/dist/config-verifier.js.map +0 -1
  175. package/dist/diagnostics.d.ts.map +0 -1
  176. package/dist/diagnostics.js.map +0 -1
  177. package/dist/exit-codes.d.ts.map +0 -1
  178. package/dist/exit-codes.js.map +0 -1
  179. package/dist/feature-finder.d.ts.map +0 -1
  180. package/dist/feature-finder.js.map +0 -1
  181. package/dist/formatters/index.d.ts.map +0 -1
  182. package/dist/formatters/index.js.map +0 -1
  183. package/dist/formatters/json.d.ts.map +0 -1
  184. package/dist/formatters/json.js.map +0 -1
  185. package/dist/formatters/junit.d.ts.map +0 -1
  186. package/dist/formatters/junit.js.map +0 -1
  187. package/dist/formatters/sarif.d.ts.map +0 -1
  188. package/dist/formatters/sarif.js.map +0 -1
  189. package/dist/formatters/stylish.d.ts.map +0 -1
  190. package/dist/formatters/stylish.js.map +0 -1
  191. package/dist/formatters/tap.d.ts.map +0 -1
  192. package/dist/formatters/tap.js.map +0 -1
  193. package/dist/gherkin/dialects.d.ts.map +0 -1
  194. package/dist/gherkin/dialects.js.map +0 -1
  195. package/dist/gherkin/keywords.d.ts.map +0 -1
  196. package/dist/gherkin/keywords.js.map +0 -1
  197. package/dist/gherkin/parse.d.ts.map +0 -1
  198. package/dist/gherkin/parse.js.map +0 -1
  199. package/dist/gherkin/traverse.d.ts.map +0 -1
  200. package/dist/gherkin/traverse.js.map +0 -1
  201. package/dist/gherkin/variables.d.ts.map +0 -1
  202. package/dist/gherkin/variables.js.map +0 -1
  203. package/dist/index.d.ts.map +0 -1
  204. package/dist/index.js.map +0 -1
  205. package/dist/linter.d.ts.map +0 -1
  206. package/dist/linter.js.map +0 -1
  207. package/dist/logger.d.ts.map +0 -1
  208. package/dist/logger.js.map +0 -1
  209. package/dist/main.d.ts.map +0 -1
  210. package/dist/main.js.map +0 -1
  211. package/dist/presets.d.ts.map +0 -1
  212. package/dist/presets.js.map +0 -1
  213. package/dist/rules/allowed-tags.d.ts.map +0 -1
  214. package/dist/rules/allowed-tags.js.map +0 -1
  215. package/dist/rules/background-setup-only.d.ts.map +0 -1
  216. package/dist/rules/background-setup-only.js.map +0 -1
  217. package/dist/rules/file-name.d.ts.map +0 -1
  218. package/dist/rules/file-name.js.map +0 -1
  219. package/dist/rules/indentation.d.ts.map +0 -1
  220. package/dist/rules/indentation.js.map +0 -1
  221. package/dist/rules/index.d.ts.map +0 -1
  222. package/dist/rules/index.js.map +0 -1
  223. package/dist/rules/keywords-in-logical-order.d.ts.map +0 -1
  224. package/dist/rules/keywords-in-logical-order.js.map +0 -1
  225. package/dist/rules/max-scenarios-per-file.d.ts.map +0 -1
  226. package/dist/rules/max-scenarios-per-file.js.map +0 -1
  227. package/dist/rules/name-length.d.ts.map +0 -1
  228. package/dist/rules/name-length.js.map +0 -1
  229. package/dist/rules/new-line-at-eof.d.ts.map +0 -1
  230. package/dist/rules/new-line-at-eof.js.map +0 -1
  231. package/dist/rules/no-background-only-scenario.d.ts.map +0 -1
  232. package/dist/rules/no-background-only-scenario.js.map +0 -1
  233. package/dist/rules/no-dupe-feature-names.d.ts.map +0 -1
  234. package/dist/rules/no-dupe-feature-names.js.map +0 -1
  235. package/dist/rules/no-dupe-file-names.d.ts.map +0 -1
  236. package/dist/rules/no-dupe-file-names.js.map +0 -1
  237. package/dist/rules/no-dupe-scenario-names.d.ts.map +0 -1
  238. package/dist/rules/no-dupe-scenario-names.js.map +0 -1
  239. package/dist/rules/no-duplicate-tags.d.ts.map +0 -1
  240. package/dist/rules/no-duplicate-tags.js.map +0 -1
  241. package/dist/rules/no-empty-background.d.ts.map +0 -1
  242. package/dist/rules/no-empty-background.js.map +0 -1
  243. package/dist/rules/no-empty-file.d.ts.map +0 -1
  244. package/dist/rules/no-empty-file.js.map +0 -1
  245. package/dist/rules/no-examples-in-scenarios.d.ts.map +0 -1
  246. package/dist/rules/no-examples-in-scenarios.js.map +0 -1
  247. package/dist/rules/no-files-without-scenarios.d.ts.map +0 -1
  248. package/dist/rules/no-files-without-scenarios.js.map +0 -1
  249. package/dist/rules/no-homogenous-tags.d.ts.map +0 -1
  250. package/dist/rules/no-homogenous-tags.js.map +0 -1
  251. package/dist/rules/no-multiple-empty-lines.d.ts.map +0 -1
  252. package/dist/rules/no-multiple-empty-lines.js.map +0 -1
  253. package/dist/rules/no-partially-commented-tag-lines.d.ts.map +0 -1
  254. package/dist/rules/no-partially-commented-tag-lines.js.map +0 -1
  255. package/dist/rules/no-restricted-patterns.d.ts.map +0 -1
  256. package/dist/rules/no-restricted-patterns.js.map +0 -1
  257. package/dist/rules/no-restricted-tags.d.ts.map +0 -1
  258. package/dist/rules/no-restricted-tags.js.map +0 -1
  259. package/dist/rules/no-scenario-outlines-without-examples.d.ts.map +0 -1
  260. package/dist/rules/no-scenario-outlines-without-examples.js.map +0 -1
  261. package/dist/rules/no-scenarios-without-then.d.ts.map +0 -1
  262. package/dist/rules/no-scenarios-without-then.js.map +0 -1
  263. package/dist/rules/no-scenarios-without-when.d.ts.map +0 -1
  264. package/dist/rules/no-scenarios-without-when.js.map +0 -1
  265. package/dist/rules/no-superfluous-tags.d.ts.map +0 -1
  266. package/dist/rules/no-superfluous-tags.js.map +0 -1
  267. package/dist/rules/no-trailing-spaces.d.ts.map +0 -1
  268. package/dist/rules/no-trailing-spaces.js.map +0 -1
  269. package/dist/rules/no-undeclared-variables.d.ts.map +0 -1
  270. package/dist/rules/no-undeclared-variables.js.map +0 -1
  271. package/dist/rules/no-unnamed-features.d.ts.map +0 -1
  272. package/dist/rules/no-unnamed-features.js.map +0 -1
  273. package/dist/rules/no-unnamed-scenarios.d.ts.map +0 -1
  274. package/dist/rules/no-unnamed-scenarios.js.map +0 -1
  275. package/dist/rules/no-unused-variables.d.ts.map +0 -1
  276. package/dist/rules/no-unused-variables.js.map +0 -1
  277. package/dist/rules/one-space-between-tags.d.ts.map +0 -1
  278. package/dist/rules/one-space-between-tags.js.map +0 -1
  279. package/dist/rules/only-one-when.d.ts.map +0 -1
  280. package/dist/rules/only-one-when.js.map +0 -1
  281. package/dist/rules/required-tags.d.ts.map +0 -1
  282. package/dist/rules/required-tags.js.map +0 -1
  283. package/dist/rules/scenario-size.d.ts.map +0 -1
  284. package/dist/rules/scenario-size.js.map +0 -1
  285. package/dist/rules/use-and.d.ts.map +0 -1
  286. package/dist/rules/use-and.js.map +0 -1
  287. package/dist/rules.d.ts.map +0 -1
  288. package/dist/rules.js.map +0 -1
  289. package/dist/stats/collect.d.ts.map +0 -1
  290. package/dist/stats/collect.js.map +0 -1
  291. package/dist/stats/command.d.ts.map +0 -1
  292. package/dist/stats/command.js.map +0 -1
  293. package/dist/stats/format/index.d.ts.map +0 -1
  294. package/dist/stats/format/index.js.map +0 -1
  295. package/dist/stats/format/json.d.ts.map +0 -1
  296. package/dist/stats/format/json.js.map +0 -1
  297. package/dist/stats/format/markdown.d.ts.map +0 -1
  298. package/dist/stats/format/markdown.js.map +0 -1
  299. package/dist/stats/format/shared.d.ts.map +0 -1
  300. package/dist/stats/format/shared.js.map +0 -1
  301. package/dist/stats/format/text.d.ts.map +0 -1
  302. package/dist/stats/format/text.js.map +0 -1
  303. package/dist/stats/index.d.ts.map +0 -1
  304. package/dist/stats/index.js.map +0 -1
  305. package/dist/stats/normalise.d.ts.map +0 -1
  306. package/dist/stats/normalise.js.map +0 -1
  307. package/dist/stats/similar.d.ts.map +0 -1
  308. package/dist/stats/similar.js.map +0 -1
  309. package/dist/stats/types.d.ts.map +0 -1
  310. package/dist/stats/types.js.map +0 -1
  311. package/dist/suppressions.d.ts.map +0 -1
  312. package/dist/suppressions.js.map +0 -1
  313. package/dist/types.d.ts.map +0 -1
  314. package/dist/types.js.map +0 -1
  315. package/dist/util/case.d.ts.map +0 -1
  316. package/dist/util/case.js.map +0 -1
  317. package/dist/util/collections.d.ts.map +0 -1
  318. package/dist/util/collections.js.map +0 -1
  319. package/dist/util/glob.d.ts.map +0 -1
  320. package/dist/util/glob.js.map +0 -1
  321. package/dist/util/json.d.ts.map +0 -1
  322. package/dist/util/json.js.map +0 -1
  323. package/dist/util/lines.d.ts.map +0 -1
  324. package/dist/util/lines.js.map +0 -1
  325. package/dist/util/location.d.ts.map +0 -1
  326. package/dist/util/location.js.map +0 -1
  327. package/dist/util/stream.d.ts.map +0 -1
  328. package/dist/util/stream.js.map +0 -1
  329. package/dist/util/xml.d.ts.map +0 -1
  330. package/dist/util/xml.js.map +0 -1
  331. package/dist/version.d.ts.map +0 -1
  332. package/dist/version.js.map +0 -1
  333. package/dist/watch.d.ts.map +0 -1
  334. package/dist/watch.js.map +0 -1
@@ -2,11 +2,13 @@ import { getNodeType } from '../gherkin/keywords.js';
2
2
  import { taggedNodesOf } from '../gherkin/traverse.js';
3
3
  import { mergeDefaults } from '../util/collections.js';
4
4
  import { at } from '../util/location.js';
5
+ import { invalidPatterns } from '../util/patterns.js';
5
6
  const name = 'no-restricted-tags';
6
7
  const availableConfigs = { tags: [], patterns: [] };
7
8
  const rule = {
8
9
  name,
9
10
  availableConfigs,
11
+ verifySettings: (settings) => invalidPatterns('patterns', settings['patterns']),
10
12
  run(feature, _file, configuration) {
11
13
  if (feature === undefined) {
12
14
  return [];
@@ -32,4 +34,3 @@ const rule = {
32
34
  },
33
35
  };
34
36
  export default rule;
35
- //# sourceMappingURL=no-restricted-tags.js.map
@@ -1,4 +1,3 @@
1
1
  import type { LintRule } from '../types.ts';
2
2
  declare const rule: LintRule;
3
3
  export default rule;
4
- //# sourceMappingURL=no-scenario-outlines-without-examples.d.ts.map
@@ -26,4 +26,3 @@ const rule = {
26
26
  },
27
27
  };
28
28
  export default rule;
29
- //# sourceMappingURL=no-scenario-outlines-without-examples.js.map
@@ -1,4 +1,3 @@
1
1
  import type { LintRule } from '../types.ts';
2
2
  declare const rule: LintRule;
3
3
  export default rule;
4
- //# sourceMappingURL=no-scenarios-without-then.d.ts.map
@@ -47,4 +47,3 @@ const rule = {
47
47
  },
48
48
  };
49
49
  export default rule;
50
- //# sourceMappingURL=no-scenarios-without-then.js.map
@@ -1,4 +1,3 @@
1
1
  import type { LintRule } from '../types.ts';
2
2
  declare const rule: LintRule;
3
3
  export default rule;
4
- //# sourceMappingURL=no-scenarios-without-when.d.ts.map
@@ -47,4 +47,3 @@ const rule = {
47
47
  },
48
48
  };
49
49
  export default rule;
50
- //# sourceMappingURL=no-scenarios-without-when.js.map
@@ -1,4 +1,3 @@
1
1
  import type { LintRule } from '../types.ts';
2
2
  declare const rule: LintRule;
3
3
  export default rule;
4
- //# sourceMappingURL=no-superfluous-tags.d.ts.map
@@ -37,4 +37,3 @@ const rule = {
37
37
  },
38
38
  };
39
39
  export default rule;
40
- //# sourceMappingURL=no-superfluous-tags.js.map
@@ -1,4 +1,3 @@
1
1
  import type { LintRule } from '../types.ts';
2
2
  declare const rule: LintRule;
3
3
  export default rule;
4
- //# sourceMappingURL=no-trailing-spaces.d.ts.map
@@ -1,11 +1,21 @@
1
- import { atLineColumn } from '../util/location.js';
1
+ import { markDocStrings } from '../util/lines.js';
2
+ import { atLineColumn, columnOf } from '../util/location.js';
2
3
  const name = 'no-trailing-spaces';
3
4
  const TRAILING_WHITESPACE = /[\t ]+$/;
4
5
  const rule = {
5
6
  name,
6
- run(_feature, file) {
7
+ run(feature, file) {
7
8
  const errors = [];
9
+ const inDocString = markDocStrings(file.lines, feature);
8
10
  file.lines.forEach((line, index) => {
11
+ // The content of a doc string is data - expected output, a request
12
+ // body - where trailing spaces may be the point. Its delimiters are
13
+ // layout like any other line.
14
+ const trimmed = line.trim();
15
+ const isDelimiter = trimmed.startsWith('"""') || trimmed.startsWith('```');
16
+ if (inDocString[index] === true && !isDelimiter) {
17
+ return;
18
+ }
9
19
  const trailing = TRAILING_WHITESPACE.exec(line);
10
20
  if (trailing !== null) {
11
21
  errors.push({
@@ -13,7 +23,7 @@ const rule = {
13
23
  rule: name,
14
24
  // Point at the first character of the run, so an editor can
15
25
  // underline exactly what has to go.
16
- ...atLineColumn(index + 1, trailing.index + 1),
26
+ ...atLineColumn(index + 1, columnOf(line, trailing.index)),
17
27
  });
18
28
  }
19
29
  });
@@ -21,4 +31,3 @@ const rule = {
21
31
  },
22
32
  };
23
33
  export default rule;
24
- //# sourceMappingURL=no-trailing-spaces.js.map
@@ -1,4 +1,3 @@
1
1
  import type { LintRule } from '../types.ts';
2
2
  declare const rule: LintRule;
3
3
  export default rule;
4
- //# sourceMappingURL=no-undeclared-variables.d.ts.map
@@ -14,17 +14,19 @@ const rule = {
14
14
  if (scenario.examples.length === 0) {
15
15
  continue;
16
16
  }
17
- const { declared, used } = variablesOf(scenario);
17
+ const { declared, tables, used } = variablesOf(scenario);
18
18
  for (const [variable, positions] of used) {
19
- if (declared.has(variable)) {
20
- continue;
21
- }
22
- for (const position of positions) {
23
- errors.push({
24
- message: `Step variable "${variable}" does not exist in the examples table`,
25
- rule: name,
26
- ...position,
27
- });
19
+ // Declared nowhere is one mistake; declared in some tables but not
20
+ // all is another, and the table leaving it out is worth naming.
21
+ const messages = !declared.has(variable)
22
+ ? [`Step variable "${variable}" does not exist in the examples table`]
23
+ : tables
24
+ .filter((table) => !table.columns.has(variable))
25
+ .map((table) => `Step variable "${variable}" does not exist in the examples table on line ${table.line}`);
26
+ for (const message of messages) {
27
+ for (const position of positions) {
28
+ errors.push({ message, rule: name, ...position });
29
+ }
28
30
  }
29
31
  }
30
32
  }
@@ -32,4 +34,3 @@ const rule = {
32
34
  },
33
35
  };
34
36
  export default rule;
35
- //# sourceMappingURL=no-undeclared-variables.js.map
@@ -1,4 +1,3 @@
1
1
  import type { LintRule } from '../types.ts';
2
2
  declare const rule: LintRule;
3
3
  export default rule;
4
- //# sourceMappingURL=no-unnamed-features.d.ts.map
@@ -16,4 +16,3 @@ const rule = {
16
16
  },
17
17
  };
18
18
  export default rule;
19
- //# sourceMappingURL=no-unnamed-features.js.map
@@ -1,4 +1,3 @@
1
1
  import type { LintRule } from '../types.ts';
2
2
  declare const rule: LintRule;
3
3
  export default rule;
4
- //# sourceMappingURL=no-unnamed-scenarios.d.ts.map
@@ -21,4 +21,3 @@ const rule = {
21
21
  },
22
22
  };
23
23
  export default rule;
24
- //# sourceMappingURL=no-unnamed-scenarios.js.map
@@ -1,4 +1,3 @@
1
1
  import type { LintRule } from '../types.ts';
2
2
  declare const rule: LintRule;
3
3
  export default rule;
4
- //# sourceMappingURL=no-unused-variables.d.ts.map
@@ -33,4 +33,3 @@ const rule = {
33
33
  },
34
34
  };
35
35
  export default rule;
36
- //# sourceMappingURL=no-unused-variables.js.map
@@ -1,4 +1,3 @@
1
1
  import type { LintRule } from '../types.ts';
2
2
  declare const rule: LintRule;
3
3
  export default rule;
4
- //# sourceMappingURL=one-space-between-tags.d.ts.map
@@ -8,7 +8,9 @@ function checkTags(tags, errors) {
8
8
  for (let index = 0; index < ordered.length - 1; index++) {
9
9
  const current = ordered[index];
10
10
  const next = ordered[index + 1];
11
- const endOfCurrent = (current.location.column ?? 0) + current.name.length;
11
+ // Gherkin counts columns in characters, not in the UTF-16 units that
12
+ // .length counts, so a tag holding an emoji is measured the same way.
13
+ const endOfCurrent = (current.location.column ?? 0) + [...current.name].length;
12
14
  if (endOfCurrent < (next.location.column ?? 0) - 1) {
13
15
  errors.push({
14
16
  message: `There is more than one space between the tags ${current.name} and ${next.name}`,
@@ -33,4 +35,3 @@ const rule = {
33
35
  },
34
36
  };
35
37
  export default rule;
36
- //# sourceMappingURL=one-space-between-tags.js.map
@@ -1,4 +1,3 @@
1
1
  import type { LintRule } from '../types.ts';
2
2
  declare const rule: LintRule;
3
3
  export default rule;
4
- //# sourceMappingURL=only-one-when.d.ts.map
@@ -28,15 +28,16 @@ const rule = {
28
28
  let firstViolation = { line: 0 };
29
29
  for (const step of scenario.steps) {
30
30
  const keyword = getNeutralKeyword(step, feature.language);
31
- // An `And` carries on from whichever keyword came before it, however
32
- // many of them are chained together.
33
- const continuesWhen = keyword === 'and' && lastRealKeyword === 'when';
31
+ // An `And` or `*` carries on from whichever keyword came before it,
32
+ // however many of them are chained together.
33
+ const continues = keyword === 'and' || keyword === 'star';
34
+ const continuesWhen = continues && lastRealKeyword === 'when';
34
35
  if (keyword !== 'when' && !continuesWhen) {
35
36
  lastRealKeyword = keyword;
36
37
  continue;
37
38
  }
38
39
  lastRealKeyword = 'when';
39
- if (keyword === 'and' && !countAnd) {
40
+ if (continues && !countAnd) {
40
41
  continue;
41
42
  }
42
43
  whenCount++;
@@ -56,4 +57,3 @@ const rule = {
56
57
  },
57
58
  };
58
59
  export default rule;
59
- //# sourceMappingURL=only-one-when.js.map
@@ -1,4 +1,3 @@
1
1
  import type { LintRule } from '../types.ts';
2
2
  declare const rule: LintRule;
3
3
  export default rule;
4
- //# sourceMappingURL=required-tags.d.ts.map
@@ -2,25 +2,36 @@ import { getNodeType } from '../gherkin/keywords.js';
2
2
  import { scenariosOf } from '../gherkin/traverse.js';
3
3
  import { mergeDefaults } from '../util/collections.js';
4
4
  import { at } from '../util/location.js';
5
+ import { invalidPatterns } from '../util/patterns.js';
5
6
  const name = 'required-tags';
6
7
  const availableConfigs = { tags: [], ignoreUntagged: true };
7
8
  const rule = {
8
9
  name,
9
10
  availableConfigs,
11
+ verifySettings: (settings) => invalidPatterns('tags', settings['tags']),
10
12
  run(feature, _file, configuration) {
11
13
  if (feature === undefined) {
12
14
  return [];
13
15
  }
14
16
  const config = mergeDefaults(availableConfigs, configuration);
15
17
  const errors = [];
16
- for (const { scenario } of scenariosOf(feature)) {
18
+ for (const { scenario, rule: parent } of scenariosOf(feature)) {
17
19
  if (config.ignoreUntagged && scenario.tags.length === 0) {
18
20
  continue;
19
21
  }
22
+ // A scenario runs with the tags of its Feature and Rule as well as its
23
+ // own, and each Examples table's rows with that table's tags on top.
24
+ // Asking for the tag to be repeated on the scenario would only have
25
+ // no-superfluous-tags complain about it.
26
+ const inherited = [...feature.tags, ...(parent?.tags ?? []), ...scenario.tags];
27
+ const tagSets = scenario.examples.length === 0
28
+ ? [inherited]
29
+ : scenario.examples.map((examples) => [...inherited, ...examples.tags]);
20
30
  const scenarioType = getNodeType(scenario, feature.language);
21
31
  for (const required of config.tags) {
22
32
  const pattern = new RegExp(required);
23
- if (!scenario.tags.some((tag) => pattern.test(tag.name))) {
33
+ const found = tagSets.every((tags) => tags.some((tag) => pattern.test(tag.name)));
34
+ if (!found) {
24
35
  errors.push({
25
36
  message: `No tag found matching ${required} for ${scenarioType}`,
26
37
  rule: name,
@@ -33,4 +44,3 @@ const rule = {
33
44
  },
34
45
  };
35
46
  export default rule;
36
- //# sourceMappingURL=required-tags.js.map
@@ -1,4 +1,3 @@
1
1
  import type { LintRule } from '../types.ts';
2
2
  declare const rule: LintRule;
3
3
  export default rule;
4
- //# sourceMappingURL=scenario-size.d.ts.map
@@ -34,4 +34,3 @@ const rule = {
34
34
  },
35
35
  };
36
36
  export default rule;
37
- //# sourceMappingURL=scenario-size.js.map
@@ -1,4 +1,3 @@
1
1
  import type { LintRule } from '../types.ts';
2
2
  declare const rule: LintRule;
3
3
  export default rule;
4
- //# sourceMappingURL=use-and.d.ts.map
@@ -13,7 +13,8 @@ const rule = {
13
13
  let previousKeyword;
14
14
  for (const step of node.steps) {
15
15
  const keyword = getNeutralKeyword(step, feature.language);
16
- if (keyword === 'and') {
16
+ // And and * already carry on from the step before them.
17
+ if (keyword === 'and' || keyword === 'star') {
17
18
  continue;
18
19
  }
19
20
  if (keyword === previousKeyword) {
@@ -30,4 +31,3 @@ const rule = {
30
31
  },
31
32
  };
32
33
  export default rule;
33
- //# sourceMappingURL=use-and.js.map
package/dist/rules.d.ts CHANGED
@@ -59,4 +59,3 @@ export declare function finishRun(rules: RuleRegistry, configuration: Configurat
59
59
  * checking a single file wants.
60
60
  */
61
61
  export declare function runEnabledRules(feature: Feature | undefined, file: FeatureFile, configuration: Configuration, rules: RuleRegistry, run?: Run): Promise<RuleError[]>;
62
- //# sourceMappingURL=rules.d.ts.map
package/dist/rules.js CHANGED
@@ -9,6 +9,7 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
9
9
  /**
10
10
  * Assembling the set of rules available to a run, and running them.
11
11
  */
12
+ import fs from 'node:fs';
12
13
  import path from 'node:path';
13
14
  import { pathToFileURL } from 'node:url';
14
15
  import { BUILT_IN_RULES } from './rules/index.js';
@@ -35,7 +36,21 @@ function extractRule(loaded, source) {
35
36
  }
36
37
  async function loadRulesFrom(directory) {
37
38
  const resolved = path.resolve(directory);
38
- const files = globSync(`*.${RULE_EXTENSIONS}`, { cwd: resolved });
39
+ // A directory that is not there would otherwise contribute no rules and no
40
+ // complaint, and a run meant to include them would pass without them.
41
+ let stats;
42
+ try {
43
+ stats = fs.statSync(resolved);
44
+ }
45
+ catch {
46
+ throw new Error(`Could not find the rules directory "${directory}".`);
47
+ }
48
+ if (!stats.isDirectory()) {
49
+ throw new Error(`The rules directory "${directory}" is not a directory.`);
50
+ }
51
+ // Declaration files sit beside TypeScript rules as a matter of course, and
52
+ // hold types, not code.
53
+ const files = globSync(`*.${RULE_EXTENSIONS}`, { cwd: resolved }).filter((file) => !/\.d\.[mc]?ts$/u.test(file));
39
54
  const loaded = [];
40
55
  for (const file of files) {
41
56
  const absolute = path.join(resolved, file);
@@ -136,6 +151,28 @@ export function beginRun(rules, configuration) {
136
151
  }
137
152
  return run;
138
153
  }
154
+ /**
155
+ * The line a finding names, or 0 - a finding about the whole file - when a
156
+ * custom rule gave none, or something that is not a line number. Passed on
157
+ * as it was, it would print as `undefined` where the line belongs.
158
+ */
159
+ function lineOf(finding) {
160
+ const { line } = finding;
161
+ return typeof line === 'number' && Number.isInteger(line) && line >= 0 ? line : 0;
162
+ }
163
+ /**
164
+ * The finding reported in place of a rule's own when it hands back something
165
+ * other than a list. Iterating it anyway would throw somewhere far from the
166
+ * rule, and the message would name whatever happened to be running there.
167
+ */
168
+ function notAList(ruleName, found) {
169
+ const what = found === null ? 'null' : typeof found;
170
+ return {
171
+ message: `Rule "${ruleName}" returned ${what} instead of an array of findings`,
172
+ rule: 'unexpected-error',
173
+ line: 0,
174
+ };
175
+ }
139
176
  /**
140
177
  * Ends a run, collecting what could only be worked out once every file had
141
178
  * been seen.
@@ -153,8 +190,12 @@ export async function finishRun(rules, configuration, run) {
153
190
  const severity = getRuleSeverity(config);
154
191
  try {
155
192
  const found = await rule.onRunEnd(getRuleSettings(config), run.contextFor(rule.name));
193
+ if (!Array.isArray(found)) {
194
+ findings.push(notAList(rule.name, found));
195
+ continue;
196
+ }
156
197
  for (const finding of found) {
157
- findings.push({ severity, ...finding });
198
+ findings.push({ severity, ...finding, line: lineOf(finding) });
158
199
  }
159
200
  }
160
201
  catch (thrown) {
@@ -190,6 +231,7 @@ export async function runEnabledRules(feature, file, configuration, rules, run =
190
231
  continue;
191
232
  }
192
233
  const severity = getRuleSeverity(config);
234
+ // Typed as what a custom rule could really hand back, not what it should.
193
235
  let found;
194
236
  try {
195
237
  found = await rule.run(feature, file, getRuleSettings(config), run.contextFor(rule.name));
@@ -206,12 +248,15 @@ export async function runEnabledRules(feature, file, configuration, rules, run =
206
248
  });
207
249
  continue;
208
250
  }
251
+ if (!Array.isArray(found)) {
252
+ errors.push(notAList(rule.name, found));
253
+ continue;
254
+ }
209
255
  for (const error of found) {
210
256
  // The configuration decides how loudly a rule reports, so a custom rule
211
257
  // needs no say in it - but one that sets a severity itself is respected.
212
- errors.push({ severity, ...error });
258
+ errors.push({ severity, ...error, line: lineOf(error) });
213
259
  }
214
260
  }
215
261
  return errors;
216
262
  }
217
- //# sourceMappingURL=rules.js.map
@@ -28,4 +28,3 @@ export declare function collectStatistics(parsed: readonly ParseResult[], option
28
28
  * suite of any size costs the same as the report it produces.
29
29
  */
30
30
  export declare function collectStatisticsFrom(parsed: Sequence<ParseResult>, options?: CollectOptions): Promise<Statistics>;
31
- //# sourceMappingURL=collect.d.ts.map
@@ -246,4 +246,3 @@ export async function collectStatisticsFrom(parsed, options = {}) {
246
246
  }
247
247
  return summarise(tally, options);
248
248
  }
249
- //# sourceMappingURL=collect.js.map
@@ -1,4 +1,3 @@
1
1
  import type { Diagnostics } from '../diagnostics.ts';
2
2
  export declare function statsUsage(): string;
3
3
  export declare function runStats(argv: readonly string[], diagnostics?: Diagnostics): Promise<number>;
4
- //# sourceMappingURL=command.d.ts.map
@@ -6,7 +6,9 @@
6
6
  * ever be the reason a build goes red. Only being unable to run at all -
7
7
  * an option that makes no sense, a path that names nothing - fails.
8
8
  */
9
+ import fs from 'node:fs';
9
10
  import { parseArgs } from 'node:util';
11
+ import { DEFAULT_CONFIG_FILE_NAME, readConfiguredLanguage } from '../config-parser.js';
10
12
  import { EXIT_OK, EXIT_USAGE } from '../exit-codes.js';
11
13
  import { DEFAULT_IGNORE_FILE_NAME, findFeatureFileStream } from '../feature-finder.js';
12
14
  import { isKnownLanguage } from '../gherkin/dialects.js';
@@ -24,7 +26,10 @@ export function statsUsage() {
24
26
  'Options:',
25
27
  ` -f, --format <format> output format: ${Object.keys(STATS_FORMATTERS).join(', ')}`,
26
28
  ` (default: ${DEFAULT_STATS_FORMAT})`,
27
- ` -i, --ignore <globs> comma separated globs to skip, overriding ${DEFAULT_IGNORE_FILE_NAME}`,
29
+ ` -c, --config <path> configuration file to take the language from`,
30
+ ` (default: ${DEFAULT_CONFIG_FILE_NAME})`,
31
+ ` -i, --ignore <globs> comma separated globs to skip, overriding ${DEFAULT_IGNORE_FILE_NAME};`,
32
+ ' may be given more than once',
28
33
  ' -l, --language <code> dialect for files with no "# language:" header',
29
34
  ` --top <n> how many entries each list shows (default: ${DEFAULT_TOP})`,
30
35
  ' -h, --help show this message',
@@ -41,7 +46,8 @@ export async function runStats(argv, diagnostics = SILENT) {
41
46
  args: [...argv],
42
47
  options: {
43
48
  format: { type: 'string', short: 'f' },
44
- ignore: { type: 'string', short: 'i' },
49
+ config: { type: 'string', short: 'c' },
50
+ ignore: { type: 'string', short: 'i', multiple: true },
45
51
  language: { type: 'string', short: 'l' },
46
52
  top: { type: 'string' },
47
53
  help: { type: 'boolean', short: 'h' },
@@ -72,8 +78,10 @@ export async function runStats(argv, diagnostics = SILENT) {
72
78
  }
73
79
  let top = DEFAULT_TOP;
74
80
  if (values.top !== undefined) {
75
- top = Number(values.top);
76
- if (!Number.isInteger(top) || top < 1) {
81
+ // Digits only: Number() would also take 0x10, 1e3 and ' 3', none of which
82
+ // anybody means as a count.
83
+ top = /^\d+$/u.test(values.top) ? Number(values.top) : Number.NaN;
84
+ if (!Number.isSafeInteger(top) || top < 1) {
77
85
  diagnostics.report({
78
86
  level: 'error',
79
87
  message: `--top needs a whole number of at least 1, not "${values.top}".`,
@@ -81,7 +89,16 @@ export async function runStats(argv, diagnostics = SILENT) {
81
89
  return EXIT_USAGE;
82
90
  }
83
91
  }
84
- const language = values.language;
92
+ if (values.config !== undefined && !fs.existsSync(values.config)) {
93
+ diagnostics.report({
94
+ level: 'error',
95
+ message: `Could not find specified config file "${values.config}"`,
96
+ });
97
+ return EXIT_USAGE;
98
+ }
99
+ // The same dialect the linter would read the files in: --language, or else
100
+ // the configuration's. Nothing else in the configuration matters here.
101
+ const language = values.language ?? (await readConfiguredLanguage(values.config));
85
102
  if (language !== undefined && !isKnownLanguage(language)) {
86
103
  diagnostics.report({
87
104
  level: 'error',
@@ -89,7 +106,8 @@ export async function runStats(argv, diagnostics = SILENT) {
89
106
  });
90
107
  return EXIT_USAGE;
91
108
  }
92
- const ignore = values.ignore?.split(',').map((pattern) => pattern.trim());
109
+ // Given more than once, the lists add up rather than the last one winning.
110
+ const ignore = values.ignore?.flatMap((list) => list.split(',').map((pattern) => pattern.trim()));
93
111
  const { files, invalidPatterns } = findFeatureFileStream(positionals, ignore);
94
112
  if (invalidPatterns.length > 0) {
95
113
  for (const pattern of invalidPatterns) {
@@ -110,4 +128,3 @@ export async function runStats(argv, diagnostics = SILENT) {
110
128
  console.log(formatter(statistics, { top }));
111
129
  return EXIT_OK;
112
130
  }
113
- //# sourceMappingURL=command.js.map
@@ -22,4 +22,3 @@ export declare function getStatsFormatter(format: string | undefined): StatsForm
22
22
  export { toJson, toMarkdown, toText };
23
23
  export { DEFAULT_TOP } from './shared.ts';
24
24
  export type { StatsFormatOptions } from './shared.ts';
25
- //# sourceMappingURL=index.d.ts.map
@@ -22,4 +22,3 @@ export function getStatsFormatter(format) {
22
22
  }
23
23
  export { toJson, toMarkdown, toText };
24
24
  export { DEFAULT_TOP } from './shared.js';
25
- //# sourceMappingURL=index.js.map
@@ -7,4 +7,3 @@
7
7
  import type { Statistics } from '../types.ts';
8
8
  /** The whole report, indented so a diff of two runs is readable. */
9
9
  export declare function toJson(statistics: Statistics): string;
10
- //# sourceMappingURL=json.d.ts.map
@@ -2,4 +2,3 @@
2
2
  export function toJson(statistics) {
3
3
  return JSON.stringify(statistics, null, 2);
4
4
  }
5
- //# sourceMappingURL=json.js.map
@@ -5,4 +5,3 @@ import type { Statistics } from '../types.ts';
5
5
  import type { StatsFormatOptions } from './shared.ts';
6
6
  /** The report, as Markdown. */
7
7
  export declare function toMarkdown(statistics: Statistics, options: StatsFormatOptions): string;
8
- //# sourceMappingURL=markdown.d.ts.map
@@ -1,11 +1,30 @@
1
1
  import { andMore, head, location, percent, plural, summarise } from './shared.js';
2
2
  /** A pipe inside a cell would start a column of its own. */
3
- function cell(text) {
3
+ function inCell(text) {
4
4
  return text.replace(/\|/gu, '\\|');
5
5
  }
6
- /** ``` `text` ```, so step text keeps its quotes and angle brackets. */
7
- function code(text) {
8
- return `\`${cell(text)}\``;
6
+ /**
7
+ * Text written into a table cell as it is: Markdown's own characters escaped,
8
+ * so a scenario called `*important*` is not shown in italics, and a line
9
+ * break, which would end the row, made a space.
10
+ */
11
+ function cell(text) {
12
+ return inCell(text.replace(/[\\`*_{}[\]<>#!~]/gu, '\\$&').replace(/\r?\n/gu, ' '));
13
+ }
14
+ /**
15
+ * ``` `text` ```, so step text keeps its quotes and angle brackets.
16
+ *
17
+ * The fence is one backtick longer than the longest run inside the text, so a
18
+ * backtick in the step cannot close it early; a space pads a text starting or
19
+ * ending with one, as CommonMark asks. Pipes are only escaped inside a table,
20
+ * because anywhere else the backslash would be shown.
21
+ */
22
+ function code(text, inTable = true) {
23
+ const longest = Math.max(0, ...(text.match(/`+/gu) ?? []).map((run) => run.length));
24
+ const fence = '`'.repeat(longest + 1);
25
+ const padding = text.startsWith('`') || text.endsWith('`') ? ' ' : '';
26
+ const span = `${fence}${padding}${text}${padding}${fence}`;
27
+ return inTable ? inCell(span) : span;
9
28
  }
10
29
  function table(headings, alignments, rows) {
11
30
  return [
@@ -106,7 +125,7 @@ export function toMarkdown(statistics, options) {
106
125
  }
107
126
  if (tags.usedOnce.length > 0) {
108
127
  const tagsOnce = head(tags.usedOnce, options.top);
109
- lines.push('', '### Tags written exactly once', '', tagsOnce.shown.map(code).join(', '), ...more(tagsOnce.hidden, 'tag'));
128
+ lines.push('', '### Tags written exactly once', '', tagsOnce.shown.map((tag) => code(tag, false)).join(', '), ...more(tagsOnce.hidden, 'tag'));
110
129
  }
111
130
  if (languages.length > 1) {
112
131
  lines.push('', '## Languages', '', ...table(['Dialect', 'Files'], ['left', 'right'], languages.map((language) => [code(language.code), String(language.files)])));
@@ -120,4 +139,3 @@ export function toMarkdown(statistics, options) {
120
139
  }
121
140
  return lines.join('\n');
122
141
  }
123
- //# sourceMappingURL=markdown.js.map
@@ -31,4 +31,3 @@ export declare function head<T>(values: readonly T[], top: number): {
31
31
  shown: T[];
32
32
  hidden: number;
33
33
  };
34
- //# sourceMappingURL=shared.d.ts.map
@@ -34,4 +34,3 @@ export function andMore(hidden, singular, many = `${singular}s`) {
34
34
  export function head(values, top) {
35
35
  return { shown: values.slice(0, top), hidden: Math.max(0, values.length - top) };
36
36
  }
37
- //# sourceMappingURL=shared.js.map
@@ -2,4 +2,3 @@ import type { Statistics } from '../types.ts';
2
2
  import type { StatsFormatOptions } from './shared.ts';
3
3
  /** The report, as a block of text. */
4
4
  export declare function toText(statistics: Statistics, options: StatsFormatOptions): string;
5
- //# sourceMappingURL=text.d.ts.map
@@ -172,4 +172,3 @@ export function toText(statistics, options) {
172
172
  }
173
173
  return lines.join('\n');
174
174
  }
175
- //# sourceMappingURL=text.js.map