miniread 1.110.0 → 1.111.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.
@@ -130,6 +130,8 @@ import { renameRestPopCallbacksTransform } from "../../transforms-by-id/rename-r
130
130
  import renameRestPopCallbacksManifest from "../../transforms-by-id/rename-rest-pop-callbacks/manifest.json" with { type: "json" };
131
131
  import { renameReturnObjectBindingsTransform } from "../../transforms-by-id/rename-return-object-bindings/rename-return-object-bindings-transform.js";
132
132
  import renameReturnObjectBindingsManifest from "../../transforms-by-id/rename-return-object-bindings/manifest.json" with { type: "json" };
133
+ import { renameSanitizedStringVariablesTransform } from "../../transforms-by-id/rename-sanitized-string-variables/rename-sanitized-string-variables-transform.js";
134
+ import renameSanitizedStringVariablesManifest from "../../transforms-by-id/rename-sanitized-string-variables/manifest.json" with { type: "json" };
133
135
  import { renameSearchParametersVariablesTransform } from "../../transforms-by-id/rename-search-parameters-variables/rename-search-parameters-variables-transform.js";
134
136
  import renameSearchParametersVariablesManifest from "../../transforms-by-id/rename-search-parameters-variables/manifest.json" with { type: "json" };
135
137
  import { renameSetstateUpdaterParametersTransform } from "../../transforms-by-id/rename-setstate-updater-parameters/rename-setstate-updater-parameters-transform.js";
@@ -514,6 +516,11 @@ export const generatedTransformCatalog = [
514
516
  transform: renameReturnObjectBindingsTransform,
515
517
  manifest: renameReturnObjectBindingsManifest,
516
518
  },
519
+ {
520
+ id: renameSanitizedStringVariablesTransform.id,
521
+ transform: renameSanitizedStringVariablesTransform,
522
+ manifest: renameSanitizedStringVariablesManifest,
523
+ },
517
524
  {
518
525
  id: renameSearchParametersVariablesTransform.id,
519
526
  transform: renameSearchParametersVariablesTransform,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "recommended": {
3
- "diffSizePercent": 26.281324413198774,
4
- "notes": "Measured with baseline none: 26.28% of original diff."
3
+ "diffSizePercent": 26.062100767282757,
4
+ "notes": "Measured with baseline none: 26.06% of original diff."
5
5
  }
6
6
  }
@@ -1,13 +1,13 @@
1
1
  {
2
- "recommended": true,
3
- "recommendedOrder": 100,
4
2
  "evaluations": {
5
3
  "claude-code-2.1.10:claude-code-2.1.11": {
6
4
  "diffSizePercent": 100,
7
- "evaluatedAt": "2026-02-07T21:15:39.757Z",
8
- "changedLines": 606,
9
- "durationSeconds": 249.25496743300002,
5
+ "evaluatedAt": "2026-02-12T13:18:42.927Z",
6
+ "changedLines": 1240,
7
+ "durationSeconds": 37.765023916,
10
8
  "stableNames": 1359
11
9
  }
12
- }
10
+ },
11
+ "recommended": true,
12
+ "recommendedOrder": 100
13
13
  }
@@ -50,9 +50,40 @@ const getKeysIteratorIdentifier = (node) => {
50
50
  return undefined;
51
51
  return declaration.id;
52
52
  };
