@voyant-travel/auth 0.129.0 → 0.131.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.
Files changed (44) hide show
  1. package/README.md +14 -0
  2. package/dist/cloud-broker/members.d.ts +9 -0
  3. package/dist/cloud-broker/members.js +10 -0
  4. package/dist/cloud-broker/members.js.map +1 -1
  5. package/dist/cloud-broker.d.ts +1 -1
  6. package/dist/cloud-broker.js +1 -1
  7. package/dist/cloud-broker.js.map +1 -1
  8. package/dist/identity-access-graph-runtime.js +2 -1
  9. package/dist/identity-access-graph-runtime.js.map +1 -1
  10. package/dist/invitations-routes.js +4 -0
  11. package/dist/invitations-routes.js.map +1 -1
  12. package/dist/local-member-access.d.ts +15 -0
  13. package/dist/local-member-access.js +119 -0
  14. package/dist/local-member-access.js.map +1 -0
  15. package/dist/mcp-runtime.d.ts +9 -0
  16. package/dist/mcp-runtime.js +38 -0
  17. package/dist/mcp-runtime.js.map +1 -0
  18. package/dist/runtime-contributor.js +18 -1
  19. package/dist/runtime-contributor.js.map +1 -1
  20. package/dist/server.d.ts +10 -6
  21. package/dist/server.js +6 -3
  22. package/dist/server.js.map +1 -1
  23. package/dist/team-management-cloud-adapter.d.ts +7 -0
  24. package/dist/team-management-cloud-adapter.js +146 -0
  25. package/dist/team-management-cloud-adapter.js.map +1 -0
  26. package/dist/team-management-local-adapter.d.ts +8 -0
  27. package/dist/team-management-local-adapter.js +285 -0
  28. package/dist/team-management-local-adapter.js.map +1 -0
  29. package/dist/team-management-policy.d.ts +27 -0
  30. package/dist/team-management-policy.js +109 -0
  31. package/dist/team-management-policy.js.map +1 -0
  32. package/dist/team-management-runtime-port.d.ts +60 -0
  33. package/dist/team-management-runtime-port.js +25 -0
  34. package/dist/team-management-runtime-port.js.map +1 -0
  35. package/dist/team-routes.d.ts +3 -3
  36. package/dist/team-routes.js +89 -138
  37. package/dist/team-routes.js.map +1 -1
  38. package/dist/tools.d.ts +58 -0
  39. package/dist/tools.js +226 -0
  40. package/dist/tools.js.map +1 -0
  41. package/dist/voyant.js +262 -7
  42. package/dist/voyant.js.map +1 -1
  43. package/openapi/admin/team.json +42 -74
  44. package/package.json +15 -4
@@ -1,17 +1,12 @@
1
1
  import { createRoute, OpenAPIHono, z } from "@hono/zod-openapi";
2
- import { cloudAuthUserLinks } from "@voyant-travel/db/schema/iam";
3
2
  import { openApiValidationHook, parseJsonBody } from "@voyant-travel/hono";
4
- import { eq } from "drizzle-orm";
5
- import { CloudAdminMembersError, inviteCloudAdminMember, listCloudAdminInvitations, listCloudAdminMemberRoles, listCloudAdminMembers, revokeCloudAdminInvitation, setCloudAdminMemberAccess, setCloudAdminMemberPermissions, } from "./cloud-broker.js";
3
+ import { TeamManagementError } from "./team-management-policy.js";
6
4
  const inviteSchema = z.object({
7
5
  email: z.string().email(),
8
- roleSlug: z.string().trim().min(1).max(120).optional().nullable(),
6
+ roleId: z.string().trim().min(1).max(120),
9
7
  expiresInDays: z.number().int().min(1).max(30).optional(),
10
8
  });
11
- const accessSchema = z.object({ hasAccess: z.boolean() });
12
- const permissionsSchema = z.object({
13
- permissions: z.array(z.string().trim().min(1).max(120)).max(200),
14
- });
9
+ const roleSchema = z.object({ roleId: z.string().trim().min(1).max(120) });
15
10
  const teamAdminApiId = "@voyant-travel/auth#team.api.admin";
