@btst/stack 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (179) 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 +9 -107
  19. package/dist/packages/stack/src/plugins/blog/api/plugin.mjs +9 -107
  20. package/dist/packages/stack/src/plugins/blog/client/plugin.cjs +1 -1
  21. package/dist/packages/stack/src/plugins/blog/client/plugin.mjs +1 -1
  22. package/dist/packages/stack/src/plugins/cms/api/getters.cjs +146 -0
  23. package/dist/packages/stack/src/plugins/cms/api/getters.mjs +138 -0
  24. package/dist/packages/stack/src/plugins/cms/api/plugin.cjs +560 -622
  25. package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +559 -621
  26. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-editor-page.internal.cjs +1 -1
  27. package/dist/packages/stack/src/plugins/cms/client/components/pages/content-editor-page.internal.mjs +1 -1
  28. package/dist/packages/stack/src/plugins/cms/client/hooks/cms-hooks.cjs +6 -3
  29. package/dist/packages/stack/src/plugins/cms/client/hooks/cms-hooks.mjs +6 -3
  30. package/dist/packages/stack/src/plugins/form-builder/api/getters.cjs +111 -0
  31. package/dist/packages/stack/src/plugins/form-builder/api/getters.mjs +104 -0
  32. package/dist/packages/stack/src/plugins/form-builder/api/plugin.cjs +16 -88
  33. package/dist/packages/stack/src/plugins/form-builder/api/plugin.mjs +12 -84
  34. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.cjs +1 -1
  35. package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.mjs +1 -1
  36. package/dist/packages/stack/src/plugins/kanban/api/getters.cjs +84 -0
  37. package/dist/packages/stack/src/plugins/kanban/api/getters.mjs +81 -0
  38. package/dist/packages/stack/src/plugins/kanban/api/plugin.cjs +9 -123
  39. package/dist/packages/stack/src/plugins/kanban/api/plugin.mjs +9 -123
  40. package/dist/packages/stack/src/plugins/kanban/client/plugin.cjs +1 -1
  41. package/dist/packages/stack/src/plugins/kanban/client/plugin.mjs +1 -1
  42. package/dist/plugins/ai-chat/api/index.cjs +3 -0
  43. package/dist/plugins/ai-chat/api/index.d.cts +27 -4
  44. package/dist/plugins/ai-chat/api/index.d.mts +27 -4
  45. package/dist/plugins/ai-chat/api/index.d.ts +27 -4
  46. package/dist/plugins/ai-chat/api/index.mjs +1 -0
  47. package/dist/plugins/ai-chat/client/hooks/index.d.cts +2 -2
  48. package/dist/plugins/ai-chat/client/hooks/index.d.mts +2 -2
  49. package/dist/plugins/ai-chat/client/hooks/index.d.ts +2 -2
  50. package/dist/plugins/ai-chat/query-keys.d.cts +9 -284
  51. package/dist/plugins/ai-chat/query-keys.d.mts +9 -284
  52. package/dist/plugins/ai-chat/query-keys.d.ts +9 -284
  53. package/dist/plugins/api/index.d.cts +4 -3
  54. package/dist/plugins/api/index.d.mts +4 -3
  55. package/dist/plugins/api/index.d.ts +4 -3
  56. package/dist/plugins/blog/api/index.cjs +4 -0
  57. package/dist/plugins/blog/api/index.d.cts +3 -2
  58. package/dist/plugins/blog/api/index.d.mts +3 -2
  59. package/dist/plugins/blog/api/index.d.ts +3 -2
  60. package/dist/plugins/blog/api/index.mjs +1 -0
  61. package/dist/plugins/blog/client/hooks/index.d.cts +4 -4
  62. package/dist/plugins/blog/client/hooks/index.d.mts +4 -4
  63. package/dist/plugins/blog/client/hooks/index.d.ts +4 -4
  64. package/dist/plugins/blog/client/index.d.cts +1 -1
  65. package/dist/plugins/blog/client/index.d.mts +1 -1
  66. package/dist/plugins/blog/client/index.d.ts +1 -1
  67. package/dist/plugins/blog/query-keys.cjs +7 -4
  68. package/dist/plugins/blog/query-keys.d.cts +81 -27
  69. package/dist/plugins/blog/query-keys.d.mts +81 -27
  70. package/dist/plugins/blog/query-keys.d.ts +81 -27
  71. package/dist/plugins/blog/query-keys.mjs +7 -4
  72. package/dist/plugins/client/index.d.cts +2 -2
  73. package/dist/plugins/client/index.d.mts +2 -2
  74. package/dist/plugins/client/index.d.ts +2 -2
  75. package/dist/plugins/cms/api/index.cjs +4 -0
  76. package/dist/plugins/cms/api/index.d.cts +61 -5
  77. package/dist/plugins/cms/api/index.d.mts +61 -5
  78. package/dist/plugins/cms/api/index.d.ts +61 -5
  79. package/dist/plugins/cms/api/index.mjs +1 -0
  80. package/dist/plugins/cms/client/hooks/index.d.cts +1 -1
  81. package/dist/plugins/cms/client/hooks/index.d.mts +1 -1
  82. package/dist/plugins/cms/client/hooks/index.d.ts +1 -1
  83. package/dist/plugins/cms/query-keys.d.cts +2 -1
  84. package/dist/plugins/cms/query-keys.d.mts +2 -1
  85. package/dist/plugins/cms/query-keys.d.ts +2 -1
  86. package/dist/plugins/form-builder/api/index.cjs +4 -0
  87. package/dist/plugins/form-builder/api/index.d.cts +77 -7
  88. package/dist/plugins/form-builder/api/index.d.mts +77 -7
  89. package/dist/plugins/form-builder/api/index.d.ts +77 -7
  90. package/dist/plugins/form-builder/api/index.mjs +1 -0
  91. package/dist/plugins/form-builder/client/components/index.d.cts +1 -1
  92. package/dist/plugins/form-builder/client/components/index.d.mts +1 -1
  93. package/dist/plugins/form-builder/client/components/index.d.ts +1 -1
  94. package/dist/plugins/form-builder/client/hooks/index.d.cts +1 -1
  95. package/dist/plugins/form-builder/client/hooks/index.d.mts +1 -1
  96. package/dist/plugins/form-builder/client/hooks/index.d.ts +1 -1
  97. package/dist/plugins/form-builder/query-keys.d.cts +2 -1
  98. package/dist/plugins/form-builder/query-keys.d.mts +2 -1
  99. package/dist/plugins/form-builder/query-keys.d.ts +2 -1
  100. package/dist/plugins/kanban/api/index.cjs +3 -0
  101. package/dist/plugins/kanban/api/index.d.cts +40 -43
  102. package/dist/plugins/kanban/api/index.d.mts +40 -43
  103. package/dist/plugins/kanban/api/index.d.ts +40 -43
  104. package/dist/plugins/kanban/api/index.mjs +1 -0
  105. package/dist/plugins/kanban/client/components/index.d.cts +1 -1
  106. package/dist/plugins/kanban/client/components/index.d.mts +1 -1
  107. package/dist/plugins/kanban/client/components/index.d.ts +1 -1
  108. package/dist/plugins/kanban/client/hooks/index.d.cts +1 -1
  109. package/dist/plugins/kanban/client/hooks/index.d.mts +1 -1
  110. package/dist/plugins/kanban/client/hooks/index.d.ts +1 -1
  111. package/dist/plugins/kanban/client/index.d.cts +1 -1
  112. package/dist/plugins/kanban/client/index.d.mts +1 -1
  113. package/dist/plugins/kanban/client/index.d.ts +1 -1
  114. package/dist/plugins/kanban/query-keys.cjs +4 -3
  115. package/dist/plugins/kanban/query-keys.d.cts +2 -1
  116. package/dist/plugins/kanban/query-keys.d.mts +2 -1
  117. package/dist/plugins/kanban/query-keys.d.ts +2 -1
  118. package/dist/plugins/kanban/query-keys.mjs +4 -3
  119. package/dist/plugins/open-api/api/index.d.cts +2 -2
  120. package/dist/plugins/open-api/api/index.d.mts +2 -2
  121. package/dist/plugins/open-api/api/index.d.ts +2 -2
  122. package/dist/plugins/route-docs/client/index.d.cts +1 -1
  123. package/dist/plugins/route-docs/client/index.d.mts +1 -1
  124. package/dist/plugins/route-docs/client/index.d.ts +1 -1
  125. package/dist/plugins/ui-builder/index.d.cts +1 -1
  126. package/dist/plugins/ui-builder/index.d.mts +1 -1
  127. package/dist/plugins/ui-builder/index.d.ts +1 -1
  128. package/dist/shared/{stack.BoA0xkJv.d.cts → stack.7n9Y_u7N.d.cts} +33 -7
  129. package/dist/shared/{stack.BoA0xkJv.d.mts → stack.7n9Y_u7N.d.mts} +33 -7
  130. package/dist/shared/{stack.BoA0xkJv.d.ts → stack.7n9Y_u7N.d.ts} +33 -7
  131. package/dist/shared/stack.BeSm90va.d.ts +289 -0
  132. package/dist/shared/{stack.DzH_wcvr.d.mts → stack.CIrIsc-A.d.cts} +2 -2
  133. package/dist/shared/{stack.DzH_wcvr.d.ts → stack.CIrIsc-A.d.mts} +2 -2
  134. package/dist/shared/{stack.DzH_wcvr.d.cts → stack.CIrIsc-A.d.ts} +2 -2
  135. package/dist/shared/stack.CMh_EdxW.d.cts +289 -0
  136. package/dist/shared/{stack.BsXokfNh.d.mts → stack.CXjzTMsb.d.cts} +1 -1
  137. package/dist/shared/{stack.BsXokfNh.d.ts → stack.CXjzTMsb.d.mts} +1 -1
  138. package/dist/shared/{stack.BsXokfNh.d.cts → stack.CXjzTMsb.d.ts} +1 -1
  139. package/dist/shared/stack.Dg09R0oB.d.mts +289 -0
  140. package/dist/shared/{stack.DKDMI-QO.d.mts → stack.QD1y_7NY.d.cts} +7 -1
  141. package/dist/shared/{stack.DKDMI-QO.d.ts → stack.QD1y_7NY.d.mts} +7 -1
  142. package/dist/shared/{stack.DKDMI-QO.d.cts → stack.QD1y_7NY.d.ts} +7 -1
  143. package/package.json +1 -1
  144. package/src/__tests__/stack-api.test.ts +118 -0
  145. package/src/api/index.ts +15 -1
  146. package/src/plugins/ai-chat/__tests__/getters.test.ts +109 -0
  147. package/src/plugins/ai-chat/api/getters.ts +71 -0
  148. package/src/plugins/ai-chat/api/index.ts +1 -0
  149. package/src/plugins/ai-chat/api/plugin.ts +8 -0
  150. package/src/plugins/api/index.ts +3 -1
  151. package/src/plugins/blog/__tests__/getters.test.ts +540 -0
  152. package/src/plugins/blog/api/getters.ts +243 -0
  153. package/src/plugins/blog/api/index.ts +7 -0
  154. package/src/plugins/blog/api/plugin.ts +13 -141
  155. package/src/plugins/blog/client/plugin.tsx +2 -1
  156. package/src/plugins/blog/query-keys.ts +16 -13
  157. package/src/plugins/cms/__tests__/getters.test.ts +206 -0
  158. package/src/plugins/cms/api/getters.ts +244 -0
  159. package/src/plugins/cms/api/index.ts +5 -0
  160. package/src/plugins/cms/api/plugin.ts +50 -154
  161. package/src/plugins/cms/client/components/pages/content-editor-page.internal.tsx +1 -1
  162. package/src/plugins/cms/client/hooks/cms-hooks.tsx +3 -0
  163. package/src/plugins/cms/types.ts +1 -1
  164. package/src/plugins/form-builder/__tests__/getters.test.ts +159 -0
  165. package/src/plugins/form-builder/api/getters.ts +203 -0
  166. package/src/plugins/form-builder/api/index.ts +1 -0
  167. package/src/plugins/form-builder/api/plugin.ts +22 -115
  168. package/src/plugins/form-builder/client/components/pages/submissions-page.internal.tsx +1 -1
  169. package/src/plugins/form-builder/types.ts +2 -2
  170. package/src/plugins/kanban/__tests__/getters.test.ts +172 -0
  171. package/src/plugins/kanban/api/getters.ts +149 -0
  172. package/src/plugins/kanban/api/index.ts +1 -0
  173. package/src/plugins/kanban/api/plugin.ts +16 -146
  174. package/src/plugins/kanban/client/plugin.tsx +2 -1
  175. package/src/plugins/kanban/query-keys.ts +8 -5
  176. package/src/types.ts +44 -5
  177. package/dist/shared/{stack.CbuN2zVV.d.cts → stack.BkYlUT_8.d.cts} +6 -6
  178. package/dist/shared/{stack.CbuN2zVV.d.mts → stack.BkYlUT_8.d.mts} +6 -6
  179. package/dist/shared/{stack.CbuN2zVV.d.ts → stack.BkYlUT_8.d.ts} +6 -6
