@btst/stack 5.0.0 → 5.1.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 (113) 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.d.cts +2 -2
  5. package/dist/client/index.d.mts +2 -2
  6. package/dist/client/index.d.ts +2 -2
  7. package/dist/context/index.d.cts +1 -1
  8. package/dist/context/index.d.mts +1 -1
  9. package/dist/context/index.d.ts +1 -1
  10. package/dist/index.d.cts +1 -1
  11. package/dist/index.d.mts +1 -1
  12. package/dist/index.d.ts +1 -1
  13. package/dist/packages/stack/src/plugins/cms/api/getters.cjs +142 -6
  14. package/dist/packages/stack/src/plugins/cms/api/getters.mjs +139 -8
  15. package/dist/packages/stack/src/plugins/cms/api/operations.cjs +67 -61
  16. package/dist/packages/stack/src/plugins/cms/api/operations.mjs +69 -63
  17. package/dist/packages/stack/src/plugins/cms/api/plugin.cjs +26 -8
  18. package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +27 -9
  19. package/dist/packages/stack/src/plugins/cms/api/query-key-defs.cjs +15 -1
  20. package/dist/packages/stack/src/plugins/cms/api/query-key-defs.mjs +14 -2
  21. package/dist/packages/stack/src/plugins/cms/client/hooks/cms-hooks.cjs +45 -24
  22. package/dist/packages/stack/src/plugins/cms/client/hooks/cms-hooks.mjs +45 -24
  23. package/dist/packages/stack/src/plugins/cms/schemas.cjs +22 -0
  24. package/dist/packages/stack/src/plugins/cms/schemas.mjs +20 -1
  25. package/dist/plugins/api/index.d.cts +2 -2
  26. package/dist/plugins/api/index.d.mts +2 -2
  27. package/dist/plugins/api/index.d.ts +2 -2
  28. package/dist/plugins/blog/api/index.d.cts +2 -2
  29. package/dist/plugins/blog/api/index.d.mts +2 -2
  30. package/dist/plugins/blog/api/index.d.ts +2 -2
  31. package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
  32. package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
  33. package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
  34. package/dist/plugins/blog/client/index.d.cts +2 -2
  35. package/dist/plugins/blog/client/index.d.mts +2 -2
  36. package/dist/plugins/blog/client/index.d.ts +2 -2
  37. package/dist/plugins/blog/query-keys.d.cts +2 -2
  38. package/dist/plugins/blog/query-keys.d.mts +2 -2
  39. package/dist/plugins/blog/query-keys.d.ts +2 -2
  40. package/dist/plugins/client/index.d.cts +2 -2
  41. package/dist/plugins/client/index.d.mts +2 -2
  42. package/dist/plugins/client/index.d.ts +2 -2
  43. package/dist/plugins/cms/api/index.cjs +1 -0
  44. package/dist/plugins/cms/api/index.d.cts +43 -11
  45. package/dist/plugins/cms/api/index.d.mts +43 -11
  46. package/dist/plugins/cms/api/index.d.ts +43 -11
  47. package/dist/plugins/cms/api/index.mjs +1 -1
  48. package/dist/plugins/cms/client/hooks/index.d.cts +90 -45
  49. package/dist/plugins/cms/client/hooks/index.d.mts +90 -45
  50. package/dist/plugins/cms/client/hooks/index.d.ts +90 -45
  51. package/dist/plugins/cms/client/index.d.cts +2 -1
  52. package/dist/plugins/cms/client/index.d.mts +2 -1
  53. package/dist/plugins/cms/client/index.d.ts +2 -1
  54. package/dist/plugins/cms/query-keys.cjs +69 -13
  55. package/dist/plugins/cms/query-keys.d.cts +89 -212
  56. package/dist/plugins/cms/query-keys.d.mts +89 -212
  57. package/dist/plugins/cms/query-keys.d.ts +89 -212
  58. package/dist/plugins/cms/query-keys.mjs +70 -14
  59. package/dist/plugins/kanban/client/index.d.cts +1 -1
  60. package/dist/plugins/kanban/client/index.d.mts +1 -1
  61. package/dist/plugins/kanban/client/index.d.ts +1 -1
  62. package/dist/plugins/route-docs/client/index.d.cts +1 -1
  63. package/dist/plugins/route-docs/client/index.d.mts +1 -1
  64. package/dist/plugins/route-docs/client/index.d.ts +1 -1
  65. package/dist/plugins/ui-builder/client/hooks/index.d.cts +3 -3
  66. package/dist/plugins/ui-builder/client/hooks/index.d.mts +3 -3
  67. package/dist/plugins/ui-builder/client/hooks/index.d.ts +3 -3
  68. package/dist/plugins/ui-builder/client/index.d.cts +3 -3
  69. package/dist/plugins/ui-builder/client/index.d.mts +3 -3
  70. package/dist/plugins/ui-builder/client/index.d.ts +3 -3
  71. package/dist/plugins/ui-builder/query-keys.d.cts +4 -3
  72. package/dist/plugins/ui-builder/query-keys.d.mts +4 -3
  73. package/dist/plugins/ui-builder/query-keys.d.ts +4 -3
  74. package/dist/shared/{stack.DMj68qY0.d.mts → stack.B2jlVVhD.d.mts} +5 -5
  75. package/dist/shared/{stack.Cvnj99cs.d.ts → stack.BB9tubJJ.d.ts} +9 -3
  76. package/dist/shared/{stack.Bt3WG2yb.d.cts → stack.BWduIMKG.d.cts} +35 -35
  77. package/dist/shared/stack.Bw09Lg2z.d.ts +1420 -0
  78. package/dist/shared/{stack.CkEz7vSt.d.mts → stack.C2Pvl-RS.d.mts} +9 -3
  79. package/dist/shared/{stack.C2l2wd_X.d.ts → stack.Ch9-ppmQ.d.ts} +35 -35
  80. package/dist/shared/{stack.Ht8mhDj5.d.cts → stack.D17yFglU.d.cts} +5 -5
  81. package/dist/shared/{stack.CiD115Ov.d.mts → stack.D6fPBfYe.d.mts} +35 -35
  82. package/dist/shared/stack.DFGj0gb7.d.mts +1420 -0
  83. package/dist/shared/{stack.pi0FxoEa.d.ts → stack.Dcfg4GNN.d.ts} +5 -5
  84. package/dist/shared/{stack.3rxARhgS.d.cts → stack.DrB3L7Ih.d.cts} +52 -3
  85. package/dist/shared/{stack.3rxARhgS.d.mts → stack.DrB3L7Ih.d.mts} +52 -3
  86. package/dist/shared/{stack.3rxARhgS.d.ts → stack.DrB3L7Ih.d.ts} +52 -3
  87. package/dist/shared/stack.NNrBKBkM.d.cts +1420 -0
  88. package/dist/shared/{stack.mRRyZBUg.d.cts → stack.Rb87lHqK.d.cts} +9 -3
  89. package/package.json +1 -1
  90. package/src/__tests__/cms-query-keys.test.ts +57 -0
  91. package/src/plugins/api/index.ts +1 -0
  92. package/src/plugins/api/operation.ts +16 -3
  93. package/src/plugins/cms/__tests__/authorization.test.ts +652 -187
  94. package/src/plugins/cms/__tests__/client-runtime.browser.test.tsx +655 -0
  95. package/src/plugins/cms/__tests__/content-read.typecheck.ts +351 -0
  96. package/src/plugins/cms/__tests__/getters.test.ts +286 -0
  97. package/src/plugins/cms/api/getters.ts +270 -12
  98. package/src/plugins/cms/api/index.ts +10 -0
  99. package/src/plugins/cms/api/operations.ts +163 -75
  100. package/src/plugins/cms/api/plugin.ts +50 -12
  101. package/src/plugins/cms/api/query-key-defs.ts +29 -2
  102. package/src/plugins/cms/client/hooks/cms-hooks.tsx +400 -91
  103. package/src/plugins/cms/client/index.ts +9 -0
  104. package/src/plugins/cms/query-keys.ts +171 -16
  105. package/src/plugins/cms/schemas.ts +30 -0
  106. package/src/plugins/cms/types.ts +49 -2
  107. package/src/plugins/media/__tests__/identity-partition.test.tsx +26 -16
  108. package/dist/shared/stack.CAmVUwjV.d.cts +0 -764
  109. package/dist/shared/stack.CQK02ujt.d.ts +0 -764
  110. package/dist/shared/stack.D9x1fR5a.d.mts +0 -764
  111. package/dist/shared/{stack.CKc_Bais.d.cts → stack.Csi-4Mgz.d.cts} +7 -7
  112. package/dist/shared/{stack.CKc_Bais.d.mts → stack.Csi-4Mgz.d.mts} +7 -7
  113. package/dist/shared/{stack.CKc_Bais.d.ts → stack.Csi-4Mgz.d.ts} +7 -7
