@netlify/spark-ui 1.31.0-alpha.3 → 1.31.0-alpha.5
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 +27 -9
- 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 +29 -27
- package/dist/components/preact/DropZone/useDropDeploy.d.ts +9 -6
- package/dist/components/preact/DropZone/useDropDeploy.js +182 -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 +24 -18
- 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 +45 -0
- package/dist/drop-core/authedApi.js +30 -0
- package/dist/drop-core/authedApi.test.d.ts +1 -0
- package/dist/{components/preact/DropZone/drop-core → drop-core}/authedDropClient.d.ts +4 -11
- package/dist/drop-core/authedDropClient.js +100 -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 +85 -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}/client.d.ts +3 -1
- package/dist/drop-core/client.js +47 -0
- package/dist/drop-core/constants.d.ts +29 -0
- package/dist/drop-core/constants.js +10 -0
- package/dist/{components/preact/DropZone/drop-core → drop-core}/deploy.d.ts +9 -0
- package/dist/drop-core/deploy.js +66 -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.d.ts +29 -0
- package/dist/drop-core/errors.js +119 -0
- package/dist/drop-core/errors.test.d.ts +1 -0
- package/dist/drop-core/fileTypes.test.d.ts +1 -0
- package/dist/drop-core/index.d.ts +25 -0
- package/dist/drop-core/index.js +47 -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 +29 -9
- 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 +301 -145
- package/packages/components/preact/index.ts +19 -2
- package/packages/drop-core/README.md +91 -0
- 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 +81 -0
- package/packages/drop-core/authedDropClient.test.ts +196 -0
- package/packages/{components/preact/DropZone/drop-core → drop-core}/authedDropClient.ts +30 -72
- package/packages/drop-core/buildClient.test.ts +112 -0
- package/packages/{components/preact/DropZone/drop-core → drop-core}/buildClient.ts +27 -57
- package/packages/drop-core/buildStash.test.ts +85 -0
- package/packages/drop-core/buildStash.ts +185 -0
- package/packages/{components/preact/DropZone/drop-core → drop-core}/client.ts +18 -6
- package/packages/drop-core/constants.ts +39 -0
- package/packages/drop-core/deploy.test.ts +177 -0
- package/packages/{components/preact/DropZone/drop-core → drop-core}/deploy.ts +59 -9
- 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 +98 -0
- package/packages/{components/preact/DropZone/drop-core → drop-core}/errors.ts +68 -11
- package/packages/drop-core/fileTypes.test.ts +37 -0
- package/packages/drop-core/index.ts +44 -0
- package/packages/drop-core/readFiles.test.ts +124 -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/client.js +0 -45
- package/dist/components/preact/DropZone/drop-core/deploy.js +0 -48
- package/dist/components/preact/DropZone/drop-core/errors.js +0 -82
- package/dist/components/preact/DropZone/drop-core/index.d.ts +0 -11
- package/dist/components/preact/DropZone/drop-core/index.js +0 -36
- package/packages/components/preact/DropZone/drop-core/index.ts +0 -11
- /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}/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}/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,119 @@
|
|
|
1
|
+
var a = Object.defineProperty;
|
|
2
|
+
var n = (e, r, t) => r in e ? a(e, r, { enumerable: !0, configurable: !0, writable: !0, value: t }) : e[r] = t;
|
|
3
|
+
var o = (e, r, t) => n(e, typeof r != "symbol" ? r + "" : r, t);
|
|
4
|
+
class l extends Error {
|
|
5
|
+
constructor() {
|
|
6
|
+
super("unsupported single file");
|
|
7
|
+
o(this, "code", "unsupported-drop");
|
|
8
|
+
this.name = "UnsupportedDropError";
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
class s extends Error {
|
|
12
|
+
constructor(t = "not authenticated") {
|
|
13
|
+
super(t);
|
|
14
|
+
o(this, "code", "not-authenticated");
|
|
15
|
+
this.name = "NotAuthenticatedError";
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function u(e) {
|
|
19
|
+
return e instanceof s ? !0 : e instanceof Error && e.code === "not-authenticated";
|
|
20
|
+
}
|
|
21
|
+
class c extends Error {
|
|
22
|
+
constructor(t) {
|
|
23
|
+
super(`site create failed${t ? `: ${t}` : ""}`);
|
|
24
|
+
o(this, "code", "site-create-failed");
|
|
25
|
+
o(this, "status");
|
|
26
|
+
this.name = "SiteCreateError", this.status = t;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
class p extends Error {
|
|
30
|
+
constructor(t) {
|
|
31
|
+
super(`build create failed${t ? `: ${t}` : ""}`);
|
|
32
|
+
o(this, "code", "build-create-failed");
|
|
33
|
+
o(this, "status");
|
|
34
|
+
this.name = "BuildCreateError", this.status = t;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
class f extends Error {
|
|
38
|
+
constructor(t) {
|
|
39
|
+
super(t ? `build failed: ${t}` : "build failed");
|
|
40
|
+
o(this, "code", "build-failed");
|
|
41
|
+
this.reason = t, this.name = "BuildFailedError";
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
class y extends Error {
|
|
45
|
+
constructor() {
|
|
46
|
+
super("Build did not finish in time");
|
|
47
|
+
o(this, "code", "build-timeout");
|
|
48
|
+
this.name = "BuildTimeoutError";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
class h extends Error {
|
|
52
|
+
constructor(t) {
|
|
53
|
+
super(t ? `deploy failed: ${t}` : "deploy failed");
|
|
54
|
+
o(this, "code", "deploy-failed");
|
|
55
|
+
this.reason = t, this.name = "DeployFailedError";
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
class g extends Error {
|
|
59
|
+
constructor() {
|
|
60
|
+
super("Deploy did not become ready in time");
|
|
61
|
+
o(this, "code", "deploy-timeout");
|
|
62
|
+
this.name = "DeployTimeoutError";
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function m(e) {
|
|
66
|
+
if (!(e instanceof Error)) return "Something went wrong. Please try again.";
|
|
67
|
+
const r = e.code;
|
|
68
|
+
if (r === "unsupported-drop")
|
|
69
|
+
return "To deploy, drop a folder or a .zip file — or a single HTML page.";
|
|
70
|
+
if (r === "not-authenticated")
|
|
71
|
+
return "Please log in to Netlify to deploy this project, then try again.";
|
|
72
|
+
if (r === "site-create-failed")
|
|
73
|
+
return "We couldn't create a project for this build. Please try again.";
|
|
74
|
+
if (r === "build-failed") {
|
|
75
|
+
const i = e.reason;
|
|
76
|
+
return i ? `Your build failed: ${i}` : "Your build failed. Check your build settings and try again.";
|
|
77
|
+
}
|
|
78
|
+
if (r === "deploy-failed") {
|
|
79
|
+
const i = e.reason;
|
|
80
|
+
return i ? `Your deploy failed: ${i}` : "Your deploy failed. Please try again.";
|
|
81
|
+
}
|
|
82
|
+
if (r === "build-timeout")
|
|
83
|
+
return "Your build is taking longer than expected. It may still finish — check your Netlify dashboard.";
|
|
84
|
+
if (r === "deploy-timeout")
|
|
85
|
+
return "Your site is taking longer than expected to go live. Please try again in a moment.";
|
|
86
|
+
if (e instanceof TypeError)
|
|
87
|
+
return "Couldn't connect to Netlify. Check your internet connection and try again.";
|
|
88
|
+
const t = "status" in e && typeof e.status == "number" ? e.status : void 0;
|
|
89
|
+
switch (t) {
|
|
90
|
+
case 429:
|
|
91
|
+
return "Too many attempts — please wait a moment and try again.";
|
|
92
|
+
case 413:
|
|
93
|
+
return "Your upload is too large to deploy this way.";
|
|
94
|
+
case 404:
|
|
95
|
+
return "We couldn't find that deploy. Please try again.";
|
|
96
|
+
case 401:
|
|
97
|
+
case 403:
|
|
98
|
+
return "That request wasn't allowed. Please try again.";
|
|
99
|
+
case 500:
|
|
100
|
+
case 502:
|
|
101
|
+
case 503:
|
|
102
|
+
case 504:
|
|
103
|
+
return "Netlify's servers are having trouble right now. Please try again shortly.";
|
|
104
|
+
default:
|
|
105
|
+
return t ? "Something went wrong talking to Netlify. Please try again." : "Something went wrong. Please try again.";
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export {
|
|
109
|
+
p as BuildCreateError,
|
|
110
|
+
f as BuildFailedError,
|
|
111
|
+
y as BuildTimeoutError,
|
|
112
|
+
h as DeployFailedError,
|
|
113
|
+
g as DeployTimeoutError,
|
|
114
|
+
s as NotAuthenticatedError,
|
|
115
|
+
c as SiteCreateError,
|
|
116
|
+
l as UnsupportedDropError,
|
|
117
|
+
m as humanizeDropError,
|
|
118
|
+
u as isNotAuthenticatedError
|
|
119
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The public surface of drop-core — nothing is public unless named here.
|
|
3
|
+
* `export *` is reserved for the three modules that are contracts in their
|
|
4
|
+
* entirety: types, errors, and the analytics event map.
|
|
5
|
+
*/
|
|
6
|
+
export * from './types';
|
|
7
|
+
export * from './errors';
|
|
8
|
+
export * from './analytics';
|
|
9
|
+
export { getSingleNonIndexHtmlFileName, hasMultipleHtmlFilesWithoutIndex, readDataTransfer, readFileList, renameSingleNonIndexHtmlToIndex, } from './readFiles';
|
|
10
|
+
export { getFileTypes } from './fileTypes';
|
|
11
|
+
export { detectBuild, inferBuildSettings } from './detectBuild';
|
|
12
|
+
export type { BuildDetection, BuildReason, InferredBuildSettings } from './detectBuild';
|
|
13
|
+
export { zipFiles } from './zip';
|
|
14
|
+
export type { ZipOptions, ZipResult } from './zip';
|
|
15
|
+
export { AnonymousDropClient } from './client';
|
|
16
|
+
export type { DropClient } from './client';
|
|
17
|
+
export { AuthenticatedDropClient } from './authedDropClient';
|
|
18
|
+
export type { AuthenticatedDropClientConfig } from './authedDropClient';
|
|
19
|
+
export { AuthenticatedBuildClient } from './buildClient';
|
|
20
|
+
export type { AuthenticatedBuildClientConfig, BuildClient, BuildResponse } from './buildClient';
|
|
21
|
+
export { deployBuild, deployFiles, deployZippedBuild } from './deploy';
|
|
22
|
+
export type { BuildDeployOptions, BuildDeployResult, DeployOptions } from './deploy';
|
|
23
|
+
export { clearDropStash, hasDropStashMarker, loadDropStash, saveDropStash } from './buildStash';
|
|
24
|
+
export type { DropBuildStash } from './buildStash';
|
|
25
|
+
export { DEFAULT_API_BASE, DEFAULT_PROXY_BASE, UPLOAD_RETRY_DELAYS_MS } from './constants';
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { BuildCreateError as o, BuildFailedError as t, BuildTimeoutError as i, DeployFailedError as l, DeployTimeoutError as p, NotAuthenticatedError as d, SiteCreateError as a, UnsupportedDropError as n, humanizeDropError as m, isNotAuthenticatedError as u } from "./errors.js";
|
|
2
|
+
import { DROPZONE_EVENTS as s } from "./analytics.js";
|
|
3
|
+
import { getSingleNonIndexHtmlFileName as D, hasMultipleHtmlFilesWithoutIndex as f, readDataTransfer as S, readFileList as h, renameSingleNonIndexHtmlToIndex as A } from "./readFiles.js";
|
|
4
|
+
import { getFileTypes as F } from "./fileTypes.js";
|
|
5
|
+
import { detectBuild as _, inferBuildSettings as y } from "./detectBuild.js";
|
|
6
|
+
import { zipFiles as c } from "./zip.js";
|
|
7
|
+
import { AnonymousDropClient as C } from "./client.js";
|
|
8
|
+
import { AuthenticatedDropClient as L } from "./authedDropClient.js";
|
|
9
|
+
import { AuthenticatedBuildClient as P } from "./buildClient.js";
|
|
10
|
+
import { deployBuild as U, deployFiles as H, deployZippedBuild as M } from "./deploy.js";
|
|
11
|
+
import { clearDropStash as z, hasDropStashMarker as Z, loadDropStash as k, saveDropStash as v } from "./buildStash.js";
|
|
12
|
+
import { DEFAULT_API_BASE as W, DEFAULT_PROXY_BASE as X, UPLOAD_RETRY_DELAYS_MS as b } from "./constants.js";
|
|
13
|
+
export {
|
|
14
|
+
C as AnonymousDropClient,
|
|
15
|
+
P as AuthenticatedBuildClient,
|
|
16
|
+
L as AuthenticatedDropClient,
|
|
17
|
+
o as BuildCreateError,
|
|
18
|
+
t as BuildFailedError,
|
|
19
|
+
i as BuildTimeoutError,
|
|
20
|
+
W as DEFAULT_API_BASE,
|
|
21
|
+
X as DEFAULT_PROXY_BASE,
|
|
22
|
+
s as DROPZONE_EVENTS,
|
|
23
|
+
l as DeployFailedError,
|
|
24
|
+
p as DeployTimeoutError,
|
|
25
|
+
d as NotAuthenticatedError,
|
|
26
|
+
a as SiteCreateError,
|
|
27
|
+
b as UPLOAD_RETRY_DELAYS_MS,
|
|
28
|
+
n as UnsupportedDropError,
|
|
29
|
+
z as clearDropStash,
|
|
30
|
+
U as deployBuild,
|
|
31
|
+
H as deployFiles,
|
|
32
|
+
M as deployZippedBuild,
|
|
33
|
+
_ as detectBuild,
|
|
34
|
+
F as getFileTypes,
|
|
35
|
+
D as getSingleNonIndexHtmlFileName,
|
|
36
|
+
Z as hasDropStashMarker,
|
|
37
|
+
f as hasMultipleHtmlFilesWithoutIndex,
|
|
38
|
+
m as humanizeDropError,
|
|
39
|
+
y as inferBuildSettings,
|
|
40
|
+
u as isNotAuthenticatedError,
|
|
41
|
+
k as loadDropStash,
|
|
42
|
+
S as readDataTransfer,
|
|
43
|
+
h as readFileList,
|
|
44
|
+
A as renameSingleNonIndexHtmlToIndex,
|
|
45
|
+
v as saveDropStash,
|
|
46
|
+
c as zipFiles
|
|
47
|
+
};
|
|
@@ -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.5",
|
|
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,
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// @vitest-environment happy-dom
|
|
2
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
import { h, render } from 'preact';
|
|
4
|
+
import DropZone from './DropZone';
|
|
5
|
+
|
|
6
|
+
function mountZone(props: Record<string, unknown> = {}) {
|
|
7
|
+
const events: Array<{ event: string; props: Record<string, unknown> | undefined }> = [];
|
|
8
|
+
const container = document.createElement('div');
|
|
9
|
+
document.body.appendChild(container);
|
|
10
|
+
render(
|
|
11
|
+
h(DropZone as never, {
|
|
12
|
+
onTrack: (event: string, properties?: Record<string, unknown>) =>
|
|
13
|
+
void events.push({ event, props: properties }),
|
|
14
|
+
...props,
|
|
15
|
+
}),
|
|
16
|
+
container
|
|
17
|
+
);
|
|
18
|
+
const zone = container.querySelector<HTMLElement>('.n-dropzone')!;
|
|
19
|
+
return {
|
|
20
|
+
events,
|
|
21
|
+
zone,
|
|
22
|
+
unmount: () => {
|
|
23
|
+
render(null, container);
|
|
24
|
+
container.remove();
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
afterEach(() => vi.restoreAllMocks());
|
|
30
|
+
|
|
31
|
+
describe('DropZone', () => {
|
|
32
|
+
it('opens the picker from the keyboard and tracks it as such', () => {
|
|
33
|
+
const { zone, events, unmount } = mountZone();
|
|
34
|
+
zone.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));
|
|
35
|
+
expect(events).toEqual([{ event: 'dropzone_browse_opened', props: { method: 'keyboard' } }]);
|
|
36
|
+
unmount();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("opens the picker from a click on the zone's own empty area", () => {
|
|
40
|
+
const { zone, events, unmount } = mountZone();
|
|
41
|
+
zone.dispatchEvent(new MouseEvent('click', { bubbles: true }));
|
|
42
|
+
expect(events).toEqual([{ event: 'dropzone_browse_opened', props: { method: 'click' } }]);
|
|
43
|
+
unmount();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('stamps dropzone_id onto every event when analyticsId is set — and only then', () => {
|
|
47
|
+
const tagged = mountZone({ analyticsId: 'homepage_hero' });
|
|
48
|
+
tagged.zone.dispatchEvent(new KeyboardEvent('keydown', { key: ' ', bubbles: true }));
|
|
49
|
+
expect(tagged.events[0].props).toEqual({ dropzone_id: 'homepage_hero', method: 'keyboard' });
|
|
50
|
+
tagged.unmount();
|
|
51
|
+
|
|
52
|
+
const untagged = mountZone();
|
|
53
|
+
untagged.zone.dispatchEvent(new KeyboardEvent('keydown', { key: ' ', bubbles: true }));
|
|
54
|
+
expect(untagged.events[0].props).not.toHaveProperty('dropzone_id');
|
|
55
|
+
untagged.unmount();
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('mirrors the deploy status on data-state for bare-mode consumers', () => {
|
|
59
|
+
const { zone, unmount } = mountZone({ showStatus: false });
|
|
60
|
+
// Idle at rest — the attribute CSS keys off (`[data-state='error']` etc.).
|
|
61
|
+
expect(zone.getAttribute('data-state')).toBe('idle');
|
|
62
|
+
expect(zone.className).toContain('is-bare');
|
|
63
|
+
unmount();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('renders no overlay until there is something to show', () => {
|
|
67
|
+
const { zone, unmount } = mountZone();
|
|
68
|
+
expect(zone.querySelector('.n-dropzone-overlay')).toBeNull();
|
|
69
|
+
unmount();
|
|
70
|
+
});
|
|
71
|
+
});
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
|
2
2
|
import type { ComponentChildren } from 'preact';
|
|
3
3
|
import {
|
|
4
|
+
DROPZONE_EVENTS,
|
|
4
5
|
getFileTypes,
|
|
5
6
|
readDataTransfer,
|
|
6
7
|
readFileList,
|
|
7
8
|
type BuildClient,
|
|
8
9
|
type BuildDetection,
|
|
9
10
|
type DropClient,
|
|
10
|
-
} from '
|
|
11
|
+
} from '../../../drop-core';
|
|
11
12
|
import {
|
|
12
13
|
useDropDeploy,
|
|
13
14
|
type DeployedBuild,
|
|
@@ -63,12 +64,11 @@ interface Props {
|
|
|
63
64
|
*/
|
|
64
65
|
siteDashboardUrl?: (siteName: string) => string;
|
|
65
66
|
/**
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
* point at your own destination.
|
|
67
|
+
* The signup hand-off for a build-required drop that can't be built here (no
|
|
68
|
+
* session, or no build wiring). The drop is stashed on this origin first, so
|
|
69
|
+
* a flow that returns the visitor to this page deploys it automatically —
|
|
70
|
+
* see `resumeStashedBuilds`. Defaults to the app signup page with
|
|
71
|
+
* `next=/drop`.
|
|
72
72
|
*/
|
|
73
73
|
buildSignupUrl?: string;
|
|
74
74
|
/**
|
|
@@ -78,7 +78,7 @@ interface Props {
|
|
|
78
78
|
* build-required drops build in place instead of being handed off to the app.
|
|
79
79
|
* On netlify.com this reads `GET /access-control/generate-access-control-token`.
|
|
80
80
|
* Resolving `null` means "no session": static drops fall back to the anonymous
|
|
81
|
-
* claim flow
|
|
81
|
+
* claim flow; build drops are stashed and handed to `buildSignupUrl`.
|
|
82
82
|
* See [Logged-in visitors](#logged-in-visitors).
|
|
83
83
|
*/
|
|
84
84
|
getUploadToken?: () => Promise<string | null>;
|
|
@@ -123,6 +123,22 @@ interface Props {
|
|
|
123
123
|
* redirects. The static drop path is unaffected either way.
|
|
124
124
|
*/
|
|
125
125
|
onBuildRequired?: (info: BuildDetection) => void;
|
|
126
|
+
/**
|
|
127
|
+
* Called instead of the `buildSignupUrl` redirect when a build-required drop
|
|
128
|
+
* can't be built here (no session). By this point the drop has been stashed
|
|
129
|
+
* on this origin (`stashed` says whether that succeeded) — own the hand-off
|
|
130
|
+
* however fits your auth flow, e.g. open a signup popup that keeps the
|
|
131
|
+
* visitor on the page. Once they're back authenticated, a remount of the
|
|
132
|
+
* zone deploys the stash automatically.
|
|
133
|
+
*/
|
|
134
|
+
onBuildSignupHandoff?: (info: { stashed: boolean; detection: BuildDetection }) => void;
|
|
135
|
+
/**
|
|
136
|
+
* Deploy a previously stashed build drop automatically when the zone mounts
|
|
137
|
+
* with an authenticated visitor (default `true`). The stash is written when a
|
|
138
|
+
* logged-out build drop is handed to signup; see
|
|
139
|
+
* [Signup hand-off and auto-resume](#signup-hand-off-and-auto-resume).
|
|
140
|
+
*/
|
|
141
|
+
resumeStashedBuilds?: boolean;
|
|
126
142
|
/** Called once the deploy is live. */
|
|
127
143
|
onDeploy?: (result: DeployedSite) => void;
|
|
128
144
|
/**
|
|
@@ -192,6 +208,8 @@ export default function DropZone({
|
|
|
192
208
|
buildDeployUrl = defaultBuildDeployUrl,
|
|
193
209
|
waitForBuild,
|
|
194
210
|
onBuildRequired,
|
|
211
|
+
onBuildSignupHandoff,
|
|
212
|
+
resumeStashedBuilds,
|
|
195
213
|
onDeploy,
|
|
196
214
|
onBuildDeploy,
|
|
197
215
|
onError,
|
|
@@ -219,6 +237,8 @@ export default function DropZone({
|
|
|
219
237
|
buildDeployUrl,
|
|
220
238
|
waitForBuild,
|
|
221
239
|
onBuildRequired,
|
|
240
|
+
onBuildSignupHandoff,
|
|
241
|
+
resumeStashedBuilds,
|
|
222
242
|
onDeploy,
|
|
223
243
|
onBuildDeploy,
|
|
224
244
|
onError,
|
|
@@ -229,7 +249,7 @@ export default function DropZone({
|
|
|
229
249
|
|
|
230
250
|
const inputRef = useRef<HTMLInputElement>(null);
|
|
231
251
|
const openPicker = (method: 'keyboard' | 'click') => {
|
|
232
|
-
track(
|
|
252
|
+
track(DROPZONE_EVENTS.BROWSE_OPENED, { method });
|
|
233
253
|
inputRef.current?.click();
|
|
234
254
|
};
|
|
235
255
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { default as DropZone } from './DropZone';
|
|
2
2
|
export {
|
|
3
3
|
AnonymousDropClient,
|
|
4
|
+
DROPZONE_EVENTS,
|
|
4
5
|
AuthenticatedBuildClient,
|
|
5
6
|
AuthenticatedDropClient,
|
|
6
7
|
BuildCreateError,
|
|
@@ -18,9 +19,13 @@ export {
|
|
|
18
19
|
SiteCreateError,
|
|
19
20
|
UnsupportedDropError,
|
|
20
21
|
zipFiles,
|
|
21
|
-
} from '
|
|
22
|
+
} from '../../../drop-core';
|
|
22
23
|
export type {
|
|
23
24
|
AuthenticatedBuildClientConfig,
|
|
25
|
+
DropMethod,
|
|
26
|
+
DropZoneEventName,
|
|
27
|
+
DropZoneEventProperties,
|
|
28
|
+
TrackFn,
|
|
24
29
|
AuthenticatedDropClientConfig,
|
|
25
30
|
BuildClient,
|
|
26
31
|
BuildDeployOptions,
|
|
@@ -39,5 +44,11 @@ export type {
|
|
|
39
44
|
ProcessedFile,
|
|
40
45
|
ZipOptions,
|
|
41
46
|
ZipResult,
|
|
42
|
-
} from '
|
|
43
|
-
export type {
|
|
47
|
+
} from '../../../drop-core';
|
|
48
|
+
export type {
|
|
49
|
+
DeployedBuild,
|
|
50
|
+
DeployedSite,
|
|
51
|
+
DeployError,
|
|
52
|
+
DeploySource,
|
|
53
|
+
DeployStatus,
|
|
54
|
+
} from './useDropDeploy';
|