@@ -0,0 +1,84 @@
1
+ 'use strict';
2
+
3
+ async function hydrateColumnsWithTasks(adapter, board) {
4
+ const columnIds = (board.column || []).map((c) => c.id);
5
+ const tasksByColumn = /* @__PURE__ */ new Map();
6
+ if (columnIds.length > 0) {
7
+ const taskResults = await Promise.all(
8
+ columnIds.map(
9
+ (columnId) => adapter.findMany({
10
+ model: "kanbanTask",
11
+ where: [
12
+ { field: "columnId", value: columnId, operator: "eq" }
13
+ ],
14
+ sortBy: { field: "order", direction: "asc" }
15
+ })
16
+ )
17
+ );
18
+ for (let i = 0; i < columnIds.length; i++) {
19
+ const columnId = columnIds[i];
20
+ const tasks = taskResults[i];
21
+ if (columnId && tasks) {
22
+ tasksByColumn.set(columnId, tasks);
23
+ }
24
+ }
25
+ }
26
+ const columns = (board.column || []).sort((a, b) => a.order - b.order).map((col) => ({ ...col, tasks: tasksByColumn.get(col.id) || [] }));
27
+ const { column: _, ...boardWithoutJoin } = board;
28
+ return { ...boardWithoutJoin, columns };
29
+ }
30
+ async function getAllBoards(adapter, params) {
31
+ const query = params ?? {};
32
+ const whereConditions = [];
33
+ if (query.slug) {
34
+ whereConditions.push({
35
+ field: "slug",
36
+ value: query.slug,
37
+ operator: "eq"
38
+ });
39
+ }
40
+ if (query.ownerId) {
41
+ whereConditions.push({
42
+ field: "ownerId",
43
+ value: query.ownerId,
44
+ operator: "eq"
45
+ });
46
+ }
47
+ if (query.organizationId) {
48
+ whereConditions.push({
49
+ field: "organizationId",
50
+ value: query.organizationId,
51
+ operator: "eq"
52
+ });
53
+ }
54
+ const where = whereConditions.length > 0 ? whereConditions : void 0;
55
+ const [boards, total] = await Promise.all([
56
+ adapter.findMany({
57
+ model: "kanbanBoard",
58
+ limit: query.limit ?? 50,
59
+ offset: query.offset ?? 0,
60
+ where,
61
+ sortBy: { field: "createdAt", direction: "desc" },
62
+ join: { kanbanColumn: true }
63
+ }),
64
+ adapter.count({ model: "kanbanBoard", where })
65
+ ]);
66
+ const items = await Promise.all(
67
+ boards.map((board) => hydrateColumnsWithTasks(adapter, board))
68
+ );
69
+ return { items, total, limit: query.limit, offset: query.offset };
70
+ }
71
+ async function getBoardById(adapter, id) {
72
+ const board = await adapter.findOne({
73
+ model: "kanbanBoard",
74
+ where: [{ field: "id", value: id, operator: "eq" }],
75
+ join: { kanbanColumn: true }
76
+ });
77
+ if (!board) {
78
+ return null;
79
+ }
80
+ return hydrateColumnsWithTasks(adapter, board);
81
+ }
82
+
83
+ exports.getAllBoards = getAllBoards;
84
+ exports.getBoardById = getBoardById;
@@ -0,0 +1,81 @@
1
+ async function hydrateColumnsWithTasks(adapter, board) {
2
+ const columnIds = (board.column || []).map((c) => c.id);
3
+ const tasksByColumn = /* @__PURE__ */ new Map();
4
+ if (columnIds.length > 0) {
5
+ const taskResults = await Promise.all(
6
+ columnIds.map(
7
+ (columnId) => adapter.findMany({
8
+ model: "kanbanTask",
9
+ where: [
10
+ { field: "columnId", value: columnId, operator: "eq" }
11
+ ],
12
+ sortBy: { field: "order", direction: "asc" }
13
+ })
14
+ )
15
+ );
16
+ for (let i = 0; i < columnIds.length; i++) {
17
+ const columnId = columnIds[i];
18
+ const tasks = taskResults[i];
19
+ if (columnId && tasks) {
20
+ tasksByColumn.set(columnId, tasks);
21
+ }
22
+ }
23
+ }
24
+ const columns = (board.column || []).sort((a, b) => a.order - b.order).map((col) => ({ ...col, tasks: tasksByColumn.get(col.id) || [] }));
25
+ const { column: _, ...boardWithoutJoin } = board;
26
+ return { ...boardWithoutJoin, columns };
27
+ }
28
+ async function getAllBoards(adapter, params) {
29
+ const query = params ?? {};
30
+ const whereConditions = [];
31
+ if (query.slug) {
32
+ whereConditions.push({
33
+ field: "slug",
34
+ value: query.slug,
35
+ operator: "eq"
36
+ });
37
+ }
38
+ if (query.ownerId) {
39
+ whereConditions.push({
40
+ field: "ownerId",
41
+ value: query.ownerId,
42
+ operator: "eq"
43
+ });
44
+ }
45
+ if (query.organizationId) {
46
+ whereConditions.push({
47
+ field: "organizationId",
48
+ value: query.organizationId,
49
+ operator: "eq"
50
+ });
51
+ }
52
+ const where = whereConditions.length > 0 ? whereConditions : void 0;
53
+ const [boards, total] = await Promise.all([
54
+ adapter.findMany({
55
+ model: "kanbanBoard",
56
+ limit: query.limit ?? 50,
57
+ offset: query.offset ?? 0,
58
+ where,
59
+ sortBy: { field: "createdAt", direction: "desc" },
60
+ join: { kanbanColumn: true }
61
+ }),
62
+ adapter.count({ model: "kanbanBoard", where })
63
+ ]);
64
+ const items = await Promise.all(
65
+ boards.map((board) => hydrateColumnsWithTasks(adapter, board))
66
+ );
67
+ return { items, total, limit: query.limit, offset: query.offset };
68
+ }
69
+ async function getBoardById(adapter, id) {
70
+ const board = await adapter.findOne({
71
+ model: "kanbanBoard",
72
+ where: [{ field: "id", value: id, operator: "eq" }],
73
+ join: { kanbanColumn: true }
74
+ });
75
+ if (!board) {
76
+ return null;
77
+ }
78
+ return hydrateColumnsWithTasks(adapter, board);
79
+ }
80
+
81
+ export { getAllBoards, getBoardById };
@@ -4,10 +4,15 @@ const api = require('@btst/stack/plugins/api');
4
4
  const db = require('../db.cjs');
