Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { z } from "zod";
import zodToJsonSchema from "zod-to-json-schema";

export const optionsSchema = z
.object({
functionSourceType: z
.enum(["absolute", "relative"])
.optional()
.describe("function source's type. you can choose absolute or relative"),
functionNameType: z
.enum(["default", "named"])
.optional()
.describe("function name's type. you can choose default or named"),
functionSource: z
.string()
.describe("function source. you can choose package name or target path"),
functionName: z.string().describe("function name"),
objectKeys: z.string().array().describe("function parameter object keys"),
})
.describe("remove props");

export const optionsSchemaJsonSchema = zodToJsonSchema(optionsSchema);

export type OptionsSchema = z.infer<typeof optionsSchema>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { it, expect, describe } from "vitest";
import transform from "./transformer";
import { OptionsSchema } from "./optionsSchema";
import getTransformParms from "../../../utils/getTransformPaths";

describe("general case", () => {
it("named export", () => {
const input = `
import { dummyFunction } from "foo";
dummyFunction("hello", "this is dashboard page");
`;
const expectedOuput = `
import { dummyFunction } from "foo";
dummyFunction({
"title": "hello",
"description": "this is dashboard page"
});
`;
const transformParms = getTransformParms<OptionsSchema>({
input,
options: {
functionSourceType: "absolute",
functionNameType: "named",
functionSource: "foo",
functionName: "dummyFunction",
objectKeys: ["title", "description"],
},
});
const output = transform(...transformParms);

expect(output).toEqual(expectedOuput);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { OptionsSchema } from "./optionsSchema";
import getConvertedPath from "../../../utils/getConvertedPath";
import type { API, FileInfo } from "jscodeshift";

function transformer(file: FileInfo, api: API, options: OptionsSchema) {
const sourceCode = file.source;
const jscodeshift = api.jscodeshift;

const {
functionSourceType = "absolute",
functionNameType = "default",
functionSource,
functionName,
objectKeys,
} = options;

const convertedComponentSource = getConvertedPath({
type: functionSourceType,
currentPath: file.path,
targetPath: functionSource,
});

let convertedComponentName: null | string = null;

jscodeshift(sourceCode)
.find(jscodeshift.ImportDeclaration)
.filter((node) => node.value.source.value === convertedComponentSource)
.forEach((node) => {
node.value.specifiers?.forEach((specifier) => {
if (
specifier.type === "ImportDefaultSpecifier" &&
functionNameType === "default"
) {
return (convertedComponentName =
specifier.local?.type === "Identifier"
? specifier.local.name
: functionName);
}

if (
specifier.type === "ImportSpecifier" &&
functionNameType === "named" &&
specifier.imported.type === "Identifier" &&
specifier.imported.name === functionName
) {
return (convertedComponentName =
specifier.local?.type === "Identifier"
? specifier.local.name
: functionName);
}

if (
specifier.type === "ImportNamespaceSpecifier" &&
functionNameType === "default"
) {
return (convertedComponentName =
specifier.local?.type === "Identifier"
? specifier.local.name
: functionName);
}

if (
specifier.type === "ImportNamespaceSpecifier" &&
functionNameType === "named"
) {
return (convertedComponentName = functionName);
}
});
});

if (!convertedComponentName) {
return sourceCode;
}

console.log(convertedComponentName);

return jscodeshift(sourceCode)
.find(jscodeshift.CallExpression)
.filter((node) => {
return (
node.value.callee.type === "Identifier" &&
node.value.callee.name === convertedComponentName &&
node.scope.isGlobal
);
})
.forEach((node) => {
console.log(node.value.arguments);
node.value.arguments = [
jscodeshift.objectExpression(
node.value.arguments
.filter((argument) => argument.type !== "SpreadElement")
.map((argument, index) => {
return jscodeshift.objectProperty(
jscodeshift.literal(objectKeys[index]),
argument
);
})
.filter(Boolean)
),
];
})
.toSource();
}

export default transformer;
2 changes: 1 addition & 1 deletion website/transformers/component/_category_.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"label": "Components",
"label": "Component",
"position": 3,
"link": {
"type": "generated-index"
Expand Down
7 changes: 7 additions & 0 deletions website/transformers/function/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"label": "Function",
"position": 4,
"link": {
"type": "generated-index"
}
}
124 changes: 124 additions & 0 deletions website/transformers/function/change-parameter-object.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
---
sidebar_position: 1
---

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import CodeBlock from "@theme/CodeBlock";

# Change Parameter Object

Modify the function argument to take an object.

<Tabs>
<TabItem value="js" label="before" default>
<CodeBlock language="ts">
{`import { dummyFunction } from "foo";
dummyFunction("hello", "this is dashboard page");`}

</CodeBlock>
</TabItem>
<TabItem value="ts" label="after">
<CodeBlock language="ts">
{`import { dummyFunction } from "foo";

dummyFunction({
"title": "hello",
"description": "this is dashboard page"
});`}

</CodeBlock>
</TabItem>
</Tabs>

## Options

```typescript
type Options = {
functionSourceType?: "absolute" | "relative";
functionNameType?: "default" | "named";
functionSource: string;
functionName: string;
objectKeys: string[];
};
```

- functionSourceType: componentSource's type. you can choose absolute or relative
- functionNameType: changed target specifier
- functionSource: component source. you can choose package name or target path
- functionName: props to add's component name
- objectKeys: add props's name

## Usage

The usage method differs depending on the source type of the import statement to be converted.

### absolute

This is a situation where the source of the import module you want to change is an absolute path.

```typescript title="option.ts"
const option = {
functionSourceType: "absolute",
functionNameType: "named",
functionSource: "foo",
functionName: "dummyFunction",
objectKeys: ["title", "description"],
};
```

<Tabs>
<TabItem value="js" label="before" default>
<CodeBlock language="ts">
{`import { dummyFunction } from "foo";
dummyFunction("hello", "this is dashboard page");`}

</CodeBlock>
</TabItem>
<TabItem value="ts" label="after">
<CodeBlock language="ts">
{`import { dummyFunction } from "foo";

dummyFunction({
"title": "hello",
"description": "this is dashboard page"
});`}

</CodeBlock>
</TabItem>
</Tabs>

### relative

This is a situation where the source of the import module you want to change is an absolute path.

```typescript title="option.ts"
const option = {
functionSourceType: "relative",
functionNameType: "named",
functionSource: path.join(process.cwd(), "../test/foo.ts"),,
functionName: "dummyFunction",
objectKeys: ["title", "description"],
};
```

<Tabs>
<TabItem value="js" label="before" default>
<CodeBlock language="ts">
{`import { dummyFunction } from "../test/foo.ts";
dummyFunction("hello", "this is dashboard page");`}

</CodeBlock>
</TabItem>
<TabItem value="ts" label="after">
<CodeBlock language="ts">
{`import { dummyFunction } from "../test/foo.ts";

dummyFunction({
"title": "hello",
"description": "this is dashboard page"
});`}

</CodeBlock>
</TabItem>
</Tabs>