@btst/stack 2.7.0 → 2.8.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 (181) hide show
  1. package/README.md +1 -0
  2. package/dist/packages/stack/src/plugins/blog/client/components/loading/post-navigation-skeleton.cjs +13 -0
  3. package/dist/packages/stack/src/plugins/blog/client/components/loading/post-navigation-skeleton.mjs +11 -0
  4. package/dist/packages/stack/src/plugins/blog/client/components/loading/recent-posts-carousel-skeleton.cjs +17 -0
  5. package/dist/packages/stack/src/plugins/blog/client/components/loading/recent-posts-carousel-skeleton.mjs +15 -0
  6. package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.internal.cjs +18 -7
  7. package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.internal.mjs +18 -7
  8. package/dist/packages/stack/src/plugins/blog/client/components/shared/post-navigation.cjs +48 -52
  9. package/dist/packages/stack/src/plugins/blog/client/components/shared/post-navigation.mjs +49 -53
  10. package/dist/packages/stack/src/plugins/blog/client/components/shared/recent-posts-carousel.cjs +34 -37
  11. package/dist/packages/stack/src/plugins/blog/client/components/shared/recent-posts-carousel.mjs +35 -38
  12. package/dist/packages/stack/src/plugins/blog/client/hooks/blog-hooks.cjs +4 -21
  13. package/dist/packages/stack/src/plugins/blog/client/hooks/blog-hooks.mjs +4 -21
  14. package/dist/packages/stack/src/plugins/comments/api/getters.cjs +284 -0
  15. package/dist/packages/stack/src/plugins/comments/api/getters.mjs +280 -0
  16. package/dist/packages/stack/src/plugins/comments/api/mutations.cjs +118 -0
  17. package/dist/packages/stack/src/plugins/comments/api/mutations.mjs +112 -0
  18. package/dist/packages/stack/src/plugins/comments/api/plugin.cjs +335 -0
  19. package/dist/packages/stack/src/plugins/comments/api/plugin.mjs +333 -0
  20. package/dist/packages/stack/src/plugins/comments/api/query-key-defs.cjs +60 -0
  21. package/dist/packages/stack/src/plugins/comments/api/query-key-defs.mjs +55 -0
  22. package/dist/packages/stack/src/plugins/comments/api/serializers.cjs +23 -0
  23. package/dist/packages/stack/src/plugins/comments/api/serializers.mjs +21 -0
  24. package/dist/packages/stack/src/plugins/comments/client/components/comment-count.cjs +46 -0
  25. package/dist/packages/stack/src/plugins/comments/client/components/comment-count.mjs +44 -0
  26. package/dist/packages/stack/src/plugins/comments/client/components/comment-form.cjs +86 -0
  27. package/dist/packages/stack/src/plugins/comments/client/components/comment-form.mjs +84 -0
  28. package/dist/packages/stack/src/plugins/comments/client/components/comment-thread.cjs +540 -0
  29. package/dist/packages/stack/src/plugins/comments/client/components/comment-thread.mjs +538 -0
  30. package/dist/packages/stack/src/plugins/comments/client/components/pages/moderation-page.cjs +64 -0
  31. package/dist/packages/stack/src/plugins/comments/client/components/pages/moderation-page.internal.cjs +426 -0
  32. package/dist/packages/stack/src/plugins/comments/client/components/pages/moderation-page.internal.mjs +424 -0
  33. package/dist/packages/stack/src/plugins/comments/client/components/pages/moderation-page.mjs +62 -0
  34. package/dist/packages/stack/src/plugins/comments/client/components/pages/my-comments-page.cjs +66 -0
  35. package/dist/packages/stack/src/plugins/comments/client/components/pages/my-comments-page.internal.cjs +256 -0
  36. package/dist/packages/stack/src/plugins/comments/client/components/pages/my-comments-page.internal.mjs +254 -0
  37. package/dist/packages/stack/src/plugins/comments/client/components/pages/my-comments-page.mjs +64 -0
  38. package/dist/packages/stack/src/plugins/comments/client/components/pages/resource-comments-page.cjs +86 -0
  39. package/dist/packages/stack/src/plugins/comments/client/components/pages/resource-comments-page.internal.cjs +191 -0
  40. package/dist/packages/stack/src/plugins/comments/client/components/pages/resource-comments-page.internal.mjs +189 -0
  41. package/dist/packages/stack/src/plugins/comments/client/components/pages/resource-comments-page.mjs +84 -0
  42. package/dist/packages/stack/src/plugins/comments/client/components/shared/page-wrapper.cjs +27 -0
  43. package/dist/packages/stack/src/plugins/comments/client/components/shared/page-wrapper.mjs +25 -0
  44. package/dist/packages/stack/src/plugins/comments/client/components/shared/pagination.cjs +37 -0
  45. package/dist/packages/stack/src/plugins/comments/client/components/shared/pagination.mjs +35 -0
  46. package/dist/packages/stack/src/plugins/comments/client/hooks/use-comments.cjs +476 -0
  47. package/dist/packages/stack/src/plugins/comments/client/hooks/use-comments.mjs +464 -0
  48. package/dist/packages/stack/src/plugins/comments/client/localization/comments-moderation.cjs +67 -0
  49. package/dist/packages/stack/src/plugins/comments/client/localization/comments-moderation.mjs +65 -0
  50. package/dist/packages/stack/src/plugins/comments/client/localization/comments-my.cjs +27 -0
  51. package/dist/packages/stack/src/plugins/comments/client/localization/comments-my.mjs +25 -0
  52. package/dist/packages/stack/src/plugins/comments/client/localization/comments-thread.cjs +30 -0
  53. package/dist/packages/stack/src/plugins/comments/client/localization/comments-thread.mjs +28 -0
  54. package/dist/packages/stack/src/plugins/comments/client/localization/index.cjs +13 -0
  55. package/dist/packages/stack/src/plugins/comments/client/localization/index.mjs +11 -0
  56. package/dist/packages/stack/src/plugins/comments/client/plugin.cjs +116 -0
  57. package/dist/packages/stack/src/plugins/comments/client/plugin.mjs +114 -0
  58. package/dist/packages/stack/src/plugins/comments/client/utils.cjs +41 -0
  59. package/dist/packages/stack/src/plugins/comments/client/utils.mjs +37 -0
  60. package/dist/packages/stack/src/plugins/comments/db.cjs +75 -0
  61. package/dist/packages/stack/src/plugins/comments/db.mjs +73 -0
  62. package/dist/packages/stack/src/plugins/comments/schemas.cjs +45 -0
  63. package/dist/packages/stack/src/plugins/comments/schemas.mjs +38 -0
  64. package/dist/packages/stack/src/plugins/kanban/client/components/forms/task-form.cjs +0 -1
  65. package/dist/packages/stack/src/plugins/kanban/client/components/forms/task-form.mjs +0 -1
  66. package/dist/packages/stack/src/plugins/kanban/client/components/pages/board-page.internal.cjs +39 -22
  67. package/dist/packages/stack/src/plugins/kanban/client/components/pages/board-page.internal.mjs +40 -23
  68. package/dist/packages/ui/src/components/avatar.mjs +1 -1
  69. package/dist/packages/ui/src/components/pagination-controls.cjs +64 -0
  70. package/dist/packages/ui/src/components/pagination-controls.mjs +62 -0
  71. package/dist/packages/ui/src/components/when-visible.cjs +39 -0
  72. package/dist/packages/ui/src/components/when-visible.mjs +37 -0
  73. package/dist/plugins/blog/client/hooks/index.d.cts +1 -1
  74. package/dist/plugins/blog/client/hooks/index.d.mts +1 -1
  75. package/dist/plugins/blog/client/hooks/index.d.ts +1 -1
  76. package/dist/plugins/blog/client/index.d.cts +24 -2
  77. package/dist/plugins/blog/client/index.d.mts +24 -2
  78. package/dist/plugins/blog/client/index.d.ts +24 -2
  79. package/dist/plugins/comments/api/index.cjs +21 -0
  80. package/dist/plugins/comments/api/index.d.cts +126 -0
  81. package/dist/plugins/comments/api/index.d.mts +126 -0
  82. package/dist/plugins/comments/api/index.d.ts +126 -0
  83. package/dist/plugins/comments/api/index.mjs +5 -0
  84. package/dist/plugins/comments/client/components/index.cjs +15 -0
  85. package/dist/plugins/comments/client/components/index.d.cts +125 -0
  86. package/dist/plugins/comments/client/components/index.d.mts +125 -0
  87. package/dist/plugins/comments/client/components/index.d.ts +125 -0
  88. package/dist/plugins/comments/client/components/index.mjs +5 -0
  89. package/dist/plugins/comments/client/hooks/index.cjs +17 -0
  90. package/dist/plugins/comments/client/hooks/index.d.cts +200 -0
  91. package/dist/plugins/comments/client/hooks/index.d.mts +200 -0
  92. package/dist/plugins/comments/client/hooks/index.d.ts +200 -0
  93. package/dist/plugins/comments/client/hooks/index.mjs +1 -0
  94. package/dist/plugins/comments/client/index.cjs +9 -0
  95. package/dist/plugins/comments/client/index.d.cts +262 -0
  96. package/dist/plugins/comments/client/index.d.mts +262 -0
  97. package/dist/plugins/comments/client/index.d.ts +262 -0
  98. package/dist/plugins/comments/client/index.mjs +2 -0
  99. package/dist/plugins/comments/client.css +2 -0
  100. package/dist/plugins/comments/query-keys.cjs +113 -0
  101. package/dist/plugins/comments/query-keys.d.cts +71 -0
  102. package/dist/plugins/comments/query-keys.d.mts +71 -0
  103. package/dist/plugins/comments/query-keys.d.ts +71 -0
  104. package/dist/plugins/comments/query-keys.mjs +111 -0
  105. package/dist/plugins/comments/style.css +15 -0
  106. package/dist/plugins/kanban/api/index.d.cts +1 -1
  107. package/dist/plugins/kanban/api/index.d.mts +1 -1
  108. package/dist/plugins/kanban/api/index.d.ts +1 -1
  109. package/dist/plugins/kanban/client/hooks/index.d.cts +1 -1
  110. package/dist/plugins/kanban/client/hooks/index.d.mts +1 -1
  111. package/dist/plugins/kanban/client/hooks/index.d.ts +1 -1
  112. package/dist/plugins/kanban/client/index.d.cts +1 -1
  113. package/dist/plugins/kanban/client/index.d.mts +1 -1
  114. package/dist/plugins/kanban/client/index.d.ts +1 -1
  115. package/dist/plugins/kanban/query-keys.d.cts +1 -1
  116. package/dist/plugins/kanban/query-keys.d.mts +1 -1
  117. package/dist/plugins/kanban/query-keys.d.ts +1 -1
  118. package/dist/shared/{stack.FeaWkglm.d.ts → stack.BxFl46lB.d.cts} +24 -1
  119. package/dist/shared/stack.C-b3Sn8j.d.cts +142 -0
  120. package/dist/shared/stack.C-b3Sn8j.d.mts +142 -0
  121. package/dist/shared/stack.C-b3Sn8j.d.ts +142 -0
  122. package/dist/shared/stack.CJE9sAjV.d.ts +335 -0
  123. package/dist/shared/stack.CmHRdhl8.d.cts +335 -0
  124. package/dist/shared/{stack.CNLHlv7r.d.mts → stack.DOZ1EXjM.d.mts} +6 -12
  125. package/dist/shared/{stack.FeaWkglm.d.mts → stack.DRpeDS6X.d.ts} +24 -1
  126. package/dist/shared/{stack.CQAZwXhV.d.cts → stack.DX-tQ93o.d.cts} +6 -12
  127. package/dist/shared/stack.Dcz6636A.d.mts +335 -0
  128. package/dist/shared/{stack.FeaWkglm.d.cts → stack.Jb0kQDJC.d.mts} +24 -1
  129. package/dist/shared/stack.Ldfkr5b2.d.cts +112 -0
  130. package/dist/shared/stack.Ldfkr5b2.d.mts +112 -0
  131. package/dist/shared/stack.Ldfkr5b2.d.ts +112 -0
  132. package/dist/shared/{stack.D3BsrpAz.d.ts → stack.VF6FhyZw.d.ts} +6 -12
  133. package/package.json +67 -2
  134. package/src/plugins/blog/client/components/loading/post-navigation-skeleton.tsx +10 -0
  135. package/src/plugins/blog/client/components/loading/recent-posts-carousel-skeleton.tsx +18 -0
  136. package/src/plugins/blog/client/components/pages/post-page.internal.tsx +23 -8
  137. package/src/plugins/blog/client/components/shared/post-navigation.tsx +0 -5
  138. package/src/plugins/blog/client/components/shared/recent-posts-carousel.tsx +1 -5
  139. package/src/plugins/blog/client/hooks/blog-hooks.tsx +8 -33
  140. package/src/plugins/blog/client/overrides.ts +26 -1
  141. package/src/plugins/cms/client/components/shared/pagination.tsx +14 -42
  142. package/src/plugins/comments/api/getters.ts +444 -0
  143. package/src/plugins/comments/api/index.ts +21 -0
  144. package/src/plugins/comments/api/mutations.ts +206 -0
  145. package/src/plugins/comments/api/plugin.ts +628 -0
  146. package/src/plugins/comments/api/query-key-defs.ts +143 -0
  147. package/src/plugins/comments/api/serializers.ts +37 -0
  148. package/src/plugins/comments/client/components/comment-count.tsx +66 -0
  149. package/src/plugins/comments/client/components/comment-form.tsx +112 -0
  150. package/src/plugins/comments/client/components/comment-thread.tsx +799 -0
  151. package/src/plugins/comments/client/components/index.tsx +11 -0
  152. package/src/plugins/comments/client/components/pages/moderation-page.internal.tsx +550 -0
  153. package/src/plugins/comments/client/components/pages/moderation-page.tsx +70 -0
  154. package/src/plugins/comments/client/components/pages/my-comments-page.internal.tsx +367 -0
  155. package/src/plugins/comments/client/components/pages/my-comments-page.tsx +72 -0
  156. package/src/plugins/comments/client/components/pages/resource-comments-page.internal.tsx +225 -0
  157. package/src/plugins/comments/client/components/pages/resource-comments-page.tsx +97 -0
  158. package/src/plugins/comments/client/components/shared/page-wrapper.tsx +32 -0
  159. package/src/plugins/comments/client/components/shared/pagination.tsx +44 -0
  160. package/src/plugins/comments/client/hooks/index.tsx +13 -0
  161. package/src/plugins/comments/client/hooks/use-comments.tsx +717 -0
  162. package/src/plugins/comments/client/index.ts +14 -0
  163. package/src/plugins/comments/client/localization/comments-moderation.ts +75 -0
  164. package/src/plugins/comments/client/localization/comments-my.ts +32 -0
  165. package/src/plugins/comments/client/localization/comments-thread.ts +32 -0
  166. package/src/plugins/comments/client/localization/index.ts +11 -0
  167. package/src/plugins/comments/client/overrides.ts +164 -0
  168. package/src/plugins/comments/client/plugin.tsx +195 -0
  169. package/src/plugins/comments/client/utils.ts +67 -0
  170. package/src/plugins/comments/client.css +2 -0
  171. package/src/plugins/comments/db.ts +77 -0
  172. package/src/plugins/comments/query-keys.ts +189 -0
  173. package/src/plugins/comments/schemas.ts +72 -0
  174. package/src/plugins/comments/style.css +15 -0
  175. package/src/plugins/comments/types.ts +73 -0
  176. package/src/plugins/kanban/client/components/forms/task-form.tsx +0 -1
  177. package/src/plugins/kanban/client/components/pages/board-page.internal.tsx +46 -27
  178. package/src/plugins/kanban/client/overrides.ts +27 -1
  179. package/dist/shared/{stack.Rtcvl8sS.d.cts → stack.BOokfhZD.d.cts} +3 -3
  180. package/dist/shared/{stack.D4Cea8II.d.ts → stack.BvCR4-9H.d.ts} +3 -3
  181. package/dist/shared/{stack.HE_IvqV5.d.mts → stack.CWxAl9K3.d.mts} +3 -3
