@dropthis/cli 0.9.1 → 0.9.3

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.
@@ -80,7 +80,7 @@ The `drops.publish()` and `drops.updateContent()` methods accept:
80
80
  - **Source URL** -- `{ kind: "source_url", sourceUrl: "https://example.com/page" }`
81
81
  - **File bundle** -- `{ kind: "files", files: [{ path, content?, contentBase64?, bytes?, contentType? }], entry? }`
82
82
 
83
- Drop **settings** (title, visibility, password, noindex, expiresAt, slug, metadata) go in the second `options` argument, not in the input object.
83
+ Drop **settings** (title, visibility, password, noindex, expiresAt, metadata) go in the second `options` argument, not in the input object.
84
84
 
85
85
  All inputs are uploaded through staged presigned URLs. The SDK handles this transparently.
86
86
 
@@ -190,7 +190,7 @@ for await (const drop of page.data) {
190
190
  }
191
191
  ```
192
192
 
193
- > To change a drop's content, use `client.drops.updateContent(dropId, newInput)`. `drops.updateSettings()` is for settings only (title, visibility, password, noindex, expiresAt, slug, metadata).
193
+ > To change a drop's content, use `client.drops.updateContent(dropId, newInput)`. `drops.updateSettings()` is for settings only (title, visibility, password, noindex, expiresAt, metadata).
194
194
 
195
195
  ### deployments
196
196
 
@@ -219,8 +219,6 @@ type CompleteUploadSessionRequest = {
219
219
  }>;
220
220
  };
221
221
  type DropOptions = {
222
- /** Change the vanity slug (update only). */
223
- slug?: string;
224
222
  /** Drop title. */
225
223
  title?: string;
226
224
  /** public (default) or unlisted. */
@@ -414,18 +412,33 @@ declare class DropsResource<TInput = PublishInput> {
414
412
  private readonly transport;
415
413
  private readonly resolve;
416
414
  constructor(transport: Transport, resolve: PublishInputResolver<TInput>);
417
- /** Publish a NEW drop. Returns the created drop. Hits POST /drops. */
415
+ /**
416
+ * Publish content to a NEW permanent public URL; returns the created drop (with its `drop_…` id).
417
+ * Use to publish / share / post / put online / make public a report, dashboard, site, or file.
418
+ * Creates a NEW drop every call — to change something already published, use {@link updateContent}
419
+ * (the files at the URL) or {@link updateSettings} (title, visibility, password, expiry,
420
+ * metadata) with the drop's id; calling publish again makes a duplicate. POST /drops.
421
+ */
418
422
  publish(input: TInput, options?: PublishOptions): Promise<DropthisResult<DropResponse>>;
419
423
  /**
420
- * Publish a NEW content version to an existing drop, keeping its URL.
421
- * Content-only: drop settings/metadata are stripped BEFORE prepare so they are never
422
- * validated, sent, or applied. Settings are owned by updateSettings(). Hits
423
- * POST /drops/{id}/deployments.
424
+ * Replace the content of an EXISTING drop, keeping its URL (ships a new deployment). Requires the
425
+ * `drop_…` id from a publish response (not the slug/URL). Content-only: settings/metadata are
426
+ * stripped BEFORE prepare, so they are never sent change those with {@link updateSettings}; create
427
+ * a new drop with {@link publish}. Not idempotent (each call is a new deployment) unless you pass the
428
+ * same `idempotencyKey`. POST /drops/{id}/deployments.
424
429
  */
425
430
  updateContent(dropId: string, input: TInput, options?: UpdateContentOptions): Promise<DropthisResult<DropResponse>>;
431
+ /** List the account's drops, newest first (paginated). Each item carries its `drop_…` id. GET /drops. */
426
432
  list(params?: ListDropsParams): Promise<DropthisResult<CursorPage<DropResponse>>>;
433
+ /** Fetch one drop by its `drop_…` id (not the slug/URL). GET /drops/{id}. */
427
434
  get(dropId: string): Promise<DropthisResult<DropResponse>>;
435
+ /**
436
+ * Change an EXISTING drop's settings — title, visibility, password, noindex, expiry,
437
+ * metadata — by its `drop_…` id. Does not touch content; replace that with {@link updateContent}.
438
+ * Idempotent. PATCH /drops/{id}.
439
+ */
428
440
  updateSettings(dropId: string, options?: DropOptions & RequestControls): Promise<DropthisResult<DropResponse>>;
441
+ /** Permanently delete a drop and its public URL by its `drop_…` id. DELETE /drops/{id}. */
429
442
  delete(dropId: string): Promise<DropthisResult<null>>;
430
443
  }
431
444
 
@@ -219,8 +219,6 @@ type CompleteUploadSessionRequest = {
219
219
  }>;
220
220
  };
221
221
  type DropOptions = {
222
- /** Change the vanity slug (update only). */
223
- slug?: string;
224
222
  /** Drop title. */
225
223
  title?: string;
226
224
  /** public (default) or unlisted. */
@@ -414,18 +412,33 @@ declare class DropsResource<TInput = PublishInput> {
414
412
  private readonly transport;
415
413
  private readonly resolve;
416
414
  constructor(transport: Transport, resolve: PublishInputResolver<TInput>);
417
- /** Publish a NEW drop. Returns the created drop. Hits POST /drops. */
415
+ /**
416
+ * Publish content to a NEW permanent public URL; returns the created drop (with its `drop_…` id).
417
+ * Use to publish / share / post / put online / make public a report, dashboard, site, or file.
418
+ * Creates a NEW drop every call — to change something already published, use {@link updateContent}
419
+ * (the files at the URL) or {@link updateSettings} (title, visibility, password, expiry,
420
+ * metadata) with the drop's id; calling publish again makes a duplicate. POST /drops.
421
+ */
418
422
  publish(input: TInput, options?: PublishOptions): Promise<DropthisResult<DropResponse>>;
419
423
  /**
420
- * Publish a NEW content version to an existing drop, keeping its URL.
421
- * Content-only: drop settings/metadata are stripped BEFORE prepare so they are never
422
- * validated, sent, or applied. Settings are owned by updateSettings(). Hits
423
- * POST /drops/{id}/deployments.
424
+ * Replace the content of an EXISTING drop, keeping its URL (ships a new deployment). Requires the
425
+ * `drop_…` id from a publish response (not the slug/URL). Content-only: settings/metadata are
426
+ * stripped BEFORE prepare, so they are never sent change those with {@link updateSettings}; create
427
+ * a new drop with {@link publish}. Not idempotent (each call is a new deployment) unless you pass the
428
+ * same `idempotencyKey`. POST /drops/{id}/deployments.
424
429
  */
425
430
  updateContent(dropId: string, input: TInput, options?: UpdateContentOptions): Promise<DropthisResult<DropResponse>>;
431
+ /** List the account's drops, newest first (paginated). Each item carries its `drop_…` id. GET /drops. */
426
432
  list(params?: ListDropsParams): Promise<DropthisResult<CursorPage<DropResponse>>>;
433
+ /** Fetch one drop by its `drop_…` id (not the slug/URL). GET /drops/{id}. */
427
434
  get(dropId: string): Promise<DropthisResult<DropResponse>>;
435
+ /**
436
+ * Change an EXISTING drop's settings — title, visibility, password, noindex, expiry,
437
+ * metadata — by its `drop_…` id. Does not touch content; replace that with {@link updateContent}.
438
+ * Idempotent. PATCH /drops/{id}.
439
+ */
428
440
  updateSettings(dropId: string, options?: DropOptions & RequestControls): Promise<DropthisResult<DropResponse>>;
441
+ /** Permanently delete a drop and its public URL by its `drop_…` id. DELETE /drops/{id}. */
429
442
  delete(dropId: string): Promise<DropthisResult<null>>;
430
443
  }
431
444
 
@@ -504,7 +504,13 @@ var DropsResource = class {
504
504
  }
505
505
  transport;
506
506
  resolve;
507
- /** Publish a NEW drop. Returns the created drop. Hits POST /drops. */
507
+ /**
508
+ * Publish content to a NEW permanent public URL; returns the created drop (with its `drop_…` id).
509
+ * Use to publish / share / post / put online / make public a report, dashboard, site, or file.
510
+ * Creates a NEW drop every call — to change something already published, use {@link updateContent}
511
+ * (the files at the URL) or {@link updateSettings} (title, visibility, password, expiry,
512
+ * metadata) with the drop's id; calling publish again makes a duplicate. POST /drops.
513
+ */
508
514
  async publish(input, options = {}) {
509
515
  let prepared;
510
516
  try {
@@ -515,10 +521,11 @@ var DropsResource = class {
515
521
  return prepared.kind === "source" ? publishSource(this.transport, prepared, "/drops", options) : publishStaged(this.transport, prepared, "/drops", options);
516
522
  }
517
523
  /**
518
- * Publish a NEW content version to an existing drop, keeping its URL.
519
- * Content-only: drop settings/metadata are stripped BEFORE prepare so they are never
520
- * validated, sent, or applied. Settings are owned by updateSettings(). Hits
521
- * POST /drops/{id}/deployments.
524
+ * Replace the content of an EXISTING drop, keeping its URL (ships a new deployment). Requires the
525
+ * `drop_…` id from a publish response (not the slug/URL). Content-only: settings/metadata are
526
+ * stripped BEFORE prepare, so they are never sent change those with {@link updateSettings}; create
527
+ * a new drop with {@link publish}. Not idempotent (each call is a new deployment) unless you pass the
528
+ * same `idempotencyKey`. POST /drops/{id}/deployments.
522
529
  */
523
530
  async updateContent(dropId, input, options = {}) {
524
531
  const opts = updateContentOptions(options);
@@ -531,6 +538,7 @@ var DropsResource = class {
531
538
  const path = `/drops/${encodeURIComponent(dropId)}/deployments`;
532
539
  return prepared.kind === "source" ? publishSource(this.transport, prepared, path, opts) : publishStaged(this.transport, prepared, path, opts);
533
540
  }
541
+ /** List the account's drops, newest first (paginated). Each item carries its `drop_…` id. GET /drops. */
534
542
  async list(params = {}) {
535
543
  const result = await this.transport.request("GET", "/drops", {
536
544
  params
@@ -544,12 +552,18 @@ var DropsResource = class {
544
552
  });
545
553
  return { data: page, error: null, headers: result.headers };
546
554
  }
555
+ /** Fetch one drop by its `drop_…` id (not the slug/URL). GET /drops/{id}. */
547
556
  get(dropId) {
548
557
  return this.transport.request(
549
558
  "GET",
550
559
  `/drops/${encodeURIComponent(dropId)}`
551
560
  );
552
561
  }
562
+ /**
563
+ * Change an EXISTING drop's settings — title, visibility, password, noindex, expiry,
564
+ * metadata — by its `drop_…` id. Does not touch content; replace that with {@link updateContent}.
565
+ * Idempotent. PATCH /drops/{id}.
566
+ */
553
567
  updateSettings(dropId, options = {}) {
554
568
  const requestOptions = {
555
569
  body: updateBody(options)
@@ -564,6 +578,7 @@ var DropsResource = class {
564
578
  requestOptions
565
579
  );
566
580
  }
581
+ /** Permanently delete a drop and its public URL by its `drop_…` id. DELETE /drops/{id}. */
567
582
  delete(dropId) {
568
583
  return this.transport.request(
569
584
  "DELETE",
@@ -576,8 +591,7 @@ var SETTINGS = [
576
591
  "visibility",
577
592
  "password",
578
593
  "noindex",
579
- "expiresAt",
580
- "slug"
594
+ "expiresAt"
581
595
  ];
582
596
  function updateBody(options) {
583
597
  const out = {};
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/edge.ts","../src/errors.ts","../src/publish/detect.ts","../src/publish/paths.ts","../src/publish/core.ts","../src/resources/account.ts","../src/resources/api-keys.ts","../src/resources/deployments.ts","../src/pagination.ts","../src/resources/drops.ts","../src/case.ts","../src/transport.ts"],"sourcesContent":["// Workers-safe entry for @dropthis/node. Reuses the fetch-based Transport and the\n// resource classes, and exposes the canonical drop lifecycle through `edge.drops.*`\n// powered by the fs-free core pipeline.\n//\n// IMPORTANT: this module must NOT import `./dropthis.js` or `./publish/node.js`,\n// which pull in `node:fs`, `node:path`, `node:crypto`, `fast-glob`, `ignore`,\n// and `Buffer` and cannot be bundled for Cloudflare Workers. The only publish\n// import allowed is `./publish/core.js` (verified fs-free). Keep the import\n// graph to: publish/core + transport + resources + errors + types only.\n//\n// Edge semantics:\n// bare string → inline content (no filesystem lookup; HTML/text auto-detected)\n// http(s) URL → {kind:\"source_url\"} via URL object or http(s) string → source flow\n// Uint8Array → staged single-file upload\n// {kind:\"files\"} → staged multi-file bundle (agent-native; full multi-file supported on edge)\n// string[] → NOT part of InMemoryPublishInput (no fs on edge)\n\nimport { type InMemoryPublishInput, resolveInMemory } from \"./publish/core.js\";\nimport { AccountResource } from \"./resources/account.js\";\nimport { ApiKeysResource } from \"./resources/api-keys.js\";\nimport { DeploymentsResource } from \"./resources/deployments.js\";\nimport { DropsResource } from \"./resources/drops.js\";\nimport { Transport } from \"./transport.js\";\nimport type { DropthisClientOptions } from \"./types.js\";\n\nexport type { InMemoryPublishInput } from \"./publish/core.js\";\n\n/** Workers-safe dropthis client. Pass an apiKey explicitly (no process.env on the edge). */\nexport class DropthisEdge {\n\tprivate readonly transport: Transport;\n\tprivate dropsResource?: DropsResource<InMemoryPublishInput>;\n\tprivate accountResource?: AccountResource;\n\tprivate apiKeysResource?: ApiKeysResource;\n\tprivate deploymentsResource?: DeploymentsResource;\n\n\tconstructor(options: DropthisClientOptions | string = {}) {\n\t\tthis.transport = new Transport(options);\n\t}\n\n\tget drops(): DropsResource<InMemoryPublishInput> {\n\t\tif (!this.dropsResource)\n\t\t\tthis.dropsResource = new DropsResource(this.transport, resolveInMemory);\n\t\treturn this.dropsResource;\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 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 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","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\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.body !== undefined ? { body: extra.body } : {}),\n\t\t},\n\t\theaders: extra.headers ?? {},\n\t};\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","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\tCreateUploadSessionRequest,\n\tCreateUploadSessionResponse,\n\tDropResponse,\n\tDropthisResult,\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. 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 */\nexport type PreparedUploadFile = {\n\tpath: string;\n\tcontentType: string;\n\tsizeBytes: number;\n\tchecksumSha256?: string;\n\tgetBody(): Promise<Uint8Array | Blob | ReadableStream>;\n};\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 }\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 };\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\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\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\tpath: normalizeManifestPath(file.path),\n\t\tcontentType: file.contentType,\n\t\tsizeBytes: file.sizeBytes,\n\t\t...(file.checksumSha256 ? { checksumSha256: file.checksumSha256 } : {}),\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};\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\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\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.\",\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((file) => {\n\t\tassertValidManifestPath(file.path);\n\t\tconst bytes = fileBytes(file);\n\t\tconst contentType = file.contentType ?? detectBytesContentType(bytes);\n\t\treturn {\n\t\t\tpath: file.path,\n\t\t\tcontentType,\n\t\t\tsizeBytes: bytes.byteLength,\n\t\t\tgetBody: async () => bytes,\n\t\t};\n\t});\n\treturn buildStagedRequest(files, options, input.entry);\n}\n\n// ---------------------------------------------------------------------------\n// Orchestration helpers\n// ---------------------------------------------------------------------------\n\ntype StagedPublishOptions = { idempotencyKey?: string; ifRevision?: number };\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/**\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: upload each file via single PUT\n\tfor (const file of prepared.files) {\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\treturn createErrorResult(\n\t\t\t\t\"unsupported_upload_strategy\",\n\t\t\t\t`Unsupported upload strategy \"${target.upload.strategy}\" for ${file.path}. This SDK uploads via single PUT only.`,\n\t\t\t\tnull,\n\t\t\t);\n\t\t}\n\t\tconst put = await transport.putSignedUrl(\n\t\t\ttarget.upload.url,\n\t\t\tawait file.getBody(),\n\t\t\ttarget.upload.headers,\n\t\t);\n\t\tif (put.error) return errorResult(put);\n\t}\n\n\t// Step 3: complete upload session\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\tbody: { files: {} },\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},\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},\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 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} 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}): Promise<DropthisResult<ApiKeyCreatedResponse>> {\n\t\treturn this.transport.request(\"POST\", \"/api-keys\", { body: input });\n\t}\n\n\tdelete(keyId: string): Promise<DropthisResult<{ ok: true }>> {\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\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 { 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\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\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.fetchNextPage = input.fetchNextPage;\n\t}\n\n\tasync autoPagingToArray(options: { limit?: number } = {}): Promise<T[]> {\n\t\tconst items: T[] = [];\n\t\tfor await (const item of this) {\n\t\t\titems.push(item);\n\t\t\tif (options.limit !== undefined && items.length >= options.limit) break;\n\t\t}\n\t\treturn items;\n\t}\n\n\tasync *[Symbol.asyncIterator](): AsyncIterableIterator<T> {\n\t\tfor (const item of this.data) yield item;\n\t\tlet current: CursorPage<T> = this;\n\t\twhile (current.hasMore && current.fetchNextPage) {\n\t\t\tconst next = await current.fetchNextPage();\n\t\t\tif (next.error) break;\n\t\t\tcurrent = next.data;\n\t\t\tfor (const item of current.data) yield item;\n\t\t}\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\tDropOptions,\n\tDropResponse,\n\tDropthisResult,\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 resolve: PublishInputResolver<TInput>,\n\t) {}\n\n\t/** Publish a NEW drop. Returns the created drop. Hits POST /drops. */\n\tasync publish(\n\t\tinput: TInput,\n\t\toptions: PublishOptions = {},\n\t): Promise<DropthisResult<DropResponse>> {\n\t\tlet prepared: PreparedPublishRequest;\n\t\ttry {\n\t\t\tprepared = await this.resolve(input, options);\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\", options)\n\t\t\t: publishStaged(this.transport, prepared, \"/drops\", options);\n\t}\n\n\t/**\n\t * Publish a NEW content version to an existing drop, keeping its URL.\n\t * Content-only: drop settings/metadata are stripped BEFORE prepare so they are never\n\t * validated, sent, or applied. Settings are owned by updateSettings(). Hits\n\t * 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.resolve(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\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\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\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\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\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\"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","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.8.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{ headers: responseHeaders },\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\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);\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\tconst parsed = parseJson(text);\n\t\t\tif (!response.ok) {\n\t\t\t\tconst body =\n\t\t\t\t\tparsed && typeof parsed === \"object\"\n\t\t\t\t\t\t? (parsed as Record<string, unknown>)\n\t\t\t\t\t\t: {};\n\t\t\t\tconst message =\n\t\t\t\t\tstringValue(body.detail) ??\n\t\t\t\t\tstringValue(body.title) ??\n\t\t\t\t\tresponse.statusText;\n\t\t\t\tconst code =\n\t\t\t\t\tstringValue(body.code) ??\n\t\t\t\t\tstringValue(body.error_code) ??\n\t\t\t\t\t`http_${response.status}`;\n\t\t\t\tconst currentRevision = numberValue(body.current_revision);\n\t\t\t\tconst type = stringValue(body.type);\n\t\t\t\tconst title = stringValue(body.title);\n\t\t\t\tconst instance = stringValue(body.instance);\n\t\t\t\treturn createErrorResult<T>(code, message, response.status, {\n\t\t\t\t\tbody,\n\t\t\t\t\t...(type !== null ? { type } : {}),\n\t\t\t\t\t...(title !== null ? { title } : {}),\n\t\t\t\t\t...(instance !== null ? { instance } : {}),\n\t\t\t\t\tdetail: stringValue(body.detail),\n\t\t\t\t\tparam: stringValue(body.param),\n\t\t\t\t\t...(currentRevision !== undefined ? { currentRevision } : {}),\n\t\t\t\t\trequestId:\n\t\t\t\t\t\tstringValue(body.request_id) ??\n\t\t\t\t\t\tresponseHeaders[\"x-request-id\"] ??\n\t\t\t\t\t\tnull,\n\t\t\t\t\tsuggestion: stringValue(body.suggestion),\n\t\t\t\t\tretryable: booleanValue(body.retryable),\n\t\t\t\t\theaders: responseHeaders,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tdata: toCamelCase(parsed) 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\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);\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t}\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"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/edge.ts","../src/errors.ts","../src/publish/detect.ts","../src/publish/paths.ts","../src/publish/core.ts","../src/resources/account.ts","../src/resources/api-keys.ts","../src/resources/deployments.ts","../src/pagination.ts","../src/resources/drops.ts","../src/case.ts","../src/transport.ts"],"sourcesContent":["// Workers-safe entry for @dropthis/node. Reuses the fetch-based Transport and the\n// resource classes, and exposes the canonical drop lifecycle through `edge.drops.*`\n// powered by the fs-free core pipeline.\n//\n// IMPORTANT: this module must NOT import `./dropthis.js` or `./publish/node.js`,\n// which pull in `node:fs`, `node:path`, `node:crypto`, `fast-glob`, `ignore`,\n// and `Buffer` and cannot be bundled for Cloudflare Workers. The only publish\n// import allowed is `./publish/core.js` (verified fs-free). Keep the import\n// graph to: publish/core + transport + resources + errors + types only.\n//\n// Edge semantics:\n// bare string → inline content (no filesystem lookup; HTML/text auto-detected)\n// http(s) URL → {kind:\"source_url\"} via URL object or http(s) string → source flow\n// Uint8Array → staged single-file upload\n// {kind:\"files\"} → staged multi-file bundle (agent-native; full multi-file supported on edge)\n// string[] → NOT part of InMemoryPublishInput (no fs on edge)\n\nimport { type InMemoryPublishInput, resolveInMemory } from \"./publish/core.js\";\nimport { AccountResource } from \"./resources/account.js\";\nimport { ApiKeysResource } from \"./resources/api-keys.js\";\nimport { DeploymentsResource } from \"./resources/deployments.js\";\nimport { DropsResource } from \"./resources/drops.js\";\nimport { Transport } from \"./transport.js\";\nimport type { DropthisClientOptions } from \"./types.js\";\n\nexport type { InMemoryPublishInput } from \"./publish/core.js\";\n\n/** Workers-safe dropthis client. Pass an apiKey explicitly (no process.env on the edge). */\nexport class DropthisEdge {\n\tprivate readonly transport: Transport;\n\tprivate dropsResource?: DropsResource<InMemoryPublishInput>;\n\tprivate accountResource?: AccountResource;\n\tprivate apiKeysResource?: ApiKeysResource;\n\tprivate deploymentsResource?: DeploymentsResource;\n\n\tconstructor(options: DropthisClientOptions | string = {}) {\n\t\tthis.transport = new Transport(options);\n\t}\n\n\tget drops(): DropsResource<InMemoryPublishInput> {\n\t\tif (!this.dropsResource)\n\t\t\tthis.dropsResource = new DropsResource(this.transport, resolveInMemory);\n\t\treturn this.dropsResource;\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 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 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","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\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.body !== undefined ? { body: extra.body } : {}),\n\t\t},\n\t\theaders: extra.headers ?? {},\n\t};\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","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\tCreateUploadSessionRequest,\n\tCreateUploadSessionResponse,\n\tDropResponse,\n\tDropthisResult,\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. 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 */\nexport type PreparedUploadFile = {\n\tpath: string;\n\tcontentType: string;\n\tsizeBytes: number;\n\tchecksumSha256?: string;\n\tgetBody(): Promise<Uint8Array | Blob | ReadableStream>;\n};\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 }\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 };\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\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\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\tpath: normalizeManifestPath(file.path),\n\t\tcontentType: file.contentType,\n\t\tsizeBytes: file.sizeBytes,\n\t\t...(file.checksumSha256 ? { checksumSha256: file.checksumSha256 } : {}),\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};\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\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\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.\",\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((file) => {\n\t\tassertValidManifestPath(file.path);\n\t\tconst bytes = fileBytes(file);\n\t\tconst contentType = file.contentType ?? detectBytesContentType(bytes);\n\t\treturn {\n\t\t\tpath: file.path,\n\t\t\tcontentType,\n\t\t\tsizeBytes: bytes.byteLength,\n\t\t\tgetBody: async () => bytes,\n\t\t};\n\t});\n\treturn buildStagedRequest(files, options, input.entry);\n}\n\n// ---------------------------------------------------------------------------\n// Orchestration helpers\n// ---------------------------------------------------------------------------\n\ntype StagedPublishOptions = { idempotencyKey?: string; ifRevision?: number };\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/**\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: upload each file via single PUT\n\tfor (const file of prepared.files) {\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\treturn createErrorResult(\n\t\t\t\t\"unsupported_upload_strategy\",\n\t\t\t\t`Unsupported upload strategy \"${target.upload.strategy}\" for ${file.path}. This SDK uploads via single PUT only.`,\n\t\t\t\tnull,\n\t\t\t);\n\t\t}\n\t\tconst put = await transport.putSignedUrl(\n\t\t\ttarget.upload.url,\n\t\t\tawait file.getBody(),\n\t\t\ttarget.upload.headers,\n\t\t);\n\t\tif (put.error) return errorResult(put);\n\t}\n\n\t// Step 3: complete upload session\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\tbody: { files: {} },\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},\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},\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 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} 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}): Promise<DropthisResult<ApiKeyCreatedResponse>> {\n\t\treturn this.transport.request(\"POST\", \"/api-keys\", { body: input });\n\t}\n\n\tdelete(keyId: string): Promise<DropthisResult<{ ok: true }>> {\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\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 { 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\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\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.fetchNextPage = input.fetchNextPage;\n\t}\n\n\tasync autoPagingToArray(options: { limit?: number } = {}): Promise<T[]> {\n\t\tconst items: T[] = [];\n\t\tfor await (const item of this) {\n\t\t\titems.push(item);\n\t\t\tif (options.limit !== undefined && items.length >= options.limit) break;\n\t\t}\n\t\treturn items;\n\t}\n\n\tasync *[Symbol.asyncIterator](): AsyncIterableIterator<T> {\n\t\tfor (const item of this.data) yield item;\n\t\tlet current: CursorPage<T> = this;\n\t\twhile (current.hasMore && current.fetchNextPage) {\n\t\t\tconst next = await current.fetchNextPage();\n\t\t\tif (next.error) break;\n\t\t\tcurrent = next.data;\n\t\t\tfor (const item of current.data) yield item;\n\t\t}\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\tDropOptions,\n\tDropResponse,\n\tDropthisResult,\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 resolve: PublishInputResolver<TInput>,\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\tasync publish(\n\t\tinput: TInput,\n\t\toptions: PublishOptions = {},\n\t): Promise<DropthisResult<DropResponse>> {\n\t\tlet prepared: PreparedPublishRequest;\n\t\ttry {\n\t\t\tprepared = await this.resolve(input, options);\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\", options)\n\t\t\t: publishStaged(this.transport, prepared, \"/drops\", options);\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.resolve(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/** List the account's drops, newest first (paginated). Each item carries its `drop_…` id. GET /drops. */\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\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 * Change an EXISTING drop's settings — title, visibility, password, noindex, expiry,\n\t * metadata — by its `drop_…` id. Does not touch content; replace that with {@link updateContent}.\n\t * Idempotent. PATCH /drops/{id}.\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] 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","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.8.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{ headers: responseHeaders },\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\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);\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\tconst parsed = parseJson(text);\n\t\t\tif (!response.ok) {\n\t\t\t\tconst body =\n\t\t\t\t\tparsed && typeof parsed === \"object\"\n\t\t\t\t\t\t? (parsed as Record<string, unknown>)\n\t\t\t\t\t\t: {};\n\t\t\t\tconst message =\n\t\t\t\t\tstringValue(body.detail) ??\n\t\t\t\t\tstringValue(body.title) ??\n\t\t\t\t\tresponse.statusText;\n\t\t\t\tconst code =\n\t\t\t\t\tstringValue(body.code) ??\n\t\t\t\t\tstringValue(body.error_code) ??\n\t\t\t\t\t`http_${response.status}`;\n\t\t\t\tconst currentRevision = numberValue(body.current_revision);\n\t\t\t\tconst type = stringValue(body.type);\n\t\t\t\tconst title = stringValue(body.title);\n\t\t\t\tconst instance = stringValue(body.instance);\n\t\t\t\treturn createErrorResult<T>(code, message, response.status, {\n\t\t\t\t\tbody,\n\t\t\t\t\t...(type !== null ? { type } : {}),\n\t\t\t\t\t...(title !== null ? { title } : {}),\n\t\t\t\t\t...(instance !== null ? { instance } : {}),\n\t\t\t\t\tdetail: stringValue(body.detail),\n\t\t\t\t\tparam: stringValue(body.param),\n\t\t\t\t\t...(currentRevision !== undefined ? { currentRevision } : {}),\n\t\t\t\t\trequestId:\n\t\t\t\t\t\tstringValue(body.request_id) ??\n\t\t\t\t\t\tresponseHeaders[\"x-request-id\"] ??\n\t\t\t\t\t\tnull,\n\t\t\t\t\tsuggestion: stringValue(body.suggestion),\n\t\t\t\t\tretryable: booleanValue(body.retryable),\n\t\t\t\t\theaders: responseHeaders,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tdata: toCamelCase(parsed) 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\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);\n\t\t} finally {\n\t\t\tclearTimeout(timeout);\n\t\t}\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"],"mappings":"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","names":[]}
@@ -1,4 +1,4 @@
1
- import { k as DropthisClientOptions, j as DropsResource, I as InMemoryPublishInput, A as AccountResource, b as ApiKeysResource, D as DeploymentsResource } from './drops-C8-OQkbF.cjs';
1
+ import { k as DropthisClientOptions, j as DropsResource, I as InMemoryPublishInput, A as AccountResource, b as ApiKeysResource, D as DeploymentsResource } from './drops-BWA0D1IW.cjs';
2
2
 
