UNPKG

@lobehub/market-sdk

Version:

LobeHub Market JavaScript SDK

1,444 lines (1,435 loc) 195 kB
// src/admin/MarketAdmin.ts import debug10 from "debug"; // src/core/BaseSDK.ts import debug from "debug"; import { SignJWT } from "jose"; import urlJoin from "url-join"; // src/core/MarketAPIError.ts var normalizeErrorDetails = (errorBody) => { if (!errorBody) return void 0; if (typeof errorBody.error === "object" && errorBody.error !== null) { return errorBody.error; } if (typeof errorBody.error === "string") { return { ...errorBody.code ? { code: errorBody.code } : {}, message: errorBody.error }; } if (typeof errorBody.message === "string") { return { ...errorBody.code ? { code: errorBody.code } : {}, message: errorBody.message }; } return void 0; }; var MarketAPIError = class _MarketAPIError extends Error { constructor(status, statusText, errorBody) { const errorDetails = normalizeErrorDetails(errorBody); const errorCode = errorDetails == null ? void 0 : errorDetails.code; const errorMessage = errorDetails == null ? void 0 : errorDetails.message; const message = errorMessage || statusText; super(message); this.name = "MarketAPIError"; this.status = status; this.code = errorCode; this.errorBody = errorBody; if (Error.captureStackTrace) { Error.captureStackTrace(this, _MarketAPIError); } } /** * Check if this is a specific error code */ isErrorCode(code) { return this.code === code; } /** * Get the full error details from the API response */ getErrorDetails() { return normalizeErrorDetails(this.errorBody); } /** * Convert to a plain object for logging or serialization */ toJSON() { return { code: this.code, errorBody: this.errorBody, message: this.message, name: this.name, status: this.status }; } }; // src/core/version.ts var SDK_VERSION = "0.31.3"; var SDK_USER_AGENT = `LobeHub-Market-SDK/${SDK_VERSION}`; // src/core/BaseSDK.ts var log = debug("lobe-market-sdk:core"); var BaseSDK = class { /** * Creates a new BaseSDK instance * * @param options - Configuration options for the SDK * @param sharedHeaders - Optional shared headers object for reuse across services * @param sharedTokenState - Optional shared token state object for reuse across services */ constructor(options = {}, sharedHeaders, sharedTokenState) { this.baseUrl = options.baseURL || process.env.MARKET_BASE_URL || "https://market.lobehub.com"; this.apiBaseUrl = urlJoin(this.baseUrl, "api"); this.oauthBaseUrl = urlJoin(this.baseUrl, "oauth"); this.defaultLocale = options.defaultLocale || "en-US"; this.initialAccessToken = options.accessToken; this.clientId = options.clientId; this.clientSecret = options.clientSecret; this.sharedTokenState = sharedTokenState; const apiKey = options.apiKey || process.env.MARKET_API_KEY; const userAgent = options.userAgent || SDK_USER_AGENT; if (sharedHeaders) { this.headers = sharedHeaders; log("Using shared headers object"); } else { this.headers = { "Content-Type": "application/json", "User-Agent": userAgent }; log("Created new headers object with User-Agent: %s", userAgent); } if (apiKey) { this.headers.Authorization = `Bearer ${apiKey}`; } if (this.initialAccessToken) { this.headers.Authorization = `Bearer ${this.initialAccessToken}`; } if (options.trustedClientToken) { this.headers["x-lobe-trust-token"] = options.trustedClientToken; log("Trusted client token configured"); } log("BaseSDK instance created: %O", { baseUrl: this.baseUrl, defaultLocale: this.defaultLocale, hasApiKey: !!apiKey, hasInitialAccessToken: !!this.initialAccessToken, hasM2MCredentials: !!this.clientId, hasSharedTokenState: !!this.sharedTokenState, hasTrustedClientToken: !!options.trustedClientToken }); } /** * Sends an HTTP request to the API and handles the response * * @param url - Request URL path (will be appended to baseUrl) * @param options - Fetch API request options * @returns Promise resolving to the parsed JSON response * @throws Error if the request fails */ // eslint-disable-next-line no-undef async request(url, options = {}) { const requestUrl = urlJoin(this.apiBaseUrl, url); log("Sending request: %s", requestUrl); if (!this.initialAccessToken && this.clientId && this.clientSecret) { await this.setM2MAuthToken(); } const mergedHeaders = { ...this.headers, ...options.headers }; log("Request headers: %O", mergedHeaders); const response = await fetch(requestUrl, { ...options, headers: mergedHeaders }); if (!response.ok) { let errorBody; try { errorBody = await response.json(); console.error("Request error: %s", JSON.stringify(errorBody)); } catch (e) { errorBody = void 0; } throw new MarketAPIError(response.status, response.statusText, errorBody); } log("Request successful: %s", url); if (response.status === 204) { return void 0; } return response.json(); } /** * Builds a URL query string from a parameters object * * @param params - Object containing query parameters * @returns Formatted query string (including leading ? if params exist) */ buildQueryString(params) { const query = Object.entries(params).filter(([_, value]) => value !== void 0 && value !== null).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`).join("&"); return query ? `?${query}` : ""; } /** * Sets an authentication token for API requests * * @param token - API authentication token */ setAuthToken(token) { log("Setting authentication token"); this.accessToken = void 0; this.tokenExpiry = void 0; if (this.sharedTokenState) { this.sharedTokenState.accessToken = void 0; this.sharedTokenState.tokenExpiry = void 0; } this.headers.Authorization = `Bearer ${token}`; } /** * Clears the authentication token */ clearAuthToken() { log("Clearing authentication token"); this.accessToken = void 0; this.tokenExpiry = void 0; if (this.sharedTokenState) { this.sharedTokenState.accessToken = void 0; this.sharedTokenState.tokenExpiry = void 0; } delete this.headers.Authorization; } /** * Fetches an M2M access token. * This method is designed for server-side use cases where you need to manage the token lifecycle * (e.g., storing it in a cookie). * * @returns A promise that resolves to an object containing the access token and its expiry time. */ async fetchM2MToken() { if (!this.clientId || !this.clientSecret) { throw new Error("clientId and clientSecret are required to fetch an M2M token."); } log("Fetching M2M token for server-side use"); const assertion = await this.createClientAssertion(); const tokenData = await this.exchangeTokenForServer(assertion); log("M2M token fetched successfully"); return { accessToken: tokenData.access_token, expiresIn: tokenData.expires_in || 3600 }; } async createClientAssertion() { if (!this.clientId || !this.clientSecret) { throw new Error("Missing clientId or clientSecret for M2M authentication."); } const secret = new TextEncoder().encode(this.clientSecret); const tokenEndpoint = `${this.oauthBaseUrl}/token`; return await new SignJWT({}).setProtectedHeader({ alg: "HS256" }).setIssuer(this.clientId).setSubject(this.clientId).setAudience(tokenEndpoint).setJti(crypto.randomUUID()).setIssuedAt().setExpirationTime("5m").sign(secret); } async exchangeToken(clientAssertion) { const tokenData = await this.exchangeTokenForServer(clientAssertion); const expiresInSeconds = tokenData.expires_in || 3600; this.tokenExpiry = Date.now() + (expiresInSeconds - 60) * 1e3; return tokenData.access_token; } async exchangeTokenForServer(clientAssertion) { const tokenEndpoint = urlJoin(this.oauthBaseUrl, "token"); log("Exchanging token at endpoint: %s", tokenEndpoint); const params = new URLSearchParams(); params.append("grant_type", "client_credentials"); params.append( "client_assertion_type", "urn:ietf:params:oauth:client-assertion-type:jwt-bearer" ); params.append("client_assertion", clientAssertion); const response = await fetch(tokenEndpoint, { body: params, headers: { "Content-Type": "application/x-www-form-urlencoded" }, method: "POST" }); const tokenData = await response.json(); if (!response.ok) { throw new Error(`Token exchange failed: ${JSON.stringify(tokenData)}`); } return tokenData; } async setM2MAuthToken() { var _a, _b, _c; const currentAccessToken = ((_a = this.sharedTokenState) == null ? void 0 : _a.accessToken) || this.accessToken; const currentTokenExpiry = ((_b = this.sharedTokenState) == null ? void 0 : _b.tokenExpiry) || this.tokenExpiry; log( "Token check: hasSharedState=%s, hasCurrentToken=%s, tokenExpiry=%d, currentTime=%d", !!this.sharedTokenState, !!currentAccessToken, currentTokenExpiry || 0, Date.now() ); if (currentAccessToken && currentTokenExpiry && Date.now() < currentTokenExpiry) { log( "Using existing M2M access token (expires in %d seconds)", Math.floor((currentTokenExpiry - Date.now()) / 1e3) ); this.headers.Authorization = `Bearer ${currentAccessToken}`; return; } if ((_c = this.sharedTokenState) == null ? void 0 : _c.tokenPromise) { log("Token request already in progress, waiting for completion..."); const token = await this.sharedTokenState.tokenPromise; this.headers.Authorization = `Bearer ${token}`; log("Using token from concurrent request"); return; } log("Fetching new M2M access token..."); const tokenPromise = this.fetchNewToken(); if (this.sharedTokenState) { this.sharedTokenState.tokenPromise = tokenPromise; } try { const newAccessToken = await tokenPromise; this.accessToken = newAccessToken; this.headers.Authorization = `Bearer ${newAccessToken}`; if (this.sharedTokenState) { this.sharedTokenState.accessToken = newAccessToken; this.sharedTokenState.tokenExpiry = this.tokenExpiry; this.sharedTokenState.tokenPromise = void 0; log( "Updated shared token state (expires in %d seconds)", Math.floor(((this.tokenExpiry || 0) - Date.now()) / 1e3) ); } log("Successfully set new M2M access token"); } catch (error) { if (this.sharedTokenState) { this.sharedTokenState.tokenPromise = void 0; } throw error; } } async fetchNewToken() { const assertion = await this.createClientAssertion(); return await this.exchangeToken(assertion); } }; // src/admin/services/AgentService.ts import debug2 from "debug"; var log2 = debug2("lobe-market-sdk:admin:agents"); var AgentService = class extends BaseSDK { /** * Retrieves a list of agents with admin details * * Supports filtering, pagination, and sorting of results. * * @param params - Query parameters for filtering and pagination * @returns Promise resolving to the agent list response with admin details */ async getAgents(params = {}) { log2("Getting agents with params: %O", params); const queryString = this.buildQueryString(params); const url = `/admin/agents${queryString}`; const result = await this.request(url); log2("Retrieved %d agents", result.data.length); return result; } /** * Retrieves agents filtered by status * * @param status - The status to filter by * @returns Promise resolving to agents matching the status */ async getAgentsByStatus(status) { log2("Getting agents by status: %s", status); const result = await this.request( `/admin/agents/by-status/${status}` ); log2("Retrieved %d agents with status %s", result.total, status); return result; } /** * Retrieves agent versions filtered by status * * @param status - The status to filter by * @returns Promise resolving to agent versions matching the status */ async getAgentVersionsByStatus(status) { log2("Getting agent versions by status: %s", status); const result = await this.request( `/admin/agents/versions/by-status/${status}` ); log2("Retrieved %d agent versions with status %s", result.total, status); return result; } /** * Retrieves a single agent with full admin details * * @param id - Agent ID or identifier * @param options - Optional query parameters * @returns Promise resolving to the detailed agent information */ async getAgent(id, options = {}) { log2("Getting agent details (admin): %s", id); const queryString = this.buildQueryString(options); const result = await this.request(`/admin/agents/${id}${queryString}`); log2("Retrieved agent: %s", result.identifier); return result; } /** * Updates agent information * * @param id - Agent ID or identifier * @param data - Agent update data containing fields to update * @returns Promise resolving to the updated agent */ async updateAgent(id, data) { log2("Updating agent: %s, data: %O", id, data); const result = await this.request(`/admin/agents/${id}`, { body: JSON.stringify(data), method: "PUT" }); log2("Agent updated successfully"); return result; } /** * Updates agent publication status * * @param id - Agent ID or identifier * @param status - New status to set * @returns Promise resolving to success response */ async updateAgentStatus(id, status) { log2("Updating agent status: %s to %s", id, status); const result = await this.request( `/admin/agents/${id}/status`, { body: JSON.stringify({ status }), method: "PATCH" } ); log2("Agent status updated successfully"); return result; } /** * Updates agent visibility * * @param id - Agent ID or identifier * @param visibility - New visibility setting * @returns Promise resolving to success response */ async updateAgentVisibility(id, visibility) { log2("Updating agent visibility: %s to %s", id, visibility); const result = await this.request( `/admin/agents/${id}/visibility`, { body: JSON.stringify({ visibility }), method: "PATCH" } ); log2("Agent visibility updated successfully"); return result; } /** * Deletes an agent * * @param id - Agent ID or identifier * @returns Promise resolving to success response */ async deleteAgent(id) { log2("Deleting agent: %s", id); const result = await this.request( `/admin/agents/${id}`, { method: "DELETE" } ); log2("Agent deleted successfully"); return result; } /** * Updates status for multiple agents in a single operation * * @param ids - Array of agent IDs to update * @param status - New status to set for all specified agents * @returns Promise resolving to success response */ async batchUpdateAgentStatus(ids, status) { log2("Batch updating agent status: %O to %s", ids, status); const result = await this.request( "/admin/agents/batch/status", { body: JSON.stringify({ ids, status }), method: "PATCH" } ); log2("Batch agent status update completed: %d updated", result.updatedCount); return result; } /** * Deletes multiple agents in a single operation * * @param ids - Array of agent IDs to delete * @returns Promise resolving to success response */ async batchDeleteAgents(ids) { log2("Batch deleting agents: %O", ids); const result = await this.request( "/admin/agents/batch/delete", { body: JSON.stringify({ ids }), method: "DELETE" } ); log2("Batch agent deletion completed: %d deleted", result.deletedCount); return result; } }; // src/admin/services/AnalysisService.ts import debug3 from "debug"; var log3 = debug3("lobe-market-sdk:admin:analysis"); var AnalysisService = class extends BaseSDK { /** * Retrieves market overview statistics * * Returns comprehensive market statistics including plugin counts, * installation metrics, new plugin trends, and rating averages * with comparison to previous periods. * * @param params - Query parameters for the analysis * @returns Promise resolving to market overview statistics */ async getMarketOverview(params = {}) { const { period = "30d" } = params; log3("Getting market overview statistics for period: %s", period); const searchParams = new URLSearchParams(); if (period) { searchParams.append("period", period); } const url = `/admin/analysis/plugin/overview${searchParams.toString() ? `?${searchParams.toString()}` : ""}`; const result = await this.request(url); log3("Market overview statistics retrieved successfully: %s", result.data); return result.data; } /** * Retrieves market overview statistics for 1 day period * * Convenience method for getting daily market statistics. * * @returns Promise resolving to market overview statistics for 1 day */ async getDailyOverview() { log3("Getting daily market overview"); return this.getMarketOverview({ period: "1d" }); } /** * Retrieves market overview statistics for 7 days period * * Convenience method for getting weekly market statistics. * * @returns Promise resolving to market overview statistics for 7 days */ async getWeeklyOverview() { log3("Getting weekly market overview"); return this.getMarketOverview({ period: "7d" }); } /** * Retrieves market overview statistics for 30 days period * * Convenience method for getting monthly market statistics. * * @returns Promise resolving to market overview statistics for 30 days */ async getMonthlyOverview() { log3("Getting monthly market overview"); return this.getMarketOverview({ period: "30d" }); } /** * Retrieves market overview statistics for current natural month * * Convenience method for getting current month vs previous month statistics. * * @returns Promise resolving to market overview statistics for current month */ async getThisMonthOverview() { log3("Getting this month market overview"); return this.getMarketOverview({ period: "1mo" }); } /** * Retrieves market overview statistics for current quarter * * Convenience method for getting current quarter vs previous quarter statistics. * * @returns Promise resolving to market overview statistics for current quarter */ async getQuarterlyOverview() { log3("Getting quarterly market overview"); return this.getMarketOverview({ period: "3mo" }); } /** * Retrieves market overview statistics for current year * * Convenience method for getting current year vs previous year statistics. * * @returns Promise resolving to market overview statistics for current year */ async getYearlyOverview() { log3("Getting yearly market overview"); return this.getMarketOverview({ period: "1y" }); } /** * Retrieves install failure analysis for plugins within a date range * * Returns detailed analysis of plugin installation failures including failure counts, * failure rates, and most common error messages for each plugin with failures. * * @param params - Query parameters for the failure analysis * @returns Promise resolving to install failure analysis data */ async getInstallFailureAnalysis(params) { const { range, limit = 15 } = params; log3("Getting install failure analysis for range: %o, limit: %d", range, limit); const searchParams = new URLSearchParams(); searchParams.append("range", JSON.stringify(range)); if (limit !== 15) { searchParams.append("limit", limit.toString()); } const url = `/admin/analysis/plugin/install-failure?${searchParams.toString()}`; const result = await this.request(url); log3("Install failure analysis retrieved successfully for %d plugins", result.data.length); return result.data; } /** * Calculates growth rate between current and previous values * * Utility method for calculating percentage growth rates from the statistics. * * @param current - Current period value * @param previous - Previous period value * @returns Growth rate as percentage (e.g., 15.5 for 15.5% growth) */ static calculateGrowthRate(current, previous) { if (previous === 0) return current > 0 ? 100 : 0; return Math.round((current - previous) / previous * 100 * 10) / 10; } /** * Formats market overview statistics with calculated growth rates * * Utility method that enhances the raw statistics with calculated growth rates * for easier consumption in dashboards and reports. * * @param stats - Raw market overview statistics * @returns Enhanced statistics with growth rate calculations */ static formatMarketOverview(stats) { return { ...stats, growth: { devices: this.calculateGrowthRate(stats.devices.count, stats.devices.prevCount), installs: this.calculateGrowthRate(stats.installs.count, stats.installs.prevCount), pluginCalls: this.calculateGrowthRate(stats.pluginCalls.count, stats.pluginCalls.prevCount), plugins: this.calculateGrowthRate(stats.plugins.count, stats.plugins.prevCount) } }; } /** * Retrieves installation trend statistics for a specified date range * * Returns daily installation counts and trends for the specified period * with optional comparison to a previous period. * * @param params - Query parameters including date range and display config * @returns Promise resolving to installation trend statistics */ async getRangeInstalls(params) { const { display, range, prevRange } = params; log3("Getting installation trend statistics for range: %s to %s", range[0], range[1]); const searchParams = new URLSearchParams(); searchParams.append("display", display); searchParams.append("range", range.join(",")); if (prevRange) { searchParams.append("prevRange", prevRange.join(",")); } const url = `/admin/analysis/plugin/range-installs?${searchParams.toString()}`; const result = await this.request(url); log3( "Installation trend statistics retrieved successfully: %d data points", result.data.data.length ); return result.data; } /** * Retrieves plugin growth trend statistics for a specified date range * * Returns daily plugin creation counts and trends for the specified period * with optional comparison to a previous period. * * @param params - Query parameters including date range and display config * @returns Promise resolving to plugin growth trend statistics */ async getRangePlugins(params) { const { display, range, prevRange } = params; log3("Getting plugin growth trend statistics for range: %s to %s", range[0], range[1]); const searchParams = new URLSearchParams(); searchParams.append("display", display); searchParams.append("range", range.join(",")); if (prevRange) { searchParams.append("prevRange", prevRange.join(",")); } const url = `/admin/analysis/plugin/range-plugins?${searchParams.toString()}`; const result = await this.request(url); log3( "Plugin growth trend statistics retrieved successfully: %d data points", result.data.data.length ); return result.data; } /** * Retrieves device growth trend statistics for a specified date range * * Note: This is a system-level statistic that tracks device registrations, * not plugin-specific metrics. It provides daily device registration counts * and trends for the specified period with optional comparison to a previous period. * * @param params - Query parameters including date range and display config * @returns Promise resolving to device growth trend statistics */ async getRangeDevices(params) { const { display, range, prevRange } = params; log3("Getting device growth trend statistics for range: %s to %s", range[0], range[1]); const searchParams = new URLSearchParams(); searchParams.append("display", display); searchParams.append("range", range.join(",")); if (prevRange) { searchParams.append("prevRange", prevRange.join(",")); } const url = `/admin/analysis/system/range-devices?${searchParams.toString()}`; const result = await this.request(url); log3( "Device growth trend statistics retrieved successfully: %d data points", result.data.data.length ); return result.data; } /** * Retrieves plugin call trend statistics for a specified date range * * Returns daily plugin call counts and trends for the specified period * with optional comparison to a previous period. * * @param params - Query parameters including date range and display config * @returns Promise resolving to plugin call trend statistics */ async getRangeCalls(params) { const { display, range, prevRange } = params; log3("Getting plugin call trend statistics for range: %s to %s", range[0], range[1]); const searchParams = new URLSearchParams(); searchParams.append("display", display); searchParams.append("range", range.join(",")); if (prevRange) { searchParams.append("prevRange", prevRange.join(",")); } const url = `/admin/analysis/plugin/range-calls?${searchParams.toString()}`; const result = await this.request(url); log3( "Plugin call trend statistics retrieved successfully: %d data points", result.data.data.length ); return result.data; } /** * Calculates trend growth rate between current and previous period totals * * Utility method for calculating percentage growth rates from range statistics. * * @param stats - Range statistics with sum and prevSum * @returns Growth rate as percentage (e.g., 15.5 for 15.5% growth) */ static calculateTrendGrowthRate(stats) { return this.calculateGrowthRate(stats.sum, stats.prevSum); } /** * Retrieves top plugins sorted by specified criteria within a date range * * Returns list of plugins sorted by the specified criteria (installs or calls) * in descending order for the specified date range. * * @param params - Query parameters including date range, sort criteria, and limit * @returns Promise resolving to list of top plugins */ async getTopPlugins(params) { const { range, sortBy = "installs", limit = 10 } = params; const searchParams = new URLSearchParams(); searchParams.append("range", range.join(",")); searchParams.append("sortBy", sortBy); searchParams.append("limit", limit.toString()); const url = `/admin/analysis/plugin/top-plugins?${searchParams.toString()}`; const result = await this.request(url); return result.data; } }; // src/admin/services/PluginService.ts import debug4 from "debug"; var log4 = debug4("lobe-market-sdk:admin:plugins"); var PluginService = class extends BaseSDK { /** * Batch imports plugin manifests using the dedicated import endpoint * * This method is intended for use with scripts and bulk import operations. * * @param manifests - Array of plugin manifests to import * @param ownerId - Optional owner ID to associate with the imported plugins * @returns Promise resolving to the import results with counts of success, skipped, failed, and a list of failed IDs */ async importPlugins(manifests, ownerId) { log4(`Starting batch plugin import of ${manifests.length} manifests`); if (ownerId) { log4(`Using specified owner ID for import: ${ownerId}`); } const response = await this.request("/admin/plugins/import", { body: JSON.stringify({ manifests, ownerId }), method: "POST" }); log4( `Plugin import completed: ${response.data.success} succeeded, ${response.data.skipped} skipped, ${response.data.failed} failed` ); return response.data; } /** * Imports plugin internationalization (i18n) data * * Allows importing localized content for a specific plugin version. * This method creates or updates localizations for the specified plugin. * * @param params - Plugin i18n import parameters containing identifier, version, and localizations * @returns Promise resolving to the import results with counts of success and failure */ async importPluginI18n(params) { log4( `Starting i18n import for plugin ${params.identifier} v${params.version} with ${params.localizations.length} localizations` ); const response = await this.request("/admin/plugins/import/i18n", { body: JSON.stringify(params), method: "POST" }); log4( `Plugin i18n import completed: ${response.data.success} succeeded, ${response.data.failed} failed, ${response.data.totalLocalizations} total` ); return response.data; } /** * Retrieves a list of plugins with admin details * * Supports filtering, pagination, and sorting of results. * * @param params - Query parameters for filtering and pagination * @returns Promise resolving to the plugin list response with admin details */ async getPlugins(params = {}) { log4("Getting plugins with params: %O", params); const queryString = this.buildQueryString(params); const url = `/admin/plugins${queryString}`; const result = await this.request(url); log4("Retrieved %d plugins", result.data.length); return result; } /** * Retrieves all published plugin identifiers * * Returns a lightweight list of all published plugin identifiers without * full plugin metadata. This is useful for admin operations that need to know * which plugins are currently published and available to users. * * @returns Promise resolving to an array containing identifiers array and last modified time */ async getPublishedIdentifiers() { log4("Getting published plugin identifiers (admin)"); const result = await this.request("/v1/plugins/identifiers"); log4("Retrieved %d published plugin identifiers (admin)", result.length); return result; } /** * Retrieves a single plugin with full admin details * * @param id - Plugin ID or identifier * @returns Promise resolving to the detailed plugin information with version history */ async getPlugin(id) { log4("Getting plugin details (admin): %d", id); const result = await this.request(`/admin/plugins/${id}`); log4("Retrieved plugin with %d versions", result.versions.length); return result; } /** * Retrieves a plugin by its GitHub repository URL * * @param githubUrl - The GitHub repository URL to search for * @returns Promise resolving to the detailed plugin information with version history */ async getPluginByGithubUrl(githubUrl) { log4("Getting plugin by GitHub URL: %s", githubUrl); const queryString = this.buildQueryString({ url: githubUrl }); const result = await this.request( `/admin/plugins/by-github-url${queryString}` ); log4("Retrieved plugin with %d versions", result.versions.length); return result; } /** * Updates plugin information * * @param id - Plugin ID * @param data - Plugin update data containing fields to update * @returns Promise resolving to the updated plugin */ async updatePlugin(id, data) { log4("Updating plugin: %d, data: %O", id, data); const result = await this.request(`/admin/plugins/${id}`, { body: JSON.stringify(data), method: "PUT" }); log4("Plugin updated successfully"); return result; } /** * Updates plugin publication status * * @param id - Plugin ID * @param status - New status to set * @returns Promise resolving to success response */ async updatePluginStatus(id, status) { log4("Updating plugin status: %d to %s", id, status); const result = await this.request( `/admin/plugins/${id}/status`, { body: JSON.stringify({ status }), method: "PATCH" } ); log4("Plugin status updated successfully"); return result; } /** * Deletes a plugin * * @param id - Plugin ID * @returns Promise resolving to success response */ async deletePlugin(id) { log4("Deleting plugin: %d", id); const result = await this.request( `/admin/plugins/${id}`, { method: "DELETE" } ); log4("Plugin deleted successfully"); return result; } /** * Retrieves the version history for a plugin * * @param pluginId - Plugin ID * @returns Promise resolving to an array of plugin versions */ async getPluginVersions(pluginId) { log4("Getting plugin versions: pluginId=%d", pluginId); const result = await this.request(`/admin/plugins/${pluginId}/versions`); log4("Retrieved %d versions", result.length); return result; } /** * Retrieves a specific plugin version * * @param pluginId - Plugin ID * @param versionId - Version ID * @returns Promise resolving to the plugin version details */ async getPluginVersion(pluginId, versionId) { log4("Getting version details: pluginId=%d, versionId=%d", pluginId, versionId); const result = await this.request( `/admin/plugins/${pluginId}/versions/${versionId}` ); log4("Version details retrieved"); return result; } /** * Retrieves all localizations for a specific plugin version * * @param pluginId - Plugin ID or identifier * @param versionId - Version ID * @returns Promise resolving to an array of plugin version localizations */ async getPluginLocalizations(pluginId, versionId) { log4("Getting localizations: pluginId=%s, versionId=%d", pluginId, versionId); const result = await this.request( `/admin/plugins/${pluginId}/versions/${versionId}/localizations` ); log4("Retrieved %d localizations for plugin %s, version %d", result.length, pluginId, versionId); return result; } /** * Creates a new plugin version with all version-specific data * * @param pluginId - Plugin ID * @param data - Version creation data including all version-specific fields * @returns Promise resolving to the created plugin version */ async createPluginVersion(pluginId, data) { log4("Creating new plugin version: pluginId=%d, data: %O", pluginId, data); const result = await this.request(`/admin/plugins/${pluginId}/versions`, { body: JSON.stringify(data), method: "POST" }); log4("Plugin version created successfully: version=%s", data.version); return result; } /** * Creates a new plugin version from a manifest * Extracts version data from the manifest for easier creation * * @param pluginId - Plugin ID * @param manifest - Plugin manifest containing all version data * @param options - Additional options for version creation * @returns Promise resolving to the created plugin version */ async createPluginVersionFromManifest(pluginId, manifest, options = {}) { var _a, _b, _c, _d, _e, _f, _g; log4( "Creating plugin version from manifest: pluginId=%d, version=%s", pluginId, manifest.version ); const versionData = { author: (_a = manifest.author) == null ? void 0 : _a.name, authorUrl: (_b = manifest.author) == null ? void 0 : _b.url, capabilitiesPrompts: (_c = manifest.capabilities) == null ? void 0 : _c.prompts, capabilitiesResources: (_d = manifest.capabilities) == null ? void 0 : _d.resources, capabilitiesTools: (_e = manifest.capabilities) == null ? void 0 : _e.tools, category: manifest.category, description: manifest.description, icon: manifest.icon, isLatest: options.isLatest, isValidated: options.isValidated, name: manifest.name, prompts: manifest.prompts, readme: (_f = manifest.overview) == null ? void 0 : _f.readme, resources: manifest.resources, summary: (_g = manifest.overview) == null ? void 0 : _g.summary, tags: manifest.tags, tools: manifest.tools, version: manifest.version }; return this.createPluginVersion(pluginId, versionData); } /** * Updates a plugin version with comprehensive version-specific data * * @param idOrIdentifier - Plugin ID * @param versionId - Version ID * @param data - Version update data including all version-specific fields * @returns Promise resolving to the updated plugin version */ async updatePluginVersion(idOrIdentifier, versionId, data) { log4( "Updating plugin version: pluginId=%d, versionId=%d, data: %O", idOrIdentifier, versionId, data ); const result = await this.request( `/admin/plugins/${idOrIdentifier}/versions/${versionId}`, { body: JSON.stringify(data), method: "PUT" } ); log4("Plugin version updated successfully"); return result; } /** * Deletes a plugin version * * @param pluginId - Plugin ID * @param versionId - Version ID * @returns Promise resolving to success response */ async deletePluginVersion(pluginId, versionId) { log4("Deleting version: pluginId=%d, versionId=%d", pluginId, versionId); const result = await this.request( `/admin/plugins/${pluginId}/versions/${versionId}`, { method: "DELETE" } ); log4("Plugin version deleted successfully"); return result; } /** * Sets a specific version as the latest version of a plugin * * @param pluginId - Plugin ID * @param versionId - Version ID to set as latest * @returns Promise resolving to success response */ async setPluginVersionAsLatest(pluginId, versionId) { log4("Setting version as latest: pluginId=%d, versionId=%d", pluginId, versionId); const result = await this.request( `/admin/plugins/${pluginId}/versions/${versionId}/latest`, { method: "POST" } ); log4("Version set as latest successfully"); return result; } /** * Updates plugin visibility * * @param id - Plugin ID * @param visibility - New visibility setting * @returns Promise resolving to success response */ async updatePluginVisibility(id, visibility) { log4("Updating plugin visibility: %d to %s", id, visibility); const result = await this.request( `/admin/plugins/${id}/visibility`, { body: JSON.stringify({ visibility }), method: "PATCH" } ); log4("Plugin visibility updated successfully"); return result; } /** * Updates status for multiple plugins in a single operation * * @param ids - Array of plugin IDs to update * @param status - New status to set for all specified plugins * @returns Promise resolving to success response */ async batchUpdatePluginStatus(ids, status) { log4("Batch updating plugin status: %O to %s", ids, status); const result = await this.request( "/admin/plugins/batch/status", { body: JSON.stringify({ ids, status }), method: "PATCH" } ); log4("Batch plugin status update completed"); return result; } /** * Deletes multiple plugins in a single operation * * @param ids - Array of plugin IDs to delete * @returns Promise resolving to success response */ async batchDeletePlugins(ids) { log4("Batch deleting plugins: %O", ids); const result = await this.request( "/admin/plugins/batch/delete", { body: JSON.stringify({ ids }), method: "DELETE" } ); log4("Batch plugin deletion completed"); return result; } /** * Retrieves detailed information about a plugin version including deployment options * * @param pluginId - Plugin ID * @param versionId - Version ID * @returns Promise resolving to version details with deployment options */ async getPluginVersionDetails(pluginId, versionId) { log4( "Getting version details with deployment options: pluginId=%d, versionId=%d", pluginId, versionId ); const result = await this.request( `/admin/plugins/${pluginId}/versions/${versionId}` ); log4("Version details with deployment options retrieved"); return result; } /** * Retrieves deployment options for a specific plugin version * * @param pluginId - Plugin ID * @param versionId - Version ID * @returns Promise resolving to an array of deployment options */ async getDeploymentOptions(pluginId, versionId) { log4("Getting deployment options: pluginId=%d, versionId=%d", pluginId, versionId); const result = await this.request( `/admin/plugins/${pluginId}/versions/${versionId}/deployment-options` ); log4("Retrieved %d deployment options", result.length); return result; } /** * Creates a new deployment option for a plugin version * * @param pluginId - Plugin ID * @param versionId - Version ID * @param data - Deployment option configuration data * @returns Promise resolving to the created deployment option */ async createDeploymentOption(pluginId, versionId, data) { log4("Creating deployment option: pluginId=%d, versionId=%d", pluginId, versionId); const result = await this.request( `/admin/plugins/${pluginId}/versions/${versionId}/deployment-options`, { body: JSON.stringify(data), method: "POST" } ); log4("Deployment option created successfully"); return result; } /** * Updates an existing deployment option * * @param pluginId - Plugin ID * @param versionId - Version ID * @param optionId - Deployment option ID * @param data - Updated deployment option configuration * @returns Promise resolving to the updated deployment option */ async updateDeploymentOption(pluginId, versionId, optionId, data) { log4( "Updating deployment option: pluginId=%d, versionId=%d, optionId=%d", pluginId, versionId, optionId ); const result = await this.request( `/admin/plugins/${pluginId}/versions/${versionId}/deployment-options/${optionId}`, { body: JSON.stringify(data), method: "PUT" } ); log4("Deployment option updated successfully"); return result; } /** * Deletes a deployment option * * @param pluginId - Plugin ID * @param versionId - Version ID * @param optionId - Deployment option ID * @returns Promise resolving to success response */ async deleteDeploymentOption(pluginId, versionId, optionId) { log4( "Deleting deployment option: pluginId=%d, versionId=%d, optionId=%d", pluginId, versionId, optionId ); const result = await this.request( `/admin/plugins/${pluginId}/versions/${versionId}/deployment-options/${optionId}`, { method: "DELETE" } ); log4("Deployment option deleted successfully"); return result; } /** * Retrieves system dependencies for a deployment option * * @param pluginId - Plugin ID * @param versionId - Version ID * @param optionId - Deployment option ID * @returns Promise resolving to an array of system dependencies */ async getDeploymentOptionSystemDependencies(pluginId, versionId, optionId) { log4( "Getting system dependencies: pluginId=%d, versionId=%d, optionId=%d", pluginId, versionId, optionId ); const result = await this.request( `/admin/plugins/${pluginId}/versions/${versionId}/deployment-options/${optionId}/system-dependencies` ); log4("Retrieved %d system dependencies", result.length); return result; } /** * Retrieves verified plugins without summary information * * Returns plugins that are validated but missing summary data. * * @returns Promise resolving to array of plugins with incomplete summary data */ async getVerifiedPluginsWithoutSummary() { log4("Getting verified plugins without summary"); const result = await this.request("/admin/plugins/verified-without-summary"); log4("Retrieved %d verified plugins without summary", result.length); return result; } /** * Retrieves plugins with incomplete internationalization * * Returns plugins where pluginVersionLocalizations has only 1 entry. * * @returns Promise resolving to an array of plugins with incomplete i18n */ async getIncompleteI18nPlugins() { log4("Getting plugins with incomplete i18n"); const result = await this.request("/admin/plugins/incomplete-i18n"); log4("Retrieved %d plugins with incomplete i18n", result.length); return result; } /** * Retrieves unclaimed plugins * * Returns plugins where isClaimed is false, containing only ID and identifier. * * @returns Promise resolving to an array of unclaimed plugins with basic info */ async getUnclaimedPlugins() { log4("Getting unclaimed plugins"); const result = await this.request("/admin/plugins/unclaimed"); log4("Retrieved %d unclaimed plugins", result.length); return result; } }; // src/admin/services/SystemDependencyService.ts import debug5 from "debug"; var log5 = debug5("lobe-market-sdk:admin:dependency"); var SystemDependencyService = class extends BaseSDK { /** * Retrieves all system dependencies * * Gets a list of all defined system dependencies that plugins may require. * * @returns Promise resolving to an array of system dependencies */ async getSystemDependencies() { log5("Getting all system dependencies"); const result = await this.request(`/admin/plugins/dependencies`); log5("Retrieved %d system dependencies", result.length); return result; } /** * Retrieves a specific system dependency by ID * * @param id - System dependency ID * @returns Promise resolving to the system dependency details */ async getSystemDependency(id) { log5("Getting system dependency details: %d", id); const result = await this.request(`/admin/plugins/dependencies/${id}`); log5("System dependency details retrieved"); return result; } /** * Creates a new system dependency * * @param data - System dependency creation data * @returns Promise resolving to the created system dependency */ async createSystemDependency(data) { log5("Creating system dependency: %O", data); const result = await this.request(`/admin/plugins/dependencies`, { body: JSON.stringify(data), method: "POST" }); log5("System dependency created successfully"); return result; } /** * Updates an existing system dependency * * @param id - System dependency ID * @param data - System dependency update data * @returns Promise resolving to the updated system dependency */ async updateSystemDependency(id, data) { log5("Updating system dependency: %d, data: %O", id, data); const result = await this.request(`/admin/plugins/dependencies/${id}`, { body: JSON.stringify(data), method: "PUT" }); log5("System dependency updated successfully"); return result; } /** * Deletes a system dependency * * @param id - System dependency ID * @returns Promise resolving to success response */ async deleteSystemDependency(id) { log5("Deleting system dependency: %d", id); const result = await this.request( `/admin/plugins/dependencies/${id}`, { method: "DELETE" } ); log5("System dependency deleted successfully"); return result; } }; // src/admin/services/SettingsService.ts import debug6 from "debug"; var log6 = debug6("lobe-market-sdk:admin:settings"); var SettingsService = class extends BaseSDK { /** * Retrieves all system settings * * Returns a consolidated map of all settings with typed values * for known setting keys. * * @returns Promise resolving to the settings map */ async getSettings() { return await this.request("/admin/settings"); } /** * Retrieves a specific setting by key * * @param key - Setting key name * @returns Promise resolving to the setting details */ async getSettingByKey(key) { log6("Getting setting: %s", key); const result = await this.request(`/admin/settings/${key}`); log6("Setting retrieved"); return result; } /** * Creates a new system setting * * @param data - Setting creation parameters * @returns Promise resolving to the created setting */ async createSetting(data) { log6("Creating setting: %O", data); const result = await this.request("/admin/settings", { body: JSON.stringify(data), method: "POST" }); log6("Setting created successfully"); return result; } /** * Updates an existing setting * * @param key - Setting key name * @param data - Setting update parameters * @returns Promise resolving to the updated setting */ async updateSetting(key, data) { log6("Updating setting: %s, data: %O", key, data); const result = await this.request(`/admin/settings/${key}`, { body: JSON.stringify(data), method: "PUT" }); log6("Setting updated successfully"); return result; } /** * Deletes a setting * * @param key - Setting key name * @returns Promise resolving to success message */ async deleteSe