@btst/stack 2.4.0 → 2.5.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 (136) hide show
  1. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.cjs +33 -47
  2. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.mjs +33 -47
  3. package/dist/packages/stack/src/plugins/ai-chat/client/plugin.cjs +14 -21
  4. package/dist/packages/stack/src/plugins/ai-chat/client/plugin.mjs +15 -22
  5. package/dist/packages/stack/src/plugins/blog/api/plugin.cjs +28 -45
  6. package/dist/packages/stack/src/plugins/blog/api/plugin.mjs +22 -39
  7. package/dist/packages/stack/src/plugins/blog/client/plugin.cjs +23 -27
  8. package/dist/packages/stack/src/plugins/blog/client/plugin.mjs +24 -28
  9. package/dist/packages/stack/src/plugins/cms/api/plugin.cjs +14 -17
  10. package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +14 -17
  11. package/dist/packages/stack/src/plugins/cms/client/plugin.cjs +11 -15
  12. package/dist/packages/stack/src/plugins/cms/client/plugin.mjs +12 -16
  13. package/dist/packages/stack/src/plugins/form-builder/api/plugin.cjs +58 -62
  14. package/dist/packages/stack/src/plugins/form-builder/api/plugin.mjs +58 -62
  15. package/dist/packages/stack/src/plugins/form-builder/client/plugin.cjs +12 -12
  16. package/dist/packages/stack/src/plugins/form-builder/client/plugin.mjs +13 -13
  17. package/dist/packages/stack/src/plugins/kanban/api/plugin.cjs +86 -117
  18. package/dist/packages/stack/src/plugins/kanban/api/plugin.mjs +83 -114
  19. package/dist/packages/stack/src/plugins/kanban/client/plugin.cjs +22 -29
  20. package/dist/packages/stack/src/plugins/kanban/client/plugin.mjs +23 -30
  21. package/dist/packages/stack/src/plugins/ui-builder/client/plugin.cjs +8 -8
  22. package/dist/packages/stack/src/plugins/ui-builder/client/plugin.mjs +9 -9
  23. package/dist/packages/stack/src/plugins/utils.cjs +42 -0
  24. package/dist/packages/stack/src/plugins/utils.mjs +41 -1
  25. package/dist/plugins/ai-chat/api/index.d.cts +1 -1
  26. package/dist/plugins/ai-chat/api/index.d.mts +1 -1
  27. package/dist/plugins/ai-chat/api/index.d.ts +1 -1
  28. package/dist/plugins/ai-chat/client/hooks/index.d.cts +1 -1
  29. package/dist/plugins/ai-chat/client/hooks/index.d.mts +1 -1
  30. package/dist/plugins/ai-chat/client/hooks/index.d.ts +1 -1
  31. package/dist/plugins/ai-chat/client/index.d.cts +8 -8
  32. package/dist/plugins/ai-chat/client/index.d.mts +8 -8
  33. package/dist/plugins/ai-chat/client/index.d.ts +8 -8
  34. package/dist/plugins/ai-chat/query-keys.d.cts +1 -1
  35. package/dist/plugins/ai-chat/query-keys.d.mts +1 -1
  36. package/dist/plugins/ai-chat/query-keys.d.ts +1 -1
  37. package/dist/plugins/blog/api/index.d.cts +1 -1
  38. package/dist/plugins/blog/api/index.d.mts +1 -1
  39. package/dist/plugins/blog/api/index.d.ts +1 -1
  40. package/dist/plugins/blog/client/index.d.cts +12 -12
  41. package/dist/plugins/blog/client/index.d.mts +12 -12
  42. package/dist/plugins/blog/client/index.d.ts +12 -12
  43. package/dist/plugins/blog/query-keys.d.cts +1 -1
  44. package/dist/plugins/blog/query-keys.d.mts +1 -1
  45. package/dist/plugins/blog/query-keys.d.ts +1 -1
  46. package/dist/plugins/client/index.cjs +1 -0
  47. package/dist/plugins/client/index.d.cts +8 -1
  48. package/dist/plugins/client/index.d.mts +8 -1
  49. package/dist/plugins/client/index.d.ts +8 -1
  50. package/dist/plugins/client/index.mjs +1 -1
  51. package/dist/plugins/cms/api/index.d.cts +2 -2
  52. package/dist/plugins/cms/api/index.d.mts +2 -2
  53. package/dist/plugins/cms/api/index.d.ts +2 -2
  54. package/dist/plugins/cms/client/hooks/index.d.cts +1 -1
  55. package/dist/plugins/cms/client/hooks/index.d.mts +1 -1
  56. package/dist/plugins/cms/client/hooks/index.d.ts +1 -1
  57. package/dist/plugins/cms/client/index.d.cts +6 -6
  58. package/dist/plugins/cms/client/index.d.mts +6 -6
  59. package/dist/plugins/cms/client/index.d.ts +6 -6
  60. package/dist/plugins/cms/query-keys.d.cts +2 -2
  61. package/dist/plugins/cms/query-keys.d.mts +2 -2
  62. package/dist/plugins/cms/query-keys.d.ts +2 -2
  63. package/dist/plugins/form-builder/api/index.d.cts +2 -2
  64. package/dist/plugins/form-builder/api/index.d.mts +2 -2
  65. package/dist/plugins/form-builder/api/index.d.ts +2 -2
  66. package/dist/plugins/form-builder/client/components/index.d.cts +1 -1
  67. package/dist/plugins/form-builder/client/components/index.d.mts +1 -1
  68. package/dist/plugins/form-builder/client/components/index.d.ts +1 -1
  69. package/dist/plugins/form-builder/client/hooks/index.d.cts +1 -1
  70. package/dist/plugins/form-builder/client/hooks/index.d.mts +1 -1
  71. package/dist/plugins/form-builder/client/hooks/index.d.ts +1 -1
  72. package/dist/plugins/form-builder/client/index.d.cts +6 -6
  73. package/dist/plugins/form-builder/client/index.d.mts +6 -6
  74. package/dist/plugins/form-builder/client/index.d.ts +6 -6
  75. package/dist/plugins/form-builder/query-keys.d.cts +2 -2
  76. package/dist/plugins/form-builder/query-keys.d.mts +2 -2
  77. package/dist/plugins/form-builder/query-keys.d.ts +2 -2
  78. package/dist/plugins/kanban/api/index.d.cts +1 -1
  79. package/dist/plugins/kanban/api/index.d.mts +1 -1
  80. package/dist/plugins/kanban/api/index.d.ts +1 -1
  81. package/dist/plugins/kanban/client/index.d.cts +12 -12
  82. package/dist/plugins/kanban/client/index.d.mts +12 -12
  83. package/dist/plugins/kanban/client/index.d.ts +12 -12
  84. package/dist/plugins/kanban/query-keys.d.cts +1 -1
  85. package/dist/plugins/kanban/query-keys.d.mts +1 -1
  86. package/dist/plugins/kanban/query-keys.d.ts +1 -1
  87. package/dist/plugins/ui-builder/client/hooks/index.d.cts +1 -1
  88. package/dist/plugins/ui-builder/client/hooks/index.d.mts +1 -1
  89. package/dist/plugins/ui-builder/client/hooks/index.d.ts +1 -1
  90. package/dist/plugins/ui-builder/client/index.d.cts +3 -3
  91. package/dist/plugins/ui-builder/client/index.d.mts +3 -3
  92. package/dist/plugins/ui-builder/client/index.d.ts +3 -3
  93. package/dist/plugins/ui-builder/index.d.cts +2 -2
  94. package/dist/plugins/ui-builder/index.d.mts +2 -2
  95. package/dist/plugins/ui-builder/index.d.ts +2 -2
  96. package/dist/shared/{stack.C-WUPMT6.d.cts → stack.B2xZTSiO.d.cts} +4 -4
  97. package/dist/shared/{stack.CczspVn2.d.mts → stack.B58oHdqm.d.mts} +1 -1
  98. package/dist/shared/{stack.CVDTkMoO.d.mts → stack.B8QD11QU.d.cts} +7 -7
  99. package/dist/shared/{stack.CVDTkMoO.d.cts → stack.B8QD11QU.d.mts} +7 -7
  100. package/dist/shared/{stack.CVDTkMoO.d.ts → stack.B8QD11QU.d.ts} +7 -7
  101. package/dist/shared/{stack.Kq2-QzOC.d.ts → stack.BDVEpue1.d.ts} +2 -2
  102. package/dist/shared/{stack.B7ONvlD_.d.mts → stack.BTvbxZvw.d.cts} +2 -2
  103. package/dist/shared/{stack.DdI5W6MB.d.mts → stack.BozPgbrZ.d.cts} +19 -19
  104. package/dist/shared/{stack.DdI5W6MB.d.cts → stack.BozPgbrZ.d.mts} +19 -19
  105. package/dist/shared/{stack.DdI5W6MB.d.ts → stack.BozPgbrZ.d.ts} +19 -19
  106. package/dist/shared/{stack.BUkC2EsZ.d.cts → stack.C9Mg2Q46.d.cts} +1 -1
  107. package/dist/shared/{stack.BEn34wW6.d.ts → stack.CTDVxbrA.d.ts} +12 -12
  108. package/dist/shared/{stack.C-Ptrz8s.d.ts → stack.Cj_zKww4.d.ts} +4 -4
  109. package/dist/shared/{stack.BepFXT3w.d.mts → stack.CxaFNQCV.d.mts} +25 -25
  110. package/dist/shared/{stack.DWoCZff7.d.cts → stack.D-b5zbPm.d.cts} +12 -12
  111. package/dist/shared/{stack.kcdnD4gA.d.cts → stack.DTtmJPQO.d.mts} +2 -2
  112. package/dist/shared/{stack.CL8ts1Mu.d.ts → stack.DXnclTG7.d.ts} +8 -8
  113. package/dist/shared/{stack.heOA9gzA.d.cts → stack.DaZM10cp.d.cts} +8 -8
  114. package/dist/shared/{stack.DTDxgFj8.d.mts → stack.FVWf2JhZ.d.mts} +12 -12
  115. package/dist/shared/{stack.Dk5r4W1F.d.mts → stack.cfCkioTe.d.mts} +8 -8
  116. package/dist/shared/{stack.6fUOjLs9.d.mts → stack.dH7u-TJH.d.mts} +4 -4
  117. package/dist/shared/{stack.CgWzG5jH.d.ts → stack.j75TpKh2.d.ts} +25 -25
  118. package/dist/shared/{stack.D3GB6wKv.d.cts → stack.n1_i1p2B.d.cts} +25 -25
  119. package/dist/shared/{stack.DASmUVjX.d.ts → stack.sO33ZDhK.d.ts} +1 -1
  120. package/package.json +1 -1
  121. package/src/plugins/ai-chat/api/plugin.ts +48 -63
  122. package/src/plugins/ai-chat/client/plugin.tsx +23 -31
  123. package/src/plugins/blog/api/plugin.ts +31 -47
  124. package/src/plugins/blog/client/plugin.tsx +36 -39
  125. package/src/plugins/client/index.ts +5 -1
  126. package/src/plugins/cms/api/plugin.ts +14 -17
  127. package/src/plugins/cms/client/plugin.tsx +18 -21
  128. package/src/plugins/cms/types.ts +7 -7
  129. package/src/plugins/form-builder/api/plugin.ts +64 -64
  130. package/src/plugins/form-builder/client/plugin.tsx +19 -18
  131. package/src/plugins/form-builder/types.ts +19 -24
  132. package/src/plugins/kanban/api/plugin.ts +111 -136
  133. package/src/plugins/kanban/client/plugin.tsx +35 -41
  134. package/src/plugins/ui-builder/client/plugin.tsx +11 -10
  135. package/src/plugins/ui-builder/types.ts +4 -4
  136. package/src/plugins/utils.ts +92 -1