5
5
  const utils = require('../utils.cjs');
6
6
  const schemas = require('../schemas.cjs');
7
+ const getters = require('./getters.cjs');
7
8
 
8
9
  const kanbanBackendPlugin = (hooks) => api.defineBackendPlugin({
9
10
  name: "kanban",
10
11
  dbPlugin: db.kanbanSchema,
12
+ api: (adapter) => ({
13
+ getAllBoards: (params) => getters.getAllBoards(adapter, params),
14
+ getBoardById: (id) => getters.getBoardById(adapter, id)
15
+ }),
11
16
  routes: (adapter) => {
12
17
  const listBoards = api.createEndpoint(
13
18
  "/boards",
@@ -27,86 +32,9 @@ const kanbanBackendPlugin = (hooks) => api.defineBackendPlugin({
27
32
  });
28
33
  }
29
34
  }
30
- const whereConditions = [];
31
- if (query.slug) {
32
- whereConditions.push({
33
- field: "slug",
34
- value: query.slug,
35
- operator: "eq"
36
- });
37
- }
38
- if (query.ownerId) {
39
- whereConditions.push({
40
- field: "ownerId",
41
- value: query.ownerId,
42
- operator: "eq"
43
- });
44
- }
45
- if (query.organizationId) {
46
- whereConditions.push({
47
- field: "organizationId",
48
- value: query.organizationId,
49
- operator: "eq"
50
- });
51
- }
52
- const boards = await adapter.findMany({
53
- model: "kanbanBoard",
54
- limit: query.limit ?? 50,
55
- offset: query.offset ?? 0,
56
- where: whereConditions,
57
- sortBy: {
58
- field: "createdAt",
59
- direction: "desc"
60
- },
61
- join: {
62
- kanbanColumn: true
63
- }
64
- });
65
- const columnIds = [];
66
- for (const board of boards) {
67
- if (board.column) {
68
- for (const col of board.column) {
69
- columnIds.push(col.id);
70
- }
71
- }
72
- }
73
- const tasksByColumn = /* @__PURE__ */ new Map();
74
- if (columnIds.length > 0) {
75
- const taskQueries = columnIds.map(
76
- (columnId) => adapter.findMany({
77
- model: "kanbanTask",
78
- where: [
79
- {
80
- field: "columnId",
81
- value: columnId,
82
- operator: "eq"
83
- }
84
- ],
85
- sortBy: { field: "order", direction: "asc" }
86
- })
87
- );
88
- const taskResults = await Promise.all(taskQueries);
89
- for (let i = 0; i < columnIds.length; i++) {
90
- const columnId = columnIds[i];
91
- const tasks = taskResults[i];
92
- if (columnId && tasks) {
93
- tasksByColumn.set(columnId, tasks);
94
- }
95
- }
96
- }
97
- const result = boards.map((board) => {
98
- const columns = (board.column || []).sort((a, b) => a.order - b.order).map((col) => ({
99
- ...col,
100
- tasks: tasksByColumn.get(col.id) || []
101
- }));
102
- const { column: _, ...boardWithoutJoin } = board;
103
- return {
104
- ...boardWithoutJoin,
105
- columns
106
- };
107
- });
35
+ const result = await getters.getAllBoards(adapter, query);
108
36
  if (hooks?.onBoardsRead) {
109
- await hooks.onBoardsRead(result, query, context);
37
+ await hooks.onBoardsRead(result.items, query, context);
110
38
  }
111
39
  return result;
112
40
  } catch (error) {
@@ -134,52 +62,10 @@ const kanbanBackendPlugin = (hooks) => api.defineBackendPlugin({
134
62
  });
135
63
  }
136
64
  }
