@opensaas/stack-core 0.37.0 → 0.39.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 (226) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +191 -0
  3. package/CLAUDE.md +42 -3
  4. package/dist/access/access-filter.d.ts +70 -113
  5. package/dist/access/access-filter.d.ts.map +1 -1
  6. package/dist/access/access-filter.js +183 -210
  7. package/dist/access/access-filter.js.map +1 -1
  8. package/dist/access/access-filter.test.js +148 -188
  9. package/dist/access/access-filter.test.js.map +1 -1
  10. package/dist/access/declared-dependencies.d.ts +66 -26
  11. package/dist/access/declared-dependencies.d.ts.map +1 -1
  12. package/dist/access/declared-dependencies.js +62 -17
  13. package/dist/access/declared-dependencies.js.map +1 -1
  14. package/dist/access/declared-dependencies.test.d.ts +2 -0
  15. package/dist/access/declared-dependencies.test.d.ts.map +1 -0
  16. package/dist/access/declared-dependencies.test.js +226 -0
  17. package/dist/access/declared-dependencies.test.js.map +1 -0
  18. package/dist/access/depth-limits.d.ts +8 -7
  19. package/dist/access/depth-limits.d.ts.map +1 -1
  20. package/dist/access/depth-limits.js +8 -7
  21. package/dist/access/depth-limits.js.map +1 -1
  22. package/dist/access/engine.d.ts +0 -20
  23. package/dist/access/engine.d.ts.map +1 -1
  24. package/dist/access/engine.js +0 -25
  25. package/dist/access/engine.js.map +1 -1
  26. package/dist/access/errors.d.ts +61 -8
  27. package/dist/access/errors.d.ts.map +1 -1
  28. package/dist/access/errors.js +91 -12
  29. package/dist/access/errors.js.map +1 -1
  30. package/dist/access/field-access.d.ts +39 -1
  31. package/dist/access/field-access.d.ts.map +1 -1
  32. package/dist/access/field-access.js +108 -42
  33. package/dist/access/field-access.js.map +1 -1
  34. package/dist/access/field-access.test.js +229 -2
  35. package/dist/access/field-access.test.js.map +1 -1
  36. package/dist/access/field-transforms.d.ts +0 -27
  37. package/dist/access/field-transforms.d.ts.map +1 -1
  38. package/dist/access/field-visibility.d.ts +2 -5
  39. package/dist/access/field-visibility.d.ts.map +1 -1
  40. package/dist/access/field-visibility.js +89 -41
  41. package/dist/access/field-visibility.js.map +1 -1
  42. package/dist/access/index.d.ts +6 -3
  43. package/dist/access/index.d.ts.map +1 -1
  44. package/dist/access/index.js +12 -2
  45. package/dist/access/index.js.map +1 -1
  46. package/dist/access/query-validation.d.ts +121 -0
  47. package/dist/access/query-validation.d.ts.map +1 -0
  48. package/dist/access/query-validation.js +292 -0
  49. package/dist/access/query-validation.js.map +1 -0
  50. package/dist/access/relationship-count.d.ts +1 -1
  51. package/dist/access/relationship-count.d.ts.map +1 -1
  52. package/dist/access/relationship-count.js +2 -10
  53. package/dist/access/relationship-count.js.map +1 -1
  54. package/dist/access/relationship-label-filter.d.ts +23 -23
  55. package/dist/access/relationship-label-filter.d.ts.map +1 -1
  56. package/dist/access/relationship-label-filter.js +5 -76
  57. package/dist/access/relationship-label-filter.js.map +1 -1
  58. package/dist/access/relationship-label-filter.test.js +19 -56
  59. package/dist/access/relationship-label-filter.test.js.map +1 -1
  60. package/dist/access/transaction-registry.d.ts +45 -0
  61. package/dist/access/transaction-registry.d.ts.map +1 -0
  62. package/dist/access/transaction-registry.js +37 -0
  63. package/dist/access/transaction-registry.js.map +1 -0
  64. package/dist/access/types.d.ts +55 -59
  65. package/dist/access/types.d.ts.map +1 -1
  66. package/dist/config/index.d.ts +9 -7
  67. package/dist/config/index.d.ts.map +1 -1
  68. package/dist/config/index.js +10 -18
  69. package/dist/config/index.js.map +1 -1
  70. package/dist/config/label.d.ts +6 -13
  71. package/dist/config/label.d.ts.map +1 -1
  72. package/dist/config/label.js +6 -13
  73. package/dist/config/label.js.map +1 -1
  74. package/dist/config/nav-count.d.ts +11 -19
  75. package/dist/config/nav-count.d.ts.map +1 -1
  76. package/dist/config/nav-count.js +11 -19
  77. package/dist/config/nav-count.js.map +1 -1
  78. package/dist/config/plugin-engine.d.ts +0 -10
  79. package/dist/config/plugin-engine.d.ts.map +1 -1
  80. package/dist/config/plugin-engine.js +1 -37
  81. package/dist/config/plugin-engine.js.map +1 -1
  82. package/dist/config/types.d.ts +94 -109
  83. package/dist/config/types.d.ts.map +1 -1
  84. package/dist/context/apply-defaults.d.ts +8 -31
  85. package/dist/context/apply-defaults.d.ts.map +1 -1
  86. package/dist/context/apply-defaults.js +12 -41
  87. package/dist/context/apply-defaults.js.map +1 -1
  88. package/dist/context/hook-pipeline.d.ts +4 -29
  89. package/dist/context/hook-pipeline.d.ts.map +1 -1
  90. package/dist/context/hook-pipeline.js +8 -41
  91. package/dist/context/hook-pipeline.js.map +1 -1
  92. package/dist/context/index.d.ts +4 -15
  93. package/dist/context/index.d.ts.map +1 -1
  94. package/dist/context/index.js +223 -215
  95. package/dist/context/index.js.map +1 -1
  96. package/dist/context/nested-operations.d.ts +7 -26
  97. package/dist/context/nested-operations.d.ts.map +1 -1
  98. package/dist/context/nested-operations.js +73 -171
  99. package/dist/context/nested-operations.js.map +1 -1
  100. package/dist/context/transaction-boundary.d.ts +36 -47
  101. package/dist/context/transaction-boundary.d.ts.map +1 -1
  102. package/dist/context/transaction-boundary.js +92 -79
  103. package/dist/context/transaction-boundary.js.map +1 -1
  104. package/dist/context/write-pipeline.d.ts +25 -64
  105. package/dist/context/write-pipeline.d.ts.map +1 -1
  106. package/dist/context/write-pipeline.js +81 -111
  107. package/dist/context/write-pipeline.js.map +1 -1
  108. package/dist/fields/format-prisma-default.d.ts.map +1 -1
  109. package/dist/fields/format-prisma-default.js +4 -7
  110. package/dist/fields/format-prisma-default.js.map +1 -1
  111. package/dist/fields/index.d.ts +17 -2
  112. package/dist/fields/index.d.ts.map +1 -1
  113. package/dist/fields/index.js +136 -147
  114. package/dist/fields/index.js.map +1 -1
  115. package/dist/filter/collect.d.ts +26 -3
  116. package/dist/filter/collect.d.ts.map +1 -1
  117. package/dist/filter/collect.js +30 -12
  118. package/dist/filter/collect.js.map +1 -1
  119. package/dist/filter/filter.test.js +98 -15
  120. package/dist/filter/filter.test.js.map +1 -1
  121. package/dist/filter/index.d.ts +1 -0
  122. package/dist/filter/index.d.ts.map +1 -1
  123. package/dist/filter/index.js.map +1 -1
  124. package/dist/filter/map.d.ts.map +1 -1
  125. package/dist/filter/map.js +0 -5
  126. package/dist/filter/map.js.map +1 -1
  127. package/dist/filter/parse.d.ts.map +1 -1
  128. package/dist/filter/parse.js +2 -9
  129. package/dist/filter/parse.js.map +1 -1
  130. package/dist/filter/serialize.d.ts.map +1 -1
  131. package/dist/filter/serialize.js +2 -4
  132. package/dist/filter/serialize.js.map +1 -1
  133. package/dist/hooks/index.d.ts +4 -42
  134. package/dist/hooks/index.d.ts.map +1 -1
  135. package/dist/hooks/index.js +5 -59
  136. package/dist/hooks/index.js.map +1 -1
  137. package/dist/index.d.ts +3 -1
  138. package/dist/index.d.ts.map +1 -1
  139. package/dist/index.js +20 -4
  140. package/dist/index.js.map +1 -1
  141. package/dist/internal.d.ts +1 -0
  142. package/dist/internal.d.ts.map +1 -1
  143. package/dist/internal.js +4 -0
  144. package/dist/internal.js.map +1 -1
  145. package/dist/lib/case-utils.d.ts +0 -32
  146. package/dist/lib/case-utils.d.ts.map +1 -1
  147. package/dist/lib/case-utils.js +0 -32
  148. package/dist/lib/case-utils.js.map +1 -1
  149. package/dist/mcp/handler.d.ts +0 -4
  150. package/dist/mcp/handler.d.ts.map +1 -1
  151. package/dist/mcp/handler.js +12 -69
  152. package/dist/mcp/handler.js.map +1 -1
  153. package/dist/query/index.d.ts +55 -227
  154. package/dist/query/index.d.ts.map +1 -1
  155. package/dist/query/index.js +41 -117
  156. package/dist/query/index.js.map +1 -1
  157. package/dist/query/relationship-options.d.ts +1 -1
  158. package/dist/query/relationship-options.js +1 -1
  159. package/dist/utils/password.d.ts +0 -68
  160. package/dist/utils/password.d.ts.map +1 -1
  161. package/dist/utils/password.js +7 -76
  162. package/dist/utils/password.js.map +1 -1
  163. package/dist/validation/field-config.d.ts.map +1 -1
  164. package/dist/validation/field-config.js +0 -6
  165. package/dist/validation/field-config.js.map +1 -1
  166. package/dist/validation/schema.d.ts +0 -7
  167. package/dist/validation/schema.d.ts.map +1 -1
  168. package/dist/validation/schema.js +0 -10
  169. package/dist/validation/schema.js.map +1 -1
  170. package/package.json +1 -1
  171. package/src/access/access-filter.test.ts +205 -275
  172. package/src/access/access-filter.ts +236 -272
  173. package/src/access/declared-dependencies.test.ts +277 -0
  174. package/src/access/declared-dependencies.ts +117 -37
  175. package/src/access/depth-limits.ts +8 -7
  176. package/src/access/engine.ts +0 -25
  177. package/src/access/errors.ts +97 -12
  178. package/src/access/field-access.test.ts +312 -2
  179. package/src/access/field-access.ts +118 -42
  180. package/src/access/field-transforms.ts +8 -39
  181. package/src/access/field-visibility.ts +99 -45
  182. package/src/access/index.ts +17 -5
  183. package/src/access/query-validation.ts +359 -0
  184. package/src/access/relationship-count.ts +3 -11
  185. package/src/access/relationship-label-filter.test.ts +19 -68
  186. package/src/access/relationship-label-filter.ts +27 -104
  187. package/src/access/transaction-registry.ts +58 -0
  188. package/src/access/types.ts +83 -86
  189. package/src/config/index.ts +10 -22
  190. package/src/config/label.ts +6 -13
  191. package/src/config/nav-count.ts +11 -19
  192. package/src/config/plugin-engine.ts +1 -37
  193. package/src/config/types.ts +95 -110
  194. package/src/context/apply-defaults.ts +12 -44
  195. package/src/context/hook-pipeline.ts +12 -67
  196. package/src/context/index.ts +311 -276
  197. package/src/context/nested-operations.ts +94 -226
  198. package/src/context/transaction-boundary.ts +113 -109
  199. package/src/context/write-pipeline.ts +99 -155
  200. package/src/fields/format-prisma-default.ts +4 -7
  201. package/src/fields/index.ts +155 -147
  202. package/src/filter/collect.ts +48 -12
  203. package/src/filter/filter.test.ts +153 -15
  204. package/src/filter/index.ts +1 -0
  205. package/src/filter/map.ts +0 -5
  206. package/src/filter/parse.ts +2 -9
  207. package/src/filter/serialize.ts +2 -4
  208. package/src/hooks/index.ts +5 -59
  209. package/src/index.ts +23 -4
  210. package/src/internal.ts +5 -0
  211. package/src/lib/case-utils.ts +0 -32
  212. package/src/mcp/handler.ts +13 -71
  213. package/src/query/index.ts +82 -235
  214. package/src/query/relationship-options.ts +1 -1
  215. package/src/utils/password.ts +7 -76
  216. package/src/validation/field-config.ts +0 -6
  217. package/src/validation/schema.ts +0 -10
  218. package/tests/access-relationships.test.ts +18 -16
  219. package/tests/computed-field-selective-evaluation.test.ts +418 -0
  220. package/tests/context.test.ts +727 -1
  221. package/tests/field-types.test.ts +222 -0
  222. package/tests/mcp-handler.test.ts +34 -0
  223. package/tests/needs-declared-dependencies.test.ts +7 -4
  224. package/tests/resolve-chain.test.ts +11 -11
  225. package/tests/transaction-boundary-outermost.test.ts +530 -0
  226. package/tsconfig.tsbuildinfo +1 -1
