@venizia/dev-configs 0.4.6 → 0.4.7-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 (199) hide show
  1. package/LICENSE.md +1 -3
  2. package/README.md +1 -1
  3. package/dist/checks/catalog.d.ts +4 -2
  4. package/dist/checks/catalog.d.ts.map +1 -1
  5. package/dist/checks/catalog.js +72 -68
  6. package/dist/checks/catalog.js.map +1 -1
  7. package/dist/checks/module-cycles.d.ts +11 -9
  8. package/dist/checks/module-cycles.d.ts.map +1 -1
  9. package/dist/checks/module-cycles.js +32 -30
  10. package/dist/checks/module-cycles.js.map +1 -1
  11. package/dist/checks/purity/manifest.d.ts +44 -38
  12. package/dist/checks/purity/manifest.d.ts.map +1 -1
  13. package/dist/checks/purity/manifest.js +121 -115
  14. package/dist/checks/purity/manifest.js.map +1 -1
  15. package/dist/checks/purity/probe.d.ts +22 -18
  16. package/dist/checks/purity/probe.d.ts.map +1 -1
  17. package/dist/checks/purity/probe.js +101 -99
  18. package/dist/checks/purity/probe.js.map +1 -1
  19. package/dist/checks/purity/run.d.ts +18 -16
  20. package/dist/checks/purity/run.d.ts.map +1 -1
  21. package/dist/checks/purity/run.js +90 -86
  22. package/dist/checks/purity/run.js.map +1 -1
  23. package/dist/checks/test-controls.d.ts +17 -15
  24. package/dist/checks/test-controls.d.ts.map +1 -1
  25. package/dist/checks/test-controls.js +71 -69
  26. package/dist/checks/test-controls.js.map +1 -1
  27. package/dist/checks/test-dead-code.d.ts +5 -3
  28. package/dist/checks/test-dead-code.d.ts.map +1 -1
  29. package/dist/checks/test-dead-code.js +23 -21
  30. package/dist/checks/test-dead-code.js.map +1 -1
  31. package/dist/checks/test-mutate.d.ts +12 -7
  32. package/dist/checks/test-mutate.d.ts.map +1 -1
  33. package/dist/checks/test-mutate.js +59 -56
  34. package/dist/checks/test-mutate.js.map +1 -1
  35. package/dist/checks/test-weight.d.ts +11 -8
  36. package/dist/checks/test-weight.d.ts.map +1 -1
  37. package/dist/checks/test-weight.js +98 -94
  38. package/dist/checks/test-weight.js.map +1 -1
  39. package/dist/cli/check.d.ts.map +1 -1
  40. package/dist/cli/check.js +11 -8
  41. package/dist/cli/check.js.map +1 -1
  42. package/dist/cli/codemod/async-style.d.ts +62 -0
  43. package/dist/cli/codemod/async-style.d.ts.map +1 -0
  44. package/dist/cli/codemod/async-style.js +248 -0
  45. package/dist/cli/codemod/async-style.js.map +1 -0
  46. package/dist/cli/codemod/const-classes.d.ts.map +1 -1
  47. package/dist/cli/codemod/const-classes.js +2 -1
  48. package/dist/cli/codemod/const-classes.js.map +1 -1
  49. package/dist/cli/codemod/drop-redundant-casts.d.ts.map +1 -1
  50. package/dist/cli/codemod/drop-redundant-casts.js +2 -1
  51. package/dist/cli/codemod/drop-redundant-casts.js.map +1 -1
  52. package/dist/cli/codemod/files.d.ts +7 -0
  53. package/dist/cli/codemod/files.d.ts.map +1 -1
  54. package/dist/cli/codemod/files.js +33 -0
  55. package/dist/cli/codemod/files.js.map +1 -1
  56. package/dist/cli/codemod/index.d.ts.map +1 -1
  57. package/dist/cli/codemod/index.js +12 -3
  58. package/dist/cli/codemod/index.js.map +1 -1
  59. package/dist/cli/codemod/model-settings.d.ts +7 -5
  60. package/dist/cli/codemod/model-settings.d.ts.map +1 -1
  61. package/dist/cli/codemod/model-settings.js +293 -291
  62. package/dist/cli/codemod/model-settings.js.map +1 -1
  63. package/dist/cli/codemod/namespace-functions/index.d.ts +20 -0
  64. package/dist/cli/codemod/namespace-functions/index.d.ts.map +1 -0
  65. package/dist/cli/codemod/namespace-functions/index.js +182 -0
  66. package/dist/cli/codemod/namespace-functions/index.js.map +1 -0
  67. package/dist/cli/codemod/namespace-functions/logger-scope.d.ts +32 -0
  68. package/dist/cli/codemod/namespace-functions/logger-scope.d.ts.map +1 -0
  69. package/dist/cli/codemod/namespace-functions/logger-scope.js +128 -0
  70. package/dist/cli/codemod/namespace-functions/logger-scope.js.map +1 -0
  71. package/dist/cli/codemod/namespace-functions/mapping.d.ts +66 -0
  72. package/dist/cli/codemod/namespace-functions/mapping.d.ts.map +1 -0
  73. package/dist/cli/codemod/namespace-functions/mapping.js +99 -0
  74. package/dist/cli/codemod/namespace-functions/mapping.js.map +1 -0
  75. package/dist/cli/codemod/namespace-functions/mappings/boot.d.ts +7 -0
  76. package/dist/cli/codemod/namespace-functions/mappings/boot.d.ts.map +1 -0
  77. package/dist/cli/codemod/namespace-functions/mappings/boot.js +28 -0
  78. package/dist/cli/codemod/namespace-functions/mappings/boot.js.map +1 -0
  79. package/dist/cli/codemod/namespace-functions/mappings/connectors.d.ts +4 -0
  80. package/dist/cli/codemod/namespace-functions/mappings/connectors.d.ts.map +1 -0
  81. package/dist/cli/codemod/namespace-functions/mappings/connectors.js +218 -0
  82. package/dist/cli/codemod/namespace-functions/mappings/connectors.js.map +1 -0
  83. package/dist/cli/codemod/namespace-functions/mappings/core-server.d.ts +7 -0
  84. package/dist/cli/codemod/namespace-functions/mappings/core-server.d.ts.map +1 -0
  85. package/dist/cli/codemod/namespace-functions/mappings/core-server.js +162 -0
  86. package/dist/cli/codemod/namespace-functions/mappings/core-server.js.map +1 -0
  87. package/dist/cli/codemod/namespace-functions/mappings/core-worker.d.ts +7 -0
  88. package/dist/cli/codemod/namespace-functions/mappings/core-worker.d.ts.map +1 -0
  89. package/dist/cli/codemod/namespace-functions/mappings/core-worker.js +18 -0
  90. package/dist/cli/codemod/namespace-functions/mappings/core-worker.js.map +1 -0
  91. package/dist/cli/codemod/namespace-functions/mappings/dev-configs.d.ts +7 -0
  92. package/dist/cli/codemod/namespace-functions/mappings/dev-configs.d.ts.map +1 -0
  93. package/dist/cli/codemod/namespace-functions/mappings/dev-configs.js +192 -0
  94. package/dist/cli/codemod/namespace-functions/mappings/dev-configs.js.map +1 -0
  95. package/dist/cli/codemod/namespace-functions/mappings/filter.d.ts +7 -0
  96. package/dist/cli/codemod/namespace-functions/mappings/filter.d.ts.map +1 -0
  97. package/dist/cli/codemod/namespace-functions/mappings/filter.js +30 -0
  98. package/dist/cli/codemod/namespace-functions/mappings/filter.js.map +1 -0
  99. package/dist/cli/codemod/namespace-functions/mappings/helpers.d.ts +16 -0
  100. package/dist/cli/codemod/namespace-functions/mappings/helpers.d.ts.map +1 -0
  101. package/dist/cli/codemod/namespace-functions/mappings/helpers.js +535 -0
  102. package/dist/cli/codemod/namespace-functions/mappings/helpers.js.map +1 -0
  103. package/dist/cli/codemod/namespace-functions/mappings/index.d.ts +4 -0
  104. package/dist/cli/codemod/namespace-functions/mappings/index.d.ts.map +1 -0
  105. package/dist/cli/codemod/namespace-functions/mappings/index.js +25 -0
  106. package/dist/cli/codemod/namespace-functions/mappings/index.js.map +1 -0
  107. package/dist/cli/codemod/namespace-functions/mappings/inversion.d.ts +10 -0
  108. package/dist/cli/codemod/namespace-functions/mappings/inversion.d.ts.map +1 -0
  109. package/dist/cli/codemod/namespace-functions/mappings/inversion.js +81 -0
  110. package/dist/cli/codemod/namespace-functions/mappings/inversion.js.map +1 -0
  111. package/dist/cli/codemod/namespace-functions/mappings/kernel.d.ts +17 -0
  112. package/dist/cli/codemod/namespace-functions/mappings/kernel.d.ts.map +1 -0
  113. package/dist/cli/codemod/namespace-functions/mappings/kernel.js +229 -0
  114. package/dist/cli/codemod/namespace-functions/mappings/kernel.js.map +1 -0
  115. package/dist/cli/codemod/namespace-functions/rewriter.d.ts +61 -0
  116. package/dist/cli/codemod/namespace-functions/rewriter.d.ts.map +1 -0
  117. package/dist/cli/codemod/namespace-functions/rewriter.js +564 -0
  118. package/dist/cli/codemod/namespace-functions/rewriter.js.map +1 -0
  119. package/dist/cli/index.js +2 -0
  120. package/dist/cli/index.js.map +1 -1
  121. package/dist/compilers/bun.d.ts +1 -1
  122. package/dist/compilers/bun.js +1 -1
  123. package/dist/compilers/bun.js.map +1 -1
  124. package/dist/linters/house/await-support.d.ts +74 -0
  125. package/dist/linters/house/await-support.d.ts.map +1 -0
  126. package/dist/linters/house/await-support.js +238 -0
  127. package/dist/linters/house/await-support.js.map +1 -0
  128. package/dist/linters/house/common.d.ts +15 -9
  129. package/dist/linters/house/common.d.ts.map +1 -1
  130. package/dist/linters/house/common.js +20 -15
  131. package/dist/linters/house/common.js.map +1 -1
  132. package/dist/linters/house/configs.d.ts +26 -0
  133. package/dist/linters/house/configs.d.ts.map +1 -1
  134. package/dist/linters/house/configs.js +55 -1
  135. package/dist/linters/house/configs.js.map +1 -1
  136. package/dist/linters/house/const-class-values.rule.d.ts.map +1 -1
  137. package/dist/linters/house/const-class-values.rule.js +27 -19
  138. package/dist/linters/house/const-class-values.rule.js.map +1 -1
  139. package/dist/linters/house/effect-cleanup-consistency.rule.d.ts +17 -0
  140. package/dist/linters/house/effect-cleanup-consistency.rule.d.ts.map +1 -0
  141. package/dist/linters/house/effect-cleanup-consistency.rule.js +87 -0
  142. package/dist/linters/house/effect-cleanup-consistency.rule.js.map +1 -0
  143. package/dist/linters/house/hook-support.d.ts +29 -0
  144. package/dist/linters/house/hook-support.d.ts.map +1 -0
  145. package/dist/linters/house/hook-support.js +72 -0
  146. package/dist/linters/house/hook-support.js.map +1 -0
  147. package/dist/linters/house/index.d.ts +9 -0
  148. package/dist/linters/house/index.d.ts.map +1 -1
  149. package/dist/linters/house/index.js +9 -0
  150. package/dist/linters/house/index.js.map +1 -1
  151. package/dist/linters/house/max-params-own.rule.d.ts.map +1 -1
  152. package/dist/linters/house/max-params-own.rule.js +33 -24
  153. package/dist/linters/house/max-params-own.rule.js.map +1 -1
  154. package/dist/linters/house/no-async-hook-callback.rule.d.ts +18 -0
  155. package/dist/linters/house/no-async-hook-callback.rule.d.ts.map +1 -0
  156. package/dist/linters/house/no-async-hook-callback.rule.js +50 -0
  157. package/dist/linters/house/no-async-hook-callback.rule.js.map +1 -0
  158. package/dist/linters/house/no-await-promise-chain.rule.d.ts +24 -0
  159. package/dist/linters/house/no-await-promise-chain.rule.d.ts.map +1 -0
  160. package/dist/linters/house/no-await-promise-chain.rule.js +298 -0
  161. package/dist/linters/house/no-await-promise-chain.rule.js.map +1 -0
  162. package/dist/linters/house/no-inline-await.rule.d.ts +20 -0
  163. package/dist/linters/house/no-inline-await.rule.d.ts.map +1 -0
  164. package/dist/linters/house/no-inline-await.rule.js +70 -0
  165. package/dist/linters/house/no-inline-await.rule.js.map +1 -0
  166. package/dist/linters/house/no-new-error.rule.js +4 -4
  167. package/dist/linters/house/no-new-error.rule.js.map +1 -1
  168. package/dist/linters/house/no-return-await.rule.d.ts +15 -0
  169. package/dist/linters/house/no-return-await.rule.d.ts.map +1 -0
  170. package/dist/linters/house/no-return-await.rule.js +92 -0
  171. package/dist/linters/house/no-return-await.rule.js.map +1 -0
  172. package/dist/linters/house/no-silent-catch.rule.d.ts +22 -0
  173. package/dist/linters/house/no-silent-catch.rule.d.ts.map +1 -0
  174. package/dist/linters/house/no-silent-catch.rule.js +88 -0
  175. package/dist/linters/house/no-silent-catch.rule.js.map +1 -0
  176. package/dist/linters/house/plugin.d.ts.map +1 -1
  177. package/dist/linters/house/plugin.js +12 -0
  178. package/dist/linters/house/plugin.js.map +1 -1
  179. package/dist/linters/house/promise-chain-support.d.ts +49 -0
  180. package/dist/linters/house/promise-chain-support.d.ts.map +1 -0
  181. package/dist/linters/house/promise-chain-support.js +188 -0
  182. package/dist/linters/house/promise-chain-support.js.map +1 -0
  183. package/dist/linters/rules/no-restricted-properties.rule.js +1 -1
  184. package/dist/linters/rules/no-restricted-properties.rule.js.map +1 -1
  185. package/dist/testing/rejection.helper.d.ts +25 -20
  186. package/dist/testing/rejection.helper.d.ts.map +1 -1
  187. package/dist/testing/rejection.helper.js +33 -31
  188. package/dist/testing/rejection.helper.js.map +1 -1
  189. package/dist/testing/repo-tmp.d.ts +19 -9
  190. package/dist/testing/repo-tmp.d.ts.map +1 -1
  191. package/dist/testing/repo-tmp.js +50 -48
  192. package/dist/testing/repo-tmp.js.map +1 -1
  193. package/dist/testing/spawn.helper.d.ts +12 -10
  194. package/dist/testing/spawn.helper.d.ts.map +1 -1
  195. package/dist/testing/spawn.helper.js +22 -16
  196. package/dist/testing/spawn.helper.js.map +1 -1
  197. package/dist/testing/tmpdir-preload.js +1 -1
  198. package/dist/testing/tmpdir-preload.js.map +1 -1
  199. package/package.json +2 -3
