Skip to content

Commit bec33db

Browse files
Merge pull request #6 from developer-bandi/feature/change-parameter-object
feature: add change-parameter-object options
2 parents 297f08c + d5b8a18 commit bec33db

6 files changed

Lines changed: 294 additions & 1 deletion

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { z } from "zod";
2+
import zodToJsonSchema from "zod-to-json-schema";
3+
4+
export const optionsSchema = z
5+
.object({
6+
functionSourceType: z
7+
.enum(["absolute", "relative"])
8+
.optional()
9+
.describe("function source's type. you can choose absolute or relative"),
10+
functionNameType: z
11+
.enum(["default", "named"])
12+
.optional()
13+
.describe("function name's type. you can choose default or named"),
14+
functionSource: z
15+
.string()
16+
.describe("function source. you can choose package name or target path"),
17+
functionName: z.string().describe("function name"),
18+
objectKeys: z.string().array().describe("function parameter object keys"),
19+
})
20+
.describe("remove props");
21+
22+
export const optionsSchemaJsonSchema = zodToJsonSchema(optionsSchema);
23+
24+
export type OptionsSchema = z.infer<typeof optionsSchema>;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { it, expect, describe } from "vitest";
2+
import transform from "./transformer";
3+
import { OptionsSchema } from "./optionsSchema";
4+
import getTransformParms from "../../../utils/getTransformPaths";
5+
6+
describe("general case", () => {
7+
it("named export", () => {
8+
const input = `
9+
import { dummyFunction } from "foo";
10+
dummyFunction("hello", "this is dashboard page");
11+
`;
12+
const expectedOuput = `
13+
import { dummyFunction } from "foo";
14+
dummyFunction({
15+
"title": "hello",
16+
"description": "this is dashboard page"
17+
});
18+
`;
19+
const transformParms = getTransformParms<OptionsSchema>({
20+
input,
21+
options: {
22+
functionSourceType: "absolute",
23+
functionNameType: "named",
24+
functionSource: "foo",
25+
functionName: "dummyFunction",
26+
objectKeys: ["title", "description"],
27+
},
28+
});
29+
const output = transform(...transformParms);
30+
31+
expect(output).toEqual(expectedOuput);
32+
});
33+
});
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import { OptionsSchema } from "./optionsSchema";
2+
import getConvertedPath from "../../../utils/getConvertedPath";
3+
import type { API, FileInfo } from "jscodeshift";
4+
5+
function transformer(file: FileInfo, api: API, options: OptionsSchema) {
6+
const sourceCode = file.source;
7+
const jscodeshift = api.jscodeshift;
8+
9+
const {
10+
functionSourceType = "absolute",
11+
functionNameType = "default",
12+
functionSource,
13+
functionName,
14+
objectKeys,
15+
} = options;
16+
17+
const convertedComponentSource = getConvertedPath({
18+
type: functionSourceType,
19+
currentPath: file.path,
20+
targetPath: functionSource,
21+
});
22+
23+
let convertedComponentName: null | string = null;
24+
25+
jscodeshift(sourceCode)
26+
.find(jscodeshift.ImportDeclaration)
27+
.filter((node) => node.value.source.value === convertedComponentSource)
28+
.forEach((node) => {
29+
node.value.specifiers?.forEach((specifier) => {
30+
if (
31+
specifier.type === "ImportDefaultSpecifier" &&
32+
functionNameType === "default"
33+
) {
34+
return (convertedComponentName =
35+
specifier.local?.type === "Identifier"
36+
? specifier.local.name
37+
: functionName);
38+
}
39+
40+
if (
41+
specifier.type === "ImportSpecifier" &&
42+
functionNameType === "named" &&
43+
specifier.imported.type === "Identifier" &&
44+
specifier.imported.name === functionName
45+
) {
46+
return (convertedComponentName =
47+
specifier.local?.type === "Identifier"
48+
? specifier.local.name
49+
: functionName);
50+
}
51+
52+
if (
53+
specifier.type === "ImportNamespaceSpecifier" &&
54+
functionNameType === "default"
55+
) {
56+
return (convertedComponentName =
57+
specifier.local?.type === "Identifier"
58+
? specifier.local.name
59+
: functionName);
60+
}
61+
62+
if (
63+
specifier.type === "ImportNamespaceSpecifier" &&
64+
functionNameType === "named"
65+
) {
66+
return (convertedComponentName = functionName);
67+
}
68+
});
69+
});
70+
71+
if (!convertedComponentName) {
72+
return sourceCode;
73+
}
74+
75+
console.log(convertedComponentName);
76+
77+
return jscodeshift(sourceCode)
78+
.find(jscodeshift.CallExpression)
79+
.filter((node) => {
80+
return (
81+
node.value.callee.type === "Identifier" &&
82+
node.value.callee.name === convertedComponentName &&
83+
node.scope.isGlobal
84+
);
85+
})
86+
.forEach((node) => {
87+
console.log(node.value.arguments);
88+
node.value.arguments = [
89+
jscodeshift.objectExpression(
90+
node.value.arguments
91+
.filter((argument) => argument.type !== "SpreadElement")
92+
.map((argument, index) => {
93+
return jscodeshift.objectProperty(
94+
jscodeshift.literal(objectKeys[index]),
95+
argument
96+
);
97+
})
98+
.filter(Boolean)
99+
),
100+
];
101+
})
102+
.toSource();
103+
}
104+
105+
export default transformer;

