@dropthis/cli 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,584 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/edge.ts
21
+ var edge_exports = {};
22
+ __export(edge_exports, {
23
+ DropthisEdge: () => DropthisEdge
24
+ });
25
+ module.exports = __toCommonJS(edge_exports);
26
+
27
+ // src/errors.ts
28
+ var API_KEY_RE = /sk_[A-Za-z0-9_-]+/g;
29
+ function redactSecrets(message) {
30
+ return message.replace(API_KEY_RE, "sk_[redacted]");
31
+ }
32
+ function createErrorResult(code, message, statusCode, extra = {}) {
33
+ return {
34
+ data: null,
35
+ error: {
36
+ code,
37
+ message: redactSecrets(message),
38
+ statusCode,
39
+ ...extra.type ? { type: extra.type } : {},
40
+ ...extra.detail !== void 0 ? { detail: extra.detail } : {},
41
+ ...extra.param !== void 0 ? { param: extra.param } : {},
42
+ ...extra.currentRevision !== void 0 ? { currentRevision: extra.currentRevision } : {},
43
+ ...extra.requestId !== void 0 ? { requestId: extra.requestId } : {},
44
+ ...extra.suggestion !== void 0 ? { suggestion: extra.suggestion } : {},
45
+ ...extra.retryable !== void 0 ? { retryable: extra.retryable } : {}
46
+ },
47
+ headers: extra.headers ?? {}
48
+ };
49
+ }
50
+
51
+ // src/resources/account.ts
52
+ var AccountResource = class {
53
+ constructor(transport) {
54
+ this.transport = transport;
55
+ }
56
+ transport;
57
+ get() {
58
+ return this.transport.request("GET", "/account");
59
+ }
60
+ update(input) {
61
+ return this.transport.request("PATCH", "/account", { body: input });
62
+ }
63
+ delete() {
64
+ return this.transport.request("DELETE", "/account");
65
+ }
66
+ };
67
+
68
+ // src/resources/api-keys.ts
69
+ var ApiKeysResource = class {
70
+ constructor(transport) {
71
+ this.transport = transport;
72
+ }
73
+ transport;
74
+ list() {
75
+ return this.transport.request("GET", "/api-keys");
76
+ }
77
+ create(input) {
78
+ return this.transport.request("POST", "/api-keys", { body: input });
79
+ }
80
+ delete(keyId) {
81
+ return this.transport.request(
82
+ "DELETE",
83
+ `/api-keys/${encodeURIComponent(keyId)}`
84
+ );
85
+ }
86
+ };
87
+
88
+ // src/resources/deployments.ts
89
+ var DeploymentsResource = class {
90
+ constructor(transport) {
91
+ this.transport = transport;
92
+ }
93
+ transport;
94
+ create(dropId, body, options = {}) {
95
+ const requestOptions = { body };
96
+ if (options.idempotencyKey)
97
+ requestOptions.idempotencyKey = options.idempotencyKey;
98
+ if (options.ifRevision !== void 0)
99
+ requestOptions.ifRevision = options.ifRevision;
100
+ return this.transport.request(
101
+ "POST",
102
+ `/drops/${encodeURIComponent(dropId)}/deployments`,
103
+ requestOptions
104
+ );
105
+ }
106
+ createRaw(dropId, body, options = {}) {
107
+ const requestOptions = {
108
+ body,
109
+ bodyCase: "raw"
110
+ };
111
+ if (options.idempotencyKey)
112
+ requestOptions.idempotencyKey = options.idempotencyKey;
113
+ if (options.ifRevision !== void 0)
114
+ requestOptions.ifRevision = options.ifRevision;
115
+ return this.transport.request(
116
+ "POST",
117
+ `/drops/${encodeURIComponent(dropId)}/deployments`,
118
+ requestOptions
119
+ );
120
+ }
121
+ list(dropId, params = {}) {
122
+ return this.transport.request(
123
+ "GET",
124
+ `/drops/${encodeURIComponent(dropId)}/deployments`,
125
+ { params }
126
+ );
127
+ }
128
+ get(dropId, deploymentId) {
129
+ return this.transport.request(
130
+ "GET",
131
+ `/drops/${encodeURIComponent(dropId)}/deployments/${encodeURIComponent(deploymentId)}`
132
+ );
133
+ }
134
+ };
135
+
136
+ // src/pagination.ts
137
+ var CursorPage = class {
138
+ object = "list";
139
+ data;
140
+ hasMore;
141
+ nextCursor;
142
+ fetchNextPage;
143
+ constructor(input) {
144
+ this.data = input.data;
145
+ this.hasMore = input.hasMore;
146
+ this.nextCursor = input.nextCursor;
147
+ this.fetchNextPage = input.fetchNextPage;
148
+ }
149
+ async autoPagingToArray(options = {}) {
150
+ const items = [];
151
+ for await (const item of this) {
152
+ items.push(item);
153
+ if (options.limit !== void 0 && items.length >= options.limit) break;
154
+ }
155
+ return items;
156
+ }
157
+ async *[Symbol.asyncIterator]() {
158
+ for (const item of this.data) yield item;
159
+ let current = this;
160
+ while (current.hasMore && current.fetchNextPage) {
161
+ const next = await current.fetchNextPage();
162
+ if (next.error) break;
163
+ current = next.data;
164
+ for (const item of current.data) yield item;
165
+ }
166
+ }
167
+ };
168
+
169
+ // src/resources/drops.ts
170
+ var DropsResource = class {
171
+ constructor(transport) {
172
+ this.transport = transport;
173
+ }
174
+ transport;
175
+ create(body, options = {}) {
176
+ const requestOptions = { body };
177
+ if (options.idempotencyKey)
178
+ requestOptions.idempotencyKey = options.idempotencyKey;
179
+ return this.transport.request("POST", "/drops", requestOptions);
180
+ }
181
+ createRaw(body, options = {}) {
182
+ const requestOptions = {
183
+ body,
184
+ bodyCase: "raw"
185
+ };
186
+ if (options.idempotencyKey)
187
+ requestOptions.idempotencyKey = options.idempotencyKey;
188
+ return this.transport.request("POST", "/drops", requestOptions);
189
+ }
190
+ async list(params = {}) {
191
+ const result = await this.transport.request("GET", "/drops", {
192
+ params
193
+ });
194
+ if (result.error) return result;
195
+ const page = new CursorPage({
196
+ data: result.data.drops,
197
+ nextCursor: result.data.nextCursor,
198
+ hasMore: result.data.nextCursor !== null,
199
+ fetchNextPage: result.data.nextCursor ? () => this.list({ ...params, cursor: result.data.nextCursor }) : void 0
200
+ });
201
+ return { data: page, error: null, headers: result.headers };
202
+ }
203
+ get(dropId) {
204
+ return this.transport.request(
205
+ "GET",
206
+ `/drops/${encodeURIComponent(dropId)}`
207
+ );
208
+ }
209
+ update(dropId, options = {}) {
210
+ const requestOptions = {
211
+ body: updateBody(options)
212
+ };
213
+ if (options.idempotencyKey)
214
+ requestOptions.idempotencyKey = options.idempotencyKey;
215
+ if (options.ifRevision !== void 0)
216
+ requestOptions.ifRevision = options.ifRevision;
217
+ return this.transport.request(
218
+ "PATCH",
219
+ `/drops/${encodeURIComponent(dropId)}`,
220
+ requestOptions
221
+ );
222
+ }
223
+ delete(dropId) {
224
+ return this.transport.request(
225
+ "DELETE",
226
+ `/drops/${encodeURIComponent(dropId)}`
227
+ );
228
+ }
229
+ };
230
+ function updateBody(options) {
231
+ const {
232
+ metadata,
233
+ idempotencyKey: _idempotencyKey,
234
+ ifRevision: _ifRevision,
235
+ entry: _entry,
236
+ ...dropOptions2
237
+ } = options;
238
+ return { options: dropOptions2, metadata };
239
+ }
240
+
241
+ // src/case.ts
242
+ function toCamelKey(key) {
243
+ return key.replace(/_([a-z])/g, (_, char) => char.toUpperCase());
244
+ }
245
+ function toSnakeKey(key) {
246
+ return key.replace(/[A-Z]/g, (char) => `_${char.toLowerCase()}`);
247
+ }
248
+ var PASSTHROUGH_KEYS = /* @__PURE__ */ new Set(["metadata"]);
249
+ function toCamelCase(value) {
250
+ if (Array.isArray(value)) return value.map(toCamelCase);
251
+ if (value && typeof value === "object") {
252
+ return Object.fromEntries(
253
+ Object.entries(value).map(([key, item]) => [
254
+ toCamelKey(key),
255
+ PASSTHROUGH_KEYS.has(key) ? item : toCamelCase(item)
256
+ ])
257
+ );
258
+ }
259
+ return value;
260
+ }
261
+ function toSnakeCase(value) {
262
+ if (Array.isArray(value)) return value.map(toSnakeCase);
263
+ if (value && typeof value === "object") {
264
+ return Object.fromEntries(
265
+ Object.entries(value).filter(([, item]) => item !== void 0).map(([key, item]) => [
266
+ toSnakeKey(key),
267
+ PASSTHROUGH_KEYS.has(key) ? item : toSnakeCase(item)
268
+ ])
269
+ );
270
+ }
271
+ return value;
272
+ }
273
+
274
+ // src/transport.ts
275
+ var DEFAULT_BASE_URL = "https://api.dropthis.app";
276
+ var SDK_VERSION = "0.5.0";
277
+ var Transport = class {
278
+ apiKey;
279
+ baseUrl;
280
+ timeoutMs;
281
+ fetchImpl;
282
+ constructor(options = {}) {
283
+ const resolved = typeof options === "string" ? { apiKey: options } : options;
284
+ this.apiKey = resolved.apiKey ?? (typeof process !== "undefined" ? process.env?.DROPTHIS_API_KEY : void 0);
285
+ this.baseUrl = (resolved.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
286
+ this.timeoutMs = resolved.timeoutMs ?? 3e4;
287
+ this.fetchImpl = resolved.fetch ?? globalThis.fetch;
288
+ }
289
+ multipart(method, path, form, options = {}) {
290
+ return this.request(method, path, { ...options, body: form });
291
+ }
292
+ async putSignedUrl(url, body, headers) {
293
+ const controller = new AbortController();
294
+ const timeout = setTimeout(() => controller.abort(), this.timeoutMs);
295
+ try {
296
+ const request = {
297
+ method: "PUT",
298
+ headers,
299
+ body,
300
+ signal: controller.signal
301
+ };
302
+ if (body instanceof ReadableStream) request.duplex = "half";
303
+ const response = await this.fetchImpl(url, request);
304
+ const responseHeaders = headersToObject(response.headers);
305
+ if (!response.ok) {
306
+ const text = await response.text();
307
+ return createErrorResult(
308
+ `signed_upload_${response.status}`,
309
+ text || response.statusText,
310
+ response.status,
311
+ { headers: responseHeaders }
312
+ );
313
+ }
314
+ return {
315
+ data: {
316
+ etag: response.headers.get("ETag") ?? responseHeaders.etag ?? null
317
+ },
318
+ error: null,
319
+ headers: responseHeaders
320
+ };
321
+ } catch (error) {
322
+ const message = error instanceof Error && error.name === "AbortError" ? "Request timed out" : error instanceof Error ? error.message : "Network error";
323
+ return createErrorResult(
324
+ error instanceof Error && error.name === "AbortError" ? "timeout" : "network_error",
325
+ message,
326
+ null
327
+ );
328
+ } finally {
329
+ clearTimeout(timeout);
330
+ }
331
+ }
332
+ async request(method, path, options = {}) {
333
+ const authenticated = options.authenticated ?? true;
334
+ if (authenticated && !this.apiKey) {
335
+ return createErrorResult(
336
+ "missing_api_key",
337
+ "No API key provided. Pass apiKey or set DROPTHIS_API_KEY.",
338
+ null
339
+ );
340
+ }
341
+ const headers = {
342
+ "user-agent": `dropthis-node/${SDK_VERSION}`
343
+ };
344
+ if (authenticated && this.apiKey)
345
+ headers.authorization = `Bearer ${this.apiKey}`;
346
+ if (options.idempotencyKey)
347
+ headers["idempotency-key"] = options.idempotencyKey;
348
+ if (options.ifRevision !== void 0)
349
+ headers["If-Revision"] = String(options.ifRevision);
350
+ if (options.body !== void 0 && !(options.body instanceof FormData))
351
+ headers["content-type"] = "application/json";
352
+ const url = new URL(`${this.baseUrl}${path}`);
353
+ const wireParams = options.bodyCase === "raw" ? options.params : toSnakeCase(options.params ?? {});
354
+ for (const [key, value] of Object.entries(wireParams ?? {})) {
355
+ if (value !== void 0 && value !== null)
356
+ url.searchParams.set(key, String(value));
357
+ }
358
+ const controller = new AbortController();
359
+ const timeout = setTimeout(
360
+ () => controller.abort(),
361
+ options.timeoutMs ?? this.timeoutMs
362
+ );
363
+ try {
364
+ const request = {
365
+ method,
366
+ headers,
367
+ signal: controller.signal
368
+ };
369
+ if (options.body instanceof FormData) {
370
+ request.body = options.body;
371
+ } else if (options.body !== void 0) {
372
+ const wireBody = options.bodyCase === "raw" ? options.body : toSnakeCase(options.body);
373
+ request.body = JSON.stringify(wireBody);
374
+ }
375
+ const response = await this.fetchImpl(url.toString(), request);
376
+ const responseHeaders = headersToObject(response.headers);
377
+ const text = await response.text();
378
+ const parsed = parseJson(text);
379
+ if (!response.ok) {
380
+ const body = parsed && typeof parsed === "object" ? parsed : {};
381
+ const message = stringValue(body.detail) ?? stringValue(body.error) ?? stringValue(body.message) ?? response.statusText;
382
+ const code = stringValue(body.code) ?? stringValue(body.error_code) ?? `http_${response.status}`;
383
+ const currentRevision = numberValue(body.current_revision);
384
+ return createErrorResult(code, message, response.status, {
385
+ detail: body,
386
+ param: stringValue(body.param),
387
+ ...currentRevision !== void 0 ? { currentRevision } : {},
388
+ requestId: stringValue(body.request_id) ?? responseHeaders["x-request-id"] ?? null,
389
+ suggestion: stringValue(body.suggestion),
390
+ retryable: booleanValue(body.retryable),
391
+ headers: responseHeaders
392
+ });
393
+ }
394
+ return {
395
+ data: toCamelCase(parsed),
396
+ error: null,
397
+ headers: responseHeaders
398
+ };
399
+ } catch (error) {
400
+ const message = error instanceof Error && error.name === "AbortError" ? "Request timed out" : error instanceof Error ? error.message : "Network error";
401
+ return createErrorResult(
402
+ error instanceof Error && error.name === "AbortError" ? "timeout" : "network_error",
403
+ message,
404
+ null
405
+ );
406
+ } finally {
407
+ clearTimeout(timeout);
408
+ }
409
+ }
410
+ };
411
+ function headersToObject(headers) {
412
+ const result = {};
413
+ headers.forEach((value, key) => {
414
+ result[key.toLowerCase()] = value;
415
+ });
416
+ return result;
417
+ }
418
+ function parseJson(text) {
419
+ if (!text) return null;
420
+ try {
421
+ return JSON.parse(text);
422
+ } catch {
423
+ return text;
424
+ }
425
+ }
426
+ function stringValue(value) {
427
+ return typeof value === "string" ? value : null;
428
+ }
429
+ function numberValue(value) {
430
+ return typeof value === "number" ? value : void 0;
431
+ }
432
+ function booleanValue(value) {
433
+ return typeof value === "boolean" ? value : null;
434
+ }
435
+
436
+ // src/edge.ts
437
+ var DROP_OPTION_KEYS = [
438
+ "title",
439
+ "visibility",
440
+ "password",
441
+ "noindex",
442
+ "expiresAt"
443
+ ];
444
+ function detectStringContentType(value) {
445
+ const trimmed = value.trimStart().toLowerCase();
446
+ if (trimmed.startsWith("<!doctype html") || trimmed.startsWith("<html") || /^<[a-z][a-z0-9:-]*(\s|>)/.test(trimmed)) {
447
+ return "text/html";
448
+ }
449
+ return "text/plain; charset=utf-8";
450
+ }
451
+ function defaultEntry(contentType) {
452
+ const media = contentType.split(";", 1)[0]?.trim().toLowerCase() ?? "";
453
+ return media === "text/html" ? "index.html" : "index.txt";
454
+ }
455
+ function normalizeInput(input, options) {
456
+ if (typeof input === "string") {
457
+ const contentType = options.contentType ?? detectStringContentType(input);
458
+ return {
459
+ bytes: new TextEncoder().encode(input),
460
+ path: options.path ?? defaultEntry(contentType),
461
+ contentType
462
+ };
463
+ }
464
+ return {
465
+ bytes: input.bytes,
466
+ path: input.filename ?? options.path ?? "index.html",
467
+ contentType: input.contentType ?? options.contentType ?? "application/octet-stream"
468
+ };
469
+ }
470
+ function dropOptions(options) {
471
+ const out = {};
472
+ for (const key of DROP_OPTION_KEYS) {
473
+ if (options[key] !== void 0) out[key] = options[key];
474
+ }
475
+ return out;
476
+ }
477
+ function errorResult(result) {
478
+ if (!result.error) throw new Error("Expected an error result");
479
+ return { data: null, error: result.error, headers: result.headers };
480
+ }
481
+ async function stagedInline(transport, input, options, finalPath) {
482
+ const { bytes, path, contentType } = normalizeInput(input, options);
483
+ const baseKey = options.idempotencyKey ?? `mcp-${crypto.randomUUID()}`;
484
+ const manifest = {
485
+ schemaVersion: 1,
486
+ files: [{ path, contentType, sizeBytes: bytes.byteLength }],
487
+ entry: path
488
+ };
489
+ const created = await transport.request(
490
+ "POST",
491
+ "/uploads",
492
+ {
493
+ body: manifest,
494
+ idempotencyKey: `${baseKey}:create-upload`
495
+ }
496
+ );
497
+ if (created.error) return errorResult(created);
498
+ const target = created.data.files[0];
499
+ if (!target) {
500
+ return createErrorResult(
501
+ "upload_target_missing",
502
+ "No upload target returned for the file.",
503
+ null
504
+ );
505
+ }
506
+ if (target.upload.strategy !== "single_put") {
507
+ return createErrorResult(
508
+ "unsupported_upload_strategy",
509
+ "Edge publishInline supports single_put uploads only; the content is too large for inline publishing.",
510
+ null
511
+ );
512
+ }
513
+ const put = await transport.putSignedUrl(
514
+ target.upload.url,
515
+ bytes,
516
+ target.upload.headers
517
+ );
518
+ if (put.error) return errorResult(put);
519
+ const completed = await transport.request(
520
+ "POST",
521
+ `/uploads/${encodeURIComponent(created.data.uploadId)}/complete`,
522
+ { body: { files: {} }, idempotencyKey: `${baseKey}:complete-upload` }
523
+ );
524
+ if (completed.error) return errorResult(completed);
525
+ const finalOptions = {
526
+ body: {
527
+ uploadId: created.data.uploadId,
528
+ options: dropOptions(options),
529
+ ...options.metadata ? { metadata: options.metadata } : {}
530
+ },
531
+ idempotencyKey: `${baseKey}:publish`
532
+ };
533
+ if (options.ifRevision !== void 0)
534
+ finalOptions.ifRevision = options.ifRevision;
535
+ return transport.request("POST", finalPath, finalOptions);
536
+ }
537
+ var DropthisEdge = class {
538
+ transport;
539
+ dropsResource;
540
+ accountResource;
541
+ apiKeysResource;
542
+ deploymentsResource;
543
+ constructor(options = {}) {
544
+ this.transport = new Transport(options);
545
+ }
546
+ get drops() {
547
+ if (!this.dropsResource)
548
+ this.dropsResource = new DropsResource(this.transport);
549
+ return this.dropsResource;
550
+ }
551
+ get account() {
552
+ if (!this.accountResource)
553
+ this.accountResource = new AccountResource(this.transport);
554
+ return this.accountResource;
555
+ }
556
+ get apiKeys() {
557
+ if (!this.apiKeysResource)
558
+ this.apiKeysResource = new ApiKeysResource(this.transport);
559
+ return this.apiKeysResource;
560
+ }
561
+ get deployments() {
562
+ if (!this.deploymentsResource)
563
+ this.deploymentsResource = new DeploymentsResource(this.transport);
564
+ return this.deploymentsResource;
565
+ }
566
+ /** Publish a NEW drop from in-memory content. */
567
+ publishInline(input, options = {}) {
568
+ return stagedInline(this.transport, input, options, "/drops");
569
+ }
570
+ /** Publish a NEW content version to an existing drop, keeping its URL. */
571
+ deployInline(dropId, input, options = {}) {
572
+ return stagedInline(
573
+ this.transport,
574
+ input,
575
+ options,
576
+ `/drops/${encodeURIComponent(dropId)}/deployments`
577
+ );
578
+ }
579
+ };
580
+ // Annotate the CommonJS export names for ESM import in node:
581
+ 0 && (module.exports = {
582
+ DropthisEdge
583
+ });
584
+ //# sourceMappingURL=edge.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/edge.ts","../src/errors.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 provides an fs-free `publishInline`/`deployInline` for\n// in-memory content (used by the dropthis MCP remote Worker and the future n8n node).\n//\n// IMPORTANT: this module must NOT import `./dropthis.js` or anything under `./publish/`,\n// which pull in `node:fs`, `node:path`, `node:crypto`, `fast-glob`, and `Buffer` and\n// cannot be bundled for Cloudflare Workers. Keep the import graph to transport +\n// resources + pure helpers only.\n\nimport { createErrorResult } from \"./errors.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 {\n\tCreateUploadSessionRequest,\n\tCreateUploadSessionResponse,\n\tDropResponse,\n\tDropthisClientOptions,\n\tDropthisResult,\n\tUploadSessionResponse,\n} from \"./types.js\";\n\n/** In-memory publish input: an HTML/text string, or raw bytes with a filename + content type. */\nexport type InlineInput =\n\t| string\n\t| { bytes: Uint8Array; filename?: string; contentType?: string };\n\nexport type PublishInlineOptions = {\n\t/** Drop title. */\n\ttitle?: string;\n\t/** Serving visibility. */\n\tvisibility?: \"public\" | \"unlisted\";\n\t/** Require a password to view (Pro). */\n\tpassword?: string | null;\n\t/** Force search engines not to index. */\n\tnoindex?: boolean | null;\n\t/** Set or clear automatic expiry (ISO 8601). */\n\texpiresAt?: string | null;\n\t/** Override the entry path/filename for string input (default index.html). */\n\tpath?: string;\n\t/** Override the detected content type for string input. */\n\tcontentType?: string;\n\t/** Custom drop metadata. */\n\tmetadata?: Record<string, unknown>;\n\t/** Idempotency key base; one is generated if omitted. */\n\tidempotencyKey?: string;\n\t/** Optimistic-concurrency revision for deployments. */\n\tifRevision?: number;\n};\n\nconst DROP_OPTION_KEYS = [\n\t\"title\",\n\t\"visibility\",\n\t\"password\",\n\t\"noindex\",\n\t\"expiresAt\",\n] as const;\n\nfunction detectStringContentType(value: string): string {\n\tconst trimmed = value.trimStart().toLowerCase();\n\tif (\n\t\ttrimmed.startsWith(\"<!doctype html\") ||\n\t\ttrimmed.startsWith(\"<html\") ||\n\t\t/^<[a-z][a-z0-9:-]*(\\s|>)/.test(trimmed)\n\t) {\n\t\treturn \"text/html\";\n\t}\n\treturn \"text/plain; charset=utf-8\";\n}\n\nfunction defaultEntry(contentType: string): string {\n\tconst media = contentType.split(\";\", 1)[0]?.trim().toLowerCase() ?? \"\";\n\treturn media === \"text/html\" ? \"index.html\" : \"index.txt\";\n}\n\nfunction normalizeInput(\n\tinput: InlineInput,\n\toptions: PublishInlineOptions,\n): { bytes: Uint8Array; path: string; contentType: string } {\n\tif (typeof input === \"string\") {\n\t\tconst contentType = options.contentType ?? detectStringContentType(input);\n\t\treturn {\n\t\t\tbytes: new TextEncoder().encode(input),\n\t\t\tpath: options.path ?? defaultEntry(contentType),\n\t\t\tcontentType,\n\t\t};\n\t}\n\treturn {\n\t\tbytes: input.bytes,\n\t\tpath: input.filename ?? options.path ?? \"index.html\",\n\t\tcontentType:\n\t\t\tinput.contentType ?? options.contentType ?? \"application/octet-stream\",\n\t};\n}\n\nfunction dropOptions(options: PublishInlineOptions): Record<string, unknown> {\n\tconst out: Record<string, unknown> = {};\n\tfor (const key of DROP_OPTION_KEYS) {\n\t\tif (options[key] !== undefined) out[key] = options[key];\n\t}\n\treturn out;\n}\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\nasync function stagedInline(\n\ttransport: Transport,\n\tinput: InlineInput,\n\toptions: PublishInlineOptions,\n\tfinalPath: string,\n): Promise<DropthisResult<DropResponse>> {\n\tconst { bytes, path, contentType } = normalizeInput(input, options);\n\tconst baseKey = options.idempotencyKey ?? `mcp-${crypto.randomUUID()}`;\n\n\tconst manifest: CreateUploadSessionRequest = {\n\t\tschemaVersion: 1,\n\t\tfiles: [{ path, contentType, sizeBytes: bytes.byteLength }],\n\t\tentry: path,\n\t};\n\tconst created = await transport.request<CreateUploadSessionResponse>(\n\t\t\"POST\",\n\t\t\"/uploads\",\n\t\t{\n\t\t\tbody: manifest,\n\t\t\tidempotencyKey: `${baseKey}:create-upload`,\n\t\t},\n\t);\n\tif (created.error) return errorResult(created);\n\n\tconst target = created.data.files[0];\n\tif (!target) {\n\t\treturn createErrorResult(\n\t\t\t\"upload_target_missing\",\n\t\t\t\"No upload target returned for the file.\",\n\t\t\tnull,\n\t\t);\n\t}\n\tif (target.upload.strategy !== \"single_put\") {\n\t\treturn createErrorResult(\n\t\t\t\"unsupported_upload_strategy\",\n\t\t\t\"Edge publishInline supports single_put uploads only; the content is too large for inline publishing.\",\n\t\t\tnull,\n\t\t);\n\t}\n\n\tconst put = await transport.putSignedUrl(\n\t\ttarget.upload.url,\n\t\tbytes,\n\t\ttarget.upload.headers,\n\t);\n\tif (put.error) return errorResult(put);\n\n\tconst completed = await transport.request<UploadSessionResponse>(\n\t\t\"POST\",\n\t\t`/uploads/${encodeURIComponent(created.data.uploadId)}/complete`,\n\t\t{ body: { files: {} }, idempotencyKey: `${baseKey}:complete-upload` },\n\t);\n\tif (completed.error) return errorResult(completed);\n\n\tconst finalOptions: Parameters<Transport[\"request\"]>[2] = {\n\t\tbody: {\n\t\t\tuploadId: created.data.uploadId,\n\t\t\toptions: dropOptions(options),\n\t\t\t...(options.metadata ? { metadata: options.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/** 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;\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 {\n\t\tif (!this.dropsResource)\n\t\t\tthis.dropsResource = new DropsResource(this.transport);\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\t/** Publish a NEW drop from in-memory content. */\n\tpublishInline(\n\t\tinput: InlineInput,\n\t\toptions: PublishInlineOptions = {},\n\t): Promise<DropthisResult<DropResponse>> {\n\t\treturn stagedInline(this.transport, input, options, \"/drops\");\n\t}\n\n\t/** Publish a NEW content version to an existing drop, keeping its URL. */\n\tdeployInline(\n\t\tdropId: string,\n\t\tinput: InlineInput,\n\t\toptions: PublishInlineOptions = {},\n\t): Promise<DropthisResult<DropResponse>> {\n\t\treturn stagedInline(\n\t\t\tthis.transport,\n\t\t\tinput,\n\t\t\toptions,\n\t\t\t`/drops/${encodeURIComponent(dropId)}/deployments`,\n\t\t);\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\tdetail?: unknown;\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} = {},\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.detail !== undefined ? { detail: extra.detail } : {}),\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},\n\t\theaders: extra.headers ?? {},\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\tDropResponse,\n\tDropthisResult,\n\tListDeploymentsParams,\n\tListDeploymentsResponse,\n} from \"../types.js\";\n\nexport class DeploymentsResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\tcreate(\n\t\tdropId: string,\n\t\tbody: Record<string, unknown>,\n\t\toptions: { idempotencyKey?: string; ifRevision?: number } = {},\n\t): Promise<DropthisResult<DropResponse>> {\n\t\tconst requestOptions: Parameters<Transport[\"request\"]>[2] = { body };\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\"POST\",\n\t\t\t`/drops/${encodeURIComponent(dropId)}/deployments`,\n\t\t\trequestOptions,\n\t\t);\n\t}\n\n\tcreateRaw(\n\t\tdropId: string,\n\t\tbody: unknown,\n\t\toptions: { idempotencyKey?: string; ifRevision?: number } = {},\n\t): Promise<DropthisResult<DropResponse>> {\n\t\tconst requestOptions: Parameters<Transport[\"request\"]>[2] = {\n\t\t\tbody,\n\t\t\tbodyCase: \"raw\",\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\"POST\",\n\t\t\t`/drops/${encodeURIComponent(dropId)}/deployments`,\n\t\t\trequestOptions,\n\t\t);\n\t}\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 { CursorPage } from \"../pagination.js\";\nimport type { Transport } from \"../transport.js\";\nimport type {\n\tDropOptions,\n\tDropResponse,\n\tDropthisResult,\n\tListDropsParams,\n\tRequestControls,\n} from \"../types.js\";\n\nexport class DropsResource {\n\tconstructor(private readonly transport: Transport) {}\n\n\tcreate(\n\t\tbody: unknown,\n\t\toptions: { idempotencyKey?: string } = {},\n\t): Promise<DropthisResult<DropResponse>> {\n\t\tconst requestOptions: Parameters<Transport[\"request\"]>[2] = { body };\n\t\tif (options.idempotencyKey)\n\t\t\trequestOptions.idempotencyKey = options.idempotencyKey;\n\t\treturn this.transport.request(\"POST\", \"/drops\", requestOptions);\n\t}\n\n\tcreateRaw(\n\t\tbody: unknown,\n\t\toptions: { idempotencyKey?: string } = {},\n\t): Promise<DropthisResult<DropResponse>> {\n\t\tconst requestOptions: Parameters<Transport[\"request\"]>[2] = {\n\t\t\tbody,\n\t\t\tbodyCase: \"raw\",\n\t\t};\n\t\tif (options.idempotencyKey)\n\t\t\trequestOptions.idempotencyKey = options.idempotencyKey;\n\t\treturn this.transport.request(\"POST\", \"/drops\", requestOptions);\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\tupdate(\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\nfunction updateBody(options: DropOptions & RequestControls): unknown {\n\tconst {\n\t\tmetadata,\n\t\tidempotencyKey: _idempotencyKey,\n\t\tifRevision: _ifRevision,\n\t\tentry: _entry,\n\t\t...dropOptions\n\t} = options;\n\treturn { options: dropOptions, metadata };\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.5.0\";\n\nexport class Transport {\n\treadonly apiKey: string | undefined;\n\treadonly baseUrl: string;\n\treadonly timeoutMs: 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\tthis.baseUrl = (resolved.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, \"\");\n\t\tthis.timeoutMs = resolved.timeoutMs ?? 30_000;\n\t\tthis.fetchImpl = resolved.fetch ?? globalThis.fetch;\n\t}\n\n\tmultipart<T>(\n\t\tmethod: string,\n\t\tpath: string,\n\t\tform: FormData,\n\t\toptions: RequestOptions = {},\n\t): Promise<DropthisResult<T>> {\n\t\treturn this.request<T>(method, path, { ...options, body: form });\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.timeoutMs);\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.error) ??\n\t\t\t\t\tstringValue(body.message) ??\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\treturn createErrorResult<T>(code, message, response.status, {\n\t\t\t\t\tdetail: body,\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":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,IAAM,aAAa;AAEZ,SAAS,cAAc,SAAyB;AACtD,SAAO,QAAQ,QAAQ,YAAY,eAAe;AACnD;AAEO,SAAS,kBACf,MACA,SACA,YACA,QASI,CAAC,GACe;AACpB,SAAO;AAAA,IACN,MAAM;AAAA,IACN,OAAO;AAAA,MACN;AAAA,MACA,SAAS,cAAc,OAAO;AAAA,MAC9B;AAAA,MACA,GAAI,MAAM,OAAO,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,MACzC,GAAI,MAAM,WAAW,SAAY,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,MAC7D,GAAI,MAAM,UAAU,SAAY,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,MAC1D,GAAI,MAAM,oBAAoB,SAC3B,EAAE,iBAAiB,MAAM,gBAAgB,IACzC,CAAC;AAAA,MACJ,GAAI,MAAM,cAAc,SAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,MACtE,GAAI,MAAM,eAAe,SACtB,EAAE,YAAY,MAAM,WAAW,IAC/B,CAAC;AAAA,MACJ,GAAI,MAAM,cAAc,SAAY,EAAE,WAAW,MAAM,UAAU,IAAI,CAAC;AAAA,IACvE;AAAA,IACA,SAAS,MAAM,WAAW,CAAC;AAAA,EAC5B;AACD;;;ACxCO,IAAM,kBAAN,MAAsB;AAAA,EAC5B,YAA6B,WAAsB;AAAtB;AAAA,EAAuB;AAAA,EAAvB;AAAA,EAE7B,MAAgD;AAC/C,WAAO,KAAK,UAAU,QAAQ,OAAO,UAAU;AAAA,EAChD;AAAA,EAEA,OAAO,OAEsC;AAC5C,WAAO,KAAK,UAAU,QAAQ,SAAS,YAAY,EAAE,MAAM,MAAM,CAAC;AAAA,EACnE;AAAA,EAEA,SAAwC;AACvC,WAAO,KAAK,UAAU,QAAQ,UAAU,UAAU;AAAA,EACnD;AACD;;;ACZO,IAAM,kBAAN,MAAsB;AAAA,EAC5B,YAA6B,WAAsB;AAAtB;AAAA,EAAuB;AAAA,EAAvB;AAAA,EAE7B,OAA4E;AAC3E,WAAO,KAAK,UAAU,QAAQ,OAAO,WAAW;AAAA,EACjD;AAAA,EAEA,OAAO,OAE4C;AAClD,WAAO,KAAK,UAAU,QAAQ,QAAQ,aAAa,EAAE,MAAM,MAAM,CAAC;AAAA,EACnE;AAAA,EAEA,OAAO,OAAsD;AAC5D,WAAO,KAAK,UAAU;AAAA,MACrB;AAAA,MACA,aAAa,mBAAmB,KAAK,CAAC;AAAA,IACvC;AAAA,EACD;AACD;;;ACjBO,IAAM,sBAAN,MAA0B;AAAA,EAChC,YAA6B,WAAsB;AAAtB;AAAA,EAAuB;AAAA,EAAvB;AAAA,EAE7B,OACC,QACA,MACA,UAA4D,CAAC,GACrB;AACxC,UAAM,iBAAsD,EAAE,KAAK;AACnE,QAAI,QAAQ;AACX,qBAAe,iBAAiB,QAAQ;AACzC,QAAI,QAAQ,eAAe;AAC1B,qBAAe,aAAa,QAAQ;AACrC,WAAO,KAAK,UAAU;AAAA,MACrB;AAAA,MACA,UAAU,mBAAmB,MAAM,CAAC;AAAA,MACpC;AAAA,IACD;AAAA,EACD;AAAA,EAEA,UACC,QACA,MACA,UAA4D,CAAC,GACrB;AACxC,UAAM,iBAAsD;AAAA,MAC3D;AAAA,MACA,UAAU;AAAA,IACX;AACA,QAAI,QAAQ;AACX,qBAAe,iBAAiB,QAAQ;AACzC,QAAI,QAAQ,eAAe;AAC1B,qBAAe,aAAa,QAAQ;AACrC,WAAO,KAAK,UAAU;AAAA,MACrB;AAAA,MACA,UAAU,mBAAmB,MAAM,CAAC;AAAA,MACpC;AAAA,IACD;AAAA,EACD;AAAA,EAEA,KACC,QACA,SAAgC,CAAC,GACkB;AACnD,WAAO,KAAK,UAAU;AAAA,MACrB;AAAA,MACA,UAAU,mBAAmB,MAAM,CAAC;AAAA,MACpC,EAAE,OAAO;AAAA,IACV;AAAA,EACD;AAAA,EAEA,IACC,QACA,cACkD;AAClD,WAAO,KAAK,UAAU;AAAA,MACrB;AAAA,MACA,UAAU,mBAAmB,MAAM,CAAC,gBAAgB,mBAAmB,YAAY,CAAC;AAAA,IACrF;AAAA,EACD;AACD;;;ACnEO,IAAM,aAAN,MAA2C;AAAA,EACxC,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACQ;AAAA,EAIjB,YAAY,OAKT;AACF,SAAK,OAAO,MAAM;AAClB,SAAK,UAAU,MAAM;AACrB,SAAK,aAAa,MAAM;AACxB,SAAK,gBAAgB,MAAM;AAAA,EAC5B;AAAA,EAEA,MAAM,kBAAkB,UAA8B,CAAC,GAAiB;AACvE,UAAM,QAAa,CAAC;AACpB,qBAAiB,QAAQ,MAAM;AAC9B,YAAM,KAAK,IAAI;AACf,UAAI,QAAQ,UAAU,UAAa,MAAM,UAAU,QAAQ,MAAO;AAAA,IACnE;AACA,WAAO;AAAA,EACR;AAAA,EAEA,QAAQ,OAAO,aAAa,IAA8B;AACzD,eAAW,QAAQ,KAAK,KAAM,OAAM;AACpC,QAAI,UAAyB;AAC7B,WAAO,QAAQ,WAAW,QAAQ,eAAe;AAChD,YAAM,OAAO,MAAM,QAAQ,cAAc;AACzC,UAAI,KAAK,MAAO;AAChB,gBAAU,KAAK;AACf,iBAAW,QAAQ,QAAQ,KAAM,OAAM;AAAA,IACxC;AAAA,EACD;AACD;;;AChCO,IAAM,gBAAN,MAAoB;AAAA,EAC1B,YAA6B,WAAsB;AAAtB;AAAA,EAAuB;AAAA,EAAvB;AAAA,EAE7B,OACC,MACA,UAAuC,CAAC,GACA;AACxC,UAAM,iBAAsD,EAAE,KAAK;AACnE,QAAI,QAAQ;AACX,qBAAe,iBAAiB,QAAQ;AACzC,WAAO,KAAK,UAAU,QAAQ,QAAQ,UAAU,cAAc;AAAA,EAC/D;AAAA,EAEA,UACC,MACA,UAAuC,CAAC,GACA;AACxC,UAAM,iBAAsD;AAAA,MAC3D;AAAA,MACA,UAAU;AAAA,IACX;AACA,QAAI,QAAQ;AACX,qBAAe,iBAAiB,QAAQ;AACzC,WAAO,KAAK,UAAU,QAAQ,QAAQ,UAAU,cAAc;AAAA,EAC/D;AAAA,EAEA,MAAM,KACL,SAA0B,CAAC,GACyB;AACpD,UAAM,SAAS,MAAM,KAAK,UAAU,QAGjC,OAAO,UAAU;AAAA,MACnB;AAAA,IACD,CAAC;AACD,QAAI,OAAO,MAAO,QAAO;AACzB,UAAM,OAAO,IAAI,WAAyB;AAAA,MACzC,MAAM,OAAO,KAAK;AAAA,MAClB,YAAY,OAAO,KAAK;AAAA,MACxB,SAAS,OAAO,KAAK,eAAe;AAAA,MACpC,eAAe,OAAO,KAAK,aACxB,MAAM,KAAK,KAAK,EAAE,GAAG,QAAQ,QAAQ,OAAO,KAAK,WAAW,CAAC,IAC7D;AAAA,IACJ,CAAC;AACD,WAAO,EAAE,MAAM,MAAM,OAAO,MAAM,SAAS,OAAO,QAAQ;AAAA,EAC3D;AAAA,EAEA,IAAI,QAAuD;AAC1D,WAAO,KAAK,UAAU;AAAA,MACrB;AAAA,MACA,UAAU,mBAAmB,MAAM,CAAC;AAAA,IACrC;AAAA,EACD;AAAA,EAEA,OACC,QACA,UAAyC,CAAC,GACF;AACxC,UAAM,iBAAsD;AAAA,MAC3D,MAAM,WAAW,OAAO;AAAA,IACzB;AACA,QAAI,QAAQ;AACX,qBAAe,iBAAiB,QAAQ;AACzC,QAAI,QAAQ,eAAe;AAC1B,qBAAe,aAAa,QAAQ;AACrC,WAAO,KAAK,UAAU;AAAA,MACrB;AAAA,MACA,UAAU,mBAAmB,MAAM,CAAC;AAAA,MACpC;AAAA,IACD;AAAA,EACD;AAAA,EAEA,OAAO,QAA+C;AACrD,WAAO,KAAK,UAAU;AAAA,MACrB;AAAA,MACA,UAAU,mBAAmB,MAAM,CAAC;AAAA,IACrC;AAAA,EACD;AACD;AAEA,SAAS,WAAW,SAAiD;AACpE,QAAM;AAAA,IACL;AAAA,IACA,gBAAgB;AAAA,IAChB,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,GAAGA;AAAA,EACJ,IAAI;AACJ,SAAO,EAAE,SAASA,cAAa,SAAS;AACzC;;;ACnGO,SAAS,WAAW,KAAqB;AAC/C,SAAO,IAAI,QAAQ,aAAa,CAAC,GAAG,SAAiB,KAAK,YAAY,CAAC;AACxE;AAEO,SAAS,WAAW,KAAqB;AAC/C,SAAO,IAAI,QAAQ,UAAU,CAAC,SAAS,IAAI,KAAK,YAAY,CAAC,EAAE;AAChE;AAEA,IAAM,mBAAmB,oBAAI,IAAI,CAAC,UAAU,CAAC;AAEtC,SAAS,YAAY,OAAyB;AACpD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,WAAW;AACtD,MAAI,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO,OAAO;AAAA,MACb,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM;AAAA,QAC1C,WAAW,GAAG;AAAA,QACd,iBAAiB,IAAI,GAAG,IAAI,OAAO,YAAY,IAAI;AAAA,MACpD,CAAC;AAAA,IACF;AAAA,EACD;AACA,SAAO;AACR;AAEO,SAAS,YAAY,OAAyB;AACpD,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,WAAW;AACtD,MAAI,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO,OAAO;AAAA,MACb,OAAO,QAAQ,KAAK,EAClB,OAAO,CAAC,CAAC,EAAE,IAAI,MAAM,SAAS,MAAS,EACvC,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM;AAAA,QACrB,WAAW,GAAG;AAAA,QACd,iBAAiB,IAAI,GAAG,IAAI,OAAO,YAAY,IAAI;AAAA,MACpD,CAAC;AAAA,IACH;AAAA,EACD;AACA,SAAO;AACR;;;AC5BA,IAAM,mBAAmB;AACzB,IAAM,cAAc;AAEb,IAAM,YAAN,MAAgB;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,UAA0C,CAAC,GAAG;AACzD,UAAM,WACL,OAAO,YAAY,WAAW,EAAE,QAAQ,QAAQ,IAAI;AACrD,SAAK,SACJ,SAAS,WACR,OAAO,YAAY,cACjB,QAAQ,KAAK,mBACb;AACJ,SAAK,WAAW,SAAS,WAAW,kBAAkB,QAAQ,QAAQ,EAAE;AACxE,SAAK,YAAY,SAAS,aAAa;AACvC,SAAK,YAAY,SAAS,SAAS,WAAW;AAAA,EAC/C;AAAA,EAEA,UACC,QACA,MACA,MACA,UAA0B,CAAC,GACE;AAC7B,WAAO,KAAK,QAAW,QAAQ,MAAM,EAAE,GAAG,SAAS,MAAM,KAAK,CAAC;AAAA,EAChE;AAAA,EAEA,MAAM,aACL,KACA,MACA,SACmD;AACnD,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,KAAK,SAAS;AACnE,QAAI;AACH,YAAM,UAA6C;AAAA,QAClD,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA,QAAQ,WAAW;AAAA,MACpB;AACA,UAAI,gBAAgB,eAAgB,SAAQ,SAAS;AACrD,YAAM,WAAW,MAAM,KAAK,UAAU,KAAK,OAAO;AAClD,YAAM,kBAAkB,gBAAgB,SAAS,OAAO;AACxD,UAAI,CAAC,SAAS,IAAI;AACjB,cAAM,OAAO,MAAM,SAAS,KAAK;AACjC,eAAO;AAAA,UACN,iBAAiB,SAAS,MAAM;AAAA,UAChC,QAAQ,SAAS;AAAA,UACjB,SAAS;AAAA,UACT,EAAE,SAAS,gBAAgB;AAAA,QAC5B;AAAA,MACD;AACA,aAAO;AAAA,QACN,MAAM;AAAA,UACL,MAAM,SAAS,QAAQ,IAAI,MAAM,KAAK,gBAAgB,QAAQ;AAAA,QAC/D;AAAA,QACA,OAAO;AAAA,QACP,SAAS;AAAA,MACV;AAAA,IACD,SAAS,OAAO;AACf,YAAM,UACL,iBAAiB,SAAS,MAAM,SAAS,eACtC,sBACA,iBAAiB,QAChB,MAAM,UACN;AACL,aAAO;AAAA,QACN,iBAAiB,SAAS,MAAM,SAAS,eACtC,YACA;AAAA,QACH;AAAA,QACA;AAAA,MACD;AAAA,IACD,UAAE;AACD,mBAAa,OAAO;AAAA,IACrB;AAAA,EACD;AAAA,EAEA,MAAM,QACL,QACA,MACA,UAII,CAAC,GACwB;AAC7B,UAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,QAAI,iBAAiB,CAAC,KAAK,QAAQ;AAClC,aAAO;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,MACD;AAAA,IACD;AAEA,UAAM,UAAkC;AAAA,MACvC,cAAc,iBAAiB,WAAW;AAAA,IAC3C;AACA,QAAI,iBAAiB,KAAK;AACzB,cAAQ,gBAAgB,UAAU,KAAK,MAAM;AAC9C,QAAI,QAAQ;AACX,cAAQ,iBAAiB,IAAI,QAAQ;AACtC,QAAI,QAAQ,eAAe;AAC1B,cAAQ,aAAa,IAAI,OAAO,QAAQ,UAAU;AACnD,QAAI,QAAQ,SAAS,UAAa,EAAE,QAAQ,gBAAgB;AAC3D,cAAQ,cAAc,IAAI;AAE3B,UAAM,MAAM,IAAI,IAAI,GAAG,KAAK,OAAO,GAAG,IAAI,EAAE;AAC5C,UAAM,aACL,QAAQ,aAAa,QAClB,QAAQ,SACP,YAAY,QAAQ,UAAU,CAAC,CAAC;AACrC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,cAAc,CAAC,CAAC,GAAG;AAC5D,UAAI,UAAU,UAAa,UAAU;AACpC,YAAI,aAAa,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,IACzC;AAEA,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,UAAU;AAAA,MACf,MAAM,WAAW,MAAM;AAAA,MACvB,QAAQ,aAAa,KAAK;AAAA,IAC3B;AACA,QAAI;AACH,YAAM,UAAuB;AAAA,QAC5B;AAAA,QACA;AAAA,QACA,QAAQ,WAAW;AAAA,MACpB;AACA,UAAI,QAAQ,gBAAgB,UAAU;AACrC,gBAAQ,OAAO,QAAQ;AAAA,MACxB,WAAW,QAAQ,SAAS,QAAW;AACtC,cAAM,WACL,QAAQ,aAAa,QAAQ,QAAQ,OAAO,YAAY,QAAQ,IAAI;AACrE,gBAAQ,OAAO,KAAK,UAAU,QAAQ;AAAA,MACvC;AAEA,YAAM,WAAW,MAAM,KAAK,UAAU,IAAI,SAAS,GAAG,OAAO;AAC7D,YAAM,kBAAkB,gBAAgB,SAAS,OAAO;AACxD,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,YAAM,SAAS,UAAU,IAAI;AAC7B,UAAI,CAAC,SAAS,IAAI;AACjB,cAAM,OACL,UAAU,OAAO,WAAW,WACxB,SACD,CAAC;AACL,cAAM,UACL,YAAY,KAAK,MAAM,KACvB,YAAY,KAAK,KAAK,KACtB,YAAY,KAAK,OAAO,KACxB,SAAS;AACV,cAAM,OACL,YAAY,KAAK,IAAI,KACrB,YAAY,KAAK,UAAU,KAC3B,QAAQ,SAAS,MAAM;AACxB,cAAM,kBAAkB,YAAY,KAAK,gBAAgB;AACzD,eAAO,kBAAqB,MAAM,SAAS,SAAS,QAAQ;AAAA,UAC3D,QAAQ;AAAA,UACR,OAAO,YAAY,KAAK,KAAK;AAAA,UAC7B,GAAI,oBAAoB,SAAY,EAAE,gBAAgB,IAAI,CAAC;AAAA,UAC3D,WACC,YAAY,KAAK,UAAU,KAC3B,gBAAgB,cAAc,KAC9B;AAAA,UACD,YAAY,YAAY,KAAK,UAAU;AAAA,UACvC,WAAW,aAAa,KAAK,SAAS;AAAA,UACtC,SAAS;AAAA,QACV,CAAC;AAAA,MACF;AACA,aAAO;AAAA,QACN,MAAM,YAAY,MAAM;AAAA,QACxB,OAAO;AAAA,QACP,SAAS;AAAA,MACV;AAAA,IACD,SAAS,OAAO;AACf,YAAM,UACL,iBAAiB,SAAS,MAAM,SAAS,eACtC,sBACA,iBAAiB,QAChB,MAAM,UACN;AACL,aAAO;AAAA,QACN,iBAAiB,SAAS,MAAM,SAAS,eACtC,YACA;AAAA,QACH;AAAA,QACA;AAAA,MACD;AAAA,IACD,UAAE;AACD,mBAAa,OAAO;AAAA,IACrB;AAAA,EACD;AACD;AAEA,SAAS,gBAAgB,SAA0C;AAClE,QAAM,SAAiC,CAAC;AACxC,UAAQ,QAAQ,CAAC,OAAO,QAAQ;AAC/B,WAAO,IAAI,YAAY,CAAC,IAAI;AAAA,EAC7B,CAAC;AACD,SAAO;AACR;AAEA,SAAS,UAAU,MAAuB;AACzC,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI;AACH,WAAO,KAAK,MAAM,IAAI;AAAA,EACvB,QAAQ;AACP,WAAO;AAAA,EACR;AACD;AAEA,SAAS,YAAY,OAA+B;AACnD,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC5C;AAEA,SAAS,YAAY,OAAoC;AACxD,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC5C;AAEA,SAAS,aAAa,OAAgC;AACrD,SAAO,OAAO,UAAU,YAAY,QAAQ;AAC7C;;;ARtLA,IAAM,mBAAmB;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAEA,SAAS,wBAAwB,OAAuB;AACvD,QAAM,UAAU,MAAM,UAAU,EAAE,YAAY;AAC9C,MACC,QAAQ,WAAW,gBAAgB,KACnC,QAAQ,WAAW,OAAO,KAC1B,2BAA2B,KAAK,OAAO,GACtC;AACD,WAAO;AAAA,EACR;AACA,SAAO;AACR;AAEA,SAAS,aAAa,aAA6B;AAClD,QAAM,QAAQ,YAAY,MAAM,KAAK,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,YAAY,KAAK;AACpE,SAAO,UAAU,cAAc,eAAe;AAC/C;AAEA,SAAS,eACR,OACA,SAC2D;AAC3D,MAAI,OAAO,UAAU,UAAU;AAC9B,UAAM,cAAc,QAAQ,eAAe,wBAAwB,KAAK;AACxE,WAAO;AAAA,MACN,OAAO,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,MACrC,MAAM,QAAQ,QAAQ,aAAa,WAAW;AAAA,MAC9C;AAAA,IACD;AAAA,EACD;AACA,SAAO;AAAA,IACN,OAAO,MAAM;AAAA,IACb,MAAM,MAAM,YAAY,QAAQ,QAAQ;AAAA,IACxC,aACC,MAAM,eAAe,QAAQ,eAAe;AAAA,EAC9C;AACD;AAEA,SAAS,YAAY,SAAwD;AAC5E,QAAM,MAA+B,CAAC;AACtC,aAAW,OAAO,kBAAkB;AACnC,QAAI,QAAQ,GAAG,MAAM,OAAW,KAAI,GAAG,IAAI,QAAQ,GAAG;AAAA,EACvD;AACA,SAAO;AACR;AAEA,SAAS,YAAe,QAAoD;AAC3E,MAAI,CAAC,OAAO,MAAO,OAAM,IAAI,MAAM,0BAA0B;AAC7D,SAAO,EAAE,MAAM,MAAM,OAAO,OAAO,OAAO,SAAS,OAAO,QAAQ;AACnE;AAEA,eAAe,aACd,WACA,OACA,SACA,WACwC;AACxC,QAAM,EAAE,OAAO,MAAM,YAAY,IAAI,eAAe,OAAO,OAAO;AAClE,QAAM,UAAU,QAAQ,kBAAkB,OAAO,OAAO,WAAW,CAAC;AAEpE,QAAM,WAAuC;AAAA,IAC5C,eAAe;AAAA,IACf,OAAO,CAAC,EAAE,MAAM,aAAa,WAAW,MAAM,WAAW,CAAC;AAAA,IAC1D,OAAO;AAAA,EACR;AACA,QAAM,UAAU,MAAM,UAAU;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,MACC,MAAM;AAAA,MACN,gBAAgB,GAAG,OAAO;AAAA,IAC3B;AAAA,EACD;AACA,MAAI,QAAQ,MAAO,QAAO,YAAY,OAAO;AAE7C,QAAM,SAAS,QAAQ,KAAK,MAAM,CAAC;AACnC,MAAI,CAAC,QAAQ;AACZ,WAAO;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AACA,MAAI,OAAO,OAAO,aAAa,cAAc;AAC5C,WAAO;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IACD;AAAA,EACD;AAEA,QAAM,MAAM,MAAM,UAAU;AAAA,IAC3B,OAAO,OAAO;AAAA,IACd;AAAA,IACA,OAAO,OAAO;AAAA,EACf;AACA,MAAI,IAAI,MAAO,QAAO,YAAY,GAAG;AAErC,QAAM,YAAY,MAAM,UAAU;AAAA,IACjC;AAAA,IACA,YAAY,mBAAmB,QAAQ,KAAK,QAAQ,CAAC;AAAA,IACrD,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,gBAAgB,GAAG,OAAO,mBAAmB;AAAA,EACrE;AACA,MAAI,UAAU,MAAO,QAAO,YAAY,SAAS;AAEjD,QAAM,eAAoD;AAAA,IACzD,MAAM;AAAA,MACL,UAAU,QAAQ,KAAK;AAAA,MACvB,SAAS,YAAY,OAAO;AAAA,MAC5B,GAAI,QAAQ,WAAW,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,IAC1D;AAAA,IACA,gBAAgB,GAAG,OAAO;AAAA,EAC3B;AACA,MAAI,QAAQ,eAAe;AAC1B,iBAAa,aAAa,QAAQ;AACnC,SAAO,UAAU,QAAsB,QAAQ,WAAW,YAAY;AACvE;AAGO,IAAM,eAAN,MAAmB;AAAA,EACR;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAER,YAAY,UAA0C,CAAC,GAAG;AACzD,SAAK,YAAY,IAAI,UAAU,OAAO;AAAA,EACvC;AAAA,EAEA,IAAI,QAAuB;AAC1B,QAAI,CAAC,KAAK;AACT,WAAK,gBAAgB,IAAI,cAAc,KAAK,SAAS;AACtD,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,IAAI,UAA2B;AAC9B,QAAI,CAAC,KAAK;AACT,WAAK,kBAAkB,IAAI,gBAAgB,KAAK,SAAS;AAC1D,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,IAAI,UAA2B;AAC9B,QAAI,CAAC,KAAK;AACT,WAAK,kBAAkB,IAAI,gBAAgB,KAAK,SAAS;AAC1D,WAAO,KAAK;AAAA,EACb;AAAA,EAEA,IAAI,cAAmC;AACtC,QAAI,CAAC,KAAK;AACT,WAAK,sBAAsB,IAAI,oBAAoB,KAAK,SAAS;AAClE,WAAO,KAAK;AAAA,EACb;AAAA;AAAA,EAGA,cACC,OACA,UAAgC,CAAC,GACO;AACxC,WAAO,aAAa,KAAK,WAAW,OAAO,SAAS,QAAQ;AAAA,EAC7D;AAAA;AAAA,EAGA,aACC,QACA,OACA,UAAgC,CAAC,GACO;AACxC,WAAO;AAAA,MACN,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA,UAAU,mBAAmB,MAAM,CAAC;AAAA,IACrC;AAAA,EACD;AACD;","names":["dropOptions"]}