UNPKG

bunnycdn

Version:

Use the unofficial BunnyCDN library quickly and easily with Javascript

597 lines (512 loc) 17.4 kB
import Collection, { APICollection } from "./Collection"; import StatusResponse from "./types/StatusResponse"; import { APIVideo, VideoList, VideoStatics } from "./types/Video"; import Video from "./Video"; import fetch from "node-fetch"; export default class Stream { constructor() { } // Library actions public GetLibrary(libraryId: number, accessKey: string) { return new Library(libraryId, accessKey); } } export class Library { public libraryId: number; public accessKey: string; constructor(libraryId: number, accessKey: string) { this.libraryId = libraryId; this.accessKey = accessKey; } /** * @description Get a video from the library */ async GetVideo(videoId: number): Promise<( { status: StatusResponse.OK, data: Video } | { status: StatusResponse.UNAUTHORIZED | StatusResponse.NOT_FOUND | StatusResponse.INTERNAL_SERVER_ERROR | StatusResponse.UNDEFINED, data: null } )> { const url = `https://video.bunnycdn.com/library/${this.libraryId}/videos/${videoId}`; const request = await fetch(url, { method: "GET", headers: { accept: 'application/json', AccessKey: this.accessKey } }); const status = request.status; let body = await request.json(); if (status === 200) { body = { ...body, dateUploaded: new Date(body.dateUploaded), transcodingMessages: body.transcodingMessages.map((message: any) => { return { ...message, date: new Date(message.timeStamp) } }) } return { status: StatusResponse.OK, data: new Video(this, body as APIVideo, videoId) } } if (status === 401) { return { status: StatusResponse.UNAUTHORIZED, data: null } } if (status === 404) { return { status: StatusResponse.NOT_FOUND, data: null } } if (status === 500) { return { status: StatusResponse.INTERNAL_SERVER_ERROR, data: null } } return { status: StatusResponse.UNDEFINED, data: null } } /** * @description Get global video statistics */ async GetVideoStatistics(params: { dateFrom?: string; dateTo?: string; hourly?: boolean; videoGuid?: string; }): Promise<( { status: StatusResponse.OK, data: VideoStatics } | { status: StatusResponse.UNAUTHORIZED | StatusResponse.NOT_FOUND | StatusResponse.INTERNAL_SERVER_ERROR | StatusResponse.UNDEFINED, data: null } )> { const validParams = ["dateFrom", "dateTo", "hourly", "videoGuid"].reduce((acc, param) => { if ((params as any)[param]) { acc[param] = (params as any)[param]; } return acc; }, {} as { [key: string]: string }); const url_params = new URLSearchParams(validParams); const url = `https://video.bunnycdn.com/library/${this.libraryId}/statistics?${url_params.toString()}` const request = await fetch(url, { method: "GET", headers: { accept: 'application/json', AccessKey: this.accessKey } }); const status = request.status; const body = await request.json(); if (status === 200) { return { status: StatusResponse.OK, data: body as VideoStatics } } if (status === 401) { return { status: StatusResponse.UNAUTHORIZED, data: null } } if (status === 404) { return { status: StatusResponse.NOT_FOUND, data: null } } if (status === 500) { return { status: StatusResponse.INTERNAL_SERVER_ERROR, data: null } } return { status: StatusResponse.UNDEFINED, data: null } } /** * @description get list of videos in the library */ async ListVideos(params: { page?: number; itemsPerPage?: number; search?: string; collection?: string; orderBy?: 'date'; }): Promise< { status: StatusResponse.OK, data: VideoList } | { status: StatusResponse.UNAUTHORIZED | StatusResponse.INTERNAL_SERVER_ERROR | StatusResponse.UNDEFINED, data: null }> { const validParams = ["page", "itemsPerPage", "search", "collection", "orderBy"].reduce((acc, param) => { if ((params as any)[param]) { acc[param] = (params as any)[param]; } return acc; }, { page: 1, itemsPerPage: 100, orderBy: 'date' } as unknown as { [key: string]: string }); const url_params = new URLSearchParams(validParams); const url = `https://video.bunnycdn.com/library/${this.libraryId}/videos?${url_params.toString()}` const request = await fetch(url, { method: "GET", headers: { accept: 'application/json', AccessKey: this.accessKey } }); const status = request.status; const body = await request.json(); if (status === 200) { body.items = body.items.map((item: APIVideo) => { return { ...item, dateUploaded: new Date(item.dateUploaded), transcodingMessages: item.transcodingMessages.map(message => { return { ...message, date: new Date(message.timeStamp) } }) } }) return { status: StatusResponse.OK, data: body as VideoList } } if (status === 401) { return { status: StatusResponse.UNAUTHORIZED, data: null } } if (status === 500) { return { status: StatusResponse.INTERNAL_SERVER_ERROR, data: null } } return { status: StatusResponse.UNDEFINED, data: null } } /** * @description create a new video in the library */ async CreateVideo(params: { title: string; collectionId?: string; thumbnailTime?: number; }): Promise< { status: StatusResponse.OK, data: Video } | { status: StatusResponse.UNAUTHORIZED | StatusResponse.INTERNAL_SERVER_ERROR | StatusResponse.UNDEFINED, data: null } > { const url = `https://video.bunnycdn.com/library/${this.libraryId}/videos`; const request = await fetch(url, { method: "POST", headers: { accept: 'application/json', 'content-type': 'application/*+json', AccessKey: this.accessKey }, body: JSON.stringify(params) }); const status = request.status; let body = await request.json(); if (status === 200) { body = { ...(body as APIVideo), dateUploaded: new Date(body.dateUploaded), transcodingMessages: body.transcodingMessages.map((message: any) => { return { ...message, date: new Date(message.timeStamp) } }) } return { status: StatusResponse.OK, data: body as Video } } if (status === 401) { return { status: StatusResponse.UNAUTHORIZED, data: null } } if (status === 500) { return { status: StatusResponse.INTERNAL_SERVER_ERROR, data: null } } return { status: StatusResponse.UNDEFINED, data: null } } /** * @description fetch a video from a url * @param bodyParams params for the request body * @param queryParams params for the query string */ async FetchVideo(bodyParams: { url: string; headers: { [key: string]: string }; }, queryParams: { collectionId?: string; lowPriority?: boolean; thumbnailTime?: number; }): Promise< { status: StatusResponse.OK, data: { success: boolean; message?: string; statusCode: number; } } | { status: StatusResponse.BAD_REQUEST | StatusResponse.UNAUTHORIZED | StatusResponse.NOT_FOUND | StatusResponse.INTERNAL_SERVER_ERROR | StatusResponse.UNDEFINED, data: null } > { const url_params = new URLSearchParams(["collectionId", "lowPriority", "thumbnailTime"].reduce((acc, param) => { if ((queryParams as any)[param]) { acc[param] = (queryParams as any)[param]; } return acc; }, {} as { [key: string]: string })); const url = `https://video.bunnycdn.com/library/${this.libraryId}/videos?${url_params.toString()}` const request = await fetch(url, { method: "POST", headers: { accept: 'application/json', 'content-type': 'application/*+json', AccessKey: this.accessKey }, body: JSON.stringify(bodyParams) }); const status = request.status; const body = await request.json(); if (status === 200) { return { status: StatusResponse.OK, data: body as { success: boolean; message?: string; statusCode: number; } } } if (status === 400) { return { status: StatusResponse.BAD_REQUEST, data: null } } if (status === 401) { return { status: StatusResponse.UNAUTHORIZED, data: null } } if (status === 404) { return { status: StatusResponse.NOT_FOUND, data: null } } if (status === 500) { return { status: StatusResponse.INTERNAL_SERVER_ERROR, data: null } } return { status: StatusResponse.UNDEFINED, data: null } } // Manage Collections /** * @description Fetch specific collection with ID * @param collectionId ID of the collection to fetch */ async GetCollection(collectionId: string): Promise< { status: StatusResponse.OK, data: Collection } | { status: StatusResponse.UNAUTHORIZED | StatusResponse.NOT_FOUND | StatusResponse.INTERNAL_SERVER_ERROR | StatusResponse.UNDEFINED, data: null } > { const url = `https://video.bunnycdn.com/library/${this.libraryId}/collections/${collectionId}`; const request = await fetch(url, { method: "GET", headers: { accept: 'application/json', AccessKey: this.accessKey } }); const status = request.status; const body = await request.json(); if (status === 200) { return { status: StatusResponse.OK, data: new Collection(body as APICollection, collectionId, this) } } if (status === 401) { return { status: StatusResponse.UNAUTHORIZED, data: null } } if (status === 404) { return { status: StatusResponse.NOT_FOUND, data: null } } if (status === 500) { return { status: StatusResponse.INTERNAL_SERVER_ERROR, data: null } } return { status: StatusResponse.UNDEFINED, data: null } } /** * @description Fetch all collections in the library * @param queryParams Query params for the request */ async GetCollectionList(queryParams: { page?: number; itemsPerPage?: number; search?: string; orderBy?: "date" }): Promise<{ status: StatusResponse.OK, data: { totalItems: number; currentPage: number; itemsPerPage: number; items?: Collection[] } } | { status: StatusResponse.UNAUTHORIZED | StatusResponse.INTERNAL_SERVER_ERROR | StatusResponse.UNDEFINED, data: null }> { const url_params = new URLSearchParams(["page", "itemsPerPage", "search", "orderBy"].reduce((acc, param) => { if ((queryParams as any)[param]) { acc[param] = (queryParams as any)[param]; } return acc; }, { page: 1, itemsPerPage: 100, orderBy: "date" } as unknown as { [key: string]: string })); const url = `https://video.bunnycdn.com/library/${this.libraryId}/collections?${url_params.toString()}`; const request = await fetch(url, { method: "GET", headers: { accept: 'application/json', AccessKey: this.accessKey } }); const status = request.status; const body = await request.json(); if (status === 200) { body.items = body.items?.map((item: APICollection) => new Collection(item, item.guid as string, this)); return { status: StatusResponse.OK, data: body as { totalItems: number; currentPage: number; itemsPerPage: number; items?: Collection[] } } } if (status === 401) { return { status: StatusResponse.UNAUTHORIZED, data: null } } if (status === 500) { return { status: StatusResponse.INTERNAL_SERVER_ERROR, data: null } } return { status: StatusResponse.UNDEFINED, data: null } } /** * @description Create a new collection * @param name Name of the collection to create * @returns */ async CreateCollection(name?: string): Promise<{ status: StatusResponse.OK, data: Collection } | { status: StatusResponse.UNAUTHORIZED | StatusResponse.INTERNAL_SERVER_ERROR | StatusResponse.UNDEFINED, data: null }> { const url = `https://video.bunnycdn.com/library/${this.libraryId}/collections`; const request = await fetch(url, { method: "POST", headers: { accept: 'application/json', 'content-type': 'application/*+json', AccessKey: this.accessKey }, body: name ? JSON.stringify({ name }) : undefined }); const status = request.status; const body = await request.json(); if (status === 200) { return { status: StatusResponse.OK, data: new Collection(body as APICollection, body.guid, this) } } if (status === 401) { return { status: StatusResponse.UNAUTHORIZED, data: null } } if (status === 500) { return { status: StatusResponse.INTERNAL_SERVER_ERROR, data: null } } return { status: StatusResponse.UNDEFINED, data: null } } }