UNPKG

@travetto/config

Version:

Configuration support

55 lines (47 loc) 1.77 kB
import fs from 'node:fs/promises'; import path from 'node:path'; import { Env, Runtime, RuntimeResources } from '@travetto/runtime'; import { ConfigSource, ConfigSpec } from './types.ts'; import { 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 { #profiles: Profile[]; #searchPaths: string[]; #parser: ParserManager; constructor(parser: ParserManager) { this.#parser = parser; this.#searchPaths = RuntimeResources.searchPaths.toReversed(); this.#profiles = ([ ['application', 100], [Runtime.env!, 200], ...(Env.TRV_PROFILES.list ?? []) .map((p, i) => [p, 300 + i * 10] as const) ] as const).filter(x => !!x[0]); } async get(): Promise<ConfigSpec[]> { const cache: Record<string, Promise<string[]>> = {}; const configs: Promise<ConfigSpec>[] = []; 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); } }