@orange-soft/strapi-deployment-trigger 1.1.2 → 1.2.0

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.
@@ -7,7 +7,7 @@ const react = require("react");
7
7
  const reactIntl = require("react-intl");
8
8
  const designSystem = require("@strapi/design-system");
9
9
  const icons = require("@strapi/icons");
10
- const index = require("./index-SuWmJtOE.js");
10
+ const index = require("./index-w-vQ80Px.js");
11
11
  const getTranslation = (id) => `${index.PLUGIN_ID}.${id}`;
12
12
  const HomePage = () => {
13
13
  const { formatMessage } = reactIntl.useIntl();
@@ -67,9 +67,18 @@ const HomePage = () => {
67
67
  }
68
68
  const settings = status?.settings || {};
69
69
  const parsed = status?.parsed || {};
70
- const isConfigured = status?.configured;
70
+ status?.configured;
71
71
  const hasToken = status?.hasToken;
72
72
  const targets = settings.targets || [];
73
+ const hasGitHubTargets = targets.some((t) => (t.type || "github") === "github");
74
+ targets.some((t) => t.type === "vercel");
75
+ const canTrigger = (target) => {
76
+ const targetType = target.type || "github";
77
+ if (targetType === "github") {
78
+ return hasToken && parsed.owner && parsed.repo;
79
+ }
80
+ return !!target.webhookUrl;
81
+ };
73
82
  return /* @__PURE__ */ jsxRuntime.jsxs(admin.Layouts.Root, { children: [
74
83
  /* @__PURE__ */ jsxRuntime.jsx(
75
84
  admin.Layouts.Header,
@@ -105,8 +114,8 @@ const HomePage = () => {
105
114
  ] })
106
115
  }
107
116
  ) }),
108
- !hasToken && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { title: "Token Missing", variant: "danger", children: "GitHub Personal Access Token is not configured. Please add it in Settings." }) }),
109
- !settings.repoUrl && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { title: "Configuration Required", variant: "warning", children: "Please configure your GitHub repository in the Settings page before triggering deployments." }) }),
117
+ hasGitHubTargets && !hasToken && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { title: "Token Missing", variant: "danger", children: "GitHub Personal Access Token is not configured. Please add it in Settings." }) }),
118
+ hasGitHubTargets && !settings.repoUrl && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Alert, { title: "Configuration Required", variant: "warning", children: "Please configure your GitHub repository in the Settings page before triggering deployments." }) }),
110
119
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
111
120
  /* @__PURE__ */ jsxRuntime.jsx(
112
121
  designSystem.Box,
@@ -159,27 +168,34 @@ const HomePage = () => {
159
168
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", tag: "h2", children: "Deployment Targets" }),
160
169
  targets.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Table, { children: [
161
170
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
171
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Type" }) }),
162
172
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Name" }) }),
163
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Workflow" }) }),
164
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Branch" }) }),
173
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Details" }) }),
165
174
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Action" }) })
166
175
  ] }) }),
167
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: targets.map((target) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
168
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", children: target.name }) }),
169
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: target.workflow }) }),
170
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: target.branch }) }),
171
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(
172
- designSystem.Button,
173
- {
174
- onClick: () => handleDeploy(target.id, target.name),
175
- loading: deployingTargetId === target.id,
176
- disabled: !isConfigured || deployingTargetId !== null,
177
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Rocket, {}),
178
- size: "S",
179
- children: deployingTargetId === target.id ? "Triggering..." : "Trigger"
180
- }
181
- ) })
182
- ] }, target.id)) })
176
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: targets.map((target) => {
177
+ const targetType = target.type || "github";
178
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
179
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", textColor: targetType === "github" ? "neutral800" : "secondary600", children: targetType === "github" ? "GitHub" : "Vercel" }) }),
180
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", children: target.name }) }),
181
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: targetType === "github" ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "omega", textColor: "neutral600", children: [
182
+ target.workflow,
183
+ " / ",
184
+ target.branch
185
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", textColor: "neutral600", children: "Webhook" }) }),
186
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(
187
+ designSystem.Button,
188
+ {
189
+ onClick: () => handleDeploy(target.id, target.name),
190
+ loading: deployingTargetId === target.id,
191
+ disabled: !canTrigger(target) || deployingTargetId !== null,
192
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Rocket, {}),
193
+ size: "S",
194
+ children: deployingTargetId === target.id ? "Triggering..." : "Trigger"
195
+ }
196
+ ) })
197
+ ] }, target.id);
198
+ }) })
183
199
  ] }) : /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", justifyContent: "center", gap: 3, padding: 6, children: [
