@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.
- package/CHANGELOG.md +5987 -0
- package/README.md +14 -0
- package/THIRD-PARTY-NOTICES.md +1122 -31
- package/dist/apiRoleEndpoints.js +108 -0
- package/dist/apiRoleObservation.js +68 -0
- package/dist/apikey.d.ts +10 -0
- package/dist/approval.js +64 -0
- package/dist/approvalDescriptors.js +26 -0
- package/dist/auth.js +389 -0
- package/dist/boundedRing.js +27 -0
- package/dist/businessRule.js +11 -0
- package/dist/canonicalJson.js +14 -0
- package/dist/connection.js +73 -0
- package/dist/devActivity.js +4 -0
- package/dist/errorSchema.js +24 -0
- package/dist/errorValue.js +21 -0
- package/dist/event.js +110 -0
- package/dist/formCapture.js +12 -0
- package/dist/httpStreamMaxDuration.js +9 -0
- package/dist/idempotency.js +121 -0
- package/dist/idempotencyInput.js +123 -0
- package/dist/identity.js +5 -9
- package/dist/index.d.ts +1095 -139
- package/dist/index.js +54 -1700
- package/dist/inspect.d.ts +1 -1
- 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/jwt.d.ts +10 -0
- package/dist/jwt.js +1 -1
- package/dist/outbox.js +10 -0
- package/dist/pairing.js +75 -0
- package/dist/plugin.js +87 -0
- package/dist/pluginAccountMerge.js +88 -0
- package/dist/pluginNaming.js +32 -0
- package/dist/pluginPrivacy.js +166 -0
- package/dist/procedure.js +280 -0
- package/dist/publicApi.js +325 -0
- package/dist/queryOptionalSources.js +14 -0
- package/dist/reactivityChannel.js +34 -0
- package/dist/rest.d.ts +260 -64
- package/dist/rest.js +345 -499
- package/dist/restFormat.js +163 -0
- package/dist/restReceipt.js +43 -0
- package/dist/revalidate.js +13 -0
- package/dist/rowEquality.js +31 -0
- package/dist/rowPatch.js +182 -0
- package/dist/schemaShape.js +67 -0
- package/dist/scopes.js +273 -0
- package/dist/secretWindows.js +71 -0
- package/dist/serverErrorBus.js +15 -0
- package/dist/serviceCall.js +14 -0
- package/dist/session.d.ts +89 -6
- package/dist/session.js +62 -63
- package/dist/{sessionHeader-DriTZhmv.js → sessionHeader.js} +1 -1
- package/dist/ssrfPolicy.js +30 -0
- 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 +16 -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 +5 -3
- package/dist/restFormat-BlgTLxm1.js +0 -298
- package/dist/scopes-ClywBij8.js +0 -548
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { subscriptionEvent as e } from "./subscriptionEvent.js";
|
|
2
|
+
import { RequestedTenantRefused as t } from "./tenantSelection.js";
|
|
3
|
+
import { Unauthenticated as n } from "./auth.js";
|
|
4
|
+
import { NoSuchResource as r, ScopeError as i, declaresResourceGuard as a, isOpenAccess as o, openAccessSpec as s, serviceAccessSpec as c, upgradedGuardShapeError as l } from "./scopes.js";
|
|
5
|
+
import { strictInput as u } from "./strictInput.js";
|
|
6
|
+
import { BusinessRuleViolation as d } from "./businessRule.js";
|
|
7
|
+
import { MutationConnectionRequired as f, MutationIdempotencyRefused as p, MutationInFlight as m } from "./idempotency.js";
|
|
8
|
+
import { ValidationError as h, ValidationErrors as g } from "./validation.js";
|
|
9
|
+
import { ApprovalErrors as _ } from "./approval.js";
|
|
10
|
+
import { normalizeSource as v } from "./reactivityChannel.js";
|
|
11
|
+
import { captureOptionalQuerySources as y } from "./queryOptionalSources.js";
|
|
12
|
+
import { Schema as b } from "effect";
|
|
13
|
+
import { Rpc as x } from "effect/rpc";
|
|
14
|
+
import { VersionConflict as S } from "@voltro/database/wire";
|
|
15
|
+
//#region src/procedure.ts
|
|
16
|
+
var C = (e) => e.internal !== !0, w = (e) => e.service === void 0 ? "client" : "service", T = (e) => C(e) && e.service === void 0, E = (e) => C(e) && e.service !== void 0, D = /^[a-z][a-z0-9-]{0,55}$/i, O = (e) => {
|
|
17
|
+
if (A(e), k(e), e.undo !== void 0 && (e.undo === null || e.undo.capture !== !1 || typeof e.undo.reason != "string" || e.undo.reason.trim() === "")) throw Error(`${e.name}: undo requires capture: false and a non-empty reason`);
|
|
18
|
+
if (e.idempotencyScope !== void 0 && e.idempotencyScope !== "subject" && e.idempotencyScope !== "connection") throw Error(`${e.name}: idempotencyScope must be 'subject' or 'connection'`);
|
|
19
|
+
let t = e.serialize;
|
|
20
|
+
if (t !== void 0) {
|
|
21
|
+
if (typeof t.key != "function") throw Error(`${e.name}: serialize.key must be a function of the input`);
|
|
22
|
+
if (t.maxPending !== void 0 && (!Number.isSafeInteger(t.maxPending) || t.maxPending < 1)) throw Error(`${e.name}: serialize.maxPending must be a positive integer`);
|
|
23
|
+
}
|
|
24
|
+
if (e.idempotencyScope === "connection" && (e.internal === !0 || e.publicApi !== void 0 || e.exposeAsTool !== void 0)) throw Error(`${e.name}: connection-scoped mutations require the native WebSocket RPC surface; internal, publicApi and exposeAsTool cannot establish its connection state`);
|
|
25
|
+
if (Array.isArray(e.guards) && e.guards.length === 0) throw Error(`${e.name}: \`guards: []\` is empty, so it enforces nothing — but it reads\n at the call site as if this procedure were protected. Omit the field for an
|
|
26
|
+
unguarded procedure, or list the scopes required to call it.`);
|
|
27
|
+
let n = typeof e.source == "string" ? [e.source] : Array.isArray(e.source) ? e.source : void 0;
|
|
28
|
+
if (n !== void 0 && (n.length === 0 || n.some((e) => String(e).trim() === ""))) throw Error(`${e.name}: \`source\` is empty, so this query declares reactivity and\n subscribes to nothing — it serves one snapshot and never updates again,
|
|
29
|
+
which is indistinguishable from "nothing changed". Name the table(s) it
|
|
30
|
+
reads, or omit \`source\` for a non-reactive query.`);
|
|
31
|
+
if (e.internal !== !0) return e;
|
|
32
|
+
if (e.openAccess !== void 0) throw Error(`${e.name}: \`internal: true\` cannot be combined with \`openAccess\`.\n \`internal\` takes the procedure OFF the wire, and \`openAccess\` declares who may
|
|
33
|
+
call it there — together they describe a decision about a surface that does not
|
|
34
|
+
exist. Drop \`openAccess\` (an internal procedure needs no wire decision), or drop
|
|
35
|
+
\`internal: true\` if the procedure really is meant to be callable.`);
|
|
36
|
+
if (e.overridesPlugin === !0) throw Error(`${e.name}: \`internal: true\` cannot be combined with \`overridesPlugin\`.\n The override REMOVES the plugin route, and an internal procedure is not
|
|
37
|
+
wire-reachable — so the plugin's route would vanish with nothing callable
|
|
38
|
+
in its place, and callers would get a 404 for something that used to work.`);
|
|
39
|
+
let r = [e.publicApi === void 0 ? void 0 : "publicApi", e.exposeAsTool === void 0 ? void 0 : "exposeAsTool"].filter((e) => e !== void 0);
|
|
40
|
+
if (r.length === 0) return e;
|
|
41
|
+
throw Error(`${e.name}: \`internal: true\` cannot be combined with ${r.map((e) => `\`${e}\``).join(" or ")}. \`internal\` takes the procedure OFF the wire; those put it back ON a different one (${r.includes("publicApi") ? "a REST route" : "an agent tool"}), and that surface is projected without consulting the flag — so the procedure would be unreachable from your client and reachable from the internet. Drop \`internal: true\` if the wider surface is intended, or remove the ${r.join(" / ")} annotation if it is not.`);
|
|
42
|
+
}, k = (e) => {
|
|
43
|
+
let t = e.service;
|
|
44
|
+
if (t === void 0) return;
|
|
45
|
+
let n = t.callers;
|
|
46
|
+
if (!Array.isArray(n) || n.length === 0) throw Error(`${e.name}: \`service.callers\` is empty, so NO app may call this procedure —\n and no browser either. Name the calling app(s), e.g. \`service: { callers: ['worker'] }\`,
|
|
47
|
+
or drop \`service:\` if the procedure is meant for this app's own clients.`);
|
|
48
|
+
let r = n.filter((e) => typeof e != "string" || !D.test(e));
|
|
49
|
+
if (r.length > 0) throw Error(`${e.name}: \`service.callers\` holds ${r.map((e) => JSON.stringify(e)).join(", ")} — a caller is an\n app name (letters, digits, dashes; starting with a letter; at most 56 characters), the same name this app
|
|
50
|
+
lists in \`serviceCallers\` and the caller's credential resolves to.`);
|
|
51
|
+
if (new Set(n).size !== n.length) throw Error(`${e.name}: \`service.callers\` lists the same app twice`);
|
|
52
|
+
let i = [
|
|
53
|
+
e.internal === !0 ? "`internal: true` (it removes the wire surface a service calls over)" : void 0,
|
|
54
|
+
e.publicApi === void 0 ? void 0 : "`publicApi` (a REST route is for callers that are not the listed apps)",
|
|
55
|
+
e.exposeAsTool === void 0 ? void 0 : "`exposeAsTool` (an agent tool is not one of the listed apps)",
|
|
56
|
+
e.requiresApproval === void 0 ? void 0 : "`requiresApproval` (a second HUMAN cannot approve a machine call)",
|
|
57
|
+
e.overridesPlugin === !0 ? "`overridesPlugin` (a plugin route is a client surface; replacing it with a service-only one breaks its clients)" : void 0,
|
|
58
|
+
e.idempotencyScope === "connection" ? "`idempotencyScope: 'connection'` (a service call dedups per service, across reconnects)" : void 0
|
|
59
|
+
].filter((e) => e !== void 0);
|
|
60
|
+
if (i.length !== 0) throw Error(`${e.name}: \`service:\` cannot be combined with ${i.join("; ")}.\n A service procedure is callable only by the listed apps of this project, over the
|
|
61
|
+
socket, with their service credential. Drop the other field, or drop \`service:\`.`);
|
|
62
|
+
}, A = (e) => {
|
|
63
|
+
let t = e.requiresApproval;
|
|
64
|
+
if (t !== void 0) {
|
|
65
|
+
if (!Array.isArray(t.approvers) || t.approvers.length === 0) throw Error(`${e.name}: \`requiresApproval.approvers\` is empty, so NOBODY can approve this\n procedure and every call would park forever. Name the scope(s) an approver must hold
|
|
66
|
+
— e.g. \`approvers: [{ scope: 'invoices:approve' }]\`.`);
|
|
67
|
+
if (e.openAccess !== void 0) throw Error(`${e.name}: \`requiresApproval\` cannot be combined with \`openAccess\`.\n The self-approval refusal compares subject ids, and an unauthenticated caller has
|
|
68
|
+
none — so on an open procedure every anonymous caller would count as a DIFFERENT
|
|
69
|
+
human from every other, and the second-pair-of-eyes control would enforce nothing.
|
|
70
|
+
Give the procedure a \`guards:\` decision, or drop \`requiresApproval\`.`);
|
|
71
|
+
}
|
|
72
|
+
}, ee = () => ({ upgraded: !0 }), te = (e) => e.action !== void 0 && e.resourceType !== void 0, ne = (e) => e.authenticated === !0, j = (e) => e.upgraded === !0, M = (e) => e.openAccess !== void 0 || e.guards !== void 0 && e.guards.length > 0, N = (e, t, n, r) => {
|
|
73
|
+
for (let e of t ?? []) {
|
|
74
|
+
let t = l(e);
|
|
75
|
+
if (t) throw t;
|
|
76
|
+
}
|
|
77
|
+
if (r !== void 0) {
|
|
78
|
+
if (n !== void 0 || t !== void 0 && t.length > 0) throw Error(`${e}: \`service:\` is an access decision of its own — only the listed apps may\n call this procedure — so it cannot sit beside \`guards:\` or \`openAccess:\`. A service
|
|
79
|
+
holds no scopes, and no user may call a service procedure. Keep exactly one.`);
|
|
80
|
+
return Array.isArray(r.callers) ? [c(r.callers)] : void 0;
|
|
81
|
+
}
|
|
82
|
+
if (n === void 0) return t;
|
|
83
|
+
if (n.trim() === "") throw Error(`${e}: \`openAccess\` needs a REASON, not an empty string. It is the sentence a\n reviewer reads to decide whether this procedure should really be callable
|
|
84
|
+
without an authorization check — e.g. \`openAccess: 'public pricing, no caller data'\`.`);
|
|
85
|
+
if (t !== void 0 && t.length > 0) throw Error(`${e}: \`openAccess\` and \`guards\` are two different access decisions, so\n declaring both says the procedure is protected AND open. Keep the guards if a
|
|
86
|
+
caller must hold a scope; drop them if anyone may call it.`);
|
|
87
|
+
return [s(n.trim())];
|
|
88
|
+
}, P = (e) => {
|
|
89
|
+
let t = v(e.source), n = y(e.name, t, e.optionalSource);
|
|
90
|
+
return O({
|
|
91
|
+
kind: "query",
|
|
92
|
+
name: e.name,
|
|
93
|
+
input: e.input,
|
|
94
|
+
output: e.output,
|
|
95
|
+
error: e.error ?? b.Never,
|
|
96
|
+
source: t,
|
|
97
|
+
...n === void 0 ? {} : { optionalSource: n },
|
|
98
|
+
cache: e.cache,
|
|
99
|
+
guards: N(e.name, e.guards, e.openAccess, e.service),
|
|
100
|
+
openAccess: e.openAccess,
|
|
101
|
+
service: e.service === void 0 ? void 0 : { callers: Array.isArray(e.service.callers) ? [...e.service.callers] : e.service.callers },
|
|
102
|
+
publicApi: e.publicApi,
|
|
103
|
+
exposeAsTool: e.exposeAsTool,
|
|
104
|
+
internal: e.internal,
|
|
105
|
+
overridesPlugin: e.overridesPlugin
|
|
106
|
+
});
|
|
107
|
+
}, F = (e) => O({
|
|
108
|
+
kind: "mutation",
|
|
109
|
+
name: e.name,
|
|
110
|
+
input: e.input,
|
|
111
|
+
output: e.output,
|
|
112
|
+
error: e.error ?? b.Never,
|
|
113
|
+
...e.idempotencyScope === void 0 ? {} : { idempotencyScope: e.idempotencyScope },
|
|
114
|
+
...e.serialize === void 0 ? {} : { serialize: e.serialize },
|
|
115
|
+
...e.undo === void 0 ? {} : { undo: e.undo },
|
|
116
|
+
target: e.target,
|
|
117
|
+
guards: N(e.name, e.guards, e.openAccess, e.service),
|
|
118
|
+
openAccess: e.openAccess,
|
|
119
|
+
service: e.service === void 0 ? void 0 : { callers: Array.isArray(e.service.callers) ? [...e.service.callers] : e.service.callers },
|
|
120
|
+
publicApi: e.publicApi,
|
|
121
|
+
exposeAsTool: e.exposeAsTool,
|
|
122
|
+
requiresApproval: e.requiresApproval,
|
|
123
|
+
internal: e.internal,
|
|
124
|
+
overridesPlugin: e.overridesPlugin
|
|
125
|
+
}), I = (e) => O({
|
|
126
|
+
kind: "action",
|
|
127
|
+
name: e.name,
|
|
128
|
+
input: e.input,
|
|
129
|
+
output: e.output,
|
|
130
|
+
error: e.error ?? b.Never,
|
|
131
|
+
guards: N(e.name, e.guards, e.openAccess, e.service),
|
|
132
|
+
openAccess: e.openAccess,
|
|
133
|
+
service: e.service === void 0 ? void 0 : { callers: Array.isArray(e.service.callers) ? [...e.service.callers] : e.service.callers },
|
|
134
|
+
source: e.source,
|
|
135
|
+
target: e.target,
|
|
136
|
+
publicApi: e.publicApi,
|
|
137
|
+
exposeAsTool: e.exposeAsTool,
|
|
138
|
+
requiresApproval: e.requiresApproval,
|
|
139
|
+
internal: e.internal,
|
|
140
|
+
overridesPlugin: e.overridesPlugin
|
|
141
|
+
}), L = (e) => O({
|
|
142
|
+
kind: "stream",
|
|
143
|
+
name: e.name,
|
|
144
|
+
input: e.input,
|
|
145
|
+
element: e.element,
|
|
146
|
+
error: e.error ?? b.Never,
|
|
147
|
+
internal: e.internal,
|
|
148
|
+
overridesPlugin: e.overridesPlugin,
|
|
149
|
+
guards: N(e.name, e.guards, e.openAccess),
|
|
150
|
+
openAccess: e.openAccess
|
|
151
|
+
}), R = (e, t) => t && t.length > 0 ? b.Union([e, ...new Set(t)]) : e, z = (e) => e !== void 0 && e.some((e) => !o(e)), B = (e) => b.Union([
|
|
152
|
+
e,
|
|
153
|
+
i,
|
|
154
|
+
n,
|
|
155
|
+
t
|
|
156
|
+
]), V = (e) => b.Union([e, d]), H = (e) => b.Union([
|
|
157
|
+
e,
|
|
158
|
+
h,
|
|
159
|
+
g
|
|
160
|
+
]), U = (e, t) => t === void 0 ? e : b.Union([e, _]), W = (e, t) => a(t) ? b.Union([e, r]) : e, G = (e, t, n) => R(K(e, t), n), K = (e, t) => {
|
|
161
|
+
let n = W(B(e.error), e.guards);
|
|
162
|
+
if (t === "stream" || t === "query") return n;
|
|
163
|
+
let r = t === "mutation" ? b.Union([
|
|
164
|
+
V(n),
|
|
165
|
+
m,
|
|
166
|
+
p,
|
|
167
|
+
S
|
|
168
|
+
]) : b.Union([
|
|
169
|
+
n,
|
|
170
|
+
m,
|
|
171
|
+
p
|
|
172
|
+
]);
|
|
173
|
+
return U(H(t === "mutation" && e.idempotencyScope === "connection" ? b.Union([r, f]) : r), e.requiresApproval);
|
|
174
|
+
}, q = {
|
|
175
|
+
query: [
|
|
176
|
+
i,
|
|
177
|
+
n,
|
|
178
|
+
t
|
|
179
|
+
],
|
|
180
|
+
stream: [
|
|
181
|
+
i,
|
|
182
|
+
n,
|
|
183
|
+
t
|
|
184
|
+
],
|
|
185
|
+
action: [
|
|
186
|
+
i,
|
|
187
|
+
n,
|
|
188
|
+
t,
|
|
189
|
+
m,
|
|
190
|
+
p,
|
|
191
|
+
h,
|
|
192
|
+
g
|
|
193
|
+
],
|
|
194
|
+
mutation: [
|
|
195
|
+
i,
|
|
196
|
+
n,
|
|
197
|
+
t,
|
|
198
|
+
d,
|
|
199
|
+
m,
|
|
200
|
+
p,
|
|
201
|
+
S,
|
|
202
|
+
h,
|
|
203
|
+
g
|
|
204
|
+
]
|
|
205
|
+
}, J = (e, t) => R(W(B(e.errorSchema), e.guards), t), Y = (e, t) => ({
|
|
206
|
+
...e,
|
|
207
|
+
name: t
|
|
208
|
+
}), X = (t, n) => x.make(t.name, {
|
|
209
|
+
payload: u(t.input, t.name, z(t.guards)),
|
|
210
|
+
success: e(t.output),
|
|
211
|
+
error: G(t, "query", n),
|
|
212
|
+
stream: !0
|
|
213
|
+
}), Z = (e, t) => x.make(e.name, {
|
|
214
|
+
payload: u(e.input, e.name, z(e.guards)),
|
|
215
|
+
success: e.output,
|
|
216
|
+
error: G(e, "mutation", t)
|
|
217
|
+
}), Q = (e, t) => x.make(e.name, {
|
|
218
|
+
payload: u(e.input, e.name, z(e.guards)),
|
|
219
|
+
success: e.output,
|
|
220
|
+
error: G(e, "action", t)
|
|
221
|
+
}), $ = (e, t) => x.make(e.name, {
|
|
222
|
+
payload: u(e.input, e.name, z(e.guards)),
|
|
223
|
+
success: e.element,
|
|
224
|
+
error: G(e, "stream", t),
|
|
225
|
+
stream: !0
|
|
226
|
+
}), re = (e) => {
|
|
227
|
+
switch (e.kind) {
|
|
228
|
+
case "query": return X(e);
|
|
229
|
+
case "mutation": return Z(e);
|
|
230
|
+
case "action": return Q(e);
|
|
231
|
+
case "stream": return $(e);
|
|
232
|
+
}
|
|
233
|
+
}, ie = (e) => {
|
|
234
|
+
let t = e.input, n = t === void 0 ? {} : { input: t }, r = e.output, i = r === void 0 ? {} : { output: r }, a = {
|
|
235
|
+
...n,
|
|
236
|
+
...i,
|
|
237
|
+
error: e.error
|
|
238
|
+
};
|
|
239
|
+
if (e.kind === "query") return {
|
|
240
|
+
kind: "query",
|
|
241
|
+
source: e.source,
|
|
242
|
+
...a
|
|
243
|
+
};
|
|
244
|
+
if (e.kind === "action") return {
|
|
245
|
+
kind: "action",
|
|
246
|
+
...a
|
|
247
|
+
};
|
|
248
|
+
if (e.kind === "stream") return {
|
|
249
|
+
kind: "stream",
|
|
250
|
+
...a
|
|
251
|
+
};
|
|
252
|
+
let o = e.target, s = e.idempotencyScope === void 0 ? {} : { idempotencyScope: e.idempotencyScope }, c = e.serialize === void 0 ? {} : { serialize: e.serialize };
|
|
253
|
+
if (o === void 0) return {
|
|
254
|
+
kind: "mutation",
|
|
255
|
+
...a,
|
|
256
|
+
...s,
|
|
257
|
+
...c
|
|
258
|
+
};
|
|
259
|
+
let l = Array.isArray(o) ? o : [o];
|
|
260
|
+
return {
|
|
261
|
+
kind: "mutation",
|
|
262
|
+
...a,
|
|
263
|
+
...s,
|
|
264
|
+
...c,
|
|
265
|
+
targets: l.map((e) => ({
|
|
266
|
+
table: e.table,
|
|
267
|
+
op: e.op,
|
|
268
|
+
..."order" in e && e.order !== void 0 ? { order: e.order } : {},
|
|
269
|
+
..."shape" in e && e.shape !== void 0 ? { shape: e.shape } : {},
|
|
270
|
+
..."identify" in e && e.identify !== void 0 ? { identify: e.identify } : {},
|
|
271
|
+
..."path" in e && e.path !== void 0 ? { path: e.path } : {},
|
|
272
|
+
..."by" in e && e.by !== void 0 ? { by: e.by } : {},
|
|
273
|
+
..."match" in e && e.match !== void 0 ? { match: e.match } : {},
|
|
274
|
+
..."shapeItem" in e && e.shapeItem !== void 0 ? { shapeItem: e.shapeItem } : {},
|
|
275
|
+
..."relations" in e && e.relations !== void 0 ? { relations: e.relations } : {}
|
|
276
|
+
}))
|
|
277
|
+
};
|
|
278
|
+
};
|
|
279
|
+
//#endregion
|
|
280
|
+
export { q as FRAMEWORK_WIRE_ERRORS, D as SERVICE_NAME_PATTERN, Q as actionToRpc, I as defineAction, F as defineMutation, P as defineQuery, L as defineStream, M as hasAccessDecision, z as hasEnforcedGuard, ne as isAuthenticatedGuard, T as isClientReachable, te as isPolicyGuard, E as isServiceReachable, j as isUpgradedGuard, C as isWireReachable, Z as mutationToRpc, ie as normalizeDescriptor, X as queryToRpc, ee as requireUpgraded, $ as streamToRpc, re as toRpc, w as wireAudienceOf, G as wireErrorUnion, Y as withRpcTag, J as workflowWireErrorUnion };
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { checkGuardsEffect as e } from "./scopes.js";
|
|
2
|
+
import { declaredErrorTags as t, errorMemberSchema as n } from "./errorSchema.js";
|
|
3
|
+
import { schemaShape as r, shapeDigest as i } from "./schemaShape.js";
|
|
4
|
+
import { validateHttpStreamMaxDuration as a } from "./httpStreamMaxDuration.js";
|
|
5
|
+
import { encodeRestError as o, resolveRestFormat as s, restViewSchema as c, toSnakeCase as l } from "./restFormat.js";
|
|
6
|
+
import { RestRouteError as u, defineRestRoute as ee, requireAuthenticated as d, requireScope as f, response as p, sse as te, sseFrame as m } from "./rest.js";
|
|
7
|
+
import { Effect as h, Schema as g, SchemaGetter as _, SchemaIssue as ne } from "effect";
|
|
8
|
+
import * as v from "effect/SchemaAST";
|
|
9
|
+
//#region src/publicApi.ts
|
|
10
|
+
var y = (e, t, n) => t.method ?? (t.resource !== void 0 && n !== void 0 ? C("", t, n).method : void 0) ?? (e === "query" ? "GET" : "POST"), b = (e, t, n) => w(t.path ?? (t.resource !== void 0 && n !== void 0 ? C(e, t, n).path : `/${t.version ?? "v1"}/${e.replace(/\./g, "/")}`)), x = (e) => {
|
|
11
|
+
let t = e.split("/").pop() ?? e;
|
|
12
|
+
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;
|
|
13
|
+
}, S = (e, t) => {
|
|
14
|
+
let n = t != null && (typeof t == "object" || typeof t == "function") && "ast" in t ? F(t) : void 0;
|
|
15
|
+
if (n === void 0) return;
|
|
16
|
+
let r = `${x(e)}Id`;
|
|
17
|
+
return n.has(r) ? r : n.has("id") ? "id" : void 0;
|
|
18
|
+
}, C = (e, t, n) => {
|
|
19
|
+
let r = (t.resource ?? "").replace(/^\/+|\/+$/g, ""), i = `/${t.version ?? "v1"}/${r}`, a = S(r, n.input), o = a === void 0 ? i : `${i}/:${a}`, s = e.split(".").pop() ?? e, c = n.target?.op;
|
|
20
|
+
return n.kind === "query" || n.kind === "stream" ? {
|
|
21
|
+
method: "GET",
|
|
22
|
+
path: o
|
|
23
|
+
} : n.kind === "mutation" && c === "insert" ? {
|
|
24
|
+
method: "POST",
|
|
25
|
+
path: i
|
|
26
|
+
} : n.kind === "mutation" && c === "update" ? {
|
|
27
|
+
method: a === void 0 ? "POST" : "PATCH",
|
|
28
|
+
path: o
|
|
29
|
+
} : n.kind === "mutation" && c === "delete" ? {
|
|
30
|
+
method: a === void 0 ? "POST" : "DELETE",
|
|
31
|
+
path: o
|
|
32
|
+
} : {
|
|
33
|
+
method: "POST",
|
|
34
|
+
path: `${o}/${s}`
|
|
35
|
+
};
|
|
36
|
+
}, w = (e) => e.replace(/\{([A-Za-z0-9_]+)\}/g, ":$1"), T = (e) => [...e.matchAll(/:([A-Za-z0-9_]+)/g)].map((e) => e[1]), E = (e) => {
|
|
37
|
+
if (v.isUnion(e)) {
|
|
38
|
+
let t = e.types.filter((e) => !v.isUndefined(e));
|
|
39
|
+
if (t.length === 1) return t[0];
|
|
40
|
+
if (t.length !== e.types.length) return new v.Union(t);
|
|
41
|
+
}
|
|
42
|
+
return e;
|
|
43
|
+
}, D = /^-?(\d+\.?\d*|\.\d+)(e[+-]?\d+)?$/i, O = (e, t) => {
|
|
44
|
+
let n = E(t);
|
|
45
|
+
if (n.encoding !== void 0) return O(e, v.toEncoded(n));
|
|
46
|
+
if (v.isUnion(n)) {
|
|
47
|
+
for (let t of n.types) {
|
|
48
|
+
let n = O(e, t);
|
|
49
|
+
if (n !== e) return n;
|
|
50
|
+
}
|
|
51
|
+
return e;
|
|
52
|
+
}
|
|
53
|
+
if (v.isArrays(n)) {
|
|
54
|
+
let t = Array.isArray(e) ? e : e === void 0 ? void 0 : [e];
|
|
55
|
+
if (t === void 0) return e;
|
|
56
|
+
let r = n.rest[0] ?? n.elements[0];
|
|
57
|
+
return r === void 0 ? t : t.map((e) => O(e, r));
|
|
58
|
+
}
|
|
59
|
+
if (typeof e != "string") return e;
|
|
60
|
+
if (v.isNumber(n)) return D.test(e.trim()) ? Number(e) : e;
|
|
61
|
+
if (v.isBoolean(n)) return e === "true" || e !== "false" && e;
|
|
62
|
+
if (v.isLiteral(n)) {
|
|
63
|
+
let t = n.literal;
|
|
64
|
+
return typeof t == "number" && D.test(e.trim()) && Number(e) === t || typeof t == "boolean" && String(t) === e ? t : e;
|
|
65
|
+
}
|
|
66
|
+
return e;
|
|
67
|
+
}, k = (e, t) => {
|
|
68
|
+
if (typeof e != "object" || !e || Array.isArray(e)) return e;
|
|
69
|
+
let n = E(v.toEncoded(t.ast));
|
|
70
|
+
if (!v.isObjects(n)) return e;
|
|
71
|
+
let r = { ...e };
|
|
72
|
+
for (let e of n.propertySignatures) {
|
|
73
|
+
let t = String(e.name);
|
|
74
|
+
t in r && (r[t] = O(r[t], e.type));
|
|
75
|
+
}
|
|
76
|
+
return r;
|
|
77
|
+
}, re = (e) => {
|
|
78
|
+
let t = E(v.toEncoded(e.ast));
|
|
79
|
+
if (!v.isObjects(t)) return (e) => e;
|
|
80
|
+
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, {
|
|
81
|
+
type: e.type,
|
|
82
|
+
order: t
|
|
83
|
+
}), !0));
|
|
84
|
+
return (e) => {
|
|
85
|
+
if (typeof e != "object" || !e || Array.isArray(e)) return e;
|
|
86
|
+
let t = { ...e }, a = i ? Object.keys(t) : void 0;
|
|
87
|
+
if (a !== void 0 && a.length * 4 < n.length) {
|
|
88
|
+
let e = [];
|
|
89
|
+
for (let t of a) {
|
|
90
|
+
let n = r.get(t);
|
|
91
|
+
n !== void 0 && e.push({
|
|
92
|
+
key: t,
|
|
93
|
+
...n
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
e.sort((e, t) => e.order - t.order);
|
|
97
|
+
for (let { key: n, type: r } of e) t[n] = O(t[n], r);
|
|
98
|
+
} else for (let e of n) {
|
|
99
|
+
let n = String(e.name);
|
|
100
|
+
n in t && (t[n] = O(t[n], e.type));
|
|
101
|
+
}
|
|
102
|
+
return t;
|
|
103
|
+
};
|
|
104
|
+
}, A = (e, t, n) => {
|
|
105
|
+
if (n !== void 0) try {
|
|
106
|
+
let r = g.encodeUnknownSync(n)(e);
|
|
107
|
+
if (typeof r == "object" && r && !Array.isArray(r)) return {
|
|
108
|
+
error: t,
|
|
109
|
+
...r
|
|
110
|
+
};
|
|
111
|
+
} catch {}
|
|
112
|
+
throw Error("Typed REST failure is incompatible with its declared schema");
|
|
113
|
+
}, j = (e, n, r, i = []) => M(e, n, r, i, t), M = (e, t, n, r, i) => {
|
|
114
|
+
if (typeof e != "object" || !e) return e;
|
|
115
|
+
let a = e._tag;
|
|
116
|
+
if (typeof a != "string" || a === "ScopeError" || a === "NoSuchResource") return e;
|
|
117
|
+
if (i(t.error).has(a)) {
|
|
118
|
+
let r = n.errorStatus?.[a] ?? 422;
|
|
119
|
+
return new u(r, A(e, a, t.error));
|
|
120
|
+
}
|
|
121
|
+
let o = r.find((e) => i(e.schema).has(a));
|
|
122
|
+
if (o === void 0) return e;
|
|
123
|
+
let s = n.errorStatus?.[a] ?? o.rest?.status ?? 422, c = o.rest?.headers?.(e);
|
|
124
|
+
return new u(s, A(e, a, o.schema), c);
|
|
125
|
+
}, N = (e, t, n, r, i, a, s) => {
|
|
126
|
+
let c = M(e, t, n, r, s);
|
|
127
|
+
if (!(c instanceof u) || i.errors === "tagged" && i.encodeError === void 0) return c;
|
|
128
|
+
let { error: l, _tag: ee, ...d } = c.body, f = typeof d.message == "string" ? d.message : typeof d.reason == "string" ? d.reason : "", p = o(i, {
|
|
129
|
+
status: c.status,
|
|
130
|
+
tag: l,
|
|
131
|
+
message: f,
|
|
132
|
+
fields: d
|
|
133
|
+
}, {
|
|
134
|
+
...a,
|
|
135
|
+
status: c.status
|
|
136
|
+
});
|
|
137
|
+
return new u(c.status, p.body, {
|
|
138
|
+
...c.headers ?? {},
|
|
139
|
+
...p.headers ?? {}
|
|
140
|
+
}, p.contentType);
|
|
141
|
+
}, P = (e) => e.split(".").map((e, t) => t === 0 ? e : e.charAt(0).toUpperCase() + e.slice(1)).join("").replace(/[^A-Za-z0-9_]/g, "_"), F = (e) => {
|
|
142
|
+
let t = E(v.toEncoded(e.ast));
|
|
143
|
+
return v.isObjects(t) && t.indexSignatures.length === 0 ? new Set(t.propertySignatures.map((e) => String(e.name))) : void 0;
|
|
144
|
+
}, I = (e, t) => e === t || JSON.stringify(e) === JSON.stringify(t), ie = (e) => {
|
|
145
|
+
let t = E(v.toEncoded(e.ast)), n = v.isObjects(t) ? new Map(t.propertySignatures.map((e) => [String(e.name), e.type])) : /* @__PURE__ */ new Map();
|
|
146
|
+
return (e) => {
|
|
147
|
+
let t = {};
|
|
148
|
+
for (let [r, i] of Object.entries(e)) {
|
|
149
|
+
let e = n.get(r);
|
|
150
|
+
t[r] = e === void 0 ? i : O(i, e);
|
|
151
|
+
}
|
|
152
|
+
return t;
|
|
153
|
+
};
|
|
154
|
+
}, L = (e, t) => {
|
|
155
|
+
if (e !== void 0) {
|
|
156
|
+
try {
|
|
157
|
+
return g.encodeUnknownSync(t)(e);
|
|
158
|
+
} catch {}
|
|
159
|
+
try {
|
|
160
|
+
return g.decodeUnknownSync(t)(e), e;
|
|
161
|
+
} catch {}
|
|
162
|
+
return e;
|
|
163
|
+
}
|
|
164
|
+
}, R = (e, t, n) => ({
|
|
165
|
+
...e.request === void 0 ? {} : { request: L(e.request, t) },
|
|
166
|
+
...e.response === void 0 ? {} : { response: L(e.response, n) }
|
|
167
|
+
}), ae = () => (e) => {
|
|
168
|
+
if (e.subject.type !== "anonymous") return;
|
|
169
|
+
let t = e.subject.credentialRejected;
|
|
170
|
+
return t === void 0 ? void 0 : {
|
|
171
|
+
status: 401,
|
|
172
|
+
message: t
|
|
173
|
+
};
|
|
174
|
+
}, z = (n, r, i, o = {}) => {
|
|
175
|
+
let u = n.publicApi;
|
|
176
|
+
if (u === void 0) throw Error(`publicApiRoute: descriptor '${n.name}' has no publicApi annotation`);
|
|
177
|
+
let x = s(o.profile, u.format), S = o.pluginErrors ?? [], C = /* @__PURE__ */ new WeakMap(), w = (e) => {
|
|
178
|
+
if (e === void 0) return /* @__PURE__ */ new Set();
|
|
179
|
+
let n = C.get(e.ast);
|
|
180
|
+
if (n !== void 0) return n;
|
|
181
|
+
let r = t(e);
|
|
182
|
+
return C.set(e.ast, r), r;
|
|
183
|
+
}, E = /* @__PURE__ */ new WeakMap(), D = (e, t) => {
|
|
184
|
+
if (e === void 0) return;
|
|
185
|
+
let n = E.get(e.ast);
|
|
186
|
+
if (n === void 0) {
|
|
187
|
+
let t = /* @__PURE__ */ new Map();
|
|
188
|
+
for (let n of v.isUnion(e.ast) ? e.ast.types : [e.ast]) {
|
|
189
|
+
let e = g.make(n);
|
|
190
|
+
for (let n of w(e)) t.has(n) || t.set(n, e);
|
|
191
|
+
}
|
|
192
|
+
n = t, E.set(e.ast, n);
|
|
193
|
+
}
|
|
194
|
+
return n.get(t);
|
|
195
|
+
}, O = {
|
|
196
|
+
kind: n.kind,
|
|
197
|
+
input: n.input,
|
|
198
|
+
target: n.target
|
|
199
|
+
}, k = y(n.kind, u, O), A = (e) => x.naming === "snake_case" ? l(e) : e, j = b(n.name, u, O), M = j.replace(/:([A-Za-z0-9_]+)/g, (e, t) => `:${A(t)}`), L = T(M), z = c(n.input, x), B = re(z), V = ie(z), H = F(z);
|
|
200
|
+
if (H !== void 0) {
|
|
201
|
+
for (let e of L) if (!H.has(e)) throw Error(`publicApi: descriptor '${n.name}' — path '${j}' binds ':${e}', and the input declares no field of that name` + (H.size > 0 ? ` (fields: ${[...H].join(", ")})` : " (the input declares no fields)"));
|
|
202
|
+
}
|
|
203
|
+
let U = c(n.output, x), oe = g.Struct({ value: z }), W = k !== "GET" && H === void 0;
|
|
204
|
+
if (k !== "GET" && H !== void 0) {
|
|
205
|
+
let e = L.length >= 32 ? new Set(L) : void 0;
|
|
206
|
+
for (let t of H) if (!(e?.has(t) ?? L.includes(t))) {
|
|
207
|
+
W = !0;
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
let G = {
|
|
212
|
+
query: g.Unknown,
|
|
213
|
+
params: g.Unknown,
|
|
214
|
+
form: g.Boolean
|
|
215
|
+
}, se = (W ? g.Struct({
|
|
216
|
+
...G,
|
|
217
|
+
body: g.Unknown
|
|
218
|
+
}) : g.Struct(G)).pipe(g.decodeTo(oe, {
|
|
219
|
+
decode: _.transformEffect((e) => {
|
|
220
|
+
let t = "body" in e ? e.body : void 0, n = k === "GET" ? B(e.query) : e.form ? B(t ?? {}) : t ?? {}, r = typeof e.params == "object" && e.params !== null ? V(e.params) : {};
|
|
221
|
+
if (typeof n != "object" || !n || Array.isArray(n)) return h.succeed({ value: n });
|
|
222
|
+
let i = n, a = Object.keys(r), o = 0;
|
|
223
|
+
for (let e of a) e in i && !I(i[e], r[e]) && (a[o++] = e);
|
|
224
|
+
if (a.length = o, a.length > 0) {
|
|
225
|
+
let t = k === "GET" ? "query string" : "body";
|
|
226
|
+
return h.fail(new ne.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));
|
|
227
|
+
}
|
|
228
|
+
return h.succeed({ value: {
|
|
229
|
+
...i,
|
|
230
|
+
...r
|
|
231
|
+
} });
|
|
232
|
+
}),
|
|
233
|
+
encode: _.transform((e) => e)
|
|
234
|
+
})), K = [
|
|
235
|
+
ae(),
|
|
236
|
+
...n.openAccess === void 0 ? [d()] : [],
|
|
237
|
+
...(u.scopes ?? []).map((e) => f(e))
|
|
238
|
+
], q = (() => {
|
|
239
|
+
let e = n.source;
|
|
240
|
+
return typeof e == "string" ? e : Array.isArray(e) ? e[0] : void 0;
|
|
241
|
+
})(), ce = (e, t = 200) => ({
|
|
242
|
+
tag: n.name,
|
|
243
|
+
method: e.method,
|
|
244
|
+
path: e.path,
|
|
245
|
+
query: e.query,
|
|
246
|
+
source: q,
|
|
247
|
+
status: t
|
|
248
|
+
});
|
|
249
|
+
K.push(async (t, r) => {
|
|
250
|
+
if (r === void 0 || typeof r.input != "object" || r.input === null) throw Error("Projected REST admission input is unavailable");
|
|
251
|
+
let i = await h.runPromise(e(t.subject, n.guards, r.input.value, {
|
|
252
|
+
defaultDeny: r.defaultDeny,
|
|
253
|
+
procedure: n.name
|
|
254
|
+
}));
|
|
255
|
+
if (i) throw i;
|
|
256
|
+
});
|
|
257
|
+
let J = u.stream === "sse" && n.kind === "query" && i !== void 0, Y = a(u.streamMaxDurationMs);
|
|
258
|
+
if (Y !== void 0 && !J) throw Error(`${n.name}: streamMaxDurationMs requires an SSE query subscription`);
|
|
259
|
+
let le = J ? (e, t) => te((n) => i(e.value, t, (e) => {
|
|
260
|
+
n(m(String(e._tag ?? "message"), e));
|
|
261
|
+
}), Y === void 0 ? {} : { maxDurationMs: Y }) : async (e, t) => {
|
|
262
|
+
let n = await r(e.value, t);
|
|
263
|
+
return p(n);
|
|
264
|
+
}, X = n.error, Z = w(X), ue = [...Z], Q = [];
|
|
265
|
+
for (let e of Object.values(u.additionalErrorStatuses ?? {})) if (e.some((e) => !Number.isInteger(e) || e < 400 || e > 599)) throw Error(`publicApi.additionalErrorStatuses for ${n.name} must contain HTTP error statuses (400–599)`);
|
|
266
|
+
let $ = (e, t, n) => {
|
|
267
|
+
for (let r of /* @__PURE__ */ new Set([t, ...u.additionalErrorStatuses?.[e] ?? []])) Q.some((t) => t.tag === e && t.status === r) || Q.push({
|
|
268
|
+
status: r,
|
|
269
|
+
tag: e,
|
|
270
|
+
schema: n
|
|
271
|
+
});
|
|
272
|
+
};
|
|
273
|
+
for (let e of ue) {
|
|
274
|
+
let t = D(X, e);
|
|
275
|
+
t !== void 0 && $(e, u.errorStatus?.[e] ?? 422, t);
|
|
276
|
+
}
|
|
277
|
+
for (let e of S) for (let t of w(e.schema)) Z.has(t) || $(t, u.errorStatus?.[t] ?? e.rest?.status ?? 422, D(e.schema, t) ?? e.schema);
|
|
278
|
+
let de = u.security === !1 ? "none" : u.security ?? (n.openAccess === void 0 ? "required" : "optional"), fe = {
|
|
279
|
+
tag: n.name,
|
|
280
|
+
kind: n.kind,
|
|
281
|
+
version: u.version ?? "v1",
|
|
282
|
+
security: de,
|
|
283
|
+
idempotent: u.idempotent === !0,
|
|
284
|
+
input: z,
|
|
285
|
+
pathParams: L,
|
|
286
|
+
output: U,
|
|
287
|
+
source: q,
|
|
288
|
+
errorResponses: Q,
|
|
289
|
+
format: x
|
|
290
|
+
};
|
|
291
|
+
return ee({
|
|
292
|
+
publicApiDescriptor: n,
|
|
293
|
+
mapFailure: (e, t) => N(e, n, u, S, x, ce(t), w),
|
|
294
|
+
method: k,
|
|
295
|
+
path: M,
|
|
296
|
+
input: se,
|
|
297
|
+
output: U,
|
|
298
|
+
handler: le,
|
|
299
|
+
...J ? { streaming: !0 } : {},
|
|
300
|
+
guards: K,
|
|
301
|
+
operationId: u.operationId ?? P(n.name),
|
|
302
|
+
tags: u.tags ?? [n.name.split(".")[0] ?? n.name],
|
|
303
|
+
projection: fe,
|
|
304
|
+
...x.etag && k === "GET" && !J ? { etag: !0 } : {},
|
|
305
|
+
...u.cache !== void 0 && k === "GET" && !J ? { cache: u.cache } : {},
|
|
306
|
+
...u.example === void 0 ? {} : { example: R(u.example, z, U) },
|
|
307
|
+
...u.summary === void 0 ? {} : { summary: u.summary },
|
|
308
|
+
...u.description === void 0 ? {} : { description: u.description },
|
|
309
|
+
...u.deprecated === void 0 ? {} : { deprecated: u.deprecated },
|
|
310
|
+
...u.sunset === void 0 ? {} : { sunset: u.sunset }
|
|
311
|
+
});
|
|
312
|
+
}, B = (e, t = {}) => e.filter((e) => e.descriptor.publicApi !== void 0).map((e) => z(e.descriptor, e.invoke, e.subscribe, t)).sort((e, t) => e.path.localeCompare(t.path)), V = (e) => i(e.filter((e) => e.projection !== void 0).map((e) => {
|
|
313
|
+
let t = e.projection, n = {
|
|
314
|
+
tag: t.tag,
|
|
315
|
+
method: e.method,
|
|
316
|
+
path: e.path,
|
|
317
|
+
pathParams: t.pathParams,
|
|
318
|
+
version: t.version,
|
|
319
|
+
security: t.security,
|
|
320
|
+
errors: [...t.errorResponses].map((e) => `${e.status}:${e.tag}`).sort()
|
|
321
|
+
};
|
|
322
|
+
return `${JSON.stringify(n)} ${r(t.input.ast)} ${r(t.output.ast)}`;
|
|
323
|
+
}).sort().join("\n"));
|
|
324
|
+
//#endregion
|
|
325
|
+
export { k as coerceQueryObject, O as coerceQueryValue, B as collectPublicApiRoutes, t as declaredErrorTags, y as derivePublicMethod, b as derivePublicPath, C as deriveResource, n as errorMemberSchema, w as normalizePathParams, P as operationIdOf, T as pathParamNames, j as projectedFailure, z as publicApiRoute, V as publicSurfaceDigest, S as resourceIdField, R as wireExample };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/queryOptionalSources.ts
|
|
2
|
+
var e = (e, t, n) => {
|
|
3
|
+
if (n === void 0) return;
|
|
4
|
+
let r = new Set(t === void 0 ? [] : typeof t == "string" ? [t] : t), i = () => /* @__PURE__ */ Error(`${e}: optionalSource must contain unique names already declared in source`);
|
|
5
|
+
if (!Array.isArray(n)) throw i();
|
|
6
|
+
let a = [];
|
|
7
|
+
for (let e of n) {
|
|
8
|
+
if (typeof e != "string" || e.length === 0 || !r.has(e) || a.includes(e)) throw i();
|
|
9
|
+
a.push(e);
|
|
10
|
+
}
|
|
11
|
+
return Object.freeze(a);
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { e as captureOptionalQuerySources };
|
|
@@ -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 };
|