@opensaas/stack-core 0.38.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 (204) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +123 -0
  3. package/CLAUDE.md +21 -0
  4. package/dist/access/access-filter.d.ts +46 -1
  5. package/dist/access/access-filter.d.ts.map +1 -1
  6. package/dist/access/access-filter.js +113 -4
  7. package/dist/access/access-filter.js.map +1 -1
  8. package/dist/access/declared-dependencies.d.ts.map +1 -1
  9. package/dist/access/declared-dependencies.js +4 -9
  10. package/dist/access/declared-dependencies.js.map +1 -1
  11. package/dist/access/engine.d.ts +0 -20
  12. package/dist/access/engine.d.ts.map +1 -1
  13. package/dist/access/engine.js +0 -25
  14. package/dist/access/engine.js.map +1 -1
  15. package/dist/access/errors.d.ts +49 -0
  16. package/dist/access/errors.d.ts.map +1 -1
  17. package/dist/access/errors.js +75 -0
  18. package/dist/access/errors.js.map +1 -1
  19. package/dist/access/field-access.d.ts +39 -1
  20. package/dist/access/field-access.d.ts.map +1 -1
  21. package/dist/access/field-access.js +108 -42
  22. package/dist/access/field-access.js.map +1 -1
  23. package/dist/access/field-access.test.js +229 -2
  24. package/dist/access/field-access.test.js.map +1 -1
  25. package/dist/access/field-transforms.d.ts +0 -27
  26. package/dist/access/field-transforms.d.ts.map +1 -1
  27. package/dist/access/field-visibility.d.ts +0 -4
  28. package/dist/access/field-visibility.d.ts.map +1 -1
  29. package/dist/access/field-visibility.js +13 -39
  30. package/dist/access/field-visibility.js.map +1 -1
  31. package/dist/access/index.d.ts +6 -2
  32. package/dist/access/index.d.ts.map +1 -1
  33. package/dist/access/index.js +12 -2
  34. package/dist/access/index.js.map +1 -1
  35. package/dist/access/query-validation.d.ts +121 -0
  36. package/dist/access/query-validation.d.ts.map +1 -0
  37. package/dist/access/query-validation.js +292 -0
  38. package/dist/access/query-validation.js.map +1 -0
  39. package/dist/access/relationship-count.d.ts.map +1 -1
  40. package/dist/access/relationship-count.js +2 -10
  41. package/dist/access/relationship-count.js.map +1 -1
  42. package/dist/access/relationship-label-filter.d.ts +23 -23
  43. package/dist/access/relationship-label-filter.d.ts.map +1 -1
  44. package/dist/access/relationship-label-filter.js +5 -76
  45. package/dist/access/relationship-label-filter.js.map +1 -1
  46. package/dist/access/relationship-label-filter.test.js +19 -56
  47. package/dist/access/relationship-label-filter.test.js.map +1 -1
  48. package/dist/access/transaction-registry.d.ts +45 -0
  49. package/dist/access/transaction-registry.d.ts.map +1 -0
  50. package/dist/access/transaction-registry.js +37 -0
  51. package/dist/access/transaction-registry.js.map +1 -0
  52. package/dist/access/types.d.ts +55 -59
  53. package/dist/access/types.d.ts.map +1 -1
  54. package/dist/config/index.d.ts +9 -7
  55. package/dist/config/index.d.ts.map +1 -1
  56. package/dist/config/index.js +10 -18
  57. package/dist/config/index.js.map +1 -1
  58. package/dist/config/label.d.ts +6 -13
  59. package/dist/config/label.d.ts.map +1 -1
  60. package/dist/config/label.js +6 -13
  61. package/dist/config/label.js.map +1 -1
  62. package/dist/config/nav-count.d.ts +11 -19
  63. package/dist/config/nav-count.d.ts.map +1 -1
  64. package/dist/config/nav-count.js +11 -19
  65. package/dist/config/nav-count.js.map +1 -1
  66. package/dist/config/plugin-engine.d.ts +0 -10
  67. package/dist/config/plugin-engine.d.ts.map +1 -1
  68. package/dist/config/plugin-engine.js +1 -37
  69. package/dist/config/plugin-engine.js.map +1 -1
  70. package/dist/config/types.d.ts +94 -109
  71. package/dist/config/types.d.ts.map +1 -1
  72. package/dist/context/apply-defaults.d.ts +8 -31
  73. package/dist/context/apply-defaults.d.ts.map +1 -1
  74. package/dist/context/apply-defaults.js +12 -41
  75. package/dist/context/apply-defaults.js.map +1 -1
  76. package/dist/context/hook-pipeline.d.ts +4 -29
  77. package/dist/context/hook-pipeline.d.ts.map +1 -1
  78. package/dist/context/hook-pipeline.js +8 -41
  79. package/dist/context/hook-pipeline.js.map +1 -1
  80. package/dist/context/index.d.ts +4 -15
  81. package/dist/context/index.d.ts.map +1 -1
  82. package/dist/context/index.js +190 -193
  83. package/dist/context/index.js.map +1 -1
  84. package/dist/context/nested-operations.d.ts +7 -26
  85. package/dist/context/nested-operations.d.ts.map +1 -1
  86. package/dist/context/nested-operations.js +73 -171
  87. package/dist/context/nested-operations.js.map +1 -1
  88. package/dist/context/transaction-boundary.d.ts +36 -47
  89. package/dist/context/transaction-boundary.d.ts.map +1 -1
  90. package/dist/context/transaction-boundary.js +92 -79
  91. package/dist/context/transaction-boundary.js.map +1 -1
  92. package/dist/context/write-pipeline.d.ts +25 -64
  93. package/dist/context/write-pipeline.d.ts.map +1 -1
  94. package/dist/context/write-pipeline.js +81 -111
  95. package/dist/context/write-pipeline.js.map +1 -1
  96. package/dist/fields/format-prisma-default.d.ts.map +1 -1
  97. package/dist/fields/format-prisma-default.js +4 -7
  98. package/dist/fields/format-prisma-default.js.map +1 -1
  99. package/dist/fields/index.d.ts +17 -2
  100. package/dist/fields/index.d.ts.map +1 -1
  101. package/dist/fields/index.js +136 -147
  102. package/dist/fields/index.js.map +1 -1
  103. package/dist/filter/collect.d.ts +26 -3
  104. package/dist/filter/collect.d.ts.map +1 -1
  105. package/dist/filter/collect.js +30 -12
  106. package/dist/filter/collect.js.map +1 -1
  107. package/dist/filter/filter.test.js +98 -15
  108. package/dist/filter/filter.test.js.map +1 -1
  109. package/dist/filter/index.d.ts +1 -0
  110. package/dist/filter/index.d.ts.map +1 -1
  111. package/dist/filter/index.js.map +1 -1
  112. package/dist/filter/map.d.ts.map +1 -1
  113. package/dist/filter/map.js +0 -5
  114. package/dist/filter/map.js.map +1 -1
  115. package/dist/filter/parse.d.ts.map +1 -1
  116. package/dist/filter/parse.js +2 -9
  117. package/dist/filter/parse.js.map +1 -1
  118. package/dist/filter/serialize.d.ts.map +1 -1
  119. package/dist/filter/serialize.js +2 -4
  120. package/dist/filter/serialize.js.map +1 -1
  121. package/dist/hooks/index.d.ts +4 -42
  122. package/dist/hooks/index.d.ts.map +1 -1
  123. package/dist/hooks/index.js +5 -59
  124. package/dist/hooks/index.js.map +1 -1
  125. package/dist/index.d.ts +3 -1
  126. package/dist/index.d.ts.map +1 -1
  127. package/dist/index.js +20 -4
  128. package/dist/index.js.map +1 -1
  129. package/dist/internal.d.ts +1 -0
  130. package/dist/internal.d.ts.map +1 -1
  131. package/dist/internal.js +4 -0
  132. package/dist/internal.js.map +1 -1
  133. package/dist/lib/case-utils.d.ts +0 -32
  134. package/dist/lib/case-utils.d.ts.map +1 -1
  135. package/dist/lib/case-utils.js +0 -32
  136. package/dist/lib/case-utils.js.map +1 -1
  137. package/dist/mcp/handler.d.ts +0 -4
  138. package/dist/mcp/handler.d.ts.map +1 -1
  139. package/dist/mcp/handler.js +12 -69
  140. package/dist/mcp/handler.js.map +1 -1
  141. package/dist/query/index.d.ts +26 -227
  142. package/dist/query/index.d.ts.map +1 -1
  143. package/dist/query/index.js +14 -117
  144. package/dist/query/index.js.map +1 -1
  145. package/dist/utils/password.d.ts +0 -68
  146. package/dist/utils/password.d.ts.map +1 -1
  147. package/dist/utils/password.js +7 -76
  148. package/dist/utils/password.js.map +1 -1
  149. package/dist/validation/field-config.d.ts.map +1 -1
  150. package/dist/validation/field-config.js +0 -6
  151. package/dist/validation/field-config.js.map +1 -1
  152. package/dist/validation/schema.d.ts +0 -7
  153. package/dist/validation/schema.d.ts.map +1 -1
  154. package/dist/validation/schema.js +0 -10
  155. package/dist/validation/schema.js.map +1 -1
  156. package/package.json +1 -1
  157. package/src/access/access-filter.ts +152 -5
  158. package/src/access/declared-dependencies.ts +4 -9
  159. package/src/access/engine.ts +0 -25
  160. package/src/access/errors.ts +81 -0
  161. package/src/access/field-access.test.ts +312 -2
  162. package/src/access/field-access.ts +118 -42
  163. package/src/access/field-transforms.ts +8 -39
  164. package/src/access/field-visibility.ts +16 -47
  165. package/src/access/index.ts +20 -2
  166. package/src/access/query-validation.ts +359 -0
  167. package/src/access/relationship-count.ts +2 -10
  168. package/src/access/relationship-label-filter.test.ts +19 -68
  169. package/src/access/relationship-label-filter.ts +27 -104
  170. package/src/access/transaction-registry.ts +58 -0
  171. package/src/access/types.ts +83 -86
  172. package/src/config/index.ts +10 -22
  173. package/src/config/label.ts +6 -13
  174. package/src/config/nav-count.ts +11 -19
  175. package/src/config/plugin-engine.ts +1 -37
  176. package/src/config/types.ts +95 -110
  177. package/src/context/apply-defaults.ts +12 -44
  178. package/src/context/hook-pipeline.ts +12 -67
  179. package/src/context/index.ts +263 -247
  180. package/src/context/nested-operations.ts +94 -226
  181. package/src/context/transaction-boundary.ts +113 -109
  182. package/src/context/write-pipeline.ts +99 -155
  183. package/src/fields/format-prisma-default.ts +4 -7
  184. package/src/fields/index.ts +155 -147
  185. package/src/filter/collect.ts +48 -12
  186. package/src/filter/filter.test.ts +153 -15
  187. package/src/filter/index.ts +1 -0
  188. package/src/filter/map.ts +0 -5
  189. package/src/filter/parse.ts +2 -9
  190. package/src/filter/serialize.ts +2 -4
  191. package/src/hooks/index.ts +5 -59
  192. package/src/index.ts +23 -4
  193. package/src/internal.ts +5 -0
  194. package/src/lib/case-utils.ts +0 -32
  195. package/src/mcp/handler.ts +13 -71
  196. package/src/query/index.ts +29 -235
  197. package/src/utils/password.ts +7 -76
  198. package/src/validation/field-config.ts +0 -6
  199. package/src/validation/schema.ts +0 -10
  200. package/tests/context.test.ts +700 -1
  201. package/tests/field-types.test.ts +222 -0
  202. package/tests/mcp-handler.test.ts +34 -0
  203. package/tests/transaction-boundary-outermost.test.ts +530 -0
  204. package/tsconfig.tsbuildinfo +1 -1
