@mysten/create-dapp 0.5.12 → 0.6.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 (43) hide show
  1. package/CHANGELOG.md +46 -2
  2. package/README.md +0 -1
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +32 -8
  6. package/dist/index.js.map +1 -1
  7. package/package.json +14 -10
  8. package/src/index.ts +58 -36
  9. package/templates/.oxlintrc.json +5 -0
  10. package/templates/react-client-dapp/README.md +31 -4
  11. package/templates/react-client-dapp/index.html +2 -48
  12. package/templates/react-client-dapp/package.json +17 -20
  13. package/templates/react-client-dapp/prettier.config.cjs +0 -1
  14. package/templates/react-client-dapp/src/App.tsx +12 -30
  15. package/templates/react-client-dapp/src/OwnedObjects.tsx +58 -31
  16. package/templates/react-client-dapp/src/WalletStatus.tsx +38 -13
  17. package/templates/react-client-dapp/src/components/ui/card.tsx +75 -0
  18. package/templates/react-client-dapp/src/dApp-kit.ts +24 -0
  19. package/templates/react-client-dapp/src/index.css +39 -0
  20. package/templates/react-client-dapp/src/lib/utils.ts +6 -0
  21. package/templates/react-client-dapp/src/main.tsx +8 -14
  22. package/templates/react-client-dapp/vite.config.mts +2 -1
  23. package/templates/react-e2e-counter/.gitattributes +2 -0
  24. package/templates/react-e2e-counter/README.md +53 -7
  25. package/templates/react-e2e-counter/index.html +2 -48
  26. package/templates/react-e2e-counter/package.json +21 -23
  27. package/templates/react-e2e-counter/prettier.config.cjs +0 -1
  28. package/templates/react-e2e-counter/src/App.tsx +29 -30
  29. package/templates/react-e2e-counter/src/Counter.tsx +147 -74
  30. package/templates/react-e2e-counter/src/CreateCounter.tsx +84 -43
  31. package/templates/react-e2e-counter/src/components/ui/button.tsx +52 -0
  32. package/templates/react-e2e-counter/src/components/ui/card.tsx +75 -0
  33. package/templates/react-e2e-counter/src/constants.ts +4 -3
  34. package/templates/react-e2e-counter/src/contracts/counter/counter.ts +96 -0
  35. package/templates/react-e2e-counter/src/contracts/utils/index.ts +243 -0
  36. package/templates/react-e2e-counter/src/dApp-kit.ts +48 -0
  37. package/templates/react-e2e-counter/src/index.css +39 -0
  38. package/templates/react-e2e-counter/src/lib/utils.ts +6 -0
  39. package/templates/react-e2e-counter/src/main.tsx +8 -14
  40. package/templates/react-e2e-counter/sui-codegen.config.ts +13 -0
  41. package/templates/react-e2e-counter/vite.config.mts +2 -1
  42. package/templates/react-client-dapp/src/networkConfig.ts +0 -17
  43. package/templates/react-e2e-counter/src/networkConfig.ts +0 -31
@@ -1,106 +1,179 @@
1
1
  import {
2
2
  useCurrentAccount,
3
- useSignAndExecuteTransaction,
4
- useSuiClient,
5
- useSuiClientQuery,
6
- } from "@mysten/dapp-kit";
7
- import type { SuiObjectData } from "@mysten/sui/client";
3
+ useCurrentClient,
4
+ useDAppKit,
5
+ } from "@mysten/dapp-kit-react";
6
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
8
7
  import { Transaction } from "@mysten/sui/transactions";
9
- import { Button, Flex, Heading, Text } from "@radix-ui/themes";
10
- import { useNetworkVariable } from "./networkConfig";
11
- import { useState } from "react";
12
- import ClipLoader from "react-spinners/ClipLoader";
8
+ import {
9
+ Counter as CounterStruct,
10
+ increment,
11
+ setValue,
12
+ } from "./contracts/counter/counter";
13
+ import { Button } from "./components/ui/button";
14
+ import {
15
+ Card,
16
+ CardContent,
17
+ CardDescription,
18
+ CardHeader,
19
+ CardTitle,
20
+ } from "./components/ui/card";
21
+ import { Plus, RotateCcw } from "lucide-react";
13
22
 
