import assert from "assert";
|
|
import { readFile } from "fs/promises";
|
|
import { readFileSync } from "fs";
|
|
import { randomBytes } from "crypto";
|
|
|
|
/**
|
|
* Await for the given number of milliseconds
|
|
*/
|
|
export async function sleep(msecs: number) {
|
|
return new Promise(resolve => {
|
|
setTimeout(resolve, msecs);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Fetch an environment variable
|
|
*/
|
|
export function env(variable: string, throwIfNotFound = true) {
|
|
let value = process.env[variable];
|
|
if (throwIfNotFound) {
|
|
assert(value !== undefined);
|
|
}
|
|
return <string>value;
|
|
}
|
|
|
|
/**
|
|
* Fetch a secret from a file
|
|
*/
|
|
export async function secret(path: string) {
|
|
return (await readFile(path)).toString().trim();
|
|
}
|
|
|
|
/**
|
|
* Fetch a secret (synchronously) from a file
|
|
*/
|
|
export function secretSync(path: string) {
|
|
return readFileSync(path).toString().trim();
|
|
}
|
|
|
|
/**
|
|
* Create a named logger instance
|
|
*/
|
|
export type Logger = ReturnType<typeof createLogger>;
|
|
export function createLogger(name: string) {
|
|
return (...args: any[]) => console.log(`[${name}]:`, ...args);
|
|
}
|
|
|
|
/**
|
|
* Format an IMDb ID
|
|
*/
|
|
export function formatImdbId(imdbId: string) {
|
|
return `tt${imdbId.replace(/^tt0*/, "").padStart(7, '0')}`;
|
|
}
|
|
|
|
/**
|
|
* Generate a random token. Length is 2*size
|
|
*/
|
|
export function generateToken(size: number = 48) {
|
|
return new Promise<string>((resolve, reject) => {
|
|
randomBytes(size, async (err, result) => {
|
|
if (err) {
|
|
reject(err);
|
|
return;
|
|
}
|
|
resolve(result.toString("hex"));
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Generate a URL to a movie/TV show on Plex
|
|
*/
|
|
export function plexMediaUrl(plexKey: number) {
|
|
return `${env("PLEX_URL")}/web/index.html#!/server/${env("PLEX_SERVER_ID")}/` +
|
|
`details?key=%2Flibrary%2Fmetadata%2F${plexKey}&context=library%3Acontent.library;`;
|
|
}
|