@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
@@ -50,6 +50,8 @@ interface Operation<TInputSchema extends z.ZodTypeAny = z.ZodTypeAny, TPermissio
50
50
  readonly permission: TPermission;
51
51
  readonly access: OperationAccess;
52
52
  readonly resultMode: TPassthroughResult extends true ? "passthrough" : "immutable";
53
+ /** Type-only result marker, preserved when an operation has a specialized call signature. */
54
+ readonly "~result"?: TResult;
53
55
  }
54
56
  /** Any plugin operation, for generic stack composition. */
55
57
  type AnyOperation = Operation<z.ZodTypeAny, AnyPermissionDescriptor, any, false> | Operation<z.ZodTypeAny, AnyPermissionDescriptor, any, true>;
@@ -59,9 +61,13 @@ type OperationInput<TOperation extends AnyOperation> = TOperation extends Operat
59
61
  type OperationTransportResult<TOperation extends AnyOperation> = TOperation extends Operation<any, any, infer TResult, infer TPassthroughResult> ? TPassthroughResult extends true ? TResult : DeepReadonly<TResult> : never;
60
62
  /** Infer the permission request enforced by an operation. */
61
63
  type OperationPermissionRequest<TOperation extends AnyOperation> = TOperation extends Operation<any, infer TPermission, any, any> ? PermissionRequestFor<TPermission> : never;
64
+ /** Input-dependent callable typing; runtime execution still uses the operation definition. */
65
+ interface OperationCallSignature<TCall extends (...args: any[]) => Promise<unknown>> {
66
+ readonly "~call": TCall;
67
+ }
62
68
  /** Convert operation definitions into their bound callable application API. */
63
69
  type OperationApi<TOperations extends OperationRecord> = {
64
- [TKey in keyof TOperations]: (input: OperationInput<TOperations[TKey]>) => Promise<OperationTransportResult<TOperations[TKey]>>;
70
+ [TKey in keyof TOperations]: TOperations[TKey] extends OperationCallSignature<infer TCall> ? TCall : (input: OperationInput<TOperations[TKey]>) => Promise<OperationTransportResult<TOperations[TKey]>>;
65
71
  };
66
72
  /** One request-bound operation plus its endpoint-binding helper. */
67
73
  type RouteOperation<TOperation extends AnyOperation> = {
@@ -609,5 +615,5 @@ type SitemapEntry = {
609
615
  };
610
616
  type Sitemap = Array<SitemapEntry>;
611
617
 
612
- export { OperationHttpError as i, defineOperation as n, definePassthroughOperation as o };
613
- export type { AnyOperation as A, BackendPlugin as B, ClientPlugin as C, DeepReadonly as D, ClientPluginEndpointOverride as E, ClientPluginEndpointOverrides as F, ClientProviderApi as G, ClientProviderPluginRuntime as H, InfrastructureRouteDeclaration as I, ClientProviderProjection as J, ClientStack as K, ClientStackContext as L, ResolvedClientApi as M, ResolvedClientStackConfig as N, OperationRecord as O, PluginOverrides as P, SitemapEntry as Q, RequiredClientPluginOverrides as R, StackContext as S, InferredPluginOverrides as T, RegisteredClientPlugins as U, PrefixedPluginRoutes as V, BackendStackConfig as W, CompatibleStackAuth as X, BackendStack as Y, PluginRaw as Z, PluginOperations as _, ComposedEndpointInventoryEntry as a, InfrastructureRouteInventory as b, Operation as c, OperationAccess as d, OperationApi as e, OperationContext as f, OperationData as g, OperationErrorContext as h, OperationPermissionRequest as j, OperationResultMode as k, RouteOperation as l, RouteOperationApi as m, ClientPluginDefinition as p, ClientPluginRegistration as q, ResolvedClientPluginRuntime as r, Sitemap as s, PluginRoutes as t, ClientStackConfig as u, ResolvedClientStack as v, ClientApiConfig as w, ClientApiEndpointOverride as x, ClientLocation as y, ClientLocationOverride as z };
618
+ export { OperationHttpError as j, defineOperation as o, definePassthroughOperation as p };
619
+ export type { PluginOperations as $, AnyOperation as A, BackendPlugin as B, ClientPlugin as C, DeepReadonly as D, ClientLocationOverride as E, ClientPluginEndpointOverride as F, ClientPluginEndpointOverrides as G, ClientProviderApi as H, InfrastructureRouteDeclaration as I, ClientProviderPluginRuntime as J, ClientProviderProjection as K, ClientStack as L, ClientStackContext as M, ResolvedClientApi as N, OperationRecord as O, PluginOverrides as P, ResolvedClientStackConfig as Q, RequiredClientPluginOverrides as R, StackContext as S, SitemapEntry as T, InferredPluginOverrides as U, RegisteredClientPlugins as V, PrefixedPluginRoutes as W, BackendStackConfig as X, CompatibleStackAuth as Y, BackendStack as Z, PluginRaw as _, ComposedEndpointInventoryEntry as a, InfrastructureRouteInventory as b, Operation as c, OperationAccess as d, OperationApi as e, OperationCallSignature as f, OperationContext as g, OperationData as h, OperationErrorContext as i, OperationPermissionRequest as k, OperationResultMode as l, RouteOperation as m, RouteOperationApi as n, ClientPluginDefinition as q, ClientPluginRegistration as r, ResolvedClientPluginRuntime as s, Sitemap as t, PluginRoutes as u, ClientStackConfig as v, ResolvedClientStack as w, ClientApiConfig as x, ClientApiEndpointOverride as y, ClientLocation as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@btst/stack",
3
- "version": "5.0.0",
3
+ "version": "5.1.0",
4
4
  "description": "A composable, plugin-based library for building full-stack applications.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -54,6 +54,63 @@ describe("cms query keys match SSG prefetch keys", () => {
54
54
  ]);