137
- const board = await adapter.findOne({
138
- model: "kanbanBoard",
139
- where: [
140
- { field: "id", value: params.id, operator: "eq" }
141
- ],
142
- join: {
143
- kanbanColumn: true
144
- }
145
- });
146
- if (!board) {
65
+ const result = await getters.getBoardById(adapter, params.id);
66
+ if (!result) {
147
67
  throw ctx.error(404, { message: "Board not found" });
148
68
  }
149
- const columnIds = (board.column || []).map((c) => c.id);
150
- const tasksByColumn = /* @__PURE__ */ new Map();
151
- if (columnIds.length > 0) {
152
- const taskQueries = columnIds.map(
153
- (columnId) => adapter.findMany({
154
- model: "kanbanTask",
155
- where: [
156
- {
157
- field: "columnId",
158
- value: columnId,
159
- operator: "eq"
160
- }
161
- ],
162
- sortBy: { field: "order", direction: "asc" }
163
- })
164
- );
165
- const taskResults = await Promise.all(taskQueries);
166
- for (let i = 0; i < columnIds.length; i++) {
167
- const columnId = columnIds[i];
168
- const tasks = taskResults[i];
169
- if (columnId && tasks) {
170
- tasksByColumn.set(columnId, tasks);
171
- }
172
- }
173
- }
174
- const columns = (board.column || []).sort((a, b) => a.order - b.order).map((col) => ({
175
- ...col,
176
- tasks: tasksByColumn.get(col.id) || []
177
- }));
178
- const { column: _, ...boardWithoutJoin } = board;
179
- const result = {
180
- ...boardWithoutJoin,
181
- columns
182
- };
183
69
  if (hooks?.onBoardRead) {
184
70
  await hooks.onBoardRead(result, context);
185
71
  }
@@ -2,10 +2,15 @@ import { defineBackendPlugin, createEndpoint } from '@btst/stack/plugins/api';
2
2
  import { kanbanSchema } from '../db.mjs';
3
3
  import { slugify } from '../utils.mjs';
4
4
  import { BoardListQuerySchema, createBoardSchema, updateBoardSchema, createColumnSchema, updateColumnSchema, reorderColumnsSchema, createTaskSchema, updateTaskSchema, moveTaskSchema, reorderTasksSchema } from '../schemas.mjs';
5
+ import { getBoardById, getAllBoards } from './getters.mjs';
5
6
 
6
7
  const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
7
8
  name: "kanban",
8
9
  dbPlugin: kanbanSchema,
10
+ api: (adapter) => ({
11
+ getAllBoards: (params) => getAllBoards(adapter, params),
12
+ getBoardById: (id) => getBoardById(adapter, id)
13
+ }),
9
14
  routes: (adapter) => {
10
15
  const listBoards = createEndpoint(
11
16
  "/boards",
@@ -25,86 +30,9 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
25
30
  });
26
31
  }