@@ -1,16 +1,16 @@
1
- import * as _btst_stack_plugins_client from '@btst/stack/plugins/client';
2
- import { createApiClient } from '@btst/stack/plugins/client';
3
- import { a as ContentListDiscriminator } from '../../shared/stack.CQK02ujt.js';
1
+ import { a as ContentListDiscriminator } from '../../shared/stack.Bw09Lg2z.js';
4
2
  import { CMSApiRouter } from './api/index.js';
5
- import { S as SerializedContentType, I as InverseRelation, a as SerializedContentItemWithType, P as PaginatedContentItems } from '../../shared/stack.3rxARhgS.js';
6
- import '@btst/stack/plugins/api';
3
+ import { createApiClient, createResourceQueryKeys } from '@btst/stack/plugins/client';
4
+ import { S as SerializedContentType, I as InverseRelation, b as SerializedContentItemWithType } from '../../shared/stack.DrB3L7Ih.js';
5
+ import { CMSReadOptions, CMSReadView, PaginatedContentItems, CMSContentFields, CMSContentItemResult } from './api/index.js';
7
6
  import '../../authorization/index.js';
8
7
  import 'zod';
8
+ import '@btst/stack/plugins/api';
9
9
  import 'better-call';
10
10
  import '@tanstack/react-query';
