import { gettextToI18next } from 'i18next-conv' import { GettextExtractor, JsExtractors } from 'gettext-extractor'; import { JsParser } from 'gettext-extractor/dist/js/parser'; import { IJsExtractorOptions } from 'gettext-extractor/dist/js/extractors/common'; let extractor = new GettextExtractor(); interface Options { pot: Partial<{ out: string callee: { calleeName: string|string[], options: IJsExtractorOptions}[] }> } export default function GettextLoader(options: Partial = {}) { const pwd = process.cwd(); let parser: JsParser|undefined = undefined; if (options.pot?.out && process.env.NODE_ENV === 'development') { let extractorFuncs = options.pot.callee?.map(c => JsExtractors.callExpression(c.calleeName, c.options)); if (!extractorFuncs || extractorFuncs.length === 0) { extractorFuncs = [ JsExtractors.callExpression(['t'], { arguments: { text: 0, context: 1, } })] } parser = extractor.createJsParser(extractorFuncs); } return { name: 'gettext-loader', async transform(source: string, id: string) { const poRegEx = /\.po$/; const jsRegEx = /\.(js|jsx|ts|tsx)$/; if (poRegEx.test(id)) { const match = source.match(/Language: (\w+)/) const lang = match ? match[1] : 'en'; return { code: `export default ${await gettextToI18next(lang, source)}` } } else if (jsRegEx.test(id)) { parser?.parseFile(id.replace(pwd, '.')) } return {}; }, async buildEnd() { if (parser && options.pot?.out) { extractor.savePotFile(options.pot.out) } } } }