@@ -0,0 +1,71 @@
1
+ import * as _tanstack_react_query from '@tanstack/react-query';
2
+ import { b as CommentsListDiscriminator, C as CommentListResult, c as CommentCountDiscriminator, a as CommentsThreadDiscriminator } from '../../shared/stack.C-b3Sn8j.cjs';
3
+ import { createApiClient } from '@btst/stack/plugins/client';
4
+ import { C as CommentsApiRouter } from '../../shared/stack.CmHRdhl8.cjs';
5
+ import '@btst/stack/plugins/api';
6
+ import 'better-call';
7
+ import 'zod';
8
+
9
+ interface CommentsListParams {
10
+ resourceId?: string;
11
+ resourceType?: string;
12
+ parentId?: string | null;
13
+ status?: "pending" | "approved" | "spam";
14
+ currentUserId?: string;
15
+ authorId?: string;
16
+ sort?: "asc" | "desc";
17
+ limit?: number;
18
+ offset?: number;
19
+ }
20
+ interface CommentCountParams {
21
+ resourceId: string;
22
+ resourceType: string;
23
+ status?: "pending" | "approved" | "spam";
24
+ }
25
+ declare function createCommentsQueryKeys(client: ReturnType<typeof createApiClient<CommentsApiRouter>>, headers?: HeadersInit): {
26
+ comments: {
27
+ _def: readonly ["comments"];
28
+ } & {
29
+ list: ((params?: CommentsListParams | undefined) => Omit<{
30
+ queryKey: readonly ["comments", "list", CommentsListDiscriminator];
31
+ queryFn: _tanstack_react_query.QueryFunction<CommentListResult, readonly ["comments", "list", CommentsListDiscriminator]>;
32
+ } & {
33
+ _def: readonly ["comments", "list"];
34
+ }, "_def">) & {
35
+ _def: readonly ["comments", "list"];
36
+ };
37
+ };
38
+ commentCount: {
39
+ _def: readonly ["commentCount"];
40
+ } & {
41
+ byResource: ((params: CommentCountParams) => Omit<{
42
+ queryKey: readonly ["commentCount", "byResource", CommentCountDiscriminator];
43
+ queryFn: _tanstack_react_query.QueryFunction<number, readonly ["commentCount", "byResource", CommentCountDiscriminator]>;
44
+ } & {
45
+ _def: readonly ["commentCount", "byResource"];
46
+ }, "_def">) & {
47
+ _def: readonly ["commentCount", "byResource"];
48
+ };
49
+ };
50
+ commentsThread: {
51
+ _def: readonly ["commentsThread"];
52
+ } & {
53
+ list: ((params?: {
54
+ resourceId?: string;
55
+ resourceType?: string;
56
+ parentId?: string | null;
57
+ status?: "pending" | "approved" | "spam";
58
+ currentUserId?: string;
59
+ limit?: number;
60
+ } | undefined) => Omit<Omit<{
61
+ queryKey: readonly ["commentsThread", "list", CommentsThreadDiscriminator];
62
+ queryFn: _tanstack_react_query.QueryFunction<unknown, readonly ["commentsThread", "list", CommentsThreadDiscriminator]>;
63
+ }, "queryFn"> & {
64
+ _def: readonly ["commentsThread", "list"];
65
+ }, "_def">) & {
66
+ _def: readonly ["commentsThread", "list"];
67
+ };
68
+ };
69
+ };
70
+
71
+ export { createCommentsQueryKeys };
@@ -0,0 +1,71 @@
1
+ import * as _tanstack_react_query from '@tanstack/react-query';
2
+ import { b as CommentsListDiscriminator, C as CommentListResult, c as CommentCountDiscriminator, a as CommentsThreadDiscriminator } from '../../shared/stack.C-b3Sn8j.mjs';
3
+ import { createApiClient } from '@btst/stack/plugins/client';
4
+ import { C as CommentsApiRouter } from '../../shared/stack.Dcz6636A.mjs';
5
+ import '@btst/stack/plugins/api';
6
+ import 'better-call';
7
+ import 'zod';
8
+
9
+ interface CommentsListParams {
10
+ resourceId?: string;
11
+ resourceType?: string;
12
+ parentId?: string | null;
13
+ status?: "pending" | "approved" | "spam";
14
+ currentUserId?: string;
15
+ authorId?: string;
16
+ sort?: "asc" | "desc";
17
+ limit?: number;
18
+ offset?: number;
19
+ }
20
+ interface CommentCountParams {
21
+ resourceId: string;
22
+ resourceType: string;
23
+ status?: "pending" | "approved" | "spam";
24
+ }
25
+ declare function createCommentsQueryKeys(client: ReturnType<typeof createApiClient<CommentsApiRouter>>, headers?: HeadersInit): {
26
+ comments: {
27
+ _def: readonly ["comments"];
28
+ } & {
29
+ list: ((params?: CommentsListParams | undefined) => Omit<{
30
+ queryKey: readonly ["comments", "list", CommentsListDiscriminator];
31
+ queryFn: _tanstack_react_query.QueryFunction<CommentListResult, readonly ["comments", "list", CommentsListDiscriminator]>;
32
+ } & {
33
+ _def: readonly ["comments", "list"];
34
+ }, "_def">) & {
35
+ _def: readonly ["comments", "list"];
36
+ };
37
+ };
38
+ commentCount: {
39
+ _def: readonly ["commentCount"];
40
+ } & {
41
+ byResource: ((params: CommentCountParams) => Omit<{
42
+ queryKey: readonly ["commentCount", "byResource", CommentCountDiscriminator];
43
+ queryFn: _tanstack_react_query.QueryFunction<number, readonly ["commentCount", "byResource", CommentCountDiscriminator]>;
44
+ } & {
45
+ _def: readonly ["commentCount", "byResource"];
46
+ }, "_def">) & {
47
+ _def: readonly ["commentCount", "byResource"];
48
+ };
49
+ };
50
+ commentsThread: {
51
+ _def: readonly ["commentsThread"];
52
+ } & {
53
+ list: ((params?: {
54
+ resourceId?: string;
55
+ resourceType?: string;
56
+ parentId?: string | null;
57
+ status?: "pending" | "approved" | "spam";
58
+ currentUserId?: string;
59
+ limit?: number;
60
+ } | undefined) => Omit<Omit<{
61
+ queryKey: readonly ["commentsThread", "list", CommentsThreadDiscriminator];
62
+ queryFn: _tanstack_react_query.QueryFunction<unknown, readonly ["commentsThread", "list", CommentsThreadDiscriminator]>;
63
+ }, "queryFn"> & {
64
+ _def: readonly ["commentsThread", "list"];
65
+ }, "_def">) & {
66
+ _def: readonly ["commentsThread", "list"];
67
+ };
68
+ };
69
+ };
70
+
71
+ export { createCommentsQueryKeys };
@@ -0,0 +1,71 @@
1
+ import * as _tanstack_react_query from '@tanstack/react-query';
2
+ import { b as CommentsListDiscriminator, C as CommentListResult, c as CommentCountDiscriminator, a as CommentsThreadDiscriminator } from '../../shared/stack.C-b3Sn8j.js';
3
+ import { createApiClient } from '@btst/stack/plugins/client';
4
+ import { C as CommentsApiRouter } from '../../shared/stack.CJE9sAjV.js';
5
+ import '@btst/stack/plugins/api';
6
+ import 'better-call';
7
+ import 'zod';
8
+
9
+ interface CommentsListParams {
10
+ resourceId?: string;
11
+ resourceType?: string;
12
+ parentId?: string | null;
13
+ status?: "pending" | "approved" | "spam";
14
+ currentUserId?: string;
15
+ authorId?: string;
16
+ sort?: "asc" | "desc";
17
+ limit?: number;
18
+ offset?: number;
19
+ }
20
+ interface CommentCountParams {
21
+ resourceId: string;
22
+ resourceType: string;
23
+ status?: "pending" | "approved" | "spam";
24
+ }
25
+ declare function createCommentsQueryKeys(client: ReturnType<typeof createApiClient<CommentsApiRouter>>, headers?: HeadersInit): {
26
+ comments: {
27
+ _def: readonly ["comments"];
28
+ } & {
29
+ list: ((params?: CommentsListParams | undefined) => Omit<{
30
+ queryKey: readonly ["comments", "list", CommentsListDiscriminator];
31
+ queryFn: _tanstack_react_query.QueryFunction<CommentListResult, readonly ["comments", "list", CommentsListDiscriminator]>;
32
+ } & {
33
+ _def: readonly ["comments", "list"];
34
+ }, "_def">) & {
35
+ _def: readonly ["comments", "list"];
36
+ };
37
+ };
38
+ commentCount: {
39
+ _def: readonly ["commentCount"];
40
+ } & {
41
+ byResource: ((params: CommentCountParams) => Omit<{
42
+ queryKey: readonly ["commentCount", "byResource", CommentCountDiscriminator];
43
+ queryFn: _tanstack_react_query.QueryFunction<number, readonly ["commentCount", "byResource", CommentCountDiscriminator]>;
44
+ } & {
45
+ _def: readonly ["commentCount", "byResource"];
46
+ }, "_def">) & {
47
+ _def: readonly ["commentCount", "byResource"];
48
+ };
49
+ };
50
+ commentsThread: {
51
+ _def: readonly ["commentsThread"];
52
+ } & {
53
+ list: ((params?: {
54
+ resourceId?: string;
55
+ resourceType?: string;
56
+ parentId?: string | null;
57
+ status?: "pending" | "approved" | "spam";
58
+ currentUserId?: string;
59
+ limit?: number;
60
+ } | undefined) => Omit<Omit<{
61
+ queryKey: readonly ["commentsThread", "list", CommentsThreadDiscriminator];
62
+ queryFn: _tanstack_react_query.QueryFunction<unknown, readonly ["commentsThread", "list", CommentsThreadDiscriminator]>;
63
+ }, "queryFn"> & {
64
+ _def: readonly ["commentsThread", "list"];
65
+ }, "_def">) & {
66
+ _def: readonly ["commentsThread", "list"];
67
+ };
68
+ };
69
+ };
70
+
71
+ export { createCommentsQueryKeys };
@@ -0,0 +1,111 @@
1
+ import { mergeQueryKeys, createQueryKeys } from '@lukemorales/query-key-factory';
2
+ import { commentsListDiscriminator, commentCountDiscriminator, commentsThreadDiscriminator } from '../../packages/stack/src/plugins/comments/api/query-key-defs.mjs';
3
+ import { toError } from '../../packages/stack/src/plugins/comments/client/utils.mjs';
4
+
5
+ function isErrorResponse(response) {
6
+ return typeof response === "object" && response !== null && "error" in response && response.error !== null && response.error !== void 0;
7
+ }
8
+ function createCommentsQueryKeys(client, headers) {
9
+ return mergeQueryKeys(
10
+ createCommentsQueries(client, headers),
11
+ createCommentCountQueries(client, headers),
12
+ createCommentsThreadQueries(client, headers)
13
+ );
14
+ }
15
+ function createCommentsQueries(client, headers) {
16
+ return createQueryKeys("comments", {
17
+ list: (params) => ({
18
+ queryKey: [commentsListDiscriminator(params)],
19
+ queryFn: async () => {
20
+ const response = await client("/comments", {
21
+ method: "GET",
22
+ query: {
23
+ resourceId: params?.resourceId,
24
+ resourceType: params?.resourceType,
25
+ parentId: params?.parentId === null ? "null" : params?.parentId,
26
+ status: params?.status,
27
+ // currentUserId is intentionally NOT sent to the server.
28
+ // The server resolves the caller's identity server-side via the
29
+ // resolveCurrentUserId hook. Sending it would allow any caller to
30
+ // impersonate another user and read their pending comments.
31
+ // It is still included in the queryKey above for client-side
32
+ // cache segregation (different users get different cache entries).
33
+ authorId: params?.authorId,
34
+ sort: params?.sort,
35
+ limit: params?.limit ?? 20,
36
+ offset: params?.offset ?? 0
37
+ },
38
+ headers
39
+ });
40
+ if (isErrorResponse(response)) {
41
+ throw toError(response.error);
42
+ }
43
+ const data = response.data;
44
+ return data ?? { items: [], total: 0, limit: 20, offset: 0 };
45
+ }
46
+ })
47
+ });
48
+ }
49
+ function createCommentCountQueries(client, headers) {
50
+ return createQueryKeys("commentCount", {
51
+ byResource: (params) => ({
52
+ queryKey: [commentCountDiscriminator(params)],
53
+ queryFn: async () => {
54
+ const response = await client("/comments/count", {
55
+ method: "GET",
56
+ query: {
57
+ resourceId: params.resourceId,
58
+ resourceType: params.resourceType,
59
+ status: params.status
60
+ },
61
+ headers
62
+ });
63
+ if (isErrorResponse(response)) {
64
+ throw toError(response.error);
65
+ }
66
+ const data = response.data;
67
+ return data?.count ?? 0;
68
+ }
69
+ })
70
+ });
71
+ }
72
+ function createCommentsThreadQueries(client, headers) {
73
+ return createQueryKeys("commentsThread", {
74
+ list: (params) => ({
75
+ // Offset is excluded from the key — it is driven by pageParam.
76
+ queryKey: [commentsThreadDiscriminator(params)],
77
+ queryFn: async ({
78
+ pageParam
79
+ } = {}) => {
80
+ const response = await client("/comments", {
81
+ method: "GET",
82
+ query: {
83
+ resourceId: params?.resourceId,
84
+ resourceType: params?.resourceType,
85
+ parentId: params?.parentId === null ? "null" : params?.parentId,
86
+ status: params?.status,
87
+ // currentUserId is intentionally NOT sent to the server.
88
+ // The server resolves the caller's identity server-side via the
89
+ // resolveCurrentUserId hook. It is still included in the queryKey
90
+ // above for client-side cache segregation.
91
+ limit: params?.limit ?? 20,
92
+ offset: pageParam ?? 0
93
+ },
94
+ headers
95
+ });
96
+ if (isErrorResponse(response)) {
97
+ throw toError(response.error);
98
+ }
99
+ const data = response.data;
100
+ return data ?? {
101
+ items: [],
102
+ total: 0,
103
+ limit: params?.limit ?? 20,
104
+ offset: pageParam ?? 0
105
+ };
106
+ }
107
+ })
108
+ });
109
+ }
110
+
111
+ export { createCommentsQueryKeys };
@@ -0,0 +1,15 @@
1
+ @import "./client.css";
2
+
3
+ /*
4
+ * Comments Plugin CSS - Includes Tailwind class scanning
5
+ *
6
+ * When consumed from npm, Tailwind v4 will automatically scan this package's
7
+ * source files for Tailwind classes. Consumers only need:
8
+ * @import "@btst/stack/plugins/comments/css";
9
+ */
10
+
11
+ /* Scan this package's source files for Tailwind classes */
12
+ @source "../../../src/**/*.{ts,tsx}";
13
+
14
+ /* Scan UI package components (when installed as npm package the UI package will be in this dir) */
15
+ @source "../../packages/ui/src";
@@ -1,4 +1,4 @@
1
- export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.Rtcvl8sS.cjs';
1
+ export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.BOokfhZD.cjs';
2
2
  import { B as BoardWithColumns, S as SerializedBoardWithColumns, C as ColumnWithTasks, a as SerializedColumn, T as Task, b as SerializedTask } from '../../../shared/stack.DJaKVY7v.cjs';