website/transformers/component/_category_.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"label": "Components",
2+
"label": "Component",
33
"position": 3,
44
"link": {
55
"type": "generated-index"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"label": "Function",
3+
"position": 4,
4+
"link": {
5+
"type": "generated-index"
6+
}
7+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
---
2+
sidebar_position: 1
3+
---
4+
5+
import Tabs from "@theme/Tabs";
6+
import TabItem from "@theme/TabItem";
7+
import CodeBlock from "@theme/CodeBlock";
8+
9+
# Change Parameter Object
10+
11+
Modify the function argument to take an object.
12+
13+
<Tabs>
14+
<TabItem value="js" label="before" default>
15+
<CodeBlock language="ts">
16+
{`import { dummyFunction } from "foo";
17+
dummyFunction("hello", "this is dashboard page");`}
18+
19+
</CodeBlock>
20+
</TabItem>
21+
<TabItem value="ts" label="after">
22+
<CodeBlock language="ts">
23+
{`import { dummyFunction } from "foo";
24+
25+
dummyFunction({
26+
"title": "hello",
27+
"description": "this is dashboard page"
28+
});`}
29+
30+
</CodeBlock>
31+
</TabItem>
32+
</Tabs>
33+
34+
## Options
35+
36+
```typescript
37+
type Options = {
38+
functionSourceType?: "absolute" | "relative";
39+
functionNameType?: "default" | "named";
40+
functionSource: string;
41+
functionName: string;
42+
objectKeys: string[];
43+
};
44+
```
45+
46+
- functionSourceType: componentSource's type. you can choose absolute or relative
47+
- functionNameType: changed target specifier
48+
- functionSource: component source. you can choose package name or target path
49+
- functionName: props to add's component name
50+
- objectKeys: add props's name
51+
52+
## Usage
53+
54+
The usage method differs depending on the source type of the import statement to be converted.
55+
56+
### absolute
57+
58+
This is a situation where the source of the import module you want to change is an absolute path.
59+
60+
```typescript title="option.ts"
61+
const option = {
62+
functionSourceType: "absolute",
63+
functionNameType: "named",
64+
functionSource: "foo",
65+
functionName: "dummyFunction",
66+
objectKeys: ["title", "description"],
67+
};
68+
```
69+
70+
<Tabs>
71+
<TabItem value="js" label="before" default>
72+
<CodeBlock language="ts">
73+
{`import { dummyFunction } from "foo";
74+
dummyFunction("hello", "this is dashboard page");`}
75+
76+
</CodeBlock>
77+
</TabItem>
78+
<TabItem value="ts" label="after">
79+
<CodeBlock language="ts">
80+
{`import { dummyFunction } from "foo";
81+
82+
dummyFunction({
83+
"title": "hello",
84+
"description": "this is dashboard page"
85+
});`}
86+
87+
</CodeBlock>
88+
</TabItem>
89+
</Tabs>
90+
91+
### relative
92+
93+
This is a situation where the source of the import module you want to change is an absolute path.
94+
95+
```typescript title="option.ts"
96+
const option = {
97+
functionSourceType: "relative",
98+
functionNameType: "named",
99+
functionSource: path.join(process.cwd(), "../test/foo.ts"),,
100+
functionName: "dummyFunction",
101+
objectKeys: ["title", "description"],
102+
};
103+
```
104+
105+
<Tabs>
106+
<TabItem value="js" label="before" default>
107+
<CodeBlock language="ts">
108+
{`import { dummyFunction } from "../test/foo.ts";
109+
dummyFunction("hello", "this is dashboard page");`}
110+
111+
</CodeBlock>
112+
</TabItem>
113+
<TabItem value="ts" label="after">
114+
<CodeBlock language="ts">
115+
{`import { dummyFunction } from "../test/foo.ts";
116+
117+
dummyFunction({
118+
"title": "hello",
119+
"description": "this is dashboard page"
120+
});`}
121+
122+
</CodeBlock>
123+
</TabItem>
124+
</Tabs>

0 commit comments

Comments
 (0)