miniread 1.103.0 → 1.104.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 (15) hide show
  1. package/dist/transforms/_generated/catalog.js +7 -0
  2. package/dist/transforms-by-id/rename-protobuf-encode-parameters/get-assigned-member-property-name.d.ts +3 -0
  3. package/dist/transforms-by-id/rename-protobuf-encode-parameters/get-assigned-member-property-name.js +18 -0
  4. package/dist/transforms-by-id/rename-protobuf-encode-parameters/get-two-identifier-parameter-names.d.ts +7 -0
  5. package/dist/transforms-by-id/rename-protobuf-encode-parameters/get-two-identifier-parameter-names.js +15 -0
  6. package/dist/transforms-by-id/rename-protobuf-encode-parameters/has-protobuf-encode-body-signals.d.ts +4 -0
  7. package/dist/transforms-by-id/rename-protobuf-encode-parameters/has-protobuf-encode-body-signals.js +94 -0
  8. package/dist/transforms-by-id/rename-protobuf-encode-parameters/is-encode-delimited-function-candidate.d.ts +4 -0
  9. package/dist/transforms-by-id/rename-protobuf-encode-parameters/is-encode-delimited-function-candidate.js +69 -0
  10. package/dist/transforms-by-id/rename-protobuf-encode-parameters/is-encode-function-candidate.d.ts +4 -0
  11. package/dist/transforms-by-id/rename-protobuf-encode-parameters/is-encode-function-candidate.js +79 -0
  12. package/dist/transforms-by-id/rename-protobuf-encode-parameters/manifest.json +14 -0
  13. package/dist/transforms-by-id/rename-protobuf-encode-parameters/rename-protobuf-encode-parameters-transform.d.ts +2 -0
  14. package/dist/transforms-by-id/rename-protobuf-encode-parameters/rename-protobuf-encode-parameters-transform.js +69 -0
  15. package/package.json +1 -1
@@ -100,6 +100,8 @@ import { renamePromiseCatchParametersTransform } from "../../transforms-by-id/re
100
100
  import renamePromiseCatchParametersManifest from "../../transforms-by-id/rename-promise-catch-parameters/manifest.json" with { type: "json" };
101
101
  import { renamePromiseExecutorParametersV2Transform } from "../../transforms-by-id/rename-promise-executor-parameters-v2/rename-promise-executor-parameters-v2-transform.js";
102
102
  import renamePromiseExecutorParametersV2Manifest from "../../transforms-by-id/rename-promise-executor-parameters-v2/manifest.json" with { type: "json" };
103
+ import { renameProtobufEncodeParametersTransform } from "../../transforms-by-id/rename-protobuf-encode-parameters/rename-protobuf-encode-parameters-transform.js";
104
+ import renameProtobufEncodeParametersManifest from "../../transforms-by-id/rename-protobuf-encode-parameters/manifest.json" with { type: "json" };
103
105
  import { renameQueueTraversalVariablesTransform } from "../../transforms-by-id/rename-queue-traversal-variables/rename-queue-traversal-variables-transform.js";
104
106
  import renameQueueTraversalVariablesManifest from "../../transforms-by-id/rename-queue-traversal-variables/manifest.json" with { type: "json" };
105
107
  import { renameRangeParametersTransform } from "../../transforms-by-id/rename-range-parameters/rename-range-parameters-transform.js";
@@ -423,6 +425,11 @@ export const generatedTransformCatalog = [
423
425
  transform: renamePromiseExecutorParametersV2Transform,
424
426
  manifest: renamePromiseExecutorParametersV2Manifest,
425
427
  },