3
3
  import '@btst/stack/plugins/api';
4
4
  import '@btst/db';
@@ -1,4 +1,4 @@
1
- export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.HE_IvqV5.mjs';
1
+ export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.CWxAl9K3.mjs';
2
2
  import { B as BoardWithColumns, S as SerializedBoardWithColumns, C as ColumnWithTasks, a as SerializedColumn, T as Task, b as SerializedTask } from '../../../shared/stack.DJaKVY7v.mjs';
3
3
  import '@btst/stack/plugins/api';
4
4
  import '@btst/db';
@@ -1,4 +1,4 @@
1
- export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.D4Cea8II.js';
1
+ export { B as BoardListResult, C as CreateKanbanTaskInput, i as KANBAN_QUERY_KEYS, b as KanbanApiContext, K as KanbanApiRouter, c as KanbanBackendHooks, a as KanbanRouteKey, e as createKanbanTask, f as findOrCreateKanbanBoard, g as getAllBoards, d as getBoardById, h as getKanbanColumnsByBoardId, k as kanbanBackendPlugin } from '../../../shared/stack.BvCR4-9H.js';
2
2
  import { B as BoardWithColumns, S as SerializedBoardWithColumns, C as ColumnWithTasks, a as SerializedColumn, T as Task, b as SerializedTask } from '../../../shared/stack.DJaKVY7v.js';
