@liiift-studio/deploy-vercel-from-sanity 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.d.mts +1 -33
- package/dist/index.d.ts +1 -33
- package/dist/index.js +185 -99
- package/dist/index.mjs +195 -108
- package/package.json +12 -8
- package/src/compat/code.tsx +0 -29
- package/src/compat/index.ts +0 -14
- package/src/compat/menu.tsx +0 -225
- package/src/compat/primitives.tsx +0 -93
- package/src/compat/resolve.ts +0 -55
- package/src/compat/toast.tsx +0 -173
- package/src/compat/tooltip.tsx +0 -78
- package/src/components/DeployHistory.tsx +0 -160
- package/src/components/DeployItem.tsx +0 -596
- package/src/components/DeployTargetForm.tsx +0 -172
- package/src/components/DeployTool.tsx +0 -318
- package/src/components/StatusBadge.tsx +0 -23
- package/src/components/TokenSetup.tsx +0 -98
- package/src/icons.tsx +0 -78
- package/src/index.ts +0 -47
- package/src/lib/api.ts +0 -102
- package/src/lib/helpers.ts +0 -131
- package/src/schema/schemaIcon.tsx +0 -38
- package/src/schema/vercelConfig.ts +0 -34
- package/src/schema/vercelDeploy.ts +0 -49
- package/src/types.ts +0 -77
- package/src/version.ts +0 -2
package/dist/index.mjs
CHANGED
|
@@ -9,10 +9,18 @@ import * as sanityUi from "@sanity/ui";
|
|
|
9
9
|
import * as sanityIcons from "@sanity/icons";
|
|
10
10
|
var UI = sanityUi;
|
|
11
11
|
var ICONS = sanityIcons;
|
|
12
|
-
function
|
|
12
|
+
function resolveComponent(ns, name) {
|
|
13
13
|
const value = ns[name];
|
|
14
14
|
return typeof value === "function" || typeof value === "object" && value !== null ? value : void 0;
|
|
15
15
|
}
|
|
16
|
+
function resolveFunction(ns, name) {
|
|
17
|
+
const value = ns[name];
|
|
18
|
+
return typeof value === "function" ? value : void 0;
|
|
19
|
+
}
|
|
20
|
+
function resolveRecord(ns, name) {
|
|
21
|
+
const value = ns[name];
|
|
22
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
23
|
+
}
|
|
16
24
|
var STACK_USES_GAP = typeof UI.Stack === "function";
|
|
17
25
|
|
|
18
26
|
// src/icons.tsx
|
|
@@ -21,11 +29,11 @@ var GLYPH = { width: "1em", height: "1em", viewBox: "0 0 25 25", fill: "none" };
|
|
|
21
29
|
var MissingIcon = forwardRef(function MissingIcon2(props, ref) {
|
|
22
30
|
return /* @__PURE__ */ jsx("svg", { ...GLYPH, xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", focusable: "false", ...props, ref });
|
|
23
31
|
});
|
|
24
|
-
var SYMBOL_MAP =
|
|
32
|
+
var SYMBOL_MAP = resolveRecord(ICONS, "icons");
|
|
25
33
|
function resolveIcon(name, symbol) {
|
|
26
|
-
const named =
|
|
34
|
+
const named = resolveComponent(ICONS, name);
|
|
27
35
|
if (named) return named;
|
|
28
|
-
const Icon =
|
|
36
|
+
const Icon = resolveComponent(ICONS, "Icon");
|
|
29
37
|
if (!Icon) return MissingIcon;
|
|
30
38
|
if (SYMBOL_MAP && !(symbol in SYMBOL_MAP)) return MissingIcon;
|
|
31
39
|
const Resolved = forwardRef(function SanityIcon(props, ref) {
|
|
@@ -63,21 +71,43 @@ import { createElement, forwardRef as forwardRef2 } from "react";
|
|
|
63
71
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
64
72
|
function domFallback(tag) {
|
|
65
73
|
const Fallback = forwardRef2(function SanityUiFallback(props, ref) {
|
|
66
|
-
const { children, style, id, className, onClick, href, title, ...rest } = props;
|
|
74
|
+
const { children, style, id, className, onClick, href, title, as, ...rest } = props;
|
|
75
|
+
const element = typeof as === "string" ? as : tag;
|
|
67
76
|
const passthrough = { style, id, className, onClick, href, title, ref };
|
|
68
|
-
for (const key of [
|
|
77
|
+
for (const key of [
|
|
78
|
+
"role",
|
|
79
|
+
"type",
|
|
80
|
+
"value",
|
|
81
|
+
"checked",
|
|
82
|
+
"placeholder",
|
|
83
|
+
"disabled",
|
|
84
|
+
"tabIndex",
|
|
85
|
+
"onChange",
|
|
86
|
+
"onKeyDown",
|
|
87
|
+
"onFocus",
|
|
88
|
+
"onBlur",
|
|
89
|
+
"onMouseEnter",
|
|
90
|
+
"onMouseLeave",
|
|
91
|
+
"htmlFor",
|
|
92
|
+
"target",
|
|
93
|
+
"rel",
|
|
94
|
+
"name",
|
|
95
|
+
"autoComplete",
|
|
96
|
+
"required",
|
|
97
|
+
"readOnly"
|
|
98
|
+
]) {
|
|
69
99
|
if (key in rest) passthrough[key] = rest[key];
|
|
70
100
|
}
|
|
71
101
|
for (const key of Object.keys(rest)) {
|
|
72
102
|
if (key.startsWith("aria-") || key.startsWith("data-")) passthrough[key] = rest[key];
|
|
73
103
|
}
|
|
74
|
-
return createElement(
|
|
104
|
+
return createElement(element, passthrough, children);
|
|
75
105
|
});
|
|
76
106
|
Fallback.displayName = `SanityUiFallback(${tag})`;
|
|
77
107
|
return Fallback;
|
|
78
108
|
}
|
|
79
109
|
function primitive(name, tag) {
|
|
80
|
-
return
|
|
110
|
+
return resolveComponent(UI, name) ?? domFallback(tag);
|
|
81
111
|
}
|
|
82
112
|
var Box = primitive("Box", "div");
|
|
83
113
|
var Card = primitive("Card", "div");
|
|
@@ -136,11 +166,19 @@ function scheduleDismiss(id, status) {
|
|
|
136
166
|
}
|
|
137
167
|
function pushLocalToast(params) {
|
|
138
168
|
const toast = { ...params, id: nextToastId++ };
|
|
139
|
-
|
|
169
|
+
const next = [...localToasts, toast];
|
|
170
|
+
for (const dropped of next.slice(0, Math.max(0, next.length - MAX_VISIBLE_TOASTS))) {
|
|
171
|
+
const timer = dismissTimers.get(dropped.id);
|
|
172
|
+
if (timer) {
|
|
173
|
+
clearTimeout(timer);
|
|
174
|
+
dismissTimers.delete(dropped.id);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
localToasts = next.slice(-MAX_VISIBLE_TOASTS);
|
|
140
178
|
emitToasts();
|
|
141
179
|
scheduleDismiss(toast.id, toast.status);
|
|
142
180
|
}
|
|
143
|
-
var installedUseToast =
|
|
181
|
+
var installedUseToast = resolveFunction(UI, "useToast");
|
|
144
182
|
var localToaster = { push: pushLocalToast };
|
|
145
183
|
function useToast() {
|
|
146
184
|
const real = installedUseToast;
|
|
@@ -157,6 +195,10 @@ function ToastViewport() {
|
|
|
157
195
|
toastListeners.delete(setToasts);
|
|
158
196
|
};
|
|
159
197
|
}, []);
|
|
198
|
+
const resume = useCallback((toast, el) => {
|
|
199
|
+
if (el && el.contains(document.activeElement)) return;
|
|
200
|
+
scheduleDismiss(toast.id, toast.status);
|
|
201
|
+
}, []);
|
|
160
202
|
const hold = useCallback((id) => {
|
|
161
203
|
const timer = dismissTimers.get(id);
|
|
162
204
|
if (timer) {
|
|
@@ -168,9 +210,8 @@ function ToastViewport() {
|
|
|
168
210
|
return /* @__PURE__ */ jsx3(
|
|
169
211
|
Box,
|
|
170
212
|
{
|
|
171
|
-
role: "
|
|
172
|
-
"aria-
|
|
173
|
-
"aria-atomic": false,
|
|
213
|
+
role: "log",
|
|
214
|
+
"aria-label": "Deployment notifications",
|
|
174
215
|
style: {
|
|
175
216
|
position: "fixed",
|
|
176
217
|
bottom: 16,
|
|
@@ -185,11 +226,12 @@ function ToastViewport() {
|
|
|
185
226
|
padding: 3,
|
|
186
227
|
radius: 2,
|
|
187
228
|
shadow: 3,
|
|
188
|
-
tone: LOCAL_TOAST_TONE[toast.status ?? "info"]
|
|
229
|
+
tone: LOCAL_TOAST_TONE[toast.status ?? "info"],
|
|
189
230
|
style: { pointerEvents: "auto" },
|
|
190
231
|
onMouseEnter: () => hold(toast.id),
|
|
191
232
|
onFocusCapture: () => hold(toast.id),
|
|
192
|
-
onMouseLeave: () =>
|
|
233
|
+
onMouseLeave: (e) => resume(toast, e.currentTarget),
|
|
234
|
+
onBlurCapture: (e) => resume(toast, e.currentTarget),
|
|
193
235
|
children: /* @__PURE__ */ jsxs(Flex, { align: "flex-start", gap: 3, children: [
|
|
194
236
|
/* @__PURE__ */ jsxs(Stack, { space: 2, flex: 1, children: [
|
|
195
237
|
toast.title && /* @__PURE__ */ jsx3(Text, { size: 1, weight: "semibold", children: toast.title }),
|
|
@@ -215,50 +257,49 @@ function ToastViewport() {
|
|
|
215
257
|
}
|
|
216
258
|
|
|
217
259
|
// src/compat/tooltip.tsx
|
|
218
|
-
import { useId, useState as useState2 } from "react";
|
|
260
|
+
import { cloneElement, isValidElement, useId, useState as useState2 } from "react";
|
|
219
261
|
import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
220
|
-
var InstalledTooltip =
|
|
262
|
+
var InstalledTooltip = resolveComponent(UI, "Tooltip");
|
|
221
263
|
function Tooltip({ text, children }) {
|
|
222
264
|
const id = useId();
|
|
223
265
|
const [visible, setVisible] = useState2(false);
|
|
224
266
|
if (InstalledTooltip) {
|
|
225
267
|
return /* @__PURE__ */ jsx4(InstalledTooltip, { content: /* @__PURE__ */ jsx4(Box, { padding: 2, children: /* @__PURE__ */ jsx4(Text, { size: 1, children: text }) }), portal: true, children });
|
|
226
268
|
}
|
|
269
|
+
const described = visible && isValidElement(children) ? cloneElement(children, { "aria-describedby": id }) : children;
|
|
227
270
|
return /* @__PURE__ */ jsxs2(
|
|
228
271
|
"span",
|
|
229
272
|
{
|
|
230
273
|
style: { position: "relative", display: "inline-flex" },
|
|
231
|
-
"aria-describedby": id,
|
|
232
274
|
onMouseEnter: () => setVisible(true),
|
|
233
275
|
onMouseLeave: () => setVisible(false),
|
|
234
276
|
onFocusCapture: () => setVisible(true),
|
|
235
277
|
onBlurCapture: () => setVisible(false),
|
|
236
278
|
onKeyDown: (e) => {
|
|
237
|
-
if (e.key === "Escape")
|
|
279
|
+
if (e.key === "Escape" && visible) {
|
|
280
|
+
e.stopPropagation();
|
|
281
|
+
setVisible(false);
|
|
282
|
+
}
|
|
238
283
|
},
|
|
239
284
|
children: [
|
|
240
|
-
|
|
241
|
-
/* @__PURE__ */ jsx4(
|
|
242
|
-
|
|
285
|
+
described,
|
|
286
|
+
visible && /* @__PURE__ */ jsx4(
|
|
287
|
+
"span",
|
|
243
288
|
{
|
|
244
289
|
id,
|
|
245
290
|
role: "tooltip",
|
|
246
|
-
radius: 2,
|
|
247
|
-
shadow: 2,
|
|
248
|
-
padding: 2,
|
|
249
291
|
style: {
|
|
250
292
|
position: "absolute",
|
|
251
293
|
bottom: "100%",
|
|
252
294
|
left: "50%",
|
|
253
295
|
transform: "translateX(-50%)",
|
|
254
|
-
|
|
296
|
+
// No gap between trigger and tooltip, so the pointer can travel onto it
|
|
297
|
+
// without leaving the hover target (WCAG 1.4.13 Hoverable).
|
|
298
|
+
paddingBottom: 4,
|
|
255
299
|
whiteSpace: "nowrap",
|
|
256
|
-
|
|
257
|
-
zIndex: 1e3,
|
|
258
|
-
// Kept in the accessibility tree when hidden so `aria-describedby` still resolves.
|
|
259
|
-
visibility: visible ? "visible" : "hidden"
|
|
300
|
+
zIndex: 1e3
|
|
260
301
|
},
|
|
261
|
-
children: /* @__PURE__ */ jsx4(Text, { size: 1, children: text })
|
|
302
|
+
children: /* @__PURE__ */ jsx4(Card, { radius: 2, shadow: 2, padding: 2, children: /* @__PURE__ */ jsx4(Text, { size: 1, children: text }) })
|
|
262
303
|
}
|
|
263
304
|
)
|
|
264
305
|
]
|
|
@@ -269,9 +310,9 @@ function Tooltip({ text, children }) {
|
|
|
269
310
|
// src/compat/menu.tsx
|
|
270
311
|
import { useCallback as useCallback2, useEffect as useEffect2, useId as useId2, useRef, useState as useState3 } from "react";
|
|
271
312
|
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
272
|
-
var InstalledMenuButton =
|
|
273
|
-
var InstalledMenu =
|
|
274
|
-
var InstalledMenuItem =
|
|
313
|
+
var InstalledMenuButton = resolveComponent(UI, "MenuButton");
|
|
314
|
+
var InstalledMenu = resolveComponent(UI, "Menu");
|
|
315
|
+
var InstalledMenuItem = resolveComponent(UI, "MenuItem");
|
|
275
316
|
var INSTALLED_MENU = InstalledMenuButton && InstalledMenu && InstalledMenuItem ? { MenuButton: InstalledMenuButton, Menu: InstalledMenu, MenuItem: InstalledMenuItem } : null;
|
|
276
317
|
var itemKey = (item, index) => item.key ?? `${index}-${item.text}`;
|
|
277
318
|
function ActionMenu({ id, label, items, buttonIcon }) {
|
|
@@ -299,7 +340,10 @@ function ActionMenu({ id, label, items, buttonIcon }) {
|
|
|
299
340
|
useEffect2(() => {
|
|
300
341
|
if (INSTALLED_MENU || !open) return;
|
|
301
342
|
const onPointerDown = (e) => {
|
|
302
|
-
if (
|
|
343
|
+
if (wrapRef.current?.contains(e.target)) return;
|
|
344
|
+
const hadFocus = wrapRef.current?.contains(document.activeElement);
|
|
345
|
+
setOpen(false);
|
|
346
|
+
if (hadFocus) triggerRef.current?.focus();
|
|
303
347
|
};
|
|
304
348
|
document.addEventListener("mousedown", onPointerDown);
|
|
305
349
|
return () => document.removeEventListener("mousedown", onPointerDown);
|
|
@@ -337,7 +381,20 @@ function ActionMenu({ id, label, items, buttonIcon }) {
|
|
|
337
381
|
return;
|
|
338
382
|
}
|
|
339
383
|
if (e.key === "Tab") {
|
|
340
|
-
|
|
384
|
+
triggerRef.current?.focus();
|
|
385
|
+
setOpen(false);
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
389
|
+
e.preventDefault();
|
|
390
|
+
const item = shownItems[activeIndex];
|
|
391
|
+
if (item) {
|
|
392
|
+
if (item.href) {
|
|
393
|
+
itemRefs.current[activeIndex]?.click();
|
|
394
|
+
} else {
|
|
395
|
+
runAction(item);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
341
398
|
return;
|
|
342
399
|
}
|
|
343
400
|
if (e.key === "ArrowDown") {
|
|
@@ -412,7 +469,6 @@ function ActionMenu({ id, label, items, buttonIcon }) {
|
|
|
412
469
|
ref: (el) => {
|
|
413
470
|
itemRefs.current[i] = el;
|
|
414
471
|
},
|
|
415
|
-
onMouseEnter: () => setActiveIndex(i),
|
|
416
472
|
style: {
|
|
417
473
|
display: "block",
|
|
418
474
|
width: "100%",
|
|
@@ -437,15 +493,17 @@ function ActionMenu({ id, label, items, buttonIcon }) {
|
|
|
437
493
|
href: item.href,
|
|
438
494
|
target: "_blank",
|
|
439
495
|
rel: "noreferrer",
|
|
440
|
-
onClick: () =>
|
|
496
|
+
onClick: () => {
|
|
497
|
+
setOpen(false);
|
|
498
|
+
triggerRef.current?.focus();
|
|
499
|
+
},
|
|
441
500
|
children: content
|
|
442
501
|
},
|
|
443
502
|
itemKey(item, i)
|
|
444
503
|
) : /* @__PURE__ */ jsx5(
|
|
445
|
-
"
|
|
504
|
+
"div",
|
|
446
505
|
{
|
|
447
506
|
...shared,
|
|
448
|
-
type: "button",
|
|
449
507
|
onClick: () => runAction(item),
|
|
450
508
|
children: content
|
|
451
509
|
},
|
|
@@ -459,7 +517,7 @@ function ActionMenu({ id, label, items, buttonIcon }) {
|
|
|
459
517
|
|
|
460
518
|
// src/compat/code.tsx
|
|
461
519
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
462
|
-
var InstalledCode =
|
|
520
|
+
var InstalledCode = resolveComponent(UI, "Code");
|
|
463
521
|
var FALLBACK_CODE_STYLE = {
|
|
464
522
|
display: "block",
|
|
465
523
|
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
|
|
@@ -633,9 +691,10 @@ function StatusBadge({ state, showSpinner }) {
|
|
|
633
691
|
}
|
|
634
692
|
|
|
635
693
|
// src/components/DeployHistory.tsx
|
|
636
|
-
import { useEffect as useEffect3, useState as useState4, useCallback as useCallback3 } from "react";
|
|
694
|
+
import { useId as useId3, useEffect as useEffect3, useState as useState4, useCallback as useCallback3 } from "react";
|
|
637
695
|
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
638
696
|
function DeployHistory({ target, token, onClose }) {
|
|
697
|
+
const dialogId = useId3();
|
|
639
698
|
const [deployments, setDeployments] = useState4([]);
|
|
640
699
|
const [loading, setLoading] = useState4(true);
|
|
641
700
|
const [error, setError] = useState4(null);
|
|
@@ -659,7 +718,7 @@ function DeployHistory({ target, token, onClose }) {
|
|
|
659
718
|
Dialog,
|
|
660
719
|
{
|
|
661
720
|
header: `${target.name} \u2014 Deployment History`,
|
|
662
|
-
id:
|
|
721
|
+
id: dialogId,
|
|
663
722
|
onClose,
|
|
664
723
|
width: 2,
|
|
665
724
|
footer: /* @__PURE__ */ jsx8(Box, { padding: 3, children: /* @__PURE__ */ jsx8(Button, { text: "Close", icon: CloseIcon, mode: "ghost", onClick: onClose }) }),
|
|
@@ -747,8 +806,11 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
747
806
|
const triggeredFromUidRef = useRef2(void 0);
|
|
748
807
|
const requestSeqRef = useRef2(0);
|
|
749
808
|
const mountedRef = useRef2(true);
|
|
750
|
-
useEffect4(() =>
|
|
751
|
-
mountedRef.current =
|
|
809
|
+
useEffect4(() => {
|
|
810
|
+
mountedRef.current = true;
|
|
811
|
+
return () => {
|
|
812
|
+
mountedRef.current = false;
|
|
813
|
+
};
|
|
752
814
|
}, []);
|
|
753
815
|
const latest = deployments[0];
|
|
754
816
|
const isPending = pendingSince !== null;
|
|
@@ -974,17 +1036,36 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
974
1036
|
formatDuration(Math.floor((latest.ready - latest.created) / 1e3)),
|
|
975
1037
|
" to build"
|
|
976
1038
|
] }),
|
|
977
|
-
latest?.url && latest.state === "READY" && /* @__PURE__ */
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
1039
|
+
latest?.url && latest.state === "READY" && /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
1040
|
+
/* @__PURE__ */ jsx9(Tooltip, { text: copied ? "Copied" : "Copy deployment URL", children: /* @__PURE__ */ jsx9(
|
|
1041
|
+
Button,
|
|
1042
|
+
{
|
|
1043
|
+
mode: "ghost",
|
|
1044
|
+
icon: copied ? CheckmarkIcon : CopyIcon,
|
|
1045
|
+
padding: 1,
|
|
1046
|
+
tone: copied ? "positive" : "default",
|
|
1047
|
+
onClick: copyUrl,
|
|
1048
|
+
"aria-label": copied ? "Deployment URL copied" : "Copy deployment URL",
|
|
1049
|
+
style: { cursor: "pointer" }
|
|
1050
|
+
}
|
|
1051
|
+
) }),
|
|
1052
|
+
/* @__PURE__ */ jsx9(
|
|
1053
|
+
"span",
|
|
1054
|
+
{
|
|
1055
|
+
role: "status",
|
|
1056
|
+
"aria-live": "polite",
|
|
1057
|
+
style: {
|
|
1058
|
+
position: "absolute",
|
|
1059
|
+
width: 1,
|
|
1060
|
+
height: 1,
|
|
1061
|
+
overflow: "hidden",
|
|
1062
|
+
clip: "rect(0 0 0 0)",
|
|
1063
|
+
whiteSpace: "nowrap"
|
|
1064
|
+
},
|
|
1065
|
+
children: copied ? "Deployment URL copied to clipboard" : ""
|
|
1066
|
+
}
|
|
1067
|
+
)
|
|
1068
|
+
] })
|
|
988
1069
|
] }),
|
|
989
1070
|
/* @__PURE__ */ jsxs6(Flex, { align: "center", gap: 2, wrap: "wrap", children: [
|
|
990
1071
|
commitMsg && /* @__PURE__ */ jsx9(
|
|
@@ -1035,7 +1116,7 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
1035
1116
|
deployError && /* @__PURE__ */ jsx9(Card, { tone: "critical", padding: 2, radius: 2, children: /* @__PURE__ */ jsx9(Text, { size: 1, children: deployError }) })
|
|
1036
1117
|
] })
|
|
1037
1118
|
] }),
|
|
1038
|
-
pollError && /* @__PURE__ */ jsx9(Card, { tone: "caution", padding: 3, radius: 2,
|
|
1119
|
+
pollError && /* @__PURE__ */ jsx9(Card, { tone: "caution", padding: 3, radius: 2, children: /* @__PURE__ */ jsxs6(Flex, { align: "center", gap: 2, children: [
|
|
1039
1120
|
/* @__PURE__ */ jsx9(WarningOutlineIcon, { "aria-hidden": "true" }),
|
|
1040
1121
|
/* @__PURE__ */ jsxs6(Text, { size: 1, children: [
|
|
1041
1122
|
"Status updates paused \u2014 ",
|
|
@@ -1143,16 +1224,18 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
1143
1224
|
}
|
|
1144
1225
|
|
|
1145
1226
|
// src/components/TokenSetup.tsx
|
|
1146
|
-
import { useId as
|
|
1227
|
+
import { useId as useId4, useState as useState6, useCallback as useCallback5 } from "react";
|
|
1147
1228
|
import { useClient } from "sanity";
|
|
1148
1229
|
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1149
1230
|
var TOKEN_DOC_ID = "config.vercelDeploy";
|
|
1150
|
-
function TokenSetup({ onSaved, onCancel }) {
|
|
1151
|
-
const
|
|
1231
|
+
function TokenSetup({ onSaved, onCancel, hasToken = false }) {
|
|
1232
|
+
const dialogId = useId4();
|
|
1233
|
+
const tokenId = useId4();
|
|
1152
1234
|
const client = useClient({ apiVersion: "2025-01-01" });
|
|
1153
1235
|
const [token, setToken] = useState6("");
|
|
1154
1236
|
const [saving, setSaving] = useState6(false);
|
|
1155
1237
|
const [error, setError] = useState6(null);
|
|
1238
|
+
const [revoking, setRevoking] = useState6(false);
|
|
1156
1239
|
const save = useCallback5(async () => {
|
|
1157
1240
|
if (!token.trim()) return;
|
|
1158
1241
|
setSaving(true);
|
|
@@ -1170,27 +1253,54 @@ function TokenSetup({ onSaved, onCancel }) {
|
|
|
1170
1253
|
setSaving(false);
|
|
1171
1254
|
}
|
|
1172
1255
|
}, [client, token, onSaved]);
|
|
1256
|
+
const revoke = useCallback5(async () => {
|
|
1257
|
+
setRevoking(true);
|
|
1258
|
+
setError(null);
|
|
1259
|
+
try {
|
|
1260
|
+
await client.delete(TOKEN_DOC_ID);
|
|
1261
|
+
onSaved();
|
|
1262
|
+
} catch (err) {
|
|
1263
|
+
setError(err instanceof Error ? err.message : "Failed to remove token");
|
|
1264
|
+
} finally {
|
|
1265
|
+
setRevoking(false);
|
|
1266
|
+
}
|
|
1267
|
+
}, [client, onSaved]);
|
|
1173
1268
|
return /* @__PURE__ */ jsx10(
|
|
1174
1269
|
Dialog,
|
|
1175
1270
|
{
|
|
1176
1271
|
header: "Connect Vercel API token",
|
|
1177
|
-
id:
|
|
1272
|
+
id: dialogId,
|
|
1178
1273
|
onClose: onCancel,
|
|
1179
1274
|
width: 1,
|
|
1180
|
-
footer: /* @__PURE__ */ jsxs7(Flex, { padding: 3, gap: 2, justify: "flex-end", children: [
|
|
1181
|
-
|
|
1182
|
-
/* @__PURE__ */ jsx10(
|
|
1275
|
+
footer: /* @__PURE__ */ jsxs7(Flex, { padding: 3, gap: 2, justify: hasToken ? "space-between" : "flex-end", children: [
|
|
1276
|
+
hasToken && /* @__PURE__ */ jsx10(
|
|
1183
1277
|
Button,
|
|
1184
1278
|
{
|
|
1185
|
-
text: "
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1279
|
+
text: "Remove token",
|
|
1280
|
+
mode: "ghost",
|
|
1281
|
+
tone: "critical",
|
|
1282
|
+
icon: TrashIcon,
|
|
1283
|
+
loading: revoking,
|
|
1284
|
+
disabled: revoking || saving,
|
|
1285
|
+
onClick: revoke,
|
|
1191
1286
|
style: { cursor: "pointer" }
|
|
1192
1287
|
}
|
|
1193
|
-
)
|
|
1288
|
+
),
|
|
1289
|
+
/* @__PURE__ */ jsxs7(Flex, { gap: 2, children: [
|
|
1290
|
+
onCancel && /* @__PURE__ */ jsx10(Button, { text: "Cancel", mode: "ghost", onClick: onCancel, style: { cursor: "pointer" } }),
|
|
1291
|
+
/* @__PURE__ */ jsx10(
|
|
1292
|
+
Button,
|
|
1293
|
+
{
|
|
1294
|
+
text: "Save and connect",
|
|
1295
|
+
tone: "primary",
|
|
1296
|
+
icon: CheckmarkCircleIcon,
|
|
1297
|
+
loading: saving,
|
|
1298
|
+
disabled: !token.trim() || saving,
|
|
1299
|
+
onClick: save,
|
|
1300
|
+
style: { cursor: "pointer" }
|
|
1301
|
+
}
|
|
1302
|
+
)
|
|
1303
|
+
] })
|
|
1194
1304
|
] }),
|
|
1195
1305
|
children: /* @__PURE__ */ jsxs7(Stack, { space: 4, padding: 4, children: [
|
|
1196
1306
|
/* @__PURE__ */ jsxs7(Stack, { space: 3, children: [
|
|
@@ -1224,20 +1334,21 @@ function TokenSetup({ onSaved, onCancel }) {
|
|
|
1224
1334
|
}
|
|
1225
1335
|
|
|
1226
1336
|
// src/components/DeployTargetForm.tsx
|
|
1227
|
-
import { useId as
|
|
1337
|
+
import { useId as useId5, useState as useState7, useCallback as useCallback6 } from "react";
|
|
1228
1338
|
import { useClient as useClient2 } from "sanity";
|
|
1229
1339
|
import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1230
1340
|
var VERCEL_HOOK_RE2 = /^https:\/\/api\.vercel\.com\/v1\/integrations\/deploy\//;
|
|
1231
1341
|
function DeployTargetForm({ initial, onSaved, onClose }) {
|
|
1232
1342
|
const client = useClient2({ apiVersion: "2025-01-01" });
|
|
1233
1343
|
const isEdit = Boolean(initial);
|
|
1234
|
-
const
|
|
1235
|
-
const
|
|
1236
|
-
const
|
|
1237
|
-
const
|
|
1238
|
-
const
|
|
1239
|
-
const
|
|
1240
|
-
const
|
|
1344
|
+
const dialogId = useId5();
|
|
1345
|
+
const nameId = useId5();
|
|
1346
|
+
const urlId = useId5();
|
|
1347
|
+
const urlErrorId = useId5();
|
|
1348
|
+
const urlHelpId = useId5();
|
|
1349
|
+
const teamId_ = useId5();
|
|
1350
|
+
const teamHelpId = useId5();
|
|
1351
|
+
const disableId = useId5();
|
|
1241
1352
|
const [name, setName] = useState7(initial?.name ?? "");
|
|
1242
1353
|
const [url, setUrl] = useState7(initial?.url ?? "");
|
|
1243
1354
|
const [teamId, setTeamId] = useState7(initial?.teamId ?? "");
|
|
@@ -1273,7 +1384,7 @@ function DeployTargetForm({ initial, onSaved, onClose }) {
|
|
|
1273
1384
|
Dialog,
|
|
1274
1385
|
{
|
|
1275
1386
|
header: isEdit ? `Edit "${initial?.name}"` : "Add deploy target",
|
|
1276
|
-
id:
|
|
1387
|
+
id: dialogId,
|
|
1277
1388
|
onClose,
|
|
1278
1389
|
width: 1,
|
|
1279
1390
|
footer: /* @__PURE__ */ jsxs8(Flex, { padding: 3, gap: 2, justify: "flex-end", children: [
|
|
@@ -1372,7 +1483,7 @@ function DeployTargetForm({ initial, onSaved, onClose }) {
|
|
|
1372
1483
|
}
|
|
1373
1484
|
|
|
1374
1485
|
// src/version.ts
|
|
1375
|
-
var VERSION = "1.2.
|
|
1486
|
+
var VERSION = "1.2.1";
|
|
1376
1487
|
|
|
1377
1488
|
// src/components/DeployTool.tsx
|
|
1378
1489
|
import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
@@ -1577,7 +1688,8 @@ function DeployTool() {
|
|
|
1577
1688
|
setShowTokenSetup(false);
|
|
1578
1689
|
load();
|
|
1579
1690
|
},
|
|
1580
|
-
onCancel: () => setShowTokenSetup(false)
|
|
1691
|
+
onCancel: () => setShowTokenSetup(false),
|
|
1692
|
+
hasToken: Boolean(token)
|
|
1581
1693
|
}
|
|
1582
1694
|
),
|
|
1583
1695
|
showCreateForm && /* @__PURE__ */ jsx12(
|
|
@@ -1724,37 +1836,13 @@ var vercelDeploySchema = defineType({
|
|
|
1724
1836
|
}
|
|
1725
1837
|
});
|
|
1726
1838
|
|
|
1727
|
-
// src/schema/vercelConfig.ts
|
|
1728
|
-
import { defineField as defineField2, defineType as defineType2 } from "sanity";
|
|
1729
|
-
var vercelConfigSchema = defineType2({
|
|
1730
|
-
name: "vercelDeploy.config",
|
|
1731
|
-
title: "Vercel Deploy Configuration",
|
|
1732
|
-
type: "document",
|
|
1733
|
-
fields: [
|
|
1734
|
-
defineField2({
|
|
1735
|
-
name: "accessToken",
|
|
1736
|
-
title: "Vercel API Token",
|
|
1737
|
-
type: "string",
|
|
1738
|
-
description: "Readable by anyone who can read this dataset. Delete this document to revoke the stored token."
|
|
1739
|
-
})
|
|
1740
|
-
],
|
|
1741
|
-
preview: {
|
|
1742
|
-
select: { token: "accessToken" },
|
|
1743
|
-
prepare: ({ token }) => ({
|
|
1744
|
-
title: "Vercel API Token",
|
|
1745
|
-
// Never render the secret itself in a preview.
|
|
1746
|
-
subtitle: token ? "Connected" : "Not set"
|
|
1747
|
-
})
|
|
1748
|
-
}
|
|
1749
|
-
});
|
|
1750
|
-
|
|
1751
1839
|
// src/index.ts
|
|
1752
1840
|
var vercelDeploy = definePlugin((options) => {
|
|
1753
1841
|
const config = options ?? {};
|
|
1754
1842
|
return {
|
|
1755
1843
|
name: "deploy-vercel-from-sanity",
|
|
1756
1844
|
schema: {
|
|
1757
|
-
types: [vercelDeploySchema
|
|
1845
|
+
types: [vercelDeploySchema]
|
|
1758
1846
|
},
|
|
1759
1847
|
tools: [
|
|
1760
1848
|
{
|
|
@@ -1767,7 +1855,6 @@ var vercelDeploy = definePlugin((options) => {
|
|
|
1767
1855
|
};
|
|
1768
1856
|
});
|
|
1769
1857
|
export {
|
|
1770
|
-
vercelConfigSchema,
|
|
1771
1858
|
vercelDeploy,
|
|
1772
1859
|
vercelDeploySchema
|
|
1773
1860
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liiift-studio/deploy-vercel-from-sanity",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Sanity Studio plugin — trigger and monitor Vercel deployments with full status, history, and build logs. Supports Studio v3.30 through v6.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Liiift Studio",
|
|
@@ -22,16 +22,20 @@
|
|
|
22
22
|
"types": "./dist/index.d.ts",
|
|
23
23
|
"exports": {
|
|
24
24
|
".": {
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
"import": {
|
|
26
|
+
"types": "./dist/index.d.mts",
|
|
27
|
+
"default": "./dist/index.mjs"
|
|
28
|
+
},
|
|
29
|
+
"require": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"default": "./dist/index.js"
|
|
32
|
+
},
|
|
28
33
|
"default": "./dist/index.mjs"
|
|
29
34
|
},
|
|
30
35
|
"./package.json": "./package.json"
|
|
31
36
|
},
|
|
32
37
|
"files": [
|
|
33
|
-
"dist"
|
|
34
|
-
"src"
|
|
38
|
+
"dist"
|
|
35
39
|
],
|
|
36
40
|
"scripts": {
|
|
37
41
|
"build": "tsup",
|
|
@@ -43,7 +47,7 @@
|
|
|
43
47
|
"@sanity/ui": ">=2 <5",
|
|
44
48
|
"react": ">=18",
|
|
45
49
|
"react-dom": ">=18",
|
|
46
|
-
"sanity": ">=3.30"
|
|
50
|
+
"sanity": ">=3.30 <7"
|
|
47
51
|
},
|
|
48
52
|
"devDependencies": {
|
|
49
53
|
"@sanity/icons": "^5",
|
|
@@ -62,6 +66,6 @@
|
|
|
62
66
|
},
|
|
63
67
|
"sideEffects": true,
|
|
64
68
|
"engines": {
|
|
65
|
-
"node": ">=20.19"
|
|
69
|
+
"node": ">=20.19 <22 || >=22.12"
|
|
66
70
|
}
|
|
67
71
|
}
|
package/src/compat/code.tsx
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
// Monospace block — Studio's Code where available, a styled <code> block otherwise
|
|
2
|
-
import type { CSSProperties, ComponentType, ReactNode } from 'react'
|
|
3
|
-
import { UI, resolveExport } from './resolve'
|
|
4
|
-
|
|
5
|
-
/** The real Code when the installed @sanity/ui still exports it, otherwise undefined. */
|
|
6
|
-
const InstalledCode = resolveExport<ComponentType<{
|
|
7
|
-
size?: number
|
|
8
|
-
style?: CSSProperties
|
|
9
|
-
children: ReactNode
|
|
10
|
-
}>>(UI, 'Code')
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Styling for the fallback Code element, approximating @sanity/ui's `size={1}`.
|
|
14
|
-
* `display: block` is included deliberately — `<code>` is inline by default while
|
|
15
|
-
* upstream's Code renders a block, so omitting it would concatenate every line.
|
|
16
|
-
*/
|
|
17
|
-
const FALLBACK_CODE_STYLE: CSSProperties = {
|
|
18
|
-
display: 'block',
|
|
19
|
-
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Consolas, monospace',
|
|
20
|
-
fontSize: '0.8125rem',
|
|
21
|
-
lineHeight: 1.4,
|
|
22
|
-
margin: 0,
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/** Monospace block. Uses Studio's Code where available, a plain `<code>` on @sanity/ui v4+. */
|
|
26
|
-
export function Code({ style, children }: { style?: CSSProperties; children: ReactNode }): React.JSX.Element {
|
|
27
|
-
if (InstalledCode) return <InstalledCode size={1} style={style}>{children}</InstalledCode>
|
|
28
|
-
return <code style={{ ...FALLBACK_CODE_STYLE, ...style }}>{children}</code>
|
|
29
|
-
}
|
package/src/compat/index.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
// Single entry point for every @sanity/ui value this plugin uses, resolved against the installed major
|
|
2
|
-
export {
|
|
3
|
-
Box, Card, Flex, Grid, Text, Heading, Label, Badge, Spinner,
|
|
4
|
-
Button, TextInput, Select, Switch, Dialog, Stack,
|
|
5
|
-
} from './primitives'
|
|
6
|
-
export type { StackProps } from './primitives'
|
|
7
|
-
export { useToast, ToastViewport } from './toast'
|
|
8
|
-
export type { ToastParams, Toaster } from './toast'
|
|
9
|
-
export { Tooltip } from './tooltip'
|
|
10
|
-
export type { TooltipProps } from './tooltip'
|
|
11
|
-
export { ActionMenu } from './menu'
|
|
12
|
-
export type { ActionMenuProps, MenuAction } from './menu'
|
|
13
|
-
export { Code } from './code'
|
|
14
|
-
export { STACK_USES_GAP } from './resolve'
|