@btst/stack 1.7.0 → 1.9.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 (110) hide show
  1. package/dist/api/index.d.cts +2 -2
  2. package/dist/api/index.d.mts +2 -2
  3. package/dist/api/index.d.ts +2 -2
  4. package/dist/client/index.cjs +6 -2
  5. package/dist/client/index.d.cts +2 -1
  6. package/dist/client/index.d.mts +2 -1
  7. package/dist/client/index.d.ts +2 -1
  8. package/dist/client/index.mjs +6 -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/better-stack/src/plugins/cms/api/plugin.cjs +445 -16
  13. package/dist/packages/better-stack/src/plugins/cms/api/plugin.mjs +445 -16
  14. package/dist/packages/better-stack/src/plugins/cms/client/components/forms/content-form.cjs +24 -7
  15. package/dist/packages/better-stack/src/plugins/cms/client/components/forms/content-form.mjs +25 -8
  16. package/dist/packages/better-stack/src/plugins/cms/client/components/forms/relation-field.cjs +224 -0
  17. package/dist/packages/better-stack/src/plugins/cms/client/components/forms/relation-field.mjs +222 -0
  18. package/dist/packages/better-stack/src/plugins/cms/client/components/inverse-relations-panel.cjs +243 -0
  19. package/dist/packages/better-stack/src/plugins/cms/client/components/inverse-relations-panel.mjs +241 -0
  20. package/dist/packages/better-stack/src/plugins/cms/client/components/pages/content-editor-page.internal.cjs +56 -2
  21. package/dist/packages/better-stack/src/plugins/cms/client/components/pages/content-editor-page.internal.mjs +56 -2
  22. package/dist/packages/better-stack/src/plugins/cms/client/hooks/cms-hooks.cjs +190 -0
  23. package/dist/packages/better-stack/src/plugins/cms/client/hooks/cms-hooks.mjs +187 -1
  24. package/dist/packages/better-stack/src/plugins/cms/db.cjs +38 -0
  25. package/dist/packages/better-stack/src/plugins/cms/db.mjs +38 -0
  26. package/dist/packages/better-stack/src/plugins/route-docs/client/components/loading/docs-skeleton.cjs +43 -0
  27. package/dist/packages/better-stack/src/plugins/route-docs/client/components/loading/docs-skeleton.mjs +41 -0
  28. package/dist/packages/better-stack/src/plugins/route-docs/client/components/pages/docs-page.cjs +794 -0
  29. package/dist/packages/better-stack/src/plugins/route-docs/client/components/pages/docs-page.mjs +788 -0
  30. package/dist/packages/better-stack/src/plugins/route-docs/client/plugin.cjs +111 -0
  31. package/dist/packages/better-stack/src/plugins/route-docs/client/plugin.mjs +106 -0
  32. package/dist/packages/better-stack/src/plugins/route-docs/generator.cjs +244 -0
  33. package/dist/packages/better-stack/src/plugins/route-docs/generator.mjs +227 -0
  34. package/dist/packages/ui/src/components/auto-form/fields/object.cjs +81 -1
  35. package/dist/packages/ui/src/components/auto-form/fields/object.mjs +81 -1
  36. package/dist/packages/ui/src/components/dialog.cjs +6 -0
  37. package/dist/packages/ui/src/components/dialog.mjs +6 -1
  38. package/dist/packages/ui/src/components/sheet.cjs +25 -0
  39. package/dist/packages/ui/src/components/sheet.mjs +24 -1
  40. package/dist/plugins/api/index.d.cts +2 -2
  41. package/dist/plugins/api/index.d.mts +2 -2
  42. package/dist/plugins/api/index.d.ts +2 -2
  43. package/dist/plugins/blog/api/index.d.cts +1 -1
  44. package/dist/plugins/blog/api/index.d.mts +1 -1
  45. package/dist/plugins/blog/api/index.d.ts +1 -1
  46. package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
  47. package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
  48. package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
  49. package/dist/plugins/blog/client/index.d.cts +1 -1
  50. package/dist/plugins/blog/client/index.d.mts +1 -1
  51. package/dist/plugins/blog/client/index.d.ts +1 -1
  52. package/dist/plugins/blog/query-keys.d.cts +2 -2
  53. package/dist/plugins/blog/query-keys.d.mts +2 -2
  54. package/dist/plugins/blog/query-keys.d.ts +2 -2
  55. package/dist/plugins/client/index.d.cts +2 -2
  56. package/dist/plugins/client/index.d.mts +2 -2
  57. package/dist/plugins/client/index.d.ts +2 -2
  58. package/dist/plugins/cms/api/index.d.cts +67 -3
  59. package/dist/plugins/cms/api/index.d.mts +67 -3
  60. package/dist/plugins/cms/api/index.d.ts +67 -3
  61. package/dist/plugins/cms/client/hooks/index.cjs +4 -0
  62. package/dist/plugins/cms/client/hooks/index.d.cts +82 -3
  63. package/dist/plugins/cms/client/hooks/index.d.mts +82 -3
  64. package/dist/plugins/cms/client/hooks/index.d.ts +82 -3
  65. package/dist/plugins/cms/client/hooks/index.mjs +1 -1
  66. package/dist/plugins/cms/query-keys.d.cts +1 -1
  67. package/dist/plugins/cms/query-keys.d.mts +1 -1
  68. package/dist/plugins/cms/query-keys.d.ts +1 -1
  69. package/dist/plugins/form-builder/api/index.d.cts +1 -1
  70. package/dist/plugins/form-builder/api/index.d.mts +1 -1
  71. package/dist/plugins/form-builder/api/index.d.ts +1 -1
  72. package/dist/plugins/open-api/api/index.d.cts +1 -1
  73. package/dist/plugins/open-api/api/index.d.mts +1 -1
  74. package/dist/plugins/open-api/api/index.d.ts +1 -1
  75. package/dist/plugins/route-docs/client/index.cjs +10 -0
  76. package/dist/plugins/route-docs/client/index.d.cts +126 -0
  77. package/dist/plugins/route-docs/client/index.d.mts +126 -0
  78. package/dist/plugins/route-docs/client/index.d.ts +126 -0
  79. package/dist/plugins/route-docs/client/index.mjs +1 -0
  80. package/dist/plugins/route-docs/client.css +3 -0
  81. package/dist/plugins/route-docs/style.css +19 -0
  82. package/dist/shared/{stack.L-UFwz2G.d.mts → stack.oGOteE6g.d.cts} +27 -5
  83. package/dist/shared/{stack.L-UFwz2G.d.ts → stack.oGOteE6g.d.mts} +27 -5
  84. package/dist/shared/{stack.L-UFwz2G.d.cts → stack.oGOteE6g.d.ts} +27 -5
  85. package/dist/shared/{stack.CSce37mX.d.cts → stack.u9iYV6vt.d.cts} +14 -2
  86. package/dist/shared/{stack.CSce37mX.d.mts → stack.u9iYV6vt.d.mts} +14 -2
  87. package/dist/shared/{stack.CSce37mX.d.ts → stack.u9iYV6vt.d.ts} +14 -2
  88. package/package.json +15 -1
  89. package/src/client/index.ts +11 -4
  90. package/src/plugins/cms/api/plugin.ts +667 -21
  91. package/src/plugins/cms/client/components/forms/content-form.tsx +60 -18
  92. package/src/plugins/cms/client/components/forms/relation-field.tsx +299 -0
  93. package/src/plugins/cms/client/components/inverse-relations-panel.tsx +329 -0
  94. package/src/plugins/cms/client/components/pages/content-editor-page.internal.tsx +127 -1
  95. package/src/plugins/cms/client/hooks/cms-hooks.tsx +344 -0
  96. package/src/plugins/cms/db.ts +38 -0
  97. package/src/plugins/cms/types.ts +99 -10
  98. package/src/plugins/route-docs/client/components/loading/docs-skeleton.tsx +82 -0
  99. package/src/plugins/route-docs/client/components/loading/index.tsx +1 -0
  100. package/src/plugins/route-docs/client/components/pages/docs-page.tsx +1240 -0
  101. package/src/plugins/route-docs/client/index.ts +7 -0
  102. package/src/plugins/route-docs/client/plugin.tsx +187 -0
  103. package/src/plugins/route-docs/client.css +3 -0
  104. package/src/plugins/route-docs/generator.ts +385 -0
  105. package/src/plugins/route-docs/index.ts +12 -0
  106. package/src/plugins/route-docs/style.css +19 -0
  107. package/src/types.ts +19 -1
  108. package/dist/shared/{stack.CcI4sYJP.d.mts → stack.DLhzx1-D.d.cts} +1 -1
  109. package/dist/shared/{stack.CcI4sYJP.d.ts → stack.DLhzx1-D.d.mts} +1 -1
  110. package/dist/shared/{stack.CcI4sYJP.d.cts → stack.DLhzx1-D.d.ts} +1 -1
