@opendatalabs/personal-server-ts-server 0.2.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-auth.d.ts +16 -0
- package/dist/api-auth.d.ts.map +1 -0
- package/dist/api-auth.js +97 -0
- package/dist/api-auth.js.map +1 -0
- package/dist/api.d.ts +4 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +3 -0
- package/dist/api.js.map +1 -1
- package/dist/app.d.ts +46 -1
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +102 -30
- package/dist/app.js.map +1 -1
- package/dist/bootstrap.d.ts +11 -3
- package/dist/bootstrap.d.ts.map +1 -1
- package/dist/bootstrap.js +266 -33
- package/dist/bootstrap.js.map +1 -1
- package/dist/client.d.ts +17 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +368 -0
- package/dist/client.js.map +1 -0
- package/dist/config/defaults.d.ts +12 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +14 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +4 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/loader.d.ts +8 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +74 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/paths.d.ts +9 -0
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +22 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/hono-context.d.ts +14 -0
- package/dist/hono-context.d.ts.map +1 -0
- package/dist/hono-context.js +2 -0
- package/dist/hono-context.js.map +1 -0
- package/dist/index.js +64 -12
- package/dist/index.js.map +1 -1
- package/dist/keys/server-account.d.ts +28 -0
- package/dist/keys/server-account.d.ts.map +1 -0
- package/dist/keys/server-account.js +48 -0
- package/dist/keys/server-account.js.map +1 -0
- package/dist/logger/index.d.ts +5 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +9 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/logging/access-log.d.ts +15 -0
- package/dist/logging/access-log.d.ts.map +1 -0
- package/dist/logging/access-log.js +25 -0
- package/dist/logging/access-log.js.map +1 -0
- package/dist/logging/access-reader.d.ts +19 -0
- package/dist/logging/access-reader.d.ts.map +1 -0
- package/dist/logging/access-reader.js +50 -0
- package/dist/logging/access-reader.js.map +1 -0
- package/dist/middleware/access-log.d.ts.map +1 -1
- package/dist/middleware/access-log.js +8 -2
- package/dist/middleware/access-log.js.map +1 -1
- package/dist/middleware/builder-check.d.ts +2 -2
- package/dist/middleware/builder-check.d.ts.map +1 -1
- package/dist/middleware/builder-check.js +7 -2
- package/dist/middleware/builder-check.js.map +1 -1
- package/dist/middleware/owner-check.js +1 -1
- package/dist/middleware/owner-check.js.map +1 -1
- package/dist/middleware/web3-auth.d.ts +12 -0
- package/dist/middleware/web3-auth.d.ts.map +1 -1
- package/dist/middleware/web3-auth.js +27 -31
- package/dist/middleware/web3-auth.js.map +1 -1
- package/dist/migrations/local-state.d.ts +21 -0
- package/dist/migrations/local-state.d.ts.map +1 -0
- package/dist/migrations/local-state.js +106 -0
- package/dist/migrations/local-state.js.map +1 -0
- package/dist/routes/access-logs.d.ts +7 -0
- package/dist/routes/access-logs.d.ts.map +1 -1
- package/dist/routes/access-logs.js +11 -17
- package/dist/routes/access-logs.js.map +1 -1
- package/dist/routes/auth-device.d.ts +49 -0
- package/dist/routes/auth-device.d.ts.map +1 -0
- package/dist/routes/auth-device.js +581 -0
- package/dist/routes/auth-device.js.map +1 -0
- package/dist/routes/data.d.ts +42 -1
- package/dist/routes/data.d.ts.map +1 -1
- package/dist/routes/data.js +36 -201
- package/dist/routes/data.js.map +1 -1
- package/dist/routes/grants.d.ts +9 -2
- package/dist/routes/grants.d.ts.map +1 -1
- package/dist/routes/grants.js +18 -196
- package/dist/routes/grants.js.map +1 -1
- package/dist/routes/health.d.ts +7 -1
- package/dist/routes/health.d.ts.map +1 -1
- package/dist/routes/health.js +39 -2
- package/dist/routes/health.js.map +1 -1
- package/dist/routes/mcp.d.ts +93 -6
- package/dist/routes/mcp.d.ts.map +1 -1
- package/dist/routes/mcp.js +526 -53
- package/dist/routes/mcp.js.map +1 -1
- package/dist/routes/oauth-token.d.ts +56 -0
- package/dist/routes/oauth-token.d.ts.map +1 -0
- package/dist/routes/oauth-token.js +49 -0
- package/dist/routes/oauth-token.js.map +1 -0
- package/dist/routes/sync.d.ts +7 -0
- package/dist/routes/sync.d.ts.map +1 -1
- package/dist/routes/sync.js +12 -39
- package/dist/routes/sync.js.map +1 -1
- package/dist/routes/ui-config.d.ts.map +1 -1
- package/dist/routes/ui-config.js +17 -82
- package/dist/routes/ui-config.js.map +1 -1
- package/dist/routes/ui-registration.d.ts +9 -0
- package/dist/routes/ui-registration.d.ts.map +1 -0
- package/dist/routes/ui-registration.js +217 -0
- package/dist/routes/ui-registration.js.map +1 -0
- package/dist/routes/ui.d.ts +1 -0
- package/dist/routes/ui.d.ts.map +1 -1
- package/dist/routes/ui.js +46 -4
- package/dist/routes/ui.js.map +1 -1
- package/dist/storage/hierarchy.d.ts +29 -0
- package/dist/storage/hierarchy.d.ts.map +1 -0
- package/dist/storage/hierarchy.js +241 -0
- package/dist/storage/hierarchy.js.map +1 -0
- package/dist/storage/index-manager.d.ts +53 -0
- package/dist/storage/index-manager.d.ts.map +1 -0
- package/dist/storage/index-manager.js +167 -0
- package/dist/storage/index-manager.js.map +1 -0
- package/dist/storage/index-schema.d.ts +5 -0
- package/dist/storage/index-schema.d.ts.map +1 -0
- package/dist/storage/index-schema.js +62 -0
- package/dist/storage/index-schema.js.map +1 -0
- package/dist/storage/node-data-storage.d.ts +9 -0
- package/dist/storage/node-data-storage.d.ts.map +1 -0
- package/dist/storage/node-data-storage.js +84 -0
- package/dist/storage/node-data-storage.js.map +1 -0
- package/dist/sync-cursor.d.ts +15 -0
- package/dist/sync-cursor.d.ts.map +1 -0
- package/dist/sync-cursor.js +110 -0
- package/dist/sync-cursor.js.map +1 -0
- package/dist/token-store.d.ts +22 -0
- package/dist/token-store.d.ts.map +1 -0
- package/dist/token-store.js +120 -0
- package/dist/token-store.js.map +1 -0
- package/dist/tunnel/auth.d.ts +4 -0
- package/dist/tunnel/auth.d.ts.map +1 -1
- package/dist/tunnel/auth.js +2 -1
- package/dist/tunnel/auth.js.map +1 -1
- package/dist/tunnel/config.d.ts +1 -0
- package/dist/tunnel/config.d.ts.map +1 -1
- package/dist/tunnel/config.js +1 -1
- package/dist/tunnel/config.js.map +1 -1
- package/dist/tunnel/manager.d.ts +21 -1
- package/dist/tunnel/manager.d.ts.map +1 -1
- package/dist/tunnel/manager.js +78 -23
- package/dist/tunnel/manager.js.map +1 -1
- package/dist/tunnel/verify.d.ts +1 -1
- package/dist/tunnel/verify.d.ts.map +1 -1
- package/dist/tunnel/verify.js +8 -2
- package/dist/tunnel/verify.js.map +1 -1
- package/dist/ui/browser_tls_rustls_bg.wasm +0 -0
- package/dist/ui/index.html +2192 -0
- package/dist/ui/ps-lite-debug.d.ts +93 -0
- package/dist/ui/ps-lite-debug.d.ts.map +1 -0
- package/dist/ui/ps-lite-debug.js +129415 -0
- package/dist/ui/ps-lite-debug.js.map +1 -0
- package/package.json +20 -8
- package/dist/middleware/grant-check.d.ts +0 -12
- package/dist/middleware/grant-check.d.ts.map +0 -1
- package/dist/middleware/grant-check.js +0 -90
- package/dist/middleware/grant-check.js.map +0 -1
- package/dist/oauth/provider.d.ts +0 -55
- package/dist/oauth/provider.d.ts.map +0 -1
- package/dist/oauth/provider.js +0 -160
- package/dist/oauth/provider.js.map +0 -1
- package/dist/oauth/routes.d.ts +0 -10
- package/dist/oauth/routes.d.ts.map +0 -1
- package/dist/oauth/routes.js +0 -206
- package/dist/oauth/routes.js.map +0 -1
package/dist/routes/data.js
CHANGED
|
@@ -1,213 +1,48 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import {
|
|
3
|
-
import { createDataFileEnvelope } from "@opendatalabs/personal-server-ts-core/schemas/data-file";
|
|
4
|
-
import { generateCollectedAt, writeDataFile, readDataFile, deleteAllForScope, } from "@opendatalabs/personal-server-ts-core/storage/hierarchy";
|
|
2
|
+
import { handlePersonalServerDataRequest, } from "@opendatalabs/personal-server-ts-core/api";
|
|
5
3
|
import { createBodyLimit, DATA_INGEST_MAX_SIZE, } from "../middleware/body-limit.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { createGrantCheckMiddleware } from "../middleware/grant-check.js";
|
|
9
|
-
import { createAccessLogMiddleware } from "../middleware/access-log.js";
|
|
10
|
-
import { createOwnerCheckMiddleware } from "../middleware/owner-check.js";
|
|
4
|
+
import { createNodeDataStorage } from "../storage/node-data-storage.js";
|
|
5
|
+
import { createServerApiAuth } from "../api-auth.js";
|
|
11
6
|
export function dataRoutes(deps) {
|
|
12
7
|
const app = new Hono();
|
|
13
|
-
|
|
14
|
-
|
|
8
|
+
const dataStorage = deps.dataStorage ??
|
|
9
|
+
createNodeDataStorage({
|
|
10
|
+
indexManager: deps.indexManager,
|
|
11
|
+
hierarchyOptions: deps.hierarchyOptions,
|
|
12
|
+
});
|
|
13
|
+
const auth = createServerApiAuth({
|
|
15
14
|
serverOrigin: deps.serverOrigin,
|
|
16
|
-
devToken: deps.devToken,
|
|
17
15
|
serverOwner: deps.serverOwner,
|
|
18
|
-
});
|
|
19
|
-
const builderCheck = createBuilderCheckMiddleware(deps.gateway);
|
|
20
|
-
const grantCheck = createGrantCheckMiddleware({
|
|
21
16
|
gateway: deps.gateway,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// 1. Validate scope
|
|
28
|
-
const scopeParam = c.req.param("scope");
|
|
29
|
-
const scopeResult = ScopeSchema.safeParse(scopeParam);
|
|
30
|
-
if (!scopeResult.success) {
|
|
31
|
-
return c.json({
|
|
32
|
-
error: "INVALID_SCOPE",
|
|
33
|
-
message: scopeResult.error.issues[0].message,
|
|
34
|
-
}, 400);
|
|
35
|
-
}
|
|
36
|
-
const scope = scopeResult.data;
|
|
37
|
-
// 2. Parse pagination
|
|
38
|
-
const limit = c.req.query("limit")
|
|
39
|
-
? parseInt(c.req.query("limit"), 10)
|
|
40
|
-
: 20;
|
|
41
|
-
const offset = c.req.query("offset")
|
|
42
|
-
? parseInt(c.req.query("offset"), 10)
|
|
43
|
-
: 0;
|
|
44
|
-
// 3. Query index
|
|
45
|
-
const entries = deps.indexManager.findByScope({ scope, limit, offset });
|
|
46
|
-
const total = deps.indexManager.countByScope(scope);
|
|
47
|
-
// 4. Return response
|
|
48
|
-
return c.json({
|
|
49
|
-
scope,
|
|
50
|
-
versions: entries.map((e) => ({
|
|
51
|
-
fileId: e.fileId,
|
|
52
|
-
collectedAt: e.collectedAt,
|
|
53
|
-
})),
|
|
54
|
-
total,
|
|
55
|
-
limit,
|
|
56
|
-
offset,
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
// GET /v1/data — list distinct scopes (requires auth + builder, no grant)
|
|
60
|
-
app.get("/", web3Auth, builderCheck, async (c) => {
|
|
61
|
-
const scopePrefix = c.req.query("scopePrefix");
|
|
62
|
-
const limit = c.req.query("limit")
|
|
63
|
-
? parseInt(c.req.query("limit"), 10)
|
|
64
|
-
: 20;
|
|
65
|
-
const offset = c.req.query("offset")
|
|
66
|
-
? parseInt(c.req.query("offset"), 10)
|
|
67
|
-
: 0;
|
|
68
|
-
const result = deps.indexManager.listDistinctScopes({
|
|
69
|
-
scopePrefix: scopePrefix || undefined,
|
|
70
|
-
limit,
|
|
71
|
-
offset,
|
|
72
|
-
});
|
|
73
|
-
return c.json({
|
|
74
|
-
scopes: result.scopes,
|
|
75
|
-
total: result.total,
|
|
76
|
-
limit,
|
|
77
|
-
offset,
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
// GET /v1/data/:scope — read a data file (requires auth + grant)
|
|
81
|
-
app.get("/:scope", web3Auth, builderCheck, grantCheck, accessLog, async (c) => {
|
|
82
|
-
// 1. Validate scope
|
|
83
|
-
const scopeParam = c.req.param("scope");
|
|
84
|
-
const scopeResult = ScopeSchema.safeParse(scopeParam);
|
|
85
|
-
if (!scopeResult.success) {
|
|
86
|
-
return c.json({
|
|
87
|
-
error: "INVALID_SCOPE",
|
|
88
|
-
message: scopeResult.error.issues[0].message,
|
|
89
|
-
}, 400);
|
|
90
|
-
}
|
|
91
|
-
const scope = scopeResult.data;
|
|
92
|
-
// 2. Determine lookup strategy: fileId, at, or latest
|
|
93
|
-
const fileIdParam = c.req.query("fileId");
|
|
94
|
-
const atParam = c.req.query("at");
|
|
95
|
-
let entry;
|
|
96
|
-
if (fileIdParam) {
|
|
97
|
-
entry = deps.indexManager.findByFileId(fileIdParam);
|
|
98
|
-
}
|
|
99
|
-
else if (atParam) {
|
|
100
|
-
entry = deps.indexManager.findClosestByScope(scope, atParam);
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
entry = deps.indexManager.findLatestByScope(scope);
|
|
104
|
-
}
|
|
105
|
-
// 3. 404 if not found
|
|
106
|
-
if (!entry) {
|
|
107
|
-
return c.json({
|
|
108
|
-
error: "NOT_FOUND",
|
|
109
|
-
message: `No data found for scope "${scope}"`,
|
|
110
|
-
}, 404);
|
|
111
|
-
}
|
|
112
|
-
// 4. Read the data file from disk
|
|
113
|
-
const envelope = await readDataFile(deps.hierarchyOptions, scope, entry.collectedAt);
|
|
114
|
-
// 5. Return 200 with envelope
|
|
115
|
-
return c.json(envelope);
|
|
17
|
+
devToken: deps.devToken,
|
|
18
|
+
accessToken: deps.accessToken,
|
|
19
|
+
tokenStore: deps.tokenStore,
|
|
20
|
+
dataStorage,
|
|
21
|
+
runtimeAvailability: deps.runtimeAvailability,
|
|
116
22
|
});
|
|
117
23
|
app.use("/:scope", createBodyLimit(DATA_INGEST_MAX_SIZE));
|
|
118
|
-
app.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (body === null || typeof body !== "object" || Array.isArray(body)) {
|
|
141
|
-
return c.json({
|
|
142
|
-
error: "INVALID_BODY",
|
|
143
|
-
message: "Request body must be a JSON object",
|
|
144
|
-
}, 400);
|
|
145
|
-
}
|
|
146
|
-
// 3. Look up schema via Gateway (strict: reject if not found)
|
|
147
|
-
let schemaUrl;
|
|
148
|
-
try {
|
|
149
|
-
const schema = await deps.gateway.getSchemaForScope(scope);
|
|
150
|
-
if (!schema) {
|
|
151
|
-
return c.json({
|
|
152
|
-
error: "NO_SCHEMA",
|
|
153
|
-
message: `No schema registered for scope: ${scope}`,
|
|
154
|
-
}, 400);
|
|
155
|
-
}
|
|
156
|
-
schemaUrl = schema.definitionUrl;
|
|
157
|
-
}
|
|
158
|
-
catch (err) {
|
|
159
|
-
deps.logger.error({ err, scope }, "Gateway schema lookup failed");
|
|
160
|
-
return c.json({
|
|
161
|
-
error: "GATEWAY_ERROR",
|
|
162
|
-
message: "Failed to look up schema for scope",
|
|
163
|
-
}, 502);
|
|
164
|
-
}
|
|
165
|
-
// 4. Generate collectedAt
|
|
166
|
-
const collectedAt = generateCollectedAt();
|
|
167
|
-
// 5. Construct envelope
|
|
168
|
-
const envelope = createDataFileEnvelope(scope, collectedAt, body, schemaUrl);
|
|
169
|
-
// 6. Write atomically
|
|
170
|
-
const writeResult = await writeDataFile(deps.hierarchyOptions, envelope);
|
|
171
|
-
// 7. Insert into index
|
|
172
|
-
deps.indexManager.insert({
|
|
173
|
-
fileId: null,
|
|
174
|
-
path: writeResult.relativePath,
|
|
175
|
-
scope,
|
|
176
|
-
collectedAt,
|
|
177
|
-
sizeBytes: writeResult.sizeBytes,
|
|
178
|
-
});
|
|
179
|
-
deps.logger.info({ scope, collectedAt, path: writeResult.relativePath }, "Data file ingested");
|
|
180
|
-
// 8. Notify sync manager of new data (if enabled)
|
|
181
|
-
let status = "stored";
|
|
182
|
-
if (deps.syncManager) {
|
|
183
|
-
deps.syncManager.notifyNewData();
|
|
184
|
-
status = "syncing";
|
|
185
|
-
}
|
|
186
|
-
// 9. Return 201
|
|
187
|
-
return c.json({ scope, collectedAt, status }, 201);
|
|
188
|
-
});
|
|
189
|
-
// Owner-check middleware (web3-auth + owner-check)
|
|
190
|
-
const ownerCheck = createOwnerCheckMiddleware(deps.serverOwner);
|
|
191
|
-
// DELETE /v1/data/:scope — delete all versions for a scope (owner auth required)
|
|
192
|
-
app.delete("/:scope", web3Auth, ownerCheck, async (c) => {
|
|
193
|
-
// 1. Validate scope
|
|
194
|
-
const scopeParam = c.req.param("scope");
|
|
195
|
-
const scopeResult = ScopeSchema.safeParse(scopeParam);
|
|
196
|
-
if (!scopeResult.success) {
|
|
197
|
-
return c.json({
|
|
198
|
-
error: "INVALID_SCOPE",
|
|
199
|
-
message: scopeResult.error.issues[0].message,
|
|
200
|
-
}, 400);
|
|
201
|
-
}
|
|
202
|
-
const scope = scopeResult.data;
|
|
203
|
-
// 2. Delete from index
|
|
204
|
-
const deletedCount = deps.indexManager.deleteByScope(scope);
|
|
205
|
-
// 3. Delete from filesystem
|
|
206
|
-
await deleteAllForScope(deps.hierarchyOptions, scope);
|
|
207
|
-
deps.logger.info({ scope, deletedCount }, "Scope deleted");
|
|
208
|
-
// 4. Return 204
|
|
209
|
-
return c.body(null, 204);
|
|
210
|
-
});
|
|
24
|
+
app.all("*", (c) => handlePersonalServerDataRequest(c.req.raw, {
|
|
25
|
+
storage: dataStorage,
|
|
26
|
+
auth,
|
|
27
|
+
accessLogWriter: deps.accessLogWriter,
|
|
28
|
+
readFulfillmentReporter: deps.readFulfillmentReporter,
|
|
29
|
+
syncManager: deps.syncManager ?? null,
|
|
30
|
+
runtimeAvailability: deps.runtimeAvailability,
|
|
31
|
+
serverSigner: deps.serverSigner,
|
|
32
|
+
serverOwner: deps.serverOwner,
|
|
33
|
+
serverAddress: deps.serverAddress,
|
|
34
|
+
gateway: deps.gateway,
|
|
35
|
+
gatewayConfig: deps.gatewayConfig,
|
|
36
|
+
gatewayUrl: deps.gatewayUrl,
|
|
37
|
+
paymentEnabled: deps.paymentEnabled,
|
|
38
|
+
// Network identifier for the 402 challenge body. We use the chain
|
|
39
|
+
// id as the convention since the gateway is chain-scoped; clients
|
|
40
|
+
// dispatch on the (scheme, chainId) pair, not the human name.
|
|
41
|
+
network: deps.gatewayConfig
|
|
42
|
+
? `vana:${deps.gatewayConfig.chainId}`
|
|
43
|
+
: undefined,
|
|
44
|
+
logger: deps.logger,
|
|
45
|
+
}, { basePath: deps.mountPath }));
|
|
211
46
|
return app;
|
|
212
47
|
}
|
|
213
48
|
//# sourceMappingURL=data.js.map
|
package/dist/routes/data.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../src/routes/data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,
|
|
1
|
+
{"version":3,"file":"data.js","sourceRoot":"","sources":["../../src/routes/data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EACL,+BAA+B,GAGhC,MAAM,2CAA2C,CAAC;AAgBnD,OAAO,EACL,eAAe,EACf,oBAAoB,GACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAmDrD,MAAM,UAAU,UAAU,CAAC,IAAmB;IAC5C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,MAAM,WAAW,GACf,IAAI,CAAC,WAAW;QAChB,qBAAqB,CAAC;YACpB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;SACxC,CAAC,CAAC;IACL,MAAM,IAAI,GAAG,mBAAmB,CAAC;QAC/B,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,WAAW;QACX,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;KAC9C,CAAC,CAAC;IAEH,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,eAAe,CAAC,oBAAoB,CAAC,CAAC,CAAC;IAC1D,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CACjB,+BAA+B,CAC7B,CAAC,CAAC,GAAG,CAAC,GAAG,EACT;QACE,OAAO,EAAE,WAAW;QACpB,IAAI;QACJ,eAAe,EAAE,IAAI,CAAC,eAAe;QACrC,uBAAuB,EAAE,IAAI,CAAC,uBAAuB;QACrD,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,IAAI;QACrC,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;QAC7C,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,cAAc,EAAE,IAAI,CAAC,cAAc;QACnC,kEAAkE;QAClE,kEAAkE;QAClE,8DAA8D;QAC9D,OAAO,EAAE,IAAI,CAAC,aAAa;YACzB,CAAC,CAAC,QAAQ,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE;YACtC,CAAC,CAAC,SAAS;QACb,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,EACD,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,CAC7B,CACF,CAAC;IAEF,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/routes/grants.d.ts
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Grants routes — GET / (owner), POST / (create grant),
|
|
2
|
+
* Grants routes — GET / (owner), POST / (create grant), DELETE /:grantId
|
|
3
|
+
* (revoke grant), POST /verify (public).
|
|
3
4
|
*/
|
|
4
5
|
import { Hono } from "hono";
|
|
5
6
|
import type { Logger } from "pino";
|
|
6
|
-
import type { GatewayClient } from "@opendatalabs/
|
|
7
|
+
import type { DataPortabilityGatewayConfig, GatewayClient } from "@opendatalabs/vana-sdk/node";
|
|
8
|
+
import { type PersonalServerApiDispatchOptions } from "@opendatalabs/personal-server-ts-core/api";
|
|
7
9
|
import type { ServerSigner } from "@opendatalabs/personal-server-ts-core/signing";
|
|
10
|
+
import type { TokenStore } from "../token-store.js";
|
|
8
11
|
export interface GrantsRouteDeps {
|
|
9
12
|
logger: Logger;
|
|
10
13
|
gateway: GatewayClient;
|
|
14
|
+
gatewayConfig?: DataPortabilityGatewayConfig;
|
|
11
15
|
serverOwner?: `0x${string}`;
|
|
12
16
|
serverOrigin: string | (() => string);
|
|
13
17
|
devToken?: string;
|
|
18
|
+
accessToken?: string;
|
|
19
|
+
tokenStore?: TokenStore;
|
|
14
20
|
serverSigner?: ServerSigner;
|
|
21
|
+
mountPath?: PersonalServerApiDispatchOptions["basePath"];
|
|
15
22
|
}
|
|
16
23
|
export declare function grantsRoutes(deps: GrantsRouteDeps): Hono;
|
|
17
24
|
//# sourceMappingURL=grants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grants.d.ts","sourceRoot":"","sources":["../../src/routes/grants.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"grants.d.ts","sourceRoot":"","sources":["../../src/routes/grants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AACnC,OAAO,KAAK,EACV,4BAA4B,EAC5B,aAAa,EACd,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,KAAK,gCAAgC,EACtC,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+CAA+C,CAAC;AAClF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGpD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,aAAa,CAAC;IACvB,aAAa,CAAC,EAAE,4BAA4B,CAAC;IAC7C,WAAW,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,SAAS,CAAC,EAAE,gCAAgC,CAAC,UAAU,CAAC,CAAC;CAC1D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CA8BxD"}
|
package/dist/routes/grants.js
CHANGED
|
@@ -1,208 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Grants routes — GET / (owner), POST / (create grant),
|
|
2
|
+
* Grants routes — GET / (owner), POST / (create grant), DELETE /:grantId
|
|
3
|
+
* (revoke grant), POST /verify (public).
|
|
3
4
|
*/
|
|
4
5
|
import { Hono } from "hono";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { createWeb3AuthMiddleware } from "../middleware/web3-auth.js";
|
|
8
|
-
import { createOwnerCheckMiddleware } from "../middleware/owner-check.js";
|
|
9
|
-
function isValidCreateBody(body) {
|
|
10
|
-
if (body === null || typeof body !== "object" || Array.isArray(body))
|
|
11
|
-
return false;
|
|
12
|
-
const b = body;
|
|
13
|
-
if (typeof b.granteeAddress !== "string" ||
|
|
14
|
-
!b.granteeAddress.startsWith("0x"))
|
|
15
|
-
return false;
|
|
16
|
-
if (!Array.isArray(b.scopes) || b.scopes.length === 0)
|
|
17
|
-
return false;
|
|
18
|
-
if (!b.scopes.every((s) => typeof s === "string"))
|
|
19
|
-
return false;
|
|
20
|
-
if (b.expiresAt !== undefined && typeof b.expiresAt !== "number")
|
|
21
|
-
return false;
|
|
22
|
-
if (b.nonce !== undefined && typeof b.nonce !== "number")
|
|
23
|
-
return false;
|
|
24
|
-
return true;
|
|
25
|
-
}
|
|
26
|
-
function isValidVerifyBody(body) {
|
|
27
|
-
if (body === null || typeof body !== "object" || Array.isArray(body))
|
|
28
|
-
return false;
|
|
29
|
-
const b = body;
|
|
30
|
-
if (typeof b.grantId !== "string" || b.grantId.length === 0)
|
|
31
|
-
return false;
|
|
32
|
-
if (typeof b.signature !== "string" || !b.signature.startsWith("0x"))
|
|
33
|
-
return false;
|
|
34
|
-
if (b.payload === null ||
|
|
35
|
-
typeof b.payload !== "object" ||
|
|
36
|
-
Array.isArray(b.payload))
|
|
37
|
-
return false;
|
|
38
|
-
const p = b.payload;
|
|
39
|
-
if (typeof p.user !== "string" || !p.user.startsWith("0x"))
|
|
40
|
-
return false;
|
|
41
|
-
if (typeof p.builder !== "string" || !p.builder.startsWith("0x"))
|
|
42
|
-
return false;
|
|
43
|
-
if (!Array.isArray(p.scopes) || p.scopes.length === 0)
|
|
44
|
-
return false;
|
|
45
|
-
if (!p.scopes.every((s) => typeof s === "string"))
|
|
46
|
-
return false;
|
|
47
|
-
if (typeof p.expiresAt !== "number")
|
|
48
|
-
return false;
|
|
49
|
-
if (typeof p.nonce !== "number")
|
|
50
|
-
return false;
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
6
|
+
import { handlePersonalServerGrantsRequest, } from "@opendatalabs/personal-server-ts-core/api";
|
|
7
|
+
import { createServerApiAuth } from "../api-auth.js";
|
|
53
8
|
export function grantsRoutes(deps) {
|
|
54
9
|
const app = new Hono();
|
|
55
|
-
const
|
|
10
|
+
const auth = createServerApiAuth({
|
|
56
11
|
serverOrigin: deps.serverOrigin,
|
|
57
12
|
devToken: deps.devToken,
|
|
13
|
+
accessToken: deps.accessToken,
|
|
14
|
+
tokenStore: deps.tokenStore,
|
|
58
15
|
serverOwner: deps.serverOwner,
|
|
16
|
+
gateway: deps.gateway,
|
|
59
17
|
});
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}, 500);
|
|
71
|
-
}
|
|
72
|
-
const grants = await deps.gateway.listGrantsByUser(deps.serverOwner);
|
|
73
|
-
return c.json({ grants });
|
|
74
|
-
});
|
|
75
|
-
// POST / — create a grant (owner-only, called by Desktop App)
|
|
76
|
-
app.post("/", web3Auth, ownerCheck, async (c) => {
|
|
77
|
-
if (!deps.serverOwner) {
|
|
78
|
-
return c.json({
|
|
79
|
-
error: {
|
|
80
|
-
code: 500,
|
|
81
|
-
errorCode: "SERVER_NOT_CONFIGURED",
|
|
82
|
-
message: "Server owner address not configured. Set VANA_MASTER_KEY_SIGNATURE environment variable.",
|
|
83
|
-
},
|
|
84
|
-
}, 500);
|
|
85
|
-
}
|
|
86
|
-
if (!deps.serverSigner) {
|
|
87
|
-
return c.json({
|
|
88
|
-
error: {
|
|
89
|
-
code: 500,
|
|
90
|
-
errorCode: "SERVER_SIGNER_NOT_CONFIGURED",
|
|
91
|
-
message: "Server signer not configured. Set VANA_MASTER_KEY_SIGNATURE environment variable.",
|
|
92
|
-
},
|
|
93
|
-
}, 500);
|
|
94
|
-
}
|
|
95
|
-
let body;
|
|
96
|
-
try {
|
|
97
|
-
body = await c.req.json();
|
|
98
|
-
}
|
|
99
|
-
catch {
|
|
100
|
-
return c.json({ error: "INVALID_BODY", message: "Invalid JSON body" }, 400);
|
|
101
|
-
}
|
|
102
|
-
if (!isValidCreateBody(body)) {
|
|
103
|
-
return c.json({
|
|
104
|
-
error: "INVALID_BODY",
|
|
105
|
-
message: "Body must include granteeAddress (0x string) and scopes (non-empty string array)",
|
|
106
|
-
}, 400);
|
|
107
|
-
}
|
|
108
|
-
const { granteeAddress, scopes, expiresAt, nonce } = body;
|
|
109
|
-
// Look up builder to get their on-chain ID
|
|
110
|
-
const builder = await deps.gateway.getBuilder(granteeAddress);
|
|
111
|
-
if (!builder) {
|
|
112
|
-
return c.json({
|
|
113
|
-
error: {
|
|
114
|
-
code: 404,
|
|
115
|
-
errorCode: "BUILDER_NOT_REGISTERED",
|
|
116
|
-
message: `Builder ${granteeAddress} is not registered on-chain`,
|
|
117
|
-
},
|
|
118
|
-
}, 404);
|
|
119
|
-
}
|
|
120
|
-
// Build the grant payload JSON string
|
|
121
|
-
const grantPayload = JSON.stringify({
|
|
122
|
-
user: deps.serverOwner,
|
|
123
|
-
builder: granteeAddress,
|
|
124
|
-
scopes,
|
|
125
|
-
expiresAt: expiresAt ?? 0,
|
|
126
|
-
nonce: nonce ?? Date.now(),
|
|
127
|
-
});
|
|
128
|
-
// Sign EIP-712 GrantRegistration
|
|
129
|
-
const signature = await deps.serverSigner.signGrantRegistration({
|
|
130
|
-
grantorAddress: deps.serverOwner,
|
|
131
|
-
granteeId: builder.id,
|
|
132
|
-
grant: grantPayload,
|
|
133
|
-
fileIds: [],
|
|
134
|
-
});
|
|
135
|
-
// Submit to Gateway
|
|
136
|
-
const result = await deps.gateway.createGrant({
|
|
137
|
-
grantorAddress: deps.serverOwner,
|
|
138
|
-
granteeId: builder.id,
|
|
139
|
-
grant: grantPayload,
|
|
140
|
-
fileIds: [],
|
|
141
|
-
signature,
|
|
142
|
-
});
|
|
143
|
-
return c.json({ grantId: result.grantId }, 201);
|
|
144
|
-
});
|
|
145
|
-
// POST /verify — public endpoint, no auth required
|
|
146
|
-
app.post("/verify", async (c) => {
|
|
147
|
-
let body;
|
|
148
|
-
try {
|
|
149
|
-
body = await c.req.json();
|
|
150
|
-
}
|
|
151
|
-
catch {
|
|
152
|
-
return c.json({ error: "INVALID_BODY", message: "Invalid JSON body" }, 400);
|
|
153
|
-
}
|
|
154
|
-
if (!isValidVerifyBody(body)) {
|
|
155
|
-
return c.json({
|
|
156
|
-
error: "INVALID_BODY",
|
|
157
|
-
message: "Body must include grantId (string), payload (object with user, builder, scopes, expiresAt, nonce), and signature (0x string)",
|
|
158
|
-
}, 400);
|
|
159
|
-
}
|
|
160
|
-
const { payload, signature } = body;
|
|
161
|
-
// Verify EIP-712 signature — recover signer and check === payload.user
|
|
162
|
-
let valid;
|
|
163
|
-
try {
|
|
164
|
-
valid = await verifyTypedData({
|
|
165
|
-
address: payload.user,
|
|
166
|
-
domain: GRANT_DOMAIN,
|
|
167
|
-
types: GRANT_TYPES,
|
|
168
|
-
primaryType: "Grant",
|
|
169
|
-
message: {
|
|
170
|
-
user: payload.user,
|
|
171
|
-
builder: payload.builder,
|
|
172
|
-
scopes: payload.scopes,
|
|
173
|
-
expiresAt: BigInt(payload.expiresAt),
|
|
174
|
-
nonce: BigInt(payload.nonce),
|
|
175
|
-
},
|
|
176
|
-
signature: signature,
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
catch {
|
|
180
|
-
return c.json({
|
|
181
|
-
valid: false,
|
|
182
|
-
error: "EIP-712 signature verification failed",
|
|
183
|
-
});
|
|
184
|
-
}
|
|
185
|
-
if (!valid) {
|
|
186
|
-
return c.json({
|
|
187
|
-
valid: false,
|
|
188
|
-
error: "Grant signature does not match user",
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
// Check expiry: expiresAt > 0 means there IS an expiry
|
|
192
|
-
if (payload.expiresAt > 0) {
|
|
193
|
-
const nowSeconds = Math.floor(Date.now() / 1000);
|
|
194
|
-
if (payload.expiresAt < nowSeconds) {
|
|
195
|
-
return c.json({ valid: false, error: "Grant has expired" });
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
return c.json({
|
|
199
|
-
valid: true,
|
|
200
|
-
user: payload.user,
|
|
201
|
-
builder: payload.builder,
|
|
202
|
-
scopes: payload.scopes,
|
|
203
|
-
expiresAt: payload.expiresAt,
|
|
204
|
-
});
|
|
205
|
-
});
|
|
18
|
+
const handler = (c) => handlePersonalServerGrantsRequest(c.req.raw, {
|
|
19
|
+
auth,
|
|
20
|
+
gateway: deps.gateway,
|
|
21
|
+
gatewayConfig: deps.gatewayConfig,
|
|
22
|
+
serverOwner: deps.serverOwner,
|
|
23
|
+
serverSigner: deps.serverSigner,
|
|
24
|
+
}, { basePath: deps.mountPath });
|
|
25
|
+
app.all("/", handler);
|
|
26
|
+
app.delete("/:grantId", handler);
|
|
27
|
+
app.all("/*", handler);
|
|
206
28
|
return app;
|
|
207
29
|
}
|
|
208
30
|
//# sourceMappingURL=grants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grants.js","sourceRoot":"","sources":["../../src/routes/grants.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"grants.js","sourceRoot":"","sources":["../../src/routes/grants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAC;AAM1C,OAAO,EACL,iCAAiC,GAElC,MAAM,2CAA2C,CAAC;AAGnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAerD,MAAM,UAAU,YAAY,CAAC,IAAqB;IAChD,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,MAAM,IAAI,GAAG,mBAAmB,CAAC;QAC/B,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,UAAU,EAAE,IAAI,CAAC,UAAU;QAC3B,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,OAAO,EAAE,IAAI,CAAC,OAAO;KACtB,CAAC,CAAC;IAEH,MAAM,OAAO,GAAY,CAAC,CAAC,EAAE,EAAE,CAC7B,iCAAiC,CAC/B,CAAC,CAAC,GAAG,CAAC,GAAG,EACT;QACE,IAAI;QACJ,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,aAAa,EAAE,IAAI,CAAC,aAAa;QACjC,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;KAChC,EACD,EAAE,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,CAC7B,CAAC;IAEJ,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACtB,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACjC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAEvB,OAAO,GAAG,CAAC;AACb,CAAC"}
|
package/dist/routes/health.d.ts
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import { Hono } from "hono";
|
|
2
|
-
import type { GatewayClient } from "@opendatalabs/
|
|
2
|
+
import type { DataPortabilityGatewayConfig, GatewayClient } from "@opendatalabs/vana-sdk/node";
|
|
3
|
+
import type { RuntimeAvailabilityPort } from "@opendatalabs/personal-server-ts-core/ports";
|
|
3
4
|
import type { Logger } from "pino";
|
|
4
5
|
import type { IdentityInfo } from "../app.js";
|
|
5
6
|
import type { TunnelStatusInfo } from "../tunnel/index.js";
|
|
6
7
|
export interface HealthDeps {
|
|
7
8
|
version: string;
|
|
8
9
|
startedAt: Date;
|
|
10
|
+
serverOrigin?: string | (() => string);
|
|
9
11
|
serverOwner?: `0x${string}`;
|
|
10
12
|
identity?: IdentityInfo;
|
|
11
13
|
gateway?: GatewayClient;
|
|
14
|
+
gatewayConfig?: DataPortabilityGatewayConfig & {
|
|
15
|
+
url?: string;
|
|
16
|
+
};
|
|
12
17
|
logger?: Logger;
|
|
13
18
|
getTunnelStatus?: () => TunnelStatusInfo | null;
|
|
19
|
+
runtimeAvailability?: RuntimeAvailabilityPort;
|
|
14
20
|
}
|
|
15
21
|
export declare function healthRoute(deps: HealthDeps): Hono;
|
|
16
22
|
//# sourceMappingURL=health.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/routes/health.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EACV,4BAA4B,EAC5B,aAAa,EACd,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,6CAA6C,CAAC;AAC3F,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,KAAK,MAAM,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,aAAa,CAAC,EAAE,4BAA4B,GAAG;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,MAAM,gBAAgB,GAAG,IAAI,CAAC;IAChD,mBAAmB,CAAC,EAAE,uBAAuB,CAAC;CAC/C;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,CAsFlD"}
|
package/dist/routes/health.js
CHANGED
|
@@ -22,14 +22,51 @@ export function healthRoute(deps) {
|
|
|
22
22
|
serverId,
|
|
23
23
|
}
|
|
24
24
|
: null;
|
|
25
|
-
const
|
|
25
|
+
const tunnelStatus = deps.getTunnelStatus?.() ?? null;
|
|
26
|
+
const fallbackOrigin = typeof deps.serverOrigin === "function"
|
|
27
|
+
? deps.serverOrigin()
|
|
28
|
+
: deps.serverOrigin;
|
|
29
|
+
const tunnelPublicUrl = tunnelStatus?.publicUrl ?? null;
|
|
30
|
+
const tunnelReady = tunnelStatus?.status === "connected" && tunnelStatus.routable !== false;
|
|
31
|
+
const apiOrigin = tunnelReady && tunnelPublicUrl
|
|
32
|
+
? tunnelPublicUrl
|
|
33
|
+
: (fallbackOrigin ?? null);
|
|
34
|
+
const registrationUrl = tunnelPublicUrl ?? apiOrigin;
|
|
35
|
+
const registration = deps.serverOwner && identity && registrationUrl
|
|
36
|
+
? {
|
|
37
|
+
ownerAddress: deps.serverOwner,
|
|
38
|
+
serverAddress: identity.address,
|
|
39
|
+
publicKey: identity.publicKey,
|
|
40
|
+
serverUrl: registrationUrl,
|
|
41
|
+
serverId,
|
|
42
|
+
registered: Boolean(serverId),
|
|
43
|
+
}
|
|
44
|
+
: null;
|
|
45
|
+
const tunnel = tunnelStatus && registration && tunnelStatus.publicUrl
|
|
46
|
+
? {
|
|
47
|
+
...tunnelStatus,
|
|
48
|
+
routable: registration.registered && tunnelStatus.routable !== false,
|
|
49
|
+
warning: registration.registered
|
|
50
|
+
? tunnelStatus.warning
|
|
51
|
+
: "Server not registered with gateway",
|
|
52
|
+
}
|
|
53
|
+
: tunnelStatus;
|
|
54
|
+
const runtimeAvailable = (await deps.runtimeAvailability?.isAvailable()) ?? true;
|
|
26
55
|
return c.json({
|
|
27
|
-
status: "healthy",
|
|
56
|
+
status: runtimeAvailable ? "healthy" : "unavailable",
|
|
28
57
|
version: deps.version,
|
|
29
58
|
uptime: Math.floor(uptimeMs / 1000),
|
|
30
59
|
owner: deps.serverOwner ?? null,
|
|
60
|
+
apiOrigin,
|
|
61
|
+
gatewayUrl: deps.gatewayConfig?.url ?? null,
|
|
62
|
+
gatewayConfig: deps.gatewayConfig ?? null,
|
|
31
63
|
identity,
|
|
64
|
+
registration,
|
|
32
65
|
tunnel,
|
|
66
|
+
runtime: {
|
|
67
|
+
kind: "ps-node",
|
|
68
|
+
available: runtimeAvailable,
|
|
69
|
+
},
|
|
33
70
|
});
|
|
34
71
|
});
|
|
35
72
|
return app;
|