53
+ const getForInIteratorIdentifier = (node) => {
54
+ if (node.left.type !== "VariableDeclaration")
55
+ return undefined;
56
+ if (node.left.declarations.length !== 1)
57
+ return undefined;
58
+ const declaration = node.left.declarations[0];
59
+ if (!declaration)
60
+ return undefined;
61
+ if (declaration.id.type !== "Identifier")
62
+ return undefined;
63
+ if (declaration.init)
64
+ return undefined;
65
+ return declaration.id;
66
+ };
67
+ const renameIteratorBinding = (path, identifier, group, options) => {
68
+ const currentName = identifier.name;
69
+ if (isStableRenamed(currentName))
70
+ return;
71
+ if (options.skipWhenObjectShadowed && path.scope.getBinding("Object"))
72
+ return;
73
+ const binding = path.scope.getBinding(currentName);
74
+ if (!binding)
75
+ return;
76
+ if (!binding.constant)
77
+ return;
78
+ group.add({
79
+ scope: binding.scope,
80
+ currentName,
81
+ baseName: BASE_NAME,
82
+ });
83
+ };
53
84
  export const renameObjectKeysIteratorVariablesTransform = {
54
85
  id: "rename-object-keys-iterator-variables",
55
- description: "Renames for-of iterator variables that loop over Object.keys(...) to stable $key (or readable key/key2/...) when safe",
86
+ description: "Renames for-of Object.keys(...) and for-in iterator variables to stable $key (or readable key/key2/...) when safe",
56
87
  scope: "file",
57
88
  parallelizable: true,
58
89
  transform(context) {
@@ -66,20 +97,17 @@ export const renameObjectKeysIteratorVariablesTransform = {
66
97
  const identifier = getKeysIteratorIdentifier(path.node);
67
98
  if (!identifier)
68
99
  return;
69
- const currentName = identifier.name;
70
- if (isStableRenamed(currentName))
71
- return;
72
- if (path.scope.getBinding("Object"))
73
- return;
74
- const binding = path.scope.getBinding(currentName);
75
- if (!binding)
76
- return;
77
- if (!binding.constant)
100
+ renameIteratorBinding(path, identifier, group, {
101
+ skipWhenObjectShadowed: true,
102
+ });
103
+ },
104
+ ForInStatement(path) {
105
+ nodesVisited++;
106
+ const identifier = getForInIteratorIdentifier(path.node);
107
+ if (!identifier)
78
108
  return;
79
- group.add({
80
- scope: binding.scope,
81
- currentName,
82
- baseName: BASE_NAME,
109
+ renameIteratorBinding(path, identifier, group, {
110
+ skipWhenObjectShadowed: false,
83
111
  });
84
112
  },
85
113
  });
@@ -0,0 +1,14 @@
1
+ {
2
+ "notes": "Renames local sanitized string pipeline variables to stable semantic names like $sanitizedText.",
3
+ "evaluations": {
4
+ "claude-code-2.1.10:claude-code-2.1.11": {
5
+ "diffSizePercent": 100,
6
+ "evaluatedAt": "2026-02-13T06:07:03.949Z",
7
+ "changedLines": 76,
8
+ "durationSeconds": 29.482188958,
9
+ "stableNames": 1358
10
+ }
11
+ },
12
+ "recommended": true,
13
+ "recommendedOrder": 101
14
+ }
@@ -0,0 +1,2 @@
1
+ import { type Transform } from "../../core/types.js";
2
+ export declare const renameSanitizedStringVariablesTransform: Transform;
@@ -0,0 +1,109 @@
1
+ import { createRequire } from "node:module";
2
+ import * as t from "@babel/types";
3
+ import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
4
+ import { getFilesToProcess, } from "../../core/types.js";
5
+ const require = createRequire(import.meta.url);
6
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
7
+ const traverse = require("@babel/traverse").default;
8
+ const STRING_CLEANUP_METHODS = new Set([
9
+ "replace",
10
+ "replaceAll",
11
+ "trim",
12
+ "trimStart",
13
+ "trimEnd",
14
+ ]);
15
+ const isIdentifierParameter = (functionPath, name) => functionPath.node.params.some((parameter) => t.isIdentifier(parameter) && parameter.name === name);
16
+ const isCleanupAssignment = (assignmentPath, variableName) => {
17
+ if (assignmentPath.node.operator !== "=")
18
+ return false;
19
+ if (!assignmentPath.get("left").isIdentifier({ name: variableName }))
20
+ return false;
21
+ const rightPath = assignmentPath.get("right");
22
+ if (!rightPath.isCallExpression())
23
+ return false;
24
+ const calleePath = rightPath.get("callee");
25
+ if (!calleePath.isMemberExpression())
26
+ return false;
27
+ const objectPath = calleePath.get("object");
28
+ if (!objectPath.isIdentifier({ name: variableName }))
29
+ return false;
30
+ if (calleePath.node.computed)
31
+ return false;
32
+ const property = calleePath.node.property;
33
+ if (!t.isIdentifier(property))
34
+ return false;
35
+ return STRING_CLEANUP_METHODS.has(property.name);
36
+ };
37
+ const isReturnedInFunctionBody = (functionPath, variableName) => {
38
+ const bodyPath = functionPath.get("body");
39
+ if (!bodyPath.isBlockStatement())
40
+ return false;
41
+ return bodyPath.get("body").some((statementPath) => {
42
+ if (!statementPath.isReturnStatement())
43
+ return false;
44
+ const returnArgument = statementPath.get("argument");
45
+ return returnArgument.isIdentifier({ name: variableName });
46
+ });
47
+ };
48
+ const isSanitizedStringVariable = (declaratorPath) => {
49
+ const idPath = declaratorPath.get("id");
50
+ if (!idPath.isIdentifier())
51
+ return false;
52
+ const initPath = declaratorPath.get("init");
53
+ if (!initPath.isIdentifier())
54
+ return false;
55
+ const identifier = idPath.node;
56
+ if (isStableRenamed(identifier.name))
57
+ return false;
58
+ const functionPath = declaratorPath.getFunctionParent();
59
+ if (!functionPath)
60
+ return false;
61
+ const binding = declaratorPath.scope.getBinding(identifier.name);
62
+ if (!binding)
63
+ return false;
64
+ if (binding.constantViolations.length === 0)
65
+ return false;
66
+ const startsFromParameter = isIdentifierParameter(functionPath, initPath.node.name);
67
+ const isReturned = isReturnedInFunctionBody(functionPath, identifier.name);
68
+ const allCleanupAssignments = binding.constantViolations.every((violationPath) => {
69
+ if (!violationPath.isAssignmentExpression())
70
+ return false;
71
+ return isCleanupAssignment(violationPath, identifier.name);
72
+ });
73
+ if (!allCleanupAssignments)
74
+ return false;
75
+ return startsFromParameter || isReturned;
76
+ };
77
+ export const renameSanitizedStringVariablesTransform = {
78
+ id: "rename-sanitized-string-variables",
79
+ description: "Renames local variables that repeatedly sanitize a string parameter before returning it.",
80
+ scope: "file",
81
+ parallelizable: true,
82
+ transform(context) {
83
+ let nodesVisited = 0;
84
+ let transformationsApplied = 0;
85
+ for (const fileInfo of getFilesToProcess(context)) {
86
+ const group = new RenameGroup();
87
+ traverse(fileInfo.ast, {
88
+ VariableDeclarator(path) {
89
+ nodesVisited++;
90
+ if (!isSanitizedStringVariable(path))
91
+ return;
92
+ const idPath = path.get("id");
93
+ if (!idPath.isIdentifier())
94
+ return;
95
+ const binding = path.scope.getBinding(idPath.node.name);
96
+ if (!binding)
97
+ return;
98
+ group.add({
99
+ scope: binding.scope,
100
+ currentName: idPath.node.name,
101
+ baseName: "sanitizedText",
102
+ });
103
+ },
104
+ });
105
+ transformationsApplied += group.apply();
106
+ }
107
+ return Promise.resolve({ nodesVisited, transformationsApplied });
108
+ },
109
+ };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "miniread",
3
3
  "author": "Łukasz Jerciński",
4
4
  "license": "MIT",
5
- "version": "1.110.0",
5
+ "version": "1.111.0",
6
6
  "description": "Transform minified JavaScript/TypeScript into a more readable form using deterministic AST-based transforms.",
7
7
  "repository": {
8
8
  "type": "git",