@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
@@ -6,6 +6,7 @@ const db = require('../db.cjs');
6
6
  const schemas = require('../schemas.cjs');
7
7
  const getters = require('./getters.cjs');
8
8
  const pageTools = require('./page-tools.cjs');
9
+ const utils = require('../../utils.cjs');
9
10
 
10
11
  const aiChatBackendPlugin = (config) => api.defineBackendPlugin({
11
12
  name: "ai-chat",
@@ -72,15 +73,11 @@ const aiChatBackendPlugin = (config) => api.defineBackendPlugin({
72
73
  role: msg.role,
73
74
  content: getMessageTextContent(msg)
74
75
  }));
75
- const canChat = await config.hooks.onBeforeChat(
76
- messagesForHook,
77
- context
76
+ await utils.runHookWithShim(
77
+ () => config.hooks.onBeforeChat(messagesForHook, context),
78
+ ctx.error,
79
+ "Unauthorized: Cannot start chat"
78
80
  );
79
- if (!canChat) {
80
- throw ctx.error(403, {
81
- message: "Unauthorized: Cannot start chat"
82
- });
83
- }
84
81
  }
85
82
  const firstMessage = uiMessages[0];
86
83
  if (!firstMessage) {
@@ -343,15 +340,14 @@ ${pageContext}` : "";
343
340
  });
344
341
  });
345
342
  if (config.hooks?.onBeforeCreateConversation) {
346
- const canCreate = await config.hooks.onBeforeCreateConversation(
347
- { id, title },
348
- context
343
+ await utils.runHookWithShim(
344
+ () => config.hooks.onBeforeCreateConversation(
345
+ { id, title },
346
+ context
347
+ ),
348
+ ctx.error,
349
+ "Unauthorized: Cannot create conversation"
349
350
  );
350
- if (!canCreate) {
351
- throw ctx.error(403, {
352
- message: "Unauthorized: Cannot create conversation"
353
- });
354
- }
355
351
  }
356
352
  const newConv = await adapter.create({
357
353
  model: "conversation",
@@ -397,12 +393,11 @@ ${pageContext}` : "";
397
393
  });
398
394
  });
399
395
  if (config.hooks?.onBeforeListConversations) {
400
- const canList = await config.hooks.onBeforeListConversations(context);
401
- if (!canList) {
402
- throw ctx.error(403, {
403
- message: "Unauthorized: Cannot list conversations"
404
- });
405
- }
396
+ await utils.runHookWithShim(
397
+ () => config.hooks.onBeforeListConversations(context),
398
+ ctx.error,
399
+ "Unauthorized: Cannot list conversations"
400
+ );
406
401
  }
407
402
  const whereConditions = [];
408
403
  if (userId) {
@@ -455,15 +450,11 @@ ${pageContext}` : "";
455
450
  });
456
451
  });
457
452
  if (config.hooks?.onBeforeGetConversation) {
458
- const canGet = await config.hooks.onBeforeGetConversation(
459
- id,
460
- context
453
+ await utils.runHookWithShim(
454
+ () => config.hooks.onBeforeGetConversation(id, context),
455
+ ctx.error,
456
+ "Unauthorized: Cannot get conversation"
461
457
  );
462
- if (!canGet) {
463
- throw ctx.error(403, {
464
- message: "Unauthorized: Cannot get conversation"
465
- });
466
- }
467
458
  }
468
459
  const conversations = await adapter.findMany({
469
460
  model: "conversation",
@@ -545,16 +536,15 @@ ${pageContext}` : "";
545
536
  });
546
537
  }
