chore: run fixes (#8257)

* chore: run fixes

* fix: type, just use hocuspocusservercontext

* fix: codemod

---------

Co-authored-by: Palanikannan M <akashmalinimurugu@gmail.com>
This commit is contained in:
Aaron 2025-12-08 23:56:50 +07:00 committed by GitHub
parent a9e9cb2983
commit 0ab94ed6d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
172 changed files with 1784 additions and 1798 deletions

View file

@ -59,7 +59,20 @@ function isComponentNameIdentifier(identifier: Identifier | null | undefined) {
return false;
}
return COMPONENT_NAME_PATTERN.test(identifier.name);
// Must start with uppercase
if (!COMPONENT_NAME_PATTERN.test(identifier.name)) {
return false;
}
// Ignore CONSTANT_CASE (all uppercase)
if (
identifier.name.toUpperCase() === identifier.name &&
identifier.name.length > 1
) {
return false;
}
return true;
}
function addComments(target: Node, comments: CommentKind[]) {
@ -121,7 +134,10 @@ function toBlockBody(j: JSCodeshift, body: BlockStatement | Expression) {
return j.blockStatement([returnStatement]);
}
function isFunction(node: Node, j: JSCodeshift): node is ArrowFunctionExpression | FunctionExpression {
function isFunction(
node: Node,
j: JSCodeshift
): node is ArrowFunctionExpression | FunctionExpression {
return (
j.ArrowFunctionExpression.check(node) || j.FunctionExpression.check(node)
);
@ -166,15 +182,39 @@ function extractPropsTypeFromWrapper(
}
const typeParam = typeParameters.params?.[0];
if (
!j.TSTypeReference.check(typeParam) ||
!isReactComponentType(typeParam, j)
) {
if (!typeParam) {
return;
}
// Extract the generic type from React.FC<PropsType>
return typeParam.typeParameters?.params?.[0];
if (
j.TSTypeReference.check(typeParam) &&
isReactComponentType(typeParam, j)
) {
// Extract the generic type from React.FC<PropsType>
return typeParam.typeParameters?.params?.[0];
}
// Check for memo<Props>
const callee = init.callee;
let isMemo = false;
if (j.Identifier.check(callee) && callee.name === "memo") {
isMemo = true;
} else if (
j.MemberExpression.check(callee) &&
j.Identifier.check(callee.property) &&
callee.property.name === "memo"
) {
isMemo = true;
}
if (isMemo) {
// For memo<Props>, the first type parameter is the props type
// @ts-expect-error: jscodeshift types are too strict here
return typeParam;
}
return;
}
function isReactForwardRef(
@ -242,12 +282,12 @@ function extractForwardRefTypes(
typeParams.length >= 2 && typeParams[1]
? typeParams[1]
: j.tsTypeReference(
j.identifier("Record"),
j.tsTypeParameterInstantiation([
j.tsStringKeyword(),
j.tsUnknownKeyword(),
])
);
j.identifier("Record"),
j.tsTypeParameterInstantiation([
j.tsStringKeyword(),
j.tsUnknownKeyword(),
])
);
// Create React.ForwardedRef<ElementType> for the ref parameter
const refType = j.tsTypeReference(
@ -411,7 +451,10 @@ export default function transform(file: FileInfo, api: API, options: Options) {
// Try to get props type from variable type annotation first
let propsType: TSType | undefined = undefined;
if (j.TSTypeReference.check(typeAnnotation) && isReactComponentType(typeAnnotation, j)) {
if (
j.TSTypeReference.check(typeAnnotation) &&
isReactComponentType(typeAnnotation, j)
) {
propsType = typeAnnotation.typeParameters?.params?.[0];
}
@ -441,6 +484,7 @@ export default function transform(file: FileInfo, api: API, options: Options) {
const wrappedFunction = j.callExpression(init.callee, [
functionExpression,
...init.arguments.slice(1),
]);
if (!j.Identifier.check(firstDeclaration.id)) {

View file

@ -13,7 +13,7 @@ describe("function-declaration", () => {
return <div>Hello, world!</div>;
};
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -39,7 +39,7 @@ describe("function-declaration", () => {
return <div>Hello, {name}!</div>;
};
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -73,7 +73,7 @@ describe("function-declaration", () => {
return <div>Hello, {name}!</div>;
};
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -101,7 +101,7 @@ describe("function-declaration", () => {
return "hello";
};
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -121,7 +121,7 @@ describe("function-declaration", () => {
return <div>Analytics</div>;
});
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -141,7 +141,7 @@ describe("function-declaration", () => {
return <a href="https://github.com">Star us</a>;
};
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -161,7 +161,7 @@ describe("function-declaration", () => {
return <div>Sidebar</div>;
});
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -179,7 +179,7 @@ describe("function-declaration", () => {
`
export const DateAlert = (props: TDateAlertProps) => <></>;
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -200,7 +200,7 @@ describe("function-declaration", () => {
return <>{children}</>;
});
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -224,7 +224,7 @@ describe("function-declaration", () => {
return <div>Hello</div>;
});
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -247,7 +247,7 @@ describe("function-declaration", () => {
return <div>Chart</div>;
});
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -271,7 +271,7 @@ describe("function-declaration", () => {
return <button ref={ref}>Click me</button>;
});
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -293,7 +293,7 @@ describe("function-declaration", () => {
export const EditorAdditionalMentionsRoot: React.FC<TCallbackMentionComponentProps> = () => null;
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -315,7 +315,7 @@ describe("function-declaration", () => {
<div ref={ref}>Content</div>
));
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -338,7 +338,7 @@ describe("function-declaration", () => {
null
);
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -381,7 +381,7 @@ export const PreloadResources = () =>
// usePreloadResources();
null;
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -426,7 +426,7 @@ export const MyObserverComponent = observer(() => {
return <div>Observer component</div>;
});
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
@ -444,7 +444,7 @@ export const MyObserverComponent = observer(() => {
`
export const Foo = () => <div />; // trailing comment
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toContain("// trailing comment");
@ -456,10 +456,111 @@ export const MyObserverComponent = observer(() => {
`
export /* leading comment */ const Foo = () => <div />;
`,
{ parser: "tsx" },
{ parser: "tsx" }
);
expect(result).toContain("/* leading comment */");
});
});
it("should preserve dependency arrays when transforming wrapped components", async () => {
const result = await applyTransform(
transformer,
`
import { useMemo } from "react";
const MyComponent = useMemo(() => {
return () => <div>Hello</div>;
}, [dep]);
`,
{ parser: "tsx", path: "file.tsx" }
);
expect(result).toMatchInlineSnapshot(`
"import { useMemo } from "react";
const MyComponent = useMemo(function MyComponent() {
return () => <div>Hello</div>;
}, [dep]);"
`);
});
it("should preserve dependency arrays for constants that look like components", async () => {
const result = await applyTransform(
transformer,
`
import { useMemo } from "react";
const ACTION_HANDLERS = useMemo(function ACTION_HANDLERS() {
return {
archived: () => {},
};
}, []);
`,
{ parser: "tsx", path: "file.tsx" }
);
expect(result).toMatchInlineSnapshot(`
"import { useMemo } from "react";
const ACTION_HANDLERS = useMemo(function ACTION_HANDLERS() {
return {
archived: () => {},
};
}, []);"
`);
});
it("should handle memo with generic type arguments correctly", async () => {
const result = await applyTransform(
transformer,
`
import { memo } from "react";
type TAccessMenuProps = {
currentAccess: number;
};
export const AccessMenu = memo<TAccessMenuProps>(
({ currentAccess }) => {
return <div>{currentAccess}</div>;
}
);
`,
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
"import { memo } from "react";
type TAccessMenuProps = {
currentAccess: number;
};
export const AccessMenu = memo(function AccessMenu(
{
currentAccess
}: TAccessMenuProps
) {
return <div>{currentAccess}</div>;
});"
`);
});
it("should not transform CONSTANT_CASE variables", async () => {
const result = await applyTransform(
transformer,
`
export const MY_CONSTANT = () => {
return "value";
};
`,
{ parser: "tsx" }
);
expect(result).toMatchInlineSnapshot(`
"export const MY_CONSTANT = () => {
return "value";
};"
`);
});
});