v0-sdk 0.0.4 → 0.0.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,10 +1,21 @@
1
- ### v0 Chats API Client
1
+ # v0 Chat SDK
2
2
 
3
- A lightweight client for interacting with the v0 Chats API to create and manage AI-powered chat conversations.
3
+ A TypeScript SDK for interacting with the v0 API to create and manage AI-powered chat conversations, projects, integrations, and more.
4
+
5
+ ## Features
6
+
7
+ - Full TypeScript support with complete type definitions
8
+ - Chat management - Create, manage, and interact with AI chats
9
+ - Project operations - Create and manage v0 projects
10
+ - Vercel integrations - Seamless Vercel project integration
11
+ - User management - Access user information and billing
12
+ - Deployment logs - Monitor and retrieve deployment information
13
+ - Comprehensive testing - Extensive test coverage for all functions
14
+ - Error handling - Robust error handling with detailed error types
4
15
 
5
16
  ## Installation
6
17
 
7
- ```shellscript
18
+ ```bash
8
19
  npm install v0-sdk
9
20
  # or
10
21
  yarn add v0-sdk
@@ -14,25 +25,23 @@ pnpm add v0-sdk
14
25
 
15
26
  ## Quick Start
16
27
 
17
- Get your API key from [v0.dev/chat/settings/keys](https://v0.dev/chat/settings/keys) and start creating chats.
18
-
19
- ```javascript
20
- import { V0Client } from 'v0-sdk'
28
+ Get your API key from [v0.dev/chat/settings/keys](https://v0.dev/chat/settings/keys).
21
29
 
22
- // Initialize with your API key
23
- const client = new V0Client('your_v0_api_key')
30
+ ```typescript
31
+ import { v0 } from 'v0-sdk'
24
32
 
25
33
  // Create a new chat
26
- const chat = await client.createChat({
34
+ const chat = await v0.chats.create({
27
35
  message: 'Create a responsive navbar with Tailwind CSS',
28
36
  system: 'You are an expert React developer',
29
37
  })
30
38
 
31
39
  console.log(`Chat created: ${chat.url}`)
32
- console.log(`Generated code: ${chat.files.length} files`)
40
+ console.log(`Generated code: ${chat.files?.length} files`)
33
41
 
34
42
  // Add a message to the chat
35
- const response = await client.addMessage(chat.chatId, {
43
+ const response = await v0.chats.createMessage({
44
+ chatId: chat.chatId,
36
45
  message: 'Add a dropdown menu to the navbar',
37
46
  })
38
47
 
@@ -43,22 +52,24 @@ console.log(`AI response: ${response.text}`)
43
52
 
44
53
  The client requires a v0 API key, which you can create at [v0.dev/chat/settings/keys](https://v0.dev/chat/settings/keys).
45
54
 
46
- ```javascript
47
- // Initialize with API key
48
- const client = new V0Client('your_v0_api_key')
55
+ ```typescript
56
+ // Set your API key as an environment variable
57
+ process.env.V0_API_KEY = 'your_v0_api_key'
49
58
 
50
- // Or set it later
51
- client.setApiKey('your_v0_api_key')
59
+ // Or pass custom base URL
60
+ // The SDK will automatically use the V0_API_KEY environment variable
52
61
  ```
53
62
 
54
63
  ## API Reference
55
64
 
56
- ### Create a Chat
65
+ ### Chat Operations
66
+
67
+ #### Create a Chat
57
68
 
58
69
  Create a new chat conversation with the AI.
59
70
 
60
- ```javascript
61
- const result = await client.createChat({
71
+ ```typescript
72
+ const result = await v0.chats.create({
62
73
  message: 'Create a login form with validation',
63
74
  system: 'You are an expert in React and form validation',
64
75
  chatPrivacy: 'private',
@@ -70,95 +81,196 @@ const result = await client.createChat({
70
81
  })
71
82
  ```
72
83
 
73
- **Response:**
84
+ #### Get Chat by ID
74
85
 
75
- ```javascript
76
- {
77
- chatId: 'abc123',
78
- url: 'https://v0.dev/chat/abc123',
79
- text: 'I'll create a login form with validation...',
80
- files: [
81
- {
82
- name: 'login-form.tsx',
83
- content: '...',
84
- type: 'component'
85
- }
86
- ],
87
- demo: 'https://v0.dev/demo/abc123'
88
- }
86
+ ```typescript
87
+ const chat = await v0.chats.getById({ chatId: 'chat_id' })
88
+ console.log(chat.messages) // Fully typed message array
89
89
  ```
90
90
 
91
- ### Add a Message
91
+ #### Manage Chat Favorites
92
+
93
+ ```typescript
94
+ // Favorite a chat
95
+ await v0.chats.favorite({ chatId: 'chat_id' })
96
+
97
+ // Unfavorite a chat
98
+ await v0.chats.unfavorite({ chatId: 'chat_id' })
99
+
100
+ // Get favorite chats
101
+ const favorites = await v0.chats.find()
102
+ ```
103
+
104
+ #### Chat History and Management
105
+
106
+ ```typescript
107
+ // Get chat history
108
+ const chats = await v0.chats.find()
92
109
 
93
- Add a message to an existing chat.
110
+ // Delete a chat
111
+ await v0.chats.delete({ chatId: 'chat_id' })
94
112
 
95
- ```javascript
96
- const response = await client.addMessage('abc123', {
113
+ // Get chat's associated project
114
+ const project = await v0.chats.getProject({ chatId: 'chat_id' })
115
+ ```
116
+
117
+ #### Add Messages to Chat
118
+
119
+ ```typescript
120
+ const response = await v0.chats.createMessage({
121
+ chatId: 'chat_id',
97
122
  message: 'Add password strength indicator',
98
123
  attachments: [{ url: 'https://example.com/mockup.jpg' }],
99
- modelConfiguration: {},
124
+ modelConfiguration: {
125
+ imageGenerations: true
126
+ },
100
127
  })
101
128
  ```
102
129
 
103
- ### Get Chat History
130
+ #### Get Version Frame Token
104
131
 
105
- Coming soon
132
+ ```typescript
133
+ const token = await v0.chats.getVersionFrameToken({
134
+ chatId: 'chat_id',
135
+ versionId: 'version_id'
136
+ })
137
+ ```
106
138
 
107
- ## Working with Attachments
139
+ ### Project Operations
108
140
 
109
- The client supports both URL and base64-encoded attachments:
141
+ #### Create a Project
110
142
 
111
- ```javascript
112
- // URL attachment
113
- const response = await client.createChat({
114
- message: 'Create a component based on this design',
115
- attachments: [{ url: 'https://example.com/design.png' }],
143
+ ```typescript
144
+ const project = await v0.projects.create({
145
+ name: 'My New Project',
146
+ description: 'A sample project',
147
+ environmentVariables: [
148
+ { key: 'API_KEY', value: 'secret_value' }
149
+ ],
150
+ icon: 'https://example.com/icon.png'
116
151
  })
152
+ ```
117
153
 
118
- // Base64 attachment (from file input)
119
- document
120
- .querySelector('input[type="file"]')
121
- .addEventListener('change', async e => {
122
- const file = e.target.files[0]
123
- const reader = new FileReader()
154
+ #### Find Projects
124
155
 
125
- reader.onload = async () => {
126
- const response = await client.createChat({
127
- message: 'Create a component based on this image',
128
- attachments: [{ url: reader.result }],
129
- })
156
+ ```typescript
157
+ const projects = await v0.projects.find()
158
+ ```
130
159
 
131
- console.log(response)
132
- }
160
+ ### Vercel Integration
133
161
 
134
- reader.readAsDataURL(file)
135
- })
162
+ #### Create Vercel Integration Project
163
+
164
+ ```typescript
165
+ const integration = await v0.integrations.vercel.projects.create({
166
+ projectId: 'vercel_project_id',
167
+ name: 'project_name'
168
+ })
169
+ ```
170
+
171
+ #### Find Vercel Projects
172
+
173
+ ```typescript
174
+ const projects = await v0.integrations.vercel.projects.find()
136
175
  ```
137
176
 
138
- ## Customizing Model Behavior
177
+ ### User Management
139
178
 
140
- Control the AI model's behavior with the `modelConfiguration` parameter:
179
+ #### Get User Information
141
180
 
142
- ```javascript
143
- const response = await client.createChat({
144
- message: 'Create a dashboard layout',
145
- modelConfiguration: {
146
- // Use a specific model version
147
- modelId: 'v0-1.5-md',
181
+ ```typescript
182
+ const userResponse = await v0.user.get()
183
+ console.log(userResponse.user.name, userResponse.user.email)
184
+ ```
148
185
 
149
- // Enable AI-generated images in the response
150
- imageGenerations: true,
151
- },
186
+ #### Get User Plan and Billing
187
+
188
+ ```typescript
189
+ const planResponse = await v0.user.getPlan()
190
+ console.log(planResponse.plan, planResponse.balance)
191
+ ```
192
+
193
+ ### Deployment and Monitoring
194
+
195
+ #### Find Deployment Logs
196
+
197
+ ```typescript
198
+ const logs = await v0.deployments.findLogs({
199
+ deploymentId: 'deployment_id'
200
+ })
201
+ ```
202
+
203
+ ### Scopes and Rate Limits
204
+
205
+ #### Find Scopes
206
+
207
+ ```typescript
208
+ const scopesResponse = await v0.scopes.find()
209
+ console.log(scopesResponse.scopes)
210
+ ```
211
+
212
+ #### Check Rate Limits
213
+
214
+ ```typescript
215
+ const rateLimits = await v0.rateLimits.find()
216
+ console.log(rateLimits.remaining, rateLimits.reset)
217
+ ```
218
+
219
+ ## Working with Attachments
220
+
221
+ The SDK supports URL and base64-encoded attachments:
222
+
223
+ ```typescript
224
+ // URL attachment
225
+ const response = await v0.chats.create({
226
+ message: 'Create a component based on this design',
227
+ attachments: [{ url: 'https://example.com/design.png' }],
152
228
  })
229
+
230
+ // Base64 attachment
231
+ const handleFileUpload = async (file: File) => {
232
+ const reader = new FileReader()
233
+
234
+ reader.onload = async () => {
235
+ const response = await v0.chats.create({
236
+ message: 'Create a component based on this image',
237
+ attachments: [{ url: reader.result as string }],
238
+ })
239
+
240
+ console.log(response)
241
+ }
242
+
243
+ reader.readAsDataURL(file)
244
+ }
245
+ ```
246
+
247
+ ## TypeScript Support
248
+
249
+ The SDK includes complete type definitions for all API operations:
250
+
251
+ ```typescript
252
+ import type {
253
+ ChatsCreateRequest,
254
+ ChatsCreateResponse,
255
+ User,
256
+ Project,
257
+ ScopeSummary
258
+ } from 'v0-sdk'
259
+
260
+ // All request and response types are fully typed
261
+ const createChatRequest: ChatsCreateRequest = {
262
+ message: 'Create a component',
263
+ system: 'You are a helpful assistant',
264
+ }
153
265
  ```
154
266
 
155
267
  ## Error Handling
156
268
 
157
- The client throws descriptive errors for various failure scenarios:
269
+ The SDK provides detailed error information:
158
270
 
159
- ```javascript
271
+ ```typescript
160
272
  try {
161
- const chat = await client.createChat({
273
+ const chat = await v0.chats.create({
162
274
  message: 'Create a component',
163
275
  })
164
276
  } catch (error) {
@@ -172,18 +284,86 @@ try {
172
284
  }
173
285
  ```
174
286
 
287
+ ## Testing
288
+
289
+ The SDK includes comprehensive test coverage. Run tests with:
290
+
291
+ ```bash
292
+ npm test
293
+ ```
294
+
295
+ ### Test Structure
296
+
297
+ Tests are organized by functionality:
298
+
299
+ ```
300
+ tests/
301
+ ├── chats/
302
+ │ ├── create.test.ts
303
+ │ ├── find.test.ts
304
+ │ ├── delete.test.ts
305
+ │ ├── getById.test.ts
306
+ │ ├── favorite.test.ts
307
+ │ ├── unfavorite.test.ts
308
+ │ ├── getProject.test.ts
309
+ │ ├── createMessage.test.ts
310
+ │ └── getVersionFrameToken.test.ts
311
+ ├── projects/
312
+ │ ├── create.test.ts
313
+ │ └── find.test.ts
314
+ ├── integrations/vercel/projects/
315
+ │ ├── create.test.ts
316
+ │ └── find.test.ts
317
+ ├── user/
318
+ │ ├── get.test.ts
319
+ │ └── getPlan.test.ts
320
+ ├── deployments/
321
+ │ └── findLogs.test.ts
322
+ ├── scopes/
323
+ │ └── find.test.ts
324
+ └── rateLimits/
325
+ └── find.test.ts
326
+ ```
327
+
328
+ ## Development
329
+
330
+ ### Building
331
+
332
+ ```bash
333
+ npm run build
334
+ ```
335
+
336
+ ### Generating SDK
337
+
338
+ The SDK is generated from the OpenAPI specification:
339
+
340
+ ```bash
341
+ npm run generate
342
+ ```
343
+
344
+ ### Running Tests
345
+
346
+ ```bash
347
+ npm test
348
+ ```
349
+
175
350
  ## Advanced Usage
176
351
 
177
- ### Streaming Responses
352
+ ### Custom Configuration
178
353
 
179
- Coming soon
354
+ ```typescript
355
+ const client = new V0Client('your_api_key', 'https://custom-api.example.com', {
356
+ timeout: 30000,
357
+ retries: 3
358
+ })
359
+ ```
180
360
 
181
361
  ### Team Collaboration
182
362
 
183
363
  Share chats with your team:
184
364
 
185
- ```javascript
186
- const chat = await client.createChat({
365
+ ```typescript
366
+ const chat = await v0.chats.create({
187
367
  message: 'Create a component for our design system',
188
368
  chatPrivacy: 'team-edit',
189
369
  teamId: 'your-team-id',
@@ -197,22 +377,20 @@ console.log(`Team chat URL: ${chat.url}`)
197
377
 
198
378
  ### Rate Limiting
199
379
 
200
- The API has rate limits of 100 requests per minute and 1,000 requests per hour. If you hit these limits, you'll receive a 429 status code.
380
+ The API has rate limits. Check your current limits:
201
381
 
202
- ### Common Errors
203
-
204
- - **403 Forbidden**: Check your API key and ensure you have a valid subscription.
205
- - **400 Bad Request**: Verify your request parameters match the API requirements.
206
- - **404 Not Found**: Ensure the chat ID exists and is accessible to your API key.
207
- - **413 Payload Too Large**: Reduce attachment size (max 10MB per attachment).
208
-
209
- ### Debugging
382
+ ```typescript
383
+ const limits = await v0.rateLimits.find()
384
+ console.log(`Remaining requests: ${limits.remaining}`)
385
+ ```
210
386
 
211
- Enable debug mode to see detailed request and response information:
387
+ ### Common Errors
212
388
 
213
- ```javascript
214
- const client = new V0Client('your_api_key', undefined, { debug: true })
215
- ```
389
+ - **403 Forbidden**: Check your API key and ensure you have a valid subscription
390
+ - **400 Bad Request**: Verify your request parameters match the API requirements
391
+ - **404 Not Found**: Ensure the resource ID exists and is accessible to your API key
392
+ - **413 Payload Too Large**: Reduce attachment size (max 10MB per attachment)
393
+ - **429 Too Many Requests**: You've hit the rate limit, wait before making more requests
216
394
 
217
395
  ## Resources
218
396
 
package/dist/index.cjs ADDED
@@ -0,0 +1,226 @@
1
+ Object.defineProperty(exports, '__esModule', { value: true });
2
+
3
+ let BASE_URL = 'https://api.v0.dev/v1';
4
+ async function fetcher(url, method, params = {}) {
5
+ const queryString = params.query ? '?' + new URLSearchParams(params.query).toString() : '';
6
+ const finalUrl = BASE_URL + url + queryString;
7
+ const apiKey = process.env.V0_API_KEY;
8
+ if (!apiKey) {
9
+ throw new Error('V0_API_KEY environment variable is required');
10
+ }
11
+ const hasBody = method !== 'GET' && params.body;
12
+ const headers = {
13
+ 'Authorization': `Bearer ${apiKey}`,
14
+ ...params.headers
15
+ };
16
+ if (hasBody) {
17
+ headers['Content-Type'] = 'application/json';
18
+ }
19
+ const res = await fetch(finalUrl, {
20
+ method,
21
+ headers,
22
+ body: hasBody ? JSON.stringify(params.body) : undefined
23
+ });
24
+ if (!res.ok) {
25
+ const text = await res.text();
26
+ throw new Error(`HTTP ${res.status}: ${text}`);
27
+ }
28
+ return res.json();
29
+ }
30
+
31
+ const v0 = {
32
+ chats: {
33
+ async create (params) {
34
+ const body = {
35
+ message: params.message,
36
+ attachments: params.attachments,
37
+ system: params.system,
38
+ chatPrivacy: params.chatPrivacy,
39
+ projectId: params.projectId,
40
+ modelConfiguration: params.modelConfiguration,
41
+ chatId: params.chatId
42
+ };
43
+ return fetcher(`/chats`, 'POST', {
44
+ body
45
+ });
46
+ },
47
+ async find () {
48
+ return fetcher(`/chats`, 'GET', {});
49
+ },
50
+ async delete (params) {
51
+ const pathParams = {
52
+ chatId: params.chatId
53
+ };
54
+ return fetcher(`/chats/${pathParams.chatId}`, 'DELETE', {
55
+ });
56
+ },
57
+ async getById (params) {
58
+ const pathParams = {
59
+ chatId: params.chatId
60
+ };
61
+ return fetcher(`/chats/${pathParams.chatId}`, 'GET', {
62
+ });
63
+ },
64
+ async favorite (params) {
65
+ const pathParams = {
66
+ chatId: params.chatId
67
+ };
68
+ return fetcher(`/chats/${pathParams.chatId}/favorite`, 'POST', {
69
+ });
70
+ },
71
+ async unfavorite (params) {
72
+ const pathParams = {
73
+ chatId: params.chatId
74
+ };
75
+ return fetcher(`/chats/${pathParams.chatId}/unfavorite`, 'POST', {
76
+ });
77
+ },
78
+ async getProject (params) {
79
+ const pathParams = {
80
+ chatId: params.chatId
81
+ };
82
+ return fetcher(`/chats/${pathParams.chatId}/project`, 'GET', {
83
+ });
84
+ },
85
+ async createMessage (params) {
86
+ const pathParams = {
87
+ chatId: params.chatId
88
+ };
89
+ const body = {
90
+ message: params.message,
91
+ attachments: params.attachments,
92
+ modelConfiguration: params.modelConfiguration
93
+ };
94
+ return fetcher(`/chats/${pathParams.chatId}/messages`, 'POST', {
95
+ body
96
+ });
97
+ },
98
+ async getVersionFrameToken (params) {
99
+ const pathParams = {
100
+ chatId: params.chatId,
101
+ versionId: params.versionId
102
+ };
103
+ return fetcher(`/chats/${pathParams.chatId}/versions/${pathParams.versionId}/frame-token`, 'GET', {
104
+ });
105
+ },
106
+ async getMetadata (params) {
107
+ const pathParams = {
108
+ chatId: params.chatId
109
+ };
110
+ return fetcher(`/chats/${pathParams.chatId}/metadata`, 'GET', {
111
+ });
112
+ },
113
+ async setPrivacy (params) {
114
+ const pathParams = {
115
+ chatId: params.chatId
116
+ };
117
+ const body = {
118
+ privacy: params.privacy
119
+ };
120
+ return fetcher(`/chats/${pathParams.chatId}/privacy`, 'POST', {
121
+ body
122
+ });
123
+ },
124
+ async upload (params) {
125
+ const pathParams = {
126
+ chatId: params.chatId
127
+ };
128
+ const body = {
129
+ file: params.file
130
+ };
131
+ return fetcher(`/chats/${pathParams.chatId}/upload`, 'POST', {
132
+ body
133
+ });
134
+ },
135
+ async resume (params) {
136
+ const pathParams = {
137
+ chatId: params.chatId,
138
+ messageId: params.messageId
139
+ };
140
+ return fetcher(`/chats/${pathParams.chatId}/messages/${pathParams.messageId}/resume`, 'POST', {
141
+ });
142
+ }
143
+ },
144
+ deployments: {
145
+ async findLogs (params) {
146
+ const pathParams = {
147
+ deploymentId: params.deploymentId
148
+ };
149
+ return fetcher(`/deployments/${pathParams.deploymentId}/logs`, 'GET', {
150
+ });
151
+ },
152
+ async findErrors (params) {
153
+ const pathParams = {
154
+ deploymentId: params.deploymentId
155
+ };
156
+ return fetcher(`/deployments/${pathParams.deploymentId}/errors`, 'GET', {
157
+ });
158
+ }
159
+ },
160
+ integrations: {
161
+ vercel: {
162
+ projects: {
163
+ async find () {
164
+ return fetcher(`/integrations/vercel/projects`, 'GET', {});
165
+ },
166
+ async create (params) {
167
+ const body = {
168
+ projectId: params.projectId,
169
+ name: params.name
170
+ };
171
+ return fetcher(`/integrations/vercel/projects`, 'POST', {
172
+ body
173
+ });
174
+ }
175
+ }
176
+ }
177
+ },
178
+ projects: {
179
+ async find () {
180
+ return fetcher(`/projects`, 'GET', {});
181
+ },
182
+ async create (params) {
183
+ const body = {
184
+ name: params.name,
185
+ description: params.description,
186
+ icon: params.icon,
187
+ environmentVariables: params.environmentVariables,
188
+ instructions: params.instructions
189
+ };
190
+ return fetcher(`/projects`, 'POST', {
191
+ body
192
+ });
193
+ },
194
+ async assign (params) {
195
+ const pathParams = {
196
+ projectId: params.projectId
197
+ };
198
+ const body = {
199
+ chatId: params.chatId
200
+ };
201
+ return fetcher(`/projects/${pathParams.projectId}/assign`, 'POST', {
202
+ body
203
+ });
204
+ }
205
+ },
206
+ scopes: {
207
+ async find () {
208
+ return fetcher(`/scopes`, 'GET', {});
209
+ }
210
+ },
211
+ rateLimits: {
212
+ async find () {
213
+ return fetcher(`/rate-limits`, 'GET', {});
214
+ }
215
+ },
216
+ user: {
217
+ async get () {
218
+ return fetcher(`/user`, 'GET', {});
219
+ },
220
+ async getPlan () {
221
+ return fetcher(`/user/plan`, 'GET', {});
222
+ }
223
+ }
224
+ };
225
+
226
+ exports.v0 = v0;
@@ -0,0 +1,313 @@
1
+ interface ScopeSummary {
2
+ id: string;
3
+ name?: string;
4
+ }
5
+ interface User {
6
+ id: string;
7
+ name?: string;
8
+ email: string;
9
+ avatar: string;
10
+ createdAt: string;
11
+ }
12
+ interface ChatsCreateRequest {
13
+ message: string;
14
+ attachments?: {
15
+ url: string;
16
+ }[];
17
+ system?: string;
18
+ chatPrivacy?: 'public' | 'private' | 'team-edit' | 'team' | 'unlisted';
19
+ projectId?: string;
20
+ modelConfiguration?: {
21
+ modelId: 'v0-1.5-sm' | 'v0-1.5-md' | 'v0-1.5-lg';
22
+ imageGenerations?: boolean;
23
+ thinking?: boolean;
24
+ };
25
+ chatId?: string;
26
+ }
27
+ type ChatsCreateResponse = {
28
+ chatId: string;
29
+ url: string;
30
+ files?: {
31
+ lang: string;
32
+ meta: Record<string, any>;
33
+ source: string;
34
+ }[];
35
+ demo?: string;
36
+ text: string;
37
+ modelConfiguration: {
38
+ modelId: 'v0-1.5-sm' | 'v0-1.5-md' | 'v0-1.5-lg';
39
+ imageGenerations?: boolean;
40
+ thinking?: boolean;
41
+ };
42
+ _deprecation?: {
43
+ message: string;
44
+ migration: string;
45
+ sunset: string;
46
+ };
47
+ };
48
+ interface ChatsFindResponse {
49
+ favorites: {
50
+ chatId: string;
51
+ shareable: boolean;
52
+ privacy: string;
53
+ title: string;
54
+ updatedAt: string;
55
+ favorite: boolean;
56
+ authorId: string;
57
+ }[];
58
+ history: {
59
+ chatId: string;
60
+ shareable: boolean;
61
+ privacy: string;
62
+ title: string;
63
+ updatedAt: string;
64
+ }[];
65
+ }
66
+ interface ChatsDeleteResponse {
67
+ success: boolean;
68
+ }
69
+ type ChatsGetByIdResponse = {
70
+ chatId: string;
71
+ url: string;
72
+ messages: {
73
+ messageId: string;
74
+ content: string;
75
+ createdAt: string;
76
+ type: 'message' | 'refinement' | 'forked-block' | 'forked-chat' | 'open-in-v0' | 'added-environment-variables' | 'added-integration' | 'deleted-file' | 'moved-file' | 'renamed-file' | 'edited-file' | 'replace-src' | 'reverted-block' | 'fix-with-v0' | 'sync-git';
77
+ }[];
78
+ };
79
+ type ChatsFavoriteResponse = {
80
+ success: boolean;
81
+ } | {
82
+ error: string;
83
+ success?: any;
84
+ };
85
+ type ChatsUnfavoriteResponse = {
86
+ success: boolean;
87
+ } | {
88
+ error: string;
89
+ success?: any;
90
+ };
91
+ interface ChatsGetProjectResponse {
92
+ project: {
93
+ id: string;
94
+ name: string;
95
+ url: string;
96
+ };
97
+ }
98
+ interface ChatsCreateMessageRequest {
99
+ message: string;
100
+ attachments?: {
101
+ url: string;
102
+ }[];
103
+ modelConfiguration?: {
104
+ modelId: 'v0-1.5-sm' | 'v0-1.5-md' | 'v0-1.5-lg';
105
+ imageGenerations?: boolean;
106
+ thinking?: boolean;
107
+ };
108
+ }
109
+ type ChatsCreateMessageResponse = {
110
+ chatId: string;
111
+ url: string;
112
+ files?: {
113
+ lang: string;
114
+ meta: Record<string, any>;
115
+ source: string;
116
+ }[];
117
+ demo?: string;
118
+ text: string;
119
+ modelConfiguration: {
120
+ modelId: 'v0-1.5-sm' | 'v0-1.5-md' | 'v0-1.5-lg';
121
+ imageGenerations?: boolean;
122
+ thinking?: boolean;
123
+ };
124
+ };
125
+ interface ChatsGetVersionFrameTokenResponse {
126
+ token: string;
127
+ }
128
+ interface ChatsGetMetadataResponse {
129
+ git: {
130
+ branch: string;
131
+ commit: string;
132
+ };
133
+ deployment: {
134
+ id: string;
135
+ };
136
+ project: {
137
+ id: string;
138
+ name: string;
139
+ url: string;
140
+ };
141
+ }
142
+ interface ChatsSetPrivacyRequest {
143
+ privacy: 'public' | 'private' | 'team' | 'team-edit' | 'unlisted';
144
+ }
145
+ type ChatsSetPrivacyResponse = {
146
+ success: 'true';
147
+ } | {
148
+ error: string;
149
+ };
150
+ interface ChatsUploadRequest {
151
+ file: any;
152
+ }
153
+ interface ChatsUploadResponse {
154
+ url: string;
155
+ }
156
+ interface ChatsResumeResponse {
157
+ message: {
158
+ id: string;
159
+ content: string;
160
+ createdAt: string;
161
+ finishReason?: string;
162
+ };
163
+ }
164
+ interface DeploymentsFindLogsResponse {
165
+ error?: string;
166
+ logs: string[];
167
+ nextSince?: number;
168
+ }
169
+ interface DeploymentsFindErrorsResponse {
170
+ error?: string;
171
+ fullErrorText?: string;
172
+ errorType?: string;
173
+ formattedError?: string;
174
+ }
175
+ interface IntegrationsVercelProjectsFindResponse {
176
+ projects: {
177
+ id: string;
178
+ name: string;
179
+ url: string;
180
+ }[];
181
+ }
182
+ interface IntegrationsVercelProjectsCreateRequest {
183
+ projectId: string;
184
+ name: string;
185
+ }
186
+ interface IntegrationsVercelProjectsCreateResponse {
187
+ success: boolean;
188
+ }
189
+ interface ProjectsFindResponse {
190
+ id: string;
191
+ name: string;
192
+ url: string;
193
+ env: string[];
194
+ }
195
+ interface ProjectsCreateRequest {
196
+ name: string;
197
+ description?: string;
198
+ icon?: string;
199
+ environmentVariables?: {
200
+ key: string;
201
+ value: string;
202
+ }[];
203
+ instructions?: string;
204
+ }
205
+ interface ProjectsCreateResponse {
206
+ id: string;
207
+ name: string;
208
+ vercelProjectId?: string;
209
+ }
210
+ interface ProjectsAssignRequest {
211
+ chatId: string;
212
+ }
213
+ interface ProjectsAssignResponse {
214
+ success: boolean;
215
+ }
216
+ interface ScopesFindResponse {
217
+ scopes: ScopeSummary[];
218
+ }
219
+ interface RateLimitsFindResponse {
220
+ remaining?: number;
221
+ reset?: number;
222
+ limit: number;
223
+ }
224
+ interface UserGetResponse {
225
+ user: User;
226
+ }
227
+ interface UserGetPlanResponse {
228
+ plan: string;
229
+ billingCycle: {
230
+ start: number;
231
+ end: number;
232
+ };
233
+ balance: {
234
+ remaining: number;
235
+ total: number;
236
+ };
237
+ }
238
+ declare const v0: {
239
+ chats: {
240
+ create(params: ChatsCreateRequest): Promise<ChatsCreateResponse>;
241
+ find(): Promise<ChatsFindResponse>;
242
+ delete(params: {
243
+ chatId: string;
244
+ }): Promise<ChatsDeleteResponse>;
245
+ getById(params: {
246
+ chatId: string;
247
+ }): Promise<ChatsGetByIdResponse>;
248
+ favorite(params: {
249
+ chatId: string;
250
+ }): Promise<ChatsFavoriteResponse>;
251
+ unfavorite(params: {
252
+ chatId: string;
253
+ }): Promise<ChatsUnfavoriteResponse>;
254
+ getProject(params: {
255
+ chatId: string;
256
+ }): Promise<ChatsGetProjectResponse>;
257
+ createMessage(params: {
258
+ chatId: string;
259
+ } & ChatsCreateMessageRequest): Promise<ChatsCreateMessageResponse>;
260
+ getVersionFrameToken(params: {
261
+ chatId: string;
262
+ versionId: string;
263
+ }): Promise<ChatsGetVersionFrameTokenResponse>;
264
+ getMetadata(params: {
265
+ chatId: string;
266
+ }): Promise<ChatsGetMetadataResponse>;
267
+ setPrivacy(params: {
268
+ chatId: string;
269
+ } & ChatsSetPrivacyRequest): Promise<ChatsSetPrivacyResponse>;
270
+ upload(params: {
271
+ chatId: string;
272
+ } & ChatsUploadRequest): Promise<ChatsUploadResponse>;
273
+ resume(params: {
274
+ chatId: string;
275
+ messageId: string;
276
+ }): Promise<ChatsResumeResponse>;
277
+ };
278
+ deployments: {
279
+ findLogs(params: {
280
+ deploymentId: string;
281
+ }): Promise<DeploymentsFindLogsResponse>;
282
+ findErrors(params: {
283
+ deploymentId: string;
284
+ }): Promise<DeploymentsFindErrorsResponse>;
285
+ };
286
+ integrations: {
287
+ vercel: {
288
+ projects: {
289
+ find(): Promise<IntegrationsVercelProjectsFindResponse>;
290
+ create(params: IntegrationsVercelProjectsCreateRequest): Promise<IntegrationsVercelProjectsCreateResponse>;
291
+ };
292
+ };
293
+ };
294
+ projects: {
295
+ find(): Promise<ProjectsFindResponse>;
296
+ create(params: ProjectsCreateRequest): Promise<ProjectsCreateResponse>;
297
+ assign(params: {
298
+ projectId: string;
299
+ } & ProjectsAssignRequest): Promise<ProjectsAssignResponse>;
300
+ };
301
+ scopes: {
302
+ find(): Promise<ScopesFindResponse>;
303
+ };
304
+ rateLimits: {
305
+ find(): Promise<RateLimitsFindResponse>;
306
+ };
307
+ user: {
308
+ get(): Promise<UserGetResponse>;
309
+ getPlan(): Promise<UserGetPlanResponse>;
310
+ };
311
+ };
312
+
313
+ export { v0 };
package/dist/index.js CHANGED
@@ -1,105 +1,224 @@
1
- /**
2
- * v0 Chats API SDK
3
- * A client library for interacting with the v0 Chats API
4
- */ class V0ChatsError extends Error {
5
- constructor(message, status, data){
6
- super(message);
7
- this.name = 'V0ChatsError';
8
- this.status = status;
9
- this.data = data;
1
+ let BASE_URL = 'https://api.v0.dev/v1';
2
+ async function fetcher(url, method, params = {}) {
3
+ const queryString = params.query ? '?' + new URLSearchParams(params.query).toString() : '';
4
+ const finalUrl = BASE_URL + url + queryString;
5
+ const apiKey = process.env.V0_API_KEY;
6
+ if (!apiKey) {
7
+ throw new Error('V0_API_KEY environment variable is required');
10
8
  }
11
- }
12
- /**
13
- * Client for the v0 Chats API
14
- */ class V0Client {
15
- /**
16
- * Create a new v0 Chats API client
17
- *
18
- * @param options Client configuration options
19
- */ constructor(options){
20
- this.apiKey = options.apiKey;
21
- this.baseUrl = options.baseUrl || 'https://api.v0.dev/';
22
- this.fetchFn = options.fetch || fetch;
23
- }
24
- /**
25
- * Create a new chat
26
- *
27
- * @param options Options for creating a new chat
28
- * @returns Promise with the created chat details
29
- */ async createChat(options) {
30
- const response = await this.request('POST', '/chats', options);
31
- return response;
32
- }
33
- /**
34
- * Add a message to an existing chat
35
- *
36
- * @param chatId The ID of the chat to add a message to
37
- * @param options Options for adding a message
38
- * @returns Promise with the updated chat details
39
- */ async addMessage(chatId, options) {
40
- const response = await this.request('POST', `/chats/${chatId}`, options);
41
- return response;
42
- }
43
- /**
44
- * Get chat details and message history
45
- *
46
- * @param chatId The ID of the chat to retrieve
47
- * @returns Promise with the chat details and messages
48
- */ async getChat(chatId) {
49
- const response = await this.request('GET', `/chats/${chatId}`);
50
- return response;
9
+ const hasBody = method !== 'GET' && params.body;
10
+ const headers = {
11
+ 'Authorization': `Bearer ${apiKey}`,
12
+ ...params.headers
13
+ };
14
+ if (hasBody) {
15
+ headers['Content-Type'] = 'application/json';
51
16
  }
52
- /**
53
- * Continue an existing chat (deprecated)
54
- *
55
- * This method is deprecated. Use addMessage() instead.
56
- *
57
- * @deprecated Use addMessage() instead
58
- * @param chatId The ID of the chat to continue
59
- * @param options Options for continuing the chat
60
- * @returns Promise with the updated chat details
61
- */ async continueChat(chatId, options) {
62
- console.warn('continueChat() is deprecated. Use addMessage() instead.');
63
- const payload = {
64
- ...options,
65
- chatId
66
- };
67
- const response = await this.request('POST', '/chats', payload);
68
- return response;
17
+ const res = await fetch(finalUrl, {
18
+ method,
19
+ headers,
20
+ body: hasBody ? JSON.stringify(params.body) : undefined
21
+ });
22
+ if (!res.ok) {
23
+ const text = await res.text();
24
+ throw new Error(`HTTP ${res.status}: ${text}`);
69
25
  }
70
- /**
71
- * Make a request to the v0 Chats API
72
- *
73
- * @param method HTTP method
74
- * @param path API path
75
- * @param data Request data
76
- * @returns Promise with the response data
77
- */ async request(method, path, data) {
78
- const url = `${this.baseUrl}${path}`;
79
- const headers = {
80
- Authorization: `Bearer ${this.apiKey}`,
81
- 'Content-Type': 'application/json'
82
- };
83
- const options = {
84
- method,
85
- headers,
86
- body: data && method !== 'GET' ? JSON.stringify(data) : undefined
87
- };
88
- try {
89
- const response = await this.fetchFn(url, options);
90
- const responseData = await response.json();
91
- if (!response.ok) {
92
- throw new V0ChatsError(responseData.error || `API request failed with status ${response.status}`, response.status, responseData);
93
- }
94
- return responseData;
95
- } catch (error) {
96
- if (error instanceof V0ChatsError) {
97
- throw error;
26
+ return res.json();
27
+ }
28
+
29
+ const v0 = {
30
+ chats: {
31
+ async create (params) {
32
+ const body = {
33
+ message: params.message,
34
+ attachments: params.attachments,
35
+ system: params.system,
36
+ chatPrivacy: params.chatPrivacy,
37
+ projectId: params.projectId,
38
+ modelConfiguration: params.modelConfiguration,
39
+ chatId: params.chatId
40
+ };
41
+ return fetcher(`/chats`, 'POST', {
42
+ body
43
+ });
44
+ },
45
+ async find () {
46
+ return fetcher(`/chats`, 'GET', {});
47
+ },
48
+ async delete (params) {
49
+ const pathParams = {
50
+ chatId: params.chatId
51
+ };
52
+ return fetcher(`/chats/${pathParams.chatId}`, 'DELETE', {
53
+ });
54
+ },
55
+ async getById (params) {
56
+ const pathParams = {
57
+ chatId: params.chatId
58
+ };
59
+ return fetcher(`/chats/${pathParams.chatId}`, 'GET', {
60
+ });
61
+ },
62
+ async favorite (params) {
63
+ const pathParams = {
64
+ chatId: params.chatId
65
+ };
66
+ return fetcher(`/chats/${pathParams.chatId}/favorite`, 'POST', {
67
+ });
68
+ },
69
+ async unfavorite (params) {
70
+ const pathParams = {
71
+ chatId: params.chatId
72
+ };
73
+ return fetcher(`/chats/${pathParams.chatId}/unfavorite`, 'POST', {
74
+ });
75
+ },
76
+ async getProject (params) {
77
+ const pathParams = {
78
+ chatId: params.chatId
79
+ };
80
+ return fetcher(`/chats/${pathParams.chatId}/project`, 'GET', {
81
+ });
82
+ },
83
+ async createMessage (params) {
84
+ const pathParams = {
85
+ chatId: params.chatId
86
+ };
87
+ const body = {
88
+ message: params.message,
89
+ attachments: params.attachments,
90
+ modelConfiguration: params.modelConfiguration
91
+ };
92
+ return fetcher(`/chats/${pathParams.chatId}/messages`, 'POST', {
93
+ body
94
+ });
95
+ },
96
+ async getVersionFrameToken (params) {
97
+ const pathParams = {
98
+ chatId: params.chatId,
99
+ versionId: params.versionId
100
+ };
101
+ return fetcher(`/chats/${pathParams.chatId}/versions/${pathParams.versionId}/frame-token`, 'GET', {
102
+ });
103
+ },
104
+ async getMetadata (params) {
105
+ const pathParams = {
106
+ chatId: params.chatId
107
+ };
108
+ return fetcher(`/chats/${pathParams.chatId}/metadata`, 'GET', {
109
+ });
110
+ },
111
+ async setPrivacy (params) {
112
+ const pathParams = {
113
+ chatId: params.chatId
114
+ };
115
+ const body = {
116
+ privacy: params.privacy
117
+ };
118
+ return fetcher(`/chats/${pathParams.chatId}/privacy`, 'POST', {
119
+ body
120
+ });
121
+ },
122
+ async upload (params) {
123
+ const pathParams = {
124
+ chatId: params.chatId
125
+ };
126
+ const body = {
127
+ file: params.file
128
+ };
129
+ return fetcher(`/chats/${pathParams.chatId}/upload`, 'POST', {
130
+ body
131
+ });
132
+ },
133
+ async resume (params) {
134
+ const pathParams = {
135
+ chatId: params.chatId,
136
+ messageId: params.messageId
137
+ };
138
+ return fetcher(`/chats/${pathParams.chatId}/messages/${pathParams.messageId}/resume`, 'POST', {
139
+ });
140
+ }
141
+ },
142
+ deployments: {
143
+ async findLogs (params) {
144
+ const pathParams = {
145
+ deploymentId: params.deploymentId
146
+ };
147
+ return fetcher(`/deployments/${pathParams.deploymentId}/logs`, 'GET', {
148
+ });
149
+ },
150
+ async findErrors (params) {
151
+ const pathParams = {
152
+ deploymentId: params.deploymentId
153
+ };
154
+ return fetcher(`/deployments/${pathParams.deploymentId}/errors`, 'GET', {
155
+ });
156
+ }
157
+ },
158
+ integrations: {
159
+ vercel: {
160
+ projects: {
161
+ async find () {
162
+ return fetcher(`/integrations/vercel/projects`, 'GET', {});
163
+ },
164
+ async create (params) {
165
+ const body = {
166
+ projectId: params.projectId,
167
+ name: params.name
168
+ };
169
+ return fetcher(`/integrations/vercel/projects`, 'POST', {
170
+ body
171
+ });
172
+ }
98
173
  }
99
- throw new V0ChatsError(error instanceof Error ? error.message : 'Unknown error occurred', 500);
174
+ }
175
+ },
176
+ projects: {
177
+ async find () {
178
+ return fetcher(`/projects`, 'GET', {});
179
+ },
180
+ async create (params) {
181
+ const body = {
182
+ name: params.name,
183
+ description: params.description,
184
+ icon: params.icon,
185
+ environmentVariables: params.environmentVariables,
186
+ instructions: params.instructions
187
+ };
188
+ return fetcher(`/projects`, 'POST', {
189
+ body
190
+ });
191
+ },
192
+ async assign (params) {
193
+ const pathParams = {
194
+ projectId: params.projectId
195
+ };
196
+ const body = {
197
+ chatId: params.chatId
198
+ };
199
+ return fetcher(`/projects/${pathParams.projectId}/assign`, 'POST', {
200
+ body
201
+ });
202
+ }
203
+ },
204
+ scopes: {
205
+ async find () {
206
+ return fetcher(`/scopes`, 'GET', {});
207
+ }
208
+ },
209
+ rateLimits: {
210
+ async find () {
211
+ return fetcher(`/rate-limits`, 'GET', {});
212
+ }
213
+ },
214
+ user: {
215
+ async get () {
216
+ return fetcher(`/user`, 'GET', {});
217
+ },
218
+ async getPlan () {
219
+ return fetcher(`/user/plan`, 'GET', {});
100
220
  }
101
221
  }
102
- }
222
+ };
103
223
 
104
- exports.V0ChatsError = V0ChatsError;
105
- exports.V0Client = V0Client;
224
+ export { v0 };
package/package.json CHANGED
@@ -1,11 +1,27 @@
1
1
  {
2
2
  "name": "v0-sdk",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "TypeScript SDK for the v0 Chats API",
5
+ "type": "module",
5
6
  "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.cjs"
13
+ }
14
+ },
6
15
  "files": [
7
16
  "dist"
8
17
  ],
18
+ "scripts": {
19
+ "type-check": "tsc --noEmit",
20
+ "type-check:go": "tsgo --noEmit",
21
+ "build": "bunchee",
22
+ "generate": "tsx src/scripts/generate.ts",
23
+ "test": "vitest"
24
+ },
9
25
  "keywords": [
10
26
  "v0",
11
27
  "vercel",
@@ -16,10 +32,10 @@
16
32
  "author": "",
17
33
  "license": "MIT",
18
34
  "devDependencies": {
35
+ "@types/node": "22.5.5",
36
+ "@typescript/native-preview": "7.0.0-dev.20250613.1",
19
37
  "bunchee": "^6.5.2",
38
+ "tsx": "^4.19.2",
20
39
  "typescript": "5.7.3"
21
- },
22
- "scripts": {
23
- "build": "bunchee"
24
40
  }
25
- }
41
+ }