@fragno-dev/project-connector-fragment 0.0.0-stage → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/LICENSE.md +16 -0
  2. package/README.md +285 -2
  3. package/bin/run.js +4 -0
  4. package/dist/browser/client/react.d.ts +174 -0
  5. package/dist/browser/client/react.d.ts.map +1 -0
  6. package/dist/browser/client/react.js +195 -0
  7. package/dist/browser/client/react.js.map +1 -0
  8. package/dist/browser/client/solid.d.ts +177 -0
  9. package/dist/browser/client/solid.d.ts.map +1 -0
  10. package/dist/browser/client/solid.js +130 -0
  11. package/dist/browser/client/solid.js.map +1 -0
  12. package/dist/browser/client/svelte.d.ts +177 -0
  13. package/dist/browser/client/svelte.d.ts.map +1 -0
  14. package/dist/browser/client/svelte.js +132 -0
  15. package/dist/browser/client/svelte.js.map +1 -0
  16. package/dist/browser/client/vanilla.d.ts +204 -0
  17. package/dist/browser/client/vanilla.d.ts.map +1 -0
  18. package/dist/browser/client/vanilla.js +160 -0
  19. package/dist/browser/client/vanilla.js.map +1 -0
  20. package/dist/browser/client/vue.d.ts +177 -0
  21. package/dist/browser/client/vue.d.ts.map +1 -0
  22. package/dist/browser/client/vue.js +128 -0
  23. package/dist/browser/client/vue.js.map +1 -0
  24. package/dist/browser/client-BCzNDSlW.d.ts +711 -0
  25. package/dist/browser/client-BCzNDSlW.d.ts.map +1 -0
  26. package/dist/browser/index.d.ts +504 -0
  27. package/dist/browser/index.d.ts.map +1 -0
  28. package/dist/browser/index.js +2 -0
  29. package/dist/browser/src-CSPQuoKz.js +2286 -0
  30. package/dist/browser/src-CSPQuoKz.js.map +1 -0
  31. package/dist/cli/authorization-browser.js +20 -0
  32. package/dist/cli/authorization-browser.js.map +1 -0
  33. package/dist/cli/cli.d.ts +6 -0
  34. package/dist/cli/cli.d.ts.map +1 -0
  35. package/dist/cli/cli.js +258 -0
  36. package/dist/cli/cli.js.map +1 -0
  37. package/dist/cli/definition.js +13 -0
  38. package/dist/cli/definition.js.map +1 -0
  39. package/dist/cli/index.js +14 -0
  40. package/dist/cli/index.js.map +1 -0
  41. package/dist/cli/project-connector-client.js +235 -0
  42. package/dist/cli/project-connector-client.js.map +1 -0
  43. package/dist/cli/project-connector-contracts.js +125 -0
  44. package/dist/cli/project-connector-contracts.js.map +1 -0
  45. package/dist/cli/routes.js +449 -0
  46. package/dist/cli/routes.js.map +1 -0
  47. package/dist/cli/schema.js +18 -0
  48. package/dist/cli/schema.js.map +1 -0
  49. package/dist/node/definition.d.ts +170 -0
  50. package/dist/node/definition.d.ts.map +1 -0
  51. package/dist/node/definition.js +13 -0
  52. package/dist/node/definition.js.map +1 -0
  53. package/dist/node/index.d.ts +456 -0
  54. package/dist/node/index.d.ts.map +1 -0
  55. package/dist/node/index.js +36 -0
  56. package/dist/node/index.js.map +1 -0
  57. package/dist/node/project-connector-client.d.ts +13 -0
  58. package/dist/node/project-connector-client.d.ts.map +1 -0
  59. package/dist/node/project-connector-client.js +235 -0
  60. package/dist/node/project-connector-client.js.map +1 -0
  61. package/dist/node/project-connector-contracts.d.ts +179 -0
  62. package/dist/node/project-connector-contracts.d.ts.map +1 -0
  63. package/dist/node/project-connector-contracts.js +125 -0
  64. package/dist/node/project-connector-contracts.js.map +1 -0
  65. package/dist/node/routes.d.ts +307 -0
  66. package/dist/node/routes.d.ts.map +1 -0
  67. package/dist/node/routes.js +449 -0
  68. package/dist/node/routes.js.map +1 -0
  69. package/dist/node/schema.d.ts +49 -0
  70. package/dist/node/schema.d.ts.map +1 -0
  71. package/dist/node/schema.js +18 -0
  72. package/dist/node/schema.js.map +1 -0
  73. package/dist/node/testing/project-connector-test-gateway.d.ts +63 -0
  74. package/dist/node/testing/project-connector-test-gateway.d.ts.map +1 -0
  75. package/dist/node/testing/project-connector-test-gateway.js +370 -0
  76. package/dist/node/testing/project-connector-test-gateway.js.map +1 -0
  77. package/package.json +111 -3
