@netlify/spark-ui 1.31.0-alpha.3 → 1.31.0-alpha.4
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/dist/components/index.d.ts +2 -2
- package/dist/components/preact/DropZone/DropZone.d.ts +21 -2
- package/dist/components/preact/DropZone/DropZone.js +59 -54
- package/dist/components/preact/DropZone/DropZone.test.d.ts +1 -0
- package/dist/components/preact/DropZone/index.d.ts +3 -3
- package/dist/components/preact/DropZone/index.js +25 -23
- package/dist/components/preact/DropZone/useDropDeploy.d.ts +10 -6
- package/dist/components/preact/DropZone/useDropDeploy.js +184 -131
- package/dist/components/preact/DropZone/useDropDeploy.test.d.ts +1 -0
- package/dist/components/preact/index.d.ts +2 -2
- package/dist/components/preact/index.js +25 -19
- package/dist/drop-core/analytics.d.ts +107 -0
- package/dist/drop-core/analytics.js +21 -0
- package/dist/drop-core/analytics.test.d.ts +1 -0
- package/dist/drop-core/authedApi.d.ts +55 -0
- package/dist/drop-core/authedApi.js +35 -0
- package/dist/drop-core/authedApi.test.d.ts +1 -0
- package/dist/drop-core/authedDropClient.js +109 -0
- package/dist/drop-core/authedDropClient.test.d.ts +1 -0
- package/dist/{components/preact/DropZone/drop-core → drop-core}/buildClient.d.ts +5 -13
- package/dist/drop-core/buildClient.js +84 -0
- package/dist/drop-core/buildClient.test.d.ts +1 -0
- package/dist/drop-core/buildStash.d.ts +37 -0
- package/dist/drop-core/buildStash.js +84 -0
- package/dist/drop-core/buildStash.test.d.ts +0 -0
- package/dist/{components/preact/DropZone/drop-core → drop-core}/deploy.d.ts +7 -0
- package/dist/drop-core/deploy.js +53 -0
- package/dist/drop-core/deploy.test.d.ts +1 -0
- package/dist/drop-core/detectBuild.test.d.ts +1 -0
- package/dist/drop-core/digest.test.d.ts +1 -0
- package/dist/{components/preact/DropZone/drop-core → drop-core}/errors.js +1 -1
- package/dist/drop-core/errors.test.d.ts +1 -0
- package/dist/drop-core/fileTypes.test.d.ts +1 -0
- package/dist/{components/preact/DropZone/drop-core → drop-core}/index.d.ts +3 -0
- package/dist/drop-core/index.js +51 -0
- package/dist/{components/preact/DropZone/drop-core → drop-core}/readFiles.js +2 -2
- package/dist/drop-core/readFiles.test.d.ts +1 -0
- package/dist/{components/preact/DropZone/drop-core → drop-core}/types.d.ts +10 -0
- package/dist/{components/preact/DropZone/drop-core → drop-core}/zip.js +1 -1
- package/dist/drop-core/zip.test.d.ts +1 -0
- package/package.json +4 -1
- package/packages/components/index.ts +19 -0
- package/packages/components/preact/DropZone/DropZone.test.ts +71 -0
- package/packages/components/preact/DropZone/DropZone.tsx +23 -2
- package/packages/components/preact/DropZone/index.tsx +14 -3
- package/packages/components/preact/DropZone/useDropDeploy.test.ts +376 -0
- package/packages/components/preact/DropZone/useDropDeploy.ts +297 -132
- package/packages/components/preact/index.ts +19 -2
- package/packages/drop-core/analytics.test.ts +17 -0
- package/packages/drop-core/analytics.ts +122 -0
- package/packages/drop-core/authedApi.test.ts +100 -0
- package/packages/drop-core/authedApi.ts +94 -0
- package/packages/drop-core/authedDropClient.test.ts +196 -0
- package/packages/{components/preact/DropZone/drop-core → drop-core}/authedDropClient.ts +30 -51
- package/packages/drop-core/buildClient.test.ts +112 -0
- package/packages/{components/preact/DropZone/drop-core → drop-core}/buildClient.ts +28 -57
- package/packages/drop-core/buildStash.test.ts +85 -0
- package/packages/drop-core/buildStash.ts +185 -0
- package/packages/drop-core/deploy.test.ts +135 -0
- package/packages/{components/preact/DropZone/drop-core → drop-core}/deploy.ts +18 -4
- package/packages/drop-core/detectBuild.test.ts +139 -0
- package/packages/drop-core/digest.test.ts +24 -0
- package/packages/drop-core/errors.test.ts +69 -0
- package/packages/{components/preact/DropZone/drop-core → drop-core}/errors.ts +1 -1
- package/packages/drop-core/fileTypes.test.ts +37 -0
- package/packages/{components/preact/DropZone/drop-core → drop-core}/index.ts +3 -0
- package/packages/drop-core/readFiles.test.ts +125 -0
- package/packages/{components/preact/DropZone/drop-core → drop-core}/types.ts +12 -6
- package/packages/drop-core/zip.test.ts +92 -0
- package/dist/components/preact/DropZone/drop-core/authedDropClient.js +0 -123
- package/dist/components/preact/DropZone/drop-core/buildClient.js +0 -99
- package/dist/components/preact/DropZone/drop-core/deploy.js +0 -48
- package/dist/components/preact/DropZone/drop-core/index.js +0 -36
- /package/dist/{components/preact/DropZone/drop-core → drop-core}/authedDropClient.d.ts +0 -0
- /package/dist/{components/preact/DropZone/drop-core → drop-core}/client.d.ts +0 -0
- /package/dist/{components/preact/DropZone/drop-core → drop-core}/client.js +0 -0
- /package/dist/{components/preact/DropZone/drop-core → drop-core}/detectBuild.d.ts +0 -0
- /package/dist/{components/preact/DropZone/drop-core → drop-core}/detectBuild.js +0 -0
- /package/dist/{components/preact/DropZone/drop-core → drop-core}/digest.d.ts +0 -0
- /package/dist/{components/preact/DropZone/drop-core → drop-core}/digest.js +0 -0
- /package/dist/{components/preact/DropZone/drop-core → drop-core}/errors.d.ts +0 -0
- /package/dist/{components/preact/DropZone/drop-core → drop-core}/fileTypes.d.ts +0 -0
- /package/dist/{components/preact/DropZone/drop-core → drop-core}/fileTypes.js +0 -0
- /package/dist/{components/preact/DropZone/drop-core → drop-core}/readFiles.d.ts +0 -0
- /package/dist/{components/preact/DropZone/drop-core → drop-core}/types.js +0 -0
- /package/dist/{components/preact/DropZone/drop-core → drop-core}/zip.d.ts +0 -0
- /package/packages/{components/preact/DropZone/drop-core → drop-core}/client.ts +0 -0
- /package/packages/{components/preact/DropZone/drop-core → drop-core}/detectBuild.ts +0 -0
- /package/packages/{components/preact/DropZone/drop-core → drop-core}/digest.ts +0 -0
- /package/packages/{components/preact/DropZone/drop-core → drop-core}/fileTypes.ts +0 -0
- /package/packages/{components/preact/DropZone/drop-core → drop-core}/readFiles.ts +0 -0
- /package/packages/{components/preact/DropZone/drop-core → drop-core}/zip.ts +0 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
var l = Object.defineProperty;
|
|
2
|
+
var c = (i, e, t) => e in i ? l(i, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : i[e] = t;
|
|
3
|
+
var a = (i, e, t) => c(i, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
import { DEFAULT_PROXY_BASE as p, DEFAULT_API_BASE as h, DEFAULT_POLL_INTERVAL_MS as u, DEFAULT_TIMEOUT_MS as y, createSiteInAccount as T, pollDeployUntilSettled as w } from "./authedApi.js";
|
|
5
|
+
import { apiError as d } from "./client.js";
|
|
6
|
+
import { NotAuthenticatedError as m } from "./errors.js";
|
|
7
|
+
const k = 20 * 1e3;
|
|
8
|
+
class M {
|
|
9
|
+
constructor({
|
|
10
|
+
proxyBase: e = p,
|
|
11
|
+
apiBase: t = h,
|
|
12
|
+
getUploadToken: o,
|
|
13
|
+
accountSlug: s,
|
|
14
|
+
pollIntervalMs: n = u,
|
|
15
|
+
timeoutMs: r = y
|
|
16
|
+
}) {
|
|
17
|
+
a(this, "proxyBase");
|
|
18
|
+
a(this, "apiBase");
|
|
19
|
+
a(this, "getUploadToken");
|
|
20
|
+
a(this, "accountSlug");
|
|
21
|
+
a(this, "pollIntervalMs");
|
|
22
|
+
a(this, "timeoutMs");
|
|
23
|
+
a(this, "cachedToken");
|
|
24
|
+
this.proxyBase = e, this.apiBase = t, this.getUploadToken = o, this.accountSlug = s, this.pollIntervalMs = n, this.timeoutMs = r;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The auth gate. Minting here — before anything is created — is what lets a
|
|
28
|
+
* logged-out visitor fail cleanly and fall back to the anonymous flow. The
|
|
29
|
+
* returned token is threaded through `deployFiles`, but only the uploads
|
|
30
|
+
* actually need one, and they re-mint rather than trusting this to still be
|
|
31
|
+
* valid by the time they run.
|
|
32
|
+
*/
|
|
33
|
+
async getToken() {
|
|
34
|
+
const e = await this.getUploadToken();
|
|
35
|
+
if (!e) throw new m();
|
|
36
|
+
return this.cachedToken = { value: e, mintedAt: Date.now() }, e;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A token young enough to authorize an upload, minting a new one once the
|
|
40
|
+
* cached one nears its 30s expiry.
|
|
41
|
+
*
|
|
42
|
+
* Deliberately NOT `NotAuthenticatedError` when minting fails: by the time
|
|
43
|
+
* uploads run the site already exists, and that error would send the drop
|
|
44
|
+
* back through the anonymous path — leaving an empty project behind and
|
|
45
|
+
* deploying a duplicate. See the class doc.
|
|
46
|
+
*/
|
|
47
|
+
async freshToken() {
|
|
48
|
+
const e = Date.now();
|
|
49
|
+
if (this.cachedToken && e - this.cachedToken.mintedAt < k)
|
|
50
|
+
return this.cachedToken.value;
|
|
51
|
+
const t = await this.getUploadToken();
|
|
52
|
+
if (!t) throw new Error("could not renew the upload token");
|
|
53
|
+
return this.cachedToken = { value: t, mintedAt: e }, t;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Two proxied calls: create the site in the visitor's account, then the
|
|
57
|
+
* deploy on it. Mapped into the anonymous `DropResponse` shape so
|
|
58
|
+
* `deployFiles` runs unchanged over either client.
|
|
59
|
+
*/
|
|
60
|
+
async createDeploy(e, t) {
|
|
61
|
+
const o = await T(this.proxyBase, this.accountSlug), s = await fetch(`${this.proxyBase}/sites/${o.id}/deploys`, {
|
|
62
|
+
method: "POST",
|
|
63
|
+
credentials: "include",
|
|
64
|
+
headers: { "Content-Type": "application/json" },
|
|
65
|
+
body: JSON.stringify({ files: e, deploy_source: "drop" })
|
|
66
|
+
});
|
|
67
|
+
if (!s.ok) throw d("deploy create", s.status);
|
|
68
|
+
const n = await s.json();
|
|
69
|
+
return {
|
|
70
|
+
id: o.id,
|
|
71
|
+
deploy_id: n.id,
|
|
72
|
+
subdomain: o.name,
|
|
73
|
+
required: n.required ?? []
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Direct to `api.netlify.com` on a freshly-aged bearer — the threaded `token`
|
|
78
|
+
* is ignored because an upload queue easily outlives the 30 seconds it was
|
|
79
|
+
* minted with. PUT (not POST) so paths with "&" etc. work.
|
|
80
|
+
*/
|
|
81
|
+
async uploadFile(e, t, o, s) {
|
|
82
|
+
const n = await this.freshToken(), r = await fetch(`${this.apiBase}/deploys/${e}/files${t}`, {
|
|
83
|
+
method: "PUT",
|
|
84
|
+
headers: { "Content-Type": "application/octet-stream", Authorization: `Bearer ${n}` },
|
|
85
|
+
body: o
|
|
86
|
+
});
|
|
87
|
+
if (!r.ok) throw d(`upload ${t}`, r.status);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Poll the deploy through the proxy until it settles: resolve on `ready`,
|
|
91
|
+
* throw on `error`/`rejected`, throw on timeout. On the session cookie rather
|
|
92
|
+
* than a bearer, so a deploy taking minutes can't outlive its own credentials.
|
|
93
|
+
*/
|
|
94
|
+
async waitUntilReady(e, t) {
|
|
95
|
+
const o = await w({
|
|
96
|
+
proxyBase: this.proxyBase,
|
|
97
|
+
deployId: e.deploy_id,
|
|
98
|
+
pollIntervalMs: this.pollIntervalMs,
|
|
99
|
+
timeoutMs: this.timeoutMs
|
|
100
|
+
});
|
|
101
|
+
if (o.outcome !== "ready")
|
|
102
|
+
throw o.outcome === "failed" ? new Error(
|
|
103
|
+
o.errorMessage ? `deploy failed: ${o.errorMessage}` : "deploy failed"
|
|
104
|
+
) : new Error("Deploy did not become ready in time");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
export {
|
|
108
|
+
M as AuthenticatedDropClient
|
|
109
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
/** site id (UUID) */
|
|
4
|
-
id: string;
|
|
5
|
-
/** the *.netlify.app subdomain, also the app's URL segment */
|
|
6
|
-
name: string;
|
|
7
|
-
/** https://<name>.netlify.app */
|
|
8
|
-
ssl_url?: string;
|
|
9
|
-
url?: string;
|
|
10
|
-
}
|
|
1
|
+
import { BuildSite } from './types';
|
|
2
|
+
export type { BuildSite } from './types';
|
|
11
3
|
/** The subset of a Netlify Build returned by `POST /sites/{id}/builds`. */
|
|
12
4
|
export interface BuildResponse {
|
|
13
5
|
/** build id */
|
|
@@ -76,9 +68,9 @@ export declare class AuthenticatedBuildClient implements BuildClient {
|
|
|
76
68
|
private timeoutMs;
|
|
77
69
|
constructor({ proxyBase, apiBase, getUploadToken, accountSlug, title, pollIntervalMs, timeoutMs, }: AuthenticatedBuildClientConfig);
|
|
78
70
|
/**
|
|
79
|
-
* Create the site the build deploys into.
|
|
80
|
-
*
|
|
81
|
-
*
|
|
71
|
+
* Create the site the build deploys into. A logged-out visitor fails here,
|
|
72
|
+
* before anything is created — see `createSiteInAccount` for the error
|
|
73
|
+
* mapping that makes the signup fallback safe.
|
|
82
74
|
*/
|
|
83
75
|
createSite(): Promise<BuildSite>;
|
|
84
76
|
/**
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
var d = Object.defineProperty;
|
|
2
|
+
var p = (r, t, e) => t in r ? d(r, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : r[t] = e;
|
|
3
|
+
var o = (r, t, e) => p(r, typeof t != "symbol" ? t + "" : t, e);
|
|
4
|
+
import { DEFAULT_PROXY_BASE as c, DEFAULT_API_BASE as h, DEFAULT_POLL_INTERVAL_MS as B, DEFAULT_TIMEOUT_MS as m, createSiteInAccount as y, pollDeployUntilSettled as w } from "./authedApi.js";
|
|
5
|
+
import { NotAuthenticatedError as l, BuildCreateError as A, BuildFailedError as E, BuildTimeoutError as M } from "./errors.js";
|
|
6
|
+
class _ {
|
|
7
|
+
constructor({
|
|
8
|
+
proxyBase: t = c,
|
|
9
|
+
apiBase: e = h,
|
|
10
|
+
getUploadToken: a,
|
|
11
|
+
accountSlug: s,
|
|
12
|
+
title: i = "Build from drop deployment",
|
|
13
|
+
pollIntervalMs: n = B,
|
|
14
|
+
timeoutMs: u = m
|
|
15
|
+
}) {
|
|
16
|
+
o(this, "proxyBase");
|
|
17
|
+
o(this, "apiBase");
|
|
18
|
+
o(this, "getUploadToken");
|
|
19
|
+
o(this, "accountSlug");
|
|
20
|
+
o(this, "title");
|
|
21
|
+
o(this, "pollIntervalMs");
|
|
22
|
+
o(this, "timeoutMs");
|
|
23
|
+
this.proxyBase = t, this.apiBase = e, this.getUploadToken = a, this.accountSlug = s, this.title = i, this.pollIntervalMs = n, this.timeoutMs = u;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Create the site the build deploys into. A logged-out visitor fails here,
|
|
27
|
+
* before anything is created — see `createSiteInAccount` for the error
|
|
28
|
+
* mapping that makes the signup fallback safe.
|
|
29
|
+
*/
|
|
30
|
+
async createSite() {
|
|
31
|
+
return y(this.proxyBase, this.accountSlug);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Upload the source archive and enqueue a build. Direct to `api.netlify.com`
|
|
35
|
+
* (see the note on `apiBase`), authorized by a freshly minted bearer token.
|
|
36
|
+
* `Content-Type` is left unset on purpose so the browser adds the multipart
|
|
37
|
+
* boundary itself.
|
|
38
|
+
*
|
|
39
|
+
* Known ceiling: this is one request on a 30s token, and re-minting can't
|
|
40
|
+
* help once it is in flight. A zip that takes longer than that to upload will
|
|
41
|
+
* fail — the app origin gets 300s for exactly this reason, and lifting the
|
|
42
|
+
* limit for other origins is a platform-side change.
|
|
43
|
+
*/
|
|
44
|
+
async createBuildFromZip(t, e) {
|
|
45
|
+
const a = await this.getUploadToken();
|
|
46
|
+
if (!a) throw new l();
|
|
47
|
+
const s = new FormData();
|
|
48
|
+
s.append("zip", e), s.append("title", this.title);
|
|
49
|
+
const i = await fetch(`${this.apiBase}/sites/${t}/builds`, {
|
|
50
|
+
method: "POST",
|
|
51
|
+
headers: { Authorization: `Bearer ${a}` },
|
|
52
|
+
body: s
|
|
53
|
+
});
|
|
54
|
+
if (i.status === 401 || i.status === 403) throw new l();
|
|
55
|
+
if (!i.ok) throw new A(i.status);
|
|
56
|
+
return i.json();
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Poll the build's deploy until it settles, mirroring
|
|
60
|
+
* `AnonymousDropClient.waitUntilReady` — resolve on `ready`, throw on
|
|
61
|
+
* `error`/`rejected`, throw on timeout. A build that hasn't been given a
|
|
62
|
+
* deploy id yet has nothing pollable, so it resolves immediately and the
|
|
63
|
+
* caller falls back to the site page.
|
|
64
|
+
*
|
|
65
|
+
* Optional in the drop flow, and off by default: a build takes minutes, so
|
|
66
|
+
* the useful hand-off is usually the project page rather than a spinner.
|
|
67
|
+
* Polling rides the session cookie, so it cannot outlive its credentials the
|
|
68
|
+
* way a 30s bearer would.
|
|
69
|
+
*/
|
|
70
|
+
async waitUntilBuildReady(t) {
|
|
71
|
+
if (!t.deploy_id) return;
|
|
72
|
+
const e = await w({
|
|
73
|
+
proxyBase: this.proxyBase,
|
|
74
|
+
deployId: t.deploy_id,
|
|
75
|
+
pollIntervalMs: this.pollIntervalMs,
|
|
76
|
+
timeoutMs: this.timeoutMs
|
|
77
|
+
});
|
|
78
|
+
if (e.outcome !== "ready")
|
|
79
|
+
throw e.outcome === "failed" ? new E(e.errorMessage) : new M();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
export {
|
|
83
|
+
_ as AuthenticatedBuildClient
|
|
84
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { InferredBuildSettings } from './detectBuild';
|
|
2
|
+
/**
|
|
3
|
+
* Carry a build-required drop across the signup round-trip.
|
|
4
|
+
*
|
|
5
|
+
* A logged-out visitor's drop can't be built (builds have no anonymous
|
|
6
|
+
* equivalent), so before handing them to signup the zone stashes the source
|
|
7
|
+
* archive here — IndexedDB, because the zip is far beyond localStorage's
|
|
8
|
+
* budget. When they return to this origin authenticated, the zone deploys the
|
|
9
|
+
* stash automatically instead of asking them to drop again.
|
|
10
|
+
*
|
|
11
|
+
* Storage is per-origin: a stash written on www.netlify.com can only ever be
|
|
12
|
+
* resumed on www.netlify.com. That is the design, not a limitation — it is
|
|
13
|
+
* exactly why the hand-off page must bring the visitor back here.
|
|
14
|
+
*
|
|
15
|
+
* Every operation is failure-swallowing: the stash is an enhancement, and a
|
|
16
|
+
* browser without IndexedDB (or with a full quota) degrades to the plain
|
|
17
|
+
* signup redirect the zone always supported.
|
|
18
|
+
*/
|
|
19
|
+
export interface DropBuildStash {
|
|
20
|
+
/** The `source.zip` exactly as it would have been uploaded. */
|
|
21
|
+
zipFile: File;
|
|
22
|
+
/** Settings synthesised into the archive's netlify.toml, if any. */
|
|
23
|
+
buildSettings: InferredBuildSettings | null;
|
|
24
|
+
createdAt: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Stash a drop's source archive for an automatic deploy after signup. Returns
|
|
28
|
+
* whether it was actually stored — callers use that only to phrase the
|
|
29
|
+
* hand-off, never to block it.
|
|
30
|
+
*/
|
|
31
|
+
export declare function saveDropStash(zipFile: File, buildSettings?: InferredBuildSettings | null): Promise<boolean>;
|
|
32
|
+
/** The stashed drop, or null when there is none, it expired, or storage is unavailable. */
|
|
33
|
+
export declare function loadDropStash(): Promise<DropBuildStash | null>;
|
|
34
|
+
/** Remove the stash and its marker. Idempotent; never throws. */
|
|
35
|
+
export declare function clearDropStash(): Promise<void>;
|
|
36
|
+
/** Cheap synchronous check so page loads don't open IndexedDB just to look for a stash. */
|
|
37
|
+
export declare function hasDropStashMarker(): boolean;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
const f = "netlify-drop";
|
|
2
|
+
const s = "build-stash", c = "latest", i = "dropBuildStash";
|
|
3
|
+
const S = (e) => Promise.race([
|
|
4
|
+
e,
|
|
5
|
+
new Promise((r, t) => {
|
|
6
|
+
setTimeout(() => t(new Error("IndexedDB operation timed out")), 3e3);
|
|
7
|
+
})
|
|
8
|
+
]), d = () => new Promise((e, r) => {
|
|
9
|
+
const t = indexedDB.open(f, 1);
|
|
10
|
+
t.onupgradeneeded = () => {
|
|
11
|
+
t.result.createObjectStore(s);
|
|
12
|
+
}, t.onsuccess = () => e(t.result), t.onerror = () => r(t.error);
|
|
13
|
+
}), u = (e, r) => S(
|
|
14
|
+
d().then(
|
|
15
|
+
(t) => new Promise((o, a) => {
|
|
16
|
+
const n = r(t.transaction(s, e).objectStore(s));
|
|
17
|
+
n.onsuccess = () => {
|
|
18
|
+
t.close(), o(n.result);
|
|
19
|
+
}, n.onerror = () => {
|
|
20
|
+
t.close(), a(n.error);
|
|
21
|
+
};
|
|
22
|
+
})
|
|
23
|
+
)
|
|
24
|
+
), p = async (e) => {
|
|
25
|
+
const { quota: r, usage: t } = await navigator.storage.estimate();
|
|
26
|
+
return r !== void 0 && t !== void 0 && r - t > e * 2;
|
|
27
|
+
}, T = () => {
|
|
28
|
+
localStorage.setItem(i, JSON.stringify({ expiresAt: Date.now() + 864e5 }));
|
|
29
|
+
}, l = () => {
|
|
30
|
+
localStorage.removeItem(i);
|
|
31
|
+
};
|
|
32
|
+
async function A(e, r = null) {
|
|
33
|
+
var t;
|
|
34
|
+
try {
|
|
35
|
+
if (typeof indexedDB > "u" || !((t = navigator.storage) != null && t.estimate) || e.size > 209715200 || !await p(e.size))
|
|
36
|
+
return !1;
|
|
37
|
+
const o = { zipFile: e, buildSettings: r, createdAt: Date.now() };
|
|
38
|
+
return await u("readwrite", (a) => a.put(o, c)), T(), !0;
|
|
39
|
+
} catch {
|
|
40
|
+
return !1;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async function D() {
|
|
44
|
+
try {
|
|
45
|
+
if (typeof indexedDB > "u") return null;
|
|
46
|
+
const e = await u(
|
|
47
|
+
"readonly",
|
|
48
|
+
(t) => t.get(c)
|
|
49
|
+
), r = e && _(e.zipFile);
|
|
50
|
+
return !e || !r ? null : Date.now() - e.createdAt > 864e5 ? (await y(), null) : { ...e, zipFile: r };
|
|
51
|
+
} catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function _(e) {
|
|
56
|
+
return e instanceof File && e.name ? e : e instanceof Blob || e && typeof e.arrayBuffer == "function" ? new File([e], "source.zip", { type: "application/zip" }) : null;
|
|
57
|
+
}
|
|
58
|
+
async function y() {
|
|
59
|
+
try {
|
|
60
|
+
l();
|
|
61
|
+
} catch {
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
if (typeof indexedDB > "u") return;
|
|
65
|
+
await u("readwrite", (e) => e.delete(c));
|
|
66
|
+
} catch {
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function O() {
|
|
70
|
+
try {
|
|
71
|
+
const e = localStorage.getItem(i);
|
|
72
|
+
if (!e) return !1;
|
|
73
|
+
const { expiresAt: r } = JSON.parse(e);
|
|
74
|
+
return typeof r != "number" || Date.now() > r ? (l(), !1) : !0;
|
|
75
|
+
} catch {
|
|
76
|
+
return !1;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export {
|
|
80
|
+
y as clearDropStash,
|
|
81
|
+
O as hasDropStashMarker,
|
|
82
|
+
D as loadDropStash,
|
|
83
|
+
A as saveDropStash
|
|
84
|
+
};
|
|
File without changes
|
|
@@ -2,6 +2,7 @@ import { BuildClient, BuildResponse, BuildSite } from './buildClient';
|
|
|
2
2
|
import { DropClient } from './client';
|
|
3
3
|
import { InferredBuildSettings } from './detectBuild';
|
|
4
4
|
import { DeployProgress, DeployResult, ProcessedFile } from './types';
|
|
5
|
+
import { ZipResult } from './zip';
|
|
5
6
|
export interface DeployOptions {
|
|
6
7
|
onProgress?: (e: DeployProgress) => void;
|
|
7
8
|
}
|
|
@@ -35,3 +36,9 @@ export interface BuildDeployOptions extends DeployOptions {
|
|
|
35
36
|
* doesn't leave an empty site behind in the user's account.
|
|
36
37
|
*/
|
|
37
38
|
export declare function deployBuild(client: BuildClient, files: ProcessedFile[], opts?: BuildDeployOptions): Promise<BuildDeployResult>;
|
|
39
|
+
/**
|
|
40
|
+
* Deploy an archive that was already zipped — the resume path for a drop
|
|
41
|
+
* stashed across the signup round-trip (see `buildStash`), where `source.zip`
|
|
42
|
+
* and its synthesised settings were produced before the visitor left.
|
|
43
|
+
*/
|
|
44
|
+
export declare function deployZippedBuild(client: BuildClient, { file: zip, buildSettings }: ZipResult, opts?: BuildDeployOptions): Promise<BuildDeployResult>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { getDigest as w } from "./digest.js";
|
|
2
|
+
import { zipFiles as y } from "./zip.js";
|
|
3
|
+
const r = 5;
|
|
4
|
+
async function f(i, n, p, a, t, e) {
|
|
5
|
+
const l = p.filter((h) => a.has(h.sha));
|
|
6
|
+
let u = 0, c = 0;
|
|
7
|
+
const d = async () => {
|
|
8
|
+
for (; u < l.length; ) {
|
|
9
|
+
const h = l[u++];
|
|
10
|
+
await i.uploadFile(n, h.path, h.content, t), e == null || e(++c);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
await Promise.all(Array.from({ length: Math.min(r, l.length) }, d));
|
|
14
|
+
}
|
|
15
|
+
async function B(i, n, p = {}) {
|
|
16
|
+
if (!n.length) throw new Error("No files to deploy");
|
|
17
|
+
const { onProgress: a } = p;
|
|
18
|
+
a == null || a({ phase: "creating" });
|
|
19
|
+
const t = await i.getToken(), e = await i.createDeploy(w(n), t), l = e.required.length;
|
|
20
|
+
return a == null || a({ phase: "uploading", uploaded: 0, total: l }), await f(
|
|
21
|
+
i,
|
|
22
|
+
e.deploy_id,
|
|
23
|
+
n,
|
|
24
|
+
new Set(e.required),
|
|
25
|
+
t,
|
|
26
|
+
(u) => a == null ? void 0 : a({ phase: "uploading", uploaded: u, total: l })
|
|
27
|
+
), a == null || a({ phase: "processing" }), await i.waitUntilReady(e, t), a == null || a({ phase: "ready" }), { deploy: e, token: t, url: `https://${e.subdomain}.netlify.app` };
|
|
28
|
+
}
|
|
29
|
+
async function F(i, n, p = {}) {
|
|
30
|
+
var t;
|
|
31
|
+
if (!n.length) throw new Error("No files to deploy");
|
|
32
|
+
(t = p.onProgress) == null || t.call(p, { phase: "zipping" });
|
|
33
|
+
const a = await y(n);
|
|
34
|
+
return o(i, a, p);
|
|
35
|
+
}
|
|
36
|
+
async function o(i, { file: n, buildSettings: p }, a = {}) {
|
|
37
|
+
const { onProgress: t, waitForBuild: e = !1 } = a;
|
|
38
|
+
t == null || t({ phase: "creating" });
|
|
39
|
+
const l = await i.createSite();
|
|
40
|
+
t == null || t({ phase: "uploading" });
|
|
41
|
+
const u = await i.createBuildFromZip(l.id, n);
|
|
42
|
+
return t == null || t({ phase: "building" }), e && await i.waitUntilBuildReady(u), t == null || t({ phase: "ready" }), {
|
|
43
|
+
site: l,
|
|
44
|
+
build: u,
|
|
45
|
+
buildSettings: p,
|
|
46
|
+
url: l.ssl_url || l.url || `https://${l.name}.netlify.app`
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export {
|
|
50
|
+
F as deployBuild,
|
|
51
|
+
B as deployFiles,
|
|
52
|
+
o as deployZippedBuild
|
|
53
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -40,7 +40,7 @@ function h(e) {
|
|
|
40
40
|
if (e instanceof o)
|
|
41
41
|
return "To deploy, drop a folder or a .zip file — or a single HTML page.";
|
|
42
42
|
if (e instanceof s)
|
|
43
|
-
return "Please log in to Netlify to deploy
|
|
43
|
+
return "Please log in to Netlify to deploy this project, then try again.";
|
|
44
44
|
if (e instanceof u)
|
|
45
45
|
return "We couldn't create a project for this build. Please try again.";
|
|
46
46
|
if (e instanceof l)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -4,8 +4,11 @@ export * from './readFiles';
|
|
|
4
4
|
export * from './fileTypes';
|
|
5
5
|
export * from './detectBuild';
|
|
6
6
|
export * from './client';
|
|
7
|
+
export * from './authedApi';
|
|
7
8
|
export * from './authedDropClient';
|
|
8
9
|
export * from './buildClient';
|
|
9
10
|
export * from './zip';
|
|
11
|
+
export * from './buildStash';
|
|
10
12
|
export * from './deploy';
|
|
11
13
|
export * from './errors';
|
|
14
|
+
export * from './analytics';
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { getDigest as o } from "./digest.js";
|
|
2
|
+
import { getSingleNonIndexHtmlFileName as i, hasMultipleHtmlFilesWithoutIndex as l, readDataTransfer as p, readFileList as a, renameSingleNonIndexHtmlToIndex as d } from "./readFiles.js";
|
|
3
|
+
import { getFileTypes as m } from "./fileTypes.js";
|
|
4
|
+
import { detectBuild as u, inferBuildSettings as s } from "./detectBuild.js";
|
|
5
|
+
import { AnonymousDropClient as f, apiError as D } from "./client.js";
|
|
6
|
+
import { DEFAULT_API_BASE as A, DEFAULT_POLL_INTERVAL_MS as T, DEFAULT_PROXY_BASE as h, DEFAULT_TIMEOUT_MS as F, createSiteInAccount as B, pollDeployUntilSettled as _ } from "./authedApi.js";
|
|
7
|
+
import { AuthenticatedDropClient as g } from "./authedDropClient.js";
|
|
8
|
+
import { AuthenticatedBuildClient as L } from "./buildClient.js";
|
|
9
|
+
import { generateNetlifyToml as y, zipFiles as U } from "./zip.js";
|
|
10
|
+
import { clearDropStash as M, hasDropStashMarker as O, loadDropStash as P, saveDropStash as H } from "./buildStash.js";
|
|
11
|
+
import { deployBuild as z, deployFiles as V, deployZippedBuild as Z } from "./deploy.js";
|
|
12
|
+
import { BuildCreateError as v, BuildFailedError as W, BuildTimeoutError as X, NotAuthenticatedError as Y, SiteCreateError as b, UnsupportedDropError as j, humanizeDropError as q } from "./errors.js";
|
|
13
|
+
import { DROPZONE_EVENTS as G } from "./analytics.js";
|
|
14
|
+
export {
|
|
15
|
+
f as AnonymousDropClient,
|
|
16
|
+
L as AuthenticatedBuildClient,
|
|
17
|
+
g as AuthenticatedDropClient,
|
|
18
|
+
v as BuildCreateError,
|
|
19
|
+
W as BuildFailedError,
|
|
20
|
+
X as BuildTimeoutError,
|
|
21
|
+
A as DEFAULT_API_BASE,
|
|
22
|
+
T as DEFAULT_POLL_INTERVAL_MS,
|
|
23
|
+
h as DEFAULT_PROXY_BASE,
|
|
24
|
+
F as DEFAULT_TIMEOUT_MS,
|
|
25
|
+
G as DROPZONE_EVENTS,
|
|
26
|
+
Y as NotAuthenticatedError,
|
|
27
|
+
b as SiteCreateError,
|
|
28
|
+
j as UnsupportedDropError,
|
|
29
|
+
D as apiError,
|
|
30
|
+
M as clearDropStash,
|
|
31
|
+
B as createSiteInAccount,
|
|
32
|
+
z as deployBuild,
|
|
33
|
+
V as deployFiles,
|
|
34
|
+
Z as deployZippedBuild,
|
|
35
|
+
u as detectBuild,
|
|
36
|
+
y as generateNetlifyToml,
|
|
37
|
+
o as getDigest,
|
|
38
|
+
m as getFileTypes,
|
|
39
|
+
i as getSingleNonIndexHtmlFileName,
|
|
40
|
+
O as hasDropStashMarker,
|
|
41
|
+
l as hasMultipleHtmlFilesWithoutIndex,
|
|
42
|
+
q as humanizeDropError,
|
|
43
|
+
s as inferBuildSettings,
|
|
44
|
+
P as loadDropStash,
|
|
45
|
+
_ as pollDeployUntilSettled,
|
|
46
|
+
p as readDataTransfer,
|
|
47
|
+
a as readFileList,
|
|
48
|
+
d as renameSingleNonIndexHtmlToIndex,
|
|
49
|
+
H as saveDropStash,
|
|
50
|
+
U as zipFiles
|
|
51
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as P } from "
|
|
1
|
+
import { g as P } from "../chunks/_commonjsHelpers.C6fGbg64.js";
|
|
2
2
|
import { UnsupportedDropError as U } from "./errors.js";
|
|
3
3
|
var L = { exports: {} }, G = L.exports, D;
|
|
4
4
|
function J() {
|
|
@@ -579,7 +579,7 @@ async function Q(y) {
|
|
|
579
579
|
return M(w);
|
|
580
580
|
}
|
|
581
581
|
async function I(y) {
|
|
582
|
-
const { unzip: m } = await import("
|
|
582
|
+
const { unzip: m } = await import("../chunks/browser.Ca2rTNTu.js"), w = new Uint8Array(await y.arrayBuffer()), _ = await new Promise(
|
|
583
583
|
(v, s) => m(w, (g, u) => g ? s(g) : v(u))
|
|
584
584
|
), h = [];
|
|
585
585
|
for (const [v, s] of Object.entries(_)) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -41,3 +41,13 @@ export interface DeployProgress {
|
|
|
41
41
|
uploaded?: number;
|
|
42
42
|
total?: number;
|
|
43
43
|
}
|
|
44
|
+
/** The subset of a Netlify Site the drop flow needs to redirect and report. */
|
|
45
|
+
export interface BuildSite {
|
|
46
|
+
/** site id (UUID) */
|
|
47
|
+
id: string;
|
|
48
|
+
/** the *.netlify.app subdomain, also the app's URL segment */
|
|
49
|
+
name: string;
|
|
50
|
+
/** https://<name>.netlify.app */
|
|
51
|
+
ssl_url?: string;
|
|
52
|
+
url?: string;
|
|
53
|
+
}
|
|
@@ -29,7 +29,7 @@ async function $(e, { name: i = "source.zip", synthesizeNetlifyToml: p = !0 } =
|
|
|
29
29
|
${n}` : n;
|
|
30
30
|
l["netlify.toml"] = m.encode(c);
|
|
31
31
|
}
|
|
32
|
-
const { zip: f } = await import("
|
|
32
|
+
const { zip: f } = await import("../chunks/browser.Ca2rTNTu.js"), o = await new Promise(
|
|
33
33
|
(t, n) => f(l, { level: 6 }, (c, s) => c ? n(c) : t(s))
|
|
34
34
|
), u = o.buffer.slice(
|
|
35
35
|
o.byteOffset,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@netlify/spark-ui",
|
|
3
3
|
"description": "Assets, design tokens, components, and utilities",
|
|
4
|
-
"version": "1.31.0-alpha.
|
|
4
|
+
"version": "1.31.0-alpha.4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/components/preact/index.js",
|
|
7
7
|
"types": "dist/components/preact/index.d.ts",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
],
|
|
27
27
|
"exports": {
|
|
28
28
|
"./preact": "./dist/components/preact/index.js",
|
|
29
|
+
"./drop-core": "./dist/drop-core/index.js",
|
|
29
30
|
"./assets/*.css": "./dist/assets/*.css",
|
|
30
31
|
"./assets/icons/*.svg": "./packages/assets/icons/*.svg",
|
|
31
32
|
"./logos/*.svg": "./packages/assets/logos/*.svg",
|
|
@@ -61,7 +62,9 @@
|
|
|
61
62
|
"eslint": "^10.0.0",
|
|
62
63
|
"eslint-config-prettier": "^10.1.1",
|
|
63
64
|
"eslint-plugin-astro": "^1.3.1",
|
|
65
|
+
"fake-indexeddb": "^6.2.5",
|
|
64
66
|
"glob": "^11.0.1",
|
|
67
|
+
"happy-dom": "^20.11.6",
|
|
65
68
|
"jsdom": "^30.0.0",
|
|
66
69
|
"preact": "^10.26.4",
|
|
67
70
|
"prettier": "^3.5.3",
|
|
@@ -11,6 +11,15 @@ export {
|
|
|
11
11
|
AnonymousDropClient,
|
|
12
12
|
AuthenticatedBuildClient,
|
|
13
13
|
AuthenticatedDropClient,
|
|
14
|
+
BuildCreateError,
|
|
15
|
+
BuildFailedError,
|
|
16
|
+
BuildTimeoutError,
|
|
17
|
+
DROPZONE_EVENTS,
|
|
18
|
+
getFileTypes,
|
|
19
|
+
humanizeDropError,
|
|
20
|
+
NotAuthenticatedError,
|
|
21
|
+
SiteCreateError,
|
|
22
|
+
UnsupportedDropError,
|
|
14
23
|
deployBuild,
|
|
15
24
|
deployFiles,
|
|
16
25
|
detectBuild,
|
|
@@ -23,6 +32,16 @@ export type {
|
|
|
23
32
|
AuthenticatedBuildClientConfig,
|
|
24
33
|
AuthenticatedDropClientConfig,
|
|
25
34
|
BuildClient,
|
|
35
|
+
BuildDeployOptions,
|
|
36
|
+
BuildReason,
|
|
37
|
+
BuildResponse,
|
|
38
|
+
DeployError,
|
|
39
|
+
DeployStatus,
|
|
40
|
+
DropZoneEventName,
|
|
41
|
+
DropZoneEventProperties,
|
|
42
|
+
TrackFn,
|
|
43
|
+
ZipOptions,
|
|
44
|
+
ZipResult,
|
|
26
45
|
BuildDeployResult,
|
|
27
46
|
BuildDetection,
|
|
28
47
|
BuildSite,
|