UNPKG

i18next-scanner-esm

Version:

Scan your code, extract translation keys/values, and merge them into i18n resource files.

131 lines (110 loc) 4.18 kB
/* eslint-disable no-buffer-constructor */ import fs from 'fs'; import path from 'path'; import eol from 'eol'; import get from 'lodash/get.js'; import includes from 'lodash/includes.js'; import VirtualFile from 'vinyl'; import through2 from 'through2'; import Parser from './parser.js'; const transform = (parser, customTransform) => { return function _transform(file, enc, done) { const { options } = parser; const content = fs.readFileSync(file.path, enc); const extname = path.extname(file.path); if (includes(get(options, 'attr.extensions'), extname)) { // Parse attribute (e.g. data-i18n="key") parser.parseAttrFromString(content, { transformOptions: { filepath: file.path, }, }); } if (includes(get(options, 'func.extensions'), extname)) { // Parse translation function (e.g. i18next.t('key')) parser.parseFuncFromString(content, { transformOptions: { filepath: file.path, }, }); } if (includes(get(options, 'trans.extensions'), extname)) { // Look for Trans components in JSX parser.parseTransFromString(content, { transformOptions: { filepath: file.path, }, }); } if (typeof customTransform === 'function') { this.parser = parser; customTransform.call(this, file, enc, done); return; } done(); }; }; const flush = (parser, customFlush) => { return function _flush(done) { const { options } = parser; if (typeof customFlush === 'function') { this.parser = parser; customFlush.call(this, done); return; } // Flush to resource store const resStore = parser.get({ sort: options.sort }); const { jsonIndent } = options.resource; const lineEnding = String(options.resource.lineEnding).toLowerCase(); Object.keys(resStore).forEach((lng) => { const namespaces = resStore[lng]; Object.keys(namespaces).forEach((ns) => { const obj = namespaces[ns]; const resPath = parser.formatResourceSavePath(lng, ns); let text = JSON.stringify(obj, null, jsonIndent) + '\n'; if (lineEnding === 'auto') { text = eol.auto(text); } else if (lineEnding === '\r\n' || lineEnding === 'crlf') { text = eol.crlf(text); } else if (lineEnding === '\n' || lineEnding === 'lf') { text = eol.lf(text); } else if (lineEnding === '\r' || lineEnding === 'cr') { text = eol.cr(text); } else { // Defaults to LF text = eol.lf(text); } let contents = null; try { // "Buffer.from(string[, encoding])" is added in Node.js v5.10.0 contents = Buffer.from(text); } catch (e) { // Fallback to "new Buffer(string[, encoding])" which is deprecated since Node.js v6.0.0 contents = new Buffer(text); } this.push( new VirtualFile({ path: resPath, contents: contents, }) ); }); }); done(); }; }; // @param {object} options The options object. // @param {function} [customTransform] // @param {function} [customFlush] // @return {object} Returns a through2.obj(). const createStream = (options, customTransform, customFlush) => { const parser = new Parser(options); const stream = through2.obj( transform(parser, customTransform), flush(parser, customFlush) ); return stream; }; const scaner = (...args) => createStream(...args); export default scaner; export { Parser, createStream };