27
32
  }
28
- const whereConditions = [];
29
- if (query.slug) {
30
- whereConditions.push({
31
- field: "slug",
32
- value: query.slug,
33
- operator: "eq"
34
- });
35
- }
36
- if (query.ownerId) {
37
- whereConditions.push({
38
- field: "ownerId",
39
- value: query.ownerId,
40
- operator: "eq"
41
- });
42
- }
43
- if (query.organizationId) {
44
- whereConditions.push({
45
- field: "organizationId",
46
- value: query.organizationId,
47
- operator: "eq"
48
- });
49
- }
50
- const boards = await adapter.findMany({
51
- model: "kanbanBoard",
52
- limit: query.limit ?? 50,
53
- offset: query.offset ?? 0,
54
- where: whereConditions,
55
- sortBy: {
56
- field: "createdAt",
57
- direction: "desc"
58
- },
59
- join: {
60
- kanbanColumn: true
61
- }
62
- });
63
- const columnIds = [];
64
- for (const board of boards) {
65
- if (board.column) {
66
- for (const col of board.column) {
67
- columnIds.push(col.id);
68
- }
69
- }
70
- }
71
- const tasksByColumn = /* @__PURE__ */ new Map();
72
- if (columnIds.length > 0) {
73
- const taskQueries = columnIds.map(
74
- (columnId) => adapter.findMany({
75
- model: "kanbanTask",
76
- where: [
77
- {
78
- field: "columnId",
79
- value: columnId,
80
- operator: "eq"
81
- }
82
- ],
83
- sortBy: { field: "order", direction: "asc" }
84
- })
85
- );
86
- const taskResults = await Promise.all(taskQueries);
87
- for (let i = 0; i < columnIds.length; i++) {
88
- const columnId = columnIds[i];
89
- const tasks = taskResults[i];
90
- if (columnId && tasks) {
91
- tasksByColumn.set(columnId, tasks);
92
- }
93
- }
94
- }
95
- const result = boards.map((board) => {
96
- const columns = (board.column || []).sort((a, b) => a.order - b.order).map((col) => ({
97
- ...col,
98
- tasks: tasksByColumn.get(col.id) || []
99
- }));
100
- const { column: _, ...boardWithoutJoin } = board;
101
- return {
102
- ...boardWithoutJoin,
103
- columns
104
- };
105
- });
33
+ const result = await getAllBoards(adapter, query);
106
34
  if (hooks?.onBoardsRead) {
107
- await hooks.onBoardsRead(result, query, context);
35
+ await hooks.onBoardsRead(result.items, query, context);
108
36
  }