@@ -1,52 +1,8 @@
1
- /**
2
- * Unwrap the item type from a field type, stripping null, undefined, and
3
- * Array wrappers so we can constrain nested fragment shapes.
4
- *
5
- * Examples:
6
- * User | null → User
7
- * User[] → User
8
- * (User | null)[] → User
9
- */
10
1
  type UnwrapItem<T> = NonNullable<T> extends Array<infer U> ? NonNullable<U> : NonNullable<T>;
11
2
  /**
12
- * A selector for a relationship field.
13
- *
14
- * Two forms are accepted:
15
- * 1. A `Fragment` directly (shorthand — no extra Prisma args on the nested query).
16
- * 2. An object `{ query, where?, orderBy?, take?, skip? }` to combine a fragment
17
- * with Prisma filter/ordering/pagination applied to the nested relationship.
18
- *
19
- * @example Shorthand (most common)
20
- * ```ts
21
- * const postFrag = defineFragment<Post>()({
22
- * id: true,
23
- * author: authorFragment, // shorthand
24
- * } as const)
25
- * ```
26
- *
27
- * @example With nested filtering
28
- * ```ts
29
- * const postFrag = defineFragment<Post>()({
30
- * id: true,
31
- * comments: {
32
- * query: commentFragment,
33
- * where: { approved: true },
34
- * orderBy: { createdAt: 'desc' },
35
- * take: 5,
36
- * },
37
- * } as const)
38
- * ```
39
- *
40
- * @example Variables via factory function
41
- * ```ts
42
- * function makePostFragment(status: string) {
43
- * return defineFragment<Post>()({
44
- * id: true,
45
- * comments: { query: commentFragment, where: { status } },
46
- * } as const)
47
- * }
48
- * type PostData = ResultOf<ReturnType<typeof makePostFragment>>
49
- * ```
3
+ * A selector for a relationship field: either a {@link Fragment} directly
4
+ * (shorthand), or `{ query, where?, orderBy?, take?, skip? }` to combine a
5
+ * fragment with Prisma filter/ordering/pagination on the nested relationship.
50
6
  */
