sdnext 0.0.6 → 0.0.8

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.
@@ -1,5 +1,6 @@
1
1
  import { Command } from "commander";
2
2
  export type HookType = "get" | "query" | "mutation";
3
+ export type OperationType = HookType | "skip";
3
4
  export type HookContentMap = Record<HookType, string>;
4
5
  export interface HookData extends HookContentMap {
5
6
  overwrite: boolean;
@@ -1,6 +1,9 @@
1
1
  import { mkdir, readFile, readdir, stat, writeFile } from "fs/promises";
2
2
  import { join, parse, relative } from "path";
3
+ import { cwd } from "process";
3
4
  import { checkbox as prompts_checkbox, select as prompts_select } from "@inquirer/prompts";
5
+ import { readSdNextSetting } from "./readSdNextSetting.js";
6
+ import { writeSdNextSetting } from "./writeSdNextSetting.js";
4
7
  function getHookTypeFromName(name) {
5
8
  if (/^get[^a-z]/.test(name)) return "get";
6
9
  if (/^query[^a-z]/.test(name)) return "query";
@@ -20,7 +23,8 @@ async function createHook(path, hookMap) {
20
23
  const hasSchema = !!match;
21
24
  const upName = name.replace(/^./, (char)=>char.toUpperCase());
22
25
  const key = name.replace(/[A-Z]/g, (char)=>`-${char.toLowerCase()}`);
23
- const mutationHook = `import { useMutation, UseMutationOptions } from "@tanstack/react-query"
26
+ const mutationHook = `import { useId } from "react"
27
+ import { useMutation, UseMutationOptions } from "@tanstack/react-query"
24
28
  import { createRequestFn } from "deepsea-tools"
25
29
 
26
30
  import { ${name}Action } from "@/actions/${join(dir, name)}"
@@ -38,15 +42,34 @@ export interface Use${upName}Params<TOnMutateResult = unknown> extends Omit<
38
42
  > {}
39
43
 
40
44
  export function use${upName}<TOnMutateResult = unknown>({ onMutate, onSuccess, onError, onSettled, ...rest }: Use${upName}Params<TOnMutateResult> = {}) {
45
+ const key = useId()
46
+
41
47
  return useMutation({
42
48
  mutationFn: ${name}Client,
43
49
  onMutate(variables, context) {
50
+ message.open({
51
+ key,
52
+ type: "loading",
53
+ content: "中...",
54
+ duration: 0,
55
+ })
44
56
  return onMutate?.(variables, context) as TOnMutateResult | Promise<TOnMutateResult>
45
57
  },
46
58
  onSuccess(data, variables, onMutateResult, context) {
59
+ context.client.invalidateQueries({ queryKey: ["query-${key.replace(/^.+-/, "")}"] })
60
+ context.client.invalidateQueries({ queryKey: ["get-${key.replace(/^.+-/, "")}", data.id] })
61
+
62
+ message.open({
63
+ key,
64
+ type: "success",
65
+ content: "成功",
66
+ })
67
+
47
68
  return onSuccess?.(data, variables, onMutateResult, context)
48
69
  },
49
70
  onError(error, variables, onMutateResult, context) {
71
+ message.destroy(key)
72
+
50
73
  return onError?.(error, variables, onMutateResult, context)
51
74
  },
52
75
  onSettled(data, error, variables, onMutateResult, context) {
@@ -70,10 +93,12 @@ export const ${name}Client = createRequestFn(${hasSchema ? `{
70
93
  fn: ${name}Action,
71
94
  }`})
72
95
 
73
- export const ${name}ClientOptional = (id?: ${hasSchema ? `${match[1].replace(/Schema$/, "Params").replace(/^./, (char)=>char.toUpperCase())} | ` : ""}undefined) => (isNonNullable(id) ? ${name}Client(id) : null)
96
+ export function ${name}ClientOptional(id?: ${hasSchema ? `${match[1].replace(/Schema$/, "Params").replace(/^./, (char)=>char.toUpperCase())} | ` : ""}undefined) {
97
+ return isNonNullable(id) ? ${name}Client(id) : null
98
+ }
74
99
 
75
100
  export const use${upName} = createUseQuery({
76
- queryFn: ${name}Client,
101
+ queryFn: ${name}ClientOptional,
77
102
  queryKey: "${key}",
78
103
  })
79
104
  `;
@@ -139,6 +164,8 @@ async function hook(options, { args }) {
139
164
  if (0 === entires.length) return void console.log("All hooks are the latest.");
140
165
  const newEntires = entires.filter(([path, { overwrite }])=>overwrite);
141
166
  const oldEntires = entires.filter(([path, { overwrite }])=>!overwrite);
167
+ const root = cwd();
168
+ const setting = await readSdNextSetting();
142
169
  for await (const [path, { overwrite, type, ...map }] of newEntires){
143
170
  const answer = await prompts_select({
144
171
  message: path,
@@ -148,8 +175,11 @@ async function hook(options, { args }) {
148
175
  "get",
149
176
  "skip"
150
177
  ],
151
- default: type
178
+ default: setting.hook?.[root]?.[path] ?? type
152
179
  });
180
+ setting.hook ??= {};
181
+ setting.hook[root] ??= {};
182
+ setting.hook[root][path] = answer;
153
183
  if ("skip" === answer) continue;
154
184
  const { dir, base } = parse(path);
155
185
  await mkdir(join("hooks", dir), {
@@ -157,6 +187,7 @@ async function hook(options, { args }) {
157
187
  });
158
188
  await writeFile(join("hooks", dir, base.replace(/^./, (char)=>`use${char.toUpperCase()}`)), map[answer]);
159
189
  }
190
+ await writeSdNextSetting(setting);
160
191
  const overwrites = await prompts_checkbox({
161
192
  message: "Please check the hooks you want to overwrite",
162
193
  choices: oldEntires.map(([key])=>key)
@@ -0,0 +1,5 @@
1
+ import { OperationType } from "./hook";
2
+ export interface SdNextSetting {
3
+ hook?: Record<string, Record<string, OperationType>>;
4
+ }
5
+ export declare function readSdNextSetting(): Promise<SdNextSetting>;
@@ -0,0 +1,14 @@
1
+ import { existsSync } from "node:fs";
2
+ import { readFile } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import { join } from "node:path";
5
+ async function readSdNextSetting() {
6
+ const userDir = homedir();
7
+ const settingPath = join(userDir, ".sdnext.json");
8
+ if (existsSync(settingPath)) {
9
+ const setting = JSON.parse(await readFile(settingPath, "utf-8"));
10
+ return setting;
11
+ }
12
+ return {};
13
+ }
14
+ export { readSdNextSetting };
@@ -0,0 +1,2 @@
1
+ import { SdNextSetting } from "./readSdNextSetting";
2
+ export declare function writeSdNextSetting(setting: SdNextSetting): Promise<void>;
@@ -0,0 +1,9 @@
1
+ import { writeFile } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ async function writeSdNextSetting(setting) {
5
+ const userDir = homedir();
6
+ const settingPath = join(userDir, ".sdnext.json");
7
+ await writeFile(settingPath, JSON.stringify(setting, void 0, 4), "utf-8");
8
+ }
9
+ export { writeSdNextSetting };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sdnext",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "exports": {
package/src/utils/hook.ts CHANGED
@@ -1,11 +1,17 @@
1
1
  import { mkdir, readdir, readFile, stat, writeFile } from "fs/promises"
2
2
  import { join, parse, relative } from "path"
3
+ import { cwd } from "process"
3
4
 
4
5
  import { checkbox, select } from "@inquirer/prompts"
5
6
  import { Command } from "commander"
6
7
 
8
+ import { readSdNextSetting } from "./readSdNextSetting"
9
+ import { writeSdNextSetting } from "./writeSdNextSetting"
10
+
7
11
  export type HookType = "get" | "query" | "mutation"
8
12
 
13
+ export type OperationType = HookType | "skip"
14
+
9
15
  export type HookContentMap = Record<HookType, string>
10
16
 
11
17
  function getHookTypeFromName(name: string): HookType {
@@ -36,7 +42,8 @@ export async function createHook(path: string, hookMap: Record<string, HookData>
36
42
  const upName = name.replace(/^./, char => char.toUpperCase())
37
43
  const key = name.replace(/[A-Z]/g, char => `-${char.toLowerCase()}`)
38
44
 
39
- const mutationHook = `import { useMutation, UseMutationOptions } from "@tanstack/react-query"
45
+ const mutationHook = `import { useId } from "react"
46
+ import { useMutation, UseMutationOptions } from "@tanstack/react-query"
40
47
  import { createRequestFn } from "deepsea-tools"
41
48
 
42
49
  import { ${name}Action } from "@/actions/${join(dir, name)}"
@@ -62,15 +69,34 @@ export interface Use${upName}Params<TOnMutateResult = unknown> extends Omit<
62
69
  > {}
63
70
 
64
71
  export function use${upName}<TOnMutateResult = unknown>({ onMutate, onSuccess, onError, onSettled, ...rest }: Use${upName}Params<TOnMutateResult> = {}) {
72
+ const key = useId()
73
+
65
74
  return useMutation({
66
75
  mutationFn: ${name}Client,
67
76
  onMutate(variables, context) {
77
+ message.open({
78
+ key,
79
+ type: "loading",
80
+ content: "中...",
81
+ duration: 0,
82
+ })
68
83
  return onMutate?.(variables, context) as TOnMutateResult | Promise<TOnMutateResult>
69
84
  },
70
85
  onSuccess(data, variables, onMutateResult, context) {
86
+ context.client.invalidateQueries({ queryKey: ["query-${key.replace(/^.+-/, "")}"] })
87
+ context.client.invalidateQueries({ queryKey: ["get-${key.replace(/^.+-/, "")}", data.id] })
88
+
89
+ message.open({
90
+ key,
91
+ type: "success",
92
+ content: "成功",
93
+ })
94
+
71
95
  return onSuccess?.(data, variables, onMutateResult, context)
72
96
  },
73
97
  onError(error, variables, onMutateResult, context) {
98
+ message.destroy(key)
99
+
74
100
  return onError?.(error, variables, onMutateResult, context)
75
101
  },
76
102
  onSettled(data, error, variables, onMutateResult, context) {
@@ -103,10 +129,12 @@ export const ${name}Client = createRequestFn(${
103
129
  }`
104
130
  })
105
131
 
106
- export const ${name}ClientOptional = (id?: ${hasSchema ? `${match[1].replace(/Schema$/, "Params").replace(/^./, char => char.toUpperCase())} | ` : ""}undefined) => (isNonNullable(id) ? ${name}Client(id) : null)
132
+ export function ${name}ClientOptional(id?: ${hasSchema ? `${match[1].replace(/Schema$/, "Params").replace(/^./, char => char.toUpperCase())} | ` : ""}undefined) {
133
+ return isNonNullable(id) ? ${name}Client(id) : null
134
+ }
107
135
 
108
136
  export const use${upName} = createUseQuery({
109
- queryFn: ${name}Client,
137
+ queryFn: ${name}ClientOptional,
110
138
  queryKey: "${key}",
111
139
  })
112
140
  `
@@ -205,15 +233,21 @@ export async function hook(options: Record<string, string>, { args }: Command) {
205
233
 
206
234
  const oldEntires = entires.filter(([path, { overwrite }]) => !overwrite)
207
235
 
208
- for await (const [path, { overwrite, type, ...map }] of newEntires) {
209
- type OperationType = HookType | "skip"
236
+ const root = cwd()
237
+
238
+ const setting = await readSdNextSetting()
210
239
 
240
+ for await (const [path, { overwrite, type, ...map }] of newEntires) {
211
241
  const answer = await select<OperationType>({
212
242
  message: path,
213
243
  choices: ["mutation", "query", "get", "skip"],
214
- default: type,
244
+ default: setting.hook?.[root]?.[path] ?? type,
215
245
  })
216
246
 
247
+ setting.hook ??= {}
248
+ setting.hook[root] ??= {}
249
+ setting.hook[root][path] = answer
250
+
217
251
  if (answer === "skip") continue
218
252
 
219
253
  const { dir, base } = parse(path)
@@ -228,6 +262,8 @@ export async function hook(options: Record<string, string>, { args }: Command) {
228
262
  )
229
263
  }
230
264
 
265
+ await writeSdNextSetting(setting)
266
+
231
267
  const overwrites = await checkbox<string>({
232
268
  message: "Please check the hooks you want to overwrite",
233
269
  choices: oldEntires.map(([key]) => key),
@@ -0,0 +1,22 @@
1
+ import { existsSync } from "node:fs"
2
+ import { readFile } from "node:fs/promises"
3
+ import { homedir } from "node:os"
4
+ import { join } from "node:path"
5
+
6
+ import { OperationType } from "./hook"
7
+
8
+ export interface SdNextSetting {
9
+ hook?: Record<string, Record<string, OperationType>>
10
+ }
11
+
12
+ export async function readSdNextSetting(): Promise<SdNextSetting> {
13
+ const userDir = homedir()
14
+ const settingPath = join(userDir, ".sdnext.json")
15
+
16
+ if (existsSync(settingPath)) {
17
+ const setting = JSON.parse(await readFile(settingPath, "utf-8"))
18
+ return setting
19
+ }
20
+
21
+ return {}
22
+ }
@@ -0,0 +1,11 @@
1
+ import { writeFile } from "node:fs/promises"
2
+ import { homedir } from "node:os"
3
+ import { join } from "node:path"
4
+
5
+ import { SdNextSetting } from "./readSdNextSetting"
6
+
7
+ export async function writeSdNextSetting(setting: SdNextSetting) {
8
+ const userDir = homedir()
9
+ const settingPath = join(userDir, ".sdnext.json")
10
+ await writeFile(settingPath, JSON.stringify(setting, undefined, 4), "utf-8")
11
+ }