184
200
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral600", textAlign: "center", children: "No deployment targets configured" }),
185
201
  /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Link, { to: `/plugins/${index.PLUGIN_ID}/settings`, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "default", startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Cog, {}), children: "Add Targets in Settings" }) })
@@ -187,7 +203,7 @@ const HomePage = () => {
187
203
  ] })
188
204
  }
189
205
  ),
190
- !isConfigured && targets.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
206
+ hasGitHubTargets && (!hasToken || !parsed.owner || !parsed.repo) && /* @__PURE__ */ jsxRuntime.jsx(
191
207
  designSystem.Box,
192
208
  {
193
209
  background: "neutral0",
@@ -198,8 +214,8 @@ const HomePage = () => {
198
214
  paddingLeft: 7,
199
215
  paddingRight: 7,
200
216
  children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", justifyContent: "center", gap: 3, children: [
201
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", textColor: "neutral600", textAlign: "center", children: "Setup Incomplete" }),
202
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral600", textAlign: "center", children: "Please ensure repository URL and GitHub token are configured in Settings." }),
217
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", textColor: "neutral600", textAlign: "center", children: "GitHub Setup Incomplete" }),
218
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", textColor: "neutral600", textAlign: "center", children: "Please ensure repository URL and GitHub token are configured in Settings for GitHub targets." }),
203
219
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Link, { to: `/plugins/${index.PLUGIN_ID}/settings`, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "default", startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Cog, {}), children: "Go to Settings" }) }) })
204
220
  ] })
205
221
  }
