@transloadit/convex 0.0.2 → 0.0.4
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 +184 -121
- package/dist/client/index.d.ts +100 -60
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +69 -31
- package/dist/client/index.js.map +1 -1
- package/dist/component/_generated/api.d.ts +2 -2
- package/dist/component/_generated/component.d.ts +35 -15
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/_generated/dataModel.d.ts +1 -1
- package/dist/component/_generated/server.d.ts +1 -1
- package/dist/component/apiUtils.d.ts +36 -7
- package/dist/component/apiUtils.d.ts.map +1 -1
- package/dist/component/apiUtils.js +60 -40
- package/dist/component/apiUtils.js.map +1 -1
- package/dist/component/lib.d.ts +71 -49
- package/dist/component/lib.d.ts.map +1 -1
- package/dist/component/lib.js +206 -73
- package/dist/component/lib.js.map +1 -1
- package/dist/component/schema.d.ts +11 -13
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +3 -10
- package/dist/component/schema.js.map +1 -1
- package/dist/debug/index.d.ts +19 -0
- package/dist/debug/index.d.ts.map +1 -0
- package/dist/debug/index.js +49 -0
- package/dist/debug/index.js.map +1 -0
- package/dist/react/index.d.ts +213 -17
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +726 -105
- package/dist/react/index.js.map +1 -1
- package/dist/shared/assemblyUrls.d.ts +10 -0
- package/dist/shared/assemblyUrls.d.ts.map +1 -0
- package/dist/shared/assemblyUrls.js +26 -0
- package/dist/shared/assemblyUrls.js.map +1 -0
- package/dist/shared/errors.d.ts +7 -0
- package/dist/shared/errors.d.ts.map +1 -0
- package/dist/shared/errors.js +10 -0
- package/dist/shared/errors.js.map +1 -0
- package/dist/shared/pollAssembly.d.ts +12 -0
- package/dist/shared/pollAssembly.d.ts.map +1 -0
- package/dist/shared/pollAssembly.js +50 -0
- package/dist/shared/pollAssembly.js.map +1 -0
- package/dist/shared/resultTypes.d.ts +37 -0
- package/dist/shared/resultTypes.d.ts.map +1 -0
- package/dist/shared/resultTypes.js +2 -0
- package/dist/shared/resultTypes.js.map +1 -0
- package/dist/shared/resultUtils.d.ts +4 -0
- package/dist/shared/resultUtils.d.ts.map +1 -0
- package/dist/shared/resultUtils.js +69 -0
- package/dist/shared/resultUtils.js.map +1 -0
- package/dist/shared/tusUpload.d.ts +13 -0
- package/dist/shared/tusUpload.d.ts.map +1 -0
- package/dist/shared/tusUpload.js +32 -0
- package/dist/shared/tusUpload.js.map +1 -0
- package/dist/test/index.d.ts +65 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/index.js +8 -0
- package/dist/test/index.js.map +1 -0
- package/dist/test/nodeModules.d.ts +2 -0
- package/dist/test/nodeModules.d.ts.map +1 -0
- package/dist/test/nodeModules.js +19 -0
- package/dist/test/nodeModules.js.map +1 -0
- package/package.json +53 -15
- package/src/client/index.ts +141 -38
- package/src/component/_generated/api.ts +2 -2
- package/src/component/_generated/component.ts +44 -13
- package/src/component/_generated/dataModel.ts +1 -1
- package/src/component/_generated/server.ts +1 -1
- package/src/component/apiUtils.test.ts +195 -2
- package/src/component/apiUtils.ts +124 -66
- package/src/component/lib.test.ts +243 -7
- package/src/component/lib.ts +302 -90
- package/src/component/schema.ts +3 -13
- package/src/debug/index.ts +84 -0
- package/src/react/index.test.tsx +340 -0
- package/src/react/index.tsx +1105 -152
- package/src/react/uploadWithTus.test.tsx +192 -0
- package/src/shared/assemblyUrls.test.ts +71 -0
- package/src/shared/assemblyUrls.ts +59 -0
- package/src/shared/errors.ts +23 -0
- package/src/shared/pollAssembly.ts +65 -0
- package/src/shared/resultTypes.ts +44 -0
- package/src/shared/resultUtils.test.ts +29 -0
- package/src/shared/resultUtils.ts +71 -0
- package/src/shared/tusUpload.ts +59 -0
- package/src/test/index.ts +10 -0
- package/src/test/nodeModules.ts +19 -0
package/README.md
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
# Transloadit Convex Component
|
|
2
2
|
|
|
3
|
-
A Convex component for creating Transloadit Assemblies,
|
|
3
|
+
A Convex component for creating Transloadit Assemblies, handling resumable uploads with tus, and persisting status/results in Convex.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- Create Assemblies with
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
- Persist Assembly status + results in Convex.
|
|
7
|
+
- Create Assemblies with Templates or inline Steps.
|
|
8
|
+
- Resumable uploads via tus (client-side hook; form/XHR uploads are intentionally not supported).
|
|
9
|
+
- Webhook ingestion with signature verification (direct or queued).
|
|
10
|
+
- Persist Assembly status + results in Convex tables.
|
|
12
11
|
- Typed API wrappers and React hooks.
|
|
13
12
|
|
|
13
|
+
## Requirements
|
|
14
|
+
|
|
15
|
+
- Node.js 24+
|
|
16
|
+
- Yarn 4 (Corepack)
|
|
17
|
+
|
|
14
18
|
## Install
|
|
15
19
|
|
|
16
20
|
```bash
|
|
@@ -34,31 +38,17 @@ export default app;
|
|
|
34
38
|
|
|
35
39
|
### 2) Set environment variables
|
|
36
40
|
|
|
37
|
-
Preferred names:
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
npx convex env set TRANSLOADIT_AUTH_KEY <your_auth_key>
|
|
41
|
-
npx convex env set TRANSLOADIT_AUTH_SECRET <your_auth_secret>
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
Aliases also supported:
|
|
45
|
-
|
|
46
41
|
```bash
|
|
47
42
|
npx convex env set TRANSLOADIT_KEY <your_auth_key>
|
|
48
43
|
npx convex env set TRANSLOADIT_SECRET <your_auth_secret>
|
|
49
44
|
```
|
|
50
45
|
|
|
51
|
-
|
|
46
|
+
## Golden path (secure by default)
|
|
52
47
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
The script reads `TRANSLOADIT_KEY/TRANSLOADIT_SECRET` (or `TRANSLOADIT_AUTH_KEY/TRANSLOADIT_AUTH_SECRET`) from `.env`,
|
|
60
|
-
creates or updates the template `convex-demo`, and prints the template id.
|
|
61
|
-
Use that id as `VITE_TRANSLOADIT_TEMPLATE_ID` in `example/.env` when running the demo app.
|
|
48
|
+
1. **Server-only create**: a Convex action creates the Assembly (auth secret stays server-side).
|
|
49
|
+
2. **Client upload**: use `useTransloaditUppy` for resumable uploads.
|
|
50
|
+
3. **Webhook ingestion**: verify the signature and `queueWebhook` for durable processing.
|
|
51
|
+
4. **Realtime UI**: query status/results and render the gallery.
|
|
62
52
|
|
|
63
53
|
## Backend API
|
|
64
54
|
|
|
@@ -69,8 +59,9 @@ import { components } from "./_generated/api";
|
|
|
69
59
|
|
|
70
60
|
export const {
|
|
71
61
|
createAssembly,
|
|
72
|
-
generateUploadParams,
|
|
73
62
|
handleWebhook,
|
|
63
|
+
queueWebhook,
|
|
64
|
+
refreshAssembly,
|
|
74
65
|
getAssemblyStatus,
|
|
75
66
|
listAssemblies,
|
|
76
67
|
listResults,
|
|
@@ -78,7 +69,23 @@ export const {
|
|
|
78
69
|
} = makeTransloaditAPI(components.transloadit);
|
|
79
70
|
```
|
|
80
71
|
|
|
81
|
-
Note:
|
|
72
|
+
Note: pass `expires` in `createAssembly` when you need a custom expiry; otherwise the component defaults to 1 hour from now.
|
|
73
|
+
|
|
74
|
+
## Data model
|
|
75
|
+
|
|
76
|
+
The component stores Transloadit metadata in two tables:
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
assemblies 1 ──── * results
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
- `assemblies`: one row per Transloadit Assembly (status/ok, notify URL, uploads, raw payload, etc).
|
|
83
|
+
- `results`: one row per output file, keyed by `assemblyId` + `stepName`, plus normalized fields (name/size/mime/url) and the raw Transloadit output object.
|
|
84
|
+
|
|
85
|
+
Lifecycle:
|
|
86
|
+
1. `createAssembly` inserts the initial `assemblies` row.
|
|
87
|
+
2. `handleWebhook`, `queueWebhook`, or `refreshAssembly` upserts the assembly + replaces results.
|
|
88
|
+
3. `listResults` returns flattened step outputs for use in UIs.
|
|
82
89
|
|
|
83
90
|
## Webhook route
|
|
84
91
|
|
|
@@ -86,150 +93,206 @@ Transloadit sends webhooks as `multipart/form-data` with `transloadit` (JSON) an
|
|
|
86
93
|
|
|
87
94
|
```ts
|
|
88
95
|
// convex/http.ts
|
|
89
|
-
import {
|
|
96
|
+
import { httpRouter } from "convex/server";
|
|
97
|
+
import { handleWebhookRequest } from "@transloadit/convex";
|
|
90
98
|
import { api } from "./_generated/api";
|
|
99
|
+
import { httpAction } from "./_generated/server";
|
|
91
100
|
|
|
92
101
|
const http = httpRouter();
|
|
93
102
|
|
|
94
103
|
http.route({
|
|
95
104
|
path: "/transloadit/webhook",
|
|
96
105
|
method: "POST",
|
|
97
|
-
handler: httpAction(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
106
|
+
handler: httpAction((ctx, request) =>
|
|
107
|
+
handleWebhookRequest(request, {
|
|
108
|
+
mode: "queue",
|
|
109
|
+
runAction: (args) => ctx.runAction(api.transloadit.queueWebhook, args),
|
|
110
|
+
}),
|
|
111
|
+
),
|
|
112
|
+
});
|
|
101
113
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
114
|
+
export default http;
|
|
115
|
+
```
|
|
105
116
|
|
|
106
|
-
|
|
117
|
+
## Client wrapper (optional)
|
|
107
118
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
rawBody: rawPayload,
|
|
111
|
-
signature: typeof signature === "string" ? signature : undefined,
|
|
112
|
-
});
|
|
119
|
+
Most integrations should use `makeTransloaditAPI` (above). If you prefer a class-based API
|
|
120
|
+
(similar to other Convex components), use `Transloadit`:
|
|
113
121
|
|
|
114
|
-
|
|
115
|
-
|
|
122
|
+
```ts
|
|
123
|
+
import { Transloadit } from "@transloadit/convex";
|
|
124
|
+
import { components } from "./_generated/api";
|
|
125
|
+
|
|
126
|
+
const transloadit = new Transloadit(components.transloadit, {
|
|
127
|
+
authKey: process.env.TRANSLOADIT_KEY!,
|
|
128
|
+
authSecret: process.env.TRANSLOADIT_SECRET!,
|
|
116
129
|
});
|
|
130
|
+
```
|
|
117
131
|
|
|
118
|
-
|
|
132
|
+
## React usage (Uppy)
|
|
133
|
+
|
|
134
|
+
```tsx
|
|
135
|
+
import { useTransloaditUppy } from "@transloadit/convex/react";
|
|
136
|
+
import { api } from "../convex/_generated/api";
|
|
137
|
+
|
|
138
|
+
const { startUpload, status, results, stage } = useTransloaditUppy({
|
|
139
|
+
uppy,
|
|
140
|
+
createAssembly: api.wedding.createWeddingAssembly,
|
|
141
|
+
getStatus: api.transloadit.getAssemblyStatus,
|
|
142
|
+
listResults: api.transloadit.listResults,
|
|
143
|
+
refreshAssembly: api.transloadit.refreshAssembly,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
await startUpload({
|
|
147
|
+
createAssemblyArgs: { guestName, uploadCode },
|
|
148
|
+
});
|
|
119
149
|
```
|
|
150
|
+
For advanced/legacy helpers (raw parsing, low-level tus uploads, polling utilities), see `docs/advanced.md`.
|
|
151
|
+
|
|
152
|
+
## Example app (Next.js + Uppy wedding gallery)
|
|
120
153
|
|
|
121
|
-
|
|
154
|
+
The `example/` app is a wedding gallery where guests upload photos + short videos. It uses Uppy on the client and Convex Auth (anonymous sign-in) to create assemblies securely. If you do not set `NEXT_PUBLIC_CONVEX_URL`, the example falls back to the in-process Convex test harness.
|
|
155
|
+
Uploads are stored via Transloadit directly into Cloudflare R2.
|
|
156
|
+
The client wiring uses the `useTransloaditUppy` hook from `@transloadit/convex/react` to keep Uppy + polling in sync.
|
|
122
157
|
|
|
123
|
-
|
|
158
|
+
Quick start (local):
|
|
124
159
|
|
|
125
160
|
```bash
|
|
126
|
-
|
|
161
|
+
# In repo root
|
|
162
|
+
export TRANSLOADIT_KEY=...
|
|
163
|
+
export TRANSLOADIT_SECRET=...
|
|
164
|
+
export TRANSLOADIT_R2_CREDENTIALS=...
|
|
165
|
+
|
|
166
|
+
# Get a public webhook URL (cloudflared is auto-downloaded if needed)
|
|
167
|
+
yarn tunnel --once
|
|
168
|
+
# Set TRANSLOADIT_NOTIFY_URL to the printed notifyUrl
|
|
169
|
+
export TRANSLOADIT_NOTIFY_URL=...
|
|
170
|
+
|
|
171
|
+
yarn example:dev
|
|
127
172
|
```
|
|
128
173
|
|
|
129
|
-
|
|
130
|
-
`VITE_TRANSLOADIT_NOTIFY_URL` for the example app.
|
|
174
|
+
If you want the API routes to talk to an existing Convex deployment (bypassing Convex Auth), set:
|
|
131
175
|
|
|
132
|
-
|
|
176
|
+
```bash
|
|
177
|
+
export CONVEX_URL=...
|
|
178
|
+
export CONVEX_ADMIN_KEY=...
|
|
179
|
+
```
|
|
133
180
|
|
|
134
|
-
|
|
181
|
+
The example exposes `POST /transloadit/webhook` and forwards webhooks into Convex via `queueWebhook`.
|
|
182
|
+
Realtime “new upload” toasts use a Convex subscription on recent assemblies.
|
|
183
|
+
The demo also applies a simple per-user upload limit in the Convex backend (see `example/convex/wedding.ts`).
|
|
135
184
|
|
|
136
|
-
|
|
137
|
-
|
|
185
|
+
### Storage (required R2 persistence)
|
|
186
|
+
|
|
187
|
+
The example uses the `/cloudflare/store` robot to write processed files into Cloudflare R2. Configure one of these:
|
|
138
188
|
|
|
139
189
|
```bash
|
|
140
|
-
|
|
190
|
+
# Option A: Transloadit template credentials (recommended)
|
|
191
|
+
export TRANSLOADIT_R2_CREDENTIALS=...
|
|
192
|
+
|
|
193
|
+
# Option B: supply R2 details directly
|
|
194
|
+
export R2_BUCKET=...
|
|
195
|
+
export R2_ACCESS_KEY_ID=...
|
|
196
|
+
export R2_SECRET_ACCESS_KEY=...
|
|
197
|
+
export R2_ACCOUNT_ID=... # or R2_HOST
|
|
198
|
+
export R2_PUBLIC_URL=... # optional public URL prefix
|
|
141
199
|
```
|
|
142
200
|
|
|
143
|
-
|
|
201
|
+
The UI hides older items based on `NEXT_PUBLIC_GALLERY_RETENTION_HOURS` (default: 24) to discourage spam/abuse.
|
|
202
|
+
If you set `WEDDING_UPLOAD_CODE` on the Convex deployment, guests must enter the passcode before uploads can start.
|
|
144
203
|
|
|
145
|
-
|
|
204
|
+
### Deploy the example (Vercel + stable Convex)
|
|
146
205
|
|
|
147
|
-
|
|
206
|
+
For a public demo, deploy the `example/` app and point it at a stable Convex deployment.
|
|
148
207
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
208
|
+
1. Deploy a Convex app that includes this component (stable/prod deployment).
|
|
209
|
+
2. Set Vercel environment variables for the project:
|
|
210
|
+
- `NEXT_PUBLIC_CONVEX_URL` (point to the stable Convex deployment)
|
|
211
|
+
- `NEXT_PUBLIC_GALLERY_RETENTION_HOURS` (optional)
|
|
212
|
+
3. Set Convex environment variables on the deployment:
|
|
213
|
+
- `TRANSLOADIT_KEY` and `TRANSLOADIT_SECRET`
|
|
214
|
+
- `TRANSLOADIT_NOTIFY_URL` (set to `https://<deployment>.convex.site/transloadit/webhook`)
|
|
215
|
+
- R2 credentials (see above)
|
|
216
|
+
- `WEDDING_UPLOAD_CODE` (optional passcode for uploads)
|
|
217
|
+
4. Trigger the Vercel deploy hook (or deploy manually).
|
|
152
218
|
|
|
153
|
-
|
|
154
|
-
const { upload, isUploading, progress, error } = useTransloaditUpload(
|
|
155
|
-
api.transloadit.generateUploadParams,
|
|
156
|
-
);
|
|
219
|
+
To deploy a stable Convex backend for the demo (once per environment), run:
|
|
157
220
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
});
|
|
163
|
-
};
|
|
221
|
+
```bash
|
|
222
|
+
export CONVEX_DEPLOY_KEY=...
|
|
223
|
+
export TRANSLOADIT_KEY=...
|
|
224
|
+
export TRANSLOADIT_SECRET=...
|
|
164
225
|
|
|
165
|
-
|
|
166
|
-
<div>
|
|
167
|
-
<input type="file" onChange={(e) => handleUpload(e.target.files![0])} />
|
|
168
|
-
{isUploading && <p>Uploading: {progress}%</p>}
|
|
169
|
-
{error && <p>{error.message}</p>}
|
|
170
|
-
</div>
|
|
171
|
-
);
|
|
172
|
-
}
|
|
226
|
+
yarn deploy:cloud
|
|
173
227
|
```
|
|
174
228
|
|
|
175
|
-
|
|
229
|
+
Once deployed, use the Vercel URL as `E2E_REMOTE_APP_URL` for `yarn verify:cloud`.
|
|
230
|
+
CI expects a stable Vercel production URL in the `E2E_REMOTE_APP_URL` secret on `main`.
|
|
176
231
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
232
|
+
## Verification and QA
|
|
233
|
+
|
|
234
|
+
Fast checks:
|
|
180
235
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
);
|
|
236
|
+
```bash
|
|
237
|
+
yarn check
|
|
238
|
+
```
|
|
185
239
|
|
|
186
|
-
|
|
187
|
-
await upload(file, {
|
|
188
|
-
templateId: "template_id_here",
|
|
189
|
-
});
|
|
190
|
-
};
|
|
240
|
+
This runs format, lint, typecheck, and unit tests. For a full verification run:
|
|
191
241
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
<input type="file" onChange={(e) => handleUpload(e.target.files![0])} />
|
|
195
|
-
{isUploading && <p>Uploading: {progress}%</p>}
|
|
196
|
-
</div>
|
|
197
|
-
);
|
|
198
|
-
}
|
|
242
|
+
```bash
|
|
243
|
+
yarn verify
|
|
199
244
|
```
|
|
200
245
|
|
|
201
|
-
|
|
246
|
+
Additional commands:
|
|
202
247
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
248
|
+
- `yarn lint` (Biome)
|
|
249
|
+
- `yarn format` (Biome write)
|
|
250
|
+
- `yarn typecheck` (tsc)
|
|
251
|
+
- `yarn test` (Vitest unit tests)
|
|
252
|
+
- `yarn verify:local` (runs the Next.js wedding example + uploads an image + video)
|
|
253
|
+
- `yarn verify:cloud` (runs the browser flow against a deployed Next.js app)
|
|
254
|
+
- `yarn deploy:cloud` (deploys a stable Convex backend for the demo app)
|
|
255
|
+
- `yarn build` (tsc build + emit package json)
|
|
256
|
+
|
|
257
|
+
Notes:
|
|
258
|
+
- `yarn tunnel` is a support tool, not verification.
|
|
259
|
+
- CI should run non-mutating checks; local `yarn check` may format/fix.
|
|
260
|
+
- `yarn verify:local` needs `TRANSLOADIT_KEY`, `TRANSLOADIT_SECRET`, `TRANSLOADIT_NOTIFY_URL`, and R2 credentials.
|
|
261
|
+
- `yarn verify:cloud` needs `E2E_REMOTE_APP_URL`.
|
|
262
|
+
- Set `TRANSLOADIT_DEBUG=1` to enable verbose verify logs.
|
|
206
263
|
|
|
207
|
-
|
|
208
|
-
const status = useAssemblyStatus(api.transloadit.getAssemblyStatus, assemblyId);
|
|
209
|
-
const results = useTransloaditFiles(api.transloadit.listResults, {
|
|
210
|
-
assemblyId,
|
|
211
|
-
});
|
|
264
|
+
## Component test helpers
|
|
212
265
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
);
|
|
220
|
-
}
|
|
266
|
+
For `convex-test`, you can use the built-in helper:
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
import { createTransloaditTest } from "@transloadit/convex/test";
|
|
270
|
+
|
|
271
|
+
const t = createTransloaditTest();
|
|
221
272
|
```
|
|
222
273
|
|
|
223
|
-
##
|
|
274
|
+
## Generated files
|
|
275
|
+
|
|
276
|
+
`src/component/_generated` is Convex codegen output. It is checked in so tests and component consumers have stable API references. If you change component functions or schemas, regenerate with Convex codegen (for example via `npx convex dev` or `npx convex codegen`) and commit the updated files.
|
|
277
|
+
|
|
278
|
+
## Release process
|
|
279
|
+
|
|
280
|
+
Releases are automated via Changesets + GitHub Actions and published to npm using OIDC (Trusted Publisher).
|
|
224
281
|
|
|
225
|
-
|
|
282
|
+
1. Ensure CI is green on `main`.
|
|
283
|
+
2. Run local checks:
|
|
226
284
|
|
|
227
285
|
```bash
|
|
228
|
-
yarn
|
|
286
|
+
yarn check
|
|
229
287
|
```
|
|
230
288
|
|
|
231
|
-
|
|
289
|
+
3. Add a changeset describing the release:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
yarn changeset
|
|
293
|
+
```
|
|
232
294
|
|
|
233
|
-
|
|
295
|
+
4. Push the changeset to `main`. The Changesets workflow will open a “Version Packages” PR.
|
|
296
|
+
5. Merge the “Version Packages” PR. This will publish to npm and tag the release.
|
|
234
297
|
|
|
235
|
-
|
|
298
|
+
Note: This package is 0.x, so breaking changes are allowed. Use changesets to document them clearly.
|