@@ -1,7 +1,7 @@
1
1
  import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
2
2
  import * as better_call from 'better-call';
3
3
  import { z } from 'zod';
4
- import { C as CMSBackendConfig, S as SerializedContentType, a as SerializedContentItemWithType } from '../../../shared/stack.L-UFwz2G.mjs';
4
+ import { C as CMSBackendConfig, S as SerializedContentType, a as SerializedContentItemWithType, I as InverseRelation } from '../../../shared/stack.oGOteE6g.mjs';
5
5
 
6
6
  /**
7
7
  * CMS backend plugin
@@ -16,8 +16,8 @@ declare const cmsBackendPlugin: (config: CMSBackendConfig) => _btst_stack_plugin
16
16
  itemCount: number;
17
17
  createdAt: string;
18
18
  updatedAt: string;
19
- name: string;
20
19
  id: string;
20
+ name: string;
21
21
  slug: string;
22
22
  description?: string | undefined;
23
23
  jsonSchema: string;
@@ -63,7 +63,7 @@ declare const cmsBackendPlugin: (config: CMSBackendConfig) => _btst_stack_plugin
63
63
  data: z.ZodObject<{}, z.core.$loose>;
64
64
  }, z.core.$strip>;
65
65
  }, {
66
- parsedData: unknown;
66
+ parsedData: Record<string, unknown>;
67
67
  createdAt: string;
68
68
  updatedAt: string;
69
69
  id: string;
@@ -92,6 +92,70 @@ declare const cmsBackendPlugin: (config: CMSBackendConfig) => _btst_stack_plugin
92
92
  }, {
93
93
  success: boolean;
94
94
  }>;
95
+ getContentItemPopulated: better_call.StrictEndpoint<"/content/:typeSlug/:id/populated", {
96
+ method: "GET";
97
+ params: z.ZodObject<{
98
+ typeSlug: z.ZodString;
99
+ id: z.ZodString;
100
+ }, z.core.$strip>;
101
+ }, {
102
+ _relations: Record<string, SerializedContentItemWithType<Record<string, unknown>>[]>;
103
+ parsedData: Record<string, unknown>;
104
+ contentType?: SerializedContentType;
105
+ createdAt: string;
106
+ updatedAt: string;
107
+ id: string;
108
+ slug: string;
109
+ contentTypeId: string;
110
+ data: string;
111
+ authorId?: string | undefined;
112
+ }>;
113
+ listContentByRelation: better_call.StrictEndpoint<"/content/:typeSlug/by-relation", {
114
+ method: "GET";
115
+ params: z.ZodObject<{
116
+ typeSlug: z.ZodString;
117
+ }, z.core.$strip>;
118
+ query: z.ZodObject<{
119
+ field: z.ZodString;
120
+ targetId: z.ZodString;
121
+ limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
122
+ offset: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
123
+ }, z.core.$strip>;
124
+ }, {
125
+ items: SerializedContentItemWithType<Record<string, unknown>>[];
126
+ total: number;
127
+ limit: number;
128
+ offset: number;
129
+ }>;
130
+ getInverseRelations: better_call.StrictEndpoint<"/content-types/:slug/inverse-relations", {
131
+ method: "GET";
132
+ params: z.ZodObject<{
133
+ slug: z.ZodString;
134
+ }, z.core.$strip>;
135
+ query: z.ZodObject<{
136
+ itemId: z.ZodOptional<z.ZodString>;
137
+ }, z.core.$strip>;
138
+ }, {
139
+ inverseRelations: InverseRelation[];
140
+ }>;
141
+ listInverseRelationItems: better_call.StrictEndpoint<"/content-types/:slug/inverse-relations/:sourceType", {
142
+ method: "GET";
143
+ params: z.ZodObject<{
144
+ slug: z.ZodString;
145
+ sourceType: z.ZodString;
146
+ }, z.core.$strip>;
147
+ query: z.ZodObject<{
148
+ itemId: z.ZodString;
149
+ fieldName: z.ZodString;
150
+ limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
151
+ offset: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
152
+ }, z.core.$strip>;
153
+ }, {
154
+ items: SerializedContentItemWithType<Record<string, unknown>>[];
155
+ total: number;
156
+ limit: number;
157
+ offset: number;
158
+ }>;
95
159
  }>;
96
160
  type CMSApiRouter = ReturnType<ReturnType<typeof cmsBackendPlugin>["routes"]>;
97
161
 
@@ -1,7 +1,7 @@
1
1
  import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
2
2
  import * as better_call from 'better-call';
3
3
  import { z } from 'zod';
4
- import { C as CMSBackendConfig, S as SerializedContentType, a as SerializedContentItemWithType } from '../../../shared/stack.L-UFwz2G.js';
4
+ import { C as CMSBackendConfig, S as SerializedContentType, a as SerializedContentItemWithType, I as InverseRelation } from '../../../shared/stack.oGOteE6g.js';
5
5
 
6
6
  /**
7
7
  * CMS backend plugin
@@ -16,8 +16,8 @@ declare const cmsBackendPlugin: (config: CMSBackendConfig) => _btst_stack_plugin
16
16
  itemCount: number;
17
17
  createdAt: string;
18
18
  updatedAt: string;
19
- name: string;
20
19
  id: string;
20
+ name: string;
21
21
  slug: string;
22
22
  description?: string | undefined;
23
23
  jsonSchema: string;
@@ -63,7 +63,7 @@ declare const cmsBackendPlugin: (config: CMSBackendConfig) => _btst_stack_plugin
63
63
  data: z.ZodObject<{}, z.core.$loose>;
64
64
  }, z.core.$strip>;
65
65
  }, {
66
- parsedData: unknown;
66
+ parsedData: Record<string, unknown>;
67
67
  createdAt: string;
68
68
  updatedAt: string;
69
69
  id: string;
@@ -92,6 +92,70 @@ declare const cmsBackendPlugin: (config: CMSBackendConfig) => _btst_stack_plugin
92
92
  }, {
93
93
  success: boolean;
94
94
  }>;
95
+ getContentItemPopulated: better_call.StrictEndpoint<"/content/:typeSlug/:id/populated", {
96
+ method: "GET";
97
+ params: z.ZodObject<{
98
+ typeSlug: z.ZodString;
99
+ id: z.ZodString;
100
+ }, z.core.$strip>;
101
+ }, {
102
+ _relations: Record<string, SerializedContentItemWithType<Record<string, unknown>>[]>;
103
+ parsedData: Record<string, unknown>;
104
+ contentType?: SerializedContentType;
105
+ createdAt: string;
106
+ updatedAt: string;
107
+ id: string;
108
+ slug: string;
109
+ contentTypeId: string;
110
+ data: string;
111
+ authorId?: string | undefined;
112
+ }>;
113
+ listContentByRelation: better_call.StrictEndpoint<"/content/:typeSlug/by-relation", {
114
+ method: "GET";
115
+ params: z.ZodObject<{
116
+ typeSlug: z.ZodString;
117
+ }, z.core.$strip>;
118
+ query: z.ZodObject<{
119
+ field: z.ZodString;
120
+ targetId: z.ZodString;
121
+ limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
122
+ offset: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
123
+ }, z.core.$strip>;
124
+ }, {
125
+ items: SerializedContentItemWithType<Record<string, unknown>>[];
126
+ total: number;
127
+ limit: number;
128
+ offset: number;
129
+ }>;
130
+ getInverseRelations: better_call.StrictEndpoint<"/content-types/:slug/inverse-relations", {
131
+ method: "GET";
132
+ params: z.ZodObject<{
133
+ slug: z.ZodString;
134
+ }, z.core.$strip>;
135
+ query: z.ZodObject<{
136
+ itemId: z.ZodOptional<z.ZodString>;
137
+ }, z.core.$strip>;
138
+ }, {
139
+ inverseRelations: InverseRelation[];
140
+ }>;
141
+ listInverseRelationItems: better_call.StrictEndpoint<"/content-types/:slug/inverse-relations/:sourceType", {
142
+ method: "GET";
143
+ params: z.ZodObject<{
144
+ slug: z.ZodString;
145
+ sourceType: z.ZodString;
146
+ }, z.core.$strip>;
147
+ query: z.ZodObject<{
148
+ itemId: z.ZodString;
149
+ fieldName: z.ZodString;
150
+ limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
151
+ offset: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
152
+ }, z.core.$strip>;
153
+ }, {
154
+ items: SerializedContentItemWithType<Record<string, unknown>>[];
155
+ total: number;
156
+ limit: number;
157
+ offset: number;
158
+ }>;
95
159
  }>;
96
160
  type CMSApiRouter = ReturnType<ReturnType<typeof cmsBackendPlugin>["routes"]>;
97
161
 
@@ -5,13 +5,17 @@ const cmsHooks = require('../../../../packages/better-stack/src/plugins/cms/clie
5
5
 
6
6
 
7
7
  exports.useContent = cmsHooks.useContent;
8
+ exports.useContentByRelation = cmsHooks.useContentByRelation;
8
9
  exports.useContentItem = cmsHooks.useContentItem;
9
10
  exports.useContentItemBySlug = cmsHooks.useContentItemBySlug;
11
+ exports.useContentItemPopulated = cmsHooks.useContentItemPopulated;
10
12
  exports.useContentType = cmsHooks.useContentType;
11
13
  exports.useContentTypes = cmsHooks.useContentTypes;
12
14
  exports.useCreateContent = cmsHooks.useCreateContent;
13
15
  exports.useDeleteContent = cmsHooks.useDeleteContent;
14
16
  exports.useSuspenseContent = cmsHooks.useSuspenseContent;
17
+ exports.useSuspenseContentByRelation = cmsHooks.useSuspenseContentByRelation;
15
18
  exports.useSuspenseContentItem = cmsHooks.useSuspenseContentItem;
19
+ exports.useSuspenseContentItemPopulated = cmsHooks.useSuspenseContentItemPopulated;
16
20
  exports.useSuspenseContentTypes = cmsHooks.useSuspenseContentTypes;
17
21
  exports.useUpdateContent = cmsHooks.useUpdateContent;
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { S as SerializedContentType, a as SerializedContentItemWithType } from '../../../../shared/stack.L-UFwz2G.cjs';
2
+ import { S as SerializedContentType, a as SerializedContentItemWithType } from '../../../../shared/stack.oGOteE6g.cjs';
3
3
  import 'zod';
4
4
 
5
5
  interface UseContentTypesResult {
@@ -195,6 +195,85 @@ declare function useUpdateContent<TData = Record<string, unknown>>(typeSlug: str
195
195
  declare function useDeleteContent(typeSlug: string): _tanstack_react_query.UseMutationResult<{
196
196
  success: boolean;
197
197
  }, Error, string, unknown>;
198
+ /**
199
+ * Content item with populated relations
200
+ */
201
+ interface ContentItemWithRelations<TData = Record<string, unknown>> extends SerializedContentItemWithType<TData> {
202
+ _relations?: Record<string, SerializedContentItemWithType[]>;
203
+ }
204
+ /**
205
+ * Hook for fetching a content item with its relations populated.
206
+ * Use this when you need to display related items alongside the main item.
207
+ *
208
+ * @template TMap - A type map of content type slugs to their data types
209
+ * @template TSlug - The content type slug (inferred from typeSlug parameter)
210
+ *
211
+ * @example
212
+ * ```typescript
213
+ * type MyCMSTypes = {
214
+ * resource: { name: string; categoryIds: Array<{ id: string }> }
215
+ * category: { name: string }
216
+ * }
217
+ * const { item } = useContentItemPopulated<MyCMSTypes, "resource">("resource", "some-id")
218
+ * // item?._relations?.categoryIds contains populated category items
219
+ * ```
220
+ */
221
+ declare function useContentItemPopulated<TMap extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TSlug extends keyof TMap = keyof TMap>(typeSlug: TSlug & string, id: string): {
222
+ item: ContentItemWithRelations<TMap[TSlug]> | null;
223
+ isLoading: boolean;
224
+ error: Error | null;
225
+ refetch: () => void;
226
+ };
227
+ /**
228
+ * Suspense variant of useContentItemPopulated
229
+ */
230
+ declare function useSuspenseContentItemPopulated<TMap extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TSlug extends keyof TMap = keyof TMap>(typeSlug: TSlug & string, id: string): {
231
+ item: ContentItemWithRelations<TMap[TSlug]> | null;
232
+ refetch: () => Promise<unknown>;
233
+ };
234
+ /**
235
+ * Options for useContentByRelation hook
236
+ */
237
+ interface UseContentByRelationOptions {
238
+ /** Number of items per page (default: 20) */
239
+ limit?: number;
240
+ /** Whether to enable the query (default: true) */
241
+ enabled?: boolean;
242
+ }
243
+ /**
244
+ * Hook for fetching content items that have a specific relation.
245
+ * Useful for "filter by category" functionality.
246
+ *
247
+ * @template TMap - A type map of content type slugs to their data types
248
+ * @template TSlug - The content type slug (inferred from typeSlug parameter)
249
+ *
250
+ * @example
251
+ * ```typescript
252
+ * // Get all resources in a specific category
253
+ * const { items } = useContentByRelation("resource", "categoryIds", categoryId)
254
+ * ```
255
+ */
256
+ declare function useContentByRelation<TMap extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TSlug extends keyof TMap = keyof TMap>(typeSlug: TSlug & string, fieldName: string, targetId: string, options?: UseContentByRelationOptions): {
257
+ items: SerializedContentItemWithType<TMap[TSlug]>[];
258
+ total: number;
259
+ isLoading: boolean;
260
+ error: Error | null;
261
+ loadMore: () => void;
262
+ hasMore: boolean;
263
+ isLoadingMore: boolean;
264
+ refetch: () => void;
265
+ };
266
+ /**
267
+ * Suspense variant of useContentByRelation
268
+ */
269
+ declare function useSuspenseContentByRelation<TMap extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TSlug extends keyof TMap = keyof TMap>(typeSlug: TSlug & string, fieldName: string, targetId: string, options?: UseContentByRelationOptions): {
270
+ items: SerializedContentItemWithType<TMap[TSlug]>[];
271
+ total: number;
272
+ loadMore: () => Promise<unknown>;
273
+ hasMore: boolean;
274
+ isLoadingMore: boolean;
275
+ refetch: () => Promise<unknown>;
276
+ };
198
277
 
