@wzyjs/next 0.3.32 → 0.3.37

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.
package/dist/Base.zmodel CHANGED
@@ -1,5 +1,6 @@
1
1
  generator client {
2
2
  provider = "prisma-client-js"
3
+ output = "../src/server/generated/prisma-client"
3
4
  }
4
5
 
5
6
  generator json {
@@ -18,32 +19,26 @@ plugin prisma {
18
19
 
19
20
  plugin enhancer {
20
21
  provider = '@core/enhancer'
21
- output = '../src/api/generated/enhancer'
22
+ output = '../src/server/generated/enhancer'
22
23
  preserveTsFiles = true
23
24
  }
24
25
 
25
- plugin zod {
26
- provider = '@core/zod'
27
- output = '../src/api/generated/zod'
28
- compile = false
29
- }
30
-
31
26
  plugin trpc {
32
27
  provider = '@zenstackhq/trpc'
33
- output = '../src/api/generated/trpc'
28
+ output = '../src/server/generated/trpc'
34
29
  version = 'v11'
35
30
  generateClientHelpers = 'next'
36
- importCreateRouter = "@/api/trpc/trpc"
37
- importProcedure = "@/api/trpc/procedures"
38
- zodSchemasImport = '@/api/generated/zod'
31
+ importCreateRouter = "@/server/trpc/init"
32
+ importProcedure = "@/server/trpc/procedures"
33
+ zodSchemasImport = '@/server/generated/.zenstack/zod'
39
34
  generateModelActions = 'findMany, findUnique, create, update, updateMany, delete, deleteMany, count'
40
35
  }
41
36
 
42
37
  plugin crud_tags {
43
38
  provider = '@wzyjs/next'
44
39
  title = 'Generate Some Api'
45
- output = 'src/api/generated'
46
- generateActions = 'crud, tags, noCheck'
40
+ output = 'src/server/generated'
41
+ generateActions = 'crud, tags, softDelete, noCheck'
47
42
  }
48
43
 
49
44
  abstract model Base {
@@ -4,7 +4,7 @@
4
4
  import { App } from '@/components'
5
5
 
6
6
  // @ts-ignore
7
- import { trpc as api } from '@/api/react'
7
+ import { api } from '@/utils/trpc'
8
8
 
9
9
  import type { Prisma } from '@prisma/client'
10
10
  import type { UseTRPCQueryOptions } from '@trpc/react-query/shared'
@@ -38,7 +38,8 @@ interface Option<TList extends FindManyArgs = FindManyArgs, TInfo extends FindUn
38
38
  }
39
39
  create?: Parameters<typeof api.habitGroup.create.useMutation>[0]
40
40
  update?: Parameters<typeof api.habitGroup.update.useMutation>[0]
41
- remove?: Parameters<typeof api.habitGroup.update.useMutation>[0]
41
+ remove?: Parameters<typeof api.habitGroup.remove.useMutation>[0]
42
+ restore?: Parameters<typeof api.habitGroup.restore.useMutation>[0]
42
43
  delete?: Parameters<typeof api.habitGroup.delete.useMutation>[0]
43
44
  }
44
45
 
@@ -55,7 +56,7 @@ const r = (q: any) => {
55
56
  }
56
57
 
57
58
  export const useHabitGroupCRUD = <TList extends FindManyArgs = FindManyArgs, TInfo extends FindUniqueArgs = FindUniqueArgs>(option: Option<TList, TInfo> = {}) => {
58
- const { list, info, create, update, remove, tags = false, delete: deleteOption, showTip = true } = option
59
+ const { list, info, create, update, remove, restore, tags = false, delete: deleteOption, showTip = true } = option
59
60
 
60
61
  const { message } = App.useApp()
61
62
 
@@ -144,7 +145,7 @@ export const useHabitGroupCRUD = <TList extends FindManyArgs = FindManyArgs, TIn
144
145
  },
145
146
  }
146
147
 