51
7
  export type RelationSelector<TRelated extends Record<string, unknown>> = Fragment<TRelated, FieldSelection<TRelated>> | {
52
8
  readonly query: Fragment<TRelated, FieldSelection<TRelated>>;
@@ -56,103 +12,45 @@ export type RelationSelector<TRelated extends Record<string, unknown>> = Fragmen
56
12
  readonly skip?: number;
57
13
  };
58
14
  /**
59
- * A field selection for model type `TItem`.
60
- *
61
- * Each key maps to:
62
- * - `true` — include the scalar/primitive field as-is
63
- * - A `Fragment` — include a relationship and recurse (shorthand)
64
- * - A `RelationSelector` — include a relationship with optional Prisma filter/ordering
65
- *
66
- * Only keys present in `TItem` are accepted. For relationship (object) fields
67
- * you may pass a Fragment, a RelationSelector, or `true` (returns the raw Prisma
68
- * value and loses type narrowing).
69
- *
70
- * @example
71
- * ```ts
72
- * const sel: FieldSelection<Post> = {
73
- * id: true,
74
- * title: true,
75
- * author: authorFragment,
76
- * comments: { query: commentFragment, where: { approved: true } },
77
- * }
78
- * ```
15
+ * A field selection for model type `TItem`. Passing `true` for a
16
+ * relationship field returns the raw Prisma value and loses type narrowing —
17
+ * use a {@link Fragment} or {@link RelationSelector} to keep it typed.
79
18
  */
