import fs from 'fs-extra'; import { SemVer } from 'semver'; import { logger } from '../../lib/logger'; export const newFiles = new Set(); /** * Get environment variable or empty string. * Used for easy mocking. * @param {string} key variable name * @returns {string} */ export function getEnv(key: string): string { return process.env[key] ?? ''; } /** * Find all module directories. * @param {string} dirname dir to search in * @returns {string[]} */ export function findModules(dirname: string): string[] { return fs .readdirSync(dirname, { withFileTypes: true }) .filter((dirent) => dirent.isDirectory()) .map((dirent) => dirent.name) .filter((name) => !name.startsWith('__')) .sort(); } /** * @param {string} input * @returns {string} */ export function camelCase(input: string): string { return input .replace(/(?:^\w|[A-Z]|\b\w)/g, (char, index) => index === 0 ? char.toLowerCase() : char.toUpperCase(), ) .replace(/-/g, ''); } /** * @param {string } file * @param {string} code * @returns {Promise} */ export async function updateFile(file: string, code: string): Promise { const oldCode = fs.existsSync(file) ? await fs.readFile(file, 'utf8') : null; if (code !== oldCode) { if (!code) { logger.error({ file }, 'Missing content'); } await fs.outputFile(file, code ?? '', { encoding: 'utf8' }); } newFiles.add(file); } /** * @param {string } file * @returns {Promise} */ export function readFile(file: string): Promise { if (fs.existsSync(file)) { return fs.readFile(file, 'utf8'); } return Promise.resolve(''); } /** * * @param val */ export function parsePositiveInt(val: string | undefined): number { if (!val) { return 0; } const r = Number.parseInt(val, 10); if (!Number.isFinite(r) || r < 0) { throw new Error(`Invalid number: ${val}`); } return r; } /** * * @param val */ export function parseVersion(val: string | undefined): SemVer | undefined { if (!val) { return undefined; } // can throw return new SemVer(val); }