UNPKG

@ilingo/fs

Version:

This is a lightweight library for translation.

118 lines (114 loc) 3.65 kB
import { locateMany, load } from 'locter'; import path from 'node:path'; import { createMerger } from 'smob'; import { MemoryStore, isBCP47LanguageCode, isLineRecord } from 'ilingo'; import { normalize } from 'pathe'; import process from 'node:process'; function buildConfig(input) { input = input || {}; let directory; if (input.directory) { directory = Array.isArray(input.directory) ? input.directory : [ input.directory ]; for(let i = 0; i < directory.length; i++){ directory[i] = normalize(directory[i]); } } else { directory = [ process.cwd() ]; } return { directory }; } class FSStore extends MemoryStore { // ------------------------------------------ async get(context) { await this.loadGroup(context.group, context.locale); return super.get(context); } async set(context) { return super.set(context); // todo: write to file! } // ------------------------------------------ async getLocales() { const locations = await locateMany([ '*' ], { path: this.directories, onlyDirectories: true }); return locations.filter((location)=>isBCP47LanguageCode(location.name)).map((location)=>location.name); } // ------------------------------------------ isLoaded(group, locale) { this.loaded[locale] = this.loaded[locale] || []; return this.loaded[locale].indexOf(group) !== -1; } setIsLoaded(group, locale) { this.loaded[locale] = this.loaded[locale] || []; this.loaded[locale].push(group); } // ------------------------------------------ async loadGroup(group, locale) { // only load file once if (this.isLoaded(group, locale)) { /* istanbul ignore next */ return {}; } this.initLines(group, locale); this.setIsLoaded(group, locale); const locations = await locateMany(this.addExtensionPattern(group), this.buildLocatorOptionsForLocale(locale)); const loadPromises = locations.map((location)=>load(location).then((data)=>data && data.default ? data.default : data)); const files = await Promise.all(loadPromises); if (files.length === 0) { return {}; } this.data[locale][group] = this.mergeFiles(files); return this.data[locale][group]; } buildLocatorOptionsForLocale(locale) { let directory; if (this.directories.length === 0) { directory = [ locale || 'en' ]; } else { directory = this.directories.map((directory)=>path.join(directory, locale || 'en')); } return { path: directory, ignore: [] }; } addExtensionPattern(name) { return `${name}.{js,mjs,cjs,ts,mts,mjs,json,conf}`; } mergeFiles(files) { const lineRecord = {}; for(let i = 0; i < files.length; i++){ const file = files[i]; if (isLineRecord(file)) { this.merger(lineRecord, file); } } return lineRecord; } constructor(input){ super({ data: {} }); const options = buildConfig(input); this.loaded = {}; this.directories = options.directory; this.merger = createMerger({ inPlace: true, array: true, arrayDistinct: true }); } } export { FSStore, FSStore as default }; //# sourceMappingURL=index.mjs.map