147
- const baseRemoveState = api.habitGroup.update.useMutation({
148
+ const baseRemoveState = api.habitGroup.remove.useMutation({
148
149
  ...remove,
149
150
  onSuccess: (...args) => {
150
151
  if (remove?.onSuccess) {
@@ -159,13 +160,11 @@ export const useHabitGroupCRUD = <TList extends FindManyArgs = FindManyArgs, TIn
159
160
  mutate: (id: string) => {
160
161
  return baseRemoveState.mutate({
161
162
  where: { id },
162
- data: { isDeleted: true },
163
163
  })
164
164
  },
165
165
  mutateAsync: (id: string) => {
166
166
  return baseRemoveState.mutateAsync({
167
167
  where: { id },
168
- data: { isDeleted: true },
169
168
  })
170
169
  },
171
170
  }
@@ -194,6 +193,30 @@ export const useHabitGroupCRUD = <TList extends FindManyArgs = FindManyArgs, TIn
194
193
  },
195
194
  }
196
195
 
196
+ const baseRestoreState = api.habitGroup.restore.useMutation({
197
+ ...restore,
198
+ onSuccess: (...args) => {
199
+ if (restore?.onSuccess) {
200
+ restore.onSuccess(...args)
201
+ }
202
+ onSuccess('恢复成功')
203
+ },
204
+ })
205
+
206
+ const restoreState = {
207
+ ...(baseRestoreState as unknown as typeof baseRestoreState),
208
+ mutate: (id: string) => {
209
+ return baseRestoreState.mutate({
210
+ where: { id },
211
+ })
212
+ },
213
+ mutateAsync: (id: string) => {
214
+ return baseRestoreState.mutateAsync({
215
+ where: { id },
216
+ })
217
+ },
218
+ }
219
+
197
220
  return {
198
221
  listState,
199
222
  countState,
@@ -205,6 +228,7 @@ export const useHabitGroupCRUD = <TList extends FindManyArgs = FindManyArgs, TIn
205
228
  createState,
206
229
  updateState,
207
230
  removeState,
231
+ restoreState,
208
232
  deleteState,
209
233
 
210
234
  apiUtils,
@@ -4,15 +4,16 @@ exports.name = void 0;
4
4
  exports.default = run;
5
5
  const crud_1 = require("./crud");
6
6
  const tags_1 = require("./tags");
7
+ const soft_delete_1 = require("./soft-delete");
7
8
  const no_check_1 = require("./no-check");
8
- exports.name = 'Generate CRUD, Tags and Generated File Banners';
9
+ exports.name = 'Generate CRUD, Tags, Soft Delete and Generated File Banners';
9
10
  async function run(model, options) {
10
11
  // 检查配置
11
12
  if (!options.output) {
12
13
  throw new Error('output is required');
13
14
  }
14
15
  const outputPath = String(options.output);
15
- const generateActions = String(options.generateActions || 'crud, tags, noCheck').replace(/\s/g, '').toLowerCase().split(',');
16
+ const generateActions = String(options.generateActions || 'crud, tags, softDelete, noCheck').replace(/\s/g, '').toLowerCase().split(',');
16
17
  // 根据配置执行相应功能
17
18
  if (generateActions.includes('crud')) {
18
19
  await (0, crud_1.generateCRUD)(model, outputPath);
@@ -20,6 +21,9 @@ async function run(model, options) {
20
21
  if (generateActions.includes('tags')) {
21
22
  await (0, tags_1.generateTags)(model, outputPath);
22
23
  }
24
+ if (generateActions.includes('softdelete')) {
25
+ await (0, soft_delete_1.generateSoftDelete)(model, outputPath);
26
+ }
23
27
  if (generateActions.includes('nocheck')) {
24
28
  await (0, no_check_1.markGeneratedNoCheck)(outputPath);
25
29
  }
@@ -4,7 +4,8 @@ exports.markGeneratedNoCheck = void 0;
4
4
  const fs = require("node:fs");
5
5
  const path = require("node:path");
6
6
  const noCheckBanner = '// @ts-nocheck';
7
- const walkTsFiles = (dirPath) => {
7
+ const noCheckExtensions = new Set(['.ts', '.tsx', '.js', '.jsx']);
8
+ const walkGeneratedFiles = (dirPath) => {
8
9
  if (!fs.existsSync(dirPath)) {
9
10
  return [];
10
11
  }
@@ -13,10 +14,10 @@ const walkTsFiles = (dirPath) => {
13
14
  for (const entry of entries) {
14
15
  const entryPath = path.join(dirPath, entry.name);
15
16
  if (entry.isDirectory()) {
16
- files.push(...walkTsFiles(entryPath));
17
+ files.push(...walkGeneratedFiles(entryPath));
17
18
  continue;
18
19
  }
19
- if (entry.isFile() && entry.name.endsWith('.ts')) {
20
+ if (entry.isFile() && noCheckExtensions.has(path.extname(entry.name))) {
20
21
  files.push(entryPath);
21
22
  }
22
23
  }
@@ -31,8 +32,8 @@ const markFile = (filePath) => {
31
32
  return true;
32
33
  };
33
34
  const markGeneratedNoCheck = async (outputPath) => {
34
- const files = walkTsFiles(outputPath);
35
+ const files = walkGeneratedFiles(outputPath);
35
36
  const changedCount = files.filter(markFile).length;
36
- console.log(`✅ Generated 文件 no-check 标记完成,共处理 ${changedCount}/${files.length} 个 TS 文件`);
37
+ console.log(`✅ Generated 文件 no-check 标记完成,共处理 ${changedCount}/${files.length} 个 TS/JS 文件`);
37
38
  };
38
39
  exports.markGeneratedNoCheck = markGeneratedNoCheck;
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateSoftDelete = void 0;
4
+ const fs = require("node:fs");
5
+ const path = require("node:path");
6
+ const hasIsDeletedUpdateInput = (outputPath, modelName) => {
7
+ const updateInputPath = path.join(outputPath, '.zenstack', 'zod', 'objects', `${modelName}UpdateInput.schema.ts`);
8
+ if (!fs.existsSync(updateInputPath)) {
9
+ return false;
10
+ }
11
+ return fs.readFileSync(updateInputPath, 'utf-8').includes('isDeleted:');
12
+ };
13
+ const createSoftDeleteInterface = (modelName, delegateName) => {
14
+ return `
15
+ remove: procedure.input($Schema.${modelName}InputSchema.delete).mutation(async ({ ctx, input }) => checkMutate(db(ctx).${delegateName}.update({
16
+ ...(input as any),
17
+ data: { isDeleted: true },
18
+ } as any))),
19
+
20
+ restore: procedure.input($Schema.${modelName}InputSchema.delete).mutation(async ({ ctx, input }) => checkMutate(db(ctx).${delegateName}.update({
21
+ ...(input as any),
22
+ data: { isDeleted: false },
23
+ } as any))),
24
+ `;
25
+ };
26
+ const generateSoftDelete = async (model, outputPath) => {
27
+ const dataModels = model.declarations.filter(item => item.$type === 'DataModel');
28
+ let processedCount = 0;
29
+ for (const dataModel of dataModels) {
30
+ const modelName = String(dataModel.name);
31
+ if (!hasIsDeletedUpdateInput(outputPath, modelName)) {
32
+ continue;
33
+ }
34
+ const routerFilePath = path.join(outputPath, 'trpc', 'routers', `${modelName}.router.ts`);
35
+ if (!fs.existsSync(routerFilePath)) {
36
+ continue;
37
+ }
38
+ let fileContent = fs.readFileSync(routerFilePath, 'utf-8');
39
+ if (fileContent.includes('remove:') && fileContent.includes('restore:')) {
40
+ continue;
41
+ }
42
+ const delegateName = modelName.charAt(0).toLowerCase() + modelName.slice(1);
43
+ const lastCommaIndex = fileContent.lastIndexOf(',');
44
+ const closingBraceIndex = fileContent.indexOf('\n }\n );', lastCommaIndex);
45
+ if (closingBraceIndex === -1) {
46
+ console.warn(`⚠️ Could not find insertion point in ${modelName}.router.ts`);
47
+ continue;
48
+ }
49
+ const beforeInsertion = fileContent.substring(0, closingBraceIndex);
50
+ const afterInsertion = fileContent.substring(closingBraceIndex);
51
+ fileContent = beforeInsertion + createSoftDeleteInterface(modelName, delegateName) + afterInsertion;
52
+ fs.writeFileSync(routerFilePath, fileContent, 'utf-8');
53
+ processedCount += 1;
54
+ }
55
+ console.log(`✅ Soft Delete 功能生成完成,共处理 ${processedCount} 个模型`);
56
+ };
57
+ exports.generateSoftDelete = generateSoftDelete;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wzyjs/next",
3
- "version": "0.3.32",
3
+ "version": "0.3.37",
4
4
  "description": "description",
5
5
  "author": "wzy",
6
6
  "main": "dist/plugin/index.js",
@@ -13,19 +13,20 @@
13
13
  "rm": "rm -rf dist",
14
14
  "cp1": "cp src/prisma/Base.zmodel dist/Base.zmodel",
15
15
  "cp2": "cp src/plugin/crud/useHabitGroupCRUD.ts dist/plugin/crud/useHabitGroupCRUD.ts",
16
- "build": "bun run rm && bun run build:plugin && bun run cp1 && bun run cp2"
16
+ "build": "bun run rm && bun run build:plugin && bun run cp1 && bun run cp2",
17
+ "typecheck": "tsc --noEmit"
17
18
  },
18
19
  "files": [
19
20
  "dist"
20
21
  ],
21
22
  "dependencies": {
22
- "@zenstackhq/sdk": "^2.12.3"
23
+ "@zenstackhq/sdk": "2.22.1"
23
24
  },
24
25
  "devDependencies": {
25
26
  "@types/node": "^20.19.23",
26
27
  "typescript": "^5.9.3"
27
28
  },
28
- "gitHead": "260d8290106ef447ec42375d4656af2e89675b15",
29
+ "gitHead": "66fc9b56ff49d9a725189dbd3360d6987cb9d604",
29
30
  "publishConfig": {
30
31
  "access": "public"
31
32
  }