v0-sdk
Version:
TypeScript SDK for the v0 Platform API
641 lines (637 loc) • 24 kB
JavaScript
Object.defineProperty(exports, '__esModule', { value: true });
function createFetcher(config = {}) {
const baseUrl = config.baseUrl || 'https://api.v0.dev/v1';
let sessionToken = null;
return async function fetcher(url, method, params = {}) {
const apiKey = config.apiKey || process.env.V0_API_KEY;
if (!apiKey) {
throw new Error('API key is required. Provide it via config.apiKey or V0_API_KEY environment variable');
}
const queryString = params.query ? '?' + new URLSearchParams(params.query).toString() : '';
const finalUrl = baseUrl + url + queryString;
const hasBody = method !== 'GET' && params.body;
const headers = {
Authorization: `Bearer ${apiKey}`,
'User-Agent': 'v0-sdk/0.1.0',
...params.headers
};
// Include session token in headers if available
if (sessionToken) {
headers['x-session-token'] = sessionToken;
}
if (hasBody) {
headers['Content-Type'] = 'application/json';
}
const res = await fetch(finalUrl, {
method,
headers,
body: hasBody ? JSON.stringify(params.body) : undefined
});
// Check for session token in response headers
const newSessionToken = res.headers.get('x-session-token');
if (newSessionToken) {
sessionToken = newSessionToken;
}
if (!res.ok) {
const text = await res.text();
throw new Error(`HTTP ${res.status}: ${text}`);
}
return res.json();
};
}
// Utility function to parse streaming events
async function* parseStreamingResponse(stream) {
const reader = stream.getReader();
const decoder = new TextDecoder();
let buffer = '';
try {
while(true){
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, {
stream: true
});
const lines = buffer.split('\n');
buffer = lines.pop() || ''; // Keep the last incomplete line in buffer
for (const line of lines){
if (line.trim() === '') continue;
if (line.startsWith('data: ')) {
const data = line.slice(6);
if (data === '[DONE]') return;
try {
yield {
event: 'message',
data: data
};
} catch (e) {
console.warn('Failed to parse streaming data:', e);
}
} else if (line.startsWith('event: ')) {
const event = line.slice(7);
yield {
event: event,
data: ''
};
}
}
}
} finally{
reader.releaseLock();
}
}
function createStreamingFetcher(config = {}) {
const baseUrl = config.baseUrl || 'https://api.v0.dev/v1';
let sessionToken = null;
return async function streamingFetcher(url, method, params = {}) {
const apiKey = config.apiKey || process.env.V0_API_KEY;
if (!apiKey) {
throw new Error('API key is required. Provide it via config.apiKey or V0_API_KEY environment variable');
}
const queryString = params.query ? '?' + new URLSearchParams(params.query).toString() : '';
const finalUrl = baseUrl + url + queryString;
const hasBody = method !== 'GET' && params.body;
const headers = {
Authorization: `Bearer ${apiKey}`,
'User-Agent': 'v0-sdk/0.1.0',
Accept: 'text/event-stream',
'Cache-Control': 'no-cache',
...params.headers
};
// Include session token in headers if available
if (sessionToken) {
headers['x-session-token'] = sessionToken;
}
if (hasBody) {
headers['Content-Type'] = 'application/json';
}
const res = await fetch(finalUrl, {
method,
headers,
body: hasBody ? JSON.stringify(params.body) : undefined
});
// Check for session token in response headers
const newSessionToken = res.headers.get('x-session-token');
if (newSessionToken) {
sessionToken = newSessionToken;
}
if (!res.ok) {
const text = await res.text();
throw new Error(`HTTP ${res.status}: ${text}`);
}
if (!res.body) {
throw new Error('No response body available for streaming');
}
return res.body;
};
}
function createClient(config = {}) {
const fetcher = createFetcher(config);
const streamingFetcher = createStreamingFetcher(config);
return {
chats: {
async create (params) {
const body = {
message: params.message,
attachments: params.attachments,
system: params.system,
chatPrivacy: params.chatPrivacy,
projectId: params.projectId,
modelConfiguration: params.modelConfiguration,
responseMode: params.responseMode,
designSystemId: params.designSystemId
};
if (params.responseMode === 'experimental_stream') {
return await streamingFetcher(`/chats`, 'POST', {
body
});
}
return fetcher(`/chats`, 'POST', {
body
});
},
async find (params) {
const query = params ? Object.fromEntries(Object.entries({
limit: params.limit,
offset: params.offset,
isFavorite: params.isFavorite
}).filter(([_, value])=>value !== undefined)) : {};
const hasQuery = Object.keys(query).length > 0;
return fetcher(`/chats`, 'GET', {
...hasQuery ? {
query
} : {}
});
},
async init (params) {
const body = params;
return fetcher(`/chats/init`, 'POST', {
body
});
},
async delete (params) {
const pathParams = {
chatId: params.chatId
};
return fetcher(`/chats/${pathParams.chatId}`, 'DELETE', {
pathParams
});
},
async getById (params) {
const pathParams = {
chatId: params.chatId
};
return fetcher(`/chats/${pathParams.chatId}`, 'GET', {
pathParams
});
},
async update (params) {
const pathParams = {
chatId: params.chatId
};
const body = {
name: params.name,
privacy: params.privacy
};
return fetcher(`/chats/${pathParams.chatId}`, 'PATCH', {
pathParams,
body
});
},
async favorite (params) {
const pathParams = {
chatId: params.chatId
};
const body = {
isFavorite: params.isFavorite
};
return fetcher(`/chats/${pathParams.chatId}/favorite`, 'PUT', {
pathParams,
body
});
},
async fork (params) {
const pathParams = {
chatId: params.chatId
};
const body = {
versionId: params.versionId,
privacy: params.privacy
};
return fetcher(`/chats/${pathParams.chatId}/fork`, 'POST', {
pathParams,
body
});
},
async findMessages (params) {
const pathParams = {
chatId: params.chatId
};
const query = Object.fromEntries(Object.entries({
limit: params.limit,
cursor: params.cursor
}).filter(([_, value])=>value !== undefined));
const hasQuery = Object.keys(query).length > 0;
return fetcher(`/chats/${pathParams.chatId}/messages`, 'GET', {
pathParams,
...hasQuery ? {
query
} : {}
});
},
async sendMessage (params) {
const pathParams = {
chatId: params.chatId
};
const body = {
message: params.message,
attachments: params.attachments,
modelConfiguration: params.modelConfiguration,
responseMode: params.responseMode
};
if (params.responseMode === 'experimental_stream') {
return await streamingFetcher(`/chats/${pathParams.chatId}/messages`, 'POST', {
pathParams,
body
});
}
return fetcher(`/chats/${pathParams.chatId}/messages`, 'POST', {
pathParams,
body
});
},
async getMessage (params) {
const pathParams = {
chatId: params.chatId,
messageId: params.messageId
};
return fetcher(`/chats/${pathParams.chatId}/messages/${pathParams.messageId}`, 'GET', {
pathParams
});
},
async findVersions (params) {
const pathParams = {
chatId: params.chatId
};
const query = Object.fromEntries(Object.entries({
limit: params.limit,
cursor: params.cursor
}).filter(([_, value])=>value !== undefined));
const hasQuery = Object.keys(query).length > 0;
return fetcher(`/chats/${pathParams.chatId}/versions`, 'GET', {
pathParams,
...hasQuery ? {
query
} : {}
});
},
async getVersion (params) {
const pathParams = {
chatId: params.chatId,
versionId: params.versionId
};
return fetcher(`/chats/${pathParams.chatId}/versions/${pathParams.versionId}`, 'GET', {
pathParams
});
},
async updateVersion (params) {
const pathParams = {
chatId: params.chatId,
versionId: params.versionId
};
const body = {
files: params.files
};
return fetcher(`/chats/${pathParams.chatId}/versions/${pathParams.versionId}`, 'PATCH', {
pathParams,
body
});
},
async resume (params) {
const pathParams = {
chatId: params.chatId,
messageId: params.messageId
};
return fetcher(`/chats/${pathParams.chatId}/messages/${pathParams.messageId}/resume`, 'POST', {
pathParams
});
}
},
projects: {
async getByChatId (params) {
const pathParams = {
chatId: params.chatId
};
return fetcher(`/chats/${pathParams.chatId}/project`, 'GET', {
pathParams
});
},
async find () {
return fetcher(`/projects`, 'GET', {});
},
async create (params) {
const body = {
name: params.name,
description: params.description,
icon: params.icon,
environmentVariables: params.environmentVariables,
instructions: params.instructions,
vercelProjectId: params.vercelProjectId,
privacy: params.privacy
};
return fetcher(`/projects`, 'POST', {
body
});
},
async getById (params) {
const pathParams = {
projectId: params.projectId
};
return fetcher(`/projects/${pathParams.projectId}`, 'GET', {
pathParams
});
},
async update (params) {
const pathParams = {
projectId: params.projectId
};
const body = {
name: params.name,
description: params.description,
instructions: params.instructions,
privacy: params.privacy
};
return fetcher(`/projects/${pathParams.projectId}`, 'PATCH', {
pathParams,
body
});
},
async delete (params) {
const pathParams = {
projectId: params.projectId
};
return fetcher(`/projects/${pathParams.projectId}`, 'DELETE', {
pathParams
});
},
async assign (params) {
const pathParams = {
projectId: params.projectId
};
const body = {
chatId: params.chatId
};
return fetcher(`/projects/${pathParams.projectId}/assign`, 'POST', {
pathParams,
body
});
},
async findEnvVars (params) {
const pathParams = {
projectId: params.projectId
};
const query = Object.fromEntries(Object.entries({
decrypted: params.decrypted
}).filter(([_, value])=>value !== undefined));
const hasQuery = Object.keys(query).length > 0;
return fetcher(`/projects/${pathParams.projectId}/env-vars`, 'GET', {
pathParams,
...hasQuery ? {
query
} : {}
});
},
async createEnvVars (params) {
const pathParams = {
projectId: params.projectId
};
const query = Object.fromEntries(Object.entries({
decrypted: params.decrypted
}).filter(([_, value])=>value !== undefined));
const body = {
environmentVariables: params.environmentVariables,
upsert: params.upsert
};
const hasQuery = Object.keys(query).length > 0;
return fetcher(`/projects/${pathParams.projectId}/env-vars`, 'POST', {
pathParams,
...hasQuery ? {
query
} : {},
body
});
},
async updateEnvVars (params) {
const pathParams = {
projectId: params.projectId
};
const query = Object.fromEntries(Object.entries({
decrypted: params.decrypted
}).filter(([_, value])=>value !== undefined));
const body = {
environmentVariables: params.environmentVariables
};
const hasQuery = Object.keys(query).length > 0;
return fetcher(`/projects/${pathParams.projectId}/env-vars`, 'PATCH', {
pathParams,
...hasQuery ? {
query
} : {},
body
});
},
async deleteEnvVars (params) {
const pathParams = {
projectId: params.projectId
};
const body = {
environmentVariableIds: params.environmentVariableIds
};
return fetcher(`/projects/${pathParams.projectId}/env-vars/delete`, 'POST', {
pathParams,
body
});
},
async getEnvVar (params) {
const pathParams = {
projectId: params.projectId,
environmentVariableId: params.environmentVariableId
};
const query = Object.fromEntries(Object.entries({
decrypted: params.decrypted
}).filter(([_, value])=>value !== undefined));
const hasQuery = Object.keys(query).length > 0;
return fetcher(`/projects/${pathParams.projectId}/env-vars/${pathParams.environmentVariableId}`, 'GET', {
pathParams,
...hasQuery ? {
query
} : {}
});
}
},
deployments: {
async find (params) {
const query = Object.fromEntries(Object.entries({
projectId: params.projectId,
chatId: params.chatId,
versionId: params.versionId
}).filter(([_, value])=>value !== undefined));
return fetcher(`/deployments`, 'GET', {
query
});
},
async create (params) {
const body = {
projectId: params.projectId,
chatId: params.chatId,
versionId: params.versionId
};
return fetcher(`/deployments`, 'POST', {
body
});
},
async getById (params) {
const pathParams = {
deploymentId: params.deploymentId
};
return fetcher(`/deployments/${pathParams.deploymentId}`, 'GET', {
pathParams
});
},
async delete (params) {
const pathParams = {
deploymentId: params.deploymentId
};
return fetcher(`/deployments/${pathParams.deploymentId}`, 'DELETE', {
pathParams
});
},
async findLogs (params) {
const pathParams = {
deploymentId: params.deploymentId
};
const query = Object.fromEntries(Object.entries({
since: params.since
}).filter(([_, value])=>value !== undefined));
const hasQuery = Object.keys(query).length > 0;
return fetcher(`/deployments/${pathParams.deploymentId}/logs`, 'GET', {
pathParams,
...hasQuery ? {
query
} : {}
});
},
async findErrors (params) {
const pathParams = {
deploymentId: params.deploymentId
};
return fetcher(`/deployments/${pathParams.deploymentId}/errors`, 'GET', {
pathParams
});
}
},
hooks: {
async find () {
return fetcher(`/hooks`, 'GET', {});
},
async create (params) {
const body = {
name: params.name,
events: params.events,
chatId: params.chatId,
url: params.url
};
return fetcher(`/hooks`, 'POST', {
body
});
},
async getById (params) {
const pathParams = {
hookId: params.hookId
};
return fetcher(`/hooks/${pathParams.hookId}`, 'GET', {
pathParams
});
},
async update (params) {
const pathParams = {
hookId: params.hookId
};
const body = {
name: params.name,
events: params.events,
url: params.url
};
return fetcher(`/hooks/${pathParams.hookId}`, 'PATCH', {
pathParams,
body
});
},
async delete (params) {
const pathParams = {
hookId: params.hookId
};
return fetcher(`/hooks/${pathParams.hookId}`, 'DELETE', {
pathParams
});
}
},
integrations: {
vercel: {
projects: {
async find () {
return fetcher(`/integrations/vercel/projects`, 'GET', {});
},
async create (params) {
const body = {
projectId: params.projectId,
name: params.name
};
return fetcher(`/integrations/vercel/projects`, 'POST', {
body
});
}
}
}
},
rateLimits: {
async find (params) {
const query = params ? Object.fromEntries(Object.entries({
scope: params.scope
}).filter(([_, value])=>value !== undefined)) : {};
const hasQuery = Object.keys(query).length > 0;
return fetcher(`/rate-limits`, 'GET', {
...hasQuery ? {
query
} : {}
});
}
},
user: {
async get () {
return fetcher(`/user`, 'GET', {});
},
async getBilling (params) {
const query = params ? Object.fromEntries(Object.entries({
scope: params.scope
}).filter(([_, value])=>value !== undefined)) : {};
const hasQuery = Object.keys(query).length > 0;
return fetcher(`/user/billing`, 'GET', {
...hasQuery ? {
query
} : {}
});
},
async getPlan () {
return fetcher(`/user/plan`, 'GET', {});
},
async getScopes () {
return fetcher(`/user/scopes`, 'GET', {});
}
}
};
}
// Default client for backward compatibility
const v0 = createClient();
exports.createClient = createClient;
exports.parseStreamingResponse = parseStreamingResponse;
exports.v0 = v0;