@@ -23,10 +23,10 @@ function createPostsLoader(published, config) {
23
23
  };
24
24
  try {
25
25
  if (hooks?.beforeLoadPosts) {
26
- const canLoad = await hooks.beforeLoadPosts({ published }, context);
27
- if (!canLoad) {
28
- throw new Error("Load prevented by beforeLoadPosts hook");
29
- }
26
+ await client.runClientHookWithShim(
27
+ () => hooks.beforeLoadPosts({ published }, context),
28
+ "Load prevented by beforeLoadPosts hook"
29
+ );
30
30
  }
31
31
  const limit = 10;
32
32
  const client$1 = client.createApiClient({
@@ -47,14 +47,10 @@ function createPostsLoader(published, config) {
47
47
  await queryClient.prefetchQuery(tagsQuery);
48
48
  if (hooks?.afterLoadPosts) {
49
49
  const posts = queryClient.getQueryData(listQuery.queryKey) || null;
50
- const canContinue = await hooks.afterLoadPosts(
51
- posts,
52
- { published },
53
- context
50
+ await client.runClientHookWithShim(
51
+ () => hooks.afterLoadPosts(posts, { published }, context),
52
+ "Load prevented by afterLoadPosts hook"
54
53
  );
55
- if (canContinue === false) {
56
- throw new Error("Load prevented by afterLoadPosts hook");
57
- }
58
54
  }
59
55
  const queryState = queryClient.getQueryState(listQuery.queryKey);
60
56
  if (queryState?.error) {
@@ -90,10 +86,10 @@ function createPostLoader(slug, config, path) {
90
86
  };
91
87
  try {
92
88
  if (hooks?.beforeLoadPost) {
93
- const canLoad = await hooks.beforeLoadPost(slug, context);
94
- if (!canLoad) {
95
- throw new Error("Load prevented by beforeLoadPost hook");
96
- }
89
+ await client.runClientHookWithShim(
90
+ () => hooks.beforeLoadPost(slug, context),
91
+ "Load prevented by beforeLoadPost hook"
92
+ );
97
93
  }
98
94
  const client$1 = client.createApiClient({
99
95
  baseURL: apiBaseURL,
@@ -104,10 +100,10 @@ function createPostLoader(slug, config, path) {
104
100
  await queryClient.prefetchQuery(postQuery);
105
101
  if (hooks?.afterLoadPost) {
106
102
  const post = queryClient.getQueryData(postQuery.queryKey) || null;
107
- const canContinue = await hooks.afterLoadPost(post, slug, context);
108
- if (canContinue === false) {
109
- throw new Error("Load prevented by afterLoadPost hook");
110
- }
103
+ await client.runClientHookWithShim(
104
+ () => hooks.afterLoadPost(post, slug, context),
105
+ "Load prevented by afterLoadPost hook"
106
+ );
111
107
  }
112
108
  const queryState = queryClient.getQueryState(postQuery.queryKey);
113
109
  if (queryState?.error) {
@@ -142,16 +138,16 @@ function createNewPostLoader(config) {
142
138
  };
143
139
  try {
144
140
  if (hooks?.beforeLoadNewPost) {
145
- const canLoad = await hooks.beforeLoadNewPost(context);
146
- if (!canLoad) {
147
- throw new Error("Load prevented by beforeLoadNewPost hook");
148
- }
141
+ await client.runClientHookWithShim(
142
+ () => hooks.beforeLoadNewPost(context),
143
+ "Load prevented by beforeLoadNewPost hook"
144
+ );
149
145
  }
150
146
  if (hooks?.afterLoadNewPost) {
151
- const canContinue = await hooks.afterLoadNewPost(context);
152
- if (canContinue === false) {
153
- throw new Error("Load prevented by afterLoadNewPost hook");
154
- }
147
+ await client.runClientHookWithShim(
148
+ () => hooks.afterLoadNewPost(context),
149
+ "Load prevented by afterLoadNewPost hook"
150
+ );
155
151
  }
156
152
  } catch (error) {
157
153
  if (hooks?.onLoadError) {
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { defineClientPlugin, createApiClient, isConnectionError } from '@btst/stack/plugins/client';
2
+ import { defineClientPlugin, createApiClient, runClientHookWithShim, isConnectionError } from '@btst/stack/plugins/client';
3
3
  import { createRoute } from '@btst/yar';
4
4
  import { createBlogQueryKeys } from '../../../../../../plugins/blog/query-keys.mjs';
5
5
  import { HomePageComponent } from './components/pages/home-page.mjs';
@@ -21,10 +21,10 @@ function createPostsLoader(published, config) {
21
21
  };
22
22
  try {
23
23
  if (hooks?.beforeLoadPosts) {
24
- const canLoad = await hooks.beforeLoadPosts({ published }, context);
25
- if (!canLoad) {
26
- throw new Error("Load prevented by beforeLoadPosts hook");
27
- }
24
+ await runClientHookWithShim(
25
+ () => hooks.beforeLoadPosts({ published }, context),
26
+ "Load prevented by beforeLoadPosts hook"
27
+ );
28
28
  }
29
29
  const limit = 10;
30
30
  const client = createApiClient({
@@ -45,14 +45,10 @@ function createPostsLoader(published, config) {
45
45
  await queryClient.prefetchQuery(tagsQuery);
46
46
  if (hooks?.afterLoadPosts) {
47
47
  const posts = queryClient.getQueryData(listQuery.queryKey) || null;
48
- const canContinue = await hooks.afterLoadPosts(
49
- posts,
50
- { published },
51
- context
48
+ await runClientHookWithShim(
49
+ () => hooks.afterLoadPosts(posts, { published }, context),
50
+ "Load prevented by afterLoadPosts hook"
52
51
  );
53
- if (canContinue === false) {
54
- throw new Error("Load prevented by afterLoadPosts hook");
55
- }
56
52
  }
57
53
  const queryState = queryClient.getQueryState(listQuery.queryKey);
58
54
  if (queryState?.error) {
@@ -88,10 +84,10 @@ function createPostLoader(slug, config, path) {
88
84
  };
89
85
  try {
90
86
  if (hooks?.beforeLoadPost) {
91
- const canLoad = await hooks.beforeLoadPost(slug, context);
92
- if (!canLoad) {
93
- throw new Error("Load prevented by beforeLoadPost hook");
94
- }
87
+ await runClientHookWithShim(
88
+ () => hooks.beforeLoadPost(slug, context),
89
+ "Load prevented by beforeLoadPost hook"
90
+ );
95
91
  }
96
92
  const client = createApiClient({
97
93
  baseURL: apiBaseURL,
@@ -102,10 +98,10 @@ function createPostLoader(slug, config, path) {
102
98
  await queryClient.prefetchQuery(postQuery);
103
99
  if (hooks?.afterLoadPost) {
104
100
  const post = queryClient.getQueryData(postQuery.queryKey) || null;
105
- const canContinue = await hooks.afterLoadPost(post, slug, context);
106
- if (canContinue === false) {
107
- throw new Error("Load prevented by afterLoadPost hook");
108
- }
101
+ await runClientHookWithShim(
102
+ () => hooks.afterLoadPost(post, slug, context),
103
+ "Load prevented by afterLoadPost hook"
104
+ );
109
105
  }
110
106
  const queryState = queryClient.getQueryState(postQuery.queryKey);
111
107
  if (queryState?.error) {
@@ -140,16 +136,16 @@ function createNewPostLoader(config) {
140
136
  };
141
137
  try {
142
138
  if (hooks?.beforeLoadNewPost) {
143
- const canLoad = await hooks.beforeLoadNewPost(context);
144
- if (!canLoad) {
145
- throw new Error("Load prevented by beforeLoadNewPost hook");
146
- }
139
+ await runClientHookWithShim(
140
+ () => hooks.beforeLoadNewPost(context),
141
+ "Load prevented by beforeLoadNewPost hook"
142
+ );
147
143
  }
148
144
  if (hooks?.afterLoadNewPost) {
149
- const canContinue = await hooks.afterLoadNewPost(context);
150
- if (canContinue === false) {
151
- throw new Error("Load prevented by afterLoadNewPost hook");
152
- }
145
+ await runClientHookWithShim(
146
+ () => hooks.afterLoadNewPost(context),
147
+ "Load prevented by afterLoadNewPost hook"
148
+ );
153
149
  }
154
150
  } catch (error) {
155
151
  if (hooks?.onLoadError) {
@@ -9,6 +9,7 @@ const utils = require('../utils.cjs');
9
9
  const getters = require('./getters.cjs');
10
10
  const mutations = require('./mutations.cjs');
11
11
  const queryKeyDefs = require('./query-key-defs.cjs');
12
+ const utils$1 = require('../../utils.cjs');
12
13
 
13
14
  async function syncContentTypes(adapter, config) {
14
15
  for (const ct of config.contentTypes) {
@@ -489,13 +490,11 @@ const cmsBackendPlugin = (config) => {
489
490
  }
490
491
  const processedData = validation.data;
491
492
  if (config.hooks?.onBeforeCreate) {
492
- const result = await config.hooks.onBeforeCreate(
493
- processedData,
494
- context
493
+ await utils$1.runHookWithShim(
494
+ () => config.hooks.onBeforeCreate(processedData, context),
495
+ ctx.error,
496
+ "Create operation denied"
495
497
  );
496
- if (result === false) {
497
- throw ctx.error(403, { message: "Create operation denied" });
498
- }
499
498
  }
500
499
  const item = await adapter.create({
501
500
  model: "contentItem",
@@ -599,14 +598,11 @@ const cmsBackendPlugin = (config) => {
599
598
  }
600
599
  const processedData = validatedData;
601
600
  if (config.hooks?.onBeforeUpdate && validatedData) {
602
- const result = await config.hooks.onBeforeUpdate(
603
- id,
604
- validatedData,
605
- context
601
+ await utils$1.runHookWithShim(
602
+ () => config.hooks.onBeforeUpdate(id, validatedData, context),
603
+ ctx.error,
604
+ "Update operation denied"
606
605
  );
607
- if (result === false) {
608
- throw ctx.error(403, { message: "Update operation denied" });
609
- }
610
606
  }
611
607
  if (relationIds) {
612
608
  await syncRelations(adapter, id, relationIds);
@@ -657,10 +653,11 @@ const cmsBackendPlugin = (config) => {
657
653
  throw ctx.error(404, { message: "Content item not found" });
658
654
  }
659
655
  if (config.hooks?.onBeforeDelete) {
660
- const canDelete = await config.hooks.onBeforeDelete(id, context);
661
- if (!canDelete) {
662
- throw ctx.error(403, { message: "Delete operation denied" });
663
- }
656
+ await utils$1.runHookWithShim(
657
+ () => config.hooks.onBeforeDelete(id, context),
658
+ ctx.error,
659
+ "Delete operation denied"
660
+ );
664
661
  }
665
662
  await adapter.delete({
666
663
  model: "contentItem",
@@ -7,6 +7,7 @@ import { slugify } from '../utils.mjs';
7
7
  import { serializeContentType, getAllContentItems, serializeContentItemWithType, serializeContentItem, getContentItemById, getContentItemBySlug, getAllContentTypes } from './getters.mjs';
8
8
  import { createCMSContentItem } from './mutations.mjs';
9
9
  import { CMS_QUERY_KEYS } from './query-key-defs.mjs';
10
+ import { runHookWithShim } from '../../utils.mjs';
10
11
 
11
12
  async function syncContentTypes(adapter, config) {
12
13
  for (const ct of config.contentTypes) {
@@ -487,13 +488,11 @@ const cmsBackendPlugin = (config) => {
487
488
  }
488
489
  const processedData = validation.data;
489
490
  if (config.hooks?.onBeforeCreate) {
490
- const result = await config.hooks.onBeforeCreate(
491
- processedData,
492
- context
491
+ await runHookWithShim(
492
+ () => config.hooks.onBeforeCreate(processedData, context),
493
+ ctx.error,
494
+ "Create operation denied"
493
495
  );
494
- if (result === false) {
495
- throw ctx.error(403, { message: "Create operation denied" });
496
- }
497
496
  }
498
497
  const item = await adapter.create({
499
498
  model: "contentItem",
@@ -597,14 +596,11 @@ const cmsBackendPlugin = (config) => {
597
596
  }
598
597
  const processedData = validatedData;
599
598
  if (config.hooks?.onBeforeUpdate && validatedData) {
600
- const result = await config.hooks.onBeforeUpdate(
601
- id,
602
- validatedData,
603
- context
599
+ await runHookWithShim(
600
+ () => config.hooks.onBeforeUpdate(id, validatedData, context),
601
+ ctx.error,
602
+ "Update operation denied"
604
603
  );
605
- if (result === false) {
606
- throw ctx.error(403, { message: "Update operation denied" });
607
- }
608
604
  }
609
605
  if (relationIds) {
610
606
  await syncRelations(adapter, id, relationIds);
@@ -655,10 +651,11 @@ const cmsBackendPlugin = (config) => {
655
651
  throw ctx.error(404, { message: "Content item not found" });
656
652
  }
657
653
  if (config.hooks?.onBeforeDelete) {
658
- const canDelete = await config.hooks.onBeforeDelete(id, context);
659
- if (!canDelete) {
660
- throw ctx.error(403, { message: "Delete operation denied" });
661
- }
654
+ await runHookWithShim(
655
+ () => config.hooks.onBeforeDelete(id, context),
656
+ ctx.error,
657
+ "Delete operation denied"
658
+ );
662
659
  }
663
660
  await adapter.delete({
664
661
  model: "contentItem",
@@ -34,10 +34,10 @@ function createDashboardLoader(config) {
34
34
  };
35
35
  try {
36
36
  if (hooks?.beforeLoadDashboard) {
37
- const canLoad = await hooks.beforeLoadDashboard(context);
38
- if (!canLoad) {
39
- throw new Error("Load prevented by beforeLoadDashboard hook");
40
- }
37
+ await client.runClientHookWithShim(
38
+ () => hooks.beforeLoadDashboard(context),
39
+ "Load prevented by beforeLoadDashboard hook"
40
+ );
41
41
  }
42
42
  const client$1 = client.createApiClient({
43
43
  baseURL: apiBaseURL,
@@ -82,10 +82,10 @@ function createContentListLoader(typeSlug, config) {
82
82
  };
83
83
  try {
84
84
  if (hooks?.beforeLoadContentList) {
85
- const canLoad = await hooks.beforeLoadContentList(typeSlug, context);
86
- if (!canLoad) {
87
- throw new Error("Load prevented by beforeLoadContentList hook");
88
- }
85
+ await client.runClientHookWithShim(
86
+ () => hooks.beforeLoadContentList(typeSlug, context),
87
+ "Load prevented by beforeLoadContentList hook"
88
+ );
89
89
  }
90
90
  const client$1 = client.createApiClient({
91
91
  baseURL: apiBaseURL,
@@ -154,14 +154,10 @@ function createContentEditorLoader(typeSlug, id, config) {
154
154
  };
155
155
  try {
156
156
  if (hooks?.beforeLoadContentEditor) {
157
- const canLoad = await hooks.beforeLoadContentEditor(
158
- typeSlug,
159
- id,
160
- context
157
+ await client.runClientHookWithShim(
158
+ () => hooks.beforeLoadContentEditor(typeSlug, id, context),
159
+ "Load prevented by beforeLoadContentEditor hook"
161
160
  );
162
- if (!canLoad) {
163
- throw new Error("Load prevented by beforeLoadContentEditor hook");
164
- }
165
161
  }
166
162
  const client$1 = client.createApiClient({
167
163
  baseURL: apiBaseURL,
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { lazy } from 'react';
3
- import { defineClientPlugin, createApiClient, isConnectionError } from '@btst/stack/plugins/client';
3
+ import { defineClientPlugin, createApiClient, runClientHookWithShim, isConnectionError } from '@btst/stack/plugins/client';
4
4
  import { createRoute } from '@btst/yar';
5
5
  import { createCMSQueryKeys } from '../../../../../../plugins/cms/query-keys.mjs';
6
6
 
@@ -32,10 +32,10 @@ function createDashboardLoader(config) {
32
32
  };
33
33
  try {
34
34
  if (hooks?.beforeLoadDashboard) {
35
- const canLoad = await hooks.beforeLoadDashboard(context);
36
- if (!canLoad) {
37
- throw new Error("Load prevented by beforeLoadDashboard hook");
38
- }
35
+ await runClientHookWithShim(
36
+ () => hooks.beforeLoadDashboard(context),
37
+ "Load prevented by beforeLoadDashboard hook"
38
+ );
39
39
  }
40
40
  const client = createApiClient({
41
41
  baseURL: apiBaseURL,
@@ -80,10 +80,10 @@ function createContentListLoader(typeSlug, config) {
80
80
  };
81
81
  try {
82
82
  if (hooks?.beforeLoadContentList) {
83
- const canLoad = await hooks.beforeLoadContentList(typeSlug, context);
84
- if (!canLoad) {
85
- throw new Error("Load prevented by beforeLoadContentList hook");
86
- }
83
+ await runClientHookWithShim(
84
+ () => hooks.beforeLoadContentList(typeSlug, context),
85
+ "Load prevented by beforeLoadContentList hook"
86
+ );
87
87
  }
88
88
  const client = createApiClient({
89
89
  baseURL: apiBaseURL,
@@ -152,14 +152,10 @@ function createContentEditorLoader(typeSlug, id, config) {
152
152
  };
153
153
  try {
154
154
  if (hooks?.beforeLoadContentEditor) {
155
- const canLoad = await hooks.beforeLoadContentEditor(
156
- typeSlug,
157
- id,
158
- context
155
+ await runClientHookWithShim(
156
+ () => hooks.beforeLoadContentEditor(typeSlug, id, context),
157
+ "Load prevented by beforeLoadContentEditor hook"
159
158
  );
160
- if (!canLoad) {
161
- throw new Error("Load prevented by beforeLoadContentEditor hook");
162
- }
163
159
  }
164
160
  const client = createApiClient({
165
161
  baseURL: apiBaseURL,
@@ -8,6 +8,7 @@ const schemas = require('../schemas.cjs');
8
8
  const utils = require('../utils.cjs');
9
9
  const getters = require('./getters.cjs');
10
10
  const queryKeyDefs = require('./query-key-defs.cjs');
11
+ const utils$1 = require('../../utils.cjs');
11
12
 
12
13
  function createFormBuilderPrefetchForRoute(adapter) {
13
14
  return async function prefetchForRoute(key, qc, params) {
@@ -98,10 +99,11 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
98
99
  const { status, limit, offset } = ctx.query;
99
100
  const context = createContext(ctx.headers);
100
101
  if (config.hooks?.onBeforeListForms) {
101
- const canList = await config.hooks.onBeforeListForms(context);
102
- if (!canList) {
103
- throw ctx.error(403, { message: "Access denied" });
104
- }
102
+ await utils$1.runHookWithShim(
103
+ () => config.hooks.onBeforeListForms(context),
104
+ ctx.error,
105
+ "Access denied"
106
+ );
105
107
  }
106
108
  return getters.getAllForms(adapter, { status, limit, offset });
107
109
  }
@@ -116,10 +118,11 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
116
118
  const { slug } = ctx.params;
117
119
  const context = createContext(ctx.headers);
118
120
  if (config.hooks?.onBeforeGetForm) {
119
- const canGet = await config.hooks.onBeforeGetForm(slug, context);
120
- if (!canGet) {
121
- throw ctx.error(403, { message: "Access denied" });
122
- }
121
+ await utils$1.runHookWithShim(
122
+ () => config.hooks.onBeforeGetForm(slug, context),
123
+ ctx.error,
124
+ "Access denied"
125
+ );
123
126
  }
124
127
  const form = await getters.getFormBySlug(adapter, slug);
125
128
  if (!form) {
@@ -138,10 +141,11 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
138
141
  const { id } = ctx.params;
139
142
  const context = createContext(ctx.headers);
140
143
  if (config.hooks?.onBeforeGetForm) {
141
- const canGet = await config.hooks.onBeforeGetForm(id, context);
142
- if (!canGet) {
143
- throw ctx.error(403, { message: "Access denied" });
144
- }
144
+ await utils$1.runHookWithShim(
145
+ () => config.hooks.onBeforeGetForm(id, context),
146
+ ctx.error,
147
+ "Access denied"
148
+ );
145
149
  }
146
150
  const form = await adapter.findOne({
147
151
  model: "form",
@@ -192,15 +196,13 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
192
196
  status: body.status
193
197
  };
194
198
  if (config.hooks?.onBeforeFormCreated) {
195
- const result = await config.hooks.onBeforeFormCreated(
196
- formInput,
197
- context
199
+ const hookResult = await utils$1.runHookWithShim(
200
+ () => config.hooks.onBeforeFormCreated(formInput, context),
201
+ ctx.error,
202
+ "Create operation denied"
198
203
  );
199
- if (result === false) {
200
- throw ctx.error(403, { message: "Create operation denied" });
201
- }
202
- if (result && typeof result === "object") {
203
- formInput = result;
204
+ if (hookResult && typeof hookResult === "object") {
205
+ formInput = hookResult;
204
206
  }
205
207
  }
206
208
  const form = await adapter.create({
@@ -282,16 +284,13 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
282
284
  status: body.status
283
285
  };
284
286
  if (config.hooks?.onBeforeFormUpdated) {
285
- const result = await config.hooks.onBeforeFormUpdated(
286
- id,
287
- updateInput,
288
- context
287
+ const hookResult = await utils$1.runHookWithShim(
288
+ () => config.hooks.onBeforeFormUpdated(id, updateInput, context),
289
+ ctx.error,
290
+ "Update operation denied"
289
291
  );
290
- if (result === false) {
291
- throw ctx.error(403, { message: "Update operation denied" });
292
- }
293
- if (result && typeof result === "object") {
294
- updateInput = result;
292
+ if (hookResult && typeof hookResult === "object") {
293
+ updateInput = hookResult;
295
294
  }
296
295
  }
297
296
  const updateData = {
@@ -343,13 +342,11 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
343
342
  throw ctx.error(404, { message: "Form not found" });
344
343
  }
345
344
  if (config.hooks?.onBeforeFormDeleted) {
346
- const canDelete = await config.hooks.onBeforeFormDeleted(
347
- id,
348
- context
345
+ await utils$1.runHookWithShim(
346
+ () => config.hooks.onBeforeFormDeleted(id, context),
347
+ ctx.error,
348
+ "Delete operation denied"
349
349
  );
350
- if (!canDelete) {
351
- throw ctx.error(403, { message: "Delete operation denied" });
352
- }
353
350
  }
354
351
  await adapter.delete({
355
352
  model: "formSubmission",
@@ -414,28 +411,33 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
414
411
  }
415
412
  let finalData = data;
416
413
  if (config.hooks?.onBeforeSubmission) {
414
+ let hookResult;
415
+ let originalError;
417
416
  try {
418
- const result = await config.hooks.onBeforeSubmission(
417
+ hookResult = await config.hooks.onBeforeSubmission(
419
418
  slug,
420
419
  data,
421
420
  submissionContext
422
421
  );
423
- if (result === false) {
424
- throw ctx.error(400, { message: "Submission rejected" });
425
- }
426
- if (result && typeof result === "object") {
427
- finalData = result;
422
+ if (hookResult === false) {
423
+ originalError = new Error("Submission rejected");
428
424
  }
429
- } catch (error) {
425
+ } catch (e) {
426
+ originalError = e instanceof Error ? e : new Error("Submission rejected");
427
+ }
428
+ if (originalError) {
430
429
  if (config.hooks?.onSubmissionError) {
431
430
  await config.hooks.onSubmissionError(
432
- error,
431
+ originalError,
433
432
  slug,
434
433
  data,
435
434
  submissionContext
436
435
  );
437
436
  }
438
- throw error;
437
+ throw ctx.error(400, { message: originalError.message });
438
+ }
439
+ if (hookResult && typeof hookResult === "object") {
440
+ finalData = hookResult;
439
441
  }
440
442
  }
441
443
  const submission = await adapter.create({
@@ -484,13 +486,11 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
484
486
  throw ctx.error(404, { message: "Form not found" });
485
487
  }
486
488
  if (config.hooks?.onBeforeListSubmissions) {
487
- const canList = await config.hooks.onBeforeListSubmissions(
488
- formId,
489
- context
489
+ await utils$1.runHookWithShim(
490
+ () => config.hooks.onBeforeListSubmissions(formId, context),
491
+ ctx.error,
492
+ "Access denied"
490
493
  );
491
- if (!canList) {
492
- throw ctx.error(403, { message: "Access denied" });
493
- }
494
494
  }
495
495
  return getters.getFormSubmissions(adapter, formId, { limit, offset });
496
496
  }
@@ -505,13 +505,11 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
505
505
  const { formId, subId } = ctx.params;
506
506
  const context = createContext(ctx.headers);
507
507
  if (config.hooks?.onBeforeGetSubmission) {
508
- const canGet = await config.hooks.onBeforeGetSubmission(
509
- subId,
510
- context
508
+ await utils$1.runHookWithShim(
509
+ () => config.hooks.onBeforeGetSubmission(subId, context),
510
+ ctx.error,
511
+ "Access denied"
511
512
  );
512
- if (!canGet) {
513
- throw ctx.error(403, { message: "Access denied" });
514
- }
515
513
  }
516
514
  const submission = await adapter.findOne({
517
515
  model: "formSubmission",
@@ -541,13 +539,11 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
541
539
  throw ctx.error(404, { message: "Submission not found" });
542
540
  }
543
541
  if (config.hooks?.onBeforeSubmissionDeleted) {
544
- const canDelete = await config.hooks.onBeforeSubmissionDeleted(
545
- subId,
546
- context
542
+ await utils$1.runHookWithShim(
543
+ () => config.hooks.onBeforeSubmissionDeleted(subId, context),
544
+ ctx.error,
545
+ "Delete operation denied"
547
546
  );
548
- if (!canDelete) {
549
- throw ctx.error(403, { message: "Delete operation denied" });
550
- }
551
547
  }
552
548
  await adapter.delete({
553
549
  model: "formSubmission",