@voltro/protocol 0.85.0 → 0.87.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 (80) hide show
  1. package/CHANGELOG.md +5987 -0
  2. package/README.md +14 -0
  3. package/THIRD-PARTY-NOTICES.md +1122 -31
  4. package/dist/apiRoleEndpoints.js +108 -0
  5. package/dist/apiRoleObservation.js +68 -0
  6. package/dist/apikey.d.ts +10 -0
  7. package/dist/approval.js +64 -0
  8. package/dist/approvalDescriptors.js +26 -0
  9. package/dist/auth.js +389 -0
  10. package/dist/boundedRing.js +27 -0
  11. package/dist/businessRule.js +11 -0
  12. package/dist/canonicalJson.js +14 -0
  13. package/dist/connection.js +73 -0
  14. package/dist/devActivity.js +4 -0
  15. package/dist/errorSchema.js +24 -0
  16. package/dist/errorValue.js +21 -0
  17. package/dist/event.js +110 -0
  18. package/dist/formCapture.js +12 -0
  19. package/dist/httpStreamMaxDuration.js +9 -0
  20. package/dist/idempotency.js +121 -0
  21. package/dist/idempotencyInput.js +123 -0
  22. package/dist/identity.js +5 -9
  23. package/dist/index.d.ts +1095 -139
  24. package/dist/index.js +54 -1700
  25. package/dist/inspect.d.ts +1 -1
  26. package/dist/inspect.js +14 -240
  27. package/dist/inspectBackfill.js +52 -0
  28. package/dist/inspectCommandRejection.js +21 -0
  29. package/dist/inspectProjection.js +133 -0
  30. package/dist/inspectStorageProjection.js +86 -0
  31. package/dist/inspectValueIdentity.js +4 -0
  32. package/dist/inspectWorkflowExecution.js +34 -0
  33. package/dist/inspectWorkflowQueuedStart.js +31 -0
  34. package/dist/jsonSchema.js +54 -0
  35. package/dist/jwt.d.ts +10 -0
  36. package/dist/jwt.js +1 -1
  37. package/dist/outbox.js +10 -0
  38. package/dist/pairing.js +75 -0
  39. package/dist/plugin.js +87 -0
  40. package/dist/pluginAccountMerge.js +88 -0
  41. package/dist/pluginNaming.js +32 -0
  42. package/dist/pluginPrivacy.js +166 -0
  43. package/dist/procedure.js +280 -0
  44. package/dist/publicApi.js +325 -0
  45. package/dist/queryOptionalSources.js +14 -0
  46. package/dist/reactivityChannel.js +34 -0
  47. package/dist/rest.d.ts +260 -64
  48. package/dist/rest.js +345 -499
  49. package/dist/restFormat.js +163 -0
  50. package/dist/restReceipt.js +43 -0
  51. package/dist/revalidate.js +13 -0
  52. package/dist/rowEquality.js +31 -0
  53. package/dist/rowPatch.js +182 -0
  54. package/dist/schemaShape.js +67 -0
  55. package/dist/scopes.js +273 -0
  56. package/dist/secretWindows.js +71 -0
  57. package/dist/serverErrorBus.js +15 -0
  58. package/dist/serviceCall.js +14 -0
  59. package/dist/session.d.ts +89 -6
  60. package/dist/session.js +62 -63
  61. package/dist/{sessionHeader-DriTZhmv.js → sessionHeader.js} +1 -1
  62. package/dist/ssrfPolicy.js +30 -0
  63. package/dist/storageAccess.js +14 -0
  64. package/dist/storeErrors.js +66 -0
  65. package/dist/storeScreenshots.js +90 -0
  66. package/dist/strictInput.js +27 -0
  67. package/dist/subscriptionEvent.js +37 -0
  68. package/dist/tenantSelection.js +40 -0
  69. package/dist/time.js +7 -0
  70. package/dist/undo.js +38 -0
  71. package/dist/validation.js +39 -0
  72. package/dist/webSocketGateway.js +16 -0
  73. package/dist/workflow.js +297 -0
  74. package/dist/workflowAccess.js +61 -0
  75. package/dist/workflowRestart.js +45 -0
  76. package/dist/workflowRetry.js +44 -0
  77. package/dist/workflowStartOutcome.js +30 -0
  78. package/package.json +5 -3
  79. package/dist/restFormat-BlgTLxm1.js +0 -298
  80. package/dist/scopes-ClywBij8.js +0 -548
