@mycreat-labs/integrations-sdk 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -2
- package/dist/adapters/bullmq.cjs +110 -0
- package/dist/adapters/bullmq.cjs.map +1 -0
- package/dist/adapters/bullmq.d.cts +11 -0
- package/dist/adapters/bullmq.d.ts +11 -0
- package/dist/adapters/bullmq.js +85 -0
- package/dist/adapters/bullmq.js.map +1 -0
- package/dist/adapters/postgres.cjs +396 -0
- package/dist/adapters/postgres.cjs.map +1 -0
- package/dist/adapters/postgres.d.cts +51 -0
- package/dist/adapters/postgres.d.ts +51 -0
- package/dist/adapters/postgres.js +368 -0
- package/dist/adapters/postgres.js.map +1 -0
- package/dist/adapters/prisma.cjs +414 -0
- package/dist/adapters/prisma.cjs.map +1 -0
- package/dist/adapters/prisma.d.cts +15 -0
- package/dist/adapters/prisma.d.ts +15 -0
- package/dist/adapters/prisma.js +386 -0
- package/dist/adapters/prisma.js.map +1 -0
- package/dist/adapters/redis.cjs +125 -0
- package/dist/adapters/redis.cjs.map +1 -0
- package/dist/adapters/redis.d.cts +20 -0
- package/dist/adapters/redis.d.ts +20 -0
- package/dist/adapters/redis.js +98 -0
- package/dist/adapters/redis.js.map +1 -0
- package/dist/errors-3hDEtzuZ.d.cts +11 -0
- package/dist/errors-3hDEtzuZ.d.ts +11 -0
- package/dist/index.cjs +1328 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +128 -0
- package/dist/index.d.ts +128 -0
- package/dist/index.js +1297 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/index.cjs +1287 -0
- package/dist/providers/index.cjs.map +1 -0
- package/dist/providers/index.d.cts +144 -0
- package/dist/providers/index.d.ts +144 -0
- package/dist/providers/index.js +1252 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/testing.cjs +275 -0
- package/dist/testing.cjs.map +1 -0
- package/dist/testing.d.cts +20 -0
- package/dist/testing.d.ts +20 -0
- package/dist/testing.js +248 -0
- package/dist/testing.js.map +1 -0
- package/dist/types-Y4-DoJ1A.d.cts +260 -0
- package/dist/types-Y4-DoJ1A.d.ts +260 -0
- package/docs/migration.md +23 -0
- package/docs/security.md +26 -0
- package/docs/verification.md +22 -0
- package/examples/embedded-host.ts +62 -0
- package/migrations/0001_initial.sql +40 -0
- package/package.json +90 -4
- package/schema.prisma +80 -0
|
@@ -0,0 +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"]}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { d as IntegrationProvider, J as Json, R as ResourcePage } from '../types-Y4-DoJ1A.cjs';
|
|
2
|
+
import { I as IntegrationError, F as FailureDisposition } from '../errors-3hDEtzuZ.cjs';
|
|
3
|
+
|
|
4
|
+
type IdentityProviderConfig = {
|
|
5
|
+
registrationId: string;
|
|
6
|
+
identityNamespace?: string;
|
|
7
|
+
clientId: string;
|
|
8
|
+
redirectUri: string;
|
|
9
|
+
};
|
|
10
|
+
type GoogleProviderConfig = IdentityProviderConfig & {
|
|
11
|
+
clientSecret?: string;
|
|
12
|
+
nativeClientIds?: readonly string[];
|
|
13
|
+
};
|
|
14
|
+
type AppleProviderConfig = IdentityProviderConfig & {
|
|
15
|
+
teamId?: string;
|
|
16
|
+
keyId?: string;
|
|
17
|
+
privateKey?: string;
|
|
18
|
+
nativeClientIds?: readonly string[];
|
|
19
|
+
};
|
|
20
|
+
type GitHubProviderConfig = IdentityProviderConfig & {
|
|
21
|
+
clientSecret: string;
|
|
22
|
+
};
|
|
23
|
+
declare function createGoogleProvider(config: GoogleProviderConfig): IntegrationProvider;
|
|
24
|
+
declare function createAppleProvider(config: AppleProviderConfig): IntegrationProvider;
|
|
25
|
+
declare function createGitHubProvider(config: GitHubProviderConfig): IntegrationProvider;
|
|
26
|
+
|
|
27
|
+
type ProviderRequestOptions = {
|
|
28
|
+
accessToken?: string;
|
|
29
|
+
clientId?: string;
|
|
30
|
+
clientSecret?: string;
|
|
31
|
+
method?: string;
|
|
32
|
+
body?: unknown;
|
|
33
|
+
signal?: AbortSignal;
|
|
34
|
+
fetch?: typeof globalThis.fetch;
|
|
35
|
+
apiVersion?: string;
|
|
36
|
+
};
|
|
37
|
+
/** Contains only safe classifications and validated receipt IDs, never upstream messages. */
|
|
38
|
+
declare class ProviderHttpError extends IntegrationError {
|
|
39
|
+
readonly status: number | null;
|
|
40
|
+
readonly providerCode?: string;
|
|
41
|
+
readonly definite: boolean;
|
|
42
|
+
readonly committedResourceId?: string;
|
|
43
|
+
readonly committedChildIds?: string[];
|
|
44
|
+
constructor(code: string, disposition: FailureDisposition, options?: {
|
|
45
|
+
status?: number;
|
|
46
|
+
providerCode?: string;
|
|
47
|
+
definite?: boolean;
|
|
48
|
+
retryAfterMs?: number;
|
|
49
|
+
committedResourceId?: string;
|
|
50
|
+
committedChildIds?: string[];
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
declare function notionRequest(path: string, options: ProviderRequestOptions): Promise<unknown>;
|
|
54
|
+
declare function raindropRequest(path: string, options: ProviderRequestOptions): Promise<unknown>;
|
|
55
|
+
|
|
56
|
+
declare const NOTION_API_VERSION = "2026-03-11";
|
|
57
|
+
type NotionProviderConfig = {
|
|
58
|
+
registrationId: string;
|
|
59
|
+
clientId: string;
|
|
60
|
+
clientSecret: string;
|
|
61
|
+
redirectUri: string;
|
|
62
|
+
apiVersion?: string;
|
|
63
|
+
};
|
|
64
|
+
type NotionClientConfig = {
|
|
65
|
+
accessToken: string;
|
|
66
|
+
fetch?: typeof globalThis.fetch;
|
|
67
|
+
signal?: AbortSignal;
|
|
68
|
+
apiVersion?: string;
|
|
69
|
+
};
|
|
70
|
+
type NotionCreatePageInput = {
|
|
71
|
+
parentId: string;
|
|
72
|
+
parentType?: "page" | "data_source";
|
|
73
|
+
title: string;
|
|
74
|
+
content?: string;
|
|
75
|
+
url?: string;
|
|
76
|
+
metadata?: {
|
|
77
|
+
[key: string]: Json;
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
declare function validateNotionCreatePage(value: unknown): NotionCreatePageInput;
|
|
81
|
+
declare function createNotionClient(config: NotionClientConfig): {
|
|
82
|
+
request: (path: string, options?: Omit<ProviderRequestOptions, "accessToken" | "clientId" | "clientSecret">) => Promise<unknown>;
|
|
83
|
+
listResources: (input?: {
|
|
84
|
+
cursor?: string;
|
|
85
|
+
query?: string;
|
|
86
|
+
parentId?: string;
|
|
87
|
+
}) => Promise<ResourcePage>;
|
|
88
|
+
resources: (input?: {
|
|
89
|
+
cursor?: string;
|
|
90
|
+
query?: string;
|
|
91
|
+
parentId?: string;
|
|
92
|
+
}) => Promise<ResourcePage>;
|
|
93
|
+
createPage: (value: NotionCreatePageInput) => Promise<{
|
|
94
|
+
id: string;
|
|
95
|
+
url: string;
|
|
96
|
+
}>;
|
|
97
|
+
};
|
|
98
|
+
declare function createNotionProvider(config: NotionProviderConfig): IntegrationProvider;
|
|
99
|
+
|
|
100
|
+
type RaindropProviderConfig = {
|
|
101
|
+
registrationId: string;
|
|
102
|
+
clientId: string;
|
|
103
|
+
clientSecret: string;
|
|
104
|
+
redirectUri: string;
|
|
105
|
+
};
|
|
106
|
+
type RaindropClientConfig = {
|
|
107
|
+
accessToken: string;
|
|
108
|
+
fetch?: typeof globalThis.fetch;
|
|
109
|
+
signal?: AbortSignal;
|
|
110
|
+
};
|
|
111
|
+
type RaindropCreateBookmarkInput = {
|
|
112
|
+
collectionId?: number;
|
|
113
|
+
url: string;
|
|
114
|
+
title?: string;
|
|
115
|
+
note?: string;
|
|
116
|
+
excerpt?: string;
|
|
117
|
+
tags?: string[];
|
|
118
|
+
metadata?: {
|
|
119
|
+
[key: string]: Json;
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
declare const RAINDROP_TOKEN_ENDPOINT = "https://api.raindrop.io/v1/oauth/access_token";
|
|
123
|
+
declare function validateRaindropCreateBookmark(value: unknown): RaindropCreateBookmarkInput;
|
|
124
|
+
declare function createRaindropClient(config: RaindropClientConfig): {
|
|
125
|
+
request: (path: string, options?: Omit<ProviderRequestOptions, "accessToken" | "clientId" | "clientSecret">) => Promise<unknown>;
|
|
126
|
+
listCollections: (input?: {
|
|
127
|
+
cursor?: string;
|
|
128
|
+
query?: string;
|
|
129
|
+
parentId?: string;
|
|
130
|
+
}) => Promise<ResourcePage>;
|
|
131
|
+
resources: (input?: {
|
|
132
|
+
cursor?: string;
|
|
133
|
+
query?: string;
|
|
134
|
+
parentId?: string;
|
|
135
|
+
}) => Promise<ResourcePage>;
|
|
136
|
+
createBookmark: (value: RaindropCreateBookmarkInput) => Promise<{
|
|
137
|
+
id: string;
|
|
138
|
+
url: string;
|
|
139
|
+
collectionId: number;
|
|
140
|
+
}>;
|
|
141
|
+
};
|
|
142
|
+
declare function createRaindropProvider(config: RaindropProviderConfig): IntegrationProvider;
|
|
143
|
+
|
|
144
|
+
export { type AppleProviderConfig, type GitHubProviderConfig, type GoogleProviderConfig, type IdentityProviderConfig, NOTION_API_VERSION, type NotionClientConfig, type NotionCreatePageInput, type NotionProviderConfig, ProviderHttpError, type ProviderRequestOptions, RAINDROP_TOKEN_ENDPOINT, type RaindropClientConfig, type RaindropCreateBookmarkInput, type RaindropProviderConfig, createAppleProvider, createGitHubProvider, createGoogleProvider, createNotionClient, createNotionProvider, createRaindropClient, createRaindropProvider, notionRequest, raindropRequest, validateNotionCreatePage, validateRaindropCreateBookmark };
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { d as IntegrationProvider, J as Json, R as ResourcePage } from '../types-Y4-DoJ1A.js';
|
|
2
|
+
import { I as IntegrationError, F as FailureDisposition } from '../errors-3hDEtzuZ.js';
|
|
3
|
+
|
|
4
|
+
type IdentityProviderConfig = {
|
|
5
|
+
registrationId: string;
|
|
6
|
+
identityNamespace?: string;
|
|
7
|
+
clientId: string;
|
|
8
|
+
redirectUri: string;
|
|
9
|
+
};
|
|
10
|
+
type GoogleProviderConfig = IdentityProviderConfig & {
|
|
11
|
+
clientSecret?: string;
|
|
12
|
+
nativeClientIds?: readonly string[];
|
|
13
|
+
};
|
|
14
|
+
type AppleProviderConfig = IdentityProviderConfig & {
|
|
15
|
+
teamId?: string;
|
|
16
|
+
keyId?: string;
|
|
17
|
+
privateKey?: string;
|
|
18
|
+
nativeClientIds?: readonly string[];
|
|
19
|
+
};
|
|
20
|
+
type GitHubProviderConfig = IdentityProviderConfig & {
|
|
21
|
+
clientSecret: string;
|
|
22
|
+
};
|
|
23
|
+
declare function createGoogleProvider(config: GoogleProviderConfig): IntegrationProvider;
|
|
24
|
+
declare function createAppleProvider(config: AppleProviderConfig): IntegrationProvider;
|
|
25
|
+
declare function createGitHubProvider(config: GitHubProviderConfig): IntegrationProvider;
|
|
26
|
+
|
|
27
|
+
type ProviderRequestOptions = {
|
|
28
|
+
accessToken?: string;
|
|
29
|
+
clientId?: string;
|
|
30
|
+
clientSecret?: string;
|
|
31
|
+
method?: string;
|
|
32
|
+
body?: unknown;
|
|
33
|
+
signal?: AbortSignal;
|
|
34
|
+
fetch?: typeof globalThis.fetch;
|
|
35
|
+
apiVersion?: string;
|
|
36
|
+
};
|
|
37
|
+
/** Contains only safe classifications and validated receipt IDs, never upstream messages. */
|
|
38
|
+
declare class ProviderHttpError extends IntegrationError {
|
|
39
|
+
readonly status: number | null;
|
|
40
|
+
readonly providerCode?: string;
|
|
41
|
+
readonly definite: boolean;
|
|
42
|
+
readonly committedResourceId?: string;
|
|
43
|
+
readonly committedChildIds?: string[];
|
|
44
|
+
constructor(code: string, disposition: FailureDisposition, options?: {
|
|
45
|
+
status?: number;
|
|
46
|
+
providerCode?: string;
|
|
47
|
+
definite?: boolean;
|
|
48
|
+
retryAfterMs?: number;
|
|
49
|
+
committedResourceId?: string;
|
|
50
|
+
committedChildIds?: string[];
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
declare function notionRequest(path: string, options: ProviderRequestOptions): Promise<unknown>;
|
|
54
|
+
declare function raindropRequest(path: string, options: ProviderRequestOptions): Promise<unknown>;
|
|
55
|
+
|
|
56
|
+
declare const NOTION_API_VERSION = "2026-03-11";
|
|
57
|
+
type NotionProviderConfig = {
|
|
58
|
+
registrationId: string;
|
|
59
|
+
clientId: string;
|
|
60
|
+
clientSecret: string;
|
|
61
|
+
redirectUri: string;
|
|
62
|
+
apiVersion?: string;
|
|
63
|
+
};
|
|
64
|
+
type NotionClientConfig = {
|
|
65
|
+
accessToken: string;
|
|
66
|
+
fetch?: typeof globalThis.fetch;
|
|
67
|
+
signal?: AbortSignal;
|
|
68
|
+
apiVersion?: string;
|
|
69
|
+
};
|
|
70
|
+
type NotionCreatePageInput = {
|
|
71
|
+
parentId: string;
|
|
72
|
+
parentType?: "page" | "data_source";
|
|
73
|
+
title: string;
|
|
74
|
+
content?: string;
|
|
75
|
+
url?: string;
|
|
76
|
+
metadata?: {
|
|
77
|
+
[key: string]: Json;
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
declare function validateNotionCreatePage(value: unknown): NotionCreatePageInput;
|
|
81
|
+
declare function createNotionClient(config: NotionClientConfig): {
|
|
82
|
+
request: (path: string, options?: Omit<ProviderRequestOptions, "accessToken" | "clientId" | "clientSecret">) => Promise<unknown>;
|
|
83
|
+
listResources: (input?: {
|
|
84
|
+
cursor?: string;
|
|
85
|
+
query?: string;
|
|
86
|
+
parentId?: string;
|
|
87
|
+
}) => Promise<ResourcePage>;
|
|
88
|
+
resources: (input?: {
|
|
89
|
+
cursor?: string;
|
|
90
|
+
query?: string;
|
|
91
|
+
parentId?: string;
|
|
92
|
+
}) => Promise<ResourcePage>;
|
|
93
|
+
createPage: (value: NotionCreatePageInput) => Promise<{
|
|
94
|
+
id: string;
|
|
95
|
+
url: string;
|
|
96
|
+
}>;
|
|
97
|
+
};
|
|
98
|
+
declare function createNotionProvider(config: NotionProviderConfig): IntegrationProvider;
|
|
99
|
+
|
|
100
|
+
type RaindropProviderConfig = {
|
|
101
|
+
registrationId: string;
|
|
102
|
+
clientId: string;
|
|
103
|
+
clientSecret: string;
|
|
104
|
+
redirectUri: string;
|
|
105
|
+
};
|
|
106
|
+
type RaindropClientConfig = {
|
|
107
|
+
accessToken: string;
|
|
108
|
+
fetch?: typeof globalThis.fetch;
|
|
109
|
+
signal?: AbortSignal;
|
|
110
|
+
};
|
|
111
|
+
type RaindropCreateBookmarkInput = {
|
|
112
|
+
collectionId?: number;
|
|
113
|
+
url: string;
|
|
114
|
+
title?: string;
|
|
115
|
+
note?: string;
|
|
116
|
+
excerpt?: string;
|
|
117
|
+
tags?: string[];
|
|
118
|
+
metadata?: {
|
|
119
|
+
[key: string]: Json;
|
|
120
|
+
};
|
|
121
|
+
};
|
|
122
|
+
declare const RAINDROP_TOKEN_ENDPOINT = "https://api.raindrop.io/v1/oauth/access_token";
|
|
123
|
+
declare function validateRaindropCreateBookmark(value: unknown): RaindropCreateBookmarkInput;
|
|
124
|
+
declare function createRaindropClient(config: RaindropClientConfig): {
|
|
125
|
+
request: (path: string, options?: Omit<ProviderRequestOptions, "accessToken" | "clientId" | "clientSecret">) => Promise<unknown>;
|
|
126
|
+
listCollections: (input?: {
|
|
127
|
+
cursor?: string;
|
|
128
|
+
query?: string;
|
|
129
|
+
parentId?: string;
|
|
130
|
+
}) => Promise<ResourcePage>;
|
|
131
|
+
resources: (input?: {
|
|
132
|
+
cursor?: string;
|
|
133
|
+
query?: string;
|
|
134
|
+
parentId?: string;
|
|
135
|
+
}) => Promise<ResourcePage>;
|
|
136
|
+
createBookmark: (value: RaindropCreateBookmarkInput) => Promise<{
|
|
137
|
+
id: string;
|
|
138
|
+
url: string;
|
|
139
|
+
collectionId: number;
|
|
140
|
+
}>;
|
|
141
|
+
};
|
|
142
|
+
declare function createRaindropProvider(config: RaindropProviderConfig): IntegrationProvider;
|
|
143
|
+
|
|
144
|
+
export { type AppleProviderConfig, type GitHubProviderConfig, type GoogleProviderConfig, type IdentityProviderConfig, NOTION_API_VERSION, type NotionClientConfig, type NotionCreatePageInput, type NotionProviderConfig, ProviderHttpError, type ProviderRequestOptions, RAINDROP_TOKEN_ENDPOINT, type RaindropClientConfig, type RaindropCreateBookmarkInput, type RaindropProviderConfig, createAppleProvider, createGitHubProvider, createGoogleProvider, createNotionClient, createNotionProvider, createRaindropClient, createRaindropProvider, notionRequest, raindropRequest, validateNotionCreatePage, validateRaindropCreateBookmark };
|