@aprovan/chat-backend 0.1.0-dev.4d82df8 → 0.1.0-dev.78c0b14

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.
@@ -9,12 +9,12 @@
9
9
  CLI Target: node20
10
10
  CLI Cleaning output folder
11
11
  ESM Build start
12
- ESM dist/index.js 38.23 KB
13
- ESM dist/lambda.js 37.91 KB
14
- ESM dist/index.js.map 70.96 KB
15
- ESM dist/lambda.js.map 70.10 KB
16
- ESM ⚡️ Build success in 105ms
12
+ ESM dist/index.js 32.89 KB
13
+ ESM dist/lambda.js 32.57 KB
14
+ ESM dist/index.js.map 59.37 KB
15
+ ESM dist/lambda.js.map 58.51 KB
16
+ ESM ⚡️ Build success in 123ms
17
17
  DTS Build start
18
- DTS ⚡️ Build success in 13399ms
19
- DTS dist/index.d.ts 2.67 KB
18
+ DTS ⚡️ Build success in 14161ms
19
+ DTS dist/index.d.ts 2.55 KB
20
20
  DTS dist/lambda.d.ts 171.00 B
package/dist/index.d.ts CHANGED
@@ -38,7 +38,6 @@ declare const envSchema: z.ZodObject<{
38
38
  AWS_REGION: z.ZodDefault<z.ZodString>;
39
39
  WORKSPACE_TABLE_NAME: z.ZodString;
40
40
  MEMBERSHIPS_TABLE_NAME: z.ZodString;
41
- USER_SESSIONS_TABLE_NAME: z.ZodString;
42
41
  OPENROUTER_SECRET_ARN: z.ZodString;
43
42
  GATEWAY_URL: z.ZodString;
44
43
  POSTHOG_PROJECT_API_KEY: z.ZodOptional<z.ZodString>;
@@ -52,7 +51,6 @@ declare const envSchema: z.ZodObject<{
52
51
  AWS_REGION: string;
53
52
  WORKSPACE_TABLE_NAME: string;
54
53
  MEMBERSHIPS_TABLE_NAME: string;
55
- USER_SESSIONS_TABLE_NAME: string;
56
54
  OPENROUTER_SECRET_ARN: string;
57
55
  GATEWAY_URL: string;
58
56
  POSTHOG_HOST: string;
@@ -63,7 +61,6 @@ declare const envSchema: z.ZodObject<{
63
61
  COGNITO_CLIENT_ID: string;
64
62
  WORKSPACE_TABLE_NAME: string;
65
63
  MEMBERSHIPS_TABLE_NAME: string;
66
- USER_SESSIONS_TABLE_NAME: string;
67
64
  OPENROUTER_SECRET_ARN: string;
68
65
  GATEWAY_URL: string;
69
66
  NODE_ENV?: "development" | "production" | "test" | undefined;
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { serve } from "@hono/node-server";
3
3
 
4
4
  // src/app.ts
5
- import { Hono as Hono7 } from "hono";
5
+ import { Hono as Hono6 } from "hono";
6
6
 
7
7
  // src/middleware/auth.ts
8
8
  import { CognitoJwtVerifier } from "aws-jwt-verify";
@@ -32,11 +32,11 @@ var authMiddleware = async (c, next) => {
32
32
  }
33
33
  };
34
34
 
35
- // src/middleware/plan.ts
35
+ // src/middleware/workspace.ts
36
36
  import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
37
- import { DynamoDBDocumentClient, GetCommand } from "@aws-sdk/lib-dynamodb";
38
- var WORKSPACE_CACHE_TTL_MS = 6e4;
39
- var workspaceCache = /* @__PURE__ */ new Map();
37
+ import { DynamoDBDocumentClient, QueryCommand } from "@aws-sdk/lib-dynamodb";
38
+ var MEMBERSHIP_CACHE_TTL_MS = 3e5;
39
+ var membershipCache = /* @__PURE__ */ new Map();
40
40
  var ddbClient = null;
41
41
  function getDdb() {
42
42
  if (!ddbClient) {
@@ -46,13 +46,57 @@ function getDdb() {
46
46
  }
47
47
  return ddbClient;
48
48
  }
49
+ async function resolveWorkspaceId(userSub) {
50
+ const now = Date.now();
51
+ const cached = membershipCache.get(userSub);
52
+ if (cached && now - cached.fetchedAt < MEMBERSHIP_CACHE_TTL_MS) {
53
+ return cached.workspaceId;
54
+ }
55
+ const result = await getDdb().send(
56
+ new QueryCommand({
57
+ TableName: process.env["MEMBERSHIPS_TABLE_NAME"],
58
+ IndexName: "ByUserSub",
59
+ KeyConditionExpression: "userSub = :sub",
60
+ ExpressionAttributeValues: { ":sub": userSub },
61
+ Limit: 1
62
+ })
63
+ );
64
+ const item = result.Items?.[0];
65
+ if (!item) return null;
66
+ membershipCache.set(userSub, { workspaceId: item.workspaceId, fetchedAt: now });
67
+ return item.workspaceId;
68
+ }
69
+ var workspaceMiddleware = async (c, next) => {
70
+ const claims = c.get("claims");
71
+ const workspaceId = await resolveWorkspaceId(claims.sub);
72
+ if (!workspaceId) {
73
+ return c.json({ error: "No workspace membership" }, 403);
74
+ }
75
+ c.set("workspaceId", workspaceId);
76
+ return next();
77
+ };
78
+
79
+ // src/middleware/plan.ts
80
+ import { DynamoDBClient as DynamoDBClient2 } from "@aws-sdk/client-dynamodb";
81
+ import { DynamoDBDocumentClient as DynamoDBDocumentClient2, GetCommand } from "@aws-sdk/lib-dynamodb";
82
+ var WORKSPACE_CACHE_TTL_MS = 6e4;
83
+ var workspaceCache = /* @__PURE__ */ new Map();
84
+ var ddbClient2 = null;
85
+ function getDdb2() {
86
+ if (!ddbClient2) {
87
+ ddbClient2 = DynamoDBDocumentClient2.from(
88
+ new DynamoDBClient2({ region: process.env["AWS_REGION"] })
89
+ );
90
+ }
91
+ return ddbClient2;
92
+ }
49
93
  async function getWorkspace(workspaceId) {
50
94
  const now = Date.now();
51
95
  const cached = workspaceCache.get(workspaceId);
52
96
  if (cached && now - cached.fetchedAt < WORKSPACE_CACHE_TTL_MS) {
53
97
  return cached.workspace;
54
98
  }
55
- const result = await getDdb().send(
99
+ const result = await getDdb2().send(
56
100
  new GetCommand({
57
101
  TableName: process.env["WORKSPACE_TABLE_NAME"],
58
102
  Key: { workspaceId }
@@ -79,116 +123,10 @@ var planMiddleware = async (c, next) => {
79
123
  return next();
80
124
  };
81
125
 
82
- // src/middleware/workspace.ts
83
- import { DynamoDBClient as DynamoDBClient3 } from "@aws-sdk/client-dynamodb";
84
- import { DynamoDBDocumentClient as DynamoDBDocumentClient3, QueryCommand } from "@aws-sdk/lib-dynamodb";
85
-
86
- // src/session.ts
87
- import { DynamoDBClient as DynamoDBClient2 } from "@aws-sdk/client-dynamodb";
88
- import {
89
- DynamoDBDocumentClient as DynamoDBDocumentClient2,
90
- GetCommand as GetCommand2,
91
- PutCommand
92
- } from "@aws-sdk/lib-dynamodb";
93
- var SESSION_CACHE_TTL_MS = 15e3;
94
- var sessionCache = /* @__PURE__ */ new Map();
95
- var ddbClient2 = null;
96
- function getDdb2() {
97
- if (!ddbClient2) {
98
- ddbClient2 = DynamoDBDocumentClient2.from(
99
- new DynamoDBClient2({ region: process.env["AWS_REGION"] })
100
- );
101
- }
102
- return ddbClient2;
103
- }
104
- function tableName() {
105
- return process.env["USER_SESSIONS_TABLE_NAME"];
106
- }
107
- async function getSessionWorkspaceId(userSub) {
108
- const now = Date.now();
109
- const cached = sessionCache.get(userSub);
110
- if (cached && now - cached.fetchedAt < SESSION_CACHE_TTL_MS) {
111
- return cached.activeWorkspaceId;
112
- }
113
- const result = await getDdb2().send(
114
- new GetCommand2({
115
- TableName: tableName(),
116
- Key: { userSub }
117
- })
118
- );
119
- const activeWorkspaceId = result.Item?.activeWorkspaceId ?? null;
120
- sessionCache.set(userSub, { activeWorkspaceId, fetchedAt: now });
121
- return activeWorkspaceId;
122
- }
123
- async function setSessionWorkspaceId(userSub, workspaceId) {
124
- await getDdb2().send(
125
- new PutCommand({
126
- TableName: tableName(),
127
- Item: {
128
- userSub,
129
- activeWorkspaceId: workspaceId,
130
- updatedAt: (/* @__PURE__ */ new Date()).toISOString()
131
- }
132
- })
133
- );
134
- sessionCache.set(userSub, {
135
- activeWorkspaceId: workspaceId,
136
- fetchedAt: Date.now()
137
- });
138
- }
139
-
140
- // src/middleware/workspace.ts
141
- var MEMBERSHIP_CACHE_TTL_MS = 3e5;
142
- var membershipCache = /* @__PURE__ */ new Map();
143
- var ddbClient3 = null;
144
- function getDdb3() {
145
- if (!ddbClient3) {
146
- ddbClient3 = DynamoDBDocumentClient3.from(
147
- new DynamoDBClient3({ region: process.env["AWS_REGION"] })
148
- );
149
- }
150
- return ddbClient3;
151
- }
152
- async function listWorkspaceMemberships(userSub) {
153
- const now = Date.now();
154
- const cached = membershipCache.get(userSub);
155
- if (cached && now - cached.fetchedAt < MEMBERSHIP_CACHE_TTL_MS) {
156
- return cached.workspaceIds;
157
- }
158
- const result = await getDdb3().send(
159
- new QueryCommand({
160
- TableName: process.env["MEMBERSHIPS_TABLE_NAME"],
161
- IndexName: "ByUserSub",
162
- KeyConditionExpression: "userSub = :sub",
163
- ExpressionAttributeValues: { ":sub": userSub }
164
- })
165
- );
166
- const workspaceIds = (result.Items ?? []).map(
167
- (item) => item.workspaceId
168
- );
169
- membershipCache.set(userSub, { workspaceIds, fetchedAt: now });
170
- return workspaceIds;
171
- }
172
- async function resolveWorkspaceId(userSub) {
173
- const [sessionWsId, workspaceIds] = await Promise.all([
174
- getSessionWorkspaceId(userSub),
175
- listWorkspaceMemberships(userSub)
176
- ]);
177
- if (workspaceIds.length === 0) return null;
178
- if (sessionWsId && workspaceIds.includes(sessionWsId)) {
179
- return sessionWsId;
180
- }
181
- return workspaceIds[0] ?? null;
182
- }
183
- var workspaceMiddleware = async (c, next) => {
184
- const claims = c.get("claims");
185
- const workspaceId = await resolveWorkspaceId(claims.sub);
186
- if (!workspaceId) {
187
- return c.json({ error: "No workspace membership" }, 403);
188
- }
189
- c.set("workspaceId", workspaceId);
190
- return next();
191
- };
126
+ // src/routes/health.ts
127
+ import { Hono } from "hono";
128
+ var health = new Hono();
129
+ health.get("/health", (c) => c.json({ status: "ok" }));
192
130
 
193
131
  // src/routes/chat.ts
194
132
  import { withTracing } from "@posthog/ai";
@@ -199,7 +137,7 @@ import {
199
137
  stepCountIs,
200
138
  jsonSchema
201
139
  } from "ai";
202
- import { Hono } from "hono";
140
+ import { Hono as Hono2 } from "hono";
203
141
  import { z } from "zod";
204
142
 
205
143
  // src/fallback-prompts.ts
@@ -553,14 +491,7 @@ var CHAT_PROMPT_ALLOWLIST = /* @__PURE__ */ new Set(["chat-patchwork-widget", "c
553
491
  var EDIT_PROMPT_ID = "edit-patchwork-widget";
554
492
 
555
493
  // src/gateway-session.ts
556
- var sessionCache2 = /* @__PURE__ */ new Map();
557
- var toolsCache = /* @__PURE__ */ new Map();
558
- function getCachedTools(sub) {
559
- return toolsCache.get(sub);
560
- }
561
- function setCachedTools(sub, tools) {
562
- toolsCache.set(sub, tools);
563
- }
494
+ var sessionCache = /* @__PURE__ */ new Map();
564
495
  function gatewayUrl() {
565
496
  const url = process.env["GATEWAY_URL"];
566
497
  if (!url) throw new Error("GATEWAY_URL is not set");
@@ -569,22 +500,16 @@ function gatewayUrl() {
569
500
  async function getGatewaySession(claims, workspaceId, cognitoToken) {
570
501
  const sub = claims.sub;
571
502
  const now = Math.floor(Date.now() / 1e3);
572
- const cached = sessionCache2.get(sub);
503
+ const cached = sessionCache.get(sub);
573
504
  if (cached && cached.expires_at > now + 60) {
574
505
  return cached;
575
506
  }
576
507
  const entry = await exchangeSession(cognitoToken, workspaceId, claims.exp);
577
- sessionCache2.set(sub, entry);
508
+ sessionCache.set(sub, entry);
578
509
  return entry;
579
510
  }
580
511
  async function exchangeSession(cognitoToken, workspaceId, exp) {
581
- let res;
582
- try {
583
- res = await callAuthSessions(cognitoToken, workspaceId);
584
- } catch {
585
- await new Promise((r) => setTimeout(r, 200));
586
- res = await callAuthSessions(cognitoToken, workspaceId);
587
- }
512
+ const res = await callAuthSessions(cognitoToken, workspaceId);
588
513
  if (res.status === 401) {
589
514
  const retryRes = await callAuthSessions(cognitoToken, workspaceId);
590
515
  if (!retryRes.ok) {
@@ -592,14 +517,6 @@ async function exchangeSession(cognitoToken, workspaceId, exp) {
592
517
  }
593
518
  return { token: cognitoToken, expires_at: exp };
594
519
  }
595
- if (res.status >= 500) {
596
- await new Promise((r) => setTimeout(r, 200));
597
- const retryRes = await callAuthSessions(cognitoToken, workspaceId);
598
- if (!retryRes.ok) {
599
- throw new GatewaySessionError(retryRes.status, await retryRes.text());
600
- }
601
- return { token: cognitoToken, expires_at: exp };
602
- }
603
520
  if (!res.ok) {
604
521
  throw new GatewaySessionError(res.status, await res.text());
605
522
  }
@@ -616,8 +533,7 @@ async function callAuthSessions(cognitoToken, workspaceId) {
616
533
  });
617
534
  }
618
535
  function evictGatewaySession(sub) {
619
- sessionCache2.delete(sub);
620
- toolsCache.delete(sub);
536
+ sessionCache.delete(sub);
621
537
  }
622
538
  var GatewaySessionError = class extends Error {
623
539
  constructor(status, message) {
@@ -758,7 +674,6 @@ var chatBodySchema = z.object({
758
674
  id: z.string(),
759
675
  messages: z.array(z.any()),
760
676
  trigger: z.string(),
761
- model: z.string().optional(),
762
677
  metadata: z.unknown().optional(),
763
678
  prompt: z.object({
764
679
  id: z.string(),
@@ -778,7 +693,7 @@ var retryAtStartMiddleware = {
778
693
  }
779
694
  }
780
695
  };
781
- var chatRoute = new Hono();
696
+ var chatRoute = new Hono2();
782
697
  async function fetchGatewayTools(gatewayUrl2, bearerToken) {
783
698
  const res = await fetch(`${gatewayUrl2}/tools`, {
784
699
  headers: { Authorization: `Bearer ${bearerToken}` }
@@ -824,16 +739,10 @@ chatRoute.post("/", async (c) => {
824
739
  if (!parsed.success) {
825
740
  return c.json({ error: "Invalid request body" }, 400);
826
741
  }
827
- const { messages, model: requestedModel, prompt: promptBody } = parsed.data;
742
+ const { messages, prompt: promptBody } = parsed.data;
828
743
  const claims = c.get("claims");
829
744
  const workspaceId = c.get("workspaceId");
830
745
  const workspace = c.get("workspace");
831
- if (requestedModel !== void 0 && !workspace.limits.maxModels.includes(requestedModel)) {
832
- return c.json(
833
- { error: "Model not allowed on your current plan", model: requestedModel },
834
- 403
835
- );
836
- }
837
746
  const promptId = promptBody?.id ?? "chat-patchwork-widget";
838
747
  if (!CHAT_PROMPT_ALLOWLIST.has(promptId)) {
839
748
  return c.json({ error: "Unknown prompt id" }, 400);
@@ -851,18 +760,11 @@ chatRoute.post("/", async (c) => {
851
760
  }
852
761
  let gatewayTools = [];
853
762
  if (sessionToken && gatewayUrl2) {
854
- const cached = getCachedTools(claims.sub);
855
- if (cached) {
856
- gatewayTools = cached;
857
- } else {
858
- gatewayTools = await fetchGatewayTools(gatewayUrl2, sessionToken).catch(
859
- () => []
860
- );
861
- if (gatewayTools.length === 0) {
862
- evictGatewaySession(claims.sub);
863
- } else {
864
- setCachedTools(claims.sub, gatewayTools);
865
- }
763
+ gatewayTools = await fetchGatewayTools(gatewayUrl2, sessionToken).catch(
764
+ () => []
765
+ );
766
+ if (gatewayTools.length === 0) {
767
+ evictGatewaySession(claims.sub);
866
768
  }
867
769
  }
868
770
  const tools = sessionToken && gatewayUrl2 ? buildTools(gatewayTools, gatewayUrl2, sessionToken) : {};
@@ -878,7 +780,7 @@ chatRoute.post("/", async (c) => {
878
780
  });
879
781
  const apiKey = await getOpenRouterKey();
880
782
  const provider = createOpenRouterProvider(apiKey);
881
- const modelId = requestedModel ?? workspace.limits.maxModels[0] ?? "openrouter/auto";
783
+ const modelId = workspace.limits.maxModels[0] ?? "openrouter/auto";
882
784
  const baseModel = provider(modelId);
883
785
  const phClient = getPostHogClient();
884
786
  const tracedModel = phClient && promptResult.source !== "code_fallback" ? withTracing(baseModel, phClient, {
@@ -906,14 +808,14 @@ chatRoute.post("/", async (c) => {
906
808
  // src/routes/edit.ts
907
809
  import { withTracing as withTracing2 } from "@posthog/ai";
908
810
  import { streamText as streamText2 } from "ai";
909
- import { Hono as Hono2 } from "hono";
811
+ import { Hono as Hono3 } from "hono";
910
812
  import { z as z2 } from "zod";
911
813
  var editBodySchema = z2.object({
912
814
  code: z2.string(),
913
815
  prompt: z2.string()
914
816
  });
915
817
  var MODEL_ID = "openrouter/auto";
916
- var editRoute = new Hono2();
818
+ var editRoute = new Hono3();
917
819
  editRoute.post("/", async (c) => {
918
820
  const body = await c.req.json().catch(() => null);
919
821
  const parsed = editBodySchema.safeParse(body);
@@ -943,19 +845,12 @@ editRoute.post("/", async (c) => {
943
845
  return result.toTextStreamResponse();
944
846
  });
945
847
 
946
- // src/routes/health.ts
947
- import { Hono as Hono3 } from "hono";
948
- var health = new Hono3();
949
- health.get("/health", (c) => c.json({ status: "ok" }));
950
-
951
- // src/routes/proxy.ts
848
+ // src/routes/services.ts
952
849
  import { Hono as Hono4 } from "hono";
953
- var proxy = new Hono4();
954
- proxy.post("/:ns/:proc{.*}", async (c) => {
850
+ var services = new Hono4();
851
+ services.get("/", async (c) => {
955
852
  const claims = c.get("claims");
956
853
  const workspaceId = c.get("workspaceId");
957
- const ns = c.req.param("ns");
958
- const proc = c.req.param("proc");
959
854
  const authHeader = c.req.header("Authorization");
960
855
  const cognitoToken = authHeader.slice("Bearer ".length);
961
856
  let sessionToken;
@@ -968,34 +863,37 @@ proxy.post("/:ns/:proc{.*}", async (c) => {
968
863
  }
969
864
  return c.json({ error: "Failed to connect to gateway" }, 502);
970
865
  }
971
- let body = {};
972
- try {
973
- body = await c.req.json();
974
- } catch {
975
- }
976
866
  const gatewayUrl2 = process.env["GATEWAY_URL"].replace(/\/$/, "");
977
- const res = await fetch(`${gatewayUrl2}/tools/${ns}/${proc}`, {
978
- method: "POST",
979
- headers: {
980
- "Content-Type": "application/json",
981
- Authorization: `Bearer ${sessionToken}`
982
- },
983
- body: JSON.stringify(body)
867
+ const res = await fetch(`${gatewayUrl2}/tools`, {
868
+ headers: { Authorization: `Bearer ${sessionToken}` }
984
869
  });
985
870
  if (res.status === 401) {
986
871
  evictGatewaySession(claims.sub);
987
872
  return c.json({ error: "Gateway authentication failed" }, 502);
988
873
  }
989
- const responseData = await res.json();
990
- return c.json(responseData, res.status);
874
+ if (!res.ok) {
875
+ return c.json({ error: "Gateway tools fetch failed" }, 502);
876
+ }
877
+ const data = await res.json();
878
+ const serviceList = data.tools.map((t) => ({
879
+ namespace: t.provider,
880
+ name: t.name,
881
+ procedure: t.operation,
882
+ description: t.description ?? "",
883
+ parameters: t.inputSchema
884
+ }));
885
+ const namespaces = Array.from(new Set(data.tools.map((t) => t.provider)));
886
+ return c.json({ namespaces, services: serviceList });
991
887
  });
992
888
 
993
- // src/routes/services.ts
889
+ // src/routes/proxy.ts
994
890
  import { Hono as Hono5 } from "hono";
995
- var services = new Hono5();
996
- services.get("/", async (c) => {
891
+ var proxy = new Hono5();
892
+ proxy.post("/:ns/:proc{.*}", async (c) => {
997
893
  const claims = c.get("claims");
998
894
  const workspaceId = c.get("workspaceId");
895
+ const ns = c.req.param("ns");
896
+ const proc = c.req.param("proc");
999
897
  const authHeader = c.req.header("Authorization");
1000
898
  const cognitoToken = authHeader.slice("Bearer ".length);
1001
899
  let sessionToken;
@@ -1008,99 +906,31 @@ services.get("/", async (c) => {
1008
906
  }
1009
907
  return c.json({ error: "Failed to connect to gateway" }, 502);
1010
908
  }
909
+ let body = {};
910
+ try {
911
+ body = await c.req.json();
912
+ } catch {
913
+ }
1011
914
  const gatewayUrl2 = process.env["GATEWAY_URL"].replace(/\/$/, "");
1012
- const res = await fetch(`${gatewayUrl2}/tools`, {
1013
- headers: { Authorization: `Bearer ${sessionToken}` }
915
+ const res = await fetch(`${gatewayUrl2}/tools/${ns}/${proc}`, {
916
+ method: "POST",
917
+ headers: {
918
+ "Content-Type": "application/json",
919
+ Authorization: `Bearer ${sessionToken}`
920
+ },
921
+ body: JSON.stringify(body)
1014
922
  });
1015
923
  if (res.status === 401) {
1016
924
  evictGatewaySession(claims.sub);
1017
925
  return c.json({ error: "Gateway authentication failed" }, 502);
1018
926
  }
1019
- if (!res.ok) {
1020
- return c.json({ error: "Gateway tools fetch failed" }, 502);
1021
- }
1022
- const data = await res.json();
1023
- const serviceList = data.tools.map((t) => ({
1024
- namespace: t.provider,
1025
- name: t.name,
1026
- procedure: t.operation,
1027
- description: t.description ?? "",
1028
- parameters: t.inputSchema
1029
- }));
1030
- const namespaces = Array.from(new Set(data.tools.map((t) => t.provider)));
1031
- return c.json({ namespaces, services: serviceList });
1032
- });
1033
-
1034
- // src/routes/workspaces.ts
1035
- import { DynamoDBClient as DynamoDBClient4 } from "@aws-sdk/client-dynamodb";
1036
- import { BatchGetCommand, DynamoDBDocumentClient as DynamoDBDocumentClient4 } from "@aws-sdk/lib-dynamodb";
1037
- import { zValidator } from "@hono/zod-validator";
1038
- import { Hono as Hono6 } from "hono";
1039
- import { z as z3 } from "zod";
1040
- var ddbClient4 = null;
1041
- function getDdb4() {
1042
- if (!ddbClient4) {
1043
- ddbClient4 = DynamoDBDocumentClient4.from(
1044
- new DynamoDBClient4({ region: process.env["AWS_REGION"] })
1045
- );
1046
- }
1047
- return ddbClient4;
1048
- }
1049
- async function batchGetWorkspaces(workspaceIds) {
1050
- if (workspaceIds.length === 0) return [];
1051
- const tableName2 = process.env["WORKSPACE_TABLE_NAME"];
1052
- const result = await getDdb4().send(
1053
- new BatchGetCommand({
1054
- RequestItems: {
1055
- [tableName2]: { Keys: workspaceIds.map((id) => ({ workspaceId: id })) }
1056
- }
1057
- })
1058
- );
1059
- return result.Responses?.[tableName2] ?? [];
1060
- }
1061
- var workspacesRoute = new Hono6();
1062
- workspacesRoute.get("/", async (c) => {
1063
- const claims = c.get("claims");
1064
- const userSub = claims.sub;
1065
- const [workspaceIds, activeWorkspaceId] = await Promise.all([
1066
- listWorkspaceMemberships(userSub),
1067
- getSessionWorkspaceId(userSub)
1068
- ]);
1069
- const workspaces = await batchGetWorkspaces(workspaceIds);
1070
- const effectiveActiveId = activeWorkspaceId && workspaceIds.includes(activeWorkspaceId) ? activeWorkspaceId : workspaceIds[0] ?? null;
1071
- const sorted = workspaceIds.map((id) => workspaces.find((w) => w.workspaceId === id)).filter((w) => w !== void 0);
1072
- return c.json({
1073
- workspaces: sorted.map((w) => ({
1074
- workspaceId: w.workspaceId,
1075
- name: w.name,
1076
- plan: w.plan,
1077
- active: w.workspaceId === effectiveActiveId
1078
- })),
1079
- activeWorkspaceId: effectiveActiveId
1080
- });
1081
- });
1082
- var setActiveSchema = z3.object({
1083
- workspaceId: z3.string().min(1)
927
+ const responseData = await res.json();
928
+ return c.json(responseData, res.status);
1084
929
  });
1085
- workspacesRoute.put(
1086
- "/active",
1087
- zValidator("json", setActiveSchema),
1088
- async (c) => {
1089
- const claims = c.get("claims");
1090
- const userSub = claims.sub;
1091
- const { workspaceId } = c.req.valid("json");
1092
- const workspaceIds = await listWorkspaceMemberships(userSub);
1093
- if (!workspaceIds.includes(workspaceId)) {
1094
- return c.json({ error: "Not a member of this workspace" }, 403);
1095
- }
1096
- await setSessionWorkspaceId(userSub, workspaceId);
1097
- return c.json({ activeWorkspaceId: workspaceId });
1098
- }
1099
- );
1100
930
 
1101
931
  // src/app.ts
1102
932
  function createChatApp() {
1103
- const app2 = new Hono7();
933
+ const app2 = new Hono6();
1104
934
  app2.route("/", health);
1105
935
  const api = app2.basePath("/api");
1106
936
  api.use(authMiddleware, workspaceMiddleware, planMiddleware);
@@ -1108,27 +938,25 @@ function createChatApp() {
1108
938
  api.route("/edit", editRoute);
1109
939
  api.route("/services", services);
1110
940
  api.route("/proxy", proxy);
1111
- api.route("/workspaces", workspacesRoute);
1112
941
  return app2;
1113
942
  }
1114
943
 
1115
944
  // src/env.ts
1116
- import { z as z4 } from "zod";
1117
- var envSchema = z4.object({
1118
- NODE_ENV: z4.enum(["development", "production", "test"]).default("development"),
1119
- PORT: z4.coerce.number().default(3001),
1120
- COGNITO_USER_POOL_ID: z4.string().min(1),
1121
- COGNITO_CLIENT_ID: z4.string().min(1),
1122
- AWS_REGION: z4.string().default("us-east-1"),
1123
- WORKSPACE_TABLE_NAME: z4.string().min(1),
1124
- MEMBERSHIPS_TABLE_NAME: z4.string().min(1),
1125
- USER_SESSIONS_TABLE_NAME: z4.string().min(1),
1126
- OPENROUTER_SECRET_ARN: z4.string().min(1),
1127
- GATEWAY_URL: z4.string().url(),
945
+ import { z as z3 } from "zod";
946
+ var envSchema = z3.object({
947
+ NODE_ENV: z3.enum(["development", "production", "test"]).default("development"),
948
+ PORT: z3.coerce.number().default(3001),
949
+ COGNITO_USER_POOL_ID: z3.string().min(1),
950
+ COGNITO_CLIENT_ID: z3.string().min(1),
951
+ AWS_REGION: z3.string().default("us-east-1"),
952
+ WORKSPACE_TABLE_NAME: z3.string().min(1),
953
+ MEMBERSHIPS_TABLE_NAME: z3.string().min(1),
954
+ OPENROUTER_SECRET_ARN: z3.string().min(1),
955
+ GATEWAY_URL: z3.string().url(),
1128
956
  // PostHog prompt management (optional — falls back to code prompts when absent)
1129
- POSTHOG_PROJECT_API_KEY: z4.string().optional(),
1130
- POSTHOG_PERSONAL_API_KEY: z4.string().optional(),
1131
- POSTHOG_HOST: z4.string().default("https://us.posthog.com")
957
+ POSTHOG_PROJECT_API_KEY: z3.string().optional(),
958
+ POSTHOG_PERSONAL_API_KEY: z3.string().optional(),
959
+ POSTHOG_HOST: z3.string().default("https://us.posthog.com")
1132
960
  });
1133
961
  function parseEnv(raw) {
1134
962
  return envSchema.parse(raw);