3
3
  import '@btst/stack/plugins/api';
4
4
  import '@btst/db';
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { a as KanbanUser } from '../../../../shared/stack.FeaWkglm.cjs';
2
+ import { a as KanbanUser } from '../../../../shared/stack.BxFl46lB.cjs';
3
3
  import { S as SerializedBoardWithColumns, c as SerializedBoard, a as SerializedColumn, b as SerializedTask, P as Priority } from '../../../../shared/stack.DJaKVY7v.cjs';
4
4
  import 'react';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { a as KanbanUser } from '../../../../shared/stack.FeaWkglm.mjs';
2
+ import { a as KanbanUser } from '../../../../shared/stack.Jb0kQDJC.mjs';
3
3
  import { S as SerializedBoardWithColumns, c as SerializedBoard, a as SerializedColumn, b as SerializedTask, P as Priority } from '../../../../shared/stack.DJaKVY7v.mjs';
4
4
  import 'react';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { a as KanbanUser } from '../../../../shared/stack.FeaWkglm.js';
2
+ import { a as KanbanUser } from '../../../../shared/stack.DRpeDS6X.js';
3
3
  import { S as SerializedBoardWithColumns, c as SerializedBoard, a as SerializedColumn, b as SerializedTask, P as Priority } from '../../../../shared/stack.DJaKVY7v.js';