428
+ {
429
+ id: renameProtobufEncodeParametersTransform.id,
430
+ transform: renameProtobufEncodeParametersTransform,
431
+ manifest: renameProtobufEncodeParametersManifest,
432
+ },
426
433
  {
427
434
  id: renameQueueTraversalVariablesTransform.id,
428
435
  transform: renameQueueTraversalVariablesTransform,
@@ -0,0 +1,3 @@
1
+ import type { NodePath } from "@babel/traverse";
2
+ import type { ArrowFunctionExpression, FunctionExpression } from "@babel/types";
3
+ export declare const getAssignedMemberPropertyName: (path: NodePath<FunctionExpression | ArrowFunctionExpression>) => string | undefined;
@@ -0,0 +1,18 @@
1
+ export const getAssignedMemberPropertyName = (path) => {
2
+ const parentPath = path.parentPath;
3
+ if (!parentPath.isAssignmentExpression({ operator: "=" }))
4
+ return undefined;
5
+ const leftPath = parentPath.get("left");
6
+ if (!leftPath.isMemberExpression())
7
+ return undefined;
8
+ if (leftPath.node.computed) {
9
+ const propertyPath = leftPath.get("property");
10
+ if (!propertyPath.isStringLiteral())
11
+ return undefined;
12
+ return propertyPath.node.value;
13
+ }
14
+ const propertyPath = leftPath.get("property");
15
+ if (!propertyPath.isIdentifier())
16
+ return undefined;
17
+ return propertyPath.node.name;
18
+ };
@@ -0,0 +1,7 @@
1
+ import type { NodePath } from "@babel/traverse";
2
+ import type { ArrowFunctionExpression, FunctionExpression } from "@babel/types";
3
+ export type ProtobufEncodeParameterNames = {
4
+ messageParameterName: string;
5
+ writerParameterName: string;
6
+ };
7
+ export declare const getTwoIdentifierParameterNames: (path: NodePath<FunctionExpression | ArrowFunctionExpression>) => ProtobufEncodeParameterNames | undefined;
@@ -0,0 +1,15 @@
1
+ export const getTwoIdentifierParameterNames = (path) => {
2
+ const parameters = path.get("params");
3
+ if (parameters.length !== 2)
4
+ return undefined;
5
+ const messageParameterPath = parameters[0];
6
+ const writerParameterPath = parameters[1];
7
+ if (!messageParameterPath?.isIdentifier())
8
+ return undefined;
9
+ if (!writerParameterPath?.isIdentifier())
10
+ return undefined;
11
+ return {
12
+ messageParameterName: messageParameterPath.node.name,
13
+ writerParameterName: writerParameterPath.node.name,
14
+ };
15
+ };
@@ -0,0 +1,4 @@
1
+ import type { NodePath } from "@babel/traverse";
2
+ import type { BlockStatement } from "@babel/types";
3
+ import type { ProtobufEncodeParameterNames } from "./get-two-identifier-parameter-names.js";
4
+ export declare const hasProtobufEncodeBodySignals: (bodyPath: NodePath<BlockStatement>, parameters: ProtobufEncodeParameterNames) => boolean;
@@ -0,0 +1,94 @@
1
+ const isObjectHasOwnPropertyCallForMessage = (callExpression, messageParameterName) => {
2
+ const callee = callExpression.callee;
3
+ if (callee.type !== "MemberExpression")
4
+ return false;
5
+ if (callee.computed)
6
+ return false;
7
+ if (callee.property.type !== "Identifier")
8
+ return false;
9
+ if (callee.property.name !== "call")
10
+ return false;
11
+ const object = callee.object;
12
+ if (object.type !== "MemberExpression")
13
+ return false;
14
+ if (object.computed)
15
+ return false;
16
+ if (object.object.type !== "Identifier")
17
+ return false;
18
+ if (object.object.name !== "Object")
19
+ return false;
20
+ if (object.property.type !== "Identifier")
21
+ return false;
22
+ if (object.property.name !== "hasOwnProperty")
23
+ return false;
24
+ if (callExpression.arguments.length < 2)
25
+ return false;
26
+ const [firstArgument, secondArgument] = callExpression.arguments;
27
+ if (!firstArgument || !secondArgument)
28
+ return false;
29
+ if (firstArgument.type !== "Identifier")
30
+ return false;
31
+ if (firstArgument.name !== messageParameterName)
32
+ return false;
33
+ return secondArgument.type === "StringLiteral";
34
+ };
35
+ const isWriterUint32Call = (callee, writerParameterName) => {
36
+ if (callee.type !== "MemberExpression")
37
+ return false;
38
+ if (callee.computed)
39
+ return false;
40
+ if (callee.object.type !== "Identifier")
41
+ return false;
42
+ if (callee.object.name !== writerParameterName)
43
+ return false;
44
+ if (callee.property.type !== "Identifier")
45
+ return false;
46
+ return callee.property.name === "uint32";
47
+ };
48
+ const collectProtobufEncodeBodySignals = (bodyPath, parameters) => {
49
+ const signals = {
50
+ hasWriterUint32Call: false,
51
+ hasMessageOwnPropertyGuard: false,
52
+ hasReturnWriter: false,
53
+ };
54
+ bodyPath.traverse({
55
+ Function(path) {
56
+ path.skip();
57
+ },
58
+ CallExpression(path) {
59
+ if (!signals.hasWriterUint32Call) {
60
+ signals.hasWriterUint32Call = isWriterUint32Call(path.node.callee, parameters.writerParameterName);
61
+ }
62
+ if (!signals.hasMessageOwnPropertyGuard) {
63
+ signals.hasMessageOwnPropertyGuard =
64
+ isObjectHasOwnPropertyCallForMessage(path.node, parameters.messageParameterName);
65
+ }
66
+ if (signals.hasWriterUint32Call &&
67
+ signals.hasMessageOwnPropertyGuard &&
68
+ signals.hasReturnWriter) {
69
+ path.stop();
70
+ }
71
+ },
72
+ ReturnStatement(path) {
73
+ if (!signals.hasReturnWriter) {
74
+ const argument = path.node.argument;
75
+ if (argument?.type === "Identifier" &&
76
+ argument.name === parameters.writerParameterName) {
77
+ signals.hasReturnWriter = true;
78
+ }
79
+ }
80
+ if (signals.hasWriterUint32Call &&
81
+ signals.hasMessageOwnPropertyGuard &&
82
+ signals.hasReturnWriter) {
83
+ path.stop();
84
+ }
85
+ },
86
+ });
87
+ return signals;
88
+ };
89
+ export const hasProtobufEncodeBodySignals = (bodyPath, parameters) => {
90
+ const signals = collectProtobufEncodeBodySignals(bodyPath, parameters);
91
+ return (signals.hasWriterUint32Call &&
92
+ signals.hasMessageOwnPropertyGuard &&
93
+ signals.hasReturnWriter);
94
+ };
@@ -0,0 +1,4 @@
1
+ import type { NodePath } from "@babel/traverse";
2
+ import type { ArrowFunctionExpression, FunctionExpression } from "@babel/types";
3
+ import type { ProtobufEncodeParameterNames } from "./get-two-identifier-parameter-names.js";
4
+ export declare const isEncodeDelimitedFunctionCandidate: (path: NodePath<FunctionExpression | ArrowFunctionExpression>, parameters: ProtobufEncodeParameterNames) => boolean;
@@ -0,0 +1,69 @@
1
+ const isEncodeDelimitedReturnExpression = (expression, messageParameterName, writerParameterName) => {
2
+ if (expression.type !== "CallExpression")
3
+ return false;
4
+ const ldelimCallee = expression.callee;
5
+ if (ldelimCallee.type !== "MemberExpression")
6
+ return false;
7
+ if (ldelimCallee.computed)
8
+ return false;
9
+ if (ldelimCallee.property.type !== "Identifier")
10
+ return false;
11
+ if (ldelimCallee.property.name !== "ldelim")
12
+ return false;
13
+ const encodeCall = ldelimCallee.object;
14
+ if (encodeCall.type !== "CallExpression")
15
+ return false;
16
+ if (encodeCall.arguments.length !== 2)
17
+ return false;
18
+ const [firstArgument, secondArgument] = encodeCall.arguments;
19
+ if (!firstArgument || !secondArgument)
20
+ return false;
21
+ if (firstArgument.type !== "Identifier")
22
+ return false;
23
+ if (secondArgument.type !== "Identifier")
24
+ return false;
25
+ if (firstArgument.name !== messageParameterName)
26
+ return false;
27
+ // Intentionally strict for high-confidence matching: require direct pass-through.
28
+ if (secondArgument.name !== writerParameterName)
29
+ return false;
30
+ const encodeCallee = encodeCall.callee;
31
+ if (encodeCallee.type !== "MemberExpression")
32
+ return false;
33
+ if (encodeCallee.computed)
34
+ return false;
35
+ if (encodeCallee.property.type !== "Identifier")
36
+ return false;
37
+ if (encodeCallee.property.name !== "encode")
38
+ return false;
39
+ // Restrict to the same object contract (`this.encode(...)`) to avoid
40
+ // misclassifying wrappers like `other.encode(...).ldelim()`.
41
+ return encodeCallee.object.type === "ThisExpression";
42
+ };
43
+ const getSingleReturnedExpression = (path) => {
44
+ if (path.isArrowFunctionExpression()) {
45
+ const bodyPath = path.get("body");
46
+ if (!bodyPath.isExpression())
47
+ return undefined;
48
+ return bodyPath.node;
49
+ }
50
+ const bodyPath = path.get("body");
51
+ if (!bodyPath.isBlockStatement())
52
+ return undefined;
53
+ const statements = bodyPath.get("body");
54
+ if (statements.length !== 1)
55
+ return undefined;
56
+ const onlyStatement = statements[0];
57
+ if (!onlyStatement?.isReturnStatement())
58
+ return undefined;
59
+ const argument = onlyStatement.node.argument;
60
+ if (!argument)
61
+ return undefined;
62
+ return argument;
63
+ };
64
+ export const isEncodeDelimitedFunctionCandidate = (path, parameters) => {
65
+ const returnedExpression = getSingleReturnedExpression(path);
66
+ if (!returnedExpression)
67
+ return false;
68
+ return isEncodeDelimitedReturnExpression(returnedExpression, parameters.messageParameterName, parameters.writerParameterName);
69
+ };
@@ -0,0 +1,4 @@
1
+ import type { NodePath } from "@babel/traverse";
2
+ import type { ArrowFunctionExpression, FunctionExpression } from "@babel/types";
3
+ import type { ProtobufEncodeParameterNames } from "./get-two-identifier-parameter-names.js";
4
+ export declare const isEncodeFunctionCandidate: (path: NodePath<FunctionExpression | ArrowFunctionExpression>, parameters: ProtobufEncodeParameterNames) => boolean;
@@ -0,0 +1,79 @@
1
+ import { hasProtobufEncodeBodySignals } from "./has-protobuf-encode-body-signals.js";
2
+ const getBlockStatementPath = (path) => {
3
+ const bodyPath = path.get("body");
4
+ if (!bodyPath.isBlockStatement())
5
+ return undefined;
6
+ return bodyPath;
7
+ };
8
+ const getSingleExpressionStatement = (statement) => {
9
+ if (statement.type === "ExpressionStatement")
10
+ return statement;
11
+ if (statement.type !== "BlockStatement")
12
+ return undefined;
13
+ if (statement.body.length !== 1)
14
+ return undefined;
15
+ const onlyStatement = statement.body[0];
16
+ if (!onlyStatement)
17
+ return undefined;
18
+ if (onlyStatement.type !== "ExpressionStatement")
19
+ return undefined;
20
+ return onlyStatement;
21
+ };
22
+ const isCreateCallExpression = (expression) => {
23
+ if (expression.type !== "CallExpression")
24
+ return false;
25
+ if (expression.arguments.length > 0)
26
+ return false;
27
+ const callee = expression.callee;
28
+ if (callee.type !== "MemberExpression")
29
+ return false;
30
+ if (callee.computed)
31
+ return false;
32
+ if (callee.property.type !== "Identifier")
33
+ return false;
34
+ return callee.property.name === "create";
35
+ };
36
+ const isWriterCreateGuard = (statement, writerParameterName) => {
37
+ if (statement.alternate)
38
+ return false;
39
+ const test = statement.test;
40
+ if (test.type !== "UnaryExpression")
41
+ return false;
42
+ if (test.operator !== "!")
43
+ return false;
44
+ if (test.argument.type !== "Identifier")
45
+ return false;
46
+ if (test.argument.name !== writerParameterName)
47
+ return false;
48
+ const expressionStatement = getSingleExpressionStatement(statement.consequent);
49
+ if (!expressionStatement)
50
+ return false;
51
+ const expression = expressionStatement.expression;
52
+ if (expression.type !== "AssignmentExpression")
53
+ return false;
54
+ if (expression.operator !== "=")
55
+ return false;
56
+ if (expression.left.type !== "Identifier")
57
+ return false;
58
+ if (expression.left.name !== writerParameterName)
59
+ return false;
60
+ return isCreateCallExpression(expression.right);
61
+ };
62
+ export const isEncodeFunctionCandidate = (path, parameters) => {
63
+ const bodyPath = getBlockStatementPath(path);
64
+ if (!bodyPath)
65
+ return false;
66
+ const statements = bodyPath.get("body");
67
+ if (statements.length === 0)
68
+ return false;
69
+ const hasWriterGuard = statements.some((statementPath) => {
70
+ if (!statementPath.isIfStatement())
71
+ return false;
72
+ return isWriterCreateGuard(statementPath.node, parameters.writerParameterName);
73
+ });
74
+ if (!hasWriterGuard)
75
+ return false;
76
+ if (!hasProtobufEncodeBodySignals(bodyPath, parameters))
77
+ return false;
78
+ return true;
79
+ };
@@ -0,0 +1,14 @@
1
+ {
2
+ "notes": "Renames protobufjs encode/encodeDelimited parameters to stable $message/$writer names when writer/create and hasOwnProperty guards indicate generated serializer code.",
3
+ "evaluations": {
4
+ "claude-code-2.1.10:claude-code-2.1.11": {
5
+ "diffSizePercent": 100,
6
+ "evaluatedAt": "2026-02-11T09:32:46.513Z",
7
+ "changedLines": 690,
8
+ "durationSeconds": 28.264948625000002,
9
+ "stableNames": 1359
10
+ }
11
+ },
12
+ "recommended": true,
13
+ "recommendedOrder": 100
14
+ }
@@ -0,0 +1,2 @@
1
+ import { type Transform } from "../../core/types.js";
2
+ export declare const renameProtobufEncodeParametersTransform: Transform;
@@ -0,0 +1,69 @@
1
+ import { createRequire } from "node:module";
2
+ import { isStableRenamed, RenameGroup } from "../../core/stable-naming.js";
3
+ import { getFilesToProcess, } from "../../core/types.js";
4
+ import { getAssignedMemberPropertyName } from "./get-assigned-member-property-name.js";
5
+ import { getTwoIdentifierParameterNames } from "./get-two-identifier-parameter-names.js";
6
+ import { isEncodeDelimitedFunctionCandidate } from "./is-encode-delimited-function-candidate.js";
7
+ import { isEncodeFunctionCandidate } from "./is-encode-function-candidate.js";
8
+ const require = createRequire(import.meta.url);
9
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
10
+ const traverse = require("@babel/traverse").default;
11
+ const MESSAGE_BASE_NAME = "message";
12
+ const WRITER_BASE_NAME = "writer";
13
+ const addRenameCandidates = (path, group, nodesVisited) => {
14
+ nodesVisited.value++;
15
+ const propertyName = getAssignedMemberPropertyName(path);
16
+ if (propertyName !== "encode" && propertyName !== "encodeDelimited")
17
+ return;
18
+ const parameters = getTwoIdentifierParameterNames(path);
19
+ if (!parameters)
20
+ return;
21
+ if (propertyName === "encode" &&
22
+ !isEncodeFunctionCandidate(path, parameters)) {
23
+ return;
24
+ }
25
+ if (propertyName === "encodeDelimited" &&
26
+ !isEncodeDelimitedFunctionCandidate(path, parameters)) {
27
+ return;
28
+ }
29
+ if (!isStableRenamed(parameters.messageParameterName)) {
30
+ group.add({
31
+ scope: path.scope,
32
+ currentName: parameters.messageParameterName,
33
+ baseName: MESSAGE_BASE_NAME,
34
+ });
35
+ }
36
+ if (!isStableRenamed(parameters.writerParameterName)) {
37
+ group.add({
38
+ scope: path.scope,
39
+ currentName: parameters.writerParameterName,
40
+ baseName: WRITER_BASE_NAME,
41
+ });
42
+ }
43
+ };
44
+ export const renameProtobufEncodeParametersTransform = {
45
+ id: "rename-protobuf-encode-parameters",
46
+ description: "Renames protobufjs encode/encodeDelimited parameters to $message/$writer when pattern confidence is high",
47
+ scope: "file",
48
+ parallelizable: true,
49
+ transform(context) {
50
+ const nodesVisited = { value: 0 };
51
+ let transformationsApplied = 0;
52
+ for (const fileInfo of getFilesToProcess(context)) {
53
+ const group = new RenameGroup();
54
+ traverse(fileInfo.ast, {
55
+ FunctionExpression(path) {
56
+ addRenameCandidates(path, group, nodesVisited);
57
+ },
58
+ ArrowFunctionExpression(path) {
59
+ addRenameCandidates(path, group, nodesVisited);
60
+ },
61
+ });
62
+ transformationsApplied += group.apply();
63
+ }
64
+ return Promise.resolve({
65
+ nodesVisited: nodesVisited.value,
66
+ transformationsApplied,
67
+ });
68
+ },
69
+ };
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.103.0",
5
+ "version": "1.104.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",