@onrails/codemod 0.2.5 → 0.2.8

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onrails/codemod",
3
- "version": "0.2.5",
3
+ "version": "0.2.8",
4
4
  "description": "Codemods for migrating onto @onrails/result (neverthrow → compat shim, and beyond)",
5
5
  "license": "MIT",
6
6
  "author": "Alan R. Soares",
@@ -42,13 +42,15 @@
42
42
  ".": "./src/index.ts"
43
43
  },
44
44
  "dependencies": {
45
- "@onrails/maybe": "0.2.0",
46
- "@onrails/pattern": "0.2.0",
47
- "@onrails/result": "0.2.0",
48
- "typescript": "^6.0.3"
45
+ "@onrails/maybe": "^0.2.3",
46
+ "@onrails/pattern": "^0.3.3",
47
+ "@onrails/result": "^0.4.0",
48
+ "typescript": "^7.0.2",
49
+ "typescript6": "npm:typescript@^6.0.3"
49
50
  },
50
51
  "scripts": {
51
52
  "typecheck": "tsc --noEmit",
52
- "test": "bun test"
53
+ "test": "bun test",
54
+ "check": "bun run typecheck && bun test"
53
55
  }
54
56
  }
package/src/ast.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { fromNullable, type Maybe, match, none, some } from "@onrails/maybe";
2
- import ts from "typescript";
2
+ import ts from "typescript6";
3
3
  import { TYPE_ONLY_NATIVE } from "./constants.js";
4
4
  import type { Edit } from "./types.js";
5
5
 
