imean-service-engine-htmx-plugin 1.1.0 → 1.2.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.
package/dist/index.d.mts CHANGED
@@ -50,6 +50,10 @@ interface PermissionResult {
50
50
  interface AuthProvider {
51
51
  /** Cookie 中存储 token 的 key(默认 "auth_token") */
52
52
  cookieKey?: string;
53
+ /** 登录页面 URL(当用户未登录且需要权限时重定向到此页面) */
54
+ loginUrl?: string;
55
+ /** 退出登录页面 URL(用于退出登录功能) */
56
+ logoutUrl?: string;
53
57
  /** 将 token 转换为用户信息 */
54
58
  tokenToUser: (token: string, ctx: Context) => UserInfo | null | Promise<UserInfo | null>;
55
59
  /** 权限校验钩子(可选,如果不提供则使用默认实现) */
package/dist/index.d.ts CHANGED
@@ -50,6 +50,10 @@ interface PermissionResult {
50
50
  interface AuthProvider {
51
51
  /** Cookie 中存储 token 的 key(默认 "auth_token") */
52
52
  cookieKey?: string;
53
+ /** 登录页面 URL(当用户未登录且需要权限时重定向到此页面) */
54
+ loginUrl?: string;
55
+ /** 退出登录页面 URL(用于退出登录功能) */
56
+ logoutUrl?: string;
53
57
  /** 将 token 转换为用户信息 */
54
58
  tokenToUser: (token: string, ctx: Context) => UserInfo | null | Promise<UserInfo | null>;
55
59
  /** 权限校验钩子(可选,如果不提供则使用默认实现) */
package/dist/index.js CHANGED
@@ -149,7 +149,7 @@ var init_Header = __esm({
149
149
  "src/components/Header.tsx"() {
150
150
  init_Breadcrumb();
151
151
  Header = (props) => {
152
- const { breadcrumbs = [], userInfo, sidebarCollapsed = false } = props;
152
+ const { breadcrumbs = [], userInfo, sidebarCollapsed = false, logoutUrl } = props;
153
153
  return /* @__PURE__ */ jsxRuntime.jsx("header", { className: "bg-white border-b border-gray-200 shadow-sm sticky top-0 z-40", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
154
154
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4 flex-1 min-w-0", children: [
155
155
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -215,7 +215,36 @@ var init_Header = __esm({
215
215
  alt: userInfo.name || "\u7528\u6237",
216
216
  className: "w-8 h-8 rounded-full"
217
217
  }
218
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 h-8 rounded-full bg-blue-600 flex items-center justify-center text-white text-sm font-medium", children: (userInfo.name || userInfo.email || "U").charAt(0).toUpperCase() })
218
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-8 h-8 rounded-full bg-blue-600 flex items-center justify-center text-white text-sm font-medium", children: (userInfo.name || userInfo.email || "U").charAt(0).toUpperCase() }),
219
+ logoutUrl && /* @__PURE__ */ jsxRuntime.jsx(
220
+ "a",
221
+ {
222
+ href: logoutUrl,
223
+ "hx-get": logoutUrl,
224
+ "hx-target": "body",
225
+ "hx-swap": "outerHTML",
226
+ className: "p-2 rounded-lg hover:bg-gray-100 transition-colors",
227
+ title: "\u9000\u51FA\u767B\u5F55",
228
+ children: /* @__PURE__ */ jsxRuntime.jsx(
229
+ "svg",
230
+ {
231
+ className: "w-5 h-5 text-gray-600",
232
+ fill: "none",
233
+ stroke: "currentColor",
234
+ viewBox: "0 0 24 24",
235
+ children: /* @__PURE__ */ jsxRuntime.jsx(
236
+ "path",
237
+ {
238
+ strokeLinecap: "round",
239
+ strokeLinejoin: "round",
240
+ strokeWidth: 2,
241
+ d: "M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"
242
+ }
243
+ )
244
+ }
245
+ )
246
+ }
247
+ )
219
248
  ] })
220
249
  ] }) }) });
221
250
  };
