140 lines
2.8 KiB
TypeScript
140 lines
2.8 KiB
TypeScript
import crypto from 'node:crypto';
|
|
import { createReadStream } from 'node:fs';
|
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
import { PassThrough } from 'node:stream';
|
|
|
|
import jwt from 'jsonwebtoken';
|
|
import { v4 as uuidv4 } from 'uuid';
|
|
|
|
import { __dirname } from './constants.js';
|
|
|
|
async function combineWithPassthrough(sources: any[], destination: any) {
|
|
for (const stream of sources) {
|
|
await new Promise((resolve, reject) => {
|
|
let s = stream;
|
|
if (typeof stream === 'function') {
|
|
s = stream();
|
|
}
|
|
|
|
if (typeof s === 'string') {
|
|
destination.push(s);
|
|
destination.push(null);
|
|
resolve(true);
|
|
return;
|
|
}
|
|
|
|
s.pipe(destination, { end: false });
|
|
s.on('end', resolve);
|
|
s.on('error', reject);
|
|
});
|
|
}
|
|
destination.emit('end');
|
|
}
|
|
|
|
export function combineStreams(streams: any[]) {
|
|
const stream = new PassThrough();
|
|
combineWithPassthrough(streams, stream).catch((err) => stream.destroy(err));
|
|
return stream;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param userId
|
|
* @param secret
|
|
* @returns
|
|
*/
|
|
export const generateAccessToken = (userId: string, secret = '') =>
|
|
jwt.sign({ id: userId }, secret, { expiresIn: '10m' });
|
|
|
|
/**
|
|
*
|
|
* @param val
|
|
* @returns
|
|
*/
|
|
export const generateEtag = (val: string) =>
|
|
crypto.createHash('sha256').update(val).digest('hex');
|
|
|
|
/**
|
|
*
|
|
* @param userId
|
|
* @param secret
|
|
* @param extendRefresh
|
|
* @returns
|
|
*/
|
|
export const generateRefreshToken = (
|
|
userId: string,
|
|
secret = '',
|
|
extendRefresh = false
|
|
) => {
|
|
const tokenId = uuidv4(); // unique ID for the refresh token
|
|
|
|
const token = jwt.sign({ id: userId, tokenId }, secret, {
|
|
expiresIn: extendRefresh ? '7d' : '1h',
|
|
});
|
|
|
|
return token;
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param value
|
|
* @returns
|
|
*/
|
|
export const getQueryParameterArray = (value: unknown | unknown[] = []) =>
|
|
Array.isArray(value)
|
|
? value.map((val) => `${val}`.trim())
|
|
: [`${value}`.trim()];
|
|
|
|
/**
|
|
*
|
|
* @param pathToFile
|
|
* @returns
|
|
*/
|
|
export const getReadStream = (pathToFile: string) => {
|
|
const theStream = createReadStream(pathToFile);
|
|
|
|
theStream.on('error', (err) => {
|
|
console.error(err);
|
|
theStream.close();
|
|
theStream.push(null);
|
|
});
|
|
|
|
return theStream;
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param value
|
|
* @returns
|
|
*/
|
|
export const getValueOrFirstEntry = (value: string | string[]) =>
|
|
Array.isArray(value) && value.length ? value[0] : value;
|
|
|
|
/**
|
|
*
|
|
* @param filePath
|
|
* @returns
|
|
*/
|
|
export const loadObjectFromJson = async (filePath: string) => {
|
|
const contents = await readFile(filePath, { encoding: 'utf8' });
|
|
return JSON.parse(contents);
|
|
};
|
|
|
|
/**
|
|
*
|
|
* @param contents
|
|
* @param filePath
|
|
*/
|
|
export const saveToJson = async (
|
|
contents: object | string,
|
|
filePath: string
|
|
) => {
|
|
const stringContents =
|
|
typeof contents === 'string' ? contents : JSON.stringify(contents, null, 2);
|
|
|
|
await writeFile(filePath, stringContents, {
|
|
encoding: 'utf8',
|
|
flag: 'w',
|
|
});
|
|
};
|