import ApplicationClient from './ApplicationClient'; import ChargebeeClient from './ChargebeeClient'; import DeviceClient from './DeviceClient'; import { BadRequestError, ConflictError, InternalServerError, UnauthorizedError, NotFoundError, ForbiddenError, } from './errors'; import FileUploadClient from './FileUploadClient'; import PlaylistClient from './PlaylistClient'; import PresentationClient from './PresentationClient'; import ThemeClient from './ThemeClient'; import UserClient from './UserClient'; import FolderClient from './FolderClient'; import DomainClient from './DomainClient'; import ResourceClient from './ResourceClient'; import PlaybackReportClient from './PlaybackReportClient'; import FontClient from './FontClient'; import AccountClient from './AccountClient'; import PaymentClient from './PaymentClient'; import InvoiceClient from './InvoiceClient'; import AdminClient from './AdminClient'; import AnalyticsClient from './AnalyticsClient'; import CatalogClient from './CatalogClient'; import ConnectionClient from './ConnectionClient'; import LocationClient from './LocationClient'; import ConnectorClient from './ConnectorClient'; import LibraryClient from './LibraryClient'; import StripeClient from './StripeClient'; const getApiClientError = async (response: Response) => { const text = (await response.text()) || response.statusText; switch (response.status) { case 400: return new BadRequestError(text); case 401: return new UnauthorizedError(text); case 403: return new ForbiddenError(text); case 404: return new NotFoundError(text); case 409: return new ConflictError(text); case 500: return new InternalServerError(text); default: return new BadRequestError(text); } }; export type ApiClientFetcher = ( input: RequestInfo, init?: RequestInit | undefined, ) => Promise; export interface ApiClientOptions { /** The base url for the api client. */ baseUrl: string; /** The (optional) access token to use when making requests. */ accessToken?: string; /** The (optional) access token getter. */ getAccessToken?: (opts: RequestOptions) => Promise; /** Set to true to use the Authorization: Bearer scheme */ isBearerToken?: boolean; /** A function to handle the underlying fetch request */ fetcher: ApiClientFetcher; } export type MethodTypes = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'; export interface RequestOptions { method: MethodTypes; url: string; body?: RequestBody; responseType?: 'blob' | 'arraybuffer' | 'json' | 'text'; } export default class ApiClient implements FolderClient, ApplicationClient, ChargebeeClient, DeviceClient, FileUploadClient, FontClient, PresentationClient, PlaylistClient, ThemeClient, UserClient, DomainClient, ResourceClient, PlaybackReportClient, AdminClient, CatalogClient, StripeClient { // Folders getDevicesFolder = FolderClient.prototype.getDevicesFolder; getV5DevicesFolder = FolderClient.prototype.getV5DevicesFolder; getLibraryFolder = FolderClient.prototype.getLibraryFolder; getFolder = FolderClient.prototype.getFolder; createFolder = FolderClient.prototype.createFolder; updateFolder = FolderClient.prototype.updateFolder; deleteFolder = FolderClient.prototype.deleteFolder; moveFolderToFolder = FolderClient.prototype.moveFolderToFolder; copyFolder = FolderClient.prototype.copyFolder; getV4DevicesFolder = FolderClient.prototype.getV4DevicesFolder; getV4LibraryFolder = FolderClient.prototype.getV4LibraryFolder; getV4LibraryLiteFolder = FolderClient.prototype.getV4LibraryLiteFolder; // Devices getDevices = DeviceClient.prototype.getDevices; getV4ReportingDevices = DeviceClient.prototype.getV4ReportingDevices; getV5Devices = DeviceClient.prototype.getV5Devices; getDevice = DeviceClient.prototype.getDevice; publishDevice = DeviceClient.prototype.publishDevice; registerDevice = DeviceClient.prototype.registerDevice; updateDevice = DeviceClient.prototype.updateDevice; updateV5Device = DeviceClient.prototype.updateV5Device; restartDevice = DeviceClient.prototype.restartDevice; rebootDevice = DeviceClient.prototype.rebootDevice; getSYBSoundZone = DeviceClient.prototype.getSYBSoundZone; generateSYBPairingCode = DeviceClient.prototype.generateSYBPairingCode; moveDeviceToFolder = DeviceClient.prototype.moveDeviceToFolder; getAffectedDevices = DeviceClient.prototype.getAffectedDevices; unregisterDevice = DeviceClient.prototype.unregisterDevice; getRecentDeviceErrors = DeviceClient.prototype.getRecentDeviceErrors; batchDeviceSettings = DeviceClient.prototype.batchDeviceSettings; getBatchDeviceStatus = DeviceClient.prototype.getBatchDeviceStatus; // Device getV5Device = DeviceClient.prototype.getV5Device; deviceHeartbeat = DeviceClient.prototype.deviceHeartbeat; getDevicePublishedContent = DeviceClient.prototype.getDevicePublishedContent; getDeviceAdContent = DeviceClient.prototype.getDeviceAdContent; devicePubnubAuth = DeviceClient.prototype.devicePubnubAuth; enableMultiTimezone = DeviceClient.prototype.enableMultiTimezone; createDeviceCharge = DeviceClient.prototype.createDeviceCharge; updateDeviceCharge = DeviceClient.prototype.updateDeviceCharge; // Device Services enableDeviceService = DeviceClient.prototype.enableDeviceService; disableDeviceService = DeviceClient.prototype.disableDeviceService; // Device AI getDeviceAISettings = DeviceClient.prototype.getDeviceAISettings; setDeviceAISettings = DeviceClient.prototype.setDeviceAISettings; setDeviceAILicenseKey = DeviceClient.prototype.setDeviceAILicenseKey; startDeviceAIVideo = DeviceClient.prototype.startDeviceAIVideo; stopDeviceAIVideo = DeviceClient.prototype.stopDeviceAIVideo; // Device Perchview getDevicePerchviewSettings = DeviceClient.prototype.getDevicePerchviewSettings; getOwnPerchviewSettings = DeviceClient.prototype.getOwnPerchviewSettings; setDevicePerchviewSettings = DeviceClient.prototype.setDevicePerchviewSettings; updateDevicePerchviewSettings = DeviceClient.prototype.updateDevicePerchviewSettings; // Device V2 Perchview getDeviceV2PerchviewSettings = DeviceClient.prototype.getDeviceV2PerchviewSettings; setDeviceV2PerchviewSettings = DeviceClient.prototype.setDeviceV2PerchviewSettings; updateDeviceV2PerchviewSettings = DeviceClient.prototype.updateDeviceV2PerchviewSettings; // Device Payment Terminal getDeviceTerminalStatus = DeviceClient.prototype.getDeviceTerminalStatus; getDeviceTerminal = DeviceClient.prototype.getDeviceTerminal; deleteDeviceTerminal = DeviceClient.prototype.deleteDeviceTerminal; // Users getProfile = UserClient.prototype.getProfile; updateProfile = UserClient.prototype.updateProfile; masquerade = UserClient.prototype.masquerade; unsubscribe = UserClient.prototype.unsubscribe; getUserStatus = UserClient.prototype.getUserStatus; setRemoteAssistance = UserClient.prototype.setRemoteAssistance; remoteAssist = UserClient.prototype.remoteAssist; changeEmail = UserClient.prototype.changeEmail; getOnboardingStatus = UserClient.prototype.getOnboardingStatus; updateOnboardingStatus = UserClient.prototype.updateOnboardingStatus; getProfileDeviceLicenses = UserClient.prototype.getProfileDeviceLicenses; getBillingAccounts = UserClient.prototype.getBillingAccounts; createBillingPortalSession = UserClient.prototype.createBillingPortalSession; // Presentations getPresentations = PresentationClient.prototype.getPresentations; deletePresentation = PresentationClient.prototype.deletePresentation; updatePresentation = PresentationClient.prototype.updatePresentation; createPresentation = PresentationClient.prototype.createPresentation; movePresentationToFolder = PresentationClient.prototype.movePresentationToFolder; copyPresentation = PresentationClient.prototype.copyPresentation; getPresentationsList = PresentationClient.prototype.getPresentationsList; // Playlists getPlaylists = PlaylistClient.prototype.getPlaylists; createPlaylist = PlaylistClient.prototype.createPlaylist; updatePlaylist = PlaylistClient.prototype.updatePlaylist; deletePlaylist = PlaylistClient.prototype.deletePlaylist; movePlaylistToFolder = PlaylistClient.prototype.movePlaylistToFolder; getPlaylistPlaybackContent = PlaylistClient.prototype.getPlaylistPlaybackContent; copyPlaylist = PlaylistClient.prototype.copyPlaylist; // File uploads uploadFile = FileUploadClient.prototype.uploadFile; // Fonts getFonts = FontClient.prototype.getFonts; createFont = FontClient.prototype.createFont; // Applications getApplications = ApplicationClient.prototype.getApplications; createApplication = ApplicationClient.prototype.createApplication; createApplicationVersion = ApplicationClient.prototype.createApplicationVersion; updateApplication = ApplicationClient.prototype.updateApplication; getApplicationVersions = ApplicationClient.prototype.getApplicationVersions; getMarketPlaceApplications = ApplicationClient.prototype.getMarketPlaceApplications; sendMarketPlaceInquiry = ApplicationClient.prototype.sendMarketPlaceInquiry; getProductList = ApplicationClient.prototype.getProductList; getEXLicenses = ApplicationClient.prototype.getEXLicenses; purchaseProduct = ApplicationClient.prototype.purchaseProduct; generateApplicationVersionToken = ApplicationClient.prototype.generateApplicationVersionToken; // Themes getThemes = ThemeClient.prototype.getThemes; updateTheme = ThemeClient.prototype.updateTheme; createTheme = ThemeClient.prototype.createTheme; deleteTheme = ThemeClient.prototype.deleteTheme; // Domain getDomain = DomainClient.prototype.getDomain; updateDomain = DomainClient.prototype.updateDomain; inviteToDomain = DomainClient.prototype.inviteToDomain; setProfileDomainRole = DomainClient.prototype.setProfileDomainRole; // Enterprise Invite getDomainUsers = DomainClient.prototype.getDomainUsers; getPendingDomainUsers = DomainClient.prototype.getPendingDomainUsers; validateEmail = DomainClient.prototype.validateEmail; inviteDomainUser = DomainClient.prototype.inviteDomainUser; resendDomainInvite = DomainClient.prototype.resendDomainInvite; cancelDomainInvite = DomainClient.prototype.cancelDomainInvite; acceptDomainInvite = DomainClient.prototype.acceptDomainInvite; updateDomainUser = DomainClient.prototype.updateDomainUser; updateDomainInvite = DomainClient.prototype.updateDomainInvite; // Resources createResourceACL = ResourceClient.prototype.createResourceACL; deleteResourceACL = ResourceClient.prototype.deleteResourceACL; listResourceACLs = ResourceClient.prototype.listResourceACLs; createResourceACLV5 = ResourceClient.prototype.createResourceACLV5; updateResourceACLV5 = ResourceClient.prototype.updateResourceACLV5; deleteResourceACLV5 = ResourceClient.prototype.deleteResourceACLV5; // Playback Report getPlaybackReports = PlaybackReportClient.prototype.getPlaybackReports; generatePlaybackReport = PlaybackReportClient.prototype.generatePlaybackReport; // Chargebee generateChargebeePortal = ChargebeeClient.prototype.generateChargebeePortal; // Invoices chargeInvoice = InvoiceClient.prototype.chargeInvoice; getInvoices = InvoiceClient.prototype.getInvoices; downloadInvoices = InvoiceClient.prototype.downloadInvoice; toggleInvoiceEmail = InvoiceClient.prototype.toggleInvoiceEmail; getOutstandingBalance = InvoiceClient.prototype.getOutstandingBalance; // Account getAddress = AccountClient.prototype.getAddress; getCountries = AccountClient.prototype.getCountries; updateAddress = AccountClient.prototype.updateAddress; //Payments captureContext = PaymentClient.prototype.captureContext; getPaymentMethods = PaymentClient.prototype.getPaymentMethods; addPaymentMethod = PaymentClient.prototype.addPaymentMethod; // Support app getProfileDevices = AdminClient.prototype.getProfileDevices; getProfilesByRecentDevices = AdminClient.prototype.getProfilesByRecentDevices; disableDevice = AdminClient.prototype.disableDevice; enableDevice = AdminClient.prototype.enableDevice; getDeviceByMacAddress = AdminClient.prototype.getDeviceByMacAddress; updateAdminDevice = AdminClient.prototype.updateAdminDevice; // Analytics getAnalytics = AnalyticsClient.prototype.getAnalytics; getContentEngagement = AnalyticsClient.prototype.getContentEngagement; getTrafficAwareness = AnalyticsClient.prototype.getTrafficAwareness; getProductEngagementExport = AnalyticsClient.prototype.getProductEngagementExport; getContentEngagementClickExport = AnalyticsClient.prototype.getContentEngagementClickExport; getTrafficAwarenessExport = AnalyticsClient.prototype.getTrafficAwarenessExport; getContentEngagementExport = AnalyticsClient.prototype.getContentEngagementExport; getAnalyticsLocations = AnalyticsClient.prototype.getLocations; getContentDetail = AnalyticsClient.prototype.getContentDetail; // Catalogs getCatalogs = CatalogClient.prototype.getCatalogs; createCatalog = CatalogClient.prototype.createCatalog; updateCatalog = CatalogClient.prototype.updateCatalog; deleteCatalog = CatalogClient.prototype.deleteCatalog; // Products getProducts = CatalogClient.prototype.getProducts; // Catalog locations getCatalogLocations = CatalogClient.prototype.getCatalogLocations; // Connections getConnections = ConnectionClient.prototype.getConnections; createConnection = ConnectionClient.prototype.createConnection; updateConnection = ConnectionClient.prototype.updateConnection; deleteConnection = ConnectionClient.prototype.deleteConnection; // Connectors getConnectors = ConnectorClient.prototype.getConnectors; // Locations getLocations = LocationClient.prototype.getLocations; createLocation = LocationClient.prototype.createLocation; editLocation = LocationClient.prototype.editLocation; deleleteLocation = LocationClient.prototype.deleteLocation; getPendingLocations = LocationClient.prototype.getPendingLocations; inviteUserToLocation = LocationClient.prototype.inviteUserToLocation; removeUserFromLocation = LocationClient.prototype.removeUserFromLocation; moveDevicesToAnotherLocation = LocationClient.prototype.moveDevicesToAnotherLocation; // Libraries getLibrary = LibraryClient.prototype.getLibrary; // Stripe createCustomerPortalSession = StripeClient.prototype.createCustomerPortalSession; createStripeCheckout = StripeClient.prototype.createStripeCheckout; getStripeCheckout = StripeClient.prototype.getStripeCheckout; getStripeProducts = StripeClient.prototype.getStripeProducts; protected baseUrl: string; protected accessToken?: string; protected getAccessToken?: (opts: RequestOptions) => Promise; protected isBearerToken: boolean; protected fetcher: ApiClientFetcher; constructor(opts: ApiClientOptions) { this.baseUrl = opts.baseUrl; this.accessToken = opts.accessToken; this.getAccessToken = opts.getAccessToken; this.isBearerToken = opts.isBearerToken ?? false; this.fetcher = opts.fetcher; } setAccessToken(accessToken: string) { this.accessToken = accessToken; } async requestProtected( opts: RequestOptions, ): Promise { let accessToken = this.accessToken; if (this.getAccessToken) { accessToken = await this.getAccessToken(opts); } if (!accessToken) throw new UnauthorizedError('Missing access token'); const response = await this.fetcher(`${this.baseUrl}${opts.url}`, { method: opts.method, headers: { 'Content-Type': 'application/json', ...(this.isBearerToken ? { Authorization: `Bearer ${accessToken}` } : { 'Mira-ApiKey': accessToken }), }, ...(opts.body ? { body: JSON.stringify(opts.body) } : {}), }); if (!response.ok) throw await getApiClientError(response); if (response.headers.get('Content-Type')?.includes('application/json')) { return await response.json(); } if (response.headers.get('Content-Type')?.includes('application/zip')) { return (await response.blob()) as any; } return (await response.text()) as any; } async requestPublic( opts: RequestOptions, ): Promise { const response = await this.fetcher(`${this.baseUrl}${opts.url}`, { method: opts.method, headers: { 'Content-Type': 'application/json', }, ...(opts.body ? { body: JSON.stringify(opts.body) } : {}), }); if (!response.ok) throw await getApiClientError(response); if (response.headers.get('Content-Type')?.includes('application/json')) { return await response.json(); } return (await response.text()) as any; } }