@mycreat-labs/integrations-sdk 0.1.0 → 0.1.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.
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.1 — 2026-11-01
|
|
4
|
+
|
|
5
|
+
- Accept Notion's documented `refresh_token: null` response without fabricating
|
|
6
|
+
a refresh credential or preserving a previously rotated refresh token. The
|
|
7
|
+
response field remains required; missing, empty or malformed values are rejected.
|
|
8
|
+
- Verify that non-refreshable grants remain usable without an advertised expiry,
|
|
9
|
+
require reauthorization on a definite 401 or advertised expiry, and never
|
|
10
|
+
automatically redispatch rejected or expired writes.
|
|
11
|
+
|
|
12
|
+
Contract: [Notion Create a token](https://developers.notion.com/reference/create-a-token).
|
|
13
|
+
This release requires no API or storage migration and does not modify the
|
|
14
|
+
published `0.1.0` artifact. Consumers choose when to upgrade their pinned version.
|
package/dist/providers/index.cjs
CHANGED
|
@@ -827,7 +827,7 @@ function tokenCredentials(value, previous) {
|
|
|
827
827
|
try {
|
|
828
828
|
const response = record(value);
|
|
829
829
|
const accessToken = text(response.access_token, 8192);
|
|
830
|
-
const refreshToken = text(response.refresh_token, 8192);
|
|
830
|
+
const refreshToken = response.refresh_token === null ? void 0 : text(response.refresh_token, 8192);
|
|
831
831
|
if (typeof response.token_type !== "string" || response.token_type.toLowerCase() !== "bearer")
|
|
832
832
|
throw new Error();
|
|
833
833
|
const expires = response.expires_in;
|
|
@@ -835,7 +835,7 @@ function tokenCredentials(value, previous) {
|
|
|
835
835
|
throw new Error();
|
|
836
836
|
return {
|
|
837
837
|
accessToken,
|
|
838
|
-
refreshToken,
|
|
838
|
+
...refreshToken !== void 0 ? { refreshToken } : {},
|
|
839
839
|
...expires !== void 0 ? { expiresAt: Date.now() + Number(expires) * 1e3 } : {},
|
|
840
840
|
...previous?.scopes ? { scopes: previous.scopes } : {},
|
|
841
841
|
...previous?.extra ? { extra: previous.extra } : {}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/providers/index.ts","../../src/providers/identity.ts","../../src/errors.ts","../../src/providers/http.ts","../../src/providers/notion.ts","../../src/providers/raindrop.ts"],"sourcesContent":["export {\n createGoogleProvider,\n createAppleProvider,\n createGitHubProvider,\n} from \"./identity.js\";\nexport type {\n IdentityProviderConfig,\n GoogleProviderConfig,\n AppleProviderConfig,\n GitHubProviderConfig,\n} from \"./identity.js\";\nexport {\n createNotionProvider,\n createNotionClient,\n validateNotionCreatePage,\n NOTION_API_VERSION,\n} from \"./notion.js\";\nexport type {\n NotionProviderConfig,\n NotionClientConfig,\n NotionCreatePageInput,\n} from \"./notion.js\";\nexport {\n createRaindropProvider,\n createRaindropClient,\n validateRaindropCreateBookmark,\n RAINDROP_TOKEN_ENDPOINT,\n} from \"./raindrop.js\";\nexport type {\n RaindropProviderConfig,\n RaindropClientConfig,\n RaindropCreateBookmarkInput,\n} from \"./raindrop.js\";\nexport { ProviderHttpError, notionRequest, raindropRequest } from \"./http.js\";\nexport type { ProviderRequestOptions } from \"./http.js\";\n","import {\n createLocalJWKSet,\n importPKCS8,\n jwtVerify,\n SignJWT,\n type JSONWebKeySet,\n type JWTPayload,\n} from \"jose\";\nimport { timingSafeEqual } from \"node:crypto\";\nimport { IntegrationError } from \"../errors.js\";\nimport type {\n AuthorizationInput,\n IntegrationProvider,\n VerifiedIdentity,\n} from \"../types.js\";\nimport { optionalText, record, requestJson, text } from \"./http.js\";\n\nexport type IdentityProviderConfig = {\n registrationId: string;\n identityNamespace?: string;\n clientId: string;\n redirectUri: string;\n};\nexport type GoogleProviderConfig = IdentityProviderConfig & {\n clientSecret?: string;\n nativeClientIds?: readonly string[];\n};\nexport type AppleProviderConfig = IdentityProviderConfig & {\n teamId?: string;\n keyId?: string;\n privateKey?: string;\n nativeClientIds?: readonly string[];\n};\nexport type GitHubProviderConfig = IdentityProviderConfig & {\n clientSecret: string;\n};\n\nfunction configure(config: IdentityProviderConfig): void {\n if (\n !config.registrationId ||\n !config.clientId ||\n !config.redirectUri ||\n config.identityNamespace === \"\"\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n let url: URL;\n try {\n url = new URL(config.redirectUri);\n } catch {\n throw new IntegrationError(\"invalid_provider_configuration\");\n }\n if (\n url.username ||\n url.password ||\n url.hash ||\n (url.protocol !== \"https:\" &&\n !(\n url.protocol === \"http:\" &&\n [\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(url.hostname)\n ))\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n}\nfunction identityPurpose(purpose: string): void {\n if (purpose !== \"identity\") throw new IntegrationError(\"unsupported_purpose\");\n}\nfunction authorizationURL(\n base: string,\n parameters: Record<string, string>,\n): string {\n const url = new URL(base);\n for (const [key, value] of Object.entries(parameters))\n url.searchParams.set(key, value);\n return url.toString();\n}\nconst keyCaches = new WeakMap<\n typeof globalThis.fetch,\n Map<\n string,\n {\n expires: number;\n refreshedAt: number;\n resolve: ReturnType<typeof createLocalJWKSet>;\n }\n >\n>();\nconst keyLoads = new WeakMap<\n typeof globalThis.fetch,\n Map<string, Promise<ReturnType<typeof createLocalJWKSet>>>\n>();\nasync function keys(\n url: string,\n fetcher: typeof globalThis.fetch,\n force = false,\n) {\n let cache = keyCaches.get(fetcher);\n if (!cache) {\n cache = new Map();\n keyCaches.set(fetcher, cache);\n }\n const existing = cache.get(url);\n if (!force && existing && existing.expires > Date.now())\n return existing.resolve;\n // An untrusted kid cannot force unlimited requests to the vendor's key endpoint.\n if (force && existing && existing.refreshedAt + 30_000 > Date.now())\n return existing.resolve;\n let loads = keyLoads.get(fetcher);\n if (!loads) {\n loads = new Map();\n keyLoads.set(fetcher, loads);\n }\n const pending = loads.get(url);\n if (pending) return pending;\n const load = (async () => {\n try {\n const value = record(await requestJson(url, {}, fetcher));\n if (!Array.isArray(value.keys) || value.keys.length > 100)\n throw new Error();\n const resolve = createLocalJWKSet(value as unknown as JSONWebKeySet);\n const now = Date.now();\n cache!.set(url, { expires: now + 300_000, refreshedAt: now, resolve });\n return resolve;\n } catch {\n throw new IntegrationError(\"identity_unavailable\", \"retryable\");\n }\n })();\n loads.set(url, load);\n try {\n return await load;\n } finally {\n loads.delete(url);\n }\n}\nasync function verifyToken(\n input: { idToken: string; nonce: string },\n config: IdentityProviderConfig,\n fetcher: typeof globalThis.fetch,\n options: { provider: \"google\" | \"apple\"; audiences: readonly string[] },\n): Promise<VerifiedIdentity> {\n if (\n !input.nonce ||\n input.nonce.length > 1024 ||\n !input.idToken ||\n input.idToken.length > 32_768 ||\n !options.audiences.length ||\n options.audiences.some((item) => !item)\n )\n throw new IntegrationError(\"invalid_identity\");\n const google = options.provider === \"google\";\n const issuer = google\n ? \"https://accounts.google.com\"\n : \"https://appleid.apple.com\";\n const jwks = google\n ? \"https://www.googleapis.com/oauth2/v3/certs\"\n : \"https://appleid.apple.com/auth/keys\";\n const verificationOptions = {\n algorithms: [\"RS256\"],\n issuer: google ? [issuer, \"accounts.google.com\"] : issuer,\n audience: [...options.audiences],\n requiredClaims: [\"sub\", \"exp\", \"iat\", \"nonce\"],\n clockTolerance: 30,\n };\n let payload: JWTPayload;\n try {\n let resolve = await keys(jwks, fetcher);\n try {\n ({ payload } = await jwtVerify(\n input.idToken,\n resolve,\n verificationOptions,\n ));\n } catch (error) {\n if (!(\n error &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ERR_JWKS_NO_MATCHING_KEY\"\n ))\n throw error;\n resolve = await keys(jwks, fetcher, true);\n ({ payload } = await jwtVerify(\n input.idToken,\n resolve,\n verificationOptions,\n ));\n }\n const expected = Buffer.from(input.nonce);\n const actual = Buffer.from(\n typeof payload.nonce === \"string\" ? payload.nonce : \"\",\n );\n if (\n expected.length !== actual.length ||\n !timingSafeEqual(expected, actual) ||\n typeof payload.iat !== \"number\" ||\n payload.iat > Date.now() / 1000 + 30 ||\n typeof payload.sub !== \"string\" ||\n !payload.sub ||\n payload.sub.length > 255\n )\n throw new Error();\n // A multi-audience assertion must identify one of this registration's clients.\n if (\n Array.isArray(payload.aud) &&\n payload.aud.length > 1 &&\n (typeof payload.azp !== \"string\" ||\n !options.audiences.includes(payload.azp))\n )\n throw new Error();\n } catch (error) {\n if (\n error instanceof IntegrationError &&\n (error.disposition === \"retryable\" ||\n error.disposition === \"outcome_unknown\")\n )\n throw new IntegrationError(\"identity_unavailable\", \"retryable\");\n throw new IntegrationError(\"invalid_identity\");\n }\n const email = optionalText(payload.email, 320);\n const name = optionalText(payload.name, 1024);\n return {\n provider: options.provider,\n issuer,\n subject: payload.sub!,\n identityNamespace: config.identityNamespace ?? config.registrationId,\n emailVerified:\n payload.email_verified === true ||\n (options.provider === \"apple\" && payload.email_verified === \"true\"),\n ...(email ? { email } : {}),\n ...(name ? { name } : {}),\n };\n}\n\nexport function createGoogleProvider(\n config: GoogleProviderConfig,\n): IntegrationProvider {\n configure(config);\n return {\n key: \"google\",\n registrationId: config.registrationId,\n purposes: [\"identity\"],\n authorization: {\n url(input: AuthorizationInput) {\n identityPurpose(input.purpose);\n return authorizationURL(\n \"https://accounts.google.com/o/oauth2/v2/auth\",\n {\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n scope: \"openid email profile\",\n state: input.state,\n nonce: input.nonce,\n code_challenge: input.challenge,\n code_challenge_method: \"S256\",\n },\n );\n },\n async exchange(input, fetcher) {\n identityPurpose(input.purpose);\n if (!config.clientSecret)\n throw new IntegrationError(\"application_unavailable\");\n const tokens = record(\n await requestJson(\n \"https://oauth2.googleapis.com/token\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n redirect_uri: config.redirectUri,\n grant_type: \"authorization_code\",\n code: input.code,\n code_verifier: input.verifier,\n }),\n ...(input.signal ? { signal: input.signal } : {}),\n },\n fetcher,\n ),\n );\n const identity = await verifyToken(\n { idToken: text(tokens.id_token, 32_768), nonce: input.nonce },\n config,\n fetcher,\n { provider: \"google\", audiences: [config.clientId] },\n );\n return { identity }; // Login never exposes or persists OAuth provider tokens.\n },\n },\n verifyNative(input, fetcher) {\n return verifyToken(input, config, fetcher, {\n provider: \"google\",\n audiences: config.nativeClientIds ?? [config.clientId],\n });\n },\n };\n}\n\nexport function createAppleProvider(\n config: AppleProviderConfig,\n): IntegrationProvider {\n configure(config);\n async function clientSecret(): Promise<string> {\n if (!config.teamId || !config.keyId || !config.privateKey)\n throw new IntegrationError(\"application_unavailable\");\n try {\n const key = await importPKCS8(config.privateKey, \"ES256\");\n return await new SignJWT({})\n .setProtectedHeader({ alg: \"ES256\", kid: config.keyId })\n .setIssuer(config.teamId)\n .setSubject(config.clientId)\n .setAudience(\"https://appleid.apple.com\")\n .setIssuedAt()\n .setExpirationTime(\"5m\")\n .sign(key);\n } catch {\n throw new IntegrationError(\"application_unavailable\");\n }\n }\n return {\n key: \"apple\",\n registrationId: config.registrationId,\n purposes: [\"identity\"],\n authorization: {\n url(input) {\n identityPurpose(input.purpose);\n return authorizationURL(\"https://appleid.apple.com/auth/authorize\", {\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n response_mode: \"form_post\",\n scope: \"name email\",\n state: input.state,\n nonce: input.nonce,\n });\n },\n async exchange(input, fetcher) {\n identityPurpose(input.purpose);\n const result = record(\n await requestJson(\n \"https://appleid.apple.com/auth/token\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: await clientSecret(),\n redirect_uri: config.redirectUri,\n grant_type: \"authorization_code\",\n code: input.code,\n }),\n ...(input.signal ? { signal: input.signal } : {}),\n },\n fetcher,\n ),\n );\n return {\n identity: await verifyToken(\n { idToken: text(result.id_token, 32_768), nonce: input.nonce },\n config,\n fetcher,\n { provider: \"apple\", audiences: [config.clientId] },\n ),\n };\n },\n },\n // nonce is the actual expected token nonce; a native host using SHA256 supplies that hash.\n verifyNative(input, fetcher) {\n return verifyToken(input, config, fetcher, {\n provider: \"apple\",\n audiences: config.nativeClientIds ?? [config.clientId],\n });\n },\n };\n}\n\nexport function createGitHubProvider(\n config: GitHubProviderConfig,\n): IntegrationProvider {\n configure(config);\n if (!config.clientSecret)\n throw new IntegrationError(\"invalid_provider_configuration\");\n return {\n key: \"github\",\n registrationId: config.registrationId,\n purposes: [\"identity\"],\n authorization: {\n url(input) {\n identityPurpose(input.purpose);\n return authorizationURL(\"https://github.com/login/oauth/authorize\", {\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n scope: \"read:user user:email\",\n state: input.state,\n code_challenge: input.challenge,\n code_challenge_method: \"S256\",\n });\n },\n async exchange(input, fetcher) {\n identityPurpose(input.purpose);\n const tokens = record(\n await requestJson(\n \"https://github.com/login/oauth/access_token\",\n {\n method: \"POST\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n redirect_uri: config.redirectUri,\n code: input.code,\n code_verifier: input.verifier,\n }),\n ...(input.signal ? { signal: input.signal } : {}),\n },\n fetcher,\n ),\n );\n const accessToken = text(tokens.access_token);\n const headers = {\n Accept: \"application/vnd.github+json\",\n Authorization: `Bearer ${accessToken}`,\n \"X-GitHub-Api-Version\": \"2026-03-10\",\n \"User-Agent\": \"mycreat-labs-integrations-sdk\",\n };\n const user = record(\n await requestJson(\n \"https://api.github.com/user\",\n { headers, ...(input.signal ? { signal: input.signal } : {}) },\n fetcher,\n ),\n );\n if (!Number.isSafeInteger(user.id) || Number(user.id) <= 0)\n throw new IntegrationError(\"invalid_identity\");\n const emails = await requestJson(\n \"https://api.github.com/user/emails?per_page=100\",\n { headers, ...(input.signal ? { signal: input.signal } : {}) },\n fetcher,\n );\n if (!Array.isArray(emails) || emails.length > 100)\n throw new IntegrationError(\"invalid_identity\");\n const primary = emails.find(\n (item) =>\n item &&\n typeof item === \"object\" &&\n item.primary === true &&\n item.verified === true,\n ) as { email?: unknown } | undefined;\n const email = primary ? text(primary.email, 320) : undefined;\n const name = optionalText(user.name, 1024);\n const username = text(user.login, 255);\n return {\n identity: {\n provider: \"github\",\n issuer: \"https://github.com\",\n subject: String(user.id),\n identityNamespace:\n config.identityNamespace ?? config.registrationId,\n emailVerified: Boolean(email),\n username,\n ...(email ? { email } : {}),\n ...(name ? { name } : {}),\n },\n };\n },\n },\n };\n}\n","export type FailureDisposition =\n \"retryable\" | \"requires_reauth\" | \"outcome_unknown\" | \"permanent_failure\";\nexport class IntegrationError extends Error {\n readonly sdkError = \"@mycreat-labs/integrations-sdk/v1\";\n constructor(\n readonly code: string,\n readonly disposition: FailureDisposition = \"permanent_failure\",\n readonly retryAfterMs?: number,\n ) {\n super(code);\n this.name = \"IntegrationError\";\n }\n}\nexport function integrationError(error: unknown): IntegrationError {\n if (error instanceof IntegrationError) return error;\n // Bundled subpath entries and independently installed copies have separate class identities.\n if (\n error instanceof Error &&\n \"sdkError\" in error &&\n error.sdkError === \"@mycreat-labs/integrations-sdk/v1\" &&\n \"code\" in error &&\n typeof error.code === \"string\" &&\n /^[a-zA-Z0-9_]{1,100}$/.test(error.code) &&\n \"disposition\" in error &&\n [\n \"retryable\",\n \"requires_reauth\",\n \"outcome_unknown\",\n \"permanent_failure\",\n ].includes(String(error.disposition))\n ) {\n const delay =\n \"retryAfterMs\" in error &&\n typeof error.retryAfterMs === \"number\" &&\n Number.isFinite(error.retryAfterMs) &&\n error.retryAfterMs >= 0\n ? error.retryAfterMs\n : undefined;\n return new IntegrationError(\n error.code,\n error.disposition as FailureDisposition,\n delay,\n );\n }\n return new IntegrationError(\"provider_unavailable\", \"outcome_unknown\");\n}\n","import { IntegrationError, type FailureDisposition } from \"../errors.js\";\nimport type { Json } from \"../types.js\";\n\nexport type ProviderRequestOptions = {\n accessToken?: string;\n clientId?: string;\n clientSecret?: string;\n method?: string;\n body?: unknown;\n signal?: AbortSignal;\n fetch?: typeof globalThis.fetch;\n apiVersion?: string;\n};\n\n/** Contains only safe classifications and validated receipt IDs, never upstream messages. */\nexport class ProviderHttpError extends IntegrationError {\n readonly status: number | null;\n readonly providerCode?: string;\n readonly definite: boolean;\n readonly committedResourceId?: string;\n readonly committedChildIds?: string[];\n constructor(\n code: string,\n disposition: FailureDisposition,\n options: {\n status?: number;\n providerCode?: string;\n definite?: boolean;\n retryAfterMs?: number;\n committedResourceId?: string;\n committedChildIds?: string[];\n } = {},\n ) {\n super(code, disposition, options.retryAfterMs);\n this.name = \"ProviderHttpError\";\n this.status = options.status ?? null;\n this.providerCode = options.providerCode;\n this.definite = options.definite ?? false;\n this.committedResourceId = options.committedResourceId;\n this.committedChildIds = options.committedChildIds;\n }\n}\n\nexport function record(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n throw new IntegrationError(\"invalid_response\");\n return value as Record<string, unknown>;\n}\nexport function text(value: unknown, max = 4096): string {\n if (typeof value !== \"string\" || value.length === 0 || value.length > max)\n throw new IntegrationError(\"invalid_response\");\n return value;\n}\nexport function optionalText(value: unknown, max = 4096): string | undefined {\n return value === undefined || value === null ? undefined : text(value, max);\n}\nexport function inputRecord(\n value: unknown,\n keys: readonly string[],\n): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n throw new IntegrationError(\"invalid_input\");\n const input = value as Record<string, unknown>;\n if (Object.keys(input).some((key) => !keys.includes(key)))\n throw new IntegrationError(\"invalid_input\");\n return input;\n}\nexport function inputText(\n value: unknown,\n maximum: number,\n required = true,\n): string | undefined {\n if (value === undefined && !required) return undefined;\n if (\n typeof value !== \"string\" ||\n (required && !value.trim()) ||\n value.length > maximum\n )\n throw new IntegrationError(\"invalid_input\");\n return value;\n}\nexport function webUrl(value: unknown): string {\n const result = inputText(value, 10_000)!;\n try {\n const url = new URL(result);\n if (\n ![\"https:\", \"http:\"].includes(url.protocol) ||\n url.username ||\n url.password\n )\n throw new Error();\n } catch {\n throw new IntegrationError(\"invalid_input\");\n }\n return result;\n}\nexport function jsonMetadata(value: unknown): Json | undefined {\n if (value === undefined) return undefined;\n const visit = (item: unknown, depth: number): boolean =>\n depth <= 10 &&\n (item === null ||\n typeof item === \"string\" ||\n typeof item === \"boolean\" ||\n (typeof item === \"number\" && Number.isFinite(item)) ||\n (Array.isArray(item) && item.every((child) => visit(child, depth + 1))) ||\n (typeof item === \"object\" &&\n item !== null &&\n Object.getPrototypeOf(item) === Object.prototype &&\n Object.values(item).every((child) => visit(child, depth + 1))));\n if (!visit(value, 0) || JSON.stringify(value).length > 16_384)\n throw new IntegrationError(\"invalid_input\");\n return value as Json;\n}\n\nconst safeCodes = new Set([\n \"invalid_client\",\n \"unauthorized_client\",\n \"invalid_grant\",\n \"bad_authorization_code\",\n \"invalid_request\",\n \"invalid_json\",\n \"validation_error\",\n \"restricted_resource\",\n \"unauthorized\",\n \"object_not_found\",\n \"rate_limited\",\n \"conflict_error\",\n \"internal_server_error\",\n \"service_unavailable\",\n \"gateway_timeout\",\n \"service_overload\",\n \"row_limit_exceeded\",\n \"invalid_token\",\n \"bad_verification_code\",\n \"incorrect_client_credentials\",\n \"redirect_uri_mismatch\",\n \"access_denied\",\n]);\nconst uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nexport const isUuid = (value: unknown): value is string =>\n typeof value === \"string\" && uuid.test(value);\nexport function retryDelay(value: string | null): number | undefined {\n if (!value) return undefined;\n const milliseconds = /^\\d+(?:\\.\\d+)?$/.test(value)\n ? Number(value) * 1000\n : Date.parse(value) - Date.now();\n return Number.isFinite(milliseconds)\n ? Math.max(0, Math.min(milliseconds, 86_400_000))\n : undefined;\n}\n\nfunction failure(\n status: number,\n body: unknown,\n write: boolean,\n retryAfterMs?: number,\n): ProviderHttpError {\n const payload =\n body && typeof body === \"object\" && !Array.isArray(body)\n ? (body as Record<string, unknown>)\n : {};\n const vendorCode =\n typeof payload.code === \"string\"\n ? payload.code\n : typeof payload.error === \"string\"\n ? payload.error\n : undefined;\n const providerCode =\n vendorCode && safeCodes.has(vendorCode) ? vendorCode : undefined;\n const extra =\n payload.additional_data && typeof payload.additional_data === \"object\"\n ? (payload.additional_data as Record<string, unknown>)\n : {};\n const committedResourceId = isUuid(extra.committed_resource_id)\n ? extra.committed_resource_id\n : undefined;\n const committedChildIds =\n Array.isArray(extra.committed_child_ids) &&\n extra.committed_child_ids.length <= 100 &&\n extra.committed_child_ids.every(isUuid)\n ? (extra.committed_child_ids as string[])\n : undefined;\n const definite =\n status >= 400 &&\n status < 500 &&\n status !== 408 &&\n !committedResourceId &&\n !committedChildIds?.length;\n let code =\n status === 401\n ? \"auth_required\"\n : status === 404\n ? \"resource_unavailable\"\n : status === 403\n ? \"permission_required\"\n : status === 429 || status === 529\n ? \"rate_limited\"\n : status >= 500\n ? \"upstream_unavailable\"\n : \"invalid_payload\";\n if (\n providerCode === \"invalid_client\" ||\n providerCode === \"unauthorized_client\" ||\n providerCode === \"incorrect_client_credentials\" ||\n payload.errorMessage === \"client_id or client_secret is invalid\"\n )\n code = \"application_unavailable\";\n else if (\n providerCode === \"invalid_grant\" ||\n providerCode === \"bad_authorization_code\" ||\n providerCode === \"invalid_token\" ||\n providerCode === \"bad_verification_code\"\n )\n code = \"auth_required\";\n else if (extra.rate_limit_reason === \"public_api_request_blocked\")\n code = \"access_restricted\";\n else if (status === 403 && providerCode === \"restricted_resource\")\n code = \"resource_unavailable\";\n else if (\n status === 403 &&\n typeof payload.message === \"string\" &&\n /block.*limit|limit.*block/i.test(payload.message)\n )\n code = \"workspace_capacity\";\n const disposition: FailureDisposition =\n code === \"auth_required\"\n ? \"requires_reauth\"\n : write && !definite\n ? \"outcome_unknown\"\n : code === \"rate_limited\" || status >= 500 || status === 408\n ? \"retryable\"\n : \"permanent_failure\";\n return new ProviderHttpError(code, disposition, {\n status,\n providerCode,\n definite,\n retryAfterMs,\n committedResourceId,\n committedChildIds,\n });\n}\n\nexport async function requestJson(\n url: string,\n init: RequestInit,\n fetcher: typeof globalThis.fetch,\n options: { write?: boolean; raindrop?: boolean; requireJson?: boolean } = {},\n): Promise<unknown> {\n const write =\n options.write ?? ![\"GET\", \"HEAD\"].includes(init.method ?? \"GET\");\n const signal = init.signal\n ? AbortSignal.any([init.signal, AbortSignal.timeout(30_000)])\n : AbortSignal.timeout(30_000);\n let response: Response;\n try {\n response = await fetcher(url, { ...init, signal, redirect: \"error\" });\n } catch (error) {\n // An SDK admission limiter rejected the request before any HTTP dispatch.\n if (\n error instanceof Error &&\n \"sdkError\" in error &&\n error.sdkError === \"@mycreat-labs/integrations-sdk/v1\" &&\n \"code\" in error &&\n error.code === \"rate_limited\" &&\n \"definite\" in error &&\n error.definite === true\n ) {\n const delay =\n \"retryAfterMs\" in error &&\n typeof error.retryAfterMs === \"number\" &&\n Number.isFinite(error.retryAfterMs)\n ? Math.max(0, Math.min(error.retryAfterMs, 86_400_000))\n : undefined;\n throw new ProviderHttpError(\"rate_limited\", \"retryable\", {\n status: 429,\n definite: true,\n retryAfterMs: delay,\n });\n }\n throw new ProviderHttpError(\n \"upstream_unavailable\",\n write ? \"outcome_unknown\" : \"retryable\",\n );\n }\n if (response.status === 204 && response.ok) return {};\n let body: unknown;\n try {\n if (\n options.requireJson &&\n !response.headers.get(\"content-type\")?.toLowerCase().includes(\"json\")\n )\n throw new Error();\n if (!response.body) throw new Error();\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n try {\n for (;;) {\n const part = await reader.read();\n if (part.done) break;\n size += part.value.length;\n if (size > 2_097_152) {\n await reader.cancel();\n throw new Error();\n }\n chunks.push(part.value);\n }\n } finally {\n reader.releaseLock();\n }\n body = JSON.parse(Buffer.concat(chunks).toString(\"utf8\")) as unknown;\n } catch {\n if (!response.ok)\n throw failure(\n response.status,\n {},\n write,\n retryDelay(response.headers.get(\"retry-after\")),\n );\n throw new ProviderHttpError(\n \"invalid_response\",\n write ? \"outcome_unknown\" : \"retryable\",\n { status: response.status },\n );\n }\n if (!response.ok)\n throw failure(\n response.status,\n body,\n write,\n retryDelay(response.headers.get(\"retry-after\")),\n );\n if (body && typeof body === \"object\" && !Array.isArray(body)) {\n const value = body as Record<string, unknown>;\n if (\n typeof value.error === \"string\" ||\n (options.raindrop && value.result === false)\n ) {\n const status =\n typeof value.status === \"number\" &&\n Number.isInteger(value.status) &&\n value.status >= 400 &&\n value.status < 600\n ? value.status\n : 400;\n throw failure(\n status,\n body,\n write,\n retryDelay(response.headers.get(\"retry-after\")),\n );\n }\n }\n return body;\n}\n\nfunction providerPath(path: string, prefix: string): string {\n if (\n path.length > 4096 ||\n !/^\\/[a-zA-Z0-9_/-]+(?:\\?[a-zA-Z0-9_%=&.~-]+)?$/.test(path) ||\n path.includes(\"//\") ||\n path.includes(\"..\")\n )\n throw new ProviderHttpError(\"invalid_upstream_path\", \"permanent_failure\", {\n status: 400,\n definite: true,\n });\n return path.startsWith(`${prefix}/`) || path === prefix\n ? path\n : `${prefix}${path}`;\n}\nexport function notionRequest(\n path: string,\n options: ProviderRequestOptions,\n): Promise<unknown> {\n const normalized = providerPath(path, \"/v1\");\n if (!options.accessToken && (!options.clientId || !options.clientSecret))\n throw new ProviderHttpError(\n \"application_unavailable\",\n \"permanent_failure\",\n { definite: true },\n );\n const authorization = options.accessToken\n ? `Bearer ${options.accessToken}`\n : `Basic ${Buffer.from(`${options.clientId}:${options.clientSecret}`).toString(\"base64\")}`;\n return requestJson(\n `https://api.notion.com${normalized}`,\n {\n method: options.method ?? (options.body === undefined ? \"GET\" : \"POST\"),\n headers: {\n \"Notion-Version\": options.apiVersion ?? \"2026-03-11\",\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Authorization: authorization,\n },\n ...(options.body === undefined\n ? {}\n : { body: JSON.stringify(options.body) }),\n ...(options.signal ? { signal: options.signal } : {}),\n },\n options.fetch ?? globalThis.fetch,\n {\n write:\n normalized !== \"/v1/search\" &&\n (options.method ?? (options.body === undefined ? \"GET\" : \"POST\")) !==\n \"GET\",\n },\n );\n}\nexport function raindropRequest(\n path: string,\n options: ProviderRequestOptions,\n): Promise<unknown> {\n const normalized =\n path === \"/v1/oauth/access_token\" ? path : providerPath(path, \"/rest/v1\");\n if (normalized !== \"/v1/oauth/access_token\" && !options.accessToken)\n throw new ProviderHttpError(\"auth_required\", \"requires_reauth\", {\n status: 401,\n definite: true,\n });\n return requestJson(\n `https://api.raindrop.io${normalized}`,\n {\n method: options.method ?? (options.body === undefined ? \"GET\" : \"POST\"),\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...(options.accessToken\n ? { Authorization: `Bearer ${options.accessToken}` }\n : {}),\n },\n ...(options.body === undefined\n ? {}\n : { body: JSON.stringify(options.body) }),\n ...(options.signal ? { signal: options.signal } : {}),\n },\n options.fetch ?? globalThis.fetch,\n { raindrop: true, requireJson: true },\n );\n}\n","import { IntegrationError } from \"../errors.js\";\nimport type {\n CredentialMaterial,\n IntegrationProvider,\n Json,\n Resource,\n ResourcePage,\n} from \"../types.js\";\nimport {\n inputRecord,\n inputText,\n isUuid,\n jsonMetadata,\n notionRequest,\n optionalText,\n record,\n text,\n webUrl,\n type ProviderRequestOptions,\n} from \"./http.js\";\n\nexport const NOTION_API_VERSION = \"2026-03-11\";\nexport type NotionProviderConfig = {\n registrationId: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n apiVersion?: string;\n};\nexport type NotionClientConfig = {\n accessToken: string;\n fetch?: typeof globalThis.fetch;\n signal?: AbortSignal;\n apiVersion?: string;\n};\nexport type NotionCreatePageInput = {\n parentId: string;\n parentType?: \"page\" | \"data_source\";\n title: string;\n content?: string;\n url?: string;\n metadata?: { [key: string]: Json };\n};\n\nfunction uuid(value: unknown): string {\n if (!isUuid(value)) throw new IntegrationError(\"invalid_input\");\n return value;\n}\nconst validCursor = (value: unknown): value is string =>\n typeof value === \"string\" && value.length > 0 && value.length <= 4096;\nexport function validateNotionCreatePage(\n value: unknown,\n): NotionCreatePageInput {\n const input = inputRecord(value, [\n \"parentId\",\n \"parentType\",\n \"title\",\n \"content\",\n \"url\",\n \"metadata\",\n ]);\n const result: NotionCreatePageInput = {\n parentId: uuid(input.parentId),\n title: inputText(input.title, 2000)!,\n };\n if (input.parentType !== undefined) {\n if (input.parentType !== \"page\" && input.parentType !== \"data_source\")\n throw new IntegrationError(\"invalid_input\");\n result.parentType = input.parentType;\n }\n if (input.content !== undefined)\n result.content = inputText(input.content, 100_000, false)!;\n if (input.url !== undefined) result.url = webUrl(input.url);\n if (input.metadata !== undefined) {\n const metadata = jsonMetadata(input.metadata);\n if (!metadata || Array.isArray(metadata) || typeof metadata !== \"object\")\n throw new IntegrationError(\"invalid_input\");\n result.metadata = metadata;\n }\n return result;\n}\nfunction richText(value: string): Json[] {\n const result: Json[] = [];\n for (let index = 0; index < value.length;) {\n let end = Math.min(index + 2000, value.length);\n if (end < value.length && /[\\uD800-\\uDBFF]/.test(value.charAt(end - 1)))\n end--;\n result.push({ type: \"text\", text: { content: value.slice(index, end) } });\n index = end;\n }\n return result;\n}\nfunction resourceTitle(value: unknown): string {\n if (!Array.isArray(value)) throw new IntegrationError(\"invalid_response\");\n return value\n .map((item) => {\n const piece = record(item);\n if (typeof piece.plain_text === \"string\") return piece.plain_text;\n return text(record(piece.text).content, 2000);\n })\n .join(\"\");\n}\nfunction pageResult(value: unknown): { id: string; url: string } {\n try {\n const page = record(value);\n if (page.object !== \"page\" || !isUuid(page.id)) throw new Error();\n const url = text(page.url, 4096);\n if (new URL(url).protocol !== \"https:\") throw new Error();\n return { id: page.id, url };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\n\nexport function createNotionClient(config: NotionClientConfig) {\n if (!config.accessToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n const request = (\n path: string,\n options: Omit<\n ProviderRequestOptions,\n \"accessToken\" | \"clientId\" | \"clientSecret\"\n > = {},\n ) => notionRequest(path, { ...config, ...options });\n async function listResources(\n input: { cursor?: string; query?: string; parentId?: string } = {},\n ): Promise<ResourcePage> {\n if (input.parentId !== undefined)\n throw new IntegrationError(\"unsupported_resource_filter\");\n if (input.cursor !== undefined && !validCursor(input.cursor))\n throw new IntegrationError(\"invalid_input\");\n if (input.query !== undefined) inputText(input.query, 1000, false);\n const response = record(\n await request(\"/search\", {\n body: {\n page_size: 100,\n ...(input.cursor ? { start_cursor: input.cursor } : {}),\n ...(input.query !== undefined ? { query: input.query } : {}),\n },\n }),\n );\n if (\n !Array.isArray(response.results) ||\n response.results.length > 100 ||\n typeof response.has_more !== \"boolean\"\n )\n throw new IntegrationError(\"invalid_response\");\n if (\n response.request_status !== undefined &&\n record(response.request_status).type !== \"complete\"\n )\n throw new IntegrationError(\"resource_listing_incomplete\");\n if (response.has_more && !validCursor(response.next_cursor))\n throw new IntegrationError(\"invalid_response\");\n const items: Resource[] = [];\n for (const item of response.results) {\n const entry = record(item);\n if (\n !isUuid(entry.id) ||\n (entry.object !== \"page\" && entry.object !== \"data_source\")\n )\n throw new IntegrationError(\"invalid_response\");\n if (\n entry.in_trash === true ||\n entry.archived === true ||\n entry.is_archived === true\n )\n continue;\n let name: string;\n if (entry.object === \"data_source\") name = resourceTitle(entry.title);\n else {\n const properties = record(entry.properties);\n const title = Object.values(properties)\n .map(record)\n .find((property) => property.type === \"title\");\n name = title ? resourceTitle(title.title) : \"\";\n }\n const url = optionalText(entry.url);\n items.push({\n id: entry.id,\n type: entry.object,\n name: name || \"Untitled\",\n ...(url ? { url } : {}),\n });\n }\n return {\n items,\n ...(response.has_more\n ? { nextCursor: response.next_cursor as string }\n : {}),\n };\n }\n async function createPage(\n value: NotionCreatePageInput,\n ): Promise<{ id: string; url: string }> {\n const input = validateNotionCreatePage(value);\n const parentType = input.parentType ?? \"page\";\n let titleKey = \"title\";\n if (parentType === \"data_source\") {\n const source = record(await request(`/data_sources/${input.parentId}`));\n if (source.id !== input.parentId || source.object !== \"data_source\")\n throw new IntegrationError(\"invalid_response\");\n const property = Object.entries(record(source.properties)).find(\n ([, definition]) => record(definition).type === \"title\",\n );\n if (!property) throw new IntegrationError(\"invalid_resource\");\n titleKey = property[0];\n }\n const children: Json[] = [];\n if (input.content) {\n for (const part of richText(input.content))\n children.push({\n object: \"block\",\n type: \"paragraph\",\n paragraph: { rich_text: [part] },\n });\n }\n if (input.url)\n children.push({\n object: \"block\",\n type: \"bookmark\",\n bookmark: { url: input.url },\n });\n return pageResult(\n await request(\"/pages\", {\n body: {\n parent:\n parentType === \"page\"\n ? { page_id: input.parentId }\n : { data_source_id: input.parentId },\n properties: {\n [titleKey]: { type: \"title\", title: richText(input.title) },\n },\n ...(children.length ? { children } : {}),\n },\n }),\n );\n }\n return { request, listResources, resources: listResources, createPage };\n}\n\nfunction tokenCredentials(\n value: unknown,\n previous?: CredentialMaterial,\n): CredentialMaterial {\n try {\n const response = record(value);\n const accessToken = text(response.access_token, 8192);\n const refreshToken = text(response.refresh_token, 8192);\n if (\n typeof response.token_type !== \"string\" ||\n response.token_type.toLowerCase() !== \"bearer\"\n )\n throw new Error();\n const expires = response.expires_in;\n if (\n expires !== undefined &&\n (typeof expires !== \"number\" ||\n !Number.isInteger(expires) ||\n expires <= 0 ||\n expires > 31_536_000)\n )\n throw new Error();\n return {\n accessToken,\n refreshToken,\n ...(expires !== undefined\n ? { expiresAt: Date.now() + Number(expires) * 1000 }\n : {}),\n ...(previous?.scopes ? { scopes: previous.scopes } : {}),\n ...(previous?.extra ? { extra: previous.extra } : {}),\n };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\nexport function createNotionProvider(\n config: NotionProviderConfig,\n): IntegrationProvider {\n if (\n !config.registrationId ||\n !config.clientId ||\n !config.clientSecret ||\n !config.redirectUri\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n const tokenRequest = (\n body: Json,\n fetcher: typeof globalThis.fetch,\n signal?: AbortSignal,\n ) =>\n notionRequest(\"/oauth/token\", {\n clientId: config.clientId,\n clientSecret: config.clientSecret,\n apiVersion: config.apiVersion,\n body,\n fetch: fetcher,\n ...(signal ? { signal } : {}),\n });\n return {\n key: \"notion\",\n registrationId: config.registrationId,\n purposes: [\"connect\"],\n authorization: {\n url(input) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const url = new URL(\"https://api.notion.com/v1/oauth/authorize\");\n url.search = new URLSearchParams({\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n owner: \"user\",\n state: input.state,\n }).toString();\n return url.toString();\n },\n async exchange(input, fetcher) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const response = record(\n await tokenRequest(\n {\n grant_type: \"authorization_code\",\n code: input.code,\n redirect_uri: config.redirectUri,\n },\n fetcher,\n input.signal,\n ),\n );\n const credentials = tokenCredentials(response);\n const workspaceId = text(response.workspace_id);\n const botId = text(response.bot_id);\n if (!isUuid(workspaceId) || !isUuid(botId))\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n const owner = record(response.owner);\n if (owner.type !== \"user\")\n throw new IntegrationError(\"invalid_response\");\n const userId = text(record(owner.user).id);\n if (!isUuid(userId)) throw new IntegrationError(\"invalid_response\");\n const label =\n optionalText(response.workspace_name) ?? \"Notion workspace\";\n credentials.extra = { workspaceId, botId, ownerId: userId };\n return {\n credentials,\n account: {\n id: `${workspaceId}:${botId}:${userId}`,\n label,\n metadata: { workspaceId, botId, ownerId: userId },\n },\n };\n },\n },\n resources(input, context) {\n return createNotionClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n apiVersion: config.apiVersion,\n }).listResources(input);\n },\n async refresh(credentials, context) {\n if (!credentials.refreshToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n return tokenCredentials(\n await tokenRequest(\n {\n grant_type: \"refresh_token\",\n refresh_token: credentials.refreshToken,\n },\n context.fetch,\n context.signal,\n ),\n credentials,\n );\n },\n async revoke(credentials, context) {\n await notionRequest(\"/oauth/revoke\", {\n clientId: config.clientId,\n clientSecret: config.clientSecret,\n apiVersion: config.apiVersion,\n body: { token: credentials.accessToken },\n fetch: context.fetch,\n signal: context.signal,\n });\n },\n actions: {\n create_page: {\n validate(value) {\n return validateNotionCreatePage(value) as unknown as Json;\n },\n async execute(value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (\n typeof checkpoint.id === \"string\" &&\n typeof checkpoint.url === \"string\"\n )\n return { id: checkpoint.id, url: checkpoint.url };\n const result = await createNotionClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n apiVersion: config.apiVersion,\n }).createPage(value as unknown as NotionCreatePageInput);\n await context.saveCheckpoint(result);\n return result;\n },\n async reconcile(_value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (!isUuid(checkpoint.id)) return { resolved: false };\n const result = pageResult(\n await notionRequest(`/pages/${checkpoint.id}`, {\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n apiVersion: config.apiVersion,\n }),\n );\n if (result.id !== checkpoint.id)\n throw new IntegrationError(\"invalid_response\");\n return { resolved: true, result };\n },\n },\n },\n };\n}\n","import { IntegrationError } from \"../errors.js\";\nimport type {\n CredentialMaterial,\n IntegrationProvider,\n Json,\n Resource,\n ResourcePage,\n} from \"../types.js\";\nimport {\n inputRecord,\n inputText,\n jsonMetadata,\n optionalText,\n raindropRequest,\n record,\n text,\n webUrl,\n type ProviderRequestOptions,\n} from \"./http.js\";\n\nexport type RaindropProviderConfig = {\n registrationId: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n};\nexport type RaindropClientConfig = {\n accessToken: string;\n fetch?: typeof globalThis.fetch;\n signal?: AbortSignal;\n};\nexport type RaindropCreateBookmarkInput = {\n collectionId?: number;\n url: string;\n title?: string;\n note?: string;\n excerpt?: string;\n tags?: string[];\n metadata?: { [key: string]: Json };\n};\nexport const RAINDROP_TOKEN_ENDPOINT =\n \"https://api.raindrop.io/v1/oauth/access_token\";\n\nfunction collectionId(value: unknown): number {\n if (\n !Number.isSafeInteger(value) ||\n (Number(value) !== -1 && Number(value) <= 0)\n )\n throw new IntegrationError(\"invalid_input\");\n return value as number;\n}\nexport function validateRaindropCreateBookmark(\n value: unknown,\n): RaindropCreateBookmarkInput {\n const input = inputRecord(value, [\n \"collectionId\",\n \"url\",\n \"title\",\n \"note\",\n \"excerpt\",\n \"tags\",\n \"metadata\",\n ]);\n const result: RaindropCreateBookmarkInput = { url: webUrl(input.url) };\n if (input.collectionId !== undefined)\n result.collectionId = collectionId(input.collectionId);\n if (input.title !== undefined)\n result.title = inputText(input.title, 10_000, false)!;\n if (input.note !== undefined)\n result.note = inputText(input.note, 100_000, false)!;\n if (input.excerpt !== undefined)\n result.excerpt = inputText(input.excerpt, 10_000, false)!;\n if (input.tags !== undefined) {\n if (\n !Array.isArray(input.tags) ||\n input.tags.length > 100 ||\n input.tags.some(\n (tag) => typeof tag !== \"string\" || !tag.trim() || tag.length > 255,\n )\n )\n throw new IntegrationError(\"invalid_input\");\n result.tags = [...new Set(input.tags as string[])];\n }\n if (input.metadata !== undefined) {\n const metadata = jsonMetadata(input.metadata);\n if (!metadata || Array.isArray(metadata) || typeof metadata !== \"object\")\n throw new IntegrationError(\"invalid_input\");\n result.metadata = metadata;\n }\n return result;\n}\nfunction bookmarkResult(\n value: unknown,\n input?: RaindropCreateBookmarkInput,\n): { id: string; url: string; collectionId: number } {\n try {\n const response = record(value);\n if (response.result !== true) throw new Error();\n const item = record(response.item);\n if (!Number.isSafeInteger(item._id) || Number(item._id) <= 0)\n throw new Error();\n const destination = collectionId(record(item.collection).$id);\n const link = text(item.link, 10_000);\n if (\n input &&\n (new URL(link).toString() !== new URL(input.url).toString() ||\n destination !== (input.collectionId ?? -1))\n )\n throw new Error();\n return {\n id: String(item._id),\n collectionId: destination,\n url: `https://app.raindrop.io/my/${destination}/item/${item._id}`,\n };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\nexport function createRaindropClient(config: RaindropClientConfig) {\n if (!config.accessToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n const request = (\n path: string,\n options: Omit<\n ProviderRequestOptions,\n \"accessToken\" | \"clientId\" | \"clientSecret\"\n > = {},\n ) => raindropRequest(path, { ...config, ...options });\n async function listCollections(\n input: { cursor?: string; query?: string; parentId?: string } = {},\n ): Promise<ResourcePage> {\n if (input.cursor !== undefined) throw new IntegrationError(\"invalid_input\");\n if (input.query !== undefined) inputText(input.query, 1000, false);\n if (input.parentId !== undefined && !/^[1-9][0-9]*$/.test(input.parentId))\n throw new IntegrationError(\"invalid_input\");\n const pages = await Promise.all([\n request(\"/collections\"),\n request(\"/collections/childrens\"),\n ]);\n const resources = new Map<string, Resource>();\n resources.set(\"-1\", { id: \"-1\", type: \"collection\", name: \"Unsorted\" });\n for (const value of pages) {\n const response = record(value);\n if (\n response.result !== true ||\n !Array.isArray(response.items) ||\n response.items.length > 10_000\n )\n throw new IntegrationError(\"invalid_response\");\n for (const value of response.items) {\n const item = record(value);\n if (!Number.isSafeInteger(item._id) || Number(item._id) <= 0)\n throw new IntegrationError(\"invalid_response\");\n const level = record(item.access).level;\n if (!Number.isInteger(level) || Number(level) < 1 || Number(level) > 4)\n throw new IntegrationError(\"invalid_response\");\n if (Number(level) < 3) continue;\n let parentId: string | undefined;\n if (item.parent !== undefined && item.parent !== null) {\n const parent = record(item.parent);\n const id = parent.$id ?? parent._id;\n if (!Number.isSafeInteger(id) || Number(id) <= 0)\n throw new IntegrationError(\"invalid_response\");\n parentId = String(id);\n }\n resources.set(String(item._id), {\n id: String(item._id),\n type: \"collection\",\n name: text(item.title),\n metadata: {\n accessLevel: Number(level),\n ...(parentId ? { parentId } : {}),\n },\n });\n }\n }\n return {\n items: [...resources.values()].filter(\n (item) =>\n (!input.parentId || item.metadata?.parentId === input.parentId) &&\n (!input.query ||\n item.name\n .toLocaleLowerCase()\n .includes(input.query.toLocaleLowerCase())),\n ),\n };\n }\n async function createBookmark(value: RaindropCreateBookmarkInput) {\n const input = validateRaindropCreateBookmark(value);\n const id = input.collectionId ?? -1;\n if (id !== -1) {\n const response = record(await request(`/collection/${id}`));\n const item = record(response.item);\n if (response.result !== true || item._id !== id)\n throw new IntegrationError(\"invalid_response\");\n const level = record(item.access).level;\n if (level !== 3 && level !== 4)\n throw new IntegrationError(\"permission_required\");\n }\n const payload: Json = {\n link: input.url,\n collection: { $id: id },\n ...(input.title !== undefined ? { title: input.title } : {}),\n ...(input.note !== undefined ? { note: input.note } : {}),\n ...(input.excerpt !== undefined ? { excerpt: input.excerpt } : {}),\n ...(input.tags ? { tags: input.tags } : {}),\n };\n return bookmarkResult(await request(\"/raindrop\", { body: payload }), input);\n }\n return {\n request,\n listCollections,\n resources: listCollections,\n createBookmark,\n };\n}\n\nfunction tokenCredentials(\n value: unknown,\n previous?: CredentialMaterial,\n): CredentialMaterial {\n try {\n const response = record(value);\n const accessToken = text(response.access_token, 8192);\n const refreshToken = text(response.refresh_token, 8192);\n const expires = response.expires_in;\n if (\n typeof response.token_type !== \"string\" ||\n response.token_type.toLowerCase() !== \"bearer\" ||\n typeof expires !== \"number\" ||\n !Number.isInteger(expires) ||\n expires <= 0 ||\n expires > 31_536_000\n )\n throw new Error();\n return {\n accessToken,\n refreshToken,\n expiresAt: Date.now() + expires * 1000,\n ...(previous?.extra ? { extra: previous.extra } : {}),\n };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\nexport function createRaindropProvider(\n config: RaindropProviderConfig,\n): IntegrationProvider {\n if (\n !config.registrationId ||\n !config.clientId ||\n !config.clientSecret ||\n !config.redirectUri\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n const tokenRequest = (\n body: Json,\n fetcher: typeof globalThis.fetch,\n signal?: AbortSignal,\n ) =>\n raindropRequest(\"/v1/oauth/access_token\", {\n body: {\n client_id: config.clientId,\n client_secret: config.clientSecret,\n ...(body as Record<string, Json>),\n },\n fetch: fetcher,\n ...(signal ? { signal } : {}),\n });\n return {\n key: \"raindrop\",\n registrationId: config.registrationId,\n purposes: [\"connect\"],\n authorization: {\n url(input) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const url = new URL(\"https://raindrop.io/oauth/authorize\");\n url.search = new URLSearchParams({\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n state: input.state,\n }).toString();\n return url.toString();\n },\n async exchange(input, fetcher) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const credentials = tokenCredentials(\n await tokenRequest(\n {\n grant_type: \"authorization_code\",\n code: input.code,\n redirect_uri: config.redirectUri,\n },\n fetcher,\n input.signal,\n ),\n );\n const response = record(\n await raindropRequest(\"/user\", {\n accessToken: credentials.accessToken,\n fetch: fetcher,\n signal: input.signal,\n }),\n );\n const user = record(response.user);\n if (\n response.result !== true ||\n !Number.isSafeInteger(user._id) ||\n Number(user._id) <= 0\n )\n throw new IntegrationError(\"invalid_response\");\n const id = String(user._id);\n return {\n credentials,\n account: {\n id,\n label: optionalText(user.fullName) ?? `Raindrop ${id}`,\n },\n };\n },\n },\n resources(input, context) {\n return createRaindropClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n }).listCollections(input);\n },\n async refresh(credentials, context) {\n if (!credentials.refreshToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n return tokenCredentials(\n await tokenRequest(\n {\n grant_type: \"refresh_token\",\n refresh_token: credentials.refreshToken,\n },\n context.fetch,\n context.signal,\n ),\n credentials,\n );\n },\n // Raindrop does not document a revocation API; local disconnect must not pretend to revoke the upstream grant.\n actions: {\n create_bookmark: {\n validate(value) {\n return validateRaindropCreateBookmark(value) as unknown as Json;\n },\n async execute(value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (\n typeof checkpoint.id === \"string\" &&\n typeof checkpoint.url === \"string\" &&\n typeof checkpoint.collectionId === \"number\"\n )\n return {\n id: checkpoint.id,\n url: checkpoint.url,\n collectionId: checkpoint.collectionId,\n };\n const result = await createRaindropClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n }).createBookmark(value as unknown as RaindropCreateBookmarkInput);\n await context.saveCheckpoint(result);\n return result;\n },\n async reconcile(value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (\n typeof checkpoint.id !== \"string\" ||\n !/^[1-9][0-9]*$/.test(checkpoint.id)\n )\n return { resolved: false };\n const result = bookmarkResult(\n await raindropRequest(`/raindrop/${checkpoint.id}`, {\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n }),\n validateRaindropCreateBookmark(value),\n );\n if (result.id !== checkpoint.id)\n throw new IntegrationError(\"invalid_response\");\n return { resolved: true, result };\n },\n },\n },\n };\n}\n"],"mappings":"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","names":["keys","uuid","value","tokenCredentials"]}
|
|
1
|
+
{"version":3,"sources":["../../src/providers/index.ts","../../src/providers/identity.ts","../../src/errors.ts","../../src/providers/http.ts","../../src/providers/notion.ts","../../src/providers/raindrop.ts"],"sourcesContent":["export {\n createGoogleProvider,\n createAppleProvider,\n createGitHubProvider,\n} from \"./identity.js\";\nexport type {\n IdentityProviderConfig,\n GoogleProviderConfig,\n AppleProviderConfig,\n GitHubProviderConfig,\n} from \"./identity.js\";\nexport {\n createNotionProvider,\n createNotionClient,\n validateNotionCreatePage,\n NOTION_API_VERSION,\n} from \"./notion.js\";\nexport type {\n NotionProviderConfig,\n NotionClientConfig,\n NotionCreatePageInput,\n} from \"./notion.js\";\nexport {\n createRaindropProvider,\n createRaindropClient,\n validateRaindropCreateBookmark,\n RAINDROP_TOKEN_ENDPOINT,\n} from \"./raindrop.js\";\nexport type {\n RaindropProviderConfig,\n RaindropClientConfig,\n RaindropCreateBookmarkInput,\n} from \"./raindrop.js\";\nexport { ProviderHttpError, notionRequest, raindropRequest } from \"./http.js\";\nexport type { ProviderRequestOptions } from \"./http.js\";\n","import {\n createLocalJWKSet,\n importPKCS8,\n jwtVerify,\n SignJWT,\n type JSONWebKeySet,\n type JWTPayload,\n} from \"jose\";\nimport { timingSafeEqual } from \"node:crypto\";\nimport { IntegrationError } from \"../errors.js\";\nimport type {\n AuthorizationInput,\n IntegrationProvider,\n VerifiedIdentity,\n} from \"../types.js\";\nimport { optionalText, record, requestJson, text } from \"./http.js\";\n\nexport type IdentityProviderConfig = {\n registrationId: string;\n identityNamespace?: string;\n clientId: string;\n redirectUri: string;\n};\nexport type GoogleProviderConfig = IdentityProviderConfig & {\n clientSecret?: string;\n nativeClientIds?: readonly string[];\n};\nexport type AppleProviderConfig = IdentityProviderConfig & {\n teamId?: string;\n keyId?: string;\n privateKey?: string;\n nativeClientIds?: readonly string[];\n};\nexport type GitHubProviderConfig = IdentityProviderConfig & {\n clientSecret: string;\n};\n\nfunction configure(config: IdentityProviderConfig): void {\n if (\n !config.registrationId ||\n !config.clientId ||\n !config.redirectUri ||\n config.identityNamespace === \"\"\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n let url: URL;\n try {\n url = new URL(config.redirectUri);\n } catch {\n throw new IntegrationError(\"invalid_provider_configuration\");\n }\n if (\n url.username ||\n url.password ||\n url.hash ||\n (url.protocol !== \"https:\" &&\n !(\n url.protocol === \"http:\" &&\n [\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(url.hostname)\n ))\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n}\nfunction identityPurpose(purpose: string): void {\n if (purpose !== \"identity\") throw new IntegrationError(\"unsupported_purpose\");\n}\nfunction authorizationURL(\n base: string,\n parameters: Record<string, string>,\n): string {\n const url = new URL(base);\n for (const [key, value] of Object.entries(parameters))\n url.searchParams.set(key, value);\n return url.toString();\n}\nconst keyCaches = new WeakMap<\n typeof globalThis.fetch,\n Map<\n string,\n {\n expires: number;\n refreshedAt: number;\n resolve: ReturnType<typeof createLocalJWKSet>;\n }\n >\n>();\nconst keyLoads = new WeakMap<\n typeof globalThis.fetch,\n Map<string, Promise<ReturnType<typeof createLocalJWKSet>>>\n>();\nasync function keys(\n url: string,\n fetcher: typeof globalThis.fetch,\n force = false,\n) {\n let cache = keyCaches.get(fetcher);\n if (!cache) {\n cache = new Map();\n keyCaches.set(fetcher, cache);\n }\n const existing = cache.get(url);\n if (!force && existing && existing.expires > Date.now())\n return existing.resolve;\n // An untrusted kid cannot force unlimited requests to the vendor's key endpoint.\n if (force && existing && existing.refreshedAt + 30_000 > Date.now())\n return existing.resolve;\n let loads = keyLoads.get(fetcher);\n if (!loads) {\n loads = new Map();\n keyLoads.set(fetcher, loads);\n }\n const pending = loads.get(url);\n if (pending) return pending;\n const load = (async () => {\n try {\n const value = record(await requestJson(url, {}, fetcher));\n if (!Array.isArray(value.keys) || value.keys.length > 100)\n throw new Error();\n const resolve = createLocalJWKSet(value as unknown as JSONWebKeySet);\n const now = Date.now();\n cache!.set(url, { expires: now + 300_000, refreshedAt: now, resolve });\n return resolve;\n } catch {\n throw new IntegrationError(\"identity_unavailable\", \"retryable\");\n }\n })();\n loads.set(url, load);\n try {\n return await load;\n } finally {\n loads.delete(url);\n }\n}\nasync function verifyToken(\n input: { idToken: string; nonce: string },\n config: IdentityProviderConfig,\n fetcher: typeof globalThis.fetch,\n options: { provider: \"google\" | \"apple\"; audiences: readonly string[] },\n): Promise<VerifiedIdentity> {\n if (\n !input.nonce ||\n input.nonce.length > 1024 ||\n !input.idToken ||\n input.idToken.length > 32_768 ||\n !options.audiences.length ||\n options.audiences.some((item) => !item)\n )\n throw new IntegrationError(\"invalid_identity\");\n const google = options.provider === \"google\";\n const issuer = google\n ? \"https://accounts.google.com\"\n : \"https://appleid.apple.com\";\n const jwks = google\n ? \"https://www.googleapis.com/oauth2/v3/certs\"\n : \"https://appleid.apple.com/auth/keys\";\n const verificationOptions = {\n algorithms: [\"RS256\"],\n issuer: google ? [issuer, \"accounts.google.com\"] : issuer,\n audience: [...options.audiences],\n requiredClaims: [\"sub\", \"exp\", \"iat\", \"nonce\"],\n clockTolerance: 30,\n };\n let payload: JWTPayload;\n try {\n let resolve = await keys(jwks, fetcher);\n try {\n ({ payload } = await jwtVerify(\n input.idToken,\n resolve,\n verificationOptions,\n ));\n } catch (error) {\n if (!(\n error &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ERR_JWKS_NO_MATCHING_KEY\"\n ))\n throw error;\n resolve = await keys(jwks, fetcher, true);\n ({ payload } = await jwtVerify(\n input.idToken,\n resolve,\n verificationOptions,\n ));\n }\n const expected = Buffer.from(input.nonce);\n const actual = Buffer.from(\n typeof payload.nonce === \"string\" ? payload.nonce : \"\",\n );\n if (\n expected.length !== actual.length ||\n !timingSafeEqual(expected, actual) ||\n typeof payload.iat !== \"number\" ||\n payload.iat > Date.now() / 1000 + 30 ||\n typeof payload.sub !== \"string\" ||\n !payload.sub ||\n payload.sub.length > 255\n )\n throw new Error();\n // A multi-audience assertion must identify one of this registration's clients.\n if (\n Array.isArray(payload.aud) &&\n payload.aud.length > 1 &&\n (typeof payload.azp !== \"string\" ||\n !options.audiences.includes(payload.azp))\n )\n throw new Error();\n } catch (error) {\n if (\n error instanceof IntegrationError &&\n (error.disposition === \"retryable\" ||\n error.disposition === \"outcome_unknown\")\n )\n throw new IntegrationError(\"identity_unavailable\", \"retryable\");\n throw new IntegrationError(\"invalid_identity\");\n }\n const email = optionalText(payload.email, 320);\n const name = optionalText(payload.name, 1024);\n return {\n provider: options.provider,\n issuer,\n subject: payload.sub!,\n identityNamespace: config.identityNamespace ?? config.registrationId,\n emailVerified:\n payload.email_verified === true ||\n (options.provider === \"apple\" && payload.email_verified === \"true\"),\n ...(email ? { email } : {}),\n ...(name ? { name } : {}),\n };\n}\n\nexport function createGoogleProvider(\n config: GoogleProviderConfig,\n): IntegrationProvider {\n configure(config);\n return {\n key: \"google\",\n registrationId: config.registrationId,\n purposes: [\"identity\"],\n authorization: {\n url(input: AuthorizationInput) {\n identityPurpose(input.purpose);\n return authorizationURL(\n \"https://accounts.google.com/o/oauth2/v2/auth\",\n {\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n scope: \"openid email profile\",\n state: input.state,\n nonce: input.nonce,\n code_challenge: input.challenge,\n code_challenge_method: \"S256\",\n },\n );\n },\n async exchange(input, fetcher) {\n identityPurpose(input.purpose);\n if (!config.clientSecret)\n throw new IntegrationError(\"application_unavailable\");\n const tokens = record(\n await requestJson(\n \"https://oauth2.googleapis.com/token\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n redirect_uri: config.redirectUri,\n grant_type: \"authorization_code\",\n code: input.code,\n code_verifier: input.verifier,\n }),\n ...(input.signal ? { signal: input.signal } : {}),\n },\n fetcher,\n ),\n );\n const identity = await verifyToken(\n { idToken: text(tokens.id_token, 32_768), nonce: input.nonce },\n config,\n fetcher,\n { provider: \"google\", audiences: [config.clientId] },\n );\n return { identity }; // Login never exposes or persists OAuth provider tokens.\n },\n },\n verifyNative(input, fetcher) {\n return verifyToken(input, config, fetcher, {\n provider: \"google\",\n audiences: config.nativeClientIds ?? [config.clientId],\n });\n },\n };\n}\n\nexport function createAppleProvider(\n config: AppleProviderConfig,\n): IntegrationProvider {\n configure(config);\n async function clientSecret(): Promise<string> {\n if (!config.teamId || !config.keyId || !config.privateKey)\n throw new IntegrationError(\"application_unavailable\");\n try {\n const key = await importPKCS8(config.privateKey, \"ES256\");\n return await new SignJWT({})\n .setProtectedHeader({ alg: \"ES256\", kid: config.keyId })\n .setIssuer(config.teamId)\n .setSubject(config.clientId)\n .setAudience(\"https://appleid.apple.com\")\n .setIssuedAt()\n .setExpirationTime(\"5m\")\n .sign(key);\n } catch {\n throw new IntegrationError(\"application_unavailable\");\n }\n }\n return {\n key: \"apple\",\n registrationId: config.registrationId,\n purposes: [\"identity\"],\n authorization: {\n url(input) {\n identityPurpose(input.purpose);\n return authorizationURL(\"https://appleid.apple.com/auth/authorize\", {\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n response_mode: \"form_post\",\n scope: \"name email\",\n state: input.state,\n nonce: input.nonce,\n });\n },\n async exchange(input, fetcher) {\n identityPurpose(input.purpose);\n const result = record(\n await requestJson(\n \"https://appleid.apple.com/auth/token\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: await clientSecret(),\n redirect_uri: config.redirectUri,\n grant_type: \"authorization_code\",\n code: input.code,\n }),\n ...(input.signal ? { signal: input.signal } : {}),\n },\n fetcher,\n ),\n );\n return {\n identity: await verifyToken(\n { idToken: text(result.id_token, 32_768), nonce: input.nonce },\n config,\n fetcher,\n { provider: \"apple\", audiences: [config.clientId] },\n ),\n };\n },\n },\n // nonce is the actual expected token nonce; a native host using SHA256 supplies that hash.\n verifyNative(input, fetcher) {\n return verifyToken(input, config, fetcher, {\n provider: \"apple\",\n audiences: config.nativeClientIds ?? [config.clientId],\n });\n },\n };\n}\n\nexport function createGitHubProvider(\n config: GitHubProviderConfig,\n): IntegrationProvider {\n configure(config);\n if (!config.clientSecret)\n throw new IntegrationError(\"invalid_provider_configuration\");\n return {\n key: \"github\",\n registrationId: config.registrationId,\n purposes: [\"identity\"],\n authorization: {\n url(input) {\n identityPurpose(input.purpose);\n return authorizationURL(\"https://github.com/login/oauth/authorize\", {\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n scope: \"read:user user:email\",\n state: input.state,\n code_challenge: input.challenge,\n code_challenge_method: \"S256\",\n });\n },\n async exchange(input, fetcher) {\n identityPurpose(input.purpose);\n const tokens = record(\n await requestJson(\n \"https://github.com/login/oauth/access_token\",\n {\n method: \"POST\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n redirect_uri: config.redirectUri,\n code: input.code,\n code_verifier: input.verifier,\n }),\n ...(input.signal ? { signal: input.signal } : {}),\n },\n fetcher,\n ),\n );\n const accessToken = text(tokens.access_token);\n const headers = {\n Accept: \"application/vnd.github+json\",\n Authorization: `Bearer ${accessToken}`,\n \"X-GitHub-Api-Version\": \"2026-03-10\",\n \"User-Agent\": \"mycreat-labs-integrations-sdk\",\n };\n const user = record(\n await requestJson(\n \"https://api.github.com/user\",\n { headers, ...(input.signal ? { signal: input.signal } : {}) },\n fetcher,\n ),\n );\n if (!Number.isSafeInteger(user.id) || Number(user.id) <= 0)\n throw new IntegrationError(\"invalid_identity\");\n const emails = await requestJson(\n \"https://api.github.com/user/emails?per_page=100\",\n { headers, ...(input.signal ? { signal: input.signal } : {}) },\n fetcher,\n );\n if (!Array.isArray(emails) || emails.length > 100)\n throw new IntegrationError(\"invalid_identity\");\n const primary = emails.find(\n (item) =>\n item &&\n typeof item === \"object\" &&\n item.primary === true &&\n item.verified === true,\n ) as { email?: unknown } | undefined;\n const email = primary ? text(primary.email, 320) : undefined;\n const name = optionalText(user.name, 1024);\n const username = text(user.login, 255);\n return {\n identity: {\n provider: \"github\",\n issuer: \"https://github.com\",\n subject: String(user.id),\n identityNamespace:\n config.identityNamespace ?? config.registrationId,\n emailVerified: Boolean(email),\n username,\n ...(email ? { email } : {}),\n ...(name ? { name } : {}),\n },\n };\n },\n },\n };\n}\n","export type FailureDisposition =\n \"retryable\" | \"requires_reauth\" | \"outcome_unknown\" | \"permanent_failure\";\nexport class IntegrationError extends Error {\n readonly sdkError = \"@mycreat-labs/integrations-sdk/v1\";\n constructor(\n readonly code: string,\n readonly disposition: FailureDisposition = \"permanent_failure\",\n readonly retryAfterMs?: number,\n ) {\n super(code);\n this.name = \"IntegrationError\";\n }\n}\nexport function integrationError(error: unknown): IntegrationError {\n if (error instanceof IntegrationError) return error;\n // Bundled subpath entries and independently installed copies have separate class identities.\n if (\n error instanceof Error &&\n \"sdkError\" in error &&\n error.sdkError === \"@mycreat-labs/integrations-sdk/v1\" &&\n \"code\" in error &&\n typeof error.code === \"string\" &&\n /^[a-zA-Z0-9_]{1,100}$/.test(error.code) &&\n \"disposition\" in error &&\n [\n \"retryable\",\n \"requires_reauth\",\n \"outcome_unknown\",\n \"permanent_failure\",\n ].includes(String(error.disposition))\n ) {\n const delay =\n \"retryAfterMs\" in error &&\n typeof error.retryAfterMs === \"number\" &&\n Number.isFinite(error.retryAfterMs) &&\n error.retryAfterMs >= 0\n ? error.retryAfterMs\n : undefined;\n return new IntegrationError(\n error.code,\n error.disposition as FailureDisposition,\n delay,\n );\n }\n return new IntegrationError(\"provider_unavailable\", \"outcome_unknown\");\n}\n","import { IntegrationError, type FailureDisposition } from \"../errors.js\";\nimport type { Json } from \"../types.js\";\n\nexport type ProviderRequestOptions = {\n accessToken?: string;\n clientId?: string;\n clientSecret?: string;\n method?: string;\n body?: unknown;\n signal?: AbortSignal;\n fetch?: typeof globalThis.fetch;\n apiVersion?: string;\n};\n\n/** Contains only safe classifications and validated receipt IDs, never upstream messages. */\nexport class ProviderHttpError extends IntegrationError {\n readonly status: number | null;\n readonly providerCode?: string;\n readonly definite: boolean;\n readonly committedResourceId?: string;\n readonly committedChildIds?: string[];\n constructor(\n code: string,\n disposition: FailureDisposition,\n options: {\n status?: number;\n providerCode?: string;\n definite?: boolean;\n retryAfterMs?: number;\n committedResourceId?: string;\n committedChildIds?: string[];\n } = {},\n ) {\n super(code, disposition, options.retryAfterMs);\n this.name = \"ProviderHttpError\";\n this.status = options.status ?? null;\n this.providerCode = options.providerCode;\n this.definite = options.definite ?? false;\n this.committedResourceId = options.committedResourceId;\n this.committedChildIds = options.committedChildIds;\n }\n}\n\nexport function record(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n throw new IntegrationError(\"invalid_response\");\n return value as Record<string, unknown>;\n}\nexport function text(value: unknown, max = 4096): string {\n if (typeof value !== \"string\" || value.length === 0 || value.length > max)\n throw new IntegrationError(\"invalid_response\");\n return value;\n}\nexport function optionalText(value: unknown, max = 4096): string | undefined {\n return value === undefined || value === null ? undefined : text(value, max);\n}\nexport function inputRecord(\n value: unknown,\n keys: readonly string[],\n): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n throw new IntegrationError(\"invalid_input\");\n const input = value as Record<string, unknown>;\n if (Object.keys(input).some((key) => !keys.includes(key)))\n throw new IntegrationError(\"invalid_input\");\n return input;\n}\nexport function inputText(\n value: unknown,\n maximum: number,\n required = true,\n): string | undefined {\n if (value === undefined && !required) return undefined;\n if (\n typeof value !== \"string\" ||\n (required && !value.trim()) ||\n value.length > maximum\n )\n throw new IntegrationError(\"invalid_input\");\n return value;\n}\nexport function webUrl(value: unknown): string {\n const result = inputText(value, 10_000)!;\n try {\n const url = new URL(result);\n if (\n ![\"https:\", \"http:\"].includes(url.protocol) ||\n url.username ||\n url.password\n )\n throw new Error();\n } catch {\n throw new IntegrationError(\"invalid_input\");\n }\n return result;\n}\nexport function jsonMetadata(value: unknown): Json | undefined {\n if (value === undefined) return undefined;\n const visit = (item: unknown, depth: number): boolean =>\n depth <= 10 &&\n (item === null ||\n typeof item === \"string\" ||\n typeof item === \"boolean\" ||\n (typeof item === \"number\" && Number.isFinite(item)) ||\n (Array.isArray(item) && item.every((child) => visit(child, depth + 1))) ||\n (typeof item === \"object\" &&\n item !== null &&\n Object.getPrototypeOf(item) === Object.prototype &&\n Object.values(item).every((child) => visit(child, depth + 1))));\n if (!visit(value, 0) || JSON.stringify(value).length > 16_384)\n throw new IntegrationError(\"invalid_input\");\n return value as Json;\n}\n\nconst safeCodes = new Set([\n \"invalid_client\",\n \"unauthorized_client\",\n \"invalid_grant\",\n \"bad_authorization_code\",\n \"invalid_request\",\n \"invalid_json\",\n \"validation_error\",\n \"restricted_resource\",\n \"unauthorized\",\n \"object_not_found\",\n \"rate_limited\",\n \"conflict_error\",\n \"internal_server_error\",\n \"service_unavailable\",\n \"gateway_timeout\",\n \"service_overload\",\n \"row_limit_exceeded\",\n \"invalid_token\",\n \"bad_verification_code\",\n \"incorrect_client_credentials\",\n \"redirect_uri_mismatch\",\n \"access_denied\",\n]);\nconst uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nexport const isUuid = (value: unknown): value is string =>\n typeof value === \"string\" && uuid.test(value);\nexport function retryDelay(value: string | null): number | undefined {\n if (!value) return undefined;\n const milliseconds = /^\\d+(?:\\.\\d+)?$/.test(value)\n ? Number(value) * 1000\n : Date.parse(value) - Date.now();\n return Number.isFinite(milliseconds)\n ? Math.max(0, Math.min(milliseconds, 86_400_000))\n : undefined;\n}\n\nfunction failure(\n status: number,\n body: unknown,\n write: boolean,\n retryAfterMs?: number,\n): ProviderHttpError {\n const payload =\n body && typeof body === \"object\" && !Array.isArray(body)\n ? (body as Record<string, unknown>)\n : {};\n const vendorCode =\n typeof payload.code === \"string\"\n ? payload.code\n : typeof payload.error === \"string\"\n ? payload.error\n : undefined;\n const providerCode =\n vendorCode && safeCodes.has(vendorCode) ? vendorCode : undefined;\n const extra =\n payload.additional_data && typeof payload.additional_data === \"object\"\n ? (payload.additional_data as Record<string, unknown>)\n : {};\n const committedResourceId = isUuid(extra.committed_resource_id)\n ? extra.committed_resource_id\n : undefined;\n const committedChildIds =\n Array.isArray(extra.committed_child_ids) &&\n extra.committed_child_ids.length <= 100 &&\n extra.committed_child_ids.every(isUuid)\n ? (extra.committed_child_ids as string[])\n : undefined;\n const definite =\n status >= 400 &&\n status < 500 &&\n status !== 408 &&\n !committedResourceId &&\n !committedChildIds?.length;\n let code =\n status === 401\n ? \"auth_required\"\n : status === 404\n ? \"resource_unavailable\"\n : status === 403\n ? \"permission_required\"\n : status === 429 || status === 529\n ? \"rate_limited\"\n : status >= 500\n ? \"upstream_unavailable\"\n : \"invalid_payload\";\n if (\n providerCode === \"invalid_client\" ||\n providerCode === \"unauthorized_client\" ||\n providerCode === \"incorrect_client_credentials\" ||\n payload.errorMessage === \"client_id or client_secret is invalid\"\n )\n code = \"application_unavailable\";\n else if (\n providerCode === \"invalid_grant\" ||\n providerCode === \"bad_authorization_code\" ||\n providerCode === \"invalid_token\" ||\n providerCode === \"bad_verification_code\"\n )\n code = \"auth_required\";\n else if (extra.rate_limit_reason === \"public_api_request_blocked\")\n code = \"access_restricted\";\n else if (status === 403 && providerCode === \"restricted_resource\")\n code = \"resource_unavailable\";\n else if (\n status === 403 &&\n typeof payload.message === \"string\" &&\n /block.*limit|limit.*block/i.test(payload.message)\n )\n code = \"workspace_capacity\";\n const disposition: FailureDisposition =\n code === \"auth_required\"\n ? \"requires_reauth\"\n : write && !definite\n ? \"outcome_unknown\"\n : code === \"rate_limited\" || status >= 500 || status === 408\n ? \"retryable\"\n : \"permanent_failure\";\n return new ProviderHttpError(code, disposition, {\n status,\n providerCode,\n definite,\n retryAfterMs,\n committedResourceId,\n committedChildIds,\n });\n}\n\nexport async function requestJson(\n url: string,\n init: RequestInit,\n fetcher: typeof globalThis.fetch,\n options: { write?: boolean; raindrop?: boolean; requireJson?: boolean } = {},\n): Promise<unknown> {\n const write =\n options.write ?? ![\"GET\", \"HEAD\"].includes(init.method ?? \"GET\");\n const signal = init.signal\n ? AbortSignal.any([init.signal, AbortSignal.timeout(30_000)])\n : AbortSignal.timeout(30_000);\n let response: Response;\n try {\n response = await fetcher(url, { ...init, signal, redirect: \"error\" });\n } catch (error) {\n // An SDK admission limiter rejected the request before any HTTP dispatch.\n if (\n error instanceof Error &&\n \"sdkError\" in error &&\n error.sdkError === \"@mycreat-labs/integrations-sdk/v1\" &&\n \"code\" in error &&\n error.code === \"rate_limited\" &&\n \"definite\" in error &&\n error.definite === true\n ) {\n const delay =\n \"retryAfterMs\" in error &&\n typeof error.retryAfterMs === \"number\" &&\n Number.isFinite(error.retryAfterMs)\n ? Math.max(0, Math.min(error.retryAfterMs, 86_400_000))\n : undefined;\n throw new ProviderHttpError(\"rate_limited\", \"retryable\", {\n status: 429,\n definite: true,\n retryAfterMs: delay,\n });\n }\n throw new ProviderHttpError(\n \"upstream_unavailable\",\n write ? \"outcome_unknown\" : \"retryable\",\n );\n }\n if (response.status === 204 && response.ok) return {};\n let body: unknown;\n try {\n if (\n options.requireJson &&\n !response.headers.get(\"content-type\")?.toLowerCase().includes(\"json\")\n )\n throw new Error();\n if (!response.body) throw new Error();\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n try {\n for (;;) {\n const part = await reader.read();\n if (part.done) break;\n size += part.value.length;\n if (size > 2_097_152) {\n await reader.cancel();\n throw new Error();\n }\n chunks.push(part.value);\n }\n } finally {\n reader.releaseLock();\n }\n body = JSON.parse(Buffer.concat(chunks).toString(\"utf8\")) as unknown;\n } catch {\n if (!response.ok)\n throw failure(\n response.status,\n {},\n write,\n retryDelay(response.headers.get(\"retry-after\")),\n );\n throw new ProviderHttpError(\n \"invalid_response\",\n write ? \"outcome_unknown\" : \"retryable\",\n { status: response.status },\n );\n }\n if (!response.ok)\n throw failure(\n response.status,\n body,\n write,\n retryDelay(response.headers.get(\"retry-after\")),\n );\n if (body && typeof body === \"object\" && !Array.isArray(body)) {\n const value = body as Record<string, unknown>;\n if (\n typeof value.error === \"string\" ||\n (options.raindrop && value.result === false)\n ) {\n const status =\n typeof value.status === \"number\" &&\n Number.isInteger(value.status) &&\n value.status >= 400 &&\n value.status < 600\n ? value.status\n : 400;\n throw failure(\n status,\n body,\n write,\n retryDelay(response.headers.get(\"retry-after\")),\n );\n }\n }\n return body;\n}\n\nfunction providerPath(path: string, prefix: string): string {\n if (\n path.length > 4096 ||\n !/^\\/[a-zA-Z0-9_/-]+(?:\\?[a-zA-Z0-9_%=&.~-]+)?$/.test(path) ||\n path.includes(\"//\") ||\n path.includes(\"..\")\n )\n throw new ProviderHttpError(\"invalid_upstream_path\", \"permanent_failure\", {\n status: 400,\n definite: true,\n });\n return path.startsWith(`${prefix}/`) || path === prefix\n ? path\n : `${prefix}${path}`;\n}\nexport function notionRequest(\n path: string,\n options: ProviderRequestOptions,\n): Promise<unknown> {\n const normalized = providerPath(path, \"/v1\");\n if (!options.accessToken && (!options.clientId || !options.clientSecret))\n throw new ProviderHttpError(\n \"application_unavailable\",\n \"permanent_failure\",\n { definite: true },\n );\n const authorization = options.accessToken\n ? `Bearer ${options.accessToken}`\n : `Basic ${Buffer.from(`${options.clientId}:${options.clientSecret}`).toString(\"base64\")}`;\n return requestJson(\n `https://api.notion.com${normalized}`,\n {\n method: options.method ?? (options.body === undefined ? \"GET\" : \"POST\"),\n headers: {\n \"Notion-Version\": options.apiVersion ?? \"2026-03-11\",\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Authorization: authorization,\n },\n ...(options.body === undefined\n ? {}\n : { body: JSON.stringify(options.body) }),\n ...(options.signal ? { signal: options.signal } : {}),\n },\n options.fetch ?? globalThis.fetch,\n {\n write:\n normalized !== \"/v1/search\" &&\n (options.method ?? (options.body === undefined ? \"GET\" : \"POST\")) !==\n \"GET\",\n },\n );\n}\nexport function raindropRequest(\n path: string,\n options: ProviderRequestOptions,\n): Promise<unknown> {\n const normalized =\n path === \"/v1/oauth/access_token\" ? path : providerPath(path, \"/rest/v1\");\n if (normalized !== \"/v1/oauth/access_token\" && !options.accessToken)\n throw new ProviderHttpError(\"auth_required\", \"requires_reauth\", {\n status: 401,\n definite: true,\n });\n return requestJson(\n `https://api.raindrop.io${normalized}`,\n {\n method: options.method ?? (options.body === undefined ? \"GET\" : \"POST\"),\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...(options.accessToken\n ? { Authorization: `Bearer ${options.accessToken}` }\n : {}),\n },\n ...(options.body === undefined\n ? {}\n : { body: JSON.stringify(options.body) }),\n ...(options.signal ? { signal: options.signal } : {}),\n },\n options.fetch ?? globalThis.fetch,\n { raindrop: true, requireJson: true },\n );\n}\n","import { IntegrationError } from \"../errors.js\";\nimport type {\n CredentialMaterial,\n IntegrationProvider,\n Json,\n Resource,\n ResourcePage,\n} from \"../types.js\";\nimport {\n inputRecord,\n inputText,\n isUuid,\n jsonMetadata,\n notionRequest,\n optionalText,\n record,\n text,\n webUrl,\n type ProviderRequestOptions,\n} from \"./http.js\";\n\nexport const NOTION_API_VERSION = \"2026-03-11\";\nexport type NotionProviderConfig = {\n registrationId: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n apiVersion?: string;\n};\nexport type NotionClientConfig = {\n accessToken: string;\n fetch?: typeof globalThis.fetch;\n signal?: AbortSignal;\n apiVersion?: string;\n};\nexport type NotionCreatePageInput = {\n parentId: string;\n parentType?: \"page\" | \"data_source\";\n title: string;\n content?: string;\n url?: string;\n metadata?: { [key: string]: Json };\n};\n\nfunction uuid(value: unknown): string {\n if (!isUuid(value)) throw new IntegrationError(\"invalid_input\");\n return value;\n}\nconst validCursor = (value: unknown): value is string =>\n typeof value === \"string\" && value.length > 0 && value.length <= 4096;\nexport function validateNotionCreatePage(\n value: unknown,\n): NotionCreatePageInput {\n const input = inputRecord(value, [\n \"parentId\",\n \"parentType\",\n \"title\",\n \"content\",\n \"url\",\n \"metadata\",\n ]);\n const result: NotionCreatePageInput = {\n parentId: uuid(input.parentId),\n title: inputText(input.title, 2000)!,\n };\n if (input.parentType !== undefined) {\n if (input.parentType !== \"page\" && input.parentType !== \"data_source\")\n throw new IntegrationError(\"invalid_input\");\n result.parentType = input.parentType;\n }\n if (input.content !== undefined)\n result.content = inputText(input.content, 100_000, false)!;\n if (input.url !== undefined) result.url = webUrl(input.url);\n if (input.metadata !== undefined) {\n const metadata = jsonMetadata(input.metadata);\n if (!metadata || Array.isArray(metadata) || typeof metadata !== \"object\")\n throw new IntegrationError(\"invalid_input\");\n result.metadata = metadata;\n }\n return result;\n}\nfunction richText(value: string): Json[] {\n const result: Json[] = [];\n for (let index = 0; index < value.length;) {\n let end = Math.min(index + 2000, value.length);\n if (end < value.length && /[\\uD800-\\uDBFF]/.test(value.charAt(end - 1)))\n end--;\n result.push({ type: \"text\", text: { content: value.slice(index, end) } });\n index = end;\n }\n return result;\n}\nfunction resourceTitle(value: unknown): string {\n if (!Array.isArray(value)) throw new IntegrationError(\"invalid_response\");\n return value\n .map((item) => {\n const piece = record(item);\n if (typeof piece.plain_text === \"string\") return piece.plain_text;\n return text(record(piece.text).content, 2000);\n })\n .join(\"\");\n}\nfunction pageResult(value: unknown): { id: string; url: string } {\n try {\n const page = record(value);\n if (page.object !== \"page\" || !isUuid(page.id)) throw new Error();\n const url = text(page.url, 4096);\n if (new URL(url).protocol !== \"https:\") throw new Error();\n return { id: page.id, url };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\n\nexport function createNotionClient(config: NotionClientConfig) {\n if (!config.accessToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n const request = (\n path: string,\n options: Omit<\n ProviderRequestOptions,\n \"accessToken\" | \"clientId\" | \"clientSecret\"\n > = {},\n ) => notionRequest(path, { ...config, ...options });\n async function listResources(\n input: { cursor?: string; query?: string; parentId?: string } = {},\n ): Promise<ResourcePage> {\n if (input.parentId !== undefined)\n throw new IntegrationError(\"unsupported_resource_filter\");\n if (input.cursor !== undefined && !validCursor(input.cursor))\n throw new IntegrationError(\"invalid_input\");\n if (input.query !== undefined) inputText(input.query, 1000, false);\n const response = record(\n await request(\"/search\", {\n body: {\n page_size: 100,\n ...(input.cursor ? { start_cursor: input.cursor } : {}),\n ...(input.query !== undefined ? { query: input.query } : {}),\n },\n }),\n );\n if (\n !Array.isArray(response.results) ||\n response.results.length > 100 ||\n typeof response.has_more !== \"boolean\"\n )\n throw new IntegrationError(\"invalid_response\");\n if (\n response.request_status !== undefined &&\n record(response.request_status).type !== \"complete\"\n )\n throw new IntegrationError(\"resource_listing_incomplete\");\n if (response.has_more && !validCursor(response.next_cursor))\n throw new IntegrationError(\"invalid_response\");\n const items: Resource[] = [];\n for (const item of response.results) {\n const entry = record(item);\n if (\n !isUuid(entry.id) ||\n (entry.object !== \"page\" && entry.object !== \"data_source\")\n )\n throw new IntegrationError(\"invalid_response\");\n if (\n entry.in_trash === true ||\n entry.archived === true ||\n entry.is_archived === true\n )\n continue;\n let name: string;\n if (entry.object === \"data_source\") name = resourceTitle(entry.title);\n else {\n const properties = record(entry.properties);\n const title = Object.values(properties)\n .map(record)\n .find((property) => property.type === \"title\");\n name = title ? resourceTitle(title.title) : \"\";\n }\n const url = optionalText(entry.url);\n items.push({\n id: entry.id,\n type: entry.object,\n name: name || \"Untitled\",\n ...(url ? { url } : {}),\n });\n }\n return {\n items,\n ...(response.has_more\n ? { nextCursor: response.next_cursor as string }\n : {}),\n };\n }\n async function createPage(\n value: NotionCreatePageInput,\n ): Promise<{ id: string; url: string }> {\n const input = validateNotionCreatePage(value);\n const parentType = input.parentType ?? \"page\";\n let titleKey = \"title\";\n if (parentType === \"data_source\") {\n const source = record(await request(`/data_sources/${input.parentId}`));\n if (source.id !== input.parentId || source.object !== \"data_source\")\n throw new IntegrationError(\"invalid_response\");\n const property = Object.entries(record(source.properties)).find(\n ([, definition]) => record(definition).type === \"title\",\n );\n if (!property) throw new IntegrationError(\"invalid_resource\");\n titleKey = property[0];\n }\n const children: Json[] = [];\n if (input.content) {\n for (const part of richText(input.content))\n children.push({\n object: \"block\",\n type: \"paragraph\",\n paragraph: { rich_text: [part] },\n });\n }\n if (input.url)\n children.push({\n object: \"block\",\n type: \"bookmark\",\n bookmark: { url: input.url },\n });\n return pageResult(\n await request(\"/pages\", {\n body: {\n parent:\n parentType === \"page\"\n ? { page_id: input.parentId }\n : { data_source_id: input.parentId },\n properties: {\n [titleKey]: { type: \"title\", title: richText(input.title) },\n },\n ...(children.length ? { children } : {}),\n },\n }),\n );\n }\n return { request, listResources, resources: listResources, createPage };\n}\n\nfunction tokenCredentials(\n value: unknown,\n previous?: CredentialMaterial,\n): CredentialMaterial {\n try {\n const response = record(value);\n const accessToken = text(response.access_token, 8192);\n // Notion requires this field but permits null. Omit only a null refresh\n // credential; missing or malformed fields still fail validation.\n const refreshToken =\n response.refresh_token === null\n ? undefined\n : text(response.refresh_token, 8192);\n if (\n typeof response.token_type !== \"string\" ||\n response.token_type.toLowerCase() !== \"bearer\"\n )\n throw new Error();\n const expires = response.expires_in;\n if (\n expires !== undefined &&\n (typeof expires !== \"number\" ||\n !Number.isInteger(expires) ||\n expires <= 0 ||\n expires > 31_536_000)\n )\n throw new Error();\n return {\n accessToken,\n ...(refreshToken !== undefined ? { refreshToken } : {}),\n ...(expires !== undefined\n ? { expiresAt: Date.now() + Number(expires) * 1000 }\n : {}),\n ...(previous?.scopes ? { scopes: previous.scopes } : {}),\n ...(previous?.extra ? { extra: previous.extra } : {}),\n };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\nexport function createNotionProvider(\n config: NotionProviderConfig,\n): IntegrationProvider {\n if (\n !config.registrationId ||\n !config.clientId ||\n !config.clientSecret ||\n !config.redirectUri\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n const tokenRequest = (\n body: Json,\n fetcher: typeof globalThis.fetch,\n signal?: AbortSignal,\n ) =>\n notionRequest(\"/oauth/token\", {\n clientId: config.clientId,\n clientSecret: config.clientSecret,\n apiVersion: config.apiVersion,\n body,\n fetch: fetcher,\n ...(signal ? { signal } : {}),\n });\n return {\n key: \"notion\",\n registrationId: config.registrationId,\n purposes: [\"connect\"],\n authorization: {\n url(input) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const url = new URL(\"https://api.notion.com/v1/oauth/authorize\");\n url.search = new URLSearchParams({\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n owner: \"user\",\n state: input.state,\n }).toString();\n return url.toString();\n },\n async exchange(input, fetcher) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const response = record(\n await tokenRequest(\n {\n grant_type: \"authorization_code\",\n code: input.code,\n redirect_uri: config.redirectUri,\n },\n fetcher,\n input.signal,\n ),\n );\n const credentials = tokenCredentials(response);\n const workspaceId = text(response.workspace_id);\n const botId = text(response.bot_id);\n if (!isUuid(workspaceId) || !isUuid(botId))\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n const owner = record(response.owner);\n if (owner.type !== \"user\")\n throw new IntegrationError(\"invalid_response\");\n const userId = text(record(owner.user).id);\n if (!isUuid(userId)) throw new IntegrationError(\"invalid_response\");\n const label =\n optionalText(response.workspace_name) ?? \"Notion workspace\";\n credentials.extra = { workspaceId, botId, ownerId: userId };\n return {\n credentials,\n account: {\n id: `${workspaceId}:${botId}:${userId}`,\n label,\n metadata: { workspaceId, botId, ownerId: userId },\n },\n };\n },\n },\n resources(input, context) {\n return createNotionClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n apiVersion: config.apiVersion,\n }).listResources(input);\n },\n async refresh(credentials, context) {\n if (!credentials.refreshToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n return tokenCredentials(\n await tokenRequest(\n {\n grant_type: \"refresh_token\",\n refresh_token: credentials.refreshToken,\n },\n context.fetch,\n context.signal,\n ),\n credentials,\n );\n },\n async revoke(credentials, context) {\n await notionRequest(\"/oauth/revoke\", {\n clientId: config.clientId,\n clientSecret: config.clientSecret,\n apiVersion: config.apiVersion,\n body: { token: credentials.accessToken },\n fetch: context.fetch,\n signal: context.signal,\n });\n },\n actions: {\n create_page: {\n validate(value) {\n return validateNotionCreatePage(value) as unknown as Json;\n },\n async execute(value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (\n typeof checkpoint.id === \"string\" &&\n typeof checkpoint.url === \"string\"\n )\n return { id: checkpoint.id, url: checkpoint.url };\n const result = await createNotionClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n apiVersion: config.apiVersion,\n }).createPage(value as unknown as NotionCreatePageInput);\n await context.saveCheckpoint(result);\n return result;\n },\n async reconcile(_value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (!isUuid(checkpoint.id)) return { resolved: false };\n const result = pageResult(\n await notionRequest(`/pages/${checkpoint.id}`, {\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n apiVersion: config.apiVersion,\n }),\n );\n if (result.id !== checkpoint.id)\n throw new IntegrationError(\"invalid_response\");\n return { resolved: true, result };\n },\n },\n },\n };\n}\n","import { IntegrationError } from \"../errors.js\";\nimport type {\n CredentialMaterial,\n IntegrationProvider,\n Json,\n Resource,\n ResourcePage,\n} from \"../types.js\";\nimport {\n inputRecord,\n inputText,\n jsonMetadata,\n optionalText,\n raindropRequest,\n record,\n text,\n webUrl,\n type ProviderRequestOptions,\n} from \"./http.js\";\n\nexport type RaindropProviderConfig = {\n registrationId: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n};\nexport type RaindropClientConfig = {\n accessToken: string;\n fetch?: typeof globalThis.fetch;\n signal?: AbortSignal;\n};\nexport type RaindropCreateBookmarkInput = {\n collectionId?: number;\n url: string;\n title?: string;\n note?: string;\n excerpt?: string;\n tags?: string[];\n metadata?: { [key: string]: Json };\n};\nexport const RAINDROP_TOKEN_ENDPOINT =\n \"https://api.raindrop.io/v1/oauth/access_token\";\n\nfunction collectionId(value: unknown): number {\n if (\n !Number.isSafeInteger(value) ||\n (Number(value) !== -1 && Number(value) <= 0)\n )\n throw new IntegrationError(\"invalid_input\");\n return value as number;\n}\nexport function validateRaindropCreateBookmark(\n value: unknown,\n): RaindropCreateBookmarkInput {\n const input = inputRecord(value, [\n \"collectionId\",\n \"url\",\n \"title\",\n \"note\",\n \"excerpt\",\n \"tags\",\n \"metadata\",\n ]);\n const result: RaindropCreateBookmarkInput = { url: webUrl(input.url) };\n if (input.collectionId !== undefined)\n result.collectionId = collectionId(input.collectionId);\n if (input.title !== undefined)\n result.title = inputText(input.title, 10_000, false)!;\n if (input.note !== undefined)\n result.note = inputText(input.note, 100_000, false)!;\n if (input.excerpt !== undefined)\n result.excerpt = inputText(input.excerpt, 10_000, false)!;\n if (input.tags !== undefined) {\n if (\n !Array.isArray(input.tags) ||\n input.tags.length > 100 ||\n input.tags.some(\n (tag) => typeof tag !== \"string\" || !tag.trim() || tag.length > 255,\n )\n )\n throw new IntegrationError(\"invalid_input\");\n result.tags = [...new Set(input.tags as string[])];\n }\n if (input.metadata !== undefined) {\n const metadata = jsonMetadata(input.metadata);\n if (!metadata || Array.isArray(metadata) || typeof metadata !== \"object\")\n throw new IntegrationError(\"invalid_input\");\n result.metadata = metadata;\n }\n return result;\n}\nfunction bookmarkResult(\n value: unknown,\n input?: RaindropCreateBookmarkInput,\n): { id: string; url: string; collectionId: number } {\n try {\n const response = record(value);\n if (response.result !== true) throw new Error();\n const item = record(response.item);\n if (!Number.isSafeInteger(item._id) || Number(item._id) <= 0)\n throw new Error();\n const destination = collectionId(record(item.collection).$id);\n const link = text(item.link, 10_000);\n if (\n input &&\n (new URL(link).toString() !== new URL(input.url).toString() ||\n destination !== (input.collectionId ?? -1))\n )\n throw new Error();\n return {\n id: String(item._id),\n collectionId: destination,\n url: `https://app.raindrop.io/my/${destination}/item/${item._id}`,\n };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\nexport function createRaindropClient(config: RaindropClientConfig) {\n if (!config.accessToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n const request = (\n path: string,\n options: Omit<\n ProviderRequestOptions,\n \"accessToken\" | \"clientId\" | \"clientSecret\"\n > = {},\n ) => raindropRequest(path, { ...config, ...options });\n async function listCollections(\n input: { cursor?: string; query?: string; parentId?: string } = {},\n ): Promise<ResourcePage> {\n if (input.cursor !== undefined) throw new IntegrationError(\"invalid_input\");\n if (input.query !== undefined) inputText(input.query, 1000, false);\n if (input.parentId !== undefined && !/^[1-9][0-9]*$/.test(input.parentId))\n throw new IntegrationError(\"invalid_input\");\n const pages = await Promise.all([\n request(\"/collections\"),\n request(\"/collections/childrens\"),\n ]);\n const resources = new Map<string, Resource>();\n resources.set(\"-1\", { id: \"-1\", type: \"collection\", name: \"Unsorted\" });\n for (const value of pages) {\n const response = record(value);\n if (\n response.result !== true ||\n !Array.isArray(response.items) ||\n response.items.length > 10_000\n )\n throw new IntegrationError(\"invalid_response\");\n for (const value of response.items) {\n const item = record(value);\n if (!Number.isSafeInteger(item._id) || Number(item._id) <= 0)\n throw new IntegrationError(\"invalid_response\");\n const level = record(item.access).level;\n if (!Number.isInteger(level) || Number(level) < 1 || Number(level) > 4)\n throw new IntegrationError(\"invalid_response\");\n if (Number(level) < 3) continue;\n let parentId: string | undefined;\n if (item.parent !== undefined && item.parent !== null) {\n const parent = record(item.parent);\n const id = parent.$id ?? parent._id;\n if (!Number.isSafeInteger(id) || Number(id) <= 0)\n throw new IntegrationError(\"invalid_response\");\n parentId = String(id);\n }\n resources.set(String(item._id), {\n id: String(item._id),\n type: \"collection\",\n name: text(item.title),\n metadata: {\n accessLevel: Number(level),\n ...(parentId ? { parentId } : {}),\n },\n });\n }\n }\n return {\n items: [...resources.values()].filter(\n (item) =>\n (!input.parentId || item.metadata?.parentId === input.parentId) &&\n (!input.query ||\n item.name\n .toLocaleLowerCase()\n .includes(input.query.toLocaleLowerCase())),\n ),\n };\n }\n async function createBookmark(value: RaindropCreateBookmarkInput) {\n const input = validateRaindropCreateBookmark(value);\n const id = input.collectionId ?? -1;\n if (id !== -1) {\n const response = record(await request(`/collection/${id}`));\n const item = record(response.item);\n if (response.result !== true || item._id !== id)\n throw new IntegrationError(\"invalid_response\");\n const level = record(item.access).level;\n if (level !== 3 && level !== 4)\n throw new IntegrationError(\"permission_required\");\n }\n const payload: Json = {\n link: input.url,\n collection: { $id: id },\n ...(input.title !== undefined ? { title: input.title } : {}),\n ...(input.note !== undefined ? { note: input.note } : {}),\n ...(input.excerpt !== undefined ? { excerpt: input.excerpt } : {}),\n ...(input.tags ? { tags: input.tags } : {}),\n };\n return bookmarkResult(await request(\"/raindrop\", { body: payload }), input);\n }\n return {\n request,\n listCollections,\n resources: listCollections,\n createBookmark,\n };\n}\n\nfunction tokenCredentials(\n value: unknown,\n previous?: CredentialMaterial,\n): CredentialMaterial {\n try {\n const response = record(value);\n const accessToken = text(response.access_token, 8192);\n const refreshToken = text(response.refresh_token, 8192);\n const expires = response.expires_in;\n if (\n typeof response.token_type !== \"string\" ||\n response.token_type.toLowerCase() !== \"bearer\" ||\n typeof expires !== \"number\" ||\n !Number.isInteger(expires) ||\n expires <= 0 ||\n expires > 31_536_000\n )\n throw new Error();\n return {\n accessToken,\n refreshToken,\n expiresAt: Date.now() + expires * 1000,\n ...(previous?.extra ? { extra: previous.extra } : {}),\n };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\nexport function createRaindropProvider(\n config: RaindropProviderConfig,\n): IntegrationProvider {\n if (\n !config.registrationId ||\n !config.clientId ||\n !config.clientSecret ||\n !config.redirectUri\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n const tokenRequest = (\n body: Json,\n fetcher: typeof globalThis.fetch,\n signal?: AbortSignal,\n ) =>\n raindropRequest(\"/v1/oauth/access_token\", {\n body: {\n client_id: config.clientId,\n client_secret: config.clientSecret,\n ...(body as Record<string, Json>),\n },\n fetch: fetcher,\n ...(signal ? { signal } : {}),\n });\n return {\n key: \"raindrop\",\n registrationId: config.registrationId,\n purposes: [\"connect\"],\n authorization: {\n url(input) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const url = new URL(\"https://raindrop.io/oauth/authorize\");\n url.search = new URLSearchParams({\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n state: input.state,\n }).toString();\n return url.toString();\n },\n async exchange(input, fetcher) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const credentials = tokenCredentials(\n await tokenRequest(\n {\n grant_type: \"authorization_code\",\n code: input.code,\n redirect_uri: config.redirectUri,\n },\n fetcher,\n input.signal,\n ),\n );\n const response = record(\n await raindropRequest(\"/user\", {\n accessToken: credentials.accessToken,\n fetch: fetcher,\n signal: input.signal,\n }),\n );\n const user = record(response.user);\n if (\n response.result !== true ||\n !Number.isSafeInteger(user._id) ||\n Number(user._id) <= 0\n )\n throw new IntegrationError(\"invalid_response\");\n const id = String(user._id);\n return {\n credentials,\n account: {\n id,\n label: optionalText(user.fullName) ?? `Raindrop ${id}`,\n },\n };\n },\n },\n resources(input, context) {\n return createRaindropClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n }).listCollections(input);\n },\n async refresh(credentials, context) {\n if (!credentials.refreshToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n return tokenCredentials(\n await tokenRequest(\n {\n grant_type: \"refresh_token\",\n refresh_token: credentials.refreshToken,\n },\n context.fetch,\n context.signal,\n ),\n credentials,\n );\n },\n // Raindrop does not document a revocation API; local disconnect must not pretend to revoke the upstream grant.\n actions: {\n create_bookmark: {\n validate(value) {\n return validateRaindropCreateBookmark(value) as unknown as Json;\n },\n async execute(value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (\n typeof checkpoint.id === \"string\" &&\n typeof checkpoint.url === \"string\" &&\n typeof checkpoint.collectionId === \"number\"\n )\n return {\n id: checkpoint.id,\n url: checkpoint.url,\n collectionId: checkpoint.collectionId,\n };\n const result = await createRaindropClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n }).createBookmark(value as unknown as RaindropCreateBookmarkInput);\n await context.saveCheckpoint(result);\n return result;\n },\n async reconcile(value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (\n typeof checkpoint.id !== \"string\" ||\n !/^[1-9][0-9]*$/.test(checkpoint.id)\n )\n return { resolved: false };\n const result = bookmarkResult(\n await raindropRequest(`/raindrop/${checkpoint.id}`, {\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n }),\n validateRaindropCreateBookmark(value),\n );\n if (result.id !== checkpoint.id)\n throw new IntegrationError(\"invalid_response\");\n return { resolved: true, result };\n },\n },\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAOO;AACP,yBAAgC;;;ACNzB,IAAM,mBAAN,cAA+B,MAAM;AAAA,EAE1C,YACW,MACA,cAAkC,qBAClC,cACT;AACA,UAAM,IAAI;AAJD;AACA;AACA;AAGT,SAAK,OAAO;AAAA,EACd;AAAA,EANW;AAAA,EACA;AAAA,EACA;AAAA,EAJF,WAAW;AAStB;;;ACGO,IAAM,oBAAN,cAAgC,iBAAiB;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT,YACE,MACA,aACA,UAOI,CAAC,GACL;AACA,UAAM,MAAM,aAAa,QAAQ,YAAY;AAC7C,SAAK,OAAO;AACZ,SAAK,SAAS,QAAQ,UAAU;AAChC,SAAK,eAAe,QAAQ;AAC5B,SAAK,WAAW,QAAQ,YAAY;AACpC,SAAK,sBAAsB,QAAQ;AACnC,SAAK,oBAAoB,QAAQ;AAAA,EACnC;AACF;AAEO,SAAS,OAAO,OAAyC;AAC9D,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK;AAC5D,UAAM,IAAI,iBAAiB,kBAAkB;AAC/C,SAAO;AACT;AACO,SAAS,KAAK,OAAgB,MAAM,MAAc;AACvD,MAAI,OAAO,UAAU,YAAY,MAAM,WAAW,KAAK,MAAM,SAAS;AACpE,UAAM,IAAI,iBAAiB,kBAAkB;AAC/C,SAAO;AACT;AACO,SAAS,aAAa,OAAgB,MAAM,MAA0B;AAC3E,SAAO,UAAU,UAAa,UAAU,OAAO,SAAY,KAAK,OAAO,GAAG;AAC5E;AACO,SAAS,YACd,OACAA,OACyB;AACzB,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK;AAC5D,UAAM,IAAI,iBAAiB,eAAe;AAC5C,QAAM,QAAQ;AACd,MAAI,OAAO,KAAK,KAAK,EAAE,KAAK,CAAC,QAAQ,CAACA,MAAK,SAAS,GAAG,CAAC;AACtD,UAAM,IAAI,iBAAiB,eAAe;AAC5C,SAAO;AACT;AACO,SAAS,UACd,OACA,SACA,WAAW,MACS;AACpB,MAAI,UAAU,UAAa,CAAC,SAAU,QAAO;AAC7C,MACE,OAAO,UAAU,YAChB,YAAY,CAAC,MAAM,KAAK,KACzB,MAAM,SAAS;AAEf,UAAM,IAAI,iBAAiB,eAAe;AAC5C,SAAO;AACT;AACO,SAAS,OAAO,OAAwB;AAC7C,QAAM,SAAS,UAAU,OAAO,GAAM;AACtC,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,MAAM;AAC1B,QACE,CAAC,CAAC,UAAU,OAAO,EAAE,SAAS,IAAI,QAAQ,KAC1C,IAAI,YACJ,IAAI;AAEJ,YAAM,IAAI,MAAM;AAAA,EACpB,QAAQ;AACN,UAAM,IAAI,iBAAiB,eAAe;AAAA,EAC5C;AACA,SAAO;AACT;AACO,SAAS,aAAa,OAAkC;AAC7D,MAAI,UAAU,OAAW,QAAO;AAChC,QAAM,QAAQ,CAAC,MAAe,UAC5B,SAAS,OACR,SAAS,QACR,OAAO,SAAS,YAChB,OAAO,SAAS,aACf,OAAO,SAAS,YAAY,OAAO,SAAS,IAAI,KAChD,MAAM,QAAQ,IAAI,KAAK,KAAK,MAAM,CAAC,UAAU,MAAM,OAAO,QAAQ,CAAC,CAAC,KACpE,OAAO,SAAS,YACf,SAAS,QACT,OAAO,eAAe,IAAI,MAAM,OAAO,aACvC,OAAO,OAAO,IAAI,EAAE,MAAM,CAAC,UAAU,MAAM,OAAO,QAAQ,CAAC,CAAC;AAClE,MAAI,CAAC,MAAM,OAAO,CAAC,KAAK,KAAK,UAAU,KAAK,EAAE,SAAS;AACrD,UAAM,IAAI,iBAAiB,eAAe;AAC5C,SAAO;AACT;AAEA,IAAM,YAAY,oBAAI,IAAI;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,OAAO;AACN,IAAM,SAAS,CAAC,UACrB,OAAO,UAAU,YAAY,KAAK,KAAK,KAAK;AACvC,SAAS,WAAW,OAA0C;AACnE,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,eAAe,kBAAkB,KAAK,KAAK,IAC7C,OAAO,KAAK,IAAI,MAChB,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI;AACjC,SAAO,OAAO,SAAS,YAAY,IAC/B,KAAK,IAAI,GAAG,KAAK,IAAI,cAAc,KAAU,CAAC,IAC9C;AACN;AAEA,SAAS,QACP,QACA,MACA,OACA,cACmB;AACnB,QAAM,UACJ,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,IAClD,OACD,CAAC;AACP,QAAM,aACJ,OAAO,QAAQ,SAAS,WACpB,QAAQ,OACR,OAAO,QAAQ,UAAU,WACvB,QAAQ,QACR;AACR,QAAM,eACJ,cAAc,UAAU,IAAI,UAAU,IAAI,aAAa;AACzD,QAAM,QACJ,QAAQ,mBAAmB,OAAO,QAAQ,oBAAoB,WACzD,QAAQ,kBACT,CAAC;AACP,QAAM,sBAAsB,OAAO,MAAM,qBAAqB,IAC1D,MAAM,wBACN;AACJ,QAAM,oBACJ,MAAM,QAAQ,MAAM,mBAAmB,KACvC,MAAM,oBAAoB,UAAU,OACpC,MAAM,oBAAoB,MAAM,MAAM,IACjC,MAAM,sBACP;AACN,QAAM,WACJ,UAAU,OACV,SAAS,OACT,WAAW,OACX,CAAC,uBACD,CAAC,mBAAmB;AACtB,MAAI,OACF,WAAW,MACP,kBACA,WAAW,MACT,yBACA,WAAW,MACT,wBACA,WAAW,OAAO,WAAW,MAC3B,iBACA,UAAU,MACR,yBACA;AACd,MACE,iBAAiB,oBACjB,iBAAiB,yBACjB,iBAAiB,kCACjB,QAAQ,iBAAiB;AAEzB,WAAO;AAAA,WAEP,iBAAiB,mBACjB,iBAAiB,4BACjB,iBAAiB,mBACjB,iBAAiB;AAEjB,WAAO;AAAA,WACA,MAAM,sBAAsB;AACnC,WAAO;AAAA,WACA,WAAW,OAAO,iBAAiB;AAC1C,WAAO;AAAA,WAEP,WAAW,OACX,OAAO,QAAQ,YAAY,YAC3B,6BAA6B,KAAK,QAAQ,OAAO;AAEjD,WAAO;AACT,QAAM,cACJ,SAAS,kBACL,oBACA,SAAS,CAAC,WACR,oBACA,SAAS,kBAAkB,UAAU,OAAO,WAAW,MACrD,cACA;AACV,SAAO,IAAI,kBAAkB,MAAM,aAAa;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,YACpB,KACA,MACA,SACA,UAA0E,CAAC,GACzD;AAClB,QAAM,QACJ,QAAQ,SAAS,CAAC,CAAC,OAAO,MAAM,EAAE,SAAS,KAAK,UAAU,KAAK;AACjE,QAAM,SAAS,KAAK,SAChB,YAAY,IAAI,CAAC,KAAK,QAAQ,YAAY,QAAQ,GAAM,CAAC,CAAC,IAC1D,YAAY,QAAQ,GAAM;AAC9B,MAAI;AACJ,MAAI;AACF,eAAW,MAAM,QAAQ,KAAK,EAAE,GAAG,MAAM,QAAQ,UAAU,QAAQ,CAAC;AAAA,EACtE,SAAS,OAAO;AAEd,QACE,iBAAiB,SACjB,cAAc,SACd,MAAM,aAAa,uCACnB,UAAU,SACV,MAAM,SAAS,kBACf,cAAc,SACd,MAAM,aAAa,MACnB;AACA,YAAM,QACJ,kBAAkB,SAClB,OAAO,MAAM,iBAAiB,YAC9B,OAAO,SAAS,MAAM,YAAY,IAC9B,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,cAAc,KAAU,CAAC,IACpD;AACN,YAAM,IAAI,kBAAkB,gBAAgB,aAAa;AAAA,QACvD,QAAQ;AAAA,QACR,UAAU;AAAA,QACV,cAAc;AAAA,MAChB,CAAC;AAAA,IACH;AACA,UAAM,IAAI;AAAA,MACR;AAAA,MACA,QAAQ,oBAAoB;AAAA,IAC9B;AAAA,EACF;AACA,MAAI,SAAS,WAAW,OAAO,SAAS,GAAI,QAAO,CAAC;AACpD,MAAI;AACJ,MAAI;AACF,QACE,QAAQ,eACR,CAAC,SAAS,QAAQ,IAAI,cAAc,GAAG,YAAY,EAAE,SAAS,MAAM;AAEpE,YAAM,IAAI,MAAM;AAClB,QAAI,CAAC,SAAS,KAAM,OAAM,IAAI,MAAM;AACpC,UAAM,SAAS,SAAS,KAAK,UAAU;AACvC,UAAM,SAAuB,CAAC;AAC9B,QAAI,OAAO;AACX,QAAI;AACF,iBAAS;AACP,cAAM,OAAO,MAAM,OAAO,KAAK;AAC/B,YAAI,KAAK,KAAM;AACf,gBAAQ,KAAK,MAAM;AACnB,YAAI,OAAO,SAAW;AACpB,gBAAM,OAAO,OAAO;AACpB,gBAAM,IAAI,MAAM;AAAA,QAClB;AACA,eAAO,KAAK,KAAK,KAAK;AAAA,MACxB;AAAA,IACF,UAAE;AACA,aAAO,YAAY;AAAA,IACrB;AACA,WAAO,KAAK,MAAM,OAAO,OAAO,MAAM,EAAE,SAAS,MAAM,CAAC;AAAA,EAC1D,QAAQ;AACN,QAAI,CAAC,SAAS;AACZ,YAAM;AAAA,QACJ,SAAS;AAAA,QACT,CAAC;AAAA,QACD;AAAA,QACA,WAAW,SAAS,QAAQ,IAAI,aAAa,CAAC;AAAA,MAChD;AACF,UAAM,IAAI;AAAA,MACR;AAAA,MACA,QAAQ,oBAAoB;AAAA,MAC5B,EAAE,QAAQ,SAAS,OAAO;AAAA,IAC5B;AAAA,EACF;AACA,MAAI,CAAC,SAAS;AACZ,UAAM;AAAA,MACJ,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA,WAAW,SAAS,QAAQ,IAAI,aAAa,CAAC;AAAA,IAChD;AACF,MAAI,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,GAAG;AAC5D,UAAM,QAAQ;AACd,QACE,OAAO,MAAM,UAAU,YACtB,QAAQ,YAAY,MAAM,WAAW,OACtC;AACA,YAAM,SACJ,OAAO,MAAM,WAAW,YACxB,OAAO,UAAU,MAAM,MAAM,KAC7B,MAAM,UAAU,OAChB,MAAM,SAAS,MACX,MAAM,SACN;AACN,YAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW,SAAS,QAAQ,IAAI,aAAa,CAAC;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,aAAa,MAAc,QAAwB;AAC1D,MACE,KAAK,SAAS,QACd,CAAC,gDAAgD,KAAK,IAAI,KAC1D,KAAK,SAAS,IAAI,KAClB,KAAK,SAAS,IAAI;AAElB,UAAM,IAAI,kBAAkB,yBAAyB,qBAAqB;AAAA,MACxE,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ,CAAC;AACH,SAAO,KAAK,WAAW,GAAG,MAAM,GAAG,KAAK,SAAS,SAC7C,OACA,GAAG,MAAM,GAAG,IAAI;AACtB;AACO,SAAS,cACd,MACA,SACkB;AAClB,QAAM,aAAa,aAAa,MAAM,KAAK;AAC3C,MAAI,CAAC,QAAQ,gBAAgB,CAAC,QAAQ,YAAY,CAAC,QAAQ;AACzD,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,MACA,EAAE,UAAU,KAAK;AAAA,IACnB;AACF,QAAM,gBAAgB,QAAQ,cAC1B,UAAU,QAAQ,WAAW,KAC7B,SAAS,OAAO,KAAK,GAAG,QAAQ,QAAQ,IAAI,QAAQ,YAAY,EAAE,EAAE,SAAS,QAAQ,CAAC;AAC1F,SAAO;AAAA,IACL,yBAAyB,UAAU;AAAA,IACnC;AAAA,MACE,QAAQ,QAAQ,WAAW,QAAQ,SAAS,SAAY,QAAQ;AAAA,MAChE,SAAS;AAAA,QACP,kBAAkB,QAAQ,cAAc;AAAA,QACxC,gBAAgB;AAAA,QAChB,QAAQ;AAAA,QACR,eAAe;AAAA,MACjB;AAAA,MACA,GAAI,QAAQ,SAAS,SACjB,CAAC,IACD,EAAE,MAAM,KAAK,UAAU,QAAQ,IAAI,EAAE;AAAA,MACzC,GAAI,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,IACrD;AAAA,IACA,QAAQ,SAAS,WAAW;AAAA,IAC5B;AAAA,MACE,OACE,eAAe,iBACd,QAAQ,WAAW,QAAQ,SAAS,SAAY,QAAQ,aACvD;AAAA,IACN;AAAA,EACF;AACF;AACO,SAAS,gBACd,MACA,SACkB;AAClB,QAAM,aACJ,SAAS,2BAA2B,OAAO,aAAa,MAAM,UAAU;AAC1E,MAAI,eAAe,4BAA4B,CAAC,QAAQ;AACtD,UAAM,IAAI,kBAAkB,iBAAiB,mBAAmB;AAAA,MAC9D,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ,CAAC;AACH,SAAO;AAAA,IACL,0BAA0B,UAAU;AAAA,IACpC;AAAA,MACE,QAAQ,QAAQ,WAAW,QAAQ,SAAS,SAAY,QAAQ;AAAA,MAChE,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,QAAQ;AAAA,QACR,GAAI,QAAQ,cACR,EAAE,eAAe,UAAU,QAAQ,WAAW,GAAG,IACjD,CAAC;AAAA,MACP;AAAA,MACA,GAAI,QAAQ,SAAS,SACjB,CAAC,IACD,EAAE,MAAM,KAAK,UAAU,QAAQ,IAAI,EAAE;AAAA,MACzC,GAAI,QAAQ,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,IACrD;AAAA,IACA,QAAQ,SAAS,WAAW;AAAA,IAC5B,EAAE,UAAU,MAAM,aAAa,KAAK;AAAA,EACtC;AACF;;;AFlZA,SAAS,UAAU,QAAsC;AACvD,MACE,CAAC,OAAO,kBACR,CAAC,OAAO,YACR,CAAC,OAAO,eACR,OAAO,sBAAsB;AAE7B,UAAM,IAAI,iBAAiB,gCAAgC;AAC7D,MAAI;AACJ,MAAI;AACF,UAAM,IAAI,IAAI,OAAO,WAAW;AAAA,EAClC,QAAQ;AACN,UAAM,IAAI,iBAAiB,gCAAgC;AAAA,EAC7D;AACA,MACE,IAAI,YACJ,IAAI,YACJ,IAAI,QACH,IAAI,aAAa,YAChB,EACE,IAAI,aAAa,WACjB,CAAC,aAAa,aAAa,OAAO,EAAE,SAAS,IAAI,QAAQ;AAG7D,UAAM,IAAI,iBAAiB,gCAAgC;AAC/D;AACA,SAAS,gBAAgB,SAAuB;AAC9C,MAAI,YAAY,WAAY,OAAM,IAAI,iBAAiB,qBAAqB;AAC9E;AACA,SAAS,iBACP,MACA,YACQ;AACR,QAAM,MAAM,IAAI,IAAI,IAAI;AACxB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,UAAU;AAClD,QAAI,aAAa,IAAI,KAAK,KAAK;AACjC,SAAO,IAAI,SAAS;AACtB;AACA,IAAM,YAAY,oBAAI,QAUpB;AACF,IAAM,WAAW,oBAAI,QAGnB;AACF,eAAe,KACb,KACA,SACA,QAAQ,OACR;AACA,MAAI,QAAQ,UAAU,IAAI,OAAO;AACjC,MAAI,CAAC,OAAO;AACV,YAAQ,oBAAI,IAAI;AAChB,cAAU,IAAI,SAAS,KAAK;AAAA,EAC9B;AACA,QAAM,WAAW,MAAM,IAAI,GAAG;AAC9B,MAAI,CAAC,SAAS,YAAY,SAAS,UAAU,KAAK,IAAI;AACpD,WAAO,SAAS;AAElB,MAAI,SAAS,YAAY,SAAS,cAAc,MAAS,KAAK,IAAI;AAChE,WAAO,SAAS;AAClB,MAAI,QAAQ,SAAS,IAAI,OAAO;AAChC,MAAI,CAAC,OAAO;AACV,YAAQ,oBAAI,IAAI;AAChB,aAAS,IAAI,SAAS,KAAK;AAAA,EAC7B;AACA,QAAM,UAAU,MAAM,IAAI,GAAG;AAC7B,MAAI,QAAS,QAAO;AACpB,QAAM,QAAQ,YAAY;AACxB,QAAI;AACF,YAAM,QAAQ,OAAO,MAAM,YAAY,KAAK,CAAC,GAAG,OAAO,CAAC;AACxD,UAAI,CAAC,MAAM,QAAQ,MAAM,IAAI,KAAK,MAAM,KAAK,SAAS;AACpD,cAAM,IAAI,MAAM;AAClB,YAAM,cAAU,+BAAkB,KAAiC;AACnE,YAAM,MAAM,KAAK,IAAI;AACrB,YAAO,IAAI,KAAK,EAAE,SAAS,MAAM,KAAS,aAAa,KAAK,QAAQ,CAAC;AACrE,aAAO;AAAA,IACT,QAAQ;AACN,YAAM,IAAI,iBAAiB,wBAAwB,WAAW;AAAA,IAChE;AAAA,EACF,GAAG;AACH,QAAM,IAAI,KAAK,IAAI;AACnB,MAAI;AACF,WAAO,MAAM;AAAA,EACf,UAAE;AACA,UAAM,OAAO,GAAG;AAAA,EAClB;AACF;AACA,eAAe,YACb,OACA,QACA,SACA,SAC2B;AAC3B,MACE,CAAC,MAAM,SACP,MAAM,MAAM,SAAS,QACrB,CAAC,MAAM,WACP,MAAM,QAAQ,SAAS,SACvB,CAAC,QAAQ,UAAU,UACnB,QAAQ,UAAU,KAAK,CAAC,SAAS,CAAC,IAAI;AAEtC,UAAM,IAAI,iBAAiB,kBAAkB;AAC/C,QAAM,SAAS,QAAQ,aAAa;AACpC,QAAM,SAAS,SACX,gCACA;AACJ,QAAM,OAAO,SACT,+CACA;AACJ,QAAM,sBAAsB;AAAA,IAC1B,YAAY,CAAC,OAAO;AAAA,IACpB,QAAQ,SAAS,CAAC,QAAQ,qBAAqB,IAAI;AAAA,IACnD,UAAU,CAAC,GAAG,QAAQ,SAAS;AAAA,IAC/B,gBAAgB,CAAC,OAAO,OAAO,OAAO,OAAO;AAAA,IAC7C,gBAAgB;AAAA,EAClB;AACA,MAAI;AACJ,MAAI;AACF,QAAI,UAAU,MAAM,KAAK,MAAM,OAAO;AACtC,QAAI;AACF,OAAC,EAAE,QAAQ,IAAI,UAAM;AAAA,QACnB,MAAM;AAAA,QACN;AAAA,QACA;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,UAAI,EACF,SACA,OAAO,UAAU,YACjB,UAAU,SACV,MAAM,SAAS;AAEf,cAAM;AACR,gBAAU,MAAM,KAAK,MAAM,SAAS,IAAI;AACxC,OAAC,EAAE,QAAQ,IAAI,UAAM;AAAA,QACnB,MAAM;AAAA,QACN;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,UAAM,WAAW,OAAO,KAAK,MAAM,KAAK;AACxC,UAAM,SAAS,OAAO;AAAA,MACpB,OAAO,QAAQ,UAAU,WAAW,QAAQ,QAAQ;AAAA,IACtD;AACA,QACE,SAAS,WAAW,OAAO,UAC3B,KAAC,oCAAgB,UAAU,MAAM,KACjC,OAAO,QAAQ,QAAQ,YACvB,QAAQ,MAAM,KAAK,IAAI,IAAI,MAAO,MAClC,OAAO,QAAQ,QAAQ,YACvB,CAAC,QAAQ,OACT,QAAQ,IAAI,SAAS;AAErB,YAAM,IAAI,MAAM;AAElB,QACE,MAAM,QAAQ,QAAQ,GAAG,KACzB,QAAQ,IAAI,SAAS,MACpB,OAAO,QAAQ,QAAQ,YACtB,CAAC,QAAQ,UAAU,SAAS,QAAQ,GAAG;AAEzC,YAAM,IAAI,MAAM;AAAA,EACpB,SAAS,OAAO;AACd,QACE,iBAAiB,qBAChB,MAAM,gBAAgB,eACrB,MAAM,gBAAgB;AAExB,YAAM,IAAI,iBAAiB,wBAAwB,WAAW;AAChE,UAAM,IAAI,iBAAiB,kBAAkB;AAAA,EAC/C;AACA,QAAM,QAAQ,aAAa,QAAQ,OAAO,GAAG;AAC7C,QAAM,OAAO,aAAa,QAAQ,MAAM,IAAI;AAC5C,SAAO;AAAA,IACL,UAAU,QAAQ;AAAA,IAClB;AAAA,IACA,SAAS,QAAQ;AAAA,IACjB,mBAAmB,OAAO,qBAAqB,OAAO;AAAA,IACtD,eACE,QAAQ,mBAAmB,QAC1B,QAAQ,aAAa,WAAW,QAAQ,mBAAmB;AAAA,IAC9D,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IACzB,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,EACzB;AACF;AAEO,SAAS,qBACd,QACqB;AACrB,YAAU,MAAM;AAChB,SAAO;AAAA,IACL,KAAK;AAAA,IACL,gBAAgB,OAAO;AAAA,IACvB,UAAU,CAAC,UAAU;AAAA,IACrB,eAAe;AAAA,MACb,IAAI,OAA2B;AAC7B,wBAAgB,MAAM,OAAO;AAC7B,eAAO;AAAA,UACL;AAAA,UACA;AAAA,YACE,WAAW,OAAO;AAAA,YAClB,cAAc,OAAO;AAAA,YACrB,eAAe;AAAA,YACf,OAAO;AAAA,YACP,OAAO,MAAM;AAAA,YACb,OAAO,MAAM;AAAA,YACb,gBAAgB,MAAM;AAAA,YACtB,uBAAuB;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,SAAS,OAAO,SAAS;AAC7B,wBAAgB,MAAM,OAAO;AAC7B,YAAI,CAAC,OAAO;AACV,gBAAM,IAAI,iBAAiB,yBAAyB;AACtD,cAAM,SAAS;AAAA,UACb,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,SAAS;AAAA,gBACP,gBAAgB;AAAA,gBAChB,QAAQ;AAAA,cACV;AAAA,cACA,MAAM,IAAI,gBAAgB;AAAA,gBACxB,WAAW,OAAO;AAAA,gBAClB,eAAe,OAAO;AAAA,gBACtB,cAAc,OAAO;AAAA,gBACrB,YAAY;AAAA,gBACZ,MAAM,MAAM;AAAA,gBACZ,eAAe,MAAM;AAAA,cACvB,CAAC;AAAA,cACD,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,YACjD;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,cAAM,WAAW,MAAM;AAAA,UACrB,EAAE,SAAS,KAAK,OAAO,UAAU,KAAM,GAAG,OAAO,MAAM,MAAM;AAAA,UAC7D;AAAA,UACA;AAAA,UACA,EAAE,UAAU,UAAU,WAAW,CAAC,OAAO,QAAQ,EAAE;AAAA,QACrD;AACA,eAAO,EAAE,SAAS;AAAA,MACpB;AAAA,IACF;AAAA,IACA,aAAa,OAAO,SAAS;AAC3B,aAAO,YAAY,OAAO,QAAQ,SAAS;AAAA,QACzC,UAAU;AAAA,QACV,WAAW,OAAO,mBAAmB,CAAC,OAAO,QAAQ;AAAA,MACvD,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,SAAS,oBACd,QACqB;AACrB,YAAU,MAAM;AAChB,iBAAe,eAAgC;AAC7C,QAAI,CAAC,OAAO,UAAU,CAAC,OAAO,SAAS,CAAC,OAAO;AAC7C,YAAM,IAAI,iBAAiB,yBAAyB;AACtD,QAAI;AACF,YAAM,MAAM,UAAM,yBAAY,OAAO,YAAY,OAAO;AACxD,aAAO,MAAM,IAAI,oBAAQ,CAAC,CAAC,EACxB,mBAAmB,EAAE,KAAK,SAAS,KAAK,OAAO,MAAM,CAAC,EACtD,UAAU,OAAO,MAAM,EACvB,WAAW,OAAO,QAAQ,EAC1B,YAAY,2BAA2B,EACvC,YAAY,EACZ,kBAAkB,IAAI,EACtB,KAAK,GAAG;AAAA,IACb,QAAQ;AACN,YAAM,IAAI,iBAAiB,yBAAyB;AAAA,IACtD;AAAA,EACF;AACA,SAAO;AAAA,IACL,KAAK;AAAA,IACL,gBAAgB,OAAO;AAAA,IACvB,UAAU,CAAC,UAAU;AAAA,IACrB,eAAe;AAAA,MACb,IAAI,OAAO;AACT,wBAAgB,MAAM,OAAO;AAC7B,eAAO,iBAAiB,4CAA4C;AAAA,UAClE,WAAW,OAAO;AAAA,UAClB,cAAc,OAAO;AAAA,UACrB,eAAe;AAAA,UACf,eAAe;AAAA,UACf,OAAO;AAAA,UACP,OAAO,MAAM;AAAA,UACb,OAAO,MAAM;AAAA,QACf,CAAC;AAAA,MACH;AAAA,MACA,MAAM,SAAS,OAAO,SAAS;AAC7B,wBAAgB,MAAM,OAAO;AAC7B,cAAM,SAAS;AAAA,UACb,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,SAAS;AAAA,gBACP,gBAAgB;AAAA,gBAChB,QAAQ;AAAA,cACV;AAAA,cACA,MAAM,IAAI,gBAAgB;AAAA,gBACxB,WAAW,OAAO;AAAA,gBAClB,eAAe,MAAM,aAAa;AAAA,gBAClC,cAAc,OAAO;AAAA,gBACrB,YAAY;AAAA,gBACZ,MAAM,MAAM;AAAA,cACd,CAAC;AAAA,cACD,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,YACjD;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,UACL,UAAU,MAAM;AAAA,YACd,EAAE,SAAS,KAAK,OAAO,UAAU,KAAM,GAAG,OAAO,MAAM,MAAM;AAAA,YAC7D;AAAA,YACA;AAAA,YACA,EAAE,UAAU,SAAS,WAAW,CAAC,OAAO,QAAQ,EAAE;AAAA,UACpD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA,IAEA,aAAa,OAAO,SAAS;AAC3B,aAAO,YAAY,OAAO,QAAQ,SAAS;AAAA,QACzC,UAAU;AAAA,QACV,WAAW,OAAO,mBAAmB,CAAC,OAAO,QAAQ;AAAA,MACvD,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,SAAS,qBACd,QACqB;AACrB,YAAU,MAAM;AAChB,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,iBAAiB,gCAAgC;AAC7D,SAAO;AAAA,IACL,KAAK;AAAA,IACL,gBAAgB,OAAO;AAAA,IACvB,UAAU,CAAC,UAAU;AAAA,IACrB,eAAe;AAAA,MACb,IAAI,OAAO;AACT,wBAAgB,MAAM,OAAO;AAC7B,eAAO,iBAAiB,4CAA4C;AAAA,UAClE,WAAW,OAAO;AAAA,UAClB,cAAc,OAAO;AAAA,UACrB,OAAO;AAAA,UACP,OAAO,MAAM;AAAA,UACb,gBAAgB,MAAM;AAAA,UACtB,uBAAuB;AAAA,QACzB,CAAC;AAAA,MACH;AAAA,MACA,MAAM,SAAS,OAAO,SAAS;AAC7B,wBAAgB,MAAM,OAAO;AAC7B,cAAM,SAAS;AAAA,UACb,MAAM;AAAA,YACJ;AAAA,YACA;AAAA,cACE,QAAQ;AAAA,cACR,SAAS;AAAA,gBACP,QAAQ;AAAA,gBACR,gBAAgB;AAAA,cAClB;AAAA,cACA,MAAM,IAAI,gBAAgB;AAAA,gBACxB,WAAW,OAAO;AAAA,gBAClB,eAAe,OAAO;AAAA,gBACtB,cAAc,OAAO;AAAA,gBACrB,MAAM,MAAM;AAAA,gBACZ,eAAe,MAAM;AAAA,cACvB,CAAC;AAAA,cACD,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,YACjD;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,cAAM,cAAc,KAAK,OAAO,YAAY;AAC5C,cAAM,UAAU;AAAA,UACd,QAAQ;AAAA,UACR,eAAe,UAAU,WAAW;AAAA,UACpC,wBAAwB;AAAA,UACxB,cAAc;AAAA,QAChB;AACA,cAAM,OAAO;AAAA,UACX,MAAM;AAAA,YACJ;AAAA,YACA,EAAE,SAAS,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC,EAAG;AAAA,YAC7D;AAAA,UACF;AAAA,QACF;AACA,YAAI,CAAC,OAAO,cAAc,KAAK,EAAE,KAAK,OAAO,KAAK,EAAE,KAAK;AACvD,gBAAM,IAAI,iBAAiB,kBAAkB;AAC/C,cAAM,SAAS,MAAM;AAAA,UACnB;AAAA,UACA,EAAE,SAAS,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC,EAAG;AAAA,UAC7D;AAAA,QACF;AACA,YAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,OAAO,SAAS;AAC5C,gBAAM,IAAI,iBAAiB,kBAAkB;AAC/C,cAAM,UAAU,OAAO;AAAA,UACrB,CAAC,SACC,QACA,OAAO,SAAS,YAChB,KAAK,YAAY,QACjB,KAAK,aAAa;AAAA,QACtB;AACA,cAAM,QAAQ,UAAU,KAAK,QAAQ,OAAO,GAAG,IAAI;AACnD,cAAM,OAAO,aAAa,KAAK,MAAM,IAAI;AACzC,cAAM,WAAW,KAAK,KAAK,OAAO,GAAG;AACrC,eAAO;AAAA,UACL,UAAU;AAAA,YACR,UAAU;AAAA,YACV,QAAQ;AAAA,YACR,SAAS,OAAO,KAAK,EAAE;AAAA,YACvB,mBACE,OAAO,qBAAqB,OAAO;AAAA,YACrC,eAAe,QAAQ,KAAK;AAAA,YAC5B;AAAA,YACA,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,YACzB,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,UACzB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AGvcO,IAAM,qBAAqB;AAuBlC,SAASC,MAAK,OAAwB;AACpC,MAAI,CAAC,OAAO,KAAK,EAAG,OAAM,IAAI,iBAAiB,eAAe;AAC9D,SAAO;AACT;AACA,IAAM,cAAc,CAAC,UACnB,OAAO,UAAU,YAAY,MAAM,SAAS,KAAK,MAAM,UAAU;AAC5D,SAAS,yBACd,OACuB;AACvB,QAAM,QAAQ,YAAY,OAAO;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,SAAgC;AAAA,IACpC,UAAUA,MAAK,MAAM,QAAQ;AAAA,IAC7B,OAAO,UAAU,MAAM,OAAO,GAAI;AAAA,EACpC;AACA,MAAI,MAAM,eAAe,QAAW;AAClC,QAAI,MAAM,eAAe,UAAU,MAAM,eAAe;AACtD,YAAM,IAAI,iBAAiB,eAAe;AAC5C,WAAO,aAAa,MAAM;AAAA,EAC5B;AACA,MAAI,MAAM,YAAY;AACpB,WAAO,UAAU,UAAU,MAAM,SAAS,KAAS,KAAK;AAC1D,MAAI,MAAM,QAAQ,OAAW,QAAO,MAAM,OAAO,MAAM,GAAG;AAC1D,MAAI,MAAM,aAAa,QAAW;AAChC,UAAM,WAAW,aAAa,MAAM,QAAQ;AAC5C,QAAI,CAAC,YAAY,MAAM,QAAQ,QAAQ,KAAK,OAAO,aAAa;AAC9D,YAAM,IAAI,iBAAiB,eAAe;AAC5C,WAAO,WAAW;AAAA,EACpB;AACA,SAAO;AACT;AACA,SAAS,SAAS,OAAuB;AACvC,QAAM,SAAiB,CAAC;AACxB,WAAS,QAAQ,GAAG,QAAQ,MAAM,UAAS;AACzC,QAAI,MAAM,KAAK,IAAI,QAAQ,KAAM,MAAM,MAAM;AAC7C,QAAI,MAAM,MAAM,UAAU,kBAAkB,KAAK,MAAM,OAAO,MAAM,CAAC,CAAC;AACpE;AACF,WAAO,KAAK,EAAE,MAAM,QAAQ,MAAM,EAAE,SAAS,MAAM,MAAM,OAAO,GAAG,EAAE,EAAE,CAAC;AACxE,YAAQ;AAAA,EACV;AACA,SAAO;AACT;AACA,SAAS,cAAc,OAAwB;AAC7C,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,OAAM,IAAI,iBAAiB,kBAAkB;AACxE,SAAO,MACJ,IAAI,CAAC,SAAS;AACb,UAAM,QAAQ,OAAO,IAAI;AACzB,QAAI,OAAO,MAAM,eAAe,SAAU,QAAO,MAAM;AACvD,WAAO,KAAK,OAAO,MAAM,IAAI,EAAE,SAAS,GAAI;AAAA,EAC9C,CAAC,EACA,KAAK,EAAE;AACZ;AACA,SAAS,WAAW,OAA6C;AAC/D,MAAI;AACF,UAAM,OAAO,OAAO,KAAK;AACzB,QAAI,KAAK,WAAW,UAAU,CAAC,OAAO,KAAK,EAAE,EAAG,OAAM,IAAI,MAAM;AAChE,UAAM,MAAM,KAAK,KAAK,KAAK,IAAI;AAC/B,QAAI,IAAI,IAAI,GAAG,EAAE,aAAa,SAAU,OAAM,IAAI,MAAM;AACxD,WAAO,EAAE,IAAI,KAAK,IAAI,IAAI;AAAA,EAC5B,QAAQ;AACN,UAAM,IAAI,iBAAiB,oBAAoB,iBAAiB;AAAA,EAClE;AACF;AAEO,SAAS,mBAAmB,QAA4B;AAC7D,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,iBAAiB,iBAAiB,iBAAiB;AAC/D,QAAM,UAAU,CACd,MACA,UAGI,CAAC,MACF,cAAc,MAAM,EAAE,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAClD,iBAAe,cACb,QAAgE,CAAC,GAC1C;AACvB,QAAI,MAAM,aAAa;AACrB,YAAM,IAAI,iBAAiB,6BAA6B;AAC1D,QAAI,MAAM,WAAW,UAAa,CAAC,YAAY,MAAM,MAAM;AACzD,YAAM,IAAI,iBAAiB,eAAe;AAC5C,QAAI,MAAM,UAAU,OAAW,WAAU,MAAM,OAAO,KAAM,KAAK;AACjE,UAAM,WAAW;AAAA,MACf,MAAM,QAAQ,WAAW;AAAA,QACvB,MAAM;AAAA,UACJ,WAAW;AAAA,UACX,GAAI,MAAM,SAAS,EAAE,cAAc,MAAM,OAAO,IAAI,CAAC;AAAA,UACrD,GAAI,MAAM,UAAU,SAAY,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,QAC5D;AAAA,MACF,CAAC;AAAA,IACH;AACA,QACE,CAAC,MAAM,QAAQ,SAAS,OAAO,KAC/B,SAAS,QAAQ,SAAS,OAC1B,OAAO,SAAS,aAAa;AAE7B,YAAM,IAAI,iBAAiB,kBAAkB;AAC/C,QACE,SAAS,mBAAmB,UAC5B,OAAO,SAAS,cAAc,EAAE,SAAS;AAEzC,YAAM,IAAI,iBAAiB,6BAA6B;AAC1D,QAAI,SAAS,YAAY,CAAC,YAAY,SAAS,WAAW;AACxD,YAAM,IAAI,iBAAiB,kBAAkB;AAC/C,UAAM,QAAoB,CAAC;AAC3B,eAAW,QAAQ,SAAS,SAAS;AACnC,YAAM,QAAQ,OAAO,IAAI;AACzB,UACE,CAAC,OAAO,MAAM,EAAE,KACf,MAAM,WAAW,UAAU,MAAM,WAAW;AAE7C,cAAM,IAAI,iBAAiB,kBAAkB;AAC/C,UACE,MAAM,aAAa,QACnB,MAAM,aAAa,QACnB,MAAM,gBAAgB;AAEtB;AACF,UAAI;AACJ,UAAI,MAAM,WAAW,cAAe,QAAO,cAAc,MAAM,KAAK;AAAA,WAC/D;AACH,cAAM,aAAa,OAAO,MAAM,UAAU;AAC1C,cAAM,QAAQ,OAAO,OAAO,UAAU,EACnC,IAAI,MAAM,EACV,KAAK,CAAC,aAAa,SAAS,SAAS,OAAO;AAC/C,eAAO,QAAQ,cAAc,MAAM,KAAK,IAAI;AAAA,MAC9C;AACA,YAAM,MAAM,aAAa,MAAM,GAAG;AAClC,YAAM,KAAK;AAAA,QACT,IAAI,MAAM;AAAA,QACV,MAAM,MAAM;AAAA,QACZ,MAAM,QAAQ;AAAA,QACd,GAAI,MAAM,EAAE,IAAI,IAAI,CAAC;AAAA,MACvB,CAAC;AAAA,IACH;AACA,WAAO;AAAA,MACL;AAAA,MACA,GAAI,SAAS,WACT,EAAE,YAAY,SAAS,YAAsB,IAC7C,CAAC;AAAA,IACP;AAAA,EACF;AACA,iBAAe,WACb,OACsC;AACtC,UAAM,QAAQ,yBAAyB,KAAK;AAC5C,UAAM,aAAa,MAAM,cAAc;AACvC,QAAI,WAAW;AACf,QAAI,eAAe,eAAe;AAChC,YAAM,SAAS,OAAO,MAAM,QAAQ,iBAAiB,MAAM,QAAQ,EAAE,CAAC;AACtE,UAAI,OAAO,OAAO,MAAM,YAAY,OAAO,WAAW;AACpD,cAAM,IAAI,iBAAiB,kBAAkB;AAC/C,YAAM,WAAW,OAAO,QAAQ,OAAO,OAAO,UAAU,CAAC,EAAE;AAAA,QACzD,CAAC,CAAC,EAAE,UAAU,MAAM,OAAO,UAAU,EAAE,SAAS;AAAA,MAClD;AACA,UAAI,CAAC,SAAU,OAAM,IAAI,iBAAiB,kBAAkB;AAC5D,iBAAW,SAAS,CAAC;AAAA,IACvB;AACA,UAAM,WAAmB,CAAC;AAC1B,QAAI,MAAM,SAAS;AACjB,iBAAW,QAAQ,SAAS,MAAM,OAAO;AACvC,iBAAS,KAAK;AAAA,UACZ,QAAQ;AAAA,UACR,MAAM;AAAA,UACN,WAAW,EAAE,WAAW,CAAC,IAAI,EAAE;AAAA,QACjC,CAAC;AAAA,IACL;AACA,QAAI,MAAM;AACR,eAAS,KAAK;AAAA,QACZ,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,UAAU,EAAE,KAAK,MAAM,IAAI;AAAA,MAC7B,CAAC;AACH,WAAO;AAAA,MACL,MAAM,QAAQ,UAAU;AAAA,QACtB,MAAM;AAAA,UACJ,QACE,eAAe,SACX,EAAE,SAAS,MAAM,SAAS,IAC1B,EAAE,gBAAgB,MAAM,SAAS;AAAA,UACvC,YAAY;AAAA,YACV,CAAC,QAAQ,GAAG,EAAE,MAAM,SAAS,OAAO,SAAS,MAAM,KAAK,EAAE;AAAA,UAC5D;AAAA,UACA,GAAI,SAAS,SAAS,EAAE,SAAS,IAAI,CAAC;AAAA,QACxC;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO,EAAE,SAAS,eAAe,WAAW,eAAe,WAAW;AACxE;AAEA,SAAS,iBACP,OACA,UACoB;AACpB,MAAI;AACF,UAAM,WAAW,OAAO,KAAK;AAC7B,UAAM,cAAc,KAAK,SAAS,cAAc,IAAI;AAGpD,UAAM,eACJ,SAAS,kBAAkB,OACvB,SACA,KAAK,SAAS,eAAe,IAAI;AACvC,QACE,OAAO,SAAS,eAAe,YAC/B,SAAS,WAAW,YAAY,MAAM;AAEtC,YAAM,IAAI,MAAM;AAClB,UAAM,UAAU,SAAS;AACzB,QACE,YAAY,WACX,OAAO,YAAY,YAClB,CAAC,OAAO,UAAU,OAAO,KACzB,WAAW,KACX,UAAU;AAEZ,YAAM,IAAI,MAAM;AAClB,WAAO;AAAA,MACL;AAAA,MACA,GAAI,iBAAiB,SAAY,EAAE,aAAa,IAAI,CAAC;AAAA,MACrD,GAAI,YAAY,SACZ,EAAE,WAAW,KAAK,IAAI,IAAI,OAAO,OAAO,IAAI,IAAK,IACjD,CAAC;AAAA,MACL,GAAI,UAAU,SAAS,EAAE,QAAQ,SAAS,OAAO,IAAI,CAAC;AAAA,MACtD,GAAI,UAAU,QAAQ,EAAE,OAAO,SAAS,MAAM,IAAI,CAAC;AAAA,IACrD;AAAA,EACF,QAAQ;AACN,UAAM,IAAI,iBAAiB,oBAAoB,iBAAiB;AAAA,EAClE;AACF;AACO,SAAS,qBACd,QACqB;AACrB,MACE,CAAC,OAAO,kBACR,CAAC,OAAO,YACR,CAAC,OAAO,gBACR,CAAC,OAAO;AAER,UAAM,IAAI,iBAAiB,gCAAgC;AAC7D,QAAM,eAAe,CACnB,MACA,SACA,WAEA,cAAc,gBAAgB;AAAA,IAC5B,UAAU,OAAO;AAAA,IACjB,cAAc,OAAO;AAAA,IACrB,YAAY,OAAO;AAAA,IACnB;AAAA,IACA,OAAO;AAAA,IACP,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,EAC7B,CAAC;AACH,SAAO;AAAA,IACL,KAAK;AAAA,IACL,gBAAgB,OAAO;AAAA,IACvB,UAAU,CAAC,SAAS;AAAA,IACpB,eAAe;AAAA,MACb,IAAI,OAAO;AACT,YAAI,MAAM,YAAY;AACpB,gBAAM,IAAI,iBAAiB,qBAAqB;AAClD,cAAM,MAAM,IAAI,IAAI,2CAA2C;AAC/D,YAAI,SAAS,IAAI,gBAAgB;AAAA,UAC/B,WAAW,OAAO;AAAA,UAClB,cAAc,OAAO;AAAA,UACrB,eAAe;AAAA,UACf,OAAO;AAAA,UACP,OAAO,MAAM;AAAA,QACf,CAAC,EAAE,SAAS;AACZ,eAAO,IAAI,SAAS;AAAA,MACtB;AAAA,MACA,MAAM,SAAS,OAAO,SAAS;AAC7B,YAAI,MAAM,YAAY;AACpB,gBAAM,IAAI,iBAAiB,qBAAqB;AAClD,cAAM,WAAW;AAAA,UACf,MAAM;AAAA,YACJ;AAAA,cACE,YAAY;AAAA,cACZ,MAAM,MAAM;AAAA,cACZ,cAAc,OAAO;AAAA,YACvB;AAAA,YACA;AAAA,YACA,MAAM;AAAA,UACR;AAAA,QACF;AACA,cAAM,cAAc,iBAAiB,QAAQ;AAC7C,cAAM,cAAc,KAAK,SAAS,YAAY;AAC9C,cAAM,QAAQ,KAAK,SAAS,MAAM;AAClC,YAAI,CAAC,OAAO,WAAW,KAAK,CAAC,OAAO,KAAK;AACvC,gBAAM,IAAI,iBAAiB,oBAAoB,iBAAiB;AAClE,cAAM,QAAQ,OAAO,SAAS,KAAK;AACnC,YAAI,MAAM,SAAS;AACjB,gBAAM,IAAI,iBAAiB,kBAAkB;AAC/C,cAAM,SAAS,KAAK,OAAO,MAAM,IAAI,EAAE,EAAE;AACzC,YAAI,CAAC,OAAO,MAAM,EAAG,OAAM,IAAI,iBAAiB,kBAAkB;AAClE,cAAM,QACJ,aAAa,SAAS,cAAc,KAAK;AAC3C,oBAAY,QAAQ,EAAE,aAAa,OAAO,SAAS,OAAO;AAC1D,eAAO;AAAA,UACL;AAAA,UACA,SAAS;AAAA,YACP,IAAI,GAAG,WAAW,IAAI,KAAK,IAAI,MAAM;AAAA,YACrC;AAAA,YACA,UAAU,EAAE,aAAa,OAAO,SAAS,OAAO;AAAA,UAClD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,UAAU,OAAO,SAAS;AACxB,aAAO,mBAAmB;AAAA,QACxB,aAAa,QAAQ,YAAY;AAAA,QACjC,OAAO,QAAQ;AAAA,QACf,QAAQ,QAAQ;AAAA,QAChB,YAAY,OAAO;AAAA,MACrB,CAAC,EAAE,cAAc,KAAK;AAAA,IACxB;AAAA,IACA,MAAM,QAAQ,aAAa,SAAS;AAClC,UAAI,CAAC,YAAY;AACf,cAAM,IAAI,iBAAiB,iBAAiB,iBAAiB;AAC/D,aAAO;AAAA,QACL,MAAM;AAAA,UACJ;AAAA,YACE,YAAY;AAAA,YACZ,eAAe,YAAY;AAAA,UAC7B;AAAA,UACA,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACA,MAAM,OAAO,aAAa,SAAS;AACjC,YAAM,cAAc,iBAAiB;AAAA,QACnC,UAAU,OAAO;AAAA,QACjB,cAAc,OAAO;AAAA,QACrB,YAAY,OAAO;AAAA,QACnB,MAAM,EAAE,OAAO,YAAY,YAAY;AAAA,QACvC,OAAO,QAAQ;AAAA,QACf,QAAQ,QAAQ;AAAA,MAClB,CAAC;AAAA,IACH;AAAA,IACA,SAAS;AAAA,MACP,aAAa;AAAA,QACX,SAAS,OAAO;AACd,iBAAO,yBAAyB,KAAK;AAAA,QACvC;AAAA,QACA,MAAM,QAAQ,OAAO,SAAS;AAC5B,gBAAM,aACJ,QAAQ,cACR,OAAO,QAAQ,eAAe,YAC9B,CAAC,MAAM,QAAQ,QAAQ,UAAU,IAC7B,QAAQ,aACR,CAAC;AACP,cACE,OAAO,WAAW,OAAO,YACzB,OAAO,WAAW,QAAQ;AAE1B,mBAAO,EAAE,IAAI,WAAW,IAAI,KAAK,WAAW,IAAI;AAClD,gBAAM,SAAS,MAAM,mBAAmB;AAAA,YACtC,aAAa,QAAQ,YAAY;AAAA,YACjC,OAAO,QAAQ;AAAA,YACf,QAAQ,QAAQ;AAAA,YAChB,YAAY,OAAO;AAAA,UACrB,CAAC,EAAE,WAAW,KAAyC;AACvD,gBAAM,QAAQ,eAAe,MAAM;AACnC,iBAAO;AAAA,QACT;AAAA,QACA,MAAM,UAAU,QAAQ,SAAS;AAC/B,gBAAM,aACJ,QAAQ,cACR,OAAO,QAAQ,eAAe,YAC9B,CAAC,MAAM,QAAQ,QAAQ,UAAU,IAC7B,QAAQ,aACR,CAAC;AACP,cAAI,CAAC,OAAO,WAAW,EAAE,EAAG,QAAO,EAAE,UAAU,MAAM;AACrD,gBAAM,SAAS;AAAA,YACb,MAAM,cAAc,UAAU,WAAW,EAAE,IAAI;AAAA,cAC7C,aAAa,QAAQ,YAAY;AAAA,cACjC,OAAO,QAAQ;AAAA,cACf,QAAQ,QAAQ;AAAA,cAChB,YAAY,OAAO;AAAA,YACrB,CAAC;AAAA,UACH;AACA,cAAI,OAAO,OAAO,WAAW;AAC3B,kBAAM,IAAI,iBAAiB,kBAAkB;AAC/C,iBAAO,EAAE,UAAU,MAAM,OAAO;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;ACjZO,IAAM,0BACX;AAEF,SAAS,aAAa,OAAwB;AAC5C,MACE,CAAC,OAAO,cAAc,KAAK,KAC1B,OAAO,KAAK,MAAM,MAAM,OAAO,KAAK,KAAK;AAE1C,UAAM,IAAI,iBAAiB,eAAe;AAC5C,SAAO;AACT;AACO,SAAS,+BACd,OAC6B;AAC7B,QAAM,QAAQ,YAAY,OAAO;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,SAAsC,EAAE,KAAK,OAAO,MAAM,GAAG,EAAE;AACrE,MAAI,MAAM,iBAAiB;AACzB,WAAO,eAAe,aAAa,MAAM,YAAY;AACvD,MAAI,MAAM,UAAU;AAClB,WAAO,QAAQ,UAAU,MAAM,OAAO,KAAQ,KAAK;AACrD,MAAI,MAAM,SAAS;AACjB,WAAO,OAAO,UAAU,MAAM,MAAM,KAAS,KAAK;AACpD,MAAI,MAAM,YAAY;AACpB,WAAO,UAAU,UAAU,MAAM,SAAS,KAAQ,KAAK;AACzD,MAAI,MAAM,SAAS,QAAW;AAC5B,QACE,CAAC,MAAM,QAAQ,MAAM,IAAI,KACzB,MAAM,KAAK,SAAS,OACpB,MAAM,KAAK;AAAA,MACT,CAAC,QAAQ,OAAO,QAAQ,YAAY,CAAC,IAAI,KAAK,KAAK,IAAI,SAAS;AAAA,IAClE;AAEA,YAAM,IAAI,iBAAiB,eAAe;AAC5C,WAAO,OAAO,CAAC,GAAG,IAAI,IAAI,MAAM,IAAgB,CAAC;AAAA,EACnD;AACA,MAAI,MAAM,aAAa,QAAW;AAChC,UAAM,WAAW,aAAa,MAAM,QAAQ;AAC5C,QAAI,CAAC,YAAY,MAAM,QAAQ,QAAQ,KAAK,OAAO,aAAa;AAC9D,YAAM,IAAI,iBAAiB,eAAe;AAC5C,WAAO,WAAW;AAAA,EACpB;AACA,SAAO;AACT;AACA,SAAS,eACP,OACA,OACmD;AACnD,MAAI;AACF,UAAM,WAAW,OAAO,KAAK;AAC7B,QAAI,SAAS,WAAW,KAAM,OAAM,IAAI,MAAM;AAC9C,UAAM,OAAO,OAAO,SAAS,IAAI;AACjC,QAAI,CAAC,OAAO,cAAc,KAAK,GAAG,KAAK,OAAO,KAAK,GAAG,KAAK;AACzD,YAAM,IAAI,MAAM;AAClB,UAAM,cAAc,aAAa,OAAO,KAAK,UAAU,EAAE,GAAG;AAC5D,UAAM,OAAO,KAAK,KAAK,MAAM,GAAM;AACnC,QACE,UACC,IAAI,IAAI,IAAI,EAAE,SAAS,MAAM,IAAI,IAAI,MAAM,GAAG,EAAE,SAAS,KACxD,iBAAiB,MAAM,gBAAgB;AAEzC,YAAM,IAAI,MAAM;AAClB,WAAO;AAAA,MACL,IAAI,OAAO,KAAK,GAAG;AAAA,MACnB,cAAc;AAAA,MACd,KAAK,8BAA8B,WAAW,SAAS,KAAK,GAAG;AAAA,IACjE;AAAA,EACF,QAAQ;AACN,UAAM,IAAI,iBAAiB,oBAAoB,iBAAiB;AAAA,EAClE;AACF;AACO,SAAS,qBAAqB,QAA8B;AACjE,MAAI,CAAC,OAAO;AACV,UAAM,IAAI,iBAAiB,iBAAiB,iBAAiB;AAC/D,QAAM,UAAU,CACd,MACA,UAGI,CAAC,MACF,gBAAgB,MAAM,EAAE,GAAG,QAAQ,GAAG,QAAQ,CAAC;AACpD,iBAAe,gBACb,QAAgE,CAAC,GAC1C;AACvB,QAAI,MAAM,WAAW,OAAW,OAAM,IAAI,iBAAiB,eAAe;AAC1E,QAAI,MAAM,UAAU,OAAW,WAAU,MAAM,OAAO,KAAM,KAAK;AACjE,QAAI,MAAM,aAAa,UAAa,CAAC,gBAAgB,KAAK,MAAM,QAAQ;AACtE,YAAM,IAAI,iBAAiB,eAAe;AAC5C,UAAM,QAAQ,MAAM,QAAQ,IAAI;AAAA,MAC9B,QAAQ,cAAc;AAAA,MACtB,QAAQ,wBAAwB;AAAA,IAClC,CAAC;AACD,UAAM,YAAY,oBAAI,IAAsB;AAC5C,cAAU,IAAI,MAAM,EAAE,IAAI,MAAM,MAAM,cAAc,MAAM,WAAW,CAAC;AACtE,eAAW,SAAS,OAAO;AACzB,YAAM,WAAW,OAAO,KAAK;AAC7B,UACE,SAAS,WAAW,QACpB,CAAC,MAAM,QAAQ,SAAS,KAAK,KAC7B,SAAS,MAAM,SAAS;AAExB,cAAM,IAAI,iBAAiB,kBAAkB;AAC/C,iBAAWC,UAAS,SAAS,OAAO;AAClC,cAAM,OAAO,OAAOA,MAAK;AACzB,YAAI,CAAC,OAAO,cAAc,KAAK,GAAG,KAAK,OAAO,KAAK,GAAG,KAAK;AACzD,gBAAM,IAAI,iBAAiB,kBAAkB;AAC/C,cAAM,QAAQ,OAAO,KAAK,MAAM,EAAE;AAClC,YAAI,CAAC,OAAO,UAAU,KAAK,KAAK,OAAO,KAAK,IAAI,KAAK,OAAO,KAAK,IAAI;AACnE,gBAAM,IAAI,iBAAiB,kBAAkB;AAC/C,YAAI,OAAO,KAAK,IAAI,EAAG;AACvB,YAAI;AACJ,YAAI,KAAK,WAAW,UAAa,KAAK,WAAW,MAAM;AACrD,gBAAM,SAAS,OAAO,KAAK,MAAM;AACjC,gBAAM,KAAK,OAAO,OAAO,OAAO;AAChC,cAAI,CAAC,OAAO,cAAc,EAAE,KAAK,OAAO,EAAE,KAAK;AAC7C,kBAAM,IAAI,iBAAiB,kBAAkB;AAC/C,qBAAW,OAAO,EAAE;AAAA,QACtB;AACA,kBAAU,IAAI,OAAO,KAAK,GAAG,GAAG;AAAA,UAC9B,IAAI,OAAO,KAAK,GAAG;AAAA,UACnB,MAAM;AAAA,UACN,MAAM,KAAK,KAAK,KAAK;AAAA,UACrB,UAAU;AAAA,YACR,aAAa,OAAO,KAAK;AAAA,YACzB,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,UACjC;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AACA,WAAO;AAAA,MACL,OAAO,CAAC,GAAG,UAAU,OAAO,CAAC,EAAE;AAAA,QAC7B,CAAC,UACE,CAAC,MAAM,YAAY,KAAK,UAAU,aAAa,MAAM,cACrD,CAAC,MAAM,SACN,KAAK,KACF,kBAAkB,EAClB,SAAS,MAAM,MAAM,kBAAkB,CAAC;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AACA,iBAAe,eAAe,OAAoC;AAChE,UAAM,QAAQ,+BAA+B,KAAK;AAClD,UAAM,KAAK,MAAM,gBAAgB;AACjC,QAAI,OAAO,IAAI;AACb,YAAM,WAAW,OAAO,MAAM,QAAQ,eAAe,EAAE,EAAE,CAAC;AAC1D,YAAM,OAAO,OAAO,SAAS,IAAI;AACjC,UAAI,SAAS,WAAW,QAAQ,KAAK,QAAQ;AAC3C,cAAM,IAAI,iBAAiB,kBAAkB;AAC/C,YAAM,QAAQ,OAAO,KAAK,MAAM,EAAE;AAClC,UAAI,UAAU,KAAK,UAAU;AAC3B,cAAM,IAAI,iBAAiB,qBAAqB;AAAA,IACpD;AACA,UAAM,UAAgB;AAAA,MACpB,MAAM,MAAM;AAAA,MACZ,YAAY,EAAE,KAAK,GAAG;AAAA,MACtB,GAAI,MAAM,UAAU,SAAY,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,MAC1D,GAAI,MAAM,SAAS,SAAY,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,MACvD,GAAI,MAAM,YAAY,SAAY,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC;AAAA,MAChE,GAAI,MAAM,OAAO,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,IAC3C;AACA,WAAO,eAAe,MAAM,QAAQ,aAAa,EAAE,MAAM,QAAQ,CAAC,GAAG,KAAK;AAAA,EAC5E;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,EACF;AACF;AAEA,SAASC,kBACP,OACA,UACoB;AACpB,MAAI;AACF,UAAM,WAAW,OAAO,KAAK;AAC7B,UAAM,cAAc,KAAK,SAAS,cAAc,IAAI;AACpD,UAAM,eAAe,KAAK,SAAS,eAAe,IAAI;AACtD,UAAM,UAAU,SAAS;AACzB,QACE,OAAO,SAAS,eAAe,YAC/B,SAAS,WAAW,YAAY,MAAM,YACtC,OAAO,YAAY,YACnB,CAAC,OAAO,UAAU,OAAO,KACzB,WAAW,KACX,UAAU;AAEV,YAAM,IAAI,MAAM;AAClB,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,WAAW,KAAK,IAAI,IAAI,UAAU;AAAA,MAClC,GAAI,UAAU,QAAQ,EAAE,OAAO,SAAS,MAAM,IAAI,CAAC;AAAA,IACrD;AAAA,EACF,QAAQ;AACN,UAAM,IAAI,iBAAiB,oBAAoB,iBAAiB;AAAA,EAClE;AACF;AACO,SAAS,uBACd,QACqB;AACrB,MACE,CAAC,OAAO,kBACR,CAAC,OAAO,YACR,CAAC,OAAO,gBACR,CAAC,OAAO;AAER,UAAM,IAAI,iBAAiB,gCAAgC;AAC7D,QAAM,eAAe,CACnB,MACA,SACA,WAEA,gBAAgB,0BAA0B;AAAA,IACxC,MAAM;AAAA,MACJ,WAAW,OAAO;AAAA,MAClB,eAAe,OAAO;AAAA,MACtB,GAAI;AAAA,IACN;AAAA,IACA,OAAO;AAAA,IACP,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,EAC7B,CAAC;AACH,SAAO;AAAA,IACL,KAAK;AAAA,IACL,gBAAgB,OAAO;AAAA,IACvB,UAAU,CAAC,SAAS;AAAA,IACpB,eAAe;AAAA,MACb,IAAI,OAAO;AACT,YAAI,MAAM,YAAY;AACpB,gBAAM,IAAI,iBAAiB,qBAAqB;AAClD,cAAM,MAAM,IAAI,IAAI,qCAAqC;AACzD,YAAI,SAAS,IAAI,gBAAgB;AAAA,UAC/B,WAAW,OAAO;AAAA,UAClB,cAAc,OAAO;AAAA,UACrB,eAAe;AAAA,UACf,OAAO,MAAM;AAAA,QACf,CAAC,EAAE,SAAS;AACZ,eAAO,IAAI,SAAS;AAAA,MACtB;AAAA,MACA,MAAM,SAAS,OAAO,SAAS;AAC7B,YAAI,MAAM,YAAY;AACpB,gBAAM,IAAI,iBAAiB,qBAAqB;AAClD,cAAM,cAAcA;AAAA,UAClB,MAAM;AAAA,YACJ;AAAA,cACE,YAAY;AAAA,cACZ,MAAM,MAAM;AAAA,cACZ,cAAc,OAAO;AAAA,YACvB;AAAA,YACA;AAAA,YACA,MAAM;AAAA,UACR;AAAA,QACF;AACA,cAAM,WAAW;AAAA,UACf,MAAM,gBAAgB,SAAS;AAAA,YAC7B,aAAa,YAAY;AAAA,YACzB,OAAO;AAAA,YACP,QAAQ,MAAM;AAAA,UAChB,CAAC;AAAA,QACH;AACA,cAAM,OAAO,OAAO,SAAS,IAAI;AACjC,YACE,SAAS,WAAW,QACpB,CAAC,OAAO,cAAc,KAAK,GAAG,KAC9B,OAAO,KAAK,GAAG,KAAK;AAEpB,gBAAM,IAAI,iBAAiB,kBAAkB;AAC/C,cAAM,KAAK,OAAO,KAAK,GAAG;AAC1B,eAAO;AAAA,UACL;AAAA,UACA,SAAS;AAAA,YACP;AAAA,YACA,OAAO,aAAa,KAAK,QAAQ,KAAK,YAAY,EAAE;AAAA,UACtD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,UAAU,OAAO,SAAS;AACxB,aAAO,qBAAqB;AAAA,QAC1B,aAAa,QAAQ,YAAY;AAAA,QACjC,OAAO,QAAQ;AAAA,QACf,QAAQ,QAAQ;AAAA,MAClB,CAAC,EAAE,gBAAgB,KAAK;AAAA,IAC1B;AAAA,IACA,MAAM,QAAQ,aAAa,SAAS;AAClC,UAAI,CAAC,YAAY;AACf,cAAM,IAAI,iBAAiB,iBAAiB,iBAAiB;AAC/D,aAAOA;AAAA,QACL,MAAM;AAAA,UACJ;AAAA,YACE,YAAY;AAAA,YACZ,eAAe,YAAY;AAAA,UAC7B;AAAA,UACA,QAAQ;AAAA,UACR,QAAQ;AAAA,QACV;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA;AAAA,IAEA,SAAS;AAAA,MACP,iBAAiB;AAAA,QACf,SAAS,OAAO;AACd,iBAAO,+BAA+B,KAAK;AAAA,QAC7C;AAAA,QACA,MAAM,QAAQ,OAAO,SAAS;AAC5B,gBAAM,aACJ,QAAQ,cACR,OAAO,QAAQ,eAAe,YAC9B,CAAC,MAAM,QAAQ,QAAQ,UAAU,IAC7B,QAAQ,aACR,CAAC;AACP,cACE,OAAO,WAAW,OAAO,YACzB,OAAO,WAAW,QAAQ,YAC1B,OAAO,WAAW,iBAAiB;AAEnC,mBAAO;AAAA,cACL,IAAI,WAAW;AAAA,cACf,KAAK,WAAW;AAAA,cAChB,cAAc,WAAW;AAAA,YAC3B;AACF,gBAAM,SAAS,MAAM,qBAAqB;AAAA,YACxC,aAAa,QAAQ,YAAY;AAAA,YACjC,OAAO,QAAQ;AAAA,YACf,QAAQ,QAAQ;AAAA,UAClB,CAAC,EAAE,eAAe,KAA+C;AACjE,gBAAM,QAAQ,eAAe,MAAM;AACnC,iBAAO;AAAA,QACT;AAAA,QACA,MAAM,UAAU,OAAO,SAAS;AAC9B,gBAAM,aACJ,QAAQ,cACR,OAAO,QAAQ,eAAe,YAC9B,CAAC,MAAM,QAAQ,QAAQ,UAAU,IAC7B,QAAQ,aACR,CAAC;AACP,cACE,OAAO,WAAW,OAAO,YACzB,CAAC,gBAAgB,KAAK,WAAW,EAAE;AAEnC,mBAAO,EAAE,UAAU,MAAM;AAC3B,gBAAM,SAAS;AAAA,YACb,MAAM,gBAAgB,aAAa,WAAW,EAAE,IAAI;AAAA,cAClD,aAAa,QAAQ,YAAY;AAAA,cACjC,OAAO,QAAQ;AAAA,cACf,QAAQ,QAAQ;AAAA,YAClB,CAAC;AAAA,YACD,+BAA+B,KAAK;AAAA,UACtC;AACA,cAAI,OAAO,OAAO,WAAW;AAC3B,kBAAM,IAAI,iBAAiB,kBAAkB;AAC/C,iBAAO,EAAE,UAAU,MAAM,OAAO;AAAA,QAClC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":["keys","uuid","value","tokenCredentials"]}
|
package/dist/providers/index.js
CHANGED
|
@@ -793,7 +793,7 @@ function tokenCredentials(value, previous) {
|
|
|
793
793
|
try {
|
|
794
794
|
const response = record(value);
|
|
795
795
|
const accessToken = text(response.access_token, 8192);
|
|
796
|
-
const refreshToken = text(response.refresh_token, 8192);
|
|
796
|
+
const refreshToken = response.refresh_token === null ? void 0 : text(response.refresh_token, 8192);
|
|
797
797
|
if (typeof response.token_type !== "string" || response.token_type.toLowerCase() !== "bearer")
|
|
798
798
|
throw new Error();
|
|
799
799
|
const expires = response.expires_in;
|
|
@@ -801,7 +801,7 @@ function tokenCredentials(value, previous) {
|
|
|
801
801
|
throw new Error();
|
|
802
802
|
return {
|
|
803
803
|
accessToken,
|
|
804
|
-
refreshToken,
|
|
804
|
+
...refreshToken !== void 0 ? { refreshToken } : {},
|
|
805
805
|
...expires !== void 0 ? { expiresAt: Date.now() + Number(expires) * 1e3 } : {},
|
|
806
806
|
...previous?.scopes ? { scopes: previous.scopes } : {},
|
|
807
807
|
...previous?.extra ? { extra: previous.extra } : {}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/providers/identity.ts","../../src/errors.ts","../../src/providers/http.ts","../../src/providers/notion.ts","../../src/providers/raindrop.ts"],"sourcesContent":["import {\n createLocalJWKSet,\n importPKCS8,\n jwtVerify,\n SignJWT,\n type JSONWebKeySet,\n type JWTPayload,\n} from \"jose\";\nimport { timingSafeEqual } from \"node:crypto\";\nimport { IntegrationError } from \"../errors.js\";\nimport type {\n AuthorizationInput,\n IntegrationProvider,\n VerifiedIdentity,\n} from \"../types.js\";\nimport { optionalText, record, requestJson, text } from \"./http.js\";\n\nexport type IdentityProviderConfig = {\n registrationId: string;\n identityNamespace?: string;\n clientId: string;\n redirectUri: string;\n};\nexport type GoogleProviderConfig = IdentityProviderConfig & {\n clientSecret?: string;\n nativeClientIds?: readonly string[];\n};\nexport type AppleProviderConfig = IdentityProviderConfig & {\n teamId?: string;\n keyId?: string;\n privateKey?: string;\n nativeClientIds?: readonly string[];\n};\nexport type GitHubProviderConfig = IdentityProviderConfig & {\n clientSecret: string;\n};\n\nfunction configure(config: IdentityProviderConfig): void {\n if (\n !config.registrationId ||\n !config.clientId ||\n !config.redirectUri ||\n config.identityNamespace === \"\"\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n let url: URL;\n try {\n url = new URL(config.redirectUri);\n } catch {\n throw new IntegrationError(\"invalid_provider_configuration\");\n }\n if (\n url.username ||\n url.password ||\n url.hash ||\n (url.protocol !== \"https:\" &&\n !(\n url.protocol === \"http:\" &&\n [\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(url.hostname)\n ))\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n}\nfunction identityPurpose(purpose: string): void {\n if (purpose !== \"identity\") throw new IntegrationError(\"unsupported_purpose\");\n}\nfunction authorizationURL(\n base: string,\n parameters: Record<string, string>,\n): string {\n const url = new URL(base);\n for (const [key, value] of Object.entries(parameters))\n url.searchParams.set(key, value);\n return url.toString();\n}\nconst keyCaches = new WeakMap<\n typeof globalThis.fetch,\n Map<\n string,\n {\n expires: number;\n refreshedAt: number;\n resolve: ReturnType<typeof createLocalJWKSet>;\n }\n >\n>();\nconst keyLoads = new WeakMap<\n typeof globalThis.fetch,\n Map<string, Promise<ReturnType<typeof createLocalJWKSet>>>\n>();\nasync function keys(\n url: string,\n fetcher: typeof globalThis.fetch,\n force = false,\n) {\n let cache = keyCaches.get(fetcher);\n if (!cache) {\n cache = new Map();\n keyCaches.set(fetcher, cache);\n }\n const existing = cache.get(url);\n if (!force && existing && existing.expires > Date.now())\n return existing.resolve;\n // An untrusted kid cannot force unlimited requests to the vendor's key endpoint.\n if (force && existing && existing.refreshedAt + 30_000 > Date.now())\n return existing.resolve;\n let loads = keyLoads.get(fetcher);\n if (!loads) {\n loads = new Map();\n keyLoads.set(fetcher, loads);\n }\n const pending = loads.get(url);\n if (pending) return pending;\n const load = (async () => {\n try {\n const value = record(await requestJson(url, {}, fetcher));\n if (!Array.isArray(value.keys) || value.keys.length > 100)\n throw new Error();\n const resolve = createLocalJWKSet(value as unknown as JSONWebKeySet);\n const now = Date.now();\n cache!.set(url, { expires: now + 300_000, refreshedAt: now, resolve });\n return resolve;\n } catch {\n throw new IntegrationError(\"identity_unavailable\", \"retryable\");\n }\n })();\n loads.set(url, load);\n try {\n return await load;\n } finally {\n loads.delete(url);\n }\n}\nasync function verifyToken(\n input: { idToken: string; nonce: string },\n config: IdentityProviderConfig,\n fetcher: typeof globalThis.fetch,\n options: { provider: \"google\" | \"apple\"; audiences: readonly string[] },\n): Promise<VerifiedIdentity> {\n if (\n !input.nonce ||\n input.nonce.length > 1024 ||\n !input.idToken ||\n input.idToken.length > 32_768 ||\n !options.audiences.length ||\n options.audiences.some((item) => !item)\n )\n throw new IntegrationError(\"invalid_identity\");\n const google = options.provider === \"google\";\n const issuer = google\n ? \"https://accounts.google.com\"\n : \"https://appleid.apple.com\";\n const jwks = google\n ? \"https://www.googleapis.com/oauth2/v3/certs\"\n : \"https://appleid.apple.com/auth/keys\";\n const verificationOptions = {\n algorithms: [\"RS256\"],\n issuer: google ? [issuer, \"accounts.google.com\"] : issuer,\n audience: [...options.audiences],\n requiredClaims: [\"sub\", \"exp\", \"iat\", \"nonce\"],\n clockTolerance: 30,\n };\n let payload: JWTPayload;\n try {\n let resolve = await keys(jwks, fetcher);\n try {\n ({ payload } = await jwtVerify(\n input.idToken,\n resolve,\n verificationOptions,\n ));\n } catch (error) {\n if (!(\n error &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ERR_JWKS_NO_MATCHING_KEY\"\n ))\n throw error;\n resolve = await keys(jwks, fetcher, true);\n ({ payload } = await jwtVerify(\n input.idToken,\n resolve,\n verificationOptions,\n ));\n }\n const expected = Buffer.from(input.nonce);\n const actual = Buffer.from(\n typeof payload.nonce === \"string\" ? payload.nonce : \"\",\n );\n if (\n expected.length !== actual.length ||\n !timingSafeEqual(expected, actual) ||\n typeof payload.iat !== \"number\" ||\n payload.iat > Date.now() / 1000 + 30 ||\n typeof payload.sub !== \"string\" ||\n !payload.sub ||\n payload.sub.length > 255\n )\n throw new Error();\n // A multi-audience assertion must identify one of this registration's clients.\n if (\n Array.isArray(payload.aud) &&\n payload.aud.length > 1 &&\n (typeof payload.azp !== \"string\" ||\n !options.audiences.includes(payload.azp))\n )\n throw new Error();\n } catch (error) {\n if (\n error instanceof IntegrationError &&\n (error.disposition === \"retryable\" ||\n error.disposition === \"outcome_unknown\")\n )\n throw new IntegrationError(\"identity_unavailable\", \"retryable\");\n throw new IntegrationError(\"invalid_identity\");\n }\n const email = optionalText(payload.email, 320);\n const name = optionalText(payload.name, 1024);\n return {\n provider: options.provider,\n issuer,\n subject: payload.sub!,\n identityNamespace: config.identityNamespace ?? config.registrationId,\n emailVerified:\n payload.email_verified === true ||\n (options.provider === \"apple\" && payload.email_verified === \"true\"),\n ...(email ? { email } : {}),\n ...(name ? { name } : {}),\n };\n}\n\nexport function createGoogleProvider(\n config: GoogleProviderConfig,\n): IntegrationProvider {\n configure(config);\n return {\n key: \"google\",\n registrationId: config.registrationId,\n purposes: [\"identity\"],\n authorization: {\n url(input: AuthorizationInput) {\n identityPurpose(input.purpose);\n return authorizationURL(\n \"https://accounts.google.com/o/oauth2/v2/auth\",\n {\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n scope: \"openid email profile\",\n state: input.state,\n nonce: input.nonce,\n code_challenge: input.challenge,\n code_challenge_method: \"S256\",\n },\n );\n },\n async exchange(input, fetcher) {\n identityPurpose(input.purpose);\n if (!config.clientSecret)\n throw new IntegrationError(\"application_unavailable\");\n const tokens = record(\n await requestJson(\n \"https://oauth2.googleapis.com/token\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n redirect_uri: config.redirectUri,\n grant_type: \"authorization_code\",\n code: input.code,\n code_verifier: input.verifier,\n }),\n ...(input.signal ? { signal: input.signal } : {}),\n },\n fetcher,\n ),\n );\n const identity = await verifyToken(\n { idToken: text(tokens.id_token, 32_768), nonce: input.nonce },\n config,\n fetcher,\n { provider: \"google\", audiences: [config.clientId] },\n );\n return { identity }; // Login never exposes or persists OAuth provider tokens.\n },\n },\n verifyNative(input, fetcher) {\n return verifyToken(input, config, fetcher, {\n provider: \"google\",\n audiences: config.nativeClientIds ?? [config.clientId],\n });\n },\n };\n}\n\nexport function createAppleProvider(\n config: AppleProviderConfig,\n): IntegrationProvider {\n configure(config);\n async function clientSecret(): Promise<string> {\n if (!config.teamId || !config.keyId || !config.privateKey)\n throw new IntegrationError(\"application_unavailable\");\n try {\n const key = await importPKCS8(config.privateKey, \"ES256\");\n return await new SignJWT({})\n .setProtectedHeader({ alg: \"ES256\", kid: config.keyId })\n .setIssuer(config.teamId)\n .setSubject(config.clientId)\n .setAudience(\"https://appleid.apple.com\")\n .setIssuedAt()\n .setExpirationTime(\"5m\")\n .sign(key);\n } catch {\n throw new IntegrationError(\"application_unavailable\");\n }\n }\n return {\n key: \"apple\",\n registrationId: config.registrationId,\n purposes: [\"identity\"],\n authorization: {\n url(input) {\n identityPurpose(input.purpose);\n return authorizationURL(\"https://appleid.apple.com/auth/authorize\", {\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n response_mode: \"form_post\",\n scope: \"name email\",\n state: input.state,\n nonce: input.nonce,\n });\n },\n async exchange(input, fetcher) {\n identityPurpose(input.purpose);\n const result = record(\n await requestJson(\n \"https://appleid.apple.com/auth/token\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: await clientSecret(),\n redirect_uri: config.redirectUri,\n grant_type: \"authorization_code\",\n code: input.code,\n }),\n ...(input.signal ? { signal: input.signal } : {}),\n },\n fetcher,\n ),\n );\n return {\n identity: await verifyToken(\n { idToken: text(result.id_token, 32_768), nonce: input.nonce },\n config,\n fetcher,\n { provider: \"apple\", audiences: [config.clientId] },\n ),\n };\n },\n },\n // nonce is the actual expected token nonce; a native host using SHA256 supplies that hash.\n verifyNative(input, fetcher) {\n return verifyToken(input, config, fetcher, {\n provider: \"apple\",\n audiences: config.nativeClientIds ?? [config.clientId],\n });\n },\n };\n}\n\nexport function createGitHubProvider(\n config: GitHubProviderConfig,\n): IntegrationProvider {\n configure(config);\n if (!config.clientSecret)\n throw new IntegrationError(\"invalid_provider_configuration\");\n return {\n key: \"github\",\n registrationId: config.registrationId,\n purposes: [\"identity\"],\n authorization: {\n url(input) {\n identityPurpose(input.purpose);\n return authorizationURL(\"https://github.com/login/oauth/authorize\", {\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n scope: \"read:user user:email\",\n state: input.state,\n code_challenge: input.challenge,\n code_challenge_method: \"S256\",\n });\n },\n async exchange(input, fetcher) {\n identityPurpose(input.purpose);\n const tokens = record(\n await requestJson(\n \"https://github.com/login/oauth/access_token\",\n {\n method: \"POST\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n redirect_uri: config.redirectUri,\n code: input.code,\n code_verifier: input.verifier,\n }),\n ...(input.signal ? { signal: input.signal } : {}),\n },\n fetcher,\n ),\n );\n const accessToken = text(tokens.access_token);\n const headers = {\n Accept: \"application/vnd.github+json\",\n Authorization: `Bearer ${accessToken}`,\n \"X-GitHub-Api-Version\": \"2026-03-10\",\n \"User-Agent\": \"mycreat-labs-integrations-sdk\",\n };\n const user = record(\n await requestJson(\n \"https://api.github.com/user\",\n { headers, ...(input.signal ? { signal: input.signal } : {}) },\n fetcher,\n ),\n );\n if (!Number.isSafeInteger(user.id) || Number(user.id) <= 0)\n throw new IntegrationError(\"invalid_identity\");\n const emails = await requestJson(\n \"https://api.github.com/user/emails?per_page=100\",\n { headers, ...(input.signal ? { signal: input.signal } : {}) },\n fetcher,\n );\n if (!Array.isArray(emails) || emails.length > 100)\n throw new IntegrationError(\"invalid_identity\");\n const primary = emails.find(\n (item) =>\n item &&\n typeof item === \"object\" &&\n item.primary === true &&\n item.verified === true,\n ) as { email?: unknown } | undefined;\n const email = primary ? text(primary.email, 320) : undefined;\n const name = optionalText(user.name, 1024);\n const username = text(user.login, 255);\n return {\n identity: {\n provider: \"github\",\n issuer: \"https://github.com\",\n subject: String(user.id),\n identityNamespace:\n config.identityNamespace ?? config.registrationId,\n emailVerified: Boolean(email),\n username,\n ...(email ? { email } : {}),\n ...(name ? { name } : {}),\n },\n };\n },\n },\n };\n}\n","export type FailureDisposition =\n \"retryable\" | \"requires_reauth\" | \"outcome_unknown\" | \"permanent_failure\";\nexport class IntegrationError extends Error {\n readonly sdkError = \"@mycreat-labs/integrations-sdk/v1\";\n constructor(\n readonly code: string,\n readonly disposition: FailureDisposition = \"permanent_failure\",\n readonly retryAfterMs?: number,\n ) {\n super(code);\n this.name = \"IntegrationError\";\n }\n}\nexport function integrationError(error: unknown): IntegrationError {\n if (error instanceof IntegrationError) return error;\n // Bundled subpath entries and independently installed copies have separate class identities.\n if (\n error instanceof Error &&\n \"sdkError\" in error &&\n error.sdkError === \"@mycreat-labs/integrations-sdk/v1\" &&\n \"code\" in error &&\n typeof error.code === \"string\" &&\n /^[a-zA-Z0-9_]{1,100}$/.test(error.code) &&\n \"disposition\" in error &&\n [\n \"retryable\",\n \"requires_reauth\",\n \"outcome_unknown\",\n \"permanent_failure\",\n ].includes(String(error.disposition))\n ) {\n const delay =\n \"retryAfterMs\" in error &&\n typeof error.retryAfterMs === \"number\" &&\n Number.isFinite(error.retryAfterMs) &&\n error.retryAfterMs >= 0\n ? error.retryAfterMs\n : undefined;\n return new IntegrationError(\n error.code,\n error.disposition as FailureDisposition,\n delay,\n );\n }\n return new IntegrationError(\"provider_unavailable\", \"outcome_unknown\");\n}\n","import { IntegrationError, type FailureDisposition } from \"../errors.js\";\nimport type { Json } from \"../types.js\";\n\nexport type ProviderRequestOptions = {\n accessToken?: string;\n clientId?: string;\n clientSecret?: string;\n method?: string;\n body?: unknown;\n signal?: AbortSignal;\n fetch?: typeof globalThis.fetch;\n apiVersion?: string;\n};\n\n/** Contains only safe classifications and validated receipt IDs, never upstream messages. */\nexport class ProviderHttpError extends IntegrationError {\n readonly status: number | null;\n readonly providerCode?: string;\n readonly definite: boolean;\n readonly committedResourceId?: string;\n readonly committedChildIds?: string[];\n constructor(\n code: string,\n disposition: FailureDisposition,\n options: {\n status?: number;\n providerCode?: string;\n definite?: boolean;\n retryAfterMs?: number;\n committedResourceId?: string;\n committedChildIds?: string[];\n } = {},\n ) {\n super(code, disposition, options.retryAfterMs);\n this.name = \"ProviderHttpError\";\n this.status = options.status ?? null;\n this.providerCode = options.providerCode;\n this.definite = options.definite ?? false;\n this.committedResourceId = options.committedResourceId;\n this.committedChildIds = options.committedChildIds;\n }\n}\n\nexport function record(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n throw new IntegrationError(\"invalid_response\");\n return value as Record<string, unknown>;\n}\nexport function text(value: unknown, max = 4096): string {\n if (typeof value !== \"string\" || value.length === 0 || value.length > max)\n throw new IntegrationError(\"invalid_response\");\n return value;\n}\nexport function optionalText(value: unknown, max = 4096): string | undefined {\n return value === undefined || value === null ? undefined : text(value, max);\n}\nexport function inputRecord(\n value: unknown,\n keys: readonly string[],\n): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n throw new IntegrationError(\"invalid_input\");\n const input = value as Record<string, unknown>;\n if (Object.keys(input).some((key) => !keys.includes(key)))\n throw new IntegrationError(\"invalid_input\");\n return input;\n}\nexport function inputText(\n value: unknown,\n maximum: number,\n required = true,\n): string | undefined {\n if (value === undefined && !required) return undefined;\n if (\n typeof value !== \"string\" ||\n (required && !value.trim()) ||\n value.length > maximum\n )\n throw new IntegrationError(\"invalid_input\");\n return value;\n}\nexport function webUrl(value: unknown): string {\n const result = inputText(value, 10_000)!;\n try {\n const url = new URL(result);\n if (\n ![\"https:\", \"http:\"].includes(url.protocol) ||\n url.username ||\n url.password\n )\n throw new Error();\n } catch {\n throw new IntegrationError(\"invalid_input\");\n }\n return result;\n}\nexport function jsonMetadata(value: unknown): Json | undefined {\n if (value === undefined) return undefined;\n const visit = (item: unknown, depth: number): boolean =>\n depth <= 10 &&\n (item === null ||\n typeof item === \"string\" ||\n typeof item === \"boolean\" ||\n (typeof item === \"number\" && Number.isFinite(item)) ||\n (Array.isArray(item) && item.every((child) => visit(child, depth + 1))) ||\n (typeof item === \"object\" &&\n item !== null &&\n Object.getPrototypeOf(item) === Object.prototype &&\n Object.values(item).every((child) => visit(child, depth + 1))));\n if (!visit(value, 0) || JSON.stringify(value).length > 16_384)\n throw new IntegrationError(\"invalid_input\");\n return value as Json;\n}\n\nconst safeCodes = new Set([\n \"invalid_client\",\n \"unauthorized_client\",\n \"invalid_grant\",\n \"bad_authorization_code\",\n \"invalid_request\",\n \"invalid_json\",\n \"validation_error\",\n \"restricted_resource\",\n \"unauthorized\",\n \"object_not_found\",\n \"rate_limited\",\n \"conflict_error\",\n \"internal_server_error\",\n \"service_unavailable\",\n \"gateway_timeout\",\n \"service_overload\",\n \"row_limit_exceeded\",\n \"invalid_token\",\n \"bad_verification_code\",\n \"incorrect_client_credentials\",\n \"redirect_uri_mismatch\",\n \"access_denied\",\n]);\nconst uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nexport const isUuid = (value: unknown): value is string =>\n typeof value === \"string\" && uuid.test(value);\nexport function retryDelay(value: string | null): number | undefined {\n if (!value) return undefined;\n const milliseconds = /^\\d+(?:\\.\\d+)?$/.test(value)\n ? Number(value) * 1000\n : Date.parse(value) - Date.now();\n return Number.isFinite(milliseconds)\n ? Math.max(0, Math.min(milliseconds, 86_400_000))\n : undefined;\n}\n\nfunction failure(\n status: number,\n body: unknown,\n write: boolean,\n retryAfterMs?: number,\n): ProviderHttpError {\n const payload =\n body && typeof body === \"object\" && !Array.isArray(body)\n ? (body as Record<string, unknown>)\n : {};\n const vendorCode =\n typeof payload.code === \"string\"\n ? payload.code\n : typeof payload.error === \"string\"\n ? payload.error\n : undefined;\n const providerCode =\n vendorCode && safeCodes.has(vendorCode) ? vendorCode : undefined;\n const extra =\n payload.additional_data && typeof payload.additional_data === \"object\"\n ? (payload.additional_data as Record<string, unknown>)\n : {};\n const committedResourceId = isUuid(extra.committed_resource_id)\n ? extra.committed_resource_id\n : undefined;\n const committedChildIds =\n Array.isArray(extra.committed_child_ids) &&\n extra.committed_child_ids.length <= 100 &&\n extra.committed_child_ids.every(isUuid)\n ? (extra.committed_child_ids as string[])\n : undefined;\n const definite =\n status >= 400 &&\n status < 500 &&\n status !== 408 &&\n !committedResourceId &&\n !committedChildIds?.length;\n let code =\n status === 401\n ? \"auth_required\"\n : status === 404\n ? \"resource_unavailable\"\n : status === 403\n ? \"permission_required\"\n : status === 429 || status === 529\n ? \"rate_limited\"\n : status >= 500\n ? \"upstream_unavailable\"\n : \"invalid_payload\";\n if (\n providerCode === \"invalid_client\" ||\n providerCode === \"unauthorized_client\" ||\n providerCode === \"incorrect_client_credentials\" ||\n payload.errorMessage === \"client_id or client_secret is invalid\"\n )\n code = \"application_unavailable\";\n else if (\n providerCode === \"invalid_grant\" ||\n providerCode === \"bad_authorization_code\" ||\n providerCode === \"invalid_token\" ||\n providerCode === \"bad_verification_code\"\n )\n code = \"auth_required\";\n else if (extra.rate_limit_reason === \"public_api_request_blocked\")\n code = \"access_restricted\";\n else if (status === 403 && providerCode === \"restricted_resource\")\n code = \"resource_unavailable\";\n else if (\n status === 403 &&\n typeof payload.message === \"string\" &&\n /block.*limit|limit.*block/i.test(payload.message)\n )\n code = \"workspace_capacity\";\n const disposition: FailureDisposition =\n code === \"auth_required\"\n ? \"requires_reauth\"\n : write && !definite\n ? \"outcome_unknown\"\n : code === \"rate_limited\" || status >= 500 || status === 408\n ? \"retryable\"\n : \"permanent_failure\";\n return new ProviderHttpError(code, disposition, {\n status,\n providerCode,\n definite,\n retryAfterMs,\n committedResourceId,\n committedChildIds,\n });\n}\n\nexport async function requestJson(\n url: string,\n init: RequestInit,\n fetcher: typeof globalThis.fetch,\n options: { write?: boolean; raindrop?: boolean; requireJson?: boolean } = {},\n): Promise<unknown> {\n const write =\n options.write ?? ![\"GET\", \"HEAD\"].includes(init.method ?? \"GET\");\n const signal = init.signal\n ? AbortSignal.any([init.signal, AbortSignal.timeout(30_000)])\n : AbortSignal.timeout(30_000);\n let response: Response;\n try {\n response = await fetcher(url, { ...init, signal, redirect: \"error\" });\n } catch (error) {\n // An SDK admission limiter rejected the request before any HTTP dispatch.\n if (\n error instanceof Error &&\n \"sdkError\" in error &&\n error.sdkError === \"@mycreat-labs/integrations-sdk/v1\" &&\n \"code\" in error &&\n error.code === \"rate_limited\" &&\n \"definite\" in error &&\n error.definite === true\n ) {\n const delay =\n \"retryAfterMs\" in error &&\n typeof error.retryAfterMs === \"number\" &&\n Number.isFinite(error.retryAfterMs)\n ? Math.max(0, Math.min(error.retryAfterMs, 86_400_000))\n : undefined;\n throw new ProviderHttpError(\"rate_limited\", \"retryable\", {\n status: 429,\n definite: true,\n retryAfterMs: delay,\n });\n }\n throw new ProviderHttpError(\n \"upstream_unavailable\",\n write ? \"outcome_unknown\" : \"retryable\",\n );\n }\n if (response.status === 204 && response.ok) return {};\n let body: unknown;\n try {\n if (\n options.requireJson &&\n !response.headers.get(\"content-type\")?.toLowerCase().includes(\"json\")\n )\n throw new Error();\n if (!response.body) throw new Error();\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n try {\n for (;;) {\n const part = await reader.read();\n if (part.done) break;\n size += part.value.length;\n if (size > 2_097_152) {\n await reader.cancel();\n throw new Error();\n }\n chunks.push(part.value);\n }\n } finally {\n reader.releaseLock();\n }\n body = JSON.parse(Buffer.concat(chunks).toString(\"utf8\")) as unknown;\n } catch {\n if (!response.ok)\n throw failure(\n response.status,\n {},\n write,\n retryDelay(response.headers.get(\"retry-after\")),\n );\n throw new ProviderHttpError(\n \"invalid_response\",\n write ? \"outcome_unknown\" : \"retryable\",\n { status: response.status },\n );\n }\n if (!response.ok)\n throw failure(\n response.status,\n body,\n write,\n retryDelay(response.headers.get(\"retry-after\")),\n );\n if (body && typeof body === \"object\" && !Array.isArray(body)) {\n const value = body as Record<string, unknown>;\n if (\n typeof value.error === \"string\" ||\n (options.raindrop && value.result === false)\n ) {\n const status =\n typeof value.status === \"number\" &&\n Number.isInteger(value.status) &&\n value.status >= 400 &&\n value.status < 600\n ? value.status\n : 400;\n throw failure(\n status,\n body,\n write,\n retryDelay(response.headers.get(\"retry-after\")),\n );\n }\n }\n return body;\n}\n\nfunction providerPath(path: string, prefix: string): string {\n if (\n path.length > 4096 ||\n !/^\\/[a-zA-Z0-9_/-]+(?:\\?[a-zA-Z0-9_%=&.~-]+)?$/.test(path) ||\n path.includes(\"//\") ||\n path.includes(\"..\")\n )\n throw new ProviderHttpError(\"invalid_upstream_path\", \"permanent_failure\", {\n status: 400,\n definite: true,\n });\n return path.startsWith(`${prefix}/`) || path === prefix\n ? path\n : `${prefix}${path}`;\n}\nexport function notionRequest(\n path: string,\n options: ProviderRequestOptions,\n): Promise<unknown> {\n const normalized = providerPath(path, \"/v1\");\n if (!options.accessToken && (!options.clientId || !options.clientSecret))\n throw new ProviderHttpError(\n \"application_unavailable\",\n \"permanent_failure\",\n { definite: true },\n );\n const authorization = options.accessToken\n ? `Bearer ${options.accessToken}`\n : `Basic ${Buffer.from(`${options.clientId}:${options.clientSecret}`).toString(\"base64\")}`;\n return requestJson(\n `https://api.notion.com${normalized}`,\n {\n method: options.method ?? (options.body === undefined ? \"GET\" : \"POST\"),\n headers: {\n \"Notion-Version\": options.apiVersion ?? \"2026-03-11\",\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Authorization: authorization,\n },\n ...(options.body === undefined\n ? {}\n : { body: JSON.stringify(options.body) }),\n ...(options.signal ? { signal: options.signal } : {}),\n },\n options.fetch ?? globalThis.fetch,\n {\n write:\n normalized !== \"/v1/search\" &&\n (options.method ?? (options.body === undefined ? \"GET\" : \"POST\")) !==\n \"GET\",\n },\n );\n}\nexport function raindropRequest(\n path: string,\n options: ProviderRequestOptions,\n): Promise<unknown> {\n const normalized =\n path === \"/v1/oauth/access_token\" ? path : providerPath(path, \"/rest/v1\");\n if (normalized !== \"/v1/oauth/access_token\" && !options.accessToken)\n throw new ProviderHttpError(\"auth_required\", \"requires_reauth\", {\n status: 401,\n definite: true,\n });\n return requestJson(\n `https://api.raindrop.io${normalized}`,\n {\n method: options.method ?? (options.body === undefined ? \"GET\" : \"POST\"),\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...(options.accessToken\n ? { Authorization: `Bearer ${options.accessToken}` }\n : {}),\n },\n ...(options.body === undefined\n ? {}\n : { body: JSON.stringify(options.body) }),\n ...(options.signal ? { signal: options.signal } : {}),\n },\n options.fetch ?? globalThis.fetch,\n { raindrop: true, requireJson: true },\n );\n}\n","import { IntegrationError } from \"../errors.js\";\nimport type {\n CredentialMaterial,\n IntegrationProvider,\n Json,\n Resource,\n ResourcePage,\n} from \"../types.js\";\nimport {\n inputRecord,\n inputText,\n isUuid,\n jsonMetadata,\n notionRequest,\n optionalText,\n record,\n text,\n webUrl,\n type ProviderRequestOptions,\n} from \"./http.js\";\n\nexport const NOTION_API_VERSION = \"2026-03-11\";\nexport type NotionProviderConfig = {\n registrationId: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n apiVersion?: string;\n};\nexport type NotionClientConfig = {\n accessToken: string;\n fetch?: typeof globalThis.fetch;\n signal?: AbortSignal;\n apiVersion?: string;\n};\nexport type NotionCreatePageInput = {\n parentId: string;\n parentType?: \"page\" | \"data_source\";\n title: string;\n content?: string;\n url?: string;\n metadata?: { [key: string]: Json };\n};\n\nfunction uuid(value: unknown): string {\n if (!isUuid(value)) throw new IntegrationError(\"invalid_input\");\n return value;\n}\nconst validCursor = (value: unknown): value is string =>\n typeof value === \"string\" && value.length > 0 && value.length <= 4096;\nexport function validateNotionCreatePage(\n value: unknown,\n): NotionCreatePageInput {\n const input = inputRecord(value, [\n \"parentId\",\n \"parentType\",\n \"title\",\n \"content\",\n \"url\",\n \"metadata\",\n ]);\n const result: NotionCreatePageInput = {\n parentId: uuid(input.parentId),\n title: inputText(input.title, 2000)!,\n };\n if (input.parentType !== undefined) {\n if (input.parentType !== \"page\" && input.parentType !== \"data_source\")\n throw new IntegrationError(\"invalid_input\");\n result.parentType = input.parentType;\n }\n if (input.content !== undefined)\n result.content = inputText(input.content, 100_000, false)!;\n if (input.url !== undefined) result.url = webUrl(input.url);\n if (input.metadata !== undefined) {\n const metadata = jsonMetadata(input.metadata);\n if (!metadata || Array.isArray(metadata) || typeof metadata !== \"object\")\n throw new IntegrationError(\"invalid_input\");\n result.metadata = metadata;\n }\n return result;\n}\nfunction richText(value: string): Json[] {\n const result: Json[] = [];\n for (let index = 0; index < value.length;) {\n let end = Math.min(index + 2000, value.length);\n if (end < value.length && /[\\uD800-\\uDBFF]/.test(value.charAt(end - 1)))\n end--;\n result.push({ type: \"text\", text: { content: value.slice(index, end) } });\n index = end;\n }\n return result;\n}\nfunction resourceTitle(value: unknown): string {\n if (!Array.isArray(value)) throw new IntegrationError(\"invalid_response\");\n return value\n .map((item) => {\n const piece = record(item);\n if (typeof piece.plain_text === \"string\") return piece.plain_text;\n return text(record(piece.text).content, 2000);\n })\n .join(\"\");\n}\nfunction pageResult(value: unknown): { id: string; url: string } {\n try {\n const page = record(value);\n if (page.object !== \"page\" || !isUuid(page.id)) throw new Error();\n const url = text(page.url, 4096);\n if (new URL(url).protocol !== \"https:\") throw new Error();\n return { id: page.id, url };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\n\nexport function createNotionClient(config: NotionClientConfig) {\n if (!config.accessToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n const request = (\n path: string,\n options: Omit<\n ProviderRequestOptions,\n \"accessToken\" | \"clientId\" | \"clientSecret\"\n > = {},\n ) => notionRequest(path, { ...config, ...options });\n async function listResources(\n input: { cursor?: string; query?: string; parentId?: string } = {},\n ): Promise<ResourcePage> {\n if (input.parentId !== undefined)\n throw new IntegrationError(\"unsupported_resource_filter\");\n if (input.cursor !== undefined && !validCursor(input.cursor))\n throw new IntegrationError(\"invalid_input\");\n if (input.query !== undefined) inputText(input.query, 1000, false);\n const response = record(\n await request(\"/search\", {\n body: {\n page_size: 100,\n ...(input.cursor ? { start_cursor: input.cursor } : {}),\n ...(input.query !== undefined ? { query: input.query } : {}),\n },\n }),\n );\n if (\n !Array.isArray(response.results) ||\n response.results.length > 100 ||\n typeof response.has_more !== \"boolean\"\n )\n throw new IntegrationError(\"invalid_response\");\n if (\n response.request_status !== undefined &&\n record(response.request_status).type !== \"complete\"\n )\n throw new IntegrationError(\"resource_listing_incomplete\");\n if (response.has_more && !validCursor(response.next_cursor))\n throw new IntegrationError(\"invalid_response\");\n const items: Resource[] = [];\n for (const item of response.results) {\n const entry = record(item);\n if (\n !isUuid(entry.id) ||\n (entry.object !== \"page\" && entry.object !== \"data_source\")\n )\n throw new IntegrationError(\"invalid_response\");\n if (\n entry.in_trash === true ||\n entry.archived === true ||\n entry.is_archived === true\n )\n continue;\n let name: string;\n if (entry.object === \"data_source\") name = resourceTitle(entry.title);\n else {\n const properties = record(entry.properties);\n const title = Object.values(properties)\n .map(record)\n .find((property) => property.type === \"title\");\n name = title ? resourceTitle(title.title) : \"\";\n }\n const url = optionalText(entry.url);\n items.push({\n id: entry.id,\n type: entry.object,\n name: name || \"Untitled\",\n ...(url ? { url } : {}),\n });\n }\n return {\n items,\n ...(response.has_more\n ? { nextCursor: response.next_cursor as string }\n : {}),\n };\n }\n async function createPage(\n value: NotionCreatePageInput,\n ): Promise<{ id: string; url: string }> {\n const input = validateNotionCreatePage(value);\n const parentType = input.parentType ?? \"page\";\n let titleKey = \"title\";\n if (parentType === \"data_source\") {\n const source = record(await request(`/data_sources/${input.parentId}`));\n if (source.id !== input.parentId || source.object !== \"data_source\")\n throw new IntegrationError(\"invalid_response\");\n const property = Object.entries(record(source.properties)).find(\n ([, definition]) => record(definition).type === \"title\",\n );\n if (!property) throw new IntegrationError(\"invalid_resource\");\n titleKey = property[0];\n }\n const children: Json[] = [];\n if (input.content) {\n for (const part of richText(input.content))\n children.push({\n object: \"block\",\n type: \"paragraph\",\n paragraph: { rich_text: [part] },\n });\n }\n if (input.url)\n children.push({\n object: \"block\",\n type: \"bookmark\",\n bookmark: { url: input.url },\n });\n return pageResult(\n await request(\"/pages\", {\n body: {\n parent:\n parentType === \"page\"\n ? { page_id: input.parentId }\n : { data_source_id: input.parentId },\n properties: {\n [titleKey]: { type: \"title\", title: richText(input.title) },\n },\n ...(children.length ? { children } : {}),\n },\n }),\n );\n }\n return { request, listResources, resources: listResources, createPage };\n}\n\nfunction tokenCredentials(\n value: unknown,\n previous?: CredentialMaterial,\n): CredentialMaterial {\n try {\n const response = record(value);\n const accessToken = text(response.access_token, 8192);\n const refreshToken = text(response.refresh_token, 8192);\n if (\n typeof response.token_type !== \"string\" ||\n response.token_type.toLowerCase() !== \"bearer\"\n )\n throw new Error();\n const expires = response.expires_in;\n if (\n expires !== undefined &&\n (typeof expires !== \"number\" ||\n !Number.isInteger(expires) ||\n expires <= 0 ||\n expires > 31_536_000)\n )\n throw new Error();\n return {\n accessToken,\n refreshToken,\n ...(expires !== undefined\n ? { expiresAt: Date.now() + Number(expires) * 1000 }\n : {}),\n ...(previous?.scopes ? { scopes: previous.scopes } : {}),\n ...(previous?.extra ? { extra: previous.extra } : {}),\n };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\nexport function createNotionProvider(\n config: NotionProviderConfig,\n): IntegrationProvider {\n if (\n !config.registrationId ||\n !config.clientId ||\n !config.clientSecret ||\n !config.redirectUri\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n const tokenRequest = (\n body: Json,\n fetcher: typeof globalThis.fetch,\n signal?: AbortSignal,\n ) =>\n notionRequest(\"/oauth/token\", {\n clientId: config.clientId,\n clientSecret: config.clientSecret,\n apiVersion: config.apiVersion,\n body,\n fetch: fetcher,\n ...(signal ? { signal } : {}),\n });\n return {\n key: \"notion\",\n registrationId: config.registrationId,\n purposes: [\"connect\"],\n authorization: {\n url(input) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const url = new URL(\"https://api.notion.com/v1/oauth/authorize\");\n url.search = new URLSearchParams({\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n owner: \"user\",\n state: input.state,\n }).toString();\n return url.toString();\n },\n async exchange(input, fetcher) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const response = record(\n await tokenRequest(\n {\n grant_type: \"authorization_code\",\n code: input.code,\n redirect_uri: config.redirectUri,\n },\n fetcher,\n input.signal,\n ),\n );\n const credentials = tokenCredentials(response);\n const workspaceId = text(response.workspace_id);\n const botId = text(response.bot_id);\n if (!isUuid(workspaceId) || !isUuid(botId))\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n const owner = record(response.owner);\n if (owner.type !== \"user\")\n throw new IntegrationError(\"invalid_response\");\n const userId = text(record(owner.user).id);\n if (!isUuid(userId)) throw new IntegrationError(\"invalid_response\");\n const label =\n optionalText(response.workspace_name) ?? \"Notion workspace\";\n credentials.extra = { workspaceId, botId, ownerId: userId };\n return {\n credentials,\n account: {\n id: `${workspaceId}:${botId}:${userId}`,\n label,\n metadata: { workspaceId, botId, ownerId: userId },\n },\n };\n },\n },\n resources(input, context) {\n return createNotionClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n apiVersion: config.apiVersion,\n }).listResources(input);\n },\n async refresh(credentials, context) {\n if (!credentials.refreshToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n return tokenCredentials(\n await tokenRequest(\n {\n grant_type: \"refresh_token\",\n refresh_token: credentials.refreshToken,\n },\n context.fetch,\n context.signal,\n ),\n credentials,\n );\n },\n async revoke(credentials, context) {\n await notionRequest(\"/oauth/revoke\", {\n clientId: config.clientId,\n clientSecret: config.clientSecret,\n apiVersion: config.apiVersion,\n body: { token: credentials.accessToken },\n fetch: context.fetch,\n signal: context.signal,\n });\n },\n actions: {\n create_page: {\n validate(value) {\n return validateNotionCreatePage(value) as unknown as Json;\n },\n async execute(value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (\n typeof checkpoint.id === \"string\" &&\n typeof checkpoint.url === \"string\"\n )\n return { id: checkpoint.id, url: checkpoint.url };\n const result = await createNotionClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n apiVersion: config.apiVersion,\n }).createPage(value as unknown as NotionCreatePageInput);\n await context.saveCheckpoint(result);\n return result;\n },\n async reconcile(_value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (!isUuid(checkpoint.id)) return { resolved: false };\n const result = pageResult(\n await notionRequest(`/pages/${checkpoint.id}`, {\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n apiVersion: config.apiVersion,\n }),\n );\n if (result.id !== checkpoint.id)\n throw new IntegrationError(\"invalid_response\");\n return { resolved: true, result };\n },\n },\n },\n };\n}\n","import { IntegrationError } from \"../errors.js\";\nimport type {\n CredentialMaterial,\n IntegrationProvider,\n Json,\n Resource,\n ResourcePage,\n} from \"../types.js\";\nimport {\n inputRecord,\n inputText,\n jsonMetadata,\n optionalText,\n raindropRequest,\n record,\n text,\n webUrl,\n type ProviderRequestOptions,\n} from \"./http.js\";\n\nexport type RaindropProviderConfig = {\n registrationId: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n};\nexport type RaindropClientConfig = {\n accessToken: string;\n fetch?: typeof globalThis.fetch;\n signal?: AbortSignal;\n};\nexport type RaindropCreateBookmarkInput = {\n collectionId?: number;\n url: string;\n title?: string;\n note?: string;\n excerpt?: string;\n tags?: string[];\n metadata?: { [key: string]: Json };\n};\nexport const RAINDROP_TOKEN_ENDPOINT =\n \"https://api.raindrop.io/v1/oauth/access_token\";\n\nfunction collectionId(value: unknown): number {\n if (\n !Number.isSafeInteger(value) ||\n (Number(value) !== -1 && Number(value) <= 0)\n )\n throw new IntegrationError(\"invalid_input\");\n return value as number;\n}\nexport function validateRaindropCreateBookmark(\n value: unknown,\n): RaindropCreateBookmarkInput {\n const input = inputRecord(value, [\n \"collectionId\",\n \"url\",\n \"title\",\n \"note\",\n \"excerpt\",\n \"tags\",\n \"metadata\",\n ]);\n const result: RaindropCreateBookmarkInput = { url: webUrl(input.url) };\n if (input.collectionId !== undefined)\n result.collectionId = collectionId(input.collectionId);\n if (input.title !== undefined)\n result.title = inputText(input.title, 10_000, false)!;\n if (input.note !== undefined)\n result.note = inputText(input.note, 100_000, false)!;\n if (input.excerpt !== undefined)\n result.excerpt = inputText(input.excerpt, 10_000, false)!;\n if (input.tags !== undefined) {\n if (\n !Array.isArray(input.tags) ||\n input.tags.length > 100 ||\n input.tags.some(\n (tag) => typeof tag !== \"string\" || !tag.trim() || tag.length > 255,\n )\n )\n throw new IntegrationError(\"invalid_input\");\n result.tags = [...new Set(input.tags as string[])];\n }\n if (input.metadata !== undefined) {\n const metadata = jsonMetadata(input.metadata);\n if (!metadata || Array.isArray(metadata) || typeof metadata !== \"object\")\n throw new IntegrationError(\"invalid_input\");\n result.metadata = metadata;\n }\n return result;\n}\nfunction bookmarkResult(\n value: unknown,\n input?: RaindropCreateBookmarkInput,\n): { id: string; url: string; collectionId: number } {\n try {\n const response = record(value);\n if (response.result !== true) throw new Error();\n const item = record(response.item);\n if (!Number.isSafeInteger(item._id) || Number(item._id) <= 0)\n throw new Error();\n const destination = collectionId(record(item.collection).$id);\n const link = text(item.link, 10_000);\n if (\n input &&\n (new URL(link).toString() !== new URL(input.url).toString() ||\n destination !== (input.collectionId ?? -1))\n )\n throw new Error();\n return {\n id: String(item._id),\n collectionId: destination,\n url: `https://app.raindrop.io/my/${destination}/item/${item._id}`,\n };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\nexport function createRaindropClient(config: RaindropClientConfig) {\n if (!config.accessToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n const request = (\n path: string,\n options: Omit<\n ProviderRequestOptions,\n \"accessToken\" | \"clientId\" | \"clientSecret\"\n > = {},\n ) => raindropRequest(path, { ...config, ...options });\n async function listCollections(\n input: { cursor?: string; query?: string; parentId?: string } = {},\n ): Promise<ResourcePage> {\n if (input.cursor !== undefined) throw new IntegrationError(\"invalid_input\");\n if (input.query !== undefined) inputText(input.query, 1000, false);\n if (input.parentId !== undefined && !/^[1-9][0-9]*$/.test(input.parentId))\n throw new IntegrationError(\"invalid_input\");\n const pages = await Promise.all([\n request(\"/collections\"),\n request(\"/collections/childrens\"),\n ]);\n const resources = new Map<string, Resource>();\n resources.set(\"-1\", { id: \"-1\", type: \"collection\", name: \"Unsorted\" });\n for (const value of pages) {\n const response = record(value);\n if (\n response.result !== true ||\n !Array.isArray(response.items) ||\n response.items.length > 10_000\n )\n throw new IntegrationError(\"invalid_response\");\n for (const value of response.items) {\n const item = record(value);\n if (!Number.isSafeInteger(item._id) || Number(item._id) <= 0)\n throw new IntegrationError(\"invalid_response\");\n const level = record(item.access).level;\n if (!Number.isInteger(level) || Number(level) < 1 || Number(level) > 4)\n throw new IntegrationError(\"invalid_response\");\n if (Number(level) < 3) continue;\n let parentId: string | undefined;\n if (item.parent !== undefined && item.parent !== null) {\n const parent = record(item.parent);\n const id = parent.$id ?? parent._id;\n if (!Number.isSafeInteger(id) || Number(id) <= 0)\n throw new IntegrationError(\"invalid_response\");\n parentId = String(id);\n }\n resources.set(String(item._id), {\n id: String(item._id),\n type: \"collection\",\n name: text(item.title),\n metadata: {\n accessLevel: Number(level),\n ...(parentId ? { parentId } : {}),\n },\n });\n }\n }\n return {\n items: [...resources.values()].filter(\n (item) =>\n (!input.parentId || item.metadata?.parentId === input.parentId) &&\n (!input.query ||\n item.name\n .toLocaleLowerCase()\n .includes(input.query.toLocaleLowerCase())),\n ),\n };\n }\n async function createBookmark(value: RaindropCreateBookmarkInput) {\n const input = validateRaindropCreateBookmark(value);\n const id = input.collectionId ?? -1;\n if (id !== -1) {\n const response = record(await request(`/collection/${id}`));\n const item = record(response.item);\n if (response.result !== true || item._id !== id)\n throw new IntegrationError(\"invalid_response\");\n const level = record(item.access).level;\n if (level !== 3 && level !== 4)\n throw new IntegrationError(\"permission_required\");\n }\n const payload: Json = {\n link: input.url,\n collection: { $id: id },\n ...(input.title !== undefined ? { title: input.title } : {}),\n ...(input.note !== undefined ? { note: input.note } : {}),\n ...(input.excerpt !== undefined ? { excerpt: input.excerpt } : {}),\n ...(input.tags ? { tags: input.tags } : {}),\n };\n return bookmarkResult(await request(\"/raindrop\", { body: payload }), input);\n }\n return {\n request,\n listCollections,\n resources: listCollections,\n createBookmark,\n };\n}\n\nfunction tokenCredentials(\n value: unknown,\n previous?: CredentialMaterial,\n): CredentialMaterial {\n try {\n const response = record(value);\n const accessToken = text(response.access_token, 8192);\n const refreshToken = text(response.refresh_token, 8192);\n const expires = response.expires_in;\n if (\n typeof response.token_type !== \"string\" ||\n response.token_type.toLowerCase() !== \"bearer\" ||\n typeof expires !== \"number\" ||\n !Number.isInteger(expires) ||\n expires <= 0 ||\n expires > 31_536_000\n )\n throw new Error();\n return {\n accessToken,\n refreshToken,\n expiresAt: Date.now() + expires * 1000,\n ...(previous?.extra ? { extra: previous.extra } : {}),\n };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\nexport function createRaindropProvider(\n config: RaindropProviderConfig,\n): IntegrationProvider {\n if (\n !config.registrationId ||\n !config.clientId ||\n !config.clientSecret ||\n !config.redirectUri\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n const tokenRequest = (\n body: Json,\n fetcher: typeof globalThis.fetch,\n signal?: AbortSignal,\n ) =>\n raindropRequest(\"/v1/oauth/access_token\", {\n body: {\n client_id: config.clientId,\n client_secret: config.clientSecret,\n ...(body as Record<string, Json>),\n },\n fetch: fetcher,\n ...(signal ? { signal } : {}),\n });\n return {\n key: \"raindrop\",\n registrationId: config.registrationId,\n purposes: [\"connect\"],\n authorization: {\n url(input) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const url = new URL(\"https://raindrop.io/oauth/authorize\");\n url.search = new URLSearchParams({\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n state: input.state,\n }).toString();\n return url.toString();\n },\n async exchange(input, fetcher) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const credentials = tokenCredentials(\n await tokenRequest(\n {\n grant_type: \"authorization_code\",\n code: input.code,\n redirect_uri: config.redirectUri,\n },\n fetcher,\n input.signal,\n ),\n );\n const response = record(\n await raindropRequest(\"/user\", {\n accessToken: credentials.accessToken,\n fetch: fetcher,\n signal: input.signal,\n }),\n );\n const user = record(response.user);\n if (\n response.result !== true ||\n !Number.isSafeInteger(user._id) ||\n Number(user._id) <= 0\n )\n throw new IntegrationError(\"invalid_response\");\n const id = String(user._id);\n return {\n credentials,\n account: {\n id,\n label: optionalText(user.fullName) ?? `Raindrop ${id}`,\n },\n };\n },\n },\n resources(input, context) {\n return createRaindropClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n }).listCollections(input);\n },\n async refresh(credentials, context) {\n if (!credentials.refreshToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n return tokenCredentials(\n await tokenRequest(\n {\n grant_type: \"refresh_token\",\n refresh_token: credentials.refreshToken,\n },\n context.fetch,\n context.signal,\n ),\n credentials,\n );\n },\n // Raindrop does not document a revocation API; local disconnect must not pretend to revoke the upstream grant.\n actions: {\n create_bookmark: {\n validate(value) {\n return validateRaindropCreateBookmark(value) as unknown as Json;\n },\n async execute(value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (\n typeof checkpoint.id === \"string\" &&\n typeof checkpoint.url === \"string\" &&\n typeof checkpoint.collectionId === \"number\"\n )\n return {\n id: checkpoint.id,\n url: checkpoint.url,\n collectionId: checkpoint.collectionId,\n };\n const result = await createRaindropClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n }).createBookmark(value as unknown as RaindropCreateBookmarkInput);\n await context.saveCheckpoint(result);\n return result;\n },\n async reconcile(value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (\n typeof checkpoint.id !== \"string\" ||\n !/^[1-9][0-9]*$/.test(checkpoint.id)\n )\n return { resolved: false };\n const result = bookmarkResult(\n await raindropRequest(`/raindrop/${checkpoint.id}`, {\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n }),\n validateRaindropCreateBookmark(value),\n );\n if (result.id !== checkpoint.id)\n throw new IntegrationError(\"invalid_response\");\n return { resolved: true, result };\n },\n },\n },\n };\n}\n"],"mappings":"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","names":["keys","uuid","value","tokenCredentials"]}
|
|
1
|
+
{"version":3,"sources":["../../src/providers/identity.ts","../../src/errors.ts","../../src/providers/http.ts","../../src/providers/notion.ts","../../src/providers/raindrop.ts"],"sourcesContent":["import {\n createLocalJWKSet,\n importPKCS8,\n jwtVerify,\n SignJWT,\n type JSONWebKeySet,\n type JWTPayload,\n} from \"jose\";\nimport { timingSafeEqual } from \"node:crypto\";\nimport { IntegrationError } from \"../errors.js\";\nimport type {\n AuthorizationInput,\n IntegrationProvider,\n VerifiedIdentity,\n} from \"../types.js\";\nimport { optionalText, record, requestJson, text } from \"./http.js\";\n\nexport type IdentityProviderConfig = {\n registrationId: string;\n identityNamespace?: string;\n clientId: string;\n redirectUri: string;\n};\nexport type GoogleProviderConfig = IdentityProviderConfig & {\n clientSecret?: string;\n nativeClientIds?: readonly string[];\n};\nexport type AppleProviderConfig = IdentityProviderConfig & {\n teamId?: string;\n keyId?: string;\n privateKey?: string;\n nativeClientIds?: readonly string[];\n};\nexport type GitHubProviderConfig = IdentityProviderConfig & {\n clientSecret: string;\n};\n\nfunction configure(config: IdentityProviderConfig): void {\n if (\n !config.registrationId ||\n !config.clientId ||\n !config.redirectUri ||\n config.identityNamespace === \"\"\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n let url: URL;\n try {\n url = new URL(config.redirectUri);\n } catch {\n throw new IntegrationError(\"invalid_provider_configuration\");\n }\n if (\n url.username ||\n url.password ||\n url.hash ||\n (url.protocol !== \"https:\" &&\n !(\n url.protocol === \"http:\" &&\n [\"localhost\", \"127.0.0.1\", \"[::1]\"].includes(url.hostname)\n ))\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n}\nfunction identityPurpose(purpose: string): void {\n if (purpose !== \"identity\") throw new IntegrationError(\"unsupported_purpose\");\n}\nfunction authorizationURL(\n base: string,\n parameters: Record<string, string>,\n): string {\n const url = new URL(base);\n for (const [key, value] of Object.entries(parameters))\n url.searchParams.set(key, value);\n return url.toString();\n}\nconst keyCaches = new WeakMap<\n typeof globalThis.fetch,\n Map<\n string,\n {\n expires: number;\n refreshedAt: number;\n resolve: ReturnType<typeof createLocalJWKSet>;\n }\n >\n>();\nconst keyLoads = new WeakMap<\n typeof globalThis.fetch,\n Map<string, Promise<ReturnType<typeof createLocalJWKSet>>>\n>();\nasync function keys(\n url: string,\n fetcher: typeof globalThis.fetch,\n force = false,\n) {\n let cache = keyCaches.get(fetcher);\n if (!cache) {\n cache = new Map();\n keyCaches.set(fetcher, cache);\n }\n const existing = cache.get(url);\n if (!force && existing && existing.expires > Date.now())\n return existing.resolve;\n // An untrusted kid cannot force unlimited requests to the vendor's key endpoint.\n if (force && existing && existing.refreshedAt + 30_000 > Date.now())\n return existing.resolve;\n let loads = keyLoads.get(fetcher);\n if (!loads) {\n loads = new Map();\n keyLoads.set(fetcher, loads);\n }\n const pending = loads.get(url);\n if (pending) return pending;\n const load = (async () => {\n try {\n const value = record(await requestJson(url, {}, fetcher));\n if (!Array.isArray(value.keys) || value.keys.length > 100)\n throw new Error();\n const resolve = createLocalJWKSet(value as unknown as JSONWebKeySet);\n const now = Date.now();\n cache!.set(url, { expires: now + 300_000, refreshedAt: now, resolve });\n return resolve;\n } catch {\n throw new IntegrationError(\"identity_unavailable\", \"retryable\");\n }\n })();\n loads.set(url, load);\n try {\n return await load;\n } finally {\n loads.delete(url);\n }\n}\nasync function verifyToken(\n input: { idToken: string; nonce: string },\n config: IdentityProviderConfig,\n fetcher: typeof globalThis.fetch,\n options: { provider: \"google\" | \"apple\"; audiences: readonly string[] },\n): Promise<VerifiedIdentity> {\n if (\n !input.nonce ||\n input.nonce.length > 1024 ||\n !input.idToken ||\n input.idToken.length > 32_768 ||\n !options.audiences.length ||\n options.audiences.some((item) => !item)\n )\n throw new IntegrationError(\"invalid_identity\");\n const google = options.provider === \"google\";\n const issuer = google\n ? \"https://accounts.google.com\"\n : \"https://appleid.apple.com\";\n const jwks = google\n ? \"https://www.googleapis.com/oauth2/v3/certs\"\n : \"https://appleid.apple.com/auth/keys\";\n const verificationOptions = {\n algorithms: [\"RS256\"],\n issuer: google ? [issuer, \"accounts.google.com\"] : issuer,\n audience: [...options.audiences],\n requiredClaims: [\"sub\", \"exp\", \"iat\", \"nonce\"],\n clockTolerance: 30,\n };\n let payload: JWTPayload;\n try {\n let resolve = await keys(jwks, fetcher);\n try {\n ({ payload } = await jwtVerify(\n input.idToken,\n resolve,\n verificationOptions,\n ));\n } catch (error) {\n if (!(\n error &&\n typeof error === \"object\" &&\n \"code\" in error &&\n error.code === \"ERR_JWKS_NO_MATCHING_KEY\"\n ))\n throw error;\n resolve = await keys(jwks, fetcher, true);\n ({ payload } = await jwtVerify(\n input.idToken,\n resolve,\n verificationOptions,\n ));\n }\n const expected = Buffer.from(input.nonce);\n const actual = Buffer.from(\n typeof payload.nonce === \"string\" ? payload.nonce : \"\",\n );\n if (\n expected.length !== actual.length ||\n !timingSafeEqual(expected, actual) ||\n typeof payload.iat !== \"number\" ||\n payload.iat > Date.now() / 1000 + 30 ||\n typeof payload.sub !== \"string\" ||\n !payload.sub ||\n payload.sub.length > 255\n )\n throw new Error();\n // A multi-audience assertion must identify one of this registration's clients.\n if (\n Array.isArray(payload.aud) &&\n payload.aud.length > 1 &&\n (typeof payload.azp !== \"string\" ||\n !options.audiences.includes(payload.azp))\n )\n throw new Error();\n } catch (error) {\n if (\n error instanceof IntegrationError &&\n (error.disposition === \"retryable\" ||\n error.disposition === \"outcome_unknown\")\n )\n throw new IntegrationError(\"identity_unavailable\", \"retryable\");\n throw new IntegrationError(\"invalid_identity\");\n }\n const email = optionalText(payload.email, 320);\n const name = optionalText(payload.name, 1024);\n return {\n provider: options.provider,\n issuer,\n subject: payload.sub!,\n identityNamespace: config.identityNamespace ?? config.registrationId,\n emailVerified:\n payload.email_verified === true ||\n (options.provider === \"apple\" && payload.email_verified === \"true\"),\n ...(email ? { email } : {}),\n ...(name ? { name } : {}),\n };\n}\n\nexport function createGoogleProvider(\n config: GoogleProviderConfig,\n): IntegrationProvider {\n configure(config);\n return {\n key: \"google\",\n registrationId: config.registrationId,\n purposes: [\"identity\"],\n authorization: {\n url(input: AuthorizationInput) {\n identityPurpose(input.purpose);\n return authorizationURL(\n \"https://accounts.google.com/o/oauth2/v2/auth\",\n {\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n scope: \"openid email profile\",\n state: input.state,\n nonce: input.nonce,\n code_challenge: input.challenge,\n code_challenge_method: \"S256\",\n },\n );\n },\n async exchange(input, fetcher) {\n identityPurpose(input.purpose);\n if (!config.clientSecret)\n throw new IntegrationError(\"application_unavailable\");\n const tokens = record(\n await requestJson(\n \"https://oauth2.googleapis.com/token\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n redirect_uri: config.redirectUri,\n grant_type: \"authorization_code\",\n code: input.code,\n code_verifier: input.verifier,\n }),\n ...(input.signal ? { signal: input.signal } : {}),\n },\n fetcher,\n ),\n );\n const identity = await verifyToken(\n { idToken: text(tokens.id_token, 32_768), nonce: input.nonce },\n config,\n fetcher,\n { provider: \"google\", audiences: [config.clientId] },\n );\n return { identity }; // Login never exposes or persists OAuth provider tokens.\n },\n },\n verifyNative(input, fetcher) {\n return verifyToken(input, config, fetcher, {\n provider: \"google\",\n audiences: config.nativeClientIds ?? [config.clientId],\n });\n },\n };\n}\n\nexport function createAppleProvider(\n config: AppleProviderConfig,\n): IntegrationProvider {\n configure(config);\n async function clientSecret(): Promise<string> {\n if (!config.teamId || !config.keyId || !config.privateKey)\n throw new IntegrationError(\"application_unavailable\");\n try {\n const key = await importPKCS8(config.privateKey, \"ES256\");\n return await new SignJWT({})\n .setProtectedHeader({ alg: \"ES256\", kid: config.keyId })\n .setIssuer(config.teamId)\n .setSubject(config.clientId)\n .setAudience(\"https://appleid.apple.com\")\n .setIssuedAt()\n .setExpirationTime(\"5m\")\n .sign(key);\n } catch {\n throw new IntegrationError(\"application_unavailable\");\n }\n }\n return {\n key: \"apple\",\n registrationId: config.registrationId,\n purposes: [\"identity\"],\n authorization: {\n url(input) {\n identityPurpose(input.purpose);\n return authorizationURL(\"https://appleid.apple.com/auth/authorize\", {\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n response_mode: \"form_post\",\n scope: \"name email\",\n state: input.state,\n nonce: input.nonce,\n });\n },\n async exchange(input, fetcher) {\n identityPurpose(input.purpose);\n const result = record(\n await requestJson(\n \"https://appleid.apple.com/auth/token\",\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: await clientSecret(),\n redirect_uri: config.redirectUri,\n grant_type: \"authorization_code\",\n code: input.code,\n }),\n ...(input.signal ? { signal: input.signal } : {}),\n },\n fetcher,\n ),\n );\n return {\n identity: await verifyToken(\n { idToken: text(result.id_token, 32_768), nonce: input.nonce },\n config,\n fetcher,\n { provider: \"apple\", audiences: [config.clientId] },\n ),\n };\n },\n },\n // nonce is the actual expected token nonce; a native host using SHA256 supplies that hash.\n verifyNative(input, fetcher) {\n return verifyToken(input, config, fetcher, {\n provider: \"apple\",\n audiences: config.nativeClientIds ?? [config.clientId],\n });\n },\n };\n}\n\nexport function createGitHubProvider(\n config: GitHubProviderConfig,\n): IntegrationProvider {\n configure(config);\n if (!config.clientSecret)\n throw new IntegrationError(\"invalid_provider_configuration\");\n return {\n key: \"github\",\n registrationId: config.registrationId,\n purposes: [\"identity\"],\n authorization: {\n url(input) {\n identityPurpose(input.purpose);\n return authorizationURL(\"https://github.com/login/oauth/authorize\", {\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n scope: \"read:user user:email\",\n state: input.state,\n code_challenge: input.challenge,\n code_challenge_method: \"S256\",\n });\n },\n async exchange(input, fetcher) {\n identityPurpose(input.purpose);\n const tokens = record(\n await requestJson(\n \"https://github.com/login/oauth/access_token\",\n {\n method: \"POST\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n body: new URLSearchParams({\n client_id: config.clientId,\n client_secret: config.clientSecret,\n redirect_uri: config.redirectUri,\n code: input.code,\n code_verifier: input.verifier,\n }),\n ...(input.signal ? { signal: input.signal } : {}),\n },\n fetcher,\n ),\n );\n const accessToken = text(tokens.access_token);\n const headers = {\n Accept: \"application/vnd.github+json\",\n Authorization: `Bearer ${accessToken}`,\n \"X-GitHub-Api-Version\": \"2026-03-10\",\n \"User-Agent\": \"mycreat-labs-integrations-sdk\",\n };\n const user = record(\n await requestJson(\n \"https://api.github.com/user\",\n { headers, ...(input.signal ? { signal: input.signal } : {}) },\n fetcher,\n ),\n );\n if (!Number.isSafeInteger(user.id) || Number(user.id) <= 0)\n throw new IntegrationError(\"invalid_identity\");\n const emails = await requestJson(\n \"https://api.github.com/user/emails?per_page=100\",\n { headers, ...(input.signal ? { signal: input.signal } : {}) },\n fetcher,\n );\n if (!Array.isArray(emails) || emails.length > 100)\n throw new IntegrationError(\"invalid_identity\");\n const primary = emails.find(\n (item) =>\n item &&\n typeof item === \"object\" &&\n item.primary === true &&\n item.verified === true,\n ) as { email?: unknown } | undefined;\n const email = primary ? text(primary.email, 320) : undefined;\n const name = optionalText(user.name, 1024);\n const username = text(user.login, 255);\n return {\n identity: {\n provider: \"github\",\n issuer: \"https://github.com\",\n subject: String(user.id),\n identityNamespace:\n config.identityNamespace ?? config.registrationId,\n emailVerified: Boolean(email),\n username,\n ...(email ? { email } : {}),\n ...(name ? { name } : {}),\n },\n };\n },\n },\n };\n}\n","export type FailureDisposition =\n \"retryable\" | \"requires_reauth\" | \"outcome_unknown\" | \"permanent_failure\";\nexport class IntegrationError extends Error {\n readonly sdkError = \"@mycreat-labs/integrations-sdk/v1\";\n constructor(\n readonly code: string,\n readonly disposition: FailureDisposition = \"permanent_failure\",\n readonly retryAfterMs?: number,\n ) {\n super(code);\n this.name = \"IntegrationError\";\n }\n}\nexport function integrationError(error: unknown): IntegrationError {\n if (error instanceof IntegrationError) return error;\n // Bundled subpath entries and independently installed copies have separate class identities.\n if (\n error instanceof Error &&\n \"sdkError\" in error &&\n error.sdkError === \"@mycreat-labs/integrations-sdk/v1\" &&\n \"code\" in error &&\n typeof error.code === \"string\" &&\n /^[a-zA-Z0-9_]{1,100}$/.test(error.code) &&\n \"disposition\" in error &&\n [\n \"retryable\",\n \"requires_reauth\",\n \"outcome_unknown\",\n \"permanent_failure\",\n ].includes(String(error.disposition))\n ) {\n const delay =\n \"retryAfterMs\" in error &&\n typeof error.retryAfterMs === \"number\" &&\n Number.isFinite(error.retryAfterMs) &&\n error.retryAfterMs >= 0\n ? error.retryAfterMs\n : undefined;\n return new IntegrationError(\n error.code,\n error.disposition as FailureDisposition,\n delay,\n );\n }\n return new IntegrationError(\"provider_unavailable\", \"outcome_unknown\");\n}\n","import { IntegrationError, type FailureDisposition } from \"../errors.js\";\nimport type { Json } from \"../types.js\";\n\nexport type ProviderRequestOptions = {\n accessToken?: string;\n clientId?: string;\n clientSecret?: string;\n method?: string;\n body?: unknown;\n signal?: AbortSignal;\n fetch?: typeof globalThis.fetch;\n apiVersion?: string;\n};\n\n/** Contains only safe classifications and validated receipt IDs, never upstream messages. */\nexport class ProviderHttpError extends IntegrationError {\n readonly status: number | null;\n readonly providerCode?: string;\n readonly definite: boolean;\n readonly committedResourceId?: string;\n readonly committedChildIds?: string[];\n constructor(\n code: string,\n disposition: FailureDisposition,\n options: {\n status?: number;\n providerCode?: string;\n definite?: boolean;\n retryAfterMs?: number;\n committedResourceId?: string;\n committedChildIds?: string[];\n } = {},\n ) {\n super(code, disposition, options.retryAfterMs);\n this.name = \"ProviderHttpError\";\n this.status = options.status ?? null;\n this.providerCode = options.providerCode;\n this.definite = options.definite ?? false;\n this.committedResourceId = options.committedResourceId;\n this.committedChildIds = options.committedChildIds;\n }\n}\n\nexport function record(value: unknown): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n throw new IntegrationError(\"invalid_response\");\n return value as Record<string, unknown>;\n}\nexport function text(value: unknown, max = 4096): string {\n if (typeof value !== \"string\" || value.length === 0 || value.length > max)\n throw new IntegrationError(\"invalid_response\");\n return value;\n}\nexport function optionalText(value: unknown, max = 4096): string | undefined {\n return value === undefined || value === null ? undefined : text(value, max);\n}\nexport function inputRecord(\n value: unknown,\n keys: readonly string[],\n): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value))\n throw new IntegrationError(\"invalid_input\");\n const input = value as Record<string, unknown>;\n if (Object.keys(input).some((key) => !keys.includes(key)))\n throw new IntegrationError(\"invalid_input\");\n return input;\n}\nexport function inputText(\n value: unknown,\n maximum: number,\n required = true,\n): string | undefined {\n if (value === undefined && !required) return undefined;\n if (\n typeof value !== \"string\" ||\n (required && !value.trim()) ||\n value.length > maximum\n )\n throw new IntegrationError(\"invalid_input\");\n return value;\n}\nexport function webUrl(value: unknown): string {\n const result = inputText(value, 10_000)!;\n try {\n const url = new URL(result);\n if (\n ![\"https:\", \"http:\"].includes(url.protocol) ||\n url.username ||\n url.password\n )\n throw new Error();\n } catch {\n throw new IntegrationError(\"invalid_input\");\n }\n return result;\n}\nexport function jsonMetadata(value: unknown): Json | undefined {\n if (value === undefined) return undefined;\n const visit = (item: unknown, depth: number): boolean =>\n depth <= 10 &&\n (item === null ||\n typeof item === \"string\" ||\n typeof item === \"boolean\" ||\n (typeof item === \"number\" && Number.isFinite(item)) ||\n (Array.isArray(item) && item.every((child) => visit(child, depth + 1))) ||\n (typeof item === \"object\" &&\n item !== null &&\n Object.getPrototypeOf(item) === Object.prototype &&\n Object.values(item).every((child) => visit(child, depth + 1))));\n if (!visit(value, 0) || JSON.stringify(value).length > 16_384)\n throw new IntegrationError(\"invalid_input\");\n return value as Json;\n}\n\nconst safeCodes = new Set([\n \"invalid_client\",\n \"unauthorized_client\",\n \"invalid_grant\",\n \"bad_authorization_code\",\n \"invalid_request\",\n \"invalid_json\",\n \"validation_error\",\n \"restricted_resource\",\n \"unauthorized\",\n \"object_not_found\",\n \"rate_limited\",\n \"conflict_error\",\n \"internal_server_error\",\n \"service_unavailable\",\n \"gateway_timeout\",\n \"service_overload\",\n \"row_limit_exceeded\",\n \"invalid_token\",\n \"bad_verification_code\",\n \"incorrect_client_credentials\",\n \"redirect_uri_mismatch\",\n \"access_denied\",\n]);\nconst uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nexport const isUuid = (value: unknown): value is string =>\n typeof value === \"string\" && uuid.test(value);\nexport function retryDelay(value: string | null): number | undefined {\n if (!value) return undefined;\n const milliseconds = /^\\d+(?:\\.\\d+)?$/.test(value)\n ? Number(value) * 1000\n : Date.parse(value) - Date.now();\n return Number.isFinite(milliseconds)\n ? Math.max(0, Math.min(milliseconds, 86_400_000))\n : undefined;\n}\n\nfunction failure(\n status: number,\n body: unknown,\n write: boolean,\n retryAfterMs?: number,\n): ProviderHttpError {\n const payload =\n body && typeof body === \"object\" && !Array.isArray(body)\n ? (body as Record<string, unknown>)\n : {};\n const vendorCode =\n typeof payload.code === \"string\"\n ? payload.code\n : typeof payload.error === \"string\"\n ? payload.error\n : undefined;\n const providerCode =\n vendorCode && safeCodes.has(vendorCode) ? vendorCode : undefined;\n const extra =\n payload.additional_data && typeof payload.additional_data === \"object\"\n ? (payload.additional_data as Record<string, unknown>)\n : {};\n const committedResourceId = isUuid(extra.committed_resource_id)\n ? extra.committed_resource_id\n : undefined;\n const committedChildIds =\n Array.isArray(extra.committed_child_ids) &&\n extra.committed_child_ids.length <= 100 &&\n extra.committed_child_ids.every(isUuid)\n ? (extra.committed_child_ids as string[])\n : undefined;\n const definite =\n status >= 400 &&\n status < 500 &&\n status !== 408 &&\n !committedResourceId &&\n !committedChildIds?.length;\n let code =\n status === 401\n ? \"auth_required\"\n : status === 404\n ? \"resource_unavailable\"\n : status === 403\n ? \"permission_required\"\n : status === 429 || status === 529\n ? \"rate_limited\"\n : status >= 500\n ? \"upstream_unavailable\"\n : \"invalid_payload\";\n if (\n providerCode === \"invalid_client\" ||\n providerCode === \"unauthorized_client\" ||\n providerCode === \"incorrect_client_credentials\" ||\n payload.errorMessage === \"client_id or client_secret is invalid\"\n )\n code = \"application_unavailable\";\n else if (\n providerCode === \"invalid_grant\" ||\n providerCode === \"bad_authorization_code\" ||\n providerCode === \"invalid_token\" ||\n providerCode === \"bad_verification_code\"\n )\n code = \"auth_required\";\n else if (extra.rate_limit_reason === \"public_api_request_blocked\")\n code = \"access_restricted\";\n else if (status === 403 && providerCode === \"restricted_resource\")\n code = \"resource_unavailable\";\n else if (\n status === 403 &&\n typeof payload.message === \"string\" &&\n /block.*limit|limit.*block/i.test(payload.message)\n )\n code = \"workspace_capacity\";\n const disposition: FailureDisposition =\n code === \"auth_required\"\n ? \"requires_reauth\"\n : write && !definite\n ? \"outcome_unknown\"\n : code === \"rate_limited\" || status >= 500 || status === 408\n ? \"retryable\"\n : \"permanent_failure\";\n return new ProviderHttpError(code, disposition, {\n status,\n providerCode,\n definite,\n retryAfterMs,\n committedResourceId,\n committedChildIds,\n });\n}\n\nexport async function requestJson(\n url: string,\n init: RequestInit,\n fetcher: typeof globalThis.fetch,\n options: { write?: boolean; raindrop?: boolean; requireJson?: boolean } = {},\n): Promise<unknown> {\n const write =\n options.write ?? ![\"GET\", \"HEAD\"].includes(init.method ?? \"GET\");\n const signal = init.signal\n ? AbortSignal.any([init.signal, AbortSignal.timeout(30_000)])\n : AbortSignal.timeout(30_000);\n let response: Response;\n try {\n response = await fetcher(url, { ...init, signal, redirect: \"error\" });\n } catch (error) {\n // An SDK admission limiter rejected the request before any HTTP dispatch.\n if (\n error instanceof Error &&\n \"sdkError\" in error &&\n error.sdkError === \"@mycreat-labs/integrations-sdk/v1\" &&\n \"code\" in error &&\n error.code === \"rate_limited\" &&\n \"definite\" in error &&\n error.definite === true\n ) {\n const delay =\n \"retryAfterMs\" in error &&\n typeof error.retryAfterMs === \"number\" &&\n Number.isFinite(error.retryAfterMs)\n ? Math.max(0, Math.min(error.retryAfterMs, 86_400_000))\n : undefined;\n throw new ProviderHttpError(\"rate_limited\", \"retryable\", {\n status: 429,\n definite: true,\n retryAfterMs: delay,\n });\n }\n throw new ProviderHttpError(\n \"upstream_unavailable\",\n write ? \"outcome_unknown\" : \"retryable\",\n );\n }\n if (response.status === 204 && response.ok) return {};\n let body: unknown;\n try {\n if (\n options.requireJson &&\n !response.headers.get(\"content-type\")?.toLowerCase().includes(\"json\")\n )\n throw new Error();\n if (!response.body) throw new Error();\n const reader = response.body.getReader();\n const chunks: Uint8Array[] = [];\n let size = 0;\n try {\n for (;;) {\n const part = await reader.read();\n if (part.done) break;\n size += part.value.length;\n if (size > 2_097_152) {\n await reader.cancel();\n throw new Error();\n }\n chunks.push(part.value);\n }\n } finally {\n reader.releaseLock();\n }\n body = JSON.parse(Buffer.concat(chunks).toString(\"utf8\")) as unknown;\n } catch {\n if (!response.ok)\n throw failure(\n response.status,\n {},\n write,\n retryDelay(response.headers.get(\"retry-after\")),\n );\n throw new ProviderHttpError(\n \"invalid_response\",\n write ? \"outcome_unknown\" : \"retryable\",\n { status: response.status },\n );\n }\n if (!response.ok)\n throw failure(\n response.status,\n body,\n write,\n retryDelay(response.headers.get(\"retry-after\")),\n );\n if (body && typeof body === \"object\" && !Array.isArray(body)) {\n const value = body as Record<string, unknown>;\n if (\n typeof value.error === \"string\" ||\n (options.raindrop && value.result === false)\n ) {\n const status =\n typeof value.status === \"number\" &&\n Number.isInteger(value.status) &&\n value.status >= 400 &&\n value.status < 600\n ? value.status\n : 400;\n throw failure(\n status,\n body,\n write,\n retryDelay(response.headers.get(\"retry-after\")),\n );\n }\n }\n return body;\n}\n\nfunction providerPath(path: string, prefix: string): string {\n if (\n path.length > 4096 ||\n !/^\\/[a-zA-Z0-9_/-]+(?:\\?[a-zA-Z0-9_%=&.~-]+)?$/.test(path) ||\n path.includes(\"//\") ||\n path.includes(\"..\")\n )\n throw new ProviderHttpError(\"invalid_upstream_path\", \"permanent_failure\", {\n status: 400,\n definite: true,\n });\n return path.startsWith(`${prefix}/`) || path === prefix\n ? path\n : `${prefix}${path}`;\n}\nexport function notionRequest(\n path: string,\n options: ProviderRequestOptions,\n): Promise<unknown> {\n const normalized = providerPath(path, \"/v1\");\n if (!options.accessToken && (!options.clientId || !options.clientSecret))\n throw new ProviderHttpError(\n \"application_unavailable\",\n \"permanent_failure\",\n { definite: true },\n );\n const authorization = options.accessToken\n ? `Bearer ${options.accessToken}`\n : `Basic ${Buffer.from(`${options.clientId}:${options.clientSecret}`).toString(\"base64\")}`;\n return requestJson(\n `https://api.notion.com${normalized}`,\n {\n method: options.method ?? (options.body === undefined ? \"GET\" : \"POST\"),\n headers: {\n \"Notion-Version\": options.apiVersion ?? \"2026-03-11\",\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n Authorization: authorization,\n },\n ...(options.body === undefined\n ? {}\n : { body: JSON.stringify(options.body) }),\n ...(options.signal ? { signal: options.signal } : {}),\n },\n options.fetch ?? globalThis.fetch,\n {\n write:\n normalized !== \"/v1/search\" &&\n (options.method ?? (options.body === undefined ? \"GET\" : \"POST\")) !==\n \"GET\",\n },\n );\n}\nexport function raindropRequest(\n path: string,\n options: ProviderRequestOptions,\n): Promise<unknown> {\n const normalized =\n path === \"/v1/oauth/access_token\" ? path : providerPath(path, \"/rest/v1\");\n if (normalized !== \"/v1/oauth/access_token\" && !options.accessToken)\n throw new ProviderHttpError(\"auth_required\", \"requires_reauth\", {\n status: 401,\n definite: true,\n });\n return requestJson(\n `https://api.raindrop.io${normalized}`,\n {\n method: options.method ?? (options.body === undefined ? \"GET\" : \"POST\"),\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n ...(options.accessToken\n ? { Authorization: `Bearer ${options.accessToken}` }\n : {}),\n },\n ...(options.body === undefined\n ? {}\n : { body: JSON.stringify(options.body) }),\n ...(options.signal ? { signal: options.signal } : {}),\n },\n options.fetch ?? globalThis.fetch,\n { raindrop: true, requireJson: true },\n );\n}\n","import { IntegrationError } from \"../errors.js\";\nimport type {\n CredentialMaterial,\n IntegrationProvider,\n Json,\n Resource,\n ResourcePage,\n} from \"../types.js\";\nimport {\n inputRecord,\n inputText,\n isUuid,\n jsonMetadata,\n notionRequest,\n optionalText,\n record,\n text,\n webUrl,\n type ProviderRequestOptions,\n} from \"./http.js\";\n\nexport const NOTION_API_VERSION = \"2026-03-11\";\nexport type NotionProviderConfig = {\n registrationId: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n apiVersion?: string;\n};\nexport type NotionClientConfig = {\n accessToken: string;\n fetch?: typeof globalThis.fetch;\n signal?: AbortSignal;\n apiVersion?: string;\n};\nexport type NotionCreatePageInput = {\n parentId: string;\n parentType?: \"page\" | \"data_source\";\n title: string;\n content?: string;\n url?: string;\n metadata?: { [key: string]: Json };\n};\n\nfunction uuid(value: unknown): string {\n if (!isUuid(value)) throw new IntegrationError(\"invalid_input\");\n return value;\n}\nconst validCursor = (value: unknown): value is string =>\n typeof value === \"string\" && value.length > 0 && value.length <= 4096;\nexport function validateNotionCreatePage(\n value: unknown,\n): NotionCreatePageInput {\n const input = inputRecord(value, [\n \"parentId\",\n \"parentType\",\n \"title\",\n \"content\",\n \"url\",\n \"metadata\",\n ]);\n const result: NotionCreatePageInput = {\n parentId: uuid(input.parentId),\n title: inputText(input.title, 2000)!,\n };\n if (input.parentType !== undefined) {\n if (input.parentType !== \"page\" && input.parentType !== \"data_source\")\n throw new IntegrationError(\"invalid_input\");\n result.parentType = input.parentType;\n }\n if (input.content !== undefined)\n result.content = inputText(input.content, 100_000, false)!;\n if (input.url !== undefined) result.url = webUrl(input.url);\n if (input.metadata !== undefined) {\n const metadata = jsonMetadata(input.metadata);\n if (!metadata || Array.isArray(metadata) || typeof metadata !== \"object\")\n throw new IntegrationError(\"invalid_input\");\n result.metadata = metadata;\n }\n return result;\n}\nfunction richText(value: string): Json[] {\n const result: Json[] = [];\n for (let index = 0; index < value.length;) {\n let end = Math.min(index + 2000, value.length);\n if (end < value.length && /[\\uD800-\\uDBFF]/.test(value.charAt(end - 1)))\n end--;\n result.push({ type: \"text\", text: { content: value.slice(index, end) } });\n index = end;\n }\n return result;\n}\nfunction resourceTitle(value: unknown): string {\n if (!Array.isArray(value)) throw new IntegrationError(\"invalid_response\");\n return value\n .map((item) => {\n const piece = record(item);\n if (typeof piece.plain_text === \"string\") return piece.plain_text;\n return text(record(piece.text).content, 2000);\n })\n .join(\"\");\n}\nfunction pageResult(value: unknown): { id: string; url: string } {\n try {\n const page = record(value);\n if (page.object !== \"page\" || !isUuid(page.id)) throw new Error();\n const url = text(page.url, 4096);\n if (new URL(url).protocol !== \"https:\") throw new Error();\n return { id: page.id, url };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\n\nexport function createNotionClient(config: NotionClientConfig) {\n if (!config.accessToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n const request = (\n path: string,\n options: Omit<\n ProviderRequestOptions,\n \"accessToken\" | \"clientId\" | \"clientSecret\"\n > = {},\n ) => notionRequest(path, { ...config, ...options });\n async function listResources(\n input: { cursor?: string; query?: string; parentId?: string } = {},\n ): Promise<ResourcePage> {\n if (input.parentId !== undefined)\n throw new IntegrationError(\"unsupported_resource_filter\");\n if (input.cursor !== undefined && !validCursor(input.cursor))\n throw new IntegrationError(\"invalid_input\");\n if (input.query !== undefined) inputText(input.query, 1000, false);\n const response = record(\n await request(\"/search\", {\n body: {\n page_size: 100,\n ...(input.cursor ? { start_cursor: input.cursor } : {}),\n ...(input.query !== undefined ? { query: input.query } : {}),\n },\n }),\n );\n if (\n !Array.isArray(response.results) ||\n response.results.length > 100 ||\n typeof response.has_more !== \"boolean\"\n )\n throw new IntegrationError(\"invalid_response\");\n if (\n response.request_status !== undefined &&\n record(response.request_status).type !== \"complete\"\n )\n throw new IntegrationError(\"resource_listing_incomplete\");\n if (response.has_more && !validCursor(response.next_cursor))\n throw new IntegrationError(\"invalid_response\");\n const items: Resource[] = [];\n for (const item of response.results) {\n const entry = record(item);\n if (\n !isUuid(entry.id) ||\n (entry.object !== \"page\" && entry.object !== \"data_source\")\n )\n throw new IntegrationError(\"invalid_response\");\n if (\n entry.in_trash === true ||\n entry.archived === true ||\n entry.is_archived === true\n )\n continue;\n let name: string;\n if (entry.object === \"data_source\") name = resourceTitle(entry.title);\n else {\n const properties = record(entry.properties);\n const title = Object.values(properties)\n .map(record)\n .find((property) => property.type === \"title\");\n name = title ? resourceTitle(title.title) : \"\";\n }\n const url = optionalText(entry.url);\n items.push({\n id: entry.id,\n type: entry.object,\n name: name || \"Untitled\",\n ...(url ? { url } : {}),\n });\n }\n return {\n items,\n ...(response.has_more\n ? { nextCursor: response.next_cursor as string }\n : {}),\n };\n }\n async function createPage(\n value: NotionCreatePageInput,\n ): Promise<{ id: string; url: string }> {\n const input = validateNotionCreatePage(value);\n const parentType = input.parentType ?? \"page\";\n let titleKey = \"title\";\n if (parentType === \"data_source\") {\n const source = record(await request(`/data_sources/${input.parentId}`));\n if (source.id !== input.parentId || source.object !== \"data_source\")\n throw new IntegrationError(\"invalid_response\");\n const property = Object.entries(record(source.properties)).find(\n ([, definition]) => record(definition).type === \"title\",\n );\n if (!property) throw new IntegrationError(\"invalid_resource\");\n titleKey = property[0];\n }\n const children: Json[] = [];\n if (input.content) {\n for (const part of richText(input.content))\n children.push({\n object: \"block\",\n type: \"paragraph\",\n paragraph: { rich_text: [part] },\n });\n }\n if (input.url)\n children.push({\n object: \"block\",\n type: \"bookmark\",\n bookmark: { url: input.url },\n });\n return pageResult(\n await request(\"/pages\", {\n body: {\n parent:\n parentType === \"page\"\n ? { page_id: input.parentId }\n : { data_source_id: input.parentId },\n properties: {\n [titleKey]: { type: \"title\", title: richText(input.title) },\n },\n ...(children.length ? { children } : {}),\n },\n }),\n );\n }\n return { request, listResources, resources: listResources, createPage };\n}\n\nfunction tokenCredentials(\n value: unknown,\n previous?: CredentialMaterial,\n): CredentialMaterial {\n try {\n const response = record(value);\n const accessToken = text(response.access_token, 8192);\n // Notion requires this field but permits null. Omit only a null refresh\n // credential; missing or malformed fields still fail validation.\n const refreshToken =\n response.refresh_token === null\n ? undefined\n : text(response.refresh_token, 8192);\n if (\n typeof response.token_type !== \"string\" ||\n response.token_type.toLowerCase() !== \"bearer\"\n )\n throw new Error();\n const expires = response.expires_in;\n if (\n expires !== undefined &&\n (typeof expires !== \"number\" ||\n !Number.isInteger(expires) ||\n expires <= 0 ||\n expires > 31_536_000)\n )\n throw new Error();\n return {\n accessToken,\n ...(refreshToken !== undefined ? { refreshToken } : {}),\n ...(expires !== undefined\n ? { expiresAt: Date.now() + Number(expires) * 1000 }\n : {}),\n ...(previous?.scopes ? { scopes: previous.scopes } : {}),\n ...(previous?.extra ? { extra: previous.extra } : {}),\n };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\nexport function createNotionProvider(\n config: NotionProviderConfig,\n): IntegrationProvider {\n if (\n !config.registrationId ||\n !config.clientId ||\n !config.clientSecret ||\n !config.redirectUri\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n const tokenRequest = (\n body: Json,\n fetcher: typeof globalThis.fetch,\n signal?: AbortSignal,\n ) =>\n notionRequest(\"/oauth/token\", {\n clientId: config.clientId,\n clientSecret: config.clientSecret,\n apiVersion: config.apiVersion,\n body,\n fetch: fetcher,\n ...(signal ? { signal } : {}),\n });\n return {\n key: \"notion\",\n registrationId: config.registrationId,\n purposes: [\"connect\"],\n authorization: {\n url(input) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const url = new URL(\"https://api.notion.com/v1/oauth/authorize\");\n url.search = new URLSearchParams({\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n owner: \"user\",\n state: input.state,\n }).toString();\n return url.toString();\n },\n async exchange(input, fetcher) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const response = record(\n await tokenRequest(\n {\n grant_type: \"authorization_code\",\n code: input.code,\n redirect_uri: config.redirectUri,\n },\n fetcher,\n input.signal,\n ),\n );\n const credentials = tokenCredentials(response);\n const workspaceId = text(response.workspace_id);\n const botId = text(response.bot_id);\n if (!isUuid(workspaceId) || !isUuid(botId))\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n const owner = record(response.owner);\n if (owner.type !== \"user\")\n throw new IntegrationError(\"invalid_response\");\n const userId = text(record(owner.user).id);\n if (!isUuid(userId)) throw new IntegrationError(\"invalid_response\");\n const label =\n optionalText(response.workspace_name) ?? \"Notion workspace\";\n credentials.extra = { workspaceId, botId, ownerId: userId };\n return {\n credentials,\n account: {\n id: `${workspaceId}:${botId}:${userId}`,\n label,\n metadata: { workspaceId, botId, ownerId: userId },\n },\n };\n },\n },\n resources(input, context) {\n return createNotionClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n apiVersion: config.apiVersion,\n }).listResources(input);\n },\n async refresh(credentials, context) {\n if (!credentials.refreshToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n return tokenCredentials(\n await tokenRequest(\n {\n grant_type: \"refresh_token\",\n refresh_token: credentials.refreshToken,\n },\n context.fetch,\n context.signal,\n ),\n credentials,\n );\n },\n async revoke(credentials, context) {\n await notionRequest(\"/oauth/revoke\", {\n clientId: config.clientId,\n clientSecret: config.clientSecret,\n apiVersion: config.apiVersion,\n body: { token: credentials.accessToken },\n fetch: context.fetch,\n signal: context.signal,\n });\n },\n actions: {\n create_page: {\n validate(value) {\n return validateNotionCreatePage(value) as unknown as Json;\n },\n async execute(value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (\n typeof checkpoint.id === \"string\" &&\n typeof checkpoint.url === \"string\"\n )\n return { id: checkpoint.id, url: checkpoint.url };\n const result = await createNotionClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n apiVersion: config.apiVersion,\n }).createPage(value as unknown as NotionCreatePageInput);\n await context.saveCheckpoint(result);\n return result;\n },\n async reconcile(_value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (!isUuid(checkpoint.id)) return { resolved: false };\n const result = pageResult(\n await notionRequest(`/pages/${checkpoint.id}`, {\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n apiVersion: config.apiVersion,\n }),\n );\n if (result.id !== checkpoint.id)\n throw new IntegrationError(\"invalid_response\");\n return { resolved: true, result };\n },\n },\n },\n };\n}\n","import { IntegrationError } from \"../errors.js\";\nimport type {\n CredentialMaterial,\n IntegrationProvider,\n Json,\n Resource,\n ResourcePage,\n} from \"../types.js\";\nimport {\n inputRecord,\n inputText,\n jsonMetadata,\n optionalText,\n raindropRequest,\n record,\n text,\n webUrl,\n type ProviderRequestOptions,\n} from \"./http.js\";\n\nexport type RaindropProviderConfig = {\n registrationId: string;\n clientId: string;\n clientSecret: string;\n redirectUri: string;\n};\nexport type RaindropClientConfig = {\n accessToken: string;\n fetch?: typeof globalThis.fetch;\n signal?: AbortSignal;\n};\nexport type RaindropCreateBookmarkInput = {\n collectionId?: number;\n url: string;\n title?: string;\n note?: string;\n excerpt?: string;\n tags?: string[];\n metadata?: { [key: string]: Json };\n};\nexport const RAINDROP_TOKEN_ENDPOINT =\n \"https://api.raindrop.io/v1/oauth/access_token\";\n\nfunction collectionId(value: unknown): number {\n if (\n !Number.isSafeInteger(value) ||\n (Number(value) !== -1 && Number(value) <= 0)\n )\n throw new IntegrationError(\"invalid_input\");\n return value as number;\n}\nexport function validateRaindropCreateBookmark(\n value: unknown,\n): RaindropCreateBookmarkInput {\n const input = inputRecord(value, [\n \"collectionId\",\n \"url\",\n \"title\",\n \"note\",\n \"excerpt\",\n \"tags\",\n \"metadata\",\n ]);\n const result: RaindropCreateBookmarkInput = { url: webUrl(input.url) };\n if (input.collectionId !== undefined)\n result.collectionId = collectionId(input.collectionId);\n if (input.title !== undefined)\n result.title = inputText(input.title, 10_000, false)!;\n if (input.note !== undefined)\n result.note = inputText(input.note, 100_000, false)!;\n if (input.excerpt !== undefined)\n result.excerpt = inputText(input.excerpt, 10_000, false)!;\n if (input.tags !== undefined) {\n if (\n !Array.isArray(input.tags) ||\n input.tags.length > 100 ||\n input.tags.some(\n (tag) => typeof tag !== \"string\" || !tag.trim() || tag.length > 255,\n )\n )\n throw new IntegrationError(\"invalid_input\");\n result.tags = [...new Set(input.tags as string[])];\n }\n if (input.metadata !== undefined) {\n const metadata = jsonMetadata(input.metadata);\n if (!metadata || Array.isArray(metadata) || typeof metadata !== \"object\")\n throw new IntegrationError(\"invalid_input\");\n result.metadata = metadata;\n }\n return result;\n}\nfunction bookmarkResult(\n value: unknown,\n input?: RaindropCreateBookmarkInput,\n): { id: string; url: string; collectionId: number } {\n try {\n const response = record(value);\n if (response.result !== true) throw new Error();\n const item = record(response.item);\n if (!Number.isSafeInteger(item._id) || Number(item._id) <= 0)\n throw new Error();\n const destination = collectionId(record(item.collection).$id);\n const link = text(item.link, 10_000);\n if (\n input &&\n (new URL(link).toString() !== new URL(input.url).toString() ||\n destination !== (input.collectionId ?? -1))\n )\n throw new Error();\n return {\n id: String(item._id),\n collectionId: destination,\n url: `https://app.raindrop.io/my/${destination}/item/${item._id}`,\n };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\nexport function createRaindropClient(config: RaindropClientConfig) {\n if (!config.accessToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n const request = (\n path: string,\n options: Omit<\n ProviderRequestOptions,\n \"accessToken\" | \"clientId\" | \"clientSecret\"\n > = {},\n ) => raindropRequest(path, { ...config, ...options });\n async function listCollections(\n input: { cursor?: string; query?: string; parentId?: string } = {},\n ): Promise<ResourcePage> {\n if (input.cursor !== undefined) throw new IntegrationError(\"invalid_input\");\n if (input.query !== undefined) inputText(input.query, 1000, false);\n if (input.parentId !== undefined && !/^[1-9][0-9]*$/.test(input.parentId))\n throw new IntegrationError(\"invalid_input\");\n const pages = await Promise.all([\n request(\"/collections\"),\n request(\"/collections/childrens\"),\n ]);\n const resources = new Map<string, Resource>();\n resources.set(\"-1\", { id: \"-1\", type: \"collection\", name: \"Unsorted\" });\n for (const value of pages) {\n const response = record(value);\n if (\n response.result !== true ||\n !Array.isArray(response.items) ||\n response.items.length > 10_000\n )\n throw new IntegrationError(\"invalid_response\");\n for (const value of response.items) {\n const item = record(value);\n if (!Number.isSafeInteger(item._id) || Number(item._id) <= 0)\n throw new IntegrationError(\"invalid_response\");\n const level = record(item.access).level;\n if (!Number.isInteger(level) || Number(level) < 1 || Number(level) > 4)\n throw new IntegrationError(\"invalid_response\");\n if (Number(level) < 3) continue;\n let parentId: string | undefined;\n if (item.parent !== undefined && item.parent !== null) {\n const parent = record(item.parent);\n const id = parent.$id ?? parent._id;\n if (!Number.isSafeInteger(id) || Number(id) <= 0)\n throw new IntegrationError(\"invalid_response\");\n parentId = String(id);\n }\n resources.set(String(item._id), {\n id: String(item._id),\n type: \"collection\",\n name: text(item.title),\n metadata: {\n accessLevel: Number(level),\n ...(parentId ? { parentId } : {}),\n },\n });\n }\n }\n return {\n items: [...resources.values()].filter(\n (item) =>\n (!input.parentId || item.metadata?.parentId === input.parentId) &&\n (!input.query ||\n item.name\n .toLocaleLowerCase()\n .includes(input.query.toLocaleLowerCase())),\n ),\n };\n }\n async function createBookmark(value: RaindropCreateBookmarkInput) {\n const input = validateRaindropCreateBookmark(value);\n const id = input.collectionId ?? -1;\n if (id !== -1) {\n const response = record(await request(`/collection/${id}`));\n const item = record(response.item);\n if (response.result !== true || item._id !== id)\n throw new IntegrationError(\"invalid_response\");\n const level = record(item.access).level;\n if (level !== 3 && level !== 4)\n throw new IntegrationError(\"permission_required\");\n }\n const payload: Json = {\n link: input.url,\n collection: { $id: id },\n ...(input.title !== undefined ? { title: input.title } : {}),\n ...(input.note !== undefined ? { note: input.note } : {}),\n ...(input.excerpt !== undefined ? { excerpt: input.excerpt } : {}),\n ...(input.tags ? { tags: input.tags } : {}),\n };\n return bookmarkResult(await request(\"/raindrop\", { body: payload }), input);\n }\n return {\n request,\n listCollections,\n resources: listCollections,\n createBookmark,\n };\n}\n\nfunction tokenCredentials(\n value: unknown,\n previous?: CredentialMaterial,\n): CredentialMaterial {\n try {\n const response = record(value);\n const accessToken = text(response.access_token, 8192);\n const refreshToken = text(response.refresh_token, 8192);\n const expires = response.expires_in;\n if (\n typeof response.token_type !== \"string\" ||\n response.token_type.toLowerCase() !== \"bearer\" ||\n typeof expires !== \"number\" ||\n !Number.isInteger(expires) ||\n expires <= 0 ||\n expires > 31_536_000\n )\n throw new Error();\n return {\n accessToken,\n refreshToken,\n expiresAt: Date.now() + expires * 1000,\n ...(previous?.extra ? { extra: previous.extra } : {}),\n };\n } catch {\n throw new IntegrationError(\"invalid_response\", \"outcome_unknown\");\n }\n}\nexport function createRaindropProvider(\n config: RaindropProviderConfig,\n): IntegrationProvider {\n if (\n !config.registrationId ||\n !config.clientId ||\n !config.clientSecret ||\n !config.redirectUri\n )\n throw new IntegrationError(\"invalid_provider_configuration\");\n const tokenRequest = (\n body: Json,\n fetcher: typeof globalThis.fetch,\n signal?: AbortSignal,\n ) =>\n raindropRequest(\"/v1/oauth/access_token\", {\n body: {\n client_id: config.clientId,\n client_secret: config.clientSecret,\n ...(body as Record<string, Json>),\n },\n fetch: fetcher,\n ...(signal ? { signal } : {}),\n });\n return {\n key: \"raindrop\",\n registrationId: config.registrationId,\n purposes: [\"connect\"],\n authorization: {\n url(input) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const url = new URL(\"https://raindrop.io/oauth/authorize\");\n url.search = new URLSearchParams({\n client_id: config.clientId,\n redirect_uri: config.redirectUri,\n response_type: \"code\",\n state: input.state,\n }).toString();\n return url.toString();\n },\n async exchange(input, fetcher) {\n if (input.purpose !== \"connect\")\n throw new IntegrationError(\"unsupported_purpose\");\n const credentials = tokenCredentials(\n await tokenRequest(\n {\n grant_type: \"authorization_code\",\n code: input.code,\n redirect_uri: config.redirectUri,\n },\n fetcher,\n input.signal,\n ),\n );\n const response = record(\n await raindropRequest(\"/user\", {\n accessToken: credentials.accessToken,\n fetch: fetcher,\n signal: input.signal,\n }),\n );\n const user = record(response.user);\n if (\n response.result !== true ||\n !Number.isSafeInteger(user._id) ||\n Number(user._id) <= 0\n )\n throw new IntegrationError(\"invalid_response\");\n const id = String(user._id);\n return {\n credentials,\n account: {\n id,\n label: optionalText(user.fullName) ?? `Raindrop ${id}`,\n },\n };\n },\n },\n resources(input, context) {\n return createRaindropClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n }).listCollections(input);\n },\n async refresh(credentials, context) {\n if (!credentials.refreshToken)\n throw new IntegrationError(\"auth_required\", \"requires_reauth\");\n return tokenCredentials(\n await tokenRequest(\n {\n grant_type: \"refresh_token\",\n refresh_token: credentials.refreshToken,\n },\n context.fetch,\n context.signal,\n ),\n credentials,\n );\n },\n // Raindrop does not document a revocation API; local disconnect must not pretend to revoke the upstream grant.\n actions: {\n create_bookmark: {\n validate(value) {\n return validateRaindropCreateBookmark(value) as unknown as Json;\n },\n async execute(value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (\n typeof checkpoint.id === \"string\" &&\n typeof checkpoint.url === \"string\" &&\n typeof checkpoint.collectionId === \"number\"\n )\n return {\n id: checkpoint.id,\n url: checkpoint.url,\n collectionId: checkpoint.collectionId,\n };\n const result = await createRaindropClient({\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n }).createBookmark(value as unknown as RaindropCreateBookmarkInput);\n await context.saveCheckpoint(result);\n return result;\n },\n async reconcile(value, context) {\n const checkpoint =\n context.checkpoint &&\n typeof context.checkpoint === \"object\" &&\n !Array.isArray(context.checkpoint)\n ? context.checkpoint\n : {};\n if (\n typeof checkpoint.id !== \"string\" ||\n !/^[1-9][0-9]*$/.test(checkpoint.id)\n )\n return { resolved: false };\n const result = bookmarkResult(\n await raindropRequest(`/raindrop/${checkpoint.id}`, {\n accessToken: context.credentials.accessToken,\n fetch: context.fetch,\n signal: context.signal,\n }),\n validateRaindropCreateBookmark(value),\n );\n if (result.id !== checkpoint.id)\n throw new IntegrationError(\"invalid_response\");\n return { resolved: true, result };\n },\n },\n },\n };\n}\n"],"mappings":"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","names":["keys","uuid","value","tokenCredentials"]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# 0.1.0 release — 2026-10-31
|
|
2
|
+
|
|
3
|
+
Package: `@mycreat-labs/integrations-sdk@0.1.0`.
|
|
4
|
+
Registry: `https://registry.npmjs.org/`. Access: public, explicitly approved by the owner.
|
|
5
|
+
The repository `.npmrc` records this registry without credentials.
|
|
6
|
+
Release source: `6e16f40120dcecfacaaeaf20e5537e93a842556b`, tag `npm-v0.1.0`.
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
npm install --save-exact @mycreat-labs/integrations-sdk@0.1.0
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The anonymously downloaded npm archive matches both products' pinned vendor
|
|
13
|
+
archives byte for byte:
|
|
14
|
+
|
|
15
|
+
SHA-256: `94b4bff090d8322c7c610c4fbfe5a702a2e093d096bcdfba8b53825c27f3fc10`.
|
|
16
|
+
The npm integrity and source inventory are recorded in `release-manifest.json`.
|
|
17
|
+
Published archives must not be replaced in place.
|
|
18
|
+
|
|
19
|
+
## Verification
|
|
20
|
+
|
|
21
|
+
- SDK: 77 unit tests, 6 isolated PostgreSQL tests and 2 packed ESM/CJS tests passed.
|
|
22
|
+
- A separate host installed the anonymously downloaded distribution and passed
|
|
23
|
+
strict TypeScript, real Prisma transaction rollback, authorization, durable
|
|
24
|
+
execution and transactional result projection checks.
|
|
25
|
+
- Kiipu: 792 current-source unit tests, application typechecks and production builds passed.
|
|
26
|
+
- Subtic: 69 relevant provider/runtime/probe unit tests passed; connector typechecks,
|
|
27
|
+
changed-file lint and production builds passed. Nine database tests in the focused
|
|
28
|
+
unit command were deliberately skipped; earlier isolated database acceptance is
|
|
29
|
+
documented in the consumer repository.
|
|
30
|
+
|
|
31
|
+
## Production consumers
|
|
32
|
+
|
|
33
|
+
| Product | Deployed code | Result |
|
|
34
|
+
| --- | --- | --- |
|
|
35
|
+
| Kiipu | `f6cee97fdab537e6bfbaef0d3d29d1e9eefd43b5` | API, Worker and Web healthy; five new migrations applied |
|
|
36
|
+
| Subtic | `9380a609b77e38cb93b627b6a581578626ff29ea` | API, Web, primary/media/search workers and all five connector workers healthy |
|
|
37
|
+
|
|
38
|
+
Production backups and the products' deployment/rollback scripts were used.
|
|
39
|
+
Public login pages and their static assets passed HTTP checks. Kiipu remained
|
|
40
|
+
ready through the shared gateway after Subtic's deployment.
|
|
41
|
+
The five database/Redis containers retained their IDs and start times.
|
|
42
|
+
|
|
43
|
+
Kiipu's independent OAuth registrations and integration encryption configuration
|
|
44
|
+
are not yet present in production. Its third-party capabilities remain disabled
|
|
45
|
+
until the product supplies these settings. Real-provider consent, remote writes,
|
|
46
|
+
revocation and native-device acceptance were not performed in this release.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mycreat-labs/integrations-sdk",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Product-embedded third-party identity and integration runtime",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"publishConfig": {
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
"migrations",
|
|
14
14
|
"schema.prisma",
|
|
15
15
|
"README.md",
|
|
16
|
+
"CHANGELOG.md",
|
|
16
17
|
"docs",
|
|
17
18
|
"examples"
|
|
18
19
|
],
|