@@ -211,6 +227,7 @@ const HomePage = () => {
211
227
  const TOKEN_PATTERN = /^github_pat_[a-zA-Z0-9_]+$/;
212
228
  const REPO_URL_PATTERN = /^https:\/\/github\.com\/[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+\/?$/;
213
229
  const WORKFLOW_PATTERN = /^[a-zA-Z0-9_.-]+\.ya?ml$/;
230
+ const VERCEL_WEBHOOK_PATTERN = /^https:\/\/api\.vercel\.com\/v1\/integrations\/deploy\/.+$/;
214
231
  const validateToken = (value) => {
215
232
  if (!value) return null;
216
233
  if (!TOKEN_PATTERN.test(value)) {
@@ -232,6 +249,13 @@ const validateWorkflow = (value) => {
232
249
  }
233
250
  return null;
234
251
  };
252
+ const validateVercelWebhook = (value) => {
253
+ if (!value) return "Webhook URL is required";
254
+ if (!VERCEL_WEBHOOK_PATTERN.test(value)) {
255
+ return "Must be a valid Vercel deploy hook URL (https://api.vercel.com/v1/integrations/deploy/...)";
256
+ }
257
+ return null;
258
+ };
235
259
  const SettingsPage = () => {
236
260
  const navigate = reactRouterDom.useNavigate();
237
261
  const { get, put, post, del } = admin.useFetchClient();
@@ -247,7 +271,7 @@ const SettingsPage = () => {
247
271
  const [saving, setSaving] = react.useState(false);
248
272
  const [notification, setNotification] = react.useState(null);
249
273
  const [editingTarget, setEditingTarget] = react.useState(null);
250
- const [targetForm, setTargetForm] = react.useState({ name: "", workflow: "", branch: "" });
274
+ const [targetForm, setTargetForm] = react.useState({ type: "github", name: "", workflow: "", branch: "", webhookUrl: "" });
251
275
  const [targetErrors, setTargetErrors] = react.useState({});
252
276
  const [showAddForm, setShowAddForm] = react.useState(false);
253
277
  const [deleteDialogOpen, setDeleteDialogOpen] = react.useState(false);
@@ -311,7 +335,7 @@ const SettingsPage = () => {
311
335
  }
312
336
  };
313
337
  const resetTargetForm = () => {
314
- setTargetForm({ name: "", workflow: "deploy.yml", branch: "master" });
338
+ setTargetForm({ type: "github", name: "", workflow: "deploy.yml", branch: "master", webhookUrl: "" });
315
339
  setTargetErrors({});
316
340
  setEditingTarget(null);
317
341
  setShowAddForm(false);
@@ -319,9 +343,14 @@ const SettingsPage = () => {
319
343
  const validateTargetForm = () => {
320
344
  const newErrors = {};
321
345
  if (!targetForm.name.trim()) newErrors.name = "Name is required";
322
- const workflowError = validateWorkflow(targetForm.workflow);
323
- if (workflowError) newErrors.workflow = workflowError;
324
- if (!targetForm.branch.trim()) newErrors.branch = "Branch is required";
346
+ if (targetForm.type === "github") {
347
+ const workflowError = validateWorkflow(targetForm.workflow);
348
+ if (workflowError) newErrors.workflow = workflowError;
349
+ if (!targetForm.branch.trim()) newErrors.branch = "Branch is required";
350
+ } else if (targetForm.type === "vercel") {
351
+ const webhookError = validateVercelWebhook(targetForm.webhookUrl);
352
+ if (webhookError) newErrors.webhookUrl = webhookError;
353
+ }
325
354
  setTargetErrors(newErrors);
326
355
  return Object.keys(newErrors).length === 0;
327
356
  };
@@ -342,7 +371,13 @@ const SettingsPage = () => {
342
371
  };
343
372
  const handleEditTarget = (target) => {
344
373
  setEditingTarget(target.id);
345
- setTargetForm({ name: target.name, workflow: target.workflow, branch: target.branch });
374
+ setTargetForm({
375
+ type: target.type || "github",
376
+ name: target.name,
377
+ workflow: target.workflow || "deploy.yml",
378
+ branch: target.branch || "master",
379
+ webhookUrl: target.webhookUrl || ""
380
+ });
346
381
  setShowAddForm(false);
347
382
  };
348
383
  const handleUpdateTarget = async () => {
@@ -484,7 +519,7 @@ const SettingsPage = () => {
484
519
  startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
485
520
  onClick: () => {
486
521
  setShowAddForm(true);
487
- setTargetForm({ name: "", workflow: "deploy.yml", branch: "master" });
522
+ setTargetForm({ type: "github", name: "", workflow: "deploy.yml", branch: "master", webhookUrl: "" });
488
523
  },
489
524
  size: "S",
490
525
  children: "Add Target"
@@ -500,7 +535,21 @@ const SettingsPage = () => {
500
535
  children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 4, children: [
501
536
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", children: editingTarget ? "Edit Target" : "Add New Target" }),
502
537
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 4, children: [
503
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "targetName", required: true, error: targetErrors.name, children: [
538
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 3, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "targetType", required: true, children: [
539
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Type" }),
540
+ /* @__PURE__ */ jsxRuntime.jsxs(
541
+ designSystem.SingleSelect,
542
+ {
543
+ value: targetForm.type,
544
+ onChange: (value) => setTargetForm((prev) => ({ ...prev, type: value })),
545
+ children: [
546
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "github", children: "GitHub" }),
547
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "vercel", children: "Vercel" })
548
+ ]
549
+ }
550
+ )
551
+ ] }) }),
552
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 3, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "targetName", required: true, error: targetErrors.name, children: [
504
553
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Name" }),
505
554
  /* @__PURE__ */ jsxRuntime.jsx(
506
555
  designSystem.Field.Input,
@@ -512,26 +561,40 @@ const SettingsPage = () => {
512
561
  ),
513
562
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
514
563
  ] }) }),
515
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "targetWorkflow", required: true, error: targetErrors.workflow, children: [
516
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Workflow File" }),
517
- /* @__PURE__ */ jsxRuntime.jsx(
518
- designSystem.Field.Input,
519
- {
520
- placeholder: "deploy.yml",
521
- value: targetForm.workflow,
522
- onChange: handleTargetFormChange("workflow")
523
- }
524
- ),
525
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
526
- ] }) }),
527
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 4, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "targetBranch", required: true, error: targetErrors.branch, children: [
528
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Branch" }),
564
+ targetForm.type === "github" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
565
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 3, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "targetWorkflow", required: true, error: targetErrors.workflow, children: [
566
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Workflow File" }),
567
+ /* @__PURE__ */ jsxRuntime.jsx(
568
+ designSystem.Field.Input,
569
+ {
570
+ placeholder: "deploy.yml",
571
+ value: targetForm.workflow,
572
+ onChange: handleTargetFormChange("workflow")
573
+ }
574
+ ),
575
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
576
+ ] }) }),
577
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 3, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "targetBranch", required: true, error: targetErrors.branch, children: [
578
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Branch" }),
579
+ /* @__PURE__ */ jsxRuntime.jsx(
580
+ designSystem.Field.Input,
581
+ {
582
+ placeholder: "main",
583
+ value: targetForm.branch,
584
+ onChange: handleTargetFormChange("branch")
585
+ }
586
+ ),
587
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
588
+ ] }) })
589
+ ] }),
590
+ targetForm.type === "vercel" && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { col: 6, s: 12, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: "targetWebhookUrl", required: true, error: targetErrors.webhookUrl, children: [
591
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Webhook URL" }),
529
592
  /* @__PURE__ */ jsxRuntime.jsx(
530
593
  designSystem.Field.Input,
531
594
  {
532
- placeholder: "main",
533
- value: targetForm.branch,
534
- onChange: handleTargetFormChange("branch")
595
+ placeholder: "https://api.vercel.com/v1/integrations/deploy/...",
596
+ value: targetForm.webhookUrl,
597
+ onChange: handleTargetFormChange("webhookUrl")
535
598
  }
536
599
  ),
537
600
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
@@ -553,39 +616,48 @@ const SettingsPage = () => {
553
616
  ),
554
617
  settings.targets.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Table, { children: [
555
618
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
619
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Type" }) }),
556
620
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Name" }) }),
557
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Workflow" }) }),
558
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Branch" }) }),
621
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Details" }) }),
559
622
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Actions" }) })
560
623
  ] }) }),
