UNPKG

@infactory/infactory-ts

Version:

Infactory TypeScript SDK for use with Infactory Workshop, MCP Server and API

1,507 lines (1,496 loc) 131 kB
'use strict'; var path = require('path'); var fs = require('fs'); var buffer = require('buffer'); function _interopNamespace(e) { if (e && e.__esModule) return e; var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var path__namespace = /*#__PURE__*/_interopNamespace(path); var fs__namespace = /*#__PURE__*/_interopNamespace(fs); // src/errors/index.ts function _process_error_message(message) { if (message === void 0 || message === null) { message = ""; } else if (typeof message !== "string") { message = JSON.stringify(message); } return message; } var InfactoryAPIError = class _InfactoryAPIError extends Error { constructor(status, code, message, requestId, details) { super(message); this.status = status; this.code = code; this.requestId = requestId; this.details = details; this.name = "InfactoryAPIError"; Object.setPrototypeOf(this, _InfactoryAPIError.prototype); } /** * Convert error to a plain object for serialization */ toJSON() { return { name: this.name, status: this.status, code: this.code, message: this.message, requestId: this.requestId, details: this.details }; } }; var AuthenticationError = class _AuthenticationError extends InfactoryAPIError { constructor(message, requestId, details) { super(401, "authentication_error", message, requestId, details); this.name = "AuthenticationError"; Object.setPrototypeOf(this, _AuthenticationError.prototype); } }; var PermissionError = class _PermissionError extends InfactoryAPIError { constructor(message, requestId, details) { super(403, "permission_denied", message, requestId, details); this.name = "PermissionError"; Object.setPrototypeOf(this, _PermissionError.prototype); } }; var NotFoundError = class _NotFoundError extends InfactoryAPIError { constructor(message, requestId, details) { super(404, "not_found", message, requestId, details); this.name = "NotFoundError"; Object.setPrototypeOf(this, _NotFoundError.prototype); } }; var ValidationError = class _ValidationError extends InfactoryAPIError { constructor(message, requestId, details) { super(422, "validation_error", message, requestId, details); this.name = "ValidationError"; Object.setPrototypeOf(this, _ValidationError.prototype); } }; var ConflictError = class _ConflictError extends InfactoryAPIError { constructor(message, requestId, details) { super(409, "conflict", message, requestId, details); this.name = "ConflictError"; Object.setPrototypeOf(this, _ConflictError.prototype); } }; var RateLimitError = class _RateLimitError extends InfactoryAPIError { constructor(message, requestId, details) { super(429, "rate_limit_exceeded", message, requestId, details); this.name = "RateLimitError"; Object.setPrototypeOf(this, _RateLimitError.prototype); } }; var ServerError = class _ServerError extends InfactoryAPIError { constructor(message, requestId, details) { super(500, "server_error", message, requestId, details); this.name = "ServerError"; Object.setPrototypeOf(this, _ServerError.prototype); } }; var ServiceUnavailableError = class _ServiceUnavailableError extends InfactoryAPIError { constructor(message, requestId, details) { super(503, "service_unavailable", message, requestId, details); this.name = "ServiceUnavailableError"; Object.setPrototypeOf(this, _ServiceUnavailableError.prototype); } }; var NetworkError = class _NetworkError extends InfactoryAPIError { constructor(message, details) { super(0, "network_error", message, void 0, details); this.name = "NetworkError"; Object.setPrototypeOf(this, _NetworkError.prototype); } }; function createErrorFromStatus(status, code = "unknown_error", message, requestId, details) { message = _process_error_message(message); switch (status) { case 400: return new ValidationError(message, requestId, details); case 401: return new AuthenticationError(message, requestId, details); case 403: return new PermissionError(message, requestId, details); case 404: return new NotFoundError(message, requestId, details); case 409: return new ConflictError(message, requestId, details); case 422: return new ValidationError(message, requestId, details); case 429: return new RateLimitError(message, requestId, details); case 503: return new ServiceUnavailableError(message, requestId, details); default: if (status >= 500) { return new ServerError(message, requestId, details); } return new InfactoryAPIError(status, code, message, requestId, details); } } // src/core/http-client.ts var SDK_VERSION = "0.6.4"; var API_BASE_URL = "/api/infactory"; function toSnakeCase(key) { if (key.includes("-")) { return key; } return key.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`); } function toCamelCase(key) { return key.replace( /_([a-z])/g, (_, letter) => letter.toUpperCase() ); } function decamelizeKeys(obj) { if (Array.isArray(obj)) { return obj.map(decamelizeKeys); } else if (obj !== null && typeof obj === "object") { return Object.keys(obj).reduce((result, key) => { const newKey = toSnakeCase(key); const newResult = decamelizeKeys(obj[key]); result[newKey] = newResult; return result; }, {}); } return obj; } function camelizeKeys(obj) { if (Array.isArray(obj)) { return obj.map(camelizeKeys); } else if (obj !== null && typeof obj === "object") { return Object.keys(obj).reduce( (result, key) => { const newKey = key === "_id" ? "id" : toCamelCase(key); result[newKey] = camelizeKeys(obj[key]); return result; }, {} ); } return obj; } var HttpClient = class { /** * Creates a new HTTP client instance. * @param options - Configuration options for the client. */ constructor(options) { this.requestInterceptors = []; this.responseInterceptors = []; this.baseUrl = options.baseUrl.replace(/\/$/, ""); this.apiKey = options.apiKey; this.fetchImpl = options.fetch || globalThis.fetch; this.defaultHeaders = options.defaultHeaders || {}; this.isServer = options.isServer ?? typeof window === "undefined"; this.authIn = options.authIn || "header"; this.defaultHeaders["x-infactory-sdk-version"] = SDK_VERSION; this.addRequestInterceptor((request) => { if (request.params) { request.params = decamelizeKeys(request.params) || {}; } if (request.jsonBody) { request.jsonBody = decamelizeKeys(request.jsonBody); } return request; }); this.addResponseInterceptor( async (response, _request) => { const contentType = response.headers.get("content-type"); if (contentType?.includes("application/json")) { const clonedResponse = response.clone(); const data = await clonedResponse.json(); const camelizedData = camelizeKeys(data); return new Response(JSON.stringify(camelizedData), { status: response.status, statusText: response.statusText, headers: response.headers }); } return response; } ); } /** * Gets the configured API key. * @returns The API key or empty string if not set. */ getApiKey() { return this.apiKey || ""; } /** * Gets the configured base URL. * @returns The base URL. */ getBaseUrl() { return this.baseUrl; } getIsServer() { return this.isServer; } /** * Adds a request interceptor to the chain. * @param interceptor - The request interceptor function. * @returns This HTTP client instance for chaining. */ addRequestInterceptor(interceptor) { this.requestInterceptors.push(interceptor); return this; } /** * Adds a response interceptor to the chain. * @param interceptor - The response interceptor function. * @returns This HTTP client instance for chaining. */ addResponseInterceptor(interceptor) { this.responseInterceptors.push(interceptor); return this; } /** * Executes an HTTP request with the configured settings and interceptors. * @param request - The HTTP request configuration. * @returns A promise resolving to the response with data of type T. */ async request(request) { try { let processedRequest = { ...request }; for (const interceptor of this.requestInterceptors) { processedRequest = await interceptor(processedRequest); } const { url, options } = this.prepareRequest(processedRequest); let response = await this.fetchImpl(url, options); for (const interceptor of this.responseInterceptors) { response = await interceptor(response, processedRequest); } return this.processResponse(response); } catch (error) { return this.handleRequestError(error); } } /** * Executes an HTTP GET request. * @param endpoint - The API endpoint path. * @param params - Optional query parameters. * @param options - Optional fetch options. * @returns A promise resolving to the response with data of type T. */ async get(endpoint, params = {}, options = {}) { return this.request({ url: endpoint, method: "GET", params, ...options }); } /** * Executes an HTTP POST request. * @param endpoint - The API endpoint path. * @param body - Optional request body (will be JSON serialized). * @param params - Optional query parameters. * @param options - Optional fetch options. * @returns A promise resolving to the response with data of type T. */ async post(endpoint, body, options = {}) { return this.request({ url: endpoint, method: "POST", jsonBody: body, ...options }); } /** * Executes an HTTP PUT request. * @param endpoint - The API endpoint path. * @param body - Optional request body (will be JSON serialized). * @param params - Optional query parameters. * @param options - Optional fetch options. * @returns A promise resolving to the response with data of type T. */ async put(endpoint, body, params = {}, options = {}) { return this.request({ url: endpoint, method: "PUT", params, jsonBody: body, ...options }); } /** * Executes an HTTP PATCH request. * @param endpoint - The API endpoint path. * @param body - Optional request body (will be JSON serialized). * @param params - Optional query parameters. * @param options - Optional fetch options. * @returns A promise resolving to the response with data of type T. */ async patch(endpoint, body, options = {}) { return this.request({ url: endpoint, method: "PATCH", jsonBody: body, ...options }); } /** * Executes an HTTP DELETE request. * @param endpoint - The API endpoint path. * @param params - Optional query parameters. * @param options - Optional fetch options. * @returns A promise resolving to the response with data of type T. */ async delete(endpoint, params = {}, options = {}) { return this.request({ url: endpoint, method: "DELETE", params, ...options }); } /** * Uploads a file to the API endpoint. * @param endpoint - The API endpoint path. * @param file - The file to upload. * @param formFields - Additional form fields to include. * @param params - Optional query parameters. * @param options - Optional fetch options. * @returns A promise resolving to the response with data of type T. */ async uploadFile(endpoint, file, formFields = {}, params = {}, options = {}) { const formData = new FormData(); formData.append("file", file); Object.entries(formFields).forEach(([key, value]) => { if (value !== void 0 && value !== null) { formData.append(key, String(value)); } }); return this.request({ url: endpoint, method: "POST", params, body: formData, ...options }); } /** * Downloads a file from the API endpoint. * @param endpoint - The API endpoint path. * @param params - Optional query parameters. * @param defaultFilename - The default filename to use if not specified in headers. * @returns A promise resolving to the response with download info of type T. */ async downloadFile(endpoint, params = {}, defaultFilename = "download.file", options = {}) { try { const { url, options: requestOptions } = this.prepareRequest({ url: endpoint, method: "GET", params, ...options }); if (this.isServer) { return this.request({ url: endpoint, method: "GET", params, ...options }); } const response = await this.fetchImpl(url, requestOptions); if (!response.ok) { throw new Error( `Download failed: ${response.status} ${response.statusText}` ); } const contentDisposition = response.headers.get("content-disposition"); let filename = defaultFilename; if (contentDisposition) { const filenameMatch = contentDisposition.match(/filename="?([^"]+)"?/); if (filenameMatch && filenameMatch[1]) { filename = filenameMatch[1]; } } const blob = await response.blob(); const objectUrl = window.URL.createObjectURL(blob); const link = document.createElement("a"); link.href = objectUrl; link.download = filename; document.body.appendChild(link); link.click(); document.body.removeChild(link); window.URL.revokeObjectURL(objectUrl); return { data: { success: true, filename } }; } catch (error) { return this.handleRequestError(error); } } /** * Creates a streaming request to the API endpoint. * @param endpoint - The API endpoint path. * @param options - The fetch options for the request. * @param signal - Optional abort signal for cancellation. * @returns A promise resolving to a readable stream. */ async createStream(endpoint, options, signal) { let processedRequest = { ...options, url: endpoint }; for (const interceptor of this.requestInterceptors) { processedRequest = await interceptor(processedRequest); } const { url, options: requestOptions } = this.prepareRequest(processedRequest); if (signal) { requestOptions.signal = signal; } const response = await this.fetchImpl(url, requestOptions); if (!response.ok) { let errorData = {}; let errorMessage = ""; try { const contentType = response.headers.get("content-type"); if (contentType && contentType.includes("application/json")) { const errorBody = await response.json(); errorData = errorBody; errorMessage = errorBody.message || errorBody.detail || `API request failed with status: ${response.status}`; } else { const errorBody = await response.text(); errorMessage = `API ${requestOptions.method} request failed ${response.status}: ${errorBody}`; } } catch { errorMessage = `API request failed with status: ${response.status}`; } const requestId = response.headers.get("x-request-id") || void 0; const error = createErrorFromStatus( response.status, errorData.code || "api_error", errorMessage, requestId, errorData.details || errorData ); if (response.status >= 500) { throw error; } throw error; } const stream = response.body; if (!stream) { throw new Error("Response does not contain a readable stream"); } return stream; } /** * Prepares the request URL and options. * @param request - The HTTP request configuration. * @returns The prepared URL and fetch options. */ prepareRequest(request) { const { url: endpoint, params: requestParams, jsonBody, ...options } = request; let params = requestParams; options.method = (options.method || "GET").toUpperCase(); const headers = new Headers(this.defaultHeaders); if (jsonBody) { headers.set("Content-Type", "application/json"); options.body = JSON.stringify(jsonBody); } if (this.authIn === "header") { if (this.apiKey) { headers.set("Authorization", `Bearer ${this.apiKey}`); } } else if (this.authIn === "query") { if (this.apiKey) { params = { ...params || {}, nf_api_key: this.apiKey }; } } else if (this.authIn === "cookie") { if (!this.isServer && typeof document !== "undefined" && document.cookie) { headers.set("Cookie", document.cookie); } else { throw new AuthenticationError( "Cookie-based authentication is only supported in browser environments" ); } } const fullUrl = this.buildUrl(endpoint, params); return { url: fullUrl, options: { ...options, headers, credentials: "include" } }; } /** * Processes an HTTP response. * @param response - The fetch response object. * @returns A promise resolving to the processed API response. */ async processResponse(response) { if (!response.ok) { let errorData = {}; let errorMessage = ""; try { const contentType2 = response.headers.get("content-type"); if (contentType2 && contentType2.includes("application/json")) { const errorBody = await response.json(); errorData = errorBody; errorMessage = errorBody.message || errorBody.detail || `API request failed with status: ${response.status}`; } else { const errorBody = await response.text(); errorMessage = `API request failed with status ${response.status}: ${errorBody}`; } } catch { errorMessage = `API request failed with status: ${response.status}`; } const requestId = response.headers.get("x-request-id") || void 0; const error = createErrorFromStatus( response.status, errorData.code || "api_error", errorMessage, requestId, errorData.details || errorData ); if (response.status < 500) { return { error }; } throw error; } const contentType = response.headers.get("content-type"); if (contentType && contentType.includes("application/json")) { const data = await response.json(); return { data }; } else { const text = await response.text(); return { data: text }; } } /** * Handles errors that occur during the request. * @param error - The error that occurred. * @returns An API response containing the error. */ handleRequestError(error) { if (error instanceof InfactoryAPIError) { throw error; } console.error("Unexpected error in API request:", error); const message = error instanceof Error ? error.message : "Unknown error occurred during API request"; const networkError = new NetworkError(message); return { error: networkError }; } /** * Builds a URL with query parameters. * @param endpoint - The API endpoint path. * @param params - The query parameters to append. * @returns The complete URL string. */ buildUrl(endpoint, params) { const apiUrl = this.isServer ? this.baseUrl : API_BASE_URL; const cleanEndpoint = endpoint.startsWith("/") && apiUrl.endsWith("/") ? endpoint.substring(1) : endpoint; let fullUrl = `${apiUrl}${cleanEndpoint}`; if (params && Object.keys(params).length > 0) { const url = new URL( fullUrl, this.isServer ? void 0 : window.location.origin ); Object.entries(params).forEach(([key, value]) => { if (value !== void 0 && value !== null) { url.searchParams.append(key, String(value)); } }); fullUrl = url.toString(); } return fullUrl; } }; // src/clients/platforms-client.ts var PlatformsClient = class { /** * Creates a new PlatformsClient instance * @param httpClient - The HTTP client to use for API requests */ constructor(httpClient) { this.httpClient = httpClient; } /** * Get a list of all platforms * @returns A promise that resolves to an API response containing an array of platforms */ async list() { return this.httpClient.get("/v1/platforms"); } /** * Get a platform by ID * @param id - The ID of the platform to retrieve * @returns A promise that resolves to an API response containing the platform */ async get(id) { return this.httpClient.get(`/v1/platforms/${id}`); } /** * Create a new platform * @param params - The parameters for creating the platform * @returns A promise that resolves to an API response containing the created platform */ async create(params) { return this.httpClient.post("/v1/platforms", params); } /** * Update a platform * @param id - The ID of the platform to update * @param params - The parameters for updating the platform * @returns A promise that resolves to an API response containing the updated platform */ async update(id, params) { return this.httpClient.patch(`/v1/platforms/${id}`, params); } /** * Delete a platform * @param id - The ID of the platform to delete * @returns A promise that resolves to an API response containing the deleted platform */ async delete(id) { return this.httpClient.delete(`/v1/platforms/${id}`); } }; // src/clients/organizations-client.ts var OrganizationsClient = class { /** * Creates a new OrganizationsClient instance * @param httpClient - The HTTP client to use for API requests */ constructor(httpClient) { this.httpClient = httpClient; } /** * Get a list of all organizations * @returns A promise that resolves to an API response containing an array of organizations */ async list() { return this.httpClient.get("/v1/orgs"); } /** * Get an organization by ID * @param id - The ID of the organization to retrieve * @returns A promise that resolves to an API response containing the organization */ async get(id) { return this.httpClient.get(`/v1/orgs/${id}`); } /** * Get an organization by Clerk ID * @param clerkOrgId - The Clerk ID of the organization to retrieve * @returns A promise that resolves to an API response containing the organization */ async getByClerkId(clerkOrgId) { return this.httpClient.get(`/v1/orgs/clerk/${clerkOrgId}`); } /** * Create a new organization * @param params - The parameters for creating the organization * @returns A promise that resolves to an API response containing the created organization */ async create(params) { return this.httpClient.post("/v1/orgs", params); } /** * Update an organization * @param id - The ID of the organization to update * @param params - The parameters for updating the organization * @returns A promise that resolves to an API response containing the updated organization */ async update(id, params) { return this.httpClient.patch(`/v1/orgs/${id}`, params); } /** * Delete an organization * @param id - The ID of the organization to delete * @returns A promise that resolves to an API response containing the deleted organization */ async delete(id) { return this.httpClient.delete(`/v1/orgs/${id}`); } /** * Move an organization to a new platform * @param id - The ID of the organization to move * @param newPlatformId - The ID of the platform to move the organization to * @returns A promise that resolves to an API response containing the moved organization */ async move(id, newPlatformId) { return this.httpClient.post(`/v1/orgs/${id}/move`, { new_platform_id: newPlatformId }); } }; // src/clients/teams-client.ts var TeamsClient = class { /** * Creates a new TeamsClient instance * @param httpClient - The HTTP client to use for API requests */ constructor(httpClient) { this.httpClient = httpClient; } /** * Get a list of all teams for an organization * @param organizationId - The ID of the organization to get teams for * @returns A promise that resolves to an API response containing an array of teams */ async getTeams(organizationId) { if (!organizationId) { throw new Error("Organization ID is required"); } return this.httpClient.get("/v1/teams", { organization_id: organizationId }); } /** * Get a team by ID * @param id - The ID of the team to retrieve * @returns A promise that resolves to an API response containing the team */ async getTeam(id) { return this.httpClient.get(`/v1/teams/${id}`); } /** * Create a new team * @param params - The parameters for creating the team * @returns A promise that resolves to an API response containing the created team */ async createTeam(params) { if (!params.name || params.name.trim() === "") { throw new Error("Team name is required"); } if (!params.organizationId) { throw new Error("Organization ID is required"); } return this.httpClient.post("/v1/teams", { name: params.name, organization_id: params.organizationId }); } /** * Update a team * @param id - The ID of the team to update * @param params - The parameters for updating the team * @returns A promise that resolves to an API response containing the updated team */ async updateTeam(id, params) { return this.httpClient.patch(`/v1/teams/${id}`, { name: params.name }); } /** * Delete a team * @param id - The ID of the team to delete * @returns A promise that resolves to an API response */ async deleteTeam(id) { return this.httpClient.delete(`/v1/teams/${id}`); } /** * Move a team to a new organization * @param id - The ID of the team to move * @param newOrganizationId - The ID of the organization to move the team to * @returns A promise that resolves to an API response containing the moved team */ async moveTeam(id, newOrganizationId) { return this.httpClient.post(`/v1/teams/${id}/move`, { new_organization_id: newOrganizationId }); } /** * Get all memberships for a team * @param teamId - The ID of the team to get memberships for * @returns A promise that resolves to an API response containing an array of team memberships */ async getTeamMemberships(teamId) { if (!teamId) { throw new Error("Team ID is required"); } return this.httpClient.get( `/v1/team-memberships/team/${teamId}` ); } /** * Create a team membership * @param teamId - The ID of the team * @param userId - The ID of the user * @param role - The role for the membership * @returns A promise that resolves to an API response containing the created team membership */ async createTeamMembership(teamId, userId, role) { if (!teamId) { throw new Error("Team ID is required"); } if (!userId) { throw new Error("User ID is required"); } if (!role) { throw new Error("Role is required"); } return this.httpClient.post("/v1/team-memberships", { teamId, userId, role }); } /** * Update a team membership * @param teamId - The ID of the team * @param userId - The ID of the user * @param role - The new role for the membership * @returns A promise that resolves to an API response containing the updated team membership */ async updateTeamMembership(teamId, userId, role) { if (!teamId) { throw new Error("Team ID is required"); } if (!userId) { throw new Error("User ID is required"); } if (!role) { throw new Error("Role is required"); } return this.httpClient.patch( `/v1/team-memberships/${userId}/${teamId}`, { role } ); } /** * Delete a team membership * @param teamId - The ID of the team * @param userId - The ID of the user * @param permanent - Whether to permanently delete the membership * @returns A promise that resolves to an API response */ async deleteTeamMembership(teamId, userId, permanent = false) { if (!teamId) { throw new Error("Team ID is required"); } if (!userId) { throw new Error("User ID is required"); } return this.httpClient.delete( `/v1/team-memberships/${userId}/${teamId}`, { permanent } ); } }; // src/clients/projects-client.ts var ProjectsClient = class { /** * Creates a new ProjectsClient instance * @param httpClient - The HTTP client to use for API requests */ constructor(httpClient) { this.httpClient = httpClient; } /** * Get a list of all projects * @param teamId - Optional team ID to filter projects by * @param includeDeleted - Whether to include deleted projects * @returns A promise that resolves to an API response containing an array of projects */ async getProjects(teamId, includeDeleted = false) { const params = {}; if (teamId) { params.teamId = teamId; } if (includeDeleted) { params.includeDeleted = includeDeleted; } return this.httpClient.get("/v1/projects", params); } /** * Get projects for a specific team * @param teamId - The ID of the team to get projects for * @param includeDeleted - Whether to include deleted projects * @returns A promise that resolves to an API response containing an array of projects */ async getTeamProjects(teamId, includeDeleted = false) { if (!teamId) { throw new Error("Team ID is required"); } return this.getProjects(teamId, includeDeleted); } /** * Get a project by ID * @param projectId - The ID of the project to retrieve * @param teamId - Optional team ID for access control * @returns A promise that resolves to an API response containing the project */ async getProject(projectId, teamId) { const params = {}; if (teamId) { params.teamId = teamId; } return this.httpClient.get(`/v1/projects/${projectId}`, params); } /** * Create a new project * @param params - The parameters for creating the project * @returns A promise that resolves to an API response containing the created project */ async createProject(params) { if (!params.name || params.name.trim() === "") { throw new Error("Project name is required"); } const payload = { ...params, teamId: params.teamId }; return this.httpClient.post("/v1/projects", payload); } /** * Update a project * @param projectId - The ID of the project to update * @param params - The parameters for updating the project * @returns A promise that resolves to an API response containing the updated project */ async updateProject(projectId, params) { return this.httpClient.patch(`/v1/projects/${projectId}`, params); } /** * Delete a project * @param projectId - The ID of the project to delete * @param permanent - Whether to permanently delete the project * @returns A promise that resolves to an API response */ async deleteProject(projectId, permanent = false) { return this.httpClient.delete(`/v1/projects/${projectId}`, { permanent }); } /** * Move a project to a new team * @param projectId - The ID of the project to move * @param newTeamId - The ID of the team to move the project to * @returns A promise that resolves to an API response containing the moved project */ async moveProject(projectId, newTeamId) { return this.httpClient.post(`/v1/projects/${projectId}/move`, { new_team_id: newTeamId }); } /** * Export a project * @param projectId - The ID of the project to export * @param teamId - The ID of the team the project belongs to * @returns A promise that resolves to an API response containing the export data */ async exportProject(projectId, teamId) { return this.httpClient.downloadFile( `/projects/${projectId}/export`, { teamId }, `project_export_${projectId}.json` ); } /** * Import a project * @param teamId - The ID of the team to import the project into * @param file - The project configuration file to import * @param conflictStrategy - Strategy for handling naming conflicts * @param renameSuffix - Custom suffix to use for renaming projects (when conflict_strategy is 'rename') * @returns A promise that resolves to an API response containing the imported project */ /** * Import a project from a JSON file. * @param teamId - The ID of the team to import the project into * @param fileOrFilePath - Either a File object (browser) or a file path string (Node.js) * @param options - Optional: { conflictStrategy, renameSuffix } * @returns A promise that resolves to an API response containing the imported project */ async importProject(teamId, fileOrFilePath, options) { try { if (typeof fileOrFilePath === "string") { console.info("Importing project using file path..."); const FormData2 = (await import('form-data')).default; const fs2 = await import('fs'); const path2 = await import('path'); const form = new FormData2(); form.append("file", fs2.createReadStream(fileOrFilePath), { filename: path2.basename(fileOrFilePath), contentType: "application/json" }); form.append("team_id", teamId); form.append("conflict_strategy", options?.conflictStrategy || "rename"); if (options?.renameSuffix) { form.append("rename_suffix", options.renameSuffix); } const fetch2 = (await import('node-fetch')).default; const headers = form.getHeaders(); const apiKey = this.httpClient.getApiKey(); if (apiKey) { headers["Authorization"] = `Bearer ${apiKey}`; } const baseURL = this.httpClient.getBaseUrl(); const url = `${baseURL}/projects/import`; const response = await fetch2(url, { method: "POST", body: form, headers }); console.info("Response status:", response.status); const responseText = await response.text(); console.info("Response body:", responseText); let responseData; try { responseData = JSON.parse(responseText); } catch (e) { console.error("Error parsing response JSON:", e); responseData = { error: "Invalid JSON response" }; } if (response.ok) { console.info("Import successful!"); return { data: responseData }; } else { console.error("Import failed with status:", response.status); return { error: responseData }; } } console.info("Importing project using browser File..."); const formData = new FormData(); formData.append("file", fileOrFilePath); formData.append("team_id", teamId); formData.append( "conflict_strategy", options?.conflictStrategy || "rename" ); if (options?.renameSuffix) { formData.append("rename_suffix", options.renameSuffix); } return await this.httpClient.request({ url: "/projects/import", method: "POST", body: formData }); } catch (error) { console.error("Error importing project:", error); throw error; } } /** * Validate a project import file without importing it * @param file - The project configuration file to validate * @returns A promise that resolves to an API response containing validation info */ async validateImport(file) { try { const formData = new FormData(); formData.append("file", file); return await this.httpClient.request({ url: "/projects/validate-import", method: "POST", body: formData }); } catch (error) { console.error("Error validating import:", error); throw error; } } /** * Get coverage information for a project's query programs * @param projectId - The ID of the project * @returns A promise that resolves to an API response containing coverage information */ async getCoverage(projectId) { return await this.httpClient.get( `/v1/coverage/${projectId}` ); } }; // src/clients/users-client.ts var UsersClient = class { /** * Creates a new UsersClient instance * @param httpClient - The HTTP client to use for API requests */ constructor(httpClient) { this.httpClient = httpClient; } /** * Get a list of all users * @param organizationId - Optional organization ID to filter users * @returns A promise that resolves to an API response containing an array of users */ async getUsers(organizationId) { const params = {}; if (organizationId) { params.organization_id = organizationId; } return this.httpClient.get("/v1/users", params); } /** * Get a user by ID * @param userId - The ID of the user to retrieve * @returns A promise that resolves to an API response containing the user */ async getUser(userId) { return this.httpClient.get(`/v1/users/${userId}`); } /** * Get the current authenticated user * @returns A promise that resolves to an API response containing the current user with teams and organization */ async getCurrentUser() { return this.httpClient.get( "/v1/authentication/me" ); } /** * Create a new user * @param params - Parameters for creating the user * @returns A promise that resolves to an API response containing the created user */ async createUser(params) { return this.httpClient.post("/v1/users", { email: params.email, name: params.name, organization_id: params.organizationId, role: params.role }); } /** * Update a user * @param userId - The ID of the user to update * @param params - Parameters for updating the user * @returns A promise that resolves to an API response containing the updated user */ async updateUser(userId, params) { return this.httpClient.patch(`/v1/users/${userId}`, { email: params.email, name: params.name, role: params.role }); } /** * Delete a user * @param userId - The ID of the user to delete * @returns A promise that resolves to an API response containing the deleted user */ async deleteUser(userId) { return this.httpClient.delete(`/v1/users/${userId}`); } /** * Move a user to a new organization * @param userId - The ID of the user to move * @param newOrganizationId - The ID of the organization to move the user to * @returns A promise that resolves to an API response containing the moved user */ async moveUser(userId, newOrganizationId) { return this.httpClient.post(`/v1/users/${userId}/move`, { new_organization_id: newOrganizationId }); } /** * Get or create a user, team, and organization based on Clerk IDs * @param params - Parameters for getting or creating the user, team, and organization * @returns A promise that resolves to an API response containing the user */ async getOrCreateUserTeamOrganization(params) { return this.httpClient.post( "/v1/users/get_or_create_user_team_organization", { body: params } ); } /** * Get teams with organizations and projects for a user * @param params - Parameters to identify the user * @returns A promise that resolves to an API response containing teams with organizations and projects */ async getTeamsWithOrganizationsAndProjects(params) { return this.httpClient.get( `/v1/users/get_teams_with_organizations_and_projects`, params ); } /** * Get roles for a user * @param userId - The ID of the user * @returns A promise that resolves to an API response containing user roles */ async getUserRoles(userId) { return this.httpClient.get(`/v1/users/${userId}/roles`); } /** * Add a role to a user * @param userId - The ID of the user * @param roleId - The ID of the role to add * @returns A promise that resolves to an API response */ async addUserRole(userId, roleId) { return this.httpClient.post(`/v1/users/${userId}/roles/${roleId}/`, { body: { roleId } }); } /** * Remove a role from a user * @param userId - The ID of the user * @param roleId - The ID of the role to remove * @returns A promise that resolves to an API response */ async removeUserRole(userId, roleId) { return this.httpClient.delete(`/v1/users/${userId}/roles/${roleId}/`); } }; // src/clients/queryprograms-client.ts var QueryProgramsClient = class { /** * Creates a new QueryProgramsClient instance * @param httpClient - The HTTP client to use for API requests */ constructor(httpClient) { this.httpClient = httpClient; } /** * List all query programs for a project * @param params - Optional pagination parameters * @returns A promise that resolves to an API response containing an array of query programs */ async listQueryPrograms(params) { return await this.httpClient.get( `/v1/queryprograms`, params ); } /** * Get a specific query program by ID * @param id - The ID of the query program to retrieve * @returns A promise that resolves to an API response containing the query program */ async getQueryProgram(id) { return await this.httpClient.get(`/v1/queryprograms/${id}`); } /** * Create a new query program * @param params - Parameters for creating the query program * @returns A promise that resolves to an API response containing the created query program */ async createQueryProgram(params) { return await this.httpClient.post( "/v1/queryprograms", params ); } /** * Update an existing query program * @param id - The ID of the query program to update * @param params - Parameters for updating the query program * @returns A promise that resolves to an API response containing the updated query program */ async updateQueryProgram(id, params) { return await this.httpClient.patch( `/v1/queryprograms/${id}`, params ); } /** * Delete a query program * @param id - The ID of the query program to delete * @param permanent - Whether to permanently delete the query program (default: false) * @returns A promise that resolves to an API response with the deletion result */ async deleteQueryProgram(id, permanent = false) { return await this.httpClient.delete(`/v1/queryprograms/${id}`, { permanent }); } // /** // * Execute a query program synchronously (replacement for executeQueryProgram) // * @param queryProgramId - The ID of the query program to execute // * @param inputData - Optional input data for the query program (currently unused) // * @returns A promise that resolves to an API response containing the query result // */ // async executeQueryProgram( // queryProgramId: string, // // eslint-disable-next-line @typescript-eslint/no-unused-vars // inputData?: Record<string, any>, // ): Promise<ApiResponse<QueryResponse> | ReadableStream<any>> { // // This method now uses evaluateQueryProgramSync internally // // since the original executeQueryProgram endpoint is returning 404 errors // // Note: inputData is currently not used because evaluateQueryProgramSync doesn't support it // // We need to extract the project ID from the query program ID // // For now, we'll use the queryProgramId for both parameters // // This should be updated when the proper project ID is available // return await this.evaluateQueryProgramSync(queryProgramId, queryProgramId); // } // /** // * Execute a query program with streaming response // * @param id - The ID of the query program to execute // * @param params - Optional parameters for streaming execution // * @returns A promise that resolves to a readable stream of execution events // */ // async executeQueryProgramStream( // id: string, // params?: Record<string, any>, // ): Promise<ReadableStream<Uint8Array>> { // return await this.httpClient.createStream( // `/v1/queryprograms/${id}/execute`, // { // url: `/v1/queryprograms/${id}/execute`, // method: 'POST', // jsonBody: params || {}, // headers: { // Accept: 'text/event-stream', // }, // }, // ); // } /** * Validate a query program without executing it * @param params - Parameters of the query program to validate * @returns A promise that resolves to an API response with validation results */ async validateQueryProgram(params) { const filteredParams = Object.fromEntries( Object.entries(params).filter(([_, value]) => value != null) ); return await this.httpClient.post( "/v1/queryprograms/validate", filteredParams ); } /** * Get execution history for a query program * @param id - The ID of the query program * @param params - Optional pagination and date filter parameters * @returns A promise that resolves to an API response containing the execution history */ async getQueryProgramHistory(id, params) { return await this.httpClient.get( `/v1/queryprograms/${id}/history`, { params } ); } /** * Create a model from a query program * @param queryProgramId - The ID of the query program * @returns A promise that resolves to an API response containing the updated query program */ async createQueryProgramModel(queryProgramId) { return await this.httpClient.post( `/v1/queryprograms/${queryProgramId}/create-model` ); } /** * Publish a query program, making it available for API endpoints * @param id - The ID of the query program to publish * @param groupSlots - Whether to group slots in the published query program * @returns A promise that resolves to an API response containing the published query program */ async publishQueryProgram(id, groupSlots = false) { return await this.httpClient.patch( `/v1/queryprograms/${id}/publish`, { group_slots: groupSlots } ); } /** * Unpublish a query program * @param id - The ID of the query program to unpublish * @returns A promise that resolves to an API response containing the unpublished query program */ async unpublishQueryProgram(id) { return await this.httpClient.patch( `/v1/queryprograms/${id}/unpublish` ); } /** * Evaluate a query program with streaming response * @param projectId - The ID of the project * @param queryprogramId - The ID of the query program to evaluate * @returns A promise that resolves to a readable stream of evaluation events */ async evaluateQueryProgram(projectId, queryprogramId, params) { params = params || {}; let url = "/v1/run/queryprogram"; const query_params = new URLSearchParams(params).toString(); if (query_params) { url = `${url}?${query_params}`; } return await this.httpClient.createStream(url, { url, method: "POST", jsonBody: { projectId, queryprogramId, stream: true // Explicitly set streaming to true }, headers: { Accept: "text/event-stream" } }); } /** * Evaluate a query program with non-streaming response * @param projectId - The ID of the project * @param queryprogramId - The ID of the query program to evaluate * @returns A promise that resolves to an API response containing the evaluation result */ async evaluateQueryProgramSync(projectId, queryprogramId, params) { params = params || {}; let url = "/v1/run/queryprogram"; const query_params = new URLSearchParams(params).toString(); if (query_params) { url = `${url}?${query_params}`; } return await this.httpClient.post( url, { projectId, queryprogramId, stream: false // Explicitly set streaming to false }, params ); } /** * Analyze a query program to get its graph representation * @param projectId - The ID of the project * @param queryprogramId - The ID of the query program to analyze * @returns A promise that resolves to an API response containing the graph representation */ async analyzeQueryProgram(projectId, queryprogramId) { return await this.httpClient.post( "/v1/actions/evaluate/queryprogram/graph", { projectId, queryprogramId } ); } /** * Get readable answer for query response * @param queryResponseId - The ID of the query response * @param query - The query to generate a readable answer for * @returns A promise that resolves to a readable stream of the answer */ async getReadableAnswerForQueryResponse(queryResponseId, query) { return await this.httpClient.createStream( `/v1/actions/generate/readableanswer-to-queryresponse/${queryResponseId}`, { url: `/v1/actions/generate/readableanswer