@@ -44,4 +44,53 @@ export declare class ResolveOutputCycleError extends Error {
44
44
  fieldKey: string;
45
45
  }[]);
46
46
  }
47
+ /**
48
+ * Thrown when a relation filter in a caller's `where` (`some`/`every`/`none`/
49
+ * `is`/`isNot`) names a relationship whose related list denies operation-level
50
+ * `query` access outright (`=== false`). Deliberately a loud failure, not a
51
+ * silently narrowed `{ id: { in: [] } }` or a pass-through: ADR-0022 requires
52
+ * an engine that cannot compute a scope to deny, never pass through, and here
53
+ * the engine CAN compute the scope (denied) — passing that through as a
54
+ * silently-empty match would itself be a distinguishable signal for a caller
55
+ * probing which relations they may filter on. `include`'s equivalent case
56
+ * (`buildAccessScopedInclude`) drops the relation silently instead, because a
57
+ * `null`/missing key in a response is indistinguishable from "not requested";
58
+ * a `where` predicate has no such neutral outcome, so a relation filter on a
59
+ * fully denied relation is refused instead. `sudo` bypasses this check
60
+ * entirely, matching every other access-control escape hatch. See #916 and
61
+ * `docs/adr/0022-access-control-fails-closed-when-it-cannot-scope.md`.
62
+ */
63
+ export declare class RelationFilterAccessDeniedError extends Error {
64
+ listKey: string;
65
+ fieldKey: string;
66
+ relatedListKey: string;
67
+ constructor(listKey: string, fieldKey: string, relatedListKey: string);
68
+ }
69
+ /**
70
+ * Thrown when a field-level access control function returns anything other
71
+ * than a strict `boolean`. `FieldAccessControl` is typed to return `boolean`
72
+ * only: field access is a single per-field visibility decision, not a row
73
+ * filter, and a denied field is removed rather than used to scope rows (see
74
+ * the "Field-level access" glossary entry in `CONTEXT.md`, ADR-0001, and
75
+ * ADR-0030).
76
+ *
77
+ * A rule that type-checks can never reach this — the only way here is a
78
+ * caller that bypasses the type (an untyped JS config, or a value forced past
79
+ * the checker), most notably a Prisma filter, which is the shape
80
+ * operation-level `AccessControl` accepts but `FieldAccessControl` does not.
81
+ * Before #913 this fell through to an unconditional `return true`, silently
82
+ * granting the field blanket access; it now fails loudly and closed instead,
83
+ * for `read`, `create`, and `update` alike.
84
+ *
85
+ * Deliberately does not expose the offending result as a public field: unlike
86
+ * `AccessScopeDepthExceededError`/`ResolveOutputCycleError`'s fields, there is
87
+ * no concretely-typed shape to give it (the whole problem is that it isn't
88
+ * the `boolean` the caller's rule promised), and the root CLAUDE.md forbids
89
+ * exposing `unknown`/`any` as part of a package's external API. A description
90
+ * of what was returned instead is folded into the message text.
91
+ */
92
+ export declare class InvalidFieldAccessResultError extends Error {
93
+ operation: 'read' | 'create' | 'update';
94
+ constructor(operation: 'read' | 'create' | 'update', result: unknown);
95
+ }
47
96
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/access/errors.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,6BAA8B,SAAQ,KAAK;IAC/C,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IAEpB,YAAY,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAW3D;CACF;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IACzC,KAAK,EAAE,SAAS;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAE9D,YAAY,KAAK,EAAE,SAAS;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,EAUlE;CACF"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/access/errors.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,6BAA8B,SAAQ,KAAK;IAC/C,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IAEpB,YAAY,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAW3D;CACF;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IACzC,KAAK,EAAE,SAAS;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAE9D,YAAY,KAAK,EAAE,SAAS;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,EAUlE;CACF;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,+BAAgC,SAAQ,KAAK;IACjD,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,MAAM,CAAA;IAE7B,YAAY,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAUpE;CACF;AASD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,6BAA8B,SAAQ,KAAK;IAC/C,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAA;IAE9C,YAAY,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,EAAE,MAAM,EAAE,OAAO,EAWnE;CACF"}
@@ -56,4 +56,79 @@ export class ResolveOutputCycleError extends Error {
56
56
  this.chain = chain;
57
57
  }
