@voltro/protocol 0.11.3 → 0.12.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 +436 -0
- package/dist/apikey.d.ts +40 -5
- package/dist/apikey.js +24 -18
- package/dist/{auth-DCE6m7Bo.js → auth-S3cnL6Tz.js} +14 -5
- package/dist/index.d.ts +89 -0
- package/dist/index.js +109 -109
- package/dist/rest.d.ts +93 -3
- package/dist/rest.js +68 -47
- package/dist/serverErrorBus-DhIVDkCi.js +0 -0
- package/dist/session.js +1 -1
- package/package.json +2 -2
- package/dist/serverErrorBus-B3hDwGoL.js +0 -0
package/dist/rest.js
CHANGED
|
@@ -1,43 +1,58 @@
|
|
|
1
|
-
import { a as e, i as t, o as n, r, t as i } from "./serverErrorBus-
|
|
2
|
-
import { s as a } from "./auth-
|
|
1
|
+
import { a as e, i as t, o as n, r, t as i } from "./serverErrorBus-DhIVDkCi.js";
|
|
2
|
+
import { s as a } from "./auth-S3cnL6Tz.js";
|
|
3
3
|
import { Effect as o, Schema as s } from "effect";
|
|
4
4
|
//#region src/publicApi.ts
|
|
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) => {
|
|
6
|
-
let
|
|
7
|
-
if (
|
|
8
|
-
let
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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) => {
|
|
6
|
+
let r = e.publicApi;
|
|
7
|
+
if (r === void 0) throw Error(`publicApiRoute: descriptor '${e.name}' has no publicApi annotation`);
|
|
8
|
+
let i = c(e.kind, r), a = l(e.name, r), o = i === "GET" ? "query" : "body", u = s.Struct({ [o]: e.input }), d = (r.scopes ?? []).map((e) => f(e)), p = r.stream === "sse" && e.kind === "query" && n !== void 0, _ = p ? (e, t) => h((r) => n(e[o], t, (e) => {
|
|
9
|
+
r(g(String(e._tag ?? "message"), e));
|
|
10
|
+
})) : (e, n) => t(e[o], n);
|
|
11
|
+
return m({
|
|
12
|
+
method: i,
|
|
13
|
+
path: a,
|
|
14
|
+
input: u,
|
|
13
15
|
output: e.output,
|
|
14
|
-
handler:
|
|
15
|
-
...
|
|
16
|
-
...
|
|
17
|
-
...
|
|
18
|
-
...
|
|
19
|
-
...
|
|
16
|
+
handler: _,
|
|
17
|
+
...p ? { streaming: !0 } : {},
|
|
18
|
+
...d.length > 0 ? { guards: d } : {},
|
|
19
|
+
...r.summary === void 0 ? {} : { summary: r.summary },
|
|
20
|
+
...r.description === void 0 ? {} : { description: r.description },
|
|
21
|
+
...r.deprecated === void 0 ? {} : { deprecated: r.deprecated },
|
|
22
|
+
...r.sunset === void 0 ? {} : { sunset: r.sunset }
|
|
20
23
|
});
|
|
21
|
-
}, d = (e) => e.filter((e) => e.descriptor.publicApi !== void 0).map((e) => u(e.descriptor, e.invoke)).sort((e, t) => e.path.localeCompare(t.path)), f = (e) => (t) => {
|
|
24
|
+
}, d = (e) => e.filter((e) => e.descriptor.publicApi !== void 0).map((e) => u(e.descriptor, e.invoke, e.subscribe)).sort((e, t) => e.path.localeCompare(t.path)), f = (e) => (t) => {
|
|
22
25
|
let n = t.subject.scopes;
|
|
23
26
|
if (!(n && (n.includes(e) || n.includes("admin:full")))) return {
|
|
24
27
|
status: 403,
|
|
25
28
|
message: `Missing required scope: ${e}`
|
|
26
29
|
};
|
|
27
|
-
}, p = (e) =>
|
|
30
|
+
}, p = (e) => (t) => {
|
|
31
|
+
let n = t.subject.scopes;
|
|
32
|
+
if (!(n && (n.includes("admin:full") || e.some((e) => n.includes(e))))) return {
|
|
33
|
+
status: 403,
|
|
34
|
+
message: `Missing required scope: one of ${e.join(", ")}`
|
|
35
|
+
};
|
|
36
|
+
}, m = (e) => e, h = (e, t = {}) => ({
|
|
37
|
+
__voltroRestStream: !0,
|
|
38
|
+
stream: {
|
|
39
|
+
subscribe: e,
|
|
40
|
+
...t.keepAliveMs === void 0 ? {} : { keepAliveMs: t.keepAliveMs }
|
|
41
|
+
}
|
|
42
|
+
}), g = (e, t) => `event: ${e}\n${(typeof t == "string" ? t : JSON.stringify(t)).split("\n").map((e) => `data: ${e}`).join("\n")}\n\n`, _ = (e) => typeof e == "object" && !!e && e.__voltroRestStream === !0, v = (e, t, n) => ({
|
|
28
43
|
status: e,
|
|
29
44
|
contentType: "application/json; charset=utf-8",
|
|
30
45
|
body: JSON.stringify(t),
|
|
31
46
|
...n ? { headers: n } : {}
|
|
32
|
-
}),
|
|
47
|
+
}), y = (e) => {
|
|
33
48
|
if (e.length === 0) return;
|
|
34
49
|
let t = new TextDecoder().decode(e);
|
|
35
50
|
if (t.trim() !== "") return JSON.parse(t);
|
|
36
|
-
},
|
|
51
|
+
}, b = (e) => {
|
|
37
52
|
let t = {};
|
|
38
53
|
for (let [n, r] of new URLSearchParams(e)) t[n] = r;
|
|
39
54
|
return t;
|
|
40
|
-
},
|
|
55
|
+
}, x = (e, t) => {
|
|
41
56
|
let n = e.split("/").filter((e) => e.length > 0), r = t.split("/").filter((e) => e.length > 0), i = {};
|
|
42
57
|
for (let e = 0; e < n.length; e++) {
|
|
43
58
|
let t = n[e];
|
|
@@ -51,22 +66,22 @@ var c = (e, t) => t.method ?? (e === "query" ? "GET" : "POST"), l = (e, t) => t.
|
|
|
51
66
|
}
|
|
52
67
|
}
|
|
53
68
|
return i;
|
|
54
|
-
},
|
|
55
|
-
query:
|
|
69
|
+
}, S = (e, t) => ({
|
|
70
|
+
query: b(e.query),
|
|
56
71
|
params: t,
|
|
57
|
-
body:
|
|
58
|
-
}),
|
|
72
|
+
body: y(e.rawBody)
|
|
73
|
+
}), C = /* @__PURE__ */ new Set([
|
|
59
74
|
"POST",
|
|
60
75
|
"PUT",
|
|
61
76
|
"PATCH",
|
|
62
77
|
"DELETE"
|
|
63
|
-
]),
|
|
78
|
+
]), w = (c, l) => {
|
|
64
79
|
let u = c.input ? s.decodeUnknown(c.input) : void 0, d = s.encode(c.output), f = {};
|
|
65
80
|
return c.deprecated !== void 0 && (f.Deprecation = "true"), c.sunset !== void 0 && (f.Sunset = c.sunset), {
|
|
66
81
|
method: "*",
|
|
67
82
|
path: c.path,
|
|
68
83
|
handle: async (s) => {
|
|
69
|
-
if (s.method.toUpperCase() !== c.method) return
|
|
84
|
+
if (s.method.toUpperCase() !== c.method) return v(405, {
|
|
70
85
|
error: "Method Not Allowed",
|
|
71
86
|
allow: c.method
|
|
72
87
|
}, {
|
|
@@ -75,68 +90,74 @@ var c = (e, t) => t.method ?? (e === "query" ? "GET" : "POST"), l = (e, t) => t.
|
|
|
75
90
|
});
|
|
76
91
|
if (c.sunset !== void 0) {
|
|
77
92
|
let e = Date.parse(c.sunset);
|
|
78
|
-
if (!Number.isNaN(e) && Date.now() >= e) return
|
|
93
|
+
if (!Number.isNaN(e) && Date.now() >= e) return v(410, {
|
|
79
94
|
error: "Gone",
|
|
80
95
|
...c.deprecated === void 0 ? {} : { replacement: c.deprecated }
|
|
81
96
|
}, f);
|
|
82
97
|
}
|
|
83
98
|
let p;
|
|
84
99
|
if (u) {
|
|
85
|
-
let e =
|
|
100
|
+
let e = S(s, x(c.path, s.path)), t = await o.runPromise(u(e).pipe(o.map((e) => ({
|
|
86
101
|
ok: !0,
|
|
87
102
|
value: e
|
|
88
103
|
})), o.catchAll((e) => o.succeed({
|
|
89
104
|
ok: !1,
|
|
90
105
|
cause: e
|
|
91
106
|
}))));
|
|
92
|
-
if (!t.ok) return
|
|
107
|
+
if (!t.ok) return v(400, {
|
|
93
108
|
error: "Invalid request",
|
|
94
109
|
detail: String(t.cause)
|
|
95
110
|
}, f);
|
|
96
111
|
p = t.value;
|
|
97
112
|
}
|
|
98
|
-
let
|
|
99
|
-
subject:
|
|
113
|
+
let m = l.resolveSubject ? await l.resolveSubject(s.headers) : a(s.headers["x-tenant"] ?? null), h = {
|
|
114
|
+
subject: m,
|
|
100
115
|
headers: s.headers,
|
|
101
116
|
store: l.store
|
|
102
117
|
};
|
|
103
118
|
if (c.guards) for (let e of c.guards) {
|
|
104
|
-
let t = await e(
|
|
105
|
-
if (t) return
|
|
119
|
+
let t = await e(h);
|
|
120
|
+
if (t) return v(t.status, { error: t.message }, f);
|
|
106
121
|
}
|
|
107
|
-
let
|
|
108
|
-
if (
|
|
109
|
-
let e = await r(
|
|
110
|
-
if (e.kind === "replay") return
|
|
122
|
+
let g = l.idempotency, y = g && C.has(c.method) ? s.headers[g.header.toLowerCase()] : void 0, b = g && y ? n(m.tenantId, c.method, c.path) : "";
|
|
123
|
+
if (g && y) {
|
|
124
|
+
let e = await r(g.store, b, y, g.ttlMs, Date.now());
|
|
125
|
+
if (e.kind === "replay") return v(e.response.status, e.response.body, {
|
|
111
126
|
...f,
|
|
112
127
|
"Idempotency-Replayed": "true"
|
|
113
128
|
});
|
|
114
|
-
if (e.kind === "conflict") return
|
|
129
|
+
if (e.kind === "conflict") return v(409, { error: "A request with this Idempotency-Key is already being processed" }, f);
|
|
115
130
|
}
|
|
116
131
|
try {
|
|
117
|
-
let t = await c.handler(p,
|
|
118
|
-
|
|
132
|
+
let t = await c.handler(p, h);
|
|
133
|
+
if (_(t)) return {
|
|
134
|
+
status: 200,
|
|
135
|
+
headers: f,
|
|
136
|
+
stream: t.stream
|
|
137
|
+
};
|
|
138
|
+
let n = await o.runPromise(d(t));
|
|
139
|
+
return g && y && await e(g.store, b, y, {
|
|
119
140
|
status: 200,
|
|
120
141
|
body: n
|
|
121
|
-
}, Date.now()),
|
|
142
|
+
}, Date.now()), v(200, n, f);
|
|
122
143
|
} catch (e) {
|
|
123
|
-
if (
|
|
144
|
+
if (g && y && await t(g.store, b, y), typeof e == "object" && e && typeof e.status == "number") {
|
|
124
145
|
let t = e;
|
|
125
|
-
return
|
|
146
|
+
return v(t.status, { error: t.message ?? "Error" }, f);
|
|
126
147
|
}
|
|
127
148
|
return i({
|
|
128
149
|
error: e,
|
|
129
150
|
source: "rest",
|
|
130
151
|
name: `${c.method} ${c.path}`,
|
|
131
152
|
fields: { status: 500 }
|
|
132
|
-
}),
|
|
153
|
+
}), v(500, { error: "Internal Server Error" }, f);
|
|
133
154
|
}
|
|
134
155
|
}
|
|
135
156
|
};
|
|
136
|
-
},
|
|
157
|
+
}, T = (e, t = {}) => e.map((e) => w(e, t)), E = async (e, t) => {
|
|
137
158
|
let n = await e[0].handle(t);
|
|
138
159
|
for (let r = 1; r < e.length && n.status === 405; r++) n = await e[r].handle(t);
|
|
139
160
|
return n;
|
|
140
161
|
};
|
|
141
162
|
//#endregion
|
|
142
|
-
export { d as collectPublicApiRoutes,
|
|
163
|
+
export { d as collectPublicApiRoutes, m as defineRestRoute, c as derivePublicMethod, l as derivePublicPath, E as dispatchSharedPath, _ as isRestStreamResponse, x as matchPathParams, u as publicApiRoute, p as requireAnyScope, f as requireScope, T as restRoutesToHttpRoutes, h as sse, g as sseFrame };
|
|
Binary file
|
package/dist/session.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@voltro/protocol",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.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",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@effect/sql": "^0.51.1",
|
|
56
|
-
"@voltro/database": "0.
|
|
56
|
+
"@voltro/database": "0.12.0",
|
|
57
57
|
"jose": "^6.2.3"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
Binary file
|