Sendbox / vercel-sdk-wrapper.js
RaBU1234's picture
Update vercel-sdk-wrapper.js
1ac7838 verified
// Node.js me EventSource support ke liye polyfill
if (typeof EventSource === 'undefined') {
global.EventSource = require('eventsource');
}
const { EventIterator } = require('event-iterator');
/**
* Vercel Sandbox API-compatible wrapper.
* Yeh class @vercel/sandbox SDK ki nakal karti hai, lekin humare custom API ka istemal karti hai.
*/
class VercelSandboxSDK {
constructor(baseURL = 'http://localhost:3001') {
this.baseURL = baseURL;
}
// Maps to: Sandbox.create({ template: '...' })
static async create(options = {}) {
const sdk = new VercelSandboxSDK();
const response = await fetch(`${sdk.baseURL}/api/sandboxes`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(options)
});
if (!response.ok) throw new Error(`Failed to create sandbox: ${await response.text()}`);
const data = await response.json();
return new SandboxInstance(data.id, sdk.baseURL);
}
// Maps to: Sandbox.findById(id)
static async findById(sandboxId) {
const sdk = new VercelSandboxSDK();
const response = await fetch(`${sdk.baseURL}/api/sandboxes/${sandboxId}`);
if (!response.ok) {
const error = new Error('Sandbox not found');
error.code = 'sandbox_not_found';
throw error;
}
return new SandboxInstance(sandboxId, sdk.baseURL);
}
}
/**
* Ek active sandbox instance ko represent karta hai.
*/
class SandboxInstance {
constructor(sandboxId, baseURL) {
this.id = sandboxId; // Original SDK uses 'id' property
this.baseURL = baseURL;
// `sandbox.fs.write()` ke liye compatibility
this.fs = {
write: this.writeFile.bind(this)
};
}
// Maps to: sandbox.run('npm install')
async run(command) {
const response = await fetch(`${this.baseURL}/api/sandboxes/${this.id}/cmd`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ command })
});
if (!response.ok) throw new Error(`Command failed: ${await response.text()}`);
const data = await response.json();
return new CommandInstance(this.id, data.id, this.baseURL);
}
// Maps to: sandbox.fs.write('path/file.js', 'content')
async writeFile(filePath, content) {
const response = await fetch(`${this.baseURL}/api/sandboxes/${this.id}/fs/write`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ path: filePath, content })
});
if (!response.ok) throw new Error(`File write failed: ${await response.text()}`);
return;
}
// Maps to: sandbox.getURL()
async getURL() {
const response = await fetch(`${this.baseURL}/api/sandboxes/${this.id}/url`);
if (!response.ok) throw new Error('Could not get sandbox URL');
const data = await response.json();
return data.url;
}
}
/**
* Ek command instance ko represent karta hai.
*/
class CommandInstance {
constructor(sandboxId, cmdId, baseURL) {
this.sandboxId = sandboxId;
this.id = cmdId; // Original SDK uses 'id'
this.baseURL = baseURL;
}
// Maps to: cmd.wait()
async wait() {
const response = await fetch(
`${this.baseURL}/api/sandboxes/${this.sandboxId}/cmds/${this.id}`
);
if (!response.ok) return { exitCode: 1, stdout: '', stderr: 'Failed to get command result' };
const data = await response.json();
// Original SDK functions `stdout()` and `stderr()` are async, so we mimic that
return {
exitCode: data.exitCode,
stdout: async () => data.stdout,
stderr: async () => data.stderr,
};
}
// Maps to: cmd.logs() for streaming logs
logs() {
const url = `${this.baseURL}/api/sandboxes/${this.sandboxId}/cmds/${this.id}/logs`;
return new EventIterator(({ push, stop, fail }) => {
const eventSource = new EventSource(url);
eventSource.onmessage = (event) => {
try {
const message = JSON.parse(event.data);
if (message.type === 'stdout' || message.type === 'stderr') {
push({ data: message.data, stream: message.type });
} else if (message.type === 'complete') {
stop();
}
} catch (e) { /* Ignore non-JSON messages */ }
};
eventSource.onerror = () => {
eventSource.close();
stop();
};
return () => eventSource.close();
});
}
}
module.exports = { Sandbox: VercelSandboxSDK };