@liiift-studio/deploy-vercel-from-sanity 0.1.3 → 0.1.6
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 +92 -70
- package/dist/index.js +303 -111
- package/dist/index.mjs +312 -115
- package/package.json +1 -1
- package/src/components/DeployItem.tsx +334 -155
- package/src/components/DeployTool.tsx +34 -27
- package/src/components/TokenSetup.tsx +1 -1
- package/src/lib/api.ts +33 -2
- package/src/lib/helpers.ts +25 -8
- package/src/types.ts +11 -3
package/README.md
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
# deploy-vercel-from-sanity
|
|
2
2
|
|
|
3
|
-
Sanity Studio
|
|
3
|
+
A [Sanity Studio](https://www.sanity.io) plugin to trigger, monitor, and manage Vercel deployments — without leaving your studio.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- Build timer while the deployment is running
|
|
7
|
-
- Branch, commit message, and creator shown inline
|
|
8
|
-
- Cancel an in-progress build
|
|
9
|
-
- Deployment history (last 10) with preview URLs and direct build log links
|
|
10
|
-
- Vercel API token stored securely in your Sanity dataset
|
|
5
|
+

|
|
11
6
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
## Requirements
|
|
7
|
+
## Features
|
|
15
8
|
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
9
|
+
- **Trigger deployments** via Vercel deploy hooks
|
|
10
|
+
- **Live status** with automatic polling — Queued → Building → Ready / Error
|
|
11
|
+
- **Build timer** showing elapsed time while a deploy is running
|
|
12
|
+
- **Cancel** in-progress deployments
|
|
13
|
+
- **Copy deployment URL** with one click
|
|
14
|
+
- **Inline error log viewer** — see build errors directly in the card without going to Vercel
|
|
15
|
+
- **Deployment history** per target
|
|
16
|
+
- **"Open in Vercel"** link to the project dashboard
|
|
17
|
+
- **Responsive grid layout** — 2 columns on desktop, 1 on mobile
|
|
18
|
+
- **Shared API token** — set it once, works for all studio users with editor access or above
|
|
19
19
|
|
|
20
20
|
---
|
|
21
21
|
|
|
@@ -29,7 +29,7 @@ npm install @liiift-studio/deploy-vercel-from-sanity
|
|
|
29
29
|
|
|
30
30
|
## Setup
|
|
31
31
|
|
|
32
|
-
### 1. Add the plugin
|
|
32
|
+
### 1. Add the plugin to your Sanity config
|
|
33
33
|
|
|
34
34
|
```ts
|
|
35
35
|
// sanity.config.ts
|
|
@@ -40,97 +40,119 @@ export default defineConfig({
|
|
|
40
40
|
// ...
|
|
41
41
|
plugins: [
|
|
42
42
|
vercelDeploy(),
|
|
43
|
-
// or with custom label/
|
|
43
|
+
// or with a custom label / name:
|
|
44
44
|
vercelDeploy({ title: 'Deploy', name: 'vercel-deploy' }),
|
|
45
45
|
],
|
|
46
46
|
})
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
### 2.
|
|
49
|
+
### 2. (Optional) Restrict the tool to editors and above
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
**Vercel → Project Settings → Git → Deploy Hooks**:
|
|
51
|
+
By default the tool is visible to all authenticated users. To hide it from viewers:
|
|
53
52
|
|
|
54
53
|
```ts
|
|
55
|
-
//
|
|
56
|
-
|
|
54
|
+
// sanity.config.ts
|
|
55
|
+
tools: (prev, { currentUser }) => {
|
|
56
|
+
const canDeploy = currentUser?.roles?.some(r =>
|
|
57
|
+
['administrator', 'editor'].includes(r.name)
|
|
58
|
+
)
|
|
59
|
+
return canDeploy ? prev : prev.filter(t => t.name !== 'vercel-deploy')
|
|
60
|
+
},
|
|
61
|
+
```
|
|
57
62
|
|
|
58
|
-
|
|
59
|
-
const client = getCliClient({ apiVersion: '2025-01-01' })
|
|
63
|
+
### 3. Connect your Vercel API token
|
|
60
64
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
Open the **Deploy** tool in Sanity Studio. Enter a Vercel API token when prompted.
|
|
66
|
+
|
|
67
|
+
To create a token: **vercel.com → Settings → Tokens → Create → Full Account scope**.
|
|
68
|
+
|
|
69
|
+
The token is stored in a `config.vercelDeploy` document in your dataset and is shared across all authenticated studio users (see [Security](#security)).
|
|
70
|
+
|
|
71
|
+
### 4. Create deploy targets
|
|
72
|
+
|
|
73
|
+
Create one or more `vercel_deploy` documents in your dataset. Each represents a deployment environment (e.g. Production, Staging).
|
|
74
|
+
|
|
75
|
+
**Via Sanity CLI:**
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
sanity documents create << 'EOF'
|
|
79
|
+
{
|
|
80
|
+
"_type": "vercel_deploy",
|
|
81
|
+
"_id": "vercel-deploy-production",
|
|
82
|
+
"name": "Production",
|
|
83
|
+
"url": "https://api.vercel.com/v1/integrations/deploy/YOUR_PROJECT_ID/YOUR_HOOK_ID"
|
|
84
|
+
}
|
|
85
|
+
EOF
|
|
67
86
|
```
|
|
68
87
|
|
|
69
|
-
|
|
88
|
+
**To get your deploy hook URL:** Vercel Dashboard → Project → Settings → Git → Deploy Hooks → Create Hook.
|
|
70
89
|
|
|
71
|
-
|
|
90
|
+
**Fields on each `vercel_deploy` document:**
|
|
72
91
|
|
|
73
|
-
|
|
74
|
-
|
|
92
|
+
| Field | Type | Required | Description |
|
|
93
|
+
|---|---|---|---|
|
|
94
|
+
| `name` | `string` | ✓ | Display label shown in the studio |
|
|
95
|
+
| `url` | `url` | ✓ | Vercel deploy hook URL |
|
|
96
|
+
| `teamId` | `string` | | Vercel team ID — required for team-owned projects |
|
|
97
|
+
| `disableDeleteAction` | `boolean` | | Hides the delete button for this target in the studio UI |
|
|
98
|
+
|
|
99
|
+
---
|
|
75
100
|
|
|
76
|
-
|
|
101
|
+
## Plugin options
|
|
102
|
+
|
|
103
|
+
| Option | Type | Default | Description |
|
|
104
|
+
|---|---|---|---|
|
|
105
|
+
| `name` | `string` | `'vercel-deploy'` | Tool slug in the Studio sidebar |
|
|
106
|
+
| `title` | `string` | `'Deploy'` | Tool label in the Studio sidebar |
|
|
107
|
+
| `icon` | `ComponentType` | `RocketIcon` | Custom sidebar icon |
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## How it works
|
|
112
|
+
|
|
113
|
+
1. Deploy targets are stored as `vercel_deploy` documents in your Sanity dataset.
|
|
114
|
+
2. The plugin fetches the last 10 deployments for each target from the Vercel API, filtered to those triggered by that hook.
|
|
115
|
+
3. While a deployment is active (Queued / Initializing / Building), it polls every 5 seconds.
|
|
116
|
+
4. Clicking **Deploy** POSTs to the hook URL — Vercel queues a new build.
|
|
117
|
+
5. If a deploy fails, clicking **Show error details** fetches the last 30 build log lines from the Vercel API inline.
|
|
77
118
|
|
|
78
119
|
---
|
|
79
120
|
|
|
80
121
|
## Security
|
|
81
122
|
|
|
82
|
-
###
|
|
123
|
+
### API token storage
|
|
83
124
|
|
|
84
|
-
The token is stored in a Sanity document with
|
|
85
|
-
platform excludes documents in the `secrets.*` namespace from public/unauthenticated
|
|
86
|
-
API access — they are only readable by authenticated Studio sessions.
|
|
125
|
+
The Vercel API token is stored in a `config.vercelDeploy` Sanity document, which is readable by **all authenticated studio users**. Anyone with a login to your Sanity project can read the token value via the Sanity API.
|
|
87
126
|
|
|
88
|
-
**
|
|
89
|
-
|
|
90
|
-
|
|
127
|
+
**Recommendations:**
|
|
128
|
+
- Audit who has access to your Sanity project at sanity.io → Project → Members.
|
|
129
|
+
- If your studio includes untrusted editors, consider a server-side proxy that holds the token outside Sanity and exposes only a scoped deploy endpoint.
|
|
91
130
|
|
|
92
|
-
|
|
93
|
-
curl "https://{projectId}.api.sanity.io/v2021-06-07/data/query/{dataset}?query=*[_id==\"secrets.vercelDeploy\"]"
|
|
94
|
-
# Should return empty results
|
|
95
|
-
```
|
|
131
|
+
### Deploy hook URL validation
|
|
96
132
|
|
|
97
|
-
|
|
133
|
+
`triggerDeploy` validates that the hook URL matches `api.vercel.com/v1/integrations/deploy/` before making the request. This prevents SSRF if a `vercel_deploy` document is created or modified outside the Studio's schema validation.
|
|
98
134
|
|
|
99
|
-
|
|
100
|
-
to allow only `http:` and `https:` protocols before being used as `href` values.
|
|
101
|
-
This prevents `javascript:` injection from a malformed API response.
|
|
135
|
+
### External links
|
|
102
136
|
|
|
103
|
-
|
|
137
|
+
All external links use `target="_blank" rel="noreferrer"` and are validated through `safeHref()` before rendering, blocking `javascript:` injection from a compromised API response.
|
|
104
138
|
|
|
105
|
-
|
|
106
|
-
Do not log them, commit them to public repos, or expose them client-side outside
|
|
107
|
-
the Studio. The plugin only sends a POST to the hook URL; the URL itself is never
|
|
108
|
-
displayed in full.
|
|
139
|
+
### GROQ queries
|
|
109
140
|
|
|
110
|
-
|
|
141
|
+
All GROQ queries in this plugin are static strings — no user input is interpolated, so there is no GROQ injection risk.
|
|
111
142
|
|
|
112
|
-
|
|
143
|
+
---
|
|
113
144
|
|
|
114
|
-
|
|
115
|
-
|---|---|---|---|
|
|
116
|
-
| `name` | string | ✓ | Display label (e.g. "Production") |
|
|
117
|
-
| `url` | url | ✓ | Vercel deploy hook URL |
|
|
118
|
-
| `teamId` | string | | Vercel team ID — required for team-owned projects |
|
|
119
|
-
| `disableDeleteAction` | boolean | | Prevent deletion from the Studio |
|
|
145
|
+
## Requirements
|
|
120
146
|
|
|
121
|
-
|
|
147
|
+
- Sanity Studio v3, v4, or v5
|
|
148
|
+
- React 18 or 19
|
|
149
|
+
- A Vercel account with at least one project configured with a deploy hook
|
|
122
150
|
|
|
123
151
|
---
|
|
124
152
|
|
|
125
|
-
##
|
|
153
|
+
## Contributing
|
|
126
154
|
|
|
127
|
-
|
|
128
|
-
vercelDeploy({
|
|
129
|
-
name?: string // Tool slug in the Studio sidebar (default: 'vercel-deploy')
|
|
130
|
-
title?: string // Tool label (default: 'Deploy')
|
|
131
|
-
icon?: React.ComponentType // Custom icon
|
|
132
|
-
})
|
|
133
|
-
```
|
|
155
|
+
Issues and pull requests are welcome at [github.com/Liiift-Studio/Deploy-Vercel-from-Sanity](https://github.com/Liiift-Studio/Deploy-Vercel-from-Sanity).
|
|
134
156
|
|
|
135
157
|
---
|
|
136
158
|
|