@voltro/protocol 0.63.0 → 0.64.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 +90 -0
- package/dist/index.d.ts +355 -23
- package/dist/index.js +503 -451
- package/dist/rest.d.ts +4 -1
- package/dist/rest.js +13 -13
- package/dist/{scopes-B0kGvAnI.js → scopes-D9t3tYc7.js} +98 -69
- package/dist/{serverErrorBus-BeN9pOpY.js → serverErrorBus-QQgyq6fV.js} +15 -7
- package/dist/session.js +1 -1
- package/package.json +3 -3
package/dist/rest.d.ts
CHANGED
|
@@ -532,7 +532,10 @@ declare interface PluginHttpRouteResult {
|
|
|
532
532
|
readonly status: number;
|
|
533
533
|
readonly body?: string | Uint8Array;
|
|
534
534
|
readonly contentType?: string;
|
|
535
|
-
|
|
535
|
+
/** Response headers. A header that repeats — two `Set-Cookie` lines, a
|
|
536
|
+
* session and a CSRF cookie from one login — is an ARRAY; `set-cookie`
|
|
537
|
+
* arrays become separate lines, every other array joins with `, `. */
|
|
538
|
+
readonly headers?: Record<string, string | ReadonlyArray<string>>;
|
|
536
539
|
/** Stream the response (SSE) instead of sending `body`. See
|
|
537
540
|
* {@link PluginHttpRouteStream}. */
|
|
538
541
|
readonly stream?: PluginHttpRouteStream;
|
package/dist/rest.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { P as e } from "./scopes-
|
|
2
|
-
import { a as t,
|
|
1
|
+
import { P as e } from "./scopes-D9t3tYc7.js";
|
|
2
|
+
import { a as t, c as n, o as r, s as i, t as a } from "./serverErrorBus-QQgyq6fV.js";
|
|
3
3
|
import { Effect as o, Schema as s } from "effect";
|
|
4
4
|
//#region src/publicApi.ts
|
|
5
5
|
var c = (e, t) => t.method ?? (e === "query" ? "GET" : "POST"), l = (e, t) => t.path ?? `/${t.version ?? "v1"}/${e.replace(/\./g, "/")}`, u = (e, t, n) => {
|
|
@@ -141,9 +141,9 @@ var c = (e, t) => t.method ?? (e === "query" ? "GET" : "POST"), l = (e, t) => t.
|
|
|
141
141
|
let t = await e(g);
|
|
142
142
|
if (t) return x(t.status, { error: t.message }, f);
|
|
143
143
|
}
|
|
144
|
-
let v = l.idempotency, S = v && E.has(c.method) ? s.headers[v.header.toLowerCase()] : void 0, C = v && S ?
|
|
144
|
+
let v = l.idempotency, S = v && E.has(c.method) ? s.headers[v.header.toLowerCase()] : void 0, C = v && S ? n(h.tenantId, c.method, c.path) : "";
|
|
145
145
|
if (v && S) {
|
|
146
|
-
let e = await
|
|
146
|
+
let e = await t(v.store, C, S, v.ttlMs, Date.now());
|
|
147
147
|
if (e.kind === "replay") return x(e.response.status, e.response.body, {
|
|
148
148
|
...f,
|
|
149
149
|
"Idempotency-Replayed": "true"
|
|
@@ -152,7 +152,7 @@ var c = (e, t) => t.method ?? (e === "query" ? "GET" : "POST"), l = (e, t) => t.
|
|
|
152
152
|
}
|
|
153
153
|
try {
|
|
154
154
|
let e = await c.handler(m, g);
|
|
155
|
-
if (_(e) || y(e)) return v && S && await
|
|
155
|
+
if (_(e) || y(e)) return v && S && await r(v.store, C, S), y(e) ? {
|
|
156
156
|
status: 200,
|
|
157
157
|
headers: f,
|
|
158
158
|
byteStream: e.byteStream,
|
|
@@ -162,26 +162,26 @@ var c = (e, t) => t.method ?? (e === "query" ? "GET" : "POST"), l = (e, t) => t.
|
|
|
162
162
|
headers: f,
|
|
163
163
|
stream: e.stream
|
|
164
164
|
};
|
|
165
|
-
let
|
|
166
|
-
if (v && S && await
|
|
165
|
+
let t = await o.runPromise(d(e));
|
|
166
|
+
if (v && S && await i(v.store, C, S, {
|
|
167
167
|
status: 200,
|
|
168
|
-
body:
|
|
168
|
+
body: t
|
|
169
169
|
}, Date.now()), c.etag === !0 && c.method === "GET") {
|
|
170
|
-
let e = `W/"${await b(JSON.stringify(
|
|
171
|
-
return
|
|
170
|
+
let e = `W/"${await b(JSON.stringify(t))}"`, n = s.headers["if-none-match"];
|
|
171
|
+
return n !== void 0 && n.split(",").some((t) => t.trim() === e) ? {
|
|
172
172
|
status: 304,
|
|
173
173
|
headers: {
|
|
174
174
|
...f,
|
|
175
175
|
ETag: e
|
|
176
176
|
}
|
|
177
|
-
} : x(200,
|
|
177
|
+
} : x(200, t, {
|
|
178
178
|
...f,
|
|
179
179
|
ETag: e
|
|
180
180
|
});
|
|
181
181
|
}
|
|
182
|
-
return x(200,
|
|
182
|
+
return x(200, t, f);
|
|
183
183
|
} catch (e) {
|
|
184
|
-
if (v && S && await
|
|
184
|
+
if (v && S && await r(v.store, C, S), typeof e == "object" && e && typeof e.status == "number") {
|
|
185
185
|
let t = e;
|
|
186
186
|
return x(t.status, { error: t.message ?? "Error" }, f);
|
|
187
187
|
}
|
|
@@ -33,21 +33,21 @@ var i = n.Record({
|
|
|
33
33
|
tenantId: n.Null,
|
|
34
34
|
scopes: a,
|
|
35
35
|
metadata: n.optional(i)
|
|
36
|
-
}),
|
|
36
|
+
}), d = n.Union(o, s, c, l, u), f = n.Union(o.omit("scopes"), s.omit("scopes"), c.omit("scopes"), l, u.omit("scopes")), p = (e) => {
|
|
37
37
|
if (e.type === "anonymous") return e;
|
|
38
38
|
let { scopes: t, ...n } = e;
|
|
39
39
|
return n;
|
|
40
|
-
},
|
|
40
|
+
}, m = (e) => e.scopes ?? [], h = (e, t) => ({
|
|
41
41
|
type: "anonymous",
|
|
42
42
|
id: null,
|
|
43
43
|
tenantId: e,
|
|
44
44
|
...t === void 0 ? {} : { credentialRejected: t }
|
|
45
|
-
}),
|
|
45
|
+
}), ee = (e, t = ["admin:full"]) => ({
|
|
46
46
|
type: "system",
|
|
47
47
|
id: e,
|
|
48
48
|
tenantId: null,
|
|
49
49
|
scopes: t
|
|
50
|
-
}),
|
|
50
|
+
}), te = (e, t) => {
|
|
51
51
|
let n = e;
|
|
52
52
|
return {
|
|
53
53
|
type: "serviceAccount",
|
|
@@ -56,15 +56,16 @@ var i = n.Record({
|
|
|
56
56
|
scopes: n.scopes ?? ["admin:full"],
|
|
57
57
|
...n.metadata === void 0 ? {} : { metadata: n.metadata }
|
|
58
58
|
};
|
|
59
|
-
}, g = (e) => e.type === "system", _ = "impersonation", v = (e) => e.metadata?.impersonation ?? null, y = class extends e.Tag("@voltro/Subject")() {}, b = class extends e.Tag("@voltro/ConnectionInfo")() {}, x = class extends r.Tag()("@voltro/AuthMiddleware", { provides: y }) {},
|
|
59
|
+
}, g = (e) => e.type === "system", _ = "impersonation", v = (e) => e.metadata?.impersonation ?? null, y = class extends e.Tag("@voltro/Subject")() {}, b = class extends e.Tag("@voltro/ConnectionInfo")() {}, x = class extends r.Tag()("@voltro/AuthMiddleware", { provides: y }) {}, ne = class extends r.Tag()("@voltro/ConnectionInfoMiddleware", { provides: b }) {}, S = (e) => typeof e.mountRoutes == "function", C = (e) => Array.isArray(e) ? {
|
|
60
60
|
kind: "grant",
|
|
61
61
|
scopes: e
|
|
62
|
-
} : e,
|
|
62
|
+
} : e, w = (e, t) => {
|
|
63
|
+
if (t.kind === "vetoed") throw new k({ reason: `${t.code}: ${t.message}` });
|
|
63
64
|
if (e.type === "anonymous") return {
|
|
64
65
|
subject: e,
|
|
65
66
|
removed: []
|
|
66
67
|
};
|
|
67
|
-
let n =
|
|
68
|
+
let n = m(e);
|
|
68
69
|
if (t.kind === "grant") {
|
|
69
70
|
if (t.scopes.length === 0) return {
|
|
70
71
|
subject: e,
|
|
@@ -87,14 +88,14 @@ var i = n.Record({
|
|
|
87
88
|
},
|
|
88
89
|
removed: i
|
|
89
90
|
};
|
|
90
|
-
},
|
|
91
|
+
}, re = 3e4, ie = 1e4, T = (e) => `${e.type}\u0000${e.tenantId ?? ""}\u0000${e.id ?? ""}`, ae = () => {
|
|
91
92
|
if (typeof process > "u") return;
|
|
92
93
|
let e = process.env.VOLTRO_AUTH_SCOPE_CACHE_TTL_MS;
|
|
93
94
|
if (e === void 0 || e === "") return;
|
|
94
95
|
let t = Number(e);
|
|
95
96
|
return Number.isFinite(t) && t >= 0 ? t : void 0;
|
|
96
|
-
},
|
|
97
|
-
let t = e.ttlMs ??
|
|
97
|
+
}, E = (e = {}) => {
|
|
98
|
+
let t = e.ttlMs ?? ae() ?? 3e4, n = e.maxEntries ?? 1e4, r = e.now ?? Date.now, i = /* @__PURE__ */ new Map(), a = () => {
|
|
98
99
|
if (i.size <= n) return;
|
|
99
100
|
let e = r();
|
|
100
101
|
for (let [t, n] of i) n.freshUntil <= e && i.delete(t);
|
|
@@ -130,80 +131,108 @@ var i = n.Record({
|
|
|
130
131
|
};
|
|
131
132
|
}
|
|
132
133
|
};
|
|
133
|
-
},
|
|
134
|
-
let n = t?.resolveScopes, r = n
|
|
135
|
-
return async (
|
|
136
|
-
let
|
|
137
|
-
...
|
|
138
|
-
store:
|
|
139
|
-
},
|
|
140
|
-
for (let
|
|
141
|
-
let e = await
|
|
134
|
+
}, D = (e) => typeof e.resolve == "function", O = (e, t) => {
|
|
135
|
+
let n = t?.resolveScopes, r = t?.subjectGuards ?? [], i = n !== void 0 || r.length > 0, a = !i || t?.scopeCache === !1 ? null : t?.scopeCache !== void 0 && D(t.scopeCache) ? t.scopeCache : E(t?.scopeCache ?? {});
|
|
136
|
+
return async (o) => {
|
|
137
|
+
let s = t?.getStore?.(), c = s === void 0 ? o : {
|
|
138
|
+
...o,
|
|
139
|
+
store: s
|
|
140
|
+
}, l;
|
|
141
|
+
for (let o of e) {
|
|
142
|
+
let e = await o.resolve(c);
|
|
142
143
|
if (e.kind === "matched") {
|
|
143
|
-
let
|
|
144
|
-
if (
|
|
145
|
-
let
|
|
146
|
-
|
|
144
|
+
let s = e.subject;
|
|
145
|
+
if (i) {
|
|
146
|
+
let i = async () => {
|
|
147
|
+
let t = n === void 0 ? {
|
|
148
|
+
kind: "grant",
|
|
149
|
+
scopes: []
|
|
150
|
+
} : C(await n(e.subject, c));
|
|
151
|
+
if (t.kind === "unavailable" || r.length === 0) return t;
|
|
152
|
+
let i = w(e.subject, t).subject, a = {
|
|
153
|
+
origin: "request",
|
|
154
|
+
headers: c.headers,
|
|
155
|
+
clientId: c.clientId,
|
|
156
|
+
store: c.store
|
|
157
|
+
};
|
|
158
|
+
for (let e of r) {
|
|
159
|
+
let t = await e(i, a);
|
|
160
|
+
if (!t.ok) return {
|
|
161
|
+
kind: "vetoed",
|
|
162
|
+
code: t.code,
|
|
163
|
+
message: t.message
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
return t;
|
|
167
|
+
}, { decision: l, fresh: u } = a === null ? {
|
|
168
|
+
decision: await i(),
|
|
147
169
|
fresh: !0
|
|
148
|
-
} : await
|
|
149
|
-
if (
|
|
150
|
-
let e =
|
|
170
|
+
} : await a.resolve(T(e.subject), i);
|
|
171
|
+
if (l.kind === "vetoed") {
|
|
172
|
+
let e = `${l.code}: ${l.message}`;
|
|
151
173
|
throw t?.onStrategyFailed?.({
|
|
152
|
-
strategyId:
|
|
174
|
+
strategyId: o.id,
|
|
153
175
|
reason: e
|
|
154
|
-
}), new
|
|
176
|
+
}), new k({ reason: e });
|
|
155
177
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
178
|
+
if (l.kind === "unavailable") {
|
|
179
|
+
let e = `scope resolution unavailable: ${l.reason}`;
|
|
180
|
+
throw t?.onStrategyFailed?.({
|
|
181
|
+
strategyId: o.id,
|
|
182
|
+
reason: e
|
|
183
|
+
}), new k({ reason: e });
|
|
184
|
+
}
|
|
185
|
+
let d = w(e.subject, l);
|
|
186
|
+
u && d.removed.length > 0 && t?.onScopesNarrowed?.({
|
|
187
|
+
strategyId: o.id,
|
|
159
188
|
subjectType: e.subject.type,
|
|
160
189
|
subjectId: e.subject.id,
|
|
161
|
-
removed:
|
|
162
|
-
granted:
|
|
163
|
-
}),
|
|
190
|
+
removed: d.removed,
|
|
191
|
+
granted: l.scopes
|
|
192
|
+
}), s = d.subject;
|
|
164
193
|
}
|
|
165
|
-
return e.credentialExpiresAt === void 0 ? { subject:
|
|
166
|
-
subject:
|
|
194
|
+
return e.credentialExpiresAt === void 0 ? { subject: s } : {
|
|
195
|
+
subject: s,
|
|
167
196
|
credentialExpiresAt: e.credentialExpiresAt
|
|
168
197
|
};
|
|
169
198
|
}
|
|
170
199
|
if (e.kind === "failed") {
|
|
171
200
|
t?.onStrategyFailed?.({
|
|
172
|
-
strategyId:
|
|
201
|
+
strategyId: o.id,
|
|
173
202
|
reason: e.reason
|
|
174
|
-
}),
|
|
203
|
+
}), l = e.reason;
|
|
175
204
|
break;
|
|
176
205
|
}
|
|
177
206
|
}
|
|
178
|
-
let
|
|
207
|
+
let u = (e) => l !== void 0 && e.type === "anonymous" ? {
|
|
179
208
|
...e,
|
|
180
|
-
credentialRejected:
|
|
209
|
+
credentialRejected: l
|
|
181
210
|
} : e;
|
|
182
|
-
if (t?.fallback) return { subject:
|
|
183
|
-
let
|
|
184
|
-
if (
|
|
185
|
-
return { subject:
|
|
211
|
+
if (t?.fallback) return { subject: u(await t.fallback(c)) };
|
|
212
|
+
let d = c.headers["x-tenant"] ?? null;
|
|
213
|
+
if (d === null && t?.anonymousTenantRequired === !0) throw new k({ reason: "tenant required (x-tenant header missing)" });
|
|
214
|
+
return { subject: u(h(d)) };
|
|
186
215
|
};
|
|
187
|
-
},
|
|
188
|
-
if (e.type === "anonymous") throw new
|
|
189
|
-
},
|
|
216
|
+
}, k = class extends n.TaggedError()("Unauthenticated", { reason: n.optional(n.String) }) {}, A = (e, t) => {
|
|
217
|
+
if (e.type === "anonymous") throw new k(t === void 0 ? {} : { reason: t });
|
|
218
|
+
}, j = "admin:full", M = "apikeys:issue:self", N = "apikeys:issue:org", P = "apikeys:issue:other", F = class extends n.TaggedError()("ScopeError", {
|
|
190
219
|
required: n.String,
|
|
191
220
|
message: n.String
|
|
192
|
-
}) {},
|
|
193
|
-
typeof e == "object" && e &&
|
|
194
|
-
},
|
|
221
|
+
}) {}, I = (e) => "scopes" in e && e.scopes ? e.scopes : [], L = /* @__PURE__ */ new WeakMap(), R = (e, t) => {
|
|
222
|
+
typeof e == "object" && e && L.set(e, t);
|
|
223
|
+
}, z = (e) => {
|
|
195
224
|
if (typeof e == "object" && e) {
|
|
196
|
-
let t =
|
|
225
|
+
let t = L.get(e);
|
|
197
226
|
if (t) return t;
|
|
198
227
|
}
|
|
199
|
-
return
|
|
200
|
-
},
|
|
201
|
-
let n =
|
|
228
|
+
return I(e);
|
|
229
|
+
}, B = (e, t) => {
|
|
230
|
+
let n = z(e);
|
|
202
231
|
return n.includes("admin:full") || n.includes(t);
|
|
203
|
-
},
|
|
204
|
-
let n =
|
|
232
|
+
}, V = (e, t) => {
|
|
233
|
+
let n = I(e);
|
|
205
234
|
return n.includes("admin:full") || n.includes(t);
|
|
206
|
-
},
|
|
235
|
+
}, H = (e, n) => B(e, n) ? t.void : t.fail(new F({
|
|
207
236
|
required: n,
|
|
208
237
|
message: `missing required scope '${n}'`
|
|
209
238
|
})), U = (e) => typeof e.action == "string" && typeof e.resourceType == "string", W = (e) => typeof e.open == "string", G = (e) => ({ open: e }), K = (e) => typeof e == "string" ? [e] : e, q, J = (e) => {
|
|
@@ -224,29 +253,29 @@ var i = n.Record({
|
|
|
224
253
|
" • Drop the `resource` extractor if a global scope check is what you meant."
|
|
225
254
|
].join("\n"), ce = () => q, Y, le = (e) => {
|
|
226
255
|
Y = e;
|
|
227
|
-
}, X = () => Y, Z = (e) => new
|
|
256
|
+
}, X = () => Y, Z = (e) => new F({
|
|
228
257
|
required: "access-decision",
|
|
229
258
|
message: `${e ?? "this procedure"} declares no access decision: it has neither \`guards:\` nor \`openAccess:\`, and the app runs with \`security.defaultDeny\`. Add the scope(s) a caller must hold (\`guards: [{ scope: '…' }]\`), or declare it open on purpose with \`openAccess: '<why anyone may call this>'\`.`
|
|
230
259
|
}), Q = (e, t) => {
|
|
231
260
|
let n = e.credentialRejected;
|
|
232
|
-
return n === void 0 ? t : new
|
|
261
|
+
return n === void 0 ? t : new k({ reason: `${n} — the request carried a credential and it was REJECTED, so this caller resolved to anonymous. The guard then refused (${t.message}); the scope is not the problem. Re-authenticate and retry.` });
|
|
233
262
|
}, $ = (e, t, n) => {
|
|
234
263
|
if (!t || t.length === 0) return n?.defaultDeny === !0 ? Z(n.procedure) : null;
|
|
235
264
|
for (let n of t) {
|
|
236
265
|
if (W(n)) continue;
|
|
237
266
|
if (U(n)) {
|
|
238
|
-
if (
|
|
239
|
-
return Q(e, new
|
|
267
|
+
if (B(e, "admin:full")) continue;
|
|
268
|
+
return Q(e, new F({
|
|
240
269
|
required: `${n.resourceType}:${n.action}`,
|
|
241
270
|
message: `relationship guard '${n.action}' on '${n.resourceType}' cannot be checked synchronously`
|
|
242
271
|
}));
|
|
243
272
|
}
|
|
244
273
|
let t = K(n.scope);
|
|
245
274
|
if (t.length === 0) continue;
|
|
246
|
-
let r = t.filter((t) =>
|
|
275
|
+
let r = t.filter((t) => B(e, t));
|
|
247
276
|
if (!((n.mode ?? "all") === "any" ? r.length > 0 : r.length === t.length)) {
|
|
248
|
-
let r = (n.mode ?? "all") === "any" ? t[0] : t.find((t) => !
|
|
249
|
-
return Q(e, new
|
|
277
|
+
let r = (n.mode ?? "all") === "any" ? t[0] : t.find((t) => !B(e, t));
|
|
278
|
+
return Q(e, new F({
|
|
250
279
|
required: r,
|
|
251
280
|
message: (n.mode ?? "all") === "any" ? `missing all of required scopes [${t.join(", ")}]` : `missing required scope '${r}'`
|
|
252
281
|
}));
|
|
@@ -254,11 +283,11 @@ var i = n.Record({
|
|
|
254
283
|
}
|
|
255
284
|
return null;
|
|
256
285
|
}, ue = (e, n, r) => {
|
|
257
|
-
let i = (e) => new
|
|
286
|
+
let i = (e) => new F({
|
|
258
287
|
required: `${n.resourceType}:${n.action}`,
|
|
259
288
|
message: e
|
|
260
289
|
});
|
|
261
|
-
if (
|
|
290
|
+
if (B(e, "admin:full")) return t.succeed(null);
|
|
262
291
|
let a = Y;
|
|
263
292
|
if (a === void 0) return t.succeed(i(`no policy resolver registered — cannot authorize '${n.action}' on '${n.resourceType}'`));
|
|
264
293
|
let o = n.resource(r);
|
|
@@ -283,7 +312,7 @@ var i = n.Record({
|
|
|
283
312
|
if (n.length === 0) continue;
|
|
284
313
|
let o = i.resource ? i.resource(r) : void 0, s = [];
|
|
285
314
|
for (let r of n) {
|
|
286
|
-
if (
|
|
315
|
+
if (B(e, r)) {
|
|
287
316
|
s.push(!0);
|
|
288
317
|
continue;
|
|
289
318
|
}
|
|
@@ -299,7 +328,7 @@ var i = n.Record({
|
|
|
299
328
|
let c = i.mode ?? "all";
|
|
300
329
|
if (!(c === "any" ? s.some(Boolean) : s.every(Boolean))) {
|
|
301
330
|
let e = c === "any" ? n[0] : n[n.findIndex((e, t) => !s[t])];
|
|
302
|
-
return new
|
|
331
|
+
return new F({
|
|
303
332
|
required: e,
|
|
304
333
|
message: c === "any" ? `missing all of required scopes [${n.join(", ")}]` : `missing required scope '${e}'` + (o === void 0 ? "" : ` on resource '${o}'`)
|
|
305
334
|
});
|
|
@@ -309,4 +338,4 @@ var i = n.Record({
|
|
|
309
338
|
});
|
|
310
339
|
};
|
|
311
340
|
//#endregion
|
|
312
|
-
export {
|
|
341
|
+
export { d as A, E as B, I as C, ie as D, ne as E, w as F, te as G, T as H, A as I, O as L, y as M, k as N, re as O, h as P, S as R, J as S, b as T, p as U, v as V, ee as W, Z as _, F as a, R as b, de as c, X as d, ce as f, U as g, W as h, M as i, f as j, _ as k, z as l, V as m, N as n, se as o, B as p, P as r, $ as s, j as t, oe as u, G as v, x as w, le as x, H as y, g as z };
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { Schema as e } from "effect";
|
|
1
2
|
//#region src/idempotency.ts
|
|
2
|
-
var
|
|
3
|
+
var t = (e, t, n) => `${e ?? "(global)"}|${t.toUpperCase()}|${n}`, n = (e, t, n) => `${e ?? "(global)"}|${t ?? "(anon)"}|WS|${n}`, r = async (e, t, n, r, i) => {
|
|
3
4
|
let a = await e.claim(t, n, i, r);
|
|
4
5
|
return a === "claimed" ? { kind: "fresh" } : a.status === "completed" && a.response ? {
|
|
5
6
|
kind: "replay",
|
|
6
7
|
response: a.response
|
|
7
8
|
} : { kind: "conflict" };
|
|
8
|
-
},
|
|
9
|
+
}, i = (e, t, n, r, i) => e.complete(t, n, r, i), a = (e, t, n) => e.release(t, n), o = () => {
|
|
9
10
|
let e = /* @__PURE__ */ new Map(), t = (e, t) => `${e}\u0000${t}`;
|
|
10
11
|
return {
|
|
11
12
|
get: async (n, r) => e.get(t(n, r)) ?? null,
|
|
@@ -32,12 +33,19 @@ var e = (e, t, n) => `${e ?? "(global)"}|${t.toUpperCase()}|${n}`, t = (e, t, n)
|
|
|
32
33
|
e.delete(t(n, r));
|
|
33
34
|
}
|
|
34
35
|
};
|
|
35
|
-
},
|
|
36
|
-
|
|
36
|
+
}, s = class extends e.TaggedError()("MutationInFlight", {
|
|
37
|
+
traceId: e.String,
|
|
38
|
+
retryAfterMs: e.Number
|
|
39
|
+
}) {
|
|
40
|
+
get message() {
|
|
41
|
+
return `a request with this idempotency key is still in flight — replay the same key after ${this.retryAfterMs}ms`;
|
|
42
|
+
}
|
|
43
|
+
}, c = 1e3, l = /* @__PURE__ */ new Set(), u = (e) => {
|
|
44
|
+
for (let t of l) try {
|
|
37
45
|
t(e);
|
|
38
46
|
} catch {}
|
|
39
|
-
},
|
|
40
|
-
|
|
47
|
+
}, d = (e) => (l.add(e), () => {
|
|
48
|
+
l.delete(e);
|
|
41
49
|
});
|
|
42
50
|
//#endregion
|
|
43
|
-
export { r as a, t as c, i,
|
|
51
|
+
export { r as a, t as c, s as i, o as l, d as n, a as o, c as r, i as s, u as t, n as u };
|
package/dist/session.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as e, U as t, j as n } from "./scopes-
|
|
1
|
+
import { C as e, U as t, j as n } from "./scopes-D9t3tYc7.js";
|
|
2
2
|
import { Schema as r } from "effect";
|
|
3
3
|
import { createHmac as i, timingSafeEqual as a } from "node:crypto";
|
|
4
4
|
import { createLogger as o } from "@voltro/logger";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/protocol",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.64.0",
|
|
4
4
|
"description": "The Voltro wire + plugin contract — defineQuery/Mutation/Action/Stream, definePlugin, sessions / JWT / API-keys, and the RPC protocol.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"voltro",
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
61
|
"@effect/sql": "^0.52.0",
|
|
62
|
-
"@voltro/database": "0.
|
|
63
|
-
"@voltro/logger": "0.
|
|
62
|
+
"@voltro/database": "0.64.0",
|
|
63
|
+
"@voltro/logger": "0.64.0",
|
|
64
64
|
"jose": "^6.2.8"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|