4
4
  import 'react';
5
5
 
@@ -3,7 +3,7 @@ import * as _btst_yar from '@btst/yar';
3
3
  import { ComponentType } from 'react';
4
4
  import { QueryClient } from '@tanstack/react-query';
5
5
  import { S as SerializedBoardWithColumns } from '../../../shared/stack.DJaKVY7v.cjs';
6
- export { K as KanbanPluginOverrides, a as KanbanUser } from '../../../shared/stack.FeaWkglm.cjs';
6
+ export { K as KanbanPluginOverrides, a as KanbanUser } from '../../../shared/stack.BxFl46lB.cjs';
7
7
 
8
8
  /**
9
9
  * Context passed to route hooks
@@ -3,7 +3,7 @@ import * as _btst_yar from '@btst/yar';
3
3
  import { ComponentType } from 'react';
4
4
  import { QueryClient } from '@tanstack/react-query';
5
5
  import { S as SerializedBoardWithColumns } from '../../../shared/stack.DJaKVY7v.mjs';
6
- export { K as KanbanPluginOverrides, a as KanbanUser } from '../../../shared/stack.FeaWkglm.mjs';
6
+ export { K as KanbanPluginOverrides, a as KanbanUser } from '../../../shared/stack.Jb0kQDJC.mjs';
7
7
 
8
8
  /**
9
9
  * Context passed to route hooks
@@ -3,7 +3,7 @@ import * as _btst_yar from '@btst/yar';
3
3
  import { ComponentType } from 'react';
4
4
  import { QueryClient } from '@tanstack/react-query';
5
5
  import { S as SerializedBoardWithColumns } from '../../../shared/stack.DJaKVY7v.js';
6
- export { K as KanbanPluginOverrides, a as KanbanUser } from '../../../shared/stack.FeaWkglm.js';
6
+ export { K as KanbanPluginOverrides, a as KanbanUser } from '../../../shared/stack.DRpeDS6X.js';
7
7
 
8
8
  /**
9
9
  * Context passed to route hooks
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.Rtcvl8sS.cjs';
2
+ import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.BOokfhZD.cjs';
3
3
  import { createApiClient } from '@btst/stack/plugins/client';
4
4
  import { S as SerializedBoardWithColumns } from '../../shared/stack.DJaKVY7v.cjs';
5
5
  import '@btst/stack/plugins/api';
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.HE_IvqV5.mjs';
2
+ import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.CWxAl9K3.mjs';
3
3
  import { createApiClient } from '@btst/stack/plugins/client';
4
4
  import { S as SerializedBoardWithColumns } from '../../shared/stack.DJaKVY7v.mjs';
5
5
  import '@btst/stack/plugins/api';
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.D4Cea8II.js';
2
+ import { K as KanbanApiRouter, j as BoardsListDiscriminator } from '../../shared/stack.BvCR4-9H.js';
3
3
  import { createApiClient } from '@btst/stack/plugins/client';
4
4
  import { S as SerializedBoardWithColumns } from '../../shared/stack.DJaKVY7v.js';
5
5
  import '@btst/stack/plugins/api';
@@ -1,4 +1,5 @@
1
- import { ComponentType } from 'react';
1
+ import { ComponentType, ReactNode } from 'react';
2
+ import { b as SerializedTask } from './stack.DJaKVY7v.cjs';
2
3
 
3
4
  interface KanbanCommonLocalization {
4
5
  backToBoards: string;
@@ -185,6 +186,28 @@ interface KanbanPluginOverrides {
185
186
  * @param context - Route context
186
187
  */
