@btst/stack 2.1.0 → 2.3.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 (229) hide show
  1. package/dist/api/index.cjs +9 -1
  2. package/dist/api/index.d.cts +4 -4
  3. package/dist/api/index.d.mts +4 -4
  4. package/dist/api/index.d.ts +4 -4
  5. package/dist/api/index.mjs +9 -1
  6. package/dist/client/index.d.cts +2 -2
  7. package/dist/client/index.d.mts +2 -2
  8. package/dist/client/index.d.ts +2 -2
  9. package/dist/index.d.cts +1 -1
  10. package/dist/index.d.mts +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/packages/stack/src/plugins/ai-chat/api/getters.cjs +42 -0
  13. package/dist/packages/stack/src/plugins/ai-chat/api/getters.mjs +39 -0
  14. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.cjs +5 -0
  15. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.mjs +5 -0
  16. package/dist/packages/stack/src/plugins/blog/api/getters.cjs +131 -0
  17. package/dist/packages/stack/src/plugins/blog/api/getters.mjs +127 -0
  18. package/dist/packages/stack/src/plugins/blog/api/plugin.cjs +60 -107
  19. package/dist/packages/stack/src/plugins/blog/api/plugin.mjs +60 -107
  20. package/dist/packages/stack/src/plugins/blog/api/query-key-defs.cjs +18 -0
  21. package/dist/packages/stack/src/plugins/blog/api/query-key-defs.mjs +15 -0
  22. package/dist/packages/stack/src/plugins/blog/api/serializers.cjs +21 -0
  23. package/dist/packages/stack/src/plugins/blog/api/serializers.mjs +18 -0
  24. package/dist/packages/stack/src/plugins/blog/client/plugin.cjs +16 -1
  25. package/dist/packages/stack/src/plugins/blog/client/plugin.mjs +17 -2
  26. package/dist/packages/stack/src/plugins/cms/api/getters.cjs +156 -0
  27. package/dist/packages/stack/src/plugins/cms/api/getters.mjs +147 -0
  28. package/dist/packages/stack/src/plugins/cms/api/plugin.cjs +624 -617
  29. package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +623 -616
  30. package/dist/packages/stack/src/plugins/cms/api/query-key-defs.cjs +29 -0
  31. package/dist/packages/stack/src/plugins/cms/api/query-key-defs.mjs +26 -0
  32. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-editor-page.internal.cjs +1 -1
  33. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-editor-page.internal.mjs +1 -1
  34. package/dist/packages/stack/src/plugins/cms/client/hooks/cms-hooks.cjs +6 -3
  35. package/dist/packages/stack/src/plugins/cms/client/hooks/cms-hooks.mjs +6 -3
  36. package/dist/packages/stack/src/plugins/cms/client/plugin.cjs +15 -0
  37. package/dist/packages/stack/src/plugins/cms/client/plugin.mjs +16 -1
  38. package/dist/packages/stack/src/plugins/form-builder/api/getters.cjs +120 -0
  39. package/dist/packages/stack/src/plugins/form-builder/api/getters.mjs +112 -0
  40. package/dist/packages/stack/src/plugins/form-builder/api/plugin.cjs +75 -86
  41. package/dist/packages/stack/src/plugins/form-builder/api/plugin.mjs +71 -82
  42. package/dist/packages/stack/src/plugins/form-builder/api/query-key-defs.cjs +37 -0
  43. package/dist/packages/stack/src/plugins/form-builder/api/query-key-defs.mjs +33 -0
  44. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.cjs +1 -1
  45. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.mjs +1 -1
  46. package/dist/packages/stack/src/plugins/form-builder/client/plugin.cjs +15 -0
  47. package/dist/packages/stack/src/plugins/form-builder/client/plugin.mjs +16 -1
  48. package/dist/packages/stack/src/plugins/kanban/api/getters.cjs +84 -0
  49. package/dist/packages/stack/src/plugins/kanban/api/getters.mjs +81 -0
  50. package/dist/packages/stack/src/plugins/kanban/api/plugin.cjs +37 -123
  51. package/dist/packages/stack/src/plugins/kanban/api/plugin.mjs +37 -123
  52. package/dist/packages/stack/src/plugins/kanban/api/query-key-defs.cjs +26 -0
  53. package/dist/packages/stack/src/plugins/kanban/api/query-key-defs.mjs +23 -0
  54. package/dist/packages/stack/src/plugins/kanban/api/serializers.cjs +30 -0
  55. package/dist/packages/stack/src/plugins/kanban/api/serializers.mjs +26 -0
  56. package/dist/packages/stack/src/plugins/kanban/client/plugin.cjs +11 -1
  57. package/dist/packages/stack/src/plugins/kanban/client/plugin.mjs +12 -2
  58. package/dist/packages/stack/src/plugins/utils.cjs +6 -0
  59. package/dist/packages/stack/src/plugins/utils.mjs +6 -1
  60. package/dist/plugins/ai-chat/api/index.cjs +3 -0
  61. package/dist/plugins/ai-chat/api/index.d.cts +27 -4
  62. package/dist/plugins/ai-chat/api/index.d.mts +27 -4
  63. package/dist/plugins/ai-chat/api/index.d.ts +27 -4
  64. package/dist/plugins/ai-chat/api/index.mjs +1 -0
  65. package/dist/plugins/ai-chat/client/hooks/index.d.cts +2 -2
  66. package/dist/plugins/ai-chat/client/hooks/index.d.mts +2 -2
  67. package/dist/plugins/ai-chat/client/hooks/index.d.ts +2 -2
  68. package/dist/plugins/ai-chat/query-keys.d.cts +9 -284
  69. package/dist/plugins/ai-chat/query-keys.d.mts +9 -284
  70. package/dist/plugins/ai-chat/query-keys.d.ts +9 -284
  71. package/dist/plugins/api/index.d.cts +4 -3
  72. package/dist/plugins/api/index.d.mts +4 -3
  73. package/dist/plugins/api/index.d.ts +4 -3
  74. package/dist/plugins/blog/api/index.cjs +9 -0
  75. package/dist/plugins/blog/api/index.d.cts +20 -4
  76. package/dist/plugins/blog/api/index.d.mts +20 -4
  77. package/dist/plugins/blog/api/index.d.ts +20 -4
  78. package/dist/plugins/blog/api/index.mjs +3 -0
  79. package/dist/plugins/blog/client/hooks/index.d.cts +5 -5
  80. package/dist/plugins/blog/client/hooks/index.d.mts +5 -5
  81. package/dist/plugins/blog/client/hooks/index.d.ts +5 -5
  82. package/dist/plugins/blog/client/index.d.cts +1 -1
  83. package/dist/plugins/blog/client/index.d.mts +1 -1
  84. package/dist/plugins/blog/client/index.d.ts +1 -1
  85. package/dist/plugins/blog/query-keys.cjs +13 -9
  86. package/dist/plugins/blog/query-keys.d.cts +8 -333
  87. package/dist/plugins/blog/query-keys.d.mts +8 -333
  88. package/dist/plugins/blog/query-keys.d.ts +8 -333
  89. package/dist/plugins/blog/query-keys.mjs +13 -9
  90. package/dist/plugins/client/index.cjs +1 -0
  91. package/dist/plugins/client/index.d.cts +10 -3
  92. package/dist/plugins/client/index.d.mts +10 -3
  93. package/dist/plugins/client/index.d.ts +10 -3
  94. package/dist/plugins/client/index.mjs +1 -1
  95. package/dist/plugins/cms/api/index.cjs +10 -0
  96. package/dist/plugins/cms/api/index.d.cts +7 -163
  97. package/dist/plugins/cms/api/index.d.mts +7 -163
  98. package/dist/plugins/cms/api/index.d.ts +7 -163
  99. package/dist/plugins/cms/api/index.mjs +2 -0
  100. package/dist/plugins/cms/client/hooks/index.d.cts +1 -1
  101. package/dist/plugins/cms/client/hooks/index.d.mts +1 -1
  102. package/dist/plugins/cms/client/hooks/index.d.ts +1 -1
  103. package/dist/plugins/cms/query-keys.cjs +2 -1
  104. package/dist/plugins/cms/query-keys.d.cts +6 -9
  105. package/dist/plugins/cms/query-keys.d.mts +6 -9
  106. package/dist/plugins/cms/query-keys.d.ts +6 -9
  107. package/dist/plugins/cms/query-keys.mjs +2 -1
  108. package/dist/plugins/form-builder/api/index.cjs +10 -0
  109. package/dist/plugins/form-builder/api/index.d.cts +7 -141
  110. package/dist/plugins/form-builder/api/index.d.mts +7 -141
  111. package/dist/plugins/form-builder/api/index.d.ts +7 -141
  112. package/dist/plugins/form-builder/api/index.mjs +2 -0
  113. package/dist/plugins/form-builder/client/components/index.d.cts +1 -1
  114. package/dist/plugins/form-builder/client/components/index.d.mts +1 -1
  115. package/dist/plugins/form-builder/client/components/index.d.ts +1 -1
  116. package/dist/plugins/form-builder/client/hooks/index.d.cts +1 -1
  117. package/dist/plugins/form-builder/client/hooks/index.d.mts +1 -1
  118. package/dist/plugins/form-builder/client/hooks/index.d.ts +1 -1
  119. package/dist/plugins/form-builder/query-keys.cjs +3 -2
  120. package/dist/plugins/form-builder/query-keys.d.cts +7 -6
  121. package/dist/plugins/form-builder/query-keys.d.mts +7 -6
  122. package/dist/plugins/form-builder/query-keys.d.ts +7 -6
  123. package/dist/plugins/form-builder/query-keys.mjs +3 -2
  124. package/dist/plugins/kanban/api/index.cjs +9 -0
  125. package/dist/plugins/kanban/api/index.d.cts +17 -395
  126. package/dist/plugins/kanban/api/index.d.mts +17 -395
  127. package/dist/plugins/kanban/api/index.d.ts +17 -395
  128. package/dist/plugins/kanban/api/index.mjs +3 -0
  129. package/dist/plugins/kanban/client/components/index.d.cts +1 -1
  130. package/dist/plugins/kanban/client/components/index.d.mts +1 -1
  131. package/dist/plugins/kanban/client/components/index.d.ts +1 -1
  132. package/dist/plugins/kanban/client/hooks/index.d.cts +1 -1
  133. package/dist/plugins/kanban/client/hooks/index.d.mts +1 -1
  134. package/dist/plugins/kanban/client/hooks/index.d.ts +1 -1
  135. package/dist/plugins/kanban/client/index.d.cts +1 -1
  136. package/dist/plugins/kanban/client/index.d.mts +1 -1
  137. package/dist/plugins/kanban/client/index.d.ts +1 -1
  138. package/dist/plugins/kanban/query-keys.cjs +6 -12
  139. package/dist/plugins/kanban/query-keys.d.cts +5 -16
  140. package/dist/plugins/kanban/query-keys.d.mts +5 -16
  141. package/dist/plugins/kanban/query-keys.d.ts +5 -16
  142. package/dist/plugins/kanban/query-keys.mjs +6 -12
  143. package/dist/plugins/open-api/api/index.d.cts +2 -2
  144. package/dist/plugins/open-api/api/index.d.mts +2 -2
  145. package/dist/plugins/open-api/api/index.d.ts +2 -2
  146. package/dist/plugins/route-docs/client/index.d.cts +1 -1
  147. package/dist/plugins/route-docs/client/index.d.mts +1 -1
  148. package/dist/plugins/route-docs/client/index.d.ts +1 -1
  149. package/dist/plugins/ui-builder/index.d.cts +1 -1
  150. package/dist/plugins/ui-builder/index.d.mts +1 -1
  151. package/dist/plugins/ui-builder/index.d.ts +1 -1
  152. package/dist/shared/{stack.BoA0xkJv.d.cts → stack.7n9Y_u7N.d.cts} +33 -7
  153. package/dist/shared/{stack.BoA0xkJv.d.mts → stack.7n9Y_u7N.d.mts} +33 -7
  154. package/dist/shared/{stack.BoA0xkJv.d.ts → stack.7n9Y_u7N.d.ts} +33 -7
  155. package/dist/shared/stack.B1EeBt1b.d.ts +297 -0
  156. package/dist/shared/stack.BIXEI6v_.d.mts +419 -0
  157. package/dist/shared/stack.BKfolAyK.d.ts +419 -0
  158. package/dist/shared/stack.BeSm90va.d.ts +289 -0
  159. package/dist/shared/stack.BpolpQpf.d.cts +445 -0
  160. package/dist/shared/stack.C5dtIncc.d.mts +293 -0
  161. package/dist/shared/stack.CIP6QS9l.d.ts +293 -0
  162. package/dist/shared/stack.CMh_EdxW.d.cts +289 -0
  163. package/dist/shared/stack.CP68pFEH.d.mts +297 -0
  164. package/dist/shared/{stack.BsXokfNh.d.mts → stack.CVDTkMoO.d.cts} +8 -2
  165. package/dist/shared/{stack.BsXokfNh.d.ts → stack.CVDTkMoO.d.mts} +8 -2
  166. package/dist/shared/{stack.BsXokfNh.d.cts → stack.CVDTkMoO.d.ts} +8 -2
  167. package/dist/shared/{stack.DKDMI-QO.d.mts → stack.DJaKVY7v.d.cts} +7 -1
  168. package/dist/shared/{stack.DKDMI-QO.d.ts → stack.DJaKVY7v.d.mts} +7 -1
  169. package/dist/shared/{stack.DKDMI-QO.d.cts → stack.DJaKVY7v.d.ts} +7 -1
  170. package/dist/shared/{stack.DzH_wcvr.d.mts → stack.DdI5W6MB.d.cts} +9 -3
  171. package/dist/shared/{stack.DzH_wcvr.d.ts → stack.DdI5W6MB.d.mts} +9 -3
  172. package/dist/shared/{stack.DzH_wcvr.d.cts → stack.DdI5W6MB.d.ts} +9 -3
  173. package/dist/shared/stack.Dg09R0oB.d.mts +289 -0
  174. package/dist/shared/stack.Dw0Ly2TM.d.cts +293 -0
  175. package/dist/shared/stack.IdtKDRka.d.cts +297 -0
  176. package/dist/shared/stack.TIBF2AOx.d.ts +445 -0
  177. package/dist/shared/stack.rTy7-wQU.d.mts +445 -0
  178. package/dist/shared/stack.snB1EDP7.d.cts +419 -0
  179. package/package.json +3 -3
  180. package/src/__tests__/stack-api.test.ts +118 -0
  181. package/src/api/index.ts +15 -1
  182. package/src/plugins/ai-chat/__tests__/getters.test.ts +109 -0
  183. package/src/plugins/ai-chat/api/getters.ts +71 -0
  184. package/src/plugins/ai-chat/api/index.ts +1 -0
  185. package/src/plugins/ai-chat/api/plugin.ts +8 -0
  186. package/src/plugins/api/index.ts +3 -1
  187. package/src/plugins/blog/__tests__/getters.test.ts +540 -0
  188. package/src/plugins/blog/api/getters.ts +243 -0
  189. package/src/plugins/blog/api/index.ts +9 -0
  190. package/src/plugins/blog/api/plugin.ts +98 -141
  191. package/src/plugins/blog/api/query-key-defs.ts +46 -0
  192. package/src/plugins/blog/api/serializers.ts +27 -0
  193. package/src/plugins/blog/client/plugin.tsx +21 -1
  194. package/src/plugins/blog/query-keys.ts +21 -20
  195. package/src/plugins/client/index.ts +1 -1
  196. package/src/plugins/cms/__tests__/getters.test.ts +206 -0
  197. package/src/plugins/cms/api/getters.ts +268 -0
  198. package/src/plugins/cms/api/index.ts +15 -1
  199. package/src/plugins/cms/api/plugin.ts +151 -150
  200. package/src/plugins/cms/api/query-key-defs.ts +53 -0
  201. package/src/plugins/cms/api/serializers.ts +12 -0
  202. package/src/plugins/cms/client/components/pages/content-editor-page.internal.tsx +1 -1
  203. package/src/plugins/cms/client/hooks/cms-hooks.tsx +3 -0
  204. package/src/plugins/cms/client/plugin.tsx +19 -0
  205. package/src/plugins/cms/query-keys.ts +2 -1
  206. package/src/plugins/cms/types.ts +1 -1
  207. package/src/plugins/form-builder/__tests__/getters.test.ts +159 -0
  208. package/src/plugins/form-builder/api/getters.ts +226 -0
  209. package/src/plugins/form-builder/api/index.ts +15 -1
  210. package/src/plugins/form-builder/api/plugin.ts +107 -109
  211. package/src/plugins/form-builder/api/query-key-defs.ts +79 -0
  212. package/src/plugins/form-builder/api/serializers.ts +12 -0
  213. package/src/plugins/form-builder/client/components/pages/submissions-page.internal.tsx +1 -1
  214. package/src/plugins/form-builder/client/plugin.tsx +19 -0
  215. package/src/plugins/form-builder/query-keys.ts +6 -2
  216. package/src/plugins/form-builder/types.ts +2 -2
  217. package/src/plugins/kanban/__tests__/getters.test.ts +172 -0
  218. package/src/plugins/kanban/api/getters.ts +149 -0
  219. package/src/plugins/kanban/api/index.ts +4 -0
  220. package/src/plugins/kanban/api/plugin.ts +65 -146
  221. package/src/plugins/kanban/api/query-key-defs.ts +54 -0
  222. package/src/plugins/kanban/api/serializers.ts +49 -0
  223. package/src/plugins/kanban/client/plugin.tsx +15 -1
  224. package/src/plugins/kanban/query-keys.ts +10 -14
  225. package/src/plugins/utils.ts +19 -0
  226. package/src/types.ts +44 -5
  227. package/dist/shared/{stack.CbuN2zVV.d.cts → stack.CBON0dWL.d.cts} +7 -7
  228. package/dist/shared/{stack.CbuN2zVV.d.mts → stack.CBON0dWL.d.mts} +7 -7
  229. package/dist/shared/{stack.CbuN2zVV.d.ts → stack.CBON0dWL.d.ts} +7 -7
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ function contentListDiscriminator(params) {
4
+ return {
5
+ typeSlug: params.typeSlug,
6
+ limit: params.limit ?? 20,
7
+ offset: params.offset ?? 0
8
+ };
9
+ }
10
+ const CMS_QUERY_KEYS = {
11
+ /**
12
+ * Key for the cmsTypes.list() query.
13
+ * Full key: ["cmsTypes", "list", "list"]
14
+ */
15
+ typesList: () => ["cmsTypes", "list", "list"],
16
+ /**
17
+ * Key for the cmsContent.list({ typeSlug, limit, offset }) query.
18
+ * Full key: ["cmsContent", "list", { typeSlug, limit, offset }]
19
+ */
20
+ contentList: (params) => ["cmsContent", "list", contentListDiscriminator(params)],
21
+ /**
22
+ * Key for the cmsContent.detail(typeSlug, id) query.
23
+ * Full key: ["cmsContent", "detail", typeSlug, id]
24
+ */
25
+ contentDetail: (typeSlug, id) => ["cmsContent", "detail", typeSlug, id]
26
+ };
27
+
28
+ exports.CMS_QUERY_KEYS = CMS_QUERY_KEYS;
29
+ exports.contentListDiscriminator = contentListDiscriminator;
@@ -0,0 +1,26 @@
1
+ function contentListDiscriminator(params) {
2
+ return {
3
+ typeSlug: params.typeSlug,
4
+ limit: params.limit ?? 20,
5
+ offset: params.offset ?? 0
6
+ };
7
+ }
8
+ const CMS_QUERY_KEYS = {
9
+ /**
10
+ * Key for the cmsTypes.list() query.
11
+ * Full key: ["cmsTypes", "list", "list"]
12
+ */
13
+ typesList: () => ["cmsTypes", "list", "list"],
14
+ /**
15
+ * Key for the cmsContent.list({ typeSlug, limit, offset }) query.
16
+ * Full key: ["cmsContent", "list", { typeSlug, limit, offset }]
17
+ */
18
+ contentList: (params) => ["cmsContent", "list", contentListDiscriminator(params)],
19
+ /**
20
+ * Key for the cmsContent.detail(typeSlug, id) query.
21
+ * Full key: ["cmsContent", "detail", typeSlug, id]
22
+ */
23
+ contentDetail: (typeSlug, id) => ["cmsContent", "detail", typeSlug, id]
24
+ };
25
+
26
+ export { CMS_QUERY_KEYS, contentListDiscriminator };
@@ -136,7 +136,7 @@ function ContentEditorPage({ typeSlug, id }) {
136
136
  contentForm.ContentForm,
137
137
  {
138
138
  contentType,
139
- initialData: isEditing ? item?.parsedData : Object.keys(prefillParams).length > 0 ? convertPrefillToFormData(
139
+ initialData: isEditing ? item?.parsedData ?? void 0 : Object.keys(prefillParams).length > 0 ? convertPrefillToFormData(
140
140
  prefillParams,
141
141
  JSON.parse(contentType.jsonSchema)
142
142
  ) : void 0,
@@ -134,7 +134,7 @@ function ContentEditorPage({ typeSlug, id }) {
134
134
  ContentForm,
135
135
  {
136
136
  contentType,
137
- initialData: isEditing ? item?.parsedData : Object.keys(prefillParams).length > 0 ? convertPrefillToFormData(
137
+ initialData: isEditing ? item?.parsedData ?? void 0 : Object.keys(prefillParams).length > 0 ? convertPrefillToFormData(
138
138
  prefillParams,
139
139
  JSON.parse(contentType.jsonSchema)
140
140
  ) : void 0,
@@ -305,10 +305,12 @@ function useCreateContent(typeSlug) {
305
305
  },
306
306
  onSuccess: async () => {
307
307
  await queryClient.invalidateQueries({
308
- queryKey: queries.cmsContent.list._def
308
+ queryKey: queries.cmsContent.list._def,
309
+ refetchType: "all"
309
310
  });
310
311
  await queryClient.invalidateQueries({
311
- queryKey: queries.cmsTypes.list._def
312
+ queryKey: queries.cmsTypes.list._def,
313
+ refetchType: "all"
312
314
  });
313
315
  if (refresh) {
314
316
  await refresh();
@@ -346,7 +348,8 @@ function useUpdateContent(typeSlug) {
346
348
  );
347
349
  }
348
350
  await queryClient.invalidateQueries({
349
- queryKey: queries.cmsContent.list._def
351
+ queryKey: queries.cmsContent.list._def,
352
+ refetchType: "all"
350
353
  });
351
354
  if (refresh) {
352
355
  await refresh();
@@ -303,10 +303,12 @@ function useCreateContent(typeSlug) {
303
303
  },
304
304
  onSuccess: async () => {
305
305
  await queryClient.invalidateQueries({
306
- queryKey: queries.cmsContent.list._def
306
+ queryKey: queries.cmsContent.list._def,
307
+ refetchType: "all"
307
308
  });
308
309
  await queryClient.invalidateQueries({
309
- queryKey: queries.cmsTypes.list._def
310
+ queryKey: queries.cmsTypes.list._def,
311
+ refetchType: "all"
310
312
  });
311
313
  if (refresh) {
312
314
  await refresh();
@@ -344,7 +346,8 @@ function useUpdateContent(typeSlug) {
344
346
  );
345
347
  }
346
348
  await queryClient.invalidateQueries({
347
- queryKey: queries.cmsContent.list._def
349
+ queryKey: queries.cmsContent.list._def,
350
+ refetchType: "all"
348
351
  });
349
352
  if (refresh) {
350
353
  await refresh();
@@ -56,6 +56,11 @@ function createDashboardLoader(config) {
56
56
  await hooks.onLoadError(error, context);
57
57
  }
58
58
  } catch (error) {
59
+ if (client.isConnectionError(error)) {
60
+ console.warn(
61
+ "[btst/cms] route.loader() failed \u2014 no server running at build time. Use myStack.api.cms.prefetchForRoute() for SSG data prefetching."
62
+ );
63
+ }
59
64
  if (hooks?.onLoadError) {
60
65
  await hooks.onLoadError(error, context);
61
66
  }
@@ -123,6 +128,11 @@ function createContentListLoader(typeSlug, config) {
123
128
  await hooks.onLoadError(error, context);
124
129
  }
125
130
  } catch (error) {
131
+ if (client.isConnectionError(error)) {
132
+ console.warn(
133
+ "[btst/cms] route.loader() failed \u2014 no server running at build time. Use myStack.api.cms.prefetchForRoute() for SSG data prefetching."
134
+ );
135
+ }
126
136
  if (hooks?.onLoadError) {
127
137
  await hooks.onLoadError(error, context);
128
138
  }
@@ -180,6 +190,11 @@ function createContentEditorLoader(typeSlug, id, config) {
180
190
  await hooks.onLoadError(error, context);
181
191
  }
182
192
  } catch (error) {
193
+ if (client.isConnectionError(error)) {
194
+ console.warn(
195
+ "[btst/cms] route.loader() failed \u2014 no server running at build time. Use myStack.api.cms.prefetchForRoute() for SSG data prefetching."
196
+ );
197
+ }
183
198
  if (hooks?.onLoadError) {
184
199
  await hooks.onLoadError(error, context);
185
200
  }
@@ -1,6 +1,6 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { lazy } from 'react';
3
- import { defineClientPlugin, createApiClient } from '@btst/stack/plugins/client';
3
+ import { defineClientPlugin, createApiClient, 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
 
@@ -54,6 +54,11 @@ function createDashboardLoader(config) {
54
54
  await hooks.onLoadError(error, context);
55
55
  }
56
56
  } catch (error) {
57
+ if (isConnectionError(error)) {
58
+ console.warn(
59
+ "[btst/cms] route.loader() failed \u2014 no server running at build time. Use myStack.api.cms.prefetchForRoute() for SSG data prefetching."
60
+ );
61
+ }
57
62
  if (hooks?.onLoadError) {
58
63
  await hooks.onLoadError(error, context);
59
64
  }
@@ -121,6 +126,11 @@ function createContentListLoader(typeSlug, config) {
121
126
  await hooks.onLoadError(error, context);
122
127
  }
123
128
  } catch (error) {
129
+ if (isConnectionError(error)) {
130
+ console.warn(
131
+ "[btst/cms] route.loader() failed \u2014 no server running at build time. Use myStack.api.cms.prefetchForRoute() for SSG data prefetching."
132
+ );
133
+ }
124
134
  if (hooks?.onLoadError) {
125
135
  await hooks.onLoadError(error, context);
126
136
  }
@@ -178,6 +188,11 @@ function createContentEditorLoader(typeSlug, id, config) {
178
188
  await hooks.onLoadError(error, context);
179
189
  }
180
190
  } catch (error) {
191
+ if (isConnectionError(error)) {
192
+ console.warn(
193
+ "[btst/cms] route.loader() failed \u2014 no server running at build time. Use myStack.api.cms.prefetchForRoute() for SSG data prefetching."
194
+ );
195
+ }
181
196
  if (hooks?.onLoadError) {
182
197
  await hooks.onLoadError(error, context);
183
198
  }
@@ -0,0 +1,120 @@
1
+ 'use strict';
2
+
3
+ function serializeForm(form) {
4
+ return {
5
+ id: form.id,
6
+ name: form.name,
7
+ slug: form.slug,
8
+ description: form.description,
9
+ schema: form.schema,
10
+ successMessage: form.successMessage,
11
+ redirectUrl: form.redirectUrl,
12
+ status: form.status,
13
+ createdBy: form.createdBy,
14
+ createdAt: form.createdAt.toISOString(),
15
+ updatedAt: form.updatedAt.toISOString()
16
+ };
17
+ }
18
+ function serializeFormSubmission(submission) {
19
+ return {
20
+ ...submission,
21
+ submittedAt: submission.submittedAt.toISOString()
22
+ };
23
+ }
24
+ function serializeFormSubmissionWithData(submission) {
25
+ let parsedData = null;
26
+ try {
27
+ parsedData = JSON.parse(submission.data);
28
+ } catch {
29
+ }
30
+ return {
31
+ ...serializeFormSubmission(submission),
32
+ parsedData,
33
+ form: submission.form ? serializeForm(submission.form) : void 0
34
+ };
35
+ }
36
+ async function getAllForms(adapter, params) {
37
+ const whereConditions = [];
38
+ if (params?.status) {
39
+ whereConditions.push({
40
+ field: "status",
41
+ value: params.status,
42
+ operator: "eq"
43
+ });
44
+ }
45
+ const total = await adapter.count({
46
+ model: "form",
47
+ where: whereConditions.length > 0 ? whereConditions : void 0
48
+ });
49
+ const forms = await adapter.findMany({
50
+ model: "form",
51
+ where: whereConditions.length > 0 ? whereConditions : void 0,
52
+ limit: params?.limit,
53
+ offset: params?.offset,
54
+ sortBy: { field: "createdAt", direction: "desc" }
55
+ });
56
+ return {
57
+ items: forms.map(serializeForm),
58
+ total,
59
+ limit: params?.limit,
60
+ offset: params?.offset
61
+ };
62
+ }
63
+ async function getFormById(adapter, id) {
64
+ const form = await adapter.findOne({
65
+ model: "form",
66
+ where: [{ field: "id", value: id, operator: "eq" }]
67
+ });
68
+ if (!form) return null;
69
+ return serializeForm(form);
70
+ }
71
+ async function getFormBySlug(adapter, slug) {
72
+ const form = await adapter.findOne({
73
+ model: "form",
74
+ where: [{ field: "slug", value: slug, operator: "eq" }]
75
+ });
76
+ if (!form) {
77
+ return null;
78
+ }
79
+ return serializeForm(form);
80
+ }
81
+ async function getFormSubmissions(adapter, formId, params) {
82
+ const form = await adapter.findOne({
83
+ model: "form",
84
+ where: [{ field: "id", value: formId, operator: "eq" }]
85
+ });
86
+ if (!form) {
87
+ return {
88
+ items: [],
89
+ total: 0,
90
+ limit: params?.limit,
91
+ offset: params?.offset
92
+ };
93
+ }
94
+ const total = await adapter.count({
95
+ model: "formSubmission",
96
+ where: [{ field: "formId", value: formId, operator: "eq" }]
97
+ });
98
+ const submissions = await adapter.findMany({
99
+ model: "formSubmission",
100
+ where: [{ field: "formId", value: formId, operator: "eq" }],
101
+ limit: params?.limit,
102
+ offset: params?.offset,
103
+ sortBy: { field: "submittedAt", direction: "desc" },
104
+ join: { form: true }
105
+ });
106
+ return {
107
+ items: submissions.map(serializeFormSubmissionWithData),
108
+ total,
109
+ limit: params?.limit,
110
+ offset: params?.offset
111
+ };
112
+ }
113
+
114
+ exports.getAllForms = getAllForms;
115
+ exports.getFormById = getFormById;
116
+ exports.getFormBySlug = getFormBySlug;
117
+ exports.getFormSubmissions = getFormSubmissions;
118
+ exports.serializeForm = serializeForm;
119
+ exports.serializeFormSubmission = serializeFormSubmission;
120
+ exports.serializeFormSubmissionWithData = serializeFormSubmissionWithData;
@@ -0,0 +1,112 @@
1
+ function serializeForm(form) {
2
+ return {
3
+ id: form.id,
4
+ name: form.name,
5
+ slug: form.slug,
6
+ description: form.description,
7
+ schema: form.schema,
8
+ successMessage: form.successMessage,
9
+ redirectUrl: form.redirectUrl,
10
+ status: form.status,
11
+ createdBy: form.createdBy,
12
+ createdAt: form.createdAt.toISOString(),
13
+ updatedAt: form.updatedAt.toISOString()
14
+ };
15
+ }
16
+ function serializeFormSubmission(submission) {
17
+ return {
18
+ ...submission,
19
+ submittedAt: submission.submittedAt.toISOString()
20
+ };
21
+ }
22
+ function serializeFormSubmissionWithData(submission) {
23
+ let parsedData = null;
24
+ try {
25
+ parsedData = JSON.parse(submission.data);
26
+ } catch {
27
+ }
28
+ return {
29
+ ...serializeFormSubmission(submission),
30
+ parsedData,
31
+ form: submission.form ? serializeForm(submission.form) : void 0
32
+ };
33
+ }
34
+ async function getAllForms(adapter, params) {
35
+ const whereConditions = [];
36
+ if (params?.status) {
37
+ whereConditions.push({
38
+ field: "status",
39
+ value: params.status,
40
+ operator: "eq"
41
+ });
42
+ }
43
+ const total = await adapter.count({
44
+ model: "form",
45
+ where: whereConditions.length > 0 ? whereConditions : void 0
46
+ });
47
+ const forms = await adapter.findMany({
48
+ model: "form",
49
+ where: whereConditions.length > 0 ? whereConditions : void 0,
50
+ limit: params?.limit,
51
+ offset: params?.offset,
52
+ sortBy: { field: "createdAt", direction: "desc" }
53
+ });
54
+ return {
55
+ items: forms.map(serializeForm),
56
+ total,
57
+ limit: params?.limit,
58
+ offset: params?.offset
59
+ };
60
+ }
61
+ async function getFormById(adapter, id) {
62
+ const form = await adapter.findOne({
63
+ model: "form",
64
+ where: [{ field: "id", value: id, operator: "eq" }]
65
+ });
66
+ if (!form) return null;
67
+ return serializeForm(form);
68
+ }
69
+ async function getFormBySlug(adapter, slug) {
70
+ const form = await adapter.findOne({
71
+ model: "form",
72
+ where: [{ field: "slug", value: slug, operator: "eq" }]
73
+ });
74
+ if (!form) {
75
+ return null;
76
+ }
77
+ return serializeForm(form);
78
+ }
79
+ async function getFormSubmissions(adapter, formId, params) {
80
+ const form = await adapter.findOne({
81
+ model: "form",
82
+ where: [{ field: "id", value: formId, operator: "eq" }]
83
+ });
84
+ if (!form) {
85
+ return {
86
+ items: [],
87
+ total: 0,
88
+ limit: params?.limit,
89
+ offset: params?.offset
90
+ };
91
+ }
92
+ const total = await adapter.count({
93
+ model: "formSubmission",
94
+ where: [{ field: "formId", value: formId, operator: "eq" }]
95
+ });
96
+ const submissions = await adapter.findMany({
97
+ model: "formSubmission",
98
+ where: [{ field: "formId", value: formId, operator: "eq" }],
99
+ limit: params?.limit,
100
+ offset: params?.offset,
101
+ sortBy: { field: "submittedAt", direction: "desc" },
102
+ join: { form: true }
103
+ });
104
+ return {
105
+ items: submissions.map(serializeFormSubmissionWithData),
106
+ total,
107
+ limit: params?.limit,
108
+ offset: params?.offset
109
+ };
110
+ }
111
+
112
+ export { getAllForms, getFormById, getFormBySlug, getFormSubmissions, serializeForm, serializeFormSubmission, serializeFormSubmissionWithData };
@@ -6,38 +6,77 @@ const schemaConverter = require('../../../../../ui/src/lib/schema-converter.cjs'
6
6
  const db = require('../db.cjs');
7
7
  const schemas = require('../schemas.cjs');
8
8
  const utils = require('../utils.cjs');
9
+ const getters = require('./getters.cjs');
10
+ const queryKeyDefs = require('./query-key-defs.cjs');
9
11
 
10
- function serializeForm(form) {
11
- return {
12
- id: form.id,
13
- name: form.name,
14
- slug: form.slug,
15
- description: form.description,
16
- schema: form.schema,
17
- successMessage: form.successMessage,
18
- redirectUrl: form.redirectUrl,
19
- status: form.status,
20
- createdBy: form.createdBy,
21
- createdAt: form.createdAt.toISOString(),
22
- updatedAt: form.updatedAt.toISOString()
23
- };
24
- }
25
- function serializeFormSubmission(submission) {
26
- return {
27
- ...submission,
28
- submittedAt: submission.submittedAt.toISOString()
29
- };
30
- }
31
- function serializeFormSubmissionWithData(submission) {
32
- return {
33
- ...serializeFormSubmission(submission),
34
- parsedData: JSON.parse(submission.data),
35
- form: submission.form ? serializeForm(submission.form) : void 0
12
+ function createFormBuilderPrefetchForRoute(adapter) {
13
+ return async function prefetchForRoute(key, qc, params) {
14
+ switch (key) {
15
+ case "formList": {
16
+ const result = await getters.getAllForms(adapter, { limit: 20, offset: 0 });
17
+ qc.setQueryData(queryKeyDefs.FORM_QUERY_KEYS.formsList({ limit: 20, offset: 0 }), {
18
+ pages: [
19
+ {
20
+ items: result.items,
21
+ total: result.total,
22
+ limit: result.limit ?? 20,
23
+ offset: result.offset ?? 0
24
+ }
25
+ ],
26
+ pageParams: [0]
27
+ });
28
+ break;
29
+ }
30
+ case "editForm": {
31
+ const id = params?.id ?? "";
32
+ if (id) {
33
+ const form = await getters.getFormById(adapter, id);
34
+ qc.setQueryData(queryKeyDefs.FORM_QUERY_KEYS.formById(id), form);
35
+ }
36
+ break;
37
+ }
38
+ case "submissions": {
39
+ const id = params?.id ?? "";
40
+ if (id) {
41
+ const [form, submissionsResult] = await Promise.all([
42
+ getters.getFormById(adapter, id),
43
+ getters.getFormSubmissions(adapter, id, { limit: 20, offset: 0 })
44
+ ]);
45
+ qc.setQueryData(queryKeyDefs.FORM_QUERY_KEYS.formById(id), form);
46
+ qc.setQueryData(
47
+ queryKeyDefs.FORM_QUERY_KEYS.submissionsList({
48
+ formId: id,
49
+ limit: 20,
50
+ offset: 0
51
+ }),
52
+ {
53
+ pages: [
54
+ {
55
+ items: submissionsResult.items,
56
+ total: submissionsResult.total,
57
+ limit: submissionsResult.limit ?? 20,
58
+ offset: submissionsResult.offset ?? 0
59
+ }
60
+ ],
61
+ pageParams: [0]
62
+ }
63
+ );
64
+ }
65
+ break;
66
+ }
67
+ }
36
68
  };
37
69
  }
38
70
  const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
39
71
  name: "form-builder",
40
72
  dbPlugin: db.formBuilderSchema,
73
+ api: (adapter) => ({
74
+ getAllForms: (params) => getters.getAllForms(adapter, params),
75
+ getFormById: (id) => getters.getFormById(adapter, id),
76
+ getFormBySlug: (slug) => getters.getFormBySlug(adapter, slug),
77
+ getFormSubmissions: (formId, params) => getters.getFormSubmissions(adapter, formId, params),
78
+ prefetchForRoute: createFormBuilderPrefetchForRoute(adapter)
79
+ }),
41
80
  routes: (adapter) => {
42
81
  const createContext = (headers) => ({
43
82
  headers,
@@ -64,32 +103,7 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
64
103
  throw ctx.error(403, { message: "Access denied" });
65
104
  }
66
105
  }
67
- const whereConditions = [];
68
- if (status) {
69
- whereConditions.push({
70
- field: "status",
71
- value: status,
72
- operator: "eq"
73
- });
74
- }
75
- const allForms = await adapter.findMany({
76
- model: "form",
77
- where: whereConditions.length > 0 ? whereConditions : void 0
78
- });
79
- const total = allForms.length;
80
- const forms = await adapter.findMany({
81
- model: "form",
82
- where: whereConditions.length > 0 ? whereConditions : void 0,
83
- limit,
84
- offset,
85
- sortBy: { field: "createdAt", direction: "desc" }
86
- });
87
- return {
88
- items: forms.map(serializeForm),
89
- total,
90
- limit,
91
- offset
92
- };
106
+ return getters.getAllForms(adapter, { status, limit, offset });
93
107
  }
94
108
  );
95
109
  const getFormBySlug = api.createEndpoint(
@@ -107,14 +121,11 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
107
121
  throw ctx.error(403, { message: "Access denied" });
108
122
  }
109
123
  }
110
- const form = await adapter.findOne({
111
- model: "form",
112
- where: [{ field: "slug", value: slug, operator: "eq" }]
113
- });
124
+ const form = await getters.getFormBySlug(adapter, slug);
114
125
  if (!form) {
115
126
  throw ctx.error(404, { message: "Form not found" });
116
127
  }
117
- return serializeForm(form);
128
+ return form;
118
129
  }
119
130
  );
120
131
  const getFormById = api.createEndpoint(
@@ -139,7 +150,7 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
139
150
  if (!form) {
140
151
  throw ctx.error(404, { message: "Form not found" });
141
152
  }
142
- return serializeForm(form);
153
+ return getters.serializeForm(form);
143
154
  }
144
155
  );
145
156
  const createForm = api.createEndpoint(
@@ -207,7 +218,7 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
207
218
  updatedAt: /* @__PURE__ */ new Date()
208
219
  }
209
220
  });
210
- const serialized = serializeForm(form);
221
+ const serialized = getters.serializeForm(form);
211
222
  if (config.hooks?.onAfterFormCreated) {
212
223
  await config.hooks.onAfterFormCreated(serialized, context);
213
224
  }
@@ -308,7 +319,7 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
308
319
  if (!updated) {
309
320
  throw ctx.error(500, { message: "Failed to fetch updated form" });
310
321
  }
311
- const serialized = serializeForm(updated);
322
+ const serialized = getters.serializeForm(updated);
312
323
  if (config.hooks?.onAfterFormUpdated) {
313
324
  await config.hooks.onAfterFormUpdated(serialized, context);
314
325
  }
@@ -437,11 +448,11 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
437
448
  userAgent: baseContext.userAgent
438
449
  }
439
450
  });
440
- const serialized = serializeFormSubmission(submission);
451
+ const serialized = getters.serializeFormSubmission(submission);
441
452
  if (config.hooks?.onAfterSubmission) {
442
453
  await config.hooks.onAfterSubmission(
443
454
  serialized,
444
- serializeForm(form),
455
+ getters.serializeForm(form),
445
456
  submissionContext
446
457
  );
447
458
  }
@@ -481,29 +492,7 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
481
492
  throw ctx.error(403, { message: "Access denied" });
482
493
  }
483
494
  }
484
- const allSubmissions = await adapter.findMany({
485
- model: "formSubmission",
486
- where: [
487
- { field: "formId", value: formId, operator: "eq" }
488
- ]
489
- });
490
- const total = allSubmissions.length;
491
- const submissions = await adapter.findMany({
492
- model: "formSubmission",
493
- where: [
494
- { field: "formId", value: formId, operator: "eq" }
495
- ],
496
- limit,
497
- offset,
498
- sortBy: { field: "submittedAt", direction: "desc" },
499
- join: { form: true }
500
- });
501
- return {
502
- items: submissions.map(serializeFormSubmissionWithData),
503
- total,
504
- limit,
505
- offset
506
- };
495
+ return getters.getFormSubmissions(adapter, formId, { limit, offset });
507
496
  }
508
497
  );
509
498
  const getSubmission = api.createEndpoint(
@@ -532,7 +521,7 @@ const formBuilderBackendPlugin = (config = {}) => api.defineBackendPlugin({
532
521
  if (!submission || submission.formId !== formId) {
533
522
  throw ctx.error(404, { message: "Submission not found" });
534
523
  }
535
- return serializeFormSubmissionWithData(submission);
524
+ return getters.serializeFormSubmissionWithData(submission);
536
525
  }
537
526
  );
538
527
  const deleteSubmission = api.createEndpoint(