58
58
  }
59
+ /**
60
+ * Thrown when a relation filter in a caller's `where` (`some`/`every`/`none`/
61
+ * `is`/`isNot`) names a relationship whose related list denies operation-level
62
+ * `query` access outright (`=== false`). Deliberately a loud failure, not a
63
+ * silently narrowed `{ id: { in: [] } }` or a pass-through: ADR-0022 requires
64
+ * an engine that cannot compute a scope to deny, never pass through, and here
65
+ * the engine CAN compute the scope (denied) — passing that through as a
66
+ * silently-empty match would itself be a distinguishable signal for a caller
67
+ * probing which relations they may filter on. `include`'s equivalent case
68
+ * (`buildAccessScopedInclude`) drops the relation silently instead, because a
69
+ * `null`/missing key in a response is indistinguishable from "not requested";
70
+ * a `where` predicate has no such neutral outcome, so a relation filter on a
71
+ * fully denied relation is refused instead. `sudo` bypasses this check
72
+ * entirely, matching every other access-control escape hatch. See #916 and
73
+ * `docs/adr/0022-access-control-fails-closed-when-it-cannot-scope.md`.
74
+ */
75
+ export class RelationFilterAccessDeniedError extends Error {
76
+ listKey;
77
+ fieldKey;
78
+ relatedListKey;
79
+ constructor(listKey, fieldKey, relatedListKey) {
80
+ super(`Cannot filter "${listKey}.${fieldKey}" — the related list "${relatedListKey}" denies ` +
81
+ `query access to this session, so this relation filter cannot be scoped. Denial is loud ` +
82
+ `rather than silently narrowed to match nothing (ADR-0022). Use sudo to bypass.`);
83
+ this.name = 'RelationFilterAccessDeniedError';
84
+ this.listKey = listKey;
85
+ this.fieldKey = fieldKey;
86
+ this.relatedListKey = relatedListKey;
87
+ }
88
+ }
89
+ function describeFieldAccessResult(result) {
90
+ if (result === null)
91
+ return 'null';
92
+ if (result === undefined)
93
+ return 'undefined';
94
+ if (typeof result === 'object')
95
+ return 'an object (e.g. a Prisma filter)';
96
+ return `a ${typeof result}`;
97
+ }
98
+ /**
99
+ * Thrown when a field-level access control function returns anything other
100
+ * than a strict `boolean`. `FieldAccessControl` is typed to return `boolean`
101
+ * only: field access is a single per-field visibility decision, not a row
102
+ * filter, and a denied field is removed rather than used to scope rows (see
103
+ * the "Field-level access" glossary entry in `CONTEXT.md`, ADR-0001, and
104
+ * ADR-0030).
105
+ *
106
+ * A rule that type-checks can never reach this — the only way here is a
107
+ * caller that bypasses the type (an untyped JS config, or a value forced past
108
+ * the checker), most notably a Prisma filter, which is the shape
109
+ * operation-level `AccessControl` accepts but `FieldAccessControl` does not.
110
+ * Before #913 this fell through to an unconditional `return true`, silently
111
+ * granting the field blanket access; it now fails loudly and closed instead,
112
+ * for `read`, `create`, and `update` alike.
113
+ *
114
+ * Deliberately does not expose the offending result as a public field: unlike
115
+ * `AccessScopeDepthExceededError`/`ResolveOutputCycleError`'s fields, there is
116
+ * no concretely-typed shape to give it (the whole problem is that it isn't
117
+ * the `boolean` the caller's rule promised), and the root CLAUDE.md forbids
118
+ * exposing `unknown`/`any` as part of a package's external API. A description
119
+ * of what was returned instead is folded into the message text.
120
+ */
121
+ export class InvalidFieldAccessResultError extends Error {
122
+ operation;
123
+ constructor(operation, result) {
124
+ super(`Field-level access control for operation "${operation}" returned ` +
125
+ `${describeFieldAccessResult(result)}, not a boolean. Field access is a per-field ` +
126
+ `visibility decision — it must return true or false, and (unlike operation-level access) ` +
127
+ `cannot scope which rows are affected. If you meant to restrict access based on the row or ` +
128
+ `the write payload, evaluate the condition yourself and return a boolean, e.g. ` +
129
+ `\`({ item, session }) => item?.ownerId === session?.userId\`.`);
130
+ this.name = 'InvalidFieldAccessResultError';
131
+ this.operation = operation;
132
+ }
133
+ }
59
134
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/access/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAE1D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,6BAA8B,SAAQ,KAAK;IAC/C,OAAO,CAAQ;IACf,QAAQ,CAAQ;IAChB,KAAK,CAAQ;IAEpB,YAAY,OAAe,EAAE,QAAgB,EAAE,KAAa;QAC1D,KAAK,CACH,mBAAmB,OAAO,IAAI,QAAQ,sBAAsB,KAAK,0BAA0B;YACzF,qCAAqC,sBAAsB,kCAAkC;YAC7F,2FAA2F;YAC3F,8DAA8D,CACjE,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAA;QAC3C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;CACF;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IACzC,KAAK,CAAkD;IAE9D,YAAY,KAAuD;QACjE,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAChF,KAAK,CACH,iCAAiC,IAAI,+CAA+C;YAClF,wFAAwF;YACxF,0FAA0F;YAC1F,iCAAiC,CACpC,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAA;QACrC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;CACF"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/access/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAE1D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,6BAA8B,SAAQ,KAAK;IAC/C,OAAO,CAAQ;IACf,QAAQ,CAAQ;IAChB,KAAK,CAAQ;IAEpB,YAAY,OAAe,EAAE,QAAgB,EAAE,KAAa;QAC1D,KAAK,CACH,mBAAmB,OAAO,IAAI,QAAQ,sBAAsB,KAAK,0BAA0B;YACzF,qCAAqC,sBAAsB,kCAAkC;YAC7F,2FAA2F;YAC3F,8DAA8D,CACjE,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAA;QAC3C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;CACF;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IACzC,KAAK,CAAkD;IAE9D,YAAY,KAAuD;QACjE,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAChF,KAAK,CACH,iCAAiC,IAAI,+CAA+C;YAClF,wFAAwF;YACxF,0FAA0F;YAC1F,iCAAiC,CACpC,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAA;QACrC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;CACF;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,+BAAgC,SAAQ,KAAK;IACjD,OAAO,CAAQ;IACf,QAAQ,CAAQ;IAChB,cAAc,CAAQ;IAE7B,YAAY,OAAe,EAAE,QAAgB,EAAE,cAAsB;QACnE,KAAK,CACH,kBAAkB,OAAO,IAAI,QAAQ,yBAAyB,cAAc,WAAW;YACrF,yFAAyF;YACzF,gFAAgF,CACnF,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,iCAAiC,CAAA;QAC7C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,cAAc,GAAG,cAAc,CAAA;IACtC,CAAC;CACF;AAED,SAAS,yBAAyB,CAAC,MAAe;IAChD,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,MAAM,CAAA;IAClC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,WAAW,CAAA;IAC5C,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,kCAAkC,CAAA;IACzE,OAAO,KAAK,OAAO,MAAM,EAAE,CAAA;AAC7B,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,6BAA8B,SAAQ,KAAK;IAC/C,SAAS,CAA8B;IAE9C,YAAY,SAAuC,EAAE,MAAe;QAClE,KAAK,CACH,6CAA6C,SAAS,aAAa;YACjE,GAAG,yBAAyB,CAAC,MAAM,CAAC,+CAA+C;YACnF,0FAA0F;YAC1F,4FAA4F;YAC5F,gFAAgF;YAChF,+DAA+D,CAClE,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,+BAA+B,CAAA;QAC3C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;IAC5B,CAAC;CACF"}
@@ -18,6 +18,10 @@ import type { FieldAccess } from './types.js';
18
18
  * (read/update/delete), and on the `inputData` being written (create/update),