199
- export { useContent, useContentItem, useContentItemBySlug, useContentType, useContentTypes, useCreateContent, useDeleteContent, useSuspenseContent, useSuspenseContentItem, useSuspenseContentTypes, useUpdateContent };
200
- export type { UseContentOptions, UseContentResult, UseContentTypesResult };
278
+ export { useContent, useContentByRelation, useContentItem, useContentItemBySlug, useContentItemPopulated, useContentType, useContentTypes, useCreateContent, useDeleteContent, useSuspenseContent, useSuspenseContentByRelation, useSuspenseContentItem, useSuspenseContentItemPopulated, useSuspenseContentTypes, useUpdateContent };
279
+ export type { ContentItemWithRelations, UseContentByRelationOptions, UseContentOptions, UseContentResult, UseContentTypesResult };
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { S as SerializedContentType, a as SerializedContentItemWithType } from '../../../../shared/stack.L-UFwz2G.mjs';
2
+ import { S as SerializedContentType, a as SerializedContentItemWithType } from '../../../../shared/stack.oGOteE6g.mjs';
3
3
  import 'zod';
4
4
 
5
5
  interface UseContentTypesResult {
@@ -195,6 +195,85 @@ declare function useUpdateContent<TData = Record<string, unknown>>(typeSlug: str
195
195
  declare function useDeleteContent(typeSlug: string): _tanstack_react_query.UseMutationResult<{
196
196
  success: boolean;
197
197
  }, Error, string, unknown>;
198
+ /**
199
+ * Content item with populated relations
200
+ */
201
+ interface ContentItemWithRelations<TData = Record<string, unknown>> extends SerializedContentItemWithType<TData> {
202
+ _relations?: Record<string, SerializedContentItemWithType[]>;
203
+ }
204
+ /**
205
+ * Hook for fetching a content item with its relations populated.
206
+ * Use this when you need to display related items alongside the main item.
207
+ *
208
+ * @template TMap - A type map of content type slugs to their data types
209
+ * @template TSlug - The content type slug (inferred from typeSlug parameter)
210
+ *
211
+ * @example
212
+ * ```typescript
213
+ * type MyCMSTypes = {
214
+ * resource: { name: string; categoryIds: Array<{ id: string }> }
215
+ * category: { name: string }
216
+ * }
217
+ * const { item } = useContentItemPopulated<MyCMSTypes, "resource">("resource", "some-id")
218
+ * // item?._relations?.categoryIds contains populated category items
219
+ * ```
220
+ */
221
+ declare function useContentItemPopulated<TMap extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TSlug extends keyof TMap = keyof TMap>(typeSlug: TSlug & string, id: string): {
222
+ item: ContentItemWithRelations<TMap[TSlug]> | null;
223
+ isLoading: boolean;
224
+ error: Error | null;
225
+ refetch: () => void;
226
+ };
227
+ /**
228
+ * Suspense variant of useContentItemPopulated
229
+ */
230
+ declare function useSuspenseContentItemPopulated<TMap extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TSlug extends keyof TMap = keyof TMap>(typeSlug: TSlug & string, id: string): {
231
+ item: ContentItemWithRelations<TMap[TSlug]> | null;
232
+ refetch: () => Promise<unknown>;
233
+ };
234
+ /**
235
+ * Options for useContentByRelation hook
236
+ */
237
+ interface UseContentByRelationOptions {
238
+ /** Number of items per page (default: 20) */
239
+ limit?: number;
240
+ /** Whether to enable the query (default: true) */
241
+ enabled?: boolean;
242
+ }
243
+ /**
244
+ * Hook for fetching content items that have a specific relation.
245
+ * Useful for "filter by category" functionality.
246
+ *
247
+ * @template TMap - A type map of content type slugs to their data types
248
+ * @template TSlug - The content type slug (inferred from typeSlug parameter)
249
+ *
250
+ * @example
251
+ * ```typescript
252
+ * // Get all resources in a specific category
253
+ * const { items } = useContentByRelation("resource", "categoryIds", categoryId)
254
+ * ```
255
+ */
256
+ declare function useContentByRelation<TMap extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TSlug extends keyof TMap = keyof TMap>(typeSlug: TSlug & string, fieldName: string, targetId: string, options?: UseContentByRelationOptions): {
257
+ items: SerializedContentItemWithType<TMap[TSlug]>[];
258
+ total: number;
259
+ isLoading: boolean;
260
+ error: Error | null;
261
+ loadMore: () => void;
262
+ hasMore: boolean;
263
+ isLoadingMore: boolean;
264
+ refetch: () => void;
265
+ };
266
+ /**
267
+ * Suspense variant of useContentByRelation
268
+ */
269
+ declare function useSuspenseContentByRelation<TMap extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TSlug extends keyof TMap = keyof TMap>(typeSlug: TSlug & string, fieldName: string, targetId: string, options?: UseContentByRelationOptions): {
270
+ items: SerializedContentItemWithType<TMap[TSlug]>[];
271
+ total: number;
272
+ loadMore: () => Promise<unknown>;
273
+ hasMore: boolean;
274
+ isLoadingMore: boolean;
275
+ refetch: () => Promise<unknown>;
276
+ };
198
277
 
199
- export { useContent, useContentItem, useContentItemBySlug, useContentType, useContentTypes, useCreateContent, useDeleteContent, useSuspenseContent, useSuspenseContentItem, useSuspenseContentTypes, useUpdateContent };
200
- export type { UseContentOptions, UseContentResult, UseContentTypesResult };
278
+ export { useContent, useContentByRelation, useContentItem, useContentItemBySlug, useContentItemPopulated, useContentType, useContentTypes, useCreateContent, useDeleteContent, useSuspenseContent, useSuspenseContentByRelation, useSuspenseContentItem, useSuspenseContentItemPopulated, useSuspenseContentTypes, useUpdateContent };
279
+ export type { ContentItemWithRelations, UseContentByRelationOptions, UseContentOptions, UseContentResult, UseContentTypesResult };
@@ -1,5 +1,5 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
- import { S as SerializedContentType, a as SerializedContentItemWithType } from '../../../../shared/stack.L-UFwz2G.js';
2
+ import { S as SerializedContentType, a as SerializedContentItemWithType } from '../../../../shared/stack.oGOteE6g.js';
3
3
  import 'zod';
4
4
 
5
5
  interface UseContentTypesResult {
@@ -195,6 +195,85 @@ declare function useUpdateContent<TData = Record<string, unknown>>(typeSlug: str
195
195
  declare function useDeleteContent(typeSlug: string): _tanstack_react_query.UseMutationResult<{
196
196
  success: boolean;
197
197
  }, Error, string, unknown>;
198
+ /**
199
+ * Content item with populated relations
200
+ */
201
+ interface ContentItemWithRelations<TData = Record<string, unknown>> extends SerializedContentItemWithType<TData> {
202
+ _relations?: Record<string, SerializedContentItemWithType[]>;
203
+ }
204
+ /**
205
+ * Hook for fetching a content item with its relations populated.
206
+ * Use this when you need to display related items alongside the main item.
207
+ *
208
+ * @template TMap - A type map of content type slugs to their data types
209
+ * @template TSlug - The content type slug (inferred from typeSlug parameter)
210
+ *
211
+ * @example
212
+ * ```typescript
213
+ * type MyCMSTypes = {
214
+ * resource: { name: string; categoryIds: Array<{ id: string }> }
215
+ * category: { name: string }
216
+ * }
217
+ * const { item } = useContentItemPopulated<MyCMSTypes, "resource">("resource", "some-id")
218
+ * // item?._relations?.categoryIds contains populated category items
219
+ * ```
220
+ */
221
+ declare function useContentItemPopulated<TMap extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TSlug extends keyof TMap = keyof TMap>(typeSlug: TSlug & string, id: string): {
222
+ item: ContentItemWithRelations<TMap[TSlug]> | null;
223
+ isLoading: boolean;
224
+ error: Error | null;
225
+ refetch: () => void;
226
+ };
227
+ /**
228
+ * Suspense variant of useContentItemPopulated
229
+ */
230
+ declare function useSuspenseContentItemPopulated<TMap extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TSlug extends keyof TMap = keyof TMap>(typeSlug: TSlug & string, id: string): {
231
+ item: ContentItemWithRelations<TMap[TSlug]> | null;
232
+ refetch: () => Promise<unknown>;
233
+ };
234
+ /**
235
+ * Options for useContentByRelation hook
236
+ */
237
+ interface UseContentByRelationOptions {
238
+ /** Number of items per page (default: 20) */
239
+ limit?: number;
240
+ /** Whether to enable the query (default: true) */
241
+ enabled?: boolean;
242
+ }
243
+ /**
244
+ * Hook for fetching content items that have a specific relation.
245
+ * Useful for "filter by category" functionality.
246
+ *
247
+ * @template TMap - A type map of content type slugs to their data types
248
+ * @template TSlug - The content type slug (inferred from typeSlug parameter)
249
+ *
250
+ * @example
251
+ * ```typescript
252
+ * // Get all resources in a specific category
253
+ * const { items } = useContentByRelation("resource", "categoryIds", categoryId)
254
+ * ```
255
+ */
256
+ declare function useContentByRelation<TMap extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TSlug extends keyof TMap = keyof TMap>(typeSlug: TSlug & string, fieldName: string, targetId: string, options?: UseContentByRelationOptions): {
257
+ items: SerializedContentItemWithType<TMap[TSlug]>[];
258
+ total: number;
259
+ isLoading: boolean;
260
+ error: Error | null;
261
+ loadMore: () => void;
262
+ hasMore: boolean;
263
+ isLoadingMore: boolean;
264
+ refetch: () => void;
265
+ };
266
+ /**
267
+ * Suspense variant of useContentByRelation
268
+ */
269
+ declare function useSuspenseContentByRelation<TMap extends Record<string, Record<string, unknown>> = Record<string, Record<string, unknown>>, TSlug extends keyof TMap = keyof TMap>(typeSlug: TSlug & string, fieldName: string, targetId: string, options?: UseContentByRelationOptions): {
270
+ items: SerializedContentItemWithType<TMap[TSlug]>[];
271
+ total: number;
272
+ loadMore: () => Promise<unknown>;
273
+ hasMore: boolean;
274
+ isLoadingMore: boolean;
275
+ refetch: () => Promise<unknown>;
276
+ };
198
277
 
199
- export { useContent, useContentItem, useContentItemBySlug, useContentType, useContentTypes, useCreateContent, useDeleteContent, useSuspenseContent, useSuspenseContentItem, useSuspenseContentTypes, useUpdateContent };
200
- export type { UseContentOptions, UseContentResult, UseContentTypesResult };
278
+ export { useContent, useContentByRelation, useContentItem, useContentItemBySlug, useContentItemPopulated, useContentType, useContentTypes, useCreateContent, useDeleteContent, useSuspenseContent, useSuspenseContentByRelation, useSuspenseContentItem, useSuspenseContentItemPopulated, useSuspenseContentTypes, useUpdateContent };
279
+ export type { ContentItemWithRelations, UseContentByRelationOptions, UseContentOptions, UseContentResult, UseContentTypesResult };
@@ -1 +1 @@
1
- export { useContent, useContentItem, useContentItemBySlug, useContentType, useContentTypes, useCreateContent, useDeleteContent, useSuspenseContent, useSuspenseContentItem, useSuspenseContentTypes, useUpdateContent } from '../../../../packages/better-stack/src/plugins/cms/client/hooks/cms-hooks.mjs';
1
+ export { useContent, useContentByRelation, useContentItem, useContentItemBySlug, useContentItemPopulated, useContentType, useContentTypes, useCreateContent, useDeleteContent, useSuspenseContent, useSuspenseContentByRelation, useSuspenseContentItem, useSuspenseContentItemPopulated, useSuspenseContentTypes, useUpdateContent } from '../../../../packages/better-stack/src/plugins/cms/client/hooks/cms-hooks.mjs';
@@ -1,6 +1,6 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
2
  import { createApiClient } from '@btst/stack/plugins/client';
3
- import { S as SerializedContentType, P as PaginatedContentItems, a as SerializedContentItemWithType } from '../../shared/stack.L-UFwz2G.cjs';
3
+ import { S as SerializedContentType, P as PaginatedContentItems, a as SerializedContentItemWithType } from '../../shared/stack.oGOteE6g.cjs';
4
4
  import { CMSApiRouter } from './api/index.cjs';
5
5
  import 'zod';
6
6
  import '@btst/stack/plugins/api';
@@ -1,6 +1,6 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
2
  import { createApiClient } from '@btst/stack/plugins/client';
3
- import { S as SerializedContentType, P as PaginatedContentItems, a as SerializedContentItemWithType } from '../../shared/stack.L-UFwz2G.mjs';
3
+ import { S as SerializedContentType, P as PaginatedContentItems, a as SerializedContentItemWithType } from '../../shared/stack.oGOteE6g.mjs';
4
4
  import { CMSApiRouter } from './api/index.mjs';
5
5
  import 'zod';
6
6
  import '@btst/stack/plugins/api';
@@ -1,6 +1,6 @@
1
1
  import * as _tanstack_react_query from '@tanstack/react-query';
2
2
  import { createApiClient } from '@btst/stack/plugins/client';
3
- import { S as SerializedContentType, P as PaginatedContentItems, a as SerializedContentItemWithType } from '../../shared/stack.L-UFwz2G.js';
3
+ import { S as SerializedContentType, P as PaginatedContentItems, a as SerializedContentItemWithType } from '../../shared/stack.oGOteE6g.js';
4
4
  import { CMSApiRouter } from './api/index.js';
5
5
  import 'zod';
6
6
  import '@btst/stack/plugins/api';
@@ -97,8 +97,8 @@ declare const formBuilderBackendPlugin: (config?: FormBuilderBackendConfig) => _
97
97
  };
98
98
  submittedAt: string;
99
99
  id: string;
100
- data: string;
101
100
  formId: string;
101
+ data: string;
102
102
  submittedBy?: string | undefined;
103
103
  ipAddress?: string | undefined;
104
104
  userAgent?: string | undefined;
@@ -97,8 +97,8 @@ declare const formBuilderBackendPlugin: (config?: FormBuilderBackendConfig) => _
97
97
  };
98
98
  submittedAt: string;
99
99
  id: string;
100
- data: string;
101
100
  formId: string;
101
+ data: string;
102
102
  submittedBy?: string | undefined;
103
103
  ipAddress?: string | undefined;
104
104
  userAgent?: string | undefined;
@@ -97,8 +97,8 @@ declare const formBuilderBackendPlugin: (config?: FormBuilderBackendConfig) => _
97
97
  };
98
98
  submittedAt: string;
99
99
  id: string;
100
- data: string;
101
100
  formId: string;
101
+ data: string;
102
102
  submittedBy?: string | undefined;
103
103
  ipAddress?: string | undefined;
104
104
  userAgent?: string | undefined;
@@ -1,6 +1,6 @@
1
1
  import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
2
2
  import * as better_call from 'better-call';
3
- import { a as BetterStackContext } from '../../../shared/stack.CSce37mX.cjs';
3
+ import { a as BetterStackContext } from '../../../shared/stack.u9iYV6vt.cjs';
4
4
  import '@btst/yar';
5
5
  import '@btst/db';
6
6
 
@@ -1,6 +1,6 @@
1
1
  import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
2
2
  import * as better_call from 'better-call';
3
- import { a as BetterStackContext } from '../../../shared/stack.CSce37mX.mjs';
3
+ import { a as BetterStackContext } from '../../../shared/stack.u9iYV6vt.mjs';
4
4
  import '@btst/yar';
5
5
  import '@btst/db';
6
6
 
@@ -1,6 +1,6 @@
1
1
  import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
2
2
  import * as better_call from 'better-call';
3
- import { a as BetterStackContext } from '../../../shared/stack.CSce37mX.js';
3
+ import { a as BetterStackContext } from '../../../shared/stack.u9iYV6vt.js';
4
4
  import '@btst/yar';
5
5
  import '@btst/db';
6
6
 
@@ -0,0 +1,10 @@
1
+ 'use strict';
2
+
3
+ const plugin = require('../../../packages/better-stack/src/plugins/route-docs/client/plugin.cjs');
4
+
5
+
6
+
7
+ exports.ROUTE_DOCS_QUERY_KEY = plugin.ROUTE_DOCS_QUERY_KEY;
8
+ exports.generateSchema = plugin.generateSchema;
9
+ exports.getStoredContext = plugin.getStoredContext;
10
+ exports.routeDocsClientPlugin = plugin.routeDocsClientPlugin;