@@ -66,9 +66,10 @@ export interface DeprecatedSynonym {
66
66
 
67
67
  /**
68
68
  * Deprecated neverthrow/fp-era synonyms → canonical onrails names.
69
- * Matching is name-based in every engine — neither GritQL nor the ESLint
70
- * rules scope by import, so same-named calls from other libraries (RxJS
71
- * `of`, fp-ts `fold`) are flagged too.
69
+ * The ESLint rule matches by name alone, so same-named calls from other
70
+ * libraries (RxJS `of`, fp-ts `fold`) are flagged too; the Biome rule scopes
71
+ * to files carrying an `@onrails/*` module source. See `ENGINE_DIVERGENCES`
72
+ * (`no-deprecated-synonyms` / `import-scoped`).
72
73
  */
73
74
  export const DEPRECATED_SYNONYMS: readonly DeprecatedSynonym[] = [
74
75
  { name: "chain", form: "method", canonical: "flatMap" },
@@ -174,6 +175,18 @@ export const ENGINE_DIVERGENCES: readonly EngineDivergence[] = [
174
175
  "flags test code too. Suppress with a biome-ignore comment or a linter " +
175
176
  "override for test globs.",
176
177
  },
178
+ {
179
+ rule: NO_DEPRECATED_SYNONYMS_RULE.id,
180
+ engine: "biome",
181
+ divergence: "import-scoped",
182
+ detail:
183
+ "GritQL can read the module sources of the file it is matching, so the " +
184
+ "Biome rule only flags synonyms in files that mention an `@onrails/*` " +
185
+ "specifier — RxJS `of` and fp-ts `fold` in unrelated files stay quiet. " +
186
+ "The ESLint rule matches by name everywhere, so it is the noisier of " +
187
+ "the two in mixed codebases and the stricter one in codebases that " +
188
+ "re-export onrails through a local alias.",
189
+ },
177
190
  {
178
191
  rule: FLUENT_STAYS_LOCAL_RULE.id,
179
192
  engine: "biome",
package/src/chains.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { compactMap, isSome, type Maybe, map, none, some } from "@onrails/maybe";
2
2
  import { match } from "@onrails/pattern";
3
- import ts from "typescript";
3
+ import ts from "typescript6";
4
4
  import { argsToText, edit, lookupMap, spanEdit, walkSource } from "./ast.js";
5
5
  import {
6
6
  ASYNC_ROOT_HINTS,
@@ -34,9 +34,7 @@ const HELPERS = [
34
34
 
35
35
  type HelperName = (typeof HELPERS)[number];
36
36
 
37
- function isHelperName(x: string): x is HelperName {
38
- return (HELPERS as readonly string[]).includes(x);
39
- }
37
+ const isHelperName = (x: string): x is HelperName => (HELPERS as readonly string[]).includes(x);
40
38
 
41
39
  function identifierCallToNative(node: ts.CallExpression): Maybe<Edit> {
42
40
  if (!ts.isIdentifier(node.expression)) return none();
package/src/pkg.ts CHANGED
@@ -9,7 +9,7 @@ const reorderDeps = (deps: Record<string, string>): Record<string, string> =>
9
9
  Object.fromEntries(Object.entries(deps).sort(([a], [b]) => a.localeCompare(b)));
10
10
 
11
11
  export const parsePackageJson = (raw: string): Result<Record<string, unknown>, Error> =>
12
- trySync(() => JSON.parse(raw) as Record<string, unknown>, toError)();
12
+ trySync(() => JSON.parse(raw) as Record<string, unknown>, toError);
13
13
 
14
14
  const applyDepRewrite =
15
15
  (fileSpec: string) =>
package/src/switch.ts CHANGED
@@ -1,4 +1,4 @@
1
- import ts from "typescript";
1
+ import ts from "typescript6";
2
2
  import type { Edit } from "./types.js";
3
3
 
4
4
  interface Comparison {
@@ -1,4 +1,4 @@
1
- import ts from "typescript";
1
+ import ts from "typescript6";
2
2
 
3
3
  // Helper to check for single statement return
4
4
  export function getSingleReturnExpression(statement: ts.Statement): ts.Expression | undefined {
@@ -135,12 +135,9 @@ export function getTernaryBranchText(node: ts.Expression, sf: ts.SourceFile): st
135
135
  let unwrapped: ts.Expression | undefined;
136
136
  if (ts.isJsxFragment(current)) {
137
137
  const children = current.children;
138
- const nonTriviaChildren = children.filter((child) => {
139
- if (ts.isJsxText(child)) {
140
- return !child.containsOnlyTriviaWhiteSpaces;
141
- }
142
- return true;
143
- });
138
+ const nonTriviaChildren = children.filter((child) =>
139
+ ts.isJsxText(child) ? !child.containsOnlyTriviaWhiteSpaces : true,
140
+ );
144
141
  if (nonTriviaChildren.length === 1) {
145
142
  const soleChild = nonTriviaChildren[0];
146
143
  if (soleChild && ts.isJsxExpression(soleChild) && soleChild.expression) {
@@ -152,12 +149,9 @@ export function getTernaryBranchText(node: ts.Expression, sf: ts.SourceFile): st
152
149
  if (tagName === "Fragment" || tagName === "React.Fragment" || tagName.endsWith(".Fragment")) {
153
150
  if (current.openingElement.attributes.properties.length === 0) {
154
151
  const children = current.children;
155
- const nonTriviaChildren = children.filter((child) => {
156
- if (ts.isJsxText(child)) {
157
- return !child.containsOnlyTriviaWhiteSpaces;
158
- }
159
- return true;
160
- });
152
+ const nonTriviaChildren = children.filter((child) =>
153
+ ts.isJsxText(child) ? !child.containsOnlyTriviaWhiteSpaces : true,
154
+ );
161
155
  if (nonTriviaChildren.length === 1) {
162
156
  const soleChild = nonTriviaChildren[0];
163
157
  if (soleChild && ts.isJsxExpression(soleChild) && soleChild.expression) {
package/src/tersify.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type Maybe, none, some } from "@onrails/maybe";
2
- import ts from "typescript";
2
+ import ts from "typescript6";
3
3
  import { edit, spanEdit, walkSource } from "./ast.js";
4
4
  import { applyEditStep, byStartDesc } from "./chains.js";
5
5
  import { scanIfToSwitchSequences } from "./switch.js";
package/src/warnings.ts CHANGED
@@ -1,4 +1,4 @@
1
- import ts from "typescript";
1
+ import ts from "typescript6";
2
2
  import { walkSource } from "./ast.js";
3
3
  import { COMPAT_ONLY_PATTERNS, COMPAT_SPEC } from "./constants.js";
4
4
  import type { Warning } from "./types.js";