16
11
  const jsonBody = (schema) => ({
17
12
  required: true,
@@ -26,185 +21,141 @@ const teamRoute = (config) => createRoute({
26
21
  ...(config.request ? { request: config.request } : {}),
27
22
  responses: responses(...config.statuses),
28
23
  });
24
+ const capabilitiesRoute = teamRoute({
25
+ method: "get",
26
+ path: "/capabilities",
27
+ operationId: "getTeamManagementCapabilities",
28
+ statuses: [200, 401, 403, 501],
29
+ });
29
30
  const listMembersRoute = teamRoute({
30
31
  method: "get",
31
32
  path: "/members",
32
33
  operationId: "listTeamMembers",
33
- statuses: [200, 401, 403, 404, 501],
34
+ statuses: [200, 401, 403, 501],
34
35
  });
35
36
  const listRolesRoute = teamRoute({
36
37
  method: "get",
37
38
  path: "/roles",
38
39
  operationId: "listTeamRoles",
39
- statuses: [200, 401, 403, 404, 501],
40
+ statuses: [200, 401, 403, 501],
40
41
  });
41
- const listTeamInvitationsRoute = teamRoute({
42
+ const listInvitationsRoute = teamRoute({
42
43
  method: "get",
43
44
  path: "/invitations",
44
45
  operationId: "listTeamInvitations",
45
- statuses: [200, 401, 403, 404, 501],
46
+ statuses: [200, 401, 403, 501],
46
47
  });
47
- const createTeamInvitationRoute = teamRoute({
48
+ const createInvitationRoute = teamRoute({
48
49
  method: "post",
49
50
  path: "/invitations",
50
51
  operationId: "createTeamInvitation",
51
52
  request: { body: jsonBody(inviteSchema) },
52
- statuses: [201, 400, 401, 403, 404, 501],
53
+ statuses: [201, 400, 401, 403, 404, 409, 501],
53
54
  });
54
- const revokeTeamInvitationRoute = teamRoute({
55
+ const revokeInvitationRoute = teamRoute({
55
56
  method: "delete",
56
57
  path: "/invitations/{invitationId}",
57
58
  operationId: "revokeTeamInvitation",
58
59
  request: { params: z.object({ invitationId: z.string() }) },
59
60
  statuses: [204, 401, 403, 404, 501],
60
61
  });
61
- const setTeamMemberAccessRoute = teamRoute({
62
+ const updateRoleRoute = teamRoute({
62
63
  method: "put",
63
- path: "/members/{membershipId}/access",
64
- operationId: "setTeamMemberAccess",
64
+ path: "/members/{memberId}/role",
65
+ operationId: "updateTeamMemberRole",
65
66
  request: {
66
- params: z.object({ membershipId: z.string() }),
67
- body: jsonBody(accessSchema),
67
+ params: z.object({ memberId: z.string() }),
68
+ body: jsonBody(roleSchema),
68
69
  },
69
- statuses: [200, 400, 401, 403, 404, 501],
70
+ statuses: [200, 400, 401, 403, 404, 409, 501],
71
+ });
72
+ const deactivateMemberRoute = teamRoute({
73
+ method: "delete",
74
+ path: "/members/{memberId}",
75
+ operationId: "deactivateTeamMember",
76
+ request: { params: z.object({ memberId: z.string() }) },
77
+ statuses: [200, 401, 403, 404, 409, 501],
70
78
  });
71
- const setTeamMemberPermissionsRoute = teamRoute({
79
+ const activateMemberRoute = teamRoute({
72
80
  method: "put",
73
- path: "/members/{membershipId}/permissions",
74
- operationId: "setTeamMemberPermissions",
75
- request: {
76
- params: z.object({ membershipId: z.string() }),
77
- body: jsonBody(permissionsSchema),
78
- },
79
- statuses: [200, 400, 401, 403, 404, 501],
81
+ path: "/members/{memberId}/activation",
82
+ operationId: "activateTeamMember",
83
+ request: { params: z.object({ memberId: z.string() }) },
84
+ statuses: [200, 401, 403, 404, 409, 501],
80
85
  });
81
- async function resolveActingWorkosUserId(db, userId) {
82
- const [link] = await db
83
- .select({ providerAccountId: cloudAuthUserLinks.providerAccountId })
84
- .from(cloudAuthUserLinks)
85
- .where(eq(cloudAuthUserLinks.userId, userId))
86
- .limit(1);
87
- return link?.providerAccountId ?? null;
86
+ function requestContext(c) {
87
+ const userId = c.get("userId");
88
+ if (!userId)
89
+ return c.json({ error: "Unauthorized" }, 401);
90
+ return { bindings: c.env, db: c.get("db"), userId };
91
+ }
92
+ function handleError(c, error) {
93
+ if (error instanceof TeamManagementError) {
94
+ return c.json({ error: error.message, code: error.code }, error.status);
95
+ }
96
+ if (error instanceof Error &&
97
+ "status" in error &&
98
+ typeof error.status === "number" &&
99
+ error.status >= 400 &&
100
+ error.status <= 599) {
101
+ return c.json({ error: error.message }, error.status);
102
+ }
103
+ throw error;
88
104
  }
89
105
  export function createTeamAdminRoutes(runtime) {
90
106
  const routes = new OpenAPIHono({ defaultHook: openApiValidationHook });
91
- const resolveContext = async (c) => {
92
- const deployment = runtime.resolveDeployment(c.env);
93
- if (deployment.authMode !== "voyant-cloud")
94
- return c.json({ error: "Not found" }, 404);
95
- const userId = c.get("userId");
96
- if (!userId)
97
- return c.json({ error: "Unauthorized" }, 401);
98
- if (!deployment.cloudAdminMembers) {
99
- return c.json({ error: "Voyant Cloud member management is not configured" }, 501);
100
- }
101
- const actingWorkosUserId = await resolveActingWorkosUserId(c.get("db"), userId);
102
- if (!actingWorkosUserId) {
103
- return c.json({ error: "No Voyant Cloud identity for this session" }, 403);
104
- }
105
- return { config: deployment.cloudAdminMembers, actingWorkosUserId };
106
- };
107
- const handleError = (c, error) => {
108
- if (error instanceof CloudAdminMembersError) {
109
- return c.json({ error: error.reason ?? error.message }, error.status);
110
- }
111
- throw error;
112
- };
113
- routes.openapi(listMembersRoute, async (c) => {
114
- const context = await resolveContext(c);
107
+ const run = async (c, operation) => {
108
+ const context = requestContext(c);
115
109
  if (context instanceof Response)
116
110
  return context;
117
111
  try {
118
- return c.json({ data: await listCloudAdminMembers(context) });
112
+ return await operation(context);
119
113
  }
120
114
  catch (error) {
121
115
  return handleError(c, error);
122
116
  }
117
+ };
118
+ routes.openapi(capabilitiesRoute, async (c) => {
119
+ const result = await run(c, (context) => runtime.getCapabilities(context));
120
+ return result instanceof Response ? result : c.json({ data: result });
121
+ });
122
+ routes.openapi(listMembersRoute, async (c) => {
123
+ const result = await run(c, (context) => runtime.listMembers(context));
124
+ return result instanceof Response ? result : c.json({ data: result });
123
125
  });
124
126
  routes.openapi(listRolesRoute, async (c) => {
125
- const context = await resolveContext(c);
126
- if (context instanceof Response)
127
- return context;
128
- try {
129
- return c.json({ data: await listCloudAdminMemberRoles(context) });
130
- }
131
- catch (error) {
132
- return handleError(c, error);
133
- }
127
+ const result = await run(c, (context) => runtime.listRoles(context));
128
+ return result instanceof Response ? result : c.json({ data: result });
134
129
  });
135
- routes.openapi(listTeamInvitationsRoute, async (c) => {
136
- const context = await resolveContext(c);
137
- if (context instanceof Response)
138
- return context;
139
- try {
140
- return c.json({ data: await listCloudAdminInvitations(context) });
141
- }
142
- catch (error) {
143
- return handleError(c, error);
144
- }
130
+ routes.openapi(listInvitationsRoute, async (c) => {
131
+ const result = await run(c, (context) => runtime.listInvitations(context));
132
+ return result instanceof Response ? result : c.json({ data: result });
145
133
  });
146
- routes.openapi(createTeamInvitationRoute, async (c) => {
147
- const context = await resolveContext(c);
148
- if (context instanceof Response)
149
- return context;
134
+ routes.openapi(createInvitationRoute, async (c) => {
150
135
  const input = await parseJsonBody(c, inviteSchema);
151
- try {
152
- return c.json({ data: await inviteCloudAdminMember({ ...context, input }) }, 201);
153
- }
154
- catch (error) {
155
- return handleError(c, error);
156
- }
136
+ const result = await run(c, (context) => runtime.inviteMember(context, input));
137
+ return result instanceof Response ? result : c.json({ data: result }, 201);
157
138
  });
158
- routes.openapi(revokeTeamInvitationRoute, async (c) => {
159
- const context = await resolveContext(c);
160
- if (context instanceof Response)
161
- return context;
162
- try {
163
- await revokeCloudAdminInvitation({
164
- ...context,
165
- invitationId: c.req.param("invitationId"),
166
- });
167
- return c.body(null, 204);
168
- }
169
- catch (error) {
170
- return handleError(c, error);
171
- }
139
+ routes.openapi(revokeInvitationRoute, async (c) => {
140
+ const { invitationId } = c.req.param();
141
+ const result = await run(c, (context) => runtime.revokeInvitation(context, invitationId));
142
+ return result instanceof Response ? result : c.body(null, 204);
172
143
  });
173
- routes.openapi(setTeamMemberAccessRoute, async (c) => {
174
- const context = await resolveContext(c);
175
- if (context instanceof Response)
176
- return context;
177
- const input = await parseJsonBody(c, accessSchema);
178
- try {
179
- return c.json({
180
- data: await setCloudAdminMemberAccess({
181
- ...context,
182
- membershipId: c.req.param("membershipId"),
183
- hasAccess: input.hasAccess,
184
- }),
185
- });
186
- }
187
- catch (error) {
188
- return handleError(c, error);
189
- }
144
+ routes.openapi(updateRoleRoute, async (c) => {
145
+ const { memberId } = c.req.param();
146
+ const input = await parseJsonBody(c, roleSchema);
147
+ const result = await run(c, (context) => runtime.updateMemberRole(context, memberId, input.roleId));
148
+ return result instanceof Response ? result : c.json({ data: result });
190
149
  });
191
- routes.openapi(setTeamMemberPermissionsRoute, async (c) => {
192
- const context = await resolveContext(c);
193
- if (context instanceof Response)
194
- return context;
195
- const input = await parseJsonBody(c, permissionsSchema);
196
- try {
197
- return c.json({
198
- data: await setCloudAdminMemberPermissions({
199
- ...context,
200
- membershipId: c.req.param("membershipId"),
201
- permissions: input.permissions,
202
- }),
203
- });
204
- }
205
- catch (error) {
206
- return handleError(c, error);
207
- }
150
+ routes.openapi(deactivateMemberRoute, async (c) => {
151
+ const { memberId } = c.req.param();
152
+ const result = await run(c, (context) => runtime.deactivateMember(context, memberId));
153
+ return result instanceof Response ? result : c.json({ data: result });
154
+ });
155
+ routes.openapi(activateMemberRoute, async (c) => {
156
+ const { memberId } = c.req.param();
157
+ const result = await run(c, (context) => runtime.activateMember(context, memberId));
158
+ return result instanceof Response ? result : c.json({ data: result });
208
159
  });
209
160
  return routes;
210
161
  }
@@ -1 +1 @@
1
- {"version":3,"file":"team-routes.js","sourceRoot":"","sources":["../src/team-routes.ts"],"names":[],"mappings":"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","sourcesContent":["import { createRoute, OpenAPIHono, z } from \"@hono/zod-openapi\"\nimport { cloudAuthUserLinks } from \"@voyant-travel/db/schema/iam\"\nimport { openApiValidationHook, parseJsonBody, type VoyantDb } from \"@voyant-travel/hono\"\nimport { eq } from \"drizzle-orm\"\nimport type { Context } from \"hono\"\n\nimport {\n type CloudAdminMembersConfig,\n CloudAdminMembersError,\n inviteCloudAdminMember,\n listCloudAdminInvitations,\n listCloudAdminMemberRoles,\n listCloudAdminMembers,\n revokeCloudAdminInvitation,\n setCloudAdminMemberAccess,\n setCloudAdminMemberPermissions,\n} from \"./cloud-broker.js\"\nimport type { IdentityAccessRuntimeProvider } from \"./identity-access-runtime-port.js\"\n\ntype IdentityAccessEnv = {\n Bindings: Record<string, unknown>\n Variables: { userId?: string; db: VoyantDb }\n}\ntype TeamContext = { config: CloudAdminMembersConfig; actingWorkosUserId: string }\ntype TeamRouteContext = Context<IdentityAccessEnv>\n\nconst inviteSchema = z.object({\n email: z.string().email(),\n roleSlug: z.string().trim().min(1).max(120).optional().nullable(),\n expiresInDays: z.number().int().min(1).max(30).optional(),\n})\nconst accessSchema = z.object({ hasAccess: z.boolean() })\nconst permissionsSchema = z.object({\n permissions: z.array(z.string().trim().min(1).max(120)).max(200),\n})\n\nconst teamAdminApiId = \"@voyant-travel/auth#team.api.admin\"\nconst jsonBody = <T extends z.ZodTypeAny>(schema: T) => ({\n required: true,\n content: { \"application/json\": { schema } },\n})\nconst responses = (...statuses: number[]) =>\n Object.fromEntries(statuses.map((status) => [status, { description: `HTTP ${status}` }]))\nconst teamRoute = <M extends \"get\" | \"post\" | \"put\" | \"delete\", P extends string>(config: {\n method: M\n path: P\n operationId: string\n request?: Record<string, unknown>\n statuses: number[]\n}) =>\n createRoute({\n method: config.method,\n path: config.path,\n operationId: config.operationId,\n \"x-voyant-api-id\": teamAdminApiId,\n ...(config.request ? { request: config.request } : {}),\n responses: responses(...config.statuses),\n })\n\nconst listMembersRoute = teamRoute({\n method: \"get\",\n path: \"/members\",\n operationId: \"listTeamMembers\",\n statuses: [200, 401, 403, 404, 501],\n})\nconst listRolesRoute = teamRoute({\n method: \"get\",\n path: \"/roles\",\n operationId: \"listTeamRoles\",\n statuses: [200, 401, 403, 404, 501],\n})\nconst listTeamInvitationsRoute = teamRoute({\n method: \"get\",\n path: \"/invitations\",\n operationId: \"listTeamInvitations\",\n statuses: [200, 401, 403, 404, 501],\n})\nconst createTeamInvitationRoute = teamRoute({\n method: \"post\",\n path: \"/invitations\",\n operationId: \"createTeamInvitation\",\n request: { body: jsonBody(inviteSchema) },\n statuses: [201, 400, 401, 403, 404, 501],\n})\nconst revokeTeamInvitationRoute = teamRoute({\n method: \"delete\",\n path: \"/invitations/{invitationId}\",\n operationId: \"revokeTeamInvitation\",\n request: { params: z.object({ invitationId: z.string() }) },\n statuses: [204, 401, 403, 404, 501],\n})\nconst setTeamMemberAccessRoute = teamRoute({\n method: \"put\",\n path: \"/members/{membershipId}/access\",\n operationId: \"setTeamMemberAccess\",\n request: {\n params: z.object({ membershipId: z.string() }),\n body: jsonBody(accessSchema),\n },\n statuses: [200, 400, 401, 403, 404, 501],\n})\nconst setTeamMemberPermissionsRoute = teamRoute({\n method: \"put\",\n path: \"/members/{membershipId}/permissions\",\n operationId: \"setTeamMemberPermissions\",\n request: {\n params: z.object({ membershipId: z.string() }),\n body: jsonBody(permissionsSchema),\n },\n statuses: [200, 400, 401, 403, 404, 501],\n})\n\nasync function resolveActingWorkosUserId(db: VoyantDb, userId: string): Promise<string | null> {\n const [link] = await db\n .select({ providerAccountId: cloudAuthUserLinks.providerAccountId })\n .from(cloudAuthUserLinks)\n .where(eq(cloudAuthUserLinks.userId, userId))\n .limit(1)\n return link?.providerAccountId ?? null\n}\n\nexport function createTeamAdminRoutes(runtime: IdentityAccessRuntimeProvider) {\n const routes = new OpenAPIHono<IdentityAccessEnv>({ defaultHook: openApiValidationHook })\n\n const resolveContext = async (c: TeamRouteContext): Promise<TeamContext | Response> => {\n const deployment = runtime.resolveDeployment(c.env)\n if (deployment.authMode !== \"voyant-cloud\") return c.json({ error: \"Not found\" }, 404)\n\n const userId = c.get(\"userId\")\n if (!userId) return c.json({ error: \"Unauthorized\" }, 401)\n if (!deployment.cloudAdminMembers) {\n return c.json({ error: \"Voyant Cloud member management is not configured\" }, 501)\n }\n\n const actingWorkosUserId = await resolveActingWorkosUserId(c.get(\"db\"), userId)\n if (!actingWorkosUserId) {\n return c.json({ error: \"No Voyant Cloud identity for this session\" }, 403)\n }\n return { config: deployment.cloudAdminMembers, actingWorkosUserId }\n }\n\n const handleError = (c: TeamRouteContext, error: unknown): Response => {\n if (error instanceof CloudAdminMembersError) {\n return c.json({ error: error.reason ?? error.message }, error.status as 403)\n }\n throw error\n }\n\n routes.openapi(listMembersRoute, async (c) => {\n const context = await resolveContext(c)\n if (context instanceof Response) return context\n try {\n return c.json({ data: await listCloudAdminMembers(context) })\n } catch (error) {\n return handleError(c, error)\n }\n })\n routes.openapi(listRolesRoute, async (c) => {\n const context = await resolveContext(c)\n if (context instanceof Response) return context\n try {\n return c.json({ data: await listCloudAdminMemberRoles(context) })\n } catch (error) {\n return handleError(c, error)\n }\n })\n routes.openapi(listTeamInvitationsRoute, async (c) => {\n const context = await resolveContext(c)\n if (context instanceof Response) return context\n try {\n return c.json({ data: await listCloudAdminInvitations(context) })\n } catch (error) {\n return handleError(c, error)\n }\n })\n routes.openapi(createTeamInvitationRoute, async (c) => {\n const context = await resolveContext(c)\n if (context instanceof Response) return context\n const input = await parseJsonBody(c, inviteSchema)\n try {\n return c.json({ data: await inviteCloudAdminMember({ ...context, input }) }, 201)\n } catch (error) {\n return handleError(c, error)\n }\n })\n routes.openapi(revokeTeamInvitationRoute, async (c) => {\n const context = await resolveContext(c)\n if (context instanceof Response) return context\n try {\n await revokeCloudAdminInvitation({\n ...context,\n invitationId: c.req.param(\"invitationId\"),\n })\n return c.body(null, 204)\n } catch (error) {\n return handleError(c, error)\n }\n })\n routes.openapi(setTeamMemberAccessRoute, async (c) => {\n const context = await resolveContext(c)\n if (context instanceof Response) return context\n const input = await parseJsonBody(c, accessSchema)\n try {\n return c.json({\n data: await setCloudAdminMemberAccess({\n ...context,\n membershipId: c.req.param(\"membershipId\"),\n hasAccess: input.hasAccess,\n }),\n })\n } catch (error) {\n return handleError(c, error)\n }\n })\n routes.openapi(setTeamMemberPermissionsRoute, async (c) => {\n const context = await resolveContext(c)\n if (context instanceof Response) return context\n const input = await parseJsonBody(c, permissionsSchema)\n try {\n return c.json({\n data: await setCloudAdminMemberPermissions({\n ...context,\n membershipId: c.req.param(\"membershipId\"),\n permissions: input.permissions,\n }),\n })\n } catch (error) {\n return handleError(c, error)\n }\n })\n\n return routes\n}\n"]}
1
+ {"version":3,"file":"team-routes.js","sourceRoot":"","sources":["../src/team-routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAiB,MAAM,qBAAqB,CAAA;AAGzF,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAA;AAYjE,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;IACzB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACzC,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC1D,CAAC,CAAA;AACF,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AAE1E,MAAM,cAAc,GAAG,oCAAoC,CAAA;AAC3D,MAAM,QAAQ,GAAG,CAAyB,MAAS,EAAE,EAAE,CAAC,CAAC;IACvD,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,EAAE,kBAAkB,EAAE,EAAE,MAAM,EAAE,EAAE;CAC5C,CAAC,CAAA;AACF,MAAM,SAAS,GAAG,CAAC,GAAG,QAAkB,EAAE,EAAE,CAC1C,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,QAAQ,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;AAC3F,MAAM,SAAS,GAAG,CAAgE,MAMjF,EAAE,EAAE,CACH,WAAW,CAAC;IACV,MAAM,EAAE,MAAM,CAAC,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC,IAAI;IACjB,WAAW,EAAE,MAAM,CAAC,WAAW;IAC/B,iBAAiB,EAAE,cAAc;IACjC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACtD,SAAS,EAAE,SAAS,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC;CACzC,CAAC,CAAA;AAEJ,MAAM,iBAAiB,GAAG,SAAS,CAAC;IAClC,MAAM,EAAE,KAAK;IACb,IAAI,EAAE,eAAe;IACrB,WAAW,EAAE,+BAA+B;IAC5C,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;CAC/B,CAAC,CAAA;AACF,MAAM,gBAAgB,GAAG,SAAS,CAAC;IACjC,MAAM,EAAE,KAAK;IACb,IAAI,EAAE,UAAU;IAChB,WAAW,EAAE,iBAAiB;IAC9B,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;CAC/B,CAAC,CAAA;AACF,MAAM,cAAc,GAAG,SAAS,CAAC;IAC/B,MAAM,EAAE,KAAK;IACb,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,eAAe;IAC5B,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;CAC/B,CAAC,CAAA;AACF,MAAM,oBAAoB,GAAG,SAAS,CAAC;IACrC,MAAM,EAAE,KAAK;IACb,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,qBAAqB;IAClC,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;CAC/B,CAAC,CAAA;AACF,MAAM,qBAAqB,GAAG,SAAS,CAAC;IACtC,MAAM,EAAE,MAAM;IACd,IAAI,EAAE,cAAc;IACpB,WAAW,EAAE,sBAAsB;IACnC,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,YAAY,CAAC,EAAE;IACzC,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;CAC9C,CAAC,CAAA;AACF,MAAM,qBAAqB,GAAG,SAAS,CAAC;IACtC,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,6BAA6B;IACnC,WAAW,EAAE,sBAAsB;IACnC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;IAC3D,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;CACpC,CAAC,CAAA;AACF,MAAM,eAAe,GAAG,SAAS,CAAC;IAChC,MAAM,EAAE,KAAK;IACb,IAAI,EAAE,0BAA0B;IAChC,WAAW,EAAE,sBAAsB;IACnC,OAAO,EAAE;QACP,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;QAC1C,IAAI,EAAE,QAAQ,CAAC,UAAU,CAAC;KAC3B;IACD,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;CAC9C,CAAC,CAAA;AACF,MAAM,qBAAqB,GAAG,SAAS,CAAC;IACtC,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,qBAAqB;IAC3B,WAAW,EAAE,sBAAsB;IACnC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;IACvD,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;CACzC,CAAC,CAAA;AACF,MAAM,mBAAmB,GAAG,SAAS,CAAC;IACpC,MAAM,EAAE,KAAK;IACb,IAAI,EAAE,gCAAgC;IACtC,WAAW,EAAE,oBAAoB;IACjC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE;IACvD,QAAQ,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC;CACzC,CAAC,CAAA;AAEF,SAAS,cAAc,CAAC,CAAmB;IACzC,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC9B,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,GAAG,CAAC,CAAA;IAC1D,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;AACrD,CAAC;AAED,SAAS,WAAW,CAAC,CAAmB,EAAE,KAAc;IACtD,IAAI,KAAK,YAAY,mBAAmB,EAAE,CAAC;QACzC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;IACzE,CAAC;IACD,IACE,KAAK,YAAY,KAAK;QACtB,QAAQ,IAAI,KAAK;QACjB,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;QAChC,KAAK,CAAC,MAAM,IAAI,GAAG;QACnB,KAAK,CAAC,MAAM,IAAI,GAAG,EACnB,CAAC;QACD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,MAAa,CAAC,CAAA;IAC9D,CAAC;IACD,MAAM,KAAK,CAAA;AACb,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAsC;IAC1E,MAAM,MAAM,GAAG,IAAI,WAAW,CAAU,EAAE,WAAW,EAAE,qBAAqB,EAAE,CAAC,CAAA;IAE/E,MAAM,GAAG,GAAG,KAAK,EACf,CAAmB,EACnB,SAAgE,EACzC,EAAE;QACzB,MAAM,OAAO,GAAG,cAAc,CAAC,CAAC,CAAC,CAAA;QACjC,IAAI,OAAO,YAAY,QAAQ;YAAE,OAAO,OAAO,CAAA;QAC/C,IAAI,CAAC;YACH,OAAO,MAAM,SAAS,CAAC,OAAO,CAAC,CAAA;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,WAAW,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;QAC9B,CAAC;IACH,CAAC,CAAA;IAED,MAAM,CAAC,OAAO,CAAC,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAA;QAC1E,OAAO,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;IACvE,CAAC,CAAC,CAAA;IACF,MAAM,CAAC,OAAO,CAAC,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC3C,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAA;QACtE,OAAO,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;IACvE,CAAC,CAAC,CAAA;IACF,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACzC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAA;QACpE,OAAO,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;IACvE,CAAC,CAAC,CAAA;IACF,MAAM,CAAC,OAAO,CAAC,oBAAoB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC/C,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAA;QAC1E,OAAO,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;IACvE,CAAC,CAAC,CAAA;IACF,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAChD,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,YAAY,CAAC,CAAA;QAClD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAA;QAC9E,OAAO,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,CAAC,CAAA;IAC5E,CAAC,CAAC,CAAA;IACF,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAChD,MAAM,EAAE,YAAY,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAA;QACtC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAA;QACzF,OAAO,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;IAChE,CAAC,CAAC,CAAA;IACF,MAAM,CAAC,OAAO,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC1C,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAA;QAClC,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,CAAC,EAAE,UAAU,CAAC,CAAA;QAChD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CACtC,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAC1D,CAAA;QACD,OAAO,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;IACvE,CAAC,CAAC,CAAA;IACF,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAChD,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAA;QAClC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAA;QACrF,OAAO,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;IACvE,CAAC,CAAC,CAAA;IACF,MAAM,CAAC,OAAO,CAAC,mBAAmB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC9C,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAA;QAClC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAA;QACnF,OAAO,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;IACvE,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC","sourcesContent":["import { createRoute, OpenAPIHono, z } from \"@hono/zod-openapi\"\nimport { openApiValidationHook, parseJsonBody, type VoyantDb } from \"@voyant-travel/hono\"\nimport type { Context } from \"hono\"\n\nimport { TeamManagementError } from \"./team-management-policy.js\"\nimport type {\n TeamManagementRequestContext,\n TeamManagementRuntimeProvider,\n} from \"./team-management-runtime-port.js\"\n\ntype TeamEnv = {\n Bindings: Record<string, unknown>\n Variables: { userId?: string; db: VoyantDb }\n}\ntype TeamRouteContext = Context<TeamEnv>\n\nconst inviteSchema = z.object({\n email: z.string().email(),\n roleId: z.string().trim().min(1).max(120),\n expiresInDays: z.number().int().min(1).max(30).optional(),\n})\nconst roleSchema = z.object({ roleId: z.string().trim().min(1).max(120) })\n\nconst teamAdminApiId = \"@voyant-travel/auth#team.api.admin\"\nconst jsonBody = <T extends z.ZodTypeAny>(schema: T) => ({\n required: true,\n content: { \"application/json\": { schema } },\n})\nconst responses = (...statuses: number[]) =>\n Object.fromEntries(statuses.map((status) => [status, { description: `HTTP ${status}` }]))\nconst teamRoute = <M extends \"get\" | \"post\" | \"put\" | \"delete\", P extends string>(config: {\n method: M\n path: P\n operationId: string\n request?: Record<string, unknown>\n statuses: number[]\n}) =>\n createRoute({\n method: config.method,\n path: config.path,\n operationId: config.operationId,\n \"x-voyant-api-id\": teamAdminApiId,\n ...(config.request ? { request: config.request } : {}),\n responses: responses(...config.statuses),\n })\n\nconst capabilitiesRoute = teamRoute({\n method: \"get\",\n path: \"/capabilities\",\n operationId: \"getTeamManagementCapabilities\",\n statuses: [200, 401, 403, 501],\n})\nconst listMembersRoute = teamRoute({\n method: \"get\",\n path: \"/members\",\n operationId: \"listTeamMembers\",\n statuses: [200, 401, 403, 501],\n})\nconst listRolesRoute = teamRoute({\n method: \"get\",\n path: \"/roles\",\n operationId: \"listTeamRoles\",\n statuses: [200, 401, 403, 501],\n})\nconst listInvitationsRoute = teamRoute({\n method: \"get\",\n path: \"/invitations\",\n operationId: \"listTeamInvitations\",\n statuses: [200, 401, 403, 501],\n})\nconst createInvitationRoute = teamRoute({\n method: \"post\",\n path: \"/invitations\",\n operationId: \"createTeamInvitation\",\n request: { body: jsonBody(inviteSchema) },\n statuses: [201, 400, 401, 403, 404, 409, 501],\n})\nconst revokeInvitationRoute = teamRoute({\n method: \"delete\",\n path: \"/invitations/{invitationId}\",\n operationId: \"revokeTeamInvitation\",\n request: { params: z.object({ invitationId: z.string() }) },\n statuses: [204, 401, 403, 404, 501],\n})\nconst updateRoleRoute = teamRoute({\n method: \"put\",\n path: \"/members/{memberId}/role\",\n operationId: \"updateTeamMemberRole\",\n request: {\n params: z.object({ memberId: z.string() }),\n body: jsonBody(roleSchema),\n },\n statuses: [200, 400, 401, 403, 404, 409, 501],\n})\nconst deactivateMemberRoute = teamRoute({\n method: \"delete\",\n path: \"/members/{memberId}\",\n operationId: \"deactivateTeamMember\",\n request: { params: z.object({ memberId: z.string() }) },\n statuses: [200, 401, 403, 404, 409, 501],\n})\nconst activateMemberRoute = teamRoute({\n method: \"put\",\n path: \"/members/{memberId}/activation\",\n operationId: \"activateTeamMember\",\n request: { params: z.object({ memberId: z.string() }) },\n statuses: [200, 401, 403, 404, 409, 501],\n})\n\nfunction requestContext(c: TeamRouteContext): TeamManagementRequestContext | Response {\n const userId = c.get(\"userId\")\n if (!userId) return c.json({ error: \"Unauthorized\" }, 401)\n return { bindings: c.env, db: c.get(\"db\"), userId }\n}\n\nfunction handleError(c: TeamRouteContext, error: unknown): Response {\n if (error instanceof TeamManagementError) {\n return c.json({ error: error.message, code: error.code }, error.status)\n }\n if (\n error instanceof Error &&\n \"status\" in error &&\n typeof error.status === \"number\" &&\n error.status >= 400 &&\n error.status <= 599\n ) {\n return c.json({ error: error.message }, error.status as 400)\n }\n throw error\n}\n\nexport function createTeamAdminRoutes(runtime: TeamManagementRuntimeProvider) {\n const routes = new OpenAPIHono<TeamEnv>({ defaultHook: openApiValidationHook })\n\n const run = async <T>(\n c: TeamRouteContext,\n operation: (context: TeamManagementRequestContext) => Promise<T>,\n ): Promise<T | Response> => {\n const context = requestContext(c)\n if (context instanceof Response) return context\n try {\n return await operation(context)\n } catch (error) {\n return handleError(c, error)\n }\n }\n\n routes.openapi(capabilitiesRoute, async (c) => {\n const result = await run(c, (context) => runtime.getCapabilities(context))\n return result instanceof Response ? result : c.json({ data: result })\n })\n routes.openapi(listMembersRoute, async (c) => {\n const result = await run(c, (context) => runtime.listMembers(context))\n return result instanceof Response ? result : c.json({ data: result })\n })\n routes.openapi(listRolesRoute, async (c) => {\n const result = await run(c, (context) => runtime.listRoles(context))\n return result instanceof Response ? result : c.json({ data: result })\n })\n routes.openapi(listInvitationsRoute, async (c) => {\n const result = await run(c, (context) => runtime.listInvitations(context))\n return result instanceof Response ? result : c.json({ data: result })\n })\n routes.openapi(createInvitationRoute, async (c) => {\n const input = await parseJsonBody(c, inviteSchema)\n const result = await run(c, (context) => runtime.inviteMember(context, input))\n return result instanceof Response ? result : c.json({ data: result }, 201)\n })\n routes.openapi(revokeInvitationRoute, async (c) => {\n const { invitationId } = c.req.param()\n const result = await run(c, (context) => runtime.revokeInvitation(context, invitationId))\n return result instanceof Response ? result : c.body(null, 204)\n })\n routes.openapi(updateRoleRoute, async (c) => {\n const { memberId } = c.req.param()\n const input = await parseJsonBody(c, roleSchema)\n const result = await run(c, (context) =>\n runtime.updateMemberRole(context, memberId, input.roleId),\n )\n return result instanceof Response ? result : c.json({ data: result })\n })\n routes.openapi(deactivateMemberRoute, async (c) => {\n const { memberId } = c.req.param()\n const result = await run(c, (context) => runtime.deactivateMember(context, memberId))\n return result instanceof Response ? result : c.json({ data: result })\n })\n routes.openapi(activateMemberRoute, async (c) => {\n const { memberId } = c.req.param()\n const result = await run(c, (context) => runtime.activateMember(context, memberId))\n return result instanceof Response ? result : c.json({ data: result })\n })\n\n return routes\n}\n"]}
@@ -0,0 +1,58 @@
1
+ import { type ToolContext } from "@voyant-travel/tools";
2
+ import type { CreatedTeamInvitationDto, InviteTeamMemberInput, TeamInvitationDto, TeamManagementCapabilitiesDto, TeamMemberDto, TeamRoleDto } from "./team-management-runtime-port.js";
3
+ export interface TeamManagementToolServices {
4
+ getCapabilities(): Promise<TeamManagementCapabilitiesDto>;
5
+ listMembers(): Promise<TeamMemberDto[]>;
6
+ listRoles(): Promise<TeamRoleDto[]>;
7
+ listInvitations(): Promise<TeamInvitationDto[]>;
8
+ inviteMember(input: InviteTeamMemberInput): Promise<CreatedTeamInvitationDto>;
9
+ revokeInvitation(invitationId: string): Promise<void>;
10
+ updateMemberRole(memberId: string, roleId: string): Promise<TeamMemberDto>;
11
+ activateMember(memberId: string): Promise<TeamMemberDto>;
12
+ deactivateMember(memberId: string): Promise<TeamMemberDto>;
13
+ }
14
+ export type TeamManagementToolContext = ToolContext & {
15
+ teamManagement?: TeamManagementToolServices;
16
+ };
17
+ export declare const getTeamManagementCapabilitiesTool: import("@voyant-travel/tools").ToolDefinition<Record<string, never>, TeamManagementCapabilitiesDto, TeamManagementToolContext>;
18
+ export declare const listTeamMembersTool: import("@voyant-travel/tools").ToolDefinition<Record<string, never>, TeamMemberDto[], TeamManagementToolContext>;
19
+ export declare const listTeamRolesTool: import("@voyant-travel/tools").ToolDefinition<Record<string, never>, TeamRoleDto[], TeamManagementToolContext>;
20
+ export declare const listTeamInvitationsTool: import("@voyant-travel/tools").ToolDefinition<Record<string, never>, TeamInvitationDto[], TeamManagementToolContext>;
21
+ export declare const inviteTeamMemberTool: import("@voyant-travel/tools").ToolDefinition<{
22
+ email: string;
23
+ roleId: string;
24
+ expiresInDays?: number | undefined;
25
+ }, TeamInvitationDto, TeamManagementToolContext>;
26
+ export declare const revokeTeamInvitationTool: import("@voyant-travel/tools").ToolDefinition<{
27
+ invitationId: string;
28
+ }, {
29
+ invitationId: string;
30
+ revoked: true;
31
+ }, TeamManagementToolContext>;
32
+ export declare const updateTeamMemberRoleTool: import("@voyant-travel/tools").ToolDefinition<{
33
+ memberId: string;
34
+ roleId: string;
35
+ }, TeamMemberDto, TeamManagementToolContext>;
36
+ export declare const activateTeamMemberTool: import("@voyant-travel/tools").ToolDefinition<{
37
+ memberId: string;
38
+ }, TeamMemberDto, TeamManagementToolContext>;
39
+ export declare const deactivateTeamMemberTool: import("@voyant-travel/tools").ToolDefinition<{
40
+ memberId: string;
41
+ }, TeamMemberDto, TeamManagementToolContext>;
42
+ export declare const teamManagementTools: readonly [import("@voyant-travel/tools").ToolDefinition<Record<string, never>, TeamManagementCapabilitiesDto, TeamManagementToolContext>, import("@voyant-travel/tools").ToolDefinition<Record<string, never>, TeamMemberDto[], TeamManagementToolContext>, import("@voyant-travel/tools").ToolDefinition<Record<string, never>, TeamRoleDto[], TeamManagementToolContext>, import("@voyant-travel/tools").ToolDefinition<Record<string, never>, TeamInvitationDto[], TeamManagementToolContext>, import("@voyant-travel/tools").ToolDefinition<{
43
+ email: string;
44
+ roleId: string;
45
+ expiresInDays?: number | undefined;
46
+ }, TeamInvitationDto, TeamManagementToolContext>, import("@voyant-travel/tools").ToolDefinition<{
47
+ invitationId: string;
48
+ }, {
49
+ invitationId: string;
50
+ revoked: true;
51
+ }, TeamManagementToolContext>, import("@voyant-travel/tools").ToolDefinition<{
52
+ memberId: string;
53
+ roleId: string;
54
+ }, TeamMemberDto, TeamManagementToolContext>, import("@voyant-travel/tools").ToolDefinition<{
55
+ memberId: string;
56
+ }, TeamMemberDto, TeamManagementToolContext>, import("@voyant-travel/tools").ToolDefinition<{
57
+ memberId: string;
58
+ }, TeamMemberDto, TeamManagementToolContext>];
package/dist/tools.js ADDED
@@ -0,0 +1,226 @@
1
+ import { defineTool, READ_ONLY_RISK, requireService, ToolError, } from "@voyant-travel/tools";
2
+ import { z } from "zod";
3
+ const teamMemberSchema = z.object({
4
+ id: z.string(),
5
+ email: z.string().email().nullable(),
6
+ name: z.string().nullable(),
7
+ roleId: z.string(),
8
+ roleName: z.string(),
9
+ status: z.enum(["active", "deactivated"]),
10
+ joinedAt: z.string().nullable(),
11
+ lastActivityAt: z.string().nullable(),
12
+ });
13
+ const teamRoleSchema = z.object({
14
+ id: z.string(),
15
+ name: z.string(),
16
+ description: z.string().nullable(),
17
+ });
18
+ const teamInvitationSchema = z.object({
19
+ id: z.string(),
20
+ email: z.string().email(),
21
+ roleId: z.string(),
22
+ roleName: z.string(),
23
+ status: z.enum(["pending", "accepted", "expired", "revoked"]),
24
+ createdAt: z.string(),
25
+ expiresAt: z.string(),
26
+ });
27
+ const teamManagementCapabilitiesSchema = z.object({
28
+ viewRoster: z.boolean(),
29
+ inviteMembers: z.boolean(),
30
+ manageRoles: z.boolean(),
31
+ activateMembers: z.boolean(),
32
+ deactivateMembers: z.boolean(),
33
+ revokeInvitations: z.boolean(),
34
+ });
35
+ const emptyInputSchema = z.object({});
36
+ const inviteTeamMemberInputSchema = z.object({
37
+ email: z.string().email().describe("Email address for the new team member."),
38
+ roleId: z.string().trim().min(1).max(120).describe("Provider-neutral team role id."),
39
+ expiresInDays: z
40
+ .number()
41
+ .int()
42
+ .min(1)
43
+ .max(30)
44
+ .optional()
45
+ .describe("Invitation validity in days. Uses the deployment default when omitted."),
46
+ });
47
+ const invitationIdInputSchema = z.object({
48
+ invitationId: z.string().min(1).describe("Team invitation id."),
49
+ });
50
+ const memberIdInputSchema = z.object({
51
+ memberId: z.string().min(1).describe("Team member id."),
52
+ });
53
+ const updateMemberRoleInputSchema = memberIdInputSchema.extend({
54
+ roleId: z.string().trim().min(1).max(120).describe("Provider-neutral team role id."),
55
+ });
56
+ const actingUserRequirement = " Requires an authenticated acting staff user; organization-only grants are rejected.";
57
+ function teamManagement(ctx) {
58
+ if (ctx.actor !== "staff" || ctx.audience !== "staff") {
59
+ throw new ToolError("Team-management tools are restricted to staff grants.", "AUTHORIZATION_DENIED", {
60
+ actor: ctx.actor,
61
+ audience: ctx.audience,
62
+ });
63
+ }
64
+ return requireService(ctx.teamManagement, "teamManagement");
65
+ }
66
+ export const getTeamManagementCapabilitiesTool = defineTool({
67
+ name: "get_team_management_capabilities",
68
+ description: "Read the current staff user's provider-neutral team-management capabilities." +
69
+ actingUserRequirement,
70
+ inputSchema: emptyInputSchema,
71
+ outputSchema: teamManagementCapabilitiesSchema,
72
+ requiredScopes: ["team:read"],
73
+ tier: "read",
74
+ riskPolicy: READ_ONLY_RISK,
75
+ async handler(_input, ctx) {
76
+ return teamManagement(ctx).getCapabilities();
77
+ },
78
+ });
79
+ export const listTeamMembersTool = defineTool({
80
+ name: "list_team_members",
81
+ description: "List the staff team roster and access status. Contains personal information." +
82
+ actingUserRequirement,
83
+ inputSchema: emptyInputSchema,
84
+ outputSchema: z.array(teamMemberSchema),
85
+ requiredScopes: ["team:read"],
86
+ tier: "sensitive",
87
+ riskPolicy: READ_ONLY_RISK,
88
+ async handler(_input, ctx) {
89
+ return teamManagement(ctx).listMembers();
90
+ },
91
+ });
92
+ export const listTeamRolesTool = defineTool({
93
+ name: "list_team_roles",
94
+ description: "List the provider-neutral roles assignable to team members. Read-only." +
95
+ actingUserRequirement,
96
+ inputSchema: emptyInputSchema,
97
+ outputSchema: z.array(teamRoleSchema),
98
+ requiredScopes: ["team:read"],
99
+ tier: "read",
100
+ riskPolicy: READ_ONLY_RISK,
101
+ async handler(_input, ctx) {
102
+ return teamManagement(ctx).listRoles();
103
+ },
104
+ });
105
+ export const listTeamInvitationsTool = defineTool({
106
+ name: "list_team_invitations",
107
+ description: "List team invitations and their lifecycle status. Contains personal information." +
108
+ actingUserRequirement,
109
+ inputSchema: emptyInputSchema,
110
+ outputSchema: z.array(teamInvitationSchema),
111
+ requiredScopes: ["team:read"],
112
+ tier: "sensitive",
113
+ riskPolicy: READ_ONLY_RISK,
114
+ async handler(_input, ctx) {
115
+ return teamManagement(ctx).listInvitations();
116
+ },
117
+ });
118
+ export const inviteTeamMemberTool = defineTool({
119
+ name: "invite_team_member",
120
+ description: "Invite a staff team member with an assigned role. Sends an external invitation and requires explicit confirmation." +
121
+ actingUserRequirement,
122
+ inputSchema: inviteTeamMemberInputSchema,
123
+ outputSchema: teamInvitationSchema,
124
+ requiredScopes: ["team:write"],
125
+ tier: "destructive",
126
+ riskPolicy: {
127
+ destructive: true,
128
+ reversible: false,
129
+ dryRunSupported: false,
130
+ confirmationRequired: true,
131
+ sideEffects: ["email", "data-write"],
132
+ },
133
+ async handler(input, ctx) {
134
+ const { acceptUrl: _acceptUrl, ...invitation } = await teamManagement(ctx).inviteMember(input);
135
+ return invitation;
136
+ },
137
+ });
138
+ export const revokeTeamInvitationTool = defineTool({
139
+ name: "revoke_team_invitation",
140
+ description: "Revoke a pending team invitation. Invalidates its acceptance path and requires confirmation." +
141
+ actingUserRequirement,
142
+ inputSchema: invitationIdInputSchema,
143
+ outputSchema: z.object({ invitationId: z.string(), revoked: z.literal(true) }),
144
+ requiredScopes: ["team:delete"],
145
+ tier: "destructive",
146
+ riskPolicy: {
147
+ destructive: true,
148
+ reversible: false,
149
+ dryRunSupported: false,
150
+ confirmationRequired: true,
151
+ sideEffects: ["data-delete"],
152
+ },
153
+ async handler({ invitationId }, ctx) {
154
+ await teamManagement(ctx).revokeInvitation(invitationId);
155
+ return { invitationId, revoked: true };
156
+ },
157
+ });
158
+ export const updateTeamMemberRoleTool = defineTool({
159
+ name: "update_team_member_role",
160
+ description: "Change a team member's role and effective access. Requires explicit confirmation." +
161
+ actingUserRequirement,
162
+ inputSchema: updateMemberRoleInputSchema,
163
+ outputSchema: teamMemberSchema,
164
+ requiredScopes: ["team:write"],
165
+ tier: "sensitive",
166
+ riskPolicy: {
167
+ destructive: false,
168
+ reversible: true,
169
+ dryRunSupported: false,
170
+ confirmationRequired: true,
171
+ sideEffects: ["data-write"],
172
+ },
173
+ async handler({ memberId, roleId }, ctx) {
174
+ return teamManagement(ctx).updateMemberRole(memberId, roleId);
175
+ },
176
+ });
177
+ export const activateTeamMemberTool = defineTool({
178
+ name: "activate_team_member",
179
+ description: "Restore a team member's deployment access. Requires explicit confirmation." +
180
+ actingUserRequirement,
181
+ inputSchema: memberIdInputSchema,
182
+ outputSchema: teamMemberSchema,
183
+ requiredScopes: ["team:write"],
184
+ tier: "sensitive",
185
+ riskPolicy: {
186
+ destructive: false,
187
+ reversible: true,
188
+ dryRunSupported: false,
189
+ confirmationRequired: true,
190
+ sideEffects: ["data-write"],
191
+ },
192
+ async handler({ memberId }, ctx) {
193
+ return teamManagement(ctx).activateMember(memberId);
194
+ },
195
+ });
196
+ export const deactivateTeamMemberTool = defineTool({
197
+ name: "deactivate_team_member",
198
+ description: "Remove a team member's deployment access and potentially revoke active credentials. Requires explicit confirmation." +
199
+ actingUserRequirement,
200
+ inputSchema: memberIdInputSchema,
201
+ outputSchema: teamMemberSchema,
202
+ requiredScopes: ["team:delete"],
203
+ tier: "destructive",
204
+ riskPolicy: {
205
+ destructive: true,
206
+ reversible: false,
207
+ dryRunSupported: false,
208
+ confirmationRequired: true,
209
+ sideEffects: ["data-write", "data-delete"],
210
+ },
211
+ async handler({ memberId }, ctx) {
212
+ return teamManagement(ctx).deactivateMember(memberId);
213
+ },
214
+ });
215
+ export const teamManagementTools = [
216
+ getTeamManagementCapabilitiesTool,
217
+ listTeamMembersTool,
218
+ listTeamRolesTool,
219
+ listTeamInvitationsTool,
220
+ inviteTeamMemberTool,
221
+ revokeTeamInvitationTool,
222
+ updateTeamMemberRoleTool,
223
+ activateTeamMemberTool,
224
+ deactivateTeamMemberTool,
225
+ ];
226
+ //# sourceMappingURL=tools.js.map