80
19
  export type FieldSelection<T> = {
81
20
  readonly [K in keyof T]?: UnwrapItem<T[K]> extends Record<string, unknown> ? RelationSelector<UnwrapItem<T[K]>> | true : true;
82
21
  };
83
22
  /**
84
23
  * A reusable, composable field-selection descriptor for model type `TItem`.
85
- *
86
- * Create with {@link defineFragment}. Compose by referencing another Fragment
87
- * (or a {@link RelationSelector}) as the value for a relationship key.
88
- *
89
- * @example
90
- * ```ts
91
- * const userFragment = defineFragment<User>()({ id: true, name: true } as const)
92
- * const postFragment = defineFragment<Post>()({
93
- * id: true,
94
- * title: true,
95
- * author: userFragment,
96
- * } as const)
97
- * ```
24
+ * Create with {@link defineFragment}.
98
25
  */
99
26
  export type Fragment<TItem, TFields extends FieldSelection<TItem> = FieldSelection<TItem>> = {
100
27
  readonly _type: 'fragment';
101
28
  readonly _fields: TFields;
102
29
  };
103
- /**
104
- * @internal
105
- * Extract the Fragment from either a Fragment directly or a RelationSelector object.
106
- * Returns `never` for scalar `true` selections (so they fall to the scalar branch).
107
- */
30
+ /** @internal Returns `never` for scalar `true` selections, so they fall to the scalar branch in {@link SelectedFields}. */
108
31
  type ExtractFragment<TSelector> = TSelector extends Fragment<infer TItem, infer TFields> ? Fragment<TItem, TFields> : TSelector extends {
109
32
  readonly query: Fragment<infer TItem, infer TFields>;
110
33
  } ? Fragment<TItem, TFields> : never;
111
- /**
112
- * @internal
113
- * Map a FieldSelection over a model type, computing the picked output type.
114
- */
34
+ /** @internal */
115
35
  type SelectedFields<TItem, TFields extends FieldSelection<TItem>> = {
116
36
  [K in keyof TFields & keyof TItem]: [ExtractFragment<TFields[K]>] extends [never] ? TItem[K] : TItem[K] extends Array<unknown> ? ResultOf<ExtractFragment<TFields[K]>>[] : null extends TItem[K] ? ResultOf<ExtractFragment<TFields[K]>> | null : undefined extends TItem[K] ? ResultOf<ExtractFragment<TFields[K]>> | undefined : ResultOf<ExtractFragment<TFields[K]>>;
117
37
  };
118
38
  /**
119
- * Infer the TypeScript result type from a Fragment.
120
- *
121
- * Analogous to `gql.tada`'s `ResultOf` helper — given a fragment definition,
122
- * `ResultOf` tells you exactly what shape you will receive at runtime.
123
- *
124
- * - Scalar fields selected with `true` retain their original Prisma type.
125
- * - Relationship fields selected with a nested Fragment/RelationSelector are
126
- * recursively narrowed.
127
- * - Nullability and array wrappers from the original model type are preserved.
128
- *
129
- * @example
130
- * ```ts
131
- * type UserData = ResultOf<typeof userFragment>
132
- * // → { id: string; name: string }
133
- *
134
- * type PostData = ResultOf<typeof postFragment>
135
- * // → { id: string; title: string; author: { id: string; name: string } | null }
136
- * ```
39
+ * Infer the TypeScript result type from a {@link Fragment} — the shape
40
+ * `runQuery`/`runQueryOne` return at runtime for that fragment.
137
41
  */
138
42
  export type ResultOf<F> = F extends Fragment<infer TItem, infer TFields> ? SelectedFields<TItem, TFields> : never;