109
37
  return result;
110
38
  } catch (error) {
@@ -132,52 +60,10 @@ const kanbanBackendPlugin = (hooks) => defineBackendPlugin({
132
60
  });
133
61
  }
134
62
  }
135
- const board = await adapter.findOne({
136
- model: "kanbanBoard",
137
- where: [
138
- { field: "id", value: params.id, operator: "eq" }
139
- ],
140
- join: {
141
- kanbanColumn: true
142
- }
143
- });
144
- if (!board) {
63
+ const result = await getBoardById(adapter, params.id);
64
+ if (!result) {
145
65
  throw ctx.error(404, { message: "Board not found" });
146
66
  }
147
- const columnIds = (board.column || []).map((c) => c.id);
148
- const tasksByColumn = /* @__PURE__ */ new Map();
149
- if (columnIds.length > 0) {
150
- const taskQueries = columnIds.map(
151
- (columnId) => adapter.findMany({
152
- model: "kanbanTask",
153
- where: [
154
- {
155
- field: "columnId",
156
- value: columnId,
157
- operator: "eq"
158
- }
159
- ],
160
- sortBy: { field: "order", direction: "asc" }
161
- })
162
- );
163
- const taskResults = await Promise.all(taskQueries);
164
- for (let i = 0; i < columnIds.length; i++) {
165
- const columnId = columnIds[i];
166
- const tasks = taskResults[i];
167
- if (columnId && tasks) {
168
- tasksByColumn.set(columnId, tasks);
169
- }
170
- }
171
- }
172
- const columns = (board.column || []).sort((a, b) => a.order - b.order).map((col) => ({
173
- ...col,
174
- tasks: tasksByColumn.get(col.id) || []
175
- }));
176
- const { column: _, ...boardWithoutJoin } = board;
177
- const result = {
178
- ...boardWithoutJoin,
179
- columns
180
- };
181
67
  if (hooks?.onBoardRead) {
182
68
  await hooks.onBoardRead(result, context);
183
69
  }
@@ -266,7 +266,7 @@ const kanbanClientPlugin = (config) => client.defineClientPlugin({
266
266
  method: "GET",
267
267
  query: { limit: 100 }
268
268
  });
269
- boards = res.data ?? [];
269
+ boards = res.data?.items ?? [];
270
270
  } catch {
271
271
  }