@@ -417,6 +446,7 @@ var init_Layout = __esm({
417
446
  const sidebarCollapsed = props.sidebarCollapsed || false;
418
447
  const breadcrumbs = props.adminContext.breadcrumbs;
419
448
  const userInfo = props.adminContext.userInfo;
449
+ const logoutUrl = props.adminContext.pluginOptions.authProvider?.logoutUrl;
420
450
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-screen", id: "main-content", children: [
421
451
  /* @__PURE__ */ jsxRuntime.jsx(
422
452
  "aside",
@@ -446,7 +476,8 @@ var init_Layout = __esm({
446
476
  {
447
477
  breadcrumbs,
448
478
  userInfo,
449
- sidebarCollapsed: sidebarCollapsed || false
479
+ sidebarCollapsed: sidebarCollapsed || false,
480
+ logoutUrl
450
481
  }
451
482
  ),
452
483
  /* @__PURE__ */ jsxRuntime.jsx("main", { className: "flex-1 overflow-auto bg-gray-50", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6", children: props.children }) })
@@ -657,15 +688,28 @@ function PermissionDeniedPage(adminContext, operationId, fromPath, registeredOpe
657
688
  {
658
689
  title: `\u6743\u9650\u4E0D\u8DB3 - ${adminContext.pluginOptions.title}`,
659
690
  description: "\u60A8\u6CA1\u6709\u6743\u9650\u8BBF\u95EE\u6B64\u8D44\u6E90",
660
- children: /* @__PURE__ */ jsxRuntime.jsx("div", { id: "main-content", className: "min-h-screen flex items-center justify-center px-4", children: /* @__PURE__ */ jsxRuntime.jsx(Card, { className: "max-w-2xl w-full p-8", children: /* @__PURE__ */ jsxRuntime.jsx(
661
- PermissionDeniedContent,
662
- {
663
- adminContext,
664
- operationId,
665
- fromPath,
666
- registeredOperations
667
- }
668
- ) }) })
691
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { id: "main-content", className: "min-h-screen flex items-center justify-center px-4", children: /* @__PURE__ */ jsxRuntime.jsxs(Card, { className: "max-w-2xl w-full p-8", children: [
692
+ /* @__PURE__ */ jsxRuntime.jsx(
693
+ PermissionDeniedContent,
694
+ {
695
+ adminContext,
696
+ operationId,
697
+ fromPath,
698
+ registeredOperations
699
+ }
700
+ ),
701
+ adminContext.pluginOptions.authProvider?.loginUrl && !adminContext.userInfo && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-8 text-center", children: /* @__PURE__ */ jsxRuntime.jsx(
702
+ Button,
703
+ {
704
+ variant: "primary",
705
+ href: adminContext.pluginOptions.authProvider.loginUrl,
706
+ hxGet: adminContext.pluginOptions.authProvider.loginUrl,
707
+ hxTarget: "body",
708
+ hxSwap: "outerHTML",
709
+ children: "\u524D\u5F80\u767B\u5F55"
710
+ }
711
+ ) })
712
+ ] }) })
669
713
  }
670
714
  );
671
715
  }
@@ -2951,7 +2995,7 @@ async function getUserInfo(ctx, authProvider) {
2951
2995
  }
2952
2996
  return await authProvider.tokenToUser(token, ctx);
2953
2997
  }
