@fragno-dev/api-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 (79) hide show
  1. package/LICENSE.md +16 -0
  2. package/README.md +249 -2
  3. package/dist/browser/client/client-3ZV9sw3i.js +2580 -0
  4. package/dist/browser/client/client-3ZV9sw3i.js.map +1 -0
  5. package/dist/browser/client/client-DPjmoaJQ.d.ts +711 -0
  6. package/dist/browser/client/client-DPjmoaJQ.d.ts.map +1 -0
  7. package/dist/browser/client/client.d.ts +1645 -0
  8. package/dist/browser/client/client.d.ts.map +1 -0
  9. package/dist/browser/client/client.js +2 -0
  10. package/dist/browser/client/react.d.ts +1665 -0
  11. package/dist/browser/client/react.d.ts.map +1 -0
  12. package/dist/browser/client/react.js +194 -0
  13. package/dist/browser/client/react.js.map +1 -0
  14. package/dist/browser/client/solid.d.ts +1668 -0
  15. package/dist/browser/client/solid.d.ts.map +1 -0
  16. package/dist/browser/client/solid.js +129 -0
  17. package/dist/browser/client/solid.js.map +1 -0
  18. package/dist/browser/client/svelte.d.ts +1668 -0
  19. package/dist/browser/client/svelte.d.ts.map +1 -0
  20. package/dist/browser/client/svelte.js +131 -0
  21. package/dist/browser/client/svelte.js.map +1 -0
  22. package/dist/browser/client/vanilla.d.ts +1695 -0
  23. package/dist/browser/client/vanilla.d.ts.map +1 -0
  24. package/dist/browser/client/vanilla.js +159 -0
  25. package/dist/browser/client/vanilla.js.map +1 -0
  26. package/dist/browser/client/vue.d.ts +1668 -0
  27. package/dist/browser/client/vue.d.ts.map +1 -0
  28. package/dist/browser/client/vue.js +127 -0
  29. package/dist/browser/client/vue.js.map +1 -0
  30. package/dist/browser/client-D4NnY-zV.d.ts +713 -0
  31. package/dist/browser/client-D4NnY-zV.d.ts.map +1 -0
  32. package/dist/browser/client-DQE0c7GI.d.ts +711 -0
  33. package/dist/browser/client-DQE0c7GI.d.ts.map +1 -0
  34. package/dist/browser/index.d.ts +3130 -0
  35. package/dist/browser/index.d.ts.map +1 -0
  36. package/dist/browser/index.js +2 -0
  37. package/dist/browser/src-BrYPVbAN.js +2404 -0
  38. package/dist/browser/src-BrYPVbAN.js.map +1 -0
  39. package/dist/browser/src-t-4wp9-f.js +2400 -0
  40. package/dist/browser/src-t-4wp9-f.js.map +1 -0
  41. package/dist/node/api-types.d.ts +731 -0
  42. package/dist/node/api-types.d.ts.map +1 -0
  43. package/dist/node/api-types.js +281 -0
  44. package/dist/node/api-types.js.map +1 -0
  45. package/dist/node/crypto.d.ts +6 -0
  46. package/dist/node/crypto.d.ts.map +1 -0
  47. package/dist/node/crypto.js +103 -0
  48. package/dist/node/crypto.js.map +1 -0
  49. package/dist/node/definition.d.ts +638 -0
  50. package/dist/node/definition.d.ts.map +1 -0
  51. package/dist/node/definition.js +315 -0
  52. package/dist/node/definition.js.map +1 -0
  53. package/dist/node/oauth.js +124 -0
  54. package/dist/node/oauth.js.map +1 -0
  55. package/dist/node/routes.d.ts +1585 -0
  56. package/dist/node/routes.d.ts.map +1 -0
  57. package/dist/node/routes.js +1100 -0
  58. package/dist/node/routes.js.map +1 -0
  59. package/dist/node/schema.d.ts +99 -0
  60. package/dist/node/schema.d.ts.map +1 -0
  61. package/dist/node/schema.js +16 -0
  62. package/dist/node/schema.js.map +1 -0
  63. package/dist/node/server.d.ts +1585 -0
  64. package/dist/node/server.d.ts.map +1 -0
  65. package/dist/node/server.js +12 -0
  66. package/dist/node/server.js.map +1 -0
  67. package/dist/node/services.d.ts +10 -0
  68. package/dist/node/services.d.ts.map +1 -0
  69. package/dist/node/services.js +304 -0
  70. package/dist/node/services.js.map +1 -0
  71. package/dist/node/webhooks/auth.d.ts +133 -0
  72. package/dist/node/webhooks/auth.d.ts.map +1 -0
  73. package/dist/node/webhooks/auth.js +268 -0
  74. package/dist/node/webhooks/auth.js.map +1 -0
  75. package/dist/node/webhooks/verification.d.ts +102 -0
  76. package/dist/node/webhooks/verification.d.ts.map +1 -0
  77. package/dist/node/webhooks/verification.js +119 -0
  78. package/dist/node/webhooks/verification.js.map +1 -0
  79. package/package.json +136 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","names":[],"sources":["../../src/routes.ts"],"sourcesContent":["import { decodeCursor, type Cursor } from \"@fragno-dev/db/cursor\";\nimport { z } from \"zod\";\n\nimport { defineRoutes } from \"@fragno-dev/core\";\nimport { isUniqueConstraintError, type TypedUnitOfWork } from \"@fragno-dev/db\";\n\nimport {\n API_OAUTH_REDIRECT_URI_QUERY_PARAMETER,\n apiAuthStatusSchema,\n apiConnectionOutputSchema,\n apiConnectionSlugSchema,\n apiConnectionsPageSchema,\n apiOAuthPendingSchema,\n apiRequestInputSchema,\n apiRequestOutputSchema,\n createApiConnectionInputSchema,\n createWebhookEndpointInputSchema,\n oauthRedirectUriSchema,\n oauthStartInputSchema,\n tokenAuthInputSchema,\n updateWebhookEndpointInputSchema,\n webhookEndpointOutputSchema,\n webhookRejectionCodeSchema,\n type WebhookDeliveryIdentity,\n type WebhookEndpoint,\n type WebhookEndpointAuthInput,\n type WebhookRejectionCode,\n} from \"./api-types\";\nimport { sha256Base64Url, utf8Bytes } from \"./crypto\";\nimport {\n apiFragmentDefinition,\n type ApiHooksMap,\n type WebhookEndpointHookSnapshot,\n} from \"./definition\";\nimport { apiSchema } from \"./schema\";\nimport {\n assertAllowedBaseUrl,\n isApiAuthReady,\n pendingOAuthLink,\n projectApiAuthStatus,\n} from \"./services\";\nimport {\n getSensitiveWebhookAuthValues,\n getWebhookAuthSecretRefs,\n verifyWebhookAuth,\n type WebhookAuthConfig,\n} from \"./webhooks/auth\";\nimport {\n createWebhookRequestValues,\n evaluateWebhookVerification,\n type WebhookRequestValues,\n type WebhookVerificationConfig,\n} from \"./webhooks/verification\";\n\nconst CONNECTIONS_PAGE_SIZE = 50;\nconst webhookEndpointsOutputSchema = z.object({ endpoints: z.array(webhookEndpointOutputSchema) });\nconst oauthStartOutputSchema = z.object({ authorizationUrl: z.string(), state: z.string() });\nconst oauthCallbackOutputSchema = z.object({ authenticated: z.boolean(), mode: z.string() });\nconst logApiRouteError = (message: string, err: unknown) => {\n const detail = err instanceof Error ? err.message : String(err);\n console.error(message, detail, err);\n};\n\nfunction publicConnection(connection: {\n id: { toString(): string } | string;\n name?: string | null;\n baseUrl: string;\n authMode: string;\n status: string;\n createdAt?: Date;\n updatedAt?: Date;\n}) {\n return {\n slug: connection.id.toString(),\n name: connection.name ?? null,\n baseUrl: connection.baseUrl,\n authMode: connection.authMode,\n status: connection.status,\n createdAt: connection.createdAt,\n updatedAt: connection.updatedAt,\n };\n}\n\nfunction connectionHookSnapshot(connection: {\n id: { toString(): string } | string;\n name?: string | null;\n baseUrl: string;\n authMode: string;\n status: string;\n}) {\n return {\n slug: connection.id.toString(),\n name: connection.name ?? null,\n baseUrl: connection.baseUrl,\n authMode: connection.authMode,\n status: connection.status,\n };\n}\n\ntype WebhookSecretDraft = { ref: string; payload: string };\n\nfunction webhookSecretId(endpointId: string, ref: string) {\n return `${endpointId}:${ref}`;\n}\n\nfunction webhookEndpointAuthStorage(auth: WebhookEndpointAuthInput): {\n authConfig: WebhookAuthConfig;\n secrets: WebhookSecretDraft[];\n} {\n if (auth.type === \"none\") {\n return { authConfig: { type: \"none\" }, secrets: [] };\n }\n if (auth.type === \"bearer\") {\n return {\n authConfig: { type: \"bearer\", tokenRef: \"token\" },\n secrets: [{ ref: \"token\", payload: auth.token }],\n };\n }\n if (auth.type === \"apiKey\") {\n return {\n authConfig: {\n type: \"apiKey\",\n location: auth.location,\n name: auth.name,\n secretRef: \"secret\",\n },\n secrets: [{ ref: \"secret\", payload: auth.secret }],\n };\n }\n if (auth.type === \"basic\") {\n return {\n authConfig: { type: \"basic\", usernameRef: \"username\", passwordRef: \"password\" },\n secrets: [\n { ref: \"username\", payload: auth.username },\n { ref: \"password\", payload: auth.password },\n ],\n };\n }\n\n return {\n authConfig: {\n type: \"hmac\",\n secretRef: \"secret\",\n algorithm: auth.algorithm,\n signature: auth.signature,\n signedPayload: auth.signedPayload,\n },\n secrets: [{ ref: \"secret\", payload: auth.secret }],\n };\n}\n\nfunction parseWebhookEndpointStatus(status: string): \"draft\" | \"active\" | \"disabled\" {\n if (status === \"draft\" || status === \"active\" || status === \"disabled\") {\n return status;\n }\n throw new Error(`Unexpected webhook endpoint status: ${status}`);\n}\n\nfunction webhookEndpointHookSnapshot(endpoint: {\n name: string;\n status: string;\n authConfig: WebhookAuthConfig;\n verification: WebhookVerificationConfig;\n deliveryIdentity: WebhookDeliveryIdentity;\n}): WebhookEndpointHookSnapshot {\n return {\n name: endpoint.name,\n status: parseWebhookEndpointStatus(endpoint.status),\n authConfig: endpoint.authConfig,\n verification: endpoint.verification,\n deliveryIdentity: endpoint.deliveryIdentity,\n secretRefs: [...getWebhookAuthSecretRefs(endpoint.authConfig)],\n };\n}\n\nfunction recordFromSearchParams(\n query: URLSearchParams,\n sensitiveQueryNames: ReadonlySet<string>,\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [name, value] of query.entries()) {\n result[name] = sensitiveQueryNames.has(name) ? \"[redacted]\" : value;\n }\n return result;\n}\n\nfunction recordFromHeaders(\n headers: Headers,\n sensitiveHeaderNames: ReadonlySet<string>,\n): Record<string, string> {\n const result: Record<string, string> = {};\n for (const [name, value] of headers.entries()) {\n result[name] = sensitiveHeaderNames.has(name.toLowerCase()) ? \"[redacted]\" : value;\n }\n return result;\n}\n\ntype WebhookDeliveryIdentityResult =\n | { ok: true; deliveryId: string }\n | { ok: false; reason: \"missing\" | \"invalid_value\" };\n\ntype WebhookRequestFailure = {\n ok: false;\n code:\n | Exclude<WebhookRejectionCode, \"WEBHOOK_VERIFICATION_NOT_MATCHED\">\n | \"WEBHOOK_ENDPOINT_NOT_FOUND\";\n};\n\ntype WebhookReceiveResult =\n | WebhookRequestFailure\n | { ok: true; type: \"verification\"; body: string }\n | { ok: true; type: \"delivery\" };\n\nfunction extractWebhookDeliveryId(input: {\n identity: WebhookDeliveryIdentity;\n requestValues: WebhookRequestValues;\n}): WebhookDeliveryIdentityResult {\n const value = input.requestValues.read(input.identity);\n if (!value.ok) {\n return {\n ok: false,\n reason: value.reason === \"missing\" ? \"missing\" : \"invalid_value\",\n };\n }\n return normalizeWebhookDeliveryId(value.value);\n}\n\nfunction normalizeWebhookDeliveryId(value: unknown): WebhookDeliveryIdentityResult {\n if (typeof value !== \"string\" && typeof value !== \"number\") {\n return value == null\n ? { ok: false, reason: \"missing\" }\n : { ok: false, reason: \"invalid_value\" };\n }\n const deliveryId = `${value}`.trim();\n if (!deliveryId) {\n return { ok: false, reason: \"missing\" };\n }\n return { ok: true, deliveryId };\n}\n\nasync function webhookHookId(endpointId: string, deliveryId: string) {\n return `webhook_${await sha256Base64Url(`${endpointId}\\0${deliveryId}`)}`;\n}\n\nfunction webhookVerificationResponse(body: string) {\n const bytes = utf8Bytes(body);\n return new Response(bytes, {\n status: 200,\n headers: {\n \"content-type\": \"text/plain; charset=utf-8\",\n \"content-length\": `${bytes.byteLength}`,\n \"x-content-type-options\": \"nosniff\",\n },\n });\n}\n\n/** Configuration writes reset delivery evidence, which then covers only the new configuration. */\nconst noWebhookDeliveryEvidence = {\n lastAcceptedAt: null,\n lastRejectedAt: null,\n lastRejectionCode: null,\n} as const;\n\nfunction publicWebhookEndpoint(endpoint: {\n id: { toString(): string } | string;\n name: string;\n status: string;\n authConfig: WebhookAuthConfig;\n verification: WebhookVerificationConfig;\n deliveryIdentity: WebhookDeliveryIdentity;\n lastAcceptedAt: Date | null;\n lastRejectedAt: Date | null;\n lastRejectionCode: string | null;\n createdAt?: Date;\n updatedAt?: Date;\n}): WebhookEndpoint {\n return {\n id: endpoint.id.toString(),\n name: endpoint.name,\n status: parseWebhookEndpointStatus(endpoint.status),\n authConfig: endpoint.authConfig,\n verification: endpoint.verification,\n deliveryIdentity: endpoint.deliveryIdentity,\n secretRefs: [...getWebhookAuthSecretRefs(endpoint.authConfig)],\n deliveries: {\n lastAcceptedAt: endpoint.lastAcceptedAt?.toISOString() ?? null,\n // The receive routes write both rejection columns together.\n lastRejection:\n endpoint.lastRejectedAt === null\n ? null\n : {\n receivedAt: endpoint.lastRejectedAt.toISOString(),\n code: webhookRejectionCodeSchema.parse(endpoint.lastRejectionCode),\n },\n },\n createdAt: endpoint.createdAt,\n updatedAt: endpoint.updatedAt,\n };\n}\n\n/**\n * Records the outcome of a receive request; unknown endpoints have no row to record on. Writes skip\n * the version check, so concurrent deliveries never conflict and the last one wins.\n */\nfunction recordWebhookRequestOutcome(\n uow: TypedUnitOfWork<typeof apiSchema, [], unknown, ApiHooksMap>,\n endpointId: string,\n rejection: WebhookRejectionCode | \"WEBHOOK_ENDPOINT_NOT_FOUND\" | null,\n) {\n if (rejection === \"WEBHOOK_ENDPOINT_NOT_FOUND\") {\n return;\n }\n uow.update(\"webhookEndpoint\", endpointId, (b) =>\n rejection === null\n ? b.set({ lastAcceptedAt: b.now() })\n : b.set({ lastRejectedAt: b.now(), lastRejectionCode: rejection }),\n );\n}\n\nexport const apiRoutesFactory = defineRoutes(apiFragmentDefinition).create(\n ({ services, defineRoute, config }) => [\n defineRoute({\n method: \"PUT\",\n path: \"/webhooks/endpoints/:endpointId\",\n inputSchema: createWebhookEndpointInputSchema,\n outputSchema: webhookEndpointOutputSchema,\n handler: async function ({ input, pathParams }, { json }) {\n const body = await input.valid();\n const authStorage = webhookEndpointAuthStorage(body.auth);\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema)\n .findFirst(\"webhookEndpoint\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.endpointId)),\n )\n .find(\"webhookSecret\", (b) =>\n b.whereIndex(\"idx_webhook_secret_endpoint_ref\", (eb) =>\n eb(\"endpointId\", \"=\", pathParams.endpointId),\n ),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [existing, existingSecrets] }) => {\n const uow = forSchema(apiSchema);\n const endpoint = {\n id: pathParams.endpointId,\n name: body.name,\n status: body.status,\n authConfig: authStorage.authConfig,\n verification: body.verification,\n deliveryIdentity: body.deliveryIdentity,\n ...noWebhookDeliveryEvidence,\n createdAt: existing?.createdAt,\n };\n if (existing) {\n uow.update(\"webhookEndpoint\", existing.id, (b) =>\n b\n .set({\n name: endpoint.name,\n status: endpoint.status,\n authConfig: endpoint.authConfig,\n verification: endpoint.verification,\n deliveryIdentity: endpoint.deliveryIdentity,\n ...noWebhookDeliveryEvidence,\n updatedAt: b.now(),\n })\n .check(),\n );\n } else {\n uow.create(\"webhookEndpoint\", {\n id: endpoint.id,\n name: endpoint.name,\n status: endpoint.status,\n authConfig: endpoint.authConfig,\n verification: endpoint.verification,\n deliveryIdentity: endpoint.deliveryIdentity,\n });\n }\n\n const nextSecretRefs = new Set(authStorage.secrets.map((secret) => secret.ref));\n const existingSecretsByRef = new Map(\n existingSecrets.map((secret) => [secret.ref, secret] as const),\n );\n for (const secret of existingSecrets) {\n if (!nextSecretRefs.has(secret.ref)) {\n uow.delete(\"webhookSecret\", secret.id);\n }\n }\n for (const secret of authStorage.secrets) {\n const existingSecret = existingSecretsByRef.get(secret.ref);\n if (existingSecret) {\n uow.update(\"webhookSecret\", existingSecret.id, (b) =>\n b.set({ payload: secret.payload, updatedAt: b.now() }).check(),\n );\n } else {\n uow.create(\"webhookSecret\", {\n id: webhookSecretId(pathParams.endpointId, secret.ref),\n endpointId: pathParams.endpointId,\n ref: secret.ref,\n payload: secret.payload,\n });\n }\n }\n\n uow.triggerHook(\n \"onWebhookEndpointChanged\",\n existing\n ? {\n change: \"updated\",\n endpointId: pathParams.endpointId,\n endpoint: webhookEndpointHookSnapshot(endpoint),\n previousStatus: parseWebhookEndpointStatus(existing.status),\n }\n : {\n change: \"created\",\n endpointId: pathParams.endpointId,\n endpoint: webhookEndpointHookSnapshot(endpoint),\n },\n );\n\n return { created: !existing, endpoint };\n })\n .execute();\n\n return json(publicWebhookEndpoint(result.endpoint), result.created ? 201 : 200);\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/webhooks/endpoints\",\n outputSchema: webhookEndpointsOutputSchema,\n handler: async function (_, { json }) {\n const [endpoints] = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema).find(\"webhookEndpoint\", (b) => b.whereIndex(\"primary\")),\n )\n .execute();\n return json({ endpoints: endpoints.map(publicWebhookEndpoint) });\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/webhooks/endpoints/:endpointId\",\n outputSchema: webhookEndpointOutputSchema,\n errorCodes: [\"WEBHOOK_ENDPOINT_NOT_FOUND\"],\n handler: async function ({ pathParams }, { json, error }) {\n const [endpoint] = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema).findFirst(\"webhookEndpoint\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.endpointId)),\n ),\n )\n .execute();\n if (!endpoint) {\n return error(\n { code: \"WEBHOOK_ENDPOINT_NOT_FOUND\", message: \"Webhook endpoint not found\" },\n 404,\n );\n }\n return json(publicWebhookEndpoint(endpoint));\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/webhooks/endpoints/:endpointId/events\",\n errorCodes: [\n \"WEBHOOK_ENDPOINT_NOT_FOUND\",\n \"WEBHOOK_ENDPOINT_DISABLED\",\n \"WEBHOOK_ENDPOINT_DRAFT\",\n \"WEBHOOK_AUTH_FAILED\",\n \"WEBHOOK_VERIFICATION_NOT_MATCHED\",\n \"WEBHOOK_VERIFICATION_RESPONSE_INVALID\",\n ],\n handler: async function ({ pathParams, headers, query, rawBody, request }, { error }) {\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema)\n .findFirst(\"webhookEndpoint\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.endpointId)),\n )\n .find(\"webhookSecret\", (b) =>\n b.whereIndex(\"idx_webhook_secret_endpoint_ref\", (eb) =>\n eb(\"endpointId\", \"=\", pathParams.endpointId),\n ),\n ),\n )\n .transformRetrieve(async ([endpoint, secrets]) => {\n if (!endpoint) {\n return { ok: false as const, code: \"WEBHOOK_ENDPOINT_NOT_FOUND\" as const };\n }\n if (endpoint.status === \"draft\") {\n return { ok: false as const, code: \"WEBHOOK_ENDPOINT_DRAFT\" as const };\n }\n if (endpoint.status !== \"active\") {\n return { ok: false as const, code: \"WEBHOOK_ENDPOINT_DISABLED\" as const };\n }\n if (!request) {\n throw new Error(\"Webhook receive route requires a web-standard Request\");\n }\n\n const secretValues = new Map(secrets.map((secret) => [secret.ref, secret.payload]));\n const auth = await verifyWebhookAuth({\n config: endpoint.authConfig,\n request,\n secrets: { get: async (ref) => secretValues.get(ref) },\n });\n if (!auth.ok) {\n return { ok: false as const, code: \"WEBHOOK_AUTH_FAILED\" as const };\n }\n\n const verification = evaluateWebhookVerification({\n config: endpoint.verification,\n method: \"GET\",\n requestValues: createWebhookRequestValues({ headers, query, rawBody }),\n });\n if (verification.type === \"not_verification\") {\n return { ok: false as const, code: \"WEBHOOK_VERIFICATION_NOT_MATCHED\" as const };\n }\n if (verification.type === \"invalid_response\") {\n return {\n ok: false as const,\n code: \"WEBHOOK_VERIFICATION_RESPONSE_INVALID\" as const,\n };\n }\n return { ok: true as const, body: verification.body };\n })\n .mutate(({ forSchema, retrieveResult }) => {\n recordWebhookRequestOutcome(\n forSchema(apiSchema),\n pathParams.endpointId,\n retrieveResult.ok ? null : retrieveResult.code,\n );\n return retrieveResult;\n })\n .execute();\n\n if (!result.ok) {\n if (result.code === \"WEBHOOK_ENDPOINT_NOT_FOUND\") {\n return error({ code: result.code, message: \"Webhook endpoint not found\" }, 404);\n }\n if (result.code === \"WEBHOOK_ENDPOINT_DISABLED\") {\n return error({ code: result.code, message: \"Webhook endpoint is disabled\" }, 409);\n }\n if (result.code === \"WEBHOOK_ENDPOINT_DRAFT\") {\n return error(\n { code: result.code, message: \"Webhook endpoint is not configured yet\" },\n 409,\n );\n }\n if (result.code === \"WEBHOOK_AUTH_FAILED\") {\n return error({ code: result.code, message: \"Webhook authentication failed\" }, 401);\n }\n if (result.code === \"WEBHOOK_VERIFICATION_RESPONSE_INVALID\") {\n return error({ code: result.code, message: \"Webhook challenge is invalid\" }, 400);\n }\n return error(\n { code: result.code, message: \"Webhook verification request not found\" },\n 404,\n );\n }\n\n return webhookVerificationResponse(result.body);\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/webhooks/endpoints/:endpointId/events\",\n errorCodes: [\n \"WEBHOOK_ENDPOINT_NOT_FOUND\",\n \"WEBHOOK_ENDPOINT_DISABLED\",\n \"WEBHOOK_ENDPOINT_DRAFT\",\n \"WEBHOOK_AUTH_FAILED\",\n \"WEBHOOK_VERIFICATION_RESPONSE_INVALID\",\n \"WEBHOOK_BODY_INVALID\",\n \"WEBHOOK_DELIVERY_ID_MISSING\",\n \"WEBHOOK_DELIVERY_ID_INVALID\",\n ],\n handler: async function ({ pathParams, headers, query, rawBody, request }, { json, error }) {\n let result: WebhookReceiveResult;\n try {\n result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema)\n .findFirst(\"webhookEndpoint\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.endpointId)),\n )\n .find(\"webhookSecret\", (b) =>\n b.whereIndex(\"idx_webhook_secret_endpoint_ref\", (eb) =>\n eb(\"endpointId\", \"=\", pathParams.endpointId),\n ),\n ),\n )\n .transformRetrieve(async ([endpoint, secrets]) => {\n if (!endpoint) {\n return { ok: false as const, code: \"WEBHOOK_ENDPOINT_NOT_FOUND\" as const };\n }\n if (endpoint.status === \"draft\") {\n return { ok: false as const, code: \"WEBHOOK_ENDPOINT_DRAFT\" as const };\n }\n if (endpoint.status !== \"active\") {\n return { ok: false as const, code: \"WEBHOOK_ENDPOINT_DISABLED\" as const };\n }\n if (!request) {\n throw new Error(\"Webhook receive route requires a web-standard Request\");\n }\n\n const authConfig = endpoint.authConfig;\n const secretValues = new Map(secrets.map((secret) => [secret.ref, secret.payload]));\n const auth = await verifyWebhookAuth({\n config: authConfig,\n request,\n secrets: { get: async (ref) => secretValues.get(ref) },\n });\n if (!auth.ok) {\n return { ok: false as const, code: \"WEBHOOK_AUTH_FAILED\" as const };\n }\n\n const requestValues = createWebhookRequestValues({ headers, query, rawBody });\n const verification = evaluateWebhookVerification({\n config: endpoint.verification,\n method: \"POST\",\n requestValues,\n });\n if (verification.type === \"invalid_response\") {\n return {\n ok: false as const,\n code: \"WEBHOOK_VERIFICATION_RESPONSE_INVALID\" as const,\n };\n }\n if (verification.type === \"response\") {\n return {\n ok: true as const,\n type: \"verification\" as const,\n body: verification.body,\n };\n }\n\n const body = requestValues.jsonBody();\n if (!body.ok) {\n return { ok: false as const, code: \"WEBHOOK_BODY_INVALID\" as const };\n }\n\n const deliveryId = extractWebhookDeliveryId({\n identity: endpoint.deliveryIdentity,\n requestValues,\n });\n if (!deliveryId.ok) {\n return {\n ok: false as const,\n code:\n deliveryId.reason === \"missing\"\n ? (\"WEBHOOK_DELIVERY_ID_MISSING\" as const)\n : (\"WEBHOOK_DELIVERY_ID_INVALID\" as const),\n };\n }\n\n return {\n ok: true as const,\n type: \"delivery\" as const,\n authConfig,\n deliveryId: deliveryId.deliveryId,\n hookId: await webhookHookId(pathParams.endpointId, deliveryId.deliveryId),\n body: body.body,\n };\n })\n .mutate(({ forSchema, retrieveResult }) => {\n const uow = forSchema(apiSchema);\n recordWebhookRequestOutcome(\n uow,\n pathParams.endpointId,\n retrieveResult.ok ? null : retrieveResult.code,\n );\n if (!retrieveResult.ok || retrieveResult.type === \"verification\") {\n return retrieveResult;\n }\n\n const sensitiveValues = getSensitiveWebhookAuthValues(retrieveResult.authConfig);\n const sensitiveHeaderNames = new Set(\n sensitiveValues.flatMap((value) =>\n value.location === \"header\" ? [value.name.toLowerCase()] : [],\n ),\n );\n const sensitiveQueryNames = new Set(\n sensitiveValues.flatMap((value) =>\n value.location === \"query\" ? [value.name] : [],\n ),\n );\n\n uow.triggerHook(\n \"onWebhookReceived\",\n {\n endpointId: pathParams.endpointId,\n deliveryId: retrieveResult.deliveryId,\n hookId: retrieveResult.hookId,\n receivedAt: new Date().toISOString(),\n headers: recordFromHeaders(headers, sensitiveHeaderNames),\n query: recordFromSearchParams(query, sensitiveQueryNames),\n rawBody: rawBody ?? \"\",\n body: retrieveResult.body,\n contentType: headers.get(\"content-type\"),\n },\n { id: retrieveResult.hookId },\n );\n return { ok: true as const, type: \"delivery\" as const };\n })\n .execute();\n } catch (err) {\n if (isUniqueConstraintError(err)) {\n return json({ accepted: true }, 202);\n }\n throw err;\n }\n\n if (!result.ok) {\n if (result.code === \"WEBHOOK_ENDPOINT_NOT_FOUND\") {\n return error({ code: result.code, message: \"Webhook endpoint not found\" }, 404);\n }\n if (result.code === \"WEBHOOK_ENDPOINT_DISABLED\") {\n return error({ code: result.code, message: \"Webhook endpoint is disabled\" }, 409);\n }\n if (result.code === \"WEBHOOK_ENDPOINT_DRAFT\") {\n return error(\n { code: result.code, message: \"Webhook endpoint is not configured yet\" },\n 409,\n );\n }\n if (result.code === \"WEBHOOK_VERIFICATION_RESPONSE_INVALID\") {\n return error({ code: result.code, message: \"Webhook challenge is invalid\" }, 400);\n }\n if (result.code === \"WEBHOOK_BODY_INVALID\") {\n return error({ code: result.code, message: \"Webhook body must be a JSON object\" }, 400);\n }\n if (result.code === \"WEBHOOK_DELIVERY_ID_MISSING\") {\n return error({ code: result.code, message: \"Webhook delivery ID is missing\" }, 400);\n }\n if (result.code === \"WEBHOOK_DELIVERY_ID_INVALID\") {\n return error({ code: result.code, message: \"Webhook delivery ID is invalid\" }, 400);\n }\n return error({ code: result.code, message: \"Webhook authentication failed\" }, 401);\n }\n\n if (result.type === \"verification\") {\n return webhookVerificationResponse(result.body);\n }\n return json({ accepted: true }, 202);\n },\n }),\n\n defineRoute({\n method: \"PATCH\",\n path: \"/webhooks/endpoints/:endpointId\",\n inputSchema: updateWebhookEndpointInputSchema,\n outputSchema: webhookEndpointOutputSchema,\n errorCodes: [\"WEBHOOK_ENDPOINT_NOT_FOUND\"],\n handler: async function ({ input, pathParams }, { json, error }) {\n const body = await input.valid();\n const authStorage = body.auth ? webhookEndpointAuthStorage(body.auth) : null;\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema)\n .findFirst(\"webhookEndpoint\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.endpointId)),\n )\n .find(\"webhookSecret\", (b) =>\n b.whereIndex(\"idx_webhook_secret_endpoint_ref\", (eb) =>\n eb(\"endpointId\", \"=\", pathParams.endpointId),\n ),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [endpoint, secrets] }) => {\n if (!endpoint) {\n return { found: false as const };\n }\n const uow = forSchema(apiSchema);\n const authConfig = authStorage?.authConfig ?? endpoint.authConfig;\n const verification = body.verification ?? endpoint.verification;\n const deliveryIdentity = body.deliveryIdentity ?? endpoint.deliveryIdentity;\n const next = {\n id: endpoint.id,\n name: body.name ?? endpoint.name,\n status: body.status ?? endpoint.status,\n authConfig,\n verification,\n deliveryIdentity,\n ...noWebhookDeliveryEvidence,\n createdAt: endpoint.createdAt,\n };\n uow.update(\"webhookEndpoint\", endpoint.id, (b) =>\n b\n .set({\n name: next.name,\n status: next.status,\n authConfig,\n verification,\n deliveryIdentity,\n ...noWebhookDeliveryEvidence,\n updatedAt: b.now(),\n })\n .check(),\n );\n if (authStorage) {\n for (const secret of secrets) {\n uow.delete(\"webhookSecret\", secret.id);\n }\n for (const secret of authStorage.secrets) {\n uow.create(\"webhookSecret\", {\n id: webhookSecretId(pathParams.endpointId, secret.ref),\n endpointId: pathParams.endpointId,\n ref: secret.ref,\n payload: secret.payload,\n });\n }\n }\n uow.triggerHook(\"onWebhookEndpointChanged\", {\n change: \"updated\",\n endpointId: pathParams.endpointId,\n endpoint: webhookEndpointHookSnapshot(next),\n previousStatus: parseWebhookEndpointStatus(endpoint.status),\n });\n return { found: true as const, endpoint: next };\n })\n .execute();\n\n if (!result.found) {\n return error(\n { code: \"WEBHOOK_ENDPOINT_NOT_FOUND\", message: \"Webhook endpoint not found\" },\n 404,\n );\n }\n\n return json(publicWebhookEndpoint(result.endpoint));\n },\n }),\n\n defineRoute({\n method: \"DELETE\",\n path: \"/webhooks/endpoints/:endpointId\",\n handler: async function ({ pathParams }, { empty }) {\n await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema)\n .findFirst(\"webhookEndpoint\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.endpointId)),\n )\n .find(\"webhookSecret\", (b) =>\n b.whereIndex(\"idx_webhook_secret_endpoint_ref\", (eb) =>\n eb(\"endpointId\", \"=\", pathParams.endpointId),\n ),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [endpoint, secrets] }) => {\n if (!endpoint) {\n return { deleted: false as const };\n }\n const uow = forSchema(apiSchema);\n for (const secret of secrets) {\n uow.delete(\"webhookSecret\", secret.id);\n }\n uow.delete(\"webhookEndpoint\", endpoint.id);\n uow.triggerHook(\"onWebhookEndpointChanged\", {\n change: \"deleted\",\n endpointId: pathParams.endpointId,\n });\n return { deleted: true as const };\n })\n .execute();\n\n return empty(204);\n },\n }),\n\n defineRoute({\n method: \"PUT\",\n path: \"/connections/:slug\",\n inputSchema: createApiConnectionInputSchema,\n outputSchema: apiConnectionOutputSchema,\n errorCodes: [\"CONNECTION_EXISTS\", \"BASE_URL_NOT_ALLOWED\", \"INVALID_SLUG\"],\n handler: async function ({ input, pathParams }, { json, error }) {\n const slug = apiConnectionSlugSchema.safeParse(pathParams.slug);\n if (!slug.success) {\n return error({ code: \"INVALID_SLUG\", message: slug.error.issues[0].message }, 400);\n }\n const body = await input.valid();\n try {\n assertAllowedBaseUrl(body.baseUrl, config);\n } catch (err) {\n logApiRouteError(\"API connection base URL rejected\", err);\n return error(\n { code: \"BASE_URL_NOT_ALLOWED\", message: \"API base URL is not allowed\" },\n 400,\n );\n }\n\n const payload = body.auth.type === \"none\" ? undefined : JSON.stringify(body.auth);\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema).findFirst(\"api_connection\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [existing] }) => {\n if (existing) {\n return { exists: true as const };\n }\n const uow = forSchema(apiSchema);\n uow.create(\"api_connection\", {\n id: pathParams.slug,\n name: body.name ?? null,\n baseUrl: body.baseUrl,\n authMode: body.auth.type,\n status: \"active\",\n });\n if (payload) {\n uow.create(\"secret\", {\n id: `${pathParams.slug}:auth`,\n connectionId: pathParams.slug,\n kind: \"auth\",\n payload,\n expiresAt: null,\n });\n }\n uow.triggerHook(\"onConnectionChanged\", {\n connectionId: pathParams.slug,\n connection: connectionHookSnapshot({\n id: pathParams.slug,\n name: body.name ?? null,\n baseUrl: body.baseUrl,\n authMode: body.auth.type,\n status: \"active\",\n }),\n });\n uow.triggerHook(\"onConnectionReadinessChanged\", {\n connectionId: pathParams.slug,\n ready: isApiAuthReady(\n body.auth.type,\n payload === undefined ? undefined : { payload, expiresAt: null },\n ),\n });\n return { exists: false as const };\n })\n .execute();\n\n if (result.exists) {\n return error(\n { code: \"CONNECTION_EXISTS\", message: \"API connection already exists\" },\n 409,\n );\n }\n return json(\n publicConnection({\n id: pathParams.slug,\n name: body.name ?? null,\n baseUrl: body.baseUrl,\n authMode: body.auth.type,\n status: \"active\",\n }),\n 201,\n );\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/connections\",\n queryParameters: [\"cursor\"],\n outputSchema: apiConnectionsPageSchema,\n errorCodes: [\"INVALID_CURSOR\"],\n handler: async function ({ query }, { json, error }) {\n let cursor: Cursor | null = null;\n const rawCursor = query.get(\"cursor\");\n if (rawCursor) {\n try {\n cursor = decodeCursor(rawCursor);\n if (\n cursor.indexName !== \"_primary\" ||\n cursor.orderDirection !== \"asc\" ||\n cursor.pageSize !== CONNECTIONS_PAGE_SIZE ||\n typeof cursor.indexValues[\"id\"] !== \"string\"\n ) {\n throw new Error(\"Connection cursor does not match this listing\");\n }\n } catch {\n return error({ code: \"INVALID_CURSOR\", message: \"Invalid connection cursor\" }, 400);\n }\n }\n const [page] = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema).findWithCursor(\"api_connection\", (b) => {\n const ordered = b\n .whereIndex(\"primary\")\n .orderByIndex(\"primary\", \"asc\")\n .pageSize(CONNECTIONS_PAGE_SIZE);\n return cursor ? ordered.after(cursor) : ordered;\n }),\n )\n .execute();\n return json({\n connections: page.items.map(publicConnection),\n cursor: page.cursor?.encode() ?? null,\n });\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/connections/:slug\",\n outputSchema: apiConnectionOutputSchema,\n errorCodes: [\"CONNECTION_NOT_FOUND\"],\n handler: async function ({ pathParams }, { json, error }) {\n const [connection] = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema).findFirst(\"api_connection\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n ),\n )\n .execute();\n if (!connection) {\n return error({ code: \"CONNECTION_NOT_FOUND\", message: \"API connection not found\" }, 404);\n }\n return json(publicConnection(connection));\n },\n }),\n\n defineRoute({\n method: \"PUT\",\n path: \"/connections/:slug/configuration\",\n inputSchema: createApiConnectionInputSchema,\n outputSchema: apiConnectionOutputSchema,\n errorCodes: [\"CONNECTION_NOT_FOUND\", \"BASE_URL_NOT_ALLOWED\"],\n handler: async function ({ input, pathParams }, { json, error }) {\n const body = await input.valid();\n try {\n assertAllowedBaseUrl(body.baseUrl, config);\n } catch (err) {\n logApiRouteError(\"API connection base URL rejected\", err);\n return error(\n { code: \"BASE_URL_NOT_ALLOWED\", message: \"API base URL is not allowed\" },\n 400,\n );\n }\n const payload = body.auth.type === \"none\" ? null : JSON.stringify(body.auth);\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema)\n .findFirst(\"api_connection\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .find(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_connection_kind\", (eb) =>\n eb(\"connectionId\", \"=\", pathParams.slug),\n ),\n )\n .find(\"oauthState\", (b) =>\n b.whereIndex(\"idx_oauth_state_connection\", (eb) =>\n eb(\"connectionId\", \"=\", pathParams.slug),\n ),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [connection, secrets, states] }) => {\n if (!connection) {\n return { connection: null };\n }\n const uow = forSchema(apiSchema);\n const replaced = {\n ...connection,\n name: body.name ?? null,\n baseUrl: body.baseUrl,\n authMode: body.auth.type,\n };\n uow.update(\"api_connection\", connection.id, (b) =>\n b\n .set({\n name: replaced.name,\n baseUrl: replaced.baseUrl,\n authMode: replaced.authMode,\n updatedAt: b.now(),\n })\n .check(),\n );\n // Replaced credentials take their tokens with them; pending links belong to the old client.\n const authSecret = secrets.find((secret) => secret.kind === \"auth\");\n for (const secret of secrets) {\n if (secret !== authSecret || payload === null) {\n uow.delete(\"secret\", secret.id);\n }\n }\n if (payload !== null) {\n if (authSecret) {\n uow.update(\"secret\", authSecret.id, (b) =>\n b.set({ payload, expiresAt: null, updatedAt: b.now() }).check(),\n );\n } else {\n uow.create(\"secret\", {\n id: `${pathParams.slug}:auth`,\n connectionId: pathParams.slug,\n kind: \"auth\",\n payload,\n expiresAt: null,\n });\n }\n }\n for (const state of states) {\n uow.delete(\"oauthState\", state.id);\n }\n uow.triggerHook(\"onConnectionChanged\", {\n connectionId: pathParams.slug,\n connection: connectionHookSnapshot(replaced),\n });\n const ready = isApiAuthReady(\n replaced.authMode,\n payload === null ? undefined : { payload, expiresAt: null },\n );\n if (ready !== isApiAuthReady(connection.authMode, authSecret)) {\n uow.triggerHook(\"onConnectionReadinessChanged\", {\n connectionId: pathParams.slug,\n ready,\n });\n }\n return { connection: replaced };\n })\n .execute();\n if (!result.connection) {\n return error({ code: \"CONNECTION_NOT_FOUND\", message: \"API connection not found\" }, 404);\n }\n return json(publicConnection(result.connection));\n },\n }),\n\n defineRoute({\n method: \"DELETE\",\n path: \"/connections/:slug\",\n errorCodes: [\"CONNECTION_NOT_FOUND\"],\n handler: async function ({ pathParams }, { empty, error }) {\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema)\n .findFirst(\"api_connection\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .find(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_connection_kind\", (eb) =>\n eb(\"connectionId\", \"=\", pathParams.slug),\n ),\n )\n .find(\"oauthState\", (b) =>\n b.whereIndex(\"idx_oauth_state_connection\", (eb) =>\n eb(\"connectionId\", \"=\", pathParams.slug),\n ),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [connection, secrets, states] }) => {\n if (!connection) {\n return { deleted: false as const };\n }\n const uow = forSchema(apiSchema);\n for (const secret of secrets) {\n uow.delete(\"secret\", secret.id);\n }\n for (const state of states) {\n uow.delete(\"oauthState\", state.id);\n }\n uow.delete(\"api_connection\", connection.id);\n uow.triggerHook(\"onConnectionDeleted\", {\n connectionId: pathParams.slug,\n previous: connectionHookSnapshot(connection),\n });\n return { deleted: true as const };\n })\n .execute();\n if (!result.deleted) {\n return error({ code: \"CONNECTION_NOT_FOUND\", message: \"API connection not found\" }, 404);\n }\n return empty(204);\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/connections/:slug/auth/status\",\n outputSchema: apiAuthStatusSchema,\n errorCodes: [\"CONNECTION_NOT_FOUND\"],\n handler: async function ({ pathParams }, { json, error }) {\n const [connection, secret, pendingState] = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema)\n .findFirst(\"api_connection\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .findFirst(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_connection_kind\", (eb) =>\n eb.and(eb(\"connectionId\", \"=\", pathParams.slug), eb(\"kind\", \"=\", \"auth\")),\n ),\n )\n .findFirst(\"oauthState\", (b) =>\n b\n .whereIndex(\"idx_oauth_state_pending\", (eb) =>\n eb.and(\n eb(\"connectionId\", \"=\", pathParams.slug),\n eb.isNull(\"consumedAt\"),\n eb(\"expiresAt\", \">\", eb.now()),\n ),\n )\n .orderByIndex(\"idx_oauth_state_pending\", \"desc\"),\n ),\n )\n .execute();\n if (!connection) {\n return error({ code: \"CONNECTION_NOT_FOUND\", message: \"API connection not found\" }, 404);\n }\n return json(\n projectApiAuthStatus({\n authMode: connection.authMode,\n authSecret: secret ?? undefined,\n hasPendingOAuth: pendingOAuthLink(pendingState) !== null,\n }),\n );\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/connections/:slug/auth/oauth/pending\",\n outputSchema: apiOAuthPendingSchema,\n errorCodes: [\"CONNECTION_NOT_FOUND\"],\n handler: async function ({ pathParams }, { json, error }) {\n const [connection, pendingState] = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema)\n .findFirst(\"api_connection\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .findFirst(\"oauthState\", (b) =>\n b\n .whereIndex(\"idx_oauth_state_pending\", (eb) =>\n eb.and(\n eb(\"connectionId\", \"=\", pathParams.slug),\n eb.isNull(\"consumedAt\"),\n eb(\"expiresAt\", \">\", eb.now()),\n ),\n )\n .orderByIndex(\"idx_oauth_state_pending\", \"desc\"),\n ),\n )\n .execute();\n if (!connection) {\n return error({ code: \"CONNECTION_NOT_FOUND\", message: \"API connection not found\" }, 404);\n }\n return json({ pending: pendingOAuthLink(pendingState) });\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/connections/:slug/auth/token\",\n inputSchema: tokenAuthInputSchema,\n outputSchema: apiAuthStatusSchema,\n errorCodes: [\"CONNECTION_NOT_FOUND\"],\n handler: async function ({ input, pathParams }, { json, error }) {\n const { token } = await input.valid();\n const payload = JSON.stringify({ type: \"bearer\", token });\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema)\n .findFirst(\"api_connection\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .findFirst(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_connection_kind\", (eb) =>\n eb.and(eb(\"connectionId\", \"=\", pathParams.slug), eb(\"kind\", \"=\", \"auth\")),\n ),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [connection, secret] }) => {\n if (!connection) {\n return { found: false as const };\n }\n const uow = forSchema(apiSchema);\n uow.update(\"api_connection\", connection.id, (b) =>\n b.set({ authMode: \"bearer\", updatedAt: b.now() }).check(),\n );\n if (secret) {\n uow.update(\"secret\", secret.id, (b) =>\n b.set({ payload, expiresAt: null, updatedAt: b.now() }).check(),\n );\n } else {\n uow.create(\"secret\", {\n id: `${pathParams.slug}:auth`,\n connectionId: pathParams.slug,\n kind: \"auth\",\n payload,\n expiresAt: null,\n });\n }\n const changedConnection = connectionHookSnapshot({\n ...connection,\n authMode: \"bearer\",\n });\n uow.triggerHook(\"onConnectionChanged\", {\n connectionId: pathParams.slug,\n connection: changedConnection,\n });\n if (!isApiAuthReady(connection.authMode, secret ?? undefined)) {\n uow.triggerHook(\"onConnectionReadinessChanged\", {\n connectionId: pathParams.slug,\n ready: true,\n });\n }\n return { found: true as const };\n })\n .execute();\n if (!result.found) {\n return error({ code: \"CONNECTION_NOT_FOUND\", message: \"API connection not found\" }, 404);\n }\n return json({ mode: \"bearer\" as const, credentials: \"present\" as const });\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/connections/:slug/auth/oauth/start\",\n inputSchema: oauthStartInputSchema,\n outputSchema: oauthStartOutputSchema,\n queryParameters: [API_OAUTH_REDIRECT_URI_QUERY_PARAMETER],\n errorCodes: [\n \"INVALID_OAUTH_REDIRECT_URI\",\n \"OAUTH_REDIRECT_URI_NOT_ALLOWED\",\n \"CONNECTION_NOT_FOUND\",\n \"AUTH_NOT_CONFIGURED\",\n \"AUTH_NOT_OAUTH\",\n \"OAUTH_ERROR\",\n ],\n handler: async function ({ input, pathParams, query }, { json, error }) {\n const body = await input.valid();\n const redirectUri = oauthRedirectUriSchema.safeParse(\n query.get(API_OAUTH_REDIRECT_URI_QUERY_PARAMETER),\n );\n if (!redirectUri.success) {\n return error(\n {\n code: \"INVALID_OAUTH_REDIRECT_URI\",\n message: \"OAuth redirect URI must be an HTTP or HTTPS URL\",\n },\n 400,\n );\n }\n const oauthRedirectUri = new URL(redirectUri.data);\n if (!config.allowedOAuthRedirectUris?.(oauthRedirectUri)) {\n return error(\n {\n code: \"OAUTH_REDIRECT_URI_NOT_ALLOWED\",\n message: \"OAuth redirect URI is not allowed by the fragment configuration\",\n },\n 400,\n );\n }\n const state = `${pathParams.slug}:${crypto.randomUUID()}`;\n try {\n const [result] = await this.handlerTx()\n .withServiceCalls(\n () =>\n [\n services.startOAuth({\n connectionId: pathParams.slug,\n stateId: state,\n redirectUri: oauthRedirectUri.toString(),\n scopes: body.scopes,\n extraAuthorizationParams: body.extraAuthorizationParams,\n discardTokens: body.discardTokens,\n }),\n ] as const,\n )\n .execute();\n if (!result.found) {\n if (result.reason === \"connection_not_found\") {\n return error(\n { code: \"CONNECTION_NOT_FOUND\", message: \"API connection not found\" },\n 404,\n );\n }\n if (result.reason === \"auth_not_configured\") {\n return error(\n { code: \"AUTH_NOT_CONFIGURED\", message: \"API connection auth is not configured\" },\n 400,\n );\n }\n return error(\n { code: \"AUTH_NOT_OAUTH\", message: \"API connection auth is not OAuth\" },\n 400,\n );\n }\n return json({ authorizationUrl: result.authorizationUrl, state });\n } catch (err) {\n logApiRouteError(\"API OAuth start failed\", err);\n return error({ code: \"OAUTH_ERROR\", message: \"An authentication error occurred\" }, 502);\n }\n },\n }),\n\n defineRoute({\n method: \"GET\",\n path: \"/oauth/callback\",\n outputSchema: oauthCallbackOutputSchema,\n errorCodes: [\n \"CONNECTION_NOT_FOUND\",\n \"AUTH_NOT_CONFIGURED\",\n \"AUTH_NOT_OAUTH\",\n \"OAUTH_ERROR\",\n \"INVALID_OAUTH_STATE\",\n ],\n handler: async function ({ query }, { json, error }) {\n const code = query.get(\"code\");\n const stateId = query.get(\"state\");\n if (!code || !stateId) {\n return error(\n { code: \"INVALID_OAUTH_STATE\", message: \"Missing OAuth code or state\" },\n 400,\n );\n }\n try {\n const [result] = await this.handlerTx()\n .withServiceCalls(() => [services.completeOAuthCallback({ stateId, code })] as const)\n .execute();\n if (!result.found) {\n if (result.reason === \"connection_not_found\") {\n return error(\n { code: \"CONNECTION_NOT_FOUND\", message: \"API connection not found\" },\n 404,\n );\n }\n if (result.reason === \"auth_not_configured\") {\n return error(\n { code: \"AUTH_NOT_CONFIGURED\", message: \"API connection auth is not configured\" },\n 400,\n );\n }\n if (result.reason === \"auth_not_oauth\") {\n return error(\n { code: \"AUTH_NOT_OAUTH\", message: \"API connection auth is not OAuth\" },\n 400,\n );\n }\n return error({ code: \"INVALID_OAUTH_STATE\", message: \"Invalid OAuth state\" }, 400);\n }\n return json({ authenticated: true, mode: \"oauth\" });\n } catch (err) {\n logApiRouteError(\"API OAuth callback failed\", err);\n return error({ code: \"OAUTH_ERROR\", message: \"An authentication error occurred\" }, 502);\n }\n },\n }),\n\n defineRoute({\n method: \"DELETE\",\n path: \"/connections/:slug/auth\",\n outputSchema: apiAuthStatusSchema,\n errorCodes: [\"CONNECTION_NOT_FOUND\"],\n handler: async function ({ pathParams }, { json, error }) {\n const result = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema)\n .findFirst(\"api_connection\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", pathParams.slug)),\n )\n .find(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_connection_kind\", (eb) =>\n eb(\"connectionId\", \"=\", pathParams.slug),\n ),\n )\n .find(\"oauthState\", (b) =>\n b.whereIndex(\"idx_oauth_state_connection\", (eb) =>\n eb(\"connectionId\", \"=\", pathParams.slug),\n ),\n ),\n )\n .mutate(({ forSchema, retrieveResult: [connection, secrets, states] }) => {\n if (!connection) {\n return { found: false as const };\n }\n const uow = forSchema(apiSchema);\n for (const secret of secrets) {\n uow.delete(\"secret\", secret.id);\n }\n for (const state of states) {\n uow.delete(\"oauthState\", state.id);\n }\n // Keep the mode: clearing credentials must not turn the connection unauthenticated.\n uow.update(\"api_connection\", connection.id, (b) =>\n b.set({ updatedAt: b.now() }).check(),\n );\n uow.triggerHook(\"onConnectionChanged\", {\n connectionId: pathParams.slug,\n connection: connectionHookSnapshot(connection),\n });\n const authSecret = secrets.find((secret) => secret.kind === \"auth\");\n const ready = isApiAuthReady(connection.authMode, undefined);\n if (ready !== isApiAuthReady(connection.authMode, authSecret)) {\n uow.triggerHook(\"onConnectionReadinessChanged\", {\n connectionId: pathParams.slug,\n ready,\n });\n }\n return {\n found: true as const,\n status: projectApiAuthStatus({\n authMode: connection.authMode,\n authSecret: undefined,\n hasPendingOAuth: false,\n }),\n };\n })\n .execute();\n if (!result.found) {\n return error({ code: \"CONNECTION_NOT_FOUND\", message: \"API connection not found\" }, 404);\n }\n return json(result.status);\n },\n }),\n\n defineRoute({\n method: \"POST\",\n path: \"/connections/:slug/request\",\n inputSchema: apiRequestInputSchema,\n outputSchema: apiRequestOutputSchema,\n handler: async function ({ input, pathParams }, { json }) {\n const request = await input.valid();\n const [result] = await this.handlerTx()\n .withServiceCalls(\n () => [services.executeApiRequest({ connectionId: pathParams.slug, request })] as const,\n )\n .execute();\n if (!result.found) {\n if (result.reason === \"connection_disabled\") {\n return json({\n ok: false,\n response: null,\n error: {\n code: \"CONNECTION_DISABLED\",\n message: \"API connection is disabled\",\n },\n });\n }\n return json({\n ok: false,\n response: null,\n error: {\n code: \"CONNECTION_NOT_FOUND\",\n message: \"API connection not found\",\n },\n });\n }\n return json(result.response);\n },\n }),\n ],\n);\n"],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ import { Column } from "@fragno-dev/db/schema";
