@dropthis/cli 0.9.3 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -2
- package/dist/cli.cjs +559 -30
- package/dist/cli.cjs.map +1 -1
- package/node_modules/@dropthis/node/README.md +146 -7
- package/node_modules/@dropthis/node/dist/{drops-BWA0D1IW.d.cts → drops-DEJcU6qw.d.cts} +235 -17
- package/node_modules/@dropthis/node/dist/{drops-BWA0D1IW.d.ts → drops-DEJcU6qw.d.ts} +235 -17
- package/node_modules/@dropthis/node/dist/edge.cjs +301 -41
- package/node_modules/@dropthis/node/dist/edge.cjs.map +1 -1
- package/node_modules/@dropthis/node/dist/edge.d.cts +3 -1
- package/node_modules/@dropthis/node/dist/edge.d.ts +3 -1
- package/node_modules/@dropthis/node/dist/edge.mjs +301 -41
- package/node_modules/@dropthis/node/dist/edge.mjs.map +1 -1
- package/node_modules/@dropthis/node/dist/index.cjs +310 -43
- package/node_modules/@dropthis/node/dist/index.cjs.map +1 -1
- package/node_modules/@dropthis/node/dist/index.d.cts +12 -7
- package/node_modules/@dropthis/node/dist/index.d.ts +12 -7
- package/node_modules/@dropthis/node/dist/index.mjs +309 -43
- package/node_modules/@dropthis/node/dist/index.mjs.map +1 -1
- package/node_modules/@dropthis/node/package.json +1 -1
- package/package.json +2 -2
|
@@ -32,6 +32,7 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
CursorPage: () => CursorPage,
|
|
34
34
|
DeploymentsResource: () => DeploymentsResource,
|
|
35
|
+
DomainsResource: () => DomainsResource,
|
|
35
36
|
Dropthis: () => Dropthis,
|
|
36
37
|
PublishInputError: () => PublishInputError,
|
|
37
38
|
UploadsResource: () => UploadsResource,
|
|
@@ -245,6 +246,8 @@ function optionsBody(options) {
|
|
|
245
246
|
if (options.expiresAt !== void 0) {
|
|
246
247
|
body.expiresAt = options.expiresAt instanceof Date ? options.expiresAt.toISOString() : options.expiresAt;
|
|
247
248
|
}
|
|
249
|
+
if (options.domain !== void 0) body.domain = options.domain;
|
|
250
|
+
if (options.slug !== void 0) body.slug = options.slug;
|
|
248
251
|
return body;
|
|
249
252
|
}
|
|
250
253
|
function updateContentOptions(options) {
|
|
@@ -373,10 +376,49 @@ async function resolveInMemory(input, options = {}) {
|
|
|
373
376
|
});
|
|
374
377
|
return buildStagedRequest(files, options, input.entry);
|
|
375
378
|
}
|
|
379
|
+
var UPLOAD_CONCURRENCY = 5;
|
|
376
380
|
function errorResult(result) {
|
|
377
381
|
if (!result.error) throw new Error("Expected an error result");
|
|
378
382
|
return { data: null, error: result.error, headers: result.headers };
|
|
379
383
|
}
|
|
384
|
+
async function uploadStagedFiles(transport, jobs) {
|
|
385
|
+
let nextIndex = 0;
|
|
386
|
+
let failed = false;
|
|
387
|
+
const failures = /* @__PURE__ */ new Map();
|
|
388
|
+
async function worker() {
|
|
389
|
+
while (!failed) {
|
|
390
|
+
const index = nextIndex;
|
|
391
|
+
nextIndex += 1;
|
|
392
|
+
if (index >= jobs.length) return;
|
|
393
|
+
const job = jobs[index];
|
|
394
|
+
if (!job) return;
|
|
395
|
+
const put = await transport.putSignedUrl(
|
|
396
|
+
job.target.upload.url,
|
|
397
|
+
await job.file.getBody(),
|
|
398
|
+
job.target.upload.headers
|
|
399
|
+
);
|
|
400
|
+
if (put.error) {
|
|
401
|
+
failed = true;
|
|
402
|
+
failures.set(index, {
|
|
403
|
+
data: null,
|
|
404
|
+
error: {
|
|
405
|
+
...put.error,
|
|
406
|
+
message: `Upload failed for ${job.file.path}: ${put.error.message}`
|
|
407
|
+
},
|
|
408
|
+
headers: put.headers
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
const workers = Array.from(
|
|
414
|
+
{ length: Math.min(UPLOAD_CONCURRENCY, jobs.length) },
|
|
415
|
+
() => worker()
|
|
416
|
+
);
|
|
417
|
+
await Promise.all(workers);
|
|
418
|
+
if (failures.size === 0) return null;
|
|
419
|
+
const firstIndex = Math.min(...failures.keys());
|
|
420
|
+
return failures.get(firstIndex) ?? null;
|
|
421
|
+
}
|
|
380
422
|
async function publishStaged(transport, prepared, finalPath, options = {}) {
|
|
381
423
|
const baseKey = options.idempotencyKey ?? `sdk-${crypto.randomUUID()}`;
|
|
382
424
|
const createResult = await transport.request(
|
|
@@ -388,6 +430,7 @@ async function publishStaged(transport, prepared, finalPath, options = {}) {
|
|
|
388
430
|
}
|
|
389
431
|
);
|
|
390
432
|
if (createResult.error) return errorResult(createResult);
|
|
433
|
+
const jobs = [];
|
|
391
434
|
for (const file of prepared.files) {
|
|
392
435
|
const target = createResult.data.files.find((f) => f.path === file.path);
|
|
393
436
|
if (!target) {
|
|
@@ -400,22 +443,18 @@ async function publishStaged(transport, prepared, finalPath, options = {}) {
|
|
|
400
443
|
if (target.upload.strategy !== "single_put") {
|
|
401
444
|
return createErrorResult(
|
|
402
445
|
"unsupported_upload_strategy",
|
|
403
|
-
`
|
|
446
|
+
`Unexpected upload strategy "${target.upload.strategy}" for ${file.path}. The dropthis upload contract is one signed PUT per file; update @dropthis/node.`,
|
|
404
447
|
null
|
|
405
448
|
);
|
|
406
449
|
}
|
|
407
|
-
|
|
408
|
-
target.upload.url,
|
|
409
|
-
await file.getBody(),
|
|
410
|
-
target.upload.headers
|
|
411
|
-
);
|
|
412
|
-
if (put.error) return errorResult(put);
|
|
450
|
+
jobs.push({ file, target });
|
|
413
451
|
}
|
|
452
|
+
const uploadFailure = await uploadStagedFiles(transport, jobs);
|
|
453
|
+
if (uploadFailure) return uploadFailure;
|
|
414
454
|
const completeResult = await transport.request(
|
|
415
455
|
"POST",
|
|
416
456
|
`/uploads/${encodeURIComponent(createResult.data.uploadId)}/complete`,
|
|
417
457
|
{
|
|
418
|
-
body: { files: {} },
|
|
419
458
|
idempotencyKey: `${baseKey}:complete-upload`
|
|
420
459
|
}
|
|
421
460
|
);
|
|
@@ -626,6 +665,7 @@ var ApiKeysResource = class {
|
|
|
626
665
|
create(input) {
|
|
627
666
|
return this.transport.request("POST", "/api-keys", { body: input });
|
|
628
667
|
}
|
|
668
|
+
/** Revoke an API key. 204 No Content — data is null on success. */
|
|
629
669
|
delete(keyId) {
|
|
630
670
|
return this.transport.request(
|
|
631
671
|
"DELETE",
|
|
@@ -652,6 +692,7 @@ var AuthResource = class {
|
|
|
652
692
|
authenticated: false
|
|
653
693
|
});
|
|
654
694
|
}
|
|
695
|
+
/** Revoke the current `at_` session token. 204 No Content — data is null on success. */
|
|
655
696
|
logout() {
|
|
656
697
|
return this.transport.request("DELETE", "/auth/session");
|
|
657
698
|
}
|
|
@@ -678,6 +719,67 @@ var DeploymentsResource = class {
|
|
|
678
719
|
}
|
|
679
720
|
};
|
|
680
721
|
|
|
722
|
+
// src/resources/domains.ts
|
|
723
|
+
var DomainsResource = class {
|
|
724
|
+
constructor(transport) {
|
|
725
|
+
this.transport = transport;
|
|
726
|
+
}
|
|
727
|
+
transport;
|
|
728
|
+
/**
|
|
729
|
+
* Connect a custom domain to the account. Returns the domain in `pending_dns` status with
|
|
730
|
+
* DNS instructions. Idempotent on (account, hostname) — re-connecting an already-connected
|
|
731
|
+
* domain returns the existing row. POST /domains.
|
|
732
|
+
*/
|
|
733
|
+
connect(input) {
|
|
734
|
+
return this.transport.request("POST", "/domains", { body: input });
|
|
735
|
+
}
|
|
736
|
+
/** List all custom domains connected to this account. GET /domains. */
|
|
737
|
+
list() {
|
|
738
|
+
return this.transport.request("GET", "/domains");
|
|
739
|
+
}
|
|
740
|
+
/** Get a domain by its stable id or hostname. GET /domains/{id_or_hostname}. */
|
|
741
|
+
get(idOrHostname) {
|
|
742
|
+
return this.transport.request(
|
|
743
|
+
"GET",
|
|
744
|
+
`/domains/${encodeURIComponent(idOrHostname)}`
|
|
745
|
+
);
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* Trigger a DNS + Cloudflare verification check. Returns the domain with updated status and
|
|
749
|
+
* per-record diagnostics. If DNS is still propagating, `dns[].retryAfter` tells you when to
|
|
750
|
+
* re-call. POST /domains/{id_or_hostname}/verify.
|
|
751
|
+
*/
|
|
752
|
+
verify(idOrHostname) {
|
|
753
|
+
return this.transport.request(
|
|
754
|
+
"POST",
|
|
755
|
+
`/domains/${encodeURIComponent(idOrHostname)}/verify`
|
|
756
|
+
);
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* Update a domain's `dropId` (dedicated mode: repoint to a different drop) or `default`
|
|
760
|
+
* flag (path mode only: set/clear the account's default publish domain). Mode is immutable
|
|
761
|
+
* — delete and reconnect to change it. PATCH /domains/{id_or_hostname}.
|
|
762
|
+
*/
|
|
763
|
+
update(idOrHostname, input) {
|
|
764
|
+
return this.transport.request(
|
|
765
|
+
"PATCH",
|
|
766
|
+
`/domains/${encodeURIComponent(idOrHostname)}`,
|
|
767
|
+
{ body: input }
|
|
768
|
+
);
|
|
769
|
+
}
|
|
770
|
+
/**
|
|
771
|
+
* Delete a custom domain and remove all its routes. The response includes a dangling-CNAME
|
|
772
|
+
* warning — remove the DNS record after deleting so another account cannot re-claim the
|
|
773
|
+
* hostname. DELETE /domains/{id_or_hostname}.
|
|
774
|
+
*/
|
|
775
|
+
delete(idOrHostname) {
|
|
776
|
+
return this.transport.request(
|
|
777
|
+
"DELETE",
|
|
778
|
+
`/domains/${encodeURIComponent(idOrHostname)}`
|
|
779
|
+
);
|
|
780
|
+
}
|
|
781
|
+
};
|
|
782
|
+
|
|
681
783
|
// src/pagination.ts
|
|
682
784
|
var CursorPage = class {
|
|
683
785
|
object = "list";
|
|
@@ -713,12 +815,29 @@ var CursorPage = class {
|
|
|
713
815
|
|
|
714
816
|
// src/resources/drops.ts
|
|
715
817
|
var DropsResource = class {
|
|
716
|
-
constructor(transport,
|
|
818
|
+
constructor(transport, resolveInput2) {
|
|
717
819
|
this.transport = transport;
|
|
718
|
-
this.
|
|
820
|
+
this.resolveInput = resolveInput2;
|
|
719
821
|
}
|
|
720
822
|
transport;
|
|
721
|
-
|
|
823
|
+
resolveInput;
|
|
824
|
+
parentHosts;
|
|
825
|
+
/**
|
|
826
|
+
* Hostnames the SDK can attribute to dropthis for slug parsing: the canonical
|
|
827
|
+
* viewer domain plus the configured baseUrl's host (covers staging/self-hosted
|
|
828
|
+
* setups where drops are served under the API's own domain).
|
|
829
|
+
*/
|
|
830
|
+
allowedParentHosts() {
|
|
831
|
+
if (!this.parentHosts) {
|
|
832
|
+
const hosts = /* @__PURE__ */ new Set([CANONICAL_VIEWER_HOST]);
|
|
833
|
+
try {
|
|
834
|
+
hosts.add(new URL(this.transport.baseUrl).hostname);
|
|
835
|
+
} catch {
|
|
836
|
+
}
|
|
837
|
+
this.parentHosts = hosts;
|
|
838
|
+
}
|
|
839
|
+
return this.parentHosts;
|
|
840
|
+
}
|
|
722
841
|
/**
|
|
723
842
|
* Publish content to a NEW permanent public URL; returns the created drop (with its `drop_…` id).
|
|
724
843
|
* Use to publish / share / post / put online / make public a report, dashboard, site, or file.
|
|
@@ -729,7 +848,7 @@ var DropsResource = class {
|
|
|
729
848
|
async publish(input, options = {}) {
|
|
730
849
|
let prepared;
|
|
731
850
|
try {
|
|
732
|
-
prepared = await this.
|
|
851
|
+
prepared = await this.resolveInput(input, options);
|
|
733
852
|
} catch (e) {
|
|
734
853
|
return toErrorResult(e);
|
|
735
854
|
}
|
|
@@ -746,7 +865,7 @@ var DropsResource = class {
|
|
|
746
865
|
const opts = updateContentOptions(options);
|
|
747
866
|
let prepared;
|
|
748
867
|
try {
|
|
749
|
-
prepared = await this.
|
|
868
|
+
prepared = await this.resolveInput(input, opts);
|
|
750
869
|
} catch (e) {
|
|
751
870
|
return toErrorResult(e);
|
|
752
871
|
}
|
|
@@ -774,10 +893,67 @@ var DropsResource = class {
|
|
|
774
893
|
`/drops/${encodeURIComponent(dropId)}`
|
|
775
894
|
);
|
|
776
895
|
}
|
|
896
|
+
/**
|
|
897
|
+
* Resolve a drop URL (or bare slug) back to the drop — the way to recover a lost
|
|
898
|
+
* `drop_…` id. The slug is parsed client-side from the first hostname label of a
|
|
899
|
+
* dropthis-attributable hostname (`https://<slug>.dropthis.app/…`, or `<slug>.` +
|
|
900
|
+
* the configured baseUrl's host), then matched owner-scoped via GET /drops?slug=.
|
|
901
|
+
* Returns the drop, or `data: null` when no drop of yours has that slug.
|
|
902
|
+
* Custom-domain URLs are rejected client-side with `invalid_drop_url` — they are
|
|
903
|
+
* not resolvable yet.
|
|
904
|
+
*/
|
|
905
|
+
async resolve(urlOrSlug) {
|
|
906
|
+
const slug = parseSlug(urlOrSlug, this.allowedParentHosts());
|
|
907
|
+
if (slug === null) {
|
|
908
|
+
return createErrorResult(
|
|
909
|
+
"invalid_drop_url",
|
|
910
|
+
`Could not resolve a drop slug from "${urlOrSlug}". Pass a canonical drop URL like https://<slug>.dropthis.app/ or the bare slug \u2014 custom-domain URLs cannot be resolved yet.`,
|
|
911
|
+
null
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
const result = await this.transport.request("GET", "/drops", { params: { slug } });
|
|
915
|
+
if (result.error)
|
|
916
|
+
return { data: null, error: result.error, headers: result.headers };
|
|
917
|
+
return {
|
|
918
|
+
data: result.data.drops[0] ?? null,
|
|
919
|
+
error: null,
|
|
920
|
+
headers: result.headers
|
|
921
|
+
};
|
|
922
|
+
}
|
|
923
|
+
async getContent(dropId, options = {}) {
|
|
924
|
+
const base = options.deploymentId !== void 0 ? `/drops/${encodeURIComponent(dropId)}/deployments/${encodeURIComponent(options.deploymentId)}/content` : `/drops/${encodeURIComponent(dropId)}/content`;
|
|
925
|
+
if (options.path === void 0)
|
|
926
|
+
return this.transport.request("GET", base);
|
|
927
|
+
const path = options.path;
|
|
928
|
+
const result = await this.transport.requestBytes(base, {
|
|
929
|
+
params: { path }
|
|
930
|
+
});
|
|
931
|
+
if (result.error)
|
|
932
|
+
return { data: null, error: result.error, headers: result.headers };
|
|
933
|
+
const { bytes, contentType } = result.data;
|
|
934
|
+
return {
|
|
935
|
+
data: {
|
|
936
|
+
path,
|
|
937
|
+
contentType,
|
|
938
|
+
bytes,
|
|
939
|
+
text: () => new TextDecoder().decode(bytes)
|
|
940
|
+
},
|
|
941
|
+
error: null,
|
|
942
|
+
headers: result.headers
|
|
943
|
+
};
|
|
944
|
+
}
|
|
777
945
|
/**
|
|
778
946
|
* Change an EXISTING drop's settings — title, visibility, password, noindex, expiry,
|
|
779
|
-
* metadata — by its `drop_…` id. Does not touch content; replace that
|
|
780
|
-
* Idempotent. PATCH /drops/{id}.
|
|
947
|
+
* metadata, domain, or slug — by its `drop_…` id. Does not touch content; replace that
|
|
948
|
+
* with {@link updateContent}. Idempotent. PATCH /drops/{id}.
|
|
949
|
+
*
|
|
950
|
+
* **`domain`** — move the drop to a different custom domain (must be live). Pass `null` to
|
|
951
|
+
* move the drop back to the shared pool (unmount from its current domain).
|
|
952
|
+
*
|
|
953
|
+
* **`slug`** — rename the vanity slug on a path-mode custom domain. Only valid when the drop
|
|
954
|
+
* lives on a path-mode domain. Unlike {@link publish} (which auto-suffixes taken slugs),
|
|
955
|
+
* `updateSettings` returns 409 on a slug conflict and never auto-suffixes — your code must
|
|
956
|
+
* catch 409 and retry with a different slug. Passing `slug` on the shared pool returns 422.
|
|
781
957
|
*/
|
|
782
958
|
updateSettings(dropId, options = {}) {
|
|
783
959
|
const requestOptions = {
|
|
@@ -801,12 +977,33 @@ var DropsResource = class {
|
|
|
801
977
|
);
|
|
802
978
|
}
|
|
803
979
|
};
|
|
980
|
+
var CANONICAL_VIEWER_HOST = "dropthis.app";
|
|
981
|
+
function parseSlug(input, allowedParents) {
|
|
982
|
+
const value = input.trim();
|
|
983
|
+
if (!value) return null;
|
|
984
|
+
if (!/[./]/.test(value)) return value;
|
|
985
|
+
const withScheme = /^[a-z][a-z0-9+.-]*:\/\//i.test(value) ? value : `https://${value}`;
|
|
986
|
+
let hostname;
|
|
987
|
+
try {
|
|
988
|
+
hostname = new URL(withScheme).hostname;
|
|
989
|
+
} catch {
|
|
990
|
+
return null;
|
|
991
|
+
}
|
|
992
|
+
hostname = hostname.replace(/\.$/, "");
|
|
993
|
+
const dot = hostname.indexOf(".");
|
|
994
|
+
if (dot <= 0) return null;
|
|
995
|
+
const slug = hostname.slice(0, dot);
|
|
996
|
+
const parent = hostname.slice(dot + 1);
|
|
997
|
+
return allowedParents.has(parent) ? slug : null;
|
|
998
|
+
}
|
|
804
999
|
var SETTINGS = [
|
|
805
1000
|
"title",
|
|
806
1001
|
"visibility",
|
|
807
1002
|
"password",
|
|
808
1003
|
"noindex",
|
|
809
|
-
"expiresAt"
|
|
1004
|
+
"expiresAt",
|
|
1005
|
+
"domain",
|
|
1006
|
+
"slug"
|
|
810
1007
|
];
|
|
811
1008
|
function updateBody(options) {
|
|
812
1009
|
const out = {};
|
|
@@ -836,8 +1033,12 @@ var UploadsResource = class {
|
|
|
836
1033
|
`/uploads/${encodeURIComponent(uploadId)}`
|
|
837
1034
|
);
|
|
838
1035
|
}
|
|
839
|
-
|
|
840
|
-
|
|
1036
|
+
/**
|
|
1037
|
+
* Verify staged objects and mark the session complete. Takes no request body —
|
|
1038
|
+
* the server verifies the uploaded bytes against the staged manifest.
|
|
1039
|
+
*/
|
|
1040
|
+
complete(uploadId, options = {}) {
|
|
1041
|
+
const requestOptions = {};
|
|
841
1042
|
if (options.idempotencyKey)
|
|
842
1043
|
requestOptions.idempotencyKey = options.idempotencyKey;
|
|
843
1044
|
return this.transport.request(
|
|
@@ -889,7 +1090,7 @@ function toSnakeCase(value) {
|
|
|
889
1090
|
|
|
890
1091
|
// src/transport.ts
|
|
891
1092
|
var DEFAULT_BASE_URL = "https://api.dropthis.app";
|
|
892
|
-
var SDK_VERSION = "0.
|
|
1093
|
+
var SDK_VERSION = "0.10.0";
|
|
893
1094
|
var Transport = class {
|
|
894
1095
|
apiKey;
|
|
895
1096
|
baseUrl;
|
|
@@ -949,6 +1150,63 @@ var Transport = class {
|
|
|
949
1150
|
clearTimeout(timeout);
|
|
950
1151
|
}
|
|
951
1152
|
}
|
|
1153
|
+
/**
|
|
1154
|
+
* Authenticated GET that returns the raw response bytes untouched (no JSON parsing,
|
|
1155
|
+
* no case conversion). Error responses are still parsed as problem+json. Used for
|
|
1156
|
+
* content read-back (`drops.getContent` with a file path).
|
|
1157
|
+
*/
|
|
1158
|
+
async requestBytes(path, options = {}) {
|
|
1159
|
+
if (!this.apiKey) {
|
|
1160
|
+
return createErrorResult(
|
|
1161
|
+
"missing_api_key",
|
|
1162
|
+
"No API key provided. Pass apiKey or set DROPTHIS_API_KEY.",
|
|
1163
|
+
null
|
|
1164
|
+
);
|
|
1165
|
+
}
|
|
1166
|
+
const headers = {
|
|
1167
|
+
"user-agent": `dropthis-node/${SDK_VERSION}`,
|
|
1168
|
+
authorization: `Bearer ${this.apiKey}`
|
|
1169
|
+
};
|
|
1170
|
+
const url = new URL(`${this.baseUrl}${path}`);
|
|
1171
|
+
for (const [key, value] of Object.entries(options.params ?? {})) {
|
|
1172
|
+
if (value !== void 0 && value !== null)
|
|
1173
|
+
url.searchParams.set(key, String(value));
|
|
1174
|
+
}
|
|
1175
|
+
const controller = new AbortController();
|
|
1176
|
+
const timeout = setTimeout(
|
|
1177
|
+
() => controller.abort(),
|
|
1178
|
+
options.timeoutMs ?? this.timeoutMs
|
|
1179
|
+
);
|
|
1180
|
+
try {
|
|
1181
|
+
const response = await this.fetchImpl(url.toString(), {
|
|
1182
|
+
method: "GET",
|
|
1183
|
+
headers,
|
|
1184
|
+
signal: controller.signal
|
|
1185
|
+
});
|
|
1186
|
+
const responseHeaders = headersToObject(response.headers);
|
|
1187
|
+
if (!response.ok) {
|
|
1188
|
+
const text = await response.text();
|
|
1189
|
+
return problemResult(response, text, responseHeaders);
|
|
1190
|
+
}
|
|
1191
|
+
return {
|
|
1192
|
+
data: {
|
|
1193
|
+
bytes: new Uint8Array(await response.arrayBuffer()),
|
|
1194
|
+
contentType: response.headers.get("content-type") ?? responseHeaders["content-type"] ?? null
|
|
1195
|
+
},
|
|
1196
|
+
error: null,
|
|
1197
|
+
headers: responseHeaders
|
|
1198
|
+
};
|
|
1199
|
+
} catch (error) {
|
|
1200
|
+
const message = error instanceof Error && error.name === "AbortError" ? "Request timed out" : error instanceof Error ? error.message : "Network error";
|
|
1201
|
+
return createErrorResult(
|
|
1202
|
+
error instanceof Error && error.name === "AbortError" ? "timeout" : "network_error",
|
|
1203
|
+
message,
|
|
1204
|
+
null
|
|
1205
|
+
);
|
|
1206
|
+
} finally {
|
|
1207
|
+
clearTimeout(timeout);
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
952
1210
|
async request(method, path, options = {}) {
|
|
953
1211
|
const authenticated = options.authenticated ?? true;
|
|
954
1212
|
if (authenticated && !this.apiKey) {
|
|
@@ -995,31 +1253,10 @@ var Transport = class {
|
|
|
995
1253
|
const response = await this.fetchImpl(url.toString(), request);
|
|
996
1254
|
const responseHeaders = headersToObject(response.headers);
|
|
997
1255
|
const text = await response.text();
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
const body = parsed && typeof parsed === "object" ? parsed : {};
|
|
1001
|
-
const message = stringValue(body.detail) ?? stringValue(body.title) ?? response.statusText;
|
|
1002
|
-
const code = stringValue(body.code) ?? stringValue(body.error_code) ?? `http_${response.status}`;
|
|
1003
|
-
const currentRevision = numberValue(body.current_revision);
|
|
1004
|
-
const type = stringValue(body.type);
|
|
1005
|
-
const title = stringValue(body.title);
|
|
1006
|
-
const instance = stringValue(body.instance);
|
|
1007
|
-
return createErrorResult(code, message, response.status, {
|
|
1008
|
-
body,
|
|
1009
|
-
...type !== null ? { type } : {},
|
|
1010
|
-
...title !== null ? { title } : {},
|
|
1011
|
-
...instance !== null ? { instance } : {},
|
|
1012
|
-
detail: stringValue(body.detail),
|
|
1013
|
-
param: stringValue(body.param),
|
|
1014
|
-
...currentRevision !== void 0 ? { currentRevision } : {},
|
|
1015
|
-
requestId: stringValue(body.request_id) ?? responseHeaders["x-request-id"] ?? null,
|
|
1016
|
-
suggestion: stringValue(body.suggestion),
|
|
1017
|
-
retryable: booleanValue(body.retryable),
|
|
1018
|
-
headers: responseHeaders
|
|
1019
|
-
});
|
|
1020
|
-
}
|
|
1256
|
+
if (!response.ok)
|
|
1257
|
+
return problemResult(response, text, responseHeaders);
|
|
1021
1258
|
return {
|
|
1022
|
-
data: toCamelCase(
|
|
1259
|
+
data: toCamelCase(parseJson(text)),
|
|
1023
1260
|
error: null,
|
|
1024
1261
|
headers: responseHeaders
|
|
1025
1262
|
};
|
|
@@ -1035,6 +1272,29 @@ var Transport = class {
|
|
|
1035
1272
|
}
|
|
1036
1273
|
}
|
|
1037
1274
|
};
|
|
1275
|
+
function problemResult(response, text, responseHeaders) {
|
|
1276
|
+
const parsed = parseJson(text);
|
|
1277
|
+
const body = parsed && typeof parsed === "object" ? parsed : {};
|
|
1278
|
+
const message = stringValue(body.detail) ?? stringValue(body.title) ?? response.statusText;
|
|
1279
|
+
const code = stringValue(body.code) ?? stringValue(body.error_code) ?? `http_${response.status}`;
|
|
1280
|
+
const currentRevision = numberValue(body.current_revision);
|
|
1281
|
+
const type = stringValue(body.type);
|
|
1282
|
+
const title = stringValue(body.title);
|
|
1283
|
+
const instance = stringValue(body.instance);
|
|
1284
|
+
return createErrorResult(code, message, response.status, {
|
|
1285
|
+
body,
|
|
1286
|
+
...type !== null ? { type } : {},
|
|
1287
|
+
...title !== null ? { title } : {},
|
|
1288
|
+
...instance !== null ? { instance } : {},
|
|
1289
|
+
detail: stringValue(body.detail),
|
|
1290
|
+
param: stringValue(body.param),
|
|
1291
|
+
...currentRevision !== void 0 ? { currentRevision } : {},
|
|
1292
|
+
requestId: stringValue(body.request_id) ?? responseHeaders["x-request-id"] ?? null,
|
|
1293
|
+
suggestion: stringValue(body.suggestion),
|
|
1294
|
+
retryable: booleanValue(body.retryable),
|
|
1295
|
+
headers: responseHeaders
|
|
1296
|
+
});
|
|
1297
|
+
}
|
|
1038
1298
|
function headersToObject(headers) {
|
|
1039
1299
|
const result = {};
|
|
1040
1300
|
headers.forEach((value, key) => {
|
|
@@ -1069,6 +1329,7 @@ var Dropthis = class {
|
|
|
1069
1329
|
dropsResource;
|
|
1070
1330
|
deploymentsResource;
|
|
1071
1331
|
uploadsResource;
|
|
1332
|
+
domainsResource;
|
|
1072
1333
|
constructor(options = {}) {
|
|
1073
1334
|
this.transport = new Transport(options);
|
|
1074
1335
|
}
|
|
@@ -1102,6 +1363,11 @@ var Dropthis = class {
|
|
|
1102
1363
|
this.uploadsResource = new UploadsResource(this.transport);
|
|
1103
1364
|
return this.uploadsResource;
|
|
1104
1365
|
}
|
|
1366
|
+
get domains() {
|
|
1367
|
+
if (!this.domainsResource)
|
|
1368
|
+
this.domainsResource = new DomainsResource(this.transport);
|
|
1369
|
+
return this.domainsResource;
|
|
1370
|
+
}
|
|
1105
1371
|
async prepare(input, options = {}) {
|
|
1106
1372
|
return resolveInput(input, options);
|
|
1107
1373
|
}
|
|
@@ -1110,6 +1376,7 @@ var Dropthis = class {
|
|
|
1110
1376
|
0 && (module.exports = {
|
|
1111
1377
|
CursorPage,
|
|
1112
1378
|
DeploymentsResource,
|
|
1379
|
+
DomainsResource,
|
|
1113
1380
|
Dropthis,
|
|
1114
1381
|
PublishInputError,
|
|
1115
1382
|
UploadsResource,
|