package/dist/rest.js CHANGED
@@ -1,355 +1,28 @@
1
- import { H as e, V as t } from "./scopes-ClywBij8.js";
2
- import { E as n, O as r, T as i, a, c as o, d as s, f as c, i as l, k as u, l as d, n as f, o as p, r as m, s as h, t as g, u as _, v, w as y, y as b } from "./restFormat-BlgTLxm1.js";
3
- import { Effect as x, Schema as S, SchemaGetter as C, SchemaIssue as w } from "effect";
4
- import * as T from "effect/SchemaAST";
5
- //#region src/publicApi.ts
6
- var E = (e, t, n) => t.method ?? (t.resource !== void 0 && n !== void 0 ? A("", t, n).method : void 0) ?? (e === "query" ? "GET" : "POST"), D = (e, t, n) => j(t.path ?? (t.resource !== void 0 && n !== void 0 ? A(e, t, n).path : `/${t.version ?? "v1"}/${e.replace(/\./g, "/")}`)), O = (e) => {
7
- let t = e.split("/").pop() ?? e;
8
- return t.endsWith("ies") ? `${t.slice(0, -3)}y` : t.endsWith("ses") || t.endsWith("xes") ? t.slice(0, -2) : t.endsWith("s") ? t.slice(0, -1) : t;
9
- }, k = (e, t) => {
10
- let n = t != null && (typeof t == "object" || typeof t == "function") && "ast" in t ? re(t) : void 0;
11
- if (n === void 0) return;
12
- let r = `${O(e)}Id`;
13
- return n.has(r) ? r : n.has("id") ? "id" : void 0;
14
- }, A = (e, t, n) => {
15
- let r = (t.resource ?? "").replace(/^\/+|\/+$/g, ""), i = `/${t.version ?? "v1"}/${r}`, a = k(r, n.input), o = a === void 0 ? i : `${i}/:${a}`, s = e.split(".").pop() ?? e, c = n.target?.op;
16
- return n.kind === "query" || n.kind === "stream" ? {
17
- method: "GET",
18
- path: o
19
- } : n.kind === "mutation" && c === "insert" ? {
20
- method: "POST",
21
- path: i
22
- } : n.kind === "mutation" && c === "update" ? {
23
- method: a === void 0 ? "POST" : "PATCH",
24
- path: o
25
- } : n.kind === "mutation" && c === "delete" ? {
26
- method: a === void 0 ? "POST" : "DELETE",
27
- path: o
28
- } : {
29
- method: "POST",
30
- path: `${o}/${s}`
31
- };
32
- }, j = (e) => e.replace(/\{([A-Za-z0-9_]+)\}/g, ":$1"), M = (e) => [...e.matchAll(/:([A-Za-z0-9_]+)/g)].map((e) => e[1]), N = (e) => {
33
- if (T.isUnion(e)) {
34
- let t = e.types.filter((e) => !T.isUndefined(e));
35
- if (t.length === 1) return t[0];
36
- if (t.length !== e.types.length) return new T.Union(t);
37
- }
38
- return e;
39
- }, P = /^-?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?$/i, F = (e, t) => {
40
- let n = N(t);
41
- if (n.encoding !== void 0) return F(e, T.toEncoded(n));
42
- if (T.isUnion(n)) {
43
- for (let t of n.types) {
44
- let n = F(e, t);
45
- if (n !== e) return n;
46
- }
47
- return e;
48
- }
49
- if (T.isArrays(n)) {
50
- let t = Array.isArray(e) ? e : e === void 0 ? void 0 : [e];
51
- if (t === void 0) return e;
52
- let r = n.rest[0] ?? n.elements[0];
53
- return r === void 0 ? t : t.map((e) => F(e, r));
54
- }
55
- if (typeof e != "string") return e;
56
- if (T.isNumber(n)) return P.test(e.trim()) ? Number(e) : e;
57
- if (T.isBoolean(n)) return e === "true" || e !== "false" && e;
58
- if (T.isLiteral(n)) {
59
- let t = n.literal;
60
- return typeof t == "number" && P.test(e.trim()) && Number(e) === t || typeof t == "boolean" && String(t) === e ? t : e;
61
- }
62
- return e;
63
- }, I = (e, t) => {
64
- if (typeof e != "object" || !e || Array.isArray(e)) return e;
65
- let n = N(T.toEncoded(t.ast));
66
- if (!T.isObjects(n)) return e;
67
- let r = { ...e };
68
- for (let e of n.propertySignatures) {
69
- let t = String(e.name);
70
- t in r && (r[t] = F(r[t], e.type));
71
- }
72
- return r;
73
- }, ee = (e) => {
74
- let t = N(T.toEncoded(e.ast));
75
- if (!T.isObjects(t)) return (e) => e;
76
- let n = t.propertySignatures, r = /* @__PURE__ */ new Map(), i = n.length >= 32 && n.every((e, t) => typeof e.name != "string" || e.name in Object.prototype || r.has(e.name) ? !1 : (r.set(e.name, {
77
- type: e.type,
78
- order: t
79
- }), !0));
80
- return (e) => {
81
- if (typeof e != "object" || !e || Array.isArray(e)) return e;
82
- let t = { ...e }, a = i ? Object.keys(t) : void 0;
83
- if (a !== void 0 && a.length * 4 < n.length) {
84
- let e = [];
85
- for (let t of a) {
86
- let n = r.get(t);
87
- n !== void 0 && e.push({
88
- key: t,
89
- ...n
90
- });
91
- }
92
- e.sort((e, t) => e.order - t.order);
93
- for (let { key: n, type: r } of e) t[n] = F(t[n], r);
94
- } else for (let e of n) {
95
- let n = String(e.name);
96
- n in t && (t[n] = F(t[n], e.type));
97
- }
98
- return t;
99
- };
100
- }, L = (e) => {
101
- let t = /* @__PURE__ */ new Set();
102
- if (e === void 0) return t;
103
- let n = (e) => {
104
- if (T.isUnion(e)) {
105
- for (let t of e.types) n(t);
106
- return;
107
- }
108
- if (e.encoding !== void 0 && n(T.toEncoded(e)), T.isObjects(e)) {
109
- let n = e.propertySignatures.find((e) => e.name === "_tag");
110
- n !== void 0 && T.isLiteral(n.type) && typeof n.type.literal == "string" && t.add(n.type.literal);
111
- }
112
- };
113
- return n(e.ast), t;
114
- }, R = (e, t, n) => {
115
- if (n !== void 0) try {
116
- let r = S.encodeUnknownSync(n)(e);
117
- if (typeof r == "object" && r) return {
118
- error: t,
119
- ...r
120
- };
121
- } catch {}
122
- let r = { error: t };
123
- for (let [t, n] of Object.entries(e)) t !== "stack" && t !== "_tag" && (r[t] = n);
124
- return r;
125
- }, z = (e, t, n, r = []) => B(e, t, n, r, L), B = (e, t, n, r, i) => {
126
- if (typeof e != "object" || !e) return e;
127
- let a = e._tag;
128
- if (typeof a != "string" || a === "ScopeError" || a === "NoSuchResource") return e;
129
- if (i(t.error).has(a)) return new Y(n.errorStatus?.[a] ?? 422, R(e, a, t.error));
130
- let o = r.find((e) => i(e.schema).has(a));
131
- if (o === void 0) return e;
132
- let s = n.errorStatus?.[a] ?? o.rest?.status ?? 422, c = o.rest?.headers?.(e);
133
- return new Y(s, R(e, a, o.schema), c);
134
- }, te = (e, t, n, r, i, a, o) => {
135
- let s = B(e, t, n, r, o);
136
- if (!(s instanceof Y) || i.errors === "tagged" && i.encodeError === void 0) return s;
137
- let { error: c, _tag: u, ...d } = s.body, f = typeof d.message == "string" ? d.message : typeof d.reason == "string" ? d.reason : "", p = l(i, {
138
- status: s.status,
139
- tag: c,
140
- message: f,
141
- fields: d
142
- }, {
143
- ...a,
144
- status: s.status
145
- });
146
- return new Y(s.status, p.body, {
147
- ...s.headers ?? {},
148
- ...p.headers ?? {}
149
- }, p.contentType);
150
- }, V = (e, t) => {
151
- if (e === void 0) return;
152
- let n = T.isUnion(e.ast) ? e.ast.types : [e.ast];
153
- for (let e of n) {
154
- let n = S.make(e);
155
- if (L(n).has(t)) return n;
156
- }
157
- }, ne = (e) => e.split(".").map((e, t) => t === 0 ? e : e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_"), re = (e) => {
158
- let t = N(T.toEncoded(e.ast));
159
- return T.isObjects(t) && t.indexSignatures.length === 0 ? new Set(t.propertySignatures.map((e) => String(e.name))) : void 0;
160
- }, ie = (e, t) => e === t || JSON.stringify(e) === JSON.stringify(t), ae = (e) => {
161
- let t = N(T.toEncoded(e.ast)), n = T.isObjects(t) ? new Map(t.propertySignatures.map((e) => [String(e.name), e.type])) : /* @__PURE__ */ new Map();
162
- return (e) => {
163
- let t = {};
164
- for (let [r, i] of Object.entries(e)) {
165
- let e = n.get(r);
166
- t[r] = e === void 0 ? i : F(i, e);
167
- }
168
- return t;
169
- };
170
- }, H = (e, t) => {
171
- if (e !== void 0) {
172
- try {
173
- return S.encodeUnknownSync(t)(e);
174
- } catch {}
175
- try {
176
- return S.decodeUnknownSync(t)(e), e;
177
- } catch {}
178
- return e;
179
- }
180
- }, oe = (e, t, n) => ({
181
- ...e.request === void 0 ? {} : { request: H(e.request, t) },
182
- ...e.response === void 0 ? {} : { response: H(e.response, n) }
183
- }), se = () => (e) => {
184
- if (e.subject.type !== "anonymous") return;
185
- let t = e.subject.credentialRejected;
186
- return t === void 0 ? void 0 : {
187
- status: 401,
188
- message: t
189
- };
190
- }, U = (e, t, n, r = {}) => {
191
- let i = e.publicApi;
192
- if (i === void 0) throw Error(`publicApiRoute: descriptor '${e.name}' has no publicApi annotation`);
193
- let o = d(r.profile, i.format), c = r.pluginErrors ?? [], l = /* @__PURE__ */ new WeakMap(), u = (e) => {
194
- if (e === void 0) return /* @__PURE__ */ new Set();
195
- let t = l.get(e.ast);
196
- if (t !== void 0) return t;
197
- let n = L(e);
198
- return l.set(e.ast, n), n;
199
- }, f = /* @__PURE__ */ new WeakMap(), p = (e, t) => {
200
- if (e === void 0) return;
201
- let n = f.get(e.ast);
202
- if (n === void 0) {
203
- let t = /* @__PURE__ */ new Map();
204
- for (let n of T.isUnion(e.ast) ? e.ast.types : [e.ast]) {
205
- let e = S.make(n);
206
- for (let n of u(e)) t.has(n) || t.set(n, e);
207
- }
208
- n = t, f.set(e.ast, n);
209
- }
210
- return n.get(t);
211
- }, m = {
212
- kind: e.kind,
213
- input: e.input,
214
- target: e.target
215
- }, h = E(e.kind, i, m), g = (e) => o.naming === "snake_case" ? s(e) : e, v = D(e.name, i, m), y = v.replace(/:([A-Za-z0-9_]+)/g, (e, t) => `:${g(t)}`), b = M(y), O = _(e.input, o), k = ee(O), A = ae(O), j = re(O);
216
- if (j !== void 0) {
217
- for (let t of b) if (!j.has(t)) throw Error(`publicApi: descriptor '${e.name}' — path '${v}' binds ':${t}', and the input declares no field of that name` + (j.size > 0 ? ` (fields: ${[...j].join(", ")})` : " (the input declares no fields)"));
218
- }
219
- let N = _(e.output, o), P = S.Struct({ value: O }), F = h !== "GET" && j === void 0;
220
- if (h !== "GET" && j !== void 0) {
221
- let e = b.length >= 32 ? new Set(b) : void 0;
222
- for (let t of j) if (!(e?.has(t) ?? b.includes(t))) {
223
- F = !0;
224
- break;
225
- }
226
- }
227
- let I = {
228
- query: S.Unknown,
229
- params: S.Unknown,
230
- form: S.Boolean
231
- }, R = (F ? S.Struct({
232
- ...I,
233
- body: S.Unknown
234
- }) : S.Struct(I)).pipe(S.decodeTo(P, {
235
- decode: C.transformEffect((e) => {
236
- let t = "body" in e ? e.body : void 0, n = h === "GET" ? k(e.query) : e.form ? k(t ?? {}) : t ?? {}, r = typeof e.params == "object" && e.params !== null ? A(e.params) : {};
237
- if (typeof n != "object" || !n || Array.isArray(n)) return x.succeed({ value: n });
238
- let i = n, a = Object.keys(r), o = 0;
239
- for (let e of a) e in i && !ie(i[e], r[e]) && (a[o++] = e);
240
- if (a.length = o, a.length > 0) {
241
- let t = h === "GET" ? "query string" : "body";
242
- return x.fail(new w.InvalidValue({ message: `${a.map((e) => `'${e}'`).join(", ")} ${a.length === 1 ? "is" : "are"} bound by the path and sent with another value in the ${t}` }, e));
243
- }
244
- return x.succeed({ value: {
245
- ...i,
246
- ...r
247
- } });
248
- }),
249
- encode: C.transform((e) => e)
250
- })), z = [
251
- se(),
252
- ...e.openAccess === void 0 ? [le()] : [],
253
- ...(i.scopes ?? []).map((e) => ue(e))
254
- ], B = (() => {
255
- let t = e.source;
256
- return typeof t == "string" ? t : Array.isArray(t) ? t[0] : void 0;
257
- })(), V = (t, n = 200) => ({
258
- tag: e.name,
259
- method: t.method,
260
- path: t.path,
261
- query: t.query,
262
- source: B,
263
- status: n
264
- }), H = i.stream === "sse" && e.kind === "query" && n !== void 0, U = S.encodeUnknownEffect(N), ce = H ? (e, t) => he((r) => n(e.value, t, (e) => {
265
- r(ge(String(e._tag ?? "message"), e));
266
- })) : async (n, r) => {
267
- let s;
268
- try {
269
- s = await t(n.value, r);
270
- } catch (t) {
271
- throw te(t, e, i, c, o, V(r), u);
272
- }
273
- let l = await x.runPromise(U(s)), d = a(o, l, V(r));
274
- return q(d.body, {
275
- ...d.headers === void 0 ? {} : { headers: d.headers },
276
- ...d.contentType === void 0 ? {} : { contentType: d.contentType }
277
- });
278
- }, W = e.error, G = u(W), de = [...G], K = [];
279
- for (let e of de) {
280
- let t = p(W, e);
281
- t !== void 0 && K.push({
282
- status: i.errorStatus?.[e] ?? 422,
283
- tag: e,
284
- schema: t
285
- });
286
- }
287
- for (let e of c) for (let t of u(e.schema)) {
288
- if (G.has(t)) continue;
289
- let n = i.errorStatus?.[t] ?? e.rest?.status;
290
- if (n === void 0) continue;
291
- let r = p(e.schema, t) ?? e.schema;
292
- K.push({
293
- status: n,
294
- tag: t,
295
- schema: r
296
- });
297
- }
298
- let fe = i.security === !1 ? "none" : i.security ?? (e.openAccess === void 0 ? "required" : "optional"), J = {
299
- tag: e.name,
300
- kind: e.kind,
301
- version: i.version ?? "v1",
302
- security: fe,
303
- idempotent: i.idempotent === !0,
304
- input: O,
305
- pathParams: b,
306
- output: N,
307
- source: B,
308
- errorResponses: K,
309
- format: o
310
- };
311
- return me({
312
- method: h,
313
- path: y,
314
- input: R,
315
- output: S.Unknown,
316
- handler: ce,
317
- ...H ? { streaming: !0 } : {},
318
- guards: z,
319
- operationId: i.operationId ?? ne(e.name),
320
- tags: i.tags ?? [e.name.split(".")[0] ?? e.name],
321
- projection: J,
322
- ...o.etag && h === "GET" && !H ? { etag: !0 } : {},
323
- ...i.cache !== void 0 && h === "GET" && !H ? { cache: i.cache } : {},
324
- ...i.example === void 0 ? {} : { example: oe(i.example, O, N) },
325
- ...i.summary === void 0 ? {} : { summary: i.summary },
326
- ...i.description === void 0 ? {} : { description: i.description },
327
- ...i.deprecated === void 0 ? {} : { deprecated: i.deprecated },
328
- ...i.sunset === void 0 ? {} : { sunset: i.sunset }
329
- });
330
- }, ce = (e, t = {}) => e.filter((e) => e.descriptor.publicApi !== void 0).map((e) => U(e.descriptor, e.invoke, e.subscribe, t)).sort((e, t) => e.path.localeCompare(t.path)), W = (e) => b(e.filter((e) => e.projection !== void 0).map((e) => {
331
- let t = e.projection, n = {
332
- tag: t.tag,
333
- method: e.method,
334
- path: e.path,
335
- pathParams: t.pathParams,
336
- version: t.version,
337
- security: t.security,
338
- errors: [...t.errorResponses].map((e) => `${e.status}:${e.tag}`).sort()
339
- };
340
- return `${JSON.stringify(n)} ${v(t.input.ast)} ${v(t.output.ast)}`;
341
- }).sort().join("\n")), le = () => (e) => {
1
+ import { Unauthenticated as e, anonymousSubject as t, currentSubjectAuthority as n } from "./auth.js";
2
+ import { effectiveScopes as r, hasEffectiveScope as i, recheckGuardsEffect as a } from "./scopes.js";
3
+ import { beginIdempotent as o, failIdempotent as s, finishIdempotent as c, holdIdempotentClaim as l, idempotencyScope as u } from "./idempotency.js";
4
+ import { declaredErrorTags as d, errorMemberSchema as f } from "./errorSchema.js";
5
+ import { prepareIdempotentInput as p } from "./idempotencyInput.js";
6
+ import { validateHttpStreamMaxDuration as m } from "./httpStreamMaxDuration.js";
7
+ import { publishServerError as h } from "./serverErrorBus.js";
8
+ import { JSONAPI_MEDIA_TYPE as g, PROBLEM_JSON as _, REST_PROFILE_NAMES as v, encodeRestError as y, encodeRestSuccess as b, nextLink as x, problemDetails as S, problemTypeOf as C, resolveRestFormat as w, restViewSchema as T, toSnakeCase as E } from "./restFormat.js";
9
+ import { makeRestReceiptCodec as D } from "./restReceipt.js";
10
+ import { coerceQueryObject as O, coerceQueryValue as k, collectPublicApiRoutes as A, derivePublicMethod as j, derivePublicPath as M, deriveResource as N, normalizePathParams as P, operationIdOf as F, pathParamNames as I, projectedFailure as ee, publicApiRoute as te, publicSurfaceDigest as ne, resourceIdField as re, wireExample as ie } from "./publicApi.js";
11
+ import { Effect as L, Schema as R } from "effect";
12
+ import * as ae from "effect/SchemaAST";
13
+ import { newTraceId as oe } from "@voltro/shared";
14
+ //#region src/rest.ts
15
+ var se = () => (e) => {
342
16
  if (e.subject.type === "anonymous") return {
343
17
  status: 401,
344
18
  message: e.subject.credentialRejected ?? "Authentication required"
345
19
  };
346
- }, ue = (e) => (t) => {
347
- let n = t.subject.scopes;
348
- if (!(n && (n.includes(e) || n.includes("admin:full")))) return {
20
+ }, ce = (e) => (t) => {
21
+ if (!i(t.subject, e)) return {
349
22
  status: 403,
350
23
  message: `Missing required scope: ${e}`
351
24
  };
352
- }, G = (e) => {
25
+ }, z = (e) => {
353
26
  for (let t of [
354
27
  "includes",
355
28
  "some",
@@ -364,24 +37,47 @@ var E = (e, t, n) => t.method ?? (t.resource !== void 0 && n !== void 0 ? A("",
364
37
  if (n === void 0 || !("value" in n) || typeof n.value != "string") return !1;
365
38
  }
366
39
  return !0;
367
- }, de = (e) => (t) => {
368
- let n = t.subject.scopes;
40
+ }, le = (e) => (t) => {
41
+ let n = r(t.subject);
369
42
  if (n) {
370
43
  if (n.includes("admin:full")) return;
371
- let t = n.length >= 32 && e.length >= 256 && G(n) && G(e) ? new Set(n) : void 0;
44
+ let t = n.length >= 32 && e.length >= 256 && z(n) && z(e) ? new Set(n) : void 0;
372
45
  if (e.some((e) => t === void 0 ? n.includes(e) : t.has(e))) return;
373
46
  }
374
47
  return {
375
48
  status: 403,
376
49
  message: `Missing required scope: one of ${e.join(", ")}`
377
50
  };
378
- }, K = (e, t) => e.method === "GET" && e.cache !== void 0 && t.status !== 200 && t.status !== 304 ? {
51
+ }, B = (e, t) => {
52
+ if (e === void 0) return {};
53
+ let n = { vary: "Origin" };
54
+ return t !== void 0 && (e.origins.includes(t) || e.origins.includes("*")) && (n["access-control-allow-origin"] = e.origins.includes("*") ? "*" : t, n["access-control-expose-headers"] = (e.exposeHeaders ?? [
55
+ "retry-after",
56
+ "ratelimit-limit",
57
+ "ratelimit-remaining",
58
+ "ratelimit-reset"
59
+ ]).join(", ")), n;
60
+ }, V = (e, t, n) => {
61
+ let r = B(e, n.origin), i = e.methods ?? (t === "GET" ? ["GET", "HEAD"] : [t]), a = e.headers ?? ["authorization", "content-type"], o = (n["access-control-request-headers"] ?? "").split(",").map((e) => e.trim().toLowerCase()).filter(Boolean), s = r["access-control-allow-origin"] !== void 0 && i.some((e) => e === n["access-control-request-method"]) && o.every((e) => a.some((t) => t.toLowerCase() === e));
62
+ return {
63
+ status: s ? 204 : 403,
64
+ headers: {
65
+ ...r,
66
+ vary: "Origin, Access-Control-Request-Method, Access-Control-Request-Headers",
67
+ ...s ? {
68
+ "access-control-allow-methods": i.join(", "),
69
+ "access-control-allow-headers": a.join(", "),
70
+ ...e.maxAge === void 0 ? {} : { "access-control-max-age": String(e.maxAge) }
71
+ } : {}
72
+ }
73
+ };
74
+ }, H = (e, t) => e.method === "GET" && e.cache !== void 0 && t.status !== 200 && t.status !== 304 ? {
379
75
  ...t,
380
76
  headers: {
381
77
  ...t.headers,
382
78
  "Cache-Control": "private, no-store"
383
79
  }
384
- } : t, fe = (e, t, n, r, i) => {
80
+ } : t, ue = (e, t, n, r, i) => {
385
81
  if (e === void 0) return {};
386
82
  let a = { Vary: e.audience === void 0 ? "Authorization, Cookie" : "Authorization" };
387
83
  if (t.headers.authorization !== void 0 || e.audience === void 0 && t.headers.cookie !== void 0) return {
@@ -407,13 +103,13 @@ var E = (e, t, n) => t.method ?? (t.resource !== void 0 && n !== void 0 ? A("",
407
103
  "Surrogate-Key": c.join(" ")
408
104
  } : {}
409
105
  };
410
- }, q = (e, t = {}) => ({
106
+ }, U = (e, t = {}) => ({
411
107
  __voltroRestResponse: !0,
412
108
  status: t.status ?? 200,
413
109
  body: e,
414
110
  ...t.headers === void 0 ? {} : { headers: t.headers },
415
111
  ...t.contentType === void 0 ? {} : { contentType: t.contentType }
416
- }), J = (e) => typeof e == "object" && !!e && e.__voltroRestResponse === !0, Y = class extends Error {
112
+ }), W = (e) => typeof e == "object" && !!e && e.__voltroRestResponse === !0, G = class extends Error {
417
113
  status;
418
114
  body;
419
115
  headers;
@@ -421,7 +117,7 @@ var E = (e, t, n) => t.method ?? (t.resource !== void 0 && n !== void 0 ? A("",
421
117
  constructor(e, t, n, r) {
422
118
  super(`REST ${e}`), this.name = "RestRouteError", this.status = e, this.body = t, this.headers = n, this.contentType = r;
423
119
  }
424
- }, pe = (e, t, n) => new Y(e, t, n), me = (e) => {
120
+ }, de = (e, t, n) => new G(e, t, n), fe = (e) => {
425
121
  if (e.version === void 0) return e;
426
122
  if (!/^v\d+$/.test(e.version)) throw Error(`defineRestRoute(${e.method} ${e.path}): version "${e.version}" must be 'v' followed by digits — 'v1', 'v2', …`);
427
123
  if ((/* @__PURE__ */ RegExp("^/v\\d+(/|$)")).test(e.path)) throw Error(`defineRestRoute(${e.method} ${e.path}): the path already starts with a version segment AND declares version: '${e.version}'. Pick one spelling — either bake the version into the path, or declare version: and keep the path bare ('/customers'). Both would mount '/${e.version}${e.path}', which is never what the author meant.`);
@@ -429,13 +125,17 @@ var E = (e, t, n) => t.method ?? (t.resource !== void 0 && n !== void 0 ? A("",
429
125
  ...e,
430
126
  path: `/${e.version}${e.path}`
431
127
  };
432
- }, he = (e, t = {}) => ({
433
- __voltroRestStream: !0,
434
- stream: {
435
- subscribe: e,
436
- ...t.keepAliveMs === void 0 ? {} : { keepAliveMs: t.keepAliveMs }
437
- }
438
- }), ge = (e, t) => `event: ${e}\n${(typeof t == "string" ? t : JSON.stringify(t)).split("\n").map((e) => `data: ${e}`).join("\n")}\n\n`, _e = (e) => typeof e == "object" && !!e && e.__voltroRestStream === !0, ve = (e, t = {}) => ({
128
+ }, pe = (e, t = {}) => {
129
+ let n = m(t.maxDurationMs);
130
+ return {
131
+ __voltroRestStream: !0,
132
+ stream: {
133
+ subscribe: e,
134
+ ...t.keepAliveMs === void 0 ? {} : { keepAliveMs: t.keepAliveMs },
135
+ ...n === void 0 ? {} : { maxDurationMs: n }
136
+ }
137
+ };
138
+ }, me = (e, t) => `event: ${e}\n${(typeof t == "string" ? t : JSON.stringify(t)).split("\n").map((e) => `data: ${e}`).join("\n")}\n\n`, K = (e) => typeof e == "object" && !!e && e.__voltroRestStream === !0, he = (e, t = {}) => ({
439
139
  __voltroRestBytes: !0,
440
140
  byteStream: {
441
141
  stream: e,
@@ -445,18 +145,18 @@ var E = (e, t, n) => t.method ?? (t.resource !== void 0 && n !== void 0 ? A("",
445
145
  ...t.contentType === void 0 ? {} : { contentType: t.contentType },
446
146
  ...t.status === void 0 ? {} : { status: t.status },
447
147
  ...t.headers === void 0 ? {} : { headers: t.headers }
448
- }), X = (e) => typeof e == "object" && !!e && e.__voltroRestBytes === !0, ye = async (e) => {
148
+ }), q = (e) => typeof e == "object" && !!e && e.__voltroRestBytes === !0, ge = async (e) => {
449
149
  let t = await globalThis.crypto.subtle.digest("SHA-1", new TextEncoder().encode(e)), n = "";
450
150
  for (let e of new Uint8Array(t)) n += e.toString(16).padStart(2, "0");
451
151
  return n;
452
- }, Z = (e, t, n, r = "application/json; charset=utf-8") => ({
152
+ }, J = (e, t, n, r = "application/json; charset=utf-8") => ({
453
153
  status: e,
454
154
  contentType: r,
455
155
  body: JSON.stringify(t),
456
156
  ...n ? { headers: n } : {}
457
- }), Q = (e, t, n, r, i, a, o) => {
157
+ }), Y = (e, t, n, r, i, a, o) => {
458
158
  let s = e.projection;
459
- if (s === void 0) return Z(n, {
159
+ if (s === void 0) return J(n, {
460
160
  error: i,
461
161
  ...a
462
162
  }, o);
@@ -467,17 +167,17 @@ var E = (e, t, n) => t.method ?? (t.resource !== void 0 && n !== void 0 ? A("",
467
167
  query: t.query,
468
168
  source: s.source,
469
169
  status: n
470
- }, u = l(s.format, {
170
+ }, l = y(s.format, {
471
171
  status: n,
472
172
  tag: r,
473
173
  message: i,
474
174
  fields: a
475
175
  }, c);
476
- return Z(n, u.body, {
176
+ return J(n, l.body, {
477
177
  ...o,
478
- ...u.headers ?? {}
479
- }, u.contentType);
480
- }, be = (e) => (e.headers["content-type"] ?? "application/json").split(";")[0].trim().toLowerCase(), xe = (e, t) => {
178
+ ...l.headers ?? {}
179
+ }, l.contentType);
180
+ }, X = (e) => (e.headers["content-type"] ?? "application/json").split(";")[0].trim().toLowerCase(), _e = (e, t) => {
481
181
  if (e.length === 0) return;
482
182
  let n = t === "application/x-www-form-urlencoded";
483
183
  if (!n && t !== "application/json" && !/^application\/[^/;\s]+\+json$/.test(t)) return;
@@ -485,21 +185,21 @@ var E = (e, t, n) => t.method ?? (t.resource !== void 0 && n !== void 0 ? A("",
485
185
  if (r.trim() !== "") {
486
186
  if (n) {
487
187
  let e = (e) => decodeURIComponent(e.replace(/\+/g, " "));
488
- return Ce((r.match(/[^&]+/g) ?? []).map((t) => {
188
+ return Z((r.match(/[^&]+/g) ?? []).map((t) => {
489
189
  let n = t.indexOf("=");
490
190
  return n < 0 ? [e(t), ""] : [e(t.slice(0, n)), e(t.slice(n + 1))];
491
191
  }));
492
192
  }
493
193
  return JSON.parse(r);
494
194
  }
495
- }, Se = (e) => Ce(new URLSearchParams(e)), Ce = (e) => {
195
+ }, ve = (e) => Z(new URLSearchParams(e)), Z = (e) => {
496
196
  let t = /* @__PURE__ */ new Map();
497
197
  for (let [n, r] of e) {
498
198
  let e = t.get(n);
499
199
  e === void 0 ? t.set(n, r) : Array.isArray(e) ? e.push(r) : t.set(n, [e, r]);
500
200
  }
501
201
  return Object.fromEntries(t);
502
- }, we = (e, t) => {
202
+ }, ye = (e, t) => {
503
203
  let n = e.match(/[^/]+/g) ?? [], r = t.match(/[^/]+/g) ?? [], i = {};
504
204
  for (let e = 0; e < n.length; e++) {
505
205
  let t = n[e];
@@ -513,7 +213,7 @@ var E = (e, t, n) => t.method ?? (t.resource !== void 0 && n !== void 0 ? A("",
513
213
  }
514
214
  }
515
215
  return i;
516
- }, Te = (e, t) => {
216
+ }, be = (e, t) => {
517
217
  let n = e.path.split("/"), r = n[n.length - 1] === "*", i = r ? n.slice(0, -1) : n, a = t.split("/");
518
218
  if (a.length < i.length) return !1;
519
219
  for (let e = 0; e < i.length; e++) {
@@ -523,191 +223,337 @@ var E = (e, t, n) => t.method ?? (t.resource !== void 0 && n !== void 0 ? A("",
523
223
  } else if (t !== n) return !1;
524
224
  }
525
225
  return a.length === i.length ? !0 : e.match === "exact" && !r ? !1 : a.slice(i.length).some((e) => e.length > 0);
526
- }, Ee = (e, t, n) => ({
527
- query: Se(e.query),
226
+ }, xe = (e, t, n) => ({
227
+ query: ve(e.query),
528
228
  params: t,
529
- body: n ? xe(e.rawBody, be(e)) : void 0,
530
- form: be(e) === "application/x-www-form-urlencoded"
531
- }), $ = /* @__PURE__ */ new Set([
229
+ body: n ? _e(e.rawBody, X(e)) : void 0,
230
+ form: X(e) === "application/x-www-form-urlencoded"
231
+ }), Q = /* @__PURE__ */ new Set([
532
232
  "POST",
533
233
  "PUT",
534
234
  "PATCH",
535
235
  "DELETE"
536
- ]), De = (e, n, r, i, a) => {
537
- if (e instanceof Y) return Z(e.status, e.body, {
236
+ ]), $ = (t, n, r, i, a) => {
237
+ if (r.mapFailure !== void 0) try {
238
+ let e = r.mapFailure(t, {
239
+ method: a.method,
240
+ path: a.path,
241
+ query: a.query
242
+ });
243
+ if (e instanceof Promise) throw e.catch(() => void 0), Error("REST failure mapping must complete synchronously");
244
+ if (L.isEffect(e) && !(e instanceof Error)) throw Error("REST failure mapping must be pure");
245
+ e !== void 0 && (t = e);
246
+ } catch {
247
+ t = /* @__PURE__ */ Error("REST failure mapping could not be applied");
248
+ }
249
+ if (t instanceof G) return J(t.status, t.body, {
538
250
  ...i,
539
- ...e.headers
540
- }, e.contentType);
541
- if (typeof e == "object" && e) {
542
- let o = e;
543
- if (typeof o.status == "number") return Q(r, a, o.status, typeof o._tag == "string" ? o._tag : "Error", typeof o.message == "string" ? o.message : "Error", {}, { ...i });
544
- if (o._tag === "Unauthenticated" || e instanceof t) return Q(r, a, 401, "Unauthorized", typeof o.reason == "string" ? o.reason : "Authentication required", {}, { ...i });
251
+ ...t.headers
252
+ }, t.contentType);
253
+ if (typeof t == "object" && t) {
254
+ let o = t;
255
+ if (typeof o.status == "number") return Y(r, a, o.status, typeof o._tag == "string" ? o._tag : "Error", typeof o.message == "string" ? o.message : "Error", {}, { ...i });
256
+ if (o._tag === "Unauthenticated" || t instanceof e) return Y(r, a, 401, "Unauthorized", typeof o.reason == "string" ? o.reason : "Authentication required", {}, { ...i });
545
257
  if (o._tag === "ScopeError") {
546
258
  let e = n.type === "anonymous" ? 401 : 403;
547
- return Q(r, a, e, e === 401 ? "Unauthorized" : "Forbidden", typeof o.message == "string" ? o.message : "Forbidden", {}, { ...i });
259
+ return Y(r, a, e, e === 401 ? "Unauthorized" : "Forbidden", typeof o.message == "string" ? o.message : "Forbidden", {}, { ...i });
548
260
  }
549
261
  if (o._tag === "NoSuchResource") {
550
- let t = e;
551
- return Q(r, a, 404, "NoSuchResource", typeof o.message == "string" ? o.message : "Not Found", {
552
- resourceType: typeof t.resourceType == "string" ? t.resourceType : null,
553
- resourceId: typeof t.resourceId == "string" ? t.resourceId : null
262
+ let e = t;
263
+ return Y(r, a, 404, "NoSuchResource", typeof o.message == "string" ? o.message : "Not Found", {
264
+ resourceType: typeof e.resourceType == "string" ? e.resourceType : null,
265
+ resourceId: typeof e.resourceId == "string" ? e.resourceId : null
554
266
  }, { ...i });
555
267
  }
556
268
  }
557
- return c({
558
- error: e,
269
+ return h({
270
+ error: t,
559
271
  source: "rest",
560
272
  name: `${r.method} ${r.path}`,
561
273
  fields: { status: 500 }
562
274
  }), {
563
- ...Q(r, a, 500, "InternalServerError", "Internal Server Error", {}, { ...i }),
564
- cause: e
275
+ ...Y(r, a, 500, "InternalServerError", "Internal Server Error", {}, { ...i }),
276
+ cause: t
565
277
  };
566
- }, Oe = (a, o, s) => {
567
- let c = a.input ? S.decodeUnknownEffect(a.input) : void 0, l = S.encodeEffect(a.output), d = a.input === void 0 ? void 0 : T.toEncoded(a.input.ast), f = d !== void 0 && (!T.isObjects(d) || d.indexSignatures.length > 0 || d.propertySignatures.some((e) => e.name === "body")), p = {};
568
- a.projection !== void 0 && (p["x-voltro-rest-profile"] = a.projection.format.name);
569
- let m = (e) => e.replace(/\/$/, "").split("/").length, h = m(a.path);
570
- return a.deprecated !== void 0 && (p.Deprecation = "true"), a.sunset !== void 0 && (p.Sunset = a.sunset), {
571
- method: a.method,
278
+ }, Se = (e, r, i) => {
279
+ let d = e.input ? R.decodeUnknownEffect(e.input) : void 0, f = R.encodeEffect(e.output), m = D(e.projection === void 0 ? e.output : e.publicApiDescriptor?.output ?? e.output, e.projection === void 0 ? "raw" : "projection"), h = (t, n, r) => {
280
+ if (!Number.isInteger(t.status) || t.status < 200 || t.status > 599) throw Error("Invalid final REST response status");
281
+ let i = e.projection;
282
+ if (i === void 0) return {
283
+ ...t,
284
+ body: n
285
+ };
286
+ let a = b(i.format, n, {
287
+ tag: i.tag,
288
+ method: r.method,
289
+ path: r.path,
290
+ query: r.query,
291
+ source: i.source,
292
+ status: t.status
293
+ });
294
+ return U(a.body, {
295
+ status: t.status,
296
+ headers: {
297
+ ...t.headers,
298
+ ...a.headers
299
+ },
300
+ ...(a.contentType ?? t.contentType) === void 0 ? {} : { contentType: a.contentType ?? t.contentType }
301
+ });
302
+ }, g = e.input === void 0 ? void 0 : ae.toEncoded(e.input.ast), _ = g !== void 0 && (!ae.isObjects(g) || g.indexSignatures.length > 0 || g.propertySignatures.some((e) => e.name === "body")), v = {};
303
+ e.projection !== void 0 && (v["x-voltro-rest-profile"] = e.projection.format.name);
304
+ let y = (e) => e.replace(/\/$/, "").split("/").length, x = y(e.path);
305
+ e.deprecated !== void 0 && (v.Deprecation = "true"), e.sunset !== void 0 && (v.Sunset = e.sunset);
306
+ let S = {
307
+ method: e.method,
308
+ ...e.publicApiDescriptor === void 0 ? {} : { restContract: e },
572
309
  answersOtherMethods: !0,
573
- path: a.path,
574
- match: a.path.endsWith("/*") ? "prefix" : "exact",
575
- ...a.maxBodyBytes === void 0 ? {} : { maxBodyBytes: a.maxBodyBytes },
576
- handle: async (d) => {
577
- if (!a.path.endsWith("/*") && m(d.path) !== h) return Q(a, d, 404, "NotFound", "Not Found", {}, { ...p });
578
- let g = d.method.toUpperCase();
579
- if (!(g === a.method || g === "HEAD" && a.method === "GET")) return Q(a, d, 405, "MethodNotAllowed", "Method Not Allowed", { allow: s }, {
580
- ...p,
581
- Allow: s
310
+ path: e.path,
311
+ match: e.path.endsWith("/*") ? "prefix" : "exact",
312
+ ...e.maxBodyBytes === void 0 ? {} : { maxBodyBytes: e.maxBodyBytes },
313
+ ...e.cors === void 0 ? {} : { cors: e.cors },
314
+ ...e.credentials === void 0 ? {} : { credentials: e.credentials },
315
+ handle: async (g) => {
316
+ if (!e.path.endsWith("/*") && y(g.path) !== x) return Y(e, g, 404, "NotFound", "Not Found", {}, { ...v });
317
+ let b = g.method.toUpperCase();
318
+ if (!(b === e.method || b === "HEAD" && e.method === "GET")) return Y(e, g, 405, "MethodNotAllowed", "Method Not Allowed", { allow: i }, {
319
+ ...v,
320
+ Allow: i
582
321
  });
583
- if (a.sunset !== void 0) {
584
- let e = Date.parse(a.sunset);
585
- if (!Number.isNaN(e) && Date.now() >= e) return Q(a, d, 410, "Gone", "Gone", {
586
- ...a.version === void 0 ? {} : { version: a.version },
587
- ...a.deprecated === void 0 ? {} : { replacement: a.deprecated }
588
- }, { ...p });
322
+ if (e.sunset !== void 0) {
323
+ let t = Date.parse(e.sunset);
324
+ if (!Number.isNaN(t) && Date.now() >= t) return Y(e, g, 410, "Gone", "Gone", {
325
+ ...e.version === void 0 ? {} : { version: e.version },
326
+ ...e.deprecated === void 0 ? {} : { replacement: e.deprecated }
327
+ }, { ...v });
589
328
  }
590
- let _;
591
- if (c) {
592
- let e;
329
+ let S;
330
+ if (d) {
331
+ let t;
593
332
  try {
594
- e = Ee(d, we(a.path, d.path), f);
333
+ t = xe(g, ye(e.path, g.path), _);
595
334
  } catch {
596
- return Q(a, d, 400, "InvalidRequest", "Malformed request body", {}, { ...p });
335
+ return Y(e, g, 400, "InvalidRequest", "Malformed request body", {}, { ...v });
597
336
  }
598
- let t = await x.runPromise(c(e).pipe(x.map((e) => ({
337
+ let n = await L.runPromise(d(t).pipe(L.map((e) => ({
599
338
  ok: !0,
600
339
  value: e
601
- })), x.catch((e) => x.succeed({
340
+ })), L.catch((e) => L.succeed({
602
341
  ok: !1,
603
342
  cause: e
604
343
  }))));
605
- if (!t.ok) return Q(a, d, 400, "InvalidRequest", "Invalid request", { detail: String(t.cause) }, { ...p });
606
- _ = t.value;
607
- }
608
- let v;
609
- try {
610
- v = o.resolveSubject ? await o.resolveSubject(d.headers) : e(d.headers["x-tenant"] ?? null);
611
- } catch (e) {
612
- if (e instanceof t || typeof e == "object" && e && e._tag === "Unauthenticated") {
613
- let t = e.reason;
614
- return Q(a, d, 401, "Unauthorized", t ?? "Authentication required", {}, { ...p });
615
- }
616
- throw e;
344
+ if (!n.ok) return Y(e, g, 400, "InvalidRequest", "Invalid request", { detail: String(n.cause) }, { ...v });
345
+ S = n.value;
617
346
  }
618
- let b;
347
+ let C;
619
348
  try {
620
- b = o.buildContext ? await o.buildContext(v, d.headers) : void 0;
621
- } catch (e) {
622
- return K(a, De(e, v, a, p, d));
623
- }
624
- let S = typeof b == "object" && b && "store" in b ? b.store : o.store, C = {
625
- subject: v,
626
- headers: d.headers,
627
- store: S,
628
- method: g,
629
- path: d.path,
630
- query: d.query,
631
- rawBody: d.rawBody,
632
- ...b === void 0 ? {} : { app: b },
633
- ...d.remoteAddr === void 0 ? {} : { remoteAddr: d.remoteAddr }
634
- };
635
- if (a.guards) for (let e of a.guards) {
636
- let t = await e(C);
637
- if (t) return Q(a, d, t.status, t.status === 401 ? "Unauthorized" : t.status === 403 ? "Forbidden" : "GuardRejected", t.message, {}, { ...p });
349
+ C = r.resolveSubject ? await r.resolveSubject(g.headers, {
350
+ path: g.path,
351
+ query: g.query
352
+ }) : t(g.headers["x-tenant"] ?? null);
353
+ } catch (n) {
354
+ return H(e, $(n, t(null), e, v, g));
638
355
  }
639
- let w = o.idempotency, T = w && $.has(a.method) ? d.headers[w.header.toLowerCase()] : void 0, E = w && T ? u(v.tenantId, a.method, a.path) : "", D;
640
- if (w && T) {
641
- let e = await y(w.store, E, T, w.ttlMs, Date.now());
642
- if (e.kind === "replay") return Z(e.response.status, e.response.body, {
643
- ...p,
644
- "Idempotency-Replayed": "true"
356
+ if (e.credentials === "bearer" && C.type === "anonymous") return Y(e, g, 401, "Unauthorized", C.credentialRejected ?? "Authentication required", {}, { ...v });
357
+ let w = C, T = r.traceId?.() ?? oe(), E = {
358
+ traceId: T,
359
+ ...g.remoteAddr === void 0 ? {} : { remoteAddr: g.remoteAddr }
360
+ }, D = r.idempotency, O = D && Q.has(e.method) ? g.headers[D.header.toLowerCase()] : void 0, k = D && O ? u(C.tenantId, e.method, e.path) : "", A = e.projection === void 0 ? void 0 : e.publicApiDescriptor, j;
361
+ if (D && O) try {
362
+ let t = await p(A?.input ?? e.input ?? R.Unknown, A === void 0 ? S : S.value, C, {
363
+ path: g.path,
364
+ ...A === void 0 && e.input === void 0 ? {
365
+ query: g.query,
366
+ rawBody: g.rawBody
367
+ } : {}
645
368
  });
646
- if (e.kind === "conflict") return Q(a, d, 409, "Conflict", "A request with this Idempotency-Key is already being processed", {}, { ...p });
647
- D = r(w.store, E, T);
369
+ S = A === void 0 ? t.input : { value: t.input }, j = t.fingerprint;
370
+ } catch {
371
+ return Y(e, g, 503, "IdempotencyUnavailable", "This request input cannot be safely retained for replay.", {}, { ...v });
648
372
  }
373
+ let M, N = async () => {
374
+ let t = r.bindReplayAuthority?.({
375
+ subject: w,
376
+ traceId: T,
377
+ tag: A?.name ?? e.operationId ?? `${e.method} ${e.path}`,
378
+ kind: A?.kind ?? "rest",
379
+ input: A === void 0 ? S : S.value,
380
+ surface: "rest",
381
+ ...A?.publicApi === void 0 ? {} : { publicApi: A.publicApi },
382
+ ...g.remoteAddr === void 0 ? {} : { remoteAddr: g.remoteAddr }
383
+ });
384
+ if (t !== void 0) throw t instanceof Promise && t.catch(() => void 0), Error("Replay authority bindings must complete synchronously");
385
+ let i = await L.runPromise(a(w, void 0, S));
386
+ if (i) throw i;
387
+ C = n(w);
388
+ let o = r.buildContext ? await r.buildContext(C, g.headers, E) : void 0, s = typeof o == "object" && o && "store" in o ? o.store : r.store;
389
+ M = {
390
+ ...E,
391
+ subject: C,
392
+ headers: g.headers,
393
+ store: s,
394
+ method: b,
395
+ path: g.path,
396
+ query: g.query,
397
+ rawBody: g.rawBody,
398
+ ...o === void 0 ? {} : { app: o }
399
+ };
400
+ for (let t of e.guards ?? []) {
401
+ let n = await t(M, {
402
+ input: S,
403
+ defaultDeny: r.defaultDeny === !0
404
+ });
405
+ if (n) return Y(e, g, n.status, n.status === 401 ? "Unauthorized" : n.status === 403 ? "Forbidden" : "GuardRejected", n.message, {}, { ...v });
406
+ }
407
+ }, P, F, I = !1;
649
408
  try {
650
- let e = await a.handler(_, C);
651
- if (_e(e) || X(e)) return w && T && await i(w.store, E, T), X(e) ? {
652
- status: e.status ?? 200,
409
+ let t = await N();
410
+ if (t) return t;
411
+ if (e.rateLimit !== void 0 && r.rateLimit !== void 0) {
412
+ let t = await L.runPromise(r.rateLimit(e.rateLimit, M, e).pipe(L.as({ allowed: !0 }), L.catch((e) => L.succeed({
413
+ allowed: !1,
414
+ error: e
415
+ }))));
416
+ if (!t.allowed) return $(t.error, C, e, v, g);
417
+ let n = await N();
418
+ if (n) return n;
419
+ }
420
+ if (D && O) {
421
+ if (j === void 0) throw Error("Missing captured REST input identity");
422
+ let t = await o(D.store, k, O, j, D.ttlMs, Date.now());
423
+ t.kind === "fresh" && (F = t.claim, P = l(D.store, F));
424
+ let n = await N();
425
+ if (n) return n;
426
+ if (t.kind === "input-conflict" || t.kind === "input-unbound") return Y(e, g, 409, "IdempotencyInputRefused", "Check the original operation before starting another action; this request cannot be matched safely.", {}, { ...v });
427
+ if (t.kind === "replay") try {
428
+ let n = t.response.status;
429
+ if (!Number.isInteger(n) || n < 200 || n > 599 || e.projection !== void 0 && n !== 200) throw Error("Invalid retained REST response status");
430
+ let r = await m.read(t.response), i = await L.runPromise(f(r.body)), a = h(U(r.body, {
431
+ status: n,
432
+ ...r.headers === void 0 ? {} : { headers: r.headers },
433
+ ...r.contentType === void 0 ? {} : { contentType: r.contentType }
434
+ }), i, g), o = {
435
+ ...v,
436
+ ...a.headers,
437
+ "Idempotency-Replayed": "true"
438
+ };
439
+ return H(e, n === 204 || n === 304 ? {
440
+ status: n,
441
+ headers: o
442
+ } : J(n, a.body, o, a.contentType));
443
+ } catch {
444
+ throw Error("Stored REST response is incompatible with the current output contract");
445
+ }
446
+ if (t.kind === "conflict") return Y(e, g, 409, "Conflict", "A request with this Idempotency-Key is already being processed", {}, { ...v });
447
+ }
448
+ let n = await e.handler(S, M);
449
+ if (I = !0, K(n) || q(n)) return D && F && await s(D.store, F), q(n) ? {
450
+ status: n.status ?? 200,
653
451
  headers: {
654
- ...p,
655
- ...e.headers
452
+ ...v,
453
+ ...n.headers
656
454
  },
657
- byteStream: e.byteStream,
658
- ...e.contentType === void 0 ? {} : { contentType: e.contentType }
455
+ byteStream: n.byteStream,
456
+ ...n.contentType === void 0 ? {} : { contentType: n.contentType }
659
457
  } : {
660
458
  status: 200,
661
- headers: p,
662
- stream: e.stream
459
+ headers: v,
460
+ stream: n.stream
663
461
  };
664
- let t = J(e) ? e : q(e), r = await x.runPromise(l(t.body)), o = a.method === "GET" && t.status === 200 ? fe(a.cache, d, r, _, v) : {}, s = {
665
- ...p,
666
- ...t.headers,
667
- ...o
462
+ let i = W(n) ? n : U(n), a = await L.runPromise(f(i.body)), u = h(i, a, g), d = u.body, p = e.method === "GET" && u.status === 200 ? ue(e.cache, g, d, S, C) : {}, _ = {
463
+ ...v,
464
+ ...u.headers,
465
+ ...p
668
466
  };
669
- if (w && T && await n(w.store, E, T, {
670
- status: t.status,
671
- body: r
672
- }, Date.now()), a.etag === !0 && a.method === "GET") {
673
- let e = `W/"${await ye(JSON.stringify(r))}"`, n = d.headers["if-none-match"];
674
- return n !== void 0 && n.split(",").some((t) => t.trim() === e) ? {
467
+ if (D && F && !await c(D.store, F, {
468
+ status: u.status,
469
+ ...await m.capture(i.body, i)
470
+ }, Date.now())) throw Error("Original idempotent response claim is no longer owned");
471
+ if (e.etag === !0 && e.method === "GET") {
472
+ let t = `W/"${await ge(JSON.stringify(d))}"`, n = g.headers["if-none-match"];
473
+ return n !== void 0 && n.split(",").some((e) => e.trim() === t) ? {
675
474
  status: 304,
676
475
  headers: {
476
+ ...v,
677
477
  ...p,
678
- ...o,
679
- ETag: e
478
+ ETag: t
680
479
  }
681
- } : K(a, Z(t.status, r, {
682
- ...s,
683
- ETag: e
684
- }, t.contentType));
480
+ } : H(e, J(u.status, d, {
481
+ ..._,
482
+ ETag: t
483
+ }, u.contentType));
685
484
  }
686
- return t.status === 204 || t.status === 304 ? K(a, {
687
- status: t.status,
688
- headers: s
689
- }) : K(a, Z(t.status, r, s, t.contentType));
690
- } catch (e) {
691
- return w && T && await i(w.store, E, T), K(a, De(e, v, a, p, d));
485
+ return u.status === 204 || u.status === 304 ? H(e, {
486
+ status: u.status,
487
+ headers: _
488
+ }) : H(e, J(u.status, d, _, u.contentType));
489
+ } catch (t) {
490
+ if (D && F && I) try {
491
+ await c(D.store, F, {
492
+ status: 500,
493
+ body: null
494
+ }, Date.now());
495
+ } catch {}
496
+ return H(e, $(I && F ? /* @__PURE__ */ Error("Idempotent response could not be retained") : t, C, e, v, g));
692
497
  } finally {
693
- D?.();
498
+ if (P?.(), D && F && !I) try {
499
+ await s(D.store, F);
500
+ } catch {}
501
+ }
502
+ }
503
+ };
504
+ return {
505
+ ...S,
506
+ handle: async (n) => {
507
+ let r = B(e.cors, n.headers.origin), i;
508
+ if (e.cors !== void 0 && n.method === "OPTIONS" && n.headers["access-control-request-method"] !== void 0 && n.headers["access-control-request-method"] === e.method) return V(e.cors, e.method, n.headers);
509
+ let a = n;
510
+ if (e.credentials === "bearer" && (n.method === e.method || n.method === "HEAD" && e.method === "GET")) {
511
+ let t = Object.fromEntries(Object.entries(n.headers).filter(([e]) => e.toLowerCase() !== "cookie"));
512
+ if (a = {
513
+ ...n,
514
+ headers: t
515
+ }, !/^Bearer\s+\S+$/i.test(t.authorization ?? "")) return Y(e, a, 401, "Unauthorized", "Bearer authentication required", {}, r);
516
+ }
517
+ try {
518
+ i = await S.handle(a);
519
+ } catch (n) {
520
+ i = $(n, t(null), e, v, a);
694
521
  }
522
+ let o = {
523
+ ...i.headers,
524
+ ...r
525
+ }, s = Object.entries(i.headers ?? {}).find(([e]) => e.toLowerCase() === "vary")?.[1];
526
+ if (s !== void 0 && e.cors !== void 0) {
527
+ for (let e of Object.keys(o)) e.toLowerCase() === "vary" && delete o[e];
528
+ o.vary = [...new Set(`${Array.isArray(s) ? s.join(", ") : s}, Origin`.split(",").map((e) => e.trim()))].join(", ");
529
+ }
530
+ return H(e, {
531
+ ...i,
532
+ headers: o
533
+ });
695
534
  }
696
535
  };
697
- }, ke = (e, t = {}) => {
536
+ }, Ce = (e, t = {}) => {
537
+ for (let n of e) {
538
+ if (n.rateLimit !== void 0 && t.rateLimit === void 0) throw Error(`REST route ${n.method} ${n.path} declares rateLimit but no rate-limit plugin is mounted`);
539
+ if (n.rateLimit !== void 0 && (!Number.isInteger(n.rateLimit.limit) || n.rateLimit.limit <= 0)) throw Error(`REST route ${n.method} ${n.path} rateLimit.limit must be a positive integer`);
540
+ }
698
541
  if (t.idempotency !== void 0) {
699
- for (let t of e) if (t.streaming === !0 && $.has(t.method)) throw Error(`REST route ${t.method} ${t.path} declares \`streaming: true\` on a method the idempotency binding claims (${[...$].join("/")}). A stream cannot complete an idempotency claim — there is no replayable body to cache — so a retried request would 409 until the claim's TTL. Either serve the stream on GET, or scope the idempotency binding away from this app's streaming routes.`);
542
+ for (let t of e) if (t.streaming === !0 && Q.has(t.method)) throw Error(`REST route ${t.method} ${t.path} declares \`streaming: true\` on a method the idempotency binding claims (${[...Q].join("/")}). A stream cannot complete an idempotency claim — there is no replayable body to cache — so a retried request would 409 until the claim's TTL. Either serve the stream on GET, or scope the idempotency binding away from this app's streaming routes.`);
700
543
  }
701
544
  let n = (e) => e.split("/").map((e) => e.startsWith(":") ? ":" : e).join("/"), r = /* @__PURE__ */ new Map();
702
545
  for (let t of e) {
703
546
  let e = r.get(n(t.path)) ?? [];
704
547
  e.includes(t.method) || e.push(t.method), r.set(n(t.path), e);
705
548
  }
706
- return e.map((e) => Oe(e, t, r.get(n(e.path)).join(", ")));
707
- }, Ae = async (e, t) => {
549
+ return e.map((e) => ({
550
+ ...Se(e, t, r.get(n(e.path)).join(", ")),
551
+ workload: "rest"
552
+ }));
553
+ }, we = async (e, t) => {
708
554
  let n = await e[0].handle(t);
709
555
  for (let r = 1; r < e.length && n.status === 405; r++) n = await e[r].handle(t);
710
556
  return n;
711
557
  };
712
558
  //#endregion
713
- export { g as JSONAPI_MEDIA_TYPE, f as PROBLEM_JSON, m as REST_PROFILE_NAMES, Y as RestRouteError, ve as bytes, I as coerceQueryObject, F as coerceQueryValue, ce as collectPublicApiRoutes, L as declaredErrorTags, me as defineRestRoute, E as derivePublicMethod, D as derivePublicPath, A as deriveResource, Ae as dispatchSharedPath, l as encodeRestError, a as encodeRestSuccess, V as errorMemberSchema, X as isRestByteResponse, J as isRestResponse, _e as isRestStreamResponse, we as matchPathParams, p as nextLink, j as normalizePathParams, ne as operationIdOf, M as pathParamNames, h as problemDetails, o as problemTypeOf, z as projectedFailure, U as publicApiRoute, W as publicSurfaceDigest, de as requireAnyScope, le as requireAuthenticated, ue as requireScope, d as resolveRestFormat, k as resourceIdField, q as response, pe as restError, ke as restRoutesToHttpRoutes, _ as restViewSchema, Te as routeAcceptsPath, he as sse, ge as sseFrame, s as toSnakeCase, oe as wireExample };
559
+ export { g as JSONAPI_MEDIA_TYPE, _ as PROBLEM_JSON, v as REST_PROFILE_NAMES, G as RestRouteError, he as bytes, O as coerceQueryObject, k as coerceQueryValue, A as collectPublicApiRoutes, d as declaredErrorTags, fe as defineRestRoute, j as derivePublicMethod, M as derivePublicPath, N as deriveResource, we as dispatchSharedPath, y as encodeRestError, b as encodeRestSuccess, f as errorMemberSchema, q as isRestByteResponse, W as isRestResponse, K as isRestStreamResponse, ye as matchPathParams, x as nextLink, P as normalizePathParams, F as operationIdOf, I as pathParamNames, S as problemDetails, C as problemTypeOf, ee as projectedFailure, te as publicApiRoute, ne as publicSurfaceDigest, le as requireAnyScope, se as requireAuthenticated, ce as requireScope, w as resolveRestFormat, re as resourceIdField, U as response, B as restCorsHeaders, V as restCorsPreflight, de as restError, Ce as restRoutesToHttpRoutes, T as restViewSchema, be as routeAcceptsPath, pe as sse, me as sseFrame, E as toSnakeCase, ie as wireExample };