@dropthis/cli 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -37,16 +37,358 @@ function createErrorResult(code, message, statusCode, extra = {}) {
37
37
  message: redactSecrets(message),
38
38
  statusCode,
39
39
  ...extra.type ? { type: extra.type } : {},
40
+ ...extra.title !== void 0 ? { title: extra.title } : {},
40
41
  ...extra.detail !== void 0 ? { detail: extra.detail } : {},
42
+ ...extra.instance !== void 0 ? { instance: extra.instance } : {},
41
43
  ...extra.param !== void 0 ? { param: extra.param } : {},
42
44
  ...extra.currentRevision !== void 0 ? { currentRevision: extra.currentRevision } : {},
43
45
  ...extra.requestId !== void 0 ? { requestId: extra.requestId } : {},
44
46
  ...extra.suggestion !== void 0 ? { suggestion: extra.suggestion } : {},
45
- ...extra.retryable !== void 0 ? { retryable: extra.retryable } : {}
47
+ ...extra.retryable !== void 0 ? { retryable: extra.retryable } : {},
48
+ ...extra.body !== void 0 ? { body: extra.body } : {}
46
49
  },
47
50
  headers: extra.headers ?? {}
48
51
  };
49
52
  }
53
+ var PublishInputError = class extends Error {
54
+ constructor(code, message, param, suggestion) {
55
+ super(message);
56
+ this.code = code;
57
+ this.param = param;
58
+ this.suggestion = suggestion;
59
+ this.name = "PublishInputError";
60
+ }
61
+ code;
62
+ param;
63
+ suggestion;
64
+ };
65
+ function toErrorResult(err) {
66
+ if (err instanceof PublishInputError)
67
+ return createErrorResult(err.code, err.message, null, {
68
+ param: err.param ?? null,
69
+ suggestion: err.suggestion ?? null
70
+ });
71
+ return createErrorResult(
72
+ "sdk_error",
73
+ err instanceof Error ? err.message : "Unknown SDK error",
74
+ null
75
+ );
76
+ }
77
+
78
+ // src/publish/detect.ts
79
+ function isHttpUrl(value) {
80
+ try {
81
+ const url = new URL(value);
82
+ return url.protocol === "http:" || url.protocol === "https:";
83
+ } catch {
84
+ return false;
85
+ }
86
+ }
87
+ function containsHtmlTag(value) {
88
+ return /<[a-z!/][^>]*>/i.test(value);
89
+ }
90
+ function contentTypeForString(value, override) {
91
+ if (override) return override;
92
+ return containsHtmlTag(value) ? "text/html" : "text/plain; charset=utf-8";
93
+ }
94
+ function detectBytesContentType(bytes) {
95
+ const text = new TextDecoder("utf-8", { fatal: false }).decode(bytes);
96
+ if (text.includes("\uFFFD")) return "application/octet-stream";
97
+ return containsHtmlTag(text) ? "text/html" : "text/plain; charset=utf-8";
98
+ }
99
+ function entryForContentType(contentType) {
100
+ const m = contentType.toLowerCase().split(";", 1)[0]?.trim() ?? "";
101
+ if (m === "text/html" || m === "application/xhtml+xml") return "index.html";
102
+ if (m === "application/json") return "index.json";
103
+ if (m === "text/css") return "index.css";
104
+ if (m === "text/javascript" || m === "application/javascript")
105
+ return "index.js";
106
+ if (m.startsWith("text/")) return "index.txt";
107
+ return "index";
108
+ }
109
+
110
+ // src/publish/paths.ts
111
+ function normalizeManifestPath(path) {
112
+ return path.replace(/\\/g, "/").replace(/^\.\//, "");
113
+ }
114
+ function assertValidManifestPath(path) {
115
+ if (path.includes("\\"))
116
+ throw new PublishInputError(
117
+ "invalid_path",
118
+ `Manifest path must use "/": "${path}".`,
119
+ path
120
+ );
121
+ const p = normalizeManifestPath(path);
122
+ if (p === "")
123
+ throw new PublishInputError(
124
+ "invalid_path",
125
+ "Manifest path must not be empty.",
126
+ path
127
+ );
128
+ if (p.startsWith("/"))
129
+ throw new PublishInputError(
130
+ "invalid_path",
131
+ `Manifest path must be relative: "${path}".`,
132
+ path
133
+ );
134
+ if (p.startsWith("~"))
135
+ throw new PublishInputError(
136
+ "invalid_path",
137
+ `Manifest path must not start with "~": "${path}".`,
138
+ path
139
+ );
140
+ if (p.split("/").includes(".."))
141
+ throw new PublishInputError(
142
+ "invalid_path",
143
+ `Manifest path must not contain "..": "${path}".`,
144
+ path
145
+ );
146
+ }
147
+ function assertNoDuplicatePaths(paths) {
148
+ const seen = /* @__PURE__ */ new Set();
149
+ for (const raw of paths) {
150
+ const p = normalizeManifestPath(raw);
151
+ if (seen.has(p))
152
+ throw new PublishInputError(
153
+ "duplicate_path",
154
+ `Duplicate file path after normalization: "${p}".`,
155
+ p,
156
+ "Give each file a unique path; basename mapping for string[] can collide."
157
+ );
158
+ seen.add(p);
159
+ }
160
+ }
161
+ function assertNonEmptyBundle(paths) {
162
+ if (paths.length === 0)
163
+ throw new PublishInputError(
164
+ "empty_bundle",
165
+ "Nothing to publish: the bundle has no files.",
166
+ void 0,
167
+ "Pass at least one file, or a directory that contains files."
168
+ );
169
+ }
170
+
171
+ // src/publish/core.ts
172
+ var VALID_VISIBILITIES = ["public", "unlisted"];
173
+ var MAX_TITLE_LENGTH = 500;
174
+ function validatePublishOptions(options) {
175
+ if (options.title !== void 0 && options.title !== null && options.title.length > MAX_TITLE_LENGTH) {
176
+ throw new Error(`Title must be ${MAX_TITLE_LENGTH} characters or less.`);
177
+ }
178
+ if (options.visibility !== void 0 && options.visibility !== null) {
179
+ if (!VALID_VISIBILITIES.includes(options.visibility)) {
180
+ throw new Error(
181
+ `Invalid visibility "${options.visibility}". Use "public" or "unlisted".`
182
+ );
183
+ }
184
+ }
185
+ if (options.expiresAt !== void 0 && options.expiresAt !== null) {
186
+ if (options.expiresAt instanceof Date) {
187
+ if (Number.isNaN(options.expiresAt.getTime())) {
188
+ throw new Error("Invalid expiresAt date.");
189
+ }
190
+ } else if (typeof options.expiresAt === "string") {
191
+ const parsed = new Date(options.expiresAt);
192
+ if (Number.isNaN(parsed.getTime())) {
193
+ throw new Error("Invalid expiresAt date.");
194
+ }
195
+ }
196
+ }
197
+ }
198
+ function optionsBody(options) {
199
+ validatePublishOptions(options);
200
+ return {
201
+ title: options.title,
202
+ visibility: options.visibility,
203
+ password: options.password,
204
+ noindex: options.noindex,
205
+ expiresAt: options.expiresAt instanceof Date ? options.expiresAt.toISOString() : options.expiresAt
206
+ };
207
+ }
208
+ function buildStagedRequest(files, options, entry) {
209
+ assertNonEmptyBundle(files.map((f) => f.path));
210
+ const normalizedPaths = files.map((f) => normalizeManifestPath(f.path));
211
+ assertNoDuplicatePaths(normalizedPaths);
212
+ const manifestFiles = files.map((file) => ({
213
+ path: normalizeManifestPath(file.path),
214
+ contentType: file.contentType,
215
+ sizeBytes: file.sizeBytes,
216
+ ...file.checksumSha256 ? { checksumSha256: file.checksumSha256 } : {}
217
+ }));
218
+ const resolvedEntry = entry ?? options.entry;
219
+ if (resolvedEntry !== void 0) assertValidManifestPath(resolvedEntry);
220
+ const manifest = {
221
+ schemaVersion: 1,
222
+ files: manifestFiles,
223
+ ...resolvedEntry ? { entry: resolvedEntry } : {}
224
+ };
225
+ const prepared = {
226
+ kind: "staged",
227
+ manifest,
228
+ files,
229
+ options: optionsBody(options)
230
+ };
231
+ if (options.metadata) prepared.metadata = options.metadata;
232
+ return prepared;
233
+ }
234
+ function buildSourceRequest(sourceUrl, options) {
235
+ if (!isHttpUrl(sourceUrl)) {
236
+ throw new PublishInputError(
237
+ "invalid_source_url",
238
+ "source_url must be an http(s) URL.",
239
+ sourceUrl,
240
+ "Fetch the content first, then pass it as content/files."
241
+ );
242
+ }
243
+ const prepared = {
244
+ kind: "source",
245
+ sourceUrl,
246
+ options: optionsBody(options)
247
+ };
248
+ if (options.metadata) prepared.metadata = options.metadata;
249
+ return prepared;
250
+ }
251
+ function decodeBase64(value) {
252
+ const binary = atob(value);
253
+ return Uint8Array.from(binary, (c) => c.charCodeAt(0));
254
+ }
255
+ function fileBytes(file) {
256
+ if (file.content !== void 0) return new TextEncoder().encode(file.content);
257
+ if (file.contentBase64 !== void 0) return decodeBase64(file.contentBase64);
258
+ if (file.bytes !== void 0) return file.bytes;
259
+ throw new PublishInputError(
260
+ "missing_file_bytes",
261
+ `File "${file.path}" is missing content bytes.`,
262
+ file.path,
263
+ "Provide one of content, contentBase64, or bytes."
264
+ );
265
+ }
266
+ function singleStagedFile(path, contentType, bytes, options) {
267
+ return buildStagedRequest(
268
+ [
269
+ {
270
+ path,
271
+ contentType,
272
+ sizeBytes: bytes.byteLength,
273
+ getBody: async () => bytes
274
+ }
275
+ ],
276
+ options
277
+ );
278
+ }
279
+ async function resolveInMemory(input, options = {}) {
280
+ if (input instanceof URL) {
281
+ return buildSourceRequest(input.toString(), options);
282
+ }
283
+ if (typeof input === "string") {
284
+ if (isHttpUrl(input)) return buildSourceRequest(input, options);
285
+ const contentType = contentTypeForString(input, options.contentType);
286
+ if (options.path !== void 0) assertValidManifestPath(options.path);
287
+ const path = options.path ?? entryForContentType(contentType);
288
+ const bytes = new TextEncoder().encode(input);
289
+ return singleStagedFile(path, contentType, bytes, options);
290
+ }
291
+ if (input instanceof Uint8Array) {
292
+ const contentType = options.contentType ?? detectBytesContentType(input);
293
+ if (options.path !== void 0) assertValidManifestPath(options.path);
294
+ const path = options.path ?? entryForContentType(contentType);
295
+ return singleStagedFile(path, contentType, input, options);
296
+ }
297
+ if (input.kind === "content") {
298
+ const contentType = input.contentType ?? options.contentType ?? "text/html";
299
+ if (input.path !== void 0) assertValidManifestPath(input.path);
300
+ if (options.path !== void 0) assertValidManifestPath(options.path);
301
+ const path = input.path ?? options.path ?? entryForContentType(contentType);
302
+ const bytes = new TextEncoder().encode(input.content);
303
+ return singleStagedFile(path, contentType, bytes, options);
304
+ }
305
+ if (input.kind === "source_url") {
306
+ return buildSourceRequest(input.sourceUrl, options);
307
+ }
308
+ const files = input.files.map((file) => {
309
+ assertValidManifestPath(file.path);
310
+ const bytes = fileBytes(file);
311
+ const contentType = file.contentType ?? detectBytesContentType(bytes);
312
+ return {
313
+ path: file.path,
314
+ contentType,
315
+ sizeBytes: bytes.byteLength,
316
+ getBody: async () => bytes
317
+ };
318
+ });
319
+ return buildStagedRequest(files, options, input.entry);
320
+ }
321
+ function errorResult(result) {
322
+ if (!result.error) throw new Error("Expected an error result");
323
+ return { data: null, error: result.error, headers: result.headers };
324
+ }
325
+ async function publishStaged(transport, prepared, finalPath, options = {}) {
326
+ const baseKey = options.idempotencyKey ?? `sdk-${crypto.randomUUID()}`;
327
+ const createResult = await transport.request(
328
+ "POST",
329
+ "/uploads",
330
+ {
331
+ body: prepared.manifest,
332
+ idempotencyKey: `${baseKey}:create-upload`
333
+ }
334
+ );
335
+ if (createResult.error) return errorResult(createResult);
336
+ for (const file of prepared.files) {
337
+ const target = createResult.data.files.find((f) => f.path === file.path);
338
+ if (!target) {
339
+ return createErrorResult(
340
+ "upload_target_missing",
341
+ `Upload target missing for ${file.path}`,
342
+ null
343
+ );
344
+ }
345
+ if (target.upload.strategy !== "single_put") {
346
+ return createErrorResult(
347
+ "unsupported_upload_strategy",
348
+ `Unsupported upload strategy "${target.upload.strategy}" for ${file.path}. This SDK uploads via single PUT only.`,
349
+ null
350
+ );
351
+ }
352
+ const put = await transport.putSignedUrl(
353
+ target.upload.url,
354
+ await file.getBody(),
355
+ target.upload.headers
356
+ );
357
+ if (put.error) return errorResult(put);
358
+ }
359
+ const completeResult = await transport.request(
360
+ "POST",
361
+ `/uploads/${encodeURIComponent(createResult.data.uploadId)}/complete`,
362
+ {
363
+ body: { files: {} },
364
+ idempotencyKey: `${baseKey}:complete-upload`
365
+ }
366
+ );
367
+ if (completeResult.error) return errorResult(completeResult);
368
+ const finalOptions = {
369
+ body: {
370
+ uploadId: createResult.data.uploadId,
371
+ options: prepared.options,
372
+ ...prepared.metadata ? { metadata: prepared.metadata } : {}
373
+ },
374
+ idempotencyKey: `${baseKey}:publish`
375
+ };
376
+ if (options.ifRevision !== void 0)
377
+ finalOptions.ifRevision = options.ifRevision;
378
+ return transport.request("POST", finalPath, finalOptions);
379
+ }
380
+ async function publishSource(transport, prepared, finalPath, options = {}) {
381
+ const baseKey = options.idempotencyKey ?? `sdk-${crypto.randomUUID()}`;
382
+ return transport.request("POST", finalPath, {
383
+ body: {
384
+ sourceUrl: prepared.sourceUrl,
385
+ options: prepared.options,
386
+ ...prepared.metadata ? { metadata: prepared.metadata } : {}
387
+ },
388
+ idempotencyKey: `${baseKey}:publish`,
389
+ ...options.ifRevision !== void 0 ? { ifRevision: options.ifRevision } : {}
390
+ });
391
+ }
50
392
 
51
393
  // src/resources/account.ts
52
394
  var AccountResource = class {
@@ -91,33 +433,6 @@ var DeploymentsResource = class {
91
433
  this.transport = transport;
92
434
  }
93
435
  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
436
  list(dropId, params = {}) {
122
437
  return this.transport.request(
123
438
  "GET",
@@ -172,21 +487,6 @@ var DropsResource = class {
172
487
  this.transport = transport;
173
488
  }
174
489
  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
490
  async list(params = {}) {
191
491
  const result = await this.transport.request("GET", "/drops", {
192
492
  params
@@ -227,15 +527,22 @@ var DropsResource = class {
227
527
  );
228
528
  }
229
529
  };
530
+ var SETTINGS = [
531
+ "title",
532
+ "visibility",
533
+ "password",
534
+ "noindex",
535
+ "expiresAt",
536
+ "slug"
537
+ ];
230
538
  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 };
539
+ const out = {};
540
+ for (const key of SETTINGS)
541
+ if (options[key] !== void 0) out[key] = options[key];
542
+ return {
543
+ options: out,
544
+ ...options.metadata !== void 0 ? { metadata: options.metadata } : {}
545
+ };
239
546
  }
240
547
 
241
548
  // src/case.ts
@@ -273,25 +580,24 @@ function toSnakeCase(value) {
273
580
 
274
581
  // src/transport.ts
275
582
  var DEFAULT_BASE_URL = "https://api.dropthis.app";
276
- var SDK_VERSION = "0.5.0";
583
+ var SDK_VERSION = "0.6.0";
277
584
  var Transport = class {
278
585
  apiKey;
279
586
  baseUrl;
280
587
  timeoutMs;
588
+ uploadTimeoutMs;
281
589
  fetchImpl;
282
590
  constructor(options = {}) {
283
591
  const resolved = typeof options === "string" ? { apiKey: options } : options;
284
592
  this.apiKey = resolved.apiKey ?? (typeof process !== "undefined" ? process.env?.DROPTHIS_API_KEY : void 0);
285
593
  this.baseUrl = (resolved.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
286
594
  this.timeoutMs = resolved.timeoutMs ?? 3e4;
595
+ this.uploadTimeoutMs = resolved.uploadTimeoutMs ?? 12e4;
287
596
  this.fetchImpl = resolved.fetch ?? globalThis.fetch;
288
597
  }
289
- multipart(method, path, form, options = {}) {
290
- return this.request(method, path, { ...options, body: form });
291
- }
292
598
  async putSignedUrl(url, body, headers) {
293
599
  const controller = new AbortController();
294
- const timeout = setTimeout(() => controller.abort(), this.timeoutMs);
600
+ const timeout = setTimeout(() => controller.abort(), this.uploadTimeoutMs);
295
601
  try {
296
602
  const request = {
297
603
  method: "PUT",
@@ -346,7 +652,7 @@ var Transport = class {
346
652
  if (options.idempotencyKey)
347
653
  headers["idempotency-key"] = options.idempotencyKey;
348
654
  if (options.ifRevision !== void 0)
349
- headers["If-Revision"] = String(options.ifRevision);
655
+ headers["if-revision"] = String(options.ifRevision);
350
656
  if (options.body !== void 0 && !(options.body instanceof FormData))
351
657
  headers["content-type"] = "application/json";
352
658
  const url = new URL(`${this.baseUrl}${path}`);
@@ -378,11 +684,18 @@ var Transport = class {
378
684
  const parsed = parseJson(text);
379
685
  if (!response.ok) {
380
686
  const body = parsed && typeof parsed === "object" ? parsed : {};
381
- const message = stringValue(body.detail) ?? stringValue(body.error) ?? stringValue(body.message) ?? response.statusText;
687
+ const message = stringValue(body.detail) ?? stringValue(body.title) ?? response.statusText;
382
688
  const code = stringValue(body.code) ?? stringValue(body.error_code) ?? `http_${response.status}`;
383
689
  const currentRevision = numberValue(body.current_revision);
690
+ const type = stringValue(body.type);
691
+ const title = stringValue(body.title);
692
+ const instance = stringValue(body.instance);
384
693
  return createErrorResult(code, message, response.status, {
385
- detail: body,
694
+ body,
695
+ ...type !== null ? { type } : {},
696
+ ...title !== null ? { title } : {},
697
+ ...instance !== null ? { instance } : {},
698
+ detail: stringValue(body.detail),
386
699
  param: stringValue(body.param),
387
700
  ...currentRevision !== void 0 ? { currentRevision } : {},
388
701
  requestId: stringValue(body.request_id) ?? responseHeaders["x-request-id"] ?? null,
@@ -434,106 +747,6 @@ function booleanValue(value) {
434
747
  }
435
748
 
436
749
  // 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
750
  var DropthisEdge = class {
538
751
  transport;
539
752
  dropsResource;
@@ -564,17 +777,25 @@ var DropthisEdge = class {
564
777
  return this.deploymentsResource;
565
778
  }
566
779
  /** Publish a NEW drop from in-memory content. */
567
- publishInline(input, options = {}) {
568
- return stagedInline(this.transport, input, options, "/drops");
780
+ async publish(input, options = {}) {
781
+ let prepared;
782
+ try {
783
+ prepared = await resolveInMemory(input, options);
784
+ } catch (e) {
785
+ return toErrorResult(e);
786
+ }
787
+ return prepared.kind === "source" ? publishSource(this.transport, prepared, "/drops", options) : publishStaged(this.transport, prepared, "/drops", options);
569
788
  }
570
789
  /** 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
- );
790
+ async deploy(dropId, input, options = {}) {
791
+ let prepared;
792
+ try {
793
+ prepared = await resolveInMemory(input, options);
794
+ } catch (e) {
795
+ return toErrorResult(e);
796
+ }
797
+ const path = `/drops/${encodeURIComponent(dropId)}/deployments`;
798
+ return prepared.kind === "source" ? publishSource(this.transport, prepared, path, options) : publishStaged(this.transport, prepared, path, options);
578
799
  }
579
800
  };
580
801
  // Annotate the CommonJS export names for ESM import in node: