@langchain/langgraph-api 1.2.2 → 1.2.4

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.
Files changed (47) hide show
  1. package/dist/experimental/embed/protocol.mjs +86 -15
  2. package/dist/graph/load.d.mts +1 -1
  3. package/dist/graph/load.utils.d.mts +1 -1
  4. package/dist/protocol/service.d.mts +9 -1
  5. package/dist/protocol/service.mjs +65 -25
  6. package/package.json +7 -7
  7. package/dist/src/api/assistants.d.mts +0 -3
  8. package/dist/src/api/assistants.mjs +0 -194
  9. package/dist/src/api/meta.d.mts +0 -3
  10. package/dist/src/api/meta.mjs +0 -65
  11. package/dist/src/api/protocol.d.mts +0 -7
  12. package/dist/src/api/protocol.mjs +0 -157
  13. package/dist/src/api/runs.d.mts +0 -3
  14. package/dist/src/api/runs.mjs +0 -335
  15. package/dist/src/api/store.d.mts +0 -3
  16. package/dist/src/api/store.mjs +0 -111
  17. package/dist/src/api/threads.d.mts +0 -3
  18. package/dist/src/api/threads.mjs +0 -143
  19. package/dist/src/graph/load.utils.d.mts +0 -22
  20. package/dist/src/graph/load.utils.mjs +0 -59
  21. package/dist/src/protocol/service.d.mts +0 -101
  22. package/dist/src/protocol/service.mjs +0 -568
  23. package/dist/src/protocol/session/event-normalizers.d.mts +0 -52
  24. package/dist/src/protocol/session/index.d.mts +0 -261
  25. package/dist/src/protocol/session/index.mjs +0 -826
  26. package/dist/src/protocol/session/namespace.d.mts +0 -47
  27. package/dist/src/protocol/session/namespace.mjs +0 -62
  28. package/dist/src/protocol/types.d.mts +0 -121
  29. package/dist/src/protocol/types.mjs +0 -1
  30. package/dist/src/schemas.d.mts +0 -1552
  31. package/dist/src/semver/index.d.mts +0 -15
  32. package/dist/src/semver/index.mjs +0 -46
  33. package/dist/src/semver/satisfiesPeerRange.d.mts +0 -1
  34. package/dist/src/semver/satisfiesPeerRange.mjs +0 -19
  35. package/dist/src/state.d.mts +0 -3
  36. package/dist/src/state.mjs +0 -30
  37. package/dist/src/storage/context.d.mts +0 -3
  38. package/dist/src/storage/context.mjs +0 -11
  39. package/dist/src/storage/ops.mjs +0 -1281
  40. package/dist/src/stream.d.mts +0 -64
  41. package/dist/src/stream.mjs +0 -427
  42. package/dist/src/utils/hono.d.mts +0 -5
  43. package/dist/src/utils/hono.mjs +0 -24
  44. package/dist/src/utils/runnableConfig.d.mts +0 -3
  45. package/dist/src/utils/runnableConfig.mjs +0 -45
  46. package/dist/src/webhook.d.mts +0 -11
  47. package/dist/src/webhook.mjs +0 -30
