UNPKG

@lineai/bluebeam-api

Version:

Your unofficial library for Bluebeam API for human and AI developers. Provides TypeScript support, entity classes, and developer-friendly features. Perfect for AI coders, construction professionals, and document management tasks. Includes comprehensive JS

152 lines 11.8 kB
import { createOAuthClient } from './auth'; import { createHttpClient } from './http-client'; import { createSessionsClient } from './sessions'; import { createSessionsMarkupsClient, } from './sessions-markups'; import { createMemoryStorage } from './storage'; export const loadFromEnvironment = () => ({ client_id: process.env.BLUEBEAM_CLIENT_ID, client_secret: process.env.BLUEBEAM_CLIENT_SECRET, access_token: process.env.BLUEBEAM_ACCESS_TOKEN, redirect_uri: process.env.BLUEBEAM_REDIRECT_URI, scope: process.env.BLUEBEAM_SCOPE, base_url: process.env.BLUEBEAM_BASE_URL, }); export const createBluebeamClient = (config = {}) => { // Merge environment variables with provided config const envConfig = loadFromEnvironment(); const mergedConfig = { ...envConfig, ...config, }; // Extract client and OAuth configs const clientConfig = { client_id: mergedConfig.client_id || '', access_token: mergedConfig.access_token, base_url: mergedConfig.base_url, }; const oauthConfig = { client_id: mergedConfig.client_id || '', client_secret: mergedConfig.client_secret || '', redirect_uri: mergedConfig.redirect_uri || '', scope: mergedConfig.scope || '', base_url: mergedConfig.base_url, }; // Validate required OAuth configuration if (!oauthConfig.client_id || !oauthConfig.client_secret) { return Promise.reject(new Error('OAuth configuration is required')); } /** * Internal interceptor that handles automatic token refresh on 401 errors */ class AuthInterceptor { config; auth; storage; autoRefresh; httpClient; constructor(config, auth, storage, autoRefresh) { this.config = config; this.auth = auth; this.storage = storage; this.autoRefresh = autoRefresh; this.httpClient = createHttpClient(config); } async get(endpoint) { return this.executeWithRetry(() => this.httpClient.get(endpoint)); } async post(endpoint, data, isFormData) { return this.executeWithRetry(() => this.httpClient.post(endpoint, data, isFormData)); } async put(endpoint, data) { return this.executeWithRetry(() => this.httpClient.put(endpoint, data)); } async delete(endpoint) { return this.executeWithRetry(() => this.httpClient.delete(endpoint)); } async executeWithRetry(requestFn) { try { return await requestFn(); } catch (error) { // Only retry on 401 if autoRefresh is enabled if (!this.autoRefresh || error.status !== 401) { throw error; } try { // Refresh token await this.auth.refreshAccessToken(); // Get fresh token from storage const tokens = await this.storage.getTokens(); // Create new HTTP client with fresh token this.httpClient = createHttpClient({ ...this.config, access_token: tokens?.access_token }); // Retry request once return await requestFn(); } catch (refreshError) { // Refresh failed, throw original error throw error; } } } } const createClientWithConfig = async (config) => { // Load existing tokens from storage first const storage = mergedConfig.tokenStorage || createMemoryStorage(); const existingTokens = await storage.getTokens(); // Use token from storage if available, otherwise use provided token const configWithToken = { ...config, access_token: existingTokens?.access_token || config.access_token, }; // Create HTTP client first const httpClient = createHttpClient(configWithToken); // Create auth client const auth = await createOAuthClient({ client_id: oauthConfig.client_id, client_secret: oauthConfig.client_secret, redirect_uri: oauthConfig.redirect_uri, scope: oauthConfig.scope, base_url: oauthConfig.base_url, tokenStorage: storage, httpClient, }); // Use interceptor if autoRefresh is enabled (default true) const autoRefresh = mergedConfig.autoRefresh !== false; const clientForApi = autoRefresh ? new AuthInterceptor(configWithToken, auth, storage, autoRefresh) : httpClient; const sessions = createSessionsClient(clientForApi); const markups = createSessionsMarkupsClient(clientForApi); const updateAccessToken = (accessToken) => { const newConfig = { ...config, access_token: accessToken }; return createClientWithConfig(newConfig); }; return { auth, sessions, markups, httpClient, updateAccessToken, }; }; return createClientWithConfig(clientConfig); }; export const createBluebeamClientWithToken = (clientId, accessToken, options) => { const config = { client_id: clientId, access_token: accessToken, ...options, }; const httpClient = createHttpClient(config); const sessions = createSessionsClient(httpClient); const markups = createSessionsMarkupsClient(httpClient); return { sessions, markups, httpClient, }; }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2xpYi9jbGllbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsT0FBTyxFQUFFLGlCQUFpQixFQUFlLE1BQU0sUUFBUSxDQUFDO0FBQ3hELE9BQU8sRUFBRSxnQkFBZ0IsRUFBNEIsTUFBTSxlQUFlLENBQUM7QUFDM0UsT0FBTyxFQUFFLG9CQUFvQixFQUFrQixNQUFNLFlBQVksQ0FBQztBQUNsRSxPQUFPLEVBQ0wsMkJBQTJCLEdBRTVCLE1BQU0sb0JBQW9CLENBQUM7QUFDNUIsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sV0FBVyxDQUFDO0FBMkJoRCxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxHQUFtQixFQUFFLENBQUMsQ0FBQztJQUN4RCxTQUFTLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQkFBa0I7SUFDekMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCO0lBQ2pELFlBQVksRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQjtJQUMvQyxZQUFZLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQkFBcUI7SUFDL0MsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsY0FBYztJQUNqQyxRQUFRLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUI7Q0FDeEMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxDQUFDLE1BQU0sb0JBQW9CLEdBQUcsQ0FDbEMsU0FBeUIsRUFBRSxFQUNGLEVBQUU7SUFDM0IsbURBQW1EO0lBQ25ELE1BQU0sU0FBUyxHQUFHLG1CQUFtQixFQUFFLENBQUM7SUFDeEMsTUFBTSxZQUFZLEdBQUc7UUFDbkIsR0FBRyxTQUFTO1FBQ1osR0FBRyxNQUFNO0tBQ1YsQ0FBQztJQUVGLG1DQUFtQztJQUNuQyxNQUFNLFlBQVksR0FBaUI7UUFDakMsU0FBUyxFQUFFLFlBQVksQ0FBQyxTQUFTLElBQUks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