561
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: settings.targets.map((target) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
562
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: target.name }) }),
563
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: target.workflow }) }),
564
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: target.branch }) }),
565
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 1, children: [
566
- /* @__PURE__ */ jsxRuntime.jsx(
567
- designSystem.IconButton,
568
- {
569
- onClick: () => handleEditTarget(target),
570
- label: "Edit",
571
- variant: "ghost",
572
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, {})
573
- }
574
- ),
575
- /* @__PURE__ */ jsxRuntime.jsx(
576
- designSystem.IconButton,
577
- {
578
- onClick: () => {
579
- setTargetToDelete(target.id);
580
- setDeleteDialogOpen(true);
581
- },
582
- label: "Delete",
583
- variant: "ghost",
584
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {})
585
- }
586
- )
587
- ] }) })
588
- ] }, target.id)) })
624
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: settings.targets.map((target) => {
625
+ const targetType = target.type || "github";
626
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
627
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "bold", textColor: targetType === "github" ? "neutral800" : "secondary600", children: targetType === "github" ? "GitHub" : "Vercel" }) }),
628
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", children: target.name }) }),
629
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: targetType === "github" ? /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "omega", textColor: "neutral600", children: [
630
+ target.workflow,
631
+ " / ",
632
+ target.branch
633
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", textColor: "neutral600", children: "Webhook configured" }) }),
634
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
635
+ /* @__PURE__ */ jsxRuntime.jsx(
636
+ designSystem.Button,
637
+ {
638
+ onClick: () => handleEditTarget(target),
639
+ variant: "tertiary",
640
+ size: "S",
641
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Pencil, {}),
642
+ children: "Edit"
643
+ }
644
+ ),
645
+ /* @__PURE__ */ jsxRuntime.jsx(
646
+ designSystem.Button,
647
+ {
648
+ onClick: () => {
649
+ setTargetToDelete(target.id);
650
+ setDeleteDialogOpen(true);
651
+ },
652
+ variant: "danger-light",
653
+ size: "S",
654
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {}),
655
+ children: "Delete"
656
+ }
657
+ )
658
+ ] }) })
659
+ ] }, target.id);
660
+ }) })
589
661
  ] }) : !showAddForm && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: 'No deployment targets configured. Click "Add Target" to create one.' })
590
662
  ] })
591
663
  }
@@ -36,7 +36,7 @@ const index = {
36
36
  defaultMessage: PLUGIN_ID
37
37
  },
38
38
  Component: async () => {
39
- const { App } = await import("./App-DRqMK_8x.mjs");
39
+ const { App } = await import("./App-k07qAAvE.mjs");
40
40
  return App;
41
41
  }
42
42
  });
@@ -37,7 +37,7 @@ const index = {
37
37
  defaultMessage: PLUGIN_ID
38
38
  },
39
39
  Component: async () => {
40
- const { App } = await Promise.resolve().then(() => require("./App-CCbQMMHR.js"));
40
+ const { App } = await Promise.resolve().then(() => require("./App-vIrt97zQ.js"));
41
41
  return App;
42
42
  }
43
43
  });
@@ -1,3 +1,3 @@
1
1
  "use strict";