187
188
  onBeforeNewBoardPageRendered?: (context: RouteContext) => boolean;
189
+ /**
190
+ * Optional slot rendered at the bottom of the task detail dialog.
191
+ * Use this to inject a comment thread or any custom content without
192
+ * coupling the kanban plugin to the comments plugin.
193
+ *
194
+ * @example
195
+ * ```tsx
196
+ * kanban: {
197
+ * taskDetailBottomSlot: (task) => (
198
+ * <CommentThread
199
+ * resourceId={task.id}
200
+ * resourceType="kanban-task"
201
+ * apiBaseURL={apiBaseURL}
202
+ * apiBasePath="/api/data"
203
+ * currentUserId={session?.userId}
204
+ * loginHref="/login"
205
+ * />
206
+ * ),
207
+ * }
208
+ * ```
209
+ */
210
+ taskDetailBottomSlot?: (task: SerializedTask) => ReactNode;
188
211
  }
189
212
 
190
213
  export type { KanbanPluginOverrides as K, KanbanUser as a };
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Comment status values
3
+ */
4
+ type CommentStatus = "pending" | "approved" | "spam";
5
+ /**
6
+ * A comment record as stored in the database
7
+ */
8
+ type Comment = {
9
+ id: string;
10
+ resourceId: string;
11
+ resourceType: string;
12
+ parentId: string | null;
13
+ authorId: string;
14
+ body: string;
15
+ status: CommentStatus;
16
+ likes: number;
17
+ editedAt?: Date;
18
+ createdAt: Date;
19
+ updatedAt: Date;
20
+ };
21
+ /**
22
+ * A comment enriched with server-resolved author info and like status.
23
+ * All dates are ISO strings (safe for serialisation over HTTP / React Query cache).
24
+ */
25
+ interface SerializedComment {
26
+ id: string;
27
+ resourceId: string;
28
+ resourceType: string;
29
+ parentId: string | null;
30
+ authorId: string;
31
+ /** Resolved from resolveUser(authorId). Falls back to "[deleted]" when user cannot be found. */
32
+ resolvedAuthorName: string;
33
+ /** Resolved avatar URL or null */
34
+ resolvedAvatarUrl: string | null;
35
+ body: string;
36
+ status: CommentStatus;
37
+ /** Denormalized counter — updated atomically on toggleLike */
38
+ likes: number;
39
+ /** True when the currentUserId query param matches an existing commentLike row */
40
+ isLikedByCurrentUser: boolean;
41
+ /** ISO string set when the comment body was edited; null for unedited comments */
42
+ editedAt: string | null;
43
+ createdAt: string;
44
+ updatedAt: string;
45
+ /**
46
+ * Number of direct replies visible to the requesting user.
47
+ * Includes approved replies plus any pending replies authored by `currentUserId`.
48
+ * Always 0 for reply comments (non-null parentId).
49
+ */
50
+ replyCount: number;
51
+ }
52
+ /**
53
+ * Paginated list result for comments
54
+ */
55
+ interface CommentListResult {
56
+ items: SerializedComment[];
57
+ total: number;
58
+ limit: number;
59
+ offset: number;
60
+ }
61
+
62
+ /**
63
+ * Internal query key constants for the Comments plugin.
64
+ * Shared between query-keys.ts (HTTP path) and any SSG/direct DB path
65
+ * to prevent key drift between loaders and prefetch calls.
66
+ */
67
+ interface CommentsListDiscriminator {
68
+ resourceId: string | undefined;
69
+ resourceType: string | undefined;
70
+ parentId: string | null | undefined;
71
+ status: string | undefined;
72
+ currentUserId: string | undefined;
73
+ authorId: string | undefined;
74
+ sort: string | undefined;
75
+ limit: number;
76
+ offset: number;
77
+ }
78
+ interface CommentCountDiscriminator {
79
+ resourceId: string;
80
+ resourceType: string;
81
+ status: string | undefined;
82
+ }
83
+ /**
84
+ * Discriminator for the infinite thread query (top-level comments only).
85
+ * Intentionally excludes `offset` — pages are driven by `pageParam`, not the key.
86
+ */
87
+ interface CommentsThreadDiscriminator {
88
+ resourceId: string | undefined;
89
+ resourceType: string | undefined;
90
+ parentId: string | null | undefined;
91
+ status: string | undefined;
92
+ currentUserId: string | undefined;
93
+ limit: number;
94
+ }
95
+ /** Full query key builders — use with queryClient.setQueryData() */
96
+ declare const COMMENTS_QUERY_KEYS: {
97
+ /**
98
+ * Key for comments list query.
99
+ * Full key: ["comments", "list", { resourceId, resourceType, parentId, status, currentUserId, limit, offset }]
100
+ */
101
+ commentsList: (params?: {
102
+ resourceId?: string;
103
+ resourceType?: string;
104
+ parentId?: string | null;
105
+ status?: string;
106
+ currentUserId?: string;
107
+ authorId?: string;
108
+ sort?: string;
109
+ limit?: number;
110
+ offset?: number;
111
+ }) => readonly ["comments", "list", CommentsListDiscriminator];
112
+ /**
113
+ * Key for a single comment detail query.
114
+ * Full key: ["comments", "detail", id]
115
+ */
116
+ commentDetail: (id: string) => readonly ["comments", "detail", string];
117
+ /**
118
+ * Key for comment count query.
119
+ * Full key: ["comments", "count", { resourceId, resourceType, status }]
120
+ */
121
+ commentCount: (params: {
122
+ resourceId: string;
123
+ resourceType: string;
124
+ status?: string;
125
+ }) => readonly ["comments", "count", CommentCountDiscriminator];
126
+ /**
127
+ * Key for the infinite thread query (top-level comments, load-more).
128
+ * Full key: ["commentsThread", "list", { resourceId, resourceType, parentId, status, currentUserId, limit }]
129
+ * Offset is excluded — it is driven by `pageParam`, not baked into the key.
130
+ */
131
+ commentsThread: (params?: {
132
+ resourceId?: string;
133
+ resourceType?: string;
134
+ parentId?: string | null;
135
+ status?: string;
136
+ currentUserId?: string;
137
+ limit?: number;
138
+ }) => readonly ["commentsThread", "list", CommentsThreadDiscriminator];
139
+ };
140
+
141
+ export { COMMENTS_QUERY_KEYS as e };
142
+ export type { CommentListResult as C, SerializedComment as S, CommentsThreadDiscriminator as a, CommentsListDiscriminator as b, CommentCountDiscriminator as c, Comment as d };