272
272
  const entries = [
@@ -264,7 +264,7 @@ const kanbanClientPlugin = (config) => defineClientPlugin({
264
264
  method: "GET",
265
265
  query: { limit: 100 }
266
266
  });
267
- boards = res.data ?? [];
267
+ boards = res.data?.items ?? [];
268
268
  } catch {
269
269
  }
270
270
  const entries = [
@@ -1,9 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  const plugin = require('../../../packages/stack/src/plugins/ai-chat/api/plugin.cjs');
4
+ const getters = require('../../../packages/stack/src/plugins/ai-chat/api/getters.cjs');
4
5
  const plugins_aiChat_queryKeys = require('../query-keys.cjs');
5
6
 
6
7
 
7
8
 
8
9
  exports.aiChatBackendPlugin = plugin.aiChatBackendPlugin;
10
+ exports.getAllConversations = getters.getAllConversations;
11
+ exports.getConversationById = getters.getConversationById;
9
12
  exports.createAiChatQueryKeys = plugins_aiChat_queryKeys.createAiChatQueryKeys;
@@ -1,9 +1,32 @@
1
- export { d as AiChatApiRouter, b as AiChatBackendConfig, A as AiChatBackendHooks, a as AiChatMode, C as ChatApiContext, c as aiChatBackendPlugin, createAiChatQueryKeys } from '../query-keys.cjs';
1
+ export { e as AiChatApiRouter, b as AiChatBackendConfig, A as AiChatBackendHooks, a as AiChatMode, C as ChatApiContext, d as aiChatBackendPlugin, c as createAiChatQueryKeys } from '../../../shared/stack.CMh_EdxW.cjs';
2
+ import { Adapter } from '@btst/db';
3
+ import { C as Conversation, M as Message } from '../../../shared/stack.Be1QIHEn.cjs';
4
+ import '@tanstack/react-query';
5
+ import '@btst/stack/plugins/client';
2
6
  import '@btst/stack/plugins/api';
3
7
  import 'better-call';
4
8
  import 'zod/v4/core';
5
9
  import 'zod';
6
10
  import 'ai';
7
- import '../../../shared/stack.Be1QIHEn.cjs';
8
- import '@tanstack/react-query';
9
- import '@btst/stack/plugins/client';
11
+
12
+ /**
13
+ * Retrieve all conversations, optionally filtered by userId.
14
+ * Pure DB function - no hooks, no HTTP context. Safe for server-side use.
15
+ *
16
+ * @param adapter - The database adapter
17
+ * @param userId - Optional user ID to filter conversations by owner
18
+ */
19
+ declare function getAllConversations(adapter: Adapter, userId?: string): Promise<Conversation[]>;
20
+ /**
21
+ * Retrieve a single conversation by its ID, including all messages.
22
+ * Returns null if the conversation is not found.
23
+ * Pure DB function - no hooks, no HTTP context. Safe for server-side use.
24
+ *
25
+ * @param adapter - The database adapter
26
+ * @param id - The conversation ID
27
+ */
28
+ declare function getConversationById(adapter: Adapter, id: string): Promise<(Conversation & {
29
+ messages: Message[];
30
+ }) | null>;
31
+
32
+ export { getAllConversations, getConversationById };
@@ -1,9 +1,32 @@
1
- export { d as AiChatApiRouter, b as AiChatBackendConfig, A as AiChatBackendHooks, a as AiChatMode, C as ChatApiContext, c as aiChatBackendPlugin, createAiChatQueryKeys } from '../query-keys.mjs';
1
+ export { e as AiChatApiRouter, b as AiChatBackendConfig, A as AiChatBackendHooks, a as AiChatMode, C as ChatApiContext, d as aiChatBackendPlugin, c as createAiChatQueryKeys } from '../../../shared/stack.Dg09R0oB.mjs';
2
+ import { Adapter } from '@btst/db';
3
+ import { C as Conversation, M as Message } from '../../../shared/stack.Be1QIHEn.mjs';
4
+ import '@tanstack/react-query';
5
+ import '@btst/stack/plugins/client';
2
6
  import '@btst/stack/plugins/api';
3
7
  import 'better-call';
4
8
  import 'zod/v4/core';
5
9
  import 'zod';
6
10
  import 'ai';
7
- import '../../../shared/stack.Be1QIHEn.mjs';
8
- import '@tanstack/react-query';
9
- import '@btst/stack/plugins/client';
11
+
12
+ /**
13
+ * Retrieve all conversations, optionally filtered by userId.
14
+ * Pure DB function - no hooks, no HTTP context. Safe for server-side use.
15
+ *
16
+ * @param adapter - The database adapter
17
+ * @param userId - Optional user ID to filter conversations by owner
18
+ */
19
+ declare function getAllConversations(adapter: Adapter, userId?: string): Promise<Conversation[]>;
20
+ /**
21
+ * Retrieve a single conversation by its ID, including all messages.
22
+ * Returns null if the conversation is not found.
23
+ * Pure DB function - no hooks, no HTTP context. Safe for server-side use.
24
+ *
25
+ * @param adapter - The database adapter
26
+ * @param id - The conversation ID
27
+ */
28
+ declare function getConversationById(adapter: Adapter, id: string): Promise<(Conversation & {
29
+ messages: Message[];
30
+ }) | null>;
31
+
32
+ export { getAllConversations, getConversationById };
@@ -1,9 +1,32 @@
1
- export { d as AiChatApiRouter, b as AiChatBackendConfig, A as AiChatBackendHooks, a as AiChatMode, C as ChatApiContext, c as aiChatBackendPlugin, createAiChatQueryKeys } from '../query-keys.js';
1
+ export { e as AiChatApiRouter, b as AiChatBackendConfig, A as AiChatBackendHooks, a as AiChatMode, C as ChatApiContext, d as aiChatBackendPlugin, c as createAiChatQueryKeys } from '../../../shared/stack.BeSm90va.js';
2
+ import { Adapter } from '@btst/db';
3
+ import { C as Conversation, M as Message } from '../../../shared/stack.Be1QIHEn.js';
4
+ import '@tanstack/react-query';
5
+ import '@btst/stack/plugins/client';
2
6
  import '@btst/stack/plugins/api';
3
7
  import 'better-call';
4
8
  import 'zod/v4/core';
5
9
  import 'zod';
6
10
  import 'ai';
7
- import '../../../shared/stack.Be1QIHEn.js';
8
- import '@tanstack/react-query';
9
- import '@btst/stack/plugins/client';
11
+
12
+ /**
13
+ * Retrieve all conversations, optionally filtered by userId.
14
+ * Pure DB function - no hooks, no HTTP context. Safe for server-side use.
15
+ *
16
+ * @param adapter - The database adapter
17
+ * @param userId - Optional user ID to filter conversations by owner
18
+ */
19
+ declare function getAllConversations(adapter: Adapter, userId?: string): Promise<Conversation[]>;
20
+ /**
21
+ * Retrieve a single conversation by its ID, including all messages.
22
+ * Returns null if the conversation is not found.
23
+ * Pure DB function - no hooks, no HTTP context. Safe for server-side use.
24
+ *
25
+ * @param adapter - The database adapter
26
+ * @param id - The conversation ID
27
+ */
28
+ declare function getConversationById(adapter: Adapter, id: string): Promise<(Conversation & {
29
+ messages: Message[];
30
+ }) | null>;
31
+
32
+ export { getAllConversations, getConversationById };
@@ -1,2 +1,3 @@
1
1
  export { aiChatBackendPlugin } from '../../../packages/stack/src/plugins/ai-chat/api/plugin.mjs';
2
+ export { getAllConversations, getConversationById } from '../../../packages/stack/src/plugins/ai-chat/api/getters.mjs';
2
3
  export { createAiChatQueryKeys } from '../query-keys.mjs';
@@ -1,13 +1,13 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { ConversationWithMessages } from '../../query-keys.cjs';
2
+ import { f as ConversationWithMessages } from '../../../../shared/stack.CMh_EdxW.cjs';
3
3
  import { S as SerializedConversation } from '../../../../shared/stack.Be1QIHEn.cjs';
4
4
  export { a as SerializedMessage } from '../../../../shared/stack.Be1QIHEn.cjs';
5
+ import '@btst/stack/plugins/client';
5
6
  import '@btst/stack/plugins/api';
6
7
  import 'better-call';
7
8
  import 'zod/v4/core';
8
9
  import 'zod';
9
10
  import 'ai';
10
- import '@btst/stack/plugins/client';
11
11
 
12
12
  /**
13
13
  * Options for the useConversations hook
@@ -1,13 +1,13 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { ConversationWithMessages } from '../../query-keys.mjs';
2
+ import { f as ConversationWithMessages } from '../../../../shared/stack.Dg09R0oB.mjs';
3
3
  import { S as SerializedConversation } from '../../../../shared/stack.Be1QIHEn.mjs';
4
4
  export { a as SerializedMessage } from '../../../../shared/stack.Be1QIHEn.mjs';
5
+ import '@btst/stack/plugins/client';
5
6
  import '@btst/stack/plugins/api';
6
7
  import 'better-call';
7
8
  import 'zod/v4/core';
8
9
  import 'zod';
9
10
  import 'ai';
10
- import '@btst/stack/plugins/client';
11
11
 
12
12
  /**
13
13
  * Options for the useConversations hook