2
- const index = require("../_chunks/index-SuWmJtOE.js");
2
+ const index = require("../_chunks/index-w-vQ80Px.js");
3
3
  module.exports = index.index;
@@ -1,4 +1,4 @@
1
- import { i } from "../_chunks/index-vQ0KWcpU.mjs";
1
+ import { i } from "../_chunks/index-BwZtnn__.mjs";
2
2
  export {
3
3
  i as default
4
4
  };
@@ -69,6 +69,30 @@ const controller = ({ strapi }) => ({
69
69
  },
70
70
  // Trigger deployment for a specific target
71
71
  async trigger(ctx) {
72
+ const service2 = getService(strapi);
73
+ const { targetId } = ctx.request.body || {};
74
+ let target;
75
+ if (targetId) {
76
+ target = await service2.getTarget(targetId);
77
+ if (!target) {
78
+ return ctx.badRequest("Target not found");
79
+ }
80
+ } else {
81
+ const settings = await service2.getSettings();
82
+ target = settings.targets?.[0];
83
+ if (!target) {
84
+ return ctx.badRequest("No deployment targets configured");
85
+ }
86
+ }
87
+ const targetType = target.type || "github";
88
+ if (targetType === "vercel") {
89
+ return this.triggerVercel(ctx, target);
90
+ } else {
91
+ return this.triggerGitHub(ctx, target);
92
+ }
93
+ },
94
+ // Trigger GitHub Actions deployment
95
+ async triggerGitHub(ctx, target) {
72
96
  const service2 = getService(strapi);
73
97
  const githubToken = await service2.getToken();
74
98
  if (!githubToken) {
@@ -79,22 +103,9 @@ const controller = ({ strapi }) => ({
79
103
  if (!owner || !repo) {
80
104
  return ctx.badRequest("GitHub repository URL is not configured or invalid. Please configure it in Settings.");
81
105
  }
82
- const { targetId, workflow: overrideWorkflow, branch: overrideBranch } = ctx.request.body || {};
83
- let workflow, branch, targetName;
84
- if (targetId) {
85
- const target = await service2.getTarget(targetId);
86
- if (!target) {
87
- return ctx.badRequest("Target not found");
88
- }
89
- workflow = overrideWorkflow || target.workflow;
90
- branch = overrideBranch || target.branch;
91
- targetName = target.name;
92
- } else {
93
- const firstTarget = settings.targets?.[0];
94
- workflow = overrideWorkflow || firstTarget?.workflow || "deploy.yml";
95
- branch = overrideBranch || firstTarget?.branch || "master";
96
- targetName = firstTarget?.name || "Default";
97
- }
106
+ const workflow = target.workflow || "deploy.yml";
107
+ const branch = target.branch || "master";
108
+ const targetName = target.name;
98
109
  const url = `https://api.github.com/repos/${owner}/${repo}/actions/workflows/${workflow}/dispatches`;
99
110
  try {
100
111
  const response = await fetch(url, {
@@ -111,11 +122,12 @@ const controller = ({ strapi }) => ({
111
122
  strapi.log.error(`GitHub API error: ${response.status} - ${errorText}`);
112
123
  return ctx.badRequest(`GitHub API error: ${response.status} - ${errorText}`);
113
124
  }
114
- strapi.log.info(`Deployment triggered for ${owner}/${repo} [${targetName}] on branch ${branch}`);
125
+ strapi.log.info(`GitHub deployment triggered for ${owner}/${repo} [${targetName}] on branch ${branch}`);
115
126
  const actionsUrl = `https://github.com/${owner}/${repo}/actions`;
116
127
  ctx.body = {
117
128
  data: {
118
129
  success: true,
130
+ type: "github",
119
131
  message: `Deployment triggered successfully for ${owner}/${repo}`,
120
132
  repository: `${owner}/${repo}`,
121
133
  targetName,
@@ -125,9 +137,39 @@ const controller = ({ strapi }) => ({
125
137
  }
126
138
  };
127
139
  } catch (error) {
128
- strapi.log.error("Error triggering deployment:", error);
140
+ strapi.log.error("Error triggering GitHub deployment:", error);
129
141
  return ctx.badRequest(`Failed to trigger deployment: ${error.message}`);
130
142
  }
143
+ },
144
+ // Trigger Vercel deployment via webhook
145
+ async triggerVercel(ctx, target) {
146
+ const webhookUrl = target.webhookUrl;
147
+ const targetName = target.name;
148
+ if (!webhookUrl) {
149
+ return ctx.badRequest("Vercel webhook URL is not configured for this target.");
150
+ }
151
+ try {
152
+ const response = await fetch(webhookUrl, {
153
+ method: "POST"
154
+ });
155
+ if (!response.ok) {
156
+ const errorText = await response.text();
157
+ strapi.log.error(`Vercel webhook error: ${response.status} - ${errorText}`);
158
+ return ctx.badRequest(`Vercel webhook error: ${response.status} - ${errorText}`);
159
+ }
160
+ strapi.log.info(`Vercel deployment triggered [${targetName}]`);
161
+ ctx.body = {
162
+ data: {
163
+ success: true,
164
+ type: "vercel",
165
+ message: "Vercel deployment triggered successfully",
166
+ targetName
167
+ }
168
+ };
169
+ } catch (error) {
170
+ strapi.log.error("Error triggering Vercel deployment:", error);
171
+ return ctx.badRequest(`Failed to trigger Vercel deployment: ${error.message}`);
172
+ }
131
173
  }
132
174
  });
133
175
  const controllers = {
@@ -249,7 +291,14 @@ const service = ({ strapi }) => ({
249
291
  migrateSettings(settings) {
250
292
  if (!settings) return null;
251
293
  if (Array.isArray(settings.targets)) {
252
- return settings;
294
+ const targetsWithType = settings.targets.map((target) => ({
295
+ ...target,
296
+ type: target.type || "github"
297
+ }));
298
+ return {
299
+ ...settings,
300
+ targets: targetsWithType
301
+ };
253
302
  }
254
303
  if (settings.workflow || settings.branch) {
255
304
  return {
@@ -257,6 +306,7 @@ const service = ({ strapi }) => ({
257
306
  githubToken: settings.githubToken || "",
258
307
  targets: [{
259
308
  id: generateId(),
309
+ type: "github",
260
310
  name: "Default",
261
311
  workflow: settings.workflow || "deploy.yml",
262
312
  branch: settings.branch || "master"
@@ -313,12 +363,18 @@ const service = ({ strapi }) => ({
313
363
  const store = strapi.store({ type: "plugin", name: PLUGIN_ID });
314
364
  let settings = await store.get({ key: STORE_KEY }) || DEFAULT_SETTINGS;
315
365
  settings = this.migrateSettings(settings) || DEFAULT_SETTINGS;
366
+ const targetType = target.type || "github";
316
367
  const newTarget = {
317
368
  id: generateId(),
318
- name: target.name || "New Target",
319
- workflow: target.workflow || "deploy.yml",
320
- branch: target.branch || "master"
369
+ type: targetType,
370
+ name: target.name || "New Target"
321
371
  };
372
+ if (targetType === "github") {
373
+ newTarget.workflow = target.workflow || "deploy.yml";
374
+ newTarget.branch = target.branch || "master";
375
+ } else if (targetType === "vercel") {
376
+ newTarget.webhookUrl = target.webhookUrl || "";
377
+ }
322
378
  settings.targets = [...settings.targets || [], newTarget];
323
379
  await store.set({ key: STORE_KEY, value: settings });
324
380
  return newTarget;
@@ -330,12 +386,20 @@ const service = ({ strapi }) => ({
330
386
  if (!settings?.targets) return null;
331
387
  const targetIndex = settings.targets.findIndex((t) => t.id === targetId);
332
388
  if (targetIndex === -1) return null;
333
- settings.targets[targetIndex] = {
334
- ...settings.targets[targetIndex],
335
- ...updates,
336
- id: targetId
337
- // Preserve ID
389
+ const existingTarget = settings.targets[targetIndex];
390
+ const targetType = updates.type || existingTarget.type || "github";
391
+ const updatedTarget = {
392
+ id: targetId,
393
+ type: targetType,
394
+ name: updates.name !== void 0 ? updates.name : existingTarget.name
338
395
  };
396
+ if (targetType === "github") {
397
+ updatedTarget.workflow = updates.workflow !== void 0 ? updates.workflow : existingTarget.workflow;
398
+ updatedTarget.branch = updates.branch !== void 0 ? updates.branch : existingTarget.branch;
399
+ } else if (targetType === "vercel") {
400
+ updatedTarget.webhookUrl = updates.webhookUrl !== void 0 ? updates.webhookUrl : existingTarget.webhookUrl;
401
+ }
402
+ settings.targets[targetIndex] = updatedTarget;
339
403
  await store.set({ key: STORE_KEY, value: settings });
340
404
  return settings.targets[targetIndex];
341
405
  },