@@ -0,0 +1,235 @@
1
+ import { projectConnectorActionSchema, projectConnectorConnectionStateSchema, projectConnectorExecutionSchema, projectConnectorHttpUrlSchema, projectConnectorProfileSchema, projectConnectorProviderConfigsSchema } from "./project-connector-contracts.js";
2
+ import { z } from "zod";
3
+ import { Connector, ConnectorError, ProjectConnector } from "@oomol-lab/connector";
4
+ //#region src/project-connector-client.ts
5
+ const projectConnectorConnectionRequestSchema = z.object({
6
+ id: z.string().min(1),
7
+ projectId: z.string().min(1),
8
+ providerConfigId: z.string().min(1),
9
+ externalUserId: z.string().min(1),
10
+ service: z.string().min(1),
11
+ connectionName: z.string().nullable(),
12
+ authorizationUrl: projectConnectorHttpUrlSchema,
13
+ expiresAt: z.string()
14
+ }).and(projectConnectorConnectionStateSchema);
15
+ const projectConnectorCallOptions = { retries: 0 };
16
+ const projectConnectorDiscoveryEnvelopeSchema = z.object({
17
+ success: z.literal(true),
18
+ data: projectConnectorProviderConfigsSchema.safeExtend({ providerConfigs: z.array(projectConnectorProviderConfigsSchema.shape.providerConfigs.element.extend({ actionIds: z.array(z.string().min(1)) })) })
19
+ });
20
+ const projectConnectorCatalogActionSchema = projectConnectorActionSchema.extend({ description: z.string().nullish().transform((description) => description ?? null) });
21
+ function createOomolProjectConnectorSdk(config) {
22
+ return new ProjectConnector({
23
+ ...config,
24
+ fetch: fetchProjectConnectorWithoutRedirects
25
+ });
26
+ }
27
+ /** A safe SDK failure exposes its code, never its raw response data or project API key. */
28
+ var ProjectConnectorClientError = class extends Error {
29
+ code;
30
+ status;
31
+ constructor(code, status) {
32
+ super(`Project Connector request failed: ${code} (HTTP ${status})`);
33
+ this.code = code;
34
+ this.status = status;
35
+ this.name = "ProjectConnectorClientError";
36
+ }
37
+ };
38
+ function parseProjectConnectorApiBaseUrl(value) {
39
+ const baseUrl = new URL(projectConnectorHttpUrlSchema.parse(value));
40
+ const pathname = baseUrl.pathname.replace(/\/+$/, "");
41
+ if (baseUrl.search || baseUrl.hash || pathname !== "/v1") throw new Error("Project Connector baseUrl must be an origin followed by /v1");
42
+ baseUrl.pathname = pathname;
43
+ return baseUrl.toString().replace(/\/$/, "");
44
+ }
45
+ function parseProjectConnectorApiKey(value) {
46
+ return z.string().min(1).regex(/^[^\s]+$/).parse(value);
47
+ }
48
+ function projectConnectorClientErrorFromKnownFailure(error) {
49
+ if (error instanceof ProjectConnectorClientError) return error;
50
+ if (error instanceof ConnectorError) {
51
+ if (error.cause instanceof ProjectConnectorClientError) return error.cause;
52
+ console.warn("Project Connector gateway request failed", {
53
+ code: error.code,
54
+ status: error.status,
55
+ message: error.message,
56
+ requestId: error.requestId
57
+ });
58
+ return new ProjectConnectorClientError(error.code, error.status);
59
+ }
60
+ return null;
61
+ }
62
+ async function callProjectConnector(operation) {
63
+ try {
64
+ return await operation();
65
+ } catch (error) {
66
+ const knownFailure = projectConnectorClientErrorFromKnownFailure(error);
67
+ if (knownFailure) throw knownFailure;
68
+ throw error;
69
+ }
70
+ }
71
+ function parseProjectConnectorResponse(schema, value) {
72
+ const parsed = schema.safeParse(value);
73
+ if (!parsed.success) throw new ProjectConnectorClientError("invalid_response", 502);
74
+ return parsed.data;
75
+ }
76
+ async function fetchProjectConnectorWithoutRedirects(input, init) {
77
+ const response = await globalThis.fetch(input, {
78
+ ...init,
79
+ redirect: "manual"
80
+ });
81
+ if ([
82
+ 301,
83
+ 302,
84
+ 303,
85
+ 307,
86
+ 308
87
+ ].includes(response.status)) {
88
+ await response.body?.cancel();
89
+ throw new ProjectConnectorClientError("unexpected_redirect", response.status);
90
+ }
91
+ return response;
92
+ }
93
+ async function fetchProjectConnectorProviderConfigs(config) {
94
+ const signal = AbortSignal.timeout(3e4);
95
+ let response;
96
+ try {
97
+ response = await fetchProjectConnectorWithoutRedirects(`${config.baseUrl}/saas/oauth/provider-configs`, {
98
+ method: "GET",
99
+ headers: { authorization: `Bearer ${config.apiKey}` },
100
+ signal
101
+ });
102
+ } catch (cause) {
103
+ if (signal.aborted) throw new ProjectConnectorClientError("client_timeout", 0);
104
+ if (cause instanceof TypeError) throw new ProjectConnectorClientError("client_network_error", 0);
105
+ throw cause;
106
+ }
107
+ let payload;
108
+ try {
109
+ payload = await response.json();
110
+ } catch (cause) {
111
+ if (signal.aborted) throw new ProjectConnectorClientError("client_timeout", 0);
112
+ if (cause instanceof TypeError) throw new ProjectConnectorClientError("client_network_error", 0);
113
+ if (!(cause instanceof SyntaxError)) throw cause;
114
+ payload = null;
115
+ }
116
+ const failure = z.object({ errorCode: z.string().min(1) }).safeParse(payload);
117
+ if (!response.ok || failure.success) throw new ProjectConnectorClientError(failure.success ? failure.data.errorCode : response.status === 429 ? "rate_limited" : "provider_error", response.status);
118
+ return parseProjectConnectorResponse(projectConnectorDiscoveryEnvelopeSchema, payload).data;
119
+ }
120
+ /** Project Connector adapter with retries disabled and project keys confined to server requests. */
121
+ function createProjectConnectorClient(config, createSdk = createOomolProjectConnectorSdk) {
122
+ const apiKey = parseProjectConnectorApiKey(config.apiKey);
123
+ const baseUrl = parseProjectConnectorApiBaseUrl(config.baseUrl);
124
+ const client = createSdk({
125
+ apiKey,
126
+ baseUrl,
127
+ maxRetries: 0
128
+ });
129
+ const catalog = config.catalogApiKey === null ? null : new Connector({
130
+ apiKey: parseProjectConnectorApiKey(config.catalogApiKey),
131
+ baseUrl,
132
+ maxRetries: 0,
133
+ fetch: fetchProjectConnectorWithoutRedirects
134
+ }).catalog;
135
+ return {
136
+ async listProviderConfigs() {
137
+ const discovery = await fetchProjectConnectorProviderConfigs({
138
+ apiKey,
139
+ baseUrl
140
+ });
141
+ return {
142
+ projectId: discovery.projectId,
143
+ providerConfigs: discovery.providerConfigs.map((config) => ({
144
+ id: config.id,
145
+ service: config.service,
146
+ displayName: config.displayName,
147
+ callbackUrl: config.callbackUrl,
148
+ effectiveScopes: config.effectiveScopes,
149
+ proxyAvailable: config.proxyAvailable
150
+ }))
151
+ };
152
+ },
153
+ async listProviderActions(providerConfigId) {
154
+ const discovery = await fetchProjectConnectorProviderConfigs({
155
+ apiKey,
156
+ baseUrl
157
+ });
158
+ const config = discovery.providerConfigs.find((config) => config.id === providerConfigId);
159
+ if (!config) return null;
160
+ const actions = [];
161
+ if (config.actionIds.length > 0) {
162
+ if (!catalog) throw new ProjectConnectorClientError("catalog_not_configured", 503);
163
+ const serviceActions = parseProjectConnectorResponse(z.array(projectConnectorCatalogActionSchema).refine((actions) => new Set(actions.map((action) => action.id)).size === actions.length, "Catalog action IDs must be unique"), await callProjectConnector(() => catalog.actions(config.service, projectConnectorCallOptions)));
164
+ const actionsById = new Map(serviceActions.map((action) => [action.id, action]));
165
+ for (const actionId of new Set(config.actionIds)) {
166
+ const action = actionsById.get(actionId);
167
+ if (!action) throw new ProjectConnectorClientError("action_not_found", 502);
168
+ if (action.service !== config.service) throw new ProjectConnectorClientError("action_identity_mismatch", 502);
169
+ actions.push(action);
170
+ }
171
+ }
172
+ return {
173
+ projectId: discovery.projectId,
174
+ providerConfigId: config.id,
175
+ actions
176
+ };
177
+ },
178
+ async check() {
179
+ try {
180
+ await client.getConnectionRequest(`fragno-check-${crypto.randomUUID()}`, projectConnectorCallOptions);
181
+ } catch (error) {
182
+ const knownFailure = projectConnectorClientErrorFromKnownFailure(error);
183
+ if (knownFailure?.status === 404 && knownFailure.code === "connection_request_not_found") return { authenticated: true };
184
+ if (knownFailure) throw knownFailure;
185
+ throw error;
186
+ }
187
+ throw new ProjectConnectorClientError("unexpected_health_response", 502);
188
+ },
189
+ async connect(externalUserId, input) {
190
+ const request = await callProjectConnector(() => client.connect.oauth(externalUserId, {
191
+ ..."providerConfigId" in input ? { providerConfigId: input.providerConfigId } : { service: input.service },
192
+ connectionName: input.connectionName,
193
+ returnUri: input.returnUri
194
+ }, projectConnectorCallOptions));
195
+ return parseProjectConnectorResponse(projectConnectorConnectionRequestSchema, request);
196
+ },
197
+ async getConnectionRequest(requestId) {
198
+ const request = await callProjectConnector(() => client.getConnectionRequest(requestId, projectConnectorCallOptions));
199
+ return parseProjectConnectorResponse(projectConnectorConnectionRequestSchema, request);
200
+ },
201
+ async getProfile(accountId) {
202
+ return parseProjectConnectorResponse(projectConnectorProfileSchema, await callProjectConnector(() => client.getUserProfile(accountId, projectConnectorCallOptions)));
203
+ },
204
+ async execute(account, actionId, input) {
205
+ const result = await callProjectConnector(() => client.executeRaw(account.externalUserId, actionId, input, {
206
+ providerConfigId: account.providerConfigId,
207
+ connectedAccountId: account.id,
208
+ retries: 0
209
+ }));
210
+ return parseProjectConnectorResponse(projectConnectorExecutionSchema, {
211
+ executionId: result.executionId,
212
+ actionId: result.actionId,
213
+ output: result.data
214
+ });
215
+ }
216
+ };
217
+ }
218
+ /** Pins the SDK response to the saved project, provider, user, and request identity. */
219
+ function confirmProjectConnectorRequest(expected, actual) {
220
+ if (actual.id !== expected.id || actual.projectId !== expected.projectId || actual.providerConfigId !== expected.providerConfigId || actual.externalUserId !== expected.externalUserId || actual.service !== expected.service || actual.connectionName !== expected.connectionName) throw new ProjectConnectorClientError("connection_identity_mismatch", 502);
221
+ if (actual.status === "initiated" || actual.status === "expired") return { status: actual.status };
222
+ if (actual.status === "connected") return {
223
+ status: "connected",
224
+ connectedAccountId: actual.connectedAccountId
225
+ };
226
+ return {
227
+ status: "failed",
228
+ errorCode: actual.errorCode,
229
+ errorMessage: actual.errorMessage
230
+ };
231
+ }
232
+ //#endregion
233
+ export { ProjectConnectorClientError, confirmProjectConnectorRequest, createProjectConnectorClient };
234
+
235
+ //# sourceMappingURL=project-connector-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-connector-client.js","names":[],"sources":["../../src/project-connector-client.ts"],"sourcesContent":["import { z } from \"zod\";\n\nimport {\n Connector,\n ConnectorError,\n ProjectConnector,\n type ProjectApi,\n type ProjectCallOptions,\n type ProjectConnectorConfig,\n} from \"@oomol-lab/connector\";\n\nimport {\n projectConnectorActionSchema,\n projectConnectorConnectionStateSchema,\n type projectConnectorConnectInputSchema,\n projectConnectorExecutionSchema,\n projectConnectorHttpUrlSchema,\n projectConnectorProfileSchema,\n projectConnectorProviderConfigsSchema,\n type ProjectConnectorConnectionState,\n} from \"./project-connector-contracts\";\n\nconst projectConnectorConnectionRequestSchema = z\n .object({\n id: z.string().min(1),\n projectId: z.string().min(1),\n providerConfigId: z.string().min(1),\n externalUserId: z.string().min(1),\n service: z.string().min(1),\n connectionName: z.string().nullable(),\n authorizationUrl: projectConnectorHttpUrlSchema,\n expiresAt: z.string(),\n })\n .and(projectConnectorConnectionStateSchema);\n\nconst projectConnectorCallOptions = { retries: 0 } satisfies ProjectCallOptions;\nconst projectConnectorDiscoveryEnvelopeSchema = z.object({\n success: z.literal(true),\n data: projectConnectorProviderConfigsSchema.safeExtend({\n providerConfigs: z.array(\n projectConnectorProviderConfigsSchema.shape.providerConfigs.element.extend({\n actionIds: z.array(z.string().min(1)),\n }),\n ),\n }),\n});\n\nconst projectConnectorCatalogActionSchema = projectConnectorActionSchema.extend({\n description: z\n .string()\n .nullish()\n .transform((description) => description ?? null),\n});\n\ntype ProjectConnectorSdk = Pick<\n ProjectApi,\n \"getConnectionRequest\" | \"getUserProfile\" | \"executeRaw\"\n> & {\n readonly connect: Pick<ProjectApi[\"connect\"], \"oauth\">;\n};\n\ntype CreateProjectConnectorSdk = (config: ProjectConnectorConfig) => ProjectConnectorSdk;\n\nfunction createOomolProjectConnectorSdk(config: ProjectConnectorConfig): ProjectConnectorSdk {\n return new ProjectConnector({\n ...config,\n // The wrapper also avoids the SDK calling native Workers fetch with a transport receiver.\n fetch: fetchProjectConnectorWithoutRedirects,\n });\n}\n\n/** A safe SDK failure exposes its code, never its raw response data or project API key. */\nexport class ProjectConnectorClientError extends Error {\n constructor(\n readonly code: string,\n readonly status: number,\n ) {\n super(`Project Connector request failed: ${code} (HTTP ${status})`);\n this.name = \"ProjectConnectorClientError\";\n }\n}\n\n/** Server-only gateway credentials; null catalogApiKey disables action discovery, not account operations. */\nexport type ProjectConnectorClientConfig = {\n baseUrl: string;\n apiKey: string;\n catalogApiKey: string | null;\n};\n\nfunction parseProjectConnectorApiBaseUrl(value: string): string {\n const baseUrl = new URL(projectConnectorHttpUrlSchema.parse(value));\n const pathname = baseUrl.pathname.replace(/\\/+$/, \"\");\n if (baseUrl.search || baseUrl.hash || pathname !== \"/v1\") {\n throw new Error(\"Project Connector baseUrl must be an origin followed by /v1\");\n }\n baseUrl.pathname = pathname;\n return baseUrl.toString().replace(/\\/$/, \"\");\n}\n\nfunction parseProjectConnectorApiKey(value: string): string {\n return z\n .string()\n .min(1)\n .regex(/^[^\\s]+$/)\n .parse(value);\n}\n\nfunction projectConnectorClientErrorFromKnownFailure(\n error: unknown,\n): ProjectConnectorClientError | null {\n if (error instanceof ProjectConnectorClientError) {\n return error;\n }\n if (error instanceof ConnectorError) {\n // The SDK wraps transport rejections as network errors; retain our safe redirect diagnosis.\n if (error.cause instanceof ProjectConnectorClientError) {\n return error.cause;\n }\n // Callers only see the code; the gateway's message (e.g. which input field it rejected) stays in\n // server logs. Gateway messages never contain the project API key.\n console.warn(\"Project Connector gateway request failed\", {\n code: error.code,\n status: error.status,\n message: error.message,\n requestId: error.requestId,\n });\n return new ProjectConnectorClientError(error.code, error.status);\n }\n return null;\n}\n\nasync function callProjectConnector<T>(operation: () => Promise<T>): Promise<T> {\n try {\n return await operation();\n } catch (error) {\n const knownFailure = projectConnectorClientErrorFromKnownFailure(error);\n if (knownFailure) {\n throw knownFailure;\n }\n throw error;\n }\n}\n\nfunction parseProjectConnectorResponse<T>(schema: z.ZodType<T>, value: unknown): T {\n const parsed = schema.safeParse(value);\n if (!parsed.success) {\n throw new ProjectConnectorClientError(\"invalid_response\", 502);\n }\n return parsed.data;\n}\n\nasync function fetchProjectConnectorWithoutRedirects(\n input: RequestInfo | URL,\n init: RequestInit | undefined,\n): Promise<Response> {\n // Workers rejects redirect: \"error\" before sending the request. Manual mode keeps credentials\n // on the original host; reject redirects before interpreting the response body.\n const response = await globalThis.fetch(input, { ...init, redirect: \"manual\" });\n if ([301, 302, 303, 307, 308].includes(response.status)) {\n await response.body?.cancel();\n throw new ProjectConnectorClientError(\"unexpected_redirect\", response.status);\n }\n return response;\n}\n\nasync function fetchProjectConnectorProviderConfigs(\n config: Pick<ProjectConnectorClientConfig, \"baseUrl\" | \"apiKey\">,\n) {\n // The SDK has no discovery method; redirects must not forward the project key elsewhere.\n const signal = AbortSignal.timeout(30_000);\n let response: Response;\n try {\n response = await fetchProjectConnectorWithoutRedirects(\n `${config.baseUrl}/saas/oauth/provider-configs`,\n {\n method: \"GET\",\n headers: { authorization: `Bearer ${config.apiKey}` },\n signal,\n },\n );\n } catch (cause) {\n if (signal.aborted) {\n throw new ProjectConnectorClientError(\"client_timeout\", 0);\n }\n if (cause instanceof TypeError) {\n throw new ProjectConnectorClientError(\"client_network_error\", 0);\n }\n throw cause;\n }\n let payload: unknown;\n try {\n payload = await response.json();\n } catch (cause) {\n if (signal.aborted) {\n throw new ProjectConnectorClientError(\"client_timeout\", 0);\n }\n if (cause instanceof TypeError) {\n throw new ProjectConnectorClientError(\"client_network_error\", 0);\n }\n if (!(cause instanceof SyntaxError)) {\n throw cause;\n }\n payload = null;\n }\n const failure = z.object({ errorCode: z.string().min(1) }).safeParse(payload);\n if (!response.ok || failure.success) {\n throw new ProjectConnectorClientError(\n failure.success\n ? failure.data.errorCode\n : response.status === 429\n ? \"rate_limited\"\n : \"provider_error\",\n response.status,\n );\n }\n return parseProjectConnectorResponse(projectConnectorDiscoveryEnvelopeSchema, payload).data;\n}\n\n/** Project Connector adapter with retries disabled and project keys confined to server requests. */\nexport function createProjectConnectorClient(\n config: ProjectConnectorClientConfig,\n createSdk: CreateProjectConnectorSdk = createOomolProjectConnectorSdk,\n) {\n const apiKey = parseProjectConnectorApiKey(config.apiKey);\n const baseUrl = parseProjectConnectorApiBaseUrl(config.baseUrl);\n const client = createSdk({ apiKey, baseUrl, maxRetries: 0 });\n // Project credentials and catalog credentials have different authority; never substitute one for the other.\n const catalog =\n config.catalogApiKey === null\n ? null\n : new Connector({\n apiKey: parseProjectConnectorApiKey(config.catalogApiKey),\n baseUrl,\n maxRetries: 0,\n fetch: fetchProjectConnectorWithoutRedirects,\n }).catalog;\n\n return {\n async listProviderConfigs() {\n const discovery = await fetchProjectConnectorProviderConfigs({ apiKey, baseUrl });\n return {\n projectId: discovery.projectId,\n providerConfigs: discovery.providerConfigs.map((config) => ({\n id: config.id,\n service: config.service,\n displayName: config.displayName,\n callbackUrl: config.callbackUrl,\n effectiveScopes: config.effectiveScopes,\n proxyAvailable: config.proxyAvailable,\n })),\n };\n },\n async listProviderActions(providerConfigId: string) {\n const discovery = await fetchProjectConnectorProviderConfigs({ apiKey, baseUrl });\n const config = discovery.providerConfigs.find((config) => config.id === providerConfigId);\n if (!config) {\n return null;\n }\n const actions: z.output<typeof projectConnectorActionSchema>[] = [];\n if (config.actionIds.length > 0) {\n if (!catalog) {\n throw new ProjectConnectorClientError(\"catalog_not_configured\", 503);\n }\n const serviceActions = parseProjectConnectorResponse(\n z\n .array(projectConnectorCatalogActionSchema)\n .refine(\n (actions) => new Set(actions.map((action) => action.id)).size === actions.length,\n \"Catalog action IDs must be unique\",\n ),\n await callProjectConnector(() =>\n catalog.actions(config.service, projectConnectorCallOptions),\n ),\n );\n const actionsById = new Map(serviceActions.map((action) => [action.id, action]));\n // Fetching the service catalog never expands this configuration's allowlist.\n for (const actionId of new Set(config.actionIds)) {\n const action = actionsById.get(actionId);\n if (!action) {\n throw new ProjectConnectorClientError(\"action_not_found\", 502);\n }\n if (action.service !== config.service) {\n throw new ProjectConnectorClientError(\"action_identity_mismatch\", 502);\n }\n actions.push(action);\n }\n }\n return {\n projectId: discovery.projectId,\n providerConfigId: config.id,\n actions,\n };\n },\n async check() {\n // The project API has no health endpoint. An authenticated lookup of a fresh,\n // nonexistent request must return connection_request_not_found, not Unauthorized.\n try {\n await client.getConnectionRequest(\n `fragno-check-${crypto.randomUUID()}`,\n projectConnectorCallOptions,\n );\n } catch (error) {\n const knownFailure = projectConnectorClientErrorFromKnownFailure(error);\n if (knownFailure?.status === 404 && knownFailure.code === \"connection_request_not_found\") {\n return { authenticated: true as const };\n }\n if (knownFailure) {\n throw knownFailure;\n }\n throw error;\n }\n throw new ProjectConnectorClientError(\"unexpected_health_response\", 502);\n },\n async connect(\n externalUserId: string,\n input: z.infer<typeof projectConnectorConnectInputSchema>,\n ) {\n const request = await callProjectConnector(() =>\n client.connect.oauth(\n externalUserId,\n {\n ...(\"providerConfigId\" in input\n ? { providerConfigId: input.providerConfigId }\n : { service: input.service }),\n connectionName: input.connectionName,\n returnUri: input.returnUri,\n },\n projectConnectorCallOptions,\n ),\n );\n return parseProjectConnectorResponse(projectConnectorConnectionRequestSchema, request);\n },\n async getConnectionRequest(requestId: string) {\n const request = await callProjectConnector(() =>\n client.getConnectionRequest(requestId, projectConnectorCallOptions),\n );\n return parseProjectConnectorResponse(projectConnectorConnectionRequestSchema, request);\n },\n async getProfile(accountId: string) {\n const profile = await callProjectConnector(() =>\n client.getUserProfile(accountId, projectConnectorCallOptions),\n );\n return parseProjectConnectorResponse(projectConnectorProfileSchema, profile);\n },\n async execute(\n account: { externalUserId: string; providerConfigId: string; id: string },\n actionId: string,\n input: Record<string, unknown>,\n ) {\n const result = await callProjectConnector(() =>\n client.executeRaw(account.externalUserId, actionId, input, {\n providerConfigId: account.providerConfigId,\n connectedAccountId: account.id,\n retries: 0,\n }),\n );\n return parseProjectConnectorResponse(projectConnectorExecutionSchema, {\n executionId: result.executionId,\n actionId: result.actionId,\n output: result.data,\n });\n },\n };\n}\n\n/** Pins the SDK response to the saved project, provider, user, and request identity. */\nexport function confirmProjectConnectorRequest(\n expected: {\n id: string;\n projectId: string;\n providerConfigId: string;\n externalUserId: string;\n service: string;\n connectionName: string;\n },\n actual: Awaited<\n ReturnType<ReturnType<typeof createProjectConnectorClient>[\"getConnectionRequest\"]>\n >,\n): ProjectConnectorConnectionState {\n if (\n actual.id !== expected.id ||\n actual.projectId !== expected.projectId ||\n actual.providerConfigId !== expected.providerConfigId ||\n actual.externalUserId !== expected.externalUserId ||\n actual.service !== expected.service ||\n actual.connectionName !== expected.connectionName\n ) {\n throw new ProjectConnectorClientError(\"connection_identity_mismatch\", 502);\n }\n if (actual.status === \"initiated\" || actual.status === \"expired\") {\n return { status: actual.status };\n }\n if (actual.status === \"connected\") {\n return { status: \"connected\", connectedAccountId: actual.connectedAccountId };\n }\n return { status: \"failed\", errorCode: actual.errorCode, errorMessage: actual.errorMessage };\n}\n"],"mappings":"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"}
@@ -0,0 +1,179 @@
1
+ import { z } from "zod";
2
+ //#region src/project-connector-contracts.d.ts
3
+ /** Only HTTP(S) URLs can be used as OAuth return destinations. */
4
+ declare const projectConnectorHttpUrlSchema: z.ZodURL;
5
+ /** A connection becomes usable only after the gateway confirms its account ID. */
6
+ declare const projectConnectorConnectionStateSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
7
+ status: z.ZodLiteral<"initiated">;
8
+ }, z.core.$strip>, z.ZodObject<{
9
+ status: z.ZodLiteral<"connected">;
10
+ connectedAccountId: z.ZodString;
11
+ }, z.core.$strip>, z.ZodObject<{
12
+ status: z.ZodLiteral<"failed">;
13
+ errorCode: z.ZodNullable<z.ZodString>;
14
+ errorMessage: z.ZodNullable<z.ZodString>;
15
+ }, z.core.$strip>, z.ZodObject<{
16
+ status: z.ZodLiteral<"expired">;
17
+ }, z.core.$strip>], "status">;
18
+ /** Persisted connection lifecycle; provider credentials never enter this fragment. */
19
+ type ProjectConnectorConnectionState = z.infer<typeof projectConnectorConnectionStateSchema>;
20
+ /** Named selectors preserve exact source identity; user ownership comes only from authentication. */
21
+ declare const projectConnectorNamedConnectionSchema: z.ZodObject<{
22
+ projectId: z.ZodString;
23
+ providerConfigId: z.ZodString;
24
+ connectionName: z.ZodString;
25
+ }, z.core.$strict>;
26
+ /** Select exactly one provider and name every connection explicitly. */
27
+ declare const projectConnectorConnectInputSchema: z.ZodUnion<readonly [z.ZodObject<{
28
+ service: z.ZodString;
29
+ connectionName: z.ZodString;
30
+ returnUri: z.ZodURL;
31
+ }, z.core.$strict>, z.ZodObject<{
32
+ providerConfigId: z.ZodString;
33
+ connectionName: z.ZodString;
34
+ returnUri: z.ZodURL;
35
+ }, z.core.$strict>]>;
36
+ /** Public connection request projection, including its verified lifecycle. */
37
+ declare const projectConnectorConnectionSchema: z.ZodObject<{
38
+ id: z.ZodString;
39
+ projectId: z.ZodString;
40
+ providerConfigId: z.ZodString;
41
+ externalUserId: z.ZodString;
42
+ service: z.ZodString;
43
+ connectionName: z.ZodString;
44
+ authorizationUrl: z.ZodURL;
45
+ expiresAt: z.ZodString;
46
+ state: z.ZodDiscriminatedUnion<[z.ZodObject<{
47
+ status: z.ZodLiteral<"initiated">;
48
+ }, z.core.$strip>, z.ZodObject<{
49
+ status: z.ZodLiteral<"connected">;
50
+ connectedAccountId: z.ZodString;
51
+ }, z.core.$strip>, z.ZodObject<{
52
+ status: z.ZodLiteral<"failed">;
53
+ errorCode: z.ZodNullable<z.ZodString>;
54
+ errorMessage: z.ZodNullable<z.ZodString>;
55
+ }, z.core.$strip>, z.ZodObject<{
56
+ status: z.ZodLiteral<"expired">;
57
+ }, z.core.$strip>], "status">;
58
+ }, z.core.$strip>;
59
+ /** Stored account selectors bind actions to a specific product user and provider. */
60
+ declare const projectConnectorAccountSchema: z.ZodObject<{
61
+ id: z.ZodString;
62
+ projectId: z.ZodString;
63
+ providerConfigId: z.ZodString;
64
+ externalUserId: z.ZodString;
65
+ service: z.ZodString;
66
+ connectionName: z.ZodString;
67
+ }, z.core.$strip>;
68
+ /** Missing named requests remain JSON results rather than empty HTTP responses. */
69
+ declare const projectConnectorNamedRequestSchema: z.ZodObject<{
70
+ request: z.ZodNullable<z.ZodObject<{
71
+ id: z.ZodString;
72
+ projectId: z.ZodString;
73
+ providerConfigId: z.ZodString;
74
+ externalUserId: z.ZodString;
75
+ service: z.ZodString;
76
+ connectionName: z.ZodString;
77
+ authorizationUrl: z.ZodURL;
78
+ expiresAt: z.ZodString;
79
+ state: z.ZodDiscriminatedUnion<[z.ZodObject<{
80
+ status: z.ZodLiteral<"initiated">;
81
+ }, z.core.$strip>, z.ZodObject<{
82
+ status: z.ZodLiteral<"connected">;
83
+ connectedAccountId: z.ZodString;
84
+ }, z.core.$strip>, z.ZodObject<{
85
+ status: z.ZodLiteral<"failed">;
86
+ errorCode: z.ZodNullable<z.ZodString>;
87
+ errorMessage: z.ZodNullable<z.ZodString>;
88
+ }, z.core.$strip>, z.ZodObject<{
89
+ status: z.ZodLiteral<"expired">;
90
+ }, z.core.$strip>], "status">;
91
+ }, z.core.$strip>>;
92
+ }, z.core.$strict>;
93
+ /** Missing named accounts remain JSON results rather than empty HTTP responses. */
94
+ declare const projectConnectorNamedAccountSchema: z.ZodObject<{
95
+ account: z.ZodNullable<z.ZodObject<{
96
+ id: z.ZodString;
97
+ projectId: z.ZodString;
98
+ providerConfigId: z.ZodString;
99
+ externalUserId: z.ZodString;
100
+ service: z.ZodString;
101
+ connectionName: z.ZodString;
102
+ }, z.core.$strip>>;
103
+ }, z.core.$strict>;
104
+ /** Account pagination is owned by the fragment rather than the provider gateway. */
105
+ declare const projectConnectorAccountsSchema: z.ZodObject<{
106
+ accounts: z.ZodArray<z.ZodObject<{
107
+ id: z.ZodString;
108
+ projectId: z.ZodString;
109
+ providerConfigId: z.ZodString;
110
+ externalUserId: z.ZodString;
111
+ service: z.ZodString;
112
+ connectionName: z.ZodString;
113
+ }, z.core.$strip>>;
114
+ cursor: z.ZodNullable<z.ZodString>;
115
+ hasNextPage: z.ZodBoolean;
116
+ }, z.core.$strip>;
117
+ /** Project-scoped OAuth provider overview excludes action IDs and credentials. */
118
+ declare const projectConnectorProviderConfigsSchema: z.ZodObject<{
119
+ projectId: z.ZodString;
120
+ providerConfigs: z.ZodArray<z.ZodObject<{
121
+ id: z.ZodString;
122
+ service: z.ZodString;
123
+ displayName: z.ZodString;
124
+ callbackUrl: z.ZodURL;
125
+ effectiveScopes: z.ZodArray<z.ZodString>;
126
+ proxyAvailable: z.ZodBoolean;
127
+ }, z.core.$strip>>;
128
+ }, z.core.$strip>;
129
+ /** Authoritative catalog contracts describe action values, not a provider's execution permissions. */
130
+ declare const projectConnectorActionSchema: z.ZodObject<{
131
+ id: z.ZodString;
132
+ service: z.ZodString;
133
+ name: z.ZodString;
134
+ description: z.ZodNullable<z.ZodString>;
135
+ inputSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
136
+ outputSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
137
+ }, z.core.$strip>;
138
+ /** Only actions allowed by this exact project OAuth configuration are included. */
139
+ declare const projectConnectorProviderActionsSchema: z.ZodObject<{
140
+ projectId: z.ZodString;
141
+ providerConfigId: z.ZodString;
142
+ actions: z.ZodArray<z.ZodObject<{
143
+ id: z.ZodString;
144
+ service: z.ZodString;
145
+ name: z.ZodString;
146
+ description: z.ZodNullable<z.ZodString>;
147
+ inputSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
148
+ outputSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
149
+ }, z.core.$strip>>;
150
+ }, z.core.$strip>;
151
+ /** Project authentication does not imply that an individual provider account is usable. */
152
+ declare const projectConnectorStatusSchema: z.ZodObject<{
153
+ authenticated: z.ZodLiteral<true>;
154
+ }, z.core.$strip>;
155
+ /** Read-only provider identity associated with one verified account. */
156
+ declare const projectConnectorProfileSchema: z.ZodObject<{
157
+ connectedAccountId: z.ZodString;
158
+ externalUserId: z.ZodString;
159
+ service: z.ZodString;
160
+ profile: z.ZodObject<{
161
+ id: z.ZodString;
162
+ kind: z.ZodString;
163
+ username: z.ZodNullable<z.ZodString>;
164
+ displayName: z.ZodNullable<z.ZodString>;
165
+ avatarUrl: z.ZodNullable<z.ZodString>;
166
+ email: z.ZodNullable<z.ZodString>;
167
+ metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
168
+ }, z.core.$strip>;
169
+ fetchedAt: z.ZodNumber;
170
+ }, z.core.$strip>;
171
+ /** Action output stays opaque; execution IDs support upstream troubleshooting. */
172
+ declare const projectConnectorExecutionSchema: z.ZodObject<{
173
+ executionId: z.ZodString;
174
+ actionId: z.ZodString;
175
+ output: z.ZodUnknown & z.ZodType<{} | null, unknown, z.core.$ZodTypeInternals<{} | null, unknown>>;
176
+ }, z.core.$strip>;
177
+ //#endregion
178
+ export { ProjectConnectorConnectionState, projectConnectorAccountSchema, projectConnectorAccountsSchema, projectConnectorActionSchema, projectConnectorConnectInputSchema, projectConnectorConnectionSchema, projectConnectorConnectionStateSchema, projectConnectorExecutionSchema, projectConnectorHttpUrlSchema, projectConnectorNamedAccountSchema, projectConnectorNamedConnectionSchema, projectConnectorNamedRequestSchema, projectConnectorProfileSchema, projectConnectorProviderActionsSchema, projectConnectorProviderConfigsSchema, projectConnectorStatusSchema };
179
+ //# sourceMappingURL=project-connector-contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-connector-contracts.d.ts","names":[],"sources":["../../src/project-connector-contracts.ts"],"mappings":";;;cAGa,+BAA6B,EAAA;;cAM7B,uCAAqC,EAAA,uBAAA,EAAA;;;;;;;;;;;;;KAYtC,kCAAkC,EAAE,aAAa;;cAYhD,uCAAqC,EAAA;;;;;;cAOrC,oCAAkC,EAAA,mBAAA,EAAA;;;;;;;;;;cAclC,kCAAgC,EAAA;;;;;;;;;;;;;;;;;;;;;;;cAahC,+BAA6B,EAAA;;;;;;;;;cAU7B,oCAAkC,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;cAKlC,oCAAkC,EAAA;;;;;;;;;;;cAKlC,gCAA8B,EAAA;;;;;;;;;;;;;cAO9B,uCAAqC,EAAA;;;;;;;;;;;;cAqBrC,8BAA4B,EAAA;;;;;;;;;cAU5B,uCAAqC,EAAA;;;;;;;;;;;;;cAOrC,8BAA4B,EAAA;;;;cAG5B,+BAA6B,EAAA;;;;;;;;;;;;;;;;cAiB7B,iCAA+B,EAAA"}
@@ -0,0 +1,125 @@
1
+ import { z } from "zod";
2
+ //#region src/project-connector-contracts.ts
3
+ /** Only HTTP(S) URLs can be used as OAuth return destinations. */
4
+ const projectConnectorHttpUrlSchema = z.url().refine((value) => {
5
+ const url = new URL(value);
6
+ return (url.protocol === "https:" || url.protocol === "http:") && !url.username && !url.password;
7
+ }, "Expected an HTTP(S) URL without embedded credentials");
8
+ /** A connection becomes usable only after the gateway confirms its account ID. */
9
+ const projectConnectorConnectionStateSchema = z.discriminatedUnion("status", [
10
+ z.object({ status: z.literal("initiated") }),
11
+ z.object({
12
+ status: z.literal("connected"),
13
+ connectedAccountId: z.string().min(1)
14
+ }),
15
+ z.object({
16
+ status: z.literal("failed"),
17
+ errorCode: z.string().nullable(),
18
+ errorMessage: z.string().nullable()
19
+ }),
20
+ z.object({ status: z.literal("expired") })
21
+ ]);
22
+ /** Mirrors the gateway's alias rule so invalid names fail here with a usable message. */
23
+ const projectConnectorConnectionNameSchema = z.string().regex(/^[a-z0-9][a-z0-9_-]*$/, "Connection names may only contain lowercase letters, digits, underscores, and hyphens, and must start with a letter or digit").describe("Lowercase letters, digits, underscores, and hyphens; starts with a letter or digit.");
24
+ /** Named selectors preserve exact source identity; user ownership comes only from authentication. */
25
+ const projectConnectorNamedConnectionSchema = z.strictObject({
26
+ projectId: z.string().min(1),
27
+ providerConfigId: z.string().min(1),
28
+ connectionName: projectConnectorConnectionNameSchema
29
+ });
30
+ /** Select exactly one provider and name every connection explicitly. */
31
+ const projectConnectorConnectInputSchema = z.union([z.strictObject({
32
+ service: z.string().regex(/^[a-z0-9_-]+$/),
33
+ connectionName: projectConnectorNamedConnectionSchema.shape.connectionName,
34
+ returnUri: projectConnectorHttpUrlSchema
35
+ }), z.strictObject({
36
+ providerConfigId: projectConnectorNamedConnectionSchema.shape.providerConfigId,
37
+ connectionName: projectConnectorNamedConnectionSchema.shape.connectionName,
38
+ returnUri: projectConnectorHttpUrlSchema
39
+ })]);
40
+ /** Public connection request projection, including its verified lifecycle. */
41
+ const projectConnectorConnectionSchema = z.object({
42
+ id: z.string(),
43
+ projectId: z.string(),
44
+ providerConfigId: z.string(),
45
+ externalUserId: z.string(),
46
+ service: z.string(),
47
+ connectionName: projectConnectorNamedConnectionSchema.shape.connectionName,
48
+ authorizationUrl: projectConnectorHttpUrlSchema,
49
+ expiresAt: z.string(),
50
+ state: projectConnectorConnectionStateSchema
51
+ });
52
+ /** Stored account selectors bind actions to a specific product user and provider. */
53
+ const projectConnectorAccountSchema = z.object({
54
+ id: z.string(),
55
+ projectId: z.string(),
56
+ providerConfigId: z.string(),
57
+ externalUserId: z.string(),
58
+ service: z.string(),
59
+ connectionName: projectConnectorNamedConnectionSchema.shape.connectionName
60
+ });
61
+ /** Missing named requests remain JSON results rather than empty HTTP responses. */
62
+ const projectConnectorNamedRequestSchema = z.strictObject({ request: projectConnectorConnectionSchema.nullable() });
63
+ /** Missing named accounts remain JSON results rather than empty HTTP responses. */
64
+ const projectConnectorNamedAccountSchema = z.strictObject({ account: projectConnectorAccountSchema.nullable() });
65
+ /** Account pagination is owned by the fragment rather than the provider gateway. */
66
+ const projectConnectorAccountsSchema = z.object({
67
+ accounts: z.array(projectConnectorAccountSchema),
68
+ cursor: z.string().nullable(),
69
+ hasNextPage: z.boolean()
70
+ });
71
+ /** Project-scoped OAuth provider overview excludes action IDs and credentials. */
72
+ const projectConnectorProviderConfigsSchema = z.object({
73
+ projectId: z.string().min(1),
74
+ providerConfigs: z.array(z.object({
75
+ id: z.string().min(1),
76
+ service: z.string().min(1),
77
+ displayName: z.string(),
78
+ callbackUrl: projectConnectorHttpUrlSchema,
79
+ effectiveScopes: z.array(z.string().min(1)),
80
+ proxyAvailable: z.boolean()
81
+ }))
82
+ }).refine(({ providerConfigs }) => new Set(providerConfigs.map((config) => config.id)).size === providerConfigs.length, "Provider configuration IDs must be unique");
83
+ /** Authoritative catalog contracts describe action values, not a provider's execution permissions. */
84
+ const projectConnectorActionSchema = z.object({
85
+ id: z.string().min(1),
86
+ service: z.string().min(1),
87
+ name: z.string(),
88
+ description: z.string().nullable(),
89
+ inputSchema: z.record(z.string(), z.unknown()),
90
+ outputSchema: z.record(z.string(), z.unknown())
91
+ });
92
+ /** Only actions allowed by this exact project OAuth configuration are included. */
93
+ const projectConnectorProviderActionsSchema = z.object({
94
+ projectId: projectConnectorProviderConfigsSchema.shape.projectId,
95
+ providerConfigId: projectConnectorProviderConfigsSchema.shape.providerConfigs.element.shape.id,
96
+ actions: z.array(projectConnectorActionSchema)
97
+ });
98
+ /** Project authentication does not imply that an individual provider account is usable. */
99
+ const projectConnectorStatusSchema = z.object({ authenticated: z.literal(true) });
100
+ /** Read-only provider identity associated with one verified account. */
101
+ const projectConnectorProfileSchema = z.object({
102
+ connectedAccountId: z.string(),
103
+ externalUserId: z.string(),
104
+ service: z.string(),
105
+ profile: z.object({
106
+ id: z.string(),
107
+ kind: z.string(),
108
+ username: z.string().nullable(),
109
+ displayName: z.string().nullable(),
110
+ avatarUrl: z.string().nullable(),
111
+ email: z.string().nullable(),
112
+ metadata: z.record(z.string(), z.unknown())
113
+ }),
114
+ fetchedAt: z.number()
115
+ });
116
+ /** Action output stays opaque; execution IDs support upstream troubleshooting. */
117
+ const projectConnectorExecutionSchema = z.object({
118
+ executionId: z.string(),
119
+ actionId: z.string(),
120
+ output: z.unknown().refine((value) => value !== void 0, "Expected action output")
121
+ });
122
+ //#endregion
123
+ export { projectConnectorAccountSchema, projectConnectorAccountsSchema, projectConnectorActionSchema, projectConnectorConnectInputSchema, projectConnectorConnectionSchema, projectConnectorConnectionStateSchema, projectConnectorExecutionSchema, projectConnectorHttpUrlSchema, projectConnectorNamedAccountSchema, projectConnectorNamedConnectionSchema, projectConnectorNamedRequestSchema, projectConnectorProfileSchema, projectConnectorProviderActionsSchema, projectConnectorProviderConfigsSchema, projectConnectorStatusSchema };
124
+
125
+ //# sourceMappingURL=project-connector-contracts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-connector-contracts.js","names":[],"sources":["../../src/project-connector-contracts.ts"],"sourcesContent":["import { z } from \"zod\";\n\n/** Only HTTP(S) URLs can be used as OAuth return destinations. */\nexport const projectConnectorHttpUrlSchema = z.url().refine((value) => {\n const url = new URL(value);\n return (url.protocol === \"https:\" || url.protocol === \"http:\") && !url.username && !url.password;\n}, \"Expected an HTTP(S) URL without embedded credentials\");\n\n/** A connection becomes usable only after the gateway confirms its account ID. */\nexport const projectConnectorConnectionStateSchema = z.discriminatedUnion(\"status\", [\n z.object({ status: z.literal(\"initiated\") }),\n z.object({ status: z.literal(\"connected\"), connectedAccountId: z.string().min(1) }),\n z.object({\n status: z.literal(\"failed\"),\n errorCode: z.string().nullable(),\n errorMessage: z.string().nullable(),\n }),\n z.object({ status: z.literal(\"expired\") }),\n]);\n\n/** Persisted connection lifecycle; provider credentials never enter this fragment. */\nexport type ProjectConnectorConnectionState = z.infer<typeof projectConnectorConnectionStateSchema>;\n\n/** Mirrors the gateway's alias rule so invalid names fail here with a usable message. */\nconst projectConnectorConnectionNameSchema = z\n .string()\n .regex(\n /^[a-z0-9][a-z0-9_-]*$/,\n \"Connection names may only contain lowercase letters, digits, underscores, and hyphens, and must start with a letter or digit\",\n )\n .describe(\"Lowercase letters, digits, underscores, and hyphens; starts with a letter or digit.\");\n\n/** Named selectors preserve exact source identity; user ownership comes only from authentication. */\nexport const projectConnectorNamedConnectionSchema = z.strictObject({\n projectId: z.string().min(1),\n providerConfigId: z.string().min(1),\n connectionName: projectConnectorConnectionNameSchema,\n});\n\n/** Select exactly one provider and name every connection explicitly. */\nexport const projectConnectorConnectInputSchema = z.union([\n z.strictObject({\n service: z.string().regex(/^[a-z0-9_-]+$/),\n connectionName: projectConnectorNamedConnectionSchema.shape.connectionName,\n returnUri: projectConnectorHttpUrlSchema,\n }),\n z.strictObject({\n providerConfigId: projectConnectorNamedConnectionSchema.shape.providerConfigId,\n connectionName: projectConnectorNamedConnectionSchema.shape.connectionName,\n returnUri: projectConnectorHttpUrlSchema,\n }),\n]);\n\n/** Public connection request projection, including its verified lifecycle. */\nexport const projectConnectorConnectionSchema = z.object({\n id: z.string(),\n projectId: z.string(),\n providerConfigId: z.string(),\n externalUserId: z.string(),\n service: z.string(),\n connectionName: projectConnectorNamedConnectionSchema.shape.connectionName,\n authorizationUrl: projectConnectorHttpUrlSchema,\n expiresAt: z.string(),\n state: projectConnectorConnectionStateSchema,\n});\n\n/** Stored account selectors bind actions to a specific product user and provider. */\nexport const projectConnectorAccountSchema = z.object({\n id: z.string(),\n projectId: z.string(),\n providerConfigId: z.string(),\n externalUserId: z.string(),\n service: z.string(),\n connectionName: projectConnectorNamedConnectionSchema.shape.connectionName,\n});\n\n/** Missing named requests remain JSON results rather than empty HTTP responses. */\nexport const projectConnectorNamedRequestSchema = z.strictObject({\n request: projectConnectorConnectionSchema.nullable(),\n});\n\n/** Missing named accounts remain JSON results rather than empty HTTP responses. */\nexport const projectConnectorNamedAccountSchema = z.strictObject({\n account: projectConnectorAccountSchema.nullable(),\n});\n\n/** Account pagination is owned by the fragment rather than the provider gateway. */\nexport const projectConnectorAccountsSchema = z.object({\n accounts: z.array(projectConnectorAccountSchema),\n cursor: z.string().nullable(),\n hasNextPage: z.boolean(),\n});\n\n/** Project-scoped OAuth provider overview excludes action IDs and credentials. */\nexport const projectConnectorProviderConfigsSchema = z\n .object({\n projectId: z.string().min(1),\n providerConfigs: z.array(\n z.object({\n id: z.string().min(1),\n service: z.string().min(1),\n displayName: z.string(),\n callbackUrl: projectConnectorHttpUrlSchema,\n effectiveScopes: z.array(z.string().min(1)),\n proxyAvailable: z.boolean(),\n }),\n ),\n })\n .refine(\n ({ providerConfigs }) =>\n new Set(providerConfigs.map((config) => config.id)).size === providerConfigs.length,\n \"Provider configuration IDs must be unique\",\n );\n\n/** Authoritative catalog contracts describe action values, not a provider's execution permissions. */\nexport const projectConnectorActionSchema = z.object({\n id: z.string().min(1),\n service: z.string().min(1),\n name: z.string(),\n description: z.string().nullable(),\n inputSchema: z.record(z.string(), z.unknown()),\n outputSchema: z.record(z.string(), z.unknown()),\n});\n\n/** Only actions allowed by this exact project OAuth configuration are included. */\nexport const projectConnectorProviderActionsSchema = z.object({\n projectId: projectConnectorProviderConfigsSchema.shape.projectId,\n providerConfigId: projectConnectorProviderConfigsSchema.shape.providerConfigs.element.shape.id,\n actions: z.array(projectConnectorActionSchema),\n});\n\n/** Project authentication does not imply that an individual provider account is usable. */\nexport const projectConnectorStatusSchema = z.object({ authenticated: z.literal(true) });\n\n/** Read-only provider identity associated with one verified account. */\nexport const projectConnectorProfileSchema = z.object({\n connectedAccountId: z.string(),\n externalUserId: z.string(),\n service: z.string(),\n profile: z.object({\n id: z.string(),\n kind: z.string(),\n username: z.string().nullable(),\n displayName: z.string().nullable(),\n avatarUrl: z.string().nullable(),\n email: z.string().nullable(),\n metadata: z.record(z.string(), z.unknown()),\n }),\n fetchedAt: z.number(),\n});\n\n/** Action output stays opaque; execution IDs support upstream troubleshooting. */\nexport const projectConnectorExecutionSchema = z.object({\n executionId: z.string(),\n actionId: z.string(),\n output: z.unknown().refine((value) => value !== undefined, \"Expected action output\"),\n});\n"],"mappings":"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"}