2954
- function checkPermissionDefault(userInfo, operation) {
2998
+ function checkPermissionDefault(userInfo, operation, loginUrl) {
2955
2999
  if (!operation) {
2956
3000
  return { allowed: true };
2957
3001
  }
@@ -2959,7 +3003,9 @@ function checkPermissionDefault(userInfo, operation) {
2959
3003
  return {
2960
3004
  allowed: false,
2961
3005
  message: "\u672A\u767B\u5F55\uFF0C\u65E0\u6CD5\u8BBF\u95EE\u6B64\u8D44\u6E90",
2962
- operationId: operation
3006
+ operationId: operation,
3007
+ redirectUrl: loginUrl
3008
+ // 如果提供了 loginUrl,则重定向到登录页面
2963
3009
  };
2964
3010
  }
2965
3011
  const userPermissions = userInfo.permissions || [];
@@ -3009,6 +3055,13 @@ function generateOperationId(ctx, moduleName, moduleOptions, serviceName) {
3009
3055
  }
3010
3056
  return `${servicePrefix}${lowerModuleName}.read`;
3011
3057
  } else if (moduleOptions.type === "custom") {
3058
+ if (method === "post") {
3059
+ return `${servicePrefix}${lowerModuleName}.create`;
3060
+ } else if (method === "put") {
3061
+ return `${servicePrefix}${lowerModuleName}.edit`;
3062
+ } else if (method === "delete") {
3063
+ return `${servicePrefix}${lowerModuleName}.delete`;
3064
+ }
3012
3065
  return `${servicePrefix}${lowerModuleName}.read`;
3013
3066
  }
3014
3067
  return `${servicePrefix}${lowerModuleName}.read`;
@@ -3028,6 +3081,9 @@ async function handlePermissionDenied(ctx, adminContext, permissionResult, getOp
3028
3081
  getRegisteredOperations
3029
3082
  );
3030
3083
  } else {
3084
+ if (permissionResult.redirectUrl) {
3085
+ return ctx.redirect(permissionResult.redirectUrl);
3086
+ }
3031
3087
  return redirectToPermissionDeniedPage(
3032
3088
  ctx,
3033
3089
  operationId,
@@ -3110,7 +3166,8 @@ var RouteHandler = class {
3110
3166
  } else {
3111
3167
  permissionResult = checkPermissionDefault(
3112
3168
  userInfo,
3113
- operation
3169
+ operation,
3170
+ this.pluginOptions.authProvider?.loginUrl
3114
3171
  );
3115
3172
  }
3116
3173
  if (!permissionResult.allowed) {
@@ -3464,73 +3521,90 @@ var HtmxAdminPlugin = class {
3464
3521
  generateOperationId(moduleName, moduleType, method, path) {
3465
3522
  const lowerModuleName = moduleName.toLowerCase();
3466
3523
  const lowerMethod = method.toLowerCase();
3524
+ const servicePrefix = this.serviceName ? `${this.serviceName}.` : "";
3467
3525
  if (moduleType === "list") {
3468
3526
  return {
3469
- operationId: `${lowerModuleName}.read`,
3527
+ operationId: `${servicePrefix}${lowerModuleName}.read`,
3470
3528
  operationType: "read"
3471
3529
  };
3472
3530
  } else if (moduleType === "detail") {
3473
3531
  if (lowerMethod === "delete") {
3474
3532
  return {
3475
- operationId: `${lowerModuleName}.delete`,
3533
+ operationId: `${servicePrefix}${lowerModuleName}.delete`,
3476
3534
  operationType: "delete"
3477
3535
  };
3478
3536
  }
3479
3537
  return {
3480
- operationId: `${lowerModuleName}.read`,
3538
+ operationId: `${servicePrefix}${lowerModuleName}.read`,
3481
3539
  operationType: "read"
3482
3540
  };
3483
3541
  } else if (moduleType === "form") {
3484
3542
  if (path.includes("/new")) {
3485
3543
  if (lowerMethod === "get") {
3486
3544
  return {
3487
- operationId: `${lowerModuleName}.create`,
3545
+ operationId: `${servicePrefix}${lowerModuleName}.create`,
3488
3546
  operationType: "create"
3489
3547
  };
3490
3548
  }
3491
3549
  return {
3492
- operationId: `${lowerModuleName}.create`,
3550
+ operationId: `${servicePrefix}${lowerModuleName}.create`,
3493
3551
  operationType: "create"
3494
3552
  };
3495
3553
  } else if (path.includes("/edit/")) {
3496
3554
  if (lowerMethod === "get") {
3497
3555
  return {
3498
- operationId: `${lowerModuleName}.edit`,
3556
+ operationId: `${servicePrefix}${lowerModuleName}.edit`,
3499
3557
  operationType: "edit"
3500
3558
  };
3501
3559
  }
3502
3560
  return {
3503
- operationId: `${lowerModuleName}.edit`,
3561
+ operationId: `${servicePrefix}${lowerModuleName}.edit`,
3504
3562
  operationType: "edit"
3505
3563
  };
3506
3564
  } else if (lowerMethod === "post") {
3507
3565
  return {
3508
- operationId: `${lowerModuleName}.create`,
3566
+ operationId: `${servicePrefix}${lowerModuleName}.create`,
3509
3567
  operationType: "create"
3510
3568
  };
3511
3569
  } else if (lowerMethod === "put") {
3512
3570
  return {
3513
- operationId: `${lowerModuleName}.edit`,
3571
+ operationId: `${servicePrefix}${lowerModuleName}.edit`,
3514
3572
  operationType: "edit"
3515
3573
  };
3516
3574
  } else if (lowerMethod === "delete") {
3517
3575
  return {
3518
- operationId: `${lowerModuleName}.delete`,
3576
+ operationId: `${servicePrefix}${lowerModuleName}.delete`,
3519
3577
  operationType: "delete"
3520
3578
  };
3521
3579
  }
3522
3580
  return {
3523
- operationId: `${lowerModuleName}.read`,
3581
+ operationId: `${servicePrefix}${lowerModuleName}.read`,
3524
3582
  operationType: "read"
3525
3583
  };
3526
3584
  } else if (moduleType === "custom") {
3585
+ if (lowerMethod === "post") {
3586
+ return {
3587
+ operationId: `${servicePrefix}${lowerModuleName}.create`,
3588
+ operationType: "create"
3589
+ };
3590
+ } else if (lowerMethod === "put") {
3591
+ return {
3592
+ operationId: `${servicePrefix}${lowerModuleName}.edit`,
3593
+ operationType: "edit"
3594
+ };
3595
+ } else if (lowerMethod === "delete") {
3596
+ return {
3597
+ operationId: `${servicePrefix}${lowerModuleName}.delete`,
3598
+ operationType: "delete"
3599
+ };
3600
+ }
3527
3601
  return {
3528
- operationId: `${lowerModuleName}.read`,
3602
+ operationId: `${servicePrefix}${lowerModuleName}.read`,
3529
3603
  operationType: "read"
3530
3604
  };
3531
3605
  }
3532
3606
  return {
3533
- operationId: `${lowerModuleName}.read`,
3607
+ operationId: `${servicePrefix}${lowerModuleName}.read`,
3534
3608
  operationType: "read"
3535
3609
  };
3536
3610
  }
@@ -3615,7 +3689,13 @@ var HtmxAdminPlugin = class {
3615
3689
  { method: "put", path: `${basePath}/:id` },
3616
3690
  { method: "delete", path: `${basePath}/:id` }
3617
3691
  ],
3618
- custom: [{ method: "get", path: basePath }]
3692
+ // custom 类型注册所有 HTTP 方法,允许模块在 render 方法中根据请求方法进行扩展
3693
+ custom: [
3694
+ { method: "get", path: basePath },
3695
+ { method: "post", path: basePath },
3696
+ { method: "put", path: basePath },
3697
+ { method: "delete", path: basePath }
3698
+ ]
3619
3699
  };
3620
3700
  const routes = routeConfig[type];
3621
3701
  for (const route of routes) {
package/dist/index.mjs CHANGED
@@ -147,7 +147,7 @@ var init_Header = __esm({
147
147
  "src/components/Header.tsx"() {
148
148
  init_Breadcrumb();
149
149
  Header = (props) => {
150
- const { breadcrumbs = [], userInfo, sidebarCollapsed = false } = props;
150
+ const { breadcrumbs = [], userInfo, sidebarCollapsed = false, logoutUrl } = props;
151
151
  return /* @__PURE__ */ jsx("header", { className: "bg-white border-b border-gray-200 shadow-sm sticky top-0 z-40", children: /* @__PURE__ */ jsx("div", { className: "px-6 py-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
152
152
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4 flex-1 min-w-0", children: [
153
153
  /* @__PURE__ */ jsx(
@@ -213,7 +213,36 @@ var init_Header = __esm({
213
213
  alt: userInfo.name || "\u7528\u6237",
214
214
  className: "w-8 h-8 rounded-full"
215
215
  }
216
- ) : /* @__PURE__ */ jsx("div", { className: "w-8 h-8 rounded-full bg-blue-600 flex items-center justify-center text-white text-sm font-medium", children: (userInfo.name || userInfo.email || "U").charAt(0).toUpperCase() })
216
+ ) : /* @__PURE__ */ jsx("div", { className: "w-8 h-8 rounded-full bg-blue-600 flex items-center justify-center text-white text-sm font-medium", children: (userInfo.name || userInfo.email || "U").charAt(0).toUpperCase() }),
217
+ logoutUrl && /* @__PURE__ */ jsx(
218
+ "a",
219
+ {
220
+ href: logoutUrl,
221
+ "hx-get": logoutUrl,
222
+ "hx-target": "body",
223
+ "hx-swap": "outerHTML",
224
+ className: "p-2 rounded-lg hover:bg-gray-100 transition-colors",
225
+ title: "\u9000\u51FA\u767B\u5F55",
226
+ children: /* @__PURE__ */ jsx(
227
+ "svg",
228
+ {
229
+ className: "w-5 h-5 text-gray-600",
230
+ fill: "none",
231
+ stroke: "currentColor",
232
+ viewBox: "0 0 24 24",
233
+ children: /* @__PURE__ */ jsx(
234
+ "path",
235
+ {
236
+ strokeLinecap: "round",
237
+ strokeLinejoin: "round",
238
+ strokeWidth: 2,
239
+ d: "M17 16l4-4m0 0l-4-4m4 4H7m6 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h4a3 3 0 013 3v1"
240
+ }
241
+ )
242
+ }
243
+ )
244
+ }
245
+ )
217
246
  ] })
218
247
  ] }) }) });
219
248
  };
@@ -415,6 +444,7 @@ var init_Layout = __esm({
415
444
  const sidebarCollapsed = props.sidebarCollapsed || false;
416
445
  const breadcrumbs = props.adminContext.breadcrumbs;
417
446
  const userInfo = props.adminContext.userInfo;
447
+ const logoutUrl = props.adminContext.pluginOptions.authProvider?.logoutUrl;
418
448
  return /* @__PURE__ */ jsxs("div", { className: "flex h-screen", id: "main-content", children: [
419
449
  /* @__PURE__ */ jsx(
420
450
  "aside",
@@ -444,7 +474,8 @@ var init_Layout = __esm({
444
474
  {
445
475
  breadcrumbs,
446
476
  userInfo,
447
- sidebarCollapsed: sidebarCollapsed || false
477
+ sidebarCollapsed: sidebarCollapsed || false,
478
+ logoutUrl
448
479
  }
449
480
  ),
450
481
  /* @__PURE__ */ jsx("main", { className: "flex-1 overflow-auto bg-gray-50", children: /* @__PURE__ */ jsx("div", { className: "p-6", children: props.children }) })
@@ -655,15 +686,28 @@ function PermissionDeniedPage(adminContext, operationId, fromPath, registeredOpe
655
686
  {
656
687
  title: `\u6743\u9650\u4E0D\u8DB3 - ${adminContext.pluginOptions.title}`,
657
688
  description: "\u60A8\u6CA1\u6709\u6743\u9650\u8BBF\u95EE\u6B64\u8D44\u6E90",
658
- children: /* @__PURE__ */ jsx("div", { id: "main-content", className: "min-h-screen flex items-center justify-center px-4", children: /* @__PURE__ */ jsx(Card, { className: "max-w-2xl w-full p-8", children: /* @__PURE__ */ jsx(
659
- PermissionDeniedContent,
660
- {
661
- adminContext,
662
- operationId,
663
- fromPath,
664
- registeredOperations
665
- }
666
- ) }) })
689
+ children: /* @__PURE__ */ jsx("div", { id: "main-content", className: "min-h-screen flex items-center justify-center px-4", children: /* @__PURE__ */ jsxs(Card, { className: "max-w-2xl w-full p-8", children: [
690
+ /* @__PURE__ */ jsx(
691
+ PermissionDeniedContent,
692
+ {
693
+ adminContext,
694
+ operationId,
695
+ fromPath,
696
+ registeredOperations
697
+ }
698
+ ),
699
+ adminContext.pluginOptions.authProvider?.loginUrl && !adminContext.userInfo && /* @__PURE__ */ jsx("div", { className: "mt-8 text-center", children: /* @__PURE__ */ jsx(
700
+ Button,
701
+ {
702
+ variant: "primary",
703
+ href: adminContext.pluginOptions.authProvider.loginUrl,
704
+ hxGet: adminContext.pluginOptions.authProvider.loginUrl,
705
+ hxTarget: "body",
706
+ hxSwap: "outerHTML",
707
+ children: "\u524D\u5F80\u767B\u5F55"
708
+ }
709
+ ) })
710
+ ] }) })
667
711
  }
668
712
  );
669
713
  }
@@ -2949,7 +2993,7 @@ async function getUserInfo(ctx, authProvider) {
2949
2993
  }
2950
2994
  return await authProvider.tokenToUser(token, ctx);
2951
2995
  }
2952
- function checkPermissionDefault(userInfo, operation) {
2996
+ function checkPermissionDefault(userInfo, operation, loginUrl) {
2953
2997
  if (!operation) {
2954
2998
  return { allowed: true };
2955
2999
  }
@@ -2957,7 +3001,9 @@ function checkPermissionDefault(userInfo, operation) {
2957
3001
  return {
2958
3002
  allowed: false,
2959
3003
  message: "\u672A\u767B\u5F55\uFF0C\u65E0\u6CD5\u8BBF\u95EE\u6B64\u8D44\u6E90",
2960
- operationId: operation
3004
+ operationId: operation,
3005
+ redirectUrl: loginUrl
3006
+ // 如果提供了 loginUrl,则重定向到登录页面
2961
3007
  };
2962
3008
  }
2963
3009
  const userPermissions = userInfo.permissions || [];
@@ -3007,6 +3053,13 @@ function generateOperationId(ctx, moduleName, moduleOptions, serviceName) {
3007
3053
  }
3008
3054
  return `${servicePrefix}${lowerModuleName}.read`;
3009
3055
  } else if (moduleOptions.type === "custom") {
3056
+ if (method === "post") {
3057
+ return `${servicePrefix}${lowerModuleName}.create`;
3058
+ } else if (method === "put") {
3059
+ return `${servicePrefix}${lowerModuleName}.edit`;
3060
+ } else if (method === "delete") {
3061
+ return `${servicePrefix}${lowerModuleName}.delete`;
3062
+ }
3010
3063
  return `${servicePrefix}${lowerModuleName}.read`;
3011
3064
  }
3012
3065
  return `${servicePrefix}${lowerModuleName}.read`;
@@ -3026,6 +3079,9 @@ async function handlePermissionDenied(ctx, adminContext, permissionResult, getOp
3026
3079
  getRegisteredOperations
3027
3080
  );
3028
3081
  } else {
3082
+ if (permissionResult.redirectUrl) {
3083
+ return ctx.redirect(permissionResult.redirectUrl);
3084
+ }
3029
3085
  return redirectToPermissionDeniedPage(
3030
3086
  ctx,
3031
3087
  operationId,
@@ -3108,7 +3164,8 @@ var RouteHandler = class {
3108
3164
  } else {
3109
3165
  permissionResult = checkPermissionDefault(
3110
3166
  userInfo,
3111
- operation
3167
+ operation,
3168
+ this.pluginOptions.authProvider?.loginUrl
3112
3169
  );
3113
3170
  }
3114
3171
  if (!permissionResult.allowed) {
@@ -3462,73 +3519,90 @@ var HtmxAdminPlugin = class {
3462
3519
  generateOperationId(moduleName, moduleType, method, path) {
3463
3520
  const lowerModuleName = moduleName.toLowerCase();
3464
3521
  const lowerMethod = method.toLowerCase();
3522
+ const servicePrefix = this.serviceName ? `${this.serviceName}.` : "";
3465
3523
  if (moduleType === "list") {
3466
3524
  return {
3467
- operationId: `${lowerModuleName}.read`,
3525
+ operationId: `${servicePrefix}${lowerModuleName}.read`,
3468
3526
  operationType: "read"
3469
3527
  };
3470
3528
  } else if (moduleType === "detail") {
3471
3529
  if (lowerMethod === "delete") {
3472
3530
  return {
3473
- operationId: `${lowerModuleName}.delete`,
3531
+ operationId: `${servicePrefix}${lowerModuleName}.delete`,
3474
3532
  operationType: "delete"
3475
3533
  };
3476
3534
  }
3477
3535
  return {
3478
- operationId: `${lowerModuleName}.read`,
3536
+ operationId: `${servicePrefix}${lowerModuleName}.read`,
3479
3537
  operationType: "read"
3480
3538
  };
3481
3539
  } else if (moduleType === "form") {
3482
3540
  if (path.includes("/new")) {
3483
3541
  if (lowerMethod === "get") {
3484
3542
  return {
3485
- operationId: `${lowerModuleName}.create`,
3543
+ operationId: `${servicePrefix}${lowerModuleName}.create`,
3486
3544
  operationType: "create"
3487
3545
  };
3488
3546
  }
3489
3547
  return {
3490
- operationId: `${lowerModuleName}.create`,
3548
+ operationId: `${servicePrefix}${lowerModuleName}.create`,
3491
3549
  operationType: "create"
3492
3550
  };
3493
3551
  } else if (path.includes("/edit/")) {
3494
3552
  if (lowerMethod === "get") {
3495
3553
  return {
3496
- operationId: `${lowerModuleName}.edit`,
3554
+ operationId: `${servicePrefix}${lowerModuleName}.edit`,
3497
3555
  operationType: "edit"
3498
3556
  };
3499
3557
  }
3500
3558
  return {
3501
- operationId: `${lowerModuleName}.edit`,
3559
+ operationId: `${servicePrefix}${lowerModuleName}.edit`,
3502
3560
  operationType: "edit"
3503
3561
  };
3504
3562
  } else if (lowerMethod === "post") {
3505
3563
  return {
3506
- operationId: `${lowerModuleName}.create`,
3564
+ operationId: `${servicePrefix}${lowerModuleName}.create`,
3507
3565
  operationType: "create"
3508
3566
  };
3509
3567
  } else if (lowerMethod === "put") {
3510
3568
  return {
3511
- operationId: `${lowerModuleName}.edit`,
3569
+ operationId: `${servicePrefix}${lowerModuleName}.edit`,
3512
3570
  operationType: "edit"
3513
3571
  };
3514
3572
  } else if (lowerMethod === "delete") {
3515
3573
  return {
3516
- operationId: `${lowerModuleName}.delete`,
3574
+ operationId: `${servicePrefix}${lowerModuleName}.delete`,
3517
3575
  operationType: "delete"
3518
3576
  };
3519
3577
  }
3520
3578
  return {
3521
- operationId: `${lowerModuleName}.read`,
3579
+ operationId: `${servicePrefix}${lowerModuleName}.read`,
3522
3580
  operationType: "read"
3523
3581
  };
3524
3582
  } else if (moduleType === "custom") {
3583
+ if (lowerMethod === "post") {
3584
+ return {
3585
+ operationId: `${servicePrefix}${lowerModuleName}.create`,
3586
+ operationType: "create"
3587
+ };
3588
+ } else if (lowerMethod === "put") {
3589
+ return {
3590
+ operationId: `${servicePrefix}${lowerModuleName}.edit`,
3591
+ operationType: "edit"
3592
+ };
3593
+ } else if (lowerMethod === "delete") {
3594
+ return {
3595
+ operationId: `${servicePrefix}${lowerModuleName}.delete`,
3596
+ operationType: "delete"
3597
+ };
3598
+ }
3525
3599
  return {
3526
- operationId: `${lowerModuleName}.read`,
3600
+ operationId: `${servicePrefix}${lowerModuleName}.read`,
3527
3601
  operationType: "read"
3528
3602
  };
3529
3603
  }
3530
3604
  return {
3531
- operationId: `${lowerModuleName}.read`,
3605
+ operationId: `${servicePrefix}${lowerModuleName}.read`,
3532
3606
  operationType: "read"
3533
3607
  };
3534
3608
  }
@@ -3613,7 +3687,13 @@ var HtmxAdminPlugin = class {
3613
3687
  { method: "put", path: `${basePath}/:id` },
3614
3688
  { method: "delete", path: `${basePath}/:id` }
3615
3689
  ],
3616
- custom: [{ method: "get", path: basePath }]
3690
+ // custom 类型注册所有 HTTP 方法,允许模块在 render 方法中根据请求方法进行扩展
3691
+ custom: [
3692
+ { method: "get", path: basePath },
3693
+ { method: "post", path: basePath },
3694
+ { method: "put", path: basePath },
3695
+ { method: "delete", path: basePath }
3696
+ ]
3617
3697
  };
3618
3698
  const routes = routeConfig[type];
3619
3699
  for (const route of routes) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "imean-service-engine-htmx-plugin",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "HtmxAdminPlugin for IMean Service Engine",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",