@@ -1,157 +0,0 @@
1
- import { zValidator } from "@hono/zod-validator";
2
- import { Hono } from "hono";
3
- import { streamSSE } from "hono/streaming";
4
- import { v7 as uuid7 } from "uuid";
5
- import { z } from "zod/v3";
6
- import { ProtocolService } from "../protocol/service.mjs";
7
- import { jsonExtra } from "../utils/hono.mjs";
8
- import { serialiseAsDict } from "../utils/serde.mjs";
9
- const ThreadIdSchema = z.object({ thread_id: z.string() });
10
- const EventsFilterSchema = z
11
- .object({
12
- channels: z.array(z.string()),
13
- namespaces: z.array(z.array(z.string())).optional(),
14
- depth: z.number().int().nonnegative().optional(),
15
- since: z.number().int().nonnegative().optional(),
16
- })
17
- .strict();
18
- const ProtocolCommandSchema = z.object({
19
- id: z.number().int().nonnegative(),
20
- method: z.string(),
21
- params: z.record(z.unknown()).optional(),
22
- });
23
- /**
24
- * Normalize browser/node websocket message payloads into UTF-8 text so the
25
- * protocol layer only needs to handle JSON strings.
26
- */
27
- const parseSocketPayload = async (event) => {
28
- if (typeof event.data === "string")
29
- return event.data;
30
- if (event.data instanceof ArrayBuffer) {
31
- return new TextDecoder().decode(new Uint8Array(event.data));
32
- }
33
- if (event.data instanceof Blob) {
34
- const buffer = await event.data.arrayBuffer();
35
- return new TextDecoder().decode(new Uint8Array(buffer));
36
- }
37
- return String(event.data);
38
- };
39
- /**
40
- * Register thread-centric protocol transport routes for LangGraph API.
41
- */
42
- export default function createProtocolApi(upgradeWebSocket, ops) {
43
- const api = new Hono();
44
- const protocolService = new ProtocolService({
45
- runs: ops.runs,
46
- threads: ops.threads,
47
- });
48
- api.get("/threads/:thread_id/stream/events", zValidator("param", ThreadIdSchema), upgradeWebSocket((c) => {
49
- const { thread_id } = c.req.valid("param");
50
- const record = protocolService.ensureThread({
51
- threadId: thread_id,
52
- transport: "websocket",
53
- auth: c.var.auth,
54
- });
55
- return {
56
- async onOpen(_event, ws) {
57
- await protocolService.attachEventSink(thread_id, (event) => {
58
- ws.send(serialiseAsDict(event));
59
- });
60
- },
61
- async onMessage(event, ws) {
62
- let payload;
63
- try {
64
- payload = JSON.parse(await parseSocketPayload(event));
65
- }
66
- catch {
67
- ws.send(serialiseAsDict({
68
- type: "error",
69
- id: null,
70
- error: "invalid_argument",
71
- message: "Protocol commands must be valid JSON.",
72
- }));
73
- return;
74
- }
75
- if (typeof payload !== "object" ||
76
- payload == null ||
77
- typeof payload.id !== "number" ||
78
- typeof payload.method !== "string") {
79
- ws.send(serialiseAsDict({
80
- type: "error",
81
- id: null,
82
- error: "invalid_argument",
83
- message: "Protocol commands must include an integer id and string method.",
84
- }));
85
- return;
86
- }
87
- const response = await protocolService.handleCommand(record.threadId, payload);
88
- // `null` means the session already wrote the response through
89
- // the shared transport queue (see
90
- // `ProtocolSession.handleSubscribeForResponse`). Sending again
91
- // here would double-deliver the success and break ordering.
92
- if (response != null) {
93
- ws.send(serialiseAsDict(response));
94
- }
95
- },
96
- onClose() {
97
- void protocolService.closeThread(record.threadId);
98
- },
99
- onError() {
100
- void protocolService.closeThread(record.threadId);
101
- },
102
- };
103
- }));
104
- api.post("/threads/:thread_id/commands", zValidator("param", ThreadIdSchema), zValidator("json", ProtocolCommandSchema), async (c) => {
105
- const { thread_id } = c.req.valid("param");
106
- protocolService.ensureThread({
107
- threadId: thread_id,
108
- transport: "sse-http",
109
- auth: c.var.auth,
110
- });
111
- const payload = c.req.valid("json");
112
- return jsonExtra(c, await protocolService.handleCommand(thread_id, payload));
113
- });
114
- api.post("/threads/:thread_id/stream/events", zValidator("param", ThreadIdSchema), zValidator("json", EventsFilterSchema), async (c) => {
115
- const { thread_id } = c.req.valid("param");
116
- protocolService.ensureThread({
117
- threadId: thread_id,
118
- transport: "sse-http",
119
- auth: c.var.auth,
120
- });
121
- const body = c.req.valid("json");
122
- const sinkId = uuid7();
123
- const filter = {
124
- channels: new Set(body.channels),
125
- namespaces: body.namespaces,
126
- depth: body.depth,
127
- since: body.since,
128
- };
129
- return streamSSE(c, async (stream) => {
130
- const delivered = new Set();
131
- const writeSse = async (event) => {
132
- if (event.event_id == null)
133
- return;
134
- if (delivered.has(event.event_id))
135
- return;
136
- delivered.add(event.event_id);
137
- await stream.writeSSE({
138
- id: event.event_id,
139
- event: event.method,
140
- data: serialiseAsDict(event),
141
- });
142
- };
143
- await protocolService.attachFilteredEventSink(thread_id, {
144
- id: sinkId,
145
- filter,
146
- send: writeSse,
147
- });
148
- stream.onAbort(() => {
149
- protocolService.detachEventSink(thread_id, sinkId);
150
- });
151
- await new Promise((resolve) => {
152
- stream.onAbort(() => resolve());
153
- });
154
- });
155
- });
156
- return api;
157
- }
@@ -1,3 +0,0 @@
1
- import { Hono } from "hono";
2
- declare const api: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
3
- export default api;
@@ -1,335 +0,0 @@
1
- import { zValidator } from "@hono/zod-validator";
2
- import { Hono } from "hono";
3
- import { HTTPException } from "hono/http-exception";
4
- import { streamSSE } from "hono/streaming";
5
- import { v7 as uuid7 } from "uuid";
6
- import { z } from "zod/v3";
7
- import { getAssistantId } from "../graph/load.mjs";
8
- import { logError, logger } from "../logging.mjs";
9
- import * as schemas from "../schemas.mjs";
10
- import { runs, threads } from "../storage/context.mjs";
11
- import { getDisconnectAbortSignal, jsonExtra, waitKeepAlive, } from "../utils/hono.mjs";
12
- import { serialiseAsDict } from "../utils/serde.mjs";
13
- const api = new Hono();
14
- const createValidRun = async (threadId, payload, kwargs) => {
15
- const { assistant_id: assistantId, ...run } = payload;
16
- const { auth, headers } = kwargs ?? {};
17
- const runId = uuid7();
18
- const streamMode = Array.isArray(payload.stream_mode)
19
- ? payload.stream_mode
20
- : payload.stream_mode != null
21
- ? [payload.stream_mode]
22
- : [];
23
- if (streamMode.length === 0)
24
- streamMode.push("values");
25
- const multitaskStrategy = payload.multitask_strategy ?? "reject";
26
- const preventInsertInInflight = multitaskStrategy === "reject";
27
- const config = { ...run.config };
28
- if (run.checkpoint_id) {
29
- config.configurable ??= {};
30
- config.configurable.checkpoint_id = run.checkpoint_id;
31
- }
32
- if (run.checkpoint) {
33
- config.configurable ??= {};
34
- Object.assign(config.configurable, run.checkpoint);
35
- }
36
- if (run.langsmith_tracer) {
37
- config.configurable ??= {};
38
- Object.assign(config.configurable, {
39
- langsmith_project: run.langsmith_tracer.project_name,
40
- langsmith_example_id: run.langsmith_tracer.example_id,
41
- });
42
- }
43
- if (headers) {
44
- for (const [rawKey, value] of headers.entries()) {
45
- const key = rawKey.toLowerCase();
46
- if (key.startsWith("x-")) {
47
- if (["x-api-key", "x-tenant-id", "x-service-key"].includes(key)) {
48
- continue;
49
- }
50
- config.configurable ??= {};
51
- config.configurable[key] = value;
52
- }
53
- else if (key === "user-agent") {
54
- config.configurable ??= {};
55
- config.configurable[key] = value;
56
- }
57
- }
58
- }
59
- let userId;
60
- if (auth) {
61
- userId = auth.user.identity ?? auth.user.id;
62
- config.configurable ??= {};
63
- config.configurable["langgraph_auth_user"] = auth.user;
64
- config.configurable["langgraph_auth_user_id"] = userId;
65
- config.configurable["langgraph_auth_permissions"] = auth.scopes;
66
- }
67
- let feedbackKeys = run.feedback_keys != null
68
- ? Array.isArray(run.feedback_keys)
69
- ? run.feedback_keys
70
- : [run.feedback_keys]
71
- : undefined;
72
- if (!feedbackKeys?.length)
73
- feedbackKeys = undefined;
74
- const [first, ...inflight] = await runs().put(runId, getAssistantId(assistantId), {
75
- input: run.input,
76
- command: run.command,
77
- config,
78
- context: run.context,
79
- stream_mode: streamMode,
80
- interrupt_before: run.interrupt_before,
81
- interrupt_after: run.interrupt_after,
82
- webhook: run.webhook,
83
- feedback_keys: feedbackKeys,
84
- temporary: threadId == null && (run.on_completion ?? "delete") === "delete",
85
- subgraphs: run.stream_subgraphs ?? false,
86
- resumable: run.stream_resumable ?? false,
87
- }, {
88
- threadId,
89
- userId,
90
- metadata: run.metadata,
91
- status: "pending",
92
- multitaskStrategy,
93
- preventInsertInInflight,
94
- afterSeconds: payload.after_seconds,
95
- ifNotExists: payload.if_not_exists,
96
- }, auth);
97
- if (first?.run_id === runId) {
98
- logger.info("Created run", { run_id: runId, thread_id: threadId });
99
- if ((multitaskStrategy === "interrupt" || multitaskStrategy === "rollback") &&
100
- inflight.length > 0) {
101
- try {
102
- await runs().cancel(threadId, inflight.map((run) => run.run_id), { action: multitaskStrategy }, auth);
103
- }
104
- catch (error) {
105
- logger.warn("Failed to cancel inflight runs, might be already cancelled", {
106
- error,
107
- run_ids: inflight.map((run) => run.run_id),
108
- thread_id: threadId,
109
- });
110
- }
111
- }
112
- return first;
113
- }
114
- else if (multitaskStrategy === "reject") {
115
- throw new HTTPException(422, {
116
- message: "Thread is already running a task. Wait for it to finish or choose a different multitask strategy.",
117
- });
118
- }
119
- throw new HTTPException(500, {
120
- message: "Unreachable state when creating run",
121
- });
122
- };
123
- api.post("/runs/crons", zValidator("json", schemas.CronCreate), async () => {
124
- // Create Thread Cron
125
- throw new HTTPException(500, { message: "Not implemented" });
126
- });
127
- api.post("/runs/crons/search", zValidator("json", schemas.CronSearch), async () => {
128
- // Search Crons
129
- throw new HTTPException(500, { message: "Not implemented" });
130
- });
131
- api.delete("/runs/crons/:cron_id", zValidator("param", z.object({ cron_id: z.string().uuid() })), async () => {
132
- // Delete Cron
133
- throw new HTTPException(500, { message: "Not implemented" });
134
- });
135
- api.post("/threads/:thread_id/runs/crons", zValidator("param", z.object({ thread_id: z.string().uuid() })), zValidator("json", schemas.CronCreate), async () => {
136
- // Create Thread Cron
137
- throw new HTTPException(500, { message: "Not implemented" });
138
- });
139
- api.post("/runs/stream", zValidator("json", schemas.RunCreate), async (c) => {
140
- // Stream Stateless Run
141
- const payload = c.req.valid("json");
142
- const run = await createValidRun(undefined, payload, {
143
- auth: c.var.auth,
144
- headers: c.req.raw.headers,
145
- });
146
- c.header("Content-Location", `/runs/${run.run_id}`);
147
- return streamSSE(c, async (stream) => {
148
- const cancelOnDisconnect = payload.on_disconnect === "cancel"
149
- ? getDisconnectAbortSignal(c, stream)
150
- : undefined;
151
- try {
152
- for await (const { event, data } of runs().stream.join(run.run_id, undefined, {
153
- signal: cancelOnDisconnect,
154
- cancelOnDisconnect: cancelOnDisconnect != null,
155
- lastEventId: run.kwargs.resumable ? "-1" : undefined,
156
- ignore404: true,
157
- }, c.var.auth)) {
158
- await stream.writeSSE({ data: serialiseAsDict(data), event });
159
- }
160
- }
161
- catch (error) {
162
- logError(error, { prefix: "Error streaming run" });
163
- }
164
- });
165
- });
166
- // TODO: port to Python API
167
- api.get("/runs/:run_id/stream", zValidator("param", z.object({ run_id: z.string().uuid() })), zValidator("query", z.object({ cancel_on_disconnect: schemas.coercedBoolean.optional() })), async (c) => {
168
- const { run_id } = c.req.valid("param");
169
- const query = c.req.valid("query");
170
- const lastEventId = c.req.header("Last-Event-ID") || undefined;
171
- c.header("Content-Location", `/runs/${run_id}`);
172
- return streamSSE(c, async (stream) => {
173
- const cancelOnDisconnect = query.cancel_on_disconnect
174
- ? getDisconnectAbortSignal(c, stream)
175
- : undefined;
176
- try {
177
- for await (const { id, event, data } of runs().stream.join(run_id, undefined, {
178
- signal: cancelOnDisconnect,
179
- cancelOnDisconnect: cancelOnDisconnect != null,
180
- lastEventId,
181
- ignore404: true,
182
- }, c.var.auth)) {
183
- await stream.writeSSE({ id, data: serialiseAsDict(data), event });
184
- }
185
- }
186
- catch (error) {
187
- logError(error, { prefix: "Error streaming run" });
188
- }
189
- });
190
- });
191
- api.post("/runs/wait", zValidator("json", schemas.RunCreate), async (c) => {
192
- // Wait Stateless Run
193
- const payload = c.req.valid("json");
194
- const run = await createValidRun(undefined, payload, {
195
- auth: c.var.auth,
196
- headers: c.req.raw.headers,
197
- });
198
- c.header("Content-Location", `/runs/${run.run_id}`);
199
- return waitKeepAlive(c, runs().wait(run.run_id, undefined, c.var.auth));
200
- });
201
- api.post("/runs", zValidator("json", schemas.RunCreate), async (c) => {
202
- // Create Stateless Run
203
- const payload = c.req.valid("json");
204
- const run = await createValidRun(undefined, payload, {
205
- auth: c.var.auth,
206
- headers: c.req.raw.headers,
207
- });
208
- c.header("Content-Location", `/runs/${run.run_id}`);
209
- return jsonExtra(c, run);
210
- });
211
- api.post("/runs/batch", zValidator("json", schemas.RunBatchCreate), async (c) => {
212
- // Batch Runs
213
- const payload = c.req.valid("json");
214
- const runs = await Promise.all(payload.map((run) => createValidRun(undefined, run, {
215
- auth: c.var.auth,
216
- headers: c.req.raw.headers,
217
- })));
218
- return jsonExtra(c, runs);
219
- });
220
- api.get("/threads/:thread_id/runs", zValidator("param", z.object({ thread_id: z.string().uuid() })), zValidator("query", z.object({
221
- limit: z.coerce.number().nullish(),
222
- offset: z.coerce.number().nullish(),
223
- status: z.string().nullish(),
224
- metadata: z.record(z.string(), z.unknown()).nullish(),
225
- })), async (c) => {
226
- // List runs
227
- const { thread_id } = c.req.valid("param");
228
- const { limit, offset, status, metadata } = c.req.valid("query");
229
- const [runsResponse] = await Promise.all([
230
- runs().search(thread_id, { limit, offset, status, metadata }, c.var.auth),
231
- threads().get(thread_id, c.var.auth),
232
- ]);
233
- return jsonExtra(c, runsResponse);
234
- });
235
- api.post("/threads/:thread_id/runs", zValidator("param", z.object({ thread_id: z.string().uuid() })), zValidator("json", schemas.RunCreate), async (c) => {
236
- // Create Run
237
- const { thread_id } = c.req.valid("param");
238
- const payload = c.req.valid("json");
239
- const run = await createValidRun(thread_id, payload, {
240
- auth: c.var.auth,
241
- headers: c.req.raw.headers,
242
- });
243
- c.header("Content-Location", `/threads/${thread_id}/runs/${run.run_id}`);
244
- return jsonExtra(c, run);
245
- });
246
- api.post("/threads/:thread_id/runs/stream", zValidator("param", z.object({ thread_id: z.string().uuid() })), zValidator("json", schemas.RunCreate), async (c) => {
247
- // Stream Run
248
- const { thread_id } = c.req.valid("param");
249
- const payload = c.req.valid("json");
250
- const run = await createValidRun(thread_id, payload, {
251
- auth: c.var.auth,
252
- headers: c.req.raw.headers,
253
- });
254
- c.header("Content-Location", `/threads/${thread_id}/runs/${run.run_id}`);
255
- return streamSSE(c, async (stream) => {
256
- const cancelOnDisconnect = payload.on_disconnect === "cancel"
257
- ? getDisconnectAbortSignal(c, stream)
258
- : undefined;
259
- try {
260
- for await (const { id, event, data } of runs().stream.join(run.run_id, thread_id, {
261
- signal: cancelOnDisconnect,
262
- cancelOnDisconnect: cancelOnDisconnect != null,
263
- lastEventId: run.kwargs.resumable ? "-1" : undefined,
264
- }, c.var.auth)) {
265
- await stream.writeSSE({ id, data: serialiseAsDict(data), event });
266
- }
267
- }
268
- catch (error) {
269
- logError(error, { prefix: "Error streaming run" });
270
- }
271
- });
272
- });
273
- api.post("/threads/:thread_id/runs/wait", zValidator("param", z.object({ thread_id: z.string().uuid() })), zValidator("json", schemas.RunCreate), async (c) => {
274
- // Wait Run
275
- const { thread_id } = c.req.valid("param");
276
- const payload = c.req.valid("json");
277
- const run = await createValidRun(thread_id, payload, {
278
- auth: c.var.auth,
279
- headers: c.req.raw.headers,
280
- });
281
- c.header("Content-Location", `/threads/${thread_id}/runs/${run.run_id}`);
282
- return waitKeepAlive(c, runs().join(run.run_id, thread_id, c.var.auth));
283
- });
284
- api.get("/threads/:thread_id/runs/:run_id", zValidator("param", z.object({ thread_id: z.string().uuid(), run_id: z.string().uuid() })), async (c) => {
285
- const { thread_id, run_id } = c.req.valid("param");
286
- const [run] = await Promise.all([
287
- runs().get(run_id, thread_id, c.var.auth),
288
- threads().get(thread_id, c.var.auth),
289
- ]);
290
- if (run == null)
291
- throw new HTTPException(404, { message: "Run not found" });
292
- return jsonExtra(c, run);
293
- });
294
- api.delete("/threads/:thread_id/runs/:run_id", zValidator("param", z.object({ thread_id: z.string().uuid(), run_id: z.string().uuid() })), async (c) => {
295
- // Delete Run
296
- const { thread_id, run_id } = c.req.valid("param");
297
- await runs().delete(run_id, thread_id, c.var.auth);
298
- return c.body(null, 204);
299
- });
300
- api.get("/threads/:thread_id/runs/:run_id/join", zValidator("param", z.object({ thread_id: z.string().uuid(), run_id: z.string().uuid() })), async (c) => {
301
- // Join Run Http
302
- const { thread_id, run_id } = c.req.valid("param");
303
- return jsonExtra(c, await runs().join(run_id, thread_id, c.var.auth));
304
- });
305
- api.get("/threads/:thread_id/runs/:run_id/stream", zValidator("param", z.object({ thread_id: z.string().uuid(), run_id: z.string().uuid() })), zValidator("query", z.object({ cancel_on_disconnect: schemas.coercedBoolean.optional() })), async (c) => {
306
- // Stream Run Http
307
- const { thread_id, run_id } = c.req.valid("param");
308
- const { cancel_on_disconnect } = c.req.valid("query");
309
- const lastEventId = c.req.header("Last-Event-ID") || undefined;
310
- return streamSSE(c, async (stream) => {
311
- const signal = cancel_on_disconnect
312
- ? getDisconnectAbortSignal(c, stream)
313
- : undefined;
314
- for await (const { id, event, data } of runs().stream.join(run_id, thread_id, {
315
- signal,
316
- cancelOnDisconnect: signal != null,
317
- lastEventId,
318
- }, c.var.auth)) {
319
- await stream.writeSSE({ id, data: serialiseAsDict(data), event });
320
- }
321
- });
322
- });
323
- api.post("/threads/:thread_id/runs/:run_id/cancel", zValidator("param", z.object({ thread_id: z.string().uuid(), run_id: z.string().uuid() })), zValidator("query", z.object({
324
- wait: z.coerce.boolean().optional().default(false),
325
- action: z.enum(["interrupt", "rollback"]).optional().default("interrupt"),
326
- })), async (c) => {
327
- // Cancel Run Http
328
- const { thread_id, run_id } = c.req.valid("param");
329
- const { wait, action } = c.req.valid("query");
330
- await runs().cancel(thread_id, [run_id], { action }, c.var.auth);
331
- if (wait)
332
- await runs().join(run_id, thread_id, c.var.auth);
333
- return c.body(null, wait ? 204 : 202);
334
- });
335
- export default api;
@@ -1,3 +0,0 @@
1
- import { Hono } from "hono";
2
- declare const api: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
3
- export default api;
@@ -1,111 +0,0 @@
1
- import { Hono } from "hono";
2
- import { zValidator } from "@hono/zod-validator";
3
- import * as schemas from "../schemas.mjs";
4
- import { HTTPException } from "hono/http-exception";
5
- import { store as storageStore } from "../storage/store.mjs";
6
- import { handleAuthEvent } from "../auth/index.mjs";
7
- const api = new Hono();
8
- const validateNamespace = (namespace) => {
9
- if (!namespace || namespace.length === 0) {
10
- throw new HTTPException(400, { message: "Namespace is required" });
11
- }
12
- for (const label of namespace) {
13
- if (!label || label.includes(".")) {
14
- throw new HTTPException(422, {
15
- message: "Namespace labels cannot be empty or contain periods. Received: " +
16
- namespace.join("."),
17
- });
18
- }
19
- }
20
- };
21
- const mapItemsToApi = (item) => {
22
- if (item == null)
23
- return null;
24
- const clonedItem = { ...item };
25
- delete clonedItem.createdAt;
26
- delete clonedItem.updatedAt;
27
- clonedItem.created_at = item.createdAt;
28
- clonedItem.updated_at = item.updatedAt;
29
- return clonedItem;
30
- };
31
- api.post("/store/namespaces", zValidator("json", schemas.StoreListNamespaces), async (c) => {
32
- // List Namespaces
33
- const payload = c.req.valid("json");
34
- if (payload.prefix)
35
- validateNamespace(payload.prefix);
36
- if (payload.suffix)
37
- validateNamespace(payload.suffix);
38
- await handleAuthEvent(c.var.auth, "store:list_namespaces", {
39
- namespace: payload.prefix,
40
- suffix: payload.suffix,
41
- max_depth: payload.max_depth,
42
- limit: payload.limit,
43
- offset: payload.offset,
44
- });
45
- return c.json({
46
- namespaces: await storageStore.listNamespaces({
47
- limit: payload.limit ?? 100,
48
- offset: payload.offset ?? 0,
49
- prefix: payload.prefix,
50
- suffix: payload.suffix,
51
- maxDepth: payload.max_depth,
52
- }),
53
- });
54
- });
55
- api.post("/store/items/search", zValidator("json", schemas.StoreSearchItems), async (c) => {
56
- // Search Items
57
- const payload = c.req.valid("json");
58
- if (payload.namespace_prefix)
59
- validateNamespace(payload.namespace_prefix);
60
- await handleAuthEvent(c.var.auth, "store:search", {
61
- namespace: payload.namespace_prefix,
62
- filter: payload.filter,
63
- limit: payload.limit,
64
- offset: payload.offset,
65
- query: payload.query,
66
- });
67
- const items = await storageStore.search(payload.namespace_prefix, {
68
- filter: payload.filter,
69
- limit: payload.limit ?? 10,
70
- offset: payload.offset ?? 0,
71
- query: payload.query,
72
- });
73
- return c.json({ items: items.map(mapItemsToApi) });
74
- });
75
- api.put("/store/items", zValidator("json", schemas.StorePutItem), async (c) => {
76
- // Put Item
77
- const payload = c.req.valid("json");
78
- if (payload.namespace)
79
- validateNamespace(payload.namespace);
80
- await handleAuthEvent(c.var.auth, "store:put", {
81
- namespace: payload.namespace,
82
- key: payload.key,
83
- value: payload.value,
84
- });
85
- await storageStore.put(payload.namespace, payload.key, payload.value);
86
- return c.body(null, 204);
87
- });
88
- api.delete("/store/items", zValidator("json", schemas.StoreDeleteItem), async (c) => {
89
- // Delete Item
90
- const payload = c.req.valid("json");
91
- if (payload.namespace)
92
- validateNamespace(payload.namespace);
93
- await handleAuthEvent(c.var.auth, "store:delete", {
94
- namespace: payload.namespace,
95
- key: payload.key,
96
- });
97
- await storageStore.delete(payload.namespace ?? [], payload.key);
98
- return c.body(null, 204);
99
- });
100
- api.get("/store/items", zValidator("query", schemas.StoreGetItem), async (c) => {
101
- // Get Item
102
- const payload = c.req.valid("query");
103
- await handleAuthEvent(c.var.auth, "store:get", {
104
- namespace: payload.namespace,
105
- key: payload.key,
106
- });
107
- const key = payload.key;
108
- const namespace = payload.namespace;
109
- return c.json(mapItemsToApi(await storageStore.get(namespace, key)));
110
- });
111
- export default api;
@@ -1,3 +0,0 @@
1
- import { Hono } from "hono";
2
- declare const api: Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
3
- export default api;