@netlify/spark-ui 1.31.0-alpha.5 → 1.31.0-alpha.7

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.
Files changed (42) hide show
  1. package/README.md +3 -4
  2. package/dist/components/preact/DropZone/DropZone.d.ts +23 -97
  3. package/dist/components/preact/DropZone/useDropDeploy.js +110 -105
  4. package/dist/drop-core/analytics.d.ts +4 -15
  5. package/dist/drop-core/authedApi.d.ts +9 -22
  6. package/dist/drop-core/authedDropClient.d.ts +13 -55
  7. package/dist/drop-core/authedDropClient.js +5 -18
  8. package/dist/drop-core/buildClient.d.ts +19 -53
  9. package/dist/drop-core/buildClient.js +27 -40
  10. package/dist/drop-core/buildStash.d.ts +6 -20
  11. package/dist/drop-core/buildStash.js +36 -24
  12. package/dist/drop-core/client.d.ts +1 -1
  13. package/dist/drop-core/constants.d.ts +1 -21
  14. package/dist/drop-core/deploy.d.ts +5 -17
  15. package/dist/drop-core/detectBuild.d.ts +8 -26
  16. package/dist/drop-core/errors.d.ts +8 -27
  17. package/dist/drop-core/fileTypes.d.ts +4 -14
  18. package/dist/drop-core/readFiles.d.ts +5 -11
  19. package/dist/drop-core/types.d.ts +2 -4
  20. package/dist/drop-core/zip.d.ts +7 -30
  21. package/package.json +1 -1
  22. package/packages/components/preact/DropZone/DropZone.tsx +27 -121
  23. package/packages/components/preact/DropZone/useDropDeploy.test.ts +12 -0
  24. package/packages/components/preact/DropZone/useDropDeploy.ts +39 -60
  25. package/packages/drop-core/README.md +311 -39
  26. package/packages/drop-core/analytics.ts +4 -15
  27. package/packages/drop-core/authedApi.ts +9 -22
  28. package/packages/drop-core/authedDropClient.ts +13 -55
  29. package/packages/drop-core/buildClient.test.ts +19 -4
  30. package/packages/drop-core/buildClient.ts +21 -63
  31. package/packages/drop-core/buildStash.test.ts +19 -0
  32. package/packages/drop-core/buildStash.ts +38 -29
  33. package/packages/drop-core/client.ts +6 -10
  34. package/packages/drop-core/constants.ts +8 -22
  35. package/packages/drop-core/deploy.ts +6 -22
  36. package/packages/drop-core/detectBuild.ts +15 -50
  37. package/packages/drop-core/errors.test.ts +3 -1
  38. package/packages/drop-core/errors.ts +9 -30
  39. package/packages/drop-core/fileTypes.ts +5 -19
  40. package/packages/drop-core/readFiles.ts +5 -12
  41. package/packages/drop-core/types.ts +2 -4
  42. package/packages/drop-core/zip.ts +7 -30