3
3
  /** Workers-safe dropthis client. Pass an apiKey explicitly (no process.env on the edge). */
4
4
  declare class DropthisEdge {
@@ -1,4 +1,4 @@
1
- import { k as DropthisClientOptions, j as DropsResource, I as InMemoryPublishInput, A as AccountResource, b as ApiKeysResource, D as DeploymentsResource } from './drops-C8-OQkbF.js';
1
+ import { k as DropthisClientOptions, j as DropsResource, I as InMemoryPublishInput, A as AccountResource, b as ApiKeysResource, D as DeploymentsResource } from './drops-BWA0D1IW.js';
2
2
 
3
3
  /** Workers-safe dropthis client. Pass an apiKey explicitly (no process.env on the edge). */
4
4
  declare class DropthisEdge {
@@ -478,7 +478,13 @@ var DropsResource = class {
478
478
  }
479
479
  transport;
480
480
  resolve;
481
- /** Publish a NEW drop. Returns the created drop. Hits POST /drops. */
481
+ /**
482
+ * Publish content to a NEW permanent public URL; returns the created drop (with its `drop_…` id).
483
+ * Use to publish / share / post / put online / make public a report, dashboard, site, or file.
484
+ * Creates a NEW drop every call — to change something already published, use {@link updateContent}
485
+ * (the files at the URL) or {@link updateSettings} (title, visibility, password, expiry,
486
+ * metadata) with the drop's id; calling publish again makes a duplicate. POST /drops.
487
+ */
482
488
  async publish(input, options = {}) {
483
489
  let prepared;
484
490
  try {
@@ -489,10 +495,11 @@ var DropsResource = class {
489
495
  return prepared.kind === "source" ? publishSource(this.transport, prepared, "/drops", options) : publishStaged(this.transport, prepared, "/drops", options);
490
496
  }
491
497
  /**
492
- * Publish a NEW content version to an existing drop, keeping its URL.
493
- * Content-only: drop settings/metadata are stripped BEFORE prepare so they are never
494
- * validated, sent, or applied. Settings are owned by updateSettings(). Hits
495
- * POST /drops/{id}/deployments.
498
+ * Replace the content of an EXISTING drop, keeping its URL (ships a new deployment). Requires the
499
+ * `drop_…` id from a publish response (not the slug/URL). Content-only: settings/metadata are
500
+ * stripped BEFORE prepare, so they are never sent change those with {@link updateSettings}; create
501
+ * a new drop with {@link publish}. Not idempotent (each call is a new deployment) unless you pass the
502
+ * same `idempotencyKey`. POST /drops/{id}/deployments.
496
503
  */
497
504
  async updateContent(dropId, input, options = {}) {
498
505
  const opts = updateContentOptions(options);
@@ -505,6 +512,7 @@ var DropsResource = class {
505
512
  const path = `/drops/${encodeURIComponent(dropId)}/deployments`;
506
513
  return prepared.kind === "source" ? publishSource(this.transport, prepared, path, opts) : publishStaged(this.transport, prepared, path, opts);
507
514
  }
515
+ /** List the account's drops, newest first (paginated). Each item carries its `drop_…` id. GET /drops. */
508
516
  async list(params = {}) {
509
517
  const result = await this.transport.request("GET", "/drops", {
510
518
  params
@@ -518,12 +526,18 @@ var DropsResource = class {
518
526
  });
519
527
  return { data: page, error: null, headers: result.headers };
520
528
  }
529
+ /** Fetch one drop by its `drop_…` id (not the slug/URL). GET /drops/{id}. */
521
530
  get(dropId) {
522
531
  return this.transport.request(
523
532
  "GET",
524
533
  `/drops/${encodeURIComponent(dropId)}`
525
534
  );
526
535
  }
536
+ /**
537
+ * Change an EXISTING drop's settings — title, visibility, password, noindex, expiry,
538
+ * metadata — by its `drop_…` id. Does not touch content; replace that with {@link updateContent}.
539
+ * Idempotent. PATCH /drops/{id}.
540
+ */
527
541
  updateSettings(dropId, options = {}) {
528
542
  const requestOptions = {
529
543
  body: updateBody(options)
@@ -538,6 +552,7 @@ var DropsResource = class {
538
552
  requestOptions
539
553
  );
540
554
  }
555
+ /** Permanently delete a drop and its public URL by its `drop_…` id. DELETE /drops/{id}. */
541
556
  delete(dropId) {
542
557
  return this.transport.request(
543
558
  "DELETE",
@@ -550,8 +565,7 @@ var SETTINGS = [
550
565
  "visibility",
551
566
  "password",
552
567
  "noindex",
553
- "expiresAt",
554
- "slug"
568
+ "expiresAt"
555
569
  ];
556
570
  function updateBody(options) {
557
571
  const out = {};