@@ -0,0 +1,62 @@
1
+ import type { Linter } from 'eslint';
2
+ export interface IAsyncStyleReport {
3
+ line: number;
4
+ column: number;
5
+ /** The rule id, or `undefined` for a file ESLint could not parse. */
6
+ ruleId: string | null;
7
+ message: string;
8
+ }
9
+ export interface IAsyncStyleResult {
10
+ output: string;
11
+ changed: boolean;
12
+ /** How many findings of the original source carried a fix, once the fixers changed it. */
13
+ fixes: number;
14
+ /** What is still reported after every pass. */
15
+ reports: IAsyncStyleReport[];
16
+ }
17
+ /** Runs the async-style rules, and only those, over source text with ESLint's own fixer loop. */
18
+ export declare class AsyncStyle {
19
+ /** The `Linter` config: the TypeScript parser and the rules of `asyncStyleConfigs`, at error. */
20
+ static createConfig(): Promise<Linter.Config[]>;
21
+ /**
22
+ * The self-check's config: four scope rules, run on the text before and after the fixers. A hoisted name must be
23
+ * declared once, shadow nothing, be used after it is declared and be used at all; when the fixers break one of these
24
+ * the count of that rule goes up, and the file is left as it was.
25
+ */
26
+ static createChecks(): Promise<Linter.Config[]>;
27
+ /** What got worse between `source` and `output` by the self-check's rules: empty when nothing did. */
28
+ static selfCheck(opts: {
29
+ linter: Linter;
30
+ checks: Linter.Config[];
31
+ source: string;
32
+ output: string;
33
+ filename: string;
34
+ }): string[];
35
+ /**
36
+ * Fixes `source` (ESLint applies up to ten passes) and returns the text and what is left. `filename` is relative to
37
+ * the linter's `cwd`. The fixed text is checked against the original (`checks`): if it has more redeclarations,
38
+ * shadowed names, uses before declaration or unused variables than the original, no fix is returned and the file is
39
+ * reported as `self-check`, so a hoisted name that does not match the expression it replaced never reaches a file.
40
+ */
41
+ static fix(opts: {
42
+ linter: Linter;
43
+ config: Linter.Config[];
44
+ checks: Linter.Config[];
45
+ source: string;
46
+ filename: string;
47
+ }): IAsyncStyleResult;
48
+ }
49
+ /**
50
+ * `devz codemod async-style [paths...] [--write | --check]`: applies the fixers of `no-inline-await`,
51
+ * `no-return-await` and `no-await-promise-chain`, and lists what is left of those and of `no-silent-catch`.
52
+ * It is a dry run unless `--write` is given. `--check` is the same dry run, and exits 1 when anything would
53
+ * change or is left unfixed.
54
+ */
55
+ export declare class AsyncStyleCommand {
56
+ static readonly USAGE = "Usage: devz codemod async-style [paths...] [--write | --check]\n\nApplies the fixers of three house lint rules, so a repository can sweep them without a lint pass:\n\n venizia/no-inline-await `expect(await f())` becomes `const result = await f(); expect(result)`\n venizia/no-return-await `return await f()` becomes `return f()` (`const result = await f(); return result;` in a try)\n venizia/no-await-promise-chain `const x = await f().catch(() => null)` becomes\n `let x; try { x = await f(); } catch (error) { x = null; }`\n\nIt changes only what the fixers can change safely, and lists the rest with its file, line and rule:\nan `await` inside a ternary or logical operand, a loop test, an unbraced `if` branch, or after a call\nthat may have effects; an awaited `.then` or `.finally`, a `.catch` whose handler has a block body or\ncalls something, and an awaited chain that is not the whole initializer of a `const` or `let`; and\nevery venizia/no-silent-catch finding (a handler or catch block that swallows the error), which it never\nfixes: what to log is your decision.\n\n --write write the changed files (without it, nothing is written)\n --check dry run that exits 1 when anything would change or is left unfixed (for CI)\n --help print this text and exit\n\nWith no flag it lists what would change and writes nothing. Inside a git repository it reads the\nfiles git knows (tracked, or untracked and not ignored), and --write refuses a file with local changes\n(changed, staged or untracked): commit or stash it first, so git can undo the codemod.";
57
+ static run(opts: {
58
+ root: string;
59
+ args: string[];
60
+ }): Promise<number>;
61
+ }
62
+ //# sourceMappingURL=async-style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-style.d.ts","sourceRoot":"","sources":["../../../src/cli/codemod/async-style.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAmDrC,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,qEAAqE;IACrE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,0FAA0F;IAC1F,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC9B;AAED,iGAAiG;AACjG,qBAAa,UAAU;IACrB,iGAAiG;WACpF,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IAgBrD;;;;OAIG;WACU,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;IAsBrD,sGAAsG;IACtG,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE;QACrB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,MAAM,EAAE;IAmBZ;;;;;OAKG;IACH,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE;QACf,MAAM,EAAE,MAAM,CAAC;QACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,iBAAiB;CA+CtB;AAED;;;;;GAKG;AACH,qBAAa,iBAAiB;IAC5B,MAAM,CAAC,QAAQ,CAAC,KAAK,+lDAAS;WAEjB,GAAG,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CA8G1E"}
@@ -0,0 +1,248 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AsyncStyleCommand = exports.AsyncStyle = void 0;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ const files_1 = require("./files");
7
+ const USAGE = `Usage: devz codemod async-style [paths...] [--write | --check]
8
+
9
+ Applies the fixers of three house lint rules, so a repository can sweep them without a lint pass:
10
+
11
+ venizia/no-inline-await \`expect(await f())\` becomes \`const result = await f(); expect(result)\`
12
+ venizia/no-return-await \`return await f()\` becomes \`return f()\` (\`const result = await f(); return result;\` in a try)
13
+ venizia/no-await-promise-chain \`const x = await f().catch(() => null)\` becomes
14
+ \`let x; try { x = await f(); } catch (error) { x = null; }\`
15
+
16
+ It changes only what the fixers can change safely, and lists the rest with its file, line and rule:
17
+ an \`await\` inside a ternary or logical operand, a loop test, an unbraced \`if\` branch, or after a call
18
+ that may have effects; an awaited \`.then\` or \`.finally\`, a \`.catch\` whose handler has a block body or
19
+ calls something, and an awaited chain that is not the whole initializer of a \`const\` or \`let\`; and
20
+ every venizia/no-silent-catch finding (a handler or catch block that swallows the error), which it never
21
+ fixes: what to log is your decision.
22
+
23
+ --write write the changed files (without it, nothing is written)
24
+ --check dry run that exits 1 when anything would change or is left unfixed (for CI)
25
+ --help print this text and exit
26
+
27
+ With no flag it lists what would change and writes nothing. Inside a git repository it reads the
28
+ files git knows (tracked, or untracked and not ignored), and --write refuses a file with local changes
29
+ (changed, staged or untracked): commit or stash it first, so git can undo the codemod.`;
30
+ /** A usage error: nothing was read or written. */
31
+ const USAGE_ERROR_CODE = 2;
32
+ /** A file that can hold an `await` or a `catch`. */
33
+ const ASYNC_TEXT = /\b(await|catch)\b/;
34
+ class AsyncStyleFlags {
35
+ static { this.WRITE = '--write'; }
36
+ static { this.CHECK = '--check'; }
37
+ static { this.HELP = '--help'; }
38
+ static { this.HELP_SHORT = '-h'; }
39
+ static { this.SCHEME_SET = new Set([
40
+ this.WRITE,
41
+ this.CHECK,
42
+ this.HELP,
43
+ this.HELP_SHORT,
44
+ ]); }
45
+ static isValid(value) {
46
+ return this.SCHEME_SET.has(value);
47
+ }
48
+ }
49
+ /** Runs the async-style rules, and only those, over source text with ESLint's own fixer loop. */
50
+ class AsyncStyle {
51
+ /** The `Linter` config: the TypeScript parser and the rules of `asyncStyleConfigs`, at error. */
52
+ static async createConfig() {
53
+ const { default: tseslint } = await import('typescript-eslint');
54
+ const { asyncStyleConfigs } = await import('../../linters/house/index.js');
55
+ return [
56
+ {
57
+ files: ['**/*.{ts,tsx,mts,cts}'],
58
+ languageOptions: { parser: tseslint.parser },
59
+ // Only the async-style rules run here, so a `// eslint-disable-next-line` for any other rule looks unused and
60
+ // ESLint's fixer would delete it. A codemod never touches a directive.
61
+ linterOptions: { reportUnusedDisableDirectives: 'off' },
62
+ },
63
+ ...asyncStyleConfigs,
64
+ ];
65
+ }
66
+ /**
67
+ * The self-check's config: four scope rules, run on the text before and after the fixers. A hoisted name must be
68
+ * declared once, shadow nothing, be used after it is declared and be used at all; when the fixers break one of these
69
+ * the count of that rule goes up, and the file is left as it was.
70
+ */
71
+ static async createChecks() {
72
+ const { default: tseslint } = await import('typescript-eslint');
73
+ return [
74
+ {
75
+ files: ['**/*.{ts,tsx,mts,cts}'],
76
+ languageOptions: { parser: tseslint.parser },
77
+ linterOptions: { reportUnusedDisableDirectives: 'off' },
78
+ plugins: { '@typescript-eslint': tseslint.plugin },
79
+ rules: {
80
+ '@typescript-eslint/no-redeclare': 'error',
81
+ '@typescript-eslint/no-shadow': 'error',
82
+ '@typescript-eslint/no-use-before-define': [
83
+ 'error',
84
+ { functions: false, classes: false },
85
+ ],
86
+ '@typescript-eslint/no-unused-vars': ['error', { args: 'none', caughtErrors: 'none' }],
87
+ },
88
+ },
89
+ ];
90
+ }
91
+ /** What got worse between `source` and `output` by the self-check's rules: empty when nothing did. */
92
+ static selfCheck(opts) {
93
+ const { linter, checks, source, output, filename } = opts;
94
+ const count = (text) => {
95
+ const found = new Map();
96
+ for (const message of linter.verify(text, checks, { filename })) {
97
+ const key = message.ruleId ?? 'parse error';
98
+ found.set(key, (found.get(key) ?? 0) + 1);
99
+ }
100
+ return found;
101
+ };
102
+ const was = count(source);
103
+ const now = count(output);
104
+ return [...now]
105
+ .filter(([rule, total]) => total > (was.get(rule) ?? 0))
106
+ .map(([rule, total]) => `${rule}: ${was.get(rule) ?? 0} before, ${total} after`);
107
+ }
108
+ /**
109
+ * Fixes `source` (ESLint applies up to ten passes) and returns the text and what is left. `filename` is relative to
110
+ * the linter's `cwd`. The fixed text is checked against the original (`checks`): if it has more redeclarations,
111
+ * shadowed names, uses before declaration or unused variables than the original, no fix is returned and the file is
112
+ * reported as `self-check`, so a hoisted name that does not match the expression it replaced never reaches a file.
113
+ */
114
+ static fix(opts) {
115
+ const { linter, config, checks, source, filename } = opts;
116
+ // A fix can leave a new finding behind (the try/catch of no-await-promise-chain is a silent catch when the
117
+ // fallback is a constant), so the count is of the fixable findings, not of the findings that went away.
118
+ const fixable = linter
119
+ .verify(source, config, { filename })
120
+ .filter((message) => message.fix !== undefined).length;
121
+ const result = linter.verifyAndFix(source, config, { filename });
122
+ if (result.output !== source) {
123
+ const broken = AsyncStyle.selfCheck({
124
+ linter,
125
+ checks,
126
+ source,
127
+ output: result.output,
128
+ filename,
129
+ });
130
+ if (broken.length > 0) {
131
+ return {
132
+ output: source,
133
+ changed: false,
134
+ fixes: 0,
135
+ reports: [
136
+ {
137
+ line: 1,
138
+ column: 1,
139
+ ruleId: 'self-check',
140
+ message: `the fixers would have made this file worse (${broken.join('; ')}); it is left as it was - fix it by hand`,
141
+ },
142
+ ],
143
+ };
144
+ }
145
+ }
146
+ return {
147
+ output: result.output,
148
+ changed: result.output !== source,
149
+ fixes: result.fixed ? fixable : 0,
150
+ reports: result.messages.map((message) => ({
151
+ line: message.line,
152
+ column: message.column,
153
+ ruleId: message.ruleId,
154
+ message: message.message,
155
+ })),
156
+ };
157
+ }
158
+ }
159
+ exports.AsyncStyle = AsyncStyle;
160
+ /**
161
+ * `devz codemod async-style [paths...] [--write | --check]`: applies the fixers of `no-inline-await`,
162
+ * `no-return-await` and `no-await-promise-chain`, and lists what is left of those and of `no-silent-catch`.
163
+ * It is a dry run unless `--write` is given. `--check` is the same dry run, and exits 1 when anything would
164
+ * change or is left unfixed.
165
+ */
166
+ class AsyncStyleCommand {
167
+ static { this.USAGE = USAGE; }
168
+ static async run(opts) {
169
+ const { root, args } = opts;
170
+ if (args.includes(AsyncStyleFlags.HELP) || args.includes(AsyncStyleFlags.HELP_SHORT)) {
171
+ console.log(USAGE);
172
+ return 0;
173
+ }
174
+ const flags = args.filter((argument) => argument.startsWith('-'));
175
+ const paths = args.filter((argument) => !argument.startsWith('-'));
176
+ const unknown = flags.filter((flag) => !AsyncStyleFlags.isValid(flag));
177
+ if (unknown.length > 0) {
178
+ console.error(`devz codemod: unknown option ${unknown.map((flag) => `"${flag}"`).join(', ')}\n${USAGE}`);
179
+ return USAGE_ERROR_CODE;
180
+ }
181
+ const isWrite = flags.includes(AsyncStyleFlags.WRITE);
182
+ const isCheck = flags.includes(AsyncStyleFlags.CHECK);
183
+ if (isWrite && isCheck) {
184
+ console.error(`devz codemod: ${AsyncStyleFlags.WRITE} and ${AsyncStyleFlags.CHECK} contradict each other\n${USAGE}`);
185
+ return USAGE_ERROR_CODE;
186
+ }
187
+ let linter;
188
+ try {
189
+ const { Linter: EslintLinter } = await import('eslint');
190
+ linter = new EslintLinter({ cwd: root });
191
+ }
192
+ catch {
193
+ console.error('devz codemod: the "eslint" package is required to run the lint fixers');
194
+ return 1;
195
+ }
196
+ const config = await AsyncStyle.createConfig();
197
+ const checks = await AsyncStyle.createChecks();
198
+ const targets = (paths.length > 0 ? paths : ['.']).map((path) => (0, node_path_1.resolve)(root, path));
199
+ let changedCount = 0;
200
+ let fixCount = 0;
201
+ let reportCount = 0;
202
+ let refusedCount = 0;
203
+ for (const target of targets) {
204
+ const files = files_1.CodemodFiles.collect({ target });
205
+ const dirty = isWrite ? files_1.CodemodFiles.dirty({ target }) : undefined;
206
+ if (files.length === 0 && paths.length > 0) {
207
+ console.warn(`devz codemod: no source files under "${(0, node_path_1.relative)(root, target) || target}" (git ignores the path, or it holds none): nothing was read`);
208
+ }
209
+ for (const file of files) {
210
+ const source = (0, node_fs_1.readFileSync)(file, 'utf8');
211
+ if (!ASYNC_TEXT.test(source)) {
212
+ continue;
213
+ }
214
+ const shown = (0, node_path_1.relative)(root, file).split('\\').join('/');
215
+ const result = AsyncStyle.fix({ linter, config, checks, source, filename: shown });
216
+ for (const report of result.reports) {
217
+ reportCount += 1;
218
+ console.warn(`${shown}:${report.line}:${report.column} ${report.ruleId ?? 'parse error'} ${report.message}`);
219
+ }
220
+ if (!result.changed) {
221
+ continue;
222
+ }
223
+ if (dirty?.has(file)) {
224
+ refusedCount += 1;
225
+ console.warn(`refused ${shown} has local changes (commit or stash them, then run again)`);
226
+ continue;
227
+ }
228
+ changedCount += 1;
229
+ fixCount += result.fixes;
230
+ console.log(`${isWrite ? 'changed' : 'would change'} ${shown} (${result.fixes} fix(es))`);
231
+ if (isWrite) {
232
+ (0, node_fs_1.writeFileSync)(file, result.output);
233
+ }
234
+ }
235
+ }
236
+ console.log(`devz codemod async-style: ${changedCount} file(s) ${isWrite ? 'changed' : 'would change'}, ${fixCount} fix(es) ${isWrite ? 'applied' : 'would be applied'}, ${reportCount} left unfixed` +
237
+ (refusedCount > 0 ? `, ${refusedCount} refused` : ''));
238
+ if (!isWrite && changedCount > 0) {
239
+ console.log(`Nothing was written. Run again with ${AsyncStyleFlags.WRITE} to apply.`);
240
+ }
241
+ if (isWrite && refusedCount > 0) {
242
+ return 1;
243
+ }
244
+ return isCheck && (changedCount > 0 || reportCount > 0) ? 1 : 0;
245
+ }
246
+ }
247
+ exports.AsyncStyleCommand = AsyncStyleCommand;
248
+ //# sourceMappingURL=async-style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-style.js","sourceRoot":"","sources":["../../../src/cli/codemod/async-style.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, writeFileSync } from 'node:fs';\nimport { relative, resolve } from 'node:path';\nimport type { Linter } from 'eslint';\nimport { CodemodFiles } from './files';\n\nconst USAGE = `Usage: devz codemod async-style [paths...] [--write | --check]\n\nApplies the fixers of three house lint rules, so a repository can sweep them without a lint pass:\n\n venizia/no-inline-await \\`expect(await f())\\` becomes \\`const result = await f(); expect(result)\\`\n venizia/no-return-await \\`return await f()\\` becomes \\`return f()\\` (\\`const result = await f(); return result;\\` in a try)\n venizia/no-await-promise-chain \\`const x = await f().catch(() => null)\\` becomes\n \\`let x; try { x = await f(); } catch (error) { x = null; }\\`\n\nIt changes only what the fixers can change safely, and lists the rest with its file, line and rule:\nan \\`await\\` inside a ternary or logical operand, a loop test, an unbraced \\`if\\` branch, or after a call\nthat may have effects; an awaited \\`.then\\` or \\`.finally\\`, a \\`.catch\\` whose handler has a block body or\ncalls something, and an awaited chain that is not the whole initializer of a \\`const\\` or \\`let\\`; and\nevery venizia/no-silent-catch finding (a handler or catch block that swallows the error), which it never\nfixes: what to log is your decision.\n\n --write write the changed files (without it, nothing is written)\n --check dry run that exits 1 when anything would change or is left unfixed (for CI)\n --help print this text and exit\n\nWith no flag it lists what would change and writes nothing. Inside a git repository it reads the\nfiles git knows (tracked, or untracked and not ignored), and --write refuses a file with local changes\n(changed, staged or untracked): commit or stash it first, so git can undo the codemod.`;\n\n/** A usage error: nothing was read or written. */\nconst USAGE_ERROR_CODE = 2;\n\n/** A file that can hold an `await` or a `catch`. */\nconst ASYNC_TEXT = /\\b(await|catch)\\b/;\n\nclass AsyncStyleFlags {\n static readonly WRITE = '--write';\n static readonly CHECK = '--check';\n static readonly HELP = '--help';\n static readonly HELP_SHORT = '-h';\n\n static readonly SCHEME_SET = new Set<string>([\n this.WRITE,\n this.CHECK,\n this.HELP,\n this.HELP_SHORT,\n ]);\n\n static isValid(value: string): boolean {\n return this.SCHEME_SET.has(value);\n }\n}\n\nexport interface IAsyncStyleReport {\n line: number;\n column: number;\n /** The rule id, or `undefined` for a file ESLint could not parse. */\n ruleId: string | null;\n message: string;\n}\n\nexport interface IAsyncStyleResult {\n output: string;\n changed: boolean;\n /** How many findings of the original source carried a fix, once the fixers changed it. */\n fixes: number;\n /** What is still reported after every pass. */\n reports: IAsyncStyleReport[];\n}\n\n/** Runs the async-style rules, and only those, over source text with ESLint's own fixer loop. */\nexport class AsyncStyle {\n /** The `Linter` config: the TypeScript parser and the rules of `asyncStyleConfigs`, at error. */\n static async createConfig(): Promise<Linter.Config[]> {\n const { default: tseslint } = await import('typescript-eslint');\n const { asyncStyleConfigs } = await import('../../linters/house/index.js');\n\n return [\n {\n files: ['**/*.{ts,tsx,mts,cts}'],\n languageOptions: { parser: tseslint.parser },\n // Only the async-style rules run here, so a `// eslint-disable-next-line` for any other rule looks unused and\n // ESLint's fixer would delete it. A codemod never touches a directive.\n linterOptions: { reportUnusedDisableDirectives: 'off' },\n },\n ...asyncStyleConfigs,\n ];\n }\n\n /**\n * The self-check's config: four scope rules, run on the text before and after the fixers. A hoisted name must be\n * declared once, shadow nothing, be used after it is declared and be used at all; when the fixers break one of these\n * the count of that rule goes up, and the file is left as it was.\n */\n static async createChecks(): Promise<Linter.Config[]> {\n const { default: tseslint } = await import('typescript-eslint');\n\n return [\n {\n files: ['**/*.{ts,tsx,mts,cts}'],\n languageOptions: { parser: tseslint.parser },\n linterOptions: { reportUnusedDisableDirectives: 'off' },\n plugins: { '@typescript-eslint': tseslint.plugin as never },\n rules: {\n '@typescript-eslint/no-redeclare': 'error',\n '@typescript-eslint/no-shadow': 'error',\n '@typescript-eslint/no-use-before-define': [\n 'error',\n { functions: false, classes: false },\n ],\n '@typescript-eslint/no-unused-vars': ['error', { args: 'none', caughtErrors: 'none' }],\n },\n },\n ];\n }\n\n /** What got worse between `source` and `output` by the self-check's rules: empty when nothing did. */\n static selfCheck(opts: {\n linter: Linter;\n checks: Linter.Config[];\n source: string;\n output: string;\n filename: string;\n }): string[] {\n const { linter, checks, source, output, filename } = opts;\n const count = (text: string): Map<string, number> => {\n const found = new Map<string, number>();\n for (const message of linter.verify(text, checks, { filename })) {\n const key = message.ruleId ?? 'parse error';\n found.set(key, (found.get(key) ?? 0) + 1);\n }\n\n return found;\n };\n const was = count(source);\n const now = count(output);\n\n return [...now]\n .filter(([rule, total]) => total > (was.get(rule) ?? 0))\n .map(([rule, total]) => `${rule}: ${was.get(rule) ?? 0} before, ${total} after`);\n }\n\n /**\n * Fixes `source` (ESLint applies up to ten passes) and returns the text and what is left. `filename` is relative to\n * the linter's `cwd`. The fixed text is checked against the original (`checks`): if it has more redeclarations,\n * shadowed names, uses before declaration or unused variables than the original, no fix is returned and the file is\n * reported as `self-check`, so a hoisted name that does not match the expression it replaced never reaches a file.\n */\n static fix(opts: {\n linter: Linter;\n config: Linter.Config[];\n checks: Linter.Config[];\n source: string;\n filename: string;\n }): IAsyncStyleResult {\n const { linter, config, checks, source, filename } = opts;\n // A fix can leave a new finding behind (the try/catch of no-await-promise-chain is a silent catch when the\n // fallback is a constant), so the count is of the fixable findings, not of the findings that went away.\n const fixable = linter\n .verify(source, config, { filename })\n .filter((message) => message.fix !== undefined).length;\n const result = linter.verifyAndFix(source, config, { filename });\n\n if (result.output !== source) {\n const broken = AsyncStyle.selfCheck({\n linter,\n checks,\n source,\n output: result.output,\n filename,\n });\n\n if (broken.length > 0) {\n return {\n output: source,\n changed: false,\n fixes: 0,\n reports: [\n {\n line: 1,\n column: 1,\n ruleId: 'self-check',\n message: `the fixers would have made this file worse (${broken.join('; ')}); it is left as it was - fix it by hand`,\n },\n ],\n };\n }\n }\n\n return {\n output: result.output,\n changed: result.output !== source,\n fixes: result.fixed ? fixable : 0,\n reports: result.messages.map((message) => ({\n line: message.line,\n column: message.column,\n ruleId: message.ruleId,\n message: message.message,\n })),\n };\n }\n}\n\n/**\n * `devz codemod async-style [paths...] [--write | --check]`: applies the fixers of `no-inline-await`,\n * `no-return-await` and `no-await-promise-chain`, and lists what is left of those and of `no-silent-catch`.\n * It is a dry run unless `--write` is given. `--check` is the same dry run, and exits 1 when anything would\n * change or is left unfixed.\n */\nexport class AsyncStyleCommand {\n static readonly USAGE = USAGE;\n\n static async run(opts: { root: string; args: string[] }): Promise<number> {\n const { root, args } = opts;\n\n if (args.includes(AsyncStyleFlags.HELP) || args.includes(AsyncStyleFlags.HELP_SHORT)) {\n console.log(USAGE);\n return 0;\n }\n\n const flags = args.filter((argument) => argument.startsWith('-'));\n const paths = args.filter((argument) => !argument.startsWith('-'));\n\n const unknown = flags.filter((flag) => !AsyncStyleFlags.isValid(flag));\n if (unknown.length > 0) {\n console.error(\n `devz codemod: unknown option ${unknown.map((flag) => `\"${flag}\"`).join(', ')}\\n${USAGE}`,\n );\n return USAGE_ERROR_CODE;\n }\n\n const isWrite = flags.includes(AsyncStyleFlags.WRITE);\n const isCheck = flags.includes(AsyncStyleFlags.CHECK);\n\n if (isWrite && isCheck) {\n console.error(\n `devz codemod: ${AsyncStyleFlags.WRITE} and ${AsyncStyleFlags.CHECK} contradict each other\\n${USAGE}`,\n );\n return USAGE_ERROR_CODE;\n }\n\n let linter: Linter;\n try {\n const { Linter: EslintLinter } = await import('eslint');\n linter = new EslintLinter({ cwd: root });\n } catch {\n console.error('devz codemod: the \"eslint\" package is required to run the lint fixers');\n return 1;\n }\n\n const config = await AsyncStyle.createConfig();\n const checks = await AsyncStyle.createChecks();\n const targets = (paths.length > 0 ? paths : ['.']).map((path) => resolve(root, path));\n let changedCount = 0;\n let fixCount = 0;\n let reportCount = 0;\n let refusedCount = 0;\n\n for (const target of targets) {\n const files = CodemodFiles.collect({ target });\n const dirty = isWrite ? CodemodFiles.dirty({ target }) : undefined;\n\n if (files.length === 0 && paths.length > 0) {\n console.warn(\n `devz codemod: no source files under \"${relative(root, target) || target}\" (git ignores the path, or it holds none): nothing was read`,\n );\n }\n\n for (const file of files) {\n const source = readFileSync(file, 'utf8');\n\n if (!ASYNC_TEXT.test(source)) {\n continue;\n }\n\n const shown = relative(root, file).split('\\\\').join('/');\n const result = AsyncStyle.fix({ linter, config, checks, source, filename: shown });\n\n for (const report of result.reports) {\n reportCount += 1;\n console.warn(\n `${shown}:${report.line}:${report.column} ${report.ruleId ?? 'parse error'} ${report.message}`,\n );\n }\n\n if (!result.changed) {\n continue;\n }\n\n if (dirty?.has(file)) {\n refusedCount += 1;\n console.warn(\n `refused ${shown} has local changes (commit or stash them, then run again)`,\n );\n continue;\n }\n\n changedCount += 1;\n fixCount += result.fixes;\n console.log(`${isWrite ? 'changed' : 'would change'} ${shown} (${result.fixes} fix(es))`);\n\n if (isWrite) {\n writeFileSync(file, result.output);\n }\n }\n }\n\n console.log(\n `devz codemod async-style: ${changedCount} file(s) ${isWrite ? 'changed' : 'would change'}, ${fixCount} fix(es) ${isWrite ? 'applied' : 'would be applied'}, ${reportCount} left unfixed` +\n (refusedCount > 0 ? `, ${refusedCount} refused` : ''),\n );\n\n if (!isWrite && changedCount > 0) {\n console.log(`Nothing was written. Run again with ${AsyncStyleFlags.WRITE} to apply.`);\n }\n\n if (isWrite && refusedCount > 0) {\n return 1;\n }\n\n return isCheck && (changedCount > 0 || reportCount > 0) ? 1 : 0;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"const-classes.d.ts","sourceRoot":"","sources":["../../../src/cli/codemod/const-classes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAGjC,KAAK,WAAW,GAAG,OAAO,EAAE,CAAC;AAU7B,2EAA2E;AAC3E,MAAM,WAAW,mBAAmB;IAClC,sBAAsB;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,oCAAoC;IACpC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAEjE,MAAM,WAAW,mBAAmB;IAClC,qGAAqG;IACrG,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,uDAAuD;IACvD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,SAAS,EAAE,oBAAoB,EAAE,CAAC;CACnC;AA4CD;;;;GAIG;AACH,qBAAa,YAAY;IACvB,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE;QACnB,UAAU,EAAE,WAAW,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,4FAA4F;QAC5F,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,CAAC,EAAE,cAAc,CAAC;QAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,iBAAiB;IA4KrB,OAAO,CAAC,MAAM,CAAC,WAAW;IA8C1B,yDAAyD;IACzD,OAAO,CAAC,MAAM,CAAC,aAAa;IAoD5B,OAAO,CAAC,MAAM,CAAC,UAAU;IAQzB,iIAAiI;IACjI,OAAO,CAAC,MAAM,CAAC,SAAS;IA+BxB,gFAAgF;IAChF,OAAO,CAAC,MAAM,CAAC,YAAY;IAuB3B,OAAO,CAAC,MAAM,CAAC,SAAS;IAqCxB,OAAO,CAAC,MAAM,CAAC,WAAW;IAuB1B,sHAAsH;IACtH,OAAO,CAAC,MAAM,CAAC,UAAU;IAkCzB,OAAO,CAAC,MAAM,CAAC,QAAQ;IA2BvB,wJAAwJ;IACxJ,OAAO,CAAC,MAAM,CAAC,UAAU;CAqD1B;AAyDD,mEAAmE;AACnE,qBAAa,mBAAmB;IAC9B,MAAM,CAAC,QAAQ,CAAC,KAAK,ipDAAS;WAEjB,GAAG,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CA2K1E"}
1
+ {"version":3,"file":"const-classes.d.ts","sourceRoot":"","sources":["../../../src/cli/codemod/const-classes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAGjC,KAAK,WAAW,GAAG,OAAO,EAAE,CAAC;AAU7B,2EAA2E;AAC3E,MAAM,WAAW,mBAAmB;IAClC,sBAAsB;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,oCAAoC;IACpC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAEjE,MAAM,WAAW,mBAAmB;IAClC,qGAAqG;IACrG,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,OAAO,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,uDAAuD;IACvD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,mBAAmB,EAAE,CAAC;IACjC,SAAS,EAAE,oBAAoB,EAAE,CAAC;CACnC;AA4CD;;;;GAIG;AACH,qBAAa,YAAY;IACvB,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE;QACnB,UAAU,EAAE,WAAW,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,4FAA4F;QAC5F,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,CAAC,EAAE,cAAc,CAAC;QAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,iBAAiB;IA4KrB,OAAO,CAAC,MAAM,CAAC,WAAW;IA8C1B,yDAAyD;IACzD,OAAO,CAAC,MAAM,CAAC,aAAa;IAoD5B,OAAO,CAAC,MAAM,CAAC,UAAU;IAQzB,iIAAiI;IACjI,OAAO,CAAC,MAAM,CAAC,SAAS;IA+BxB,gFAAgF;IAChF,OAAO,CAAC,MAAM,CAAC,YAAY;IAuB3B,OAAO,CAAC,MAAM,CAAC,SAAS;IAqCxB,OAAO,CAAC,MAAM,CAAC,WAAW;IAuB1B,sHAAsH;IACtH,OAAO,CAAC,MAAM,CAAC,UAAU;IAkCzB,OAAO,CAAC,MAAM,CAAC,QAAQ;IA2BvB,wJAAwJ;IACxJ,OAAO,CAAC,MAAM,CAAC,UAAU;CAqD1B;AAyDD,mEAAmE;AACnE,qBAAa,mBAAmB;IAC9B,MAAM,CAAC,QAAQ,CAAC,KAAK,ipDAAS;WAEjB,GAAG,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;CA4K1E"}
@@ -531,7 +531,8 @@ class ConstClassesCommand {
531
531
  }
532
532
  let typescript;
533
533
  try {
534
- typescript = (await import('typescript')).default;
534
+ const result2 = await import('typescript');
535
+ typescript = result2.default;
535
536
  }
536
537
  catch {
537
538
  console.error('devz codemod: the "typescript" package is required to read your sources');