import { Collections } from "./constants"; import { EndpointAllIds, EndpointAllSDKUrls, EndpointAudio, EndpointChronologyEvent, EndpointCollectible, EndpointCollectibleGallery, EndpointCollectibleGalleryImage, EndpointCollectibleScanPage, EndpointCollectibleScans, EndpointCurrency, EndpointFile, EndpointFolder, EndpointImage, EndpointLanguage, EndpointPage, EndpointRecorder, EndpointVideo, EndpointWebsiteConfig, EndpointWording, } from "./endpoint-types"; export const getSDKEndpoint = { getConfigEndpoint: () => `/globals/${Collections.WebsiteConfig}/config`, getFolderEndpoint: (slug: string) => `/${Collections.Folders}/slug/${slug}`, getLanguagesEndpoint: () => `/${Collections.Languages}/all`, getCurrenciesEndpoint: () => `/${Collections.Currencies}/all`, getWordingsEndpoint: () => `/${Collections.Wordings}/all`, getPageEndpoint: (slug: string) => `/${Collections.Pages}/slug/${slug}`, getCollectibleEndpoint: (slug: string) => `/${Collections.Collectibles}/slug/${slug}`, getCollectibleScansEndpoint: (slug: string) => `/${Collections.Collectibles}/slug/${slug}/scans`, getCollectibleScanPageEndpoint: (slug: string, index: string) => `/${Collections.Collectibles}/slug/${slug}/scans/${index}`, getCollectibleGalleryEndpoint: (slug: string) => `/${Collections.Collectibles}/slug/${slug}/gallery`, getCollectibleGalleryImageEndpoint: (slug: string, index: string) => `/${Collections.Collectibles}/slug/${slug}/gallery/${index}`, getChronologyEventsEndpoint: () => `/${Collections.ChronologyEvents}/all`, getChronologyEventByIDEndpoint: (id: string) => `/${Collections.ChronologyEvents}/id/${id}`, getImageByIDEndpoint: (id: string) => `/${Collections.Images}/id/${id}`, getAudioByIDEndpoint: (id: string) => `/${Collections.Audios}/id/${id}`, getVideoByIDEndpoint: (id: string) => `/${Collections.Videos}/id/${id}`, getFileByIDEndpoint: (id: string) => `/${Collections.Files}/id/${id}`, getRecorderByIDEndpoint: (id: string) => `/${Collections.Recorders}/id/${id}`, getAllSDKUrlsEndpoint: () => `/all-sdk-urls`, getAllIds: () => `/all-ids`, getLoginEndpoint: () => `/${Collections.Recorders}/login`, }; type PayloadSDKResponse = { data: T; endpointCalled: string; }; type PayloadTokenCache = { set: (token: string, expirationTimestamp: number) => void; get: () => string | undefined; }; type PayloadDataCache = { set: (url: string, response: any) => void; get: (url: string) => any | undefined; }; export class PayloadSDK { private tokenCache: PayloadTokenCache | undefined; private dataCache: PayloadDataCache | undefined; constructor( private readonly apiURL: string, private readonly email: string, private readonly password: string ) {} addTokenCache(tokenCache: PayloadTokenCache) { this.tokenCache = tokenCache; } addDataCache(dataCache: PayloadDataCache) { this.dataCache = dataCache; } private logResponse(res: Response) { console.log(res.status, res.statusText, res.url); } private async refreshToken() { const loginUrl = `${this.apiURL}${getSDKEndpoint.getLoginEndpoint()}`; const loginResult = await fetch(loginUrl, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email: this.email, password: this.password }), }); this.logResponse(loginResult); if (loginResult.status !== 200) { throw new Error("Unable to login"); } const { token, exp } = (await loginResult.json()) as { token: string; exp: number; }; this.tokenCache?.set(token, exp); return token; } async request(endpoint: string): Promise> { const cachedResponse = this.dataCache?.get(endpoint); if (cachedResponse) { return cachedResponse; } const result = await fetch(`${this.apiURL}${endpoint}`, { headers: { Authorization: `JWT ${ this.tokenCache?.get() ?? (await this.refreshToken()) }`, }, }); this.logResponse(result); if (!result.ok) { throw new Error("Unhandled fetch error"); } const response = { data: await result.json(), endpointCalled: endpoint }; this.dataCache?.set(endpoint, response); return response; } async getConfig(): Promise> { return await this.request(getSDKEndpoint.getConfigEndpoint()); } async getFolder(slug: string): Promise> { return await this.request(getSDKEndpoint.getFolderEndpoint(slug)); } async getLanguages(): Promise> { return await this.request(getSDKEndpoint.getLanguagesEndpoint()); } async getCurrencies(): Promise> { return await this.request(getSDKEndpoint.getCurrenciesEndpoint()); } async getWordings(): Promise> { return await this.request(getSDKEndpoint.getWordingsEndpoint()); } async getPage(slug: string): Promise> { return await this.request(getSDKEndpoint.getPageEndpoint(slug)); } async getCollectible( slug: string ): Promise> { return await this.request(getSDKEndpoint.getCollectibleEndpoint(slug)); } async getCollectibleScans( slug: string ): Promise> { return await this.request(getSDKEndpoint.getCollectibleScansEndpoint(slug)); } async getCollectibleScanPage( slug: string, index: string ): Promise> { return await this.request( getSDKEndpoint.getCollectibleScanPageEndpoint(slug, index) ); } async getCollectibleGallery( slug: string ): Promise> { return await this.request( getSDKEndpoint.getCollectibleGalleryEndpoint(slug) ); } async getCollectibleGalleryImage( slug: string, index: string ): Promise> { return await this.request( getSDKEndpoint.getCollectibleGalleryImageEndpoint(slug, index) ); } async getChronologyEvents(): Promise< PayloadSDKResponse > { return await this.request(getSDKEndpoint.getChronologyEventsEndpoint()); } async getChronologyEventByID( id: string ): Promise> { return await this.request( getSDKEndpoint.getChronologyEventByIDEndpoint(id) ); } async getImageByID(id: string): Promise> { return await this.request(getSDKEndpoint.getImageByIDEndpoint(id)); } async getAudioByID(id: string): Promise> { return await this.request(getSDKEndpoint.getAudioByIDEndpoint(id)); } async getVideoByID(id: string): Promise> { return await this.request(getSDKEndpoint.getVideoByIDEndpoint(id)); } async getFileByID(id: string): Promise> { return await this.request(getSDKEndpoint.getFileByIDEndpoint(id)); } async getRecorderByID( id: string ): Promise> { return await this.request(getSDKEndpoint.getRecorderByIDEndpoint(id)); } async getAllSdkUrls(): Promise> { return await this.request(getSDKEndpoint.getAllSDKUrlsEndpoint()); } async getAllIds(): Promise> { return await this.request(getSDKEndpoint.getAllIds()); } }