55
55
  });
56
56
 
57
+ it("normalizes equivalent selections across read identities and preserves prefetch parity", () => {
58
+ const fields = ["title", "name.with.dot", "title"];
59
+ const keys = [
60
+ (selection?: readonly string[]) =>
61
+ queries.cmsContent.options({
62
+ typeSlug: "post",
63
+ view: "content",
64
+ fields: selection,
65
+ }).queryKey,
66
+ (selection?: readonly string[]) =>
67
+ queries.cmsContent.list({
68
+ typeSlug: "post",
69
+ view: "content",
70
+ fields: selection,
71
+ }).queryKey,
72
+ (selection?: readonly string[]) =>
73
+ queries.cmsContent.detail("post", "id", {
74
+ view: "content",
75
+ fields: selection,
76
+ }).queryKey,
77
+ (selection?: readonly string[]) =>
78
+ queries.cmsContent.bySlug("post", "slug", {
79
+ view: "content",
80
+ fields: selection,
81
+ }).queryKey,
82
+ (selection?: readonly string[]) =>
83
+ queries.cmsContent.byRelation({
84
+ typeSlug: "post",
85
+ field: "authorId",
86
+ targetId: "author",
87
+ view: "content",
88
+ fields: selection,
89
+ }).queryKey,
90
+ (selection?: readonly string[]) =>
91
+ queries.cmsTypes.inverseRelationItems({
92
+ slug: "author",
93
+ sourceType: "post",
94
+ itemId: "author",
95
+ fieldName: "authorId",
96
+ view: "content",
97
+ fields: selection,
98
+ }).queryKey,
99
+ ];
100
+ for (const key of keys) {
101
+ expect(key(fields)).toEqual(key(["name.with.dot", "title"]));
102
+ expect(key(fields)).not.toEqual(key(["title"]));
103
+ expect(key(fields)).not.toEqual(key());
104
+ }
105
+ expect(fields).toEqual(["title", "name.with.dot", "title"]);
106
+ expect(keys[1]!(fields)).toEqual(
107
+ CMS_QUERY_KEYS.contentList({ typeSlug: "post", view: "content", fields }),
108
+ );
109
+ expect(keys[2]!(fields)).toEqual(
110
+ CMS_QUERY_KEYS.contentDetail("post", "id", { view: "content", fields }),
111
+ );
112
+ });
113
+
57
114
  it("exposes the same _def prefixes as the previous factory", () => {
58
115
  expect([...queries.cmsTypes._def]).toEqual(["cmsTypes"]);
59
116
  expect([...queries.cmsTypes.list._def]).toEqual(["cmsTypes", "list"]);
@@ -51,6 +51,7 @@ export {
51
51
  type Operation,
52
52
  type OperationAccess,
53
53
  type OperationApi,
54
+ type OperationCallSignature,
54
55
  type OperationContext,
55
56
  type OperationData,
56
57
  type OperationErrorContext,
@@ -201,6 +201,8 @@ export interface Operation<
201
201
  readonly resultMode: TPassthroughResult extends true
202
202
  ? "passthrough"
203
203
  : "immutable";
204
+ /** Type-only result marker, preserved when an operation has a specialized call signature. */
205
+ readonly "~result"?: TResult;
204
206
  }
205
207
 
206
208
  /** Any plugin operation, for generic stack composition. */
@@ -237,11 +239,22 @@ export type OperationPermissionRequest<TOperation extends AnyOperation> =
237
239
  export type OperationPermissionId<TOperation extends AnyOperation> =
238
240
  OperationPermissionRequest<TOperation>["id"];
239
241
 
242
+ /** Input-dependent callable typing; runtime execution still uses the operation definition. */
243
+ export interface OperationCallSignature<
244
+ TCall extends (...args: any[]) => Promise<unknown>,
245
+ > {
246
+ readonly "~call": TCall;
247
+ }
248
+
240
249
  /** Convert operation definitions into their bound callable application API. */
241
250
  export type OperationApi<TOperations extends OperationRecord> = {
242
- [TKey in keyof TOperations]: (
243
- input: OperationInput<TOperations[TKey]>,
244
- ) => Promise<OperationTransportResult<TOperations[TKey]>>;
251
+ [TKey in keyof TOperations]: TOperations[TKey] extends OperationCallSignature<
252
+ infer TCall
253
+ >
254
+ ? TCall
255
+ : (
256
+ input: OperationInput<TOperations[TKey]>,
257
+ ) => Promise<OperationTransportResult<TOperations[TKey]>>;
245
258
  };
246
259
 
247
260
  /** One request-bound operation plus its endpoint-binding helper. */