139
43
  /**
140
44
  * Arguments accepted by {@link runQuery}.
141
45
  */
142
46
  export type QueryArgs = {
143
- /** Prisma where filter. The access control layer will additionally scope results. */
47
+ /** Prisma where filter the access control layer additionally scopes results. */
144
48
  where?: Record<string, unknown>;
145
- /** Prisma orderBy clause. Pass a single object or an array for multi-column ordering. */
146
49
  orderBy?: Record<string, 'asc' | 'desc'> | Array<Record<string, 'asc' | 'desc'>>;
147
- /** Maximum number of records to return. */
148
50
  take?: number;
149
- /** Number of records to skip (for pagination). */
150
51
  skip?: number;
151
52
  };
152
- /**
153
- * Minimal context shape required by the query runners.
154
- * Compatible with the full `AccessContext` produced by `getContext()`.
155
- */
53
+ /** Compatible with the full `AccessContext` produced by `getContext()`. */
156
54
  export interface QueryRunnerContext {
157
55
  db: {
158
56
  [key: string]: {
@@ -162,137 +60,67 @@ export interface QueryRunnerContext {
162
60
  };
163
61
  }
164
62
  /**
165
- * Create a type-safe, reusable fragment for a given model type.
166
- *
167
- * The function is curried so that TypeScript can infer both the model type
168
- * (from the explicit type parameter) and the field selection (from the
169
- * argument), without requiring you to repeat yourself.
170
- *
171
- * @example Basic usage
172
- * ```ts
173
- * import type { User } from '.prisma/client'
174
- * import { defineFragment } from '@opensaas/stack-core'
175
- *
176
- * export const userFragment = defineFragment<User>()({
177
- * id: true,
178
- * name: true,
179
- * email: true,
180
- * } as const)
181
- * ```
182
- *
183
- * @example Compose fragments
184
- * ```ts
185
- * import type { Post } from '.prisma/client'
186
- *
187
- * export const postFragment = defineFragment<Post>()({
188
- * id: true,
189
- * title: true,
190
- * author: userFragment,
191
- * } as const)
192
- * ```
193
- *
194
- * @example Nested filtering with RelationSelector
195
- * ```ts
196
- * export const postWithApprovedComments = defineFragment<Post>()({
197
- * id: true,
198
- * title: true,
199
- * comments: {
200
- * query: commentFragment,
201
- * where: { approved: true },
202
- * orderBy: { createdAt: 'desc' },
203
- * take: 5,
204
- * },
205
- * } as const)
206
- * ```
207
- *
208
- * @example Variables via factory function
209
- * ```ts
210
- * function makePostFragment(status: string) {
211
- * return defineFragment<Post>()({
212
- * id: true,
213
- * comments: { query: commentFragment, where: { status } },
214
- * } as const)
215
- * }
216
- * type PostData = ResultOf<ReturnType<typeof makePostFragment>>
217
- *
218
- * const posts = await context.db.post.findMany({
219
- * query: makePostFragment('approved'),
220
- * where: { published: true },
221
- * })
222
- * ```
63
+ * Create a type-safe, reusable fragment for a given model type. Curried so
64
+ * TypeScript can infer the model type from the explicit type parameter and
65
+ * the field selection from the argument.
223
66
  */
224
67
  export declare function defineFragment<TItem>(): <TFields extends FieldSelection<TItem>>(fields: TFields) => Fragment<TItem, TFields>;
225
68
  /** @internal */
226
69
  export declare function isFragment(value: unknown): value is Fragment<unknown, FieldSelection<unknown>>;
227
70
  /**
228
- * Walk a field selection and build the Prisma `include` map needed to eagerly
229
- * load all nested relationship fragments/selectors.
230
- *
231
- * Scalar fields (`true`) do not require an include entry — Prisma returns all
232
- * scalar columns by default. Only relationship fields backed by a Fragment or
233
- * RelationSelector generate include entries (recursively).
234
- *
235
- * Exported for use in `context/index.ts` when the `query` parameter is present.
71
+ * Build the Prisma `include` map for a field selection's nested fragments.
72
+ * Scalar fields (`true`) need no include entry — Prisma returns all scalar
73
+ * columns by default; only relationship fields backed by a Fragment or
74
+ * RelationSelector generate one (recursively).
236
75
  * @internal
237
76
  */
238
77
  export declare function buildInclude(fields: FieldSelection<unknown>): Record<string, unknown> | undefined;
78
+ /**
79
+ * A snapshot of which field names a fragment selects at one nesting level,
80
+ * plus the same tree one level down for every relation selected via a nested
81
+ * Fragment/RelationSelector. `fields: undefined` means "unrestricted" — every
82
+ * field at this level is going to be returned, which is what a bare or
83
+ * `include`-based read means for the whole tree (only a `query` fragment ever
84
+ * produces a restricted scope, and only as deep as it names).
85
+ *
86
+ * Used to make computed-field evaluation (`filterReadableFields`) and
87
+ * declared-dependency folding (`foldDeclaredDependencies`) projection-aware
88
+ * (ADR-0027): a field not named by the scope at its level is never computed
89
+ * and its `needs` are never folded, because the read is never going to
90
+ * return it.
91
+ * @internal
92
+ */
93
+ export type FieldSelectionScope = {
94
+ readonly fields: ReadonlySet<string> | undefined;
95
+ readonly nested: Readonly<Record<string, FieldSelectionScope>>;
96
+ };
97
+ /**
98
+ * Build the `FieldSelectionScope` for one fragment's field selection,
99
+ * recursing into nested Fragment/RelationSelector entries the same way
100
+ * `buildInclude` does. A relation named with the bare `true` shorthand (no
101
+ * narrower nested Fragment) gets no entry in `nested`, so a level reached
102
+ * through it is treated as unrestricted — the caller asked for "everything"
103
+ * there and gave no narrower shape to restrict it with.
104
+ * @internal
105
+ */
106
+ export declare function buildFieldSelectionScope(fields: FieldSelection<unknown>): FieldSelectionScope;
239
107
  /**
240
108
  * Recursively pick only the fields requested by a fragment from a raw Prisma
241
- * result object. This ensures the runtime shape exactly matches the type
242
- * produced by `ResultOf<F>`.
243
- *
244
- * Exported for use in `context/index.ts`.
109
+ * result object, so the runtime shape matches `ResultOf<F>`.
245
110
  * @internal
246
111
  */
247
112
  export declare function pickFields<TItem, TFields extends FieldSelection<TItem>>(item: TItem, fields: TFields): SelectedFields<TItem, TFields>;
248
113
  /**
249
114
  * Execute a fragment-based query against a list, returning all matching
250
- * records shaped to the fragment's field selection.
251
- *
252
- * Under the hood this calls `context.db[listKey].findMany()`, so all access
253
- * control rules defined in your config are still enforced.
254
- *
255
- * **Tip:** You can also call `context.db.post.findMany({ query: fragment, ... })`
256
- * directly — both forms produce the same result.
257
- *
258
- * @param context - An `AccessContext` (or any object with a compatible `db`).
259
- * @param listKey - The PascalCase list name (e.g. `'Post'`, `'BlogPost'`).
260
- * @param fragment - A fragment created with {@link defineFragment}.
261
- * @param args - Optional query arguments (where, orderBy, take, skip).
262
- * @returns An array typed to exactly the fragment's field selection.
263
- *
264
- * @example
265
- * ```ts
266
- * const posts = await runQuery(context, 'Post', postFragment, {
267
- * where: { published: true },
268
- * orderBy: { createdAt: 'desc' },
269
- * take: 10,
270
- * })
271
- * // posts: Array<ResultOf<typeof postFragment>>
272
- * ```
115
+ * records shaped to the fragment's field selection. Calls
116
+ * `context.db[listKey].findMany()` under the hood, so access control still
117
+ * applies.
273
118
  */
274
119
  export declare function runQuery<TItem, TFields extends FieldSelection<TItem>>(context: QueryRunnerContext, listKey: string, fragment: Fragment<TItem, TFields>, args?: QueryArgs): Promise<SelectedFields<TItem, TFields>[]>;
275
120
  /**
276
121
  * Execute a fragment-based query that returns a single record (or `null`).
277
- *
278
- * Under the hood this calls `context.db[listKey].findFirst()`, so all access
279
- * control rules are still enforced.
280
- *
281
- * **Tip:** You can also call `context.db.post.findUnique({ where: { id }, query: fragment })`
282
- * directly.
283
- *
284
- * @param context - An `AccessContext` (or any object with a compatible `db`).
285
- * @param listKey - The PascalCase list name (e.g. `'Post'`).
286
- * @param fragment - A fragment created with {@link defineFragment}.
287
- * @param where - A Prisma where clause to identify the record.
288
- * @returns The matched record shaped to the fragment, or `null`.
289
- *
290
- * @example
291
- * ```ts
292
- * const post = await runQueryOne(context, 'Post', postFragment, { id: postId })
293
- * if (!post) return notFound()
294
- * // post: ResultOf<typeof postFragment>
295
- * ```
122
+ * Calls `context.db[listKey].findFirst()` under the hood, so access control
123
+ * still applies.
296
124
  */
297
125
  export declare function runQueryOne<TItem, TFields extends FieldSelection<TItem>>(context: QueryRunnerContext, listKey: string, fragment: Fragment<TItem, TFields>, where: Record<string, unknown>): Promise<SelectedFields<TItem, TFields> | null>;
298
126
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"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"}
@@ -3,64 +3,9 @@ import { getDbKey } from '../lib/case-utils.js';
3
3
  // Fragment factory
4
4
  // ─────────────────────────────────────────────────────────────
5
5
  /**
6
- * Create a type-safe, reusable fragment for a given model type.
7
- *
8
- * The function is curried so that TypeScript can infer both the model type
9
- * (from the explicit type parameter) and the field selection (from the
10
- * argument), without requiring you to repeat yourself.
11
- *
12
- * @example Basic usage
13
- * ```ts
14
- * import type { User } from '.prisma/client'
15
- * import { defineFragment } from '@opensaas/stack-core'
16
- *
17
- * export const userFragment = defineFragment<User>()({
18
- * id: true,
19
- * name: true,
20
- * email: true,
21
- * } as const)
22
- * ```
23
- *
24
- * @example Compose fragments
25
- * ```ts
26
- * import type { Post } from '.prisma/client'
27
- *
28
- * export const postFragment = defineFragment<Post>()({
29
- * id: true,
30
- * title: true,
31
- * author: userFragment,
32
- * } as const)
33
- * ```
34
- *
35
- * @example Nested filtering with RelationSelector
36
- * ```ts
37
- * export const postWithApprovedComments = defineFragment<Post>()({
38
- * id: true,
39
- * title: true,
40
- * comments: {
41
- * query: commentFragment,
42
- * where: { approved: true },
43
- * orderBy: { createdAt: 'desc' },
44
- * take: 5,
45
- * },
46
- * } as const)
47
- * ```
48
- *
49
- * @example Variables via factory function
50
- * ```ts
51
- * function makePostFragment(status: string) {
52
- * return defineFragment<Post>()({
53
- * id: true,
54
- * comments: { query: commentFragment, where: { status } },
55
- * } as const)
56
- * }
57
- * type PostData = ResultOf<ReturnType<typeof makePostFragment>>
58
- *
59
- * const posts = await context.db.post.findMany({
60
- * query: makePostFragment('approved'),
61
- * where: { published: true },
62
- * })
63
- * ```
6
+ * Create a type-safe, reusable fragment for a given model type. Curried so
7
+ * TypeScript can infer the model type from the explicit type parameter and
8
+ * the field selection from the argument.
64
9
  */
65
10
  export function defineFragment() {
66
11
  return function (fields) {
@@ -68,7 +13,7 @@ export function defineFragment() {
68
13
  };
69
14
  }
70
15
  // ─────────────────────────────────────────────────────────────
71
- // Runtime helpers — exported for use in context/index.ts
16
+ // Runtime helpers
72
17
  // ─────────────────────────────────────────────────────────────
73
18
  /** @internal */
74
19
  export function isFragment(value) {
@@ -78,14 +23,10 @@ export function isFragment(value) {
78
23
  value._type === 'fragment');
79
24
  }
80
25
  /**
81
- * Walk a field selection and build the Prisma `include` map needed to eagerly
82
- * load all nested relationship fragments/selectors.
83
- *
84
- * Scalar fields (`true`) do not require an include entry — Prisma returns all
85
- * scalar columns by default. Only relationship fields backed by a Fragment or
86
- * RelationSelector generate include entries (recursively).
87
- *
88
- * Exported for use in `context/index.ts` when the `query` parameter is present.
26
+ * Build the Prisma `include` map for a field selection's nested fragments.
27
+ * Scalar fields (`true`) need no include entry — Prisma returns all scalar
28
+ * columns by default; only relationship fields backed by a Fragment or
29
+ * RelationSelector generate one (recursively).
89
30
  * @internal
90
31
  */
91
32
  export function buildInclude(fields) {
@@ -95,14 +36,12 @@ export function buildInclude(fields) {
95
36
  if (value === null || value === true || typeof value !== 'object')
96
37
  continue;
97
38
  const val = value;
98
- // ── Shorthand: Fragment directly ──────────────────────────
99
39
  if (isFragment(val)) {
100
40
  hasIncludes = true;
101
41
  const nestedInclude = buildInclude(val._fields);
102
42
  include[key] = nestedInclude ? { include: nestedInclude } : true;
103
43
  continue;
104
44
  }
105
- // ── RelationSelector: { query, where?, orderBy?, take?, skip? } ──
106
45
  if ('query' in val && isFragment(val.query)) {
107
46
  hasIncludes = true;
108
47
  const selector = val;
@@ -124,12 +63,36 @@ export function buildInclude(fields) {
124
63
  }
125
64
  return hasIncludes ? include : undefined;
126
65
  }
66
+ /**
67
+ * Build the `FieldSelectionScope` for one fragment's field selection,
68
+ * recursing into nested Fragment/RelationSelector entries the same way
69
+ * `buildInclude` does. A relation named with the bare `true` shorthand (no
70
+ * narrower nested Fragment) gets no entry in `nested`, so a level reached
71
+ * through it is treated as unrestricted — the caller asked for "everything"
72
+ * there and gave no narrower shape to restrict it with.
73
+ * @internal
74
+ */
75
+ export function buildFieldSelectionScope(fields) {
76
+ const fieldNames = new Set(Object.keys(fields));
77
+ const nested = {};
78
+ for (const [key, value] of Object.entries(fields)) {
79
+ if (value === null || value === true || typeof value !== 'object')
80
+ continue;
81
+ const val = value;
82
+ if (isFragment(val)) {
83
+ nested[key] = buildFieldSelectionScope(val._fields);
84
+ continue;
85
+ }
86
+ if ('query' in val && isFragment(val.query)) {
87
+ nested[key] = buildFieldSelectionScope(val.query
88
+ ._fields);
89
+ }
90
+ }
91
+ return { fields: fieldNames, nested };
92
+ }
127
93
  /**
128
94
  * Recursively pick only the fields requested by a fragment from a raw Prisma
129
- * result object. This ensures the runtime shape exactly matches the type
130
- * produced by `ResultOf<F>`.
131
- *
132
- * Exported for use in `context/index.ts`.
95
+ * result object, so the runtime shape matches `ResultOf<F>`.
133
96
  * @internal
134
97
  */
135
98
  export function pickFields(item, fields) {
@@ -143,7 +106,6 @@ export function pickFields(item, fields) {
143
106
  if (value === null || typeof value !== 'object')
144
107
  continue;
145
108
  const val = value;
146
- // ── Shorthand: Fragment directly ──────────────────────────
147
109
  if (isFragment(val)) {
148
110
  if (Array.isArray(fieldValue)) {
149
111
  result[key] = fieldValue.map((elem) => pickFields(elem, val._fields));
@@ -156,7 +118,6 @@ export function pickFields(item, fields) {
156
118
  }
157
119
  continue;
158
120
  }
159
- // ── RelationSelector: { query, where?, ... } ──────────────
160
121
  if ('query' in val && isFragment(val.query)) {
161
122
  const nestedFrag = val.query;
162
123
  if (Array.isArray(fieldValue)) {
@@ -178,29 +139,9 @@ export function pickFields(item, fields) {
178
139
  // ─────────────────────────────────────────────────────────────
179
140
  /**
180
141
  * Execute a fragment-based query against a list, returning all matching
181
- * records shaped to the fragment's field selection.
182
- *
183
- * Under the hood this calls `context.db[listKey].findMany()`, so all access
184
- * control rules defined in your config are still enforced.
185
- *
186
- * **Tip:** You can also call `context.db.post.findMany({ query: fragment, ... })`
187
- * directly — both forms produce the same result.
188
- *
189
- * @param context - An `AccessContext` (or any object with a compatible `db`).
190
- * @param listKey - The PascalCase list name (e.g. `'Post'`, `'BlogPost'`).
191
- * @param fragment - A fragment created with {@link defineFragment}.
192
- * @param args - Optional query arguments (where, orderBy, take, skip).
193
- * @returns An array typed to exactly the fragment's field selection.
194
- *
195
- * @example
196
- * ```ts
197
- * const posts = await runQuery(context, 'Post', postFragment, {
198
- * where: { published: true },
199
- * orderBy: { createdAt: 'desc' },
200
- * take: 10,
201
- * })
202
- * // posts: Array<ResultOf<typeof postFragment>>
203
- * ```
142
+ * records shaped to the fragment's field selection. Calls
143
+ * `context.db[listKey].findMany()` under the hood, so access control still
144
+ * applies.
204
145
  */
205
146
  export async function runQuery(context, listKey, fragment, args) {
206
147
  const dbKey = getDbKey(listKey);
@@ -221,25 +162,8 @@ export async function runQuery(context, listKey, fragment, args) {
221
162
  }
222
163
  /**
223
164
  * Execute a fragment-based query that returns a single record (or `null`).
224
- *
225
- * Under the hood this calls `context.db[listKey].findFirst()`, so all access
226
- * control rules are still enforced.
227
- *
228
- * **Tip:** You can also call `context.db.post.findUnique({ where: { id }, query: fragment })`
229
- * directly.
230
- *
231
- * @param context - An `AccessContext` (or any object with a compatible `db`).
232
- * @param listKey - The PascalCase list name (e.g. `'Post'`).
233
- * @param fragment - A fragment created with {@link defineFragment}.
234
- * @param where - A Prisma where clause to identify the record.
235
- * @returns The matched record shaped to the fragment, or `null`.
236
- *
237
- * @example
238
- * ```ts
239
- * const post = await runQueryOne(context, 'Post', postFragment, { id: postId })
240
- * if (!post) return notFound()
241
- * // post: ResultOf<typeof postFragment>
242
- * ```
165
+ * Calls `context.db[listKey].findFirst()` under the hood, so access control
166
+ * still applies.
243
167
  */
244
168
  export async function runQueryOne(context, listKey, fragment, where) {
245
169
  const dbKey = getDbKey(listKey);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"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"}
@@ -17,7 +17,7 @@ export interface RelationshipOptionsArgs {
17
17
  * editor — the read primitive behind the `relationshipOptions` serverAction
18
18
  * op. Selects only `id` and the resolved label field (via
19
19
  * {@link getLabelFieldName}), so the fragment carries no relation keys and
20
- * `buildIncludeWithAccessControl`'s depth-5 auto-include never runs.
20
+ * `buildAccessScopedInclude` never has anything to scope.
21
21
  *
22
22
  * Operation-level `query` access on `relatedListKey` still applies — a denied
23
23
  * list resolves to `[]` (via the underlying access-controlled `findMany`).
@@ -6,7 +6,7 @@ const DEFAULT_TAKE = 50;
6
6
  * editor — the read primitive behind the `relationshipOptions` serverAction
7
7
  * op. Selects only `id` and the resolved label field (via
8
8
  * {@link getLabelFieldName}), so the fragment carries no relation keys and
9
- * `buildIncludeWithAccessControl`'s depth-5 auto-include never runs.
9
+ * `buildAccessScopedInclude` never has anything to scope.
10
10
  *
11
11
  * Operation-level `query` access on `relatedListKey` still applies — a denied
12
12
  * list resolves to `[]` (via the underlying access-controlled `findMany`).