package/README.md CHANGED
@@ -147,13 +147,13 @@ This repo includes a [Claude Code](https://claude.ai/code) skill for generating
147
147
 
148
148
  The skill is available automatically. Run:
149
149
 
150
- ```text
150
+ ```
151
151
  /project:landing-page <describe the page you want>
152
152
  ```
153
153
 
154
154
  For example:
155
155
 
156
- ```text
156
+ ```
157
157
  /project:landing-page A landing page for a new enterprise hosting product with a hero, feature cards, and a pricing comparison
158
158
  ```
159
159
 
@@ -185,7 +185,7 @@ When you’re ready to validate your component changes in a deploy preview, you
185
185
  >
186
186
  > Reach out to #internal-permissions in Slack
187
187
 
188
- ### Steps to Publish an Alpha Release
188
+ ### Steps to Publish an Alpha Release:
189
189
 
190
190
  1. **Make sure you're logged into npm locally**
191
191
 
@@ -206,7 +206,6 @@ When you’re ready to validate your component changes in a deploy preview, you
206
206
  ```
207
207
 
208
208
  1. **Install the updated package:**
209
-
210
209
  ```bash
211
210
  npm install
212
211
  ```
@@ -10,29 +10,17 @@ interface Props {
10
10
  client?: DropClient;
11
11
  /** Build the "claim this site" URL from the assigned site name (subdomain). */
12
12
  claimUrl?: (siteName: string) => string;
13
- /**
14
- * Where an authenticated static deploy sends the visitor — the site already
15
- * lives in their account, so there is no claim step. Defaults to the new
16
- * site's project overview on app.netlify.com.
17
- */
13
+ /** Destination after an authenticated static deploy (no claim step). Default: the project overview. */
18
14
  siteDashboardUrl?: (siteName: string) => string;
19
15
  /**
20
- * The signup hand-off for a build-required drop that can't be built here (no
21
- * session, or no build wiring). The drop is stashed on this origin first, so
22
- * a flow that returns the visitor to this page deploys it automatically —
23
- * see `resumeStashedBuilds`. Defaults to the app signup page with
24
- * `next=/drop`.
16
+ * Signup hand-off for a build drop with no session. The drop is stashed on
17
+ * this origin first — return the visitor here and it deploys automatically.
25
18
  */
26
19
  buildSignupUrl?: string;
27
20
  /**
28
- * Mint a short-lived bearer token for direct api.netlify.com uploads — pass it
29
- * to switch on the whole authenticated path for logged-in visitors: static
30
- * drops deploy straight into their account (then `siteDashboardUrl`), and
31
- * build-required drops build in place instead of being handed off to the app.
32
- * On netlify.com this reads `GET /access-control/generate-access-control-token`.
33
- * Resolving `null` means "no session": static drops fall back to the anonymous
34
- * claim flow; build drops are stashed and handed to `buildSignupUrl`.
35
- * See [Logged-in visitors](#logged-in-visitors).
21
+ * Mint the upload bearer — passing this switches on the whole authenticated
22
+ * path. `null` means "no session": static drops fall back to the anonymous
23
+ * claim flow; build drops stash and hand off. See the docs' Logged-in visitors.
36
24
  */
37
25
  getUploadToken?: () => Promise<string | null>;
38
26
  /**
@@ -40,111 +28,49 @@ interface Props {
40
28
  * Takes precedence over `getUploadToken` for the build path.
41
29
  */
42
30
  buildClient?: BuildClient;
43
- /**
44
- * Inject a custom authenticated `DropClient` for static drops (tests, staging,
45
- * a different account flow). Takes precedence over `getUploadToken` for the
46
- * static path. Distinct from `client`, which is the anonymous fallback.
47
- */
31
+ /** Custom authenticated static-drop client; wins over `getUploadToken`. (`client` is the anonymous fallback.) */
48
32
  authenticatedDropClient?: DropClient;
49
- /**
50
- * API root for the authenticated paths' JSON calls, which go through your
51
- * access-control rewrite so the session cookie authorizes them. Defaults to
52
- * `/access-control/bb-api/api/v1`. (Uploads always go direct to
53
- * `api.netlify.com` — the proxy can't carry bodies that large.)
54
- */
33
+ /** Root for the session-cookie JSON calls, via your access-control rewrite. Uploads always go direct. */
55
34
  proxyBase?: string;
56
35
  /** Create the visitor's new project in this account. Omit for their default account. */
57
36
  accountSlug?: string;
58
- /**
59
- * Where an enqueued build sends the visitor. Defaults to the new site's
60
- * project overview, same as a static deploy; `build.deployId` is available for
61
- * consumers who want the deploy-log page instead.
62
- */
37
+ /** Destination after a build is enqueued. Default: the project overview (`build.deployId` for the logs page). */
63
38
  buildDeployUrl?: (build: DeployedBuild) => string;
64
39
  /**
65
- * Poll until the build finishes before handing off, instead of redirecting as
66
- * soon as it's enqueued. The trade-off: waiting means a failing build surfaces
67
- * its own error message here (via `onError` and the overlay) rather than the
68
- * visitor discovering it on the deploy page — at the cost of holding them on a
69
- * spinner for the length of the build, which is minutes. Off by default.
40
+ * Hold the visitor until the build finishes (off by default — builds take
41
+ * minutes). On is the only way a failing build's own message reaches `onError`.
70
42
  */
71
43
  waitForBuild?: boolean;
72
- /**
73
- * Called when a build-required drop is detected, instead of building it or
74
- * redirecting. Use it to own the hand-off yourself (custom routing, persisting
75
- * the drop, gating on auth). When set, the component neither builds nor
76
- * redirects. The static drop path is unaffected either way.
77
- */
44
+ /** Take over build-required drops entirely — when set, the component neither builds nor redirects. */
78
45
  onBuildRequired?: (info: BuildDetection) => void;
79
46
  /**
80
- * Called instead of the `buildSignupUrl` redirect when a build-required drop
81
- * can't be built here (no session). By this point the drop has been stashed
82
- * on this origin (`stashed` says whether that succeeded) — own the hand-off
83
- * however fits your auth flow, e.g. open a signup popup that keeps the
84
- * visitor on the page. Once they're back authenticated, a remount of the
85
- * zone deploys the stash automatically.
47
+ * Own the signup hand-off instead of the `buildSignupUrl` redirect (e.g. an
48
+ * auth popup). The drop is already stashed; a remount while authenticated
49
+ * deploys it.
86
50
  */
87
51
  onBuildSignupHandoff?: (info: {
88
52
  stashed: boolean;
89
53
  detection: BuildDetection;
90
54
  }) => void;
91
- /**
92
- * Deploy a previously stashed build drop automatically when the zone mounts
93
- * with an authenticated visitor (default `true`). The stash is written when a
94
- * logged-out build drop is handed to signup; see
95
- * [Signup hand-off and auto-resume](#signup-hand-off-and-auto-resume).
96
- */
55
+ /** Auto-deploy a stashed build drop on mount when authenticated (default true). */
97
56
  resumeStashedBuilds?: boolean;
98
57
  /** Called once the deploy is live. */
99
58
  onDeploy?: (result: DeployedSite) => void;
100
- /**
101
- * Called once a build-required drop has been zipped, uploaded and enqueued —
102
- * before the redirect to `buildDeployUrl`. The site exists at this point but
103
- * won't serve content until the build finishes.
104
- */
59
+ /** Called once a build is enqueued, before the `buildDeployUrl` redirect. */
105
60
  onBuildDeploy?: (build: DeployedBuild) => void;
106
- /**
107
- * Called when a deploy fails, with a humanized `message` (ready to show a
108
- * user — the same copy the built-in overlay uses) and the raw `reason`. Pair
109
- * this with `showStatus={false}` to render your own error UI.
110
- */
61
+ /** Deploy failures: humanized `message` (the overlay's copy) + raw `reason`. Pair with showStatus={false}. */
111
62
  onError?: (error: DeployError) => void;
112
63
  /**
113
- * Render the built-in status overlay (drag tint, spinner, progress bar, error).
114
- * Set to `false` to suppress it entirely and keep your children visible, then
115
- * drive your own feedback from the `data-state` attribute on the root element.
116
- * Note: in this mode you're responsible for surfacing errors yourself — use
117
- * `onError` to get the message.
64
+ * Render the built-in overlay. `false` keeps children visible — drive your
65
+ * own feedback from `data-state`, and surface errors yourself via `onError`.
118
66
  */
119
67
  showStatus?: boolean;
120
68
  /**
121
- * Analytics hook. Called at each tracked moment with an event name and
122
- * properties. Stays provider-agnostic — wire it to Segment/Amplitude/GA in the
123
- * consuming app, e.g. `onTrack={(name, props) => new Analytics().track(name, props)}`.
124
- * Emitted events (all include `dropzone_id` when `analyticsId` is set):
125
- * - `dropzone_files_dropped` — files dropped via drag ({ method: 'drag', file_count, file_types })
126
- * - `dropzone_browse_opened` — file picker opened ({ method: 'keyboard' | 'click' })
127
- * - `dropzone_build_required` — drop needs a build (built here, or handed off) ({ method, reason, file_count, file_types })
128
- * - `dropzone_deploy_succeeded` — static deploy went live ({ method, site_name, file_count, authenticated, auth_fallback?, file_types })
129
- * - `dropzone_build_deploy_succeeded` — build enqueued for a logged-in visitor ({ method, reason, site_name, file_count, framework?, file_types })
130
- * - `dropzone_deploy_failed` — deploy or build errored out ({ method, reason, file_count?, file_types })
131
- *
132
- * `authenticated` says whether the deploy landed in the visitor's account;
133
- * `auth_fallback: true` is sent only when an authenticated attempt bounced
134
- * (stale auth hint) and the drop completed anonymously — omitted otherwise.
135
- * `file_types` is the sorted, de-duplicated list of MIME types in the
136
- * selection, with `application/octet-stream` standing in wherever the browser
137
- * reports none (a dragged folder, an `.exe`). It is omitted when the browser
138
- * exposes no files at all. Note `dropzone_files_dropped` only fires for drag —
139
- * a file-picker selection reports its types on the outcome events, as
140
- * `dropzone_browse_opened` fires before any file exists.
69
+ * Provider-agnostic analytics hook. Event names and payload shapes live in
70
+ * DROPZONE_EVENTS / DropZoneEventProperties (drop-core/analytics.ts).
141
71
  */
142
72
  onTrack?: TrackFn;
143
- /**
144
- * Stable identifier for this instance, attached to every tracked event as
145
- * `dropzone_id`. Set it when a page renders more than one Drop Zone so the
146
- * events can be told apart in Amplitude.
147
- */
73
+ /** Stamped on every event as `dropzone_id` — set when a page has more than one zone. */
148
74
  analyticsId?: string;
149
75
  className?: string;
150
76
  }
@@ -1,22 +1,22 @@
1
- import { d as R, A as S, y as nt } from "../../../chunks/hooks.module.DRcxknIz.js";
2
- import { humanizeDropError as rt, isNotAuthenticatedError as O } from "../../../drop-core/errors.js";
1
+ import { d as O, A as S, y as nt } from "../../../chunks/hooks.module.DRcxknIz.js";
2
+ import { humanizeDropError as rt, isNotAuthenticatedError as R } from "../../../drop-core/errors.js";
3
3
  import { DROPZONE_EVENTS as c } from "../../../drop-core/analytics.js";
4
4
  import { renameSingleNonIndexHtmlToIndex as at, getSingleNonIndexHtmlFileName as ot, hasMultipleHtmlFilesWithoutIndex as st } from "../../../drop-core/readFiles.js";
5
5
  import { detectBuild as dt } from "../../../drop-core/detectBuild.js";
6
- import { zipFiles as lt } from "../../../drop-core/zip.js";
7
- import { AnonymousDropClient as ut } from "../../../drop-core/client.js";
6
+ import { zipFiles as ut } from "../../../drop-core/zip.js";
7
+ import { AnonymousDropClient as lt } from "../../../drop-core/client.js";
8
8
  import { AuthenticatedDropClient as ct } from "../../../drop-core/authedDropClient.js";
9
9
  import { AuthenticatedBuildClient as mt } from "../../../drop-core/buildClient.js";
10
10
  import { deployZippedBuild as ft, deployFiles as v } from "../../../drop-core/deploy.js";
11
- import { hasDropStashMarker as gt, loadDropStash as ht, clearDropStash as E, saveDropStash as pt } from "../../../drop-core/buildStash.js";
12
- function I(l) {
13
- switch (l.phase) {
11
+ import { hasDropStashMarker as gt, loadDropStash as ht, clearDropStash as y, saveDropStash as pt } from "../../../drop-core/buildStash.js";
12
+ function I(u) {
13
+ switch (u.phase) {
14
14
  case "zipping":
15
15
  return { kind: "zipping" };
16
16
  case "creating":
17
17
  return { kind: "creating" };
18
18
  case "uploading":
19
- return { kind: "uploading", uploaded: l.uploaded ?? 0, total: l.total ?? 0 };
19
+ return { kind: "uploading", uploaded: u.uploaded ?? 0, total: u.total ?? 0 };
20
20
  case "building":
21
21
  return { kind: "building" };
22
22
  case "processing":
@@ -24,192 +24,197 @@ function I(l) {
24
24
  return { kind: "processing" };
25
25
  }
26
26
  }
27
- function wt(l) {
28
- const m = ot(l);
29
- return m ? `No index.html found — "${m}" won’t be served at the site root.` : st(l) ? "No index.html found — your site may not have a landing page." : null;
27
+ function wt(u) {
28
+ const m = ot(u);
29
+ return m ? `No index.html found — "${m}" won’t be served at the site root.` : st(u) ? "No index.html found — your site may not have a landing page." : null;
30
30
  }
31
- function St(l, m) {
31
+ function St(u, m) {
32
32
  try {
33
- localStorage.setItem("drop-token", l), localStorage.setItem("dropSiteName", m);
33
+ localStorage.setItem("drop-token", u), localStorage.setItem("dropSiteName", m);
34
34
  } catch {
35
35
  }
36
36
  }
37
- function Pt({
38
- apiBase: l,
37
+ function Ft({
38
+ apiBase: u,
39
39
  client: m,
40
40
  claimUrl: z,
41
- siteDashboardUrl: H,
42
- buildSignupUrl: W,
43
- buildClient: Y,
41
+ siteDashboardUrl: Y,
42
+ buildSignupUrl: H,
43
+ buildClient: W,
44
44
  authenticatedDropClient: M,
45
45
  getUploadToken: p,
46
46
  proxyBase: N,
47
47
  accountSlug: A,
48
- buildDeployUrl: C,
48
+ buildDeployUrl: L,
49
49
  waitForBuild: Z,
50
- onBuildRequired: L,
51
- onBuildSignupHandoff: P,
50
+ onBuildRequired: C,
51
+ onBuildSignupHandoff: F,
52
52
  resumeStashedBuilds: $ = !0,
53
- onDeploy: k,
53
+ onDeploy: _,
54
54
  onBuildDeploy: f,
55
55
  onError: g,
56
56
  track: q
57
57
  }) {
58
- const u = (n, t) => (
58
+ const l = (n, i) => (
59
59
  // The event interfaces carry no index signature, hence the cast to TrackFn's record.
60
- q(n, t)
61
- ), [b, a] = R({ kind: "idle" }), [U, _] = R(null), j = S(m ?? new ut(l)).current, w = S(
62
- Y ?? (p ? new mt({ proxyBase: N, getUploadToken: p, accountSlug: A }) : null)
63
- ).current, y = S(
60
+ q(n, i)
61
+ ), [k, a] = O({ kind: "idle" }), [U, b] = O(null), j = S(m ?? new lt(u)).current, w = S(
62
+ W ?? (p ? new mt({ proxyBase: N, getUploadToken: p, accountSlug: A }) : null)
63
+ ).current, D = S(
64
64
  M ?? (p ? new ct({ proxyBase: N, getUploadToken: p, accountSlug: A }) : null)
65
- ).current, J = b.kind !== "idle" && b.kind !== "error";
66
- async function x(n, t) {
65
+ ).current, J = k.kind !== "idle" && k.kind !== "error";
66
+ async function P(n, i) {
67
67
  try {
68
- const { site: i, build: r, buildSettings: o, url: e } = await ft(n, t, {
68
+ const { site: e, build: r, buildSettings: o, url: t } = await ft(n, i, {
69
69
  onProgress: (s) => a(I(s)),
70
70
  waitForBuild: Z
71
71
  });
72
72
  return {
73
- url: e,
74
- siteName: i.name,
75
- siteId: i.id,
73
+ url: t,
74
+ siteName: e.name,
75
+ siteId: e.id,
76
76
  buildId: r.id,
77
77
  deployId: r.deploy_id,
78
78
  buildSettings: o
79
79
  };
80
- } catch (i) {
81
- if (O(i)) return null;
82
- throw i;
80
+ } catch (e) {
81
+ if (R(e)) return null;
82
+ throw e;
83
83
  }
84
84
  }
85
- async function Q(n, t, i) {
86
- _(null), a({ kind: "reading" });
87
- const r = i.length ? { file_types: i } : {}, o = (e, s, d) => {
88
- a({ kind: "error", message: e }), u(c.DEPLOY_FAILED, { method: t, reason: s, ...r, ...d }), g == null || g({ message: e, reason: s });
85
+ async function Q(n, i, e) {
86
+ b(null), a({ kind: "reading" });
87
+ const r = e.length ? { file_types: e } : {}, o = (t, s, d) => {
88
+ a({ kind: "error", message: t }), l(c.DEPLOY_FAILED, { method: i, reason: s, ...r, ...d }), g == null || g({ message: t, reason: s });
89
89
  };
90
90
  try {
91
- const e = at(await n());
92
- if (!e.length) {
91
+ const t = at(await n());
92
+ if (!t.length) {
93
93
  o("No files found to deploy.", "No files found to deploy.", { file_count: 0 });
94
94
  return;
95
95
  }
96
- t === "drag" && u(c.FILES_DROPPED, {
97
- method: t,
98
- file_count: e.length,
96
+ i === "drag" && l(c.FILES_DROPPED, {
97
+ method: i,
98
+ file_count: t.length,
99
99
  ...r
100
100
  });
101
- const s = { source: t, fileCount: e.length, typeProps: r }, d = dt(e);
102
- d.buildRequired ? await T(e, d, s) : await G(e, s);
103
- } catch (e) {
104
- const s = e instanceof Error ? e.message : String(e);
105
- o(rt(e), s);
101
+ const s = { source: i, fileCount: t.length, typeProps: r }, d = dt(t);
102
+ d.buildRequired ? await T(t, d, s) : await G(t, s);
103
+ } catch (t) {
104
+ const s = t instanceof Error ? t.message : String(t);
105
+ o(rt(t), s);
106
106
  }
107
107
  }
108
- async function T(n, t, { source: i, fileCount: r, typeProps: o }) {
109
- if (u(c.BUILD_REQUIRED, {
110
- method: i,
111
- reason: t.reason,
108
+ async function T(n, i, { source: e, fileCount: r, typeProps: o }) {
109
+ if (l(c.BUILD_REQUIRED, {
110
+ method: e,
111
+ reason: i.reason,
112
112
  file_count: r,
113
113
  ...o
114
- }), L) {
115
- a({ kind: "idle" }), L(t);
114
+ }), C) {
115
+ a({ kind: "idle" }), C(i);
116
116
  return;
117
117
  }
118
- let e = !1;
118
+ let t = !1;
119
119
  if (w) {
120
120
  a({ kind: "zipping" });
121
- const s = await lt(n), d = await x(w, s);
121
+ const s = await ut(n), d = await P(w, s);
122
122
  if (d) {
123
- a({ kind: "redirecting", target: "build" }), u(c.BUILD_DEPLOY_SUCCEEDED, {
124
- method: i,
125
- reason: t.reason,
123
+ a({ kind: "redirecting", target: "build" }), l(c.BUILD_DEPLOY_SUCCEEDED, {
124
+ method: e,
125
+ reason: i.reason,
126
126
  site_name: d.siteName,
127
127
  file_count: r,
128
128
  ...d.buildSettings ? { framework: d.buildSettings.framework } : {},
129
129
  ...o
130
- }), f == null || f(d), window.location.assign(C(d));
130
+ }), f == null || f(d), window.location.assign(L(d));
131
131
  return;
132
132
  }
133
- e = await pt(s.file, s.buildSettings), e && u(c.PROJECT_STASHED, {
134
- method: i,
135
- reason: t.reason,
133
+ t = await pt(s.file, s.buildSettings), t && l(c.PROJECT_STASHED, {
134
+ method: e,
135
+ reason: i.reason,
136
136
  file_count: r,
137
137
  ...o
138
138
  });
139
139
  }
140
- if (P) {
141
- a({ kind: "idle" }), P({ stashed: e, detection: t });
140
+ if (t || l(c.DEPLOY_FAILED, {
141
+ method: e,
142
+ reason: "anonymous_build_not_supported",
143
+ file_count: r,
144
+ ...o
145
+ }), F) {
146
+ a({ kind: "idle" }), F({ stashed: t, detection: i });
142
147
  return;
143
148
  }
144
- a({ kind: "redirecting", target: "signup" }), window.location.assign(W);
149
+ a({ kind: "redirecting", target: "signup" }), window.location.assign(H);
145
150
  }
146
- async function V(n, t) {
151
+ async function V(n, i) {
147
152
  try {
148
- return await v(n, t, {
149
- onProgress: (i) => a(I(i))
153
+ return await v(n, i, {
154
+ onProgress: (e) => a(I(e))
150
155
  });
151
- } catch (i) {
152
- if (O(i)) return null;
153
- throw i;
156
+ } catch (e) {
157
+ if (R(e)) return null;
158
+ throw e;
154
159
  }
155
160
  }
156
- async function G(n, { source: t, fileCount: i, typeProps: r }) {
157
- _(wt(n));
158
- const o = y ? await V(y, n) : null, e = o !== null, s = y !== null && !e, d = o ?? await v(j, n, {
159
- onProgress: (it) => a(I(it))
160
- }), { url: et, token: D, deploy: h } = d;
161
- e || St(D, h.subdomain), a({ kind: "redirecting", target: e ? "dashboard" : "claim" }), u(c.DEPLOY_SUCCEEDED, {
162
- method: t,
161
+ async function G(n, { source: i, fileCount: e, typeProps: r }) {
162
+ b(wt(n));
163
+ const o = D ? await V(D, n) : null, t = o !== null, s = D !== null && !t, d = o ?? await v(j, n, {
164
+ onProgress: (et) => a(I(et))
165
+ }), { url: it, token: E, deploy: h } = d;
166
+ t || St(E, h.subdomain), a({ kind: "redirecting", target: t ? "dashboard" : "claim" }), l(c.DEPLOY_SUCCEEDED, {
167
+ method: i,
163
168
  site_name: h.subdomain,
164
- file_count: i,
165
- authenticated: e,
169
+ file_count: e,
170
+ authenticated: t,
166
171
  ...s ? { auth_fallback: !0 } : {},
167
172
  ...r
168
- }), k == null || k({
169
- url: et,
170
- ...e ? {} : { token: D },
173
+ }), _ == null || _({
174
+ url: it,
175
+ ...t ? {} : { token: E },
171
176
  siteName: h.subdomain,
172
177
  siteId: h.id,
173
- authenticated: e
174
- }), K(e, h.subdomain, D);
178
+ authenticated: t
179
+ }), K(t, h.subdomain, E);
175
180
  }
176
- function K(n, t, i) {
177
- n ? window.location.assign(H(t)) : window.location.assign(`${z(t)}#drop_token=${i}`);
181
+ function K(n, i, e) {
182
+ n ? window.location.assign(Y(i)) : window.location.assign(`${z(i)}#drop_token=${e}`);
178
183
  }
179
184
  async function X(n) {
180
- const t = await ht();
181
- if (!t) {
182
- await E();
185
+ const i = await ht();
186
+ if (!i) {
187
+ await y();
183
188
  return;
184
189
  }
185
- u(c.RESUMED, {}), a({ kind: "creating" });
186
- const i = { file: t.zipFile, buildSettings: t.buildSettings };
190
+ l(c.RESUMED, {}), a({ kind: "creating" });
191
+ const e = { file: i.zipFile, buildSettings: i.buildSettings };
187
192
  let r;
188
193
  try {
189
- r = await x(n, i);
194
+ r = await P(n, e);
190
195
  } catch (o) {
191
- await E(), B(o instanceof Error ? o.message : String(o));
196
+ await y(), B(o instanceof Error ? o.message : String(o));
192
197
  return;
193
198
  }
194
199
  if (!r) {
195
200
  a({ kind: "idle" });
196
201
  return;
197
202
  }
198
- await E(), a({ kind: "redirecting", target: "build" }), f == null || f(r), window.location.assign(C(r));
203
+ await y(), a({ kind: "redirecting", target: "build" }), f == null || f(r), window.location.assign(L(r));
199
204
  }
200
205
  function B(n) {
201
- const t = "We couldn’t automatically deploy your project. Drop it again to publish it.";
202
- a({ kind: "error", message: t }), u(c.DEPLOY_FAILED, { reason: "resume_failed" }), g == null || g({ message: t, reason: n });
206
+ const i = "We couldn’t automatically deploy your project. Drop it again to publish it.";
207
+ a({ kind: "error", message: i }), l(c.DEPLOY_FAILED, { reason: "resume_failed" }), g == null || g({ message: i, reason: n });
203
208
  }
204
- const F = S(!1);
209
+ const x = S(!1);
205
210
  nt(() => {
206
- F.current || !$ || !w || !gt() || (F.current = !0, X(w));
211
+ x.current || !$ || !w || !gt() || (x.current = !0, X(w));
207
212
  }, []);
208
213
  function tt() {
209
- _(null), a({ kind: "idle" });
214
+ b(null), a({ kind: "idle" });
210
215
  }
211
- return { status: b, warning: U, busy: J, deploy: Q, reset: tt };
216
+ return { status: k, warning: U, busy: J, deploy: Q, reset: tt };
212
217
  }
213
218
  export {
214
- Pt as useDropDeploy
219
+ Ft as useDropDeploy
215
220
  };
@@ -1,17 +1,10 @@
1
1
  import { BuildReason } from './detectBuild';
2
- /**
3
- * The Drop Zone's analytics contract — the canonical event names and property
4
- * shapes, exported so no consumer (this package's own component, a host site's
5
- * GTM wiring, or another Netlify surface implementing its own Drop UI over
6
- * drop-core) ever hand-writes the strings.
7
- */
2
+ /** The analytics contract: canonical event names + property shapes, so no consumer hand-writes them. */
8
3
  /** How the files reached the zone — carried on every drop-initiated event as `method`. */
9
4
  export type DropMethod = 'drag' | 'browse';
10
5
  /**
11
- * Canonical Drop Zone lifecycle events. The values are the wire names:
12
- * analytics history in Amplitude/Segment keys off these exact strings, so
13
- * renaming a value silently forks every funnel built on it — treat them as
14
- * append-only.
6
+ * The wire names. Amplitude/Segment history keys off these exact strings —
7
+ * append-only, never rename.
15
8
  */
16
9
  export declare const DROPZONE_EVENTS: {
17
10
  /** Files arrived via drag — the picker path reports its files on outcome events instead. */
@@ -99,9 +92,5 @@ export interface DropZoneEventProperties {
99
92
  dropzone_project_stashed: ProjectStashedProps;
100
93
  dropzone_resumed: ResumedProps;
101
94
  }
102
- /**
103
- * Provider-agnostic analytics sink. Deliberately loose (string, not the event
104
- * union): hosts forward these to Segment/GA/GTM and often pipe their own
105
- * events through the same function.
106
- */
95
+ /** Provider-agnostic sink — loose on purpose, since hosts pipe their own events through it too. */
107
96
  export type TrackFn = (event: string, properties?: Record<string, unknown>) => void;
@@ -1,20 +1,13 @@
1
1
  import { BuildSite } from './types';
2
2
  /**
3
- * The transport both authenticated clients share: JSON calls ride the
4
- * consumer's access-control rewrite on the session cookie, so nothing
5
- * credential-shaped lives in the browser and nothing can expire mid-deploy.
6
- * (Uploads are the exception — the proxy's Lambda caps request bodies at
7
- * ~6MB — and each client handles its own, bearer-authorized.)
3
+ * Transport shared by both authenticated clients: JSON rides the consumer's
4
+ * access-control rewrite on the session cookie. Uploads are each client's own
5
+ * (bearer-direct — the proxy can't carry them).
8
6
  */
9
7
  /**
10
- * Create a site in the visitor's account via `POST {proxyBase}/sites` (scoped
11
- * to `accountSlug` when given, else the user's default account), attributed
12
- * `created_via: 'drop'`.
13
- *
14
- * A logged-out visitor 401s here, before anything is created — the one
15
- * pre-mutation point where callers may still safely fall back to an anonymous
16
- * flow, which is why it maps to `NotAuthenticatedError`. Any other failure is
17
- * a `SiteCreateError` carrying the status.
8
+ * `POST {proxyBase}/sites`, attributed `created_via: 'drop'`. A logged-out
9
+ * visitor 401s here, before anything is created — the one point an anonymous
10
+ * fallback is still safe, hence NotAuthenticatedError.
18
11
  */
19
12
  export declare function createSiteInAccount(proxyBase: string, accountSlug?: string): Promise<BuildSite>;
20
13
  /** How a watched deploy ended. `errorMessage` is the API's own explanation, when it gave one. */
@@ -27,15 +20,9 @@ export type SettledDeploy = {
27
20
  outcome: 'timed-out';
28
21
  };
29
22
  /**
30
- * Poll `GET {proxyBase}/deploys/{deployId}` on the session cookie until the
31
- * deploy settles, and report how. Purely mechanical on purpose: each caller
32
- * maps the outcome onto its own error vocabulary (the drop client throws plain
33
- * errors `humanizeDropError` understands; the build client throws
34
- * `BuildFailedError`/`BuildTimeoutError`), so that knowledge stays next to the
35
- * class it belongs to.
36
- *
37
- * A non-ok poll response is skipped, not fatal — a transient proxy hiccup
38
- * shouldn't kill a deploy that is still progressing.
23
+ * Polls the deploy on the session cookie and reports the terminal outcome —
24
+ * callers map it onto their own error vocabulary. Non-ok reads are skipped,
25
+ * not fatal: a proxy hiccup shouldn't kill a progressing deploy.
39
26
  */
40
27
  export declare function pollDeployUntilSettled(options: {
41
28
  proxyBase: string;