@cerbos/orm-prisma 4.0.0 → 5.0.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 (203) hide show
  1. package/README.md +611 -460
  2. package/lib/collections.d.ts +30 -0
  3. package/lib/collections.d.ts.map +1 -0
  4. package/lib/collections.js +421 -0
  5. package/lib/collections.js.map +1 -0
  6. package/lib/comparison.d.ts +24 -0
  7. package/lib/comparison.d.ts.map +1 -0
  8. package/lib/comparison.js +731 -0
  9. package/lib/comparison.js.map +1 -0
  10. package/lib/errors.d.ts +13 -0
  11. package/lib/errors.d.ts.map +1 -0
  12. package/lib/errors.js +17 -0
  13. package/lib/errors.js.map +1 -0
  14. package/lib/evaluate.d.ts +5 -0
  15. package/lib/evaluate.d.ts.map +1 -0
  16. package/lib/evaluate.js +118 -0
  17. package/lib/evaluate.js.map +1 -0
  18. package/lib/fields.d.ts +34 -0
  19. package/lib/fields.d.ts.map +1 -0
  20. package/lib/fields.js +253 -0
  21. package/lib/fields.js.map +1 -0
  22. package/lib/functions.d.ts +5 -0
  23. package/lib/functions.d.ts.map +1 -0
  24. package/lib/functions.js +408 -0
  25. package/lib/functions.js.map +1 -0
  26. package/lib/hierarchy.d.ts +6 -0
  27. package/lib/hierarchy.d.ts.map +1 -0
  28. package/lib/hierarchy.js +266 -0
  29. package/lib/hierarchy.js.map +1 -0
  30. package/lib/index.d.ts +91 -8
  31. package/lib/index.d.ts.map +1 -1
  32. package/lib/index.js +34 -2301
  33. package/lib/index.js.map +1 -1
  34. package/lib/literals.d.ts +20 -0
  35. package/lib/literals.d.ts.map +1 -0
  36. package/lib/literals.js +290 -0
  37. package/lib/literals.js.map +1 -0
  38. package/lib/mapping.d.ts +95 -0
  39. package/lib/mapping.d.ts.map +1 -0
  40. package/lib/mapping.js +316 -0
  41. package/lib/mapping.js.map +1 -0
  42. package/lib/narrowing.d.ts +12 -0
  43. package/lib/narrowing.d.ts.map +1 -0
  44. package/lib/narrowing.js +32 -0
  45. package/lib/narrowing.js.map +1 -0
  46. package/lib/plan.d.ts +49 -0
  47. package/lib/plan.d.ts.map +1 -0
  48. package/lib/plan.js +86 -0
  49. package/lib/plan.js.map +1 -0
  50. package/lib/presence.d.ts +25 -0
  51. package/lib/presence.d.ts.map +1 -0
  52. package/lib/presence.js +82 -0
  53. package/lib/presence.js.map +1 -0
  54. package/lib/regex.d.ts +33 -0
  55. package/lib/regex.d.ts.map +1 -0
  56. package/lib/regex.js +480 -0
  57. package/lib/regex.js.map +1 -0
  58. package/lib/relations.d.ts +58 -0
  59. package/lib/relations.d.ts.map +1 -0
  60. package/lib/relations.js +175 -0
  61. package/lib/relations.js.map +1 -0
  62. package/lib/rewrite.d.ts +36 -0
  63. package/lib/rewrite.d.ts.map +1 -0
  64. package/lib/rewrite.js +366 -0
  65. package/lib/rewrite.js.map +1 -0
  66. package/lib/solve.d.ts +20 -0
  67. package/lib/solve.d.ts.map +1 -0
  68. package/lib/solve.js +77 -0
  69. package/lib/solve.js.map +1 -0
  70. package/lib/strings.d.ts +12 -0
  71. package/lib/strings.d.ts.map +1 -0
  72. package/lib/strings.js +110 -0
  73. package/lib/strings.js.map +1 -0
  74. package/lib/ternary.d.ts +12 -0
  75. package/lib/ternary.d.ts.map +1 -0
  76. package/lib/ternary.js +192 -0
  77. package/lib/ternary.js.map +1 -0
  78. package/lib/timestamp.d.ts +45 -0
  79. package/lib/timestamp.d.ts.map +1 -0
  80. package/lib/timestamp.js +225 -0
  81. package/lib/timestamp.js.map +1 -0
  82. package/lib/translate.d.ts +20 -0
  83. package/lib/translate.d.ts.map +1 -0
  84. package/lib/translate.js +287 -0
  85. package/lib/translate.js.map +1 -0
  86. package/lib/types.d.ts +29 -0
  87. package/lib/types.d.ts.map +1 -0
  88. package/lib/types.js +980 -0
  89. package/lib/types.js.map +1 -0
  90. package/lib/value.d.ts +8 -0
  91. package/lib/value.d.ts.map +1 -0
  92. package/lib/value.js +7 -0
  93. package/lib/value.js.map +1 -0
  94. package/package.json +31 -18
  95. package/src/adversarial.test.ts +488 -488
  96. package/src/collections.ts +738 -0
  97. package/src/comparison.ts +1157 -0
  98. package/src/corpus.ts +597 -0
  99. package/src/errors.ts +12 -0
  100. package/src/evaluate.ts +170 -0
  101. package/src/fields.ts +373 -0
  102. package/src/functions.ts +548 -0
  103. package/src/generated/prisma-adversarial/browser.ts +20 -0
  104. package/src/generated/prisma-adversarial/client.ts +20 -0
  105. package/src/generated/prisma-adversarial/commonInputTypes.ts +116 -127
  106. package/src/generated/prisma-adversarial/internal/class.ts +44 -4
  107. package/src/generated/prisma-adversarial/internal/prismaNamespace.ts +350 -3
  108. package/src/generated/prisma-adversarial/internal/prismaNamespaceBrowser.ts +49 -2
  109. package/src/generated/prisma-adversarial/models/AdversarialBoolListElement.ts +1272 -0
  110. package/src/generated/prisma-adversarial/models/AdversarialInner.ts +1369 -0
  111. package/src/generated/prisma-adversarial/models/AdversarialNumberListElement.ts +1316 -0
  112. package/src/generated/prisma-adversarial/models/AdversarialParent.ts +1474 -0
  113. package/src/generated/prisma-adversarial/models/AdversarialResource.ts +547 -75
  114. package/src/generated/prisma-adversarial/models.ts +4 -0
  115. package/src/generated/prisma-adversarial-mysql/browser.ts +64 -0
  116. package/src/generated/{prisma → prisma-adversarial-mysql}/client.ts +23 -18
  117. package/src/generated/{prisma → prisma-adversarial-mysql}/commonInputTypes.ts +167 -92
  118. package/src/generated/prisma-adversarial-mysql/internal/class.ts +284 -0
  119. package/src/generated/prisma-adversarial-mysql/internal/prismaNamespace.ts +1518 -0
  120. package/src/generated/prisma-adversarial-mysql/internal/prismaNamespaceBrowser.ts +274 -0
  121. package/src/generated/prisma-adversarial-mysql/models/AdversarialBoolListElement.ts +1157 -0
  122. package/src/generated/prisma-adversarial-mysql/models/AdversarialCategory.ts +1286 -0
  123. package/src/generated/prisma-adversarial-mysql/models/AdversarialInner.ts +1247 -0
  124. package/src/generated/prisma-adversarial-mysql/models/AdversarialLabel.ts +1157 -0
  125. package/src/generated/prisma-adversarial-mysql/models/AdversarialNumberListElement.ts +1201 -0
  126. package/src/generated/prisma-adversarial-mysql/models/AdversarialParent.ts +1352 -0
  127. package/src/generated/prisma-adversarial-mysql/models/AdversarialResource.ts +2021 -0
  128. package/src/generated/prisma-adversarial-mysql/models/AdversarialSubCategory.ts +1286 -0
  129. package/src/generated/prisma-adversarial-mysql/models/AdversarialTag.ts +1190 -0
  130. package/src/generated/prisma-adversarial-mysql/models.ts +20 -0
  131. package/src/generated/prisma-adversarial-mysql-v6/index.d.ts +13822 -0
  132. package/src/generated/prisma-adversarial-pg/browser.ts +64 -0
  133. package/src/generated/prisma-adversarial-pg/client.ts +86 -0
  134. package/src/generated/prisma-adversarial-pg/commonInputTypes.ts +345 -0
  135. package/src/generated/prisma-adversarial-pg/enums.ts +15 -0
  136. package/src/generated/prisma-adversarial-pg/internal/class.ts +284 -0
  137. package/src/generated/prisma-adversarial-pg/internal/prismaNamespace.ts +1542 -0
  138. package/src/generated/{prisma → prisma-adversarial-pg}/internal/prismaNamespaceBrowser.ts +72 -43
  139. package/src/generated/prisma-adversarial-pg/models/AdversarialBoolListElement.ts +1275 -0
  140. package/src/generated/prisma-adversarial-pg/models/AdversarialCategory.ts +1404 -0
  141. package/src/generated/prisma-adversarial-pg/models/AdversarialInner.ts +1371 -0
  142. package/src/generated/prisma-adversarial-pg/models/AdversarialLabel.ts +1275 -0
  143. package/src/generated/prisma-adversarial-pg/models/AdversarialNumberListElement.ts +1319 -0
  144. package/src/generated/prisma-adversarial-pg/models/AdversarialParent.ts +1476 -0
  145. package/src/generated/prisma-adversarial-pg/models/AdversarialResource.ts +2139 -0
  146. package/src/generated/prisma-adversarial-pg/models/AdversarialSubCategory.ts +1404 -0
  147. package/src/generated/prisma-adversarial-pg/models/AdversarialTag.ts +1310 -0
  148. package/src/generated/prisma-adversarial-pg/models.ts +20 -0
  149. package/src/generated/prisma-adversarial-pg-v6/client.d.ts +1 -0
  150. package/src/generated/prisma-adversarial-pg-v6/default.d.ts +1 -0
  151. package/src/generated/prisma-adversarial-pg-v6/edge.d.ts +1 -0
  152. package/src/generated/prisma-adversarial-pg-v6/index.d.ts +14918 -0
  153. package/src/generated/prisma-adversarial-pg-v6/runtime/index-browser.d.ts +370 -0
  154. package/src/generated/prisma-adversarial-pg-v6/runtime/library.d.ts +3982 -0
  155. package/src/generated/prisma-adversarial-pg-v6/wasm.d.ts +1 -0
  156. package/src/generated/prisma-adversarial-v6/index.d.ts +6515 -304
  157. package/src/hierarchy.ts +405 -0
  158. package/src/index.ts +134 -3325
  159. package/src/literals.ts +363 -0
  160. package/src/mapping.ts +474 -0
  161. package/src/narrowing.ts +33 -0
  162. package/src/plan.ts +125 -0
  163. package/src/presence.ts +114 -0
  164. package/src/regex.ts +596 -0
  165. package/src/relations.ts +226 -0
  166. package/src/rewrite.ts +524 -0
  167. package/src/solve.ts +96 -0
  168. package/src/strings.ts +152 -0
  169. package/src/ternary.ts +359 -0
  170. package/src/test-setup.adversarial-url.ts +21 -0
  171. package/src/test-setup.adversarial.mysql.v6.ts +13 -0
  172. package/src/test-setup.adversarial.mysql.v7.ts +12 -0
  173. package/src/test-setup.adversarial.pg.v6.ts +13 -0
  174. package/src/test-setup.adversarial.pg.v7.ts +9 -0
  175. package/src/test-setup.adversarial.v7.ts +1 -0
  176. package/src/timestamp.ts +308 -0
  177. package/src/translate.ts +419 -0
  178. package/src/translator.test.ts +766 -0
  179. package/src/types.ts +1310 -0
  180. package/src/value.ts +16 -0
  181. package/src/generated/prisma/browser.ts +0 -59
  182. package/src/generated/prisma/internal/class.ts +0 -274
  183. package/src/generated/prisma/internal/prismaNamespace.ts +0 -1403
  184. package/src/generated/prisma/models/Category.ts +0 -1412
  185. package/src/generated/prisma/models/Label.ts +0 -1276
  186. package/src/generated/prisma/models/NestedResource.ts +0 -1562
  187. package/src/generated/prisma/models/NextLevelNestedResource.ts +0 -1337
  188. package/src/generated/prisma/models/Resource.ts +0 -2196
  189. package/src/generated/prisma/models/SubCategory.ts +0 -1412
  190. package/src/generated/prisma/models/Tag.ts +0 -1276
  191. package/src/generated/prisma/models/User.ts +0 -1503
  192. package/src/generated/prisma/models.ts +0 -19
  193. package/src/generated/prisma-v6/index.d.ts +0 -13726
  194. package/src/index.test.ts +0 -8885
  195. package/src/test-setup.v6.ts +0 -5
  196. package/src/test-setup.v7.ts +0 -7
  197. /package/src/generated/{prisma → prisma-adversarial-mysql}/enums.ts +0 -0
  198. /package/src/generated/{prisma-v6 → prisma-adversarial-mysql-v6}/client.d.ts +0 -0
  199. /package/src/generated/{prisma-v6 → prisma-adversarial-mysql-v6}/default.d.ts +0 -0
  200. /package/src/generated/{prisma-v6 → prisma-adversarial-mysql-v6}/edge.d.ts +0 -0
  201. /package/src/generated/{prisma-v6 → prisma-adversarial-mysql-v6}/runtime/index-browser.d.ts +0 -0
  202. /package/src/generated/{prisma-v6 → prisma-adversarial-mysql-v6}/runtime/library.d.ts +0 -0
  203. /package/src/generated/{prisma-v6 → prisma-adversarial-mysql-v6}/wasm.d.ts +0 -0
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ // RFC 3339 timestamp literals, validated to CEL's instant range and Prisma's millisecond precision.
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.normalizeRfc3339Milliseconds = normalizeRfc3339Milliseconds;
5
+ exports.parseRfc3339Instant = parseRfc3339Instant;
6
+ exports.roundSubMillisecond = roundSubMillisecond;
7
+ exports.rewriteTemporalComparison = rewriteTemporalComparison;
8
+ const plan_1 = require("./plan");
9
+ const errors_1 = require("./errors");
10
+ const narrowing_1 = require("./narrowing");
11
+ const RFC3339_MILLISECOND_TIMESTAMP = /^((?!0000)\d{4})-(\d{2})-(\d{2})[Tt](?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.(\d{1,9}))?(?:[Zz]|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/;
12
+ const MIN_RFC3339_TIMESTAMP_MILLISECONDS = Date.parse("0001-01-01T00:00:00.000Z");
13
+ const MAX_RFC3339_TIMESTAMP_MILLISECONDS = Date.parse("9999-12-31T23:59:59.999Z");
14
+ /**
15
+ * Parses an RFC 3339 literal into the ISO string Prisma binds. Anything a lenient `Date` parse
16
+ * would coerce into some other instant — a missing time part, a day that does not exist, digits
17
+ * past the millisecond, an instant outside CEL's range — is refused instead.
18
+ */
19
+ function normalizeRfc3339Milliseconds(value) {
20
+ const { iso, subMillisecond } = parseRfc3339Instant(value);
21
+ if (subMillisecond) {
22
+ throw new errors_1.UnsupportedQueryPlanError(`Timestamp value exceeds millisecond precision: ${value}`);
23
+ }
24
+ return iso;
25
+ }
26
+ /**
27
+ * Parses an RFC 3339 literal like normalizeRfc3339Milliseconds, except that an instant between
28
+ * two milliseconds is accepted: `iso` is then the NEXT millisecond, and `subMillisecond` says so.
29
+ * A comparison against it has to be rewritten for that rounding (see roundSubMillisecond).
30
+ */
31
+ function parseRfc3339Instant(value) {
32
+ const match = RFC3339_MILLISECOND_TIMESTAMP.exec(value);
33
+ const yearText = match?.[1];
34
+ const monthText = match?.[2];
35
+ const dayText = match?.[3];
36
+ const fraction = match?.[4] ?? "";
37
+ if (!yearText || !monthText || !dayText) {
38
+ throw new errors_1.UnsupportedQueryPlanError(`Invalid RFC 3339 timestamp value: ${value}`);
39
+ }
40
+ const subMillisecond = [...fraction.slice(3)].some((digit) => digit !== "0");
41
+ const year = Number(yearText);
42
+ const month = Number(monthText);
43
+ const day = Number(dayText);
44
+ const calendarDate = new Date(0);
45
+ calendarDate.setUTCHours(0, 0, 0, 0);
46
+ calendarDate.setUTCFullYear(year, month - 1, day);
47
+ if (calendarDate.getUTCFullYear() !== year ||
48
+ calendarDate.getUTCMonth() !== month - 1 ||
49
+ calendarDate.getUTCDate() !== day) {
50
+ throw new errors_1.UnsupportedQueryPlanError(`Invalid RFC 3339 timestamp value: ${value}`);
51
+ }
52
+ const milliseconds = Date.parse(value);
53
+ if (Number.isNaN(milliseconds)) {
54
+ throw new errors_1.UnsupportedQueryPlanError(`Invalid RFC 3339 timestamp value: ${value}`);
55
+ }
56
+ if (milliseconds < MIN_RFC3339_TIMESTAMP_MILLISECONDS ||
57
+ milliseconds > MAX_RFC3339_TIMESTAMP_MILLISECONDS) {
58
+ throw new errors_1.UnsupportedQueryPlanError(`Timestamp value is outside CEL's supported instant range: ${value}`);
59
+ }
60
+ // Date.parse drops the digits past the millisecond, so a sub-millisecond instant lies strictly
61
+ // between `milliseconds` and the next one.
62
+ const rounded = subMillisecond ? milliseconds + 1 : milliseconds;
63
+ if (rounded > MAX_RFC3339_TIMESTAMP_MILLISECONDS) {
64
+ throw new errors_1.UnsupportedQueryPlanError(`Timestamp value is outside CEL's supported instant range: ${value}`);
65
+ }
66
+ return { iso: new Date(rounded).toISOString(), subMillisecond };
67
+ }
68
+ /**
69
+ * A Prisma `DateTime` carries milliseconds, so the attribute an application builds from one is a
70
+ * whole millisecond `a`, truncated from whatever the column stores. Against an instant `T` strictly
71
+ * between two milliseconds, with `C` the millisecond after it: `a < T` and `a <= T` both mean
72
+ * `column < C`, `a > T` and `a >= T` both mean `column >= C`, and `a == T` never holds. Returns the
73
+ * operator to compare against `C`, or null for the equality family.
74
+ */
75
+ function roundSubMillisecond(operator) {
76
+ switch (operator) {
77
+ case "lt":
78
+ case "le":
79
+ return "lt";
80
+ case "gt":
81
+ case "ge":
82
+ return "ge";
83
+ default:
84
+ return null;
85
+ }
86
+ }
87
+ // -- timestamp arithmetic, solved for the column -------------------------------------------------
88
+ const MIN_INSTANT = MIN_RFC3339_TIMESTAMP_MILLISECONDS;
89
+ const MAX_INSTANT = MAX_RFC3339_TIMESTAMP_MILLISECONDS;
90
+ /**
91
+ * A comparison over timestamp arithmetic, rewritten as a comparison of the bare `timestamp(x)`
92
+ * against a literal instant, or undefined for any other shape:
93
+ *
94
+ * - `timeSince(timestamp(x)) CMP duration(d)`: timeSince is `now - x`, read from the clock when
95
+ * the query runs, so it holds exactly when `x` lies on the mirrored side of `now - d`. Cerbos
96
+ * computes it with Go's saturating `time.Sub`, which raises no error.
97
+ * - `timestamp(x) ± duration(d) CMP timestamp(t)`: the shift is monotone, so it holds exactly when
98
+ * `x CMP t ∓ d`. CEL raises an error when the shifted instant leaves 0001-01-01..9999-12-31,
99
+ * which the comparison alone cannot carry: `positive` says whether the leaf sits under an even
100
+ * number of negations, and the rows that overflow are then excluded from (positive) or included
101
+ * in (negative) the leaf, so the enclosing negations never select them.
102
+ *
103
+ * Both sides may come in either order. A duration or instant that is not a whole millisecond, or a
104
+ * bound outside CEL's range, is left alone for the translator to refuse.
105
+ */
106
+ function rewriteTemporalComparison(expr, positive, now = Date.now()) {
107
+ if (!plan_1.COMPARISON_OPERATORS.has(expr.operator) || expr.operands.length !== 2)
108
+ return undefined;
109
+ let [left, right] = (0, narrowing_1.pair)(expr.operands);
110
+ let operator = expr.operator;
111
+ if (!isTemporalArithmetic(left) && isTemporalArithmetic(right)) {
112
+ [left, right] = [right, left];
113
+ operator = (0, plan_1.mirrorOperator)(operator);
114
+ }
115
+ if (!(0, plan_1.isOperatorOperand)(left))
116
+ return undefined;
117
+ if (left.operator === "timeSince") {
118
+ const [column] = left.operands;
119
+ const duration = durationMilliseconds(right);
120
+ if (left.operands.length !== 1 || !isTimestampColumn(column) || duration === undefined) {
121
+ return undefined;
122
+ }
123
+ const bound = instantLiteral(now - duration);
124
+ // now - x CMP d <=> x mirror(CMP) now - d
125
+ return bound && compareInstant((0, plan_1.mirrorOperator)(operator), column, bound);
126
+ }
127
+ if ((left.operator !== "add" && left.operator !== "sub") || left.operands.length !== 2) {
128
+ return undefined;
129
+ }
130
+ const [a, b] = (0, narrowing_1.pair)(left.operands);
131
+ let column;
132
+ let duration;
133
+ if (isTimestampColumn(a) && durationMilliseconds(b) !== undefined) {
134
+ [column, duration] = [a, durationMilliseconds(b)];
135
+ }
136
+ else if (left.operator === "add" && isTimestampColumn(b)) {
137
+ [column, duration] = [b, durationMilliseconds(a)];
138
+ }
139
+ else {
140
+ return undefined;
141
+ }
142
+ const instant = instantMilliseconds(right);
143
+ if (duration === undefined || instant === undefined)
144
+ return undefined;
145
+ const shift = left.operator === "add" ? duration : -duration;
146
+ const bound = instantLiteral(instant - shift);
147
+ if (bound === undefined)
148
+ return undefined;
149
+ const solved = compareInstant(operator, column, bound);
150
+ if (shift === 0)
151
+ return solved;
152
+ const limit = instantLiteral(shift > 0 ? MAX_INSTANT - shift : MIN_INSTANT - shift);
153
+ if (limit === undefined)
154
+ return undefined;
155
+ const inRange = compareInstant(shift > 0 ? "le" : "ge", column, limit);
156
+ return positive
157
+ ? { operator: "and", operands: [solved, inRange] }
158
+ : { operator: "or", operands: [solved, { operator: "not", operands: [inRange] }] };
159
+ }
160
+ function isTemporalArithmetic(operand) {
161
+ return ((0, plan_1.isOperatorOperand)(operand) &&
162
+ (operand.operator === "timeSince" ||
163
+ ((operand.operator === "add" || operand.operator === "sub") &&
164
+ operand.operands.some(isTimestampColumn))));
165
+ }
166
+ /** `timestamp(column)`. */
167
+ function isTimestampColumn(operand) {
168
+ return (operand !== undefined &&
169
+ (0, plan_1.isOperatorOperand)(operand) &&
170
+ operand.operator === "timestamp" &&
171
+ operand.operands.length === 1 &&
172
+ (0, plan_1.isNamedOperand)(operand.operands[0]));
173
+ }
174
+ const PROTOBUF_DURATION = /^(-)?(\d+)(?:\.(\d{1,9}))?s$/;
175
+ /** A `duration("...")` literal in the planner's protobuf spelling, in whole milliseconds. */
176
+ function durationMilliseconds(operand) {
177
+ if (!(0, plan_1.isOperatorOperand)(operand) ||
178
+ operand.operator !== "duration" ||
179
+ operand.operands.length !== 1) {
180
+ return undefined;
181
+ }
182
+ const [literal] = operand.operands;
183
+ if (!(0, plan_1.isValueOperand)(literal) || !(0, narrowing_1.isString)(literal.value))
184
+ return undefined;
185
+ const match = PROTOBUF_DURATION.exec(literal.value);
186
+ if (!match)
187
+ return undefined;
188
+ const fraction = (match[3] ?? "").padEnd(9, "0");
189
+ if (fraction.slice(3) !== "000000")
190
+ return undefined;
191
+ const milliseconds = Number(match[2]) * 1000 + Number(fraction.slice(0, 3));
192
+ if (!Number.isSafeInteger(milliseconds))
193
+ return undefined;
194
+ return match[1] ? -milliseconds : milliseconds;
195
+ }
196
+ /** A `timestamp("...")` literal at a whole millisecond. */
197
+ function instantMilliseconds(operand) {
198
+ if (!(0, plan_1.isOperatorOperand)(operand) ||
199
+ operand.operator !== "timestamp" ||
200
+ operand.operands.length !== 1) {
201
+ return undefined;
202
+ }
203
+ const [literal] = operand.operands;
204
+ if (!(0, plan_1.isValueOperand)(literal) || !(0, narrowing_1.isString)(literal.value))
205
+ return undefined;
206
+ try {
207
+ const { iso, subMillisecond } = parseRfc3339Instant(literal.value);
208
+ return subMillisecond ? undefined : Date.parse(iso);
209
+ }
210
+ catch {
211
+ return undefined;
212
+ }
213
+ }
214
+ function instantLiteral(milliseconds) {
215
+ if (!Number.isFinite(milliseconds) ||
216
+ milliseconds < MIN_INSTANT ||
217
+ milliseconds > MAX_INSTANT) {
218
+ return undefined;
219
+ }
220
+ return { operator: "timestamp", operands: [{ value: new Date(milliseconds).toISOString() }] };
221
+ }
222
+ function compareInstant(operator, column, instant) {
223
+ return { operator, operands: [column, instant] };
224
+ }
225
+ //# sourceMappingURL=timestamp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timestamp.js","sourceRoot":"","sources":["../src/timestamp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { PlanExpressionOperand, Value } from "@cerbos/core";
2
+ import type { PrismaFilter } from "./index";
3
+ import type { ResolvedOperand, TranslationContext } from "./mapping";
4
+ import type { OperatorOperand } from "./plan";
5
+ /**
6
+ * Builds a Prisma filter from a Cerbos expression.
7
+ */
8
+ export declare function buildPrismaFilterFromCerbosExpression(expression: PlanExpressionOperand, context: TranslationContext): PrismaFilter;
9
+ export declare function buildNegatedFilter(operand: PlanExpressionOperand, context: TranslationContext): PrismaFilter;
10
+ /**
11
+ * Resolves a plan operand into a column reference or a constant. A nested expression that is
12
+ * neither a timestamp nor foldable arithmetic resolves to the filter it translates to.
13
+ *
14
+ * A timestamp literal between two milliseconds is refused unless `allowSubMillisecond` is set, by
15
+ * a caller that compares it against a column and applies roundSubMillisecond.
16
+ */
17
+ export declare function resolveOperand(operand: PlanExpressionOperand, context: TranslationContext, allowSubMillisecond?: boolean): ResolvedOperand;
18
+ /** The value of arithmetic over two constant operands, or null when it cannot be folded. */
19
+ export declare function tryFoldValueExpression(expr: OperatorOperand, context: TranslationContext): Value | null;
20
+ //# sourceMappingURL=translate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../src/translate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,qBAAqB,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAqBjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAQrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AAW9C;;GAEG;AACH,wBAAgB,qCAAqC,CACnD,UAAU,EAAE,qBAAqB,EACjC,OAAO,EAAE,kBAAkB,GAC1B,YAAY,CAkFd;AAqCD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,kBAAkB,GAC1B,YAAY,CAiHd;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,kBAAkB,EAC3B,mBAAmB,UAAQ,GAC1B,eAAe,CAyBjB;AAuED,4FAA4F;AAC5F,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,kBAAkB,GAC1B,KAAK,GAAG,IAAI,CAmBd"}
@@ -0,0 +1,287 @@
1
+ "use strict";
2
+ // The translator's core: one dispatch from a plan operator to its handler, the negation that
3
+ // every handler shares, and the resolution of an operand into a column or a constant.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.buildPrismaFilterFromCerbosExpression = buildPrismaFilterFromCerbosExpression;
6
+ exports.buildNegatedFilter = buildNegatedFilter;
7
+ exports.resolveOperand = resolveOperand;
8
+ exports.tryFoldValueExpression = tryFoldValueExpression;
9
+ const collections_1 = require("./collections");
10
+ const comparison_1 = require("./comparison");
11
+ const evaluate_1 = require("./evaluate");
12
+ const fields_1 = require("./fields");
13
+ const hierarchy_1 = require("./hierarchy");
14
+ const mapping_1 = require("./mapping");
15
+ const plan_1 = require("./plan");
16
+ const presence_1 = require("./presence");
17
+ const relations_1 = require("./relations");
18
+ const rewrite_1 = require("./rewrite");
19
+ const regex_1 = require("./regex");
20
+ const strings_1 = require("./strings");
21
+ const ternary_1 = require("./ternary");
22
+ const timestamp_1 = require("./timestamp");
23
+ const errors_1 = require("./errors");
24
+ const narrowing_1 = require("./narrowing");
25
+ /**
26
+ * Builds a Prisma filter from a Cerbos expression.
27
+ */
28
+ function buildPrismaFilterFromCerbosExpression(expression, context) {
29
+ // A bare named operand represents a boolean field reference (e.g. `R.attr.booleanAttr`)
30
+ if ((0, plan_1.isNamedOperand)(expression)) {
31
+ return (0, fields_1.buildFieldFilter)(booleanFieldReference(expression.name, context), "equals", true);
32
+ }
33
+ if (!(0, plan_1.isOperatorOperand)(expression)) {
34
+ throw new errors_1.UnsupportedQueryPlanError("Invalid Cerbos expression structure");
35
+ }
36
+ // Every plan operator this adapter translates. Adding an operator is adding a case here;
37
+ // anything else is refused as unsupported.
38
+ const { operator, operands } = expression;
39
+ (0, plan_1.assertLogicalOperands)(operator, operands);
40
+ switch (operator) {
41
+ case "and":
42
+ return {
43
+ AND: operands.map((operand) => buildPrismaFilterFromCerbosExpression(operand, context)),
44
+ };
45
+ case "or":
46
+ return {
47
+ OR: operands.map((operand) => buildPrismaFilterFromCerbosExpression(operand, context)),
48
+ };
49
+ case "not": {
50
+ const operand = operands[0];
51
+ if (!operand) {
52
+ throw new errors_1.UnsupportedQueryPlanError("not operator requires an operand");
53
+ }
54
+ return buildNegatedFilter(operand, context);
55
+ }
56
+ case "if":
57
+ return (0, ternary_1.handleBooleanTernaryOperator)(operands, context);
58
+ case "eq":
59
+ case "ne":
60
+ case "lt":
61
+ case "le":
62
+ case "gt":
63
+ case "ge":
64
+ return (0, comparison_1.handleRelationalOperator)(operator, operands, context);
65
+ case "in":
66
+ return (0, comparison_1.handleInOperator)(operands, context);
67
+ case "contains":
68
+ case "startsWith":
69
+ case "endsWith":
70
+ return (0, strings_1.handleStringOperator)(operator, operands, context);
71
+ case "matches":
72
+ return (0, regex_1.handleMatchesOperator)(operands, context);
73
+ case "has":
74
+ return (0, presence_1.handleHasOperator)(operands, context, false);
75
+ case "hasIntersection":
76
+ return (0, collections_1.handleHasIntersectionOperator)(operands, context);
77
+ case "lambda":
78
+ return (0, collections_1.handleLambdaOperator)(operands, context);
79
+ case "exists":
80
+ case "exists_one":
81
+ case "all":
82
+ case "except":
83
+ case "filter":
84
+ return (0, collections_1.handleCollectionOperator)(operator, operands, context);
85
+ case "map":
86
+ return (0, collections_1.handleMapOperator)(operands, context);
87
+ case "overlaps":
88
+ return (0, hierarchy_1.handleOverlapsOperator)(operands, context);
89
+ case "ancestorOf":
90
+ return (0, hierarchy_1.handleAncestorDescendantOperator)(operands, context, "ancestor");
91
+ case "descendentOf":
92
+ return (0, hierarchy_1.handleAncestorDescendantOperator)(operands, context, "descendant");
93
+ default:
94
+ throw new errors_1.UnsupportedQueryPlanError(`Unsupported operator: ${operator}`);
95
+ }
96
+ }
97
+ /**
98
+ * Builds the filter for `!expr`. Plain field predicates negate correctly with Prisma's NOT
99
+ * (SQL three-valued logic keeps NULL rows excluded under both polarities), but relation
100
+ * subqueries collapse UNKNOWN to false at the EXISTS boundary, so `NOT(some(P))` would
101
+ * wrongly include rows whose elements make P UNKNOWN (a NULL element column is a missing
102
+ * attribute — a CEL error — on the check side, which Cerbos treats as deny). Negation is
103
+ * therefore pushed down to the collection operators, which encode CEL's exact error
104
+ * semantics:
105
+ *
106
+ * - exists(c,P) is TRUE with a true witness, FALSE if every element is definitively false,
107
+ * and an ERROR otherwise — so `!exists` admits only rows with no P-match AND no
108
+ * UNKNOWN-element (the nullable-field guard).
109
+ * - all(c,P) is FALSE only with a definitive false witness (a false witness absorbs error
110
+ * elements) — so `!all` is `some(NOT P)`, which SQL already evaluates definitively.
111
+ */
112
+ /**
113
+ * A field read where CEL needs a boolean. A field declared another type is a no-overload error,
114
+ * which no Prisma filter keeps out under both polarities, so it is refused.
115
+ */
116
+ function booleanFieldReference(name, context) {
117
+ if ((0, mapping_1.lookupMapping)(context.mapper, name)?.relation?.type === "many") {
118
+ throw new errors_1.UnsupportedQueryPlanError("A list in boolean position is a CEL type error");
119
+ }
120
+ const fieldRef = (0, mapping_1.resolveFieldReference)(name, context);
121
+ if (fieldRef.valueType !== undefined && fieldRef.valueType !== "boolean") {
122
+ throw new errors_1.UnsupportedQueryPlanError(`A ${fieldRef.valueType} field in boolean position is a CEL type error`);
123
+ }
124
+ return fieldRef;
125
+ }
126
+ function buildNegatedFilter(operand, context) {
127
+ if ((0, plan_1.isOperatorOperand)(operand)) {
128
+ if (operand.operator === "not") {
129
+ return buildPrismaFilterFromCerbosExpression((0, plan_1.assertDefined)(operand.operands[0], "not requires an operand"), context);
130
+ }
131
+ if (operand.operator === "has") {
132
+ return (0, presence_1.handleHasOperator)(operand.operands, context, true);
133
+ }
134
+ const ternary = (0, ternary_1.tryHandleTernaryComparison)(operand.operator, operand.operands, context, true);
135
+ if (ternary !== null)
136
+ return ternary;
137
+ const lookup = (0, comparison_1.tryHandleMapLiteralLookup)(operand.operator, operand.operands, context, true);
138
+ if (lookup !== null)
139
+ return lookup;
140
+ }
141
+ if ((0, plan_1.isNamedOperand)(operand)) {
142
+ const { relations, ...fieldRef } = booleanFieldReference(operand.name, context);
143
+ if (!relations || relations.length === 0) {
144
+ return (0, fields_1.buildFieldFilter)(fieldRef, "equals", false);
145
+ }
146
+ return (0, relations_1.negateRequiringHops)(operand, buildPrismaFilterFromCerbosExpression(operand, context), context);
147
+ }
148
+ // `and`/`or` must be pushed through with De Morgan whenever a branch can be UNKNOWN, so
149
+ // CEL's error absorption survives: `!(A && B)` with A erroring and B false is TRUE in CEL,
150
+ // and `OR[!A, !B]` reproduces that where a single outer NOT over the conjunction — with the
151
+ // hop requirement ANDed outside it — would deny. A to-one hop is the second source of UNKNOWN
152
+ // besides the collection macros, so it opens the same push-down, and each leaf requires only
153
+ // the hops it reads itself. (A nested `not` was already unwrapped above.) A lookup into a map literal
154
+ // is the third: a missing key is an error, which the comparison's own negation leaves out.
155
+ if ((0, plan_1.isOperatorOperand)(operand) &&
156
+ ((0, rewrite_1.containsCollectionOperator)(operand) ||
157
+ (0, comparison_1.containsMapLiteralLookup)(operand) ||
158
+ (0, relations_1.referencesRequiredHop)(operand, context))) {
159
+ switch (operand.operator) {
160
+ case "and":
161
+ return {
162
+ OR: operand.operands.map((o) => buildNegatedFilter(o, context)),
163
+ };
164
+ case "or":
165
+ return {
166
+ AND: operand.operands.map((o) => buildNegatedFilter(o, context)),
167
+ };
168
+ // `!(c ? a : b)` is `c ? !a : !b`, errors included: a condition that errors errors either
169
+ // way. A NOT over the guarded-branch disjunction instead selects the rows where the
170
+ // condition is UNKNOWN, which neither guarded branch matched.
171
+ case "if":
172
+ if (operand.operands.length === 3) {
173
+ const [condition, thenBranch, elseBranch] = (0, narrowing_1.triple)(operand.operands);
174
+ return (0, ternary_1.handleBooleanTernaryOperator)([
175
+ condition,
176
+ { operator: "not", operands: [thenBranch] },
177
+ { operator: "not", operands: [elseBranch] },
178
+ ], context);
179
+ }
180
+ break;
181
+ case "exists":
182
+ case "all":
183
+ case "except":
184
+ case "exists_one":
185
+ case "filter":
186
+ return (0, collections_1.buildNegatedCollectionFilter)(operand.operator, operand.operands, context);
187
+ }
188
+ if ((0, comparison_1.containsMapLiteralLookup)(operand)) {
189
+ // A missing key is an error under both polarities, which a NOT over the positive filter
190
+ // would turn into a match; only and/or and the comparison itself push the negation down.
191
+ throw new errors_1.UnsupportedQueryPlanError(`Cannot negate ${operand.operator} over an index into a map literal: a missing key is an ` +
192
+ "error under both polarities, and a NOT over its filter would select it");
193
+ }
194
+ }
195
+ return (0, relations_1.negateRequiringHops)(operand, buildPrismaFilterFromCerbosExpression(operand, context), context);
196
+ }
197
+ /**
198
+ * Resolves a plan operand into a column reference or a constant. A nested expression that is
199
+ * neither a timestamp nor foldable arithmetic resolves to the filter it translates to.
200
+ *
201
+ * A timestamp literal between two milliseconds is refused unless `allowSubMillisecond` is set, by
202
+ * a caller that compares it against a column and applies roundSubMillisecond.
203
+ */
204
+ function resolveOperand(operand, context, allowSubMillisecond = false) {
205
+ if ((0, plan_1.isNamedOperand)(operand)) {
206
+ return (0, mapping_1.resolveFieldReference)(operand.name, context);
207
+ }
208
+ if ((0, plan_1.isValueOperand)(operand)) {
209
+ return { value: operand.value };
210
+ }
211
+ if ((0, plan_1.isOperatorOperand)(operand)) {
212
+ if (operand.operator === "timestamp") {
213
+ return resolveTimestampOperand(operand, context, allowSubMillisecond);
214
+ }
215
+ const identity = resolveIdentityCast(operand, context);
216
+ if (identity !== undefined)
217
+ return identity;
218
+ const folded = tryFoldValueExpression(operand, context);
219
+ if (folded !== null)
220
+ return { value: folded };
221
+ return { value: buildPrismaFilterFromCerbosExpression(operand, context) };
222
+ }
223
+ throw new errors_1.UnsupportedQueryPlanError("Operand must have name, value, or be an expression");
224
+ }
225
+ /**
226
+ * `string(column)` over a string column and `double(column)` over a number column convert nothing:
227
+ * the column itself, except that the cast of a null VALUE is an error. The reference is resolved
228
+ * as one whose NULL is missing, so no comparison against it can select a NULL row.
229
+ */
230
+ function resolveIdentityCast(expression, context) {
231
+ const target = (0, narrowing_1.lookup)(IDENTITY_CASTS, expression.operator);
232
+ const [operand] = expression.operands;
233
+ if (target === undefined ||
234
+ expression.operands.length !== 1 ||
235
+ operand === undefined ||
236
+ !(0, plan_1.isNamedOperand)(operand)) {
237
+ return undefined;
238
+ }
239
+ const fieldRef = (0, mapping_1.resolveFieldReference)(operand.name, context);
240
+ if (fieldRef.valueType !== target)
241
+ return undefined;
242
+ return { ...fieldRef, nullAttributeRepresentation: "omitted" };
243
+ }
244
+ const IDENTITY_CASTS = { string: "string", double: "number" };
245
+ function resolveTimestampOperand(expression, context, allowSubMillisecond) {
246
+ if (expression.operands.length !== 1) {
247
+ throw new errors_1.UnsupportedQueryPlanError("timestamp() requires exactly one operand");
248
+ }
249
+ const operand = (0, plan_1.assertDefined)(expression.operands[0], "timestamp() requires an operand");
250
+ if ((0, plan_1.isNamedOperand)(operand)) {
251
+ const fieldRef = (0, mapping_1.resolveFieldReference)(operand.name, context);
252
+ if (fieldRef.valueType !== "dateTime") {
253
+ throw new errors_1.UnsupportedQueryPlanError(`timestamp() field ${operand.name} must be mapped with valueType: \"dateTime\"`);
254
+ }
255
+ return { ...fieldRef, timestampWrapped: true };
256
+ }
257
+ if (!(0, plan_1.isValueOperand)(operand) || !(0, narrowing_1.isString)(operand.value)) {
258
+ throw new errors_1.UnsupportedQueryPlanError("timestamp() requires a field reference or RFC 3339 string");
259
+ }
260
+ if (!allowSubMillisecond) {
261
+ return { value: (0, timestamp_1.normalizeRfc3339Milliseconds)(operand.value) };
262
+ }
263
+ const { iso, subMillisecond } = (0, timestamp_1.parseRfc3339Instant)(operand.value);
264
+ return subMillisecond ? { value: iso, subMillisecond } : { value: iso };
265
+ }
266
+ /** The value of arithmetic over two constant operands, or null when it cannot be folded. */
267
+ function tryFoldValueExpression(expr, context) {
268
+ if (!evaluate_1.ARITHMETIC_OPERATORS.has(expr.operator))
269
+ return null;
270
+ const leftOp = expr.operands[0];
271
+ const rightOp = expr.operands[1];
272
+ if (!leftOp || !rightOp)
273
+ return null;
274
+ const left = resolveOperand(leftOp, context);
275
+ if (!(0, mapping_1.isResolvedValue)(left))
276
+ return null;
277
+ const right = resolveOperand(rightOp, context);
278
+ if (!(0, mapping_1.isResolvedValue)(right))
279
+ return null;
280
+ try {
281
+ return (0, evaluate_1.foldArithmetic)(expr.operator, left.value, right.value);
282
+ }
283
+ catch {
284
+ return null;
285
+ }
286
+ }
287
+ //# sourceMappingURL=translate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translate.js","sourceRoot":"","sources":["../src/translate.ts"],"names":[],"mappings":"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"}
package/lib/types.d.ts ADDED
@@ -0,0 +1,29 @@
1
+ import type { PlanExpressionOperand } from "@cerbos/core";
2
+ import type { ResolvedFieldReference, TranslationContext } from "./mapping";
3
+ import type { NamedOperand } from "./plan";
4
+ /**
5
+ * Replaces every leaf whose outcome the mapped value types settle with the constant that decides
6
+ * the same rows, then leaves the rest of the plan to the translator.
7
+ *
8
+ * CEL's `&&`, `||` and `!` are Kleene's strong three-valued logic with an error in the role of
9
+ * UNKNOWN, and `exists`/`all` are its disjunction and conjunction over the elements. Kleene logic
10
+ * is regular — a formula that is TRUE with an UNKNOWN operand is TRUE whatever that operand is —
11
+ * so under an even number of negations a leaf that is only ever FALSE or an error decides every
12
+ * row exactly as a constant FALSE does, and under an odd number a leaf that is only ever TRUE or
13
+ * an error decides every row exactly as a constant TRUE does. A leaf that can be both TRUE and
14
+ * FALSE, or that sits where its polarity is not fixed (a ternary condition, an operand of `==`,
15
+ * the body of `exists_one`), is left for the translator to lower or refuse.
16
+ */
17
+ export declare function settleTypeMismatches(expr: PlanExpressionOperand, context: TranslationContext, positive?: boolean): PlanExpressionOperand;
18
+ /**
19
+ * CEL's string() of a double: cel-go's `fmt.Sprintf("%g", d)`, the shortest digits that
20
+ * round-trip, in exponent form below 1e-4 or from 1e+06.
21
+ */
22
+ export declare function formatCelDouble(x: number): string;
23
+ /**
24
+ * A predicate TRUE for a present value of the column and UNKNOWN for a NULL one, spelled with
25
+ * the plain comparisons the translator leaves to SQL's three-valued logic. Undefined for a column
26
+ * whose type is not declared.
27
+ */
28
+ export declare function presence(column: NamedOperand, fieldRef: ResolvedFieldReference): PlanExpressionOperand | undefined;
29
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,qBAAqB,EAAS,MAAM,cAAc,CAAC;AAKjE,OAAO,KAAK,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAM5E,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,QAAQ,CAAC;AAuC5D;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,qBAAqB,EAC3B,OAAO,EAAE,kBAAkB,EAC3B,QAAQ,UAAO,GACd,qBAAqB,CAsEvB;AAqkBD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CA8BjD;AAwPD;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,YAAY,EACpB,QAAQ,EAAE,sBAAsB,GAC/B,qBAAqB,GAAG,SAAS,CAgBnC"}