@liiift-studio/deploy-vercel-from-sanity 1.1.1 → 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 +33 -19
- package/dist/index.d.mts +6 -8
- package/dist/index.d.ts +6 -8
- package/dist/index.js +872 -431
- package/dist/index.mjs +863 -465
- package/package.json +21 -11
- package/src/components/DeployHistory.tsx +0 -158
- package/src/components/DeployItem.tsx +0 -571
- package/src/components/DeployTargetForm.tsx +0 -146
- package/src/components/DeployTool.tsx +0 -296
- package/src/components/StatusBadge.tsx +0 -23
- package/src/components/TokenSetup.tsx +0 -98
- package/src/icons.tsx +0 -71
- package/src/index.ts +0 -42
- package/src/lib/api.ts +0 -96
- package/src/lib/helpers.ts +0 -114
- package/src/schema/vercelDeploy.ts +0 -49
- package/src/types.ts +0 -77
- package/src/ui.tsx +0 -337
- package/src/version.ts +0 -2
package/dist/index.js
CHANGED
|
@@ -38,18 +38,39 @@ var import_sanity5 = require("sanity");
|
|
|
38
38
|
|
|
39
39
|
// src/icons.tsx
|
|
40
40
|
var import_react = require("react");
|
|
41
|
+
|
|
42
|
+
// src/compat/resolve.ts
|
|
43
|
+
var sanityUi = __toESM(require("@sanity/ui"));
|
|
41
44
|
var sanityIcons = __toESM(require("@sanity/icons"));
|
|
45
|
+
var UI = sanityUi;
|
|
46
|
+
var ICONS = sanityIcons;
|
|
47
|
+
function resolveComponent(ns, name) {
|
|
48
|
+
const value = ns[name];
|
|
49
|
+
return typeof value === "function" || typeof value === "object" && value !== null ? value : void 0;
|
|
50
|
+
}
|
|
51
|
+
function resolveFunction(ns, name) {
|
|
52
|
+
const value = ns[name];
|
|
53
|
+
return typeof value === "function" ? value : void 0;
|
|
54
|
+
}
|
|
55
|
+
function resolveRecord(ns, name) {
|
|
56
|
+
const value = ns[name];
|
|
57
|
+
return typeof value === "object" && value !== null ? value : void 0;
|
|
58
|
+
}
|
|
59
|
+
var STACK_USES_GAP = typeof UI.Stack === "function";
|
|
60
|
+
|
|
61
|
+
// src/icons.tsx
|
|
42
62
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
43
|
-
var INSTALLED = sanityIcons;
|
|
44
63
|
var GLYPH = { width: "1em", height: "1em", viewBox: "0 0 25 25", fill: "none" };
|
|
45
64
|
var MissingIcon = (0, import_react.forwardRef)(function MissingIcon2(props, ref) {
|
|
46
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { ...GLYPH, xmlns: "http://www.w3.org/2000/svg", ...props, ref });
|
|
65
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { ...GLYPH, xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", focusable: "false", ...props, ref });
|
|
47
66
|
});
|
|
67
|
+
var SYMBOL_MAP = resolveRecord(ICONS, "icons");
|
|
48
68
|
function resolveIcon(name, symbol) {
|
|
49
|
-
const named =
|
|
69
|
+
const named = resolveComponent(ICONS, name);
|
|
50
70
|
if (named) return named;
|
|
51
|
-
const Icon =
|
|
71
|
+
const Icon = resolveComponent(ICONS, "Icon");
|
|
52
72
|
if (!Icon) return MissingIcon;
|
|
73
|
+
if (SYMBOL_MAP && !(symbol in SYMBOL_MAP)) return MissingIcon;
|
|
53
74
|
const Resolved = (0, import_react.forwardRef)(function SanityIcon(props, ref) {
|
|
54
75
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { symbol, ...props, ref });
|
|
55
76
|
});
|
|
@@ -68,51 +89,131 @@ var EditIcon = resolveIcon("EditIcon", "edit");
|
|
|
68
89
|
var EllipsisVerticalIcon = resolveIcon("EllipsisVerticalIcon", "ellipsis-vertical");
|
|
69
90
|
var LaunchIcon = resolveIcon("LaunchIcon", "launch");
|
|
70
91
|
var RocketIcon = resolveIcon("RocketIcon", "rocket");
|
|
71
|
-
var SchemaIcon = resolveIcon("SchemaIcon", "schema");
|
|
72
92
|
var TokenIcon = resolveIcon("TokenIcon", "token");
|
|
73
93
|
var TrashIcon = resolveIcon("TrashIcon", "trash");
|
|
74
94
|
var WarningOutlineIcon = resolveIcon("WarningOutlineIcon", "warning-outline");
|
|
75
95
|
|
|
76
96
|
// src/components/DeployTool.tsx
|
|
77
|
-
var
|
|
97
|
+
var import_react10 = require("react");
|
|
78
98
|
var import_sanity3 = require("sanity");
|
|
79
|
-
var import_ui11 = require("@sanity/ui");
|
|
80
99
|
|
|
81
|
-
// src/
|
|
100
|
+
// src/components/DeployItem.tsx
|
|
101
|
+
var import_react7 = require("react");
|
|
102
|
+
var import_react_dom = require("react-dom");
|
|
103
|
+
|
|
104
|
+
// src/compat/primitives.tsx
|
|
82
105
|
var import_react2 = require("react");
|
|
83
|
-
var sanityUi = __toESM(require("@sanity/ui"));
|
|
84
|
-
var import_ui = require("@sanity/ui");
|
|
85
106
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
86
|
-
|
|
87
|
-
|
|
107
|
+
function domFallback(tag) {
|
|
108
|
+
const Fallback = (0, import_react2.forwardRef)(function SanityUiFallback(props, ref) {
|
|
109
|
+
const { children, style, id, className, onClick, href, title, as, ...rest } = props;
|
|
110
|
+
const element = typeof as === "string" ? as : tag;
|
|
111
|
+
const passthrough = { style, id, className, onClick, href, title, ref };
|
|
112
|
+
for (const key of [
|
|
113
|
+
"role",
|
|
114
|
+
"type",
|
|
115
|
+
"value",
|
|
116
|
+
"checked",
|
|
117
|
+
"placeholder",
|
|
118
|
+
"disabled",
|
|
119
|
+
"tabIndex",
|
|
120
|
+
"onChange",
|
|
121
|
+
"onKeyDown",
|
|
122
|
+
"onFocus",
|
|
123
|
+
"onBlur",
|
|
124
|
+
"onMouseEnter",
|
|
125
|
+
"onMouseLeave",
|
|
126
|
+
"htmlFor",
|
|
127
|
+
"target",
|
|
128
|
+
"rel",
|
|
129
|
+
"name",
|
|
130
|
+
"autoComplete",
|
|
131
|
+
"required",
|
|
132
|
+
"readOnly"
|
|
133
|
+
]) {
|
|
134
|
+
if (key in rest) passthrough[key] = rest[key];
|
|
135
|
+
}
|
|
136
|
+
for (const key of Object.keys(rest)) {
|
|
137
|
+
if (key.startsWith("aria-") || key.startsWith("data-")) passthrough[key] = rest[key];
|
|
138
|
+
}
|
|
139
|
+
return (0, import_react2.createElement)(element, passthrough, children);
|
|
140
|
+
});
|
|
141
|
+
Fallback.displayName = `SanityUiFallback(${tag})`;
|
|
142
|
+
return Fallback;
|
|
143
|
+
}
|
|
144
|
+
function primitive(name, tag) {
|
|
145
|
+
return resolveComponent(UI, name) ?? domFallback(tag);
|
|
146
|
+
}
|
|
147
|
+
var Box = primitive("Box", "div");
|
|
148
|
+
var Card = primitive("Card", "div");
|
|
149
|
+
var Flex = primitive("Flex", "div");
|
|
150
|
+
var Grid = primitive("Grid", "div");
|
|
151
|
+
var Text = primitive("Text", "span");
|
|
152
|
+
var Heading = primitive("Heading", "h2");
|
|
153
|
+
var Label = primitive("Label", "label");
|
|
154
|
+
var Badge = primitive("Badge", "span");
|
|
155
|
+
var Spinner = primitive("Spinner", "span");
|
|
156
|
+
var Button = primitive("Button", "button");
|
|
157
|
+
var TextInput = primitive("TextInput", "input");
|
|
158
|
+
var Select = primitive("Select", "select");
|
|
159
|
+
var Switch = primitive("Switch", "input");
|
|
160
|
+
var Dialog = primitive("Dialog", "div");
|
|
161
|
+
var SanityStack = primitive("Stack", "div");
|
|
88
162
|
function Stack({ space, children, ...rest }) {
|
|
89
|
-
const spacing = space === void 0 ? {} :
|
|
90
|
-
|
|
91
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Component, { ...rest, ...spacing, children });
|
|
163
|
+
const spacing = space === void 0 ? {} : STACK_USES_GAP ? { gap: space } : { space };
|
|
164
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(SanityStack, { ...rest, ...spacing, children });
|
|
92
165
|
}
|
|
93
|
-
|
|
166
|
+
|
|
167
|
+
// src/compat/toast.tsx
|
|
168
|
+
var import_react3 = require("react");
|
|
169
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
170
|
+
var LOCAL_TOAST_MS = 6e3;
|
|
171
|
+
var MAX_VISIBLE_TOASTS = 4;
|
|
172
|
+
var TOAST_Z_INDEX = 1e6;
|
|
94
173
|
var LOCAL_TOAST_TONE = {
|
|
95
174
|
success: "positive",
|
|
96
175
|
error: "critical",
|
|
97
176
|
warning: "caution",
|
|
98
177
|
info: "primary"
|
|
99
178
|
};
|
|
179
|
+
var PERSISTENT_STATUSES = /* @__PURE__ */ new Set(["error", "warning"]);
|
|
100
180
|
var nextToastId = 0;
|
|
101
181
|
var localToasts = [];
|
|
102
182
|
var toastListeners = /* @__PURE__ */ new Set();
|
|
183
|
+
var dismissTimers = /* @__PURE__ */ new Map();
|
|
103
184
|
function emitToasts() {
|
|
104
185
|
for (const listener of toastListeners) listener(localToasts);
|
|
105
186
|
}
|
|
187
|
+
function removeLocalToast(id) {
|
|
188
|
+
const timer = dismissTimers.get(id);
|
|
189
|
+
if (timer) {
|
|
190
|
+
clearTimeout(timer);
|
|
191
|
+
dismissTimers.delete(id);
|
|
192
|
+
}
|
|
193
|
+
localToasts = localToasts.filter((t) => t.id !== id);
|
|
194
|
+
emitToasts();
|
|
195
|
+
}
|
|
196
|
+
function scheduleDismiss(id, status) {
|
|
197
|
+
if (PERSISTENT_STATUSES.has(status ?? "info")) return;
|
|
198
|
+
const existing = dismissTimers.get(id);
|
|
199
|
+
if (existing) clearTimeout(existing);
|
|
200
|
+
dismissTimers.set(id, setTimeout(() => removeLocalToast(id), LOCAL_TOAST_MS));
|
|
201
|
+
}
|
|
106
202
|
function pushLocalToast(params) {
|
|
107
203
|
const toast = { ...params, id: nextToastId++ };
|
|
108
|
-
|
|
204
|
+
const next = [...localToasts, toast];
|
|
205
|
+
for (const dropped of next.slice(0, Math.max(0, next.length - MAX_VISIBLE_TOASTS))) {
|
|
206
|
+
const timer = dismissTimers.get(dropped.id);
|
|
207
|
+
if (timer) {
|
|
208
|
+
clearTimeout(timer);
|
|
209
|
+
dismissTimers.delete(dropped.id);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
localToasts = next.slice(-MAX_VISIBLE_TOASTS);
|
|
109
213
|
emitToasts();
|
|
110
|
-
|
|
111
|
-
localToasts = localToasts.filter((t) => t.id !== toast.id);
|
|
112
|
-
emitToasts();
|
|
113
|
-
}, LOCAL_TOAST_MS);
|
|
214
|
+
scheduleDismiss(toast.id, toast.status);
|
|
114
215
|
}
|
|
115
|
-
var installedUseToast =
|
|
216
|
+
var installedUseToast = resolveFunction(UI, "useToast");
|
|
116
217
|
var localToaster = { push: pushLocalToast };
|
|
117
218
|
function useToast() {
|
|
118
219
|
const real = installedUseToast;
|
|
@@ -120,160 +221,350 @@ function useToast() {
|
|
|
120
221
|
return localToaster;
|
|
121
222
|
}
|
|
122
223
|
function ToastViewport() {
|
|
123
|
-
const [toasts, setToasts] = (0,
|
|
124
|
-
(0,
|
|
224
|
+
const [toasts, setToasts] = (0, import_react3.useState)(localToasts);
|
|
225
|
+
(0, import_react3.useEffect)(() => {
|
|
125
226
|
if (installedUseToast) return;
|
|
126
227
|
toastListeners.add(setToasts);
|
|
228
|
+
setToasts(localToasts);
|
|
127
229
|
return () => {
|
|
128
230
|
toastListeners.delete(setToasts);
|
|
129
231
|
};
|
|
130
232
|
}, []);
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
233
|
+
const resume = (0, import_react3.useCallback)((toast, el) => {
|
|
234
|
+
if (el && el.contains(document.activeElement)) return;
|
|
235
|
+
scheduleDismiss(toast.id, toast.status);
|
|
236
|
+
}, []);
|
|
237
|
+
const hold = (0, import_react3.useCallback)((id) => {
|
|
238
|
+
const timer = dismissTimers.get(id);
|
|
239
|
+
if (timer) {
|
|
240
|
+
clearTimeout(timer);
|
|
241
|
+
dismissTimers.delete(id);
|
|
242
|
+
}
|
|
243
|
+
}, []);
|
|
244
|
+
if (installedUseToast) return null;
|
|
245
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
246
|
+
Box,
|
|
134
247
|
{
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
248
|
+
role: "log",
|
|
249
|
+
"aria-label": "Deployment notifications",
|
|
250
|
+
style: {
|
|
251
|
+
position: "fixed",
|
|
252
|
+
bottom: 16,
|
|
253
|
+
right: 16,
|
|
254
|
+
zIndex: TOAST_Z_INDEX,
|
|
255
|
+
width: "min(360px, calc(100vw - 32px))",
|
|
256
|
+
pointerEvents: "none"
|
|
257
|
+
},
|
|
258
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Stack, { space: 2, children: toasts.map((toast) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
259
|
+
Card,
|
|
260
|
+
{
|
|
261
|
+
padding: 3,
|
|
262
|
+
radius: 2,
|
|
263
|
+
shadow: 3,
|
|
264
|
+
tone: LOCAL_TOAST_TONE[toast.status ?? "info"],
|
|
265
|
+
style: { pointerEvents: "auto" },
|
|
266
|
+
onMouseEnter: () => hold(toast.id),
|
|
267
|
+
onFocusCapture: () => hold(toast.id),
|
|
268
|
+
onMouseLeave: (e) => resume(toast, e.currentTarget),
|
|
269
|
+
onBlurCapture: (e) => resume(toast, e.currentTarget),
|
|
270
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Flex, { align: "flex-start", gap: 3, children: [
|
|
271
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Stack, { space: 2, flex: 1, children: [
|
|
272
|
+
toast.title && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { size: 1, weight: "semibold", children: toast.title }),
|
|
273
|
+
toast.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Text, { size: 1, muted: true, children: toast.description })
|
|
274
|
+
] }),
|
|
275
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
276
|
+
Button,
|
|
277
|
+
{
|
|
278
|
+
mode: "bleed",
|
|
279
|
+
padding: 2,
|
|
280
|
+
icon: CloseIcon,
|
|
281
|
+
text: "",
|
|
282
|
+
"aria-label": "Dismiss notification",
|
|
283
|
+
onClick: () => removeLocalToast(toast.id)
|
|
284
|
+
}
|
|
285
|
+
)
|
|
286
|
+
] })
|
|
287
|
+
},
|
|
288
|
+
toast.id
|
|
289
|
+
)) })
|
|
290
|
+
}
|
|
291
|
+
);
|
|
146
292
|
}
|
|
147
|
-
|
|
293
|
+
|
|
294
|
+
// src/compat/tooltip.tsx
|
|
295
|
+
var import_react4 = require("react");
|
|
296
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
297
|
+
var InstalledTooltip = resolveComponent(UI, "Tooltip");
|
|
148
298
|
function Tooltip({ text, children }) {
|
|
299
|
+
const id = (0, import_react4.useId)();
|
|
300
|
+
const [visible, setVisible] = (0, import_react4.useState)(false);
|
|
149
301
|
if (InstalledTooltip) {
|
|
150
|
-
return /* @__PURE__ */ (0,
|
|
302
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(InstalledTooltip, { content: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box, { padding: 2, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { size: 1, children: text }) }), portal: true, children });
|
|
151
303
|
}
|
|
152
|
-
|
|
304
|
+
const described = visible && (0, import_react4.isValidElement)(children) ? (0, import_react4.cloneElement)(children, { "aria-describedby": id }) : children;
|
|
305
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
306
|
+
"span",
|
|
307
|
+
{
|
|
308
|
+
style: { position: "relative", display: "inline-flex" },
|
|
309
|
+
onMouseEnter: () => setVisible(true),
|
|
310
|
+
onMouseLeave: () => setVisible(false),
|
|
311
|
+
onFocusCapture: () => setVisible(true),
|
|
312
|
+
onBlurCapture: () => setVisible(false),
|
|
313
|
+
onKeyDown: (e) => {
|
|
314
|
+
if (e.key === "Escape" && visible) {
|
|
315
|
+
e.stopPropagation();
|
|
316
|
+
setVisible(false);
|
|
317
|
+
}
|
|
318
|
+
},
|
|
319
|
+
children: [
|
|
320
|
+
described,
|
|
321
|
+
visible && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
322
|
+
"span",
|
|
323
|
+
{
|
|
324
|
+
id,
|
|
325
|
+
role: "tooltip",
|
|
326
|
+
style: {
|
|
327
|
+
position: "absolute",
|
|
328
|
+
bottom: "100%",
|
|
329
|
+
left: "50%",
|
|
330
|
+
transform: "translateX(-50%)",
|
|
331
|
+
// No gap between trigger and tooltip, so the pointer can travel onto it
|
|
332
|
+
// without leaving the hover target (WCAG 1.4.13 Hoverable).
|
|
333
|
+
paddingBottom: 4,
|
|
334
|
+
whiteSpace: "nowrap",
|
|
335
|
+
zIndex: 1e3
|
|
336
|
+
},
|
|
337
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Card, { radius: 2, shadow: 2, padding: 2, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Text, { size: 1, children: text }) })
|
|
338
|
+
}
|
|
339
|
+
)
|
|
340
|
+
]
|
|
341
|
+
}
|
|
342
|
+
);
|
|
153
343
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
var
|
|
157
|
-
var
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
344
|
+
|
|
345
|
+
// src/compat/menu.tsx
|
|
346
|
+
var import_react5 = require("react");
|
|
347
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
348
|
+
var InstalledMenuButton = resolveComponent(UI, "MenuButton");
|
|
349
|
+
var InstalledMenu = resolveComponent(UI, "Menu");
|
|
350
|
+
var InstalledMenuItem = resolveComponent(UI, "MenuItem");
|
|
351
|
+
var INSTALLED_MENU = InstalledMenuButton && InstalledMenu && InstalledMenuItem ? { MenuButton: InstalledMenuButton, Menu: InstalledMenu, MenuItem: InstalledMenuItem } : null;
|
|
352
|
+
var itemKey = (item, index) => item.key ?? `${index}-${item.text}`;
|
|
353
|
+
function ActionMenu({ id, label, items, buttonIcon }) {
|
|
354
|
+
const menuId = (0, import_react5.useId)();
|
|
355
|
+
const [open, setOpen] = (0, import_react5.useState)(false);
|
|
356
|
+
const [activeIndex, setActiveIndex] = (0, import_react5.useState)(0);
|
|
357
|
+
const wrapRef = (0, import_react5.useRef)(null);
|
|
358
|
+
const triggerRef = (0, import_react5.useRef)(null);
|
|
359
|
+
const itemRefs = (0, import_react5.useRef)([]);
|
|
360
|
+
const [frozenItems, setFrozenItems] = (0, import_react5.useState)(items);
|
|
361
|
+
const shownItems = open ? frozenItems : items;
|
|
362
|
+
const close = (0, import_react5.useCallback)((returnFocus = true) => {
|
|
363
|
+
setOpen(false);
|
|
364
|
+
if (returnFocus) triggerRef.current?.focus();
|
|
365
|
+
}, []);
|
|
366
|
+
const openMenu = (0, import_react5.useCallback)((index) => {
|
|
367
|
+
setFrozenItems(items);
|
|
368
|
+
setActiveIndex(index);
|
|
369
|
+
setOpen(true);
|
|
370
|
+
}, [items]);
|
|
371
|
+
(0, import_react5.useEffect)(() => {
|
|
372
|
+
if (!open || INSTALLED_MENU) return;
|
|
373
|
+
itemRefs.current[activeIndex]?.focus();
|
|
374
|
+
}, [open, activeIndex]);
|
|
375
|
+
(0, import_react5.useEffect)(() => {
|
|
376
|
+
if (INSTALLED_MENU || !open) return;
|
|
163
377
|
const onPointerDown = (e) => {
|
|
164
|
-
if (
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (
|
|
378
|
+
if (wrapRef.current?.contains(e.target)) return;
|
|
379
|
+
const hadFocus = wrapRef.current?.contains(document.activeElement);
|
|
380
|
+
setOpen(false);
|
|
381
|
+
if (hadFocus) triggerRef.current?.focus();
|
|
168
382
|
};
|
|
169
383
|
document.addEventListener("mousedown", onPointerDown);
|
|
170
|
-
document.
|
|
171
|
-
return () => {
|
|
172
|
-
document.removeEventListener("mousedown", onPointerDown);
|
|
173
|
-
document.removeEventListener("keydown", onKeyDown);
|
|
174
|
-
};
|
|
384
|
+
return () => document.removeEventListener("mousedown", onPointerDown);
|
|
175
385
|
}, [open]);
|
|
176
|
-
const runAction = (0,
|
|
177
|
-
|
|
386
|
+
const runAction = (0, import_react5.useCallback)((item) => {
|
|
387
|
+
close();
|
|
178
388
|
item.onClick?.();
|
|
179
|
-
}, []);
|
|
180
|
-
if (
|
|
181
|
-
const MenuButton =
|
|
182
|
-
|
|
183
|
-
const MenuItem = InstalledMenuItem;
|
|
184
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
389
|
+
}, [close]);
|
|
390
|
+
if (INSTALLED_MENU) {
|
|
391
|
+
const { MenuButton, Menu, MenuItem } = INSTALLED_MENU;
|
|
392
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
185
393
|
MenuButton,
|
|
186
394
|
{
|
|
187
395
|
id,
|
|
188
|
-
button: /* @__PURE__ */ (0,
|
|
396
|
+
button: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Button, { mode: "ghost", icon: buttonIcon, padding: 2, "aria-label": label }),
|
|
189
397
|
popover: { placement: "bottom-end" },
|
|
190
|
-
menu: /* @__PURE__ */ (0,
|
|
398
|
+
menu: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Menu, { children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
191
399
|
MenuItem,
|
|
192
400
|
{
|
|
193
401
|
text: item.text,
|
|
194
402
|
icon: item.icon,
|
|
195
403
|
tone: item.tone,
|
|
196
|
-
...item.href ? { as: "a", href: item.href, target: "_blank", rel: "noreferrer" } : { onClick:
|
|
404
|
+
...item.href ? { as: "a", href: item.href, target: "_blank", rel: "noreferrer" } : { onClick: item.onClick }
|
|
197
405
|
},
|
|
198
|
-
item
|
|
406
|
+
itemKey(item, i)
|
|
199
407
|
)) })
|
|
200
408
|
}
|
|
201
409
|
);
|
|
202
410
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
411
|
+
const onMenuKeyDown = (e) => {
|
|
412
|
+
const last = shownItems.length - 1;
|
|
413
|
+
if (e.key === "Escape") {
|
|
414
|
+
e.stopPropagation();
|
|
415
|
+
close();
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
if (e.key === "Tab") {
|
|
419
|
+
triggerRef.current?.focus();
|
|
420
|
+
setOpen(false);
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
424
|
+
e.preventDefault();
|
|
425
|
+
const item = shownItems[activeIndex];
|
|
426
|
+
if (item) {
|
|
427
|
+
if (item.href) {
|
|
428
|
+
itemRefs.current[activeIndex]?.click();
|
|
429
|
+
} else {
|
|
430
|
+
runAction(item);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
if (e.key === "ArrowDown") {
|
|
436
|
+
e.preventDefault();
|
|
437
|
+
setActiveIndex((i) => i >= last ? 0 : i + 1);
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
if (e.key === "ArrowUp") {
|
|
441
|
+
e.preventDefault();
|
|
442
|
+
setActiveIndex((i) => i <= 0 ? last : i - 1);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
if (e.key === "Home") {
|
|
446
|
+
e.preventDefault();
|
|
447
|
+
setActiveIndex(0);
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
if (e.key === "End") {
|
|
451
|
+
e.preventDefault();
|
|
452
|
+
setActiveIndex(last);
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
};
|
|
456
|
+
const onTriggerKeyDown = (e) => {
|
|
457
|
+
if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
|
|
458
|
+
e.preventDefault();
|
|
459
|
+
openMenu(0);
|
|
460
|
+
} else if (e.key === "ArrowUp") {
|
|
461
|
+
e.preventDefault();
|
|
462
|
+
openMenu(items.length - 1);
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: wrapRef, style: { position: "relative" }, children: [
|
|
466
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
467
|
+
Button,
|
|
206
468
|
{
|
|
469
|
+
ref: triggerRef,
|
|
207
470
|
mode: "ghost",
|
|
208
471
|
icon: buttonIcon,
|
|
209
472
|
padding: 2,
|
|
210
473
|
id,
|
|
474
|
+
"aria-label": label,
|
|
211
475
|
"aria-haspopup": "menu",
|
|
212
476
|
"aria-expanded": open,
|
|
213
|
-
|
|
477
|
+
"aria-controls": open ? menuId : void 0,
|
|
478
|
+
onClick: () => open ? close() : openMenu(0),
|
|
479
|
+
onKeyDown: onTriggerKeyDown
|
|
214
480
|
}
|
|
215
481
|
),
|
|
216
|
-
open && /* @__PURE__ */ (0,
|
|
217
|
-
|
|
482
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
483
|
+
Card,
|
|
218
484
|
{
|
|
485
|
+
id: menuId,
|
|
219
486
|
radius: 2,
|
|
220
487
|
shadow: 3,
|
|
221
488
|
padding: 1,
|
|
222
489
|
role: "menu",
|
|
223
|
-
|
|
224
|
-
|
|
490
|
+
"aria-labelledby": id,
|
|
491
|
+
onKeyDown: onMenuKeyDown,
|
|
492
|
+
style: { position: "absolute", top: "100%", right: 0, marginTop: 4, zIndex: 1e3, minWidth: 200 },
|
|
493
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Stack, { space: 1, role: "none", children: shownItems.map((item, i) => {
|
|
225
494
|
const Icon = item.icon;
|
|
226
|
-
const
|
|
227
|
-
/* @__PURE__ */ (0,
|
|
228
|
-
/* @__PURE__ */ (0,
|
|
495
|
+
const row = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Flex, { align: "center", gap: 2, paddingX: 2, paddingY: 2, children: [
|
|
496
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Icon, { width: "1em", height: "1em", "aria-hidden": "true" }),
|
|
497
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { size: 1, children: item.text })
|
|
229
498
|
] });
|
|
230
|
-
|
|
499
|
+
const content = item.tone === "critical" ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Card, { tone: "critical", radius: 1, children: row }) : row;
|
|
500
|
+
const shared = {
|
|
501
|
+
role: "menuitem",
|
|
502
|
+
// Roving tabindex — the menu is one tab stop, arrows move within it.
|
|
503
|
+
tabIndex: i === activeIndex ? 0 : -1,
|
|
504
|
+
ref: (el) => {
|
|
505
|
+
itemRefs.current[i] = el;
|
|
506
|
+
},
|
|
507
|
+
style: {
|
|
508
|
+
display: "block",
|
|
509
|
+
width: "100%",
|
|
510
|
+
textAlign: "left",
|
|
511
|
+
cursor: "pointer",
|
|
512
|
+
borderRadius: 3,
|
|
513
|
+
background: "none",
|
|
514
|
+
border: 0,
|
|
515
|
+
padding: 0,
|
|
516
|
+
font: "inherit",
|
|
517
|
+
color: "inherit",
|
|
518
|
+
textDecoration: "none",
|
|
519
|
+
// Card suppresses its own focus ring, so the active item draws one explicitly.
|
|
520
|
+
outline: i === activeIndex ? "2px solid var(--card-focus-ring-color, currentColor)" : "none",
|
|
521
|
+
outlineOffset: -2
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
return item.href ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
231
525
|
"a",
|
|
232
526
|
{
|
|
233
|
-
|
|
527
|
+
...shared,
|
|
234
528
|
href: item.href,
|
|
235
529
|
target: "_blank",
|
|
236
530
|
rel: "noreferrer",
|
|
237
|
-
onClick: () =>
|
|
238
|
-
|
|
239
|
-
|
|
531
|
+
onClick: () => {
|
|
532
|
+
setOpen(false);
|
|
533
|
+
triggerRef.current?.focus();
|
|
534
|
+
},
|
|
535
|
+
children: content
|
|
240
536
|
},
|
|
241
|
-
item
|
|
242
|
-
) : /* @__PURE__ */ (0,
|
|
243
|
-
|
|
537
|
+
itemKey(item, i)
|
|
538
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
539
|
+
"div",
|
|
244
540
|
{
|
|
245
|
-
|
|
246
|
-
role: "menuitem",
|
|
247
|
-
tone: item.tone === "critical" ? "critical" : "default",
|
|
248
|
-
radius: 1,
|
|
541
|
+
...shared,
|
|
249
542
|
onClick: () => runAction(item),
|
|
250
|
-
|
|
251
|
-
children: label
|
|
543
|
+
children: content
|
|
252
544
|
},
|
|
253
|
-
item
|
|
545
|
+
itemKey(item, i)
|
|
254
546
|
);
|
|
255
547
|
}) })
|
|
256
548
|
}
|
|
257
549
|
)
|
|
258
550
|
] });
|
|
259
551
|
}
|
|
260
|
-
|
|
552
|
+
|
|
553
|
+
// src/compat/code.tsx
|
|
554
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
555
|
+
var InstalledCode = resolveComponent(UI, "Code");
|
|
261
556
|
var FALLBACK_CODE_STYLE = {
|
|
557
|
+
display: "block",
|
|
262
558
|
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace",
|
|
263
559
|
fontSize: "0.8125rem",
|
|
264
560
|
lineHeight: 1.4,
|
|
265
561
|
margin: 0
|
|
266
562
|
};
|
|
267
563
|
function Code({ style, children }) {
|
|
268
|
-
if (InstalledCode) return /* @__PURE__ */ (0,
|
|
269
|
-
return /* @__PURE__ */ (0,
|
|
564
|
+
if (InstalledCode) return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(InstalledCode, { size: 1, style, children });
|
|
565
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { style: { ...FALLBACK_CODE_STYLE, ...style }, children });
|
|
270
566
|
}
|
|
271
567
|
|
|
272
|
-
// src/components/DeployItem.tsx
|
|
273
|
-
var import_react4 = require("react");
|
|
274
|
-
var import_react_dom = require("react-dom");
|
|
275
|
-
var import_ui5 = require("@sanity/ui");
|
|
276
|
-
|
|
277
568
|
// src/lib/api.ts
|
|
278
569
|
var BASE = "https://api.vercel.com";
|
|
279
570
|
var VERCEL_HOOK_RE = /^https:\/\/api\.vercel\.com\/v1\/integrations\/deploy\//;
|
|
@@ -306,10 +597,14 @@ async function listDeployments(opts) {
|
|
|
306
597
|
return data.deployments ?? [];
|
|
307
598
|
}
|
|
308
599
|
async function cancelDeployment(opts) {
|
|
309
|
-
const params =
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
600
|
+
const params = new URLSearchParams();
|
|
601
|
+
if (opts.teamId) params.set("teamId", opts.teamId);
|
|
602
|
+
const query = params.toString() ? `?${params}` : "";
|
|
603
|
+
await vercelFetch(
|
|
604
|
+
`/v12/deployments/${encodeURIComponent(opts.deploymentId)}/cancel${query}`,
|
|
605
|
+
opts.token,
|
|
606
|
+
{ method: "PATCH" }
|
|
607
|
+
);
|
|
313
608
|
}
|
|
314
609
|
async function triggerDeploy(hookUrl) {
|
|
315
610
|
if (!VERCEL_HOOK_RE.test(hookUrl)) {
|
|
@@ -373,6 +668,11 @@ function safeHref(url) {
|
|
|
373
668
|
return void 0;
|
|
374
669
|
}
|
|
375
670
|
}
|
|
671
|
+
function deploymentHref(host) {
|
|
672
|
+
if (!host) return void 0;
|
|
673
|
+
if (!/^[a-z0-9.-]+$/i.test(host)) return void 0;
|
|
674
|
+
return safeHref(`https://${host}`);
|
|
675
|
+
}
|
|
376
676
|
function shortSha(sha) {
|
|
377
677
|
return sha ? sha.slice(0, 7) : "";
|
|
378
678
|
}
|
|
@@ -415,27 +715,26 @@ function projectHref(inspectorUrl) {
|
|
|
415
715
|
}
|
|
416
716
|
|
|
417
717
|
// src/components/StatusBadge.tsx
|
|
418
|
-
var
|
|
419
|
-
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
718
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
420
719
|
function StatusBadge({ state, showSpinner }) {
|
|
421
720
|
const { label, tone } = stateLabel(state);
|
|
422
721
|
const spinning = showSpinner && (state === "QUEUED" || state === "INITIALIZING" || state === "BUILDING");
|
|
423
|
-
return /* @__PURE__ */ (0,
|
|
424
|
-
spinning && /* @__PURE__ */ (0,
|
|
425
|
-
/* @__PURE__ */ (0,
|
|
722
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Flex, { align: "center", gap: 2, children: [
|
|
723
|
+
spinning && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Spinner, { muted: true }),
|
|
724
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Badge, { tone, padding: 2, children: label })
|
|
426
725
|
] });
|
|
427
726
|
}
|
|
428
727
|
|
|
429
728
|
// src/components/DeployHistory.tsx
|
|
430
|
-
var
|
|
431
|
-
var
|
|
432
|
-
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
729
|
+
var import_react6 = require("react");
|
|
730
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
433
731
|
function DeployHistory({ target, token, onClose }) {
|
|
434
|
-
const
|
|
435
|
-
const [
|
|
436
|
-
const [
|
|
732
|
+
const dialogId = (0, import_react6.useId)();
|
|
733
|
+
const [deployments, setDeployments] = (0, import_react6.useState)([]);
|
|
734
|
+
const [loading, setLoading] = (0, import_react6.useState)(true);
|
|
735
|
+
const [error, setError] = (0, import_react6.useState)(null);
|
|
437
736
|
const { projectId, hookId } = parseHookUrl(target.url);
|
|
438
|
-
const load = (0,
|
|
737
|
+
const load = (0, import_react6.useCallback)(async () => {
|
|
439
738
|
setLoading(true);
|
|
440
739
|
setError(null);
|
|
441
740
|
try {
|
|
@@ -447,64 +746,68 @@ function DeployHistory({ target, token, onClose }) {
|
|
|
447
746
|
setLoading(false);
|
|
448
747
|
}
|
|
449
748
|
}, [projectId, hookId, token, target.teamId]);
|
|
450
|
-
(0,
|
|
749
|
+
(0, import_react6.useEffect)(() => {
|
|
451
750
|
load();
|
|
452
751
|
}, [load]);
|
|
453
|
-
return /* @__PURE__ */ (0,
|
|
454
|
-
|
|
752
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
753
|
+
Dialog,
|
|
455
754
|
{
|
|
456
755
|
header: `${target.name} \u2014 Deployment History`,
|
|
457
|
-
id:
|
|
756
|
+
id: dialogId,
|
|
458
757
|
onClose,
|
|
459
758
|
width: 2,
|
|
460
|
-
footer: /* @__PURE__ */ (0,
|
|
461
|
-
children: /* @__PURE__ */ (0,
|
|
462
|
-
loading && /* @__PURE__ */ (0,
|
|
463
|
-
error && /* @__PURE__ */ (0,
|
|
464
|
-
!loading && !error && deployments.length === 0 && /* @__PURE__ */ (0,
|
|
465
|
-
!loading && deployments.length > 0 && /* @__PURE__ */ (0,
|
|
466
|
-
/* @__PURE__ */ (0,
|
|
467
|
-
/* @__PURE__ */ (0,
|
|
468
|
-
/* @__PURE__ */ (0,
|
|
469
|
-
/* @__PURE__ */ (0,
|
|
470
|
-
/* @__PURE__ */ (0,
|
|
471
|
-
/* @__PURE__ */ (0,
|
|
759
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Box, { padding: 3, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Button, { text: "Close", icon: CloseIcon, mode: "ghost", onClick: onClose }) }),
|
|
760
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Box, { padding: 4, children: [
|
|
761
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Flex, { justify: "center", padding: 6, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Spinner, { muted: true }) }),
|
|
762
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Card, { tone: "critical", padding: 4, radius: 2, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { size: 1, children: error }) }),
|
|
763
|
+
!loading && !error && deployments.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Card, { tone: "transparent", padding: 4, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { size: 1, muted: true, align: "center", children: "No deployments found for this hook." }) }),
|
|
764
|
+
!loading && deployments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Stack, { space: 2, children: [
|
|
765
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Card, { padding: 3, radius: 2, tone: "transparent", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Flex, { gap: 3, children: [
|
|
766
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Box, { flex: 2, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { size: 0, weight: "semibold", muted: true, children: "Preview URL" }) }),
|
|
767
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Box, { flex: 1, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { size: 0, weight: "semibold", muted: true, children: "Status" }) }),
|
|
768
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Box, { flex: 2, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { size: 0, weight: "semibold", muted: true, children: "Branch \xB7 Commit" }) }),
|
|
769
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Box, { flex: 1, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { size: 0, weight: "semibold", muted: true, children: "Deployed" }) }),
|
|
770
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Box, { style: { width: 64 }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { size: 0, weight: "semibold", muted: true, children: "Logs" }) })
|
|
472
771
|
] }) }),
|
|
473
772
|
deployments.map((d) => {
|
|
474
773
|
const { label, tone } = stateLabel(d.state);
|
|
475
774
|
const branch = d.meta?.githubCommitRef ?? "\u2014";
|
|
476
775
|
const sha = shortSha(d.meta?.githubCommitSha);
|
|
477
776
|
const message = d.meta?.githubCommitMessage?.split("\n")[0] ?? "";
|
|
478
|
-
return /* @__PURE__ */ (0,
|
|
479
|
-
/* @__PURE__ */ (0,
|
|
777
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Card, { padding: 3, radius: 2, shadow: 1, tone: "default", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Flex, { gap: 3, align: "center", children: [
|
|
778
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Box, { flex: 2, style: { overflow: "hidden" }, children: deploymentHref(d.url) ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
480
779
|
"a",
|
|
481
780
|
{
|
|
482
|
-
href:
|
|
781
|
+
href: deploymentHref(d.url),
|
|
483
782
|
target: "_blank",
|
|
484
783
|
rel: "noreferrer",
|
|
485
784
|
style: { color: "inherit" },
|
|
486
|
-
children: /* @__PURE__ */ (0,
|
|
785
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { size: 1, style: { textDecoration: "underline" }, children: d.url.length > 36 ? `${d.url.slice(0, 36)}\u2026` : d.url })
|
|
487
786
|
}
|
|
488
|
-
) : /* @__PURE__ */ (0,
|
|
489
|
-
/* @__PURE__ */ (0,
|
|
490
|
-
/* @__PURE__ */ (0,
|
|
491
|
-
/* @__PURE__ */ (0,
|
|
492
|
-
sha && /* @__PURE__ */ (0,
|
|
787
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { size: 1, muted: true, children: "\u2014" }) }),
|
|
788
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Box, { flex: 1, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Badge, { tone, children: label }) }),
|
|
789
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Box, { flex: 2, style: { overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Stack, { space: 1, children: [
|
|
790
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { size: 1, children: branch }),
|
|
791
|
+
sha && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { size: 0, muted: true, children: [
|
|
493
792
|
sha,
|
|
494
793
|
message ? ` \xB7 ${message.slice(0, 40)}${message.length > 40 ? "\u2026" : ""}` : ""
|
|
495
794
|
] })
|
|
496
795
|
] }) }),
|
|
497
|
-
/* @__PURE__ */ (0,
|
|
498
|
-
/* @__PURE__ */ (0,
|
|
499
|
-
|
|
796
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Box, { flex: 1, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { size: 1, muted: true, children: timeAgo(d.created) }) }),
|
|
797
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Box, { style: { width: 64 }, children: safeHref(d.inspectorUrl) ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
798
|
+
Button,
|
|
500
799
|
{
|
|
800
|
+
as: "a",
|
|
801
|
+
href: safeHref(d.inspectorUrl),
|
|
802
|
+
target: "_blank",
|
|
803
|
+
rel: "noreferrer",
|
|
501
804
|
text: "Logs",
|
|
502
805
|
mode: "ghost",
|
|
503
806
|
tone: "default",
|
|
504
807
|
icon: LaunchIcon,
|
|
505
808
|
style: { fontSize: "12px" }
|
|
506
809
|
}
|
|
507
|
-
)
|
|
810
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { size: 1, muted: true, children: "\u2014" }) })
|
|
508
811
|
] }) }, d.uid);
|
|
509
812
|
})
|
|
510
813
|
] })
|
|
@@ -514,58 +817,72 @@ function DeployHistory({ target, token, onClose }) {
|
|
|
514
817
|
}
|
|
515
818
|
|
|
516
819
|
// src/components/DeployItem.tsx
|
|
517
|
-
var
|
|
820
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
518
821
|
var POLL_INTERVAL_MS = 5e3;
|
|
519
822
|
var LABEL_WIDTH = 64;
|
|
520
823
|
var PENDING_TIMEOUT_MS = 6e4;
|
|
521
824
|
function DeployItem({ target, token, onDelete, onEdit }) {
|
|
522
825
|
const { projectId, hookId } = parseHookUrl(target.url);
|
|
523
826
|
const toast = useToast();
|
|
524
|
-
const [deployments, setDeployments] = (0,
|
|
525
|
-
const [loadingInitial, setLoadingInitial] = (0,
|
|
526
|
-
const [pendingSince, setPendingSince] = (0,
|
|
527
|
-
const [canceling, setCanceling] = (0,
|
|
528
|
-
const [deployError, setDeployError] = (0,
|
|
529
|
-
const [showHistory, setShowHistory] = (0,
|
|
530
|
-
const [elapsed, setElapsed] = (0,
|
|
531
|
-
const [copied, setCopied] = (0,
|
|
532
|
-
const [showDetails, setShowDetails] = (0,
|
|
533
|
-
const [showErrorLogs, setShowErrorLogs] = (0,
|
|
534
|
-
const [errorLines, setErrorLines] = (0,
|
|
535
|
-
const [loadingLogs, setLoadingLogs] = (0,
|
|
536
|
-
const [logError, setLogError] = (0,
|
|
537
|
-
const
|
|
827
|
+
const [deployments, setDeployments] = (0, import_react7.useState)([]);
|
|
828
|
+
const [loadingInitial, setLoadingInitial] = (0, import_react7.useState)(true);
|
|
829
|
+
const [pendingSince, setPendingSince] = (0, import_react7.useState)(null);
|
|
830
|
+
const [canceling, setCanceling] = (0, import_react7.useState)(false);
|
|
831
|
+
const [deployError, setDeployError] = (0, import_react7.useState)(null);
|
|
832
|
+
const [showHistory, setShowHistory] = (0, import_react7.useState)(false);
|
|
833
|
+
const [elapsed, setElapsed] = (0, import_react7.useState)(0);
|
|
834
|
+
const [copied, setCopied] = (0, import_react7.useState)(false);
|
|
835
|
+
const [showDetails, setShowDetails] = (0, import_react7.useState)(false);
|
|
836
|
+
const [showErrorLogs, setShowErrorLogs] = (0, import_react7.useState)(false);
|
|
837
|
+
const [errorLines, setErrorLines] = (0, import_react7.useState)([]);
|
|
838
|
+
const [loadingLogs, setLoadingLogs] = (0, import_react7.useState)(false);
|
|
839
|
+
const [logError, setLogError] = (0, import_react7.useState)(null);
|
|
840
|
+
const [pollError, setPollError] = (0, import_react7.useState)(null);
|
|
841
|
+
const triggeredFromUidRef = (0, import_react7.useRef)(void 0);
|
|
842
|
+
const requestSeqRef = (0, import_react7.useRef)(0);
|
|
843
|
+
const mountedRef = (0, import_react7.useRef)(true);
|
|
844
|
+
(0, import_react7.useEffect)(() => {
|
|
845
|
+
mountedRef.current = true;
|
|
846
|
+
return () => {
|
|
847
|
+
mountedRef.current = false;
|
|
848
|
+
};
|
|
849
|
+
}, []);
|
|
538
850
|
const latest = deployments[0];
|
|
539
851
|
const isPending = pendingSince !== null;
|
|
540
852
|
const isActive = isPending || isActiveState(latest?.state);
|
|
541
|
-
const fetchDeployments = (0,
|
|
853
|
+
const fetchDeployments = (0, import_react7.useCallback)(async () => {
|
|
542
854
|
if (!projectId || !hookId || !token) return;
|
|
855
|
+
const seq = ++requestSeqRef.current;
|
|
543
856
|
try {
|
|
544
857
|
const data = await listDeployments({ projectId, hookId, token, teamId: target.teamId });
|
|
858
|
+
if (seq !== requestSeqRef.current || !mountedRef.current) return;
|
|
545
859
|
setDeployments(data);
|
|
860
|
+
setPollError(null);
|
|
546
861
|
} catch (err) {
|
|
547
|
-
|
|
862
|
+
if (seq !== requestSeqRef.current || !mountedRef.current) return;
|
|
863
|
+
setPollError(err instanceof Error ? err.message : "Could not reach the Vercel API");
|
|
864
|
+
console.error("Deploy-vercel-from-sanity: fetch error", err);
|
|
548
865
|
}
|
|
549
866
|
}, [projectId, hookId, token, target.teamId]);
|
|
550
|
-
(0,
|
|
867
|
+
(0, import_react7.useEffect)(() => {
|
|
551
868
|
fetchDeployments().finally(() => setLoadingInitial(false));
|
|
552
869
|
}, [fetchDeployments]);
|
|
553
|
-
(0,
|
|
870
|
+
(0, import_react7.useEffect)(() => {
|
|
554
871
|
if (!isActive) return;
|
|
555
872
|
const id = setInterval(fetchDeployments, POLL_INTERVAL_MS);
|
|
556
873
|
return () => clearInterval(id);
|
|
557
874
|
}, [isActive, fetchDeployments]);
|
|
558
|
-
(0,
|
|
875
|
+
(0, import_react7.useEffect)(() => {
|
|
559
876
|
if (!isPending) return;
|
|
560
877
|
if (latest?.uid && latest.uid !== triggeredFromUidRef.current) setPendingSince(null);
|
|
561
878
|
}, [isPending, latest?.uid]);
|
|
562
|
-
(0,
|
|
879
|
+
(0, import_react7.useEffect)(() => {
|
|
563
880
|
if (!isPending) return;
|
|
564
881
|
const id = setTimeout(() => setPendingSince(null), PENDING_TIMEOUT_MS);
|
|
565
882
|
return () => clearTimeout(id);
|
|
566
883
|
}, [isPending]);
|
|
567
|
-
const prevStateRef = (0,
|
|
568
|
-
(0,
|
|
884
|
+
const prevStateRef = (0, import_react7.useRef)(void 0);
|
|
885
|
+
(0, import_react7.useEffect)(() => {
|
|
569
886
|
const current = latest?.state;
|
|
570
887
|
const prev = prevStateRef.current;
|
|
571
888
|
if (prev && isActiveState(prev) && current && !isActiveState(current)) {
|
|
@@ -579,13 +896,13 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
579
896
|
}
|
|
580
897
|
prevStateRef.current = current;
|
|
581
898
|
}, [latest?.state, target.name, toast]);
|
|
582
|
-
(0,
|
|
899
|
+
(0, import_react7.useEffect)(() => {
|
|
583
900
|
setShowErrorLogs(false);
|
|
584
901
|
setErrorLines([]);
|
|
585
902
|
setLogError(null);
|
|
586
903
|
}, [latest?.uid]);
|
|
587
|
-
const timerRef = (0,
|
|
588
|
-
(0,
|
|
904
|
+
const timerRef = (0, import_react7.useRef)(null);
|
|
905
|
+
(0, import_react7.useEffect)(() => {
|
|
589
906
|
if (isActive) {
|
|
590
907
|
const start = pendingSince ?? latest?.created ?? Date.now();
|
|
591
908
|
setElapsed(Math.floor((Date.now() - start) / 1e3));
|
|
@@ -600,7 +917,7 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
600
917
|
if (timerRef.current) clearInterval(timerRef.current);
|
|
601
918
|
};
|
|
602
919
|
}, [isActive, pendingSince, latest?.created]);
|
|
603
|
-
const deploy = (0,
|
|
920
|
+
const deploy = (0, import_react7.useCallback)(() => {
|
|
604
921
|
(0, import_react_dom.flushSync)(() => {
|
|
605
922
|
setDeployError(null);
|
|
606
923
|
triggeredFromUidRef.current = latest?.uid;
|
|
@@ -616,7 +933,7 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
616
933
|
}
|
|
617
934
|
})();
|
|
618
935
|
}, [target.url, fetchDeployments, latest?.uid]);
|
|
619
|
-
const cancel = (0,
|
|
936
|
+
const cancel = (0, import_react7.useCallback)(async () => {
|
|
620
937
|
if (!latest?.uid) return;
|
|
621
938
|
setCanceling(true);
|
|
622
939
|
try {
|
|
@@ -628,9 +945,9 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
628
945
|
setCanceling(false);
|
|
629
946
|
}
|
|
630
947
|
}, [latest?.uid, token, target.teamId, fetchDeployments]);
|
|
631
|
-
const copyUrl = (0,
|
|
948
|
+
const copyUrl = (0, import_react7.useCallback)(() => {
|
|
632
949
|
if (!latest?.url) return;
|
|
633
|
-
const fullUrl =
|
|
950
|
+
const fullUrl = deploymentHref(latest.url) ?? "";
|
|
634
951
|
navigator.clipboard.writeText(fullUrl).then(() => {
|
|
635
952
|
setCopied(true);
|
|
636
953
|
setTimeout(() => setCopied(false), 2e3);
|
|
@@ -638,7 +955,7 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
638
955
|
window.prompt("Copy deployment URL:", fullUrl);
|
|
639
956
|
});
|
|
640
957
|
}, [latest?.url]);
|
|
641
|
-
const fetchErrorLogs = (0,
|
|
958
|
+
const fetchErrorLogs = (0, import_react7.useCallback)(async () => {
|
|
642
959
|
if (!latest?.uid) return;
|
|
643
960
|
setLoadingLogs(true);
|
|
644
961
|
setLogError(null);
|
|
@@ -656,7 +973,7 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
656
973
|
setLoadingLogs(false);
|
|
657
974
|
}
|
|
658
975
|
}, [latest?.uid, token, target.teamId]);
|
|
659
|
-
const toggleErrorLogs = (0,
|
|
976
|
+
const toggleErrorLogs = (0, import_react7.useCallback)(() => {
|
|
660
977
|
if (!showErrorLogs && errorLines.length === 0 && !logError) fetchErrorLogs();
|
|
661
978
|
setShowErrorLogs((v) => !v);
|
|
662
979
|
}, [showErrorLogs, errorLines.length, logError, fetchErrorLogs]);
|
|
@@ -664,26 +981,26 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
664
981
|
const commitMsg = latest?.meta?.githubCommitMessage?.split("\n")[0];
|
|
665
982
|
const sha = shortSha(latest?.meta?.githubCommitSha);
|
|
666
983
|
const fullSha = latest?.meta?.githubCommitSha;
|
|
667
|
-
const commitHref = githubCommitHref(latest?.meta);
|
|
984
|
+
const commitHref = safeHref(githubCommitHref(latest?.meta) ?? void 0);
|
|
668
985
|
const creator = latest?.creator?.username;
|
|
669
986
|
const deployedAt = latest?.created ? timeAgo(latest.created) : null;
|
|
670
987
|
const vercelProjectUrl = projectHref(latest?.inspectorUrl);
|
|
671
988
|
const isError = latest?.state === "ERROR";
|
|
672
|
-
return /* @__PURE__ */ (0,
|
|
673
|
-
/* @__PURE__ */ (0,
|
|
674
|
-
/* @__PURE__ */ (0,
|
|
675
|
-
/* @__PURE__ */ (0,
|
|
676
|
-
/* @__PURE__ */ (0,
|
|
677
|
-
/* @__PURE__ */ (0,
|
|
678
|
-
/* @__PURE__ */ (0,
|
|
679
|
-
branch && /* @__PURE__ */ (0,
|
|
989
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
990
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Card, { radius: 2, shadow: 1, tone: "default", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { align: "stretch", className: "dvfs-card-flex", children: [
|
|
991
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { direction: "column", flex: 1, style: { minWidth: 0 }, children: [
|
|
992
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Stack, { space: 3, padding: 3, style: { flex: 1 }, children: [
|
|
993
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { align: "center", justify: "space-between", gap: 2, children: [
|
|
994
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { align: "center", gap: 2, style: { minWidth: 0, flexWrap: "wrap" }, children: [
|
|
995
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 2, weight: "semibold", style: { flexShrink: 0 }, children: target.name }),
|
|
996
|
+
branch && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Badge, { tone: "default", padding: 2, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { align: "center", gap: 1, children: [
|
|
680
997
|
branch,
|
|
681
|
-
/* @__PURE__ */ (0,
|
|
998
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 16 16", fill: "currentColor", "aria-hidden": "true", style: { marginLeft: "-0.1em", opacity: 0.5 }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("path", { d: "M5 3.25a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0zm0 2.122a2.25 2.25 0 1 0-1.5 0v.878A2.25 2.25 0 0 0 5.75 8.5h1.5v2.128a2.251 2.251 0 1 0 1.5 0V8.5h1.5a2.25 2.25 0 0 0 2.25-2.25v-.878a2.25 2.25 0 1 0-1.5 0v.878a.75.75 0 0 1-.75.75h-4.5A.75.75 0 0 1 5 6.25v-.878zm3.75 7.378a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0zm3-8.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0z" }) })
|
|
682
999
|
] }) }),
|
|
683
|
-
token && !loadingInitial && /* @__PURE__ */ (0,
|
|
684
|
-
isPending ? /* @__PURE__ */ (0,
|
|
685
|
-
isActiveState(latest?.state) && /* @__PURE__ */ (0,
|
|
686
|
-
|
|
1000
|
+
token && !loadingInitial && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1001
|
+
isPending ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(StatusBadge, { state: "QUEUED" }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(StatusBadge, { state: latest?.state }),
|
|
1002
|
+
isActiveState(latest?.state) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1003
|
+
Button,
|
|
687
1004
|
{
|
|
688
1005
|
text: "Cancel",
|
|
689
1006
|
mode: "ghost",
|
|
@@ -696,17 +1013,18 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
696
1013
|
),
|
|
697
1014
|
isPending ? (
|
|
698
1015
|
/* Optimistic — dimmed spinner only; no elapsed time until a real build exists */
|
|
699
|
-
/* @__PURE__ */ (0,
|
|
700
|
-
) : isActive ? /* @__PURE__ */ (0,
|
|
701
|
-
/* @__PURE__ */ (0,
|
|
702
|
-
/* @__PURE__ */ (0,
|
|
703
|
-
] }) : deployedAt ? /* @__PURE__ */ (0,
|
|
1016
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Spinner, { muted: true, style: { marginLeft: 4, opacity: 0.5 } })
|
|
1017
|
+
) : isActive ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { align: "center", gap: 1, children: [
|
|
1018
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Spinner, { muted: true, style: { marginLeft: 4 } }),
|
|
1019
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 1, muted: true, children: formatDuration(elapsed) })
|
|
1020
|
+
] }) : deployedAt ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 1, muted: true, children: deployedAt }) : null
|
|
704
1021
|
] })
|
|
705
1022
|
] }),
|
|
706
|
-
/* @__PURE__ */ (0,
|
|
1023
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
707
1024
|
ActionMenu,
|
|
708
1025
|
{
|
|
709
1026
|
id: `menu-${target._id}`,
|
|
1027
|
+
label: `Actions for ${target.name}`,
|
|
710
1028
|
buttonIcon: EllipsisVerticalIcon,
|
|
711
1029
|
items: [
|
|
712
1030
|
{ text: "Edit target", icon: EditIcon, onClick: () => onEdit(target) },
|
|
@@ -718,56 +1036,75 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
718
1036
|
}
|
|
719
1037
|
)
|
|
720
1038
|
] }),
|
|
721
|
-
/* @__PURE__ */ (0,
|
|
722
|
-
!token ? /* @__PURE__ */ (0,
|
|
723
|
-
/* @__PURE__ */ (0,
|
|
724
|
-
/* @__PURE__ */ (0,
|
|
725
|
-
] }) : /* @__PURE__ */ (0,
|
|
726
|
-
/* @__PURE__ */ (0,
|
|
727
|
-
latest?.url && latest.state === "READY" && /* @__PURE__ */ (0,
|
|
1039
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("hr", { style: { border: "none", borderTop: "1px solid currentColor", opacity: 0.1, margin: 0 } }),
|
|
1040
|
+
!token ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 1, muted: true, children: "Connect a Vercel API token to see deployment status." }) : loadingInitial ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { align: "center", gap: 2, children: [
|
|
1041
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Spinner, { muted: true }),
|
|
1042
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 1, muted: true, children: "Loading\u2026" })
|
|
1043
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Stack, { space: 2, children: [
|
|
1044
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { align: "center", gap: 2, wrap: "wrap", children: [
|
|
1045
|
+
latest?.url && latest.state === "READY" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_jsx_runtime9.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
728
1046
|
"a",
|
|
729
1047
|
{
|
|
730
|
-
href:
|
|
1048
|
+
href: deploymentHref(latest.url),
|
|
731
1049
|
target: "_blank",
|
|
732
1050
|
rel: "noreferrer",
|
|
733
1051
|
style: { color: "inherit" },
|
|
734
|
-
children: /* @__PURE__ */ (0,
|
|
1052
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Flex, { align: "center", gap: 1, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 1, children: latest.url }) })
|
|
735
1053
|
}
|
|
736
1054
|
) }),
|
|
737
|
-
sha && /* @__PURE__ */ (0,
|
|
1055
|
+
sha && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Tooltip, { text: commitMsg ?? sha, children: commitHref ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
738
1056
|
"a",
|
|
739
1057
|
{
|
|
740
1058
|
href: commitHref,
|
|
741
1059
|
target: "_blank",
|
|
742
1060
|
rel: "noreferrer",
|
|
743
1061
|
style: { color: "inherit", textDecoration: "none" },
|
|
744
|
-
children: /* @__PURE__ */ (0,
|
|
1062
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 1, muted: true, style: { cursor: "pointer", fontFamily: "monospace" }, children: sha })
|
|
745
1063
|
}
|
|
746
|
-
) : /* @__PURE__ */ (0,
|
|
747
|
-
creator && /* @__PURE__ */ (0,
|
|
1064
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 1, muted: true, style: { cursor: "default", fontFamily: "monospace" }, children: sha }) }),
|
|
1065
|
+
creator && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { size: 1, muted: true, children: [
|
|
748
1066
|
"by ",
|
|
749
1067
|
creator
|
|
750
1068
|
] }),
|
|
751
|
-
latest?.state === "READY" && latest.ready && latest.created && /* @__PURE__ */ (0,
|
|
1069
|
+
latest?.state === "READY" && latest.ready && latest.created && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { size: 1, muted: true, children: [
|
|
752
1070
|
"Took ",
|
|
753
1071
|
formatDuration(Math.floor((latest.ready - latest.created) / 1e3)),
|
|
754
1072
|
" to build"
|
|
755
1073
|
] }),
|
|
756
|
-
latest?.url && latest.state === "READY" && /* @__PURE__ */ (0,
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
1074
|
+
latest?.url && latest.state === "READY" && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
|
|
1075
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Tooltip, { text: copied ? "Copied" : "Copy deployment URL", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1076
|
+
Button,
|
|
1077
|
+
{
|
|
1078
|
+
mode: "ghost",
|
|
1079
|
+
icon: copied ? CheckmarkIcon : CopyIcon,
|
|
1080
|
+
padding: 1,
|
|
1081
|
+
tone: copied ? "positive" : "default",
|
|
1082
|
+
onClick: copyUrl,
|
|
1083
|
+
"aria-label": copied ? "Deployment URL copied" : "Copy deployment URL",
|
|
1084
|
+
style: { cursor: "pointer" }
|
|
1085
|
+
}
|
|
1086
|
+
) }),
|
|
1087
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1088
|
+
"span",
|
|
1089
|
+
{
|
|
1090
|
+
role: "status",
|
|
1091
|
+
"aria-live": "polite",
|
|
1092
|
+
style: {
|
|
1093
|
+
position: "absolute",
|
|
1094
|
+
width: 1,
|
|
1095
|
+
height: 1,
|
|
1096
|
+
overflow: "hidden",
|
|
1097
|
+
clip: "rect(0 0 0 0)",
|
|
1098
|
+
whiteSpace: "nowrap"
|
|
1099
|
+
},
|
|
1100
|
+
children: copied ? "Deployment URL copied to clipboard" : ""
|
|
1101
|
+
}
|
|
1102
|
+
)
|
|
1103
|
+
] })
|
|
767
1104
|
] }),
|
|
768
|
-
/* @__PURE__ */ (0,
|
|
769
|
-
commitMsg && /* @__PURE__ */ (0,
|
|
770
|
-
|
|
1105
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { align: "center", gap: 2, wrap: "wrap", children: [
|
|
1106
|
+
commitMsg && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1107
|
+
Text,
|
|
771
1108
|
{
|
|
772
1109
|
size: 0,
|
|
773
1110
|
muted: true,
|
|
@@ -775,10 +1112,11 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
775
1112
|
children: commitMsg
|
|
776
1113
|
}
|
|
777
1114
|
),
|
|
778
|
-
isError && /* @__PURE__ */ (0,
|
|
779
|
-
/* @__PURE__ */ (0,
|
|
780
|
-
|
|
1115
|
+
isError && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Stack, { space: 2, children: [
|
|
1116
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1117
|
+
Button,
|
|
781
1118
|
{
|
|
1119
|
+
"aria-expanded": showErrorLogs,
|
|
782
1120
|
text: showErrorLogs ? "Hide error details" : "Show error details",
|
|
783
1121
|
mode: "ghost",
|
|
784
1122
|
tone: "critical",
|
|
@@ -789,37 +1127,45 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
789
1127
|
style: { alignSelf: "flex-start", cursor: "pointer" }
|
|
790
1128
|
}
|
|
791
1129
|
),
|
|
792
|
-
showErrorLogs && /* @__PURE__ */ (0,
|
|
793
|
-
loadingLogs && /* @__PURE__ */ (0,
|
|
794
|
-
/* @__PURE__ */ (0,
|
|
795
|
-
/* @__PURE__ */ (0,
|
|
1130
|
+
showErrorLogs && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Card, { tone: "critical", radius: 2, padding: 3, children: [
|
|
1131
|
+
loadingLogs && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { align: "center", gap: 2, children: [
|
|
1132
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Spinner, { muted: true }),
|
|
1133
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 1, muted: true, children: "Loading logs\u2026" })
|
|
796
1134
|
] }),
|
|
797
|
-
logError && /* @__PURE__ */ (0,
|
|
798
|
-
/* @__PURE__ */ (0,
|
|
799
|
-
safeHref(latest?.inspectorUrl) && /* @__PURE__ */ (0,
|
|
800
|
-
/* @__PURE__ */ (0,
|
|
801
|
-
/* @__PURE__ */ (0,
|
|
1135
|
+
logError && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Stack, { space: 2, children: [
|
|
1136
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 1, children: logError }),
|
|
1137
|
+
safeHref(latest?.inspectorUrl) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("a", { href: safeHref(latest?.inspectorUrl), target: "_blank", rel: "noreferrer", style: { color: "inherit" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { align: "center", gap: 1, children: [
|
|
1138
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LaunchIcon, {}),
|
|
1139
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 1, children: "View full logs in Vercel" })
|
|
802
1140
|
] }) })
|
|
803
1141
|
] }),
|
|
804
|
-
!loadingLogs && !logError && errorLines.length > 0 && /* @__PURE__ */ (0,
|
|
805
|
-
/* @__PURE__ */ (0,
|
|
806
|
-
safeHref(latest?.inspectorUrl) && /* @__PURE__ */ (0,
|
|
807
|
-
/* @__PURE__ */ (0,
|
|
808
|
-
/* @__PURE__ */ (0,
|
|
1142
|
+
!loadingLogs && !logError && errorLines.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Stack, { space: 2, children: [
|
|
1143
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Box, { style: { maxHeight: 240, overflowY: "auto", fontFamily: "monospace", fontSize: 13, lineHeight: 1.6 }, children: errorLines.map((line, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Code, { style: { display: "block", whiteSpace: "pre-wrap", wordBreak: "break-all" }, children: line }, i)) }),
|
|
1144
|
+
safeHref(latest?.inspectorUrl) && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("a", { href: safeHref(latest?.inspectorUrl), target: "_blank", rel: "noreferrer", style: { color: "inherit" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { align: "center", gap: 1, children: [
|
|
1145
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LaunchIcon, {}),
|
|
1146
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 1, children: "View full logs in Vercel" })
|
|
809
1147
|
] }) })
|
|
810
1148
|
] })
|
|
811
1149
|
] })
|
|
812
1150
|
] }),
|
|
813
|
-
deployError && /* @__PURE__ */ (0,
|
|
1151
|
+
deployError && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Card, { tone: "critical", padding: 2, radius: 2, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 1, children: deployError }) })
|
|
814
1152
|
] })
|
|
815
|
-
] })
|
|
1153
|
+
] }),
|
|
1154
|
+
pollError && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Card, { tone: "caution", padding: 3, radius: 2, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { align: "center", gap: 2, children: [
|
|
1155
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(WarningOutlineIcon, { "aria-hidden": "true" }),
|
|
1156
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { size: 1, children: [
|
|
1157
|
+
"Status updates paused \u2014 ",
|
|
1158
|
+
pollError
|
|
1159
|
+
] })
|
|
1160
|
+
] }) })
|
|
816
1161
|
] }),
|
|
817
|
-
/* @__PURE__ */ (0,
|
|
818
|
-
/* @__PURE__ */ (0,
|
|
819
|
-
|
|
1162
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box, { children: [
|
|
1163
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1164
|
+
Button,
|
|
820
1165
|
{
|
|
821
1166
|
mode: "ghost",
|
|
822
1167
|
iconRight: showDetails ? ChevronUpIcon : ChevronDownIcon,
|
|
1168
|
+
"aria-expanded": showDetails,
|
|
823
1169
|
text: "Details",
|
|
824
1170
|
fontSize: 0,
|
|
825
1171
|
padding: 3,
|
|
@@ -827,62 +1173,62 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
827
1173
|
style: { width: "100%", justifyContent: "flex-start", borderRadius: 0, cursor: "pointer" }
|
|
828
1174
|
}
|
|
829
1175
|
),
|
|
830
|
-
showDetails && /* @__PURE__ */ (0,
|
|
831
|
-
/* @__PURE__ */ (0,
|
|
832
|
-
/* @__PURE__ */ (0,
|
|
833
|
-
/* @__PURE__ */ (0,
|
|
1176
|
+
showDetails && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Card, { tone: "primary", padding: 3, className: "dvfs-accordion-content", style: { borderRadius: 0, borderTop: "1px solid rgba(128,128,128,0.15)" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Stack, { space: 2, children: [
|
|
1177
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { gap: 2, align: "center", children: [
|
|
1178
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, weight: "semibold", style: { minWidth: LABEL_WIDTH }, children: "Project" }),
|
|
1179
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, style: { fontFamily: "monospace" }, children: projectId || "\u2014" })
|
|
834
1180
|
] }),
|
|
835
|
-
/* @__PURE__ */ (0,
|
|
836
|
-
/* @__PURE__ */ (0,
|
|
837
|
-
/* @__PURE__ */ (0,
|
|
1181
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { gap: 2, align: "center", children: [
|
|
1182
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, weight: "semibold", style: { minWidth: LABEL_WIDTH }, children: "Hook" }),
|
|
1183
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, style: { fontFamily: "monospace" }, children: hookId || "\u2014" })
|
|
838
1184
|
] }),
|
|
839
|
-
target.teamId && /* @__PURE__ */ (0,
|
|
840
|
-
/* @__PURE__ */ (0,
|
|
841
|
-
/* @__PURE__ */ (0,
|
|
1185
|
+
target.teamId && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { gap: 2, align: "center", children: [
|
|
1186
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, weight: "semibold", style: { minWidth: LABEL_WIDTH }, children: "Team" }),
|
|
1187
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, style: { fontFamily: "monospace" }, children: target.teamId })
|
|
842
1188
|
] }),
|
|
843
|
-
fullSha && /* @__PURE__ */ (0,
|
|
844
|
-
/* @__PURE__ */ (0,
|
|
845
|
-
/* @__PURE__ */ (0,
|
|
1189
|
+
fullSha && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { gap: 2, align: "flex-start", children: [
|
|
1190
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, weight: "semibold", style: { minWidth: LABEL_WIDTH }, children: "Commit" }),
|
|
1191
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, style: { fontFamily: "monospace", wordBreak: "break-all" }, children: fullSha })
|
|
846
1192
|
] }),
|
|
847
|
-
latest?.meta?.githubCommitAuthorName && /* @__PURE__ */ (0,
|
|
848
|
-
/* @__PURE__ */ (0,
|
|
849
|
-
/* @__PURE__ */ (0,
|
|
1193
|
+
latest?.meta?.githubCommitAuthorName && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { gap: 2, align: "center", children: [
|
|
1194
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, weight: "semibold", style: { minWidth: LABEL_WIDTH }, children: "Author" }),
|
|
1195
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, children: latest.meta.githubCommitAuthorName })
|
|
850
1196
|
] }),
|
|
851
|
-
branch && /* @__PURE__ */ (0,
|
|
852
|
-
/* @__PURE__ */ (0,
|
|
853
|
-
/* @__PURE__ */ (0,
|
|
1197
|
+
branch && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { gap: 2, align: "center", children: [
|
|
1198
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, weight: "semibold", style: { minWidth: LABEL_WIDTH }, children: "Branch" }),
|
|
1199
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, style: { fontFamily: "monospace" }, children: branch })
|
|
854
1200
|
] }),
|
|
855
|
-
latest?.uid && /* @__PURE__ */ (0,
|
|
856
|
-
/* @__PURE__ */ (0,
|
|
857
|
-
/* @__PURE__ */ (0,
|
|
1201
|
+
latest?.uid && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { gap: 2, align: "center", children: [
|
|
1202
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, weight: "semibold", style: { minWidth: LABEL_WIDTH }, children: "Deploy ID" }),
|
|
1203
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, style: { fontFamily: "monospace" }, children: latest.uid })
|
|
858
1204
|
] }),
|
|
859
|
-
latest?.url && /* @__PURE__ */ (0,
|
|
860
|
-
/* @__PURE__ */ (0,
|
|
861
|
-
/* @__PURE__ */ (0,
|
|
1205
|
+
latest?.url && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { gap: 2, align: "flex-start", children: [
|
|
1206
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, weight: "semibold", style: { minWidth: LABEL_WIDTH }, children: "URL" }),
|
|
1207
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, style: { fontFamily: "monospace", wordBreak: "break-all" }, children: latest.url })
|
|
862
1208
|
] }),
|
|
863
|
-
safeHref(latest?.inspectorUrl) && /* @__PURE__ */ (0,
|
|
864
|
-
/* @__PURE__ */ (0,
|
|
865
|
-
/* @__PURE__ */ (0,
|
|
866
|
-
/* @__PURE__ */ (0,
|
|
867
|
-
/* @__PURE__ */ (0,
|
|
1209
|
+
safeHref(latest?.inspectorUrl) && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { gap: 2, align: "center", children: [
|
|
1210
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, weight: "semibold", style: { minWidth: LABEL_WIDTH }, children: "Inspector" }),
|
|
1211
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("a", { href: safeHref(latest?.inspectorUrl), target: "_blank", rel: "noreferrer", style: { color: "inherit" }, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { align: "center", gap: 1, children: [
|
|
1212
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, style: { fontFamily: "monospace" }, children: "Open in Vercel" }),
|
|
1213
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LaunchIcon, { style: { width: 10, height: 10 } })
|
|
868
1214
|
] }) })
|
|
869
1215
|
] }),
|
|
870
|
-
latest?.created && /* @__PURE__ */ (0,
|
|
871
|
-
/* @__PURE__ */ (0,
|
|
872
|
-
/* @__PURE__ */ (0,
|
|
1216
|
+
latest?.created && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Flex, { gap: 2, align: "center", children: [
|
|
1217
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, weight: "semibold", style: { minWidth: LABEL_WIDTH }, children: "Created" }),
|
|
1218
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Text, { size: 0, muted: true, children: new Date(latest.created).toLocaleString() })
|
|
873
1219
|
] })
|
|
874
1220
|
] }) })
|
|
875
1221
|
] })
|
|
876
1222
|
] }),
|
|
877
|
-
/* @__PURE__ */ (0,
|
|
878
|
-
|
|
1223
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1224
|
+
Flex,
|
|
879
1225
|
{
|
|
880
1226
|
direction: "column",
|
|
881
1227
|
gap: 2,
|
|
882
1228
|
className: "dvfs-deploy-col",
|
|
883
1229
|
style: { flexShrink: 0, alignSelf: "stretch" },
|
|
884
|
-
children: /* @__PURE__ */ (0,
|
|
885
|
-
|
|
1230
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1231
|
+
Button,
|
|
886
1232
|
{
|
|
887
1233
|
text: "Deploy",
|
|
888
1234
|
tone: "primary",
|
|
@@ -901,7 +1247,7 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
901
1247
|
}
|
|
902
1248
|
)
|
|
903
1249
|
] }) }),
|
|
904
|
-
showHistory && /* @__PURE__ */ (0,
|
|
1250
|
+
showHistory && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
905
1251
|
DeployHistory,
|
|
906
1252
|
{
|
|
907
1253
|
target,
|
|
@@ -913,17 +1259,19 @@ function DeployItem({ target, token, onDelete, onEdit }) {
|
|
|
913
1259
|
}
|
|
914
1260
|
|
|
915
1261
|
// src/components/TokenSetup.tsx
|
|
916
|
-
var
|
|
1262
|
+
var import_react8 = require("react");
|
|
917
1263
|
var import_sanity = require("sanity");
|
|
918
|
-
var
|
|
919
|
-
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1264
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
920
1265
|
var TOKEN_DOC_ID = "config.vercelDeploy";
|
|
921
|
-
function TokenSetup({ onSaved, onCancel }) {
|
|
1266
|
+
function TokenSetup({ onSaved, onCancel, hasToken = false }) {
|
|
1267
|
+
const dialogId = (0, import_react8.useId)();
|
|
1268
|
+
const tokenId = (0, import_react8.useId)();
|
|
922
1269
|
const client = (0, import_sanity.useClient)({ apiVersion: "2025-01-01" });
|
|
923
|
-
const [token, setToken] = (0,
|
|
924
|
-
const [saving, setSaving] = (0,
|
|
925
|
-
const [error, setError] = (0,
|
|
926
|
-
const
|
|
1270
|
+
const [token, setToken] = (0, import_react8.useState)("");
|
|
1271
|
+
const [saving, setSaving] = (0, import_react8.useState)(false);
|
|
1272
|
+
const [error, setError] = (0, import_react8.useState)(null);
|
|
1273
|
+
const [revoking, setRevoking] = (0, import_react8.useState)(false);
|
|
1274
|
+
const save = (0, import_react8.useCallback)(async () => {
|
|
927
1275
|
if (!token.trim()) return;
|
|
928
1276
|
setSaving(true);
|
|
929
1277
|
setError(null);
|
|
@@ -940,45 +1288,73 @@ function TokenSetup({ onSaved, onCancel }) {
|
|
|
940
1288
|
setSaving(false);
|
|
941
1289
|
}
|
|
942
1290
|
}, [client, token, onSaved]);
|
|
943
|
-
|
|
944
|
-
|
|
1291
|
+
const revoke = (0, import_react8.useCallback)(async () => {
|
|
1292
|
+
setRevoking(true);
|
|
1293
|
+
setError(null);
|
|
1294
|
+
try {
|
|
1295
|
+
await client.delete(TOKEN_DOC_ID);
|
|
1296
|
+
onSaved();
|
|
1297
|
+
} catch (err) {
|
|
1298
|
+
setError(err instanceof Error ? err.message : "Failed to remove token");
|
|
1299
|
+
} finally {
|
|
1300
|
+
setRevoking(false);
|
|
1301
|
+
}
|
|
1302
|
+
}, [client, onSaved]);
|
|
1303
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1304
|
+
Dialog,
|
|
945
1305
|
{
|
|
946
1306
|
header: "Connect Vercel API token",
|
|
947
|
-
id:
|
|
1307
|
+
id: dialogId,
|
|
948
1308
|
onClose: onCancel,
|
|
949
1309
|
width: 1,
|
|
950
|
-
footer: /* @__PURE__ */ (0,
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
import_ui7.Button,
|
|
1310
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Flex, { padding: 3, gap: 2, justify: hasToken ? "space-between" : "flex-end", children: [
|
|
1311
|
+
hasToken && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1312
|
+
Button,
|
|
954
1313
|
{
|
|
955
|
-
text: "
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
1314
|
+
text: "Remove token",
|
|
1315
|
+
mode: "ghost",
|
|
1316
|
+
tone: "critical",
|
|
1317
|
+
icon: TrashIcon,
|
|
1318
|
+
loading: revoking,
|
|
1319
|
+
disabled: revoking || saving,
|
|
1320
|
+
onClick: revoke,
|
|
961
1321
|
style: { cursor: "pointer" }
|
|
962
1322
|
}
|
|
963
|
-
)
|
|
1323
|
+
),
|
|
1324
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Flex, { gap: 2, children: [
|
|
1325
|
+
onCancel && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Button, { text: "Cancel", mode: "ghost", onClick: onCancel, style: { cursor: "pointer" } }),
|
|
1326
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1327
|
+
Button,
|
|
1328
|
+
{
|
|
1329
|
+
text: "Save and connect",
|
|
1330
|
+
tone: "primary",
|
|
1331
|
+
icon: CheckmarkCircleIcon,
|
|
1332
|
+
loading: saving,
|
|
1333
|
+
disabled: !token.trim() || saving,
|
|
1334
|
+
onClick: save,
|
|
1335
|
+
style: { cursor: "pointer" }
|
|
1336
|
+
}
|
|
1337
|
+
)
|
|
1338
|
+
] })
|
|
964
1339
|
] }),
|
|
965
|
-
children: /* @__PURE__ */ (0,
|
|
966
|
-
/* @__PURE__ */ (0,
|
|
967
|
-
/* @__PURE__ */ (0,
|
|
968
|
-
/* @__PURE__ */ (0,
|
|
1340
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Stack, { space: 4, padding: 4, children: [
|
|
1341
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Stack, { space: 3, children: [
|
|
1342
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { size: 1, muted: true, children: "A Vercel API token lets this tool read deployment status, history, build logs, and branch metadata. Without it you can still trigger deploys \u2014 you just won't see any feedback." }),
|
|
1343
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Text, { size: 1, muted: true, children: [
|
|
969
1344
|
"Create one at ",
|
|
970
|
-
/* @__PURE__ */ (0,
|
|
1345
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { children: "vercel.com \u2192 Settings \u2192 Tokens" }),
|
|
971
1346
|
" with",
|
|
972
1347
|
" ",
|
|
973
|
-
/* @__PURE__ */ (0,
|
|
1348
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)("strong", { children: "Full Account" }),
|
|
974
1349
|
" scope. The token is stored in your Sanity dataset and shared across all authenticated studio users."
|
|
975
1350
|
] })
|
|
976
1351
|
] }),
|
|
977
|
-
/* @__PURE__ */ (0,
|
|
978
|
-
/* @__PURE__ */ (0,
|
|
979
|
-
/* @__PURE__ */ (0,
|
|
980
|
-
|
|
1352
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(Stack, { space: 2, children: [
|
|
1353
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Label, { as: "label", size: 1, htmlFor: tokenId, children: "Vercel API Token" }),
|
|
1354
|
+
/* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1355
|
+
TextInput,
|
|
981
1356
|
{
|
|
1357
|
+
id: tokenId,
|
|
982
1358
|
value: token,
|
|
983
1359
|
onChange: (e) => setToken(e.target.value),
|
|
984
1360
|
placeholder: "xxxxxxxxxxxxxxxxxxxxxxxx",
|
|
@@ -986,30 +1362,37 @@ function TokenSetup({ onSaved, onCancel }) {
|
|
|
986
1362
|
}
|
|
987
1363
|
)
|
|
988
1364
|
] }),
|
|
989
|
-
error && /* @__PURE__ */ (0,
|
|
1365
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Card, { tone: "critical", padding: 3, radius: 2, role: "alert", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Text, { size: 1, children: error }) })
|
|
990
1366
|
] })
|
|
991
1367
|
}
|
|
992
1368
|
);
|
|
993
1369
|
}
|
|
994
1370
|
|
|
995
1371
|
// src/components/DeployTargetForm.tsx
|
|
996
|
-
var
|
|
1372
|
+
var import_react9 = require("react");
|
|
997
1373
|
var import_sanity2 = require("sanity");
|
|
998
|
-
var
|
|
999
|
-
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1374
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1000
1375
|
var VERCEL_HOOK_RE2 = /^https:\/\/api\.vercel\.com\/v1\/integrations\/deploy\//;
|
|
1001
1376
|
function DeployTargetForm({ initial, onSaved, onClose }) {
|
|
1002
1377
|
const client = (0, import_sanity2.useClient)({ apiVersion: "2025-01-01" });
|
|
1003
1378
|
const isEdit = Boolean(initial);
|
|
1004
|
-
const
|
|
1005
|
-
const
|
|
1006
|
-
const
|
|
1007
|
-
const
|
|
1008
|
-
const
|
|
1009
|
-
const
|
|
1379
|
+
const dialogId = (0, import_react9.useId)();
|
|
1380
|
+
const nameId = (0, import_react9.useId)();
|
|
1381
|
+
const urlId = (0, import_react9.useId)();
|
|
1382
|
+
const urlErrorId = (0, import_react9.useId)();
|
|
1383
|
+
const urlHelpId = (0, import_react9.useId)();
|
|
1384
|
+
const teamId_ = (0, import_react9.useId)();
|
|
1385
|
+
const teamHelpId = (0, import_react9.useId)();
|
|
1386
|
+
const disableId = (0, import_react9.useId)();
|
|
1387
|
+
const [name, setName] = (0, import_react9.useState)(initial?.name ?? "");
|
|
1388
|
+
const [url, setUrl] = (0, import_react9.useState)(initial?.url ?? "");
|
|
1389
|
+
const [teamId, setTeamId] = (0, import_react9.useState)(initial?.teamId ?? "");
|
|
1390
|
+
const [disableDelete, setDisableDelete] = (0, import_react9.useState)(initial?.disableDeleteAction ?? false);
|
|
1391
|
+
const [saving, setSaving] = (0, import_react9.useState)(false);
|
|
1392
|
+
const [error, setError] = (0, import_react9.useState)(null);
|
|
1010
1393
|
const urlValid = !url || VERCEL_HOOK_RE2.test(url.trim());
|
|
1011
1394
|
const canSave = name.trim() && url.trim() && urlValid;
|
|
1012
|
-
const save = (0,
|
|
1395
|
+
const save = (0, import_react9.useCallback)(async () => {
|
|
1013
1396
|
if (!canSave) return;
|
|
1014
1397
|
setSaving(true);
|
|
1015
1398
|
setError(null);
|
|
@@ -1032,17 +1415,17 @@ function DeployTargetForm({ initial, onSaved, onClose }) {
|
|
|
1032
1415
|
setSaving(false);
|
|
1033
1416
|
}
|
|
1034
1417
|
}, [canSave, isEdit, initial, client, name, url, teamId, disableDelete, onSaved]);
|
|
1035
|
-
return /* @__PURE__ */ (0,
|
|
1036
|
-
|
|
1418
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1419
|
+
Dialog,
|
|
1037
1420
|
{
|
|
1038
1421
|
header: isEdit ? `Edit "${initial?.name}"` : "Add deploy target",
|
|
1039
|
-
id:
|
|
1422
|
+
id: dialogId,
|
|
1040
1423
|
onClose,
|
|
1041
1424
|
width: 1,
|
|
1042
|
-
footer: /* @__PURE__ */ (0,
|
|
1043
|
-
/* @__PURE__ */ (0,
|
|
1044
|
-
/* @__PURE__ */ (0,
|
|
1045
|
-
|
|
1425
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Flex, { padding: 3, gap: 2, justify: "flex-end", children: [
|
|
1426
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Button, { text: "Cancel", mode: "ghost", onClick: onClose, style: { cursor: "pointer" } }),
|
|
1427
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1428
|
+
Button,
|
|
1046
1429
|
{
|
|
1047
1430
|
text: isEdit ? "Save changes" : "Add target",
|
|
1048
1431
|
tone: "primary",
|
|
@@ -1054,95 +1437,105 @@ function DeployTargetForm({ initial, onSaved, onClose }) {
|
|
|
1054
1437
|
}
|
|
1055
1438
|
)
|
|
1056
1439
|
] }),
|
|
1057
|
-
children: /* @__PURE__ */ (0,
|
|
1058
|
-
/* @__PURE__ */ (0,
|
|
1059
|
-
/* @__PURE__ */ (0,
|
|
1440
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Box, { padding: 4, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Stack, { space: 4, children: [
|
|
1441
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Stack, { space: 2, children: [
|
|
1442
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Label, { as: "label", size: 1, htmlFor: nameId, children: [
|
|
1060
1443
|
"Name ",
|
|
1061
|
-
/* @__PURE__ */ (0,
|
|
1444
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { "aria-hidden": "true", children: "*" })
|
|
1062
1445
|
] }),
|
|
1063
|
-
/* @__PURE__ */ (0,
|
|
1064
|
-
|
|
1446
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1447
|
+
TextInput,
|
|
1065
1448
|
{
|
|
1449
|
+
id: nameId,
|
|
1450
|
+
required: true,
|
|
1451
|
+
"aria-required": "true",
|
|
1066
1452
|
value: name,
|
|
1067
1453
|
onChange: (e) => setName(e.target.value),
|
|
1068
1454
|
placeholder: "Production"
|
|
1069
1455
|
}
|
|
1070
1456
|
)
|
|
1071
1457
|
] }),
|
|
1072
|
-
/* @__PURE__ */ (0,
|
|
1073
|
-
/* @__PURE__ */ (0,
|
|
1458
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Stack, { space: 2, children: [
|
|
1459
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Label, { as: "label", size: 1, htmlFor: urlId, children: [
|
|
1074
1460
|
"Deploy hook URL ",
|
|
1075
|
-
/* @__PURE__ */ (0,
|
|
1461
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { "aria-hidden": "true", children: "*" })
|
|
1076
1462
|
] }),
|
|
1077
|
-
/* @__PURE__ */ (0,
|
|
1078
|
-
|
|
1463
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1464
|
+
TextInput,
|
|
1079
1465
|
{
|
|
1466
|
+
id: urlId,
|
|
1467
|
+
required: true,
|
|
1468
|
+
"aria-required": "true",
|
|
1469
|
+
"aria-invalid": Boolean(url) && !urlValid,
|
|
1470
|
+
"aria-describedby": `${urlHelpId}${url && !urlValid ? ` ${urlErrorId}` : ""}`,
|
|
1080
1471
|
value: url,
|
|
1081
1472
|
onChange: (e) => setUrl(e.target.value),
|
|
1082
1473
|
placeholder: "https://api.vercel.com/v1/integrations/deploy/\u2026"
|
|
1083
1474
|
}
|
|
1084
1475
|
),
|
|
1085
|
-
url && !urlValid && /* @__PURE__ */ (0,
|
|
1086
|
-
/* @__PURE__ */ (0,
|
|
1476
|
+
url && !urlValid && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Card, { tone: "critical", padding: 2, radius: 2, role: "alert", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { id: urlErrorId, size: 1, children: "Must be a Vercel deploy hook URL (api.vercel.com/v1/integrations/deploy/\u2026)" }) }),
|
|
1477
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { id: urlHelpId, size: 0, muted: true, children: "Vercel dashboard \u2192 Project \u2192 Settings \u2192 Git \u2192 Deploy Hooks" })
|
|
1087
1478
|
] }),
|
|
1088
|
-
/* @__PURE__ */ (0,
|
|
1089
|
-
/* @__PURE__ */ (0,
|
|
1479
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Stack, { space: 2, children: [
|
|
1480
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Label, { as: "label", size: 1, htmlFor: teamId_, children: [
|
|
1090
1481
|
"Team ID ",
|
|
1091
|
-
/* @__PURE__ */ (0,
|
|
1482
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { style: { opacity: 0.5, fontWeight: "normal" }, children: "\u2014 optional" })
|
|
1092
1483
|
] }),
|
|
1093
|
-
/* @__PURE__ */ (0,
|
|
1094
|
-
|
|
1484
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1485
|
+
TextInput,
|
|
1095
1486
|
{
|
|
1487
|
+
id: teamId_,
|
|
1488
|
+
"aria-describedby": teamHelpId,
|
|
1096
1489
|
value: teamId,
|
|
1097
1490
|
onChange: (e) => setTeamId(e.target.value),
|
|
1098
1491
|
placeholder: "team_xxxxxxxx"
|
|
1099
1492
|
}
|
|
1100
1493
|
),
|
|
1101
|
-
/* @__PURE__ */ (0,
|
|
1494
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Text, { id: teamHelpId, size: 0, muted: true, children: [
|
|
1102
1495
|
"Required for team-owned Vercel projects. Find it at Vercel \u2192 Settings \u2192 General \u2192 Team ID (starts with ",
|
|
1103
|
-
/* @__PURE__ */ (0,
|
|
1496
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("code", { children: "team_" }),
|
|
1104
1497
|
")."
|
|
1105
1498
|
] })
|
|
1106
1499
|
] }),
|
|
1107
|
-
/* @__PURE__ */ (0,
|
|
1108
|
-
/* @__PURE__ */ (0,
|
|
1109
|
-
|
|
1500
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Flex, { align: "center", gap: 3, children: [
|
|
1501
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1502
|
+
Switch,
|
|
1110
1503
|
{
|
|
1111
1504
|
checked: disableDelete,
|
|
1112
1505
|
onChange: (e) => setDisableDelete(e.target.checked),
|
|
1113
|
-
id:
|
|
1506
|
+
id: disableId
|
|
1114
1507
|
}
|
|
1115
1508
|
),
|
|
1116
|
-
/* @__PURE__ */ (0,
|
|
1117
|
-
/* @__PURE__ */ (0,
|
|
1118
|
-
/* @__PURE__ */ (0,
|
|
1509
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Stack, { space: 1, children: [
|
|
1510
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Label, { as: "label", size: 1, htmlFor: disableId, children: "Disable delete action" }),
|
|
1511
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { size: 0, muted: true, children: "Hides the delete button for this target in the studio." })
|
|
1119
1512
|
] })
|
|
1120
1513
|
] }),
|
|
1121
|
-
error && /* @__PURE__ */ (0,
|
|
1514
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Card, { tone: "critical", padding: 3, radius: 2, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Text, { size: 1, children: error }) })
|
|
1122
1515
|
] }) })
|
|
1123
1516
|
}
|
|
1124
1517
|
);
|
|
1125
1518
|
}
|
|
1126
1519
|
|
|
1127
1520
|
// src/version.ts
|
|
1128
|
-
var VERSION = "1.
|
|
1521
|
+
var VERSION = "1.2.1";
|
|
1129
1522
|
|
|
1130
1523
|
// src/components/DeployTool.tsx
|
|
1131
|
-
var
|
|
1524
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
1132
1525
|
var TOKEN_QUERY = `*[_id == "config.vercelDeploy"][0].accessToken`;
|
|
1133
|
-
var TARGETS_QUERY = `*[_type == "vercel_deploy"] | order(_createdAt asc)`;
|
|
1526
|
+
var TARGETS_QUERY = `*[_type == "vercel_deploy" && !(_id in path("drafts.**"))] | order(_createdAt asc)`;
|
|
1134
1527
|
function DeployTool() {
|
|
1135
1528
|
const client = (0, import_sanity3.useClient)({ apiVersion: "2025-01-01" });
|
|
1136
1529
|
const toast = useToast();
|
|
1137
|
-
const [token, setToken] = (0,
|
|
1138
|
-
const [targets, setTargets] = (0,
|
|
1139
|
-
const [loading, setLoading] = (0,
|
|
1140
|
-
const [showTokenSetup, setShowTokenSetup] = (0,
|
|
1141
|
-
const [showCreateForm, setShowCreateForm] = (0,
|
|
1142
|
-
const [pendingEdit, setPendingEdit] = (0,
|
|
1143
|
-
const [pendingDelete, setPendingDelete] = (0,
|
|
1144
|
-
const [deleting, setDeleting] = (0,
|
|
1145
|
-
const load = (0,
|
|
1530
|
+
const [token, setToken] = (0, import_react10.useState)(null);
|
|
1531
|
+
const [targets, setTargets] = (0, import_react10.useState)([]);
|
|
1532
|
+
const [loading, setLoading] = (0, import_react10.useState)(true);
|
|
1533
|
+
const [showTokenSetup, setShowTokenSetup] = (0, import_react10.useState)(false);
|
|
1534
|
+
const [showCreateForm, setShowCreateForm] = (0, import_react10.useState)(false);
|
|
1535
|
+
const [pendingEdit, setPendingEdit] = (0, import_react10.useState)(null);
|
|
1536
|
+
const [pendingDelete, setPendingDelete] = (0, import_react10.useState)(null);
|
|
1537
|
+
const [deleting, setDeleting] = (0, import_react10.useState)(false);
|
|
1538
|
+
const load = (0, import_react10.useCallback)(async () => {
|
|
1146
1539
|
setLoading(true);
|
|
1147
1540
|
try {
|
|
1148
1541
|
const [fetchedToken, fetchedTargets] = await Promise.all([
|
|
@@ -1157,11 +1550,20 @@ function DeployTool() {
|
|
|
1157
1550
|
setLoading(false);
|
|
1158
1551
|
}
|
|
1159
1552
|
}, [client]);
|
|
1160
|
-
(0,
|
|
1553
|
+
(0, import_react10.useEffect)(() => {
|
|
1161
1554
|
load();
|
|
1162
1555
|
}, [load]);
|
|
1163
|
-
(0,
|
|
1164
|
-
|
|
1556
|
+
(0, import_react10.useEffect)(() => {
|
|
1557
|
+
const existing = document.getElementById("dvfs-styles");
|
|
1558
|
+
if (existing) {
|
|
1559
|
+
const n = Number(existing.dataset.refs ?? "1") + 1;
|
|
1560
|
+
existing.dataset.refs = String(n);
|
|
1561
|
+
return () => {
|
|
1562
|
+
const left = Number(existing.dataset.refs ?? "1") - 1;
|
|
1563
|
+
existing.dataset.refs = String(left);
|
|
1564
|
+
if (left <= 0) existing.remove();
|
|
1565
|
+
};
|
|
1566
|
+
}
|
|
1165
1567
|
const style = document.createElement("style");
|
|
1166
1568
|
style.id = "dvfs-styles";
|
|
1167
1569
|
style.textContent = `
|
|
@@ -1182,11 +1584,14 @@ function DeployTool() {
|
|
|
1182
1584
|
}
|
|
1183
1585
|
`;
|
|
1184
1586
|
document.head.appendChild(style);
|
|
1587
|
+
style.dataset.refs = "1";
|
|
1185
1588
|
return () => {
|
|
1186
|
-
|
|
1589
|
+
const left = Number(style.dataset.refs ?? "1") - 1;
|
|
1590
|
+
style.dataset.refs = String(left);
|
|
1591
|
+
if (left <= 0) style.remove();
|
|
1187
1592
|
};
|
|
1188
1593
|
}, []);
|
|
1189
|
-
(0,
|
|
1594
|
+
(0, import_react10.useEffect)(() => {
|
|
1190
1595
|
const sub = client.listen(TARGETS_QUERY).subscribe(() => {
|
|
1191
1596
|
client.fetch(TARGETS_QUERY).then(setTargets).catch((err) => {
|
|
1192
1597
|
console.error("deploy-vercel-from-sanity: subscription refresh error", err);
|
|
@@ -1194,11 +1599,13 @@ function DeployTool() {
|
|
|
1194
1599
|
});
|
|
1195
1600
|
return () => sub.unsubscribe();
|
|
1196
1601
|
}, [client]);
|
|
1197
|
-
const confirmDelete = (0,
|
|
1602
|
+
const confirmDelete = (0, import_react10.useCallback)(async () => {
|
|
1198
1603
|
if (!pendingDelete) return;
|
|
1199
1604
|
setDeleting(true);
|
|
1200
1605
|
try {
|
|
1201
1606
|
await client.delete(pendingDelete._id);
|
|
1607
|
+
await client.delete(`drafts.${pendingDelete._id}`).catch(() => {
|
|
1608
|
+
});
|
|
1202
1609
|
setTargets((prev) => prev.filter((t) => t._id !== pendingDelete._id));
|
|
1203
1610
|
toast.push({ status: "success", title: `Deleted "${pendingDelete.name}"` });
|
|
1204
1611
|
} catch (err) {
|
|
@@ -1209,15 +1616,15 @@ function DeployTool() {
|
|
|
1209
1616
|
}
|
|
1210
1617
|
}, [client, pendingDelete, toast]);
|
|
1211
1618
|
if (loading) {
|
|
1212
|
-
return /* @__PURE__ */ (0,
|
|
1619
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Card, { height: "fill", tone: "transparent", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Flex, { align: "center", justify: "center", height: "fill", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Spinner, { muted: true }) }) });
|
|
1213
1620
|
}
|
|
1214
|
-
return /* @__PURE__ */ (0,
|
|
1215
|
-
/* @__PURE__ */ (0,
|
|
1216
|
-
/* @__PURE__ */ (0,
|
|
1217
|
-
/* @__PURE__ */ (0,
|
|
1218
|
-
/* @__PURE__ */ (0,
|
|
1219
|
-
/* @__PURE__ */ (0,
|
|
1220
|
-
|
|
1621
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Card, { height: "fill", tone: "transparent", children: [
|
|
1622
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Box, { padding: 5, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Stack, { space: 5, children: [
|
|
1623
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Flex, { align: "center", justify: "space-between", className: "dvfs-header", children: [
|
|
1624
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Heading, { size: 2, children: "Deploy with Vercel" }),
|
|
1625
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Flex, { align: "center", gap: 3, className: "dvfs-header-actions", children: [
|
|
1626
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1627
|
+
Button,
|
|
1221
1628
|
{
|
|
1222
1629
|
text: token ? "Token connected" : "Connect API token",
|
|
1223
1630
|
mode: "ghost",
|
|
@@ -1228,8 +1635,8 @@ function DeployTool() {
|
|
|
1228
1635
|
style: { cursor: "pointer" }
|
|
1229
1636
|
}
|
|
1230
1637
|
),
|
|
1231
|
-
/* @__PURE__ */ (0,
|
|
1232
|
-
|
|
1638
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1639
|
+
Button,
|
|
1233
1640
|
{
|
|
1234
1641
|
text: "Add target",
|
|
1235
1642
|
mode: "ghost",
|
|
@@ -1241,13 +1648,13 @@ function DeployTool() {
|
|
|
1241
1648
|
)
|
|
1242
1649
|
] })
|
|
1243
1650
|
] }),
|
|
1244
|
-
!token && /* @__PURE__ */ (0,
|
|
1245
|
-
/* @__PURE__ */ (0,
|
|
1246
|
-
/* @__PURE__ */ (0,
|
|
1247
|
-
/* @__PURE__ */ (0,
|
|
1651
|
+
!token && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Card, { padding: 4, radius: 2, tone: "caution", shadow: 1, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Flex, { align: "center", justify: "space-between", gap: 4, children: [
|
|
1652
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Stack, { space: 2, children: [
|
|
1653
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { size: 1, weight: "semibold", children: "Deploy status is not connected" }),
|
|
1654
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { size: 1, muted: true, children: "You can trigger deploys now. Connect a Vercel API token to also see deployment status, build logs, history, and commit metadata." })
|
|
1248
1655
|
] }),
|
|
1249
|
-
/* @__PURE__ */ (0,
|
|
1250
|
-
|
|
1656
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1657
|
+
Button,
|
|
1251
1658
|
{
|
|
1252
1659
|
text: "Connect",
|
|
1253
1660
|
tone: "caution",
|
|
@@ -1257,16 +1664,16 @@ function DeployTool() {
|
|
|
1257
1664
|
}
|
|
1258
1665
|
)
|
|
1259
1666
|
] }) }),
|
|
1260
|
-
targets.length === 0 && /* @__PURE__ */ (0,
|
|
1261
|
-
/* @__PURE__ */ (0,
|
|
1262
|
-
/* @__PURE__ */ (0,
|
|
1667
|
+
targets.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Card, { padding: 5, radius: 2, tone: "transparent", shadow: 1, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Stack, { space: 4, style: { textAlign: "center" }, children: [
|
|
1668
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { size: 2, weight: "semibold", children: "No deploy targets configured" }),
|
|
1669
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { size: 1, muted: true, children: [
|
|
1263
1670
|
"Add a deploy target using the button above, or create a",
|
|
1264
1671
|
" ",
|
|
1265
|
-
/* @__PURE__ */ (0,
|
|
1672
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("code", { children: "vercel_deploy" }),
|
|
1266
1673
|
" document directly in the dataset."
|
|
1267
1674
|
] }),
|
|
1268
|
-
/* @__PURE__ */ (0,
|
|
1269
|
-
|
|
1675
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Flex, { justify: "center", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1676
|
+
Button,
|
|
1270
1677
|
{
|
|
1271
1678
|
text: "Add deploy target",
|
|
1272
1679
|
tone: "primary",
|
|
@@ -1276,12 +1683,12 @@ function DeployTool() {
|
|
|
1276
1683
|
}
|
|
1277
1684
|
) })
|
|
1278
1685
|
] }) }),
|
|
1279
|
-
targets.length > 0 && /* @__PURE__ */ (0,
|
|
1686
|
+
targets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "dvfs-grid", style: {
|
|
1280
1687
|
display: "grid",
|
|
1281
1688
|
gridTemplateColumns: "repeat(auto-fill, minmax(min(540px, 100%), 1fr))",
|
|
1282
1689
|
gap: "16px",
|
|
1283
1690
|
alignItems: "start"
|
|
1284
|
-
}, children: targets.map((target) => /* @__PURE__ */ (0,
|
|
1691
|
+
}, children: targets.map((target) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1285
1692
|
DeployItem,
|
|
1286
1693
|
{
|
|
1287
1694
|
target,
|
|
@@ -1292,8 +1699,8 @@ function DeployTool() {
|
|
|
1292
1699
|
target._id
|
|
1293
1700
|
)) })
|
|
1294
1701
|
] }) }),
|
|
1295
|
-
/* @__PURE__ */ (0,
|
|
1296
|
-
|
|
1702
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1703
|
+
Box,
|
|
1297
1704
|
{
|
|
1298
1705
|
style: {
|
|
1299
1706
|
position: "fixed",
|
|
@@ -1303,23 +1710,24 @@ function DeployTool() {
|
|
|
1303
1710
|
pointerEvents: "none",
|
|
1304
1711
|
userSelect: "none"
|
|
1305
1712
|
},
|
|
1306
|
-
children: /* @__PURE__ */ (0,
|
|
1713
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { size: 0, muted: true, children: [
|
|
1307
1714
|
"v",
|
|
1308
1715
|
VERSION
|
|
1309
1716
|
] })
|
|
1310
1717
|
}
|
|
1311
1718
|
),
|
|
1312
|
-
showTokenSetup && /* @__PURE__ */ (0,
|
|
1719
|
+
showTokenSetup && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1313
1720
|
TokenSetup,
|
|
1314
1721
|
{
|
|
1315
1722
|
onSaved: () => {
|
|
1316
1723
|
setShowTokenSetup(false);
|
|
1317
1724
|
load();
|
|
1318
1725
|
},
|
|
1319
|
-
onCancel:
|
|
1726
|
+
onCancel: () => setShowTokenSetup(false),
|
|
1727
|
+
hasToken: Boolean(token)
|
|
1320
1728
|
}
|
|
1321
1729
|
),
|
|
1322
|
-
showCreateForm && /* @__PURE__ */ (0,
|
|
1730
|
+
showCreateForm && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1323
1731
|
DeployTargetForm,
|
|
1324
1732
|
{
|
|
1325
1733
|
onSaved: () => {
|
|
@@ -1329,7 +1737,7 @@ function DeployTool() {
|
|
|
1329
1737
|
onClose: () => setShowCreateForm(false)
|
|
1330
1738
|
}
|
|
1331
1739
|
),
|
|
1332
|
-
pendingEdit && /* @__PURE__ */ (0,
|
|
1740
|
+
pendingEdit && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1333
1741
|
DeployTargetForm,
|
|
1334
1742
|
{
|
|
1335
1743
|
initial: pendingEdit,
|
|
@@ -1340,16 +1748,16 @@ function DeployTool() {
|
|
|
1340
1748
|
onClose: () => setPendingEdit(null)
|
|
1341
1749
|
}
|
|
1342
1750
|
),
|
|
1343
|
-
pendingDelete && /* @__PURE__ */ (0,
|
|
1344
|
-
|
|
1751
|
+
pendingDelete && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1752
|
+
Dialog,
|
|
1345
1753
|
{
|
|
1346
1754
|
header: "Delete deploy target?",
|
|
1347
1755
|
id: "confirm-delete",
|
|
1348
1756
|
onClose: () => setPendingDelete(null),
|
|
1349
1757
|
width: 1,
|
|
1350
|
-
footer: /* @__PURE__ */ (0,
|
|
1351
|
-
/* @__PURE__ */ (0,
|
|
1352
|
-
|
|
1758
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Flex, { padding: 3, gap: 2, justify: "flex-end", children: [
|
|
1759
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1760
|
+
Button,
|
|
1353
1761
|
{
|
|
1354
1762
|
text: "Cancel",
|
|
1355
1763
|
mode: "ghost",
|
|
@@ -1357,8 +1765,8 @@ function DeployTool() {
|
|
|
1357
1765
|
style: { cursor: "pointer" }
|
|
1358
1766
|
}
|
|
1359
1767
|
),
|
|
1360
|
-
/* @__PURE__ */ (0,
|
|
1361
|
-
|
|
1768
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
1769
|
+
Button,
|
|
1362
1770
|
{
|
|
1363
1771
|
text: "Delete",
|
|
1364
1772
|
tone: "critical",
|
|
@@ -1370,26 +1778,59 @@ function DeployTool() {
|
|
|
1370
1778
|
}
|
|
1371
1779
|
)
|
|
1372
1780
|
] }),
|
|
1373
|
-
children: /* @__PURE__ */ (0,
|
|
1374
|
-
/* @__PURE__ */ (0,
|
|
1375
|
-
/* @__PURE__ */ (0,
|
|
1376
|
-
/* @__PURE__ */ (0,
|
|
1781
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Box, { padding: 4, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Stack, { space: 3, children: [
|
|
1782
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Flex, { align: "center", gap: 2, children: [
|
|
1783
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(WarningOutlineIcon, {}),
|
|
1784
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { size: 2, weight: "semibold", children: pendingDelete.name })
|
|
1377
1785
|
] }),
|
|
1378
|
-
/* @__PURE__ */ (0,
|
|
1786
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Text, { size: 1, muted: true, children: "This removes the deploy target from the dataset. The Vercel deploy hook itself is not affected." })
|
|
1379
1787
|
] }) })
|
|
1380
1788
|
}
|
|
1381
1789
|
),
|
|
1382
|
-
/* @__PURE__ */ (0,
|
|
1790
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ToastViewport, {})
|
|
1383
1791
|
] });
|
|
1384
1792
|
}
|
|
1385
1793
|
|
|
1386
1794
|
// src/schema/vercelDeploy.ts
|
|
1387
1795
|
var import_sanity4 = require("sanity");
|
|
1796
|
+
|
|
1797
|
+
// src/schema/schemaIcon.tsx
|
|
1798
|
+
var import_react11 = require("react");
|
|
1799
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
1800
|
+
var SchemaRocketIcon = (0, import_react11.forwardRef)(
|
|
1801
|
+
function SchemaRocketIcon2(props, ref) {
|
|
1802
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1803
|
+
"svg",
|
|
1804
|
+
{
|
|
1805
|
+
width: "1em",
|
|
1806
|
+
height: "1em",
|
|
1807
|
+
viewBox: "0 0 25 25",
|
|
1808
|
+
fill: "none",
|
|
1809
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1810
|
+
"aria-hidden": "true",
|
|
1811
|
+
focusable: "false",
|
|
1812
|
+
...props,
|
|
1813
|
+
ref,
|
|
1814
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1815
|
+
"path",
|
|
1816
|
+
{
|
|
1817
|
+
d: "M12.5 20.5L15.5 14M11 9.49999L4.5 12.5M9 14C9 14 7.54688 14.9531 6.5 16C5.5 17 4.5 20.5 4.5 20.5C4.5 20.5 8 19.5 9 18.5C10 17.5 11 16 11 16M9 14C9 14 10.1 9.9 12.5 7.5C15.5 4.5 20.5 4.5 20.5 4.5C20.5 4.5 20.5 9.5 17.5 12.5C15.7492 14.2508 11 16 11 16L9 14ZM16.5 9.99999C16.5 10.8284 15.8284 11.5 15 11.5C14.1716 11.5 13.5 10.8284 13.5 9.99999C13.5 9.17157 14.1716 8.49999 15 8.49999C15.8284 8.49999 16.5 9.17157 16.5 9.99999Z",
|
|
1818
|
+
stroke: "currentColor",
|
|
1819
|
+
strokeWidth: 1.2,
|
|
1820
|
+
strokeLinejoin: "round"
|
|
1821
|
+
}
|
|
1822
|
+
)
|
|
1823
|
+
}
|
|
1824
|
+
);
|
|
1825
|
+
}
|
|
1826
|
+
);
|
|
1827
|
+
|
|
1828
|
+
// src/schema/vercelDeploy.ts
|
|
1388
1829
|
var vercelDeploySchema = (0, import_sanity4.defineType)({
|
|
1389
1830
|
name: "vercel_deploy",
|
|
1390
1831
|
title: "Deploy Target",
|
|
1391
1832
|
type: "document",
|
|
1392
|
-
icon:
|
|
1833
|
+
icon: SchemaRocketIcon,
|
|
1393
1834
|
fields: [
|
|
1394
1835
|
(0, import_sanity4.defineField)({
|
|
1395
1836
|
name: "name",
|