UNPKG

@vizlook/sdk

Version:
270 lines (268 loc) 8.73 kB
// src/errors.ts var HttpStatusCode = /* @__PURE__ */ ((HttpStatusCode2) => { HttpStatusCode2[HttpStatusCode2["BadRequest"] = 400] = "BadRequest"; HttpStatusCode2[HttpStatusCode2["Unauthorized"] = 401] = "Unauthorized"; HttpStatusCode2[HttpStatusCode2["InsufficientBalance"] = 402] = "InsufficientBalance"; HttpStatusCode2[HttpStatusCode2["TooManyRequests"] = 429] = "TooManyRequests"; HttpStatusCode2[HttpStatusCode2["InternalServerError"] = 500] = "InternalServerError"; return HttpStatusCode2; })(HttpStatusCode || {}); var VizlookError = class extends Error { /** * @param {string} [message] - Error message * @param {number} [statusCode] - HTTP status code * @param {Object} [options] - Error options * @param {string} [options.timestamp] - ISO timestamp string * @param {string} [options.path] - Path that caused the error * @param {Record<string, any>} [options.extra] - Extra information */ constructor(message, statusCode, options) { super(message); this.name = "VizlookError"; this.statusCode = statusCode; this.timestamp = options?.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(); this.path = options?.path; this.extra = options?.extra; } }; // src/vizlook.ts var Vizlook = class { /** * Constructs the Vizlook SDK client. * @param {VizlookOptions} [VizlookOptions] - The options for the Vizlook SDK client. * @param {string} [VizlookOptions.apiKey] - The API key for authentication. * @param {string} [VizlookOptions.baseURL] - The base URL of the Vizlook API. */ constructor({ apiKey, baseURL } = {}) { if (!apiKey) { apiKey = process.env.VIZLOOK_API_KEY; if (!apiKey) { throw new VizlookError( "The API key must be provided as an argument or as an environment variable (VIZLOOK_API_KEY).", 401 /* Unauthorized */ ); } } this.baseURL = baseURL || "https://api.vizlook.com"; this.headers = new Headers({ "x-api-key": apiKey, "Content-Type": "application/json", "User-Agent": "vizlook-js-sdk 1.0.0" }); } /** * Makes a request to the Vizlook API. * @param {string} endpoint - The API endpoint to call. * @param {string} method - The HTTP method to use. * @param {any} [body] - The request body for POST requests. * @param {Record<string, any>} [params] - The query parameters. * @returns {Promise<T>} The response from the API. * @throws {VizlookError} When any API request fails with structured error information. */ async request(endpoint, method, body, params, headers) { let url = this.baseURL + endpoint; if (params && Object.keys(params).length > 0) { const searchParams = new URLSearchParams(); for (const [key, value] of Object.entries(params)) { if (Array.isArray(value)) { for (const item of value) { searchParams.append(key, item); } } else if (value !== void 0) { searchParams.append(key, String(value)); } } url += `?${searchParams.toString()}`; } let combinedHeaders = {}; this.headers.forEach((value, key) => { combinedHeaders[key] = value; }); if (headers) { combinedHeaders = { ...combinedHeaders, ...headers }; } try { const response = await fetch(url, { method, headers: combinedHeaders, body: body ? JSON.stringify(body) : void 0 }); if (!response.ok) { const errorData = await response.json(); const { error = "Unknown error.", ...extra } = errorData; throw new VizlookError(error, response.status, { path: endpoint, extra }); } return await response.json(); } catch (err) { if (err instanceof VizlookError) { throw err; } throw new VizlookError( `An unknown error occurred while making the request. ${err.message || String(err)}`, 500 /* InternalServerError */, { path: endpoint } ); } } /** * Performs a search with a query. * * @param {string} query - The query string. The query is limited to 500 characters. * @param {SearchOptions} [options] - Additional search options * @returns {Promise<SearchResponse>} A list of relevant search results. */ async search(query, options) { const { includeTranscription, includeSummary, ...restOptions } = options || {}; return await this.request("/search", "POST", { query, contentOptions: { includeTranscription, includeSummary }, ...restOptions }); } /** * Answers a query in non-stream mode. * * @param {string} query - The query string. The query is limited to 500 characters. * @param {AnswerOptions} [options] - Additional answer options * @returns {Promise<AnswerResponse>} The answer to the query. */ async answer(query, options) { const body = { query, stream: false, contentOptions: { includeTranscription: options?.includeTranscription } }; return await this.request("/answer", "POST", body); } /** * Answers a query in stream mode. * * @param {string} query - The query string. The query is limited to 500 characters. * @param {AnswerOptions} [options] - Additional answer options * @returns {Promise<AnswerStreamChunk>} The stream of answer chunks. * * Example: * ```ts * for await (const chunk of vizlook.streamAnswer("How to learn python?", { * needTranscription: true, * })) { * console.log(chunk); * } * ``` */ async *streamAnswer(query, options) { const body = { query, stream: true, contentOptions: { includeTranscription: options?.includeTranscription } }; const response = await fetch(this.baseURL + "/answer", { method: "POST", headers: this.headers, body: JSON.stringify(body) }); if (!response.ok) { const errorData = await response.json(); const { error = "Unknown error.", ...extra } = errorData; throw new VizlookError(error, response.status, { path: "/answer", extra }); } const reader = response.body?.getReader(); if (!reader) { throw new VizlookError( "No response body available for streaming.", 500 /* InternalServerError */, { path: "/answer" } ); } 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() || ""; for (const line of lines) { if (!line.startsWith("data: ")) { continue; } const jsonStr = line.replace(/^data:\s*/, "").trim(); if (!jsonStr || jsonStr === "[DONE]") { continue; } let chunkData; try { chunkData = JSON.parse(jsonStr); yield chunkData; } catch (err) { continue; } } } if (buffer.startsWith("data: ")) { const leftover = buffer.replace(/^data:\s*/, "").trim(); if (leftover && leftover !== "[DONE]") { try { const chunkData = JSON.parse(leftover); yield chunkData; } catch (e) { } } } } finally { reader.releaseLock(); } } /** * Retrieves contents of videos based on URLs. * * @param {string | string[]} urls - A URL or array of URLs. Only support YouTube URLs for now, such as https://www.youtube.com/watch?v=xxxxxx * @param {VideoContentsOptions} [options] - Additional options for retrieving video contents. * @returns {Promise<VideoContentsResponse>} A list of video contents for the requested URLs. */ async getVideoContents(urls, options) { if (!Array.isArray(urls)) { urls = [urls]; } const { includeTranscription, includeSummary, ...restOptions } = options || {}; return await this.request("/videos", "POST", { urls, contentOptions: { // The result will include at least one of the transcription and summary; by default, the transcription will be returned. includeTranscription: includeTranscription || !includeSummary, includeSummary }, ...restOptions }); } }; // src/index.ts var index_default = Vizlook; export { HttpStatusCode, Vizlook, VizlookError, index_default as default }; //# sourceMappingURL=index.mjs.map