14
23
  export function Counter({ id }: { id: string }) {
15
- const counterPackageId = useNetworkVariable("counterPackageId");
16
- const suiClient = useSuiClient();
24
+ const client = useCurrentClient();
17
25
  const currentAccount = useCurrentAccount();
18
- const { mutate: signAndExecute } = useSignAndExecuteTransaction();
19
- const { data, isPending, error, refetch } = useSuiClientQuery("getObject", {
20
- id,
21
- options: {
22
- showContent: true,
23
- showOwner: true,
26
+ const dAppKit = useDAppKit();
27
+ const queryClient = useQueryClient();
28
+
29
+ // Fetch counter object with React Query
30
+ const { data, isPending, error } = useQuery({
31
+ queryKey: ["counter", id],
32
+ queryFn: async () => {
33
+ const { object } = await client.getObject({
34
+ objectId: id,
35
+ include: { content: true },
36
+ });
37
+ return object;
24
38
  },
25
39
  });
26
40
 
27
- const [waitingForTxn, setWaitingForTxn] = useState("");
41
+ // Mutation for executing move calls
42
+ const incrementMutation = useMutation({
43
+ mutationFn: async () => {
44
+ const tx = new Transaction();
45
+ tx.add(increment({ arguments: { counter: id } }));
28
46
 
29
- const executeMoveCall = (method: "increment" | "reset") => {
30
- setWaitingForTxn(method);
47
+ const result = await dAppKit.signAndExecuteTransaction({
48
+ transaction: tx,
49
+ });
31
50
 
32
- const tx = new Transaction();
51
+ if (result.$kind === "FailedTransaction") {
52
+ throw new Error("Transaction failed");
53
+ }
33
54
 
34
- if (method === "reset") {
35
- tx.moveCall({
36
- arguments: [tx.object(id), tx.pure.u64(0)],
37
- target: `${counterPackageId}::counter::set_value`,
38
- });
39
- } else {
40
- tx.moveCall({
41
- arguments: [tx.object(id)],
42
- target: `${counterPackageId}::counter::increment`,
43
- });
44
- }
55
+ await client.waitForTransaction({ result });
56
+ return result;
57
+ },
58
+ onSuccess: () => {
59
+ queryClient.invalidateQueries({ queryKey: ["counter", id] });
60
+ },
61
+ onError: (err) => {
62
+ console.error(err);
63
+ },
64
+ });
45
65
 
46
- signAndExecute(
47
- {
66
+ const resetMutation = useMutation({
67
+ mutationFn: async () => {
68
+ const tx = new Transaction();
69
+ tx.add(setValue({ arguments: { counter: id, value: 0 } }));
70
+
71
+ const result = await dAppKit.signAndExecuteTransaction({
48
72
  transaction: tx,
49
- },
50
- {
51
- onSuccess: (tx) => {
52
- suiClient.waitForTransaction({ digest: tx.digest }).then(async () => {
53
- await refetch();
54
- setWaitingForTxn("");
55
- });
56
- },
57
- },
58
- );
59
- };
73
+ });
74
+
75
+ if (result.$kind === "FailedTransaction") {
76
+ throw new Error("Transaction failed");
77
+ }
60
78
 
61
- if (isPending) return <Text>Loading...</Text>;
79
+ await client.waitForTransaction({ result });
80
+ return result;
81
+ },
82
+ onSuccess: () => {
83
+ queryClient.invalidateQueries({ queryKey: ["counter", id] });
84
+ },
85
+ onError: (err) => {
86
+ console.error(err);
87
+ },
88
+ });
89
+
90
+ const isAnyMutationPending =
91
+ incrementMutation.isPending || resetMutation.isPending;
92
+
93
+ if (isPending) {
94
+ return (
95
+ <Card>
96
+ <CardContent className="flex items-center justify-center py-12">
97
+ <div className="text-muted-foreground">Loading...</div>
98
+ </CardContent>
99
+ </Card>
100
+ );
101
+ }
62
102
 
63
- if (error) return <Text>Error: {error.message}</Text>;
103
+ if (error) {
104
+ return (
105
+ <Card>
106
+ <CardContent className="py-6">
107
+ <p className="text-destructive-foreground">
108
+ Error: {(error as Error)?.message || "Unknown error"}
109
+ </p>
110
+ </CardContent>
111
+ </Card>
112
+ );
113
+ }
64
114
 
65
- if (!data.data) return <Text>Not found</Text>;
115
+ if (!data) {
116
+ return (
117
+ <Card>
118
+ <CardContent className="py-6">
119
+ <p className="text-muted-foreground">Counter not found</p>
120
+ </CardContent>
121
+ </Card>
122
+ );
123
+ }
66
124
 
67
- const ownedByCurrentAccount =
68
- getCounterFields(data.data)?.owner === currentAccount?.address;
125
+ const fields = getCounterFields(data);
126
+ const ownedByCurrentAccount = fields?.owner === currentAccount?.address;
69
127
 
70
128
  return (
71
- <>
72
- <Heading size="3">Counter {id}</Heading>
73
-
74
- <Flex direction="column" gap="2">
75
- <Text>Count: {getCounterFields(data.data)?.value}</Text>
76
- <Flex direction="row" gap="2">
129
+ <Card>
130
+ <CardHeader>
131
+ <CardTitle>Counter</CardTitle>
132
+ <CardDescription className="font-mono text-xs break-all">
133
+ {id}
134
+ </CardDescription>
135
+ </CardHeader>
136
+ <CardContent className="space-y-6">
137
+ <div className="text-center">
138
+ <span className="text-6xl font-bold tabular-nums">
139
+ {fields?.value ?? 0}
140
+ </span>
141
+ </div>
142
+ <div className="flex gap-2 justify-center">
77
143
  <Button
78
- onClick={() => executeMoveCall("increment")}
79
- disabled={waitingForTxn !== ""}
144
+ onClick={() => incrementMutation.mutate()}
145
+ loading={incrementMutation.isPending}
146
+ disabled={isAnyMutationPending}
80
147
  >
81
- {waitingForTxn === "increment" ? (
82
- <ClipLoader size={20} />
83
- ) : (
84
- "Increment"
85
- )}
148
+ <Plus className="h-4 w-4" />
149
+ Increment
86
150
  </Button>
87
- {ownedByCurrentAccount ? (
151
+ {ownedByCurrentAccount && (
88
152
  <Button
89
- onClick={() => executeMoveCall("reset")}
90
- disabled={waitingForTxn !== ""}
153
+ variant="secondary"
154
+ onClick={() => resetMutation.mutate()}
155
+ loading={resetMutation.isPending}
156
+ disabled={isAnyMutationPending}
91
157
  >
92
- {waitingForTxn === "reset" ? <ClipLoader size={20} /> : "Reset"}
158
+ <RotateCcw className="h-4 w-4" />
159
+ Reset
93
160
  </Button>
94
- ) : null}
95
- </Flex>
96
- </Flex>
97
- </>
161
+ )}
162
+ </div>
163
+ </CardContent>
164
+ </Card>
98
165
  );
99
166
  }
100
- function getCounterFields(data: SuiObjectData) {
101
- if (data.content?.dataType !== "moveObject") {
167
+
168
+ function getCounterFields(data: { content?: Uint8Array }) {
169
+ if (!data.content) {
102
170
  return null;
103
171
  }
104
172
 
105
- return data.content.fields as { value: number; owner: string };
173
+ try {
174
+ const parsed = CounterStruct.parse(data.content);
175
+ return { value: Number(parsed.value), owner: parsed.owner };
176
+ } catch {
177
+ return null;
178
+ }
106
179
  }
@@ -1,60 +1,101 @@
1
1
  import { Transaction } from "@mysten/sui/transactions";
2
- import { Button, Container } from "@radix-ui/themes";
3
- import { useSignAndExecuteTransaction, useSuiClient } from "@mysten/dapp-kit";
4
- import { useNetworkVariable } from "./networkConfig";
5
- import ClipLoader from "react-spinners/ClipLoader";
2
+ import { useCurrentClient, useDAppKit } from "@mysten/dapp-kit-react";
3
+ import { useState } from "react";
4
+ import { create as createCounter } from "./contracts/counter/counter";
5
+ import { Button } from "./components/ui/button";
6
+ import {
7
+ Card,
8
+ CardContent,
9
+ CardDescription,
10
+ CardHeader,
11
+ CardTitle,
12
+ } from "./components/ui/card";
13
+ import { PlusCircle } from "lucide-react";
6
14
 
7
15
  export function CreateCounter({
8
16
  onCreated,
9
17
  }: {
10
18
  onCreated: (id: string) => void;
11
19
  }) {
12
- const counterPackageId = useNetworkVariable("counterPackageId");
13
- const suiClient = useSuiClient();
14
- const {
15
- mutate: signAndExecute,
16
- isSuccess,
17
- isPending,
18
- } = useSignAndExecuteTransaction();
19
-
20
- function create() {
20
+ const client = useCurrentClient();
21
+ const dAppKit = useDAppKit();
22
+ const [isPending, setIsPending] = useState(false);
23
+ const [error, setError] = useState<string | null>(null);
24
+
25
+ async function create() {
26
+ setIsPending(true);
27
+ setError(null);
28
+
21
29
  const tx = new Transaction();
22
30
 
23
- tx.moveCall({
24
- arguments: [],
25
- target: `${counterPackageId}::counter::create`,
26
- });
31
+ tx.add(createCounter());
27
32
 
28
- signAndExecute(
29
- {
33
+ try {
34
+ const result = await dAppKit.signAndExecuteTransaction({
30
35
  transaction: tx,
31
- },
32
- {
33
- onSuccess: async ({ digest }) => {
34
- const { effects } = await suiClient.waitForTransaction({
35
- digest: digest,
36
- options: {
37
- showEffects: true,
38
- },
39
- });
40
-
41
- onCreated(effects?.created?.[0]?.reference?.objectId!);
36
+ });
37
+
38
+ if (result.$kind === "FailedTransaction") {
39
+ throw new Error("Transaction failed");
40
+ }
41
+
42
+ const txResult = await client.waitForTransaction({
43
+ digest: result.Transaction.digest,
44
+ include: {
45
+ effects: true,
42
46
  },
43
- },
44
- );
47
+ });
48
+
49
+ if (txResult.$kind === "FailedTransaction") {
50
+ throw new Error("Transaction failed");
51
+ }
52
+
53
+ // Find the created object from the effects
54
+ const createdObject = txResult.Transaction.effects?.changedObjects?.find(
55
+ (obj: { idOperation?: string; objectId?: string }) =>
56
+ obj.idOperation === "Created",
57
+ );
58
+
59
+ const id = createdObject?.objectId;
60
+
61
+ if (!id) {
62
+ throw new Error("Counter object ID not found in transaction effects");
63
+ }
64
+
65
+ onCreated(id);
66
+ } catch (err) {
67
+ console.error(err);
68
+ setError(err instanceof Error ? err.message : "An error occurred");
69
+ setIsPending(false);
70
+ }
45
71
  }
46
72
 
47
73
  return (
48
- <Container>
49
- <Button
50
- size="3"
51
- onClick={() => {
52
- create();
53
- }}
54
- disabled={isSuccess || isPending}
55
- >
56
- {isSuccess || isPending ? <ClipLoader size={20} /> : "Create Counter"}
57
- </Button>
58
- </Container>
74
+ <Card>
75
+ <CardHeader>
76
+ <CardTitle className="flex items-center gap-2">
77
+ <PlusCircle className="h-5 w-5" />
78
+ Create Counter
79
+ </CardTitle>
80
+ <CardDescription>
81
+ Deploy a new counter object on the Sui blockchain.
82
+ </CardDescription>
83
+ </CardHeader>
84
+ <CardContent>
85
+ {error && (
86
+ <div className="mb-4 p-3 rounded-md bg-red-50 border border-red-200 text-red-800 text-sm">
87
+ {error}
88
+ </div>
89
+ )}
90
+ <Button
91
+ size="lg"
92
+ className="w-full"
93
+ onClick={create}
94
+ loading={isPending}
95
+ >
96
+ Create Counter
97
+ </Button>
98
+ </CardContent>
99
+ </Card>
59
100
  );
60
101
  }
@@ -0,0 +1,52 @@
1
+ import type { ButtonHTMLAttributes } from "react";
2
+ import { cn } from "../../lib/utils";
3
+ import { Loader2 } from "lucide-react";
4
+
5
+ export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
6
+ variant?: "default" | "secondary" | "outline" | "ghost";
7
+ size?: "default" | "sm" | "lg";
8
+ loading?: boolean;
9
+ ref?: React.Ref<HTMLButtonElement>;
10
+ }
11
+
12
+ function Button({
13
+ className,
14
+ variant = "default",
15
+ size = "default",
16
+ loading = false,
17
+ disabled,
18
+ children,
19
+ ref,
20
+ ...props
21
+ }: ButtonProps) {
22
+ return (
23
+ <button
24
+ className={cn(
25
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",
26
+ {
27
+ "bg-primary text-primary-foreground shadow hover:bg-primary/90":
28
+ variant === "default",
29
+ "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80":
30
+ variant === "secondary",
31
+ "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground":
32
+ variant === "outline",
33
+ "hover:bg-accent hover:text-accent-foreground": variant === "ghost",
34
+ },
35
+ {
36
+ "h-9 px-4 py-2": size === "default",
37
+ "h-8 rounded-md px-3 text-xs": size === "sm",
38
+ "h-10 rounded-md px-8": size === "lg",
39
+ },
40
+ className,
41
+ )}
42
+ ref={ref}
43
+ disabled={disabled || loading}
44
+ {...props}
45
+ >
46
+ {loading && <Loader2 className="h-4 w-4 animate-spin" />}
47
+ {children}
48
+ </button>
49
+ );
50
+ }
51
+
52
+ export { Button };
@@ -0,0 +1,75 @@
1
+ import type { HTMLAttributes } from "react";
2
+ import { cn } from "../../lib/utils";
3
+
4
+ function Card({
5
+ className,
6
+ ref,
7
+ ...props
8
+ }: HTMLAttributes<HTMLDivElement> & { ref?: React.Ref<HTMLDivElement> }) {
9
+ return (
10
+ <div
11
+ ref={ref}
12
+ className={cn(
13
+ "rounded-xl border bg-card text-card-foreground shadow",
14
+ className,
15
+ )}
16
+ {...props}
17
+ />
18
+ );
19
+ }
20
+
21
+ function CardHeader({
22
+ className,
23
+ ref,
24
+ ...props
25
+ }: HTMLAttributes<HTMLDivElement> & { ref?: React.Ref<HTMLDivElement> }) {
26
+ return (
27
+ <div
28
+ ref={ref}
29
+ className={cn("flex flex-col space-y-1.5 p-6", className)}
30
+ {...props}
31
+ />
32
+ );
33
+ }
34
+
35
+ function CardTitle({
36
+ className,
37
+ ref,
38
+ ...props
39
+ }: HTMLAttributes<HTMLHeadingElement> & {
40
+ ref?: React.Ref<HTMLHeadingElement>;
41
+ }) {
42
+ return (
43
+ <h3
44
+ ref={ref}
45
+ className={cn("font-semibold leading-none tracking-tight", className)}
46
+ {...props}
47
+ />
48
+ );
49
+ }
50
+
51
+ function CardDescription({
52
+ className,
53
+ ref,
54
+ ...props
55
+ }: HTMLAttributes<HTMLParagraphElement> & {
56
+ ref?: React.Ref<HTMLParagraphElement>;
57
+ }) {
58
+ return (
59
+ <p
60
+ ref={ref}
61
+ className={cn("text-sm text-muted-foreground", className)}
62
+ {...props}
63
+ />
64
+ );
65
+ }
66
+
67
+ function CardContent({
68
+ className,
69
+ ref,
70
+ ...props
71
+ }: HTMLAttributes<HTMLDivElement> & { ref?: React.Ref<HTMLDivElement> }) {
72
+ return <div ref={ref} className={cn("p-6 pt-0", className)} {...props} />;
73
+ }
74
+
75
+ export { Card, CardHeader, CardTitle, CardDescription, CardContent };
@@ -1,3 +1,4 @@
1
- export const DEVNET_COUNTER_PACKAGE_ID = "0xTODO";
2
- export const TESTNET_COUNTER_PACKAGE_ID = "0xTODO";
3
- export const MAINNET_COUNTER_PACKAGE_ID = "0xTODO";
1
+ // TODO: Update these with your deployed package IDs after running `sui client publish`
2
+ export const DEVNET_COUNTER_PACKAGE_ID: string | undefined = undefined;
3
+ export const TESTNET_COUNTER_PACKAGE_ID: string | undefined = undefined;
4
+ export const MAINNET_COUNTER_PACKAGE_ID: string | undefined = undefined;
@@ -0,0 +1,96 @@
1
+ /**************************************************************
2
+ * THIS FILE IS GENERATED AND SHOULD NOT BE MANUALLY MODIFIED *
3
+ **************************************************************/
4
+
5
+ /**
6
+ * This example demonstrates a basic use of a shared object. Rules:
7
+ *
8
+ * - anyone can create and share a counter
9
+ * - everyone can increment a counter by 1
10
+ * - the owner of the counter can reset it to any value
11
+ */
12
+
13
+ import {
14
+ MoveStruct,
15
+ normalizeMoveArguments,
16
+ type RawTransactionArgument,
17
+ } from "../utils/index.js";
18
+ import { bcs } from "@mysten/sui/bcs";
19
+ import { type Transaction } from "@mysten/sui/transactions";
20
+ const $moduleName = "@local-pkg/counter::counter";
21
+ export const Counter = new MoveStruct({
22
+ name: `${$moduleName}::Counter`,
23
+ fields: {
24
+ id: bcs.Address,
25
+ owner: bcs.Address,
26
+ value: bcs.u64(),
27
+ },
28
+ });
29
+ export interface CreateOptions {
30
+ package?: string;
31
+ arguments?: [];
32
+ }
33
+ /** Create and share a Counter object. */
34
+ export function create(options: CreateOptions = {}) {
35
+ const packageAddress = options.package ?? "@local-pkg/counter";
36
+ return (tx: Transaction) =>
37
+ tx.moveCall({
38
+ package: packageAddress,
39
+ module: "counter",
40
+ function: "create",
41
+ });
42
+ }
43
+ export interface IncrementArguments {
44
+ counter: RawTransactionArgument<string>;
45
+ }
46
+ export interface IncrementOptions {
47
+ package?: string;
48
+ arguments: IncrementArguments | [counter: RawTransactionArgument<string>];
49
+ }
50
+ /** Increment a counter by 1. */
51
+ export function increment(options: IncrementOptions) {
52
+ const packageAddress = options.package ?? "@local-pkg/counter";
53
+ const argumentsTypes = [null] satisfies (string | null)[];
54
+ const parameterNames = ["counter"];
55
+ return (tx: Transaction) =>
56
+ tx.moveCall({
57
+ package: packageAddress,
58
+ module: "counter",
59
+ function: "increment",
60
+ arguments: normalizeMoveArguments(
61
+ options.arguments,
62
+ argumentsTypes,
63
+ parameterNames,
64
+ ),
65
+ });
66
+ }
67
+ export interface SetValueArguments {
68
+ counter: RawTransactionArgument<string>;
69
+ value: RawTransactionArgument<number | bigint>;
70
+ }
71
+ export interface SetValueOptions {
72
+ package?: string;
73
+ arguments:
74
+ | SetValueArguments
75
+ | [
76
+ counter: RawTransactionArgument<string>,
77
+ value: RawTransactionArgument<number | bigint>,
78
+ ];
79
+ }
80
+ /** Set value (only runnable by the Counter owner) */
81
+ export function setValue(options: SetValueOptions) {
82
+ const packageAddress = options.package ?? "@local-pkg/counter";
83
+ const argumentsTypes = [null, "u64"] satisfies (string | null)[];
84
+ const parameterNames = ["counter", "value"];
85
+ return (tx: Transaction) =>
86
+ tx.moveCall({
87
+ package: packageAddress,
88
+ module: "counter",
89
+ function: "set_value",
90
+ arguments: normalizeMoveArguments(
91
+ options.arguments,
92
+ argumentsTypes,
93
+ parameterNames,
94
+ ),
95
+ });
96
+ }