import md5 from 'md5'; export const makeId = () => md5(`${Date.now()}${Math.random()}`); export const isObject = (v: unknown): v is Record => typeof v === 'object' && v !== null; export const isArray = (v: unknown): v is Array => Array.isArray(v); export const isString = (v: unknown): v is string => typeof v === 'string'; export const isFunction = (v: unknown): v is Function => typeof v === 'function'; export type ObjectType = Record; export type ToDeepPromise = { [K in keyof T]: T[K] extends (...args: infer P) => infer R ? (...args: P) => Promise> : T[K] extends object ? ToDeepPromise : T[K] }; export async function getRandomAvailablePort() { const { createServer } = await import('http'); const server = createServer(); return new Promise((resolve, reject) => { server.on('listening', () => { const address = server.address(); if (address && isObject(address)) { const port = address.port; server.close(() => { resolve(port); }) } else { server.close(); reject(new Error('Failed to get port')); } }); server.on('error', (err) => { server.close(); reject(err); }); server.listen(0); }) } const publicMethodMap = new WeakMap(); export function publicMethod(target: any, propertyKey: string, descriptor: PropertyDescriptor) { publicMethodMap.set(descriptor.value, true); }; export function isPublicMethod(target: Function) { return publicMethodMap.get(target); }; export function markAsPublicMethod | unknown>(obj: T, options?: { deep?: boolean }): T { const accessed = new Set(); function markAs(obj: Function | Record | unknown) { if (accessed.has(obj)) { return; } if (isFunction(obj)) { publicMethodMap.set(obj, true); } else if (isObject(obj)) { accessed.add(obj); Object.values(obj).forEach(subObj => { if (isFunction(subObj)) { publicMethodMap.set(subObj, true); } if (options?.deep && isObject(subObj)) { markAs(subObj); } }); } } markAs(obj); return obj; } export function createDeferrablePromise() { let resolve!: (value: T | PromiseLike) => void; let reject!: (reason?: unknown) => void; const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); return { promise, resolve, reject }; }