@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":"client-3ZV9sw3i.js","names":["extractPathParams","pathPattern","segments","split","filter","s","length","names","segment","startsWith","push","slice","buildPath","params","patternSegments","builtSegments","name","value","Error","encodeURIComponent","join","isBinaryRequestBody","body","ReadableStream","Blob","ArrayBuffer","isView","containsFileBody","value","File","FormData","Object","values","some","entry","appendFormDataValue","formData","key","append","name","JSON","stringify","prepareMultipartBody","entries","TypeError","prepareRouteRequestBody","contentType","prepareClientRequestBody","prepareInferredRequestBody","URLSearchParams","applyPreparedRequestBodyContentType","headers","preparedBody","delete","set","createRequestInitWithBody","method","options","requestInit","duplex","getMountRoute","opts","mountRoute","name","endsWith","slice","FragnoApiError","Error","status","code","constructor","message","name","toResponse","Response","json","FragnoApiValidationError","issues","FragnoApiValidationError","RequestInputContext","path","method","pathParams","searchParams","headers","body","request","parsedBody","inputSchema","shouldValidateInput","constructor","config","rawBody","fromRequest","state","fromSSRContext","URLSearchParams","Headers","query","formData","FormData","Error","isFormData","bodyStream","ReadableStream","isBodyStream","input","schema","valid","validateInput","#validateInput","Blob","result","validate","issues","value","ResponseStream","writer","encoder","abortSubscribers","responseReadable","aborted","abortPromise","closed","constructor","writable","readable","getWriter","TextEncoder","reader","getReader","push","cancel","ReadableStream","pull","controller","done","value","read","close","enqueue","abort","writeRaw","input","encode","write","JSON","stringify","sleep","ms","Promise","resolve","setTimeout","onAbort","listener","allSettled","map","subscriber","then","results","errors","result","status","reason","length","AggregateError","ResponseStream","mergeHeaders","headerSources","mergedHeaders","Headers","headerSource","key","value","entries","set","Array","isArray","Object","OutputContext","runJsonStreamCallback","constructor","options","error","message","code","initOrStatus","headers","Response","json","status","empty","defaultHeaders","object","jsonStream","cb","onError","readable","writable","TransformStream","stream","runStreamCallback","e","Error","console","close","Promise","resolve","catch","responseReadable","RequestOutputContext","outputSchema","resolveRouteFactories","context","routesOrFactories","routes","item","factoryRoutes","push","defineRoute","config","defineRoutes","_definition","create","fn","ctx","parseContentType","contentType","trimmed","trim","parts","split","map","part","mediaType","typeParts","length","type","subtype","toLowerCase","parameters","i","param","equalIndex","indexOf","key","slice","value","startsWith","endsWith","unwrapAtom","value","get","unwrapObject","params","Object","fromEntries","entries","map","key","isReadableAtom","lc","notify","off","subscribe","tasks","resolves","startTask","prevResolves","i","task","cb","endTask","promise","finally","t","allTasks","Promise","resolve","push","cleanTasks","cleanTasks","clean","Symbol","cleanStores","stores","process","env","NODE_ENV","Error","$store","mocked","clean","listenerQueue","lqIndex","QUEUE_ITEMS_PER_LISTENER","nanostoresGlobal","globalThis","epoch","atom","initialValue","listeners","$atom","get","lc","listen","value","init","listener","push","i","length","splice","index","indexOf","off","notify","oldValue","changedKey","runListenerQueue","set","newValue","subscribe","unbind","process","env","NODE_ENV","readonlyType","store","clean","START","STOP","SET","NOTIFY","MOUNT","UNMOUNT","REVERT_MUTATION","on","object","listener","eventKey","mutateStore","events","eventProps","reduceRight","event","l","shared","push","currentListeners","index","indexOf","splice","length","onStart","$store","runListeners","originListen","listen","arg","lc","starting","onStop","originOff","off","onSet","originSet","set","originSetKey","setKey","changed","changedValue","isAborted","abort","newValue","value","onNotify","originNotify","notify","oldValue","STORE_UNMOUNT_DELAY","onMount","initialize","payload","destroy","args","active","setTimeout","process","env","NODE_ENV","originClean","warned","warn","text","console","groupCollapsed","trace","groupEnd","atom","nanostoresGlobal","onMount","warn","computedStore","stores","cb","batched","Array","isArray","previousArgs","currentEpoch","set","epoch","args","map","$store","get","some","arg","i","value","then","t","process","env","NODE_ENV","asyncValue","$computed","undefined","timer","run","clearTimeout","setTimeout","unbinds","listen","unbind","computed","fn","atom","map","initial","$map","setKey","key","value","oldMap","notify","allTasks","stores","getStores","addStore","store","push","cleanStores","clientInitialData","hydrateFromWindow","window","__FRAGNO_INITIAL_DATA__","Map","console","warn","Array","from","entries","getInitialData","key","has","data","get","delete","listenToStores","listen","getFinalStoreValues","storesInitialValue","value","loading","set","FragnoClientError","Error","code","constructor","message","options","cause","name","FragnoClientFetchError","fromUnknownFetchError","error","FragnoClientFetchNetworkError","FragnoClientFetchAbortError","FragnoClientUnknownApiError","status","FragnoClientApiError","fromResponse","response","unknown","json","mergeFetcherConfigs","authorConfig","userConfig","type","authorOpts","options","userOpts","Object","keys","length","headers","mergeHeaders","author","user","merged","Headers","forEach","value","key","set","next","done","FragnoClientFetchAbortError","FragnoClientFetchError","FragnoClientUnknownApiError","createAbortPromise","abortSignal","Promise","_","reject","abortHandler","aborted","addEventListener","once","parseNdjsonBuffer","buffer","options","lines","split","trailingBuffer","flush","pop","index","length","line","trim","jsonObject","JSON","parse","parseError","parseErrorStatus","cause","onItem","remainingLines","slice","stopped","join","handleNdjsonStreamingFirstItem","response","store","body","decoder","TextDecoder","reader","getReader","firstItem","items","releaseLock","done","value","race","read","decode","stream","push","streamingPromise","continueStreaming","error","setError","clientError","initialBuffer","appendItem","setData","createNanoEvents","emit","event","args","callbacks","events","i","length","on","cb","push","filter","map","onStart","onStop","atom","batched","startTask","createNanoEvents","defaultOnErrorRetry","retryCount","Math","random","nanoqueryFactory","isAppVisible","visibilityChangeSubscribe","reconnectChangeSubscribe","nanoquery","cache","Map","fetcher","globalFetcher","globalSettings","events","focus","emit","FOCUS","RECONNECT","_revalidateOnInterval","_errorInvalidateTimeouts","_runningFetches","rewrittenSettings","getCachedValueByKey","key","fromCache","get","cacheHit","expires","getNow","data","error","runFetcher","keyParts","store","settings","set","v","SET_CACHE","setAsLoading","prev","toSet","loading","promise","dedupeTime","cacheLifetime","Infinity","onErrorRetry","now","has","value","cachedValue","cachedError","created","notLoading","finishTask","clearTimeout","res","onError","timer","setTimeout","invalidateKeys","delete","createFetcherStore","keyInput","fetcherSettings","process","env","NODE_ENV","Error","fetcherStore","_","fetcherSymbol","invalidate","revalidate","revalidateKeys","mutate","mutateCache","fetch","resolve","Promise","r","unsub","listen","finally","keysInternalUnsub","prevKey","prevKeyParts","keyUnsub","keyStore","evtUnsubs","firstRun","getKeyStore","subscribe","currentKeys","newKey","currentKeyValue","handleNewListener","revalidateInterval","revalidateOnFocus","revalidateOnReconnect","runRefetcher","setInterval","push","on","cacheKeyChangeHandler","keySelector","testKeyAgainstSelector","INVALIDATE_KEYS","REVALIDATE_KEYS","full","originListen","listener","forEach","fn","clearInterval","iterOverCache","cb","keys","cached","createMutatorStore","mutator","opts","throttleCalls","newMutator","keysToInvalidate","keysToRevalidate","safeKeySet","k","lc","setKey","result","getCacheUpdater","shouldRevalidate","newVal","__unsafeOverruleSettings","console","warn","isSomeKey","$key","keysAsStoresToIndexes","setKeyStoreValue","some","join","i","length","keyOrStore","storesAsArray","$storeKeys","storeValues","partIndex","noop","selector","Array","isArray","includes","Date","getTime","Symbol","name","isServer","window","addEventListener","browserCompat","document","hidden","buildPath","extractPathParams","createRequestInitWithBody","prepareClientRequestBody","getMountRoute","RequestInputContext","RequestOutputContext","resolveRouteFactories","parseContentType","unwrapObject","addStore","FragnoClientApiError","FragnoClientError","FragnoClientFetchAbortError","FragnoClientFetchError","FragnoClientFetchNetworkError","FragnoClientUnknownApiError","mergeFetcherConfigs","handleNdjsonStreamingFirstItem","computed","task","nanoquery","GET_HOOK_SYMBOL","Symbol","MUTATOR_HOOK_SYMBOL","STORE_SYMBOL","schemaAllowsUndefined","schema","validate","issues","assertBodyProvided","body","inputSchema","errorMessage","Error","mergeRequestHeaders","headerSources","result","hasHeaders","source","Headers","key","value","entries","Array","isArray","Object","buildUrl","config","params","baseUrl","mountRoute","path","pathParams","queryParams","normalizedPathParams","normalizedQueryParams","filteredQueryParams","fromEntries","filter","_","searchParams","URLSearchParams","toString","getCacheKey","method","pathParamValues","map","name","queryParamValues","keys","sort","v","isStreamingResponse","response","contentType","headers","get","subtype","isGetHook","hook","isMutatorHook","isStore","obj","ClientBuilder","publicConfig","fragmentConfig","fetcherConfig","cache","Map","createFetcherStore","createMutatorStore","invalidateKeys","constructor","cacheLifetime","Infinity","cacheEntries","createStore","input","factory","query","getFetcher","fetcher","defaultOptions","getFetcherOptions","#getFetcher","type","globalThis","fetch","bind","#getFetcherOptions","options","createHook","route","routes","find","r","outputSchema","createRouteQueryHook","createMutator","onInvalidate","createRouteQueryMutator","#createRouteQueryHook","String","fetcherOptions","useFetcherOnServer","useOnServer","callServerSideHandler","handler","fromSSRContext","executeQuery","window","url","error","fromUnknownFetchError","ok","fromResponse","store","args","isStreaming","json","getReader","cancel","items","setData","mutate","setError","set","onErrorRetry","dedupeTime","streamingPromise","#createRouteQueryMutator","invalidate","executeMutateQuery","preparedBody","bodyHeaders","requestOptions","mutatorStore","data","status","firstItem","loading","length","onError","console","mutateQuery","#invalidate","prefix","k","join","startsWith","createClientBuilder","definition","routesOrFactories","authorFetcherConfig","deps","services","serviceDeps","mergedFetcherConfig","column","idColumn","referenceColumn","schema","Column","WebhookDeliveryIdentity","WebhookAuthConfig","WebhookVerificationConfig","JsonColumn","T","jsonColumn","apiSchema","s","addTable","t","addColumn","nullable","defaultTo","b","now","table","createIndex","unique","alterTable","defineFragment","HookContext","HookFn","TypedUnitOfWork","ApiFragmentConfig","BaseApiFragmentConfig","ApiRequestInput","WebhookEndpoint","apiSchema","ApiConnectionHookSnapshot","slug","name","baseUrl","authMode","status","ApiConnectionChangedPayload","connectionId","connection","ApiConnectionDeletedPayload","previous","ApiConnectionReadinessChangedPayload","ready","ApiConnectionReadinessChange","InternalAuthExpiredPayload","expiresAt","InternalWebhookReceivedPayload","endpointId","deliveryId","hookId","receivedAt","headers","Record","query","rawBody","body","contentType","WebhookEndpointHookSnapshot","authConfig","verification","deliveryIdentity","secretRefs","WebhookEndpointChangedPayload","change","endpoint","previousStatus","WebhookReceivedPayload","ApiFragmentHooksConfig","onConnectionChanged","payload","context","Promise","onConnectionDeleted","onConnectionReadinessChanged","onWebhookEndpointChanged","onWebhookReceived","ApiHooksMap","onAuthExpired","ApiUow","apiFragmentDefinition","extend","x","providesBaseService","build","textEncoder","TextEncoder","textDecoder","TextDecoder","HmacAlgorithm","hmacHashName","algorithm","sha1","sha256","sha512","toArrayBuffer","bytes","Uint8Array","ArrayBuffer","copy","byteLength","set","buffer","utf8Bytes","value","encode","assertAscii","label","index","length","charCodeAt","Error","asciiToBase64","btoa","bytesToBase64","binary","byte","String","fromCharCode","bytesToBase64Url","replace","bytesToHex","map","toString","padStart","join","decodeHex","normalized","trim","test","Number","parseInt","slice","decodeBase64","encoding","normalizeBase64","atob","decodeBase64ToText","decode","paddingLength","repeat","randomBase64Url","data","crypto","getRandomValues","sha256Bytes","subtle","digest","sha256Base64Url","importHmacKey","input","secret","importKey","name","hash","signHmacBytes","payload","key","sign","verifyHmacSignature","signature","verify","digestEqual","first","second","firstDigest","secondDigest","Promise","all","equalLengthBytes","diff","timingSafeEqualText","timingSafeEqualBytes","z","decodeBase64","decodeBase64ToText","decodeHex","timingSafeEqualText","verifySecretText","utf8Bytes","verifyHmacSignature","secretRefSchema","string","trim","min","requestValueNameSchema","webhookAuthConfigSchema","discriminatedUnion","object","type","literal","tokenRef","location","enum","name","secretRef","usernameRef","passwordRef","algorithm","signature","encoding","prefix","optional","signedPayload","timestampHeader","delimiter","toleranceSeconds","number","int","positive","WebhookAuthConfig","infer","WebhookAuthType","WebhookAuthSecretRef","WebhookSecretResolver","get","ref","Promise","WebhookAuthFailureReason","WebhookAuthResult","ok","reason","SensitiveRequestValue","WebhookAuthVerificationContext","request","Request","now","Date","secrets","rawBodyBytes","Uint8Array","WebhookAuthVerifier","TConfig","requiredSecretRefs","config","sensitiveRequestValues","verify","context","WebhookAuthVerifierRegistry","Extract","TType","VerifyWebhookAuthInput","getHeaderAuthorizationCredential","scheme","header","headers","headerScheme","rest","split","toLowerCase","length","join","getRequestValue","URL","url","searchParams","WebhookAuthFailure","ResolvedSecret","secret","requireSecret","noneVerifier","bearerVerifier","token","apiKeyVerifier","credential","basicVerifier","username","password","encodedCredential","decodedCredential","separatorIndex","indexOf","actualUsername","slice","actualPassword","hmacVerifier","signatureValue","normalizedSignature","normalizeSignature","buildSignedPayload","providedSignature","decodeSignature","payload","webhookAuthVerifiers","none","bearer","apiKey","basic","hmac","verifyWebhookAuth","verifier","getWebhookAuthVerifier","clone","arrayBuffer","getWebhookAuthSecretRefs","getSensitiveWebhookAuthValues","timestamp","timestampMs","parseWebhookTimestampMs","toleranceMs","Math","abs","getTime","concatBytes","trimmed","startsWith","withoutPrefix","value","normalized","test","numeric","Number","isSafeInteger","first","second","output","set","timingSafeEqualBytes","z","webhookRequestValueNameSchema","string","trim","min","webhookRequestValueSourceSchema","discriminatedUnion","object","type","literal","name","path","array","webhookVerificationPredicateSchema","source","value","webhookVerificationConfigSchema","method","enum","when","response","WebhookRequestValueSource","infer","WebhookVerificationConfig","WebhookJsonBodyResult","ok","body","Record","reason","WebhookRequestValueResult","WebhookRequestValues","jsonBody","read","WebhookVerificationResult","createWebhookRequestValues","input","headers","Headers","query","URLSearchParams","rawBody","parsedJsonBody","JSON","parse","isJsonObject","requestValue","get","segment","evaluateWebhookVerification","config","requestValues","predicateValue","matches","responseValue","length","Array","isArray","z","webhookAuthConfigSchema","webhookVerificationConfigSchema","ApiFragmentConfig","allowedBaseUrls","url","URL","allowedOAuthRedirectUris","fetch","tokenEndpointAuthMethodSchema","enum","authConfigSchema","discriminatedUnion","object","type","literal","token","string","min","username","password","tokenEndpoint","clientId","clientSecret","scopes","array","optional","audience","tokenEndpointAuthMethod","default","authorizationEndpoint","extraAuthorizationParams","record","extraTokenParams","apiConnectionSlugSchema","regex","createApiConnectionInputSchema","name","baseUrl","auth","apiConnectionOutputSchema","slug","nullable","authMode","status","createdAt","union","date","updatedAt","apiConnectionsPageSchema","connections","cursor","describe","apiCredentialsPresenceSchema","apiAuthStatusSchema","mode","credentials","state","apiOAuthPendingSchema","pending","authorizationUrl","expiresAt","tokenAuthInputSchema","API_OAUTH_REDIRECT_URI_QUERY_PARAMETER","oauthRedirectUriSchema","refine","value","protocol","oauthStartInputSchema","discardTokens","boolean","apiRequestBodySchema","unknown","apiRequestInputSchema","method","path","query","headers","body","timeoutMs","number","int","positive","max","apiResponseBodySchema","null","apiHttpResponseSchema","statusText","apiRequestOutputSchema","ok","response","error","code","message","webhookSecretRefSchema","trim","webhookRequestValueNameSchema","webhookDeliveryIdentitySchema","webhookEndpointAuthInputSchema","location","secret","algorithm","signature","encoding","prefix","signedPayload","timestampHeader","delimiter","toleranceSeconds","webhookEndpointStatusSchema","webhookRejectionCodeSchema","webhookDeliveryEvidenceSchema","lastAcceptedAt","lastRejection","receivedAt","webhookEndpointOutputSchema","id","authConfig","verification","deliveryIdentity","secretRefs","deliveries","createWebhookEndpointInputSchema","updateWebhookEndpointInputSchema","AuthConfig","infer","ApiConnectionInput","ApiConnection","ApiConnectionsPage","ApiAuthStatus","ApiOAuthPending","ApiRequestBody","ApiRequestInput","ApiResponseBody","ApiHttpResponse","ApiRequestOutput","WebhookDeliveryIdentity","WebhookEndpointAuthInput","WebhookEndpointInput","UpdateWebhookEndpointInput","WebhookEndpoint","WebhookRejectionCode","WebhookDeliveryEvidence","Cursor","z","defineRoutes","TypedUnitOfWork","API_OAUTH_REDIRECT_URI_QUERY_PARAMETER","apiAuthStatusSchema","apiConnectionOutputSchema","apiConnectionsPageSchema","apiOAuthPendingSchema","apiRequestInputSchema","apiRequestOutputSchema","createApiConnectionInputSchema","createWebhookEndpointInputSchema","oauthStartInputSchema","tokenAuthInputSchema","updateWebhookEndpointInputSchema","webhookEndpointOutputSchema","WebhookDeliveryIdentity","WebhookEndpoint","WebhookEndpointAuthInput","WebhookRejectionCode","apiFragmentDefinition","ApiHooksMap","WebhookEndpointHookSnapshot","WebhookAuthConfig","WebhookRequestValues","WebhookVerificationConfig","webhookEndpointsOutputSchema","object","endpoints","array","oauthStartOutputSchema","authorizationUrl","string","state","oauthCallbackOutputSchema","authenticated","boolean","mode","WebhookSecretDraft","ref","payload","WebhookDeliveryIdentityResult","ok","deliveryId","reason","WebhookRequestFailure","code","Exclude","WebhookReceiveResult","type","body","apiRoutesFactory","create","services","defineRoute","config","method","path","inputSchema","outputSchema","handler","errorCodes","queryParameters","createClientBuilder","FragnoPublicClientConfig","apiFragmentDefinition","apiRoutesFactory","apiRoutes","const","createApiFragmentClients","fragnoConfig","builder","useConnections","createHook","useConnection","useAuthStatus","usePendingOAuth","createConnection","createMutator","deleteConnection","setBearerToken","startOAuth","deleteAuth","request","useWebhookEndpoints","useWebhookEndpoint","createWebhookEndpoint","updateWebhookEndpoint","deleteWebhookEndpoint"],"sources":["../../../../fragno/dist/api/internal/path.js","../../../../fragno/dist/api/request-body.js","../../../../fragno/dist/api/internal/route.js","../../../../fragno/dist/api/error.js","../../../../fragno/dist/api/request-input-context.js","../../../../fragno/dist/api/internal/response-stream.js","../../../../fragno/dist/api/request-output-context.js","../../../../fragno/dist/api/route.js","../../../../fragno/dist/util/content-type.js","../../../../fragno/dist/util/nanostores.js","../../../../../node_modules/.pnpm/nanostores@1.3.0/node_modules/nanostores/task/index.js","../../../../../node_modules/.pnpm/nanostores@1.3.0/node_modules/nanostores/clean-stores/index.js","../../../../../node_modules/.pnpm/nanostores@1.3.0/node_modules/nanostores/atom/index.js","../../../../../node_modules/.pnpm/nanostores@1.3.0/node_modules/nanostores/lifecycle/index.js","../../../../../node_modules/.pnpm/nanostores@1.3.0/node_modules/nanostores/warn/index.js","../../../../../node_modules/.pnpm/nanostores@1.3.0/node_modules/nanostores/computed/index.js","../../../../../node_modules/.pnpm/nanostores@1.3.0/node_modules/nanostores/map/index.js","../../../../fragno/dist/util/ssr.js","../../../../fragno/dist/client/client-error.js","../../../../fragno/dist/client/internal/fetcher-merge.js","../../../../fragno/dist/client/internal/ndjson-streaming.js","../../../../../node_modules/.pnpm/nanoevents@9.1.0/node_modules/nanoevents/index.js","../../../../../node_modules/.pnpm/@nanostores+query@0.3.4_nanostores@1.3.0/node_modules/@nanostores/query/dist/nanoquery.js","../../../../fragno/dist/client/client.js","../../../src/schema.ts","../../../src/definition.ts","../../../src/crypto.ts","../../../src/webhooks/auth.ts","../../../src/webhooks/verification.ts","../../../src/api-types.ts","../../../src/routes.ts","../../../src/client/client.ts"],"sourcesContent":["//#region src/api/internal/path.ts\n/**\n* Extract parameter names from a path pattern at runtime.\n* Examples:\n* - \"/users/:id\" => [\"id\"]\n* - \"/files/**\" => [\"**\"]\n* - \"/files/**:rest\" => [\"rest\"]\n*/\nfunction extractPathParams(pathPattern) {\n\tconst segments = pathPattern.split(\"/\").filter((s) => s.length > 0);\n\tconst names = [];\n\tfor (const segment of segments) {\n\t\tif (segment.startsWith(\":\")) {\n\t\t\tnames.push(segment.slice(1));\n\t\t\tcontinue;\n\t\t}\n\t\tif (segment === \"**\") {\n\t\t\tnames.push(\"**\");\n\t\t\tcontinue;\n\t\t}\n\t\tif (segment.startsWith(\"**:\")) {\n\t\t\tnames.push(segment.slice(3));\n\t\t\tcontinue;\n\t\t}\n\t}\n\treturn names;\n}\n/**\n* Build a concrete path by replacing placeholders in a path pattern with values.\n*\n* Supports the same placeholder syntax as the matcher:\n* - Named parameter \":name\" is URL-encoded as a single segment\n* - Anonymous wildcard \"**\" inserts the remainder as-is (slashes preserved)\n* - Named wildcard \"**:name\" inserts the remainder from the named key\n*\n* Examples:\n* - buildPath(\"/users/:id\", { id: \"123\" }) => \"/users/123\"\n* - buildPath(\"/files/**\", { \"**\": \"a/b\" }) => \"/files/a/b\"\n* - buildPath(\"/files/**:rest\", { rest: \"a/b\" }) => \"/files/a/b\"\n*/\nfunction buildPath(pathPattern, params) {\n\tconst patternSegments = pathPattern.split(\"/\");\n\tconst builtSegments = [];\n\tfor (const segment of patternSegments) {\n\t\tif (segment.length === 0) {\n\t\t\tbuiltSegments.push(\"\");\n\t\t\tcontinue;\n\t\t}\n\t\tif (segment.startsWith(\":\")) {\n\t\t\tconst name = segment.slice(1);\n\t\t\tconst value = params[name];\n\t\t\tif (value === void 0) throw new Error(`Missing value for path parameter :${name}`);\n\t\t\tbuiltSegments.push(encodeURIComponent(value));\n\t\t\tcontinue;\n\t\t}\n\t\tif (segment === \"**\") {\n\t\t\tconst value = params[\"**\"];\n\t\t\tif (value === void 0) throw new Error(\"Missing value for path wildcard **\");\n\t\t\tbuiltSegments.push(value);\n\t\t\tcontinue;\n\t\t}\n\t\tif (segment.startsWith(\"**:\")) {\n\t\t\tconst name = segment.slice(3);\n\t\t\tconst value = params[name];\n\t\t\tif (value === void 0) throw new Error(`Missing value for path wildcard **:${name}`);\n\t\t\tbuiltSegments.push(value);\n\t\t\tcontinue;\n\t\t}\n\t\tbuiltSegments.push(segment);\n\t}\n\treturn builtSegments.join(\"/\");\n}\n//#endregion\nexport { buildPath, extractPathParams };\n\n//# sourceMappingURL=path.js.map","//#region src/api/request-body.ts\nconst isBinaryRequestBody = (body) => body instanceof ReadableStream || body instanceof Blob || body instanceof ArrayBuffer || ArrayBuffer.isView(body);\nconst containsFileBody = (value) => {\n\tif (value instanceof File || value instanceof Blob || value instanceof FormData) return true;\n\treturn typeof value === \"object\" && value !== null && Object.values(value).some((entry) => entry instanceof File || entry instanceof Blob || entry instanceof FormData);\n};\nconst appendFormDataValue = (formData, key, value) => {\n\tif (value instanceof File) formData.append(key, value, value.name);\n\telse if (value instanceof Blob) formData.append(key, value);\n\telse if (value !== void 0 && value !== null) formData.append(key, typeof value === \"string\" ? value : JSON.stringify(value));\n};\nconst prepareMultipartBody = (body) => {\n\tif (body instanceof FormData) return body;\n\tconst formData = new FormData();\n\tif (body instanceof File) {\n\t\tformData.append(\"file\", body, body.name);\n\t\treturn formData;\n\t}\n\tif (body instanceof Blob) {\n\t\tformData.append(\"file\", body);\n\t\treturn formData;\n\t}\n\tif (typeof body === \"object\" && body !== null) {\n\t\tfor (const [key, value] of Object.entries(body)) appendFormDataValue(formData, key, value);\n\t\treturn formData;\n\t}\n\tthrow new TypeError(\"Multipart routes require FormData, File, Blob, or an object body.\");\n};\nconst prepareRouteRequestBody = (body, contentType = \"application/json\") => {\n\tif (body === void 0) return {\n\t\tbody: void 0,\n\t\tcontentType: void 0\n\t};\n\tswitch (contentType) {\n\t\tcase \"application/json\": return {\n\t\t\tbody: JSON.stringify(body),\n\t\t\tcontentType\n\t\t};\n\t\tcase \"multipart/form-data\": return {\n\t\t\tbody: prepareMultipartBody(body),\n\t\t\tcontentType: null\n\t\t};\n\t\tcase \"application/octet-stream\":\n\t\t\tif (!isBinaryRequestBody(body)) throw new TypeError(\"Octet-stream routes require Blob, ArrayBuffer, ArrayBufferView, or ReadableStream bodies.\");\n\t\t\treturn {\n\t\t\t\tbody,\n\t\t\t\tcontentType\n\t\t\t};\n\t\tdefault: throw new TypeError(\"Unsupported route content type.\");\n\t}\n};\nconst prepareClientRequestBody = (body, contentType) => {\n\tif (body === void 0) return {\n\t\tbody: void 0,\n\t\tcontentType: void 0\n\t};\n\tif (contentType === \"application/octet-stream\") {\n\t\tif (!isBinaryRequestBody(body)) throw new TypeError(\"Octet-stream routes require Blob, ArrayBuffer, ArrayBufferView, or ReadableStream bodies.\");\n\t\treturn {\n\t\t\tbody,\n\t\t\tcontentType\n\t\t};\n\t}\n\tif (body instanceof FormData || body instanceof File || body instanceof Blob) return {\n\t\tbody: prepareMultipartBody(body),\n\t\tcontentType: null\n\t};\n\tif (containsFileBody(body)) return {\n\t\tbody: prepareMultipartBody(body),\n\t\tcontentType: null\n\t};\n\treturn {\n\t\tbody: JSON.stringify(body),\n\t\tcontentType: \"application/json\"\n\t};\n};\nconst prepareInferredRequestBody = (body) => {\n\tif (body === void 0) return {\n\t\tbody: void 0,\n\t\tcontentType: void 0\n\t};\n\tif (typeof body === \"string\" || body instanceof URLSearchParams || body instanceof FormData || isBinaryRequestBody(body)) return {\n\t\tbody,\n\t\tcontentType: null\n\t};\n\treturn {\n\t\tbody: JSON.stringify(body),\n\t\tcontentType: \"application/json\"\n\t};\n};\nconst applyPreparedRequestBodyContentType = (headers, preparedBody) => {\n\tif (preparedBody.contentType === null) headers.delete(\"content-type\");\n\telse if (preparedBody.contentType !== void 0) headers.set(\"content-type\", preparedBody.contentType);\n};\nconst createRequestInitWithBody = (method, headers, body, options = {}) => {\n\tconst requestInit = {\n\t\t...options,\n\t\tmethod,\n\t\theaders,\n\t\tbody\n\t};\n\tif (body instanceof ReadableStream) requestInit.duplex = \"half\";\n\treturn requestInit;\n};\n//#endregion\nexport { applyPreparedRequestBodyContentType, createRequestInitWithBody, prepareClientRequestBody, prepareInferredRequestBody, prepareRouteRequestBody };\n\n//# sourceMappingURL=request-body.js.map","//#region src/api/internal/route.ts\nfunction getMountRoute(opts) {\n\tconst mountRoute = opts.mountRoute ?? `/api/${opts.name}`;\n\tif (mountRoute.endsWith(\"/\")) return mountRoute.slice(0, -1);\n\treturn mountRoute;\n}\n//#endregion\nexport { getMountRoute };\n\n//# sourceMappingURL=route.js.map","//#region src/api/error.ts\nvar FragnoApiError = class extends Error {\n\t#status;\n\t#code;\n\tconstructor({ message, code }, status) {\n\t\tsuper(message);\n\t\tthis.name = \"FragnoApiError\";\n\t\tthis.#status = status;\n\t\tthis.#code = code;\n\t}\n\tget status() {\n\t\treturn this.#status;\n\t}\n\tget code() {\n\t\treturn this.#code;\n\t}\n\ttoResponse() {\n\t\treturn Response.json({\n\t\t\tmessage: this.message,\n\t\t\tcode: this.code\n\t\t}, { status: this.status });\n\t}\n};\nvar FragnoApiValidationError = class extends FragnoApiError {\n\tissues;\n\tconstructor(message, issues) {\n\t\tsuper({\n\t\t\tmessage,\n\t\t\tcode: \"FRAGNO_VALIDATION_ERROR\"\n\t\t}, 400);\n\t\tthis.name = \"FragnoApiValidationError\";\n\t\tthis.issues = issues;\n\t}\n\ttoResponse() {\n\t\treturn Response.json({\n\t\t\tmessage: this.message,\n\t\t\tissues: this.issues,\n\t\t\tcode: this.code\n\t\t}, { status: this.status });\n\t}\n};\n//#endregion\nexport { FragnoApiError, FragnoApiValidationError };\n\n//# sourceMappingURL=error.js.map","import { FragnoApiValidationError } from \"./error.js\";\n//#region src/api/request-input-context.ts\nvar RequestInputContext = class RequestInputContext {\n\t#path;\n\t#method;\n\t#pathParams;\n\t#searchParams;\n\t#headers;\n\t#body;\n\t#request;\n\t#parsedBody;\n\t#inputSchema;\n\t#shouldValidateInput;\n\tconstructor(config) {\n\t\tthis.#path = config.path;\n\t\tthis.#method = config.method;\n\t\tthis.#pathParams = config.pathParams;\n\t\tthis.#searchParams = config.searchParams;\n\t\tthis.#headers = config.headers;\n\t\tthis.#body = config.rawBody;\n\t\tthis.#request = config.request;\n\t\tthis.#parsedBody = config.parsedBody;\n\t\tthis.#inputSchema = config.inputSchema;\n\t\tthis.#shouldValidateInput = config.shouldValidateInput ?? true;\n\t}\n\t/**\n\t* Create a RequestContext from a Request object for server-side handling\n\t*/\n\tstatic async fromRequest(config) {\n\t\treturn new RequestInputContext({\n\t\t\tmethod: config.method,\n\t\t\tpath: config.path,\n\t\t\tpathParams: config.state.pathParams,\n\t\t\tsearchParams: config.state.searchParams,\n\t\t\theaders: config.state.headers,\n\t\t\trequest: config.request,\n\t\t\tparsedBody: config.state.body,\n\t\t\trawBody: config.rawBody,\n\t\t\tinputSchema: config.inputSchema,\n\t\t\tshouldValidateInput: config.shouldValidateInput\n\t\t});\n\t}\n\t/**\n\t* Create a RequestContext for server-side rendering contexts (no Request object)\n\t*/\n\tstatic fromSSRContext(config) {\n\t\treturn new RequestInputContext({\n\t\t\tmethod: config.method,\n\t\t\tpath: config.path,\n\t\t\tpathParams: config.pathParams,\n\t\t\tsearchParams: config.searchParams ?? new URLSearchParams(),\n\t\t\theaders: config.headers ?? new Headers(),\n\t\t\tparsedBody: \"body\" in config ? config.body : void 0,\n\t\t\tinputSchema: \"inputSchema\" in config ? config.inputSchema : void 0,\n\t\t\tshouldValidateInput: false\n\t\t});\n\t}\n\t/**\n\t* The HTTP method as string (e.g., `GET`, `POST`)\n\t*/\n\tget method() {\n\t\treturn this.#method;\n\t}\n\t/**\n\t* The matched route path (e.g., `/users/:id`)\n\t* @remarks `string`\n\t*/\n\tget path() {\n\t\treturn this.#path;\n\t}\n\t/**\n\t* Extracted path parameters as object (e.g., `{ id: '123' }`)\n\t* @remarks `Record<string, string>`\n\t*/\n\tget pathParams() {\n\t\treturn this.#pathParams;\n\t}\n\t/**\n\t* [URLSearchParams](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) object for query parameters\n\t* @remarks `URLSearchParams`\n\t*/\n\tget query() {\n\t\treturn this.#searchParams;\n\t}\n\t/**\n\t* [Headers](https://developer.mozilla.org/en-US/docs/Web/API/Headers) object for request headers\n\t* @remarks `Headers`\n\t*/\n\tget headers() {\n\t\treturn this.#headers;\n\t}\n\tget rawBody() {\n\t\treturn this.#body;\n\t}\n\tget request() {\n\t\treturn this.#request;\n\t}\n\t/**\n\t* Access the request body as FormData.\n\t*\n\t* Use this method when handling file uploads or multipart form submissions.\n\t* The request must have been sent with Content-Type: multipart/form-data.\n\t*\n\t* @throws Error if the request body is not FormData\n\t*\n\t* @example\n\t* ```typescript\n\t* defineRoute({\n\t* method: \"POST\",\n\t* path: \"/upload\",\n\t* async handler(ctx, res) {\n\t* const formData = ctx.formData();\n\t* const file = formData.get(\"file\") as File;\n\t* const description = formData.get(\"description\") as string;\n\t* // ... process file\n\t* }\n\t* });\n\t* ```\n\t*/\n\tformData() {\n\t\tif (!(this.#parsedBody instanceof FormData)) throw new Error(\"Request body is not FormData. Ensure the request was sent with Content-Type: multipart/form-data.\");\n\t\treturn this.#parsedBody;\n\t}\n\t/**\n\t* Check if the request body is FormData.\n\t*\n\t* Useful for routes that accept both JSON and FormData payloads.\n\t*\n\t* @example\n\t* ```typescript\n\t* defineRoute({\n\t* method: \"POST\",\n\t* path: \"/upload\",\n\t* async handler(ctx, res) {\n\t* if (ctx.isFormData()) {\n\t* const formData = ctx.formData();\n\t* // handle file upload\n\t* } else {\n\t* const json = await ctx.input.valid();\n\t* // handle JSON payload\n\t* }\n\t* }\n\t* });\n\t* ```\n\t*/\n\tisFormData() {\n\t\treturn this.#parsedBody instanceof FormData;\n\t}\n\t/**\n\t* Access the request body as a ReadableStream (application/octet-stream).\n\t*\n\t* @throws Error if the request body is not a ReadableStream\n\t*/\n\tbodyStream() {\n\t\tif (!(this.#parsedBody instanceof ReadableStream)) throw new Error(\"Request body is not a ReadableStream. Ensure the request was sent with Content-Type: application/octet-stream.\");\n\t\treturn this.#parsedBody;\n\t}\n\t/**\n\t* Check if the request body is a ReadableStream.\n\t*/\n\tisBodyStream() {\n\t\treturn this.#parsedBody instanceof ReadableStream;\n\t}\n\t/**\n\t* Input validation context (only if inputSchema is defined)\n\t* @remarks `InputContext`\n\t*/\n\tget input() {\n\t\tif (!this.#inputSchema) return;\n\t\treturn {\n\t\t\tschema: this.#inputSchema,\n\t\t\tvalid: async () => {\n\t\t\t\tif (!this.#shouldValidateInput) return this.#parsedBody;\n\t\t\t\treturn this.#validateInput();\n\t\t\t}\n\t\t};\n\t}\n\tasync #validateInput() {\n\t\tif (!this.#inputSchema) throw new Error(\"No input schema defined for this route\");\n\t\tif (this.#parsedBody instanceof FormData || this.#parsedBody instanceof Blob) throw new Error(\"Schema validation is only supported for JSON data, not FormData or Blob\");\n\t\tif (this.#parsedBody instanceof ReadableStream) throw new Error(\"Schema validation is only supported for JSON data, not FormData, Blob, or ReadableStream\");\n\t\tconst result = await this.#inputSchema[\"~standard\"].validate(this.#parsedBody);\n\t\tif (result.issues) throw new FragnoApiValidationError(\"Validation failed\", result.issues);\n\t\treturn result.value;\n\t}\n};\n//#endregion\nexport { RequestInputContext };\n\n//# sourceMappingURL=request-input-context.js.map","//#region src/api/internal/response-stream.ts\nvar ResponseStream = class {\n\t#writer;\n\t#encoder;\n\t#abortSubscribers = [];\n\t#responseReadable;\n\t#aborted = false;\n\t#abortPromise;\n\t#closed = false;\n\t/**\n\t* Whether the stream has been aborted.\n\t*/\n\tget aborted() {\n\t\treturn this.#aborted;\n\t}\n\t/**\n\t* Whether the stream has been closed normally.\n\t*/\n\tget closed() {\n\t\treturn this.#closed;\n\t}\n\t/**\n\t* The readable stream that the response is piped to.\n\t*/\n\tget responseReadable() {\n\t\treturn this.#responseReadable;\n\t}\n\tconstructor(writable, readable) {\n\t\tthis.#writer = writable.getWriter();\n\t\tthis.#encoder = new TextEncoder();\n\t\tconst reader = readable.getReader();\n\t\tthis.#abortSubscribers.push(async () => {\n\t\t\tawait reader.cancel();\n\t\t});\n\t\tthis.#responseReadable = new ReadableStream({\n\t\t\tasync pull(controller) {\n\t\t\t\tconst { done, value } = await reader.read();\n\t\t\t\tif (done) controller.close();\n\t\t\t\telse controller.enqueue(value);\n\t\t\t},\n\t\t\tcancel: () => this.abort()\n\t\t});\n\t}\n\tasync writeRaw(input) {\n\t\ttry {\n\t\t\tif (typeof input === \"string\") input = this.#encoder.encode(input);\n\t\t\tawait this.#writer.write(input);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\tasync write(input) {\n\t\tawait this.writeRaw(JSON.stringify(input) + \"\\n\");\n\t}\n\tsleep(ms) {\n\t\treturn new Promise((resolve) => {\n\t\t\tsetTimeout(resolve, ms);\n\t\t});\n\t}\n\tasync close() {\n\t\ttry {\n\t\t\tawait this.#writer.close();\n\t\t} catch {} finally {\n\t\t\tthis.#closed = true;\n\t\t}\n\t}\n\tonAbort(listener) {\n\t\tthis.#abortSubscribers.push(listener);\n\t}\n\t/**\n\t* Abort the stream.\n\t* You can call this method when stream is aborted by external event.\n\t*/\n\tabort() {\n\t\tif (!this.#abortPromise) {\n\t\t\tthis.#aborted = true;\n\t\t\tthis.#abortPromise = Promise.allSettled(this.#abortSubscribers.map(async (subscriber) => subscriber())).then((results) => {\n\t\t\t\tconst errors = [];\n\t\t\t\tfor (const result of results) if (result.status === \"rejected\") errors.push(result.reason);\n\t\t\t\tif (errors.length > 0) throw new AggregateError(errors, \"Failed to abort response stream.\");\n\t\t\t});\n\t\t}\n\t\treturn this.#abortPromise;\n\t}\n};\n//#endregion\nexport { ResponseStream };\n\n//# sourceMappingURL=response-stream.js.map","import { ResponseStream } from \"./internal/response-stream.js\";\n//#region src/api/request-output-context.ts\n/**\n* Utility function to merge headers from multiple sources.\n* Later headers override earlier ones.\n*/\nfunction mergeHeaders(...headerSources) {\n\tconst mergedHeaders = new Headers();\n\tfor (const headerSource of headerSources) {\n\t\tif (!headerSource) continue;\n\t\tif (headerSource instanceof Headers) for (const [key, value] of headerSource.entries()) mergedHeaders.set(key, value);\n\t\telse if (Array.isArray(headerSource)) for (const [key, value] of headerSource) mergedHeaders.set(key, value);\n\t\telse for (const [key, value] of Object.entries(headerSource)) mergedHeaders.set(key, value);\n\t}\n\treturn mergedHeaders;\n}\nvar OutputContext = class {\n\t#runJsonStreamCallback;\n\tconstructor(options = {}) {\n\t\tthis.#runJsonStreamCallback = options.runJsonStreamCallback;\n\t}\n\t/**\n\t* Creates an error response.\n\t*\n\t* Shortcut for `throw new FragnoApiError(...)`\n\t*/\n\terror = ({ message, code }, initOrStatus, headers) => {\n\t\tif (typeof initOrStatus === \"undefined\") return Response.json({\n\t\t\tmessage,\n\t\t\tcode\n\t\t}, {\n\t\t\tstatus: 500,\n\t\t\theaders\n\t\t});\n\t\tif (typeof initOrStatus === \"number\") return Response.json({\n\t\t\tmessage,\n\t\t\tcode\n\t\t}, {\n\t\t\tstatus: initOrStatus,\n\t\t\theaders\n\t\t});\n\t\tconst mergedHeaders = mergeHeaders(initOrStatus.headers, headers);\n\t\treturn Response.json({\n\t\t\tmessage,\n\t\t\tcode\n\t\t}, {\n\t\t\tstatus: initOrStatus.status,\n\t\t\theaders: mergedHeaders\n\t\t});\n\t};\n\tempty = (initOrStatus, headers) => {\n\t\tconst defaultHeaders = {};\n\t\tif (typeof initOrStatus === \"undefined\") {\n\t\t\tconst mergedHeaders = mergeHeaders(defaultHeaders, headers);\n\t\t\treturn new Response(null, {\n\t\t\t\tstatus: 201,\n\t\t\t\theaders: mergedHeaders\n\t\t\t});\n\t\t}\n\t\tif (typeof initOrStatus === \"number\") {\n\t\t\tconst mergedHeaders = mergeHeaders(defaultHeaders, headers);\n\t\t\treturn new Response(null, {\n\t\t\t\tstatus: initOrStatus,\n\t\t\t\theaders: mergedHeaders\n\t\t\t});\n\t\t}\n\t\tconst mergedHeaders = mergeHeaders(defaultHeaders, initOrStatus.headers, headers);\n\t\treturn new Response(null, {\n\t\t\tstatus: initOrStatus.status,\n\t\t\theaders: mergedHeaders\n\t\t});\n\t};\n\tjson = (object, initOrStatus, headers) => {\n\t\tif (typeof initOrStatus === \"undefined\") return Response.json(object, {\n\t\t\tstatus: 200,\n\t\t\theaders\n\t\t});\n\t\tif (typeof initOrStatus === \"number\") return Response.json(object, {\n\t\t\tstatus: initOrStatus,\n\t\t\theaders\n\t\t});\n\t\tconst mergedHeaders = mergeHeaders(initOrStatus.headers, headers);\n\t\treturn Response.json(object, {\n\t\t\tstatus: initOrStatus.status,\n\t\t\theaders: mergedHeaders\n\t\t});\n\t};\n\tjsonStream = (cb, { onError, headers } = {}) => {\n\t\tconst defaultHeaders = {\n\t\t\t\"content-type\": \"application/x-ndjson; charset=utf-8\",\n\t\t\t\"transfer-encoding\": \"chunked\",\n\t\t\t\"cache-control\": \"no-cache\"\n\t\t};\n\t\tconst { readable, writable } = new TransformStream();\n\t\tconst stream = new ResponseStream(writable, readable);\n\t\tconst runStreamCallback = async () => {\n\t\t\ttry {\n\t\t\t\tawait cb(stream);\n\t\t\t} catch (e) {\n\t\t\t\tif (e === void 0) {} else if (e instanceof Error && onError) await onError(e, stream);\n\t\t\t\telse console.error(e);\n\t\t\t} finally {\n\t\t\t\tawait stream.close();\n\t\t\t}\n\t\t};\n\t\ttry {\n\t\t\tPromise.resolve(this.#runJsonStreamCallback ? this.#runJsonStreamCallback(runStreamCallback) : runStreamCallback()).catch(async (error) => {\n\t\t\t\tconsole.error(error);\n\t\t\t\tawait stream.close();\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error(error);\n\t\t\tstream.close();\n\t\t}\n\t\treturn new Response(stream.responseReadable, {\n\t\t\tstatus: 200,\n\t\t\theaders: mergeHeaders(defaultHeaders, headers)\n\t\t});\n\t};\n};\nvar RequestOutputContext = class extends OutputContext {\n\t#outputSchema;\n\tconstructor(outputSchema, options) {\n\t\tsuper(options);\n\t\tthis.#outputSchema = outputSchema;\n\t}\n};\n//#endregion\nexport { OutputContext, RequestOutputContext };\n\n//# sourceMappingURL=request-output-context.js.map","//#region src/api/route.ts\n/**\n* Helper to resolve route factories into routes\n* @internal\n*/\nfunction resolveRouteFactories(context, routesOrFactories) {\n\tconst routes = [];\n\tfor (const item of routesOrFactories) if (typeof item === \"function\") {\n\t\tconst factoryRoutes = item(context);\n\t\troutes.push(...factoryRoutes);\n\t} else routes.push(item);\n\treturn routes;\n}\nfunction defineRoute(config) {\n\treturn config;\n}\nfunction defineRoutes(_definition) {\n\treturn { create: (fn) => {\n\t\treturn (ctx) => {\n\t\t\treturn fn({\n\t\t\t\t...ctx,\n\t\t\t\tdefineRoute\n\t\t\t});\n\t\t};\n\t} };\n}\n//#endregion\nexport { defineRoute, defineRoutes, resolveRouteFactories };\n\n//# sourceMappingURL=route.js.map","//#region src/util/content-type.ts\n/**\n* Parses a content-type header string into its components\n*\n* @param contentType - The content-type header value to parse\n* @returns A ParsedContentType object or null if the input is invalid\n*\n* @example\n* ```ts\n* const { type, subtype, mediaType, parameters }\n* = parseContentType(\"application/json; charset=utf-8\");\n* console.assert(type === \"application\");\n* console.assert(subtype === \"json\");\n* console.assert(mediaType === \"application/json\");\n* console.assert(parameters[\"charset\"] === \"utf-8\");\n*/\nfunction parseContentType(contentType) {\n\tif (!contentType || typeof contentType !== \"string\") return null;\n\tconst trimmed = contentType.trim();\n\tif (!trimmed) return null;\n\tconst parts = trimmed.split(\";\").map((part) => part.trim());\n\tconst mediaType = parts[0];\n\tif (!mediaType) return null;\n\tconst typeParts = mediaType.split(\"/\");\n\tif (typeParts.length !== 2) return null;\n\tconst [type, subtype] = typeParts.map((part) => part.trim().toLowerCase());\n\tif (!type || !subtype) return null;\n\tconst parameters = {};\n\tfor (let i = 1; i < parts.length; i++) {\n\t\tconst param = parts[i];\n\t\tconst equalIndex = param.indexOf(\"=\");\n\t\tif (equalIndex > 0) {\n\t\t\tconst key = param.slice(0, equalIndex).trim().toLowerCase();\n\t\t\tlet value = param.slice(equalIndex + 1).trim();\n\t\t\tif (value.startsWith(\"\\\"\") && value.endsWith(\"\\\"\")) value = value.slice(1, -1);\n\t\t\tif (key) parameters[key] = value;\n\t\t}\n\t}\n\treturn {\n\t\ttype,\n\t\tsubtype,\n\t\tmediaType: `${type}/${subtype}`,\n\t\tparameters\n\t};\n}\n//#endregion\nexport { parseContentType };\n\n//# sourceMappingURL=content-type.js.map","//#region src/util/nanostores.ts\n/**\n* Normalizes a value that could be a plain value, an Atom, or a Vue Ref to a plain value.\n*/\nfunction unwrapAtom(value) {\n\tif (value && typeof value === \"object\" && \"get\" in value && typeof value.get === \"function\") return value.get();\n\treturn value;\n}\n/**\n* Normalizes an object where values can be plain values, Atoms, or Vue Refs.\n* Returns a new object with all values normalized to plain values.\n*/\nfunction unwrapObject(params) {\n\tif (!params) return;\n\treturn Object.fromEntries(Object.entries(params).map(([key, value]) => [key, unwrapAtom(value)]));\n}\nfunction isReadableAtom(value) {\n\tif (!value) return false;\n\tif (typeof value !== \"object\" || value === null) return false;\n\tif (!(\"get\" in value) || typeof value.get !== \"function\") return false;\n\tif (!(\"lc\" in value) || typeof value.lc !== \"number\") return false;\n\tif (!(\"notify\" in value) || typeof value.notify !== \"function\") return false;\n\tif (!(\"off\" in value) || typeof value.off !== \"function\") return false;\n\tif (!(\"subscribe\" in value) || typeof value.subscribe !== \"function\") return false;\n\tif (!(\"value\" in value)) return false;\n\treturn true;\n}\n//#endregion\nexport { isReadableAtom, unwrapAtom, unwrapObject };\n\n//# sourceMappingURL=nanostores.js.map","let tasks = 0\nlet resolves = []\n\nexport function startTask() {\n tasks += 1\n return () => {\n tasks -= 1\n if (tasks === 0) {\n let prevResolves = resolves\n resolves = []\n for (let i of prevResolves) i()\n }\n }\n}\n\nexport function task(cb) {\n let endTask = startTask()\n let promise = cb().finally(endTask)\n promise.t = true\n return promise\n}\n\nexport function allTasks() {\n if (tasks === 0) {\n return Promise.resolve()\n } else {\n return new Promise(resolve => {\n resolves.push(resolve)\n })\n }\n}\n\nexport function cleanTasks() {\n tasks = 0\n}\n","import { cleanTasks } from '../task/index.js'\n\nexport const clean = Symbol('clean')\n\nexport const cleanStores = (...stores) => {\n if (process.env.NODE_ENV === 'production') {\n throw new Error(\n 'cleanStores() can be used only during development or tests'\n )\n }\n cleanTasks()\n for (let $store of stores) {\n if ($store) {\n if ($store.mocked) delete $store.mocked\n if ($store[clean]) $store[clean]()\n }\n }\n}\n","import { clean } from '../clean-stores/index.js'\n\nlet listenerQueue = []\nlet lqIndex = 0\nconst QUEUE_ITEMS_PER_LISTENER = 4\n// Use globalThis.nanostoresGlobal to store epoch so all module instances share\n// the same counter. This fixes issues when Nano Store is bundled separately\n// in different parts of an application (e.g., tree-shaking separates core\n// from React), causing each bundle to have its own epoch instance.\nexport const nanostoresGlobal = (globalThis.nanostoresGlobal ||= { epoch: 0 })\n\n/* @__NO_SIDE_EFFECTS__ */\nexport const atom = initialValue => {\n let listeners = []\n let $atom = {\n get() {\n if (!$atom.lc) {\n $atom.listen(() => {})()\n }\n return $atom.value\n },\n init: initialValue,\n lc: 0,\n listen(listener) {\n $atom.lc = listeners.push(listener)\n\n return () => {\n for (\n let i = lqIndex + QUEUE_ITEMS_PER_LISTENER;\n i < listenerQueue.length;\n ) {\n if (listenerQueue[i] === listener) {\n listenerQueue.splice(i, QUEUE_ITEMS_PER_LISTENER)\n } else {\n i += QUEUE_ITEMS_PER_LISTENER\n }\n }\n\n let index = listeners.indexOf(listener)\n if (~index) {\n listeners.splice(index, 1)\n if (!--$atom.lc) $atom.off()\n }\n }\n },\n notify(oldValue, changedKey) {\n nanostoresGlobal.epoch++\n let runListenerQueue = !listenerQueue.length\n for (let listener of listeners) {\n listenerQueue.push(listener, $atom.value, oldValue, changedKey)\n }\n\n if (runListenerQueue) {\n for (\n lqIndex = 0;\n lqIndex < listenerQueue.length;\n lqIndex += QUEUE_ITEMS_PER_LISTENER\n ) {\n listenerQueue[lqIndex](\n listenerQueue[lqIndex + 1],\n listenerQueue[lqIndex + 2],\n listenerQueue[lqIndex + 3]\n )\n }\n listenerQueue.length = 0\n }\n },\n /* It will be called on last listener unsubscribing.\n We will redefine it in onMount and onStop. */\n off() {},\n set(newValue) {\n let oldValue = $atom.value\n if (oldValue !== newValue) {\n $atom.value = newValue\n $atom.notify(oldValue)\n }\n },\n subscribe(listener) {\n let unbind = $atom.listen(listener)\n listener($atom.value)\n return unbind\n },\n value: initialValue\n }\n\n if (process.env.NODE_ENV !== 'production') {\n $atom[clean] = () => {\n listeners = []\n $atom.lc = 0\n $atom.off()\n }\n }\n\n return $atom\n}\n\nexport const readonlyType = store => store\n","import { clean } from '../clean-stores/index.js'\n\nconst START = 0\nconst STOP = 1\nconst SET = 2\nconst NOTIFY = 3\nconst MOUNT = 5\nconst UNMOUNT = 6\nconst REVERT_MUTATION = 10\n\nexport let on = (object, listener, eventKey, mutateStore) => {\n object.events = object.events || {}\n if (!object.events[eventKey + REVERT_MUTATION]) {\n object.events[eventKey + REVERT_MUTATION] = mutateStore(eventProps => {\n // eslint-disable-next-line no-sequences\n object.events[eventKey].reduceRight((event, l) => (l(event), event), {\n shared: {},\n ...eventProps\n })\n })\n }\n object.events[eventKey] = object.events[eventKey] || []\n object.events[eventKey].push(listener)\n return () => {\n let currentListeners = object.events[eventKey]\n let index = currentListeners.indexOf(listener)\n currentListeners.splice(index, 1)\n if (!currentListeners.length) {\n delete object.events[eventKey]\n object.events[eventKey + REVERT_MUTATION]()\n delete object.events[eventKey + REVERT_MUTATION]\n }\n }\n}\n\nexport let onStart = ($store, listener) =>\n on($store, listener, START, runListeners => {\n let originListen = $store.listen\n $store.listen = arg => {\n if (!$store.lc && !$store.starting) {\n $store.starting = true\n runListeners()\n delete $store.starting\n }\n return originListen(arg)\n }\n return () => {\n $store.listen = originListen\n }\n })\n\nexport let onStop = ($store, listener) =>\n on($store, listener, STOP, runListeners => {\n let originOff = $store.off\n $store.off = () => {\n runListeners()\n originOff()\n }\n return () => {\n $store.off = originOff\n }\n })\n\nexport let onSet = ($store, listener) =>\n on($store, listener, SET, runListeners => {\n let originSet = $store.set\n let originSetKey = $store.setKey\n if ($store.setKey) {\n $store.setKey = (changed, changedValue) => {\n let isAborted\n let abort = () => {\n isAborted = true\n }\n\n runListeners({\n abort,\n changed,\n newValue: { ...$store.value, [changed]: changedValue }\n })\n if (!isAborted) return originSetKey(changed, changedValue)\n }\n }\n $store.set = newValue => {\n let isAborted\n let abort = () => {\n isAborted = true\n }\n\n runListeners({ abort, newValue })\n if (!isAborted) return originSet(newValue)\n }\n return () => {\n $store.set = originSet\n $store.setKey = originSetKey\n }\n })\n\nexport let onNotify = ($store, listener) =>\n on($store, listener, NOTIFY, runListeners => {\n let originNotify = $store.notify\n $store.notify = (oldValue, changed) => {\n let isAborted\n let abort = () => {\n isAborted = true\n }\n\n runListeners({ abort, changed, oldValue })\n if (!isAborted) return originNotify(oldValue, changed)\n }\n return () => {\n $store.notify = originNotify\n }\n })\n\nexport const STORE_UNMOUNT_DELAY = 1000\n\nexport let onMount = ($store, initialize) => {\n let listener = payload => {\n let destroy = initialize(payload)\n if (destroy) $store.events[UNMOUNT].push(destroy)\n }\n return on($store, listener, MOUNT, runListeners => {\n let originListen = $store.listen\n $store.listen = (...args) => {\n if (!$store.lc && !$store.active) {\n $store.active = true\n runListeners()\n }\n return originListen(...args)\n }\n\n let originOff = $store.off\n $store.events[UNMOUNT] = []\n $store.off = () => {\n originOff()\n setTimeout(() => {\n if ($store.active && !$store.lc) {\n $store.active = false\n for (let destroy of $store.events[UNMOUNT]) destroy()\n $store.events[UNMOUNT] = []\n }\n }, STORE_UNMOUNT_DELAY)\n }\n\n if (process.env.NODE_ENV !== 'production') {\n let originClean = $store[clean]\n $store[clean] = () => {\n for (let destroy of $store.events[UNMOUNT]) destroy()\n $store.events[UNMOUNT] = []\n $store.active = false\n originClean()\n }\n }\n\n return () => {\n $store.listen = originListen\n $store.off = originOff\n }\n })\n}\n","let warned = {}\n\nexport function warn(text) {\n if (!warned[text]) {\n warned[text] = true\n if (typeof console !== 'undefined' && console.warn) {\n console.groupCollapsed('Nano Stores: ' + text)\n console.trace('Source of deprecated call')\n console.groupEnd()\n }\n }\n}\n","import { atom, nanostoresGlobal } from '../atom/index.js'\nimport { onMount } from '../lifecycle/index.js'\nimport { warn } from '../warn/index.js'\n\nlet computedStore = (stores, cb, batched) => {\n if (!Array.isArray(stores)) stores = [stores]\n\n let previousArgs\n let currentEpoch\n let set = () => {\n if (currentEpoch === nanostoresGlobal.epoch) return\n currentEpoch = nanostoresGlobal.epoch\n let args = stores.map($store => $store.get())\n if (!previousArgs || args.some((arg, i) => arg !== previousArgs[i])) {\n previousArgs = args\n let value = cb(...args)\n if (value && value.then && value.t) {\n if (process.env.NODE_ENV !== 'production') {\n warn(\n 'Use @nanostores/async for async computed. We will remove Promise support in computed() in Nano Stores 2.0'\n )\n }\n value.then(asyncValue => {\n if (previousArgs === args) {\n // Prevent a stale set\n $computed.set(asyncValue)\n }\n })\n } else {\n $computed.set(value)\n currentEpoch = nanostoresGlobal.epoch\n }\n }\n }\n let $computed = atom(undefined)\n let get = $computed.get\n $computed.get = () => {\n set()\n return get()\n }\n\n let timer\n let run = batched\n ? () => {\n clearTimeout(timer)\n timer = setTimeout(set)\n }\n : set\n\n onMount($computed, () => {\n let unbinds = stores.map($store => $store.listen(run))\n set()\n return () => {\n for (let unbind of unbinds) unbind()\n }\n })\n\n return $computed\n}\n\n/* @__NO_SIDE_EFFECTS__ */\nexport const computed = (stores, fn) => computedStore(stores, fn)\n\n/* @__NO_SIDE_EFFECTS__ */\nexport const batched = (stores, fn) => computedStore(stores, fn, true)\n","import { atom } from '../atom/index.js'\n\n/* @__NO_SIDE_EFFECTS__ */\nexport const map = (initial = {}) => {\n let $map = atom(initial)\n\n $map.setKey = function (key, value) {\n let oldMap = $map.value\n if (typeof value === 'undefined' && key in $map.value) {\n $map.value = { ...$map.value }\n delete $map.value[key]\n $map.notify(oldMap, key)\n } else if ($map.value[key] !== value) {\n $map.value = {\n ...$map.value,\n [key]: value\n }\n $map.notify(oldMap, key)\n }\n }\n\n return $map\n}\n","import { allTasks } from \"nanostores\";\n//#region src/util/ssr.ts\nlet stores = [];\nfunction getStores() {\n\treturn stores;\n}\nfunction addStore(store) {\n\tstores.push(store);\n}\nfunction cleanStores() {\n\tstores = [];\n}\nlet clientInitialData;\nfunction hydrateFromWindow() {\n\tif (window?.__FRAGNO_INITIAL_DATA__) {\n\t\tclientInitialData = new Map(window.__FRAGNO_INITIAL_DATA__);\n\t\tdelete window.__FRAGNO_INITIAL_DATA__;\n\t\tconsole.warn(\"hydrateFromWindow\", { clientInitialData: Array.from(clientInitialData.entries()) });\n\t}\n}\nfunction getInitialData(key) {\n\tif (clientInitialData?.has(key)) {\n\t\tconst data = clientInitialData.get(key);\n\t\tclientInitialData.delete(key);\n\t\treturn data;\n\t}\n}\nfunction listenToStores() {\n\tfor (const store of getStores()) store.listen(() => {});\n}\nasync function getFinalStoreValues() {\n\tlistenToStores();\n\tawait allTasks();\n\tconst stores = getStores();\n\tconst storesInitialValue = /* @__PURE__ */ new Map();\n\tfor (const store of stores) {\n\t\tconst value = store.get();\n\t\tif (!value || !store.key || value.loading) continue;\n\t\tstoresInitialValue.set(store.key, value.data);\n\t}\n\treturn storesInitialValue;\n}\n//#endregion\nexport { addStore, cleanStores, getFinalStoreValues, getInitialData, getStores, hydrateFromWindow };\n\n//# sourceMappingURL=ssr.js.map","//#region src/client/client-error.ts\n/**\n* Base error class for all Fragno client errors.\n*/\nvar FragnoClientError = class extends Error {\n\t#code;\n\tconstructor(message, code, options = {}) {\n\t\tsuper(message, { cause: options.cause });\n\t\tthis.name = \"FragnoClientError\";\n\t\tthis.#code = code;\n\t}\n\tget code() {\n\t\treturn this.#code;\n\t}\n};\nvar FragnoClientFetchError = class extends FragnoClientError {\n\tconstructor(message, code, options = {}) {\n\t\tsuper(message, code, options);\n\t\tthis.name = \"FragnoClientFetchError\";\n\t}\n\tstatic fromUnknownFetchError(error) {\n\t\tif (!(error instanceof Error)) return new FragnoClientFetchNetworkError(\"Network request failed\", { cause: error });\n\t\tif (error.name === \"AbortError\") return new FragnoClientFetchAbortError(\"Request was aborted\", { cause: error });\n\t\treturn new FragnoClientFetchNetworkError(\"Network request failed\", { cause: error });\n\t}\n};\n/**\n* Error thrown when a network request fails (e.g., no internet connection, DNS failure).\n*/\nvar FragnoClientFetchNetworkError = class extends FragnoClientFetchError {\n\tconstructor(message = \"Network request failed\", options = {}) {\n\t\tsuper(message, \"NETWORK_ERROR\", options);\n\t\tthis.name = \"FragnoClientFetchNetworkError\";\n\t}\n};\n/**\n* Error thrown when a request is aborted (e.g., user cancels request, timeout).\n*/\nvar FragnoClientFetchAbortError = class extends FragnoClientFetchError {\n\tconstructor(message = \"Request was aborted\", options = {}) {\n\t\tsuper(message, \"ABORT_ERROR\", options);\n\t\tthis.name = \"FragnoClientFetchAbortError\";\n\t}\n};\n/**\n* Error thrown when the API result is unexpected, e.g. no json is returned.\n*/\nvar FragnoClientUnknownApiError = class extends FragnoClientError {\n\t#status;\n\tconstructor(message = \"Unknown API error\", status, options = {}) {\n\t\tsuper(message, \"UNKNOWN_API_ERROR\", options);\n\t\tthis.name = \"FragnoClientUnknownApiError\";\n\t\tthis.#status = status;\n\t}\n\tget status() {\n\t\treturn this.#status;\n\t}\n};\nvar FragnoClientApiError = class FragnoClientApiError extends FragnoClientError {\n\t#status;\n\tconstructor({ message, code }, status, options = {}) {\n\t\tsuper(message, code, options);\n\t\tthis.name = \"FragnoClientApiError\";\n\t\tthis.#status = status;\n\t}\n\tget status() {\n\t\treturn this.#status;\n\t}\n\t/**\n\t* The error code returned by the API.\n\t*\n\t* The type is `TErrorCode` (the set of known error codes for this route), but may also be a string\n\t* for forward compatibility with future error codes.\n\t*/\n\tget code() {\n\t\treturn super.code;\n\t}\n\tstatic async fromResponse(response) {\n\t\tconst unknown = await response.json();\n\t\tconst status = response.status;\n\t\tif (!(\"message\" in unknown || \"code\" in unknown)) return new FragnoClientUnknownApiError(\"Unknown API error\", status);\n\t\tif (!(typeof unknown.message === \"string\" && typeof unknown.code === \"string\")) return new FragnoClientUnknownApiError(\"Unknown API error\", status);\n\t\treturn new FragnoClientApiError({\n\t\t\tmessage: unknown.message,\n\t\t\tcode: unknown.code\n\t\t}, status);\n\t}\n};\n//#endregion\nexport { FragnoClientApiError, FragnoClientError, FragnoClientFetchAbortError, FragnoClientFetchError, FragnoClientFetchNetworkError, FragnoClientUnknownApiError };\n\n//# sourceMappingURL=client-error.js.map","//#region src/client/internal/fetcher-merge.ts\n/**\n* Merge two fetcher configurations, with user config taking precedence.\n* If user provides a custom function, it takes full precedence.\n* Otherwise, deep merge RequestInit options.\n*/\nfunction mergeFetcherConfigs(authorConfig, userConfig) {\n\tif (userConfig?.type === \"function\") return userConfig;\n\tif (!userConfig && authorConfig?.type === \"function\") return authorConfig;\n\tconst authorOpts = authorConfig?.type === \"options\" ? authorConfig.options : {};\n\tconst userOpts = userConfig?.type === \"options\" ? userConfig.options : {};\n\tif (Object.keys(authorOpts).length === 0 && Object.keys(userOpts).length === 0) return;\n\treturn {\n\t\ttype: \"options\",\n\t\toptions: {\n\t\t\t...authorOpts,\n\t\t\t...userOpts,\n\t\t\theaders: mergeHeaders(authorOpts.headers, userOpts.headers)\n\t\t}\n\t};\n}\n/**\n* Merge headers from author and user configs.\n* User headers override author headers.\n*/\nfunction mergeHeaders(author, user) {\n\tif (!author && !user) return;\n\tconst merged = new Headers(author);\n\tnew Headers(user).forEach((value, key) => {\n\t\tmerged.set(key, value);\n\t});\n\tif (merged.keys().next().done) return;\n\treturn merged;\n}\n//#endregion\nexport { mergeFetcherConfigs };\n\n//# sourceMappingURL=fetcher-merge.js.map","import { FragnoClientFetchAbortError, FragnoClientFetchError, FragnoClientUnknownApiError } from \"../client-error.js\";\n//#region src/client/internal/ndjson-streaming.ts\n/**\n* Creates a promise that rejects when the abort signal is triggered\n*/\nfunction createAbortPromise(abortSignal) {\n\treturn new Promise((_, reject) => {\n\t\tconst abortHandler = () => {\n\t\t\treject(new FragnoClientFetchAbortError(\"Operation was aborted\"));\n\t\t};\n\t\tif (abortSignal.aborted) abortHandler();\n\t\telse abortSignal.addEventListener(\"abort\", abortHandler, { once: true });\n\t});\n}\nconst parseNdjsonBuffer = (buffer, options) => {\n\tconst lines = buffer.split(\"\\n\");\n\tconst trailingBuffer = options.flush ? \"\" : lines.pop() ?? \"\";\n\tfor (let index = 0; index < lines.length; index += 1) {\n\t\tconst line = lines[index];\n\t\tif (!line.trim()) continue;\n\t\tlet jsonObject;\n\t\ttry {\n\t\t\tjsonObject = JSON.parse(line);\n\t\t} catch (parseError) {\n\t\t\tthrow new FragnoClientUnknownApiError(\"Failed to parse NDJSON line\", options.parseErrorStatus, { cause: parseError });\n\t\t}\n\t\tif (options.onItem(jsonObject) === false) {\n\t\t\tconst remainingLines = lines.slice(index + 1);\n\t\t\treturn {\n\t\t\t\tstopped: true,\n\t\t\t\tbuffer: remainingLines.length > 0 ? `${remainingLines.join(\"\\n\")}\\n${trailingBuffer}` : trailingBuffer\n\t\t\t};\n\t\t}\n\t}\n\treturn {\n\t\tstopped: false,\n\t\tbuffer: trailingBuffer\n\t};\n};\n/**\n* Handles NDJSON streaming responses by returning the first item from the fetcher\n* and then continuing to stream updates via the store's mutate method.\n*\n* This makes it so that we can wait until the first chunk before updating the store, if we did\n* not do this, `loading` would briefly be false before the first item would be populated in the\n* result.\n*\n* @param response - The fetch Response object containing the NDJSON stream\n* @param store - The fetcher store to update with streaming data\n* @param abortSignal - Optional AbortSignal to cancel the streaming operation\n* @returns A promise that resolves to an object containing the first item and a streaming promise\n*/\nasync function handleNdjsonStreamingFirstItem(response, store, options = {}) {\n\tif (!response.body) throw new FragnoClientFetchError(\"Streaming response has no body\", \"NO_BODY\");\n\tconst { abortSignal } = options;\n\tif (abortSignal?.aborted) throw new FragnoClientFetchAbortError(\"Operation was aborted\");\n\tconst decoder = new TextDecoder();\n\tconst reader = response.body.getReader();\n\tlet buffer = \"\";\n\tlet firstItem = null;\n\tconst items = [];\n\ttry {\n\t\twhile (firstItem === null) {\n\t\t\tif (abortSignal?.aborted) {\n\t\t\t\treader.releaseLock();\n\t\t\t\tthrow new FragnoClientFetchAbortError(\"Operation was aborted\");\n\t\t\t}\n\t\t\tconst { done, value } = await (abortSignal ? Promise.race([reader.read(), createAbortPromise(abortSignal)]) : reader.read());\n\t\t\tif (done) break;\n\t\t\tbuffer += decoder.decode(value, { stream: true });\n\t\t\tbuffer = parseNdjsonBuffer(buffer, {\n\t\t\t\tparseErrorStatus: 500,\n\t\t\t\tonItem: (jsonObject) => {\n\t\t\t\t\titems.push(jsonObject);\n\t\t\t\t\tfirstItem = jsonObject;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}).buffer;\n\t\t\tif (firstItem !== null) {\n\t\t\t\tconst streamingPromise = continueStreaming(reader, decoder, buffer, items, store, abortSignal);\n\t\t\t\treturn {\n\t\t\t\t\tfirstItem,\n\t\t\t\t\titems,\n\t\t\t\t\tstreamingPromise\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\tif (firstItem === null) {\n\t\t\treader.releaseLock();\n\t\t\tthrow new FragnoClientUnknownApiError(\"NDJSON stream contained no valid items\", 500);\n\t\t}\n\t\treader.releaseLock();\n\t\tthrow new FragnoClientFetchError(\"Unexpected end of stream processing\", \"NO_BODY\");\n\t} catch (error) {\n\t\tif (error instanceof FragnoClientFetchError || error instanceof FragnoClientUnknownApiError) {\n\t\t\tstore?.setError(error);\n\t\t\tthrow error;\n\t\t}\n\t\tconst clientError = new FragnoClientUnknownApiError(\"Unknown streaming error\", 500, { cause: error });\n\t\tstore?.setError(clientError);\n\t\tthrow clientError;\n\t}\n}\n/**\n* Continues streaming the remaining items in the background\n*/\nasync function continueStreaming(reader, decoder, initialBuffer, items, store, abortSignal) {\n\tlet buffer = initialBuffer;\n\tconst appendItem = (jsonObject) => {\n\t\titems.push(jsonObject);\n\t\tstore?.setData([...items]);\n\t};\n\ttry {\n\t\twhile (true) {\n\t\t\tbuffer = parseNdjsonBuffer(buffer, {\n\t\t\t\tparseErrorStatus: 400,\n\t\t\t\tonItem: appendItem\n\t\t\t}).buffer;\n\t\t\tif (abortSignal?.aborted) throw new FragnoClientFetchAbortError(\"Operation was aborted\");\n\t\t\tconst { done, value } = await (abortSignal ? Promise.race([reader.read(), createAbortPromise(abortSignal)]) : reader.read());\n\t\t\tif (done) {\n\t\t\t\tparseNdjsonBuffer(buffer, {\n\t\t\t\t\tflush: true,\n\t\t\t\t\tparseErrorStatus: 400,\n\t\t\t\t\tonItem: appendItem\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tbuffer += decoder.decode(value, { stream: true });\n\t\t}\n\t} catch (error) {\n\t\tif (error instanceof FragnoClientFetchError || error instanceof FragnoClientUnknownApiError) {\n\t\t\tstore?.setError(error);\n\t\t\tthrow error;\n\t\t}\n\t\tconst clientError = new FragnoClientUnknownApiError(\"Unknown streaming error\", 400, { cause: error });\n\t\tstore?.setError(clientError);\n\t\tthrow clientError;\n\t} finally {\n\t\treader.releaseLock();\n\t}\n\treturn items;\n}\n//#endregion\nexport { handleNdjsonStreamingFirstItem };\n\n//# sourceMappingURL=ndjson-streaming.js.map","export let createNanoEvents = () => ({\n emit(event, ...args) {\n for (\n let callbacks = this.events[event] || [],\n i = 0,\n length = callbacks.length;\n i < length;\n i++\n ) {\n callbacks[i](...args)\n }\n },\n events: {},\n on(event, cb) {\n ;(this.events[event] ||= []).push(cb)\n return () => {\n this.events[event] = this.events[event]?.filter(i => cb !== i)\n }\n }\n})\n","import { map, onStart, onStop, atom, batched, startTask } from 'nanostores';\nimport { createNanoEvents } from 'nanoevents';\n\nfunction defaultOnErrorRetry({ retryCount }) {\n return ~~((Math.random() + 0.5) * (1 << (retryCount < 8 ? retryCount : 8))) * 2e3;\n}\nconst nanoqueryFactory = ([\n isAppVisible,\n visibilityChangeSubscribe,\n reconnectChangeSubscribe\n]) => {\n const nanoquery = ({\n cache = /* @__PURE__ */ new Map(),\n fetcher: globalFetcher,\n ...globalSettings\n } = {}) => {\n const events = createNanoEvents();\n let focus = true;\n visibilityChangeSubscribe(() => {\n focus = isAppVisible();\n focus && events.emit(FOCUS);\n });\n reconnectChangeSubscribe(() => events.emit(RECONNECT));\n const _revalidateOnInterval = /* @__PURE__ */ new Map(), _errorInvalidateTimeouts = /* @__PURE__ */ new Map(), _runningFetches = /* @__PURE__ */ new Map();\n let rewrittenSettings = {};\n const getCachedValueByKey = (key) => {\n const fromCache = cache.get(key);\n if (!fromCache)\n return [];\n const cacheHit = (fromCache.expires || 0) > getNow();\n return cacheHit ? [fromCache.data, fromCache.error] : [];\n };\n const runFetcher = async ([key, keyParts], store, settings) => {\n if (!focus)\n return;\n const set = (v) => {\n if (store.key === key) {\n store.set(v);\n events.emit(SET_CACHE, key, v, true);\n }\n };\n const setAsLoading = (prev) => {\n const toSet = prev === void 0 ? {} : { data: prev };\n set({\n ...toSet,\n ...loading,\n promise: _runningFetches.get(key)\n });\n };\n let {\n dedupeTime = 4e3,\n cacheLifetime = Infinity,\n fetcher,\n onErrorRetry = defaultOnErrorRetry\n } = {\n ...settings,\n ...rewrittenSettings\n };\n if (cacheLifetime < dedupeTime)\n cacheLifetime = dedupeTime;\n const now = getNow();\n if (_runningFetches.has(key)) {\n if (!store.value.loading)\n setAsLoading(getCachedValueByKey(key)[0]);\n return;\n }\n let cachedValue, cachedError;\n const fromCache = cache.get(key);\n if (fromCache?.data !== void 0 || fromCache?.error) {\n [cachedValue, cachedError] = getCachedValueByKey(key);\n if ((fromCache.created || 0) + dedupeTime > now) {\n if (store.value.data != cachedValue || store.value.error != cachedError) {\n set({ ...notLoading, data: cachedValue, error: cachedError });\n }\n return;\n }\n }\n const finishTask = startTask();\n try {\n clearTimeout(_errorInvalidateTimeouts.get(key));\n const promise = fetcher(...keyParts);\n _runningFetches.set(key, promise);\n setAsLoading(cachedValue);\n const res = await promise;\n cache.set(key, {\n data: res,\n created: getNow(),\n expires: getNow() + cacheLifetime\n });\n set({ data: res, ...notLoading });\n } catch (error) {\n settings.onError?.(error);\n const retryCount = (cache.get(key)?.retryCount || 0) + 1;\n cache.set(key, {\n error,\n created: getNow(),\n expires: getNow() + cacheLifetime,\n retryCount\n });\n if (onErrorRetry) {\n const timer = onErrorRetry({\n error,\n key,\n retryCount\n });\n if (timer)\n _errorInvalidateTimeouts.set(\n key,\n setTimeout(() => {\n invalidateKeys(key);\n cache.set(key, { retryCount });\n }, timer)\n );\n }\n set({ data: store.value.data, error, ...notLoading });\n } finally {\n finishTask();\n _runningFetches.delete(key);\n }\n };\n const createFetcherStore = (keyInput, {\n fetcher = globalFetcher,\n ...fetcherSettings\n } = {}) => {\n if (process.env.NODE_ENV !== \"production\" && !fetcher) {\n throw new Error(\n \"You need to set up either global fetcher of fetcher in createFetcherStore\"\n );\n }\n const fetcherStore = map({\n ...notLoading\n }), settings = { ...globalSettings, ...fetcherSettings, fetcher };\n fetcherStore._ = fetcherSymbol;\n fetcherStore.invalidate = () => {\n const { key } = fetcherStore;\n if (key) {\n invalidateKeys(key);\n }\n };\n fetcherStore.revalidate = () => {\n const { key } = fetcherStore;\n if (key) {\n revalidateKeys(key);\n }\n };\n fetcherStore.mutate = (data) => {\n const { key } = fetcherStore;\n if (key) {\n mutateCache(key, data);\n }\n };\n fetcherStore.fetch = async () => {\n let resolve;\n const promise = new Promise((r) => resolve = r);\n const unsub = fetcherStore.listen(({ error, data }) => {\n if (error !== void 0)\n resolve({ error });\n if (data !== void 0)\n resolve({ data });\n });\n return promise.finally(unsub);\n };\n let keysInternalUnsub, prevKey, prevKeyParts, keyUnsub, keyStore;\n let evtUnsubs = [];\n onStart(fetcherStore, () => {\n const firstRun = !keysInternalUnsub;\n [keyStore, keysInternalUnsub] = getKeyStore(keyInput);\n keyUnsub = keyStore.subscribe((currentKeys) => {\n if (currentKeys) {\n const [newKey, keyParts] = currentKeys;\n fetcherStore.key = newKey;\n runFetcher([newKey, keyParts], fetcherStore, settings);\n prevKey = newKey;\n prevKeyParts = keyParts;\n } else {\n fetcherStore.key = prevKey = prevKeyParts = void 0;\n fetcherStore.set({ ...notLoading });\n }\n });\n const currentKeyValue = keyStore.get();\n if (currentKeyValue) {\n [prevKey, prevKeyParts] = currentKeyValue;\n if (firstRun)\n handleNewListener();\n }\n const {\n revalidateInterval = 0,\n revalidateOnFocus,\n revalidateOnReconnect\n } = settings;\n const runRefetcher = () => {\n if (prevKey)\n runFetcher([prevKey, prevKeyParts], fetcherStore, settings);\n };\n if (revalidateInterval > 0) {\n _revalidateOnInterval.set(\n keyInput,\n setInterval(runRefetcher, revalidateInterval)\n );\n }\n if (revalidateOnFocus)\n evtUnsubs.push(events.on(FOCUS, runRefetcher));\n if (revalidateOnReconnect)\n evtUnsubs.push(events.on(RECONNECT, runRefetcher));\n const cacheKeyChangeHandler = (keySelector) => {\n if (prevKey && testKeyAgainstSelector(prevKey, keySelector)) {\n runFetcher([prevKey, prevKeyParts], fetcherStore, settings);\n }\n };\n evtUnsubs.push(\n events.on(INVALIDATE_KEYS, cacheKeyChangeHandler),\n events.on(REVALIDATE_KEYS, cacheKeyChangeHandler),\n events.on(SET_CACHE, (keySelector, data, full) => {\n if (prevKey && testKeyAgainstSelector(prevKey, keySelector) && fetcherStore.value !== data && fetcherStore.value.data !== data) {\n fetcherStore.set(\n full ? data : { data, ...notLoading }\n );\n }\n })\n );\n });\n const handleNewListener = () => {\n if (prevKey && prevKeyParts)\n runFetcher([prevKey, prevKeyParts], fetcherStore, settings);\n };\n const originListen = fetcherStore.listen;\n fetcherStore.listen = (listener) => {\n const unsub = originListen(listener);\n listener(fetcherStore.value);\n handleNewListener();\n return unsub;\n };\n onStop(fetcherStore, () => {\n fetcherStore.value = { ...notLoading };\n keysInternalUnsub?.();\n evtUnsubs.forEach((fn) => fn());\n evtUnsubs = [];\n keyUnsub?.();\n clearInterval(_revalidateOnInterval.get(keyInput));\n });\n return fetcherStore;\n };\n const iterOverCache = (keySelector, cb) => {\n for (const key of cache.keys()) {\n if (testKeyAgainstSelector(key, keySelector))\n cb(key);\n }\n };\n const invalidateKeys = (keySelector) => {\n iterOverCache(keySelector, (key) => {\n cache.delete(key);\n });\n events.emit(INVALIDATE_KEYS, keySelector);\n };\n const revalidateKeys = (keySelector) => {\n iterOverCache(keySelector, (key) => {\n const cached = cache.get(key);\n if (cached) {\n cache.set(key, { ...cached, created: -Infinity });\n }\n });\n events.emit(REVALIDATE_KEYS, keySelector);\n };\n const mutateCache = (keySelector, data) => {\n iterOverCache(keySelector, (key) => {\n if (data === void 0)\n cache.delete(key);\n else {\n cache.set(key, {\n data,\n created: getNow(),\n expires: getNow() + (globalSettings.cacheLifetime ?? 8e3)\n });\n }\n });\n events.emit(SET_CACHE, keySelector, data);\n };\n function createMutatorStore(mutator, opts) {\n const { throttleCalls, onError } = opts ?? {\n throttleCalls: true,\n onError: globalSettings?.onError\n };\n const mutate = async (data) => {\n if (throttleCalls && store.value?.loading)\n return;\n const newMutator = rewrittenSettings.fetcher ?? mutator;\n const keysToInvalidate = [], keysToRevalidate = [];\n const safeKeySet = (k, v) => {\n if (store.lc) {\n store.setKey(k, v);\n }\n };\n try {\n store.set({\n error: void 0,\n data: void 0,\n mutate,\n ...loading\n });\n const result = await newMutator({\n data,\n invalidate: (key) => {\n keysToInvalidate.push(key);\n },\n revalidate: (key) => {\n keysToRevalidate.push(key);\n },\n getCacheUpdater: (key, shouldRevalidate = true) => [\n (newVal) => {\n mutateCache(key, newVal);\n if (shouldRevalidate) {\n keysToRevalidate.push(key);\n }\n },\n cache.get(key)?.data\n ]\n });\n safeKeySet(\"data\", result);\n return result;\n } catch (error) {\n onError?.(error);\n safeKeySet(\"error\", error);\n store.setKey(\"error\", error);\n } finally {\n safeKeySet(\"loading\", false);\n keysToInvalidate.forEach(invalidateKeys);\n keysToRevalidate.forEach(revalidateKeys);\n }\n };\n const store = map({\n mutate,\n ...notLoading\n });\n onStop(\n store,\n () => store.set({ mutate, ...notLoading })\n );\n store.mutate = mutate;\n return store;\n }\n const __unsafeOverruleSettings = (data) => {\n if (process.env.NODE_ENV !== \"test\") {\n console.warn(\n `You should only use __unsafeOverruleSettings in test environment`\n );\n }\n rewrittenSettings = data;\n };\n return [\n createFetcherStore,\n createMutatorStore,\n { __unsafeOverruleSettings, invalidateKeys, revalidateKeys, mutateCache }\n ];\n };\n function isSomeKey(key) {\n return typeof key === \"string\" || typeof key === \"number\" || key === true;\n }\n const getKeyStore = (keys) => {\n if (isSomeKey(keys))\n return [\n atom([\"\" + keys, [keys]]),\n () => {\n }\n ];\n const keyParts = [];\n const $key = atom(null);\n const keysAsStoresToIndexes = /* @__PURE__ */ new Map();\n const setKeyStoreValue = () => {\n if (keyParts.some((v) => v === null || v === void 0 || v === false)) {\n $key.set(null);\n } else {\n $key.set([keyParts.join(\"\"), keyParts]);\n }\n };\n for (let i = 0; i < keys.length; i++) {\n const keyOrStore = keys[i];\n if (isSomeKey(keyOrStore)) {\n keyParts.push(keyOrStore);\n } else {\n keyParts.push(null);\n keysAsStoresToIndexes.set(keyOrStore, i);\n }\n }\n const storesAsArray = [...keysAsStoresToIndexes.keys()];\n const $storeKeys = batched(storesAsArray, (...storeValues) => {\n for (let i = 0; i < storeValues.length; i++) {\n const store = storesAsArray[i], partIndex = keysAsStoresToIndexes.get(store);\n keyParts[partIndex] = store._ === fetcherSymbol ? store.value && \"data\" in store.value ? store.key : null : storeValues[i];\n }\n setKeyStoreValue();\n });\n setKeyStoreValue();\n return [$key, $storeKeys.subscribe(noop)];\n };\n function noop() {\n }\n const FOCUS = 1, RECONNECT = 2, INVALIDATE_KEYS = 3, REVALIDATE_KEYS = 4, SET_CACHE = 5;\n const testKeyAgainstSelector = (key, selector) => {\n if (Array.isArray(selector))\n return selector.includes(key);\n else if (typeof selector === \"function\")\n return selector(key);\n else\n return key === selector;\n };\n const getNow = () => (/* @__PURE__ */ new Date()).getTime();\n const fetcherSymbol = Symbol();\n const loading = { loading: true }, notLoading = { loading: false };\n return nanoquery;\n};\n\nconst subscribe = (name, fn) => {\n const isServer = typeof window === \"undefined\";\n if (!isServer) {\n addEventListener(name, fn);\n }\n};\nconst browserCompat = [\n () => !document.hidden,\n (cb) => subscribe(\"visibilitychange\", cb),\n (cb) => subscribe(\"online\", cb)\n];\n\nconst nanoquery = nanoqueryFactory(browserCompat);\n\nexport { nanoquery, defaultOnErrorRetry as onErrorRetry };\n","import { buildPath, extractPathParams } from \"../api/internal/path.js\";\nimport { createRequestInitWithBody, prepareClientRequestBody } from \"../api/request-body.js\";\nimport { getMountRoute } from \"../api/internal/route.js\";\nimport { RequestInputContext } from \"../api/request-input-context.js\";\nimport { RequestOutputContext } from \"../api/request-output-context.js\";\nimport { resolveRouteFactories } from \"../api/route.js\";\nimport { parseContentType } from \"../util/content-type.js\";\nimport { unwrapObject } from \"../util/nanostores.js\";\nimport { addStore } from \"../util/ssr.js\";\nimport { FragnoClientApiError, FragnoClientError, FragnoClientFetchAbortError, FragnoClientFetchError, FragnoClientFetchNetworkError, FragnoClientUnknownApiError } from \"./client-error.js\";\nimport { mergeFetcherConfigs } from \"./internal/fetcher-merge.js\";\nimport { handleNdjsonStreamingFirstItem } from \"./internal/ndjson-streaming.js\";\nimport { computed, task } from \"nanostores\";\nimport { nanoquery } from \"@nanostores/query\";\n//#region src/client/client.ts\n/**\n* Symbols used to identify hook types\n*/\nconst GET_HOOK_SYMBOL = Symbol(\"fragno-get-hook\");\nconst MUTATOR_HOOK_SYMBOL = Symbol(\"fragno-mutator-hook\");\nconst STORE_SYMBOL = Symbol(\"fragno-store\");\nasync function schemaAllowsUndefined(schema) {\n\ttry {\n\t\treturn !(await schema[\"~standard\"].validate(void 0)).issues;\n\t} catch {\n\t\treturn false;\n\t}\n}\nasync function assertBodyProvided(body, inputSchema, errorMessage) {\n\tif (typeof body !== \"undefined\" || inputSchema === void 0) return;\n\tif (await schemaAllowsUndefined(inputSchema)) return;\n\tthrow new Error(errorMessage);\n}\n/**\n* Merge request headers from multiple sources.\n* Returns undefined if there are no headers to merge.\n* @internal\n*/\nfunction mergeRequestHeaders(...headerSources) {\n\tconst result = {};\n\tlet hasHeaders = false;\n\tfor (const source of headerSources) {\n\t\tif (!source) continue;\n\t\tif (source instanceof Headers) for (const [key, value] of source.entries()) {\n\t\t\tresult[key] = value;\n\t\t\thasHeaders = true;\n\t\t}\n\t\telse if (Array.isArray(source)) for (const [key, value] of source) {\n\t\t\tresult[key] = value;\n\t\t\thasHeaders = true;\n\t\t}\n\t\telse for (const [key, value] of Object.entries(source)) {\n\t\t\tresult[key] = value;\n\t\t\thasHeaders = true;\n\t\t}\n\t}\n\treturn hasHeaders ? result : void 0;\n}\n/**\n* @internal\n*/\nfunction buildUrl(config, params) {\n\tconst { baseUrl = \"\", mountRoute, path } = config;\n\tconst { pathParams, queryParams } = params ?? {};\n\tconst normalizedPathParams = unwrapObject(pathParams);\n\tconst normalizedQueryParams = unwrapObject(queryParams) ?? {};\n\tconst filteredQueryParams = Object.fromEntries(Object.entries(normalizedQueryParams).filter(([_, value]) => value !== void 0));\n\tconst searchParams = new URLSearchParams(filteredQueryParams);\n\treturn `${baseUrl}${mountRoute}${buildPath(path, normalizedPathParams ?? {})}${searchParams.toString() ? `?${searchParams.toString()}` : \"\"}`;\n}\n/**\n* This method returns an array, which can be passed directly to nanostores.\n*\n* The returned array is always: path, pathParams (In order they appear in the path), queryParams (In alphabetical order)\n* Missing pathParams are replaced with \"<missing>\".\n* Atoms with undefined values are wrapped in computed atoms that map undefined to \"\" to avoid nanoquery treating the key as incomplete.\n* @param path\n* @param params\n* @returns\n* @internal\n*/\nfunction getCacheKey(method, path, params) {\n\tif (!params) return [method, path];\n\tconst { pathParams, queryParams } = params;\n\tconst pathParamValues = extractPathParams(path).map((name) => pathParams?.[name] ?? \"<missing>\");\n\tconst queryParamValues = queryParams ? Object.keys(queryParams).sort().map((key) => {\n\t\tconst value = queryParams[key];\n\t\tif (value && typeof value === \"object\" && \"get\" in value) return computed(value, (v) => v ?? \"\");\n\t\treturn value ?? \"\";\n\t}) : [];\n\treturn [\n\t\tmethod,\n\t\tpath,\n\t\t...pathParamValues,\n\t\t...queryParamValues\n\t];\n}\nfunction isStreamingResponse(response) {\n\tconst contentType = parseContentType(response.headers.get(\"content-type\"));\n\tif (!contentType) return false;\n\tif (!(response.headers.get(\"transfer-encoding\") === \"chunked\")) return false;\n\tif (contentType.subtype === \"octet-stream\") return \"octet-stream\";\n\tif (contentType.subtype === \"x-ndjson\") return \"ndjson\";\n\treturn false;\n}\n/**\n* @internal\n*/\nfunction isGetHook(hook) {\n\treturn typeof hook === \"object\" && hook !== null && GET_HOOK_SYMBOL in hook && hook[GET_HOOK_SYMBOL] === true;\n}\n/**\n* @internal\n*/\nfunction isMutatorHook(hook) {\n\treturn typeof hook === \"object\" && hook !== null && MUTATOR_HOOK_SYMBOL in hook && hook[MUTATOR_HOOK_SYMBOL] === true;\n}\n/**\n* @internal\n*/\nfunction isStore(obj) {\n\treturn typeof obj === \"object\" && obj !== null && STORE_SYMBOL in obj && obj[STORE_SYMBOL] === true;\n}\nvar ClientBuilder = class {\n\t#publicConfig;\n\t#fragmentConfig;\n\t#fetcherConfig;\n\t#cache = /* @__PURE__ */ new Map();\n\t#createFetcherStore;\n\t#createMutatorStore;\n\t#invalidateKeys;\n\tconstructor(publicConfig, fragmentConfig) {\n\t\tthis.#publicConfig = publicConfig;\n\t\tthis.#fragmentConfig = fragmentConfig;\n\t\tthis.#fetcherConfig = publicConfig.fetcherConfig;\n\t\tconst [createFetcherStore, createMutatorStore, { invalidateKeys }] = nanoquery({\n\t\t\tcache: this.#cache,\n\t\t\tcacheLifetime: Infinity\n\t\t});\n\t\tthis.#createFetcherStore = createFetcherStore;\n\t\tthis.#createMutatorStore = createMutatorStore;\n\t\tthis.#invalidateKeys = invalidateKeys;\n\t}\n\tget cacheEntries() {\n\t\treturn Object.fromEntries(this.#cache.entries());\n\t}\n\tcreateStore(input) {\n\t\tif (typeof input === \"function\") return {\n\t\t\tfactory: input,\n\t\t\t[STORE_SYMBOL]: true\n\t\t};\n\t\treturn {\n\t\t\tobj: input,\n\t\t\t[STORE_SYMBOL]: true\n\t\t};\n\t}\n\t/**\n\t* Build a URL for a custom backend call using the configured baseUrl and mountRoute.\n\t* Useful for fragment authors who need to make custom fetch calls.\n\t*/\n\tbuildUrl(path, params) {\n\t\treturn buildUrl({\n\t\t\tbaseUrl: this.#publicConfig.baseUrl ?? \"\",\n\t\t\tmountRoute: getMountRoute({\n\t\t\t\tname: this.#fragmentConfig.name,\n\t\t\t\tmountRoute: this.#publicConfig.mountRoute\n\t\t\t}),\n\t\t\tpath\n\t\t}, {\n\t\t\tpathParams: params?.path,\n\t\t\tqueryParams: params?.query\n\t\t});\n\t}\n\t/**\n\t* Get the configured fetcher function for custom backend calls.\n\t* Returns fetch with merged options applied.\n\t*/\n\tgetFetcher() {\n\t\treturn {\n\t\t\tfetcher: this.#getFetcher(),\n\t\t\tdefaultOptions: this.#getFetcherOptions()\n\t\t};\n\t}\n\t#getFetcher() {\n\t\tif (this.#fetcherConfig?.type === \"function\") return this.#fetcherConfig.fetcher;\n\t\treturn globalThis.fetch.bind(globalThis);\n\t}\n\t#getFetcherOptions() {\n\t\tif (this.#fetcherConfig?.type === \"options\") return this.#fetcherConfig.options;\n\t}\n\tcreateHook(path, options) {\n\t\tconst route = this.#fragmentConfig.routes.find((r) => r.path === path && r.method === \"GET\" && r.outputSchema !== void 0);\n\t\tif (!route) throw new Error(`Route '${path}' not found or is not a GET route with an output schema.`);\n\t\treturn this.#createRouteQueryHook(route, options);\n\t}\n\tcreateMutator(method, path, onInvalidate) {\n\t\tconst route = this.#fragmentConfig.routes.find((r) => r.method !== \"GET\" && r.path === path && r.method === method);\n\t\tif (!route) throw new Error(`Route '${path}' not found or is a GET route with an input and output schema.`);\n\t\treturn this.#createRouteQueryMutator(route, onInvalidate);\n\t}\n\t#createRouteQueryHook(route, options = {}) {\n\t\tif (route.method !== \"GET\") throw new Error(`Only GET routes are supported for hooks. Route '${route.path}' is a ${String(route.method)} route.`);\n\t\tif (!route.outputSchema) throw new Error(`Output schema is required for GET routes. Route '${route.path}' has no output schema.`);\n\t\tconst baseUrl = this.#publicConfig.baseUrl ?? \"\";\n\t\tconst mountRoute = getMountRoute({\n\t\t\tname: this.#fragmentConfig.name,\n\t\t\tmountRoute: this.#publicConfig.mountRoute\n\t\t});\n\t\tconst fetcher = this.#getFetcher();\n\t\tconst fetcherOptions = this.#getFetcherOptions();\n\t\tconst useFetcherOnServer = this.#fetcherConfig?.type === \"function\" && this.#fetcherConfig.useOnServer;\n\t\tasync function callServerSideHandler(params) {\n\t\t\tconst { pathParams, queryParams } = params ?? {};\n\t\t\tconst normalizedPathParams = unwrapObject(pathParams);\n\t\t\tconst normalizedQueryParams = unwrapObject(queryParams) ?? {};\n\t\t\tconst filteredQueryParams = Object.fromEntries(Object.entries(normalizedQueryParams).filter(([_, value]) => value !== void 0));\n\t\t\tconst searchParams = new URLSearchParams(filteredQueryParams);\n\t\t\treturn await route.handler(RequestInputContext.fromSSRContext({\n\t\t\t\tmethod: route.method,\n\t\t\t\tpath: route.path,\n\t\t\t\tpathParams: normalizedPathParams,\n\t\t\t\tsearchParams\n\t\t\t}), new RequestOutputContext(route.outputSchema));\n\t\t}\n\t\tasync function executeQuery(params) {\n\t\t\tconst { pathParams, queryParams } = params ?? {};\n\t\t\tif (typeof window === \"undefined\" && !useFetcherOnServer) return task(async () => callServerSideHandler({\n\t\t\t\tpathParams,\n\t\t\t\tqueryParams\n\t\t\t}));\n\t\t\tconst url = buildUrl({\n\t\t\t\tbaseUrl,\n\t\t\t\tmountRoute,\n\t\t\t\tpath: route.path\n\t\t\t}, {\n\t\t\t\tpathParams,\n\t\t\t\tqueryParams\n\t\t\t});\n\t\t\tlet response;\n\t\t\ttry {\n\t\t\t\tresponse = fetcherOptions ? await fetcher(url, fetcherOptions) : await fetcher(url);\n\t\t\t} catch (error) {\n\t\t\t\tthrow FragnoClientFetchError.fromUnknownFetchError(error);\n\t\t\t}\n\t\t\tif (!response.ok) throw await FragnoClientApiError.fromResponse(response);\n\t\t\treturn response;\n\t\t}\n\t\treturn {\n\t\t\troute,\n\t\t\tstore: (args) => {\n\t\t\t\tconst { path, query } = args ?? {};\n\t\t\t\tconst key = getCacheKey(route.method, route.path, {\n\t\t\t\t\tpathParams: path,\n\t\t\t\t\tqueryParams: query\n\t\t\t\t});\n\t\t\t\tconst store = this.#createFetcherStore(key, {\n\t\t\t\t\tfetcher: async () => {\n\t\t\t\t\t\tconst response = await executeQuery({\n\t\t\t\t\t\t\tpathParams: path,\n\t\t\t\t\t\t\tqueryParams: query\n\t\t\t\t\t\t});\n\t\t\t\t\t\tconst isStreaming = isStreamingResponse(response);\n\t\t\t\t\t\tif (!isStreaming) return response.json();\n\t\t\t\t\t\tif (typeof window === \"undefined\" && !useFetcherOnServer) {\n\t\t\t\t\t\t\tif (response.body) await response.body.getReader().cancel();\n\t\t\t\t\t\t\treturn [];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (isStreaming === \"ndjson\") {\n\t\t\t\t\t\t\tconst { items } = await handleNdjsonStreamingFirstItem(response, {\n\t\t\t\t\t\t\t\tsetData: (value) => {\n\t\t\t\t\t\t\t\t\tstore.mutate(value);\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tsetError: (value) => {\n\t\t\t\t\t\t\t\t\tstore.set({\n\t\t\t\t\t\t\t\t\t\t...store.get(),\n\t\t\t\t\t\t\t\t\t\terror: value\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn items;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (isStreaming === \"octet-stream\") throw new Error(\"Octet-stream streaming is not supported.\");\n\t\t\t\t\t\tthrow new Error(\"Unreachable\");\n\t\t\t\t\t},\n\t\t\t\t\tonErrorRetry: options?.onErrorRetry,\n\t\t\t\t\tdedupeTime: Infinity\n\t\t\t\t});\n\t\t\t\tif (typeof window === \"undefined\") addStore(store);\n\t\t\t\treturn store;\n\t\t\t},\n\t\t\tquery: async (args) => {\n\t\t\t\tconst { path, query } = args ?? {};\n\t\t\t\tconst response = await executeQuery({\n\t\t\t\t\tpathParams: path,\n\t\t\t\t\tqueryParams: query\n\t\t\t\t});\n\t\t\t\tconst isStreaming = isStreamingResponse(response);\n\t\t\t\tif (!isStreaming) return await response.json();\n\t\t\t\tif (isStreaming === \"ndjson\") {\n\t\t\t\t\tconst { streamingPromise } = await handleNdjsonStreamingFirstItem(response);\n\t\t\t\t\treturn await streamingPromise;\n\t\t\t\t}\n\t\t\t\tif (isStreaming === \"octet-stream\") throw new Error(\"Octet-stream streaming is not supported.\");\n\t\t\t\tthrow new Error(\"Unreachable\");\n\t\t\t},\n\t\t\t[GET_HOOK_SYMBOL]: true\n\t\t};\n\t}\n\t#createRouteQueryMutator(route, onInvalidate = (invalidate, params) => {\n\t\tinvalidate(\"GET\", route.path, params);\n\t}) {\n\t\tconst method = route.method;\n\t\tconst baseUrl = this.#publicConfig.baseUrl ?? \"\";\n\t\tconst mountRoute = getMountRoute({\n\t\t\tname: this.#fragmentConfig.name,\n\t\t\tmountRoute: this.#publicConfig.mountRoute\n\t\t});\n\t\tconst fetcher = this.#getFetcher();\n\t\tconst fetcherOptions = this.#getFetcherOptions();\n\t\tconst useFetcherOnServer = this.#fetcherConfig?.type === \"function\" && this.#fetcherConfig.useOnServer;\n\t\tasync function executeMutateQuery({ body, path, query }) {\n\t\t\tif (typeof window === \"undefined\" && !useFetcherOnServer) return task(async () => route.handler(RequestInputContext.fromSSRContext({\n\t\t\t\tinputSchema: route.inputSchema,\n\t\t\t\tmethod,\n\t\t\t\tpath: route.path,\n\t\t\t\tpathParams: path ?? {},\n\t\t\t\tsearchParams: new URLSearchParams(query),\n\t\t\t\tbody\n\t\t\t}), new RequestOutputContext(route.outputSchema)));\n\t\t\tconst url = buildUrl({\n\t\t\t\tbaseUrl,\n\t\t\t\tmountRoute,\n\t\t\t\tpath: route.path\n\t\t\t}, {\n\t\t\t\tpathParams: path,\n\t\t\t\tqueryParams: query\n\t\t\t});\n\t\t\tlet response;\n\t\t\ttry {\n\t\t\t\tconst preparedBody = prepareClientRequestBody(body, route.contentType);\n\t\t\t\tconst bodyHeaders = preparedBody.contentType === void 0 || preparedBody.contentType === null ? void 0 : { \"Content-Type\": preparedBody.contentType };\n\t\t\t\tconst headers = mergeRequestHeaders(fetcherOptions?.headers, bodyHeaders);\n\t\t\t\tconst requestOptions = createRequestInitWithBody(method, headers ?? {}, preparedBody.body, fetcherOptions);\n\t\t\t\tresponse = await fetcher(url, requestOptions);\n\t\t\t} catch (error) {\n\t\t\t\tthrow FragnoClientFetchError.fromUnknownFetchError(error);\n\t\t\t}\n\t\t\tif (!response.ok) throw await FragnoClientApiError.fromResponse(response);\n\t\t\treturn response;\n\t\t}\n\t\tconst mutatorStore = this.#createMutatorStore(async ({ data }) => {\n\t\t\tif (typeof window === \"undefined\") {}\n\t\t\tconst { body, path, query } = data;\n\t\t\tawait assertBodyProvided(body, route.inputSchema, \"Body is required.\");\n\t\t\tconst response = await executeMutateQuery({\n\t\t\t\tbody,\n\t\t\t\tpath,\n\t\t\t\tquery\n\t\t\t});\n\t\t\tonInvalidate(this.#invalidate.bind(this), {\n\t\t\t\tpathParams: path ?? {},\n\t\t\t\tqueryParams: query\n\t\t\t});\n\t\t\tif (response.status === 201 || response.status === 204) return;\n\t\t\tconst isStreaming = isStreamingResponse(response);\n\t\t\tif (!isStreaming) return await response.json();\n\t\t\tif (typeof window === \"undefined\") return [];\n\t\t\tif (isStreaming === \"ndjson\") {\n\t\t\t\tconst { firstItem } = await handleNdjsonStreamingFirstItem(response, {\n\t\t\t\t\tsetData: (value) => {\n\t\t\t\t\t\tmutatorStore.set({\n\t\t\t\t\t\t\t...mutatorStore.get(),\n\t\t\t\t\t\t\tloading: !(Array.isArray(value) && value.length > 0),\n\t\t\t\t\t\t\tdata: value\n\t\t\t\t\t\t});\n\t\t\t\t\t},\n\t\t\t\t\tsetError: (value) => {\n\t\t\t\t\t\tmutatorStore.set({\n\t\t\t\t\t\t\t...mutatorStore.get(),\n\t\t\t\t\t\t\terror: value\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn [firstItem];\n\t\t\t}\n\t\t\tif (isStreaming === \"octet-stream\") throw new Error(\"Octet-stream streaming is not supported.\");\n\t\t\tthrow new Error(\"Unreachable\");\n\t\t}, { onError: (error) => {\n\t\t\tconsole.error(\"Error in mutatorStore\", error);\n\t\t} });\n\t\tconst mutateQuery = (async (data) => {\n\t\t\tconst { body, path, query } = data;\n\t\t\tawait assertBodyProvided(body, route.inputSchema, \"Body is required for mutateQuery\");\n\t\t\tconst response = await executeMutateQuery({\n\t\t\t\tbody,\n\t\t\t\tpath,\n\t\t\t\tquery\n\t\t\t});\n\t\t\tif (response.status === 201 || response.status === 204) return;\n\t\t\tconst isStreaming = isStreamingResponse(response);\n\t\t\tif (!isStreaming) return await response.json();\n\t\t\tif (isStreaming === \"ndjson\") {\n\t\t\t\tconst { streamingPromise } = await handleNdjsonStreamingFirstItem(response);\n\t\t\t\treturn await streamingPromise;\n\t\t\t}\n\t\t\tif (isStreaming === \"octet-stream\") throw new Error(\"Octet-stream streaming is not supported for mutations\");\n\t\t\tthrow new Error(\"Unreachable\");\n\t\t});\n\t\treturn {\n\t\t\troute,\n\t\t\tmutateQuery,\n\t\t\tmutatorStore,\n\t\t\t[MUTATOR_HOOK_SYMBOL]: true\n\t\t};\n\t}\n\t#invalidate(method, path, params) {\n\t\tconst prefix = getCacheKey(method, path, {\n\t\t\tpathParams: params?.pathParams,\n\t\t\tqueryParams: params?.queryParams\n\t\t}).map((k) => typeof k === \"string\" ? k : k.get()).join(\"\");\n\t\tthis.#invalidateKeys((key) => key.startsWith(prefix));\n\t}\n};\n/**\n* Create a client builder for fragments using the new fragment definition API.\n* This is the same as createClientBuilder but works with FragmentDefinition.\n*/\nfunction createClientBuilder(definition, publicConfig, routesOrFactories, authorFetcherConfig) {\n\tconst routes = resolveRouteFactories({\n\t\tconfig: {},\n\t\tdeps: {},\n\t\tservices: {},\n\t\tserviceDeps: {}\n\t}, routesOrFactories);\n\tconst fragmentConfig = {\n\t\tname: definition.name,\n\t\troutes\n\t};\n\tconst mountRoute = getMountRoute({\n\t\tname: definition.name,\n\t\tmountRoute: publicConfig.mountRoute\n\t});\n\tconst mergedFetcherConfig = mergeFetcherConfigs(authorFetcherConfig, publicConfig.fetcherConfig);\n\treturn new ClientBuilder({\n\t\t...publicConfig,\n\t\tmountRoute,\n\t\tfetcherConfig: mergedFetcherConfig\n\t}, fragmentConfig);\n}\n//#endregion\nexport { ClientBuilder, FragnoClientApiError, FragnoClientError, FragnoClientFetchAbortError, FragnoClientFetchError, FragnoClientFetchNetworkError, FragnoClientUnknownApiError, buildUrl, createClientBuilder, getCacheKey, isGetHook, isMutatorHook, isStore };\n\n//# sourceMappingURL=client.js.map","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","import { defineFragment } from \"@fragno-dev/core\";\nimport { withDatabase, type HookContext, type HookFn, type TypedUnitOfWork } from \"@fragno-dev/db\";\n\nimport type {\n ApiFragmentConfig as BaseApiFragmentConfig,\n ApiRequestInput,\n WebhookEndpoint,\n} from \"./api-types\";\nimport { apiSchema } from \"./schema\";\nimport {\n apiAuthReadyUntil,\n createOAuthCallbackSnapshot,\n createOAuthStartSnapshot,\n isApiAuthReady,\n performApiRequest,\n resolveApiOperationAuth,\n storedAuthPayloadSchema,\n} from \"./services\";\n\nexport interface ApiConnectionHookSnapshot {\n slug: string;\n name: string | null;\n baseUrl: string;\n authMode: string;\n status: string;\n}\n\nexport interface ApiConnectionChangedPayload {\n connectionId: string;\n connection: ApiConnectionHookSnapshot;\n}\n\nexport interface ApiConnectionDeletedPayload {\n connectionId: string;\n previous: ApiConnectionHookSnapshot;\n}\n\nexport interface ApiConnectionReadinessChangedPayload {\n connectionId: string;\n /** Whether stored auth can authorize requests; providers can still reject it. */\n ready: boolean;\n}\n\n/**\n * A readiness change as delivered. The connection is read at delivery rather than stored with the\n * hook, so it is the current connection, or null after it was deleted.\n */\nexport interface ApiConnectionReadinessChange extends ApiConnectionReadinessChangedPayload {\n connection: ApiConnectionHookSnapshot | null;\n}\n\n/** The token stored when expiry was scheduled; a later write replaces it and reports itself. */\ninterface InternalAuthExpiredPayload {\n connectionId: string;\n expiresAt: string;\n}\n\ninterface InternalWebhookReceivedPayload {\n endpointId: string;\n deliveryId: string;\n hookId: string;\n receivedAt: string;\n headers: Record<string, string>;\n query: Record<string, string>;\n rawBody: string;\n body: Record<string, unknown>;\n contentType: string | null;\n}\n\nexport interface WebhookEndpointHookSnapshot {\n name: WebhookEndpoint[\"name\"];\n status: WebhookEndpoint[\"status\"];\n authConfig: WebhookEndpoint[\"authConfig\"];\n verification: WebhookEndpoint[\"verification\"];\n deliveryIdentity: WebhookEndpoint[\"deliveryIdentity\"];\n secretRefs: WebhookEndpoint[\"secretRefs\"];\n}\n\nexport type WebhookEndpointChangedPayload =\n | { change: \"created\"; endpointId: string; endpoint: WebhookEndpointHookSnapshot }\n | {\n change: \"updated\";\n endpointId: string;\n endpoint: WebhookEndpointHookSnapshot;\n /** Lets consumers tell whether the write changed if the endpoint accepts deliveries. */\n previousStatus: WebhookEndpoint[\"status\"];\n }\n | { change: \"deleted\"; endpointId: string };\n\nexport interface WebhookReceivedPayload {\n endpointId: string;\n deliveryId: string;\n hookId: string;\n receivedAt: string;\n headers: Record<string, string>;\n query: Record<string, string>;\n body: Record<string, unknown>;\n contentType: string | null;\n}\n\nexport interface ApiFragmentHooksConfig {\n onConnectionChanged?: (\n payload: ApiConnectionChangedPayload,\n context: HookContext,\n ) => Promise<void> | void;\n onConnectionDeleted?: (\n payload: ApiConnectionDeletedPayload,\n context: HookContext,\n ) => Promise<void> | void;\n /**\n * Fires when a write changes whether the connection can authorize requests, including creation,\n * and when an access token without a refresh token expires.\n */\n onConnectionReadinessChanged?: (\n payload: ApiConnectionReadinessChange,\n context: HookContext,\n ) => Promise<void> | void;\n onWebhookEndpointChanged?: (\n payload: WebhookEndpointChangedPayload,\n context: HookContext,\n ) => Promise<void> | void;\n onWebhookReceived?: (\n payload: WebhookReceivedPayload,\n context: HookContext,\n ) => Promise<void> | void;\n}\n\nexport type ApiFragmentConfig = BaseApiFragmentConfig & ApiFragmentHooksConfig;\n\nexport type ApiHooksMap = {\n onConnectionChanged: HookFn<ApiConnectionChangedPayload>;\n onConnectionDeleted: HookFn<ApiConnectionDeletedPayload>;\n onConnectionReadinessChanged: HookFn<ApiConnectionReadinessChangedPayload>;\n onAuthExpired: HookFn<InternalAuthExpiredPayload>;\n onWebhookEndpointChanged: HookFn<WebhookEndpointChangedPayload>;\n onWebhookReceived: HookFn<InternalWebhookReceivedPayload>;\n};\n\ntype ApiUow = TypedUnitOfWork<typeof apiSchema, unknown[], unknown, ApiHooksMap>;\n\n/** Expiry changes readiness without a write, so a write that starts the countdown schedules it. */\nfunction scheduleAuthExpiry(\n uow: ApiUow,\n connectionId: string,\n authMode: string,\n after: { payload: string; expiresAt: Date | null },\n) {\n const readyUntil = apiAuthReadyUntil(authMode, after);\n if (readyUntil && after.expiresAt && isApiAuthReady(authMode, after)) {\n uow.triggerHook(\n \"onAuthExpired\",\n { connectionId, expiresAt: after.expiresAt.toISOString() },\n { processAt: readyUntil },\n );\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}): ApiConnectionHookSnapshot {\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\nexport const apiFragmentDefinition = defineFragment<ApiFragmentConfig>(\"api-fragment\")\n .extend(withDatabase(apiSchema))\n .provideHooks<ApiHooksMap>(({ defineHook, config }) => ({\n onConnectionChanged: defineHook(async function (payload) {\n await config.onConnectionChanged?.(payload, this);\n }),\n onConnectionDeleted: defineHook(async function (payload) {\n await config.onConnectionDeleted?.(payload, this);\n }),\n onConnectionReadinessChanged: defineHook(async function (payload) {\n const connection = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema).findFirst(\"api_connection\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", payload.connectionId)),\n ),\n )\n .transformRetrieve(([connection]) => connection && connectionHookSnapshot(connection))\n .execute();\n await config.onConnectionReadinessChanged?.({ ...payload, connection }, this);\n }),\n onAuthExpired: defineHook(async function ({ connectionId, expiresAt }) {\n const expired = await this.handlerTx()\n .retrieve(({ forSchema }) =>\n forSchema(apiSchema)\n .findFirst(\"api_connection\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", connectionId)),\n )\n .findFirst(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_connection_kind\", (eb) =>\n eb.and(eb(\"connectionId\", \"=\", connectionId), eb(\"kind\", \"=\", \"auth\")),\n ),\n ),\n )\n .transformRetrieve(([connection, secret]) =>\n // The hook's due time already passed, so an untouched token is the expired one.\n connection !== null &&\n secret !== null &&\n secret.expiresAt?.getTime() === Date.parse(expiresAt) &&\n apiAuthReadyUntil(connection.authMode, secret) !== null\n ? connectionHookSnapshot(connection)\n : null,\n )\n .execute();\n if (expired) {\n await config.onConnectionReadinessChanged?.(\n { connectionId, ready: false, connection: expired },\n this,\n );\n }\n }),\n onWebhookEndpointChanged: defineHook(async function (payload) {\n await config.onWebhookEndpointChanged?.(payload, this);\n }),\n onWebhookReceived: defineHook(async function (payload) {\n await config.onWebhookReceived?.(\n {\n endpointId: payload.endpointId,\n deliveryId: payload.deliveryId,\n hookId: payload.hookId,\n receivedAt: payload.receivedAt,\n headers: payload.headers,\n query: payload.query,\n body: payload.body,\n contentType: payload.contentType,\n },\n this,\n );\n }),\n }))\n .providesBaseService(({ defineService, config }) =>\n defineService({\n startOAuth: function (input: {\n connectionId: string;\n stateId: string;\n redirectUri: string;\n scopes?: string[];\n extraAuthorizationParams?: Record<string, string>;\n discardTokens: boolean;\n }) {\n return this.serviceTx(apiSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"api_connection\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", input.connectionId)),\n )\n .findFirst(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_connection_kind\", (eb) =>\n eb.and(eb(\"connectionId\", \"=\", input.connectionId), eb(\"kind\", \"=\", \"auth\")),\n ),\n ),\n )\n .transformRetrieve(async ([connection, secret]) => {\n if (!connection) {\n return { found: false as const, reason: \"connection_not_found\" as const };\n }\n if (!secret) {\n return { found: false as const, reason: \"auth_not_configured\" as const };\n }\n const auth = storedAuthPayloadSchema.parse(JSON.parse(secret.payload));\n if (auth.type !== \"oauth\") {\n return { found: false as const, reason: \"auth_not_oauth\" as const };\n }\n const snapshot = await createOAuthStartSnapshot({\n connection,\n auth,\n stateId: input.stateId,\n redirectUri: input.redirectUri,\n scopes: input.scopes,\n extraAuthorizationParams: input.extraAuthorizationParams,\n });\n // Keeps the client configuration; only consent evidence is discarded.\n const clientPayload = JSON.stringify({\n ...auth,\n tokens: undefined,\n redirectUri: undefined,\n });\n return {\n found: true as const,\n authorizationUrl: snapshot.authorizationUrl.toString(),\n oauthState: snapshot.oauthState,\n connectionId: connection.id.toString(),\n secretId: secret.id,\n clientPayload,\n discardChangesReadiness:\n isApiAuthReady(connection.authMode, secret) !==\n isApiAuthReady(connection.authMode, { payload: clientPayload, expiresAt: null }),\n };\n })\n .mutate(({ uow, retrieveResult }) => {\n if (!retrieveResult.found) {\n return retrieveResult;\n }\n uow.create(\"oauthState\", {\n id: retrieveResult.oauthState.id,\n connectionId: retrieveResult.oauthState.connectionId,\n authorizationUrl: retrieveResult.oauthState.authorizationUrl,\n codeVerifier: retrieveResult.oauthState.codeVerifier,\n redirectUri: retrieveResult.oauthState.redirectUri,\n scope: retrieveResult.oauthState.scope,\n expiresAt: retrieveResult.oauthState.expiresAt,\n consumedAt: null,\n });\n if (input.discardTokens) {\n uow.update(\"secret\", retrieveResult.secretId, (b) =>\n b\n .set({\n payload: retrieveResult.clientPayload,\n expiresAt: null,\n updatedAt: b.now(),\n })\n .check(),\n );\n if (retrieveResult.discardChangesReadiness) {\n uow.triggerHook(\"onConnectionReadinessChanged\", {\n connectionId: retrieveResult.connectionId,\n ready: false,\n });\n }\n }\n return { found: true as const, authorizationUrl: retrieveResult.authorizationUrl };\n })\n .transform(({ retrieveResult }) => retrieveResult)\n .build();\n },\n\n completeOAuthCallback: function (input: { stateId: string; code: string }) {\n const stateConnectionSeparatorIndex = input.stateId.lastIndexOf(\":\");\n const connectionId =\n stateConnectionSeparatorIndex === -1\n ? \"\"\n : input.stateId.slice(0, stateConnectionSeparatorIndex);\n return this.serviceTx(apiSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"oauthState\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", input.stateId)),\n )\n .findFirst(\"api_connection\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", connectionId)),\n )\n .findFirst(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_connection_kind\", (eb) =>\n eb.and(eb(\"connectionId\", \"=\", connectionId), eb(\"kind\", \"=\", \"auth\")),\n ),\n ),\n )\n .transformRetrieve(async ([state, connection, secret]) => {\n if (!state || state.consumedAt || new Date(state.expiresAt).getTime() < Date.now()) {\n return { found: false as const, reason: \"invalid_state\" as const };\n }\n if (!connection) {\n return { found: false as const, reason: \"connection_not_found\" as const };\n }\n if (!secret) {\n return { found: false as const, reason: \"auth_not_configured\" as const };\n }\n const auth = storedAuthPayloadSchema.parse(JSON.parse(secret.payload));\n if (auth.type !== \"oauth\") {\n return { found: false as const, reason: \"auth_not_oauth\" as const };\n }\n const changes = await createOAuthCallbackSnapshot({\n config,\n stateId: input.stateId,\n code: input.code,\n state,\n auth,\n });\n return {\n found: true as const,\n connection,\n changes,\n wasReady: isApiAuthReady(connection.authMode, secret),\n };\n })\n .mutate(({ uow, retrieveResult }) => {\n if (!retrieveResult.found) {\n return retrieveResult;\n }\n const connectionId = retrieveResult.connection.id.toString();\n if (retrieveResult.changes.authPayload) {\n uow.update(\"secret\", `${connectionId}:auth`, (b) =>\n b.set({\n payload: retrieveResult.changes.authPayload,\n expiresAt: retrieveResult.changes.authExpiresAt ?? null,\n updatedAt: b.now(),\n }),\n );\n uow.update(\"api_connection\", retrieveResult.connection.id, (b) =>\n b.set({ authMode: \"oauth\", updatedAt: b.now() }).check(),\n );\n const connection = connectionHookSnapshot({\n ...retrieveResult.connection,\n authMode: \"oauth\",\n });\n uow.triggerHook(\"onConnectionChanged\", { connectionId, connection });\n const after = {\n payload: retrieveResult.changes.authPayload,\n expiresAt: retrieveResult.changes.authExpiresAt ?? null,\n };\n const ready = isApiAuthReady(\"oauth\", after);\n if (ready !== retrieveResult.wasReady) {\n uow.triggerHook(\"onConnectionReadinessChanged\", { connectionId, ready });\n }\n scheduleAuthExpiry(uow, connectionId, \"oauth\", after);\n }\n uow.update(\"oauthState\", input.stateId, (b) => b.set({ consumedAt: b.now() }));\n return { found: true as const };\n })\n .transform(({ retrieveResult }) => retrieveResult)\n .build();\n },\n\n executeApiRequest: function (input: { connectionId: string; request: ApiRequestInput }) {\n return this.serviceTx(apiSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"api_connection\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", input.connectionId)),\n )\n .find(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_connection_kind\", (eb) =>\n eb(\"connectionId\", \"=\", input.connectionId),\n ),\n ),\n )\n .transformRetrieve(async ([connection, secrets]) => {\n if (!connection) {\n return { found: false as const };\n }\n if (connection.status !== \"active\") {\n return { found: false as const, reason: \"connection_disabled\" as const };\n }\n const resolved = await resolveApiOperationAuth({ config, secrets });\n const response = await performApiRequest({\n config,\n baseUrl: connection.baseUrl,\n authorization: resolved.authorization,\n request: input.request,\n });\n return {\n found: true as const,\n connection,\n secrets,\n authChanges: resolved.authChanges,\n response,\n };\n })\n .mutate(({ uow, retrieveResult }) => {\n if (!retrieveResult.found) {\n return retrieveResult;\n }\n const connectionId = retrieveResult.connection.id.toString();\n const authChanges = retrieveResult.authChanges;\n if (authChanges?.authPayload) {\n const existing = retrieveResult.secrets.find((secret) => secret.kind === \"auth\");\n if (existing) {\n uow.update(\"secret\", existing.id, (b) =>\n b\n .set({\n payload: authChanges.authPayload,\n expiresAt: authChanges.authExpiresAt ?? null,\n updatedAt: b.now(),\n })\n .check(),\n );\n } else {\n uow.create(\"secret\", {\n id: `${connectionId}:auth`,\n connectionId,\n kind: \"auth\",\n payload: authChanges.authPayload,\n expiresAt: authChanges.authExpiresAt ?? null,\n });\n }\n uow.triggerHook(\"onConnectionChanged\", {\n connectionId,\n connection: connectionHookSnapshot(retrieveResult.connection),\n });\n const { authMode } = retrieveResult.connection;\n const after = {\n payload: authChanges.authPayload,\n expiresAt: authChanges.authExpiresAt ?? null,\n };\n const ready = isApiAuthReady(authMode, after);\n if (ready !== isApiAuthReady(authMode, existing)) {\n uow.triggerHook(\"onConnectionReadinessChanged\", { connectionId, ready });\n }\n scheduleAuthExpiry(uow, connectionId, authMode, after);\n }\n return { found: true as const, response: retrieveResult.response };\n })\n .transform(({ mutateResult }) => mutateResult)\n .build();\n },\n\n refreshClientCredentialsToken: function (input: { connectionId: string }) {\n return this.serviceTx(apiSchema)\n .retrieve((uow) =>\n uow\n .findFirst(\"api_connection\", (b) =>\n b.whereIndex(\"primary\", (eb) => eb(\"id\", \"=\", input.connectionId)),\n )\n .find(\"secret\", (b) =>\n b.whereIndex(\"idx_secret_connection_kind\", (eb) =>\n eb(\"connectionId\", \"=\", input.connectionId),\n ),\n ),\n )\n .transformRetrieve(async ([connection, secrets]) => {\n if (!connection) {\n return { found: false as const };\n }\n const resolved = await resolveApiOperationAuth({ config, secrets });\n return {\n found: true as const,\n connection,\n secrets,\n authChanges: resolved.authChanges,\n tokenPresent: Boolean(resolved.authorization),\n };\n })\n .mutate(({ uow, retrieveResult }) => {\n if (!retrieveResult.found) {\n return retrieveResult;\n }\n const authChanges = retrieveResult.authChanges;\n if (authChanges?.authPayload) {\n const existing = retrieveResult.secrets.find((secret) => secret.kind === \"auth\");\n if (existing) {\n uow.update(\"secret\", existing.id, (b) =>\n b\n .set({\n payload: authChanges.authPayload,\n expiresAt: authChanges.authExpiresAt ?? null,\n updatedAt: b.now(),\n })\n .check(),\n );\n }\n const connectionId = retrieveResult.connection.id.toString();\n const connection = connectionHookSnapshot(retrieveResult.connection);\n uow.triggerHook(\"onConnectionChanged\", { connectionId, connection });\n const { authMode } = retrieveResult.connection;\n const after = {\n payload: authChanges.authPayload,\n expiresAt: authChanges.authExpiresAt ?? null,\n };\n const ready = isApiAuthReady(authMode, after);\n if (ready !== isApiAuthReady(authMode, existing)) {\n uow.triggerHook(\"onConnectionReadinessChanged\", { connectionId, ready });\n }\n scheduleAuthExpiry(uow, connectionId, authMode, after);\n }\n return { found: true as const, tokenPresent: retrieveResult.tokenPresent };\n })\n .transform(({ mutateResult }) => mutateResult)\n .build();\n },\n }),\n )\n .build();\n","const textEncoder = new TextEncoder();\nconst textDecoder = new TextDecoder();\n\nexport type HmacAlgorithm = \"sha1\" | \"sha256\" | \"sha512\";\n\nconst hmacHashName = (algorithm: HmacAlgorithm) =>\n ({\n sha1: \"SHA-1\",\n sha256: \"SHA-256\",\n sha512: \"SHA-512\",\n })[algorithm];\n\nexport function toArrayBuffer(bytes: Uint8Array): ArrayBuffer {\n const copy = new Uint8Array(bytes.byteLength);\n copy.set(bytes);\n return copy.buffer;\n}\n\nexport function utf8Bytes(value: string) {\n return textEncoder.encode(value);\n}\n\nexport function assertAscii(value: string, label: string) {\n for (let index = 0; index < value.length; index += 1) {\n if (value.charCodeAt(index) > 0x7f) {\n throw new Error(`${label} must contain ASCII characters only`);\n }\n }\n}\n\nexport function asciiToBase64(value: string, label: string) {\n assertAscii(value, label);\n return btoa(value);\n}\n\nexport function bytesToBase64(bytes: Uint8Array) {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary);\n}\n\nexport function bytesToBase64Url(bytes: Uint8Array) {\n return bytesToBase64(bytes).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/, \"\");\n}\n\nexport function bytesToHex(bytes: Uint8Array) {\n return [...bytes].map((byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport function decodeHex(value: string) {\n const normalized = value.trim();\n if (normalized.length === 0 || normalized.length % 2 !== 0 || /[^0-9a-f]/i.test(normalized)) {\n return null;\n }\n\n const bytes = new Uint8Array(normalized.length / 2);\n for (let index = 0; index < normalized.length; index += 2) {\n bytes[index / 2] = Number.parseInt(normalized.slice(index, index + 2), 16);\n }\n return bytes;\n}\n\nexport function decodeBase64(value: string, encoding: \"base64\" | \"base64url\") {\n const normalized = normalizeBase64(value, encoding);\n if (!normalized) {\n return null;\n }\n\n try {\n const binary = atob(normalized);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index += 1) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes;\n } catch {\n return null;\n }\n}\n\nexport function decodeBase64ToText(value: string, encoding: \"base64\" | \"base64url\") {\n const bytes = decodeBase64(value, encoding);\n if (!bytes) {\n return null;\n }\n\n return textDecoder.decode(bytes);\n}\n\nexport function normalizeBase64(value: string, encoding: \"base64\" | \"base64url\") {\n let normalized = value.trim();\n if (!normalized) {\n return null;\n }\n\n if (encoding === \"base64url\") {\n normalized = normalized.replace(/-/g, \"+\").replace(/_/g, \"/\");\n }\n\n const paddingLength = (4 - (normalized.length % 4)) % 4;\n return `${normalized}${\"=\".repeat(paddingLength)}`;\n}\n\nexport function randomBase64Url(bytes = 32) {\n const data = new Uint8Array(bytes);\n crypto.getRandomValues(data);\n return bytesToBase64Url(data);\n}\n\nexport async function sha256Bytes(bytes: Uint8Array) {\n return new Uint8Array(await crypto.subtle.digest(\"SHA-256\", toArrayBuffer(bytes)));\n}\n\nexport async function sha256Base64Url(value: string) {\n return bytesToBase64Url(await sha256Bytes(utf8Bytes(value)));\n}\n\nexport async function importHmacKey(input: { algorithm: HmacAlgorithm; secret: string }) {\n return await crypto.subtle.importKey(\n \"raw\",\n toArrayBuffer(utf8Bytes(input.secret)),\n { name: \"HMAC\", hash: hmacHashName(input.algorithm) },\n false,\n [\"sign\", \"verify\"],\n );\n}\n\nexport async function signHmacBytes(input: {\n algorithm: HmacAlgorithm;\n secret: string;\n payload: Uint8Array;\n}) {\n const key = await importHmacKey(input);\n return new Uint8Array(await crypto.subtle.sign(\"HMAC\", key, toArrayBuffer(input.payload)));\n}\n\nexport async function verifyHmacSignature(input: {\n algorithm: HmacAlgorithm;\n secret: string;\n payload: Uint8Array;\n signature: Uint8Array;\n}) {\n const key = await importHmacKey(input);\n return await crypto.subtle.verify(\n \"HMAC\",\n key,\n toArrayBuffer(input.signature),\n toArrayBuffer(input.payload),\n );\n}\n\nexport async function digestEqual(first: Uint8Array, second: Uint8Array) {\n const [firstDigest, secondDigest] = await Promise.all([sha256Bytes(first), sha256Bytes(second)]);\n return equalLengthBytes(firstDigest, secondDigest);\n}\n\nfunction equalLengthBytes(first: Uint8Array, second: Uint8Array) {\n if (first.length !== second.length) {\n return false;\n }\n\n let diff = 0;\n for (let index = 0; index < first.length; index += 1) {\n diff |= first[index] ^ second[index];\n }\n return diff === 0;\n}\n\nexport async function timingSafeEqualText(first: string, second: string) {\n return await digestEqual(utf8Bytes(first), utf8Bytes(second));\n}\n\nexport async function timingSafeEqualBytes(first: Uint8Array, second: Uint8Array) {\n return await digestEqual(first, second);\n}\n","import { z } from \"zod\";\n\nimport {\n decodeBase64,\n decodeBase64ToText,\n decodeHex,\n timingSafeEqualText as verifySecretText,\n utf8Bytes,\n verifyHmacSignature,\n} from \"../crypto\";\n\nconst secretRefSchema = z.string().trim().min(1);\nconst requestValueNameSchema = z.string().trim().min(1);\n\nexport const webhookAuthConfigSchema = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"none\") }),\n z.object({ type: z.literal(\"bearer\"), tokenRef: secretRefSchema }),\n z.object({\n type: z.literal(\"apiKey\"),\n location: z.enum([\"header\", \"query\"]),\n name: requestValueNameSchema,\n secretRef: secretRefSchema,\n }),\n z.object({\n type: z.literal(\"basic\"),\n usernameRef: secretRefSchema,\n passwordRef: secretRefSchema,\n }),\n z.object({\n type: z.literal(\"hmac\"),\n secretRef: secretRefSchema,\n algorithm: z.enum([\"sha1\", \"sha256\", \"sha512\"]),\n signature: z.object({\n location: z.enum([\"header\", \"query\"]),\n name: requestValueNameSchema,\n encoding: z.enum([\"hex\", \"base64\", \"base64url\"]),\n prefix: z.string().optional(),\n }),\n signedPayload: z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"rawBody\") }),\n z.object({\n type: z.literal(\"timestampedBody\"),\n prefix: z.string(),\n timestampHeader: requestValueNameSchema,\n delimiter: z.string(),\n toleranceSeconds: z.number().int().positive(),\n }),\n ]),\n }),\n]);\n\nexport type WebhookAuthConfig = z.infer<typeof webhookAuthConfigSchema>;\nexport type WebhookAuthType = WebhookAuthConfig[\"type\"];\nexport type WebhookAuthSecretRef = string;\n\nexport type WebhookSecretResolver = {\n get(ref: WebhookAuthSecretRef): string | undefined | Promise<string | undefined>;\n};\n\nexport type WebhookAuthFailureReason =\n | \"missing_secret\"\n | \"missing_credential\"\n | \"invalid_credential\"\n | \"timestamp_out_of_range\"\n | \"bad_config\";\n\nexport type WebhookAuthResult = { ok: true } | { ok: false; reason: WebhookAuthFailureReason };\n\nexport type SensitiveRequestValue = {\n location: \"header\" | \"query\";\n name: string;\n};\n\nexport type WebhookAuthVerificationContext = {\n request: Request;\n now: Date;\n secrets: WebhookSecretResolver;\n rawBodyBytes(): Promise<Uint8Array>;\n};\n\nexport interface WebhookAuthVerifier<TConfig extends WebhookAuthConfig> {\n type: TConfig[\"type\"];\n requiredSecretRefs(config: TConfig): readonly WebhookAuthSecretRef[];\n sensitiveRequestValues(config: TConfig): readonly SensitiveRequestValue[];\n verify(config: TConfig, context: WebhookAuthVerificationContext): Promise<WebhookAuthResult>;\n}\n\ntype WebhookAuthVerifierRegistry = {\n [TType in WebhookAuthType]: WebhookAuthVerifier<Extract<WebhookAuthConfig, { type: TType }>>;\n};\n\nexport type VerifyWebhookAuthInput = {\n config: WebhookAuthConfig;\n /** Pass the original web-standard Request or a clone. The body is read from request.clone(). */\n request: Request;\n secrets: WebhookSecretResolver;\n now?: Date;\n};\n\nconst getHeaderAuthorizationCredential = (request: Request, scheme: \"basic\" | \"bearer\") => {\n const header = request.headers.get(\"authorization\");\n if (!header) {\n return null;\n }\n\n const [headerScheme, ...rest] = header.split(/\\s+/);\n if (headerScheme?.toLowerCase() !== scheme || rest.length === 0) {\n return null;\n }\n\n return rest.join(\" \");\n};\n\nconst getRequestValue = (\n request: Request,\n location: \"header\" | \"query\",\n name: string,\n): string | null => {\n if (location === \"header\") {\n return request.headers.get(name);\n }\n\n return new URL(request.url).searchParams.get(name);\n};\n\ntype WebhookAuthFailure = Extract<WebhookAuthResult, { ok: false }>;\n\ntype ResolvedSecret = WebhookAuthFailure | { ok: true; secret: string };\n\nconst requireSecret = async (\n context: WebhookAuthVerificationContext,\n ref: WebhookAuthSecretRef,\n): Promise<ResolvedSecret> => {\n const secret = await context.secrets.get(ref);\n if (!secret) {\n return { ok: false, reason: \"missing_secret\" };\n }\n\n return { ok: true, secret };\n};\n\nconst noneVerifier: WebhookAuthVerifier<Extract<WebhookAuthConfig, { type: \"none\" }>> = {\n type: \"none\",\n requiredSecretRefs: () => [],\n sensitiveRequestValues: () => [],\n verify: async () => ({ ok: true }),\n};\n\nconst bearerVerifier: WebhookAuthVerifier<Extract<WebhookAuthConfig, { type: \"bearer\" }>> = {\n type: \"bearer\",\n requiredSecretRefs: (config) => [config.tokenRef],\n sensitiveRequestValues: () => [{ location: \"header\", name: \"authorization\" }],\n verify: async (config, context) => {\n const secret = await requireSecret(context, config.tokenRef);\n if (!secret.ok) {\n return secret;\n }\n\n const token = getHeaderAuthorizationCredential(context.request, \"bearer\");\n if (!token) {\n return { ok: false, reason: \"missing_credential\" };\n }\n\n return (await verifySecretText(token, secret.secret))\n ? { ok: true }\n : { ok: false, reason: \"invalid_credential\" };\n },\n};\n\nconst apiKeyVerifier: WebhookAuthVerifier<Extract<WebhookAuthConfig, { type: \"apiKey\" }>> = {\n type: \"apiKey\",\n requiredSecretRefs: (config) => [config.secretRef],\n sensitiveRequestValues: (config) => [{ location: config.location, name: config.name }],\n verify: async (config, context) => {\n const secret = await requireSecret(context, config.secretRef);\n if (!secret.ok) {\n return secret;\n }\n\n const credential = getRequestValue(context.request, config.location, config.name);\n if (!credential) {\n return { ok: false, reason: \"missing_credential\" };\n }\n\n return (await verifySecretText(credential, secret.secret))\n ? { ok: true }\n : { ok: false, reason: \"invalid_credential\" };\n },\n};\n\nconst basicVerifier: WebhookAuthVerifier<Extract<WebhookAuthConfig, { type: \"basic\" }>> = {\n type: \"basic\",\n requiredSecretRefs: (config) => [config.usernameRef, config.passwordRef],\n sensitiveRequestValues: () => [{ location: \"header\", name: \"authorization\" }],\n verify: async (config, context) => {\n const username = await requireSecret(context, config.usernameRef);\n if (!username.ok) {\n return username;\n }\n const password = await requireSecret(context, config.passwordRef);\n if (!password.ok) {\n return password;\n }\n\n const encodedCredential = getHeaderAuthorizationCredential(context.request, \"basic\");\n if (!encodedCredential) {\n return { ok: false, reason: \"missing_credential\" };\n }\n\n const decodedCredential = decodeBase64ToText(encodedCredential, \"base64\");\n if (decodedCredential === null) {\n return { ok: false, reason: \"invalid_credential\" };\n }\n\n const separatorIndex = decodedCredential.indexOf(\":\");\n if (separatorIndex === -1) {\n return { ok: false, reason: \"invalid_credential\" };\n }\n\n const actualUsername = decodedCredential.slice(0, separatorIndex);\n const actualPassword = decodedCredential.slice(separatorIndex + 1);\n\n return (await verifySecretText(actualUsername, username.secret)) &&\n (await verifySecretText(actualPassword, password.secret))\n ? { ok: true }\n : { ok: false, reason: \"invalid_credential\" };\n },\n};\n\nconst hmacVerifier: WebhookAuthVerifier<Extract<WebhookAuthConfig, { type: \"hmac\" }>> = {\n type: \"hmac\",\n requiredSecretRefs: (config) => [config.secretRef],\n sensitiveRequestValues: (config) => [\n { location: config.signature.location, name: config.signature.name },\n ],\n verify: async (config, context) => {\n const secret = await requireSecret(context, config.secretRef);\n if (!secret.ok) {\n return secret;\n }\n\n const signatureValue = getRequestValue(\n context.request,\n config.signature.location,\n config.signature.name,\n );\n if (!signatureValue) {\n return { ok: false, reason: \"missing_credential\" };\n }\n\n const normalizedSignature = normalizeSignature(signatureValue, config.signature.prefix);\n if (normalizedSignature === null) {\n return { ok: false, reason: \"invalid_credential\" };\n }\n\n const signedPayload = await buildSignedPayload(config, context);\n if (!signedPayload.ok) {\n return signedPayload;\n }\n\n const providedSignature = decodeSignature(normalizedSignature, config.signature.encoding);\n if (!providedSignature) {\n return { ok: false, reason: \"invalid_credential\" };\n }\n\n return (await verifyHmacSignature({\n algorithm: config.algorithm,\n secret: secret.secret,\n payload: signedPayload.payload,\n signature: providedSignature,\n }))\n ? { ok: true }\n : { ok: false, reason: \"invalid_credential\" };\n },\n};\n\nexport const webhookAuthVerifiers = {\n none: noneVerifier,\n bearer: bearerVerifier,\n apiKey: apiKeyVerifier,\n basic: basicVerifier,\n hmac: hmacVerifier,\n} satisfies WebhookAuthVerifierRegistry;\n\nexport async function verifyWebhookAuth({\n config,\n request,\n secrets,\n now = new Date(),\n}: VerifyWebhookAuthInput): Promise<WebhookAuthResult> {\n const verifier = getWebhookAuthVerifier(config);\n let rawBodyBytes: Uint8Array | null = null;\n\n return await verifier.verify(config, {\n request,\n now,\n secrets,\n rawBodyBytes: async () => {\n rawBodyBytes ??= new Uint8Array(await request.clone().arrayBuffer());\n return rawBodyBytes;\n },\n });\n}\n\nexport function getWebhookAuthSecretRefs(\n config: WebhookAuthConfig,\n): readonly WebhookAuthSecretRef[] {\n return getWebhookAuthVerifier(config).requiredSecretRefs(config);\n}\n\nexport function getSensitiveWebhookAuthValues(\n config: WebhookAuthConfig,\n): readonly SensitiveRequestValue[] {\n return getWebhookAuthVerifier(config).sensitiveRequestValues(config);\n}\n\nfunction getWebhookAuthVerifier<TConfig extends WebhookAuthConfig>(\n config: TConfig,\n): WebhookAuthVerifier<TConfig> {\n return webhookAuthVerifiers[config.type] as WebhookAuthVerifier<TConfig>;\n}\n\nasync function buildSignedPayload(\n config: Extract<WebhookAuthConfig, { type: \"hmac\" }>,\n context: WebhookAuthVerificationContext,\n): Promise<{ ok: true; payload: Uint8Array } | WebhookAuthFailure> {\n if (config.signedPayload.type === \"rawBody\") {\n return { ok: true, payload: await context.rawBodyBytes() };\n }\n\n const timestamp = context.request.headers.get(config.signedPayload.timestampHeader);\n if (!timestamp) {\n return { ok: false, reason: \"missing_credential\" };\n }\n\n const timestampMs = parseWebhookTimestampMs(timestamp);\n if (timestampMs === null) {\n return { ok: false, reason: \"invalid_credential\" };\n }\n\n const toleranceMs = config.signedPayload.toleranceSeconds * 1000;\n if (Math.abs(context.now.getTime() - timestampMs) > toleranceMs) {\n return { ok: false, reason: \"timestamp_out_of_range\" };\n }\n\n return {\n ok: true,\n payload: concatBytes(\n utf8Bytes(`${config.signedPayload.prefix}${timestamp}${config.signedPayload.delimiter}`),\n await context.rawBodyBytes(),\n ),\n };\n}\n\nfunction normalizeSignature(signature: string, prefix: string | undefined) {\n const trimmed = signature.trim();\n if (!prefix) {\n return trimmed || null;\n }\n\n if (!trimmed.startsWith(prefix)) {\n return null;\n }\n\n const withoutPrefix = trimmed.slice(prefix.length).trim();\n return withoutPrefix || null;\n}\n\nfunction decodeSignature(signature: string, encoding: \"hex\" | \"base64\" | \"base64url\") {\n if (encoding === \"hex\") {\n return decodeHex(signature);\n }\n\n return decodeBase64(signature, encoding);\n}\n\nfunction parseWebhookTimestampMs(value: string) {\n const normalized = value.trim();\n if (!/^\\d+$/.test(normalized)) {\n return null;\n }\n\n const numeric = Number(normalized);\n if (!Number.isSafeInteger(numeric) || numeric <= 0) {\n return null;\n }\n\n return numeric < 1_000_000_000_000 ? numeric * 1000 : numeric;\n}\n\nfunction concatBytes(first: Uint8Array, second: Uint8Array) {\n const output = new Uint8Array(first.length + second.length);\n output.set(first, 0);\n output.set(second, first.length);\n return output;\n}\n\nexport { timingSafeEqualBytes, timingSafeEqualText } from \"../crypto\";\n","import { z } from \"zod\";\n\nconst webhookRequestValueNameSchema = z.string().trim().min(1);\n\nexport const webhookRequestValueSourceSchema = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"header\"), name: webhookRequestValueNameSchema }),\n z.object({ type: z.literal(\"query\"), name: webhookRequestValueNameSchema }),\n z.object({\n type: z.literal(\"jsonBodyPath\"),\n path: z.array(z.string().trim().min(1)).min(1),\n }),\n]);\n\nconst webhookVerificationPredicateSchema = z.discriminatedUnion(\"type\", [\n z.object({\n type: z.literal(\"present\"),\n source: webhookRequestValueSourceSchema,\n }),\n z.object({\n type: z.literal(\"equals\"),\n source: webhookRequestValueSourceSchema,\n value: z.string().min(1),\n }),\n]);\n\nexport const webhookVerificationConfigSchema = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"none\") }),\n z.object({\n type: z.literal(\"challenge\"),\n method: z.enum([\"GET\", \"POST\"]),\n when: webhookVerificationPredicateSchema,\n response: z.object({\n type: z.literal(\"echoText\"),\n source: webhookRequestValueSourceSchema,\n }),\n }),\n]);\n\nexport type WebhookRequestValueSource = z.infer<typeof webhookRequestValueSourceSchema>;\nexport type WebhookVerificationConfig = z.infer<typeof webhookVerificationConfigSchema>;\n\nexport type WebhookJsonBodyResult =\n | { ok: true; body: Record<string, unknown> }\n | { ok: false; reason: \"invalid_json\" | \"invalid_value\" };\n\nexport type WebhookRequestValueResult =\n | { ok: true; value: string }\n | { ok: false; reason: \"missing\" | \"invalid_json\" | \"invalid_value\" };\n\nexport type WebhookRequestValues = {\n jsonBody(): WebhookJsonBodyResult;\n read(source: WebhookRequestValueSource): WebhookRequestValueResult;\n};\n\nexport type WebhookVerificationResult =\n | { type: \"not_verification\" }\n | { type: \"response\"; body: string }\n | {\n type: \"invalid_response\";\n reason: \"missing\" | \"invalid_json\" | \"invalid_value\";\n };\n\nexport function createWebhookRequestValues(input: {\n headers: Headers;\n query: URLSearchParams;\n rawBody: string | undefined;\n}): WebhookRequestValues {\n let parsedJsonBody: WebhookJsonBodyResult | undefined;\n\n function jsonBody(): WebhookJsonBodyResult {\n if (parsedJsonBody) {\n return parsedJsonBody;\n }\n\n let value: unknown;\n try {\n value = JSON.parse(input.rawBody ?? \"\");\n } catch {\n parsedJsonBody = { ok: false, reason: \"invalid_json\" };\n return parsedJsonBody;\n }\n\n parsedJsonBody = isJsonObject(value)\n ? { ok: true, body: value }\n : { ok: false, reason: \"invalid_value\" };\n return parsedJsonBody;\n }\n\n function read(source: WebhookRequestValueSource): WebhookRequestValueResult {\n if (source.type === \"header\") {\n return requestValue(input.headers.get(source.name));\n }\n if (source.type === \"query\") {\n return requestValue(input.query.get(source.name));\n }\n\n const body = jsonBody();\n if (!body.ok) {\n return body;\n }\n\n let value: unknown = body.body;\n for (const segment of source.path) {\n if (!isJsonObject(value) || !(segment in value)) {\n return { ok: false, reason: \"missing\" };\n }\n value = value[segment];\n }\n return requestValue(value);\n }\n\n return { jsonBody, read };\n}\n\nexport function evaluateWebhookVerification(input: {\n config: WebhookVerificationConfig;\n method: \"GET\" | \"POST\";\n requestValues: WebhookRequestValues;\n}): WebhookVerificationResult {\n if (input.config.type === \"none\" || input.config.method !== input.method) {\n return { type: \"not_verification\" };\n }\n\n const predicateValue = input.requestValues.read(input.config.when.source);\n if (!predicateValue.ok) {\n return { type: \"not_verification\" };\n }\n\n const matches =\n input.config.when.type === \"present\" || predicateValue.value === input.config.when.value;\n if (!matches) {\n return { type: \"not_verification\" };\n }\n\n const responseValue = input.requestValues.read(input.config.response.source);\n if (!responseValue.ok) {\n return { type: \"invalid_response\", reason: responseValue.reason };\n }\n\n return { type: \"response\", body: responseValue.value };\n}\n\nfunction requestValue(value: unknown): WebhookRequestValueResult {\n if (typeof value === \"string\") {\n return value.length > 0 ? { ok: true, value } : { ok: false, reason: \"missing\" };\n }\n if (typeof value === \"number\") {\n return { ok: true, value: `${value}` };\n }\n return value == null ? { ok: false, reason: \"missing\" } : { ok: false, reason: \"invalid_value\" };\n}\n\nfunction isJsonObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n","import { z } from \"zod\";\n\nimport { webhookAuthConfigSchema } from \"./webhooks/auth\";\nimport { webhookVerificationConfigSchema } from \"./webhooks/verification\";\n\nexport interface ApiFragmentConfig {\n /** Optional URL allow-list. If omitted, only http(s) URL syntax is checked. */\n allowedBaseUrls?: (url: URL) => boolean;\n /** Allows OAuth callback URLs. OAuth start is rejected when this policy is omitted. */\n allowedOAuthRedirectUris?: (url: URL) => boolean;\n /** Optional fetch implementation for tests/custom runtimes. */\n fetch?: typeof fetch;\n}\n\nconst tokenEndpointAuthMethodSchema = z.enum([\"client_secret_basic\", \"client_secret_post\", \"none\"]);\n\nexport const authConfigSchema = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"none\") }),\n z.object({ type: z.literal(\"bearer\"), token: z.string().min(1) }),\n z.object({\n type: z.literal(\"basic\"),\n username: z.string().min(1),\n password: z.string().min(1),\n }),\n z.object({\n type: z.literal(\"client_credentials\"),\n tokenEndpoint: z.url(),\n clientId: z.string().min(1),\n clientSecret: z.string().min(1),\n scopes: z.array(z.string()).optional(),\n audience: z.string().min(1).optional(),\n tokenEndpointAuthMethod: z\n .enum([\"client_secret_basic\", \"client_secret_post\"])\n .default(\"client_secret_basic\"),\n }),\n z.object({\n type: z.literal(\"oauth\"),\n authorizationEndpoint: z.url(),\n tokenEndpoint: z.url(),\n clientId: z.string().min(1),\n clientSecret: z.string().min(1).optional(),\n scopes: z.array(z.string()).optional(),\n tokenEndpointAuthMethod: tokenEndpointAuthMethodSchema.default(\"client_secret_basic\"),\n extraAuthorizationParams: z.record(z.string(), z.string()).optional(),\n extraTokenParams: z.record(z.string(), z.string()).optional(),\n }),\n]);\n\n/** Slugs are URL path segments; whitespace and dot segments would make a connection unaddressable. */\nexport const apiConnectionSlugSchema = z\n .string()\n .regex(\n /^[A-Za-z0-9][A-Za-z0-9._-]*$/,\n \"API connection slugs start with a letter or digit and contain only letters, digits, '.', '_', or '-'.\",\n );\n\nexport const createApiConnectionInputSchema = z.object({\n name: z.string().min(1).optional(),\n baseUrl: z.url(),\n auth: authConfigSchema.default({ type: \"none\" }),\n});\n\nexport const apiConnectionOutputSchema = z.object({\n slug: z.string(),\n name: z.string().nullable().optional(),\n baseUrl: z.string(),\n authMode: z.string(),\n status: z.string(),\n createdAt: z.union([z.string(), z.date()]).optional(),\n updatedAt: z.union([z.string(), z.date()]).optional(),\n});\n\nexport const apiConnectionsPageSchema = z.object({\n connections: z.array(apiConnectionOutputSchema),\n cursor: z.string().nullable().describe(\"Null means every connection has been listed.\"),\n});\n\nconst apiCredentialsPresenceSchema = z\n .enum([\"present\", \"missing\"])\n .describe(\"Whether credentials are stored, not whether the provider accepts them.\");\n\n/** Sanitized auth state derived from stored configuration; it never proves live provider access. */\nexport const apiAuthStatusSchema = z.discriminatedUnion(\"mode\", [\n z.object({ mode: z.literal(\"none\") }),\n z.object({ mode: z.literal(\"bearer\"), credentials: apiCredentialsPresenceSchema }),\n z.object({ mode: z.literal(\"basic\"), credentials: apiCredentialsPresenceSchema }),\n z.object({ mode: z.literal(\"client_credentials\"), credentials: apiCredentialsPresenceSchema }),\n z.object({\n mode: z.literal(\"oauth\"),\n state: z\n .enum([\"client-missing\", \"consent-required\", \"consent-pending\", \"authorized\", \"expired\"])\n .describe(\n \"Expired means the access token expired and no refresh token is stored; pending means an unexpired authorization link exists.\",\n ),\n }),\n]);\n\n/** The pending link embeds the callback state, so reading it requires connection-create authority. */\nexport const apiOAuthPendingSchema = z.object({\n pending: z\n .object({ authorizationUrl: z.url(), expiresAt: z.union([z.string(), z.date()]) })\n .nullable()\n .describe(\n \"The newest unexpired, unconsumed authorization link; any pending link completes it.\",\n ),\n});\n\nexport const tokenAuthInputSchema = z.object({ token: z.string().min(1) });\n\n/** Query parameter carrying the OAuth callback URI for an OAuth start request. */\nexport const API_OAUTH_REDIRECT_URI_QUERY_PARAMETER = \"redirectUri\";\n\nexport const oauthRedirectUriSchema = z.url().refine((value) => {\n const protocol = new URL(value).protocol;\n return protocol === \"https:\" || protocol === \"http:\";\n}, \"OAuth redirect URI must use HTTP or HTTPS\");\n\nexport const oauthStartInputSchema = z.object({\n scopes: z.array(z.string()).optional(),\n extraAuthorizationParams: z.record(z.string(), z.string()).optional(),\n discardTokens: z\n .boolean()\n .default(false)\n .describe(\n \"Drop stored tokens so status reports pending consent until this new consent completes.\",\n ),\n});\n\nexport const apiRequestBodySchema = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"empty\") }),\n z.object({ type: z.literal(\"json\"), value: z.unknown() }),\n z.object({ type: z.literal(\"text\"), value: z.string() }),\n]);\n\nexport const apiRequestInputSchema = z.object({\n method: z.enum([\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\"]),\n path: z.string().min(1),\n query: z.record(z.string(), z.string()).optional(),\n headers: z.record(z.string(), z.string()).optional(),\n body: apiRequestBodySchema,\n timeoutMs: z.number().int().positive().max(120_000).optional(),\n});\n\nexport const apiResponseBodySchema = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"json\"), value: z.unknown() }),\n z.object({ type: z.literal(\"text\"), value: z.string() }),\n z.object({ type: z.literal(\"empty\"), value: z.null() }),\n]);\n\nexport const apiHttpResponseSchema = z.object({\n status: z.number().int(),\n statusText: z.string(),\n headers: z.record(z.string(), z.string()),\n body: apiResponseBodySchema,\n});\n\nexport const apiRequestOutputSchema = z.discriminatedUnion(\"ok\", [\n z.object({\n ok: z.literal(true),\n response: apiHttpResponseSchema,\n error: z.null(),\n }),\n z.object({\n ok: z.literal(false),\n response: apiHttpResponseSchema.nullable(),\n error: z.object({\n code: z.enum([\n \"HTTP_ERROR\",\n \"REQUEST_ERROR\",\n \"RESPONSE_DECODING_ERROR\",\n \"CONNECTION_NOT_FOUND\",\n \"CONNECTION_DISABLED\",\n ]),\n message: z.string(),\n }),\n }),\n]);\n\nconst webhookSecretRefSchema = z.string().trim().min(1);\nconst webhookRequestValueNameSchema = z.string().trim().min(1);\n\nexport const webhookDeliveryIdentitySchema = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"header\"), name: webhookRequestValueNameSchema }),\n z.object({ type: z.literal(\"query\"), name: webhookRequestValueNameSchema }),\n z.object({\n type: z.literal(\"jsonBodyPath\"),\n path: z.array(z.string().trim().min(1)).min(1),\n }),\n]);\n\nexport const webhookEndpointAuthInputSchema = z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"none\") }),\n z.object({ type: z.literal(\"bearer\"), token: webhookSecretRefSchema }),\n z.object({\n type: z.literal(\"apiKey\"),\n location: z.enum([\"header\", \"query\"]),\n name: webhookRequestValueNameSchema,\n secret: webhookSecretRefSchema,\n }),\n z.object({\n type: z.literal(\"basic\"),\n username: webhookSecretRefSchema,\n password: webhookSecretRefSchema,\n }),\n z.object({\n type: z.literal(\"hmac\"),\n secret: webhookSecretRefSchema,\n algorithm: z.enum([\"sha1\", \"sha256\", \"sha512\"]),\n signature: z.object({\n location: z.enum([\"header\", \"query\"]),\n name: webhookRequestValueNameSchema,\n encoding: z.enum([\"hex\", \"base64\", \"base64url\"]),\n prefix: z.string().optional(),\n }),\n signedPayload: z.discriminatedUnion(\"type\", [\n z.object({ type: z.literal(\"rawBody\") }),\n z.object({\n type: z.literal(\"timestampedBody\"),\n prefix: z.string(),\n timestampHeader: webhookRequestValueNameSchema,\n delimiter: z.string(),\n toleranceSeconds: z.number().int().positive(),\n }),\n ]),\n }),\n]);\n\nexport const webhookEndpointStatusSchema = z.enum([\"draft\", \"active\", \"disabled\"]);\n\n/** Why the receive routes refused a request for an existing endpoint. */\nexport const webhookRejectionCodeSchema = z.enum([\n \"WEBHOOK_ENDPOINT_DISABLED\",\n \"WEBHOOK_ENDPOINT_DRAFT\",\n \"WEBHOOK_AUTH_FAILED\",\n \"WEBHOOK_VERIFICATION_NOT_MATCHED\",\n \"WEBHOOK_VERIFICATION_RESPONSE_INVALID\",\n \"WEBHOOK_BODY_INVALID\",\n \"WEBHOOK_DELIVERY_ID_MISSING\",\n \"WEBHOOK_DELIVERY_ID_INVALID\",\n]);\n\nexport const webhookDeliveryEvidenceSchema = z\n .object({\n lastAcceptedAt: z\n .string()\n .nullable()\n .describe(\"Last accepted delivery or answered verification challenge.\"),\n lastRejection: z\n .object({ receivedAt: z.string(), code: webhookRejectionCodeSchema })\n .nullable()\n .describe(\n \"Last refused request. Anyone with the URL can cause one, so it is diagnostic, not proof of a provider problem.\",\n ),\n })\n .describe(\"Requests since the endpoint's configuration last changed.\");\n\nexport const webhookEndpointOutputSchema = z.object({\n id: z.string(),\n name: z.string(),\n status: webhookEndpointStatusSchema,\n authConfig: webhookAuthConfigSchema,\n verification: webhookVerificationConfigSchema,\n deliveryIdentity: webhookDeliveryIdentitySchema,\n secretRefs: z.array(z.string()),\n deliveries: webhookDeliveryEvidenceSchema,\n createdAt: z.union([z.string(), z.date()]).optional(),\n updatedAt: z.union([z.string(), z.date()]).optional(),\n});\n\nexport const createWebhookEndpointInputSchema = z.object({\n name: z.string().min(1),\n status: webhookEndpointStatusSchema.default(\"active\"),\n verification: webhookVerificationConfigSchema,\n deliveryIdentity: webhookDeliveryIdentitySchema,\n auth: webhookEndpointAuthInputSchema,\n});\n\nexport const updateWebhookEndpointInputSchema = z.object({\n name: z.string().min(1).optional(),\n status: webhookEndpointStatusSchema.optional(),\n verification: webhookVerificationConfigSchema.optional(),\n deliveryIdentity: webhookDeliveryIdentitySchema.optional(),\n auth: webhookEndpointAuthInputSchema.optional(),\n});\n\nexport type AuthConfig = z.infer<typeof authConfigSchema>;\nexport type ApiConnectionInput = z.infer<typeof createApiConnectionInputSchema>;\nexport type ApiConnection = z.infer<typeof apiConnectionOutputSchema>;\nexport type ApiConnectionsPage = z.infer<typeof apiConnectionsPageSchema>;\nexport type ApiAuthStatus = z.infer<typeof apiAuthStatusSchema>;\nexport type ApiOAuthPending = z.infer<typeof apiOAuthPendingSchema>;\nexport type ApiRequestBody = z.infer<typeof apiRequestBodySchema>;\nexport type ApiRequestInput = z.infer<typeof apiRequestInputSchema>;\nexport type ApiResponseBody = z.infer<typeof apiResponseBodySchema>;\nexport type ApiHttpResponse = z.infer<typeof apiHttpResponseSchema>;\nexport type ApiRequestOutput = z.infer<typeof apiRequestOutputSchema>;\nexport type WebhookDeliveryIdentity = z.infer<typeof webhookDeliveryIdentitySchema>;\nexport type WebhookEndpointAuthInput = z.infer<typeof webhookEndpointAuthInputSchema>;\nexport type WebhookEndpointInput = z.infer<typeof createWebhookEndpointInputSchema>;\nexport type UpdateWebhookEndpointInput = z.infer<typeof updateWebhookEndpointInputSchema>;\nexport type WebhookEndpoint = z.infer<typeof webhookEndpointOutputSchema>;\nexport type WebhookRejectionCode = z.infer<typeof webhookRejectionCodeSchema>;\nexport type WebhookDeliveryEvidence = z.infer<typeof webhookDeliveryEvidenceSchema>;\n","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","import { createClientBuilder, type FragnoPublicClientConfig } from \"@fragno-dev/core/client\";\n\nimport { apiFragmentDefinition } from \"../definition\";\nimport { apiRoutesFactory } from \"../routes\";\n\nconst apiRoutes = [apiRoutesFactory] as const;\n\nexport function createApiFragmentClients(fragnoConfig: FragnoPublicClientConfig = {}) {\n const builder = createClientBuilder(apiFragmentDefinition, fragnoConfig, apiRoutes);\n\n return {\n useConnections: builder.createHook(\"/connections\"),\n useConnection: builder.createHook(\"/connections/:slug\"),\n useAuthStatus: builder.createHook(\"/connections/:slug/auth/status\"),\n usePendingOAuth: builder.createHook(\"/connections/:slug/auth/oauth/pending\"),\n createConnection: builder.createMutator(\"PUT\", \"/connections/:slug\"),\n deleteConnection: builder.createMutator(\"DELETE\", \"/connections/:slug\"),\n setBearerToken: builder.createMutator(\"POST\", \"/connections/:slug/auth/token\"),\n startOAuth: builder.createMutator(\"POST\", \"/connections/:slug/auth/oauth/start\"),\n deleteAuth: builder.createMutator(\"DELETE\", \"/connections/:slug/auth\"),\n request: builder.createMutator(\"POST\", \"/connections/:slug/request\"),\n useWebhookEndpoints: builder.createHook(\"/webhooks/endpoints\"),\n useWebhookEndpoint: builder.createHook(\"/webhooks/endpoints/:endpointId\"),\n createWebhookEndpoint: builder.createMutator(\"PUT\", \"/webhooks/endpoints/:endpointId\"),\n updateWebhookEndpoint: builder.createMutator(\"PATCH\", \"/webhooks/endpoints/:endpointId\"),\n deleteWebhookEndpoint: builder.createMutator(\"DELETE\", \"/webhooks/endpoints/:endpointId\"),\n };\n}\n"],"x_google_ignoreList":[10,11,12,13,14,15,16,21,22],"mappings":"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"}