|
#!/usr/bin/env node |
|
|
|
import { promises as fsp } from 'fs' |
|
import { program } from 'commander' |
|
import colors from 'colors' |
|
import path from 'path' |
|
import sort from 'gulp-sort' |
|
import vfs from 'vinyl-fs' |
|
import { lilconfig } from 'lilconfig' |
|
import { |
|
esConfigLoader, |
|
tsConfigLoader, |
|
yamlConfigLoader, |
|
} from '../dist/helpers.js' |
|
import i18nTransform from '../dist/transform.js' |
|
;(async () => { |
|
const pkg = JSON.parse( |
|
await fsp.readFile(new URL('../package.json', import.meta.url), 'utf-8') |
|
) |
|
|
|
program |
|
.version(pkg.version) |
|
.option( |
|
'-c, --config <path>', |
|
'Path to the config file (default: i18next-parser.config.{js,mjs,json,ts,yaml,yml})' |
|
) |
|
.option( |
|
'-o, --output <path>', |
|
'Path to the output directory (default: locales/$LOCALE/$NAMESPACE.json)' |
|
) |
|
.option('-s, --silent', 'Disable logging to stdout') |
|
.option('--fail-on-warnings', 'Exit with an exit code of 1 on warnings') |
|
.option( |
|
'--fail-on-update', |
|
'Exit with an exit code of 1 when translations are updated (for CI purpose)' |
|
) |
|
|
|
program.on('--help', function () { |
|
console.log(' Examples:') |
|
console.log('') |
|
console.log(' $ i18next "src/**/*.{js,jsx}"') |
|
console.log( |
|
' $ i18next "/path/to/src/app.js" "/path/to/assets/index.html"' |
|
) |
|
console.log( |
|
' $ i18next --config i18next-parser.config.js --output locales/$LOCALE/$NAMESPACE.json' |
|
) |
|
console.log('') |
|
}) |
|
|
|
program.parse(process.argv) |
|
|
|
let config = {} |
|
try { |
|
const lilconfigOptions = { |
|
searchPlaces: [ |
|
`${pkg.name}.config.js`, |
|
`${pkg.name}.config.mjs`, |
|
`${pkg.name}.config.json`, |
|
`${pkg.name}.config.ts`, |
|
`${pkg.name}.config.yaml`, |
|
`${pkg.name}.config.yml`, |
|
], |
|
loaders: { |
|
'.js': esConfigLoader, |
|
'.mjs': esConfigLoader, |
|
'.ts': tsConfigLoader, |
|
'.yaml': yamlConfigLoader, |
|
'.yml': yamlConfigLoader, |
|
}, |
|
} |
|
let result |
|
if (program.opts().config) { |
|
result = await lilconfig(pkg.name, lilconfigOptions).load( |
|
program.opts().config |
|
) |
|
} else { |
|
result = await lilconfig(pkg.name, lilconfigOptions).search() |
|
} |
|
|
|
if (result) { |
|
config = result.config |
|
} |
|
} catch (err) { |
|
if (err.code === 'MODULE_NOT_FOUND') { |
|
console.log( |
|
' [error] '.red + |
|
'Config file does not exist: ' + |
|
program.opts().config |
|
) |
|
} else { |
|
throw err |
|
} |
|
} |
|
|
|
config.output = |
|
program.opts().output || config.output || 'locales/$LOCALE/$NAMESPACE.json' |
|
config.failOnWarnings = |
|
program.opts().failOnWarnings || config.failOnWarnings || false |
|
config.failOnUpdate = |
|
program.opts().failOnUpdate || config.failOnUpdate || false |
|
|
|
let args = program.args || [] |
|
let globs |
|
|
|
|
|
if (args.length) { |
|
globs = args.map(function (s) { |
|
s = s.trim() |
|
if (s.match(/(^'.*'$|^".*"$)/)) { |
|
s = s.slice(1, -1) |
|
} |
|
return s |
|
}) |
|
} |
|
|
|
|
|
else if (config.input) { |
|
if (!Array.isArray(config.input)) { |
|
if (typeof config.input === 'string') { |
|
config.input = [config.input] |
|
} else { |
|
console.log( |
|
' [error] '.red + |
|
'`input` must be an array when specified in the config' |
|
) |
|
program.help() |
|
program.exit(1) |
|
} |
|
} |
|
|
|
let basePath = process.cwd() |
|
|
|
if (program.opts().config) { |
|
basePath = path.dirname(path.resolve(program.opts().config)) |
|
} |
|
|
|
globs = config.input.map(function (s) { |
|
var negate = '' |
|
if (s.startsWith('!')) { |
|
negate = '!' |
|
s = s.substr(1) |
|
} |
|
return negate + path.resolve(basePath, s) |
|
}) |
|
} |
|
|
|
if (!globs || !globs.length) { |
|
console.log(' [error] '.red + 'missing argument: ') |
|
program.help() |
|
process.exit(0) |
|
} |
|
|
|
|
|
if (!program.opts().silent) { |
|
console.log() |
|
console.log(' i18next Parser'.cyan) |
|
console.log(' --------------'.cyan) |
|
console.log(' Input: '.cyan + args.join(', ')) |
|
console.log(' Output: '.cyan + config.output) |
|
console.log() |
|
} |
|
|
|
var count = 0 |
|
|
|
vfs |
|
.src(globs) |
|
.pipe(sort()) |
|
.pipe( |
|
new i18nTransform(config) |
|
.on('reading', function (file) { |
|
if (!program.opts().silent) { |
|
console.log(' [read] '.green + file.path) |
|
} |
|
count++ |
|
}) |
|
.on('data', function (file) { |
|
if (!program.opts().silent) { |
|
console.log(' [write] '.green + file.path) |
|
} |
|
}) |
|
.on('error', function (message, region) { |
|
if (typeof region === 'string') { |
|
message += ': ' + region.trim() |
|
} |
|
console.log(' [error] '.red + message) |
|
}) |
|
.on('warning', function (message) { |
|
if (!program.opts().silent) { |
|
console.log(' [warning] '.yellow + message) |
|
} |
|
}) |
|
.on('finish', function () { |
|
if (!program.opts().silent) { |
|
console.log() |
|
console.log(' Stats: '.cyan + count + ' files were parsed') |
|
} |
|
}) |
|
) |
|
.pipe(vfs.dest(process.cwd())) |
|
})() |
|
|