547
538
  if (config.hooks?.onBeforeUpdateConversation) {
548
- const canUpdate = await config.hooks.onBeforeUpdateConversation(
549
- id,
550
- { title },
551
- context
539
+ await utils.runHookWithShim(
540
+ () => config.hooks.onBeforeUpdateConversation(
541
+ id,
542
+ { title },
543
+ context
544
+ ),
545
+ ctx.error,
546
+ "Unauthorized: Cannot update conversation"
552
547
  );
553
- if (!canUpdate) {
554
- throw ctx.error(403, {
555
- message: "Unauthorized: Cannot update conversation"
556
- });
557
- }
558
548
  }
559
549
  const updated = await adapter.update({
560
550
  model: "conversation",
@@ -619,15 +609,11 @@ ${pageContext}` : "";
619
609
  });
620
610
  }
621
611
  if (config.hooks?.onBeforeDeleteConversation) {
622
- const canDelete = await config.hooks.onBeforeDeleteConversation(
623
- id,
624
- context
612
+ await utils.runHookWithShim(
613
+ () => config.hooks.onBeforeDeleteConversation(id, context),
614
+ ctx.error,
615
+ "Unauthorized: Cannot delete conversation"
625
616
  );
626
- if (!canDelete) {
627
- throw ctx.error(403, {
628
- message: "Unauthorized: Cannot delete conversation"
629
- });
630
- }
631
617
  }
632
618
  await adapter.delete({
633
619
  model: "conversation",
@@ -4,6 +4,7 @@ import { aiChatSchema } from '../db.mjs';
4
4
  import { chatRequestSchema, createConversationSchema, updateConversationSchema } from '../schemas.mjs';
5
5
  import { getConversationById, getAllConversations } from './getters.mjs';
6
6
  import { BUILT_IN_PAGE_TOOL_SCHEMAS, BUILT_IN_PAGE_TOOL_ROUTE_ALLOWLIST } from './page-tools.mjs';
7
+ import { runHookWithShim } from '../../utils.mjs';
7
8
 
8
9
  const aiChatBackendPlugin = (config) => defineBackendPlugin({
9
10
  name: "ai-chat",
@@ -70,15 +71,11 @@ const aiChatBackendPlugin = (config) => defineBackendPlugin({
70
71
  role: msg.role,
71
72
  content: getMessageTextContent(msg)
72
73
  }));
73
- const canChat = await config.hooks.onBeforeChat(
74
- messagesForHook,
75
- context
74
+ await runHookWithShim(
75
+ () => config.hooks.onBeforeChat(messagesForHook, context),
76
+ ctx.error,
77
+ "Unauthorized: Cannot start chat"
76
78
  );
77
- if (!canChat) {
78
- throw ctx.error(403, {
79
- message: "Unauthorized: Cannot start chat"
80
- });
81
- }
82
79
  }
83
80
  const firstMessage = uiMessages[0];
84
81
  if (!firstMessage) {
@@ -341,15 +338,14 @@ ${pageContext}` : "";
341
338
  });
342
339
  });
343
340
  if (config.hooks?.onBeforeCreateConversation) {
344
- const canCreate = await config.hooks.onBeforeCreateConversation(
345
- { id, title },
346
- context
341
+ await runHookWithShim(
342
+ () => config.hooks.onBeforeCreateConversation(
343
+ { id, title },
344
+ context
345
+ ),
346
+ ctx.error,
347
+ "Unauthorized: Cannot create conversation"
347
348
  );
348
- if (!canCreate) {
349
- throw ctx.error(403, {
350
- message: "Unauthorized: Cannot create conversation"
351
- });
352
- }
353
349
  }
354
350
  const newConv = await adapter.create({
355
351
  model: "conversation",
@@ -395,12 +391,11 @@ ${pageContext}` : "";
395
391
  });
396
392
  });
397
393
  if (config.hooks?.onBeforeListConversations) {
398
- const canList = await config.hooks.onBeforeListConversations(context);
399
- if (!canList) {
400
- throw ctx.error(403, {
401
- message: "Unauthorized: Cannot list conversations"
402
- });
403
- }
394
+ await runHookWithShim(
395
+ () => config.hooks.onBeforeListConversations(context),
396
+ ctx.error,
397
+ "Unauthorized: Cannot list conversations"
398
+ );
404
399
  }
405
400
  const whereConditions = [];
406
401
  if (userId) {
@@ -453,15 +448,11 @@ ${pageContext}` : "";
453
448
  });
454
449
  });
455
450
  if (config.hooks?.onBeforeGetConversation) {
456
- const canGet = await config.hooks.onBeforeGetConversation(
457
- id,
458
- context
451
+ await runHookWithShim(
452
+ () => config.hooks.onBeforeGetConversation(id, context),
453
+ ctx.error,
454
+ "Unauthorized: Cannot get conversation"
459
455
  );
460
- if (!canGet) {
461
- throw ctx.error(403, {
462
- message: "Unauthorized: Cannot get conversation"
463
- });
464
- }
465
456
  }
466
457
  const conversations = await adapter.findMany({
467
458
  model: "conversation",
@@ -543,16 +534,15 @@ ${pageContext}` : "";
543
534
  });
544
535
  }
545
536
  if (config.hooks?.onBeforeUpdateConversation) {
546
- const canUpdate = await config.hooks.onBeforeUpdateConversation(
547
- id,
548
- { title },
549
- context
537
+ await runHookWithShim(
538
+ () => config.hooks.onBeforeUpdateConversation(
539
+ id,
540
+ { title },
541
+ context
542
+ ),
543
+ ctx.error,
544
+ "Unauthorized: Cannot update conversation"
550
545
  );
551
- if (!canUpdate) {
552
- throw ctx.error(403, {
553
- message: "Unauthorized: Cannot update conversation"
554
- });
555
- }
556
546
  }
557
547
  const updated = await adapter.update({
558
548
  model: "conversation",
@@ -617,15 +607,11 @@ ${pageContext}` : "";
617
607
  });
618
608
  }