19
19
  * so all of those are accepted. Do not introduce a parallel evaluator with a
20
20
  * narrower signature.
21
+ *
22
+ * Returns a strict boolean, never a filter: a rule that returns anything else
23
+ * throws `InvalidFieldAccessResultError` rather than defaulting to allow (see
24
+ * that error's doc, ADR-0001, and ADR-0030).
21
25
  */
22
26
  export declare function checkFieldAccess(fieldAccess: FieldAccess | undefined, operation: 'read' | 'create' | 'update', args: {
23
27
  session: Session | null;
@@ -28,8 +32,42 @@ export declare function checkFieldAccess(fieldAccess: FieldAccess | undefined, o
28
32
  inputData?: Record<string, unknown>;
29
33
  }): Promise<boolean>;
30
34
  /**
31
- * Filter fields from input data based on write access (create/update)
35
+ * Whether a field's `read` access allows it to be NAMED in a `where`/`orderBy`
36
+ * predicate, evaluated BEFORE the query runs (#915).
37
+ *
38
+ * Field-level `read` access has always been a post-query check (Field
39
+ * Visibility, `field-visibility.ts`): it strips a denied key from a row that
40
+ * has already been fetched. That leaves the predicate itself unconstrained —
41
+ * a caller can still filter or sort by a field whose value they could never
42
+ * read, and recover it (or its relative order) by probing. This function is
43
+ * the pre-query counterpart, called from `query-validation.ts`'s `where`/
44
+ * `orderBy` walk for every key that resolves to a declared field.
45
+ *
46
+ * It delegates to the same evaluator Field Visibility uses (`checkFieldAccess`),
47
+ * per this module's canonical-evaluator rule above. The one difference is the
48
+ * `item` it hands the rule: there is no fetched row
49
+ * yet, so a rule that depends on one (the shape `FieldAccess['read']`
50
+ * documents as the norm, e.g. `item?.ownerId === session?.userId`) cannot be
51
+ * answered here. Rather than skip the check for such a rule — which would
52
+ * reopen exactly the hole this closes for the fields most likely to be
53
+ * sensitive — it is handed a poisoned `item` that throws on any property
54
+ * read, and that throw is caught and resolved to `false`: a row-dependent
55
+ * `read` rule always denies at predicate time, documented and deliberate
56
+ * (see docs/adr/0031). A rule that never touches `item` (checking only
57
+ * `session`, the common case for a field meant to be filterable/sortable at
58
+ * all) evaluates normally and returns its real answer.
59
+ *
60
+ * A rule that returns a non-boolean is a distinct, louder failure (#913,
61
+ * ADR-0030) — `InvalidFieldAccessResultError` — and is deliberately NOT
62
+ * folded into the `false` here; it propagates so the config bug it signals is
63
+ * never mistaken for an ordinary field-level denial.
32
64
  */
65
+ export declare function isFieldReadableForPredicate(fieldAccess: FieldAccess | undefined, args: {
66
+ session: Session | null;
67
+ context: AccessContext & {
68
+ _isSudo?: boolean;
69
+ };
70
+ }): Promise<boolean>;
33
71
  export declare function filterWritableFields<T extends Record<string, unknown>>(data: T, fieldConfigs: Record<string, {
34
72
  access?: FieldAccess;
35
73
  type?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"field-access.d.ts","sourceRoot":"","sources":["../../src/access/field-access.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAM7C;;;;;;;;;GASG;AAEH;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,WAAW,GAAG,SAAS,EACpC,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,EACvC,IAAI,EAAE;IACJ,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,OAAO,EAAE,aAAa,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC,GACA,OAAO,CAAC,OAAO,CAAC,CAmClB;AA8BD;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1E,IAAI,EAAE,CAAC,EACP,YAAY,EAAE,MAAM,CAClB,MAAM,EACN;IACE,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EAAE,CAAA;CACjD,CACF,EACD,SAAS,EAAE,QAAQ,GAAG,QAAQ,EAC9B,IAAI,EAAE;IACJ,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,OAAO,EAAE,aAAa,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC,GACA,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CA2HrB"}
1
+ {"version":3,"file":"field-access.d.ts","sourceRoot":"","sources":["../../src/access/field-access.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACxD,OAAO,KAAK,EAAE,WAAW,EAAsB,MAAM,YAAY,CAAA;AA6CjE;;;;;;;;;GASG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAsB,gBAAgB,CACpC,WAAW,EAAE,WAAW,GAAG,SAAS,EACpC,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,EACvC,IAAI,EAAE;IACJ,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,OAAO,EAAE,aAAa,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC,GACA,OAAO,CAAC,OAAO,CAAC,CA+ClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAsB,2BAA2B,CAC/C,WAAW,EAAE,WAAW,GAAG,SAAS,EACpC,IAAI,EAAE;IACJ,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACvB,OAAO,EAAE,aAAa,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CAC/C,GACA,OAAO,CAAC,OAAO,CAAC,CAelB;AAED,wBAAsB,oBAAoB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1E,IAAI,EAAE,CAAC,EACP,YAAY,EAAE,MAAM,CAClB,MAAM,EACN;IACE,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,EAAE,CAAA;CACjD,CACF,EACD,SAAS,EAAE,QAAQ,GAAG,QAAQ,EAC9B,IAAI,EAAE;IACJ,OAAO,EAAE,OAAO,GAAG,IAAI,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,OAAO,EAAE,aAAa,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC,GACA,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAyHrB"}
@@ -2,6 +2,41 @@
2
2
  // at module-evaluation time, so the field-access ⇄ hooks import cycle is safe
3
3
  // under ESM live bindings.
4
4
  import { ValidationError } from '../hooks/index.js';
5
+ import { InvalidFieldAccessResultError } from './errors.js';
6
+ /**
7
+ * Marks a throw caused by touching {@link createPoisonedItem}'s `item`, as
8
+ * opposed to some other error a field rule legitimately raises. Not exported
9
+ * — callers only ever see its effect (a `false` from
10
+ * `isFieldReadableForPredicate`), never the class itself.
11
+ */
12
+ class PredicateTimeItemAccessError extends Error {
13
+ }
14
+ /**
15
+ * An `item` that throws {@link PredicateTimeItemAccessError} on ANY attempt to
16
+ * read a property off it — including via optional chaining (`item?.x`),
17
+ * since the Proxy itself is a truthy object and optional chaining still
18
+ * performs the property read once its base is non-nullish. Used by
19
+ * `isFieldReadableForPredicate` to detect a read rule that depends on the
20
+ * fetched row: there is no row yet at predicate-evaluation time (see that
21
+ * function's doc), so any rule that reaches into `item` at all cannot be
22
+ * answered here.
23
+ */
24
+ function createPoisonedItem() {
25
+ return new Proxy({}, {
26
+ get(_target, prop) {
27
+ throw new PredicateTimeItemAccessError(String(prop));
28
+ },
29
+ has(_target, prop) {
30
+ throw new PredicateTimeItemAccessError(String(prop));
31
+ },
32
+ ownKeys() {
33
+ throw new PredicateTimeItemAccessError('ownKeys');
34
+ },
35
+ getOwnPropertyDescriptor(_target, prop) {
36
+ throw new PredicateTimeItemAccessError(String(prop));
37
+ },
38
+ });
39
+ }
5
40
  /**
6
41
  * Shared field-level access evaluation.
7
42
  *
@@ -20,18 +55,29 @@ import { ValidationError } from '../hooks/index.js';
20
55
  * (read/update/delete), and on the `inputData` being written (create/update),
21
56
  * so all of those are accepted. Do not introduce a parallel evaluator with a
22
57
  * narrower signature.
58
+ *
59
+ * Returns a strict boolean, never a filter: a rule that returns anything else
60
+ * throws `InvalidFieldAccessResultError` rather than defaulting to allow (see
61
+ * that error's doc, ADR-0001, and ADR-0030).
23
62
  */
24
63
  export async function checkFieldAccess(fieldAccess, operation, args) {
25
- // Skip access check in sudo mode
26
64
  if (args.context._isSudo) {
27
65
  return true;
28
66
  }
29
67
  if (!fieldAccess) {
30
- return true; // No field access means allow
68
+ return true;
31
69
  }
70
+ // `FieldAccess['read']` is narrower than `FieldAccess['create'/'update']` (it
71
+ // only accepts the single `operation: 'read'` call shape, see `types.ts`),
72
+ // so indexing by a not-yet-narrowed `operation` union produces a callable
73
+ // whose effective parameter type collapses to an intersection TypeScript
74
+ // can't satisfy generically here. Widen back to the general
75
+ // `FieldAccessControl` — the same shape this function has always built and
76
+ // passed below — since by construction the args object always matches
77
+ // whichever operation is actually requested.
32
78
  const accessControl = fieldAccess[operation];
33
79
  if (!accessControl) {
34
- return true; // No specific access control means allow
80
+ return true;
35
81
  }
36
82
  const result = await accessControl({
37
83
  session: args.session,
@@ -40,53 +86,74 @@ export async function checkFieldAccess(fieldAccess, operation, args) {
40
86
  inputData: args.inputData,
41
87
  operation,
42
88
  });
43
- // If result is false, deny access
44
89
  if (result === false) {
45
90
  return false;
46
91
  }
47
- // If result is true, allow access
48
92
  if (result === true) {
49
93
  return true;
50
94
  }
51
- // Default to allowing access if we can't determine
52
- return true;
95
+ // `FieldAccessControl` is typed to return `boolean` only field access is a
96
+ // per-field visibility decision, not a row filter (ADR-0001, ADR-0030). A
97
+ // well-typed rule can never reach this line; getting here means a caller
98
+ // bypassed the type (most notably by returning a Prisma filter, the shape
99
+ // operation-level `AccessControl` accepts but this does not). Fail loudly
100
+ // and closed — this operation applies identically whether or not `item` is
101
+ // available, so `create` (which has no `item` to evaluate a filter against)
102
+ // needs no separate answer: neither operation ever honours a non-boolean.
103
+ throw new InvalidFieldAccessResultError(operation, result);
53
104
  }
54
105
  /**
55
- * Simple filter matching for field-level access
56
- * Checks if an item matches a Prisma-like filter object
106
+ * Whether a field's `read` access allows it to be NAMED in a `where`/`orderBy`
107
+ * predicate, evaluated BEFORE the query runs (#915).
108
+ *
109
+ * Field-level `read` access has always been a post-query check (Field
110
+ * Visibility, `field-visibility.ts`): it strips a denied key from a row that
111
+ * has already been fetched. That leaves the predicate itself unconstrained —
112
+ * a caller can still filter or sort by a field whose value they could never
113
+ * read, and recover it (or its relative order) by probing. This function is
114
+ * the pre-query counterpart, called from `query-validation.ts`'s `where`/
115
+ * `orderBy` walk for every key that resolves to a declared field.
116
+ *
117
+ * It delegates to the same evaluator Field Visibility uses (`checkFieldAccess`),
118
+ * per this module's canonical-evaluator rule above. The one difference is the
119
+ * `item` it hands the rule: there is no fetched row
120
+ * yet, so a rule that depends on one (the shape `FieldAccess['read']`
121
+ * documents as the norm, e.g. `item?.ownerId === session?.userId`) cannot be
122
+ * answered here. Rather than skip the check for such a rule — which would
123
+ * reopen exactly the hole this closes for the fields most likely to be
124
+ * sensitive — it is handed a poisoned `item` that throws on any property
125
+ * read, and that throw is caught and resolved to `false`: a row-dependent
126
+ * `read` rule always denies at predicate time, documented and deliberate
127
+ * (see docs/adr/0031). A rule that never touches `item` (checking only
128
+ * `session`, the common case for a field meant to be filterable/sortable at
129
+ * all) evaluates normally and returns its real answer.
130
+ *
131
+ * A rule that returns a non-boolean is a distinct, louder failure (#913,
132
+ * ADR-0030) — `InvalidFieldAccessResultError` — and is deliberately NOT
133
+ * folded into the `false` here; it propagates so the config bug it signals is
134
+ * never mistaken for an ordinary field-level denial.
57
135
  */
58
- function matchesFilter(item, filter) {
59
- for (const [key, condition] of Object.entries(filter)) {
60
- if (typeof condition === 'object' && condition !== null) {
61
- // Handle nested conditions like { equals: value }
62
- if ('equals' in condition) {
63
- if (item[key] !== condition.equals) {
64
- return false;
65
- }
66
- }
67
- else if ('not' in condition) {
68
- if (item[key] === condition.not) {
69
- return false;
70
- }
71
- }
72
- // Add more condition types as needed
73
- }
74
- else {
75
- // Direct equality check
76
- if (item[key] !== condition) {
77
- return false;
78
- }
79
- }
136
+ export async function isFieldReadableForPredicate(fieldAccess, args) {
137
+ try {
138
+ return await checkFieldAccess(fieldAccess, 'read', {
139
+ session: args.session,
140
+ context: args.context,
141
+ item: createPoisonedItem(),
142
+ });
143
+ }
144
+ catch (err) {
145
+ // Only the poisoned-item signal means "row-dependent, deny". Anything
146
+ // else including `InvalidFieldAccessResultError` and a genuine bug in
147
+ // the rule itself — propagates unchanged rather than being silently
148
+ // folded into an ordinary denial (found in review of #925).
149
+ if (err instanceof PredicateTimeItemAccessError)
150
+ return false;
151
+ throw err;
80
152
  }
81
- return true;
82
153
  }
83
- /**
84
- * Filter fields from input data based on write access (create/update)
85
- */
86
154
  export async function filterWritableFields(data, fieldConfigs, operation, args) {
87
155
  const filtered = {};
88
- // Build a set of foreign key field names to exclude
89
- // Foreign keys should not be in the data when using Prisma's relation syntax
156
+ // Foreign keys must not appear in `data` when using Prisma's relation syntax.
90
157
  const foreignKeyFields = new Set();
91
158
  // Map each raw per-part column name contributed by a multi-column field
92
159
  // (e.g. storage image()/file() in Keystone-parity mode) back to its OWNING
@@ -122,17 +189,16 @@ export async function filterWritableFields(data, fieldConfigs, operation, args)
122
189
  const isSudo = args.context._isSudo === true;
123
190
  for (const [fieldName, value] of Object.entries(data)) {
124
191
  const fieldConfig = fieldConfigs[fieldName];
125
- // Skip system fields
126
192
  if (['id', 'createdAt', 'updatedAt'].includes(fieldName)) {
127
193
  continue;
128
194
  }
129
- // Skip virtual fields - they don't store in database
130
- // Virtual fields with resolveInput hooks handle side effects separately
195
+ // Virtual fields don't store in the database — skipped here, but their
196
+ // resolveInput hooks still run as a separate side-effect step.
131
197
  if (fieldConfig && 'virtual' in fieldConfig && fieldConfig.virtual) {
132
198
  continue;
133
199
  }
134
- // Skip foreign key fields (e.g., authorId) when their corresponding relationship field exists
135
- // This prevents conflicts when using Prisma's relation syntax (e.g., author: { connect: { id } })
200
+ // Prevents conflicts with Prisma's relation syntax (e.g.,
201
+ // `author: { connect: { id } }`).
136
202
  if (foreignKeyFields.has(fieldName)) {
137
203
  continue;
138
204
  }
@@ -1 +1 @@
1
- {"version":3,"file":"field-access.js","sourceRoot":"","sources":["../../src/access/field-access.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"field-access.js","sourceRoot":"","sources":["../../src/access/field-access.ts"],"names":[],"mappings":"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"}