@dropthis/cli 0.33.2 → 0.35.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/publish/node.ts","../src/errors.ts","../src/publish/checksum.ts","../src/publish/detect.ts","../src/publish/paths.ts","../src/publish/core.ts","../src/publish/files.ts","../src/resources/account.ts","../src/resources/api-keys.ts","../src/resources/auth.ts","../src/resources/deployments.ts","../src/resources/domains.ts","../src/pagination.ts","../src/resources/drops.ts","../src/resources/invitations.ts","../src/resources/members.ts","../src/resources/uploads.ts","../src/resources/workspaces.ts","../src/case.ts","../src/transport.ts","../src/dropthis.ts","../src/types.ts"],"sourcesContent":["import { readFile, stat } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\nimport { PublishInputError } from \"../errors.js\";\nimport type { PublishInput, PublishOptions } from \"../types.js\";\nimport { sha256File } from \"./checksum.js\";\nimport {\n\tbuildStagedRequest,\n\ttype InMemoryPublishInput,\n\ttype PreparedPublishRequest,\n\ttype PreparedUploadFile,\n\tresolveInMemory,\n} from \"./core.js\";\nimport { isHttpUrl, isPathShaped } from \"./detect.js\";\nimport type { PublishFile } from \"./files.js\";\nimport { collectPublishFiles, detectPathContentType } from \"./files.js\";\nimport { assertValidManifestPath } from \"./paths.js\";\n\n/**\n * Files at or above this size get a precomputed sha256 so the server can verify\n * the signed upload. Smaller files skip the hash to keep publishes snappy.\n * Matches the threshold the legacy prepare.ts used.\n */\nconst SINGLE_PUT_CHECKSUM_THRESHOLD = 10 * 1024 * 1024;\n\n/**\n * Resolves any {@link PublishInput} into a {@link PreparedPublishRequest},\n * adding filesystem support on top of the pure in-memory resolver in core.ts.\n *\n * - URL / Uint8Array / `{ kind }` objects → delegate to {@link resolveInMemory}.\n * - `string[]` → a local bundle of files/directories.\n * - bare `string` → stat-first: http URL → source; multiline/oversized → inline\n * content; otherwise stat the path (file/dir) or treat as inline prose.\n */\nexport async function resolveInput(\n\tinput: PublishInput,\n\toptions: PublishOptions = {},\n): Promise<PreparedPublishRequest> {\n\tif (\n\t\tinput instanceof URL ||\n\t\tinput instanceof Uint8Array ||\n\t\t(typeof input === \"object\" && input !== null && \"kind\" in input)\n\t) {\n\t\treturn resolveInMemory(input as InMemoryPublishInput, options);\n\t}\n\n\tif (Array.isArray(input)) {\n\t\treturn resolveBundle(input, options);\n\t}\n\n\tif (typeof input === \"string\") {\n\t\treturn resolveString(input, options);\n\t}\n\n\t// Exhaustive: the PublishInput union has no other members.\n\treturn resolveInMemory(input as InMemoryPublishInput, options);\n}\n\n/**\n * Bare-string resolution. ORDER MATTERS:\n * 1. http(s) URL → source. MUST precede stat: a URL is path-shaped (has \"/\"),\n * so a stat/path-shaped check first would wrongly report file_not_found.\n * 2. multiline or oversized (>4096) → inline content (cannot be a path).\n * 3. stat the value: file → fileStaged, dir → folderStaged, missing →\n * file_not_found if path-shaped, else inline prose content.\n */\nasync function resolveString(\n\tvalue: string,\n\toptions: PublishOptions,\n): Promise<PreparedPublishRequest> {\n\tif (isHttpUrl(value)) return resolveInMemory(value, options);\n\tif (value.includes(\"\\n\") || value.length > 4096) {\n\t\treturn resolveInMemory(value, options);\n\t}\n\n\tlet info: Awaited<ReturnType<typeof stat>> | undefined;\n\ttry {\n\t\tinfo = await stat(value);\n\t} catch {\n\t\tinfo = undefined;\n\t}\n\n\tif (info?.isFile()) return fileStaged(value, options);\n\tif (info?.isDirectory()) return folderStaged(value, options);\n\n\tif (isPathShaped(value)) {\n\t\tthrow new PublishInputError(\n\t\t\t\"file_not_found\",\n\t\t\t`No file or directory at \"${value}\".`,\n\t\t\tvalue,\n\t\t\t'To publish this as inline text, pass { kind: \"content\", content }.',\n\t\t);\n\t}\n\treturn resolveInMemory(value, options);\n}\n\n/** Stages a single local file. Defers the entry to buildStagedRequest. */\nasync function fileStaged(\n\tpath: string,\n\toptions: PublishOptions,\n): Promise<PreparedPublishRequest> {\n\tconst fileStat = await stat(path);\n\tif (options.path !== undefined) assertValidManifestPath(options.path);\n\tconst manifestPath = options.path ?? basename(path);\n\tconst contentType =\n\t\toptions.contentType ?? (await detectPathContentType(path));\n\tconst checksumSha256 =\n\t\tfileStat.size > SINGLE_PUT_CHECKSUM_THRESHOLD\n\t\t\t? await sha256File(path)\n\t\t\t: undefined;\n\tconst file: PreparedUploadFile = {\n\t\tpath: manifestPath,\n\t\tcontentType,\n\t\tsizeBytes: fileStat.size,\n\t\t...(checksumSha256 ? { checksumSha256 } : {}),\n\t\tgetBody: () => readFile(path),\n\t};\n\treturn buildStagedRequest([file], options);\n}\n\n/** Stages every file under a local directory (tree-relative manifest paths). */\nasync function folderStaged(\n\tpath: string,\n\toptions: PublishOptions,\n): Promise<PreparedPublishRequest> {\n\tconst files = await collectPublishFiles(path, options);\n\tconst preparedFiles = await Promise.all(files.map(toPreparedFile));\n\treturn buildStagedRequest(preparedFiles, options);\n}\n\n/**\n * Stages a list of local file/directory paths. Each element is statted (missing\n * → file_not_found) then expanded via collectPublishFiles (basename for a file,\n * tree-relative for a directory). Basename collisions across elements surface as\n * duplicate_path from buildStagedRequest.\n */\nasync function resolveBundle(\n\tpaths: string[],\n\toptions: PublishOptions,\n): Promise<PreparedPublishRequest> {\n\tconst collected: PublishFile[] = [];\n\tfor (const element of paths) {\n\t\ttry {\n\t\t\tawait stat(element);\n\t\t} catch {\n\t\t\tthrow new PublishInputError(\n\t\t\t\t\"file_not_found\",\n\t\t\t\t`No file or directory at \"${element}\".`,\n\t\t\t\telement,\n\t\t\t);\n\t\t}\n\t\tcollected.push(...(await collectPublishFiles(element, options)));\n\t}\n\tconst preparedFiles = await Promise.all(collected.map(toPreparedFile));\n\treturn buildStagedRequest(preparedFiles, options);\n}\n\n/** Maps a collected PublishFile to a lazy-body PreparedUploadFile. */\nasync function toPreparedFile(pf: PublishFile): Promise<PreparedUploadFile> {\n\tconst checksumSha256 =\n\t\tpf.sizeBytes > SINGLE_PUT_CHECKSUM_THRESHOLD\n\t\t\t? await sha256File(pf.absolutePath)\n\t\t\t: undefined;\n\treturn {\n\t\tpath: pf.path,\n\t\tcontentType: pf.contentType,\n\t\tsizeBytes: pf.sizeBytes,\n\t\t...(checksumSha256 ? { checksumSha256 } : {}),\n\t\tgetBody: () => readFile(pf.absolutePath),\n\t};\n}\n","import type { DropthisResult } from \"./types.js\";\n\nconst API_KEY_RE = /sk_[A-Za-z0-9_-]+/g;\n\nexport function redactSecrets(message: string): string {\n\treturn message.replace(API_KEY_RE, \"sk_[redacted]\");\n}\n\nexport function createErrorResult<T>(\n\tcode: string,\n\tmessage: string,\n\tstatusCode: number | null,\n\textra: {\n\t\ttype?: string;\n\t\ttitle?: string;\n\t\tdetail?: string | null;\n\t\tinstance?: string | null;\n\t\tparam?: string | null;\n\t\tcurrentRevision?: number;\n\t\trequestId?: string | null;\n\t\theaders?: Record<string, string>;\n\t\tsuggestion?: string | null;\n\t\tretryable?: boolean | null;\n\t\t// Plan-gate fields (feature_not_in_plan / quota_exceeded — the unified\n\t\t// gate contract). Present only on plan denials; null/absent otherwise.\n\t\tfeature?: string | null;\n\t\tcurrentPlan?: string | null;\n\t\trequiredPlan?: string | null;\n\t\tupgradeUrl?: string | null;\n\t\tlimit?: number | null;\n\t\tused?: number | null;\n\t\trequested?: number | null;\n\t\tbody?: unknown;\n\t} = {},\n): DropthisResult<T> {\n\treturn {\n\t\tdata: null,\n\t\terror: {\n\t\t\tcode,\n\t\t\tmessage: redactSecrets(message),\n\t\t\tstatusCode,\n\t\t\t...(extra.type ? { type: extra.type } : {}),\n\t\t\t...(extra.title !== undefined ? { title: extra.title } : {}),\n\t\t\t...(extra.detail !== undefined ? { detail: extra.detail } : {}),\n\t\t\t...(extra.instance !== undefined ? { instance: extra.instance } : {}),\n\t\t\t...(extra.param !== undefined ? { param: extra.param } : {}),\n\t\t\t...(extra.currentRevision !== undefined\n\t\t\t\t? { currentRevision: extra.currentRevision }\n\t\t\t\t: {}),\n\t\t\t...(extra.requestId !== undefined ? { requestId: extra.requestId } : {}),\n\t\t\t...(extra.suggestion !== undefined\n\t\t\t\t? { suggestion: extra.suggestion }\n\t\t\t\t: {}),\n\t\t\t...(extra.retryable !== undefined ? { retryable: extra.retryable } : {}),\n\t\t\t...(extra.feature != null ? { feature: extra.feature } : {}),\n\t\t\t...(extra.currentPlan != null ? { currentPlan: extra.currentPlan } : {}),\n\t\t\t...(extra.requiredPlan != null\n\t\t\t\t? { requiredPlan: extra.requiredPlan }\n\t\t\t\t: {}),\n\t\t\t...(extra.upgradeUrl != null ? { upgradeUrl: extra.upgradeUrl } : {}),\n\t\t\t...(extra.limit != null ? { limit: extra.limit } : {}),\n\t\t\t...(extra.used != null ? { used: extra.used } : {}),\n\t\t\t...(extra.requested != null ? { requested: extra.requested } : {}),\n\t\t\t...(extra.body !== undefined ? { body: extra.body } : {}),\n\t\t},\n\t\theaders: extra.headers ?? {},\n\t};\n}\n\n/** True for a capability denial (`feature_not_in_plan`) — a plan gate, never retryable. */\nexport function isFeatureNotInPlan(error: { code: string } | null): boolean {\n\treturn error?.code === \"feature_not_in_plan\";\n}\n\n/** True for a numeric-ceiling denial (`quota_exceeded`: per-drop bytes 413, or an\n * account ceiling 403). Never retryable — a plan ceiling does not free up on retry. */\nexport function isQuotaExceeded(error: { code: string } | null): boolean {\n\treturn error?.code === \"quota_exceeded\";\n}\n\n/** True for either plan-gate code — branch a retry layer on this to stop and\n * hand off to a human instead of re-issuing a request that can never succeed. */\nexport function isPlanGate(error: { code: string } | null): boolean {\n\treturn isFeatureNotInPlan(error) || isQuotaExceeded(error);\n}\n\nexport class PublishInputError extends Error {\n\tconstructor(\n\t\treadonly code: string,\n\t\tmessage: string,\n\t\treadonly param?: string,\n\t\treadonly suggestion?: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"PublishInputError\";\n\t}\n}\n\nexport function toErrorResult<T>(err: unknown): DropthisResult<T> {\n\tif (err instanceof PublishInputError)\n\t\treturn createErrorResult<T>(err.code, err.message, null, {\n\t\t\tparam: err.param ?? null,\n\t\t\tsuggestion: err.suggestion ?? null,\n\t\t});\n\treturn createErrorResult<T>(\n\t\t\"sdk_error\",\n\t\terr instanceof Error ? err.message : \"Unknown SDK error\",\n\t\tnull,\n\t);\n}\n","import { createHash } from \"node:crypto\";\nimport { createReadStream } from \"node:fs\";\n\nexport function sha256Bytes(bytes: Uint8Array): string {\n\treturn createHash(\"sha256\").update(bytes).digest(\"hex\");\n}\n\nexport async function sha256File(path: string): Promise<string> {\n\tconst hash = createHash(\"sha256\");\n\tfor await (const chunk of createReadStream(path)) {\n\t\thash.update(chunk);\n\t}\n\treturn hash.digest(\"hex\");\n}\n","export function isHttpUrl(value: string): boolean {\n\ttry {\n\t\tconst url = new URL(value);\n\t\treturn url.protocol === \"http:\" || url.protocol === \"https:\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport function containsHtmlTag(value: string): boolean {\n\treturn /<[a-z!/][^>]*>/i.test(value);\n}\n\nconst FILE_EXT = /\\.[A-Za-z0-9]{1,8}([?#].*)?$/;\nexport function isPathShaped(value: string): boolean {\n\tif (value.length === 0 || value.length > 4096 || value.includes(\"\\n\"))\n\t\treturn false;\n\t// Reject strings that look like HTML (tags disqualify path interpretation)\n\tif (containsHtmlTag(value)) return false;\n\tif (value.includes(\"/\") || value.includes(\"\\\\\")) return true;\n\tif (/^[A-Za-z]:[\\\\/]/.test(value)) return true;\n\treturn FILE_EXT.test(value);\n}\n\nexport function contentTypeForString(value: string, override?: string): string {\n\tif (override) return override;\n\treturn containsHtmlTag(value) ? \"text/html\" : \"text/plain; charset=utf-8\";\n}\n\nexport function detectBytesContentType(bytes: Uint8Array): string {\n\tconst text = new TextDecoder(\"utf-8\", { fatal: false }).decode(bytes);\n\tif (text.includes(\"�\")) return \"application/octet-stream\";\n\treturn containsHtmlTag(text) ? \"text/html\" : \"text/plain; charset=utf-8\";\n}\n\nexport function entryForContentType(contentType: string): string {\n\tconst m = contentType.toLowerCase().split(\";\", 1)[0]?.trim() ?? \"\";\n\tif (m === \"text/html\" || m === \"application/xhtml+xml\") return \"index.html\";\n\tif (m === \"application/json\") return \"index.json\";\n\tif (m === \"text/css\") return \"index.css\";\n\tif (m === \"text/javascript\" || m === \"application/javascript\")\n\t\treturn \"index.js\";\n\tif (m.startsWith(\"text/\")) return \"index.txt\";\n\treturn \"index\";\n}\n","import { PublishInputError } from \"../errors.js\";\n\nexport function normalizeManifestPath(path: string): string {\n\treturn path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n}\n\nexport function assertValidManifestPath(path: string): void {\n\t// User-supplied manifest paths ({kind:\"files\"}.path, options.path, options.entry) must be POSIX.\n\t// Local filesystem paths are normalized via normalizeManifestPath, NOT passed here.\n\tif (path.includes(\"\\\\\"))\n\t\tthrow new PublishInputError(\n\t\t\t\"invalid_path\",\n\t\t\t`Manifest path must use \"/\": \"${path}\".`,\n\t\t\tpath,\n\t\t);\n\tconst p = normalizeManifestPath(path);\n\tif (p === \"\")\n\t\tthrow new PublishInputError(\n\t\t\t\"invalid_path\",\n\t\t\t\"Manifest path must not be empty.\",\n\t\t\tpath,\n\t\t);\n\tif (p.startsWith(\"/\"))\n\t\tthrow new PublishInputError(\n\t\t\t\"invalid_path\",\n\t\t\t`Manifest path must be relative: \"${path}\".`,\n\t\t\tpath,\n\t\t);\n\tif (p.startsWith(\"~\"))\n\t\tthrow new PublishInputError(\n\t\t\t\"invalid_path\",\n\t\t\t`Manifest path must not start with \"~\": \"${path}\".`,\n\t\t\tpath,\n\t\t);\n\tif (p.split(\"/\").includes(\"..\"))\n\t\tthrow new PublishInputError(\n\t\t\t\"invalid_path\",\n\t\t\t`Manifest path must not contain \"..\": \"${path}\".`,\n\t\t\tpath,\n\t\t);\n}\n\nexport function assertNoDuplicatePaths(paths: string[]): void {\n\tconst seen = new Set<string>();\n\tfor (const raw of paths) {\n\t\tconst p = normalizeManifestPath(raw);\n\t\tif (seen.has(p))\n\t\t\tthrow new PublishInputError(\n\t\t\t\t\"duplicate_path\",\n\t\t\t\t`Duplicate file path after normalization: \"${p}\".`,\n\t\t\t\tp,\n\t\t\t\t\"Give each file a unique path; basename mapping for string[] can collide.\",\n\t\t\t);\n\t\tseen.add(p);\n\t}\n}\n\nexport function assertNonEmptyBundle(paths: string[]): void {\n\tif (paths.length === 0)\n\t\tthrow new PublishInputError(\n\t\t\t\"empty_bundle\",\n\t\t\t\"Nothing to publish: the bundle has no files.\",\n\t\t\tundefined,\n\t\t\t\"Pass at least one file, or a directory that contains files.\",\n\t\t);\n}\n","import { createErrorResult, PublishInputError } from \"../errors.js\";\nimport type { Transport } from \"../transport.js\";\nimport type {\n\tCreateUploadSessionFileResponse,\n\tCreateUploadSessionRequest,\n\tCreateUploadSessionResponse,\n\tDropResponse,\n\tDropthisResult,\n\tIngestSessionResponse,\n\tPublishFileInput,\n\tPublishOptions,\n\tUpdateContentOptions,\n\tUploadManifestFile,\n\tUploadSessionResponse,\n} from \"../types.js\";\nimport {\n\tcontentTypeForString,\n\tdetectBytesContentType,\n\tentryForContentType,\n\tisHttpUrl,\n} from \"./detect.js\";\nimport {\n\tassertNoDuplicatePaths,\n\tassertNonEmptyBundle,\n\tassertValidManifestPath,\n\tnormalizeManifestPath,\n} from \"./paths.js\";\n\n/**\n * A file ready to be staged for upload. Two shapes:\n *\n * - **client-put** — the SDK pushes the bytes. The body is lazy: the orchestrator\n * calls `getBody()` per file when it is ready to push bytes to the signed URL.\n * This keeps the resolution layer pure and lets the filesystem layer (node.ts)\n * defer reads/streams until upload time.\n * - **remote** (`sourceUrl` set, no `getBody`) — the server fetches the bytes from\n * `sourceUrl` during `POST /uploads/{id}/ingest`. No bytes leave this process, so\n * it has no `getBody`, no `sizeBytes`, and consumes no signed PUT target.\n */\nexport type PreparedUploadFile =\n\t| {\n\t\t\tpath: string;\n\t\t\tcontentType: string;\n\t\t\tsizeBytes: number;\n\t\t\tchecksumSha256?: string;\n\t\t\tsourceUrl?: never;\n\t\t\tgetBody(): Promise<Uint8Array | Blob | ReadableStream>;\n\t }\n\t| {\n\t\t\tpath: string;\n\t\t\tsourceUrl: string;\n\t\t\tcontentType?: string;\n\t\t\t/** Optional hint: declared byte size for upfront quota admission (server-side). */\n\t\t\tsizeBytes?: number;\n\t\t\t/** Optional hint: expected SHA-256 hex digest for server-side integrity check. */\n\t\t\tchecksumSha256?: string;\n\t\t\tgetBody?: never;\n\t };\n\n/**\n * Resolves a publish input into a {@link PreparedPublishRequest}. Two implementations exist:\n * the fs-free {@link resolveInMemory} (Workers-safe) and the fs-capable `resolveInput` in\n * `publish/node.ts`. `DropsResource` takes one by injection so it can power both the Node client\n * and the edge client WITHOUT statically importing the Node-only pipeline (which would poison the\n * Workers bundle with `node:fs`/`fast-glob`). `TInput` is the input type the chosen resolver\n * accepts ({@link InMemoryPublishInput} on the edge, the full `PublishInput` on Node).\n */\nexport type PublishInputResolver<TInput> = (\n\tinput: TInput,\n\toptions: PublishOptions,\n) => Promise<PreparedPublishRequest>;\n\nexport type PreparedPublishRequest =\n\t| {\n\t\t\tkind: \"staged\";\n\t\t\tmanifest: CreateUploadSessionRequest;\n\t\t\tfiles: PreparedUploadFile[];\n\t\t\toptions: Record<string, unknown>;\n\t\t\tmetadata?: Record<string, unknown>;\n\t\t\t/** Target workspace slug or id (delegated credentials only). Bound at upload-session creation. */\n\t\t\tworkspace?: string;\n\t }\n\t| {\n\t\t\tkind: \"source\";\n\t\t\tsourceUrl: string;\n\t\t\toptions: Record<string, unknown>;\n\t\t\tmetadata?: Record<string, unknown>;\n\t\t\t/** Target workspace slug or id (delegated credentials only). Forwarded as top-level field in POST /drops. */\n\t\t\tworkspace?: string;\n\t };\n\n/**\n * The canonical publish inputs that can be resolved with no filesystem access:\n * the {@link PublishInput} union minus `string[]` (which is inherently a list\n * of filesystem paths handled by node.ts).\n */\nexport type InMemoryPublishInput =\n\t| string\n\t| URL\n\t| Uint8Array\n\t| { kind: \"content\"; content: string; contentType?: string; path?: string }\n\t| { kind: \"source_url\"; sourceUrl: string }\n\t| { kind: \"files\"; files: PublishFileInput[]; entry?: string };\n\nconst VALID_VISIBILITIES = [\"public\", \"unlisted\"] as const;\nconst MAX_TITLE_LENGTH = 500;\n\nexport function validatePublishOptions(options: PublishOptions): void {\n\tif (\n\t\toptions.title !== undefined &&\n\t\toptions.title !== null &&\n\t\toptions.title.length > MAX_TITLE_LENGTH\n\t) {\n\t\tthrow new Error(`Title must be ${MAX_TITLE_LENGTH} characters or less.`);\n\t}\n\n\tif (options.visibility !== undefined && options.visibility !== null) {\n\t\tif (\n\t\t\t!(VALID_VISIBILITIES as readonly string[]).includes(options.visibility)\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid visibility \"${options.visibility}\". Use \"public\" or \"unlisted\".`,\n\t\t\t);\n\t\t}\n\t}\n\n\tif (options.expiresAt !== undefined && options.expiresAt !== null) {\n\t\tif (options.expiresAt instanceof Date) {\n\t\t\tif (Number.isNaN(options.expiresAt.getTime())) {\n\t\t\t\tthrow new Error(\"Invalid expiresAt date.\");\n\t\t\t}\n\t\t} else if (typeof options.expiresAt === \"string\") {\n\t\t\tconst parsed = new Date(options.expiresAt);\n\t\t\tif (Number.isNaN(parsed.getTime())) {\n\t\t\t\tthrow new Error(\"Invalid expiresAt date.\");\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport function optionsBody(options: PublishOptions): Record<string, unknown> {\n\tvalidatePublishOptions(options);\n\tconst body: Record<string, unknown> = {};\n\tif (options.title !== undefined) body.title = options.title;\n\tif (options.visibility !== undefined) body.visibility = options.visibility;\n\tif (options.password !== undefined) body.password = options.password;\n\tif (options.noindex !== undefined) body.noindex = options.noindex;\n\tif (options.expiresAt !== undefined) {\n\t\tbody.expiresAt =\n\t\t\toptions.expiresAt instanceof Date\n\t\t\t\t? options.expiresAt.toISOString()\n\t\t\t\t: options.expiresAt;\n\t}\n\tif (options.domain !== undefined) body.domain = options.domain;\n\tif (options.slug !== undefined) body.slug = options.slug;\n\treturn body;\n}\n\n/**\n * Narrow options to the content-only subset for `drops.updateContent()`: a content update ships a\n * new content version and never changes drop settings (title, visibility, password, noindex,\n * expiry, metadata). Picking only content-prep + request controls drops any settings BEFORE\n * prepare, so they are never validated, sent, or applied.\n */\nexport function updateContentOptions(\n\toptions: UpdateContentOptions,\n): UpdateContentOptions {\n\tconst out: UpdateContentOptions = {};\n\tif (options.entry !== undefined) out.entry = options.entry;\n\tif (options.contentType !== undefined) out.contentType = options.contentType;\n\tif (options.path !== undefined) out.path = options.path;\n\tif (options.ignore !== undefined) out.ignore = options.ignore;\n\tif (options.ignoreDefaults !== undefined)\n\t\tout.ignoreDefaults = options.ignoreDefaults;\n\tif (options.idempotencyKey !== undefined)\n\t\tout.idempotencyKey = options.idempotencyKey;\n\tif (options.ifRevision !== undefined) out.ifRevision = options.ifRevision;\n\tif (options.mode !== undefined) out.mode = options.mode;\n\tif (options.deletePaths !== undefined) out.deletePaths = options.deletePaths;\n\treturn out;\n}\n\n/**\n * Builds a staged upload request from already-prepared files. Validates the\n * bundle is non-empty, normalizes manifest paths, and rejects duplicates.\n * Reused by core's in-memory paths AND by node.ts for file/dir/string[] inputs.\n *\n * `entry` argument wins over `options.entry`.\n */\nexport function buildStagedRequest(\n\tfiles: PreparedUploadFile[],\n\toptions: PublishOptions,\n\tentry?: string,\n): PreparedPublishRequest {\n\tassertNonEmptyBundle(files.map((f) => f.path));\n\tconst normalizedPaths = files.map((f) => normalizeManifestPath(f.path));\n\tassertNoDuplicatePaths(normalizedPaths);\n\n\tconst manifestFiles: UploadManifestFile[] = files.map((file) =>\n\t\tfile.sourceUrl !== undefined\n\t\t\t? // Remote entry: the server fetches the bytes on /ingest. Emit sourceUrl\n\t\t\t\t// plus optional metadata hints (contentType, sizeBytes, checksumSha256)\n\t\t\t\t// when the caller declared them. The transport snake_cases all camelCase\n\t\t\t\t// keys to source_url / content_type / size_bytes / checksum_sha256.\n\t\t\t\t{\n\t\t\t\t\tpath: normalizeManifestPath(file.path),\n\t\t\t\t\tsourceUrl: file.sourceUrl,\n\t\t\t\t\t...(file.contentType ? { contentType: file.contentType } : {}),\n\t\t\t\t\t...(file.sizeBytes !== undefined\n\t\t\t\t\t\t? { sizeBytes: file.sizeBytes }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\t...(file.checksumSha256\n\t\t\t\t\t\t? { checksumSha256: file.checksumSha256 }\n\t\t\t\t\t\t: {}),\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\tpath: normalizeManifestPath(file.path),\n\t\t\t\t\tcontentType: file.contentType,\n\t\t\t\t\tsizeBytes: file.sizeBytes,\n\t\t\t\t\t...(file.checksumSha256\n\t\t\t\t\t\t? { checksumSha256: file.checksumSha256 }\n\t\t\t\t\t\t: {}),\n\t\t\t\t},\n\t);\n\n\tconst resolvedEntry = entry ?? options.entry;\n\tif (resolvedEntry !== undefined) assertValidManifestPath(resolvedEntry);\n\tconst manifest: CreateUploadSessionRequest = {\n\t\tschemaVersion: 1,\n\t\tfiles: manifestFiles,\n\t\t...(resolvedEntry ? { entry: resolvedEntry } : {}),\n\t\t...(options.workspace !== undefined\n\t\t\t? { workspace: options.workspace }\n\t\t\t: {}),\n\t};\n\n\tconst prepared: Extract<PreparedPublishRequest, { kind: \"staged\" }> = {\n\t\tkind: \"staged\",\n\t\tmanifest,\n\t\tfiles,\n\t\toptions: optionsBody(options),\n\t};\n\tif (options.metadata) prepared.metadata = options.metadata;\n\tif (options.workspace !== undefined) prepared.workspace = options.workspace;\n\treturn prepared;\n}\n\n/** Builds a `source_url` request (validates http(s)). */\nexport function buildSourceRequest(\n\tsourceUrl: string,\n\toptions: PublishOptions,\n): PreparedPublishRequest {\n\tif (!isHttpUrl(sourceUrl)) {\n\t\tthrow new PublishInputError(\n\t\t\t\"invalid_source_url\",\n\t\t\t\"source_url must be an http(s) URL.\",\n\t\t\tsourceUrl,\n\t\t\t\"Fetch the content first, then pass it as content/files.\",\n\t\t);\n\t}\n\tconst prepared: Extract<PreparedPublishRequest, { kind: \"source\" }> = {\n\t\tkind: \"source\",\n\t\tsourceUrl,\n\t\toptions: optionsBody(options),\n\t};\n\tif (options.metadata) prepared.metadata = options.metadata;\n\tif (options.workspace !== undefined) prepared.workspace = options.workspace;\n\treturn prepared;\n}\n\nfunction decodeBase64(value: string): Uint8Array {\n\tconst binary = atob(value);\n\treturn Uint8Array.from(binary, (c) => c.charCodeAt(0));\n}\n\nfunction fileBytes(file: PublishFileInput): Uint8Array {\n\tif (file.content !== undefined) return new TextEncoder().encode(file.content);\n\tif (file.contentBase64 !== undefined) return decodeBase64(file.contentBase64);\n\tif (file.bytes !== undefined) return file.bytes;\n\tthrow new PublishInputError(\n\t\t\"missing_file_bytes\",\n\t\t`File \"${file.path}\" is missing content bytes.`,\n\t\tfile.path,\n\t\t\"Provide one of content, contentBase64, or bytes, or set sourceUrl.\",\n\t);\n}\n\n/** True when a bundle entry supplies its bytes inline (vs. by reference). */\nfunction hasInlineBytes(file: PublishFileInput): boolean {\n\treturn (\n\t\tfile.content !== undefined ||\n\t\tfile.contentBase64 !== undefined ||\n\t\tfile.bytes !== undefined\n\t);\n}\n\n/**\n * Resolves one `{ kind: \"files\" }` entry into a {@link PreparedUploadFile}.\n * A `sourceUrl` entry becomes a remote file (server fetches it on /ingest) —\n * no bytes leave this process. Optional `contentType`, `sizeBytes`, and\n * `checksumSha256` hints are forwarded to the server for quota admission and\n * integrity verification. Rejects an entry that mixes inline bytes with\n * `sourceUrl`, and a non-http(s) `sourceUrl`.\n */\nfunction prepareBundleFile(file: PublishFileInput): PreparedUploadFile {\n\tassertValidManifestPath(file.path);\n\tif (file.sourceUrl !== undefined) {\n\t\tif (hasInlineBytes(file)) {\n\t\t\tthrow new PublishInputError(\n\t\t\t\t\"conflicting_file_source\",\n\t\t\t\t`File \"${file.path}\" sets both inline content and sourceUrl; pick one.`,\n\t\t\t\tfile.path,\n\t\t\t\t\"Drop sourceUrl to upload bytes, or drop content/contentBase64/bytes to fetch by reference.\",\n\t\t\t);\n\t\t}\n\t\tif (!isHttpUrl(file.sourceUrl)) {\n\t\t\tthrow new PublishInputError(\n\t\t\t\t\"invalid_source_url\",\n\t\t\t\t`File \"${file.path}\" sourceUrl must be an http(s) URL.`,\n\t\t\t\tfile.path,\n\t\t\t\t\"Fetch the bytes first and pass them inline, or use an http(s) URL.\",\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\tpath: file.path,\n\t\t\tsourceUrl: file.sourceUrl,\n\t\t\t...(file.contentType ? { contentType: file.contentType } : {}),\n\t\t\t...(file.sizeBytes !== undefined ? { sizeBytes: file.sizeBytes } : {}),\n\t\t\t...(file.checksumSha256 ? { checksumSha256: file.checksumSha256 } : {}),\n\t\t};\n\t}\n\tconst bytes = fileBytes(file);\n\tconst contentType = file.contentType ?? detectBytesContentType(bytes);\n\treturn {\n\t\tpath: file.path,\n\t\tcontentType,\n\t\tsizeBytes: bytes.byteLength,\n\t\tgetBody: async () => bytes,\n\t};\n}\n\nfunction singleStagedFile(\n\tpath: string,\n\tcontentType: string,\n\tbytes: Uint8Array,\n\toptions: PublishOptions,\n): PreparedPublishRequest {\n\treturn buildStagedRequest(\n\t\t[\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\tcontentType,\n\t\t\t\tsizeBytes: bytes.byteLength,\n\t\t\t\tgetBody: async () => bytes,\n\t\t\t},\n\t\t],\n\t\toptions,\n\t);\n}\n\n/**\n * Resolves the in-memory canonical inputs (the edge subset of {@link PublishInput})\n * into a {@link PreparedPublishRequest}. Performs NO filesystem access.\n */\nexport async function resolveInMemory(\n\tinput: InMemoryPublishInput,\n\toptions: PublishOptions = {},\n): Promise<PreparedPublishRequest> {\n\tif (input instanceof URL) {\n\t\treturn buildSourceRequest(input.toString(), options);\n\t}\n\n\tif (typeof input === \"string\") {\n\t\tif (isHttpUrl(input)) return buildSourceRequest(input, options);\n\t\tconst contentType = contentTypeForString(input, options.contentType);\n\t\tif (options.path !== undefined) assertValidManifestPath(options.path);\n\t\tconst path = options.path ?? entryForContentType(contentType);\n\t\tconst bytes = new TextEncoder().encode(input);\n\t\treturn singleStagedFile(path, contentType, bytes, options);\n\t}\n\n\t// A Node binary buffer is a Uint8Array subclass, so this branch also covers\n\t// it without referencing the Node-only global.\n\tif (input instanceof Uint8Array) {\n\t\tconst contentType = options.contentType ?? detectBytesContentType(input);\n\t\tif (options.path !== undefined) assertValidManifestPath(options.path);\n\t\tconst path = options.path ?? entryForContentType(contentType);\n\t\treturn singleStagedFile(path, contentType, input, options);\n\t}\n\n\tif (input.kind === \"content\") {\n\t\tconst contentType = input.contentType ?? options.contentType ?? \"text/html\";\n\t\tif (input.path !== undefined) assertValidManifestPath(input.path);\n\t\tif (options.path !== undefined) assertValidManifestPath(options.path);\n\t\tconst path = input.path ?? options.path ?? entryForContentType(contentType);\n\t\tconst bytes = new TextEncoder().encode(input.content);\n\t\treturn singleStagedFile(path, contentType, bytes, options);\n\t}\n\n\tif (input.kind === \"source_url\") {\n\t\treturn buildSourceRequest(input.sourceUrl, options);\n\t}\n\n\t// input.kind === \"files\"\n\tconst files: PreparedUploadFile[] = input.files.map(prepareBundleFile);\n\treturn buildStagedRequest(files, options, input.entry);\n}\n\n// ---------------------------------------------------------------------------\n// Orchestration helpers\n// ---------------------------------------------------------------------------\n\ntype StagedPublishOptions = {\n\tidempotencyKey?: string;\n\tifRevision?: number;\n\t/**\n\t * Partial-update mode for a content update (ADR 0065). Emitted as the wire field\n\t * `mode` on the deployment body. Only set by `drops.updateContent()`; `publish()`\n\t * never carries it, so a fresh publish has no mode field.\n\t */\n\tmode?: \"patch\" | \"replace\";\n\t/**\n\t * Paths to delete on a patch-mode content update. Emitted as the wire field\n\t * `delete_paths` on the deployment body. Only set by `drops.updateContent()`.\n\t */\n\tdeletePaths?: string[];\n};\n\n/**\n * The partial-update fields (`mode`, `delete_paths`) for a content-update deployment\n * body, snake_cased by the transport. Only included when set — a fresh publish or a\n * default-mode update omits them entirely.\n */\nfunction partialUpdateBody(\n\toptions: StagedPublishOptions,\n): Record<string, unknown> {\n\treturn {\n\t\t...(options.mode !== undefined ? { mode: options.mode } : {}),\n\t\t...(options.deletePaths !== undefined\n\t\t\t? { deletePaths: options.deletePaths }\n\t\t\t: {}),\n\t};\n}\n\n/** How many signed file PUTs run concurrently during a staged upload. */\nconst UPLOAD_CONCURRENCY = 5;\n\n/**\n * Timeout for `POST /uploads/{id}/ingest`. The server fetches every remote\n * (`sourceUrl`) file over the network during this call, so it can take far\n * longer than a normal control-plane request — give it the upload-sized budget.\n */\nconst INGEST_TIMEOUT_MS = 120_000;\n\nfunction errorResult<T>(result: DropthisResult<unknown>): DropthisResult<T> {\n\tif (!result.error) throw new Error(\"Expected an error result\");\n\treturn { data: null, error: result.error, headers: result.headers };\n}\n\n/** A client-put file paired with its signed target. Remote files never become jobs. */\ntype UploadJob = {\n\tfile: Extract<PreparedUploadFile, { getBody: unknown }>;\n\ttarget: CreateUploadSessionFileResponse;\n};\n\n/**\n * Uploads staged files through their signed PUT targets with bounded parallelism.\n * Fail-fast: the first failure stops new uploads from starting (in-flight ones\n * drain). Returns the lowest-index failure — attributed to its file path — or null\n * when every upload succeeded. Each PUT sends exactly the headers the server signed\n * for that file (this is what carries the checksum contract).\n */\nasync function uploadStagedFiles(\n\ttransport: Transport,\n\tjobs: UploadJob[],\n): Promise<DropthisResult<never> | null> {\n\tlet nextIndex = 0;\n\tlet failed = false;\n\tconst failures = new Map<number, DropthisResult<never>>();\n\n\tasync function worker(): Promise<void> {\n\t\twhile (!failed) {\n\t\t\tconst index = nextIndex;\n\t\t\tnextIndex += 1;\n\t\t\tif (index >= jobs.length) return;\n\t\t\tconst job = jobs[index];\n\t\t\tif (!job) return;\n\t\t\tconst put = await transport.putSignedUrl(\n\t\t\t\tjob.target.upload.url,\n\t\t\t\tawait job.file.getBody(),\n\t\t\t\tjob.target.upload.headers,\n\t\t\t);\n\t\t\tif (put.error) {\n\t\t\t\tfailed = true;\n\t\t\t\tfailures.set(index, {\n\t\t\t\t\tdata: null,\n\t\t\t\t\terror: {\n\t\t\t\t\t\t...put.error,\n\t\t\t\t\t\tmessage: `Upload failed for ${job.file.path}: ${put.error.message}`,\n\t\t\t\t\t},\n\t\t\t\t\theaders: put.headers,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tconst workers = Array.from(\n\t\t{ length: Math.min(UPLOAD_CONCURRENCY, jobs.length) },\n\t\t() => worker(),\n\t);\n\tawait Promise.all(workers);\n\n\tif (failures.size === 0) return null;\n\tconst firstIndex = Math.min(...failures.keys());\n\treturn failures.get(firstIndex) ?? null;\n}\n\n/**\n * Executes the staged-upload publish flow (single-PUT only).\n * Calls POST /uploads → PUT signed URL per file → POST /uploads/{id}/complete\n * → POST finalPath. (Paths are version-agnostic here; the transport prefixes /v1.)\n */\nexport async function publishStaged(\n\ttransport: Transport,\n\tprepared: Extract<PreparedPublishRequest, { kind: \"staged\" }>,\n\tfinalPath: string,\n\toptions: StagedPublishOptions = {},\n): Promise<DropthisResult<DropResponse>> {\n\tconst baseKey = options.idempotencyKey ?? `sdk-${crypto.randomUUID()}`;\n\n\t// Step 1: create upload session\n\tconst createResult = await transport.request<CreateUploadSessionResponse>(\n\t\t\"POST\",\n\t\t\"/uploads\",\n\t\t{\n\t\t\tbody: prepared.manifest,\n\t\t\tidempotencyKey: `${baseKey}:create-upload`,\n\t\t},\n\t);\n\tif (createResult.error) return errorResult(createResult);\n\n\t// Step 2: pair every CLIENT-PUT file with its signed target, then upload via\n\t// bounded-parallel single PUTs. Remote (sourceUrl) files are server-fetched on\n\t// /ingest, so they get no signed target and consume no PUT. Target validation\n\t// happens up front so no bytes move when the session response is malformed.\n\tconst jobs: UploadJob[] = [];\n\tfor (const file of prepared.files) {\n\t\tif (file.sourceUrl !== undefined) continue;\n\t\tconst target = createResult.data.files.find((f) => f.path === file.path);\n\t\tif (!target) {\n\t\t\treturn createErrorResult(\n\t\t\t\t\"upload_target_missing\",\n\t\t\t\t`Upload target missing for ${file.path}`,\n\t\t\t\tnull,\n\t\t\t);\n\t\t}\n\t\tif (target.upload.strategy !== \"single_put\") {\n\t\t\t// Defensive: a single signed PUT per file IS the upload contract — the server\n\t\t\t// only ever assigns single_put. Anything else means a newer server contract\n\t\t\t// this SDK predates.\n\t\t\treturn createErrorResult(\n\t\t\t\t\"unsupported_upload_strategy\",\n\t\t\t\t`Unexpected upload strategy \"${target.upload.strategy}\" for ${file.path}. The dropthis upload contract is one signed PUT per file; update @dropthis/node.`,\n\t\t\t\tnull,\n\t\t\t);\n\t\t}\n\t\tjobs.push({ file, target });\n\t}\n\tconst uploadFailure = await uploadStagedFiles(transport, jobs);\n\tif (uploadFailure) return uploadFailure;\n\n\t// Step 2b: if any manifest entry is remote (sourceUrl), tell the server to fetch\n\t// those files into staging. This runs AFTER the client-put files land and BEFORE\n\t// /complete so the session has every file before it is verified. Server-side\n\t// fetches can be slow, so use an extended timeout.\n\tconst hasRemote = prepared.files.some((f) => f.sourceUrl !== undefined);\n\tif (hasRemote) {\n\t\tconst ingestResult = await transport.request<IngestSessionResponse>(\n\t\t\t\"POST\",\n\t\t\t`/uploads/${encodeURIComponent(createResult.data.uploadId)}/ingest`,\n\t\t\t{\n\t\t\t\tidempotencyKey: `${baseKey}:ingest-upload`,\n\t\t\t\ttimeoutMs: INGEST_TIMEOUT_MS,\n\t\t\t},\n\t\t);\n\t\tif (ingestResult.error) return errorResult(ingestResult);\n\t}\n\n\t// Step 3: complete upload session (no request body — the server verifies the\n\t// staged objects against the manifest)\n\tconst completeResult = await transport.request<UploadSessionResponse>(\n\t\t\"POST\",\n\t\t`/uploads/${encodeURIComponent(createResult.data.uploadId)}/complete`,\n\t\t{\n\t\t\tidempotencyKey: `${baseKey}:complete-upload`,\n\t\t},\n\t);\n\tif (completeResult.error) return errorResult(completeResult);\n\n\t// Step 4: final publish\n\tconst finalOptions: Parameters<Transport[\"request\"]>[2] = {\n\t\tbody: {\n\t\t\tuploadId: createResult.data.uploadId,\n\t\t\t...(Object.keys(prepared.options).length > 0\n\t\t\t\t? { options: prepared.options }\n\t\t\t\t: {}),\n\t\t\t...(prepared.metadata ? { metadata: prepared.metadata } : {}),\n\t\t\t...partialUpdateBody(options),\n\t\t},\n\t\tidempotencyKey: `${baseKey}:publish`,\n\t};\n\tif (options.ifRevision !== undefined)\n\t\tfinalOptions.ifRevision = options.ifRevision;\n\treturn transport.request<DropResponse>(\"POST\", finalPath, finalOptions);\n}\n\n/**\n * Executes the source-URL publish flow.\n * Sends a single POST to finalPath with { sourceUrl, options } and optional metadata.\n */\nexport async function publishSource(\n\ttransport: Transport,\n\tprepared: Extract<PreparedPublishRequest, { kind: \"source\" }>,\n\tfinalPath: string,\n\toptions: StagedPublishOptions = {},\n): Promise<DropthisResult<DropResponse>> {\n\tconst baseKey = options.idempotencyKey ?? `sdk-${crypto.randomUUID()}`;\n\treturn transport.request<DropResponse>(\"POST\", finalPath, {\n\t\tbody: {\n\t\t\tsourceUrl: prepared.sourceUrl,\n\t\t\t...(Object.keys(prepared.options).length > 0\n\t\t\t\t? { options: prepared.options }\n\t\t\t\t: {}),\n\t\t\t...(prepared.metadata ? { metadata: prepared.metadata } : {}),\n\t\t\t...(prepared.workspace !== undefined\n\t\t\t\t? { workspace: prepared.workspace }\n\t\t\t\t: {}),\n\t\t\t...partialUpdateBody(options),\n\t\t},\n\t\tidempotencyKey: `${baseKey}:publish`,\n\t\t...(options.ifRevision !== undefined\n\t\t\t? { ifRevision: options.ifRevision }\n\t\t\t: {}),\n\t});\n}\n","import { readFile, stat } from \"node:fs/promises\";\nimport { basename, sep } from \"node:path\";\nimport fg from \"fast-glob\";\nimport ignore from \"ignore\";\nimport { lookup } from \"mime-types\";\nimport { detectBytesContentType } from \"./detect.js\";\n\nexport type PublishFile = {\n\tabsolutePath: string;\n\tpath: string;\n\tcontentType: string;\n\tsizeBytes: number;\n};\n\nconst DEFAULT_IGNORES = [\n\t\".git\",\n\t\".git/**\",\n\t\"node_modules\",\n\t\"node_modules/**\",\n\t\".DS_Store\",\n\t\".env\",\n\t\".env.*\",\n\t\".cache\",\n\t\".cache/**\",\n\t\".tmp\",\n\t\".tmp/**\",\n\t\"dist/.cache\",\n\t\"dist/.cache/**\",\n];\n\nexport async function collectPublishFiles(\n\tinputPath: string,\n\toptions: { ignore?: string[]; ignoreDefaults?: boolean } = {},\n): Promise<PublishFile[]> {\n\tconst inputStat = await stat(inputPath);\n\tif (inputStat.isFile()) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tabsolutePath: inputPath,\n\t\t\t\tpath: basename(inputPath),\n\t\t\t\tcontentType: await detectPathContentType(inputPath),\n\t\t\t\tsizeBytes: inputStat.size,\n\t\t\t},\n\t\t];\n\t}\n\tif (!inputStat.isDirectory()) {\n\t\tthrow new Error(`Input is not a file or directory: ${inputPath}`);\n\t}\n\n\tconst matcher = ignore().add([\n\t\t...(options.ignoreDefaults === false ? [] : DEFAULT_IGNORES),\n\t\t...(options.ignore ?? []),\n\t]);\n\tconst entries = await fg(\"**/*\", {\n\t\tcwd: inputPath,\n\t\tonlyFiles: true,\n\t\tfollowSymbolicLinks: false,\n\t\tdot: true,\n\t\tunique: true,\n\t});\n\tconst paths = entries\n\t\t.map((entry) => entry.split(sep).join(\"/\"))\n\t\t.filter((entry) => !matcher.ignores(entry))\n\t\t.sort((a, b) => a.localeCompare(b));\n\treturn Promise.all(\n\t\tpaths.map(async (path) => {\n\t\t\tconst absolutePath = `${inputPath}/${path}`;\n\t\t\tconst fileStat = await stat(absolutePath);\n\t\t\treturn {\n\t\t\t\tabsolutePath,\n\t\t\t\tpath,\n\t\t\t\tcontentType: await detectPathContentType(absolutePath),\n\t\t\t\tsizeBytes: fileStat.size,\n\t\t\t};\n\t\t}),\n\t);\n}\n\nexport async function detectPathContentType(path: string): Promise<string> {\n\tconst detected = lookup(path);\n\tif (detected) return detected;\n\treturn detectBytesContentType(await readFile(path));\n}\n","import type { Transport } from \"../transport.js\";\nimport type { AccountResponse, DropthisResult } from \"../types.js\";\n\nexport class AccountResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\tget(): Promise<DropthisResult<AccountResponse>> {\n\t\treturn this.transport.request(\"GET\", \"/account\");\n\t}\n\n\tupdate(input: {\n\t\tdisplayName: string | null;\n\t}): Promise<DropthisResult<AccountResponse>> {\n\t\treturn this.transport.request(\"PATCH\", \"/account\", { body: input });\n\t}\n\n\tdelete(): Promise<DropthisResult<null>> {\n\t\treturn this.transport.request(\"DELETE\", \"/account\");\n\t}\n}\n","import type { Transport } from \"../transport.js\";\nimport type {\n\tApiKeyCreatedResponse,\n\tApiKeyResponse,\n\tDropthisResult,\n\tKeyType,\n} from \"../types.js\";\n\nexport class ApiKeysResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\tlist(): Promise<DropthisResult<{ object: \"list\"; data: ApiKeyResponse[] }>> {\n\t\treturn this.transport.request(\"GET\", \"/api-keys\");\n\t}\n\n\tcreate(input: {\n\t\tlabel: string;\n\t\t/** Key type: `\"delegated\"` (default on server) or `\"service\"` (pinned to a workspace). */\n\t\ttype?: KeyType;\n\t\t/** Pin a `service` key to this workspace slug or id. */\n\t\tworkspace?: string;\n\t\t/** Restrict a `delegated` key to these workspace slugs or ids. */\n\t\tallowedWorkspaces?: string[];\n\t\t/**\n\t\t * Request the credential's capability scopes (ADR 0068). Each entry is a bundle\n\t\t * name (`publish`, `team`, `team-admin`) or a fine-grained scope (`members:admin`).\n\t\t * The minted key gets the requested set intersected with your own scopes\n\t\t * (downscope-only). Omit for the default `publish` bundle; pass `[\"team\"]` to mint\n\t\t * a credential that can create + manage teams (`login --scope team`).\n\t\t */\n\t\tscopes?: string[];\n\t}): Promise<DropthisResult<ApiKeyCreatedResponse>> {\n\t\t// Build the wire body with exact snake_case keys the server expects.\n\t\t// We cannot rely on the transport's auto-conversion for `allowed_workspace_ids`\n\t\t// because `allowedWorkspaces` → `allowed_workspaces`, not `allowed_workspace_ids`.\n\t\tconst body: Record<string, unknown> = { label: input.label };\n\t\tif (input.type !== undefined) body.key_type = input.type;\n\t\tif (input.workspace !== undefined) body.workspace = input.workspace;\n\t\tif (input.allowedWorkspaces !== undefined)\n\t\t\tbody.allowed_workspace_ids = input.allowedWorkspaces;\n\t\tif (input.scopes !== undefined) body.scopes = input.scopes;\n\t\treturn this.transport.request(\"POST\", \"/api-keys\", { body });\n\t}\n\n\t/** Revoke an API key. 204 No Content — data is null on success. */\n\tdelete(keyId: string): Promise<DropthisResult<null>> {\n\t\treturn this.transport.request(\n\t\t\t\"DELETE\",\n\t\t\t`/api-keys/${encodeURIComponent(keyId)}`,\n\t\t);\n\t}\n}\n","import type { Transport } from \"../transport.js\";\nimport type {\n\tDropthisResult,\n\tEmailOtpResponse,\n\tSessionResponse,\n} from \"../types.js\";\n\nexport class AuthResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\trequestEmailOtp(input: {\n\t\temail: string;\n\t}): Promise<DropthisResult<EmailOtpResponse>> {\n\t\treturn this.transport.request(\"POST\", \"/auth/email/otp\", {\n\t\t\tbody: input,\n\t\t\tauthenticated: false,\n\t\t});\n\t}\n\n\t/**\n\t * Verify an email OTP and exchange it for a short-lived `at_` session token.\n\t * On failure the error `code` distinguishes `otp_expired` (no active code —\n\t * request a new one) from `otp_invalid` (wrong digits — re-check, do not\n\t * auto-resend). 401 on either. See dropthis#80.\n\t */\n\tverifyEmailOtp(input: {\n\t\temail: string;\n\t\tcode: string;\n\t}): Promise<DropthisResult<SessionResponse>> {\n\t\treturn this.transport.request(\"POST\", \"/auth/email/verify\", {\n\t\t\tbody: input,\n\t\t\tauthenticated: false,\n\t\t});\n\t}\n\n\t/** Revoke the current `at_` session token. 204 No Content — data is null on success. */\n\tlogout(): Promise<DropthisResult<null>> {\n\t\treturn this.transport.request(\"DELETE\", \"/auth/session\");\n\t}\n}\n","import type { Transport } from \"../transport.js\";\nimport type {\n\tDropDeploymentResponse,\n\tDropthisResult,\n\tListDeploymentsParams,\n\tListDeploymentsResponse,\n} from \"../types.js\";\n\nexport class DeploymentsResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\tlist(\n\t\tdropId: string,\n\t\tparams: ListDeploymentsParams = {},\n\t): Promise<DropthisResult<ListDeploymentsResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"GET\",\n\t\t\t`/drops/${encodeURIComponent(dropId)}/deployments`,\n\t\t\t{ params },\n\t\t);\n\t}\n\n\tget(\n\t\tdropId: string,\n\t\tdeploymentId: string,\n\t): Promise<DropthisResult<DropDeploymentResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"GET\",\n\t\t\t`/drops/${encodeURIComponent(dropId)}/deployments/${encodeURIComponent(deploymentId)}`,\n\t\t);\n\t}\n}\n","import type { Transport } from \"../transport.js\";\nimport type {\n\tDomainDeletedResponse,\n\tDomainListResponse,\n\tDomainResponse,\n\tDropthisResult,\n} from \"../types.js\";\n\nexport class DomainsResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\t/**\n\t * Connect a custom domain to the account. Returns the domain in `pending_dns` status with\n\t * DNS instructions. Idempotent on (account, hostname) — re-connecting an already-connected\n\t * domain returns the existing row. POST /domains.\n\t */\n\tconnect(input: {\n\t\thostname: string;\n\t\tmode: \"path\" | \"dedicated\";\n\t}): Promise<DropthisResult<DomainResponse>> {\n\t\treturn this.transport.request(\"POST\", \"/domains\", { body: input });\n\t}\n\n\t/** List all custom domains connected to this account. GET /domains. */\n\tlist(): Promise<DropthisResult<DomainListResponse>> {\n\t\treturn this.transport.request(\"GET\", \"/domains\");\n\t}\n\n\t/** Get a domain by its stable id or hostname. GET /domains/{id_or_hostname}. */\n\tget(idOrHostname: string): Promise<DropthisResult<DomainResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"GET\",\n\t\t\t`/domains/${encodeURIComponent(idOrHostname)}`,\n\t\t);\n\t}\n\n\t/**\n\t * Trigger a DNS + Cloudflare verification check. Returns the domain with updated status and\n\t * per-record diagnostics. If DNS is still propagating, `dns[].retryAfter` tells you when to\n\t * re-call. POST /domains/{id_or_hostname}/verify.\n\t */\n\tverify(idOrHostname: string): Promise<DropthisResult<DomainResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"POST\",\n\t\t\t`/domains/${encodeURIComponent(idOrHostname)}/verify`,\n\t\t);\n\t}\n\n\t/**\n\t * Update a domain's `dropId` (dedicated mode: repoint to a different drop) or `default`\n\t * flag (path mode only: set/clear the account's default publish domain). Mode is immutable\n\t * — delete and reconnect to change it. PATCH /domains/{id_or_hostname}.\n\t */\n\tupdate(\n\t\tidOrHostname: string,\n\t\tinput: { dropId?: string | null; default?: boolean | null },\n\t): Promise<DropthisResult<DomainResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"PATCH\",\n\t\t\t`/domains/${encodeURIComponent(idOrHostname)}`,\n\t\t\t{ body: input },\n\t\t);\n\t}\n\n\t/**\n\t * Delete a custom domain and remove all its routes. The response includes a dangling-CNAME\n\t * warning — remove the DNS record after deleting so another account cannot re-claim the\n\t * hostname. DELETE /domains/{id_or_hostname}.\n\t */\n\tdelete(idOrHostname: string): Promise<DropthisResult<DomainDeletedResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"DELETE\",\n\t\t\t`/domains/${encodeURIComponent(idOrHostname)}`,\n\t\t);\n\t}\n}\n","import type { DropthisResult, ListPage } from \"./types.js\";\n\nexport class CursorPage<T> implements ListPage<T> {\n\treadonly object = \"list\" as const;\n\treadonly data: T[];\n\treadonly hasMore: boolean;\n\treadonly nextCursor: string | null;\n\t/** Response headers from the fetch that produced this page. */\n\treadonly headers: Record<string, string>;\n\tprivate readonly fetchNextPage:\n\t\t| (() => Promise<DropthisResult<CursorPage<T>>>)\n\t\t| undefined;\n\n\tconstructor(input: {\n\t\tdata: T[];\n\t\thasMore: boolean;\n\t\tnextCursor: string | null;\n\t\theaders?: Record<string, string>;\n\t\tfetchNextPage?: (() => Promise<DropthisResult<CursorPage<T>>>) | undefined;\n\t}) {\n\t\tthis.data = input.data;\n\t\tthis.hasMore = input.hasMore;\n\t\tthis.nextCursor = input.nextCursor;\n\t\tthis.headers = input.headers ?? {};\n\t\tthis.fetchNextPage = input.fetchNextPage;\n\t}\n\n\t/**\n\t * Collect items across every page into a single array.\n\t *\n\t * No-throw, consistent with the rest of the SDK's {@link DropthisResult}\n\t * contract: returns `{ data: items, error: null }` on success, or\n\t * `{ data: null, error }` if fetching a later page fails — never a thrown\n\t * exception, and never a silently truncated list. Inspect `.error`\n\t * (`code`/`statusCode`/`retryable`/`requestId`) exactly as you would for any\n\t * other call. Pass `limit` to stop once that many items are collected.\n\t */\n\tasync autoPagingToArray(\n\t\toptions: { limit?: number } = {},\n\t): Promise<DropthisResult<T[]>> {\n\t\tconst { limit } = options;\n\t\tif (limit !== undefined && limit <= 0) {\n\t\t\treturn { data: [], error: null, headers: this.headers };\n\t\t}\n\t\tconst items: T[] = [];\n\t\tlet current: CursorPage<T> | undefined = this;\n\t\tlet lastHeaders: Record<string, string> = this.headers;\n\n\t\twhile (current) {\n\t\t\tfor (const item of current.data) {\n\t\t\t\titems.push(item);\n\t\t\t\tif (limit !== undefined && items.length >= limit) {\n\t\t\t\t\treturn { data: items, error: null, headers: lastHeaders };\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!current.hasMore || !current.fetchNextPage) break;\n\t\t\tconst next = await current.fetchNextPage();\n\t\t\tif (next.error) {\n\t\t\t\treturn { data: null, error: next.error, headers: next.headers };\n\t\t\t}\n\t\t\tlastHeaders = next.headers;\n\t\t\tcurrent = next.data;\n\t\t}\n\n\t\treturn { data: items, error: null, headers: lastHeaders };\n\t}\n}\n","import { toErrorResult } from \"../errors.js\";\nimport { CursorPage } from \"../pagination.js\";\nimport {\n\ttype PreparedPublishRequest,\n\ttype PublishInputResolver,\n\tpublishSource,\n\tpublishStaged,\n\tupdateContentOptions,\n} from \"../publish/core.js\";\nimport type { Transport } from \"../transport.js\";\nimport type {\n\tDeploymentContentManifest,\n\tDropContentFile,\n\tDropOptions,\n\tDropResponse,\n\tDropthisResult,\n\tGetContentOptions,\n\tListDropsParams,\n\tPublishInput,\n\tPublishOptions,\n\tRequestControls,\n\tUpdateContentOptions,\n} from \"../types.js\";\n\n/**\n * The drop lifecycle resource. `TInput` is the publish-input type the injected resolver accepts:\n * the full `PublishInput` on the Node client, the fs-free `InMemoryPublishInput` on the edge. The\n * resolver is injected (not statically imported) so this module never pulls in the Node-only\n * publish pipeline and stays Workers-safe.\n */\nexport class DropsResource<TInput = PublishInput> {\n\tconstructor(\n\t\tprivate readonly transport: Transport,\n\t\tprivate readonly resolveInput: PublishInputResolver<TInput>,\n\t\tprivate readonly defaultWorkspace?: string,\n\t) {}\n\n\t/**\n\t * Publish content to a NEW permanent public URL; returns the created drop (with its `drop_…` id).\n\t * Use to publish / share / post / put online / make public a report, dashboard, site, or file.\n\t * Creates a NEW drop every call — to change something already published, use {@link updateContent}\n\t * (the files at the URL) or {@link updateSettings} (title, visibility, password, expiry,\n\t * metadata) with the drop's id; calling publish again makes a duplicate. POST /drops.\n\t *\n\t * Mount target: `options.domain` accepts a connected custom hostname, or `SHARED_POOL`\n\t * (`\"shared\"`) to publish to the shared pool even when the account has a default domain.\n\t *\n\t * Two URLs come back on the response: `url` is the canonical, **always-branded** human\n\t * view (badge guaranteed, no client detection); `rawUrl` is the drop's exact bytes at\n\t * their natural path — hand it to other agents. `rawUrl` is populated only for single\n\t * non-HTML files (`renderMode: \"file_viewer\"`) and is `null` for HTML drops and\n\t * collections. To stream bytes through the SDK for any drop kind, use {@link getContent}.\n\t */\n\tasync publish(\n\t\tinput: TInput,\n\t\toptions: PublishOptions = {},\n\t): Promise<DropthisResult<DropResponse>> {\n\t\t// Merge the client-level workspace default ONLY for fresh publish (never for\n\t\t// updateContent, which stays in the drop's own workspace).\n\t\tconst merged: PublishOptions =\n\t\t\tthis.defaultWorkspace !== undefined && options.workspace === undefined\n\t\t\t\t? { ...options, workspace: this.defaultWorkspace }\n\t\t\t\t: options;\n\t\tlet prepared: PreparedPublishRequest;\n\t\ttry {\n\t\t\tprepared = await this.resolveInput(input, merged);\n\t\t} catch (e) {\n\t\t\treturn toErrorResult<DropResponse>(e);\n\t\t}\n\t\treturn prepared.kind === \"source\"\n\t\t\t? publishSource(this.transport, prepared, \"/drops\", merged)\n\t\t\t: publishStaged(this.transport, prepared, \"/drops\", merged);\n\t}\n\n\t/**\n\t * Replace the content of an EXISTING drop, keeping its URL (ships a new deployment). Requires the\n\t * `drop_…` id from a publish response (not the slug/URL). Content-only: settings/metadata are\n\t * stripped BEFORE prepare, so they are never sent — change those with {@link updateSettings}; create\n\t * a new drop with {@link publish}. Not idempotent (each call is a new deployment) unless you pass the\n\t * same `idempotencyKey`. POST /drops/{id}/deployments.\n\t */\n\tasync updateContent(\n\t\tdropId: string,\n\t\tinput: TInput,\n\t\toptions: UpdateContentOptions = {},\n\t): Promise<DropthisResult<DropResponse>> {\n\t\tconst opts = updateContentOptions(options);\n\t\tlet prepared: PreparedPublishRequest;\n\t\ttry {\n\t\t\tprepared = await this.resolveInput(input, opts);\n\t\t} catch (e) {\n\t\t\treturn toErrorResult<DropResponse>(e);\n\t\t}\n\t\tconst path = `/drops/${encodeURIComponent(dropId)}/deployments`;\n\t\treturn prepared.kind === \"source\"\n\t\t\t? publishSource(this.transport, prepared, path, opts)\n\t\t\t: publishStaged(this.transport, prepared, path, opts);\n\t}\n\n\t/**\n\t * List the account's drops, newest first (paginated). Each item carries its `drop_…` id.\n\t * Pass `domain` to only list drops mounted on that custom domain — the recovery path\n\t * when you have a custom-domain URL but no drop id. GET /drops.\n\t */\n\tasync list(\n\t\tparams: ListDropsParams = {},\n\t): Promise<DropthisResult<CursorPage<DropResponse>>> {\n\t\tconst result = await this.transport.request<{\n\t\t\tdrops: DropResponse[];\n\t\t\tnextCursor: string | null;\n\t\t}>(\"GET\", \"/drops\", {\n\t\t\tparams: params as Record<string, string | number | boolean>,\n\t\t});\n\t\tif (result.error) return result;\n\t\tconst page = new CursorPage<DropResponse>({\n\t\t\tdata: result.data.drops,\n\t\t\tnextCursor: result.data.nextCursor,\n\t\t\thasMore: result.data.nextCursor !== null,\n\t\t\theaders: result.headers,\n\t\t\tfetchNextPage: result.data.nextCursor\n\t\t\t\t? () => this.list({ ...params, cursor: result.data.nextCursor })\n\t\t\t\t: undefined,\n\t\t});\n\t\treturn { data: page, error: null, headers: result.headers };\n\t}\n\n\t/** Fetch one drop by its `drop_…` id (not the slug/URL). GET /drops/{id}. */\n\tget(dropId: string): Promise<DropthisResult<DropResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"GET\",\n\t\t\t`/drops/${encodeURIComponent(dropId)}`,\n\t\t);\n\t}\n\n\t/**\n\t * Resolve a public locator (a drop URL, a custom-domain URL, or a bare vanity/shared\n\t * slug) back to the drop — the way to recover a lost `drop_…` id. Sends the raw target\n\t * to the server (POST /drops/resolve), which owner-scopes and decomposes it. Returns the\n\t * full drop, or `data: null` when nothing of yours matches. A `drop_…` id passed as the\n\t * target round-trips to an owner-scoped id lookup (null instead of 404).\n\t *\n\t * Persist the drop_… id. URLs, raw_url, and slugs are locators, not identifiers — a vanity\n\t * slug is renameable and the pool host rotates, so a stored URL can drift; the id never\n\t * moves. Treat drop_… as an opaque case-sensitive string.\n\t */\n\tasync resolve(target: string): Promise<DropthisResult<DropResponse | null>> {\n\t\tconst result = await this.transport.request<{ data: DropResponse | null }>(\n\t\t\t\"POST\",\n\t\t\t\"/drops/resolve\",\n\t\t\t{ body: { target } },\n\t\t);\n\t\tif (result.error)\n\t\t\treturn { data: null, error: result.error, headers: result.headers };\n\t\treturn { data: result.data.data, error: null, headers: result.headers };\n\t}\n\n\t/**\n\t * Read back what a drop is serving (owner-only; works regardless of any viewer\n\t * password). By default returns the JSON manifest of the CURRENT deployment's files;\n\t * pass `deploymentId` to read a historical (even superseded) deployment — downloading\n\t * an old version's files and republishing them via {@link updateContent} is the\n\t * rollback path. Pass `path` (one of the manifest's `files[].path` values) to download\n\t * that file's exact stored bytes instead. GET /drops/{id}/content.\n\t */\n\tgetContent(\n\t\tdropId: string,\n\t\toptions: GetContentOptions & { path: string },\n\t): Promise<DropthisResult<DropContentFile>>;\n\tgetContent(\n\t\tdropId: string,\n\t\toptions?: Omit<GetContentOptions, \"path\">,\n\t): Promise<DropthisResult<DeploymentContentManifest>>;\n\tasync getContent(\n\t\tdropId: string,\n\t\toptions: GetContentOptions = {},\n\t): Promise<DropthisResult<DeploymentContentManifest | DropContentFile>> {\n\t\tconst base =\n\t\t\toptions.deploymentId !== undefined\n\t\t\t\t? `/drops/${encodeURIComponent(dropId)}/deployments/${encodeURIComponent(options.deploymentId)}/content`\n\t\t\t\t: `/drops/${encodeURIComponent(dropId)}/content`;\n\t\tif (options.path === undefined)\n\t\t\treturn this.transport.request<DeploymentContentManifest>(\"GET\", base);\n\t\tconst path = options.path;\n\t\tconst result = await this.transport.requestBytes(base, {\n\t\t\tparams: { path },\n\t\t});\n\t\tif (result.error)\n\t\t\treturn { data: null, error: result.error, headers: result.headers };\n\t\tconst { bytes, contentType } = result.data;\n\t\treturn {\n\t\t\tdata: {\n\t\t\t\tpath,\n\t\t\t\tcontentType,\n\t\t\t\tbytes,\n\t\t\t\ttext: () => new TextDecoder().decode(bytes),\n\t\t\t},\n\t\t\terror: null,\n\t\t\theaders: result.headers,\n\t\t};\n\t}\n\n\t/**\n\t * Change an EXISTING drop's settings — title, visibility, password, noindex, expiry,\n\t * metadata, domain, or slug — by its `drop_…` id. Does not touch content; replace that\n\t * with {@link updateContent}. Idempotent. PATCH /drops/{id}.\n\t *\n\t * **`domain`** — move the drop to a different custom domain (must be live). Pass `null` to\n\t * move the drop back to the shared pool (unmount from its current domain).\n\t *\n\t * **`slug`** — rename the vanity slug on a path-mode custom domain. Only valid when the drop\n\t * lives on a path-mode domain. Unlike {@link publish} (which auto-suffixes taken slugs),\n\t * `updateSettings` returns 409 on a slug conflict and never auto-suffixes — your code must\n\t * catch 409 and retry with a different slug. Passing `slug` on the shared pool returns 422.\n\t */\n\tupdateSettings(\n\t\tdropId: string,\n\t\toptions: DropOptions & RequestControls = {},\n\t): Promise<DropthisResult<DropResponse>> {\n\t\tconst requestOptions: Parameters<Transport[\"request\"]>[2] = {\n\t\t\tbody: updateBody(options),\n\t\t};\n\t\tif (options.idempotencyKey)\n\t\t\trequestOptions.idempotencyKey = options.idempotencyKey;\n\t\tif (options.ifRevision !== undefined)\n\t\t\trequestOptions.ifRevision = options.ifRevision;\n\t\treturn this.transport.request(\n\t\t\t\"PATCH\",\n\t\t\t`/drops/${encodeURIComponent(dropId)}`,\n\t\t\trequestOptions,\n\t\t);\n\t}\n\n\t/** Permanently delete a drop and its public URL by its `drop_…` id. DELETE /drops/{id}. */\n\tdelete(dropId: string): Promise<DropthisResult<null>> {\n\t\treturn this.transport.request(\n\t\t\t\"DELETE\",\n\t\t\t`/drops/${encodeURIComponent(dropId)}`,\n\t\t);\n\t}\n}\n\nconst SETTINGS = [\n\t\"title\",\n\t\"visibility\",\n\t\"password\",\n\t\"noindex\",\n\t\"expiresAt\",\n\t\"domain\",\n\t\"slug\",\n] as const;\n\nfunction updateBody(options: DropOptions & RequestControls): unknown {\n\tconst out: Record<string, unknown> = {};\n\tfor (const key of SETTINGS)\n\t\tif (options[key] !== undefined) out[key] = options[key];\n\treturn {\n\t\toptions: out,\n\t\t...(options.metadata !== undefined ? { metadata: options.metadata } : {}),\n\t};\n}\n","import type { Transport } from \"../transport.js\";\nimport type {\n\tDropthisResult,\n\tInvitationListResponse,\n\tWorkspace,\n} from \"../types.js\";\n\n/** Invitee-side invitations (ADR 0068). Listing needs `members:read`; accepting needs `members:write`. */\nexport class InvitationsResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\t/** List the calling account's own pending invitations. */\n\tlist(): Promise<DropthisResult<InvitationListResponse>> {\n\t\treturn this.transport.request(\"GET\", \"/invitations\");\n\t}\n\n\t/** Accept by the raw single-use token from the invite email. Joins + switches active workspace. */\n\taccept(input: { token: string }): Promise<DropthisResult<Workspace>> {\n\t\treturn this.transport.request(\"POST\", \"/invitations/accept\", {\n\t\t\tbody: input,\n\t\t});\n\t}\n\n\t/** Accept by invitation id, once authenticated as the invited email — the agent path, no token. */\n\tacceptById(input: {\n\t\tinvitationId: string;\n\t}): Promise<DropthisResult<Workspace>> {\n\t\treturn this.transport.request(\"POST\", \"/invitations/accept-by-id\", {\n\t\t\tbody: input,\n\t\t});\n\t}\n}\n","import type { Transport } from \"../transport.js\";\nimport type {\n\tDropthisResult,\n\tInvitableRole,\n\tInvitation,\n\tMember,\n\tMemberListResponse,\n\tWorkspaceRole,\n} from \"../types.js\";\n\n/** Team membership management (ADR 0068). Capability follows the credential's scopes. */\nexport class MembersResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\t/** List a workspace's members (any member, `members:read`). */\n\tlist(workspaceId: string): Promise<DropthisResult<MemberListResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"GET\",\n\t\t\t`/workspaces/${encodeURIComponent(workspaceId)}/members`,\n\t\t);\n\t}\n\n\t/** Invite an email to the workspace (owner/admin, `members:write`). */\n\tinvite(\n\t\tworkspaceId: string,\n\t\tinput: { email: string; role: InvitableRole },\n\t): Promise<DropthisResult<Invitation>> {\n\t\treturn this.transport.request(\n\t\t\t\"POST\",\n\t\t\t`/workspaces/${encodeURIComponent(workspaceId)}/invitations`,\n\t\t\t{ body: input },\n\t\t);\n\t}\n\n\t/** Change a member's role (`members:admin`, owner-only-touches-owner enforced server-side). */\n\tupdateRole(\n\t\tworkspaceId: string,\n\t\taccountId: string,\n\t\tinput: { role: WorkspaceRole },\n\t): Promise<DropthisResult<Member>> {\n\t\treturn this.transport.request(\n\t\t\t\"PATCH\",\n\t\t\t`/workspaces/${encodeURIComponent(workspaceId)}/members/${encodeURIComponent(accountId)}`,\n\t\t\t{ body: input },\n\t\t);\n\t}\n\n\t/** Remove a member, or leave the workspace (your own id). Removing others needs `members:admin`;\n\t * leaving needs `members:write`. 204 — data is null. */\n\tremove(\n\t\tworkspaceId: string,\n\t\taccountId: string,\n\t): Promise<DropthisResult<null>> {\n\t\treturn this.transport.request(\n\t\t\t\"DELETE\",\n\t\t\t`/workspaces/${encodeURIComponent(workspaceId)}/members/${encodeURIComponent(accountId)}`,\n\t\t);\n\t}\n}\n","import type { Transport } from \"../transport.js\";\nimport type {\n\tCreateUploadSessionRequest,\n\tCreateUploadSessionResponse,\n\tDropthisResult,\n\tUploadSessionResponse,\n} from \"../types.js\";\n\nexport class UploadsResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\tcreate(\n\t\tbody: CreateUploadSessionRequest,\n\t\toptions: { idempotencyKey?: string } = {},\n\t): Promise<DropthisResult<CreateUploadSessionResponse>> {\n\t\tconst requestOptions: Parameters<Transport[\"request\"]>[2] = { body };\n\t\tif (options.idempotencyKey)\n\t\t\trequestOptions.idempotencyKey = options.idempotencyKey;\n\t\treturn this.transport.request(\"POST\", \"/uploads\", requestOptions);\n\t}\n\n\tget(uploadId: string): Promise<DropthisResult<UploadSessionResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"GET\",\n\t\t\t`/uploads/${encodeURIComponent(uploadId)}`,\n\t\t);\n\t}\n\n\t/**\n\t * Verify staged objects and mark the session complete. Takes no request body —\n\t * the server verifies the uploaded bytes against the staged manifest.\n\t */\n\tcomplete(\n\t\tuploadId: string,\n\t\toptions: { idempotencyKey?: string } = {},\n\t): Promise<DropthisResult<UploadSessionResponse>> {\n\t\tconst requestOptions: Parameters<Transport[\"request\"]>[2] = {};\n\t\tif (options.idempotencyKey)\n\t\t\trequestOptions.idempotencyKey = options.idempotencyKey;\n\t\treturn this.transport.request(\n\t\t\t\"POST\",\n\t\t\t`/uploads/${encodeURIComponent(uploadId)}/complete`,\n\t\t\trequestOptions,\n\t\t);\n\t}\n\n\tcancel(uploadId: string): Promise<DropthisResult<null>> {\n\t\treturn this.transport.request(\n\t\t\t\"DELETE\",\n\t\t\t`/uploads/${encodeURIComponent(uploadId)}`,\n\t\t);\n\t}\n}\n","import type { Transport } from \"../transport.js\";\nimport type { DropthisResult, Workspace } from \"../types.js\";\n\nexport class WorkspacesResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\t// GET /v1/workspaces returns `{ workspaces: Workspace[] }` (server WorkspaceListResponse) — NOT a\n\t// `{ object, data }` page. Reading `.data` here silently yielded an empty list on every surface\n\t// (CLI/MCP/extension); the console worked only because its own client read `.workspaces`.\n\tlist(): Promise<DropthisResult<{ workspaces: Workspace[] }>> {\n\t\treturn this.transport.request(\"GET\", \"/workspaces\");\n\t}\n\n\t/** Create a team workspace (the caller becomes its sole owner). Needs `workspaces:write`. */\n\tcreate(input: {\n\t\tname: string;\n\t\t/** URL-safe slug; derived from the name when omitted. A clash on an explicit slug → 409. */\n\t\tslug?: string;\n\t}): Promise<DropthisResult<Workspace>> {\n\t\treturn this.transport.request(\"POST\", \"/workspaces\", { body: input });\n\t}\n\n\t/** Rename a team workspace (owner/admin). Needs `workspaces:write`. */\n\trename(\n\t\tworkspaceId: string,\n\t\tinput: { name?: string; slug?: string },\n\t): Promise<DropthisResult<Workspace>> {\n\t\treturn this.transport.request(\n\t\t\t\"PATCH\",\n\t\t\t`/workspaces/${encodeURIComponent(workspaceId)}`,\n\t\t\t{ body: input },\n\t\t);\n\t}\n\n\t/** Delete a team workspace (owner only). Needs `workspaces:admin`. 204 — data is null. */\n\tdelete(workspaceId: string): Promise<DropthisResult<null>> {\n\t\treturn this.transport.request(\n\t\t\t\"DELETE\",\n\t\t\t`/workspaces/${encodeURIComponent(workspaceId)}`,\n\t\t);\n\t}\n\n\tuse(workspace: string): Promise<DropthisResult<Workspace>> {\n\t\treturn this.transport.request(\"PUT\", \"/account/active-workspace\", {\n\t\t\tbody: { workspace },\n\t\t});\n\t}\n\n\tasync active(): Promise<DropthisResult<Workspace | null>> {\n\t\tconst result = await this.list();\n\t\tif (result.error !== null) {\n\t\t\treturn result as DropthisResult<Workspace | null>;\n\t\t}\n\t\tconst found = result.data.workspaces.find((ws) => ws.isActive) ?? null;\n\t\treturn { data: found, error: null, headers: result.headers };\n\t}\n}\n","export function toCamelKey(key: string): string {\n\treturn key.replace(/_([a-z])/g, (_, char: string) => char.toUpperCase());\n}\n\nexport function toSnakeKey(key: string): string {\n\treturn key.replace(/[A-Z]/g, (char) => `_${char.toLowerCase()}`);\n}\n\nconst PASSTHROUGH_KEYS = new Set([\"metadata\"]);\n\nexport function toCamelCase(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(toCamelCase);\n\tif (value && typeof value === \"object\") {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(value).map(([key, item]) => [\n\t\t\t\ttoCamelKey(key),\n\t\t\t\tPASSTHROUGH_KEYS.has(key) ? item : toCamelCase(item),\n\t\t\t]),\n\t\t);\n\t}\n\treturn value;\n}\n\nexport function toSnakeCase(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(toSnakeCase);\n\tif (value && typeof value === \"object\") {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(value)\n\t\t\t\t.filter(([, item]) => item !== undefined)\n\t\t\t\t.map(([key, item]) => [\n\t\t\t\t\ttoSnakeKey(key),\n\t\t\t\t\tPASSTHROUGH_KEYS.has(key) ? item : toSnakeCase(item),\n\t\t\t\t]),\n\t\t);\n\t}\n\treturn value;\n}\n","import { toCamelCase, toSnakeCase } from \"./case.js\";\nimport { createErrorResult } from \"./errors.js\";\nimport type {\n\tDropthisClientOptions,\n\tDropthisResult,\n\tRequestOptions,\n} from \"./types.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.dropthis.app\";\nconst SDK_VERSION = \"0.29.0\";\n\nexport class Transport {\n\treadonly apiKey: string | undefined;\n\treadonly baseUrl: string;\n\treadonly timeoutMs: number;\n\treadonly uploadTimeoutMs: number;\n\treadonly fetchImpl: typeof globalThis.fetch;\n\n\tconstructor(options: DropthisClientOptions | string = {}) {\n\t\tconst resolved =\n\t\t\ttypeof options === \"string\" ? { apiKey: options } : options;\n\t\tthis.apiKey =\n\t\t\tresolved.apiKey ??\n\t\t\t(typeof process !== \"undefined\"\n\t\t\t\t? process.env?.DROPTHIS_API_KEY\n\t\t\t\t: undefined);\n\t\t// All API endpoints live under the /v1 version prefix; fold it into the configured host\n\t\t// (default or custom) once, so resource paths stay version-agnostic (\"/drops\", …). Parse via\n\t\t// URL so a stray trailing slash, query, or hash on the base can't corrupt the request path.\n\t\tconst base = new URL(resolved.baseUrl ?? DEFAULT_BASE_URL);\n\t\tconst basePath = base.pathname.replace(/\\/+$/, \"\");\n\t\tbase.pathname = basePath.endsWith(\"/v1\") ? basePath : `${basePath}/v1`;\n\t\tbase.search = \"\";\n\t\tbase.hash = \"\";\n\t\tthis.baseUrl = base.toString().replace(/\\/+$/, \"\");\n\t\tthis.timeoutMs = resolved.timeoutMs ?? 30_000;\n\t\tthis.uploadTimeoutMs = resolved.uploadTimeoutMs ?? 120_000;\n\t\tthis.fetchImpl = resolved.fetch ?? globalThis.fetch;\n\t}\n\n\tasync putSignedUrl(\n\t\turl: string,\n\t\tbody: Uint8Array | Blob | ReadableStream,\n\t\theaders: Record<string, string>,\n\t): Promise<DropthisResult<{ etag: string | null }>> {\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(() => controller.abort(), this.uploadTimeoutMs);\n\t\ttry {\n\t\t\tconst request: RequestInit & { duplex?: \"half\" } = {\n\t\t\t\tmethod: \"PUT\",\n\t\t\t\theaders,\n\t\t\t\tbody: body as BodyInit,\n\t\t\t\tsignal: controller.signal,\n\t\t\t};\n\t\t\tif (body instanceof ReadableStream) request.duplex = \"half\";\n\t\t\tconst response = await this.fetchImpl(url, request);\n\t\t\tconst responseHeaders = headersToObject(response.headers);\n\t\t\tif (!response.ok) {\n\t\t\t\tconst text = await response.text();\n\t\t\t\treturn createErrorResult(\n\t\t\t\t\t`signed_upload_${response.status}`,\n\t\t\t\t\ttext || response.statusText,\n\t\t\t\t\tresponse.status,\n\t\t\t\t\t// A 5xx from object storage is a transient upstream failure — safe to\n\t\t\t\t\t// re-PUT. A 4xx (e.g. 403 expired/denied signed URL) won't fix itself on\n\t\t\t\t\t// a blind retry, so leave it unmarked.\n\t\t\t\t\t{ headers: responseHeaders, retryable: response.status >= 500 },\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tdata: {\n\t\t\t\t\tetag: response.headers.get(\"ETag\") ?? responseHeaders.etag ?? null,\n\t\t\t\t},\n\t\t\t\terror: null,\n\t\t\t\theaders: responseHeaders,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconst message =\n\t\t\t\terror instanceof Error && error.name === \"AbortError\"\n\t\t\t\t\t? \"Request timed out\"\n\t\t\t\t\t: error instanceof Error\n\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t: \"Network error\";\n\t\t\t// A timeout or transport-level network failure carries no server body, so the\n\t\t\t// only retry signal we can offer is our own: both are inherently transient and\n\t\t\t// safe for an agent to retry (idempotency keys keep publishes single).\n\t\t\treturn createErrorResult(\n\t\t\t\terror instanceof Error && error.name === \"AbortError\"\n\t\t\t\t\t? \"timeout\"\n\t\t\t\t\t: \"network_error\",\n\t\t\t\tmessage,\n\t\t\t\tnull,\n\t\t\t\t{ retryable: true },\n\t\t\t);\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\t}\n\n\t/**\n\t * Authenticated GET that returns the raw response bytes untouched (no JSON parsing,\n\t * no case conversion). Error responses are still parsed as problem+json. Used for\n\t * content read-back (`drops.getContent` with a file path).\n\t */\n\tasync requestBytes(\n\t\tpath: string,\n\t\toptions: RequestOptions & {\n\t\t\tparams?: Record<string, string | number | boolean | null | undefined>;\n\t\t} = {},\n\t): Promise<\n\t\tDropthisResult<{ bytes: Uint8Array; contentType: string | null }>\n\t> {\n\t\tif (!this.apiKey) {\n\t\t\treturn createErrorResult(\n\t\t\t\t\"missing_api_key\",\n\t\t\t\t\"No API key provided. Pass apiKey or set DROPTHIS_API_KEY.\",\n\t\t\t\tnull,\n\t\t\t);\n\t\t}\n\n\t\tconst headers: Record<string, string> = {\n\t\t\t\"user-agent\": `dropthis-node/${SDK_VERSION}`,\n\t\t\tauthorization: `Bearer ${this.apiKey}`,\n\t\t};\n\n\t\tconst url = new URL(`${this.baseUrl}${path}`);\n\t\tfor (const [key, value] of Object.entries(options.params ?? {})) {\n\t\t\tif (value !== undefined && value !== null)\n\t\t\t\turl.searchParams.set(key, String(value));\n\t\t}\n\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(\n\t\t\t() => controller.abort(),\n\t\t\toptions.timeoutMs ?? this.timeoutMs,\n\t\t);\n\t\ttry {\n\t\t\tconst response = await this.fetchImpl(url.toString(), {\n\t\t\t\tmethod: \"GET\",\n\t\t\t\theaders,\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\t\t\tconst responseHeaders = headersToObject(response.headers);\n\t\t\tif (!response.ok) {\n\t\t\t\tconst text = await response.text();\n\t\t\t\treturn problemResult(response, text, responseHeaders);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tdata: {\n\t\t\t\t\tbytes: new Uint8Array(await response.arrayBuffer()),\n\t\t\t\t\tcontentType:\n\t\t\t\t\t\tresponse.headers.get(\"content-type\") ??\n\t\t\t\t\t\tresponseHeaders[\"content-type\"] ??\n\t\t\t\t\t\tnull,\n\t\t\t\t},\n\t\t\t\terror: null,\n\t\t\t\theaders: responseHeaders,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconst message =\n\t\t\t\terror instanceof Error && error.name === \"AbortError\"\n\t\t\t\t\t? \"Request timed out\"\n\t\t\t\t\t: error instanceof Error\n\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t: \"Network error\";\n\t\t\treturn createErrorResult(\n\t\t\t\terror instanceof Error && error.name === \"AbortError\"\n\t\t\t\t\t? \"timeout\"\n\t\t\t\t\t: \"network_error\",\n\t\t\t\tmessage,\n\t\t\t\tnull,\n\t\t\t\t{ retryable: true },\n\t\t\t);\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\t}\n\n\tasync request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\toptions: RequestOptions & {\n\t\t\tbody?: unknown;\n\t\t\tbodyCase?: \"snake\" | \"raw\";\n\t\t\tparams?: Record<string, string | number | boolean | null | undefined>;\n\t\t} = {},\n\t): Promise<DropthisResult<T>> {\n\t\tconst authenticated = options.authenticated ?? true;\n\t\tif (authenticated && !this.apiKey) {\n\t\t\treturn createErrorResult<T>(\n\t\t\t\t\"missing_api_key\",\n\t\t\t\t\"No API key provided. Pass apiKey or set DROPTHIS_API_KEY.\",\n\t\t\t\tnull,\n\t\t\t);\n\t\t}\n\n\t\tconst headers: Record<string, string> = {\n\t\t\t\"user-agent\": `dropthis-node/${SDK_VERSION}`,\n\t\t};\n\t\tif (authenticated && this.apiKey)\n\t\t\theaders.authorization = `Bearer ${this.apiKey}`;\n\t\tif (options.idempotencyKey)\n\t\t\theaders[\"idempotency-key\"] = options.idempotencyKey;\n\t\tif (options.ifRevision !== undefined)\n\t\t\theaders[\"if-revision\"] = String(options.ifRevision);\n\t\tif (options.body !== undefined && !(options.body instanceof FormData))\n\t\t\theaders[\"content-type\"] = \"application/json\";\n\n\t\tconst url = new URL(`${this.baseUrl}${path}`);\n\t\tconst wireParams =\n\t\t\toptions.bodyCase === \"raw\"\n\t\t\t\t? options.params\n\t\t\t\t: (toSnakeCase(options.params ?? {}) as Record<string, unknown>);\n\t\tfor (const [key, value] of Object.entries(wireParams ?? {})) {\n\t\t\tif (value !== undefined && value !== null)\n\t\t\t\turl.searchParams.set(key, String(value));\n\t\t}\n\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(\n\t\t\t() => controller.abort(),\n\t\t\toptions.timeoutMs ?? this.timeoutMs,\n\t\t);\n\t\ttry {\n\t\t\tconst request: RequestInit = {\n\t\t\t\tmethod,\n\t\t\t\theaders,\n\t\t\t\tsignal: controller.signal,\n\t\t\t};\n\t\t\tif (options.body instanceof FormData) {\n\t\t\t\trequest.body = options.body;\n\t\t\t} else if (options.body !== undefined) {\n\t\t\t\tconst wireBody =\n\t\t\t\t\toptions.bodyCase === \"raw\" ? options.body : toSnakeCase(options.body);\n\t\t\t\trequest.body = JSON.stringify(wireBody);\n\t\t\t}\n\n\t\t\tconst response = await this.fetchImpl(url.toString(), request);\n\t\t\tconst responseHeaders = headersToObject(response.headers);\n\t\t\tconst text = await response.text();\n\t\t\tif (!response.ok)\n\t\t\t\treturn problemResult<T>(response, text, responseHeaders);\n\t\t\treturn {\n\t\t\t\tdata: toCamelCase(parseJson(text)) as T,\n\t\t\t\terror: null,\n\t\t\t\theaders: responseHeaders,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconst message =\n\t\t\t\terror instanceof Error && error.name === \"AbortError\"\n\t\t\t\t\t? \"Request timed out\"\n\t\t\t\t\t: error instanceof Error\n\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t: \"Network error\";\n\t\t\t// A timeout/network failure on a mutating method is only safe to retry when the\n\t\t\t// request is deduplicated: the server may have applied a bare POST/PATCH/DELETE\n\t\t\t// before the connection dropped. Idempotent GETs are always safe; any method\n\t\t\t// carrying an idempotency key is dedupe-safe. Otherwise leave retryable unset\n\t\t\t// so an agent doesn't blindly re-issue a side effect.\n\t\t\tconst retrySafe =\n\t\t\t\tmethod.toUpperCase() === \"GET\" || options.idempotencyKey !== undefined;\n\t\t\treturn createErrorResult<T>(\n\t\t\t\terror instanceof Error && error.name === \"AbortError\"\n\t\t\t\t\t? \"timeout\"\n\t\t\t\t\t: \"network_error\",\n\t\t\t\tmessage,\n\t\t\t\tnull,\n\t\t\t\tretrySafe ? { retryable: true } : {},\n\t\t\t);\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\t}\n}\n\n/** Maps a non-2xx response's problem+json body into the typed error result shape. */\nfunction problemResult<T>(\n\tresponse: Response,\n\ttext: string,\n\tresponseHeaders: Record<string, string>,\n): DropthisResult<T> {\n\tconst parsed = parseJson(text);\n\tconst body =\n\t\tparsed && typeof parsed === \"object\"\n\t\t\t? (parsed as Record<string, unknown>)\n\t\t\t: {};\n\tconst message =\n\t\tstringValue(body.detail) ?? stringValue(body.title) ?? response.statusText;\n\tconst code =\n\t\tstringValue(body.code) ??\n\t\tstringValue(body.error_code) ??\n\t\t`http_${response.status}`;\n\tconst currentRevision = numberValue(body.current_revision);\n\tconst type = stringValue(body.type);\n\tconst title = stringValue(body.title);\n\tconst instance = stringValue(body.instance);\n\treturn createErrorResult<T>(code, message, response.status, {\n\t\tbody,\n\t\t...(type !== null ? { type } : {}),\n\t\t...(title !== null ? { title } : {}),\n\t\t...(instance !== null ? { instance } : {}),\n\t\tdetail: stringValue(body.detail),\n\t\tparam: stringValue(body.param),\n\t\t...(currentRevision !== undefined ? { currentRevision } : {}),\n\t\trequestId:\n\t\t\tstringValue(body.request_id) ?? responseHeaders[\"x-request-id\"] ?? null,\n\t\tsuggestion: stringValue(body.suggestion),\n\t\tretryable: booleanValue(body.retryable),\n\t\t// Unified plan-gate contract (feature_not_in_plan / quota_exceeded). The\n\t\t// error body isn't camelCased like a success body, so map the snake keys here.\n\t\tfeature: stringValue(body.feature),\n\t\tcurrentPlan: stringValue(body.current_plan),\n\t\trequiredPlan: stringValue(body.required_plan),\n\t\tupgradeUrl: stringValue(body.upgrade_url),\n\t\tlimit: numberValue(body.limit) ?? null,\n\t\tused: numberValue(body.used) ?? null,\n\t\trequested: numberValue(body.requested) ?? null,\n\t\theaders: responseHeaders,\n\t});\n}\n\nfunction headersToObject(headers: Headers): Record<string, string> {\n\tconst result: Record<string, string> = {};\n\theaders.forEach((value, key) => {\n\t\tresult[key.toLowerCase()] = value;\n\t});\n\treturn result;\n}\n\nfunction parseJson(text: string): unknown {\n\tif (!text) return null;\n\ttry {\n\t\treturn JSON.parse(text);\n\t} catch {\n\t\treturn text;\n\t}\n}\n\nfunction stringValue(value: unknown): string | null {\n\treturn typeof value === \"string\" ? value : null;\n}\n\nfunction numberValue(value: unknown): number | undefined {\n\treturn typeof value === \"number\" ? value : undefined;\n}\n\nfunction booleanValue(value: unknown): boolean | null {\n\treturn typeof value === \"boolean\" ? value : null;\n}\n","import type { PreparedPublishRequest } from \"./publish/core.js\";\nimport { resolveInput } from \"./publish/node.js\";\nimport { AccountResource } from \"./resources/account.js\";\nimport { ApiKeysResource } from \"./resources/api-keys.js\";\nimport { AuthResource } from \"./resources/auth.js\";\nimport { DeploymentsResource } from \"./resources/deployments.js\";\nimport { DomainsResource } from \"./resources/domains.js\";\nimport { DropsResource } from \"./resources/drops.js\";\nimport { InvitationsResource } from \"./resources/invitations.js\";\nimport { MembersResource } from \"./resources/members.js\";\nimport { UploadsResource } from \"./resources/uploads.js\";\nimport { WorkspacesResource } from \"./resources/workspaces.js\";\nimport { Transport } from \"./transport.js\";\nimport type {\n\tDropthisClientOptions,\n\tPublishInput,\n\tPublishOptions,\n} from \"./types.js\";\n\nexport class Dropthis {\n\tprivate readonly transport: Transport;\n\t/** Client-level workspace default; applied when a publish call omits `options.workspace`. */\n\tprivate readonly defaultWorkspace: string | undefined;\n\tprivate authResource?: AuthResource;\n\tprivate apiKeysResource?: ApiKeysResource;\n\tprivate accountResource?: AccountResource;\n\tprivate dropsResource?: DropsResource<PublishInput>;\n\tprivate deploymentsResource?: DeploymentsResource;\n\tprivate uploadsResource?: UploadsResource;\n\tprivate domainsResource?: DomainsResource;\n\tprivate workspacesResource?: WorkspacesResource;\n\tprivate membersResource?: MembersResource;\n\tprivate invitationsResource?: InvitationsResource;\n\n\tconstructor(options: DropthisClientOptions | string = {}) {\n\t\tthis.transport = new Transport(options);\n\t\tthis.defaultWorkspace =\n\t\t\ttypeof options === \"string\" ? undefined : options.workspace;\n\t}\n\n\tget auth(): AuthResource {\n\t\tif (!this.authResource)\n\t\t\tthis.authResource = new AuthResource(this.transport);\n\t\treturn this.authResource;\n\t}\n\n\tget apiKeys(): ApiKeysResource {\n\t\tif (!this.apiKeysResource)\n\t\t\tthis.apiKeysResource = new ApiKeysResource(this.transport);\n\t\treturn this.apiKeysResource;\n\t}\n\n\tget account(): AccountResource {\n\t\tif (!this.accountResource)\n\t\t\tthis.accountResource = new AccountResource(this.transport);\n\t\treturn this.accountResource;\n\t}\n\n\tget drops(): DropsResource<PublishInput> {\n\t\tif (!this.dropsResource) {\n\t\t\t// Pass defaultWorkspace as the 3rd arg so DropsResource.publish() merges it\n\t\t\t// only for fresh publishes — never for updateContent (which stays in the\n\t\t\t// drop's own workspace).\n\t\t\tthis.dropsResource = new DropsResource(\n\t\t\t\tthis.transport,\n\t\t\t\tresolveInput,\n\t\t\t\tthis.defaultWorkspace,\n\t\t\t);\n\t\t}\n\t\treturn this.dropsResource;\n\t}\n\n\tget deployments(): DeploymentsResource {\n\t\tif (!this.deploymentsResource)\n\t\t\tthis.deploymentsResource = new DeploymentsResource(this.transport);\n\t\treturn this.deploymentsResource;\n\t}\n\n\tget uploads(): UploadsResource {\n\t\tif (!this.uploadsResource)\n\t\t\tthis.uploadsResource = new UploadsResource(this.transport);\n\t\treturn this.uploadsResource;\n\t}\n\n\tget domains(): DomainsResource {\n\t\tif (!this.domainsResource)\n\t\t\tthis.domainsResource = new DomainsResource(this.transport);\n\t\treturn this.domainsResource;\n\t}\n\n\tget workspaces(): WorkspacesResource {\n\t\tif (!this.workspacesResource)\n\t\t\tthis.workspacesResource = new WorkspacesResource(this.transport);\n\t\treturn this.workspacesResource;\n\t}\n\n\tget members(): MembersResource {\n\t\tif (!this.membersResource)\n\t\t\tthis.membersResource = new MembersResource(this.transport);\n\t\treturn this.membersResource;\n\t}\n\n\tget invitations(): InvitationsResource {\n\t\tif (!this.invitationsResource)\n\t\t\tthis.invitationsResource = new InvitationsResource(this.transport);\n\t\treturn this.invitationsResource;\n\t}\n\n\tasync prepare(\n\t\tinput: PublishInput,\n\t\toptions: PublishOptions = {},\n\t): Promise<PreparedPublishRequest> {\n\t\tconst merged: PublishOptions =\n\t\t\tthis.defaultWorkspace !== undefined && options.workspace === undefined\n\t\t\t\t? { ...options, workspace: this.defaultWorkspace }\n\t\t\t\t: options;\n\t\treturn resolveInput(input, merged);\n\t}\n}\n","export type DropthisClientOptions = {\n\tapiKey?: string;\n\tbaseUrl?: string;\n\ttimeoutMs?: number;\n\tuploadTimeoutMs?: number;\n\tfetch?: typeof globalThis.fetch;\n\t/**\n\t * Default workspace slug or id applied to every publish/prepare call that\n\t * does not supply its own `options.workspace`. Delegated credentials only;\n\t * ignored by pinned service keys.\n\t */\n\tworkspace?: string;\n};\n\nexport type RequestOptions = {\n\tauthenticated?: boolean;\n\tidempotencyKey?: string;\n\tifRevision?: number;\n\ttimeoutMs?: number;\n};\n\nexport type DropthisErrorResponse = {\n\tcode: string;\n\tmessage: string;\n\tstatusCode: number | null;\n\ttype?: string;\n\ttitle?: string;\n\tdetail?: string | null;\n\tinstance?: string | null;\n\tparam?: string | null;\n\tcurrentRevision?: number;\n\trequestId?: string | null;\n\tsuggestion?: string | null;\n\tretryable?: boolean | null;\n\t/** The gated capability (on `feature_not_in_plan`), e.g. `password_protect`. */\n\tfeature?: string | null;\n\t/** The caller's current plan (on `feature_not_in_plan` / `quota_exceeded`). */\n\tcurrentPlan?: string | null;\n\t/** The lowest plan that unlocks the feature (on `feature_not_in_plan`). */\n\trequiredPlan?: string | null;\n\t/** The pricing/upgrade URL to hand a human (on a plan gate). */\n\tupgradeUrl?: string | null;\n\t/** Numeric ceiling that was hit (on `quota_exceeded`). */\n\tlimit?: number | null;\n\t/** Amount already used toward the ceiling (on `quota_exceeded`). */\n\tused?: number | null;\n\t/** Amount the request asked for (on `quota_exceeded`). */\n\trequested?: number | null;\n\tbody?: unknown;\n};\n\nexport type DropthisResult<T> =\n\t| { data: T; error: null; headers: Record<string, string> }\n\t| {\n\t\t\tdata: null;\n\t\t\terror: DropthisErrorResponse;\n\t\t\theaders: Record<string, string>;\n\t };\n\nexport type ActionResolve = {\n\tmethod: string;\n\turl?: string | null;\n\tendpoint?: string | null;\n};\n\nexport type DropAction = {\n\tcode: string;\n\tkind: \"api\" | \"human\";\n\tpriority: \"required\" | \"suggested\";\n\tmessage: string;\n\tresolve?: ActionResolve | null;\n};\n\nexport type TierInfo = {\n\tname: string;\n\tmaxSizeBytes: number;\n\tttlDays: number | null;\n\tpersistent: boolean;\n\tbadge: boolean;\n};\n\nexport type Limitations = {\n\tactions: DropAction[];\n};\n\n/**\n * Workspace context echoed on every drop response. Identifies which workspace\n * the drop was published into (ADR 0066).\n */\nexport type DropWorkspace = {\n\tid: string;\n\tname: string;\n\tslug: string;\n\t/** `personal` for a solo workspace, `team` for a shared team workspace. */\n\tkind: string;\n};\n\nexport type DropResponse = {\n\tid: string;\n\tslug: string;\n\turl: string;\n\tdeploymentId: string | null;\n\ttitle: string;\n\tcontentType: string;\n\tvisibility: string;\n\tstatus: string;\n\trevision: number;\n\tcontentRevision: number;\n\taccessRevision: number;\n\tsizeBytes: number;\n\trenderMode: string;\n\twarnings: Array<Record<string, unknown>>;\n\tcreatedAt: string;\n\texpiresAt: string | null;\n\tnoindex: boolean;\n\tpasswordProtected: boolean;\n\tmetadata: Record<string, unknown>;\n\t/** When the drop was last updated (content or settings), ISO 8601. */\n\tupdatedAt: string;\n\t/** Origin that created the drop (e.g. \"api\", \"cli\", \"mcp\"); null/omitted when unattributed. */\n\tsource?: string | null;\n\tobject: string;\n\taccessible: boolean;\n\tpersistent: boolean;\n\tbadgeApplied: boolean;\n\ttier: TierInfo;\n\tlimitations: Limitations;\n\t/** Hostname of the custom domain this drop is mounted on; null for shared-pool drops. */\n\tdomain: string | null;\n\t/**\n\t * Direct URL to the drop's raw bytes — the agent byte-fetch path. The canonical\n\t * `url` always serves a branded human view (so the badge is guaranteed); `rawUrl`\n\t * serves the underlying file's exact bytes at its natural path under the mount\n\t * (ADR 0061). Populated only for single-file (`renderMode: \"file_viewer\"`) drops\n\t * (= canonical URL + the entry filename); `null` for `user_html` drops (the page\n\t * IS the artifact) and collections (per-file natural paths come from the manifest —\n\t * see {@link DeploymentContentManifest}). Hand `url` to humans and `rawUrl` to agents.\n\t * To stream bytes through the SDK regardless of drop kind, use `drops.getContent()`.\n\t */\n\trawUrl: string | null;\n\t/** The workspace this drop belongs to (echoed from the server on every response). */\n\tworkspace: DropWorkspace;\n};\n\nexport type DropDeploymentResponse = {\n\tid: string;\n\tdropId: string;\n\trevision: number;\n\tstatus: string;\n\tentry: string | null;\n\tcontentType: string;\n\trenderMode: string;\n\tfiles: Array<Record<string, unknown>>;\n\twarnings: Array<Record<string, unknown>>;\n\tsizeBytes: number;\n\tclassificationVersion: number;\n\tclassificationReason: string;\n\terrorCode: string | null;\n\terrorMessage: string | null;\n\tcreatedAt: string;\n\treadyAt: string | null;\n\tpublishedAt: string | null;\n};\n\nexport type ListDeploymentsParams = { cursor?: string | null; limit?: number };\n\nexport type ListDeploymentsResponse = {\n\tdeployments: DropDeploymentResponse[];\n\tnextCursor: string | null;\n};\n\nexport type ListPage<T> = {\n\tobject: \"list\";\n\tdata: T[];\n\thasMore: boolean;\n\tnextCursor: string | null;\n\tautoPagingToArray(options?: { limit?: number }): Promise<DropthisResult<T[]>>;\n};\n\nexport type Action = {\n\tcode: string;\n\tkind: string;\n\tmethod?: string | null;\n\tendpoint?: string | null;\n\tmessage: string;\n};\n\nexport type EmailOtpResponse = {\n\t/** Always `true` on success; optional because the server defaults it. */\n\tok?: true;\n\texpiresIn: number;\n\tnextAction?: Action | null;\n};\nexport type SessionResponse = {\n\tobject: \"session\";\n\ttoken: string;\n\taccountId: string;\n\tisNewAccount: boolean;\n\texpiresIn: number;\n\t/**\n\t * Rotating refresh token for a console browser session. Present when a session is\n\t * started (email/verify, refresh); `null`/omitted for non-session token issuance.\n\t */\n\trefreshToken?: string | null;\n};\n\n/**\n * Why an API key exists. `delegated` keys act on behalf of the owning account (scoped\n * to the active workspace or an allowed set); `service` keys are pinned to a single\n * workspace and are intended for CI/automation.\n */\nexport type KeyType = \"delegated\" | \"service\";\n\n/** What breaks when a key is revoked. */\nexport type RevokeImpact = \"disconnects_app\" | \"breaks_automation\";\n\nexport type ApiKeyResponse = {\n\tobject: \"api_key\";\n\tid: string;\n\tkeyLast4: string;\n\tlabel: string;\n\t/** Human-facing credential name: the user's label for `standard` keys, the connected client name for `mcp_oauth` keys. */\n\tappName: string;\n\t/** Why the key exists (drives quota accounting). */\n\tkeyType: KeyType;\n\t/** Scopes granted to this key. */\n\tscopes: string[];\n\t/** When the key was last used to authenticate, ISO 8601; null/omitted if never used. */\n\tlastUsedAt?: string | null;\n\t/** What breaks if this key is revoked. */\n\trevokeImpact: RevokeImpact;\n\tcreatedAt: string;\n};\nexport type ApiKeyCreatedResponse = ApiKeyResponse & {\n\tkey: string;\n\taccountId?: string | null;\n\tisNewAccount?: boolean;\n};\n/** Numeric limits for the active plan — use these to size a publish before uploading. */\nexport type EntitlementLimits = {\n\t/** Maximum size of a single drop in bytes. */\n\tmaxSizeBytes: number;\n\t/** Total account storage cap in bytes; null means no account-level cap. */\n\tmaxStorageBytes: number | null;\n\t/** Drop lifetime in seconds before expiry; null means drops are permanent. */\n\tdefaultTtlSeconds: number | null;\n\t/** Maximum number of custom hostnames the workspace may connect. */\n\tmaxCustomHostnames: number;\n\t/** Maximum members the workspace may hold (owner included). */\n\tseatLimit: number;\n\t/** Maximum concurrent in-flight upload sessions (a transient concurrency cap). */\n\tmaxActiveUploadSessions: number;\n};\n\n/**\n * The full capability matrix for the active plan — the single read to pre-check a\n * feature gate before attempting an operation.\n */\nexport type Entitlements = {\n\t/**\n\t * Per-capability state for the active plan. Boolean caps are `true`/`false`;\n\t * enum caps (`ogPreview`, `analytics`) carry a value — compare by value, never\n\t * truthiness (`\"none\"` is truthy).\n\t */\n\tcapabilities: Record<string, boolean | string>;\n\t/**\n\t * The lowest plan that unlocks each gated capability — drives the upgrade nudge.\n\t * Enum sub-values are keyed `ogPreview.customImage` / `analytics.full`.\n\t */\n\trequiredPlan: Record<string, string>;\n\t/** Numeric limits for the active plan. */\n\tlimits: EntitlementLimits;\n};\n\n/** Current resource usage for the account's active workspace. */\nexport type AccountUsage = {\n\t/** Total bytes consumed across all active drops. */\n\tstorageUsedBytes: number;\n\t/** Number of custom domain hostnames currently in use. */\n\tcustomDomainsUsed: number;\n\t/** Members currently in the workspace (owner included). */\n\tseatsUsed: number;\n};\n\n/** The workspace a principal acts within (ADR 0066). For an sk_ API key, the workspace the key is bound to. */\nexport type AccountWorkspace = {\n\tid: string;\n\tname: string;\n\tslug: string;\n\t/** `personal` for a solo workspace, `team` when shared with other members. */\n\tkind: string;\n\t/** The calling account's role in this workspace: `owner`, `admin`, or `member`. */\n\trole: string;\n};\n\n/**\n * A workspace the caller belongs to or has delegated access to.\n * Returned by `GET /v1/workspaces` and `PUT /v1/account/active-workspace`.\n */\nexport type Workspace = {\n\tid: string;\n\tname: string;\n\tslug: string;\n\t/** `personal` for a solo workspace, `team` for a shared team workspace. */\n\tkind: string;\n\t/** The calling account's role in this workspace: `owner`, `admin`, or `member`. */\n\trole: string;\n\t/** The plan tier of this workspace. */\n\tplan: string;\n\t/** Whether this workspace is currently the caller's active workspace. */\n\tisActive: boolean;\n\t/**\n\t * On CREATE only (null otherwise): whether the credential that created this workspace can act\n\t * in it. `false` means an allowlist-restricted key created a workspace outside its allowlist —\n\t * it will be denied on the next write; re-authenticate to obtain a credential that reaches it.\n\t */\n\tcreatorCanReach?: boolean | null;\n};\n\n/** A role grantable via invite or a member role-change (owner is transferred, never granted). */\nexport type WorkspaceRole = \"owner\" | \"admin\" | \"member\";\nexport type InvitableRole = \"admin\" | \"member\";\n\n/** A member of a team workspace. */\nexport type Member = {\n\taccountId: string;\n\t/** The member's email, or null if their account was deleted. */\n\temail: string | null;\n\trole: WorkspaceRole;\n\t/** Whether this row is the calling account. */\n\tisYou: boolean;\n\tjoinedAt: string;\n};\nexport type MemberListResponse = { members: Member[] };\n\n/** An invitation to join a team workspace. */\nexport type Invitation = {\n\tid: string;\n\tworkspaceId: string;\n\temail: string;\n\trole: WorkspaceRole;\n\t/** `pending`, `accepted`, or `revoked`. */\n\tstatus: string;\n\texpiresAt: string;\n\tcreatedAt: string;\n\tacceptedAt?: string | null;\n};\nexport type InvitationListResponse = { invitations: Invitation[] };\n\nexport type AccountResponse = {\n\tid: string;\n\temail: string;\n\tdisplayName: string | null;\n\tplan: string;\n\tstatus: string;\n\tcreatedAt: string;\n\t/** The full capability matrix + numeric limits for the active plan. */\n\tentitlements: Entitlements;\n\tusage: AccountUsage;\n\tworkspace: AccountWorkspace;\n\t/** URL to upgrade; present on every plan below Business, null on the top tier. */\n\tupgradeUrl: string | null;\n};\nexport type ListDropsParams = {\n\tcursor?: string | null;\n\tlimit?: number;\n\t/** Only drops mounted on this custom domain hostname (e.g. \"reports.example.com\"). */\n\tdomain?: string;\n};\n\n/**\n * One file in an upload manifest. A discriminated union:\n *\n * - **client-put** — the SDK pushes the bytes through a signed PUT. Requires\n * `contentType` and `sizeBytes`; an optional `checksumSha256` locks the\n * transfer integrity.\n * - **remote** — the server fetches the bytes itself from `sourceUrl` during\n * `POST /uploads/{id}/ingest`. No bytes leave this process, so `sizeBytes`,\n * `contentType`, and `checksumSha256` are all optional (the server infers\n * them on fetch). Carries NO signed PUT target.\n *\n * `sourceUrl` is the discriminant: present ⇒ remote, absent ⇒ client-put. The\n * camelCase `sourceUrl` becomes the wire field `source_url` via the transport's\n * snake_case conversion (exactly like `contentType` → `content_type`).\n */\nexport type UploadManifestFile =\n\t| {\n\t\t\tpath: string;\n\t\t\tcontentType: string;\n\t\t\tsizeBytes: number;\n\t\t\tchecksumSha256?: string | null;\n\t\t\tsourceUrl?: never;\n\t }\n\t| {\n\t\t\tpath: string;\n\t\t\tsourceUrl: string;\n\t\t\tcontentType?: string;\n\t\t\tsizeBytes?: number;\n\t\t\tchecksumSha256?: string | null;\n\t };\n\nexport type CreateUploadSessionRequest = {\n\tschemaVersion?: 1;\n\tfiles: UploadManifestFile[];\n\tentry?: string | null;\n\t/**\n\t * Target workspace slug or id for this upload session. Delegated credentials only;\n\t * ignored by pinned service keys. Bound at session creation and inherited by the\n\t * subsequent POST /drops call.\n\t */\n\tworkspace?: string;\n};\n\nexport type UploadTarget = {\n\t/** Always `single_put` — one signed PUT per file is the upload contract. */\n\tstrategy: \"single_put\";\n\turl: string;\n\theaders: Record<string, string>;\n\texpiresAt: string;\n};\n\nexport type CreateUploadSessionFileResponse = {\n\tfileId: string;\n\tpath: string;\n\tobjectKey: string;\n\tupload: UploadTarget;\n};\n\nexport type UploadSessionFileResponse = {\n\tfileId: string;\n\tpath: string;\n\t/** Declared MIME type; `null`/omitted for remote-fetch files until ingested. */\n\tcontentType?: string | null;\n\t/** Declared byte size; `null`/omitted for remote-fetch files until ingested. */\n\tsizeBytes?: number | null;\n\tobjectKey: string;\n\t/** How the file enters staging: \"client_put\" (client PUTs bytes) or \"remote_fetch\" (server fetches sourceUrl). */\n\torigin: \"client_put\" | \"remote_fetch\";\n\t/** Ingest lifecycle state for remote-fetch files (e.g. \"pending\" | \"fetching\" | \"fetched\" | \"failed\"). */\n\tstate: string;\n\t/** Public http(s) URL the server fetches into staging; `null`/omitted for client-put files. */\n\tsourceUrl?: string | null;\n\tverified: boolean;\n};\n\nexport type UploadSessionResponse = {\n\tuploadId: string;\n\tstatus: string;\n\texpiresAt: string;\n\tentry?: string | null;\n\tfiles: UploadSessionFileResponse[];\n\tnextAction?: Action | null;\n};\n\n/**\n * Response body from `POST /uploads/{id}/ingest`.\n * The server fetches all remote (`sourceUrl`) manifest entries into staging and\n * returns a count of the files it staged plus a lifecycle status string.\n * The SDK requires 2xx and discards the body; this type documents the wire shape.\n */\nexport type IngestSessionResponse = {\n\t/** Number of remote files successfully fetched into staging. */\n\tstaged: number;\n\t/** Upload session lifecycle status after ingestion (e.g. \"ingested\"). */\n\tstatus: string;\n};\n\nexport type CreateUploadSessionResponse = {\n\tuploadId: string;\n\texpiresAt: string;\n\tfiles: CreateUploadSessionFileResponse[];\n\tnextAction?: Action | null;\n};\n\n/**\n * Sentinel for `DropOptions.domain`: publish to the shared pool even when the\n * account has a default custom domain (dropthis#55). Collision-free — the\n * literal \"shared\" can never be a real hostname (single-label names are\n * rejected at domain connect). These drops read back `domain: null`.\n */\nexport const SHARED_POOL = \"shared\";\n\nexport type DropOptions = {\n\t/** Drop title. */\n\ttitle?: string;\n\t/** public (default) or unlisted. */\n\tvisibility?: \"public\" | \"unlisted\";\n\t/** Require password to view. Pass `null` to remove password protection. */\n\tpassword?: string | null;\n\t/** Prevent search-engine indexing. Pass `null` to allow indexing (default). */\n\tnoindex?: boolean | null;\n\t/** Auto-delete after this ISO 8601 date. Pass `null` to clear. */\n\texpiresAt?: string | Date | null;\n\t/** Entry file for multi-file bundles (default: index.html). */\n\tentry?: string;\n\t/** Attach JSON key-value pairs, e.g. `{ source: \"ci\" }`. */\n\tmetadata?: Record<string, unknown>;\n\t/**\n\t * Hostname of a custom domain connected to this account (must be live — see\n\t * `client.domains`), or {@link SHARED_POOL} (`\"shared\"`) to publish to the shared\n\t * pool even when the account has a default domain. Path-mode domains serve the drop\n\t * at `https://{domain}/{slug}/`; dedicated domains serve it at the root and conflict\n\t * (409) once occupied. Omit to use the account's default path domain if one exists,\n\t * else the shared pool.\n\t */\n\tdomain?: string | null;\n\t/**\n\t * Vanity slug — only valid when the target is a path-mode custom domain. 1–63\n\t * lowercase letters/digits/hyphens (no leading/trailing/double hyphen). Taken slugs\n\t * are auto-suffixed; omit for a random slug. Setting this on the shared pool returns\n\t * 422.\n\t */\n\tslug?: string | null;\n};\n\nexport type PrepareOptions = {\n\t/** Glob patterns to ignore when publishing directories. */\n\tignore?: string[];\n\t/** Disable default ignore patterns. */\n\tignoreDefaults?: boolean;\n\t/** Override MIME type (auto-detected from extension). */\n\tcontentType?: string;\n\t/** Set filename when publishing from stdin or bytes. */\n\tpath?: string;\n};\n\nexport type RequestControls = {\n\t/** Prevent duplicate publishes on retry (auto-generated by CLI). */\n\tidempotencyKey?: string;\n\t/** Fail if current revision doesn't match -- optimistic lock (update only). */\n\tifRevision?: number;\n};\n\nexport type PublishOptions = DropOptions &\n\tPrepareOptions &\n\tRequestControls & {\n\t\t/**\n\t\t * Target workspace slug or id — publish/prepare only (a fresh drop's workspace).\n\t\t * Delegated credentials only; ignored by pinned service keys. Falls back to the\n\t\t * client-level `workspace` default when omitted. Not a settings field: it is NOT\n\t\t * accepted by `updateSettings` (a drop never moves workspace) nor by `updateContent`\n\t\t * (which stays in the drop's own workspace).\n\t\t */\n\t\tworkspace?: string;\n\t};\n\n/**\n * Options for `drops.updateContent()` — content-only. A content update ships a new content version\n * and never changes drop settings (title, visibility, password, noindex, expiry, metadata); those\n * belong on `drops.updateSettings()`. Carries only content-prep + request controls + the bundle\n * `entry`.\n */\nexport type UpdateContentOptions = PrepareOptions &\n\tRequestControls & {\n\t\t/** Entry file for multi-file bundles (default: index.html). */\n\t\tentry?: string;\n\t\t/**\n\t\t * How the supplied files combine with what the drop already serves\n\t\t * (partial-by-default, ADR 0065):\n\t\t *\n\t\t * - `\"patch\"` (default): the supplied files upsert by path and every\n\t\t * unmentioned file is carried forward, so editing one file never drops the\n\t\t * rest. Use `deletePaths` to remove files.\n\t\t * - `\"replace\"`: the supplied files become the drop's entire content set —\n\t\t * a full swap. Anything not supplied is gone. `deletePaths` is invalid here.\n\t\t *\n\t\t * Omit to default to `\"patch\"`.\n\t\t */\n\t\tmode?: \"patch\" | \"replace\";\n\t\t/**\n\t\t * Paths to remove from the drop's content (patch-mode only). Each path must\n\t\t * exist or the server rejects the update (loud, never a silent no-op). Invalid\n\t\t * with `mode: \"replace\"`. Wire field: `delete_paths`.\n\t\t */\n\t\tdeletePaths?: string[];\n\t};\n\n/**\n * One file in a multi-file `{ kind: \"files\" }` bundle. Supply the bytes inline\n * exactly one way — `content` (UTF-8 text), `contentBase64`, or `bytes` — OR set\n * `sourceUrl` to a public http(s) URL and let the server fetch that file for you\n * server-side (no bytes pass through your process). A single entry may NOT carry\n * both inline bytes and `sourceUrl`. Mix freely within one bundle: e.g. inline\n * `content` for `index.html` plus a `sourceUrl` for each image referenced by it,\n * yielding one self-contained drop.\n */\nexport type PublishFileInput = {\n\tpath: string;\n\tcontentType?: string;\n\tcontent?: string;\n\tcontentBase64?: string;\n\tbytes?: Uint8Array;\n\t/**\n\t * Public http(s) URL the server fetches this file's bytes from during publish\n\t * (publish by reference). Mutually exclusive with `content`/`contentBase64`/`bytes`.\n\t */\n\tsourceUrl?: string;\n\t/**\n\t * Declared byte size of the remote file (optional hint for `sourceUrl` files).\n\t * When provided, the server uses this for upfront quota admission before fetching,\n\t * so a large file is rejected immediately rather than after the server downloads it.\n\t * Ignored for inline files (size is computed from the bytes).\n\t */\n\tsizeBytes?: number;\n\t/**\n\t * Expected SHA-256 hex digest of the remote file (optional hint for `sourceUrl` files).\n\t * When provided, the server verifies the fetched content matches this checksum and\n\t * rejects the publish if it does not, giving you integrity verification without\n\t * downloading the bytes yourself.\n\t * Ignored for inline files (checksum is computed by the SDK/server from actual bytes).\n\t */\n\tchecksumSha256?: string;\n};\n\nexport type PublishInput =\n\t| string\n\t| string[]\n\t| URL\n\t| Uint8Array\n\t| { kind: \"content\"; content: string; contentType?: string; path?: string }\n\t| { kind: \"source_url\"; sourceUrl: string }\n\t| { kind: \"files\"; files: PublishFileInput[]; entry?: string };\n\n/** Structured next-step hint returned by domain operations (and publish). */\nexport type NextHint = { action: string; message: string };\n\n/** One DNS record instruction or diagnostic for a custom domain. */\nexport type DnsRecord = {\n\t/** Purpose of the record, e.g. \"routing\". */\n\tpurpose: string;\n\t/** DNS record type, e.g. \"CNAME\". */\n\ttype: string;\n\t/** The DNS name to create the record for. */\n\tname: string;\n\t/** The value the record must point at. */\n\tvalue: string;\n\t/** Current DNS status: \"missing\" | \"ok\" | \"mismatch\". */\n\tstatus: \"missing\" | \"ok\" | \"mismatch\";\n\t/** What DoH currently resolves for this record (verify only). */\n\tobserved?: string | null;\n\t/** Specific guidance for fixing this record. */\n\thint?: string | null;\n\t/** Seconds to wait before retrying verify while DNS/cert propagates. */\n\tretryAfter?: number | null;\n};\n\n/** Full domain resource representation. */\nexport type DomainResponse = {\n\tobject: \"domain\";\n\t/** Stable domain identifier. */\n\tid: string;\n\t/** Canonical hostname registered with dropthis. */\n\thostname: string;\n\t/** Mount mode: \"path\" (many drops at hostname/{slug}/) or \"dedicated\" (one drop at hostname/). */\n\tmode: \"path\" | \"dedicated\";\n\t/** Lifecycle status: \"pending_dns\" | \"verifying\" | \"live\" | \"failed\". */\n\tstatus: \"pending_dns\" | \"verifying\" | \"live\" | \"failed\";\n\t/** Reason for failure status. */\n\tfailureReason?: string | null;\n\t/** Whether this is the account's default publish domain. */\n\tdefault: boolean;\n\t/** Mounted drop id (dedicated mode only). */\n\tdropId?: string | null;\n\t/** DNS records required for this domain. */\n\tdns: DnsRecord[];\n\t/** Creation timestamp. */\n\tcreatedAt: string;\n\t/** When the domain first reached \"live\" status. */\n\tverifiedAt?: string | null;\n\t/** Structured next-step hints for the agent. */\n\tnext: NextHint[];\n\t/**\n\t * Deep link to this domain's setup page in the dropthis console\n\t * (e.g. https://app.dropthis.app/domains/dom_…). Hand this to a human so\n\t * they can add the DNS record and watch it go live in a polished UI.\n\t */\n\tconsoleUrl: string;\n};\n\n/** List of domains for the account. */\nexport type DomainListResponse = {\n\tobject: \"domain.list\";\n\t/** Domains connected to this account. */\n\tdomains: DomainResponse[];\n};\n\n/** Response body for a successful domain deletion. */\nexport type DomainDeletedResponse = {\n\tobject: \"domain.deleted\";\n\t/** Id of the deleted domain. */\n\tid: string;\n\t/** Hostname of the deleted domain. */\n\thostname: string;\n\t/** Dangling-CNAME risk warning (always present; instructs you to remove the DNS record). */\n\twarning: string;\n};\n\n/** One readable file in a deployment's content manifest. */\nexport type DeploymentContentFile = {\n\t/** File path within the deployment, relative to its root. */\n\tpath: string;\n\t/** Stored MIME type the file is served with. */\n\tcontentType: string;\n\t/** Stored file size in bytes. */\n\tsizeBytes: number;\n};\n\n/**\n * Manifest of one deployment's readable files (content read-back).\n * Fetch a single file's bytes with `drops.getContent(dropId, { path })`.\n */\nexport type DeploymentContentManifest = {\n\t/** Parent drop identifier. */\n\tdropId: string;\n\t/** Deployment identifier. */\n\tdeploymentId: string;\n\t/** Content revision of this deployment. */\n\trevision: number;\n\t/** Deployment lifecycle status. */\n\tstatus: string;\n\t/** Total deployment size in bytes. */\n\tsizeBytes: number;\n\t/** Entry path served at the drop root. */\n\tentry?: string | null;\n\t/** Readable files in this deployment; pass files[].path as `path` to download one. */\n\tfiles: DeploymentContentFile[];\n};\n\n/** Options for `drops.getContent()`. */\nexport type GetContentOptions = {\n\t/** Read a historical deployment instead of the current one. */\n\tdeploymentId?: string;\n\t/** Download this single file's raw stored bytes instead of the JSON manifest. */\n\tpath?: string;\n};\n\n/** A single file downloaded via `drops.getContent(dropId, { path })`. */\nexport type DropContentFile = {\n\t/** The requested file path. */\n\tpath: string;\n\t/** Stored MIME type the file is served with (from the response Content-Type). */\n\tcontentType: string | null;\n\t/** Exact stored bytes. */\n\tbytes: Uint8Array;\n\t/** Decode the bytes as UTF-8 text. */\n\ttext(): string;\n};\n"],"mappings":"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","names":["readFile","stat","basename","stat","basename","readFile","resolveInput"]}
1
+ {"version":3,"sources":["../src/publish/node.ts","../src/errors.ts","../src/publish/checksum.ts","../src/publish/detect.ts","../src/publish/paths.ts","../src/publish/core.ts","../src/publish/files.ts","../src/resources/account.ts","../src/resources/api-keys.ts","../src/resources/auth.ts","../src/resources/deployments.ts","../src/resources/domains.ts","../src/pagination.ts","../src/resources/drops.ts","../src/resources/invitations.ts","../src/resources/members.ts","../src/resources/uploads.ts","../src/resources/workspaces.ts","../src/case.ts","../src/transport.ts","../src/dropthis.ts","../src/types.ts"],"sourcesContent":["import { readFile, stat } from \"node:fs/promises\";\nimport { basename } from \"node:path\";\nimport { PublishInputError } from \"../errors.js\";\nimport type { PublishInput, PublishOptions } from \"../types.js\";\nimport { sha256File } from \"./checksum.js\";\nimport {\n\tbuildStagedRequest,\n\ttype InMemoryPublishInput,\n\ttype PreparedPublishRequest,\n\ttype PreparedUploadFile,\n\tresolveInMemory,\n} from \"./core.js\";\nimport { isHttpUrl, isPathShaped } from \"./detect.js\";\nimport type { PublishFile } from \"./files.js\";\nimport { collectPublishFiles, detectPathContentType } from \"./files.js\";\nimport { assertValidManifestPath } from \"./paths.js\";\n\n/**\n * Files at or above this size get a precomputed sha256 so the server can verify\n * the signed upload. Smaller files skip the hash to keep publishes snappy.\n * Matches the threshold the legacy prepare.ts used.\n */\nconst SINGLE_PUT_CHECKSUM_THRESHOLD = 10 * 1024 * 1024;\n\n/**\n * Resolves any {@link PublishInput} into a {@link PreparedPublishRequest},\n * adding filesystem support on top of the pure in-memory resolver in core.ts.\n *\n * - URL / Uint8Array / `{ kind }` objects → delegate to {@link resolveInMemory}.\n * - `string[]` → a local bundle of files/directories.\n * - bare `string` → stat-first: http URL → source; multiline/oversized → inline\n * content; otherwise stat the path (file/dir) or treat as inline prose.\n */\nexport async function resolveInput(\n\tinput: PublishInput,\n\toptions: PublishOptions = {},\n): Promise<PreparedPublishRequest> {\n\tif (\n\t\tinput instanceof URL ||\n\t\tinput instanceof Uint8Array ||\n\t\t(typeof input === \"object\" && input !== null && \"kind\" in input)\n\t) {\n\t\treturn resolveInMemory(input as InMemoryPublishInput, options);\n\t}\n\n\tif (Array.isArray(input)) {\n\t\treturn resolveBundle(input, options);\n\t}\n\n\tif (typeof input === \"string\") {\n\t\treturn resolveString(input, options);\n\t}\n\n\t// Exhaustive: the PublishInput union has no other members.\n\treturn resolveInMemory(input as InMemoryPublishInput, options);\n}\n\n/**\n * Bare-string resolution. ORDER MATTERS:\n * 1. http(s) URL → source. MUST precede stat: a URL is path-shaped (has \"/\"),\n * so a stat/path-shaped check first would wrongly report file_not_found.\n * 2. multiline or oversized (>4096) → inline content (cannot be a path).\n * 3. stat the value: file → fileStaged, dir → folderStaged, missing →\n * file_not_found if path-shaped, else inline prose content.\n */\nasync function resolveString(\n\tvalue: string,\n\toptions: PublishOptions,\n): Promise<PreparedPublishRequest> {\n\tif (isHttpUrl(value)) return resolveInMemory(value, options);\n\tif (value.includes(\"\\n\") || value.length > 4096) {\n\t\treturn resolveInMemory(value, options);\n\t}\n\n\tlet info: Awaited<ReturnType<typeof stat>> | undefined;\n\ttry {\n\t\tinfo = await stat(value);\n\t} catch {\n\t\tinfo = undefined;\n\t}\n\n\tif (info?.isFile()) return fileStaged(value, options);\n\tif (info?.isDirectory()) return folderStaged(value, options);\n\n\tif (isPathShaped(value)) {\n\t\tthrow new PublishInputError(\n\t\t\t\"file_not_found\",\n\t\t\t`No file or directory at \"${value}\".`,\n\t\t\tvalue,\n\t\t\t'To publish this as inline text, pass { kind: \"content\", content }.',\n\t\t);\n\t}\n\treturn resolveInMemory(value, options);\n}\n\n/** Stages a single local file. Defers the entry to buildStagedRequest. */\nasync function fileStaged(\n\tpath: string,\n\toptions: PublishOptions,\n): Promise<PreparedPublishRequest> {\n\tconst fileStat = await stat(path);\n\tif (options.path !== undefined) assertValidManifestPath(options.path);\n\tconst manifestPath = options.path ?? basename(path);\n\tconst contentType =\n\t\toptions.contentType ?? (await detectPathContentType(path));\n\tconst checksumSha256 =\n\t\tfileStat.size > SINGLE_PUT_CHECKSUM_THRESHOLD\n\t\t\t? await sha256File(path)\n\t\t\t: undefined;\n\tconst file: PreparedUploadFile = {\n\t\tpath: manifestPath,\n\t\tcontentType,\n\t\tsizeBytes: fileStat.size,\n\t\t...(checksumSha256 ? { checksumSha256 } : {}),\n\t\tgetBody: () => readFile(path),\n\t};\n\treturn buildStagedRequest([file], options);\n}\n\n/** Stages every file under a local directory (tree-relative manifest paths). */\nasync function folderStaged(\n\tpath: string,\n\toptions: PublishOptions,\n): Promise<PreparedPublishRequest> {\n\tconst files = await collectPublishFiles(path, options);\n\tconst preparedFiles = await Promise.all(files.map(toPreparedFile));\n\treturn buildStagedRequest(preparedFiles, options);\n}\n\n/**\n * Stages a list of local file/directory paths. Each element is statted (missing\n * → file_not_found) then expanded via collectPublishFiles (basename for a file,\n * tree-relative for a directory). Basename collisions across elements surface as\n * duplicate_path from buildStagedRequest.\n */\nasync function resolveBundle(\n\tpaths: string[],\n\toptions: PublishOptions,\n): Promise<PreparedPublishRequest> {\n\tconst collected: PublishFile[] = [];\n\tfor (const element of paths) {\n\t\ttry {\n\t\t\tawait stat(element);\n\t\t} catch {\n\t\t\tthrow new PublishInputError(\n\t\t\t\t\"file_not_found\",\n\t\t\t\t`No file or directory at \"${element}\".`,\n\t\t\t\telement,\n\t\t\t);\n\t\t}\n\t\tcollected.push(...(await collectPublishFiles(element, options)));\n\t}\n\tconst preparedFiles = await Promise.all(collected.map(toPreparedFile));\n\treturn buildStagedRequest(preparedFiles, options);\n}\n\n/** Maps a collected PublishFile to a lazy-body PreparedUploadFile. */\nasync function toPreparedFile(pf: PublishFile): Promise<PreparedUploadFile> {\n\tconst checksumSha256 =\n\t\tpf.sizeBytes > SINGLE_PUT_CHECKSUM_THRESHOLD\n\t\t\t? await sha256File(pf.absolutePath)\n\t\t\t: undefined;\n\treturn {\n\t\tpath: pf.path,\n\t\tcontentType: pf.contentType,\n\t\tsizeBytes: pf.sizeBytes,\n\t\t...(checksumSha256 ? { checksumSha256 } : {}),\n\t\tgetBody: () => readFile(pf.absolutePath),\n\t};\n}\n","import type { DropthisResult } from \"./types.js\";\n\nconst API_KEY_RE = /sk_[A-Za-z0-9_-]+/g;\n\nexport function redactSecrets(message: string): string {\n\treturn message.replace(API_KEY_RE, \"sk_[redacted]\");\n}\n\nexport function createErrorResult<T>(\n\tcode: string,\n\tmessage: string,\n\tstatusCode: number | null,\n\textra: {\n\t\ttype?: string;\n\t\ttitle?: string;\n\t\tdetail?: string | null;\n\t\tinstance?: string | null;\n\t\tparam?: string | null;\n\t\tcurrentRevision?: number;\n\t\trequestId?: string | null;\n\t\theaders?: Record<string, string>;\n\t\tsuggestion?: string | null;\n\t\tretryable?: boolean | null;\n\t\t// Plan-gate fields (feature_not_in_plan / quota_exceeded — the unified\n\t\t// gate contract). Present only on plan denials; null/absent otherwise.\n\t\tfeature?: string | null;\n\t\tcurrentPlan?: string | null;\n\t\trequiredPlan?: string | null;\n\t\tupgradeUrl?: string | null;\n\t\tlimit?: number | null;\n\t\tused?: number | null;\n\t\trequested?: number | null;\n\t\tbody?: unknown;\n\t} = {},\n): DropthisResult<T> {\n\treturn {\n\t\tdata: null,\n\t\terror: {\n\t\t\tcode,\n\t\t\tmessage: redactSecrets(message),\n\t\t\tstatusCode,\n\t\t\t...(extra.type ? { type: extra.type } : {}),\n\t\t\t...(extra.title !== undefined ? { title: extra.title } : {}),\n\t\t\t...(extra.detail !== undefined ? { detail: extra.detail } : {}),\n\t\t\t...(extra.instance !== undefined ? { instance: extra.instance } : {}),\n\t\t\t...(extra.param !== undefined ? { param: extra.param } : {}),\n\t\t\t...(extra.currentRevision !== undefined\n\t\t\t\t? { currentRevision: extra.currentRevision }\n\t\t\t\t: {}),\n\t\t\t...(extra.requestId !== undefined ? { requestId: extra.requestId } : {}),\n\t\t\t...(extra.suggestion !== undefined\n\t\t\t\t? { suggestion: extra.suggestion }\n\t\t\t\t: {}),\n\t\t\t...(extra.retryable !== undefined ? { retryable: extra.retryable } : {}),\n\t\t\t...(extra.feature != null ? { feature: extra.feature } : {}),\n\t\t\t...(extra.currentPlan != null ? { currentPlan: extra.currentPlan } : {}),\n\t\t\t...(extra.requiredPlan != null\n\t\t\t\t? { requiredPlan: extra.requiredPlan }\n\t\t\t\t: {}),\n\t\t\t...(extra.upgradeUrl != null ? { upgradeUrl: extra.upgradeUrl } : {}),\n\t\t\t...(extra.limit != null ? { limit: extra.limit } : {}),\n\t\t\t...(extra.used != null ? { used: extra.used } : {}),\n\t\t\t...(extra.requested != null ? { requested: extra.requested } : {}),\n\t\t\t...(extra.body !== undefined ? { body: extra.body } : {}),\n\t\t},\n\t\theaders: extra.headers ?? {},\n\t};\n}\n\n/** True for a capability denial (`feature_not_in_plan`) — a plan gate, never retryable. */\nexport function isFeatureNotInPlan(error: { code: string } | null): boolean {\n\treturn error?.code === \"feature_not_in_plan\";\n}\n\n/** True for a numeric-ceiling denial (`quota_exceeded`: per-drop bytes 413, or an\n * account ceiling 403). Never retryable — a plan ceiling does not free up on retry. */\nexport function isQuotaExceeded(error: { code: string } | null): boolean {\n\treturn error?.code === \"quota_exceeded\";\n}\n\n/** True for either plan-gate code — branch a retry layer on this to stop and\n * hand off to a human instead of re-issuing a request that can never succeed. */\nexport function isPlanGate(error: { code: string } | null): boolean {\n\treturn isFeatureNotInPlan(error) || isQuotaExceeded(error);\n}\n\nexport class PublishInputError extends Error {\n\tconstructor(\n\t\treadonly code: string,\n\t\tmessage: string,\n\t\treadonly param?: string,\n\t\treadonly suggestion?: string,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"PublishInputError\";\n\t}\n}\n\nexport function toErrorResult<T>(err: unknown): DropthisResult<T> {\n\tif (err instanceof PublishInputError)\n\t\treturn createErrorResult<T>(err.code, err.message, null, {\n\t\t\tparam: err.param ?? null,\n\t\t\tsuggestion: err.suggestion ?? null,\n\t\t});\n\treturn createErrorResult<T>(\n\t\t\"sdk_error\",\n\t\terr instanceof Error ? err.message : \"Unknown SDK error\",\n\t\tnull,\n\t);\n}\n","import { createHash } from \"node:crypto\";\nimport { createReadStream } from \"node:fs\";\n\nexport function sha256Bytes(bytes: Uint8Array): string {\n\treturn createHash(\"sha256\").update(bytes).digest(\"hex\");\n}\n\nexport async function sha256File(path: string): Promise<string> {\n\tconst hash = createHash(\"sha256\");\n\tfor await (const chunk of createReadStream(path)) {\n\t\thash.update(chunk);\n\t}\n\treturn hash.digest(\"hex\");\n}\n","export function isHttpUrl(value: string): boolean {\n\ttry {\n\t\tconst url = new URL(value);\n\t\treturn url.protocol === \"http:\" || url.protocol === \"https:\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport function containsHtmlTag(value: string): boolean {\n\treturn /<[a-z!/][^>]*>/i.test(value);\n}\n\nconst FILE_EXT = /\\.[A-Za-z0-9]{1,8}([?#].*)?$/;\nexport function isPathShaped(value: string): boolean {\n\tif (value.length === 0 || value.length > 4096 || value.includes(\"\\n\"))\n\t\treturn false;\n\t// Reject strings that look like HTML (tags disqualify path interpretation)\n\tif (containsHtmlTag(value)) return false;\n\tif (value.includes(\"/\") || value.includes(\"\\\\\")) return true;\n\tif (/^[A-Za-z]:[\\\\/]/.test(value)) return true;\n\treturn FILE_EXT.test(value);\n}\n\nexport function contentTypeForString(value: string, override?: string): string {\n\tif (override) return override;\n\treturn containsHtmlTag(value) ? \"text/html\" : \"text/plain; charset=utf-8\";\n}\n\nexport function detectBytesContentType(bytes: Uint8Array): string {\n\tconst text = new TextDecoder(\"utf-8\", { fatal: false }).decode(bytes);\n\tif (text.includes(\"�\")) return \"application/octet-stream\";\n\treturn containsHtmlTag(text) ? \"text/html\" : \"text/plain; charset=utf-8\";\n}\n\nexport function entryForContentType(contentType: string): string {\n\tconst m = contentType.toLowerCase().split(\";\", 1)[0]?.trim() ?? \"\";\n\tif (m === \"text/html\" || m === \"application/xhtml+xml\") return \"index.html\";\n\tif (m === \"application/json\") return \"index.json\";\n\tif (m === \"text/css\") return \"index.css\";\n\tif (m === \"text/javascript\" || m === \"application/javascript\")\n\t\treturn \"index.js\";\n\tif (m.startsWith(\"text/\")) return \"index.txt\";\n\treturn \"index\";\n}\n","import { PublishInputError } from \"../errors.js\";\n\nexport function normalizeManifestPath(path: string): string {\n\treturn path.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n}\n\nexport function assertValidManifestPath(path: string): void {\n\t// User-supplied manifest paths ({kind:\"files\"}.path, options.path, options.entry) must be POSIX.\n\t// Local filesystem paths are normalized via normalizeManifestPath, NOT passed here.\n\tif (path.includes(\"\\\\\"))\n\t\tthrow new PublishInputError(\n\t\t\t\"invalid_path\",\n\t\t\t`Manifest path must use \"/\": \"${path}\".`,\n\t\t\tpath,\n\t\t);\n\tconst p = normalizeManifestPath(path);\n\tif (p === \"\")\n\t\tthrow new PublishInputError(\n\t\t\t\"invalid_path\",\n\t\t\t\"Manifest path must not be empty.\",\n\t\t\tpath,\n\t\t);\n\tif (p.startsWith(\"/\"))\n\t\tthrow new PublishInputError(\n\t\t\t\"invalid_path\",\n\t\t\t`Manifest path must be relative: \"${path}\".`,\n\t\t\tpath,\n\t\t);\n\tif (p.startsWith(\"~\"))\n\t\tthrow new PublishInputError(\n\t\t\t\"invalid_path\",\n\t\t\t`Manifest path must not start with \"~\": \"${path}\".`,\n\t\t\tpath,\n\t\t);\n\tif (p.split(\"/\").includes(\"..\"))\n\t\tthrow new PublishInputError(\n\t\t\t\"invalid_path\",\n\t\t\t`Manifest path must not contain \"..\": \"${path}\".`,\n\t\t\tpath,\n\t\t);\n}\n\nexport function assertNoDuplicatePaths(paths: string[]): void {\n\tconst seen = new Set<string>();\n\tfor (const raw of paths) {\n\t\tconst p = normalizeManifestPath(raw);\n\t\tif (seen.has(p))\n\t\t\tthrow new PublishInputError(\n\t\t\t\t\"duplicate_path\",\n\t\t\t\t`Duplicate file path after normalization: \"${p}\".`,\n\t\t\t\tp,\n\t\t\t\t\"Give each file a unique path; basename mapping for string[] can collide.\",\n\t\t\t);\n\t\tseen.add(p);\n\t}\n}\n\nexport function assertNonEmptyBundle(paths: string[]): void {\n\tif (paths.length === 0)\n\t\tthrow new PublishInputError(\n\t\t\t\"empty_bundle\",\n\t\t\t\"Nothing to publish: the bundle has no files.\",\n\t\t\tundefined,\n\t\t\t\"Pass at least one file, or a directory that contains files.\",\n\t\t);\n}\n","import { createErrorResult, PublishInputError } from \"../errors.js\";\nimport type { Transport } from \"../transport.js\";\nimport type {\n\tCreateUploadSessionFileResponse,\n\tCreateUploadSessionRequest,\n\tCreateUploadSessionResponse,\n\tDropResponse,\n\tDropthisResult,\n\tImageTransform,\n\tIngestSessionResponse,\n\tPublishFileInput,\n\tPublishOptions,\n\tUpdateContentOptions,\n\tUploadManifestFile,\n\tUploadSessionResponse,\n} from \"../types.js\";\nimport {\n\tcontentTypeForString,\n\tdetectBytesContentType,\n\tentryForContentType,\n\tisHttpUrl,\n} from \"./detect.js\";\nimport {\n\tassertNoDuplicatePaths,\n\tassertNonEmptyBundle,\n\tassertValidManifestPath,\n\tnormalizeManifestPath,\n} from \"./paths.js\";\n\n/**\n * A file ready to be staged for upload. Two shapes:\n *\n * - **client-put** — the SDK pushes the bytes. The body is lazy: the orchestrator\n * calls `getBody()` per file when it is ready to push bytes to the signed URL.\n * This keeps the resolution layer pure and lets the filesystem layer (node.ts)\n * defer reads/streams until upload time.\n * - **remote** (`sourceUrl` set, no `getBody`) — the server fetches the bytes from\n * `sourceUrl` during `POST /uploads/{id}/ingest`. No bytes leave this process, so\n * it has no `getBody`, no `sizeBytes`, and consumes no signed PUT target.\n */\nexport type PreparedUploadFile =\n\t| {\n\t\t\tpath: string;\n\t\t\tcontentType: string;\n\t\t\tsizeBytes: number;\n\t\t\tchecksumSha256?: string;\n\t\t\tsourceUrl?: never;\n\t\t\tgetBody(): Promise<Uint8Array | Blob | ReadableStream>;\n\t }\n\t| {\n\t\t\tpath: string;\n\t\t\tsourceUrl: string;\n\t\t\tcontentType?: string;\n\t\t\t/** Optional hint: declared byte size for upfront quota admission (server-side). */\n\t\t\tsizeBytes?: number;\n\t\t\t/** Optional hint: expected SHA-256 hex digest for server-side integrity check. */\n\t\t\tchecksumSha256?: string;\n\t\t\t/** Optional server-side image transform applied on ingest (resize/re-encode). */\n\t\t\ttransform?: ImageTransform;\n\t\t\tgetBody?: never;\n\t };\n\n/**\n * Resolves a publish input into a {@link PreparedPublishRequest}. Two implementations exist:\n * the fs-free {@link resolveInMemory} (Workers-safe) and the fs-capable `resolveInput` in\n * `publish/node.ts`. `DropsResource` takes one by injection so it can power both the Node client\n * and the edge client WITHOUT statically importing the Node-only pipeline (which would poison the\n * Workers bundle with `node:fs`/`fast-glob`). `TInput` is the input type the chosen resolver\n * accepts ({@link InMemoryPublishInput} on the edge, the full `PublishInput` on Node).\n */\nexport type PublishInputResolver<TInput> = (\n\tinput: TInput,\n\toptions: PublishOptions,\n) => Promise<PreparedPublishRequest>;\n\nexport type PreparedPublishRequest =\n\t| {\n\t\t\tkind: \"staged\";\n\t\t\tmanifest: CreateUploadSessionRequest;\n\t\t\tfiles: PreparedUploadFile[];\n\t\t\toptions: Record<string, unknown>;\n\t\t\tmetadata?: Record<string, unknown>;\n\t\t\t/** Target workspace slug or id (delegated credentials only). Bound at upload-session creation. */\n\t\t\tworkspace?: string;\n\t }\n\t| {\n\t\t\tkind: \"source\";\n\t\t\tsourceUrl: string;\n\t\t\toptions: Record<string, unknown>;\n\t\t\tmetadata?: Record<string, unknown>;\n\t\t\t/** Target workspace slug or id (delegated credentials only). Forwarded as top-level field in POST /drops. */\n\t\t\tworkspace?: string;\n\t };\n\n/**\n * The canonical publish inputs that can be resolved with no filesystem access:\n * the {@link PublishInput} union minus `string[]` (which is inherently a list\n * of filesystem paths handled by node.ts).\n */\nexport type InMemoryPublishInput =\n\t| string\n\t| URL\n\t| Uint8Array\n\t| { kind: \"content\"; content: string; contentType?: string; path?: string }\n\t| { kind: \"source_url\"; sourceUrl: string }\n\t| { kind: \"files\"; files: PublishFileInput[]; entry?: string };\n\nconst VALID_VISIBILITIES = [\"public\", \"unlisted\"] as const;\nconst MAX_TITLE_LENGTH = 500;\n\nexport function validatePublishOptions(options: PublishOptions): void {\n\tif (\n\t\toptions.title !== undefined &&\n\t\toptions.title !== null &&\n\t\toptions.title.length > MAX_TITLE_LENGTH\n\t) {\n\t\tthrow new Error(`Title must be ${MAX_TITLE_LENGTH} characters or less.`);\n\t}\n\n\tif (options.visibility !== undefined && options.visibility !== null) {\n\t\tif (\n\t\t\t!(VALID_VISIBILITIES as readonly string[]).includes(options.visibility)\n\t\t) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid visibility \"${options.visibility}\". Use \"public\" or \"unlisted\".`,\n\t\t\t);\n\t\t}\n\t}\n\n\tif (options.expiresAt !== undefined && options.expiresAt !== null) {\n\t\tif (options.expiresAt instanceof Date) {\n\t\t\tif (Number.isNaN(options.expiresAt.getTime())) {\n\t\t\t\tthrow new Error(\"Invalid expiresAt date.\");\n\t\t\t}\n\t\t} else if (typeof options.expiresAt === \"string\") {\n\t\t\tconst parsed = new Date(options.expiresAt);\n\t\t\tif (Number.isNaN(parsed.getTime())) {\n\t\t\t\tthrow new Error(\"Invalid expiresAt date.\");\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport function optionsBody(options: PublishOptions): Record<string, unknown> {\n\tvalidatePublishOptions(options);\n\tconst body: Record<string, unknown> = {};\n\tif (options.title !== undefined) body.title = options.title;\n\tif (options.visibility !== undefined) body.visibility = options.visibility;\n\tif (options.password !== undefined) body.password = options.password;\n\tif (options.noindex !== undefined) body.noindex = options.noindex;\n\tif (options.expiresAt !== undefined) {\n\t\tbody.expiresAt =\n\t\t\toptions.expiresAt instanceof Date\n\t\t\t\t? options.expiresAt.toISOString()\n\t\t\t\t: options.expiresAt;\n\t}\n\tif (options.domain !== undefined) body.domain = options.domain;\n\tif (options.slug !== undefined) body.slug = options.slug;\n\treturn body;\n}\n\n/**\n * Narrow options to the content-only subset for `drops.updateContent()`: a content update ships a\n * new content version and never changes drop settings (title, visibility, password, noindex,\n * expiry, metadata). Picking only content-prep + request controls drops any settings BEFORE\n * prepare, so they are never validated, sent, or applied.\n */\nexport function updateContentOptions(\n\toptions: UpdateContentOptions,\n): UpdateContentOptions {\n\tconst out: UpdateContentOptions = {};\n\tif (options.entry !== undefined) out.entry = options.entry;\n\tif (options.contentType !== undefined) out.contentType = options.contentType;\n\tif (options.path !== undefined) out.path = options.path;\n\tif (options.ignore !== undefined) out.ignore = options.ignore;\n\tif (options.ignoreDefaults !== undefined)\n\t\tout.ignoreDefaults = options.ignoreDefaults;\n\tif (options.idempotencyKey !== undefined)\n\t\tout.idempotencyKey = options.idempotencyKey;\n\tif (options.ifRevision !== undefined) out.ifRevision = options.ifRevision;\n\tif (options.mode !== undefined) out.mode = options.mode;\n\tif (options.deletePaths !== undefined) out.deletePaths = options.deletePaths;\n\treturn out;\n}\n\n/**\n * Builds a staged upload request from already-prepared files. Validates the\n * bundle is non-empty, normalizes manifest paths, and rejects duplicates.\n * Reused by core's in-memory paths AND by node.ts for file/dir/string[] inputs.\n *\n * `entry` argument wins over `options.entry`.\n */\nexport function buildStagedRequest(\n\tfiles: PreparedUploadFile[],\n\toptions: PublishOptions,\n\tentry?: string,\n): PreparedPublishRequest {\n\tassertNonEmptyBundle(files.map((f) => f.path));\n\tconst normalizedPaths = files.map((f) => normalizeManifestPath(f.path));\n\tassertNoDuplicatePaths(normalizedPaths);\n\n\tconst manifestFiles: UploadManifestFile[] = files.map((file) =>\n\t\tfile.sourceUrl !== undefined\n\t\t\t? // Remote entry: the server fetches the bytes on /ingest. Emit sourceUrl\n\t\t\t\t// plus optional metadata hints (contentType, sizeBytes, checksumSha256)\n\t\t\t\t// when the caller declared them. The transport snake_cases all camelCase\n\t\t\t\t// keys to source_url / content_type / size_bytes / checksum_sha256.\n\t\t\t\t{\n\t\t\t\t\tpath: normalizeManifestPath(file.path),\n\t\t\t\t\tsourceUrl: file.sourceUrl,\n\t\t\t\t\t...(file.contentType ? { contentType: file.contentType } : {}),\n\t\t\t\t\t...(file.sizeBytes !== undefined\n\t\t\t\t\t\t? { sizeBytes: file.sizeBytes }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\t...(file.checksumSha256\n\t\t\t\t\t\t? { checksumSha256: file.checksumSha256 }\n\t\t\t\t\t\t: {}),\n\t\t\t\t\t...(file.transform ? { transform: file.transform } : {}),\n\t\t\t\t}\n\t\t\t: {\n\t\t\t\t\tpath: normalizeManifestPath(file.path),\n\t\t\t\t\tcontentType: file.contentType,\n\t\t\t\t\tsizeBytes: file.sizeBytes,\n\t\t\t\t\t...(file.checksumSha256\n\t\t\t\t\t\t? { checksumSha256: file.checksumSha256 }\n\t\t\t\t\t\t: {}),\n\t\t\t\t},\n\t);\n\n\tconst resolvedEntry = entry ?? options.entry;\n\tif (resolvedEntry !== undefined) assertValidManifestPath(resolvedEntry);\n\tconst manifest: CreateUploadSessionRequest = {\n\t\tschemaVersion: 1,\n\t\tfiles: manifestFiles,\n\t\t...(resolvedEntry ? { entry: resolvedEntry } : {}),\n\t\t...(options.workspace !== undefined\n\t\t\t? { workspace: options.workspace }\n\t\t\t: {}),\n\t};\n\n\tconst prepared: Extract<PreparedPublishRequest, { kind: \"staged\" }> = {\n\t\tkind: \"staged\",\n\t\tmanifest,\n\t\tfiles,\n\t\toptions: optionsBody(options),\n\t};\n\tif (options.metadata) prepared.metadata = options.metadata;\n\tif (options.workspace !== undefined) prepared.workspace = options.workspace;\n\treturn prepared;\n}\n\n/** Builds a `source_url` request (validates http(s)). */\nexport function buildSourceRequest(\n\tsourceUrl: string,\n\toptions: PublishOptions,\n): PreparedPublishRequest {\n\tif (!isHttpUrl(sourceUrl)) {\n\t\tthrow new PublishInputError(\n\t\t\t\"invalid_source_url\",\n\t\t\t\"source_url must be an http(s) URL.\",\n\t\t\tsourceUrl,\n\t\t\t\"Fetch the content first, then pass it as content/files.\",\n\t\t);\n\t}\n\tconst prepared: Extract<PreparedPublishRequest, { kind: \"source\" }> = {\n\t\tkind: \"source\",\n\t\tsourceUrl,\n\t\toptions: optionsBody(options),\n\t};\n\tif (options.metadata) prepared.metadata = options.metadata;\n\tif (options.workspace !== undefined) prepared.workspace = options.workspace;\n\treturn prepared;\n}\n\nfunction decodeBase64(value: string): Uint8Array {\n\tconst binary = atob(value);\n\treturn Uint8Array.from(binary, (c) => c.charCodeAt(0));\n}\n\nfunction fileBytes(file: PublishFileInput): Uint8Array {\n\tif (file.content !== undefined) return new TextEncoder().encode(file.content);\n\tif (file.contentBase64 !== undefined) return decodeBase64(file.contentBase64);\n\tif (file.bytes !== undefined) return file.bytes;\n\tthrow new PublishInputError(\n\t\t\"missing_file_bytes\",\n\t\t`File \"${file.path}\" is missing content bytes.`,\n\t\tfile.path,\n\t\t\"Provide one of content, contentBase64, or bytes, or set sourceUrl.\",\n\t);\n}\n\n/** True when a bundle entry supplies its bytes inline (vs. by reference). */\nfunction hasInlineBytes(file: PublishFileInput): boolean {\n\treturn (\n\t\tfile.content !== undefined ||\n\t\tfile.contentBase64 !== undefined ||\n\t\tfile.bytes !== undefined\n\t);\n}\n\n/**\n * Resolves one `{ kind: \"files\" }` entry into a {@link PreparedUploadFile}.\n * A `sourceUrl` entry becomes a remote file (server fetches it on /ingest) —\n * no bytes leave this process. Optional `contentType`, `sizeBytes`, and\n * `checksumSha256` hints are forwarded to the server for quota admission and\n * integrity verification. Rejects an entry that mixes inline bytes with\n * `sourceUrl`, and a non-http(s) `sourceUrl`.\n */\nfunction prepareBundleFile(file: PublishFileInput): PreparedUploadFile {\n\tassertValidManifestPath(file.path);\n\tif (file.sourceUrl !== undefined) {\n\t\tif (hasInlineBytes(file)) {\n\t\t\tthrow new PublishInputError(\n\t\t\t\t\"conflicting_file_source\",\n\t\t\t\t`File \"${file.path}\" sets both inline content and sourceUrl; pick one.`,\n\t\t\t\tfile.path,\n\t\t\t\t\"Drop sourceUrl to upload bytes, or drop content/contentBase64/bytes to fetch by reference.\",\n\t\t\t);\n\t\t}\n\t\tif (!isHttpUrl(file.sourceUrl)) {\n\t\t\tthrow new PublishInputError(\n\t\t\t\t\"invalid_source_url\",\n\t\t\t\t`File \"${file.path}\" sourceUrl must be an http(s) URL.`,\n\t\t\t\tfile.path,\n\t\t\t\t\"Fetch the bytes first and pass them inline, or use an http(s) URL.\",\n\t\t\t);\n\t\t}\n\t\treturn {\n\t\t\tpath: file.path,\n\t\t\tsourceUrl: file.sourceUrl,\n\t\t\t...(file.contentType ? { contentType: file.contentType } : {}),\n\t\t\t...(file.sizeBytes !== undefined ? { sizeBytes: file.sizeBytes } : {}),\n\t\t\t...(file.checksumSha256 ? { checksumSha256: file.checksumSha256 } : {}),\n\t\t\t...(file.transform ? { transform: file.transform } : {}),\n\t\t};\n\t}\n\tconst bytes = fileBytes(file);\n\tconst contentType = file.contentType ?? detectBytesContentType(bytes);\n\treturn {\n\t\tpath: file.path,\n\t\tcontentType,\n\t\tsizeBytes: bytes.byteLength,\n\t\tgetBody: async () => bytes,\n\t};\n}\n\nfunction singleStagedFile(\n\tpath: string,\n\tcontentType: string,\n\tbytes: Uint8Array,\n\toptions: PublishOptions,\n): PreparedPublishRequest {\n\treturn buildStagedRequest(\n\t\t[\n\t\t\t{\n\t\t\t\tpath,\n\t\t\t\tcontentType,\n\t\t\t\tsizeBytes: bytes.byteLength,\n\t\t\t\tgetBody: async () => bytes,\n\t\t\t},\n\t\t],\n\t\toptions,\n\t);\n}\n\n/**\n * Resolves the in-memory canonical inputs (the edge subset of {@link PublishInput})\n * into a {@link PreparedPublishRequest}. Performs NO filesystem access.\n */\nexport async function resolveInMemory(\n\tinput: InMemoryPublishInput,\n\toptions: PublishOptions = {},\n): Promise<PreparedPublishRequest> {\n\tif (input instanceof URL) {\n\t\treturn buildSourceRequest(input.toString(), options);\n\t}\n\n\tif (typeof input === \"string\") {\n\t\tif (isHttpUrl(input)) return buildSourceRequest(input, options);\n\t\tconst contentType = contentTypeForString(input, options.contentType);\n\t\tif (options.path !== undefined) assertValidManifestPath(options.path);\n\t\tconst path = options.path ?? entryForContentType(contentType);\n\t\tconst bytes = new TextEncoder().encode(input);\n\t\treturn singleStagedFile(path, contentType, bytes, options);\n\t}\n\n\t// A Node binary buffer is a Uint8Array subclass, so this branch also covers\n\t// it without referencing the Node-only global.\n\tif (input instanceof Uint8Array) {\n\t\tconst contentType = options.contentType ?? detectBytesContentType(input);\n\t\tif (options.path !== undefined) assertValidManifestPath(options.path);\n\t\tconst path = options.path ?? entryForContentType(contentType);\n\t\treturn singleStagedFile(path, contentType, input, options);\n\t}\n\n\tif (input.kind === \"content\") {\n\t\tconst contentType = input.contentType ?? options.contentType ?? \"text/html\";\n\t\tif (input.path !== undefined) assertValidManifestPath(input.path);\n\t\tif (options.path !== undefined) assertValidManifestPath(options.path);\n\t\tconst path = input.path ?? options.path ?? entryForContentType(contentType);\n\t\tconst bytes = new TextEncoder().encode(input.content);\n\t\treturn singleStagedFile(path, contentType, bytes, options);\n\t}\n\n\tif (input.kind === \"source_url\") {\n\t\treturn buildSourceRequest(input.sourceUrl, options);\n\t}\n\n\t// input.kind === \"files\"\n\tconst files: PreparedUploadFile[] = input.files.map(prepareBundleFile);\n\treturn buildStagedRequest(files, options, input.entry);\n}\n\n// ---------------------------------------------------------------------------\n// Orchestration helpers\n// ---------------------------------------------------------------------------\n\ntype StagedPublishOptions = {\n\tidempotencyKey?: string;\n\tifRevision?: number;\n\t/**\n\t * Partial-update mode for a content update (ADR 0065). Emitted as the wire field\n\t * `mode` on the deployment body. Only set by `drops.updateContent()`; `publish()`\n\t * never carries it, so a fresh publish has no mode field.\n\t */\n\tmode?: \"patch\" | \"replace\";\n\t/**\n\t * Paths to delete on a patch-mode content update. Emitted as the wire field\n\t * `delete_paths` on the deployment body. Only set by `drops.updateContent()`.\n\t */\n\tdeletePaths?: string[];\n};\n\n/**\n * The partial-update fields (`mode`, `delete_paths`) for a content-update deployment\n * body, snake_cased by the transport. Only included when set — a fresh publish or a\n * default-mode update omits them entirely.\n */\nfunction partialUpdateBody(\n\toptions: StagedPublishOptions,\n): Record<string, unknown> {\n\treturn {\n\t\t...(options.mode !== undefined ? { mode: options.mode } : {}),\n\t\t...(options.deletePaths !== undefined\n\t\t\t? { deletePaths: options.deletePaths }\n\t\t\t: {}),\n\t};\n}\n\n/** How many signed file PUTs run concurrently during a staged upload. */\nconst UPLOAD_CONCURRENCY = 5;\n\n/**\n * Timeout for `POST /uploads/{id}/ingest`. The server fetches every remote\n * (`sourceUrl`) file over the network during this call, so it can take far\n * longer than a normal control-plane request — give it the upload-sized budget.\n */\nconst INGEST_TIMEOUT_MS = 120_000;\n\nfunction errorResult<T>(result: DropthisResult<unknown>): DropthisResult<T> {\n\tif (!result.error) throw new Error(\"Expected an error result\");\n\treturn { data: null, error: result.error, headers: result.headers };\n}\n\n/** A client-put file paired with its signed target. Remote files never become jobs. */\ntype UploadJob = {\n\tfile: Extract<PreparedUploadFile, { getBody: unknown }>;\n\ttarget: CreateUploadSessionFileResponse;\n};\n\n/**\n * Uploads staged files through their signed PUT targets with bounded parallelism.\n * Fail-fast: the first failure stops new uploads from starting (in-flight ones\n * drain). Returns the lowest-index failure — attributed to its file path — or null\n * when every upload succeeded. Each PUT sends exactly the headers the server signed\n * for that file (this is what carries the checksum contract).\n */\nasync function uploadStagedFiles(\n\ttransport: Transport,\n\tjobs: UploadJob[],\n): Promise<DropthisResult<never> | null> {\n\tlet nextIndex = 0;\n\tlet failed = false;\n\tconst failures = new Map<number, DropthisResult<never>>();\n\n\tasync function worker(): Promise<void> {\n\t\twhile (!failed) {\n\t\t\tconst index = nextIndex;\n\t\t\tnextIndex += 1;\n\t\t\tif (index >= jobs.length) return;\n\t\t\tconst job = jobs[index];\n\t\t\tif (!job) return;\n\t\t\tconst put = await transport.putSignedUrl(\n\t\t\t\tjob.target.upload.url,\n\t\t\t\tawait job.file.getBody(),\n\t\t\t\tjob.target.upload.headers,\n\t\t\t);\n\t\t\tif (put.error) {\n\t\t\t\tfailed = true;\n\t\t\t\tfailures.set(index, {\n\t\t\t\t\tdata: null,\n\t\t\t\t\terror: {\n\t\t\t\t\t\t...put.error,\n\t\t\t\t\t\tmessage: `Upload failed for ${job.file.path}: ${put.error.message}`,\n\t\t\t\t\t},\n\t\t\t\t\theaders: put.headers,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tconst workers = Array.from(\n\t\t{ length: Math.min(UPLOAD_CONCURRENCY, jobs.length) },\n\t\t() => worker(),\n\t);\n\tawait Promise.all(workers);\n\n\tif (failures.size === 0) return null;\n\tconst firstIndex = Math.min(...failures.keys());\n\treturn failures.get(firstIndex) ?? null;\n}\n\n/**\n * Executes the staged-upload publish flow (single-PUT only).\n * Calls POST /uploads → PUT signed URL per file → POST /uploads/{id}/complete\n * → POST finalPath. (Paths are version-agnostic here; the transport prefixes /v1.)\n */\nexport async function publishStaged(\n\ttransport: Transport,\n\tprepared: Extract<PreparedPublishRequest, { kind: \"staged\" }>,\n\tfinalPath: string,\n\toptions: StagedPublishOptions = {},\n): Promise<DropthisResult<DropResponse>> {\n\tconst baseKey = options.idempotencyKey ?? `sdk-${crypto.randomUUID()}`;\n\n\t// Step 1: create upload session\n\tconst createResult = await transport.request<CreateUploadSessionResponse>(\n\t\t\"POST\",\n\t\t\"/uploads\",\n\t\t{\n\t\t\tbody: prepared.manifest,\n\t\t\tidempotencyKey: `${baseKey}:create-upload`,\n\t\t},\n\t);\n\tif (createResult.error) return errorResult(createResult);\n\n\t// Step 2: pair every CLIENT-PUT file with its signed target, then upload via\n\t// bounded-parallel single PUTs. Remote (sourceUrl) files are server-fetched on\n\t// /ingest, so they get no signed target and consume no PUT. Target validation\n\t// happens up front so no bytes move when the session response is malformed.\n\tconst jobs: UploadJob[] = [];\n\tfor (const file of prepared.files) {\n\t\tif (file.sourceUrl !== undefined) continue;\n\t\tconst target = createResult.data.files.find((f) => f.path === file.path);\n\t\tif (!target) {\n\t\t\treturn createErrorResult(\n\t\t\t\t\"upload_target_missing\",\n\t\t\t\t`Upload target missing for ${file.path}`,\n\t\t\t\tnull,\n\t\t\t);\n\t\t}\n\t\tif (target.upload.strategy !== \"single_put\") {\n\t\t\t// Defensive: a single signed PUT per file IS the upload contract — the server\n\t\t\t// only ever assigns single_put. Anything else means a newer server contract\n\t\t\t// this SDK predates.\n\t\t\treturn createErrorResult(\n\t\t\t\t\"unsupported_upload_strategy\",\n\t\t\t\t`Unexpected upload strategy \"${target.upload.strategy}\" for ${file.path}. The dropthis upload contract is one signed PUT per file; update @dropthis/node.`,\n\t\t\t\tnull,\n\t\t\t);\n\t\t}\n\t\tjobs.push({ file, target });\n\t}\n\tconst uploadFailure = await uploadStagedFiles(transport, jobs);\n\tif (uploadFailure) return uploadFailure;\n\n\t// Step 2b: if any manifest entry is remote (sourceUrl), tell the server to fetch\n\t// those files into staging. This runs AFTER the client-put files land and BEFORE\n\t// /complete so the session has every file before it is verified. Server-side\n\t// fetches can be slow, so use an extended timeout.\n\tconst hasRemote = prepared.files.some((f) => f.sourceUrl !== undefined);\n\tif (hasRemote) {\n\t\tconst ingestResult = await transport.request<IngestSessionResponse>(\n\t\t\t\"POST\",\n\t\t\t`/uploads/${encodeURIComponent(createResult.data.uploadId)}/ingest`,\n\t\t\t{\n\t\t\t\tidempotencyKey: `${baseKey}:ingest-upload`,\n\t\t\t\ttimeoutMs: INGEST_TIMEOUT_MS,\n\t\t\t},\n\t\t);\n\t\tif (ingestResult.error) return errorResult(ingestResult);\n\t}\n\n\t// Step 3: complete upload session (no request body — the server verifies the\n\t// staged objects against the manifest)\n\tconst completeResult = await transport.request<UploadSessionResponse>(\n\t\t\"POST\",\n\t\t`/uploads/${encodeURIComponent(createResult.data.uploadId)}/complete`,\n\t\t{\n\t\t\tidempotencyKey: `${baseKey}:complete-upload`,\n\t\t},\n\t);\n\tif (completeResult.error) return errorResult(completeResult);\n\n\t// Step 4: final publish\n\tconst finalOptions: Parameters<Transport[\"request\"]>[2] = {\n\t\tbody: {\n\t\t\tuploadId: createResult.data.uploadId,\n\t\t\t...(Object.keys(prepared.options).length > 0\n\t\t\t\t? { options: prepared.options }\n\t\t\t\t: {}),\n\t\t\t...(prepared.metadata ? { metadata: prepared.metadata } : {}),\n\t\t\t...partialUpdateBody(options),\n\t\t},\n\t\tidempotencyKey: `${baseKey}:publish`,\n\t};\n\tif (options.ifRevision !== undefined)\n\t\tfinalOptions.ifRevision = options.ifRevision;\n\treturn transport.request<DropResponse>(\"POST\", finalPath, finalOptions);\n}\n\n/**\n * Executes the source-URL publish flow.\n * Sends a single POST to finalPath with { sourceUrl, options } and optional metadata.\n */\nexport async function publishSource(\n\ttransport: Transport,\n\tprepared: Extract<PreparedPublishRequest, { kind: \"source\" }>,\n\tfinalPath: string,\n\toptions: StagedPublishOptions = {},\n): Promise<DropthisResult<DropResponse>> {\n\tconst baseKey = options.idempotencyKey ?? `sdk-${crypto.randomUUID()}`;\n\treturn transport.request<DropResponse>(\"POST\", finalPath, {\n\t\tbody: {\n\t\t\tsourceUrl: prepared.sourceUrl,\n\t\t\t...(Object.keys(prepared.options).length > 0\n\t\t\t\t? { options: prepared.options }\n\t\t\t\t: {}),\n\t\t\t...(prepared.metadata ? { metadata: prepared.metadata } : {}),\n\t\t\t...(prepared.workspace !== undefined\n\t\t\t\t? { workspace: prepared.workspace }\n\t\t\t\t: {}),\n\t\t\t...partialUpdateBody(options),\n\t\t},\n\t\tidempotencyKey: `${baseKey}:publish`,\n\t\t...(options.ifRevision !== undefined\n\t\t\t? { ifRevision: options.ifRevision }\n\t\t\t: {}),\n\t});\n}\n","import { readFile, stat } from \"node:fs/promises\";\nimport { basename, sep } from \"node:path\";\nimport fg from \"fast-glob\";\nimport ignore from \"ignore\";\nimport { lookup } from \"mime-types\";\nimport { detectBytesContentType } from \"./detect.js\";\n\nexport type PublishFile = {\n\tabsolutePath: string;\n\tpath: string;\n\tcontentType: string;\n\tsizeBytes: number;\n};\n\nconst DEFAULT_IGNORES = [\n\t\".git\",\n\t\".git/**\",\n\t\"node_modules\",\n\t\"node_modules/**\",\n\t\".DS_Store\",\n\t\".env\",\n\t\".env.*\",\n\t\".cache\",\n\t\".cache/**\",\n\t\".tmp\",\n\t\".tmp/**\",\n\t\"dist/.cache\",\n\t\"dist/.cache/**\",\n];\n\nexport async function collectPublishFiles(\n\tinputPath: string,\n\toptions: { ignore?: string[]; ignoreDefaults?: boolean } = {},\n): Promise<PublishFile[]> {\n\tconst inputStat = await stat(inputPath);\n\tif (inputStat.isFile()) {\n\t\treturn [\n\t\t\t{\n\t\t\t\tabsolutePath: inputPath,\n\t\t\t\tpath: basename(inputPath),\n\t\t\t\tcontentType: await detectPathContentType(inputPath),\n\t\t\t\tsizeBytes: inputStat.size,\n\t\t\t},\n\t\t];\n\t}\n\tif (!inputStat.isDirectory()) {\n\t\tthrow new Error(`Input is not a file or directory: ${inputPath}`);\n\t}\n\n\tconst matcher = ignore().add([\n\t\t...(options.ignoreDefaults === false ? [] : DEFAULT_IGNORES),\n\t\t...(options.ignore ?? []),\n\t]);\n\tconst entries = await fg(\"**/*\", {\n\t\tcwd: inputPath,\n\t\tonlyFiles: true,\n\t\tfollowSymbolicLinks: false,\n\t\tdot: true,\n\t\tunique: true,\n\t});\n\tconst paths = entries\n\t\t.map((entry) => entry.split(sep).join(\"/\"))\n\t\t.filter((entry) => !matcher.ignores(entry))\n\t\t.sort((a, b) => a.localeCompare(b));\n\treturn Promise.all(\n\t\tpaths.map(async (path) => {\n\t\t\tconst absolutePath = `${inputPath}/${path}`;\n\t\t\tconst fileStat = await stat(absolutePath);\n\t\t\treturn {\n\t\t\t\tabsolutePath,\n\t\t\t\tpath,\n\t\t\t\tcontentType: await detectPathContentType(absolutePath),\n\t\t\t\tsizeBytes: fileStat.size,\n\t\t\t};\n\t\t}),\n\t);\n}\n\nexport async function detectPathContentType(path: string): Promise<string> {\n\tconst detected = lookup(path);\n\tif (detected) return detected;\n\treturn detectBytesContentType(await readFile(path));\n}\n","import type { Transport } from \"../transport.js\";\nimport type { AccountResponse, DropthisResult } from \"../types.js\";\n\nexport class AccountResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\tget(): Promise<DropthisResult<AccountResponse>> {\n\t\treturn this.transport.request(\"GET\", \"/account\");\n\t}\n\n\tupdate(input: {\n\t\tdisplayName: string | null;\n\t}): Promise<DropthisResult<AccountResponse>> {\n\t\treturn this.transport.request(\"PATCH\", \"/account\", { body: input });\n\t}\n\n\tdelete(): Promise<DropthisResult<null>> {\n\t\treturn this.transport.request(\"DELETE\", \"/account\");\n\t}\n}\n","import type { Transport } from \"../transport.js\";\nimport type {\n\tApiKeyCreatedResponse,\n\tApiKeyResponse,\n\tDropthisResult,\n\tKeyType,\n} from \"../types.js\";\n\nexport class ApiKeysResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\tlist(): Promise<DropthisResult<{ object: \"list\"; data: ApiKeyResponse[] }>> {\n\t\treturn this.transport.request(\"GET\", \"/api-keys\");\n\t}\n\n\tcreate(input: {\n\t\tlabel: string;\n\t\t/** Key type: `\"delegated\"` (default on server) or `\"service\"` (pinned to a workspace). */\n\t\ttype?: KeyType;\n\t\t/** Pin a `service` key to this workspace slug or id. */\n\t\tworkspace?: string;\n\t\t/** Restrict a `delegated` key to these workspace slugs or ids. */\n\t\tallowedWorkspaces?: string[];\n\t\t/**\n\t\t * Request the credential's capability scopes (ADR 0068). Each entry is a bundle\n\t\t * name (`publish`, `team`, `team-admin`) or a fine-grained scope (`members:admin`).\n\t\t * The minted key gets the requested set intersected with your own scopes\n\t\t * (downscope-only). Omit for the default `publish` bundle; pass `[\"team\"]` to mint\n\t\t * a credential that can create + manage teams (`login --scope team`).\n\t\t */\n\t\tscopes?: string[];\n\t}): Promise<DropthisResult<ApiKeyCreatedResponse>> {\n\t\t// Build the wire body with exact snake_case keys the server expects.\n\t\t// We cannot rely on the transport's auto-conversion for `allowed_workspace_ids`\n\t\t// because `allowedWorkspaces` → `allowed_workspaces`, not `allowed_workspace_ids`.\n\t\tconst body: Record<string, unknown> = { label: input.label };\n\t\tif (input.type !== undefined) body.key_type = input.type;\n\t\tif (input.workspace !== undefined) body.workspace = input.workspace;\n\t\tif (input.allowedWorkspaces !== undefined)\n\t\t\tbody.allowed_workspace_ids = input.allowedWorkspaces;\n\t\tif (input.scopes !== undefined) body.scopes = input.scopes;\n\t\treturn this.transport.request(\"POST\", \"/api-keys\", { body });\n\t}\n\n\t/** Revoke an API key. 204 No Content — data is null on success. */\n\tdelete(keyId: string): Promise<DropthisResult<null>> {\n\t\treturn this.transport.request(\n\t\t\t\"DELETE\",\n\t\t\t`/api-keys/${encodeURIComponent(keyId)}`,\n\t\t);\n\t}\n}\n","import type { Transport } from \"../transport.js\";\nimport type {\n\tDropthisResult,\n\tEmailOtpResponse,\n\tSessionResponse,\n} from \"../types.js\";\n\nexport class AuthResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\trequestEmailOtp(input: {\n\t\temail: string;\n\t}): Promise<DropthisResult<EmailOtpResponse>> {\n\t\treturn this.transport.request(\"POST\", \"/auth/email/otp\", {\n\t\t\tbody: input,\n\t\t\tauthenticated: false,\n\t\t});\n\t}\n\n\t/**\n\t * Verify an email OTP and exchange it for a short-lived `at_` session token.\n\t * On failure the error `code` distinguishes `otp_expired` (no active code —\n\t * request a new one) from `otp_invalid` (wrong digits — re-check, do not\n\t * auto-resend). 401 on either. See dropthis#80.\n\t */\n\tverifyEmailOtp(input: {\n\t\temail: string;\n\t\tcode: string;\n\t}): Promise<DropthisResult<SessionResponse>> {\n\t\treturn this.transport.request(\"POST\", \"/auth/email/verify\", {\n\t\t\tbody: input,\n\t\t\tauthenticated: false,\n\t\t});\n\t}\n\n\t/** Revoke the current `at_` session token. 204 No Content — data is null on success. */\n\tlogout(): Promise<DropthisResult<null>> {\n\t\treturn this.transport.request(\"DELETE\", \"/auth/session\");\n\t}\n}\n","import type { Transport } from \"../transport.js\";\nimport type {\n\tDropDeploymentResponse,\n\tDropthisResult,\n\tListDeploymentsParams,\n\tListDeploymentsResponse,\n} from \"../types.js\";\n\nexport class DeploymentsResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\tlist(\n\t\tdropId: string,\n\t\tparams: ListDeploymentsParams = {},\n\t): Promise<DropthisResult<ListDeploymentsResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"GET\",\n\t\t\t`/drops/${encodeURIComponent(dropId)}/deployments`,\n\t\t\t{ params },\n\t\t);\n\t}\n\n\tget(\n\t\tdropId: string,\n\t\tdeploymentId: string,\n\t): Promise<DropthisResult<DropDeploymentResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"GET\",\n\t\t\t`/drops/${encodeURIComponent(dropId)}/deployments/${encodeURIComponent(deploymentId)}`,\n\t\t);\n\t}\n}\n","import type { Transport } from \"../transport.js\";\nimport type {\n\tDomainDeletedResponse,\n\tDomainListResponse,\n\tDomainResponse,\n\tDropthisResult,\n} from \"../types.js\";\n\nexport class DomainsResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\t/**\n\t * Connect a custom domain to the account. Returns the domain in `pending_dns` status with\n\t * DNS instructions. Idempotent on (account, hostname) — re-connecting an already-connected\n\t * domain returns the existing row. POST /domains.\n\t */\n\tconnect(input: {\n\t\thostname: string;\n\t\tmode: \"path\" | \"dedicated\";\n\t}): Promise<DropthisResult<DomainResponse>> {\n\t\treturn this.transport.request(\"POST\", \"/domains\", { body: input });\n\t}\n\n\t/** List all custom domains connected to this account. GET /domains. */\n\tlist(): Promise<DropthisResult<DomainListResponse>> {\n\t\treturn this.transport.request(\"GET\", \"/domains\");\n\t}\n\n\t/** Get a domain by its stable id or hostname. GET /domains/{id_or_hostname}. */\n\tget(idOrHostname: string): Promise<DropthisResult<DomainResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"GET\",\n\t\t\t`/domains/${encodeURIComponent(idOrHostname)}`,\n\t\t);\n\t}\n\n\t/**\n\t * Trigger a DNS + Cloudflare verification check. Returns the domain with updated status and\n\t * per-record diagnostics. If DNS is still propagating, `dns[].retryAfter` tells you when to\n\t * re-call. POST /domains/{id_or_hostname}/verify.\n\t */\n\tverify(idOrHostname: string): Promise<DropthisResult<DomainResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"POST\",\n\t\t\t`/domains/${encodeURIComponent(idOrHostname)}/verify`,\n\t\t);\n\t}\n\n\t/**\n\t * Update a domain's `dropId` (dedicated mode: repoint to a different drop) or `default`\n\t * flag (path mode only: set/clear the account's default publish domain). Mode is immutable\n\t * — delete and reconnect to change it. PATCH /domains/{id_or_hostname}.\n\t */\n\tupdate(\n\t\tidOrHostname: string,\n\t\tinput: { dropId?: string | null; default?: boolean | null },\n\t): Promise<DropthisResult<DomainResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"PATCH\",\n\t\t\t`/domains/${encodeURIComponent(idOrHostname)}`,\n\t\t\t{ body: input },\n\t\t);\n\t}\n\n\t/**\n\t * Delete a custom domain and remove all its routes. The response includes a dangling-CNAME\n\t * warning — remove the DNS record after deleting so another account cannot re-claim the\n\t * hostname. DELETE /domains/{id_or_hostname}.\n\t */\n\tdelete(idOrHostname: string): Promise<DropthisResult<DomainDeletedResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"DELETE\",\n\t\t\t`/domains/${encodeURIComponent(idOrHostname)}`,\n\t\t);\n\t}\n}\n","import type { DropthisResult, ListPage } from \"./types.js\";\n\nexport class CursorPage<T> implements ListPage<T> {\n\treadonly object = \"list\" as const;\n\treadonly data: T[];\n\treadonly hasMore: boolean;\n\treadonly nextCursor: string | null;\n\t/** Response headers from the fetch that produced this page. */\n\treadonly headers: Record<string, string>;\n\tprivate readonly fetchNextPage:\n\t\t| (() => Promise<DropthisResult<CursorPage<T>>>)\n\t\t| undefined;\n\n\tconstructor(input: {\n\t\tdata: T[];\n\t\thasMore: boolean;\n\t\tnextCursor: string | null;\n\t\theaders?: Record<string, string>;\n\t\tfetchNextPage?: (() => Promise<DropthisResult<CursorPage<T>>>) | undefined;\n\t}) {\n\t\tthis.data = input.data;\n\t\tthis.hasMore = input.hasMore;\n\t\tthis.nextCursor = input.nextCursor;\n\t\tthis.headers = input.headers ?? {};\n\t\tthis.fetchNextPage = input.fetchNextPage;\n\t}\n\n\t/**\n\t * Collect items across every page into a single array.\n\t *\n\t * No-throw, consistent with the rest of the SDK's {@link DropthisResult}\n\t * contract: returns `{ data: items, error: null }` on success, or\n\t * `{ data: null, error }` if fetching a later page fails — never a thrown\n\t * exception, and never a silently truncated list. Inspect `.error`\n\t * (`code`/`statusCode`/`retryable`/`requestId`) exactly as you would for any\n\t * other call. Pass `limit` to stop once that many items are collected.\n\t */\n\tasync autoPagingToArray(\n\t\toptions: { limit?: number } = {},\n\t): Promise<DropthisResult<T[]>> {\n\t\tconst { limit } = options;\n\t\tif (limit !== undefined && limit <= 0) {\n\t\t\treturn { data: [], error: null, headers: this.headers };\n\t\t}\n\t\tconst items: T[] = [];\n\t\tlet current: CursorPage<T> | undefined = this;\n\t\tlet lastHeaders: Record<string, string> = this.headers;\n\n\t\twhile (current) {\n\t\t\tfor (const item of current.data) {\n\t\t\t\titems.push(item);\n\t\t\t\tif (limit !== undefined && items.length >= limit) {\n\t\t\t\t\treturn { data: items, error: null, headers: lastHeaders };\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!current.hasMore || !current.fetchNextPage) break;\n\t\t\tconst next = await current.fetchNextPage();\n\t\t\tif (next.error) {\n\t\t\t\treturn { data: null, error: next.error, headers: next.headers };\n\t\t\t}\n\t\t\tlastHeaders = next.headers;\n\t\t\tcurrent = next.data;\n\t\t}\n\n\t\treturn { data: items, error: null, headers: lastHeaders };\n\t}\n}\n","import { toErrorResult } from \"../errors.js\";\nimport { CursorPage } from \"../pagination.js\";\nimport {\n\ttype PreparedPublishRequest,\n\ttype PublishInputResolver,\n\tpublishSource,\n\tpublishStaged,\n\tupdateContentOptions,\n} from \"../publish/core.js\";\nimport type { Transport } from \"../transport.js\";\nimport type {\n\tDeploymentContentManifest,\n\tDropContentFile,\n\tDropOptions,\n\tDropResponse,\n\tDropthisResult,\n\tGetContentOptions,\n\tListDropsParams,\n\tPublishInput,\n\tPublishOptions,\n\tRequestControls,\n\tUpdateContentOptions,\n} from \"../types.js\";\n\n/**\n * The drop lifecycle resource. `TInput` is the publish-input type the injected resolver accepts:\n * the full `PublishInput` on the Node client, the fs-free `InMemoryPublishInput` on the edge. The\n * resolver is injected (not statically imported) so this module never pulls in the Node-only\n * publish pipeline and stays Workers-safe.\n */\nexport class DropsResource<TInput = PublishInput> {\n\tconstructor(\n\t\tprivate readonly transport: Transport,\n\t\tprivate readonly resolveInput: PublishInputResolver<TInput>,\n\t\tprivate readonly defaultWorkspace?: string,\n\t) {}\n\n\t/**\n\t * Publish content to a NEW permanent public URL; returns the created drop (with its `drop_…` id).\n\t * Use to publish / share / post / put online / make public a report, dashboard, site, or file.\n\t * Creates a NEW drop every call — to change something already published, use {@link updateContent}\n\t * (the files at the URL) or {@link updateSettings} (title, visibility, password, expiry,\n\t * metadata) with the drop's id; calling publish again makes a duplicate. POST /drops.\n\t *\n\t * Mount target: `options.domain` accepts a connected custom hostname, or `SHARED_POOL`\n\t * (`\"shared\"`) to publish to the shared pool even when the account has a default domain.\n\t *\n\t * Two URLs come back on the response: `url` is the canonical, **always-branded** human\n\t * view (badge guaranteed, no client detection); `rawUrl` is the drop's exact bytes at\n\t * their natural path — hand it to other agents. `rawUrl` is populated only for single\n\t * non-HTML files (`renderMode: \"file_viewer\"`) and is `null` for HTML drops and\n\t * collections. To stream bytes through the SDK for any drop kind, use {@link getContent}.\n\t */\n\tasync publish(\n\t\tinput: TInput,\n\t\toptions: PublishOptions = {},\n\t): Promise<DropthisResult<DropResponse>> {\n\t\t// Merge the client-level workspace default ONLY for fresh publish (never for\n\t\t// updateContent, which stays in the drop's own workspace).\n\t\tconst merged: PublishOptions =\n\t\t\tthis.defaultWorkspace !== undefined && options.workspace === undefined\n\t\t\t\t? { ...options, workspace: this.defaultWorkspace }\n\t\t\t\t: options;\n\t\tlet prepared: PreparedPublishRequest;\n\t\ttry {\n\t\t\tprepared = await this.resolveInput(input, merged);\n\t\t} catch (e) {\n\t\t\treturn toErrorResult<DropResponse>(e);\n\t\t}\n\t\treturn prepared.kind === \"source\"\n\t\t\t? publishSource(this.transport, prepared, \"/drops\", merged)\n\t\t\t: publishStaged(this.transport, prepared, \"/drops\", merged);\n\t}\n\n\t/**\n\t * Replace the content of an EXISTING drop, keeping its URL (ships a new deployment). Requires the\n\t * `drop_…` id from a publish response (not the slug/URL). Content-only: settings/metadata are\n\t * stripped BEFORE prepare, so they are never sent — change those with {@link updateSettings}; create\n\t * a new drop with {@link publish}. Not idempotent (each call is a new deployment) unless you pass the\n\t * same `idempotencyKey`. POST /drops/{id}/deployments.\n\t */\n\tasync updateContent(\n\t\tdropId: string,\n\t\tinput: TInput,\n\t\toptions: UpdateContentOptions = {},\n\t): Promise<DropthisResult<DropResponse>> {\n\t\tconst opts = updateContentOptions(options);\n\t\tlet prepared: PreparedPublishRequest;\n\t\ttry {\n\t\t\tprepared = await this.resolveInput(input, opts);\n\t\t} catch (e) {\n\t\t\treturn toErrorResult<DropResponse>(e);\n\t\t}\n\t\tconst path = `/drops/${encodeURIComponent(dropId)}/deployments`;\n\t\treturn prepared.kind === \"source\"\n\t\t\t? publishSource(this.transport, prepared, path, opts)\n\t\t\t: publishStaged(this.transport, prepared, path, opts);\n\t}\n\n\t/**\n\t * List the account's drops, newest first (paginated). Each item carries its `drop_…` id.\n\t * Pass `domain` to only list drops mounted on that custom domain — the recovery path\n\t * when you have a custom-domain URL but no drop id. GET /drops.\n\t */\n\tasync list(\n\t\tparams: ListDropsParams = {},\n\t): Promise<DropthisResult<CursorPage<DropResponse>>> {\n\t\tconst result = await this.transport.request<{\n\t\t\tdrops: DropResponse[];\n\t\t\tnextCursor: string | null;\n\t\t}>(\"GET\", \"/drops\", {\n\t\t\tparams: params as Record<string, string | number | boolean>,\n\t\t});\n\t\tif (result.error) return result;\n\t\tconst page = new CursorPage<DropResponse>({\n\t\t\tdata: result.data.drops,\n\t\t\tnextCursor: result.data.nextCursor,\n\t\t\thasMore: result.data.nextCursor !== null,\n\t\t\theaders: result.headers,\n\t\t\tfetchNextPage: result.data.nextCursor\n\t\t\t\t? () => this.list({ ...params, cursor: result.data.nextCursor })\n\t\t\t\t: undefined,\n\t\t});\n\t\treturn { data: page, error: null, headers: result.headers };\n\t}\n\n\t/** Fetch one drop by its `drop_…` id (not the slug/URL). GET /drops/{id}. */\n\tget(dropId: string): Promise<DropthisResult<DropResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"GET\",\n\t\t\t`/drops/${encodeURIComponent(dropId)}`,\n\t\t);\n\t}\n\n\t/**\n\t * Resolve a public locator (a drop URL, a custom-domain URL, or a bare vanity/shared\n\t * slug) back to the drop — the way to recover a lost `drop_…` id. Sends the raw target\n\t * to the server (POST /drops/resolve), which owner-scopes and decomposes it. Returns the\n\t * full drop, or `data: null` when nothing of yours matches. A `drop_…` id passed as the\n\t * target round-trips to an owner-scoped id lookup (null instead of 404).\n\t *\n\t * Persist the drop_… id. URLs, raw_url, and slugs are locators, not identifiers — a vanity\n\t * slug is renameable and the pool host rotates, so a stored URL can drift; the id never\n\t * moves. Treat drop_… as an opaque case-sensitive string.\n\t */\n\tasync resolve(target: string): Promise<DropthisResult<DropResponse | null>> {\n\t\tconst result = await this.transport.request<{ data: DropResponse | null }>(\n\t\t\t\"POST\",\n\t\t\t\"/drops/resolve\",\n\t\t\t{ body: { target } },\n\t\t);\n\t\tif (result.error)\n\t\t\treturn { data: null, error: result.error, headers: result.headers };\n\t\treturn { data: result.data.data, error: null, headers: result.headers };\n\t}\n\n\t/**\n\t * Read back what a drop is serving (owner-only; works regardless of any viewer\n\t * password). By default returns the JSON manifest of the CURRENT deployment's files;\n\t * pass `deploymentId` to read a historical (even superseded) deployment — downloading\n\t * an old version's files and republishing them via {@link updateContent} is the\n\t * rollback path. Pass `path` (one of the manifest's `files[].path` values) to download\n\t * that file's exact stored bytes instead. GET /drops/{id}/content.\n\t */\n\tgetContent(\n\t\tdropId: string,\n\t\toptions: GetContentOptions & { path: string },\n\t): Promise<DropthisResult<DropContentFile>>;\n\tgetContent(\n\t\tdropId: string,\n\t\toptions?: Omit<GetContentOptions, \"path\">,\n\t): Promise<DropthisResult<DeploymentContentManifest>>;\n\tasync getContent(\n\t\tdropId: string,\n\t\toptions: GetContentOptions = {},\n\t): Promise<DropthisResult<DeploymentContentManifest | DropContentFile>> {\n\t\tconst base =\n\t\t\toptions.deploymentId !== undefined\n\t\t\t\t? `/drops/${encodeURIComponent(dropId)}/deployments/${encodeURIComponent(options.deploymentId)}/content`\n\t\t\t\t: `/drops/${encodeURIComponent(dropId)}/content`;\n\t\tif (options.path === undefined)\n\t\t\treturn this.transport.request<DeploymentContentManifest>(\"GET\", base);\n\t\tconst path = options.path;\n\t\tconst result = await this.transport.requestBytes(base, {\n\t\t\tparams: { path },\n\t\t});\n\t\tif (result.error)\n\t\t\treturn { data: null, error: result.error, headers: result.headers };\n\t\tconst { bytes, contentType } = result.data;\n\t\treturn {\n\t\t\tdata: {\n\t\t\t\tpath,\n\t\t\t\tcontentType,\n\t\t\t\tbytes,\n\t\t\t\ttext: () => new TextDecoder().decode(bytes),\n\t\t\t},\n\t\t\terror: null,\n\t\t\theaders: result.headers,\n\t\t};\n\t}\n\n\t/**\n\t * Change an EXISTING drop's settings — title, visibility, password, noindex, expiry,\n\t * metadata, domain, or slug — by its `drop_…` id. Does not touch content; replace that\n\t * with {@link updateContent}. Idempotent. PATCH /drops/{id}.\n\t *\n\t * **`domain`** — move the drop to a different custom domain (must be live). Pass `null` to\n\t * move the drop back to the shared pool (unmount from its current domain).\n\t *\n\t * **`slug`** — rename the vanity slug on a path-mode custom domain. Only valid when the drop\n\t * lives on a path-mode domain. Unlike {@link publish} (which auto-suffixes taken slugs),\n\t * `updateSettings` returns 409 on a slug conflict and never auto-suffixes — your code must\n\t * catch 409 and retry with a different slug. Passing `slug` on the shared pool returns 422.\n\t */\n\tupdateSettings(\n\t\tdropId: string,\n\t\toptions: DropOptions & RequestControls = {},\n\t): Promise<DropthisResult<DropResponse>> {\n\t\tconst requestOptions: Parameters<Transport[\"request\"]>[2] = {\n\t\t\tbody: updateBody(options),\n\t\t};\n\t\tif (options.idempotencyKey)\n\t\t\trequestOptions.idempotencyKey = options.idempotencyKey;\n\t\tif (options.ifRevision !== undefined)\n\t\t\trequestOptions.ifRevision = options.ifRevision;\n\t\treturn this.transport.request(\n\t\t\t\"PATCH\",\n\t\t\t`/drops/${encodeURIComponent(dropId)}`,\n\t\t\trequestOptions,\n\t\t);\n\t}\n\n\t/** Permanently delete a drop and its public URL by its `drop_…` id. DELETE /drops/{id}. */\n\tdelete(dropId: string): Promise<DropthisResult<null>> {\n\t\treturn this.transport.request(\n\t\t\t\"DELETE\",\n\t\t\t`/drops/${encodeURIComponent(dropId)}`,\n\t\t);\n\t}\n}\n\nconst SETTINGS = [\n\t\"title\",\n\t\"visibility\",\n\t\"password\",\n\t\"noindex\",\n\t\"expiresAt\",\n\t\"domain\",\n\t\"slug\",\n] as const;\n\nfunction updateBody(options: DropOptions & RequestControls): unknown {\n\tconst out: Record<string, unknown> = {};\n\tfor (const key of SETTINGS)\n\t\tif (options[key] !== undefined) out[key] = options[key];\n\treturn {\n\t\toptions: out,\n\t\t...(options.metadata !== undefined ? { metadata: options.metadata } : {}),\n\t};\n}\n","import type { Transport } from \"../transport.js\";\nimport type {\n\tDropthisResult,\n\tInvitationListResponse,\n\tWorkspace,\n} from \"../types.js\";\n\n/** Invitee-side invitations (ADR 0068). Listing needs `members:read`; accepting needs `members:write`. */\nexport class InvitationsResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\t/** List the calling account's own pending invitations. */\n\tlist(): Promise<DropthisResult<InvitationListResponse>> {\n\t\treturn this.transport.request(\"GET\", \"/invitations\");\n\t}\n\n\t/** Accept by the raw single-use token from the invite email. Joins + switches active workspace. */\n\taccept(input: { token: string }): Promise<DropthisResult<Workspace>> {\n\t\treturn this.transport.request(\"POST\", \"/invitations/accept\", {\n\t\t\tbody: input,\n\t\t});\n\t}\n\n\t/** Accept by invitation id, once authenticated as the invited email — the agent path, no token. */\n\tacceptById(input: {\n\t\tinvitationId: string;\n\t}): Promise<DropthisResult<Workspace>> {\n\t\treturn this.transport.request(\"POST\", \"/invitations/accept-by-id\", {\n\t\t\tbody: input,\n\t\t});\n\t}\n}\n","import type { Transport } from \"../transport.js\";\nimport type {\n\tDropthisResult,\n\tInvitableRole,\n\tInvitation,\n\tMember,\n\tMemberListResponse,\n\tWorkspaceRole,\n} from \"../types.js\";\n\n/** Team membership management (ADR 0068). Capability follows the credential's scopes. */\nexport class MembersResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\t/** List a workspace's members (any member, `members:read`). */\n\tlist(workspaceId: string): Promise<DropthisResult<MemberListResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"GET\",\n\t\t\t`/workspaces/${encodeURIComponent(workspaceId)}/members`,\n\t\t);\n\t}\n\n\t/** Invite an email to the workspace (owner/admin, `members:write`). */\n\tinvite(\n\t\tworkspaceId: string,\n\t\tinput: { email: string; role: InvitableRole },\n\t): Promise<DropthisResult<Invitation>> {\n\t\treturn this.transport.request(\n\t\t\t\"POST\",\n\t\t\t`/workspaces/${encodeURIComponent(workspaceId)}/invitations`,\n\t\t\t{ body: input },\n\t\t);\n\t}\n\n\t/** Change a member's role (`members:admin`, owner-only-touches-owner enforced server-side). */\n\tupdateRole(\n\t\tworkspaceId: string,\n\t\taccountId: string,\n\t\tinput: { role: WorkspaceRole },\n\t): Promise<DropthisResult<Member>> {\n\t\treturn this.transport.request(\n\t\t\t\"PATCH\",\n\t\t\t`/workspaces/${encodeURIComponent(workspaceId)}/members/${encodeURIComponent(accountId)}`,\n\t\t\t{ body: input },\n\t\t);\n\t}\n\n\t/** Remove a member, or leave the workspace (your own id). Removing others needs `members:admin`;\n\t * leaving needs `members:write`. 204 — data is null. */\n\tremove(\n\t\tworkspaceId: string,\n\t\taccountId: string,\n\t): Promise<DropthisResult<null>> {\n\t\treturn this.transport.request(\n\t\t\t\"DELETE\",\n\t\t\t`/workspaces/${encodeURIComponent(workspaceId)}/members/${encodeURIComponent(accountId)}`,\n\t\t);\n\t}\n}\n","import type { Transport } from \"../transport.js\";\nimport type {\n\tCreateUploadSessionRequest,\n\tCreateUploadSessionResponse,\n\tDropthisResult,\n\tUploadSessionResponse,\n} from \"../types.js\";\n\nexport class UploadsResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\tcreate(\n\t\tbody: CreateUploadSessionRequest,\n\t\toptions: { idempotencyKey?: string } = {},\n\t): Promise<DropthisResult<CreateUploadSessionResponse>> {\n\t\tconst requestOptions: Parameters<Transport[\"request\"]>[2] = { body };\n\t\tif (options.idempotencyKey)\n\t\t\trequestOptions.idempotencyKey = options.idempotencyKey;\n\t\treturn this.transport.request(\"POST\", \"/uploads\", requestOptions);\n\t}\n\n\tget(uploadId: string): Promise<DropthisResult<UploadSessionResponse>> {\n\t\treturn this.transport.request(\n\t\t\t\"GET\",\n\t\t\t`/uploads/${encodeURIComponent(uploadId)}`,\n\t\t);\n\t}\n\n\t/**\n\t * Verify staged objects and mark the session complete. Takes no request body —\n\t * the server verifies the uploaded bytes against the staged manifest.\n\t */\n\tcomplete(\n\t\tuploadId: string,\n\t\toptions: { idempotencyKey?: string } = {},\n\t): Promise<DropthisResult<UploadSessionResponse>> {\n\t\tconst requestOptions: Parameters<Transport[\"request\"]>[2] = {};\n\t\tif (options.idempotencyKey)\n\t\t\trequestOptions.idempotencyKey = options.idempotencyKey;\n\t\treturn this.transport.request(\n\t\t\t\"POST\",\n\t\t\t`/uploads/${encodeURIComponent(uploadId)}/complete`,\n\t\t\trequestOptions,\n\t\t);\n\t}\n\n\tcancel(uploadId: string): Promise<DropthisResult<null>> {\n\t\treturn this.transport.request(\n\t\t\t\"DELETE\",\n\t\t\t`/uploads/${encodeURIComponent(uploadId)}`,\n\t\t);\n\t}\n}\n","import type { Transport } from \"../transport.js\";\nimport type { DropthisResult, Workspace } from \"../types.js\";\n\nexport class WorkspacesResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\t// GET /v1/workspaces returns `{ workspaces: Workspace[] }` (server WorkspaceListResponse) — NOT a\n\t// `{ object, data }` page. Reading `.data` here silently yielded an empty list on every surface\n\t// (CLI/MCP/extension); the console worked only because its own client read `.workspaces`.\n\tlist(): Promise<DropthisResult<{ workspaces: Workspace[] }>> {\n\t\treturn this.transport.request(\"GET\", \"/workspaces\");\n\t}\n\n\t/** Create a team workspace (the caller becomes its sole owner). Needs `workspaces:write`. */\n\tcreate(input: {\n\t\tname: string;\n\t\t/** URL-safe slug; derived from the name when omitted. A clash on an explicit slug → 409. */\n\t\tslug?: string;\n\t}): Promise<DropthisResult<Workspace>> {\n\t\treturn this.transport.request(\"POST\", \"/workspaces\", { body: input });\n\t}\n\n\t/** Rename a team workspace (owner/admin). Needs `workspaces:write`. */\n\trename(\n\t\tworkspaceId: string,\n\t\tinput: { name?: string; slug?: string },\n\t): Promise<DropthisResult<Workspace>> {\n\t\treturn this.transport.request(\n\t\t\t\"PATCH\",\n\t\t\t`/workspaces/${encodeURIComponent(workspaceId)}`,\n\t\t\t{ body: input },\n\t\t);\n\t}\n\n\t/** Delete a team workspace (owner only). Needs `workspaces:admin`. 204 — data is null. */\n\tdelete(workspaceId: string): Promise<DropthisResult<null>> {\n\t\treturn this.transport.request(\n\t\t\t\"DELETE\",\n\t\t\t`/workspaces/${encodeURIComponent(workspaceId)}`,\n\t\t);\n\t}\n\n\tuse(workspace: string): Promise<DropthisResult<Workspace>> {\n\t\treturn this.transport.request(\"PUT\", \"/account/active-workspace\", {\n\t\t\tbody: { workspace },\n\t\t});\n\t}\n\n\tasync active(): Promise<DropthisResult<Workspace | null>> {\n\t\tconst result = await this.list();\n\t\tif (result.error !== null) {\n\t\t\treturn result as DropthisResult<Workspace | null>;\n\t\t}\n\t\tconst found = result.data.workspaces.find((ws) => ws.isActive) ?? null;\n\t\treturn { data: found, error: null, headers: result.headers };\n\t}\n}\n","export function toCamelKey(key: string): string {\n\treturn key.replace(/_([a-z])/g, (_, char: string) => char.toUpperCase());\n}\n\nexport function toSnakeKey(key: string): string {\n\treturn key.replace(/[A-Z]/g, (char) => `_${char.toLowerCase()}`);\n}\n\nconst PASSTHROUGH_KEYS = new Set([\"metadata\"]);\n\nexport function toCamelCase(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(toCamelCase);\n\tif (value && typeof value === \"object\") {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(value).map(([key, item]) => [\n\t\t\t\ttoCamelKey(key),\n\t\t\t\tPASSTHROUGH_KEYS.has(key) ? item : toCamelCase(item),\n\t\t\t]),\n\t\t);\n\t}\n\treturn value;\n}\n\nexport function toSnakeCase(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(toSnakeCase);\n\tif (value && typeof value === \"object\") {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(value)\n\t\t\t\t.filter(([, item]) => item !== undefined)\n\t\t\t\t.map(([key, item]) => [\n\t\t\t\t\ttoSnakeKey(key),\n\t\t\t\t\tPASSTHROUGH_KEYS.has(key) ? item : toSnakeCase(item),\n\t\t\t\t]),\n\t\t);\n\t}\n\treturn value;\n}\n","import { toCamelCase, toSnakeCase } from \"./case.js\";\nimport { createErrorResult } from \"./errors.js\";\nimport type {\n\tDropthisClientOptions,\n\tDropthisResult,\n\tRequestOptions,\n} from \"./types.js\";\n\nconst DEFAULT_BASE_URL = \"https://api.dropthis.app\";\n// Injected at build/test time from package.json (see tsup.config.ts / vitest.config.ts) so the\n// version has a single source of truth and can never drift from package.json.\ndeclare const __SDK_VERSION__: string;\nconst SDK_VERSION =\n\ttypeof __SDK_VERSION__ === \"string\" ? __SDK_VERSION__ : \"0.0.0-dev\";\n\nexport class Transport {\n\treadonly apiKey: string | undefined;\n\treadonly baseUrl: string;\n\treadonly timeoutMs: number;\n\treadonly uploadTimeoutMs: number;\n\treadonly fetchImpl: typeof globalThis.fetch;\n\n\tconstructor(options: DropthisClientOptions | string = {}) {\n\t\tconst resolved =\n\t\t\ttypeof options === \"string\" ? { apiKey: options } : options;\n\t\tthis.apiKey =\n\t\t\tresolved.apiKey ??\n\t\t\t(typeof process !== \"undefined\"\n\t\t\t\t? process.env?.DROPTHIS_API_KEY\n\t\t\t\t: undefined);\n\t\t// All API endpoints live under the /v1 version prefix; fold it into the configured host\n\t\t// (default or custom) once, so resource paths stay version-agnostic (\"/drops\", …). Parse via\n\t\t// URL so a stray trailing slash, query, or hash on the base can't corrupt the request path.\n\t\tconst base = new URL(resolved.baseUrl ?? DEFAULT_BASE_URL);\n\t\tconst basePath = base.pathname.replace(/\\/+$/, \"\");\n\t\tbase.pathname = basePath.endsWith(\"/v1\") ? basePath : `${basePath}/v1`;\n\t\tbase.search = \"\";\n\t\tbase.hash = \"\";\n\t\tthis.baseUrl = base.toString().replace(/\\/+$/, \"\");\n\t\tthis.timeoutMs = resolved.timeoutMs ?? 30_000;\n\t\tthis.uploadTimeoutMs = resolved.uploadTimeoutMs ?? 120_000;\n\t\tthis.fetchImpl = resolved.fetch ?? globalThis.fetch;\n\t}\n\n\tasync putSignedUrl(\n\t\turl: string,\n\t\tbody: Uint8Array | Blob | ReadableStream,\n\t\theaders: Record<string, string>,\n\t): Promise<DropthisResult<{ etag: string | null }>> {\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(() => controller.abort(), this.uploadTimeoutMs);\n\t\ttry {\n\t\t\tconst request: RequestInit & { duplex?: \"half\" } = {\n\t\t\t\tmethod: \"PUT\",\n\t\t\t\theaders,\n\t\t\t\tbody: body as BodyInit,\n\t\t\t\tsignal: controller.signal,\n\t\t\t};\n\t\t\tif (body instanceof ReadableStream) request.duplex = \"half\";\n\t\t\tconst response = await this.fetchImpl(url, request);\n\t\t\tconst responseHeaders = headersToObject(response.headers);\n\t\t\tif (!response.ok) {\n\t\t\t\tconst text = await response.text();\n\t\t\t\treturn createErrorResult(\n\t\t\t\t\t`signed_upload_${response.status}`,\n\t\t\t\t\ttext || response.statusText,\n\t\t\t\t\tresponse.status,\n\t\t\t\t\t// A 5xx from object storage is a transient upstream failure — safe to\n\t\t\t\t\t// re-PUT. A 4xx (e.g. 403 expired/denied signed URL) won't fix itself on\n\t\t\t\t\t// a blind retry, so leave it unmarked.\n\t\t\t\t\t{ headers: responseHeaders, retryable: response.status >= 500 },\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tdata: {\n\t\t\t\t\tetag: response.headers.get(\"ETag\") ?? responseHeaders.etag ?? null,\n\t\t\t\t},\n\t\t\t\terror: null,\n\t\t\t\theaders: responseHeaders,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconst message =\n\t\t\t\terror instanceof Error && error.name === \"AbortError\"\n\t\t\t\t\t? \"Request timed out\"\n\t\t\t\t\t: error instanceof Error\n\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t: \"Network error\";\n\t\t\t// A timeout or transport-level network failure carries no server body, so the\n\t\t\t// only retry signal we can offer is our own: both are inherently transient and\n\t\t\t// safe for an agent to retry (idempotency keys keep publishes single).\n\t\t\treturn createErrorResult(\n\t\t\t\terror instanceof Error && error.name === \"AbortError\"\n\t\t\t\t\t? \"timeout\"\n\t\t\t\t\t: \"network_error\",\n\t\t\t\tmessage,\n\t\t\t\tnull,\n\t\t\t\t{ retryable: true },\n\t\t\t);\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\t}\n\n\t/**\n\t * Authenticated GET that returns the raw response bytes untouched (no JSON parsing,\n\t * no case conversion). Error responses are still parsed as problem+json. Used for\n\t * content read-back (`drops.getContent` with a file path).\n\t */\n\tasync requestBytes(\n\t\tpath: string,\n\t\toptions: RequestOptions & {\n\t\t\tparams?: Record<string, string | number | boolean | null | undefined>;\n\t\t} = {},\n\t): Promise<\n\t\tDropthisResult<{ bytes: Uint8Array; contentType: string | null }>\n\t> {\n\t\tif (!this.apiKey) {\n\t\t\treturn createErrorResult(\n\t\t\t\t\"missing_api_key\",\n\t\t\t\t\"No API key provided. Pass apiKey or set DROPTHIS_API_KEY.\",\n\t\t\t\tnull,\n\t\t\t);\n\t\t}\n\n\t\tconst headers: Record<string, string> = {\n\t\t\t\"user-agent\": `dropthis-node/${SDK_VERSION}`,\n\t\t\tauthorization: `Bearer ${this.apiKey}`,\n\t\t};\n\n\t\tconst url = new URL(`${this.baseUrl}${path}`);\n\t\tfor (const [key, value] of Object.entries(options.params ?? {})) {\n\t\t\tif (value !== undefined && value !== null)\n\t\t\t\turl.searchParams.set(key, String(value));\n\t\t}\n\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(\n\t\t\t() => controller.abort(),\n\t\t\toptions.timeoutMs ?? this.timeoutMs,\n\t\t);\n\t\ttry {\n\t\t\tconst response = await this.fetchImpl(url.toString(), {\n\t\t\t\tmethod: \"GET\",\n\t\t\t\theaders,\n\t\t\t\tsignal: controller.signal,\n\t\t\t});\n\t\t\tconst responseHeaders = headersToObject(response.headers);\n\t\t\tif (!response.ok) {\n\t\t\t\tconst text = await response.text();\n\t\t\t\treturn problemResult(response, text, responseHeaders);\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tdata: {\n\t\t\t\t\tbytes: new Uint8Array(await response.arrayBuffer()),\n\t\t\t\t\tcontentType:\n\t\t\t\t\t\tresponse.headers.get(\"content-type\") ??\n\t\t\t\t\t\tresponseHeaders[\"content-type\"] ??\n\t\t\t\t\t\tnull,\n\t\t\t\t},\n\t\t\t\terror: null,\n\t\t\t\theaders: responseHeaders,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconst message =\n\t\t\t\terror instanceof Error && error.name === \"AbortError\"\n\t\t\t\t\t? \"Request timed out\"\n\t\t\t\t\t: error instanceof Error\n\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t: \"Network error\";\n\t\t\treturn createErrorResult(\n\t\t\t\terror instanceof Error && error.name === \"AbortError\"\n\t\t\t\t\t? \"timeout\"\n\t\t\t\t\t: \"network_error\",\n\t\t\t\tmessage,\n\t\t\t\tnull,\n\t\t\t\t{ retryable: true },\n\t\t\t);\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\t}\n\n\tasync request<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\toptions: RequestOptions & {\n\t\t\tbody?: unknown;\n\t\t\tbodyCase?: \"snake\" | \"raw\";\n\t\t\tparams?: Record<string, string | number | boolean | null | undefined>;\n\t\t} = {},\n\t): Promise<DropthisResult<T>> {\n\t\tconst authenticated = options.authenticated ?? true;\n\t\tif (authenticated && !this.apiKey) {\n\t\t\treturn createErrorResult<T>(\n\t\t\t\t\"missing_api_key\",\n\t\t\t\t\"No API key provided. Pass apiKey or set DROPTHIS_API_KEY.\",\n\t\t\t\tnull,\n\t\t\t);\n\t\t}\n\n\t\tconst headers: Record<string, string> = {\n\t\t\t\"user-agent\": `dropthis-node/${SDK_VERSION}`,\n\t\t};\n\t\tif (authenticated && this.apiKey)\n\t\t\theaders.authorization = `Bearer ${this.apiKey}`;\n\t\tif (options.idempotencyKey)\n\t\t\theaders[\"idempotency-key\"] = options.idempotencyKey;\n\t\tif (options.ifRevision !== undefined)\n\t\t\theaders[\"if-revision\"] = String(options.ifRevision);\n\t\tif (options.body !== undefined && !(options.body instanceof FormData))\n\t\t\theaders[\"content-type\"] = \"application/json\";\n\n\t\tconst url = new URL(`${this.baseUrl}${path}`);\n\t\tconst wireParams =\n\t\t\toptions.bodyCase === \"raw\"\n\t\t\t\t? options.params\n\t\t\t\t: (toSnakeCase(options.params ?? {}) as Record<string, unknown>);\n\t\tfor (const [key, value] of Object.entries(wireParams ?? {})) {\n\t\t\tif (value !== undefined && value !== null)\n\t\t\t\turl.searchParams.set(key, String(value));\n\t\t}\n\n\t\tconst controller = new AbortController();\n\t\tconst timeout = setTimeout(\n\t\t\t() => controller.abort(),\n\t\t\toptions.timeoutMs ?? this.timeoutMs,\n\t\t);\n\t\ttry {\n\t\t\tconst request: RequestInit = {\n\t\t\t\tmethod,\n\t\t\t\theaders,\n\t\t\t\tsignal: controller.signal,\n\t\t\t};\n\t\t\tif (options.body instanceof FormData) {\n\t\t\t\trequest.body = options.body;\n\t\t\t} else if (options.body !== undefined) {\n\t\t\t\tconst wireBody =\n\t\t\t\t\toptions.bodyCase === \"raw\" ? options.body : toSnakeCase(options.body);\n\t\t\t\trequest.body = JSON.stringify(wireBody);\n\t\t\t}\n\n\t\t\tconst response = await this.fetchImpl(url.toString(), request);\n\t\t\tconst responseHeaders = headersToObject(response.headers);\n\t\t\tconst text = await response.text();\n\t\t\tif (!response.ok)\n\t\t\t\treturn problemResult<T>(response, text, responseHeaders);\n\t\t\treturn {\n\t\t\t\tdata: toCamelCase(parseJson(text)) as T,\n\t\t\t\terror: null,\n\t\t\t\theaders: responseHeaders,\n\t\t\t};\n\t\t} catch (error) {\n\t\t\tconst message =\n\t\t\t\terror instanceof Error && error.name === \"AbortError\"\n\t\t\t\t\t? \"Request timed out\"\n\t\t\t\t\t: error instanceof Error\n\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t: \"Network error\";\n\t\t\t// A timeout/network failure on a mutating method is only safe to retry when the\n\t\t\t// request is deduplicated: the server may have applied a bare POST/PATCH/DELETE\n\t\t\t// before the connection dropped. Idempotent GETs are always safe; any method\n\t\t\t// carrying an idempotency key is dedupe-safe. Otherwise leave retryable unset\n\t\t\t// so an agent doesn't blindly re-issue a side effect.\n\t\t\tconst retrySafe =\n\t\t\t\tmethod.toUpperCase() === \"GET\" || options.idempotencyKey !== undefined;\n\t\t\treturn createErrorResult<T>(\n\t\t\t\terror instanceof Error && error.name === \"AbortError\"\n\t\t\t\t\t? \"timeout\"\n\t\t\t\t\t: \"network_error\",\n\t\t\t\tmessage,\n\t\t\t\tnull,\n\t\t\t\tretrySafe ? { retryable: true } : {},\n\t\t\t);\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t}\n\t}\n}\n\n/** Maps a non-2xx response's problem+json body into the typed error result shape. */\nfunction problemResult<T>(\n\tresponse: Response,\n\ttext: string,\n\tresponseHeaders: Record<string, string>,\n): DropthisResult<T> {\n\tconst parsed = parseJson(text);\n\tconst body =\n\t\tparsed && typeof parsed === \"object\"\n\t\t\t? (parsed as Record<string, unknown>)\n\t\t\t: {};\n\tconst message =\n\t\tstringValue(body.detail) ?? stringValue(body.title) ?? response.statusText;\n\tconst code =\n\t\tstringValue(body.code) ??\n\t\tstringValue(body.error_code) ??\n\t\t`http_${response.status}`;\n\tconst currentRevision = numberValue(body.current_revision);\n\tconst type = stringValue(body.type);\n\tconst title = stringValue(body.title);\n\tconst instance = stringValue(body.instance);\n\treturn createErrorResult<T>(code, message, response.status, {\n\t\tbody,\n\t\t...(type !== null ? { type } : {}),\n\t\t...(title !== null ? { title } : {}),\n\t\t...(instance !== null ? { instance } : {}),\n\t\tdetail: stringValue(body.detail),\n\t\tparam: stringValue(body.param),\n\t\t...(currentRevision !== undefined ? { currentRevision } : {}),\n\t\trequestId:\n\t\t\tstringValue(body.request_id) ?? responseHeaders[\"x-request-id\"] ?? null,\n\t\tsuggestion: stringValue(body.suggestion),\n\t\tretryable: booleanValue(body.retryable),\n\t\t// Unified plan-gate contract (feature_not_in_plan / quota_exceeded). The\n\t\t// error body isn't camelCased like a success body, so map the snake keys here.\n\t\tfeature: stringValue(body.feature),\n\t\tcurrentPlan: stringValue(body.current_plan),\n\t\trequiredPlan: stringValue(body.required_plan),\n\t\tupgradeUrl: stringValue(body.upgrade_url),\n\t\tlimit: numberValue(body.limit) ?? null,\n\t\tused: numberValue(body.used) ?? null,\n\t\trequested: numberValue(body.requested) ?? null,\n\t\theaders: responseHeaders,\n\t});\n}\n\nfunction headersToObject(headers: Headers): Record<string, string> {\n\tconst result: Record<string, string> = {};\n\theaders.forEach((value, key) => {\n\t\tresult[key.toLowerCase()] = value;\n\t});\n\treturn result;\n}\n\nfunction parseJson(text: string): unknown {\n\tif (!text) return null;\n\ttry {\n\t\treturn JSON.parse(text);\n\t} catch {\n\t\treturn text;\n\t}\n}\n\nfunction stringValue(value: unknown): string | null {\n\treturn typeof value === \"string\" ? value : null;\n}\n\nfunction numberValue(value: unknown): number | undefined {\n\treturn typeof value === \"number\" ? value : undefined;\n}\n\nfunction booleanValue(value: unknown): boolean | null {\n\treturn typeof value === \"boolean\" ? value : null;\n}\n","import type { PreparedPublishRequest } from \"./publish/core.js\";\nimport { resolveInput } from \"./publish/node.js\";\nimport { AccountResource } from \"./resources/account.js\";\nimport { ApiKeysResource } from \"./resources/api-keys.js\";\nimport { AuthResource } from \"./resources/auth.js\";\nimport { DeploymentsResource } from \"./resources/deployments.js\";\nimport { DomainsResource } from \"./resources/domains.js\";\nimport { DropsResource } from \"./resources/drops.js\";\nimport { InvitationsResource } from \"./resources/invitations.js\";\nimport { MembersResource } from \"./resources/members.js\";\nimport { UploadsResource } from \"./resources/uploads.js\";\nimport { WorkspacesResource } from \"./resources/workspaces.js\";\nimport { Transport } from \"./transport.js\";\nimport type {\n\tDropthisClientOptions,\n\tPublishInput,\n\tPublishOptions,\n} from \"./types.js\";\n\nexport class Dropthis {\n\tprivate readonly transport: Transport;\n\t/** Client-level workspace default; applied when a publish call omits `options.workspace`. */\n\tprivate readonly defaultWorkspace: string | undefined;\n\tprivate authResource?: AuthResource;\n\tprivate apiKeysResource?: ApiKeysResource;\n\tprivate accountResource?: AccountResource;\n\tprivate dropsResource?: DropsResource<PublishInput>;\n\tprivate deploymentsResource?: DeploymentsResource;\n\tprivate uploadsResource?: UploadsResource;\n\tprivate domainsResource?: DomainsResource;\n\tprivate workspacesResource?: WorkspacesResource;\n\tprivate membersResource?: MembersResource;\n\tprivate invitationsResource?: InvitationsResource;\n\n\tconstructor(options: DropthisClientOptions | string = {}) {\n\t\tthis.transport = new Transport(options);\n\t\tthis.defaultWorkspace =\n\t\t\ttypeof options === \"string\" ? undefined : options.workspace;\n\t}\n\n\tget auth(): AuthResource {\n\t\tif (!this.authResource)\n\t\t\tthis.authResource = new AuthResource(this.transport);\n\t\treturn this.authResource;\n\t}\n\n\tget apiKeys(): ApiKeysResource {\n\t\tif (!this.apiKeysResource)\n\t\t\tthis.apiKeysResource = new ApiKeysResource(this.transport);\n\t\treturn this.apiKeysResource;\n\t}\n\n\tget account(): AccountResource {\n\t\tif (!this.accountResource)\n\t\t\tthis.accountResource = new AccountResource(this.transport);\n\t\treturn this.accountResource;\n\t}\n\n\tget drops(): DropsResource<PublishInput> {\n\t\tif (!this.dropsResource) {\n\t\t\t// Pass defaultWorkspace as the 3rd arg so DropsResource.publish() merges it\n\t\t\t// only for fresh publishes — never for updateContent (which stays in the\n\t\t\t// drop's own workspace).\n\t\t\tthis.dropsResource = new DropsResource(\n\t\t\t\tthis.transport,\n\t\t\t\tresolveInput,\n\t\t\t\tthis.defaultWorkspace,\n\t\t\t);\n\t\t}\n\t\treturn this.dropsResource;\n\t}\n\n\tget deployments(): DeploymentsResource {\n\t\tif (!this.deploymentsResource)\n\t\t\tthis.deploymentsResource = new DeploymentsResource(this.transport);\n\t\treturn this.deploymentsResource;\n\t}\n\n\tget uploads(): UploadsResource {\n\t\tif (!this.uploadsResource)\n\t\t\tthis.uploadsResource = new UploadsResource(this.transport);\n\t\treturn this.uploadsResource;\n\t}\n\n\tget domains(): DomainsResource {\n\t\tif (!this.domainsResource)\n\t\t\tthis.domainsResource = new DomainsResource(this.transport);\n\t\treturn this.domainsResource;\n\t}\n\n\tget workspaces(): WorkspacesResource {\n\t\tif (!this.workspacesResource)\n\t\t\tthis.workspacesResource = new WorkspacesResource(this.transport);\n\t\treturn this.workspacesResource;\n\t}\n\n\tget members(): MembersResource {\n\t\tif (!this.membersResource)\n\t\t\tthis.membersResource = new MembersResource(this.transport);\n\t\treturn this.membersResource;\n\t}\n\n\tget invitations(): InvitationsResource {\n\t\tif (!this.invitationsResource)\n\t\t\tthis.invitationsResource = new InvitationsResource(this.transport);\n\t\treturn this.invitationsResource;\n\t}\n\n\tasync prepare(\n\t\tinput: PublishInput,\n\t\toptions: PublishOptions = {},\n\t): Promise<PreparedPublishRequest> {\n\t\tconst merged: PublishOptions =\n\t\t\tthis.defaultWorkspace !== undefined && options.workspace === undefined\n\t\t\t\t? { ...options, workspace: this.defaultWorkspace }\n\t\t\t\t: options;\n\t\treturn resolveInput(input, merged);\n\t}\n}\n","export type DropthisClientOptions = {\n\tapiKey?: string;\n\tbaseUrl?: string;\n\ttimeoutMs?: number;\n\tuploadTimeoutMs?: number;\n\tfetch?: typeof globalThis.fetch;\n\t/**\n\t * Default workspace slug or id applied to every publish/prepare call that\n\t * does not supply its own `options.workspace`. Delegated credentials only;\n\t * ignored by pinned service keys.\n\t */\n\tworkspace?: string;\n};\n\nexport type RequestOptions = {\n\tauthenticated?: boolean;\n\tidempotencyKey?: string;\n\tifRevision?: number;\n\ttimeoutMs?: number;\n};\n\nexport type DropthisErrorResponse = {\n\tcode: string;\n\tmessage: string;\n\tstatusCode: number | null;\n\ttype?: string;\n\ttitle?: string;\n\tdetail?: string | null;\n\tinstance?: string | null;\n\tparam?: string | null;\n\tcurrentRevision?: number;\n\trequestId?: string | null;\n\tsuggestion?: string | null;\n\tretryable?: boolean | null;\n\t/** The gated capability (on `feature_not_in_plan`), e.g. `password_protect`. */\n\tfeature?: string | null;\n\t/** The caller's current plan (on `feature_not_in_plan` / `quota_exceeded`). */\n\tcurrentPlan?: string | null;\n\t/** The lowest plan that unlocks the feature (on `feature_not_in_plan`). */\n\trequiredPlan?: string | null;\n\t/** The pricing/upgrade URL to hand a human (on a plan gate). */\n\tupgradeUrl?: string | null;\n\t/** Numeric ceiling that was hit (on `quota_exceeded`). */\n\tlimit?: number | null;\n\t/** Amount already used toward the ceiling (on `quota_exceeded`). */\n\tused?: number | null;\n\t/** Amount the request asked for (on `quota_exceeded`). */\n\trequested?: number | null;\n\tbody?: unknown;\n};\n\nexport type DropthisResult<T> =\n\t| { data: T; error: null; headers: Record<string, string> }\n\t| {\n\t\t\tdata: null;\n\t\t\terror: DropthisErrorResponse;\n\t\t\theaders: Record<string, string>;\n\t };\n\nexport type ActionResolve = {\n\tmethod: string;\n\turl?: string | null;\n\tendpoint?: string | null;\n};\n\nexport type DropAction = {\n\tcode: string;\n\tkind: \"api\" | \"human\";\n\tpriority: \"required\" | \"suggested\";\n\tmessage: string;\n\tresolve?: ActionResolve | null;\n};\n\nexport type TierInfo = {\n\tname: string;\n\tmaxSizeBytes: number;\n\tttlDays: number | null;\n\tpersistent: boolean;\n\tbadge: boolean;\n};\n\nexport type Limitations = {\n\tactions: DropAction[];\n};\n\n/**\n * Workspace context echoed on every drop response. Identifies which workspace\n * the drop was published into (ADR 0066).\n */\nexport type DropWorkspace = {\n\tid: string;\n\tname: string;\n\tslug: string;\n\t/** `personal` for a solo workspace, `team` for a shared team workspace. */\n\tkind: string;\n};\n\nexport type DropResponse = {\n\tid: string;\n\tslug: string;\n\turl: string;\n\tdeploymentId: string | null;\n\ttitle: string;\n\tcontentType: string;\n\tvisibility: string;\n\tstatus: string;\n\trevision: number;\n\tcontentRevision: number;\n\taccessRevision: number;\n\tsizeBytes: number;\n\trenderMode: string;\n\twarnings: Array<Record<string, unknown>>;\n\tcreatedAt: string;\n\texpiresAt: string | null;\n\tnoindex: boolean;\n\tpasswordProtected: boolean;\n\tmetadata: Record<string, unknown>;\n\t/** When the drop was last updated (content or settings), ISO 8601. */\n\tupdatedAt: string;\n\t/** Origin that created the drop (e.g. \"api\", \"cli\", \"mcp\"); null/omitted when unattributed. */\n\tsource?: string | null;\n\tobject: string;\n\taccessible: boolean;\n\tpersistent: boolean;\n\tbadgeApplied: boolean;\n\ttier: TierInfo;\n\tlimitations: Limitations;\n\t/** Hostname of the custom domain this drop is mounted on; null for shared-pool drops. */\n\tdomain: string | null;\n\t/**\n\t * Direct URL to the drop's raw bytes — the agent byte-fetch path. The canonical\n\t * `url` always serves a branded human view (so the badge is guaranteed); `rawUrl`\n\t * serves the underlying file's exact bytes at its natural path under the mount\n\t * (ADR 0061). Populated only for single-file (`renderMode: \"file_viewer\"`) drops\n\t * (= canonical URL + the entry filename); `null` for `user_html` drops (the page\n\t * IS the artifact) and collections (per-file natural paths come from the manifest —\n\t * see {@link DeploymentContentManifest}). Hand `url` to humans and `rawUrl` to agents.\n\t * To stream bytes through the SDK regardless of drop kind, use `drops.getContent()`.\n\t */\n\trawUrl: string | null;\n\t/** The workspace this drop belongs to (echoed from the server on every response). */\n\tworkspace: DropWorkspace;\n};\n\nexport type DropDeploymentResponse = {\n\tid: string;\n\tdropId: string;\n\trevision: number;\n\tstatus: string;\n\tentry: string | null;\n\tcontentType: string;\n\trenderMode: string;\n\tfiles: Array<Record<string, unknown>>;\n\twarnings: Array<Record<string, unknown>>;\n\tsizeBytes: number;\n\tclassificationVersion: number;\n\tclassificationReason: string;\n\terrorCode: string | null;\n\terrorMessage: string | null;\n\tcreatedAt: string;\n\treadyAt: string | null;\n\tpublishedAt: string | null;\n};\n\nexport type ListDeploymentsParams = { cursor?: string | null; limit?: number };\n\nexport type ListDeploymentsResponse = {\n\tdeployments: DropDeploymentResponse[];\n\tnextCursor: string | null;\n};\n\nexport type ListPage<T> = {\n\tobject: \"list\";\n\tdata: T[];\n\thasMore: boolean;\n\tnextCursor: string | null;\n\tautoPagingToArray(options?: { limit?: number }): Promise<DropthisResult<T[]>>;\n};\n\nexport type Action = {\n\tcode: string;\n\tkind: string;\n\tmethod?: string | null;\n\tendpoint?: string | null;\n\tmessage: string;\n};\n\nexport type EmailOtpResponse = {\n\t/** Always `true` on success; optional because the server defaults it. */\n\tok?: true;\n\texpiresIn: number;\n\tnextAction?: Action | null;\n};\nexport type SessionResponse = {\n\tobject: \"session\";\n\ttoken: string;\n\taccountId: string;\n\tisNewAccount: boolean;\n\texpiresIn: number;\n\t/**\n\t * Rotating refresh token for a console browser session. Present when a session is\n\t * started (email/verify, refresh); `null`/omitted for non-session token issuance.\n\t */\n\trefreshToken?: string | null;\n};\n\n/**\n * Why an API key exists. `delegated` keys act on behalf of the owning account (scoped\n * to the active workspace or an allowed set); `service` keys are pinned to a single\n * workspace and are intended for CI/automation.\n */\nexport type KeyType = \"delegated\" | \"service\";\n\n/** What breaks when a key is revoked. */\nexport type RevokeImpact = \"disconnects_app\" | \"breaks_automation\";\n\nexport type ApiKeyResponse = {\n\tobject: \"api_key\";\n\tid: string;\n\tkeyLast4: string;\n\tlabel: string;\n\t/** Human-facing credential name: the user's label for `standard` keys, the connected client name for `mcp_oauth` keys. */\n\tappName: string;\n\t/** Why the key exists (drives quota accounting). */\n\tkeyType: KeyType;\n\t/** Scopes granted to this key. */\n\tscopes: string[];\n\t/** When the key was last used to authenticate, ISO 8601; null/omitted if never used. */\n\tlastUsedAt?: string | null;\n\t/** What breaks if this key is revoked. */\n\trevokeImpact: RevokeImpact;\n\tcreatedAt: string;\n};\nexport type ApiKeyCreatedResponse = ApiKeyResponse & {\n\tkey: string;\n\taccountId?: string | null;\n\tisNewAccount?: boolean;\n};\n/** Numeric limits for the active plan — use these to size a publish before uploading. */\nexport type EntitlementLimits = {\n\t/** Maximum size of a single drop in bytes. */\n\tmaxSizeBytes: number;\n\t/** Total account storage cap in bytes; null means no account-level cap. */\n\tmaxStorageBytes: number | null;\n\t/** Drop lifetime in seconds before expiry; null means drops are permanent. */\n\tdefaultTtlSeconds: number | null;\n\t/** Maximum number of custom hostnames the workspace may connect. */\n\tmaxCustomHostnames: number;\n\t/** Maximum members the workspace may hold (owner included). */\n\tseatLimit: number;\n\t/** Maximum concurrent in-flight upload sessions (a transient concurrency cap). */\n\tmaxActiveUploadSessions: number;\n};\n\n/**\n * The full capability matrix for the active plan — the single read to pre-check a\n * feature gate before attempting an operation.\n */\nexport type Entitlements = {\n\t/**\n\t * Per-capability state for the active plan. Boolean caps are `true`/`false`;\n\t * enum caps (`ogPreview`, `analytics`) carry a value — compare by value, never\n\t * truthiness (`\"none\"` is truthy).\n\t */\n\tcapabilities: Record<string, boolean | string>;\n\t/**\n\t * The lowest plan that unlocks each gated capability — drives the upgrade nudge.\n\t * Enum sub-values are keyed `ogPreview.customImage` / `analytics.full`.\n\t */\n\trequiredPlan: Record<string, string>;\n\t/** Numeric limits for the active plan. */\n\tlimits: EntitlementLimits;\n};\n\n/** Current resource usage for the account's active workspace. */\nexport type AccountUsage = {\n\t/** Total bytes consumed across all active drops. */\n\tstorageUsedBytes: number;\n\t/** Number of custom domain hostnames currently in use. */\n\tcustomDomainsUsed: number;\n\t/** Members currently in the workspace (owner included). */\n\tseatsUsed: number;\n};\n\n/** The workspace a principal acts within (ADR 0066). For an sk_ API key, the workspace the key is bound to. */\nexport type AccountWorkspace = {\n\tid: string;\n\tname: string;\n\tslug: string;\n\t/** `personal` for a solo workspace, `team` when shared with other members. */\n\tkind: string;\n\t/** The calling account's role in this workspace: `owner`, `admin`, or `member`. */\n\trole: string;\n};\n\n/**\n * A workspace the caller belongs to or has delegated access to.\n * Returned by `GET /v1/workspaces` and `PUT /v1/account/active-workspace`.\n */\nexport type Workspace = {\n\tid: string;\n\tname: string;\n\tslug: string;\n\t/** `personal` for a solo workspace, `team` for a shared team workspace. */\n\tkind: string;\n\t/** The calling account's role in this workspace: `owner`, `admin`, or `member`. */\n\trole: string;\n\t/** The plan tier of this workspace. */\n\tplan: string;\n\t/** Whether this workspace is currently the caller's active workspace. */\n\tisActive: boolean;\n\t/**\n\t * On CREATE only (null otherwise): whether the credential that created this workspace can act\n\t * in it. `false` means an allowlist-restricted key created a workspace outside its allowlist —\n\t * it will be denied on the next write; re-authenticate to obtain a credential that reaches it.\n\t */\n\tcreatorCanReach?: boolean | null;\n};\n\n/** A role grantable via invite or a member role-change (owner is transferred, never granted). */\nexport type WorkspaceRole = \"owner\" | \"admin\" | \"member\";\nexport type InvitableRole = \"admin\" | \"member\";\n\n/** A member of a team workspace. */\nexport type Member = {\n\taccountId: string;\n\t/** The member's email, or null if their account was deleted. */\n\temail: string | null;\n\trole: WorkspaceRole;\n\t/** Whether this row is the calling account. */\n\tisYou: boolean;\n\tjoinedAt: string;\n};\nexport type MemberListResponse = { members: Member[] };\n\n/** An invitation to join a team workspace. */\nexport type Invitation = {\n\tid: string;\n\tworkspaceId: string;\n\temail: string;\n\trole: WorkspaceRole;\n\t/** `pending`, `accepted`, or `revoked`. */\n\tstatus: string;\n\texpiresAt: string;\n\tcreatedAt: string;\n\tacceptedAt?: string | null;\n};\nexport type InvitationListResponse = { invitations: Invitation[] };\n\nexport type AccountResponse = {\n\tid: string;\n\temail: string;\n\tdisplayName: string | null;\n\tplan: string;\n\tstatus: string;\n\tcreatedAt: string;\n\t/** The full capability matrix + numeric limits for the active plan. */\n\tentitlements: Entitlements;\n\tusage: AccountUsage;\n\tworkspace: AccountWorkspace;\n\t/** URL to upgrade; present on every plan below Business, null on the top tier. */\n\tupgradeUrl: string | null;\n};\nexport type ListDropsParams = {\n\tcursor?: string | null;\n\tlimit?: number;\n\t/** Only drops mounted on this custom domain hostname (e.g. \"reports.example.com\"). */\n\tdomain?: string;\n};\n\n/**\n * One file in an upload manifest. A discriminated union:\n *\n * - **client-put** — the SDK pushes the bytes through a signed PUT. Requires\n * `contentType` and `sizeBytes`; an optional `checksumSha256` locks the\n * transfer integrity.\n * - **remote** — the server fetches the bytes itself from `sourceUrl` during\n * `POST /uploads/{id}/ingest`. No bytes leave this process, so `sizeBytes`,\n * `contentType`, and `checksumSha256` are all optional (the server infers\n * them on fetch). Carries NO signed PUT target.\n *\n * `sourceUrl` is the discriminant: present ⇒ remote, absent ⇒ client-put. The\n * camelCase `sourceUrl` becomes the wire field `source_url` via the transport's\n * snake_case conversion (exactly like `contentType` → `content_type`).\n */\nexport type UploadManifestFile =\n\t| {\n\t\t\tpath: string;\n\t\t\tcontentType: string;\n\t\t\tsizeBytes: number;\n\t\t\tchecksumSha256?: string | null;\n\t\t\tsourceUrl?: never;\n\t }\n\t| {\n\t\t\tpath: string;\n\t\t\tsourceUrl: string;\n\t\t\tcontentType?: string;\n\t\t\tsizeBytes?: number;\n\t\t\tchecksumSha256?: string | null;\n\t\t\ttransform?: ImageTransform;\n\t };\n\nexport type CreateUploadSessionRequest = {\n\tschemaVersion?: 1;\n\tfiles: UploadManifestFile[];\n\tentry?: string | null;\n\t/**\n\t * Target workspace slug or id for this upload session. Delegated credentials only;\n\t * ignored by pinned service keys. Bound at session creation and inherited by the\n\t * subsequent POST /drops call.\n\t */\n\tworkspace?: string;\n};\n\nexport type UploadTarget = {\n\t/** Always `single_put` — one signed PUT per file is the upload contract. */\n\tstrategy: \"single_put\";\n\turl: string;\n\theaders: Record<string, string>;\n\texpiresAt: string;\n};\n\nexport type CreateUploadSessionFileResponse = {\n\tfileId: string;\n\tpath: string;\n\tobjectKey: string;\n\tupload: UploadTarget;\n};\n\nexport type UploadSessionFileResponse = {\n\tfileId: string;\n\tpath: string;\n\t/** Declared MIME type; `null`/omitted for remote-fetch files until ingested. */\n\tcontentType?: string | null;\n\t/** Declared byte size; `null`/omitted for remote-fetch files until ingested. */\n\tsizeBytes?: number | null;\n\tobjectKey: string;\n\t/** How the file enters staging: \"client_put\" (client PUTs bytes) or \"remote_fetch\" (server fetches sourceUrl). */\n\torigin: \"client_put\" | \"remote_fetch\";\n\t/** Ingest lifecycle state for remote-fetch files (e.g. \"pending\" | \"fetching\" | \"fetched\" | \"failed\"). */\n\tstate: string;\n\t/** Public http(s) URL the server fetches into staging; `null`/omitted for client-put files. */\n\tsourceUrl?: string | null;\n\tverified: boolean;\n};\n\nexport type UploadSessionResponse = {\n\tuploadId: string;\n\tstatus: string;\n\texpiresAt: string;\n\tentry?: string | null;\n\tfiles: UploadSessionFileResponse[];\n\tnextAction?: Action | null;\n};\n\n/**\n * Response body from `POST /uploads/{id}/ingest`.\n * The server fetches all remote (`sourceUrl`) manifest entries into staging and\n * returns a count of the files it staged plus a lifecycle status string.\n * The SDK requires 2xx and discards the body; this type documents the wire shape.\n */\nexport type IngestSessionResponse = {\n\t/** Number of remote files successfully fetched into staging. */\n\tstaged: number;\n\t/** Upload session lifecycle status after ingestion (e.g. \"ingested\"). */\n\tstatus: string;\n};\n\nexport type CreateUploadSessionResponse = {\n\tuploadId: string;\n\texpiresAt: string;\n\tfiles: CreateUploadSessionFileResponse[];\n\tnextAction?: Action | null;\n};\n\n/**\n * Sentinel for `DropOptions.domain`: publish to the shared pool even when the\n * account has a default custom domain (dropthis#55). Collision-free — the\n * literal \"shared\" can never be a real hostname (single-label names are\n * rejected at domain connect). These drops read back `domain: null`.\n */\nexport const SHARED_POOL = \"shared\";\n\nexport type DropOptions = {\n\t/** Drop title. */\n\ttitle?: string;\n\t/** public (default) or unlisted. */\n\tvisibility?: \"public\" | \"unlisted\";\n\t/** Require password to view. Pass `null` to remove password protection. */\n\tpassword?: string | null;\n\t/** Prevent search-engine indexing. Pass `null` to allow indexing (default). */\n\tnoindex?: boolean | null;\n\t/** Auto-delete after this ISO 8601 date. Pass `null` to clear. */\n\texpiresAt?: string | Date | null;\n\t/** Entry file for multi-file bundles (default: index.html). */\n\tentry?: string;\n\t/** Attach JSON key-value pairs, e.g. `{ source: \"ci\" }`. */\n\tmetadata?: Record<string, unknown>;\n\t/**\n\t * Hostname of a custom domain connected to this account (must be live — see\n\t * `client.domains`), or {@link SHARED_POOL} (`\"shared\"`) to publish to the shared\n\t * pool even when the account has a default domain. Path-mode domains serve the drop\n\t * at `https://{domain}/{slug}/`; dedicated domains serve it at the root and conflict\n\t * (409) once occupied. Omit to use the account's default path domain if one exists,\n\t * else the shared pool.\n\t */\n\tdomain?: string | null;\n\t/**\n\t * Vanity slug — only valid when the target is a path-mode custom domain. 1–63\n\t * lowercase letters/digits/hyphens (no leading/trailing/double hyphen). Taken slugs\n\t * are auto-suffixed; omit for a random slug. Setting this on the shared pool returns\n\t * 422.\n\t */\n\tslug?: string | null;\n};\n\nexport type PrepareOptions = {\n\t/** Glob patterns to ignore when publishing directories. */\n\tignore?: string[];\n\t/** Disable default ignore patterns. */\n\tignoreDefaults?: boolean;\n\t/** Override MIME type (auto-detected from extension). */\n\tcontentType?: string;\n\t/** Set filename when publishing from stdin or bytes. */\n\tpath?: string;\n};\n\nexport type RequestControls = {\n\t/** Prevent duplicate publishes on retry (auto-generated by CLI). */\n\tidempotencyKey?: string;\n\t/** Fail if current revision doesn't match -- optimistic lock (update only). */\n\tifRevision?: number;\n};\n\nexport type PublishOptions = DropOptions &\n\tPrepareOptions &\n\tRequestControls & {\n\t\t/**\n\t\t * Target workspace slug or id — publish/prepare only (a fresh drop's workspace).\n\t\t * Delegated credentials only; ignored by pinned service keys. Falls back to the\n\t\t * client-level `workspace` default when omitted. Not a settings field: it is NOT\n\t\t * accepted by `updateSettings` (a drop never moves workspace) nor by `updateContent`\n\t\t * (which stays in the drop's own workspace).\n\t\t */\n\t\tworkspace?: string;\n\t};\n\n/**\n * Options for `drops.updateContent()` — content-only. A content update ships a new content version\n * and never changes drop settings (title, visibility, password, noindex, expiry, metadata); those\n * belong on `drops.updateSettings()`. Carries only content-prep + request controls + the bundle\n * `entry`.\n */\nexport type UpdateContentOptions = PrepareOptions &\n\tRequestControls & {\n\t\t/** Entry file for multi-file bundles (default: index.html). */\n\t\tentry?: string;\n\t\t/**\n\t\t * How the supplied files combine with what the drop already serves\n\t\t * (partial-by-default, ADR 0065):\n\t\t *\n\t\t * - `\"patch\"` (default): the supplied files upsert by path and every\n\t\t * unmentioned file is carried forward, so editing one file never drops the\n\t\t * rest. Use `deletePaths` to remove files.\n\t\t * - `\"replace\"`: the supplied files become the drop's entire content set —\n\t\t * a full swap. Anything not supplied is gone. `deletePaths` is invalid here.\n\t\t *\n\t\t * Omit to default to `\"patch\"`.\n\t\t */\n\t\tmode?: \"patch\" | \"replace\";\n\t\t/**\n\t\t * Paths to remove from the drop's content (patch-mode only). Each path must\n\t\t * exist or the server rejects the update (loud, never a silent no-op). Invalid\n\t\t * with `mode: \"replace\"`. Wire field: `delete_paths`.\n\t\t */\n\t\tdeletePaths?: string[];\n\t};\n\n/**\n * One file in a multi-file `{ kind: \"files\" }` bundle. Supply the bytes inline\n * exactly one way — `content` (UTF-8 text), `contentBase64`, or `bytes` — OR set\n * `sourceUrl` to a public http(s) URL and let the server fetch that file for you\n * server-side (no bytes pass through your process). A single entry may NOT carry\n * both inline bytes and `sourceUrl`. Mix freely within one bundle: e.g. inline\n * `content` for `index.html` plus a `sourceUrl` for each image referenced by it,\n * yielding one self-contained drop.\n */\n/**\n * Optional server-side image transform applied to a `sourceUrl` file on ingest\n * (publish by reference). The server resizes/re-encodes the fetched image so you can\n * point at a big original and store a small web-optimised derivative. Fits inside the\n * given box preserving aspect ratio, never upscales, strips metadata. Only valid on\n * `sourceUrl` entries; when set, omit `sizeBytes`/`checksumSha256` (the stored object\n * reflects the transform OUTPUT, computed server-side).\n */\nexport type ImageTransform = {\n\t/** Max output width in pixels (fit inside, no upscale). */\n\twidth?: number;\n\t/** Max output height in pixels (fit inside, no upscale). */\n\theight?: number;\n\t/** Encoder quality 1-100 (jpeg/webp). */\n\tquality?: number;\n\t/** Output format. Omit to keep the source raster format. */\n\tformat?: \"jpeg\" | \"png\" | \"webp\";\n};\n\nexport type PublishFileInput = {\n\tpath: string;\n\tcontentType?: string;\n\tcontent?: string;\n\tcontentBase64?: string;\n\tbytes?: Uint8Array;\n\t/**\n\t * Public http(s) URL the server fetches this file's bytes from during publish\n\t * (publish by reference). Mutually exclusive with `content`/`contentBase64`/`bytes`.\n\t */\n\tsourceUrl?: string;\n\t/**\n\t * Optional image transform applied server-side to a `sourceUrl` file on ingest\n\t * (resize/re-encode). Only valid with `sourceUrl`; when set, omit\n\t * `sizeBytes`/`checksumSha256` (the stored object reflects the output).\n\t */\n\ttransform?: ImageTransform;\n\t/**\n\t * Declared byte size of the remote file (optional hint for `sourceUrl` files).\n\t * When provided, the server uses this for upfront quota admission before fetching,\n\t * so a large file is rejected immediately rather than after the server downloads it.\n\t * Ignored for inline files (size is computed from the bytes).\n\t */\n\tsizeBytes?: number;\n\t/**\n\t * Expected SHA-256 hex digest of the remote file (optional hint for `sourceUrl` files).\n\t * When provided, the server verifies the fetched content matches this checksum and\n\t * rejects the publish if it does not, giving you integrity verification without\n\t * downloading the bytes yourself.\n\t * Ignored for inline files (checksum is computed by the SDK/server from actual bytes).\n\t */\n\tchecksumSha256?: string;\n};\n\nexport type PublishInput =\n\t| string\n\t| string[]\n\t| URL\n\t| Uint8Array\n\t| { kind: \"content\"; content: string; contentType?: string; path?: string }\n\t| { kind: \"source_url\"; sourceUrl: string }\n\t| { kind: \"files\"; files: PublishFileInput[]; entry?: string };\n\n/** Structured next-step hint returned by domain operations (and publish). */\nexport type NextHint = { action: string; message: string };\n\n/** One DNS record instruction or diagnostic for a custom domain. */\nexport type DnsRecord = {\n\t/** Purpose of the record, e.g. \"routing\". */\n\tpurpose: string;\n\t/** DNS record type, e.g. \"CNAME\". */\n\ttype: string;\n\t/** The DNS name to create the record for. */\n\tname: string;\n\t/** The value the record must point at. */\n\tvalue: string;\n\t/** Current DNS status: \"missing\" | \"ok\" | \"mismatch\". */\n\tstatus: \"missing\" | \"ok\" | \"mismatch\";\n\t/** What DoH currently resolves for this record (verify only). */\n\tobserved?: string | null;\n\t/** Specific guidance for fixing this record. */\n\thint?: string | null;\n\t/** Seconds to wait before retrying verify while DNS/cert propagates. */\n\tretryAfter?: number | null;\n};\n\n/** Full domain resource representation. */\nexport type DomainResponse = {\n\tobject: \"domain\";\n\t/** Stable domain identifier. */\n\tid: string;\n\t/** Canonical hostname registered with dropthis. */\n\thostname: string;\n\t/** Mount mode: \"path\" (many drops at hostname/{slug}/) or \"dedicated\" (one drop at hostname/). */\n\tmode: \"path\" | \"dedicated\";\n\t/** Lifecycle status: \"pending_dns\" | \"verifying\" | \"live\" | \"failed\". */\n\tstatus: \"pending_dns\" | \"verifying\" | \"live\" | \"failed\";\n\t/** Reason for failure status. */\n\tfailureReason?: string | null;\n\t/** Whether this is the account's default publish domain. */\n\tdefault: boolean;\n\t/** Mounted drop id (dedicated mode only). */\n\tdropId?: string | null;\n\t/** DNS records required for this domain. */\n\tdns: DnsRecord[];\n\t/** Creation timestamp. */\n\tcreatedAt: string;\n\t/** When the domain first reached \"live\" status. */\n\tverifiedAt?: string | null;\n\t/** Structured next-step hints for the agent. */\n\tnext: NextHint[];\n\t/**\n\t * Deep link to this domain's setup page in the dropthis console\n\t * (e.g. https://app.dropthis.app/domains/dom_…). Hand this to a human so\n\t * they can add the DNS record and watch it go live in a polished UI.\n\t */\n\tconsoleUrl: string;\n};\n\n/** List of domains for the account. */\nexport type DomainListResponse = {\n\tobject: \"domain.list\";\n\t/** Domains connected to this account. */\n\tdomains: DomainResponse[];\n};\n\n/** Response body for a successful domain deletion. */\nexport type DomainDeletedResponse = {\n\tobject: \"domain.deleted\";\n\t/** Id of the deleted domain. */\n\tid: string;\n\t/** Hostname of the deleted domain. */\n\thostname: string;\n\t/** Dangling-CNAME risk warning (always present; instructs you to remove the DNS record). */\n\twarning: string;\n};\n\n/** One readable file in a deployment's content manifest. */\nexport type DeploymentContentFile = {\n\t/** File path within the deployment, relative to its root. */\n\tpath: string;\n\t/** Stored MIME type the file is served with. */\n\tcontentType: string;\n\t/** Stored file size in bytes. */\n\tsizeBytes: number;\n};\n\n/**\n * Manifest of one deployment's readable files (content read-back).\n * Fetch a single file's bytes with `drops.getContent(dropId, { path })`.\n */\nexport type DeploymentContentManifest = {\n\t/** Parent drop identifier. */\n\tdropId: string;\n\t/** Deployment identifier. */\n\tdeploymentId: string;\n\t/** Content revision of this deployment. */\n\trevision: number;\n\t/** Deployment lifecycle status. */\n\tstatus: string;\n\t/** Total deployment size in bytes. */\n\tsizeBytes: number;\n\t/** Entry path served at the drop root. */\n\tentry?: string | null;\n\t/** Readable files in this deployment; pass files[].path as `path` to download one. */\n\tfiles: DeploymentContentFile[];\n};\n\n/** Options for `drops.getContent()`. */\nexport type GetContentOptions = {\n\t/** Read a historical deployment instead of the current one. */\n\tdeploymentId?: string;\n\t/** Download this single file's raw stored bytes instead of the JSON manifest. */\n\tpath?: string;\n};\n\n/** A single file downloaded via `drops.getContent(dropId, { path })`. */\nexport type DropContentFile = {\n\t/** The requested file path. */\n\tpath: string;\n\t/** Stored MIME type the file is served with (from the response Content-Type). */\n\tcontentType: string | null;\n\t/** Exact stored bytes. */\n\tbytes: Uint8Array;\n\t/** Decode the bytes as UTF-8 text. */\n\ttext(): string;\n};\n"],"mappings":"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","names":["readFile","stat","basename","stat","basename","readFile","resolveInput"]}