11
11
 
12
12
  /** Params for the paginated content list (one page per `limit`). */
13
- interface ContentListParams {
13
+ interface ContentListParams extends CMSReadOptions {
14
14
  typeSlug: string;
15
15
  limit?: number;
16
16
  /**
@@ -22,12 +22,12 @@ interface ContentListParams {
22
22
  /** Free-text search across item slugs and data values */
23
23
  search?: string;
24
24
  }
25
- interface ContentOptionsParams {
25
+ interface ContentOptionsParams extends CMSReadOptions {
26
26
  typeSlug: string;
27
27
  search?: string;
28
28
  limit?: number;
29
29
  }
30
- interface ContentByRelationParams {
30
+ interface ContentByRelationParams extends CMSReadOptions {
31
31
  typeSlug: string;
32
32
  field: string;
33
33
  targetId: string;
@@ -37,11 +37,13 @@ interface InverseRelationsParams {
37
37
  slug: string;
38
38
  itemId: string;
39
39
  }
40
- interface InverseRelationItemsParams {
40
+ interface InverseRelationItemsParams extends CMSReadOptions {
41
41
  slug: string;
42
42
  sourceType: string;
43
43
  itemId: string;
44
44
  fieldName: string;
45
+ limit?: number;
46
+ offset?: number;
45
47
  }
46
48
  /**
47
49
  * CMS resource declaration — the single source of truth for query keys,
@@ -92,8 +94,17 @@ declare const cmsResources: {
92
94
  query: (p: InverseRelationItemsParams) => {
93
95
  itemId: string;
94
96
  fieldName: string;
97
+ limit: number;
98
+ offset: number;
99
+ view: CMSReadView;
100
+ fields: string | undefined;
95
101
  };
96
- key: (p: InverseRelationItemsParams) => string[];
102
+ key: (p: InverseRelationItemsParams) => (string | {
103
+ fields?: string[] | undefined;
104
+ view?: "content" | undefined;
105
+ limit: number;
106
+ offset: number;
107
+ })[];
97
108
  select: (data: any) => {
98
109
  items: SerializedContentItemWithType[];
99
110
  total: number;
@@ -111,6 +122,8 @@ declare const cmsResources: {
111
122
  query: (p: ContentListParams) => {
112
123
  limit: number;
113
124
  search: string | undefined;
125
+ view: CMSReadView;
126
+ fields: string | undefined;
114
127
  };
115
128
  key: (p: ContentListParams) => ContentListDiscriminator[];
116
129
  select: (data: any, _p: ContentListParams) => PaginatedContentItems;
@@ -120,24 +133,36 @@ declare const cmsResources: {
120
133
  };
121
134
  detail: {
122
135
  path: string;
123
- params: (typeSlug: string, id: string) => {
136
+ params: (typeSlug: string, id: string, _options?: CMSReadOptions) => {
124
137
  typeSlug: string;
125
138
  id: string;
126
139
  };
127
- key: (typeSlug: string, id: string) => string[];
128
- select: (data: any, _typeSlug: string, _id: string) => SerializedContentItemWithType | null;
140
+ query: (_typeSlug: string, _id: string, options?: CMSReadOptions) => {
141
+ view: CMSReadView;
142
+ fields: string | undefined;
143
+ };
144
+ key: (typeSlug: string, id: string, options?: CMSReadOptions) => (string | {
145
+ fields?: string[] | undefined;
146
+ view?: "content" | undefined;
147
+ })[];
148
+ select: (data: any, _typeSlug: string, _id: string, _options?: CMSReadOptions) => SerializedContentItemWithType | null;
129
149
  skip: (typeSlug: string, id: string) => boolean;
130
150
  };
131
151
  bySlug: {
132
152
  path: string;
133
- params: (typeSlug: string, _slug: string) => {
153
+ params: (typeSlug: string, _slug: string, _options?: CMSReadOptions) => {
134
154
  typeSlug: string;
135
155
  };
136
- query: (_typeSlug: string, slug: string) => {
156
+ query: (_typeSlug: string, slug: string, options?: CMSReadOptions) => {
157
+ view: CMSReadView;
158
+ fields: string | undefined;
137
159
  slug: string;
138
160
  limit: number;
139
161
  };
140
- key: (typeSlug: string, slug: string) => string[];
162
+ key: (typeSlug: string, slug: string, options?: CMSReadOptions) => (string | {
163
+ fields?: string[] | undefined;
164
+ view?: "content" | undefined;
165
+ })[];
141
166
  select: (data: any) => SerializedContentItemWithType | null;
142
167
  skip: (typeSlug: string, slug: string) => boolean;
143
168
  };
@@ -160,8 +185,15 @@ declare const cmsResources: {
160
185
  field: string;
161
186
  targetId: string;
162
187
  limit: number;
188
+ view: CMSReadView;
189
+ fields: string | undefined;
163
190
  };
164
- key: (p: ContentByRelationParams) => string[];
191
+ key: (p: ContentByRelationParams) => (string | {
192
+ fields?: string[] | undefined;
193
+ view?: "content" | undefined;
194
+ limit: number;
195
+ offset: number;
196
+ })[];
165
197
  select: (data: any, _p: ContentByRelationParams) => PaginatedContentItems;
166
198
  infinite: true;
167
199
  pageSize: (p: ContentByRelationParams) => number;
@@ -175,8 +207,13 @@ declare const cmsResources: {
175
207
  query: (p: ContentOptionsParams) => {
176
208
  search: string | undefined;
177
209
  limit: number;
210
+ view: CMSReadView;
211
+ fields: string | undefined;
178
212
  };
179
- key: (p: ContentOptionsParams) => (string | number | undefined)[];
213
+ key: (p: ContentOptionsParams) => (string | number | {
214
+ fields?: string[] | undefined;
215
+ view?: "content" | undefined;
216
+ } | undefined)[];
180
217
  select: (data: any, _p: ContentOptionsParams) => SerializedContentItemWithType[];
181
218
  };
182
219
  };
@@ -247,204 +284,44 @@ declare const cmsResources: {
247
284
  };
248
285
  };
249
286
  };
250
- /**
251
- * Create CMS query keys for React Query
252
- * Used by consumers and SSR loaders to fetch content types and content items
253
- */
254
- declare function createCMSQueryKeys(client: ReturnType<typeof createApiClient<CMSApiRouter>>, headers?: HeadersInit): _btst_stack_plugins_client.ResourceQueryKeys<{
255
- cmsTypes: {
256
- queries: {
257
- list: {
258
- path: string;
259
- key: () => string[];
260
- select: (data: any) => (SerializedContentType & {
261
- itemCount: number;
262
- })[];
263
- };
264
- detail: {
265
- path: string;
266
- params: (slug: string) => {
267
- slug: string;
268
- };
269
- key: (slug: string) => string[];
270
- select: (data: any, _slug: string) => SerializedContentType | null;
271
- skip: (slug: string) => boolean;
272
- };
273
- inverseRelations: {
274
- path: string;
275
- params: (p: InverseRelationsParams) => {
276
- slug: string;
277
- };
278
- query: (p: InverseRelationsParams) => {
279
- itemId: string;
280
- };
281
- key: (p: InverseRelationsParams) => string[];
282
- select: (data: any) => InverseRelation[];
283
- };
284
- inverseRelationItems: {
285
- path: string;
286
- params: (p: InverseRelationItemsParams) => {
287
- slug: string;
288
- sourceType: string;
289
- };
290
- query: (p: InverseRelationItemsParams) => {
291
- itemId: string;
292
- fieldName: string;
293
- };
294
- key: (p: InverseRelationItemsParams) => string[];
295
- select: (data: any) => {
296
- items: SerializedContentItemWithType[];
297
- total: number;
298
- };
299
- };
300
- };
287
+ type CMSResourceQueryKeys = ReturnType<typeof createResourceQueryKeys<typeof cmsResources>>;
288
+ type ContentQueryResult<TData> = {
289
+ queryKey: readonly unknown[];
290
+ queryFn: (context?: {
291
+ pageParam?: unknown;
292
+ }) => Promise<TData>;
293
+ };
294
+ type CMSItemQueryEntry = {
295
+ <TView extends CMSReadView = undefined, const TFields extends CMSContentFields = undefined>(typeSlug: string, identity: string, options?: CMSReadOptions<TView, TFields>): ContentQueryResult<CMSContentItemResult<Record<string, unknown>, TView, TFields> | null>;
296
+ _def: readonly [string, string];
297
+ };
298
+ type CMSRelationQueryEntry<TParams> = {
299
+ <TView extends CMSReadView = undefined, const TFields extends CMSContentFields = undefined>(params: Omit<TParams, "view" | "fields"> & CMSReadOptions<TView, TFields>): ContentQueryResult<PaginatedContentItems<Record<string, unknown>, TView, TFields>>;
300
+ _def: readonly [string, string];
301
+ };
302
+ type CMSQueryKeys = Omit<CMSResourceQueryKeys, "cmsContent" | "cmsTypes"> & {
303
+ cmsTypes: Omit<CMSResourceQueryKeys["cmsTypes"], "inverseRelationItems"> & {
304
+ inverseRelationItems: CMSRelationQueryEntry<InverseRelationItemsParams>;
301
305
  };
302
- cmsContent: {
303
- queries: {
304
- list: {
305
- path: string;
306
- params: (p: ContentListParams) => {
307
- typeSlug: string;
308
- };
309
- query: (p: ContentListParams) => {
310
- limit: number;
311
- search: string | undefined;
312
- };
313
- key: (p: ContentListParams) => ContentListDiscriminator[];
314
- select: (data: any, _p: ContentListParams) => PaginatedContentItems;
315
- infinite: true;
316
- pageSize: (p: ContentListParams) => number;
317
- nextPageParam: (lastPage: PaginatedContentItems, allPages: PaginatedContentItems[], p: ContentListParams) => number | undefined;
318
- };
319
- detail: {
320
- path: string;
321
- params: (typeSlug: string, id: string) => {
322
- typeSlug: string;
323
- id: string;
324
- };
325
- key: (typeSlug: string, id: string) => string[];
326
- select: (data: any, _typeSlug: string, _id: string) => SerializedContentItemWithType | null;
327
- skip: (typeSlug: string, id: string) => boolean;
328
- };
329
- bySlug: {
330
- path: string;
331
- params: (typeSlug: string, _slug: string) => {
332
- typeSlug: string;
333
- };
334
- query: (_typeSlug: string, slug: string) => {
335
- slug: string;
336
- limit: number;
337
- };
338
- key: (typeSlug: string, slug: string) => string[];
339
- select: (data: any) => SerializedContentItemWithType | null;
340
- skip: (typeSlug: string, slug: string) => boolean;
341
- };
342
- populated: {
343
- path: string;
344
- params: (typeSlug: string, id: string) => {
345
- typeSlug: string;
346
- id: string;
347
- };
348
- key: (typeSlug: string, id: string) => string[];
349
- select: (data: any) => SerializedContentItemWithType | null;
350
- skip: (typeSlug: string, id: string) => boolean;
351
- };
352
- byRelation: {
353
- path: string;
354
- params: (p: ContentByRelationParams) => {
355
- typeSlug: string;
356
- };
357
- query: (p: ContentByRelationParams) => {
358
- field: string;
359
- targetId: string;
360
- limit: number;
361
- };
362
- key: (p: ContentByRelationParams) => string[];
363
- select: (data: any, _p: ContentByRelationParams) => PaginatedContentItems;
364
- infinite: true;
365
- pageSize: (p: ContentByRelationParams) => number;
366
- nextPageParam: (lastPage: PaginatedContentItems, allPages: PaginatedContentItems[], p: ContentByRelationParams) => number | undefined;
367
- };
368
- options: {
369
- path: string;
370
- params: (p: ContentOptionsParams) => {
371
- typeSlug: string;
372
- };
373
- query: (p: ContentOptionsParams) => {
374
- search: string | undefined;
375
- limit: number;
376
- };
377
- key: (p: ContentOptionsParams) => (string | number | undefined)[];
378
- select: (data: any, _p: ContentOptionsParams) => SerializedContentItemWithType[];
379
- };
306
+ cmsContent: Omit<CMSResourceQueryKeys["cmsContent"], "list" | "detail" | "bySlug" | "byRelation" | "options"> & {
307
+ list: {
308
+ <TView extends CMSReadView = undefined, const TFields extends CMSContentFields = undefined>(params: Omit<ContentListParams, "view" | "fields"> & CMSReadOptions<TView, TFields>): ContentQueryResult<PaginatedContentItems<Record<string, unknown>, TView, TFields>>;
309
+ _def: readonly [string, string];
380
310
  };
381
- mutations: {
382
- create: {
383
- path: string;
384
- method: "POST";
385
- input: (vars: {
386
- typeSlug: string;
387
- slug: string;
388
- data: Record<string, unknown>;
389
- }) => {
390
- params: {
391
- typeSlug: string;
392
- };
393
- body: {
394
- slug: string;
395
- data: Record<string, unknown>;
396
- };
397
- };
398
- select: (data: any) => SerializedContentItemWithType | null;
399
- invalidates: string[];
400
- };
401
- update: {
402
- path: string;
403
- method: "PUT";
404
- input: (vars: {
405
- typeSlug: string;
406
- id: string;
407
- data: {
408
- slug?: string;
409
- data?: Record<string, unknown>;
410
- };
411
- }) => {
412
- params: {
413
- typeSlug: string;
414
- id: string;
415
- };
416
- body: {
417
- slug?: string;
418
- data?: Record<string, unknown>;
419
- };
420
- };
421
- select: (data: any) => SerializedContentItemWithType | null;
422
- invalidates: string[];
423
- setData: {
424
- query: string;
425
- args: (updated: SerializedContentItemWithType | null) => string[] | null;
426
- };
427
- };
428
- delete: {
429
- path: string;
430
- method: "DELETE";
431
- input: (vars: {
432
- typeSlug: string;
433
- id: string;
434
- }) => {
435
- params: {
436
- typeSlug: string;
437
- id: string;
438
- };
439
- };
440
- select: (data: any) => {
441
- success: boolean;
442
- };
443
- invalidates: string[];
444
- };
311
+ options: {
312
+ <TView extends CMSReadView = undefined, const TFields extends CMSContentFields = undefined>(params: Omit<ContentOptionsParams, "view" | "fields"> & CMSReadOptions<TView, TFields>): ContentQueryResult<CMSContentItemResult<Record<string, unknown>, TView, TFields>[]>;
313
+ _def: readonly [string, string];
445
314
  };
315
+ detail: CMSItemQueryEntry;
316
+ bySlug: CMSItemQueryEntry;
317
+ byRelation: CMSRelationQueryEntry<ContentByRelationParams>;
446
318
  };
447
- }>;
319
+ };
320
+ /**
321
+ * Create CMS query keys for React Query
322
+ * Used by consumers and SSR loaders to fetch content types and content items
323
+ */
324
+ declare function createCMSQueryKeys(client: ReturnType<typeof createApiClient<CMSApiRouter>>, headers?: HeadersInit): CMSQueryKeys;
448
325
 
449
326
  export { cmsResources, createCMSQueryKeys };
450
327
  export type { ContentListParams };
@@ -1,9 +1,21 @@
1
+ import { normalizeContentFields } from '../../packages/stack/src/plugins/cms/schemas.mjs';
1
2
  import { createResourceQueryKeys } from '@btst/stack/plugins/client';
2
- import { contentListDiscriminator } from '../../packages/stack/src/plugins/cms/api/query-key-defs.mjs';
3
+ import { contentReadKey, contentListDiscriminator, contentReadDiscriminator } from '../../packages/stack/src/plugins/cms/api/query-key-defs.mjs';
3
4
 
4
5
  function normalizeSearch(search) {
5
6
  return search !== void 0 && search.trim() === "" ? void 0 : search;
6
7
  }
8
+ function contentReadQuery(options) {
9
+ return {
10
+ view: options?.view,
11
+ fields: options?.fields === void 0 ? void 0 : JSON.stringify(normalizeContentFields(options.fields))
12
+ };
13
+ }
14
+ function relationPageKey(params) {
15
+ const limit = params.limit ?? 20;
16
+ const offset = params.offset ?? 0;
17
+ return limit === 20 && offset === 0 && !params.view && params.fields === void 0 ? [] : [{ limit, offset, ...contentReadDiscriminator(params) }];
18
+ }
7
19
  function paginatedNextPageParam(lastPage, allPages, limit) {
8
20
  const items = Array.isArray(lastPage?.items) ? lastPage.items : [];
9
21
  if (items.length < limit) return void 0;
@@ -44,14 +56,18 @@ const cmsResources = {
44
56
  sourceType: p.sourceType
45
57
  }),
46
58
  query: (p) => ({
59
+ ...contentReadQuery(p),
47
60
  itemId: p.itemId,
48
- fieldName: p.fieldName
61
+ fieldName: p.fieldName,
62
+ limit: p.limit ?? 20,
63
+ offset: p.offset ?? 0
49
64
  }),
50
65
  key: (p) => [
51
66
  p.slug,
52
67
  p.sourceType,
53
68
  p.itemId,
54
- p.fieldName
69
+ p.fieldName,
70
+ ...relationPageKey(p)
55
71
  ],
56
72
  select: (data) => data ?? { items: [], total: 0 }
57
73
  }
@@ -63,6 +79,7 @@ const cmsResources = {
63
79
  path: "/content/:typeSlug",
64
80
  params: (p) => ({ typeSlug: p.typeSlug }),
65
81
  query: (p) => ({
82
+ ...contentReadQuery(p),
66
83
  limit: p.limit ?? 20,
67
84
  search: normalizeSearch(p.search)
68
85
  }),
@@ -74,16 +91,33 @@ const cmsResources = {
74
91
  },
75
92
  detail: {
76
93
  path: "/content/:typeSlug/:id",
77
- params: (typeSlug, id) => ({ typeSlug, id }),
78
- key: (typeSlug, id) => [typeSlug, id],
79
- select: (data, _typeSlug, _id) => data ?? null,
94
+ params: (typeSlug, id, _options) => ({
95
+ typeSlug,
96
+ id
97
+ }),
98
+ query: (_typeSlug, _id, options) => contentReadQuery(options),
99
+ key: (typeSlug, id, options) => [
100
+ typeSlug,
101
+ id,
102
+ ...contentReadKey(options)
103
+ ],
104
+ select: (data, _typeSlug, _id, _options) => data ?? null,
80
105
  skip: (typeSlug, id) => !typeSlug || !id
81
106
  },
82
107
  bySlug: {
83
108
  path: "/content/:typeSlug",
84
- params: (typeSlug, _slug) => ({ typeSlug }),
85
- query: (_typeSlug, slug) => ({ slug, limit: 1 }),
86
- key: (typeSlug, slug) => ["bySlug", typeSlug, slug],
109
+ params: (typeSlug, _slug, _options) => ({ typeSlug }),
110
+ query: (_typeSlug, slug, options) => ({
111
+ slug,
112
+ limit: 1,
113
+ ...contentReadQuery(options)
114
+ }),
115
+ key: (typeSlug, slug, options) => [
116
+ "bySlug",
117
+ typeSlug,
118
+ slug,
119
+ ...contentReadKey(options)
120
+ ],
87
121
  select: (data) => data?.items?.[0] ?? null,
88
122
  skip: (typeSlug, slug) => !typeSlug || !slug
89
123
  },
@@ -98,11 +132,17 @@ const cmsResources = {
98
132
  path: "/content/:typeSlug/by-relation",
99
133
  params: (p) => ({ typeSlug: p.typeSlug }),
100
134
  query: (p) => ({
135
+ ...contentReadQuery(p),
101
136
  field: p.field,
102
137
  targetId: p.targetId,
103
138
  limit: p.limit ?? 20
104
139
  }),
105
- key: (p) => [p.typeSlug, p.field, p.targetId],
140
+ key: (p) => [
141
+ p.typeSlug,
142
+ p.field,
143
+ p.targetId,
144
+ ...relationPageKey(p)
145
+ ],
106
146
  select: (data, _p) => data,
107
147
  infinite: true,
108
148
  pageSize: (p) => p.limit ?? 20,
@@ -113,6 +153,7 @@ const cmsResources = {
113
153
  path: "/content/:typeSlug",
114
154
  params: (p) => ({ typeSlug: p.typeSlug }),
115
155
  query: (p) => ({
156
+ ...contentReadQuery(p),
116
157
  search: normalizeSearch(p.search),
117
158
  limit: p.limit ?? 50
118
159
  }),
@@ -120,7 +161,8 @@ const cmsResources = {
120
161
  "options",
121
162
  p.typeSlug,
122
163
  normalizeSearch(p.search),
123
- p.limit ?? 50
164
+ p.limit ?? 50,
165
+ ...contentReadKey(p)
124
166
  ],
125
167
  select: (data, _p) => data?.items ?? []
126
168
  }
@@ -134,7 +176,12 @@ const cmsResources = {
134
176
  body: { slug: vars.slug, data: vars.data }
135
177
  }),
136
178
  select: (data) => data,
137
- invalidates: ["cmsContent.list", "cmsTypes.list"]
179
+ invalidates: [
180
+ "cmsContent",
181
+ "cmsTypes.list",
182
+ "cmsTypes.inverseRelationItems",
183
+ "cmsTypes.inverseRelations"
184
+ ]
138
185
  },
139
186
  update: {
140
187
  path: "@put/content/:typeSlug/:id",
@@ -144,7 +191,11 @@ const cmsResources = {
144
191
  body: vars.data
145
192
  }),
146
193
  select: (data) => data,
147
- invalidates: ["cmsContent.list"],
194
+ invalidates: [
195
+ "cmsContent",
196
+ "cmsTypes.inverseRelationItems",
197
+ "cmsTypes.inverseRelations"
198
+ ],
148
199
  setData: {
149
200
  query: "detail",
150
201
  args: (updated) => updated?.contentType?.slug ? [updated.contentType.slug, updated.id] : null
@@ -157,7 +208,12 @@ const cmsResources = {
157
208
  params: { typeSlug: vars.typeSlug, id: vars.id }
158
209
  }),
159
210
  select: (data) => data,
160
- invalidates: ["cmsContent", "cmsTypes.list"]
211
+ invalidates: [
212
+ "cmsContent",
213
+ "cmsTypes.list",
214
+ "cmsTypes.inverseRelationItems",
215
+ "cmsTypes.inverseRelations"
216
+ ]
161
217
  }
162
218
  }
163
219
  }
@@ -7,7 +7,7 @@ import { S as SerializedBoardWithColumns } from '../../../shared/stack.D1xZ8jQs.
7
7
  import { SerializedBoardSummary } from '../api/index.cjs';
8
8
  import { a as KanbanPluginOverrides } from '../../../shared/stack.DkS7Ep5O.cjs';
9
9
  export { K as KanbanUser } from '../../../shared/stack.DkS7Ep5O.cjs';
10
- import { R as RequiredClientPluginOverrides } from '../../../shared/stack.mRRyZBUg.cjs';
10
+ import { R as RequiredClientPluginOverrides } from '../../../shared/stack.Rb87lHqK.cjs';
11
11
  import { BoardsListPageComponent, NewBoardPageComponent } from './components/index.cjs';
12
12
  import '@btst/stack/plugins/client';
13
13
  import '../../../shared/stack.rnzek-35.cjs';
@@ -7,7 +7,7 @@ import { S as SerializedBoardWithColumns } from '../../../shared/stack.DMT5a6QX.
7
7
  import { SerializedBoardSummary } from '../api/index.mjs';
8
8
  import { a as KanbanPluginOverrides } from '../../../shared/stack.CGNR93ov.mjs';
9
9
  export { K as KanbanUser } from '../../../shared/stack.CGNR93ov.mjs';
10
- import { R as RequiredClientPluginOverrides } from '../../../shared/stack.CkEz7vSt.mjs';
10
+ import { R as RequiredClientPluginOverrides } from '../../../shared/stack.C2Pvl-RS.mjs';
11
11
  import { BoardsListPageComponent, NewBoardPageComponent } from './components/index.mjs';
12
12
  import '@btst/stack/plugins/client';
13
13
  import '../../../shared/stack.CPWAjBMS.mjs';
@@ -7,7 +7,7 @@ import { S as SerializedBoardWithColumns } from '../../../shared/stack.CoRAvur1.
7
7
  import { SerializedBoardSummary } from '../api/index.js';
8
8
  import { a as KanbanPluginOverrides } from '../../../shared/stack.DDsVU85b.js';
9
9
  export { K as KanbanUser } from '../../../shared/stack.DDsVU85b.js';
10
- import { R as RequiredClientPluginOverrides } from '../../../shared/stack.Cvnj99cs.js';
10
+ import { R as RequiredClientPluginOverrides } from '../../../shared/stack.BB9tubJJ.js';
11
11
  import { BoardsListPageComponent, NewBoardPageComponent } from './components/index.js';
12
12
  import '@btst/stack/plugins/client';
13
13
  import '../../../shared/stack.CyetYoMl.js';
@@ -2,7 +2,7 @@ import * as _btst_stack_client from '@btst/stack/client';
2
2
  import * as _btst_yar from '@btst/yar';
3
3
  import * as react from 'react';
4
4
  import { ComponentType } from 'react';
5
- import { Q as SitemapEntry } from '../../../shared/stack.mRRyZBUg.cjs';
5
+ import { T as SitemapEntry } from '../../../shared/stack.Rb87lHqK.cjs';
6
6
  import { ClientStackContext, ClientStack } from '../../../client/index.cjs';
7
7
  import { QueryKey } from '@tanstack/react-query';
8
8
  import '@btst/db';
@@ -2,7 +2,7 @@ import * as _btst_stack_client from '@btst/stack/client';
2
2
  import * as _btst_yar from '@btst/yar';
3
3
  import * as react from 'react';
4
4
  import { ComponentType } from 'react';
5
- import { Q as SitemapEntry } from '../../../shared/stack.CkEz7vSt.mjs';
5
+ import { T as SitemapEntry } from '../../../shared/stack.C2Pvl-RS.mjs';
6
6
  import { ClientStackContext, ClientStack } from '../../../client/index.mjs';
7
7
  import { QueryKey } from '@tanstack/react-query';
8
8
  import '@btst/db';
@@ -2,7 +2,7 @@ import * as _btst_stack_client from '@btst/stack/client';
2
2
  import * as _btst_yar from '@btst/yar';
3
3
  import * as react from 'react';
4
4
  import { ComponentType } from 'react';
5
- import { Q as SitemapEntry } from '../../../shared/stack.Cvnj99cs.js';
5
+ import { T as SitemapEntry } from '../../../shared/stack.BB9tubJJ.js';
6
6
  import { ClientStackContext, ClientStack } from '../../../client/index.js';
7
7
  import { QueryKey } from '@tanstack/react-query';
8
8
  import '@btst/db';
@@ -8,11 +8,11 @@ import 'react';
8
8
  import '../../../../shared/stack.TOEmfBQ4.cjs';
9
9
  import 'react-hook-form';
10
10
  import '@btst/stack/plugins/client';
11
- import '../../../../shared/stack.CAmVUwjV.cjs';
12
- import '@btst/stack/plugins/api';
11
+ import '../../../../shared/stack.NNrBKBkM.cjs';
13
12
  import '../../../../authorization/index.cjs';
13
+ import '@btst/stack/plugins/api';
14
14
  import 'better-call';
15
- import '../../../../shared/stack.3rxARhgS.cjs';
15
+ import '../../../../shared/stack.DrB3L7Ih.cjs';
16
16
 
17
17
  interface UseUIBuilderPagesOptions {
18
18
  /** Number of items per page (default: 10). */
@@ -8,11 +8,11 @@ import 'react';
8
8
  import '../../../../shared/stack.TOEmfBQ4.mjs';
9
9
  import 'react-hook-form';
10
10
  import '@btst/stack/plugins/client';
11
- import '../../../../shared/stack.D9x1fR5a.mjs';
12
- import '@btst/stack/plugins/api';
11
+ import '../../../../shared/stack.DFGj0gb7.mjs';
13
12
  import '../../../../authorization/index.mjs';
13
+ import '@btst/stack/plugins/api';
14
14
  import 'better-call';
15
- import '../../../../shared/stack.3rxARhgS.mjs';
15
+ import '../../../../shared/stack.DrB3L7Ih.mjs';
16
16
 
17
17
  interface UseUIBuilderPagesOptions {
18
18
  /** Number of items per page (default: 10). */
@@ -8,11 +8,11 @@ import 'react';
8
8
  import '../../../../shared/stack.TOEmfBQ4.js';
9
9
  import 'react-hook-form';
10
10
  import '@btst/stack/plugins/client';
11
- import '../../../../shared/stack.CQK02ujt.js';
12
- import '@btst/stack/plugins/api';
11
+ import '../../../../shared/stack.Bw09Lg2z.js';
13
12
  import '../../../../authorization/index.js';
13
+ import '@btst/stack/plugins/api';
14
14
  import 'better-call';
15
- import '../../../../shared/stack.3rxARhgS.js';
15
+ import '../../../../shared/stack.DrB3L7Ih.js';
16
16
 
17
17
  interface UseUIBuilderPagesOptions {
18
18
  /** Number of items per page (default: 10). */