619
609
  if (config.hooks?.onBeforeDeleteConversation) {
620
- const canDelete = await config.hooks.onBeforeDeleteConversation(
621
- id,
622
- context
610
+ await runHookWithShim(
611
+ () => config.hooks.onBeforeDeleteConversation(id, context),
612
+ ctx.error,
613
+ "Unauthorized: Cannot delete conversation"
623
614
  );
624
- if (!canDelete) {
625
- throw ctx.error(403, {
626
- message: "Unauthorized: Cannot delete conversation"
627
- });
628
- }
629
615
  }
630
616
  await adapter.delete({
631
617
  model: "conversation",
@@ -22,10 +22,10 @@ function createConversationsLoader(config) {
22
22
  };
23
23
  try {
24
24
  if (hooks?.beforeLoadConversations) {
25
- const canLoad = await hooks.beforeLoadConversations(context);
26
- if (!canLoad) {
27
- throw new Error("Load prevented by beforeLoadConversations hook");
28
- }
25
+ await client.runClientHookWithShim(
26
+ () => hooks.beforeLoadConversations(context),
27
+ "Load prevented by beforeLoadConversations hook"
28
+ );
29
29
  }
30
30
  const client$1 = client.createApiClient({
31
31
  baseURL: apiBaseURL,
@@ -38,13 +38,10 @@ function createConversationsLoader(config) {
38
38
  const conversations = queryClient.getQueryData(
39
39
  listQuery.queryKey
40
40
  ) || null;
41
- const canContinue = await hooks.afterLoadConversations(
42
- conversations,
43
- context
41
+ await client.runClientHookWithShim(
42
+ () => hooks.afterLoadConversations(conversations, context),
43
+ "Load prevented by afterLoadConversations hook"
44
44
  );
45
- if (canContinue === false) {
46
- throw new Error("Load prevented by afterLoadConversations hook");
47
- }
48
45
  }
49
46
  const queryState = queryClient.getQueryState(listQuery.queryKey);
50
47
  if (queryState?.error && hooks?.onLoadError) {
@@ -73,10 +70,10 @@ function createConversationLoader(id, config) {
73
70
  };
74
71
  try {
75
72
  if (hooks?.beforeLoadConversation) {
76
- const canLoad = await hooks.beforeLoadConversation(id, context);
77
- if (!canLoad) {
78
- throw new Error("Load prevented by beforeLoadConversation hook");
79
- }
73
+ await client.runClientHookWithShim(
74
+ () => hooks.beforeLoadConversation(id, context),
75
+ "Load prevented by beforeLoadConversation hook"
76
+ );
80
77
  }
81
78
  const client$1 = client.createApiClient({
82
79
  baseURL: apiBaseURL,
@@ -91,14 +88,10 @@ function createConversationLoader(id, config) {
91
88
  ]);
92
89
  if (hooks?.afterLoadConversation) {
93
90
  const conversation = queryClient.getQueryData(conversationQuery.queryKey) || null;
94
- const canContinue = await hooks.afterLoadConversation(
95
- conversation,
96
- id,
97
- context
91
+ await client.runClientHookWithShim(
92
+ () => hooks.afterLoadConversation(conversation, id, context),
93
+ "Load prevented by afterLoadConversation hook"
98
94
  );
99
- if (canContinue === false) {
100
- throw new Error("Load prevented by afterLoadConversation hook");
101
- }
102
95
  }
103
96
  const queryState = queryClient.getQueryState(
104
97
  conversationQuery.queryKey
@@ -1,5 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { defineClientPlugin, createApiClient } from '@btst/stack/plugins/client';
2
+ import { defineClientPlugin, runClientHookWithShim, createApiClient } from '@btst/stack/plugins/client';
3
3
  import { createRoute } from '@btst/yar';
4
4
  import { createAiChatQueryKeys } from '../../../../../../plugins/ai-chat/query-keys.mjs';
5
5
  import { ChatLayout } from './components/chat-layout.mjs';
@@ -20,10 +20,10 @@ function createConversationsLoader(config) {
20
20
  };
21
21
  try {
22
22
  if (hooks?.beforeLoadConversations) {
23
- const canLoad = await hooks.beforeLoadConversations(context);
24
- if (!canLoad) {
25
- throw new Error("Load prevented by beforeLoadConversations hook");
26
- }
23
+ await runClientHookWithShim(
24
+ () => hooks.beforeLoadConversations(context),
25
+ "Load prevented by beforeLoadConversations hook"
26
+ );
27
27
  }
28
28
  const client = createApiClient({
29
29
  baseURL: apiBaseURL,
@@ -36,13 +36,10 @@ function createConversationsLoader(config) {
36
36
  const conversations = queryClient.getQueryData(
37
37
  listQuery.queryKey
38
38
  ) || null;
39
- const canContinue = await hooks.afterLoadConversations(
40
- conversations,
41
- context
39
+ await runClientHookWithShim(
40
+ () => hooks.afterLoadConversations(conversations, context),
41
+ "Load prevented by afterLoadConversations hook"
42
42
  );
43
- if (canContinue === false) {
44
- throw new Error("Load prevented by afterLoadConversations hook");
45
- }
46
43
  }
47
44
  const queryState = queryClient.getQueryState(listQuery.queryKey);
48
45
  if (queryState?.error && hooks?.onLoadError) {
@@ -71,10 +68,10 @@ function createConversationLoader(id, config) {
71
68
  };
72
69
  try {
73
70
  if (hooks?.beforeLoadConversation) {
74
- const canLoad = await hooks.beforeLoadConversation(id, context);
75
- if (!canLoad) {
76
- throw new Error("Load prevented by beforeLoadConversation hook");
77
- }
71
+ await runClientHookWithShim(
72
+ () => hooks.beforeLoadConversation(id, context),
73
+ "Load prevented by beforeLoadConversation hook"
74
+ );
78
75
  }
79
76
  const client = createApiClient({
80
77
  baseURL: apiBaseURL,
@@ -89,14 +86,10 @@ function createConversationLoader(id, config) {
89
86
  ]);
90
87
  if (hooks?.afterLoadConversation) {
91
88
  const conversation = queryClient.getQueryData(conversationQuery.queryKey) || null;
92
- const canContinue = await hooks.afterLoadConversation(
93
- conversation,
94
- id,
95
- context
89
+ await runClientHookWithShim(
90
+ () => hooks.afterLoadConversation(conversation, id, context),
91
+ "Load prevented by afterLoadConversation hook"
96
92
  );
97
- if (canContinue === false) {
98
- throw new Error("Load prevented by afterLoadConversation hook");
99
- }
100
93
  }
101
94
  const queryState = queryClient.getQueryState(
102
95
  conversationQuery.queryKey
@@ -3,11 +3,12 @@
3
3
  const api = require('@btst/stack/plugins/api');
4
4
  const z = require('zod');
5
5
  const db = require('../db.cjs');
6
- const utils = require('../utils.cjs');
6
+ const utils$1 = require('../utils.cjs');
7
7
  const schemas = require('../schemas.cjs');
8
8
  const getters = require('./getters.cjs');
9
9
  const queryKeyDefs = require('./query-key-defs.cjs');
10
10
  const serializers = require('./serializers.cjs');
11
+ const utils = require('../../utils.cjs');
11
12
 
12
13
  function createBlogPrefetchForRoute(adapter) {
13
14
  return async function prefetchForRoute(key, qc, params) {
@@ -113,7 +114,7 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
113
114
  for (const tag of allTags) {
114
115
  tagMapBySlug.set(tag.slug, tag);
115
116
  }
116
- const tagSlugs = tagsToFindOrCreate.map((tag) => utils.slugify(tag.name));
117
+ const tagSlugs = tagsToFindOrCreate.map((tag) => utils$1.slugify(tag.name));
117
118
  const foundTags = [];
118
119
  for (const slug of tagSlugs) {
119
120
  const tag = tagMapBySlug.get(slug);
@@ -126,7 +127,7 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
126
127
  ...foundTags.map((tag) => tag.slug)
127
128
  ]);
128
129
  const tagsToCreate = tagsToFindOrCreate.filter(
129
- (tag) => !existingSlugs.has(utils.slugify(tag.name))
130
+ (tag) => !existingSlugs.has(utils$1.slugify(tag.name))
130
131
  );
131
132
  const createdTags = [];
132
133
  for (const tag of tagsToCreate) {
@@ -135,7 +136,7 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
135
136
  model: "tag",
136
137
  data: {
137
138
  name: normalizedName,
138
- slug: utils.slugify(normalizedName),
139
+ slug: utils$1.slugify(normalizedName),
139
140
  createdAt: /* @__PURE__ */ new Date(),
140
141
  updatedAt: /* @__PURE__ */ new Date()
141
142
  }
@@ -155,12 +156,11 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
155
156
  const context = { query, headers };
156
157
  try {
157
158
  if (hooks?.onBeforeListPosts) {
158
- const canList = await hooks.onBeforeListPosts(query, context);
159
- if (!canList) {
160
- throw ctx.error(403, {
161
- message: "Unauthorized: Cannot list posts"
162
- });
163
- }
159
+ await utils.runHookWithShim(
160
+ () => hooks.onBeforeListPosts(query, context),
161
+ ctx.error,
162
+ "Unauthorized: Cannot list posts"
163
+ );
164
164
  }
165
165
  const result = await getters.getAllPosts(adapter, query);
166
166
  if (hooks?.onPostsRead) {
@@ -188,19 +188,15 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
188
188
  };
189
189
  try {
190
190
  if (hooks?.onBeforeCreatePost) {
191
- const canCreate = await hooks.onBeforeCreatePost(
192
- ctx.body,
193
- context
191
+ await utils.runHookWithShim(
192
+ () => hooks.onBeforeCreatePost(ctx.body, context),
193
+ ctx.error,
194
+ "Unauthorized: Cannot create post"
194
195
  );
195
- if (!canCreate) {
196
- throw ctx.error(403, {
197
- message: "Unauthorized: Cannot create post"
198
- });
199
- }
200
196
  }
201
197
  const { tags, ...postData } = ctx.body;
202
198
  const tagNames = tags || [];
203
- const slug = utils.slugify(postData.slug || postData.title);
199
+ const slug = utils$1.slugify(postData.slug || postData.title);
204
200
  if (!slug) {
205
201
  throw ctx.error(400, {
206
202
  message: "Invalid slug: must contain at least one alphanumeric character"
@@ -259,20 +255,15 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
259
255
  };
260
256
  try {
261
257
  if (hooks?.onBeforeUpdatePost) {
262
- const canUpdate = await hooks.onBeforeUpdatePost(
263
- ctx.params.id,
264
- ctx.body,
265
- context
258
+ await utils.runHookWithShim(
259
+ () => hooks.onBeforeUpdatePost(ctx.params.id, ctx.body, context),
260
+ ctx.error,
261
+ "Unauthorized: Cannot update post"
266
262
  );
267
- if (!canUpdate) {
268
- throw ctx.error(403, {
269
- message: "Unauthorized: Cannot update post"
270
- });
271
- }
272
263
  }
273
264
  const { tags, slug: rawSlug, ...restPostData } = ctx.body;
274
265
  const tagNames = tags || [];
275
- const slugified = rawSlug ? utils.slugify(rawSlug) : void 0;
266
+ const slugified = rawSlug ? utils$1.slugify(rawSlug) : void 0;
276
267
  if (rawSlug && !slugified) {
277
268
  throw ctx.error(400, {
278
269
  message: "Invalid slug: must contain at least one alphanumeric character"
@@ -364,15 +355,11 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
364
355
  };
365
356
  try {
366
357
  if (hooks?.onBeforeDeletePost) {
367
- const canDelete = await hooks.onBeforeDeletePost(
368
- ctx.params.id,
369
- context
358
+ await utils.runHookWithShim(
359
+ () => hooks.onBeforeDeletePost(ctx.params.id, context),
360
+ ctx.error,
361
+ "Unauthorized: Cannot delete post"
370
362
  );
371
- if (!canDelete) {
372
- throw ctx.error(403, {
373
- message: "Unauthorized: Cannot delete post"
374
- });
375
- }
376
363
  }
377
364
  await adapter.delete({
378
365
  model: "post",
@@ -401,15 +388,11 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
401
388
  const context = { query, headers };
402
389
  try {
403
390
  if (hooks?.onBeforeListPosts) {
404
- const canList = await hooks.onBeforeListPosts(
405
- { published: true },
406
- context
391
+ await utils.runHookWithShim(
392
+ () => hooks.onBeforeListPosts({ published: true }, context),
393
+ ctx.error,
394
+ "Unauthorized: Cannot list posts"
407
395
  );
408
- if (!canList) {
409
- throw ctx.error(403, {
410
- message: "Unauthorized: Cannot list posts"
411
- });
412
- }
413
396
  }
414
397
  const date = query.date;
415
398
  const previousPosts = await adapter.findMany({
@@ -6,6 +6,7 @@ import { createPostSchema, updatePostSchema } from '../schemas.mjs';
6
6
  import { getAllTags, getPostBySlug, getAllPosts } from './getters.mjs';
7
7
  import { BLOG_QUERY_KEYS } from './query-key-defs.mjs';
8
8
  import { serializePost, serializeTag } from './serializers.mjs';
9
+ import { runHookWithShim } from '../../utils.mjs';
9
10
 
10
11
  function createBlogPrefetchForRoute(adapter) {
11
12
  return async function prefetchForRoute(key, qc, params) {
@@ -153,12 +154,11 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
153
154
  const context = { query, headers };
154
155
  try {
155
156
  if (hooks?.onBeforeListPosts) {
156
- const canList = await hooks.onBeforeListPosts(query, context);
157
- if (!canList) {
158
- throw ctx.error(403, {
159
- message: "Unauthorized: Cannot list posts"
160
- });
161
- }
157
+ await runHookWithShim(
158
+ () => hooks.onBeforeListPosts(query, context),
159
+ ctx.error,
160
+ "Unauthorized: Cannot list posts"
161
+ );
162
162
  }
163
163
  const result = await getAllPosts(adapter, query);
164
164
  if (hooks?.onPostsRead) {
@@ -186,15 +186,11 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
186
186
  };
187
187
  try {
188
188
  if (hooks?.onBeforeCreatePost) {
189
- const canCreate = await hooks.onBeforeCreatePost(
190
- ctx.body,
191
- context
189
+ await runHookWithShim(
190
+ () => hooks.onBeforeCreatePost(ctx.body, context),
191
+ ctx.error,
192
+ "Unauthorized: Cannot create post"
192
193
  );
193
- if (!canCreate) {
194
- throw ctx.error(403, {
195
- message: "Unauthorized: Cannot create post"
196
- });
197
- }
198
194
  }
199
195
  const { tags, ...postData } = ctx.body;
200
196
  const tagNames = tags || [];
@@ -257,16 +253,11 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
257
253
  };
258
254
  try {
259
255
  if (hooks?.onBeforeUpdatePost) {
260
- const canUpdate = await hooks.onBeforeUpdatePost(
261
- ctx.params.id,
262
- ctx.body,
263
- context
256
+ await runHookWithShim(
257
+ () => hooks.onBeforeUpdatePost(ctx.params.id, ctx.body, context),
258
+ ctx.error,
259
+ "Unauthorized: Cannot update post"
264
260
  );
265
- if (!canUpdate) {
266
- throw ctx.error(403, {
267
- message: "Unauthorized: Cannot update post"
268
- });
269
- }
270
261
  }
271
262
  const { tags, slug: rawSlug, ...restPostData } = ctx.body;
272
263
  const tagNames = tags || [];
@@ -362,15 +353,11 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
362
353
  };
363
354
  try {
364
355
  if (hooks?.onBeforeDeletePost) {
365
- const canDelete = await hooks.onBeforeDeletePost(
366
- ctx.params.id,
367
- context
356
+ await runHookWithShim(
357
+ () => hooks.onBeforeDeletePost(ctx.params.id, context),
358
+ ctx.error,
359
+ "Unauthorized: Cannot delete post"
368
360
  );
369
- if (!canDelete) {
370
- throw ctx.error(403, {
371
- message: "Unauthorized: Cannot delete post"
372
- });
373
- }
374
361
  }
375
362
  await adapter.delete({
376
363
  model: "post",
@@ -399,15 +386,11 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
399
386
  const context = { query, headers };
400
387
  try {
401
388
  if (hooks?.onBeforeListPosts) {
402
- const canList = await hooks.onBeforeListPosts(
403
- { published: true },
404
- context
389
+ await runHookWithShim(
390
+ () => hooks.onBeforeListPosts({ published: true }, context),
391
+ ctx.error,
392
+ "Unauthorized: Cannot list posts"
405
393
  );
406
- if (!canList) {
407
- throw ctx.error(403, {
408
- message: "Unauthorized: Cannot list posts"
409
- });
410
- }
411
394
  }
412
395
  const date = query.date;
413
396
  const previousPosts = await adapter.findMany({