@voltro/protocol 0.69.1 → 0.71.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.
package/dist/rest.js CHANGED
@@ -1,74 +1,100 @@
1
- import { F as e, P as t } from "./scopes-DVtiKKsm.js";
2
- import { c as n, l as r, o as i, s as a, t as o } from "./serverErrorBus-BTnTpMqj.js";
3
- import { Effect as s, Schema as c } from "effect";
4
- import * as l from "effect/SchemaAST";
1
+ import { F as e, I as t } from "./scopes-CW9_LbDO.js";
2
+ import { C as n, S as r, T as i, _ as a, a as o, c as s, d as c, f as l, i 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 } from "./restFormat-ChSVyufA.js";
3
+ import { Effect as b, ParseResult as x, Schema as S } from "effect";
4
+ import * as C from "effect/SchemaAST";
5
5
  //#region src/publicApi.ts
6
- var u = (e, t) => t.method ?? (e === "query" ? "GET" : "POST"), d = (e, t) => t.path ?? `/${t.version ?? "v1"}/${e.replace(/\./g, "/")}`, f = (e) => {
7
- if (l.isUnion(e)) {
8
- let t = e.types.filter((e) => !l.isUndefinedKeyword(e));
6
+ var w = (e, t, n) => t.method ?? (t.resource !== void 0 && n !== void 0 ? D("", t, n).method : void 0) ?? (e === "query" ? "GET" : "POST"), T = (e, t, n) => O(t.path ?? (t.resource !== void 0 && n !== void 0 ? D(e, t, n).path : `/${t.version ?? "v1"}/${e.replace(/\./g, "/")}`)), ee = (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
+ }, E = (e, t) => {
10
+ let n = t != null && (typeof t == "object" || typeof t == "function") && "ast" in t ? z(t) : void 0;
11
+ if (n === void 0) return;
12
+ let r = `${ee(e)}Id`;
13
+ return n.has(r) ? r : n.has("id") ? "id" : void 0;
14
+ }, D = (e, t, n) => {
15
+ let r = (t.resource ?? "").replace(/^\/+|\/+$/g, ""), i = `/${t.version ?? "v1"}/${r}`, a = E(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
+ }, O = (e) => e.replace(/\{([A-Za-z0-9_]+)\}/g, ":$1"), k = (e) => [...e.matchAll(/:([A-Za-z0-9_]+)/g)].map((e) => e[1]), A = (e) => {
33
+ if (C.isUnion(e)) {
34
+ let t = e.types.filter((e) => !C.isUndefinedKeyword(e));
9
35
  if (t.length === 1) return t[0];
10
- if (t.length !== e.types.length) return l.Union.make(t);
36
+ if (t.length !== e.types.length) return C.Union.make(t);
11
37
  }
12
38
  return e;
13
- }, p = /^-?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?$/i, m = (e, t) => {
14
- let n = f(t);
15
- if (l.isRefinement(n) || l.isTransformation(n)) return m(e, n.from);
16
- if (l.isUnion(n)) {
39
+ }, j = /^-?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?$/i, M = (e, t) => {
40
+ let n = A(t);
41
+ if (C.isRefinement(n) || C.isTransformation(n)) return M(e, n.from);
42
+ if (C.isUnion(n)) {
17
43
  for (let t of n.types) {
18
- let n = m(e, t);
44
+ let n = M(e, t);
19
45
  if (n !== e) return n;
20
46
  }
21
47
  return e;
22
48
  }
23
- if (l.isTupleType(n)) {
49
+ if (C.isTupleType(n)) {
24
50
  let t = Array.isArray(e) ? e : e === void 0 ? void 0 : [e];
25
51
  if (t === void 0) return e;
26
52
  let r = n.rest[0]?.type ?? n.elements[0]?.type;
27
- return r === void 0 ? t : t.map((e) => m(e, r));
53
+ return r === void 0 ? t : t.map((e) => M(e, r));
28
54
  }
29
55
  if (typeof e != "string") return e;
30
- if (l.isNumberKeyword(n)) return p.test(e.trim()) ? Number(e) : e;
31
- if (l.isBooleanKeyword(n)) return e === "true" || e !== "false" && e;
32
- if (l.isLiteral(n)) {
56
+ if (C.isNumberKeyword(n)) return j.test(e.trim()) ? Number(e) : e;
57
+ if (C.isBooleanKeyword(n)) return e === "true" || e !== "false" && e;
58
+ if (C.isLiteral(n)) {
33
59
  let t = n.literal;
34
- return typeof t == "number" && p.test(e.trim()) && Number(e) === t || typeof t == "boolean" && String(t) === e ? t : e;
60
+ return typeof t == "number" && j.test(e.trim()) && Number(e) === t || typeof t == "boolean" && String(t) === e ? t : e;
35
61
  }
36
62
  return e;
37
- }, h = (e, t) => {
63
+ }, N = (e, t) => {
38
64
  if (typeof e != "object" || !e || Array.isArray(e)) return e;
39
- let n = f(l.encodedAST(t.ast));
40
- if (!l.isTypeLiteral(n)) return e;
65
+ let n = A(C.encodedAST(t.ast));
66
+ if (!C.isTypeLiteral(n)) return e;
41
67
  let r = { ...e };
42
68
  for (let e of n.propertySignatures) {
43
69
  let t = String(e.name);
44
- t in r && (r[t] = m(r[t], e.type));
70
+ t in r && (r[t] = M(r[t], e.type));
45
71
  }
46
72
  return r;
47
- }, g = (e) => {
73
+ }, P = (e) => {
48
74
  let t = /* @__PURE__ */ new Set();
49
75
  if (e === void 0) return t;
50
76
  let n = (e) => {
51
- if (l.isUnion(e)) {
77
+ if (C.isUnion(e)) {
52
78
  for (let t of e.types) n(t);
53
79
  return;
54
80
  }
55
- if (l.isTransformation(e)) {
81
+ if (C.isTransformation(e)) {
56
82
  n(e.from), n(e.to);
57
83
  return;
58
84
  }
59
- if (l.isRefinement(e)) {
85
+ if (C.isRefinement(e)) {
60
86
  n(e.from);
61
87
  return;
62
88
  }
63
- if (l.isTypeLiteral(e)) {
89
+ if (C.isTypeLiteral(e)) {
64
90
  let n = e.propertySignatures.find((e) => e.name === "_tag");
65
- n !== void 0 && l.isLiteral(n.type) && typeof n.type.literal == "string" && t.add(n.type.literal);
91
+ n !== void 0 && C.isLiteral(n.type) && typeof n.type.literal == "string" && t.add(n.type.literal);
66
92
  }
67
93
  };
68
94
  return n(e.ast), t;
69
- }, _ = (e, t, n) => {
95
+ }, F = (e, t, n) => {
70
96
  if (n !== void 0) try {
71
- let r = c.encodeUnknownSync(n)(e);
97
+ let r = S.encodeUnknownSync(n)(e);
72
98
  if (typeof r == "object" && r) return {
73
99
  error: t,
74
100
  ...r
@@ -77,69 +103,224 @@ var u = (e, t) => t.method ?? (e === "query" ? "GET" : "POST"), d = (e, t) => t.
77
103
  let r = { error: t };
78
104
  for (let [t, n] of Object.entries(e)) t !== "stack" && t !== "_tag" && (r[t] = n);
79
105
  return r;
80
- }, v = (e, t, n) => {
106
+ }, I = (e, t, n, r = []) => {
81
107
  if (typeof e != "object" || !e) return e;
82
- let r = e._tag;
83
- return typeof r != "string" || r === "ScopeError" || !g(t.error).has(r) ? e : new E(n.errorStatus?.[r] ?? 422, _(e, r, t.error));
84
- }, y = (e, t, n) => {
85
- let r = e.publicApi;
86
- if (r === void 0) throw Error(`publicApiRoute: descriptor '${e.name}' has no publicApi annotation`);
87
- let i = u(e.kind, r), a = d(e.name, r), o = i === "GET" ? "query" : "body", s = c.Struct({ [o]: e.input }), l = i === "GET" ? c.transform(c.Struct({ query: c.Unknown }), s, {
108
+ let i = e._tag;
109
+ if (typeof i != "string" || i === "ScopeError") return e;
110
+ if (P(t.error).has(i)) return new Y(n.errorStatus?.[i] ?? 422, F(e, i, t.error));
111
+ let a = r.find((e) => P(e.schema).has(i));
112
+ if (a === void 0) return e;
113
+ let o = n.errorStatus?.[i] ?? a.rest?.status ?? 422, s = a.rest?.headers?.(e);
114
+ return new Y(o, F(e, i, a.schema), s);
115
+ }, te = (e, t, n, r, i, a) => {
116
+ let o = I(e, t, n, r);
117
+ if (!(o instanceof Y) || i.errors === "tagged" && i.encodeError === void 0) return o;
118
+ let { error: s, _tag: c, ...l } = o.body, d = typeof l.message == "string" ? l.message : typeof l.reason == "string" ? l.reason : "", f = u(i, {
119
+ status: o.status,
120
+ tag: s,
121
+ message: d,
122
+ fields: l
123
+ }, {
124
+ ...a,
125
+ status: o.status
126
+ });
127
+ return new Y(o.status, f.body, {
128
+ ...o.headers ?? {},
129
+ ...f.headers ?? {}
130
+ }, f.contentType);
131
+ }, L = (e, t) => {
132
+ if (e === void 0) return;
133
+ let n = C.isUnion(e.ast) ? e.ast.types : [e.ast];
134
+ for (let e of n) {
135
+ let n = S.make(e);
136
+ if (P(n).has(t)) return n;
137
+ }
138
+ }, R = (e) => e.split(".").map((e, t) => t === 0 ? e : e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_"), z = (e) => {
139
+ let t = A(C.encodedAST(e.ast));
140
+ return C.isTypeLiteral(t) && t.indexSignatures.length === 0 ? new Set(t.propertySignatures.map((e) => String(e.name))) : void 0;
141
+ }, ne = (e, t) => e === t || JSON.stringify(e) === JSON.stringify(t), re = (e, t) => {
142
+ let n = A(C.encodedAST(t.ast)), r = {}, i = C.isTypeLiteral(n) ? new Map(n.propertySignatures.map((e) => [String(e.name), e.type])) : /* @__PURE__ */ new Map();
143
+ for (let [t, n] of Object.entries(e)) {
144
+ let e = i.get(t);
145
+ r[t] = e === void 0 ? n : M(n, e);
146
+ }
147
+ return r;
148
+ }, B = (e, t) => {
149
+ if (e !== void 0) {
150
+ try {
151
+ return S.encodeUnknownSync(t)(e);
152
+ } catch {}
153
+ try {
154
+ return S.decodeUnknownSync(t)(e), e;
155
+ } catch {}
156
+ return e;
157
+ }
158
+ }, ie = (e, t, n) => ({
159
+ ...e.request === void 0 ? {} : { request: B(e.request, t) },
160
+ ...e.response === void 0 ? {} : { response: B(e.response, n) }
161
+ }), ae = () => (e) => {
162
+ if (e.subject.type !== "anonymous") return;
163
+ let t = e.subject.credentialRejected;
164
+ return t === void 0 ? void 0 : {
165
+ status: 401,
166
+ message: t
167
+ };
168
+ }, V = (e, t, n, r = {}) => {
169
+ let i = e.publicApi;
170
+ if (i === void 0) throw Error(`publicApiRoute: descriptor '${e.name}' has no publicApi annotation`);
171
+ let a = d(r.profile, i.format), s = r.pluginErrors ?? [], l = {
172
+ kind: e.kind,
173
+ input: e.input,
174
+ target: e.target
175
+ }, u = w(e.kind, i, l), f = (e) => a.naming === "snake_case" ? c(e) : e, p = T(e.name, i, l), m = p.replace(/:([A-Za-z0-9_]+)/g, (e, t) => `:${f(t)}`), h = k(m), g = _(e.input, a), v = z(g);
176
+ if (v !== void 0) {
177
+ for (let t of h) if (!v.has(t)) throw Error(`publicApi: descriptor '${e.name}' — path '${p}' binds ':${t}', and the input declares no field of that name` + (v.size > 0 ? ` (fields: ${[...v].join(", ")})` : " (the input declares no fields)"));
178
+ }
179
+ let y = _(e.output, a), C = S.Struct({ value: g }), ee = u !== "GET" && (v === void 0 || [...v].some((e) => !h.includes(e))), E = {
180
+ query: S.Unknown,
181
+ params: S.Unknown,
182
+ form: S.Boolean
183
+ }, D = ee ? S.Struct({
184
+ ...E,
185
+ body: S.Unknown
186
+ }) : S.Struct(E), O = S.transformOrFail(D, C, {
88
187
  strict: !1,
89
- decode: (t) => ({ query: h(t.query, e.input) }),
90
- encode: (e) => e
91
- }) : s, f = [...e.openAccess === void 0 ? [x()] : [], ...(r.scopes ?? []).map((e) => S(e))], p = r.stream === "sse" && e.kind === "query" && n !== void 0, m = p ? (e, t) => k((r) => n(e[o], t, (e) => {
92
- r(A(String(e._tag ?? "message"), e));
93
- })) : async (n, i) => {
188
+ decode: (e, t, n) => {
189
+ let r = "body" in e ? e.body : void 0, i = u === "GET" ? N(e.query, g) : e.form ? N(r ?? {}, g) : r ?? {}, a = typeof e.params == "object" && e.params !== null ? re(e.params, g) : {};
190
+ if (typeof i != "object" || !i || Array.isArray(i)) return x.succeed({ value: i });
191
+ let o = i, s = Object.keys(a).filter((e) => e in o && !ne(o[e], a[e]));
192
+ if (s.length > 0) {
193
+ let t = u === "GET" ? "query string" : "body";
194
+ return x.fail(new x.Type(n, e, `${s.map((e) => `'${e}'`).join(", ")} ${s.length === 1 ? "is" : "are"} bound by the path and sent with another value in the ${t}`));
195
+ }
196
+ return x.succeed({ value: {
197
+ ...o,
198
+ ...a
199
+ } });
200
+ },
201
+ encode: (e) => x.succeed(e)
202
+ }), A = [
203
+ ae(),
204
+ ...e.openAccess === void 0 ? [W()] : [],
205
+ ...(i.scopes ?? []).map((e) => G(e))
206
+ ], j = (() => {
207
+ let t = e.source;
208
+ return typeof t == "string" ? t : Array.isArray(t) ? t[0] : void 0;
209
+ })(), M = (t, n = 200) => ({
210
+ tag: e.name,
211
+ method: t.method,
212
+ path: t.path,
213
+ query: t.query,
214
+ source: j,
215
+ status: n
216
+ }), F = i.stream === "sse" && e.kind === "query" && n !== void 0, I = S.encodeUnknown(y), B = F ? (e, t) => ce((r) => n(e.value, t, (e) => {
217
+ r(le(String(e._tag ?? "message"), e));
218
+ })) : async (n, r) => {
219
+ let c;
94
220
  try {
95
- return await t(n[o], i);
221
+ c = await t(n.value, r);
96
222
  } catch (t) {
97
- throw v(t, e, r);
223
+ throw te(t, e, i, s, a, M(r));
98
224
  }
225
+ let l = await b.runPromise(I(c)), u = o(a, l, M(r));
226
+ return q(u.body, {
227
+ ...u.headers === void 0 ? {} : { headers: u.headers },
228
+ ...u.contentType === void 0 ? {} : { contentType: u.contentType }
229
+ });
230
+ }, V = e.error, H = [...P(V)], U = [];
231
+ for (let e of H) {
232
+ let t = L(V, e);
233
+ t !== void 0 && U.push({
234
+ status: i.errorStatus?.[e] ?? 422,
235
+ tag: e,
236
+ schema: t
237
+ });
238
+ }
239
+ for (let e of s) for (let t of P(e.schema)) {
240
+ if (H.includes(t)) continue;
241
+ let n = i.errorStatus?.[t] ?? e.rest?.status;
242
+ if (n === void 0) continue;
243
+ let r = L(e.schema, t) ?? e.schema;
244
+ U.push({
245
+ status: n,
246
+ tag: t,
247
+ schema: r
248
+ });
249
+ }
250
+ let K = i.security === !1 ? "none" : i.security ?? (e.openAccess === void 0 ? "required" : "optional"), J = {
251
+ tag: e.name,
252
+ kind: e.kind,
253
+ version: i.version ?? "v1",
254
+ security: K,
255
+ idempotent: i.idempotent === !0,
256
+ input: g,
257
+ pathParams: h,
258
+ output: y,
259
+ source: j,
260
+ errorResponses: U,
261
+ format: a
99
262
  };
100
- return O({
101
- method: i,
102
- path: a,
103
- input: l,
104
- output: e.output,
105
- handler: m,
106
- ...p ? { streaming: !0 } : {},
107
- guards: f,
108
- ...r.summary === void 0 ? {} : { summary: r.summary },
109
- ...r.description === void 0 ? {} : { description: r.description },
110
- ...r.deprecated === void 0 ? {} : { deprecated: r.deprecated },
111
- ...r.sunset === void 0 ? {} : { sunset: r.sunset }
263
+ return se({
264
+ method: u,
265
+ path: m,
266
+ input: O,
267
+ output: S.Unknown,
268
+ handler: B,
269
+ ...F ? { streaming: !0 } : {},
270
+ guards: A,
271
+ operationId: i.operationId ?? R(e.name),
272
+ tags: i.tags ?? [e.name.split(".")[0] ?? e.name],
273
+ projection: J,
274
+ ...a.etag && u === "GET" && !F ? { etag: !0 } : {},
275
+ ...i.example === void 0 ? {} : { example: ie(i.example, g, y) },
276
+ ...i.summary === void 0 ? {} : { summary: i.summary },
277
+ ...i.description === void 0 ? {} : { description: i.description },
278
+ ...i.deprecated === void 0 ? {} : { deprecated: i.deprecated },
279
+ ...i.sunset === void 0 ? {} : { sunset: i.sunset }
112
280
  });
113
- }, b = (e) => e.filter((e) => e.descriptor.publicApi !== void 0).map((e) => y(e.descriptor, e.invoke, e.subscribe)).sort((e, t) => e.path.localeCompare(t.path)), x = () => (e) => {
281
+ }, H = (e, t = {}) => e.filter((e) => e.descriptor.publicApi !== void 0).map((e) => V(e.descriptor, e.invoke, e.subscribe, t)).sort((e, t) => e.path.localeCompare(t.path)), U = (e) => v(e.filter((e) => e.projection !== void 0).map((e) => {
282
+ let t = e.projection, n = {
283
+ tag: t.tag,
284
+ method: e.method,
285
+ path: e.path,
286
+ pathParams: t.pathParams,
287
+ version: t.version,
288
+ security: t.security,
289
+ errors: [...t.errorResponses].map((e) => `${e.status}:${e.tag}`).sort()
290
+ };
291
+ return `${JSON.stringify(n)} ${a(t.input.ast)} ${a(t.output.ast)}`;
292
+ }).sort().join("\n")), W = () => (e) => {
114
293
  if (e.subject.type === "anonymous") return {
115
294
  status: 401,
116
295
  message: e.subject.credentialRejected ?? "Authentication required"
117
296
  };
118
- }, S = (e) => (t) => {
297
+ }, G = (e) => (t) => {
119
298
  let n = t.subject.scopes;
120
299
  if (!(n && (n.includes(e) || n.includes("admin:full")))) return {
121
300
  status: 403,
122
301
  message: `Missing required scope: ${e}`
123
302
  };
124
- }, C = (e) => (t) => {
303
+ }, K = (e) => (t) => {
125
304
  let n = t.subject.scopes;
126
305
  if (!(n && (n.includes("admin:full") || e.some((e) => n.includes(e))))) return {
127
306
  status: 403,
128
307
  message: `Missing required scope: one of ${e.join(", ")}`
129
308
  };
130
- }, w = (e, t = {}) => ({
309
+ }, q = (e, t = {}) => ({
131
310
  __voltroRestResponse: !0,
132
311
  status: t.status ?? 200,
133
312
  body: e,
134
- ...t.headers === void 0 ? {} : { headers: t.headers }
135
- }), T = (e) => typeof e == "object" && !!e && e.__voltroRestResponse === !0, E = class extends Error {
313
+ ...t.headers === void 0 ? {} : { headers: t.headers },
314
+ ...t.contentType === void 0 ? {} : { contentType: t.contentType }
315
+ }), J = (e) => typeof e == "object" && !!e && e.__voltroRestResponse === !0, Y = class extends Error {
136
316
  status;
137
317
  body;
138
318
  headers;
139
- constructor(e, t, n) {
140
- super(`REST ${e}`), this.name = "RestRouteError", this.status = e, this.body = t, this.headers = n;
319
+ contentType;
320
+ constructor(e, t, n, r) {
321
+ super(`REST ${e}`), this.name = "RestRouteError", this.status = e, this.body = t, this.headers = n, this.contentType = r;
141
322
  }
142
- }, D = (e, t, n) => new E(e, t, n), O = (e) => {
323
+ }, oe = (e, t, n) => new Y(e, t, n), se = (e) => {
143
324
  if (e.version === void 0) return e;
144
325
  if (!/^v\d+$/.test(e.version)) throw Error(`defineRestRoute(${e.method} ${e.path}): version "${e.version}" must be 'v' followed by digits — 'v1', 'v2', …`);
145
326
  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.`);
@@ -147,13 +328,13 @@ var u = (e, t) => t.method ?? (e === "query" ? "GET" : "POST"), d = (e, t) => t.
147
328
  ...e,
148
329
  path: `/${e.version}${e.path}`
149
330
  };
150
- }, k = (e, t = {}) => ({
331
+ }, ce = (e, t = {}) => ({
151
332
  __voltroRestStream: !0,
152
333
  stream: {
153
334
  subscribe: e,
154
335
  ...t.keepAliveMs === void 0 ? {} : { keepAliveMs: t.keepAliveMs }
155
336
  }
156
- }), A = (e, t) => `event: ${e}\n${(typeof t == "string" ? t : JSON.stringify(t)).split("\n").map((e) => `data: ${e}`).join("\n")}\n\n`, j = (e) => typeof e == "object" && !!e && e.__voltroRestStream === !0, M = (e, t = {}) => ({
337
+ }), le = (e, t) => `event: ${e}\n${(typeof t == "string" ? t : JSON.stringify(t)).split("\n").map((e) => `data: ${e}`).join("\n")}\n\n`, ue = (e) => typeof e == "object" && !!e && e.__voltroRestStream === !0, de = (e, t = {}) => ({
157
338
  __voltroRestBytes: !0,
158
339
  byteStream: {
159
340
  stream: e,
@@ -163,26 +344,60 @@ var u = (e, t) => t.method ?? (e === "query" ? "GET" : "POST"), d = (e, t) => t.
163
344
  ...t.contentType === void 0 ? {} : { contentType: t.contentType },
164
345
  ...t.status === void 0 ? {} : { status: t.status },
165
346
  ...t.headers === void 0 ? {} : { headers: t.headers }
166
- }), N = (e) => typeof e == "object" && !!e && e.__voltroRestBytes === !0, P = async (e) => {
347
+ }), X = (e) => typeof e == "object" && !!e && e.__voltroRestBytes === !0, fe = async (e) => {
167
348
  let t = await globalThis.crypto.subtle.digest("SHA-1", new TextEncoder().encode(e));
168
349
  return [...new Uint8Array(t)].map((e) => e.toString(16).padStart(2, "0")).join("");
169
- }, F = (e, t, n) => ({
350
+ }, Z = (e, t, n, r = "application/json; charset=utf-8") => ({
170
351
  status: e,
171
- contentType: "application/json; charset=utf-8",
352
+ contentType: r,
172
353
  body: JSON.stringify(t),
173
354
  ...n ? { headers: n } : {}
174
- }), I = (e) => {
355
+ }), Q = (e, t, n, r, i, a, o) => {
356
+ let s = e.projection;
357
+ if (s === void 0) return Z(n, {
358
+ error: i,
359
+ ...a
360
+ }, o);
361
+ let c = {
362
+ tag: s.tag,
363
+ method: t.method,
364
+ path: t.path,
365
+ query: t.query,
366
+ source: s.source,
367
+ status: n
368
+ }, l = u(s.format, {
369
+ status: n,
370
+ tag: r,
371
+ message: i,
372
+ fields: a
373
+ }, c);
374
+ return Z(n, l.body, {
375
+ ...o,
376
+ ...l.headers ?? {}
377
+ }, l.contentType);
378
+ }, pe = (e) => (e.headers["content-type"] ?? "application/json").split(";")[0].trim().toLowerCase(), me = (e, t) => {
175
379
  if (e.length === 0) return;
176
- let t = new TextDecoder().decode(e);
177
- if (t.trim() !== "") return JSON.parse(t);
178
- }, L = (e) => {
179
- let t = {};
180
- for (let [n, r] of new URLSearchParams(e)) {
181
- let e = t[n];
182
- e === void 0 ? t[n] = r : Array.isArray(e) ? e.push(r) : t[n] = [e, r];
380
+ let n = t === "application/x-www-form-urlencoded";
381
+ if (!n && t !== "application/json" && !/^application\/[^/;\s]+\+json$/.test(t)) return;
382
+ let r = new TextDecoder("utf-8", { fatal: !0 }).decode(e);
383
+ if (r.trim() !== "") {
384
+ if (n) {
385
+ let e = (e) => decodeURIComponent(e.replace(/\+/g, " "));
386
+ return ge(r.split("&").filter(Boolean).map((t) => {
387
+ let n = t.indexOf("=");
388
+ return n < 0 ? [e(t), ""] : [e(t.slice(0, n)), e(t.slice(n + 1))];
389
+ }));
390
+ }
391
+ return JSON.parse(r);
392
+ }
393
+ }, he = (e) => ge(new URLSearchParams(e)), ge = (e) => {
394
+ let t = /* @__PURE__ */ new Map();
395
+ for (let [n, r] of e) {
396
+ let e = t.get(n);
397
+ e === void 0 ? t.set(n, r) : Array.isArray(e) ? e.push(r) : t.set(n, [e, r]);
183
398
  }
184
- return t;
185
- }, R = (e, t) => {
399
+ return Object.fromEntries(t);
400
+ }, _e = (e, t) => {
186
401
  let n = e.split("/").filter((e) => e.length > 0), r = t.split("/").filter((e) => e.length > 0), i = {};
187
402
  for (let e = 0; e < n.length; e++) {
188
403
  let t = n[e];
@@ -196,163 +411,182 @@ var u = (e, t) => t.method ?? (e === "query" ? "GET" : "POST"), d = (e, t) => t.
196
411
  }
197
412
  }
198
413
  return i;
199
- }, z = (e, t) => ({
200
- query: L(e.query),
414
+ }, ve = (e, t) => {
415
+ let n = e.path.split("/"), r = n[n.length - 1] === "*", i = r ? n.slice(0, -1) : n, a = t.split("/");
416
+ if (a.length < i.length) return !1;
417
+ for (let e = 0; e < i.length; e++) {
418
+ let t = i[e], n = a[e];
419
+ if (t.startsWith(":")) {
420
+ if (n.length === 0) return !1;
421
+ } else if (t !== n) return !1;
422
+ }
423
+ return a.length === i.length ? !0 : e.match === "exact" && !r ? !1 : a.slice(i.length).some((e) => e.length > 0);
424
+ }, ye = (e, t, n) => ({
425
+ query: he(e.query),
201
426
  params: t,
202
- body: I(e.rawBody)
203
- }), B = /* @__PURE__ */ new Set([
427
+ body: n ? me(e.rawBody, pe(e)) : void 0,
428
+ form: pe(e) === "application/x-www-form-urlencoded"
429
+ }), $ = /* @__PURE__ */ new Set([
204
430
  "POST",
205
431
  "PUT",
206
432
  "PATCH",
207
433
  "DELETE"
208
- ]), V = (e, n, r, i) => {
209
- if (e instanceof E) return F(e.status, e.body, {
434
+ ]), be = (t, n, r, i, a) => {
435
+ if (t instanceof Y) return Z(t.status, t.body, {
210
436
  ...i,
211
- ...e.headers
212
- });
213
- if (typeof e == "object" && e) {
214
- let r = e;
215
- if (typeof r.status == "number") return F(r.status, { error: typeof r.message == "string" ? r.message : "Error" }, i);
216
- if (r._tag === "Unauthenticated" || e instanceof t) return F(401, { error: typeof r.reason == "string" ? r.reason : "Authentication required" }, i);
217
- if (r._tag === "ScopeError") return F(n.type === "anonymous" ? 401 : 403, { error: typeof r.message == "string" ? r.message : "Forbidden" }, i);
437
+ ...t.headers
438
+ }, t.contentType);
439
+ if (typeof t == "object" && t) {
440
+ let o = t;
441
+ 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 });
442
+ if (o._tag === "Unauthenticated" || t instanceof e) return Q(r, a, 401, "Unauthorized", typeof o.reason == "string" ? o.reason : "Authentication required", {}, { ...i });
443
+ if (o._tag === "ScopeError") {
444
+ let e = n.type === "anonymous" ? 401 : 403;
445
+ return Q(r, a, e, e === 401 ? "Unauthorized" : "Forbidden", typeof o.message == "string" ? o.message : "Forbidden", {}, { ...i });
446
+ }
218
447
  }
219
- return o({
220
- error: e,
448
+ return l({
449
+ error: t,
221
450
  source: "rest",
222
451
  name: `${r.method} ${r.path}`,
223
452
  fields: { status: 500 }
224
- }), F(500, { error: "Internal Server Error" }, i);
225
- }, H = (o, l) => {
226
- let u = o.input ? c.decodeUnknown(o.input) : void 0, d = c.encode(o.output), f = {}, p = (e) => e.replace(/\/$/, "").split("/").length, m = p(o.path);
227
- return o.deprecated !== void 0 && (f.Deprecation = "true"), o.sunset !== void 0 && (f.Sunset = o.sunset), {
453
+ }), {
454
+ ...Q(r, a, 500, "InternalServerError", "Internal Server Error", {}, { ...i }),
455
+ cause: t
456
+ };
457
+ }, xe = (a, o) => {
458
+ let s = a.input ? S.decodeUnknown(a.input) : void 0, c = S.encode(a.output), l = a.input === void 0 ? void 0 : C.encodedAST(a.input.ast), u = l !== void 0 && (!C.isTypeLiteral(l) || l.indexSignatures.length > 0 || l.propertySignatures.some((e) => e.name === "body")), d = {};
459
+ a.projection !== void 0 && (d["x-voltro-rest-profile"] = a.projection.format.name);
460
+ let f = (e) => e.replace(/\/$/, "").split("/").length, p = f(a.path);
461
+ return a.deprecated !== void 0 && (d.Deprecation = "true"), a.sunset !== void 0 && (d.Sunset = a.sunset), {
228
462
  method: "*",
229
- path: o.path,
230
- ...o.maxBodyBytes === void 0 ? {} : { maxBodyBytes: o.maxBodyBytes },
231
- handle: async (c) => {
232
- if (!o.path.endsWith("/*") && p(c.path) !== m) return F(404, { error: "Not Found" }, f);
233
- let h = c.method.toUpperCase();
234
- if (!(h === o.method || h === "HEAD" && o.method === "GET")) return F(405, {
235
- error: "Method Not Allowed",
236
- allow: o.method
237
- }, {
238
- ...f,
239
- Allow: o.method
463
+ path: a.path,
464
+ match: a.path.endsWith("/*") ? "prefix" : "exact",
465
+ ...a.maxBodyBytes === void 0 ? {} : { maxBodyBytes: a.maxBodyBytes },
466
+ handle: async (l) => {
467
+ if (!a.path.endsWith("/*") && f(l.path) !== p) return Q(a, l, 404, "NotFound", "Not Found", {}, { ...d });
468
+ let m = l.method.toUpperCase();
469
+ if (!(m === a.method || m === "HEAD" && a.method === "GET")) return Q(a, l, 405, "MethodNotAllowed", "Method Not Allowed", { allow: a.method }, {
470
+ ...d,
471
+ Allow: a.method
240
472
  });
241
- if (o.sunset !== void 0) {
242
- let e = Date.parse(o.sunset);
243
- if (!Number.isNaN(e) && Date.now() >= e) return F(410, {
244
- error: "Gone",
245
- ...o.version === void 0 ? {} : { version: o.version },
246
- ...o.deprecated === void 0 ? {} : { replacement: o.deprecated }
247
- }, f);
473
+ if (a.sunset !== void 0) {
474
+ let e = Date.parse(a.sunset);
475
+ if (!Number.isNaN(e) && Date.now() >= e) return Q(a, l, 410, "Gone", "Gone", {
476
+ ...a.version === void 0 ? {} : { version: a.version },
477
+ ...a.deprecated === void 0 ? {} : { replacement: a.deprecated }
478
+ }, { ...d });
248
479
  }
249
- let g;
250
- if (u) {
251
- let e = z(c, R(o.path, c.path)), t = await s.runPromise(u(e).pipe(s.map((e) => ({
480
+ let h;
481
+ if (s) {
482
+ let e;
483
+ try {
484
+ e = ye(l, _e(a.path, l.path), u);
485
+ } catch {
486
+ return Q(a, l, 400, "InvalidRequest", "Malformed request body", {}, { ...d });
487
+ }
488
+ let t = await b.runPromise(s(e).pipe(b.map((e) => ({
252
489
  ok: !0,
253
490
  value: e
254
- })), s.catchAll((e) => s.succeed({
491
+ })), b.catchAll((e) => b.succeed({
255
492
  ok: !1,
256
493
  cause: e
257
494
  }))));
258
- if (!t.ok) return F(400, {
259
- error: "Invalid request",
260
- detail: String(t.cause)
261
- }, f);
262
- g = t.value;
495
+ if (!t.ok) return Q(a, l, 400, "InvalidRequest", "Invalid request", { detail: String(t.cause) }, { ...d });
496
+ h = t.value;
263
497
  }
264
- let _;
498
+ let g;
265
499
  try {
266
- _ = l.resolveSubject ? await l.resolveSubject(c.headers) : e(c.headers["x-tenant"] ?? null);
267
- } catch (e) {
268
- if (e instanceof t || typeof e == "object" && e && e._tag === "Unauthenticated") {
269
- let t = e.reason;
270
- return F(401, { error: t ?? "Authentication required" }, f);
500
+ g = o.resolveSubject ? await o.resolveSubject(l.headers) : t(l.headers["x-tenant"] ?? null);
501
+ } catch (t) {
502
+ if (t instanceof e || typeof t == "object" && t && t._tag === "Unauthenticated") {
503
+ let e = t.reason;
504
+ return Q(a, l, 401, "Unauthorized", e ?? "Authentication required", {}, { ...d });
271
505
  }
272
- throw e;
506
+ throw t;
273
507
  }
274
- let v;
508
+ let _;
275
509
  try {
276
- v = l.buildContext ? await l.buildContext(_, c.headers) : void 0;
510
+ _ = o.buildContext ? await o.buildContext(g, l.headers) : void 0;
277
511
  } catch (e) {
278
- return V(e, _, o, f);
512
+ return be(e, g, a, d, l);
279
513
  }
280
- let y = typeof v == "object" && v && "store" in v ? v.store : l.store, b = {
281
- subject: _,
282
- headers: c.headers,
283
- store: y,
284
- method: h,
285
- path: c.path,
286
- query: c.query,
287
- rawBody: c.rawBody,
288
- ...v === void 0 ? {} : { app: v }
514
+ let v = typeof _ == "object" && _ && "store" in _ ? _.store : o.store, x = {
515
+ subject: g,
516
+ headers: l.headers,
517
+ store: v,
518
+ method: m,
519
+ path: l.path,
520
+ query: l.query,
521
+ rawBody: l.rawBody,
522
+ ..._ === void 0 ? {} : { app: _ }
289
523
  };
290
- if (o.guards) for (let e of o.guards) {
291
- let t = await e(b);
292
- if (t) return F(t.status, { error: t.message }, f);
524
+ if (a.guards) for (let e of a.guards) {
525
+ let t = await e(x);
526
+ if (t) return Q(a, l, t.status, t.status === 401 ? "Unauthorized" : t.status === 403 ? "Forbidden" : "GuardRejected", t.message, {}, { ...d });
293
527
  }
294
- let x = l.idempotency, S = x && B.has(o.method) ? c.headers[x.header.toLowerCase()] : void 0, C = x && S ? r(_.tenantId, o.method, o.path) : "";
295
- if (x && S) {
296
- let e = await i(x.store, C, S, x.ttlMs, Date.now());
297
- if (e.kind === "replay") return F(e.response.status, e.response.body, {
298
- ...f,
528
+ let S = o.idempotency, C = S && $.has(a.method) ? l.headers[S.header.toLowerCase()] : void 0, w = S && C ? i(g.tenantId, a.method, a.path) : "";
529
+ if (S && C) {
530
+ let e = await r(S.store, w, C, S.ttlMs, Date.now());
531
+ if (e.kind === "replay") return Z(e.response.status, e.response.body, {
532
+ ...d,
299
533
  "Idempotency-Replayed": "true"
300
534
  });
301
- if (e.kind === "conflict") return F(409, { error: "A request with this Idempotency-Key is already being processed" }, f);
535
+ if (e.kind === "conflict") return Q(a, l, 409, "Conflict", "A request with this Idempotency-Key is already being processed", {}, { ...d });
302
536
  }
303
537
  try {
304
- let e = await o.handler(g, b);
305
- if (j(e) || N(e)) return x && S && await a(x.store, C, S), N(e) ? {
538
+ let e = await a.handler(h, x);
539
+ if (ue(e) || X(e)) return S && C && await n(S.store, w, C), X(e) ? {
306
540
  status: e.status ?? 200,
307
541
  headers: {
308
- ...f,
542
+ ...d,
309
543
  ...e.headers
310
544
  },
311
545
  byteStream: e.byteStream,
312
546
  ...e.contentType === void 0 ? {} : { contentType: e.contentType }
313
547
  } : {
314
548
  status: 200,
315
- headers: f,
549
+ headers: d,
316
550
  stream: e.stream
317
551
  };
318
- let t = T(e) ? e : w(e), r = await s.runPromise(d(t.body)), i = {
319
- ...f,
552
+ let t = J(e) ? e : q(e), r = await b.runPromise(c(t.body)), i = {
553
+ ...d,
320
554
  ...t.headers
321
555
  };
322
- if (x && S && await n(x.store, C, S, {
556
+ if (S && C && await y(S.store, w, C, {
323
557
  status: t.status,
324
558
  body: r
325
- }, Date.now()), o.etag === !0 && o.method === "GET") {
326
- let e = `W/"${await P(JSON.stringify(r))}"`, n = c.headers["if-none-match"];
559
+ }, Date.now()), a.etag === !0 && a.method === "GET") {
560
+ let e = `W/"${await fe(JSON.stringify(r))}"`, n = l.headers["if-none-match"];
327
561
  return n !== void 0 && n.split(",").some((t) => t.trim() === e) ? {
328
562
  status: 304,
329
563
  headers: {
330
- ...f,
564
+ ...d,
331
565
  ETag: e
332
566
  }
333
- } : F(t.status, r, {
567
+ } : Z(t.status, r, {
334
568
  ...i,
335
569
  ETag: e
336
- });
570
+ }, t.contentType);
337
571
  }
338
572
  return t.status === 204 || t.status === 304 ? {
339
573
  status: t.status,
340
574
  headers: i
341
- } : F(t.status, r, i);
575
+ } : Z(t.status, r, i, t.contentType);
342
576
  } catch (e) {
343
- return x && S && await a(x.store, C, S), V(e, _, o, f);
577
+ return S && C && await n(S.store, w, C), be(e, g, a, d, l);
344
578
  }
345
579
  }
346
580
  };
347
- }, U = (e, t = {}) => {
581
+ }, Se = (e, t = {}) => {
348
582
  if (t.idempotency !== void 0) {
349
- for (let t of e) if (t.streaming === !0 && B.has(t.method)) throw Error(`REST route ${t.method} ${t.path} declares \`streaming: true\` on a method the idempotency binding claims (${[...B].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.`);
583
+ 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.`);
350
584
  }
351
- return e.map((e) => H(e, t));
352
- }, W = async (e, t) => {
585
+ return e.map((e) => xe(e, t));
586
+ }, Ce = async (e, t) => {
353
587
  let n = await e[0].handle(t);
354
588
  for (let r = 1; r < e.length && n.status === 405; r++) n = await e[r].handle(t);
355
589
  return n;
356
590
  };
357
591
  //#endregion
358
- export { E as RestRouteError, M as bytes, h as coerceQueryObject, m as coerceQueryValue, b as collectPublicApiRoutes, g as declaredErrorTags, O as defineRestRoute, u as derivePublicMethod, d as derivePublicPath, W as dispatchSharedPath, N as isRestByteResponse, T as isRestResponse, j as isRestStreamResponse, R as matchPathParams, v as projectedFailure, y as publicApiRoute, C as requireAnyScope, x as requireAuthenticated, S as requireScope, w as response, D as restError, U as restRoutesToHttpRoutes, k as sse, A as sseFrame };
592
+ export { g as JSONAPI_MEDIA_TYPE, f as PROBLEM_JSON, m as REST_PROFILE_NAMES, Y as RestRouteError, de as bytes, N as coerceQueryObject, M as coerceQueryValue, H as collectPublicApiRoutes, P as declaredErrorTags, se as defineRestRoute, w as derivePublicMethod, T as derivePublicPath, D as deriveResource, Ce as dispatchSharedPath, u as encodeRestError, o as encodeRestSuccess, L as errorMemberSchema, X as isRestByteResponse, J as isRestResponse, ue as isRestStreamResponse, _e as matchPathParams, p as nextLink, O as normalizePathParams, R as operationIdOf, k as pathParamNames, h as problemDetails, s as problemTypeOf, I as projectedFailure, V as publicApiRoute, U as publicSurfaceDigest, K as requireAnyScope, W as requireAuthenticated, G as requireScope, d as resolveRestFormat, E as resourceIdField, q as response, oe as restError, Se as restRoutesToHttpRoutes, _ as restViewSchema, ve as routeAcceptsPath, ce as sse, le as sseFrame, c as toSnakeCase, ie as wireExample };