@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 CHANGED
@@ -1,21 +1,21 @@
1
1
  # deploy-vercel-from-sanity
2
2
 
3
- Sanity Studio v5 plugin trigger and monitor Vercel deployments directly from the Studio.
3
+ A [Sanity Studio](https://www.sanity.io) plugin to trigger, monitor, and manage Vercel deployments without leaving your studio.
4
4
 
5
- - Deploy button per target with live status polling
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
+ ![Deploy tool screenshot](./docs/screenshot.png)
11
6
 
12
- ---
13
-
14
- ## Requirements
7
+ ## Features
15
8
 
16
- - Sanity Studio v5
17
- - A Vercel project with at least one [Deploy Hook](https://vercel.com/docs/git/deploy-hooks) configured
18
- - A Vercel API token (for reading deployment status, history, and logs)
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/icon:
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. Add a deploy hook document
49
+ ### 2. (Optional) Restrict the tool to editors and above
50
50
 
51
- Create a `vercel_deploy` document in your Sanity dataset with the deploy hook URL from
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
- // Via Sanity CLI (run once):
56
- // npx sanity exec scripts/seed.js --with-user-token
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
- import { getCliClient } from 'sanity/cli'
59
- const client = getCliClient({ apiVersion: '2025-01-01' })
63
+ ### 3. Connect your Vercel API token
60
64
 
61
- await client.createOrReplace({
62
- _id: 'vercel-deploy-production',
63
- _type: 'vercel_deploy',
64
- name: 'Production',
65
- url: 'https://api.vercel.com/v1/integrations/deploy/prj_xxx/yyy',
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
- Or create it from the Studio the plugin registers the `vercel_deploy` schema automatically.
88
+ **To get your deploy hook URL:** Vercel Dashboard Project Settings Git → Deploy Hooks → Create Hook.
70
89
 
71
- ### 3. Add your Vercel API token
90
+ **Fields on each `vercel_deploy` document:**
72
91
 
73
- On first launch, the plugin shows a token setup screen. Create a token at
74
- **vercel.com → Settings → Tokens** with **Full Account** scope, paste it in, and save.
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
- The token is stored in a Sanity document at `_id: "secrets.vercelDeploy"`.
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
- ### Vercel API token storage
123
+ ### API token storage
83
124
 
84
- The token is stored in a Sanity document with `_id: "secrets.vercelDeploy"`. Sanity's
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
- **If your dataset is in public mode**, verify this protection is in place before storing
89
- sensitive credentials. You can confirm by attempting to fetch the document without an
90
- auth token:
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
- ```bash
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
- ### Link safety
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
- All external links (`inspectorUrl`, preview URLs) from the Vercel API are validated
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
- ### Deploy hook URLs
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
- Deploy hook URLs act as secrets — anyone with the URL can trigger a deployment.
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
- ## `vercel_deploy` document schema
143
+ ---
113
144
 
114
- | Field | Type | Required | Description |
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
- The `projectId` and hook ID are parsed automatically from the hook URL.
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
- ## Options
153
+ ## Contributing
126
154
 
127
- ```ts
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