UNPKG

@travetto/config

Version:

Configuration support

66 lines (57 loc) 2.06 kB
import fs from 'node:fs/promises'; import path from 'node:path'; import { Env, Runtime, RuntimeResources } from '@travetto/runtime'; import type { ConfigSource, ConfigPayload } from './types.ts'; import type { ParserManager } from '../parser/parser.ts'; type Profile = [string, number] | readonly [string, number]; /** * File-based config source, relies on resource search paths for finding files */ export class FileConfigSource implements ConfigSource { static getProfiles(): Profile[] { const profiles: Profile[] = [ ['application', 100] ]; if (Runtime.role === 'std') { if (Runtime.localDevelopment) { profiles.push(['local', 200]); } } else { profiles.push([Runtime.role, 200]); } profiles.push(...(Env.TRV_PROFILES.list ?? []) .map((profile, i) => [profile, 300 + i * 10] as const)); return profiles; } #profiles: Profile[]; #searchPaths: string[]; #parser: ParserManager; constructor(parser: ParserManager) { this.#parser = parser; this.#searchPaths = RuntimeResources.searchPaths.toReversed(); this.#profiles = FileConfigSource.getProfiles(); } async get(): Promise<ConfigPayload[]> { const cache: Record<string, Promise<string[]>> = {}; const configs: Promise<ConfigPayload>[] = []; for (const [profile, priority] of this.#profiles) { let i = priority; for (const folder of this.#searchPaths) { const files = await (cache[folder] ??= fs.readdir(folder).catch(() => [])); for (const file of files) { if (this.#parser.matches(file) && path.basename(file, path.extname(file)) === profile) { const full = path.resolve(folder, file); const configPriority = i++; configs.push(this.#parser.parse(full).then(data => ({ data, priority: configPriority, source: `file://${profile}`, detail: Runtime.stripWorkspacePath(full) }))); } } } } return Promise.all(configs); } }