bunnycdn
Version:
Use the unofficial BunnyCDN library quickly and easily with Javascript
597 lines (512 loc) • 17.4 kB
text/typescript
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
}
}
}