@voltro/protocol 0.85.0 → 0.86.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/CHANGELOG.md +666 -0
- package/README.md +14 -0
- package/THIRD-PARTY-NOTICES.md +5 -33
- package/dist/approval.js +64 -0
- package/dist/approvalDescriptors.js +26 -0
- package/dist/auth.js +369 -0
- package/dist/boundedRing.js +27 -0
- package/dist/businessRule.js +11 -0
- package/dist/connection.js +73 -0
- package/dist/devActivity.js +4 -0
- package/dist/errorValue.js +21 -0
- package/dist/event.js +104 -0
- package/dist/idempotency.js +66 -0
- package/dist/identity.js +5 -9
- package/dist/index.d.ts +225 -21
- package/dist/index.js +42 -1700
- package/dist/inspect.js +14 -240
- package/dist/inspectBackfill.js +52 -0
- package/dist/inspectCommandRejection.js +21 -0
- package/dist/inspectProjection.js +133 -0
- package/dist/inspectStorageProjection.js +86 -0
- package/dist/inspectValueIdentity.js +4 -0
- package/dist/inspectWorkflowExecution.js +34 -0
- package/dist/inspectWorkflowQueuedStart.js +31 -0
- package/dist/jsonSchema.js +54 -0
- package/dist/outbox.js +10 -0
- package/dist/pairing.js +75 -0
- package/dist/plugin.js +61 -0
- package/dist/pluginNaming.js +32 -0
- package/dist/procedure.js +262 -0
- package/dist/publicApi.js +344 -0
- package/dist/reactivityChannel.js +34 -0
- package/dist/rest.d.ts +33 -0
- package/dist/rest.js +213 -470
- package/dist/restFormat.js +163 -0
- package/dist/rowEquality.js +31 -0
- package/dist/rowPatch.js +182 -0
- package/dist/schemaShape.js +67 -0
- package/dist/scopes.js +240 -0
- package/dist/serverErrorBus.js +15 -0
- package/dist/serviceCall.js +14 -0
- package/dist/session.js +13 -15
- package/dist/{sessionHeader-DriTZhmv.js → sessionHeader.js} +1 -1
- package/dist/storageAccess.js +14 -0
- package/dist/storeErrors.js +66 -0
- package/dist/storeScreenshots.js +90 -0
- package/dist/strictInput.js +27 -0
- package/dist/subscriptionEvent.js +37 -0
- package/dist/tenantSelection.js +40 -0
- package/dist/time.js +7 -0
- package/dist/undo.js +38 -0
- package/dist/validation.js +39 -0
- package/dist/webSocketGateway.js +10 -0
- package/dist/workflow.js +297 -0
- package/dist/workflowAccess.js +61 -0
- package/dist/workflowRestart.js +45 -0
- package/dist/workflowRetry.js +44 -0
- package/dist/workflowStartOutcome.js +30 -0
- package/package.json +3 -3
- package/dist/restFormat-BlgTLxm1.js +0 -298
- package/dist/scopes-ClywBij8.js +0 -548
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import { schemaShape as e, shapeDigest as t } from "./schemaShape.js";
|
|
2
|
+
import { encodeRestError as n, encodeRestSuccess as r, resolveRestFormat as i, restViewSchema as a, toSnakeCase as o } from "./restFormat.js";
|
|
3
|
+
import { RestRouteError as s, defineRestRoute as c, requireAuthenticated as l, requireScope as u, response as ee, sse as d, sseFrame as f } from "./rest.js";
|
|
4
|
+
import { Effect as p, Schema as m, SchemaGetter as h, SchemaIssue as g } from "effect";
|
|
5
|
+
import * as _ from "effect/SchemaAST";
|
|
6
|
+
//#region src/publicApi.ts
|
|
7
|
+
var v = (e, t, n) => t.method ?? (t.resource !== void 0 && n !== void 0 ? S("", t, n).method : void 0) ?? (e === "query" ? "GET" : "POST"), y = (e, t, n) => C(t.path ?? (t.resource !== void 0 && n !== void 0 ? S(e, t, n).path : `/${t.version ?? "v1"}/${e.replace(/\./g, "/")}`)), b = (e) => {
|
|
8
|
+
let t = e.split("/").pop() ?? e;
|
|
9
|
+
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;
|
|
10
|
+
}, x = (e, t) => {
|
|
11
|
+
let n = t != null && (typeof t == "object" || typeof t == "function") && "ast" in t ? L(t) : void 0;
|
|
12
|
+
if (n === void 0) return;
|
|
13
|
+
let r = `${b(e)}Id`;
|
|
14
|
+
return n.has(r) ? r : n.has("id") ? "id" : void 0;
|
|
15
|
+
}, S = (e, t, n) => {
|
|
16
|
+
let r = (t.resource ?? "").replace(/^\/+|\/+$/g, ""), i = `/${t.version ?? "v1"}/${r}`, a = x(r, n.input), o = a === void 0 ? i : `${i}/:${a}`, s = e.split(".").pop() ?? e, c = n.target?.op;
|
|
17
|
+
return n.kind === "query" || n.kind === "stream" ? {
|
|
18
|
+
method: "GET",
|
|
19
|
+
path: o
|
|
20
|
+
} : n.kind === "mutation" && c === "insert" ? {
|
|
21
|
+
method: "POST",
|
|
22
|
+
path: i
|
|
23
|
+
} : n.kind === "mutation" && c === "update" ? {
|
|
24
|
+
method: a === void 0 ? "POST" : "PATCH",
|
|
25
|
+
path: o
|
|
26
|
+
} : n.kind === "mutation" && c === "delete" ? {
|
|
27
|
+
method: a === void 0 ? "POST" : "DELETE",
|
|
28
|
+
path: o
|
|
29
|
+
} : {
|
|
30
|
+
method: "POST",
|
|
31
|
+
path: `${o}/${s}`
|
|
32
|
+
};
|
|
33
|
+
}, C = (e) => e.replace(/\{([A-Za-z0-9_]+)\}/g, ":$1"), w = (e) => [...e.matchAll(/:([A-Za-z0-9_]+)/g)].map((e) => e[1]), T = (e) => {
|
|
34
|
+
if (_.isUnion(e)) {
|
|
35
|
+
let t = e.types.filter((e) => !_.isUndefined(e));
|
|
36
|
+
if (t.length === 1) return t[0];
|
|
37
|
+
if (t.length !== e.types.length) return new _.Union(t);
|
|
38
|
+
}
|
|
39
|
+
return e;
|
|
40
|
+
}, E = /^-?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?$/i, D = (e, t) => {
|
|
41
|
+
let n = T(t);
|
|
42
|
+
if (n.encoding !== void 0) return D(e, _.toEncoded(n));
|
|
43
|
+
if (_.isUnion(n)) {
|
|
44
|
+
for (let t of n.types) {
|
|
45
|
+
let n = D(e, t);
|
|
46
|
+
if (n !== e) return n;
|
|
47
|
+
}
|
|
48
|
+
return e;
|
|
49
|
+
}
|
|
50
|
+
if (_.isArrays(n)) {
|
|
51
|
+
let t = Array.isArray(e) ? e : e === void 0 ? void 0 : [e];
|
|
52
|
+
if (t === void 0) return e;
|
|
53
|
+
let r = n.rest[0] ?? n.elements[0];
|
|
54
|
+
return r === void 0 ? t : t.map((e) => D(e, r));
|
|
55
|
+
}
|
|
56
|
+
if (typeof e != "string") return e;
|
|
57
|
+
if (_.isNumber(n)) return E.test(e.trim()) ? Number(e) : e;
|
|
58
|
+
if (_.isBoolean(n)) return e === "true" || e !== "false" && e;
|
|
59
|
+
if (_.isLiteral(n)) {
|
|
60
|
+
let t = n.literal;
|
|
61
|
+
return typeof t == "number" && E.test(e.trim()) && Number(e) === t || typeof t == "boolean" && String(t) === e ? t : e;
|
|
62
|
+
}
|
|
63
|
+
return e;
|
|
64
|
+
}, O = (e, t) => {
|
|
65
|
+
if (typeof e != "object" || !e || Array.isArray(e)) return e;
|
|
66
|
+
let n = T(_.toEncoded(t.ast));
|
|
67
|
+
if (!_.isObjects(n)) return e;
|
|
68
|
+
let r = { ...e };
|
|
69
|
+
for (let e of n.propertySignatures) {
|
|
70
|
+
let t = String(e.name);
|
|
71
|
+
t in r && (r[t] = D(r[t], e.type));
|
|
72
|
+
}
|
|
73
|
+
return r;
|
|
74
|
+
}, k = (e) => {
|
|
75
|
+
let t = T(_.toEncoded(e.ast));
|
|
76
|
+
if (!_.isObjects(t)) return (e) => e;
|
|
77
|
+
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, {
|
|
78
|
+
type: e.type,
|
|
79
|
+
order: t
|
|
80
|
+
}), !0));
|
|
81
|
+
return (e) => {
|
|
82
|
+
if (typeof e != "object" || !e || Array.isArray(e)) return e;
|
|
83
|
+
let t = { ...e }, a = i ? Object.keys(t) : void 0;
|
|
84
|
+
if (a !== void 0 && a.length * 4 < n.length) {
|
|
85
|
+
let e = [];
|
|
86
|
+
for (let t of a) {
|
|
87
|
+
let n = r.get(t);
|
|
88
|
+
n !== void 0 && e.push({
|
|
89
|
+
key: t,
|
|
90
|
+
...n
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
e.sort((e, t) => e.order - t.order);
|
|
94
|
+
for (let { key: n, type: r } of e) t[n] = D(t[n], r);
|
|
95
|
+
} else for (let e of n) {
|
|
96
|
+
let n = String(e.name);
|
|
97
|
+
n in t && (t[n] = D(t[n], e.type));
|
|
98
|
+
}
|
|
99
|
+
return t;
|
|
100
|
+
};
|
|
101
|
+
}, A = (e) => {
|
|
102
|
+
let t = /* @__PURE__ */ new Set();
|
|
103
|
+
if (e === void 0) return t;
|
|
104
|
+
let n = (e) => {
|
|
105
|
+
if (_.isUnion(e)) for (let t of e.types) n(t);
|
|
106
|
+
else if (e.encoding !== void 0 && n(_.toEncoded(e)), _.isObjects(e)) {
|
|
107
|
+
let n = e.propertySignatures.find((e) => e.name === "_tag");
|
|
108
|
+
n !== void 0 && _.isLiteral(n.type) && typeof n.type.literal == "string" && t.add(n.type.literal);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
return n(e.ast), t;
|
|
112
|
+
}, j = (e, t, n) => {
|
|
113
|
+
if (n !== void 0) try {
|
|
114
|
+
let r = m.encodeUnknownSync(n)(e);
|
|
115
|
+
if (typeof r == "object" && r) return {
|
|
116
|
+
error: t,
|
|
117
|
+
...r
|
|
118
|
+
};
|
|
119
|
+
} catch {}
|
|
120
|
+
let r = { error: t };
|
|
121
|
+
for (let [t, n] of Object.entries(e)) t !== "stack" && t !== "_tag" && (r[t] = n);
|
|
122
|
+
return r;
|
|
123
|
+
}, M = (e, t, n, r = []) => N(e, t, n, r, A), N = (e, t, n, r, i) => {
|
|
124
|
+
if (typeof e != "object" || !e) return e;
|
|
125
|
+
let a = e._tag;
|
|
126
|
+
if (typeof a != "string" || a === "ScopeError" || a === "NoSuchResource") return e;
|
|
127
|
+
if (i(t.error).has(a)) {
|
|
128
|
+
let r = n.errorStatus?.[a] ?? 422;
|
|
129
|
+
return new s(r, j(e, a, t.error));
|
|
130
|
+
}
|
|
131
|
+
let o = r.find((e) => i(e.schema).has(a));
|
|
132
|
+
if (o === void 0) return e;
|
|
133
|
+
let c = n.errorStatus?.[a] ?? o.rest?.status ?? 422, l = o.rest?.headers?.(e);
|
|
134
|
+
return new s(c, j(e, a, o.schema), l);
|
|
135
|
+
}, P = (e, t, r, i, a, o, c) => {
|
|
136
|
+
let l = N(e, t, r, i, c);
|
|
137
|
+
if (!(l instanceof s) || a.errors === "tagged" && a.encodeError === void 0) return l;
|
|
138
|
+
let { error: u, _tag: ee, ...d } = l.body, f = typeof d.message == "string" ? d.message : typeof d.reason == "string" ? d.reason : "", p = n(a, {
|
|
139
|
+
status: l.status,
|
|
140
|
+
tag: u,
|
|
141
|
+
message: f,
|
|
142
|
+
fields: d
|
|
143
|
+
}, {
|
|
144
|
+
...o,
|
|
145
|
+
status: l.status
|
|
146
|
+
});
|
|
147
|
+
return new s(l.status, p.body, {
|
|
148
|
+
...l.headers ?? {},
|
|
149
|
+
...p.headers ?? {}
|
|
150
|
+
}, p.contentType);
|
|
151
|
+
}, F = (e, t) => {
|
|
152
|
+
if (e === void 0) return;
|
|
153
|
+
let n = _.isUnion(e.ast) ? e.ast.types : [e.ast];
|
|
154
|
+
for (let e of n) {
|
|
155
|
+
let n = m.make(e);
|
|
156
|
+
if (A(n).has(t)) return n;
|
|
157
|
+
}
|
|
158
|
+
}, I = (e) => e.split(".").map((e, t) => t === 0 ? e : e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_"), L = (e) => {
|
|
159
|
+
let t = T(_.toEncoded(e.ast));
|
|
160
|
+
return _.isObjects(t) && t.indexSignatures.length === 0 ? new Set(t.propertySignatures.map((e) => String(e.name))) : void 0;
|
|
161
|
+
}, R = (e, t) => e === t || JSON.stringify(e) === JSON.stringify(t), te = (e) => {
|
|
162
|
+
let t = T(_.toEncoded(e.ast)), n = _.isObjects(t) ? new Map(t.propertySignatures.map((e) => [String(e.name), e.type])) : /* @__PURE__ */ new Map();
|
|
163
|
+
return (e) => {
|
|
164
|
+
let t = {};
|
|
165
|
+
for (let [r, i] of Object.entries(e)) {
|
|
166
|
+
let e = n.get(r);
|
|
167
|
+
t[r] = e === void 0 ? i : D(i, e);
|
|
168
|
+
}
|
|
169
|
+
return t;
|
|
170
|
+
};
|
|
171
|
+
}, z = (e, t) => {
|
|
172
|
+
if (e !== void 0) {
|
|
173
|
+
try {
|
|
174
|
+
return m.encodeUnknownSync(t)(e);
|
|
175
|
+
} catch {}
|
|
176
|
+
try {
|
|
177
|
+
return m.decodeUnknownSync(t)(e), e;
|
|
178
|
+
} catch {}
|
|
179
|
+
return e;
|
|
180
|
+
}
|
|
181
|
+
}, B = (e, t, n) => ({
|
|
182
|
+
...e.request === void 0 ? {} : { request: z(e.request, t) },
|
|
183
|
+
...e.response === void 0 ? {} : { response: z(e.response, n) }
|
|
184
|
+
}), ne = () => (e) => {
|
|
185
|
+
if (e.subject.type !== "anonymous") return;
|
|
186
|
+
let t = e.subject.credentialRejected;
|
|
187
|
+
return t === void 0 ? void 0 : {
|
|
188
|
+
status: 401,
|
|
189
|
+
message: t
|
|
190
|
+
};
|
|
191
|
+
}, V = (e, t, n, s = {}) => {
|
|
192
|
+
let b = e.publicApi;
|
|
193
|
+
if (b === void 0) throw Error(`publicApiRoute: descriptor '${e.name}' has no publicApi annotation`);
|
|
194
|
+
let x = i(s.profile, b.format), S = s.pluginErrors ?? [], C = /* @__PURE__ */ new WeakMap(), T = (e) => {
|
|
195
|
+
if (e === void 0) return /* @__PURE__ */ new Set();
|
|
196
|
+
let t = C.get(e.ast);
|
|
197
|
+
if (t !== void 0) return t;
|
|
198
|
+
let n = A(e);
|
|
199
|
+
return C.set(e.ast, n), n;
|
|
200
|
+
}, E = /* @__PURE__ */ new WeakMap(), D = (e, t) => {
|
|
201
|
+
if (e === void 0) return;
|
|
202
|
+
let n = E.get(e.ast);
|
|
203
|
+
if (n === void 0) {
|
|
204
|
+
let t = /* @__PURE__ */ new Map();
|
|
205
|
+
for (let n of _.isUnion(e.ast) ? e.ast.types : [e.ast]) {
|
|
206
|
+
let e = m.make(n);
|
|
207
|
+
for (let n of T(e)) t.has(n) || t.set(n, e);
|
|
208
|
+
}
|
|
209
|
+
n = t, E.set(e.ast, n);
|
|
210
|
+
}
|
|
211
|
+
return n.get(t);
|
|
212
|
+
}, O = {
|
|
213
|
+
kind: e.kind,
|
|
214
|
+
input: e.input,
|
|
215
|
+
target: e.target
|
|
216
|
+
}, j = v(e.kind, b, O), M = (e) => x.naming === "snake_case" ? o(e) : e, N = y(e.name, b, O), F = N.replace(/:([A-Za-z0-9_]+)/g, (e, t) => `:${M(t)}`), z = w(F), V = a(e.input, x), H = k(V), U = te(V), W = L(V);
|
|
217
|
+
if (W !== void 0) {
|
|
218
|
+
for (let t of z) if (!W.has(t)) throw Error(`publicApi: descriptor '${e.name}' — path '${N}' binds ':${t}', and the input declares no field of that name` + (W.size > 0 ? ` (fields: ${[...W].join(", ")})` : " (the input declares no fields)"));
|
|
219
|
+
}
|
|
220
|
+
let G = a(e.output, x), re = m.Struct({ value: V }), K = j !== "GET" && W === void 0;
|
|
221
|
+
if (j !== "GET" && W !== void 0) {
|
|
222
|
+
let e = z.length >= 32 ? new Set(z) : void 0;
|
|
223
|
+
for (let t of W) if (!(e?.has(t) ?? z.includes(t))) {
|
|
224
|
+
K = !0;
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
let q = {
|
|
229
|
+
query: m.Unknown,
|
|
230
|
+
params: m.Unknown,
|
|
231
|
+
form: m.Boolean
|
|
232
|
+
}, ie = (K ? m.Struct({
|
|
233
|
+
...q,
|
|
234
|
+
body: m.Unknown
|
|
235
|
+
}) : m.Struct(q)).pipe(m.decodeTo(re, {
|
|
236
|
+
decode: h.transformEffect((e) => {
|
|
237
|
+
let t = "body" in e ? e.body : void 0, n = j === "GET" ? H(e.query) : e.form ? H(t ?? {}) : t ?? {}, r = typeof e.params == "object" && e.params !== null ? U(e.params) : {};
|
|
238
|
+
if (typeof n != "object" || !n || Array.isArray(n)) return p.succeed({ value: n });
|
|
239
|
+
let i = n, a = Object.keys(r), o = 0;
|
|
240
|
+
for (let e of a) e in i && !R(i[e], r[e]) && (a[o++] = e);
|
|
241
|
+
if (a.length = o, a.length > 0) {
|
|
242
|
+
let t = j === "GET" ? "query string" : "body";
|
|
243
|
+
return p.fail(new g.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));
|
|
244
|
+
}
|
|
245
|
+
return p.succeed({ value: {
|
|
246
|
+
...i,
|
|
247
|
+
...r
|
|
248
|
+
} });
|
|
249
|
+
}),
|
|
250
|
+
encode: h.transform((e) => e)
|
|
251
|
+
})), ae = [
|
|
252
|
+
ne(),
|
|
253
|
+
...e.openAccess === void 0 ? [l()] : [],
|
|
254
|
+
...(b.scopes ?? []).map((e) => u(e))
|
|
255
|
+
], J = (() => {
|
|
256
|
+
let t = e.source;
|
|
257
|
+
return typeof t == "string" ? t : Array.isArray(t) ? t[0] : void 0;
|
|
258
|
+
})(), Y = (t, n = 200) => ({
|
|
259
|
+
tag: e.name,
|
|
260
|
+
method: t.method,
|
|
261
|
+
path: t.path,
|
|
262
|
+
query: t.query,
|
|
263
|
+
source: J,
|
|
264
|
+
status: n
|
|
265
|
+
}), X = b.stream === "sse" && e.kind === "query" && n !== void 0, oe = m.encodeUnknownEffect(G), se = X ? (e, t) => d((r) => n(e.value, t, (e) => {
|
|
266
|
+
r(f(String(e._tag ?? "message"), e));
|
|
267
|
+
})) : async (n, i) => {
|
|
268
|
+
let a;
|
|
269
|
+
try {
|
|
270
|
+
a = await t(n.value, i);
|
|
271
|
+
} catch (t) {
|
|
272
|
+
throw P(t, e, b, S, x, Y(i), T);
|
|
273
|
+
}
|
|
274
|
+
let o = await p.runPromise(oe(a)), s = r(x, o, Y(i));
|
|
275
|
+
return ee(s.body, {
|
|
276
|
+
...s.headers === void 0 ? {} : { headers: s.headers },
|
|
277
|
+
...s.contentType === void 0 ? {} : { contentType: s.contentType }
|
|
278
|
+
});
|
|
279
|
+
}, Z = e.error, Q = T(Z), ce = [...Q], $ = [];
|
|
280
|
+
for (let e of ce) {
|
|
281
|
+
let t = D(Z, e);
|
|
282
|
+
t !== void 0 && $.push({
|
|
283
|
+
status: b.errorStatus?.[e] ?? 422,
|
|
284
|
+
tag: e,
|
|
285
|
+
schema: t
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
for (let e of S) for (let t of T(e.schema)) {
|
|
289
|
+
if (Q.has(t)) continue;
|
|
290
|
+
let n = b.errorStatus?.[t] ?? e.rest?.status;
|
|
291
|
+
if (n === void 0) continue;
|
|
292
|
+
let r = D(e.schema, t) ?? e.schema;
|
|
293
|
+
$.push({
|
|
294
|
+
status: n,
|
|
295
|
+
tag: t,
|
|
296
|
+
schema: r
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
let le = b.security === !1 ? "none" : b.security ?? (e.openAccess === void 0 ? "required" : "optional"), ue = {
|
|
300
|
+
tag: e.name,
|
|
301
|
+
kind: e.kind,
|
|
302
|
+
version: b.version ?? "v1",
|
|
303
|
+
security: le,
|
|
304
|
+
idempotent: b.idempotent === !0,
|
|
305
|
+
input: V,
|
|
306
|
+
pathParams: z,
|
|
307
|
+
output: G,
|
|
308
|
+
source: J,
|
|
309
|
+
errorResponses: $,
|
|
310
|
+
format: x
|
|
311
|
+
};
|
|
312
|
+
return c({
|
|
313
|
+
method: j,
|
|
314
|
+
path: F,
|
|
315
|
+
input: ie,
|
|
316
|
+
output: m.Unknown,
|
|
317
|
+
handler: se,
|
|
318
|
+
...X ? { streaming: !0 } : {},
|
|
319
|
+
guards: ae,
|
|
320
|
+
operationId: b.operationId ?? I(e.name),
|
|
321
|
+
tags: b.tags ?? [e.name.split(".")[0] ?? e.name],
|
|
322
|
+
projection: ue,
|
|
323
|
+
...x.etag && j === "GET" && !X ? { etag: !0 } : {},
|
|
324
|
+
...b.cache !== void 0 && j === "GET" && !X ? { cache: b.cache } : {},
|
|
325
|
+
...b.example === void 0 ? {} : { example: B(b.example, V, G) },
|
|
326
|
+
...b.summary === void 0 ? {} : { summary: b.summary },
|
|
327
|
+
...b.description === void 0 ? {} : { description: b.description },
|
|
328
|
+
...b.deprecated === void 0 ? {} : { deprecated: b.deprecated },
|
|
329
|
+
...b.sunset === void 0 ? {} : { sunset: b.sunset }
|
|
330
|
+
});
|
|
331
|
+
}, 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 = (n) => t(n.filter((e) => e.projection !== void 0).map((t) => {
|
|
332
|
+
let n = t.projection, r = {
|
|
333
|
+
tag: n.tag,
|
|
334
|
+
method: t.method,
|
|
335
|
+
path: t.path,
|
|
336
|
+
pathParams: n.pathParams,
|
|
337
|
+
version: n.version,
|
|
338
|
+
security: n.security,
|
|
339
|
+
errors: [...n.errorResponses].map((e) => `${e.status}:${e.tag}`).sort()
|
|
340
|
+
};
|
|
341
|
+
return `${JSON.stringify(r)} ${e(n.input.ast)} ${e(n.output.ast)}`;
|
|
342
|
+
}).sort().join("\n"));
|
|
343
|
+
//#endregion
|
|
344
|
+
export { O as coerceQueryObject, D as coerceQueryValue, H as collectPublicApiRoutes, A as declaredErrorTags, v as derivePublicMethod, y as derivePublicPath, S as deriveResource, F as errorMemberSchema, C as normalizePathParams, I as operationIdOf, w as pathParamNames, M as projectedFailure, V as publicApiRoute, U as publicSurfaceDigest, x as resourceIdField, B as wireExample };
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/reactivityChannel.ts
|
|
2
|
+
var e = "channel:", t = Symbol.for("@voltro/protocol/reactivityChannels"), n = globalThis, r = n[t] ?? (n[t] = /* @__PURE__ */ new Map()), i = /^[a-z][a-z0-9-]*(\.[a-z0-9-]+)*$/, a = (t) => {
|
|
3
|
+
if (!i.test(t)) throw Error(`reactivityChannel('${t}'): invalid channel name.\n Use lowercase kebab segments separated by dots — \`presence\`, \`job-queue\`,
|
|
4
|
+
\`billing.usage\`. A \`:\` is refused because it is the namespace separator in
|
|
5
|
+
the routing key (\`${e}<name>\`), and an uppercase letter is\n refused because a key that differs only by case reads as one channel and
|
|
6
|
+
routes as two.`);
|
|
7
|
+
let n = r.get(t);
|
|
8
|
+
if (n !== void 0) return n;
|
|
9
|
+
let a = `${e}${t}`, o = Object.freeze({
|
|
10
|
+
kind: "reactivity-channel",
|
|
11
|
+
name: t,
|
|
12
|
+
key: a,
|
|
13
|
+
toString: () => a
|
|
14
|
+
});
|
|
15
|
+
return r.set(t, o), o;
|
|
16
|
+
}, o = (e) => typeof e == "object" && !!e && e.kind === "reactivity-channel", s = (t) => t.startsWith(e), c = () => new Set([...r.values()].map((e) => e.key)), l = (e) => o(e) ? e.key : e, u = (e) => e === void 0 ? [] : Array.isArray(e) ? e.map(l) : [l(e)], d = (e) => e === void 0 ? void 0 : Array.isArray(e) ? e.map(l) : l(e), f = (e) => {
|
|
17
|
+
let t = c(), n = [];
|
|
18
|
+
for (let r of e) for (let e of u(r.source)) s(e) && !t.has(e) && n.push({
|
|
19
|
+
procedure: r.name,
|
|
20
|
+
key: e
|
|
21
|
+
});
|
|
22
|
+
return n;
|
|
23
|
+
}, p = (e, t) => {
|
|
24
|
+
let n = e?.injectExternalChange;
|
|
25
|
+
return n !== void 0 && (n.call(e, {
|
|
26
|
+
table: t.key,
|
|
27
|
+
op: "update",
|
|
28
|
+
new: {},
|
|
29
|
+
old: {},
|
|
30
|
+
origin: "inline"
|
|
31
|
+
}), !0);
|
|
32
|
+
};
|
|
33
|
+
//#endregion
|
|
34
|
+
export { e as REACTIVITY_CHANNEL_PREFIX, c as declaredReactivityChannelKeys, o as isReactivityChannel, s as isReactivityChannelKey, d as normalizeSource, p as publishReactivity, a as reactivityChannel, u as sourceKeys, f as undeclaredChannelKeys };
|
package/dist/rest.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as AST from 'effect/SchemaAST';
|
|
2
2
|
import { DataStore } from '@voltro/database';
|
|
3
|
+
import { Effect } from 'effect';
|
|
3
4
|
import { Schema } from 'effect';
|
|
4
5
|
|
|
5
6
|
declare interface ActionProcedureDescriptor<Name extends string, Input extends Schema.Top, Output extends Schema.Top, Error extends Schema.Top> {
|
|
@@ -589,6 +590,9 @@ declare interface PluginHttpRoute {
|
|
|
589
590
|
* handler branches on: exempting `/saml` exempts `POST /saml/anything`.
|
|
590
591
|
*/
|
|
591
592
|
readonly originGuard?: 'exempt';
|
|
593
|
+
readonly cors?: RestCors;
|
|
594
|
+
/** Bearer-only routes must discard cookie authority before authentication. */
|
|
595
|
+
readonly credentials?: 'bearer';
|
|
592
596
|
}
|
|
593
597
|
|
|
594
598
|
/**
|
|
@@ -1225,6 +1229,22 @@ export declare interface RestCache {
|
|
|
1225
1229
|
readonly audience?: (output: unknown, input: unknown, subject: Subject) => 'public' | 'private';
|
|
1226
1230
|
}
|
|
1227
1231
|
|
|
1232
|
+
/** Cross-origin browser access for one route. Origins are exact, including opaque `null`. */
|
|
1233
|
+
export declare interface RestCors {
|
|
1234
|
+
readonly origins: ReadonlyArray<string>;
|
|
1235
|
+
readonly headers?: ReadonlyArray<string>;
|
|
1236
|
+
readonly methods?: ReadonlyArray<RestMethod>;
|
|
1237
|
+
/** Preflight cache lifetime in seconds. */
|
|
1238
|
+
readonly maxAge?: number;
|
|
1239
|
+
readonly exposeHeaders?: ReadonlyArray<string>;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
/** Shared by the descriptor adapter and listener, including early transport refusals. */
|
|
1243
|
+
export declare const restCorsHeaders: (cors: RestCors | undefined, origin: string | undefined) => Record<string, string>;
|
|
1244
|
+
|
|
1245
|
+
/** Preflight never authenticates, consumes quota, reads a body or executes a handler. */
|
|
1246
|
+
export declare const restCorsPreflight: (cors: RestCors, method: string, headers: Readonly<Record<string, string>>) => PluginHttpRouteResult;
|
|
1247
|
+
|
|
1228
1248
|
export declare type RestDates = 'iso' | 'epoch-ms';
|
|
1229
1249
|
|
|
1230
1250
|
export declare type RestEnvelope = 'none' | 'data' | 'jsonapi';
|
|
@@ -1327,6 +1347,13 @@ export declare type RestNaming = 'camelCase' | 'snake_case';
|
|
|
1327
1347
|
|
|
1328
1348
|
export declare type RestPagination = 'link-header' | 'body-cursor';
|
|
1329
1349
|
|
|
1350
|
+
/** Uses the mounted rate-limit plugin's store, algorithms and dynamic policy. */
|
|
1351
|
+
export declare interface RestRateLimit {
|
|
1352
|
+
readonly limit: number;
|
|
1353
|
+
readonly window: string;
|
|
1354
|
+
readonly by?: 'subject' | 'tenant' | 'apiKey' | 'ip' | 'global';
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1330
1357
|
/** A schema-encoded REST body with an application-selected HTTP status and
|
|
1331
1358
|
* response headers. The marker keeps ordinary domain objects unambiguous.
|
|
1332
1359
|
* `output` still validates/encodes `body`; use `Schema.Void` with a 204 when
|
|
@@ -1425,6 +1452,10 @@ export declare interface RestRouteDescriptor<I, O> {
|
|
|
1425
1452
|
*/
|
|
1426
1453
|
readonly version?: `v${number}`;
|
|
1427
1454
|
readonly guards?: ReadonlyArray<RestGuard>;
|
|
1455
|
+
readonly cors?: RestCors;
|
|
1456
|
+
/** Only an explicit bearer header may authenticate; cookies are removed before auth and context construction. */
|
|
1457
|
+
readonly credentials?: 'bearer';
|
|
1458
|
+
readonly rateLimit?: RestRateLimit;
|
|
1428
1459
|
/**
|
|
1429
1460
|
* This route STREAMS (Server-Sent Events) rather than resolving one value — its
|
|
1430
1461
|
* handler returns `sse(...)`. Declared on the descriptor, not left implicit in
|
|
@@ -1510,6 +1541,8 @@ export declare const restRoutesToHttpRoutes: (routes: ReadonlyArray<RestRouteDes
|
|
|
1510
1541
|
* auth subject + the bound DataStore.
|
|
1511
1542
|
*/
|
|
1512
1543
|
export declare interface RestServeBindings {
|
|
1544
|
+
/** Bound once from the app's mounted rate-limit plugin. */
|
|
1545
|
+
readonly rateLimit?: (policy: RestRateLimit, ctx: RestRouteContext, route: RestRouteDescriptor<any, any>) => Effect.Effect<void, unknown>;
|
|
1513
1546
|
/** Resolve the calling subject from the request headers. */
|
|
1514
1547
|
readonly resolveSubject?: (headers: Readonly<Record<string, string>>) => Subject | Promise<Subject>;
|
|
1515
1548
|
/** The bound framework DataStore. */
|