2
+ //#region src/schema.d.ts
3
+ type JsonColumn<T> = Column<"json", T, T>;
4
+ declare const apiSchema: import("@fragno-dev/db/schema").Schema<{
5
+ api_connection: import("@fragno-dev/db/schema").Table<Record<"id", import("@fragno-dev/db/schema").IdColumn<"varchar(128)", string | import("@fragno-dev/db/schema").FragnoId | null, import("@fragno-dev/db/schema").FragnoId>> & Record<"name", Column<"string", string | null, string | null>> & Record<"baseUrl", Column<"string", string, string>> & Record<"authMode", Column<"string", string, string>> & Record<"status", Column<"string", string, string>> & Record<"createdAt", Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date>> & Record<"updatedAt", Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date>>, {}>;
6
+ secret: import("@fragno-dev/db/schema").Table<Record<"id", import("@fragno-dev/db/schema").IdColumn<"varchar(128)", string | import("@fragno-dev/db/schema").FragnoId | null, import("@fragno-dev/db/schema").FragnoId>> & Record<"connectionId", Column<"bigint", string | bigint | import("@fragno-dev/db/schema").FragnoId | import("@fragno-dev/db/schema").FragnoReference, import("@fragno-dev/db/schema").FragnoReference>> & Record<"kind", Column<"string", string, string>> & Record<"payload", Column<"text", string, string>> & Record<"expiresAt", Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date | null>> & Record<"updatedAt", Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date>>, Record<"idx_secret_connection_kind", import("@fragno-dev/db/schema").Index<readonly [Column<"bigint", string | bigint | import("@fragno-dev/db/schema").FragnoId | import("@fragno-dev/db/schema").FragnoReference, import("@fragno-dev/db/schema").FragnoReference>, Column<"string", string, string>] & import("@fragno-dev/db/schema").AnyColumn[], readonly ["connectionId", "kind"]>>>;
7
+ oauthState: import("@fragno-dev/db/schema").Table<Record<"id", import("@fragno-dev/db/schema").IdColumn<"varchar(128)", string | import("@fragno-dev/db/schema").FragnoId | null, import("@fragno-dev/db/schema").FragnoId>> & Record<"connectionId", Column<"bigint", string | bigint | import("@fragno-dev/db/schema").FragnoId | import("@fragno-dev/db/schema").FragnoReference, import("@fragno-dev/db/schema").FragnoReference>> & Record<"codeVerifier", Column<"text", string, string>> & Record<"redirectUri", Column<"string", string, string>> & Record<"scope", Column<"string", string | null, string | null>> & Record<"expiresAt", Column<"timestamp", Date | import("@fragno-dev/db").DbNow, Date>> & Record<"consumedAt", Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date | null>> & Record<"authorizationUrl", Column<"text", string | null, string | null>>, Record<"idx_oauth_state_connection", import("@fragno-dev/db/schema").Index<readonly [Column<"bigint", string | bigint | import("@fragno-dev/db/schema").FragnoId | import("@fragno-dev/db/schema").FragnoReference, import("@fragno-dev/db/schema").FragnoReference>] & import("@fragno-dev/db/schema").AnyColumn[], readonly ["connectionId"]>> & Record<"idx_oauth_state_pending", import("@fragno-dev/db/schema").Index<readonly [Column<"bigint", string | bigint | import("@fragno-dev/db/schema").FragnoId | import("@fragno-dev/db/schema").FragnoReference, import("@fragno-dev/db/schema").FragnoReference>, Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date | null>, Column<"timestamp", Date | import("@fragno-dev/db").DbNow, Date>] & import("@fragno-dev/db/schema").AnyColumn[], readonly ["connectionId", "consumedAt", "expiresAt"]>>>;
8
+ webhookEndpoint: import("@fragno-dev/db/schema").Table<Record<"id", import("@fragno-dev/db/schema").IdColumn<"varchar(128)", string | import("@fragno-dev/db/schema").FragnoId | null, import("@fragno-dev/db/schema").FragnoId>> & Record<"name", Column<"string", string, string>> & Record<"status", Column<"string", string, string>> & Record<"authConfig", JsonColumn<{
9
+ type: "none";
10
+ } | {
11
+ type: "bearer";
12
+ tokenRef: string;
13
+ } | {
14
+ type: "apiKey";
15
+ location: "header" | "query";
16
+ name: string;
17
+ secretRef: string;
18
+ } | {
19
+ type: "basic";
20
+ usernameRef: string;
21
+ passwordRef: string;
22
+ } | {
23
+ type: "hmac";
24
+ secretRef: string;
25
+ algorithm: "sha1" | "sha256" | "sha512";
26
+ signature: {
27
+ location: "header" | "query";
28
+ name: string;
29
+ encoding: "hex" | "base64" | "base64url";
30
+ prefix?: string | undefined;
31
+ };
32
+ signedPayload: {
33
+ type: "rawBody";
34
+ } | {
35
+ type: "timestampedBody";
36
+ prefix: string;
37
+ timestampHeader: string;
38
+ delimiter: string;
39
+ toleranceSeconds: number;
40
+ };
41
+ }>> & Record<"verification", JsonColumn<{
42
+ type: "none";
43
+ } | {
44
+ type: "challenge";
45
+ method: "GET" | "POST";
46
+ when: {
47
+ type: "present";
48
+ source: {
49
+ type: "header";
50
+ name: string;
51
+ } | {
52
+ type: "query";
53
+ name: string;
54
+ } | {
55
+ type: "jsonBodyPath";
56
+ path: string[];
57
+ };
58
+ } | {
59
+ type: "equals";
60
+ source: {
61
+ type: "header";
62
+ name: string;
63
+ } | {
64
+ type: "query";
65
+ name: string;
66
+ } | {
67
+ type: "jsonBodyPath";
68
+ path: string[];
69
+ };
70
+ value: string;
71
+ };
72
+ response: {
73
+ type: "echoText";
74
+ source: {
75
+ type: "header";
76
+ name: string;
77
+ } | {
78
+ type: "query";
79
+ name: string;
80
+ } | {
81
+ type: "jsonBodyPath";
82
+ path: string[];
83
+ };
84
+ };
85
+ }>> & Record<"deliveryIdentity", JsonColumn<{
86
+ type: "header";
87
+ name: string;
88
+ } | {
89
+ type: "query";
90
+ name: string;
91
+ } | {
92
+ type: "jsonBodyPath";
93
+ path: string[];
94
+ }>> & Record<"createdAt", Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date>> & Record<"updatedAt", Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date>> & Record<"lastAcceptedAt", Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date | null>> & Record<"lastRejectedAt", Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date | null>> & Record<"lastRejectionCode", Column<"string", string | null, string | null>>, {}>;
95
+ webhookSecret: import("@fragno-dev/db/schema").Table<Record<"id", import("@fragno-dev/db/schema").IdColumn<"varchar(128)", string | import("@fragno-dev/db/schema").FragnoId | null, import("@fragno-dev/db/schema").FragnoId>> & Record<"endpointId", Column<"bigint", string | bigint | import("@fragno-dev/db/schema").FragnoId | import("@fragno-dev/db/schema").FragnoReference, import("@fragno-dev/db/schema").FragnoReference>> & Record<"ref", Column<"string", string, string>> & Record<"payload", Column<"text", string, string>> & Record<"updatedAt", Column<"timestamp", (Date | import("@fragno-dev/db").DbNow) | null, Date>>, Record<"idx_webhook_secret_endpoint_ref", import("@fragno-dev/db/schema").Index<readonly [Column<"bigint", string | bigint | import("@fragno-dev/db/schema").FragnoId | import("@fragno-dev/db/schema").FragnoReference, import("@fragno-dev/db/schema").FragnoReference>, Column<"string", string, string>] & import("@fragno-dev/db/schema").AnyColumn[], readonly ["endpointId", "ref"]>>>;
96
+ }>;
97
+ //#endregion
98
+ export { apiSchema };
99
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","names":[],"sources":["../../src/schema.ts"],"mappings":";;KAMK,WAAW,KAAK,eAAe,GAAG;cAM1B,2CAAS"}
@@ -0,0 +1,16 @@
1
+ import { column, idColumn, referenceColumn, schema } from "@fragno-dev/db/schema";
2
+ //#region src/schema.ts
3
+ function jsonColumn() {
4
+ return column("json");
5
+ }
6
+ const apiSchema = schema("api-fragment", (s) => {
7
+ return s.addTable("api_connection", (t) => t.addColumn("id", idColumn()).addColumn("name", column("string").nullable()).addColumn("baseUrl", column("string")).addColumn("authMode", column("string")).addColumn("status", column("string")).addColumn("createdAt", column("timestamp").defaultTo((b) => b.now())).addColumn("updatedAt", column("timestamp").defaultTo((b) => b.now()))).addTable("secret", (t) => t.addColumn("id", idColumn()).addColumn("connectionId", referenceColumn({ table: "api_connection" })).addColumn("kind", column("string")).addColumn("payload", column("text")).addColumn("expiresAt", column("timestamp").nullable()).addColumn("updatedAt", column("timestamp").defaultTo((b) => b.now())).createIndex("idx_secret_connection_kind", ["connectionId", "kind"], { unique: true })).addTable("oauthState", (t) => t.addColumn("id", idColumn()).addColumn("connectionId", referenceColumn({ table: "api_connection" })).addColumn("codeVerifier", column("text")).addColumn("redirectUri", column("string")).addColumn("scope", column("string").nullable()).addColumn("expiresAt", column("timestamp")).addColumn("consumedAt", column("timestamp").nullable()).createIndex("idx_oauth_state_connection", ["connectionId"])).addTable("webhookEndpoint", (t) => t.addColumn("id", idColumn()).addColumn("name", column("string")).addColumn("status", column("string")).addColumn("authConfig", jsonColumn()).addColumn("verification", jsonColumn()).addColumn("deliveryIdentity", jsonColumn()).addColumn("createdAt", column("timestamp").defaultTo((b) => b.now())).addColumn("updatedAt", column("timestamp").defaultTo((b) => b.now()))).addTable("webhookSecret", (t) => t.addColumn("id", idColumn()).addColumn("endpointId", referenceColumn({ table: "webhookEndpoint" })).addColumn("ref", column("string")).addColumn("payload", column("text")).addColumn("updatedAt", column("timestamp").defaultTo((b) => b.now())).createIndex("idx_webhook_secret_endpoint_ref", ["endpointId", "ref"], { unique: true })).alterTable("oauthState", (t) => t.addColumn("authorizationUrl", column("text").nullable())).alterTable("oauthState", (t) => t.createIndex("idx_oauth_state_pending", [
8
+ "connectionId",
9
+ "consumedAt",
10
+ "expiresAt"
11
+ ])).alterTable("webhookEndpoint", (t) => t.addColumn("lastAcceptedAt", column("timestamp").nullable()).addColumn("lastRejectedAt", column("timestamp").nullable()).addColumn("lastRejectionCode", column("string").nullable()));
12
+ });
13
+ //#endregion
14
+ export { apiSchema };
15
+
16
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","names":[],"sources":["../../src/schema.ts"],"sourcesContent":["import { column, idColumn, referenceColumn, schema, type Column } from \"@fragno-dev/db/schema\";\n\nimport type { WebhookDeliveryIdentity } from \"./api-types\";\nimport type { WebhookAuthConfig } from \"./webhooks/auth\";\nimport type { WebhookVerificationConfig } from \"./webhooks/verification\";\n\ntype JsonColumn<T> = Column<\"json\", T, T>;\n\nfunction jsonColumn<T>(): JsonColumn<T> {\n return column(\"json\") as unknown as JsonColumn<T>;\n}\n\nexport const apiSchema = schema(\"api-fragment\", (s) => {\n return s\n .addTable(\"api_connection\", (t) =>\n t\n .addColumn(\"id\", idColumn())\n .addColumn(\"name\", column(\"string\").nullable())\n .addColumn(\"baseUrl\", column(\"string\"))\n .addColumn(\"authMode\", column(\"string\"))\n .addColumn(\"status\", column(\"string\"))\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\n \"updatedAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n ),\n )\n .addTable(\"secret\", (t) =>\n t\n .addColumn(\"id\", idColumn())\n .addColumn(\"connectionId\", referenceColumn({ table: \"api_connection\" }))\n .addColumn(\"kind\", column(\"string\"))\n .addColumn(\"payload\", column(\"text\"))\n .addColumn(\"expiresAt\", column(\"timestamp\").nullable())\n .addColumn(\n \"updatedAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_secret_connection_kind\", [\"connectionId\", \"kind\"], { unique: true }),\n )\n .addTable(\"oauthState\", (t) =>\n t\n .addColumn(\"id\", idColumn())\n .addColumn(\"connectionId\", referenceColumn({ table: \"api_connection\" }))\n .addColumn(\"codeVerifier\", column(\"text\"))\n .addColumn(\"redirectUri\", column(\"string\"))\n .addColumn(\"scope\", column(\"string\").nullable())\n .addColumn(\"expiresAt\", column(\"timestamp\"))\n .addColumn(\"consumedAt\", column(\"timestamp\").nullable())\n .createIndex(\"idx_oauth_state_connection\", [\"connectionId\"]),\n )\n .addTable(\"webhookEndpoint\", (t) =>\n t\n .addColumn(\"id\", idColumn())\n .addColumn(\"name\", column(\"string\"))\n .addColumn(\"status\", column(\"string\"))\n .addColumn(\"authConfig\", jsonColumn<WebhookAuthConfig>())\n .addColumn(\"verification\", jsonColumn<WebhookVerificationConfig>())\n .addColumn(\"deliveryIdentity\", jsonColumn<WebhookDeliveryIdentity>())\n .addColumn(\n \"createdAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .addColumn(\n \"updatedAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n ),\n )\n .addTable(\"webhookSecret\", (t) =>\n t\n .addColumn(\"id\", idColumn())\n .addColumn(\"endpointId\", referenceColumn({ table: \"webhookEndpoint\" }))\n .addColumn(\"ref\", column(\"string\"))\n .addColumn(\"payload\", column(\"text\"))\n .addColumn(\n \"updatedAt\",\n column(\"timestamp\").defaultTo((b) => b.now()),\n )\n .createIndex(\"idx_webhook_secret_endpoint_ref\", [\"endpointId\", \"ref\"], {\n unique: true,\n }),\n )\n .alterTable(\"oauthState\", (t) =>\n // Null only for states started before links were retained; those cannot be resumed.\n t.addColumn(\"authorizationUrl\", column(\"text\").nullable()),\n )\n .alterTable(\"oauthState\", (t) =>\n // States are retained after use, so pending reads seek the newest live one instead of scanning.\n t.createIndex(\"idx_oauth_state_pending\", [\"connectionId\", \"consumedAt\", \"expiresAt\"]),\n )\n .alterTable(\"webhookEndpoint\", (t) =>\n // Evidence about requests since the configuration last changed; writes reset all three, and a\n // rejection always sets both rejection columns.\n t\n .addColumn(\"lastAcceptedAt\", column(\"timestamp\").nullable())\n .addColumn(\"lastRejectedAt\", column(\"timestamp\").nullable())\n .addColumn(\"lastRejectionCode\", column(\"string\").nullable()),\n );\n});\n"],"mappings":"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"}