Skip to content

Commit

Permalink
feat: rewrite TypeScript (#46)
Browse files Browse the repository at this point in the history
  • Loading branch information
akameco authored Aug 24, 2019
1 parent 22f05b6 commit 06537fa
Show file tree
Hide file tree
Showing 42 changed files with 429 additions and 233 deletions.
5 changes: 4 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"extends": ["precure/oss"],
"extends": ["precure/auto"],
"rules": {
"@typescript-eslint/explicit-function-return-type": "off"
}
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
node_modules
lib
example/i18n
dist
.eslintcache
6 changes: 1 addition & 5 deletions cli.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env node
/* eslint-disable no-console */
/* eslint-disable no-console, @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires */
'use strict'
const meow = require('meow')
const fn = require('.')
Expand All @@ -16,7 +16,6 @@ const cli = meow(
-f, --format json | yaml [default: json]
-d, --default-locale default locale
--flat json [default: true] | yaml [default: false]
--module-name module source name from where components are imported
Example
$ extract-messages --locales=ja,en --output app/translations 'app/**/*.js'
Expand Down Expand Up @@ -44,9 +43,6 @@ const cli = meow(
type: 'string',
alias: 'd'
},
'module-name': {
type: 'string'
},
withDescriptions: {
type: 'boolean',
default: false
Expand Down
125 changes: 3 additions & 122 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,123 +1,4 @@
/* eslint-disable no-unused-vars */
'use strict'
const path = require('path')
const fs = require('fs')
const mkdirp = require('mkdirp')
const pick = require('lodash.pick')
const yaml = require('js-yaml')
const pify = require('pify')
const { flatten, unflatten } = require('flat')
const loadJsonFile = require('load-json-file')
const writeJsonFile = require('write-json-file')
const sortKeys = require('sort-keys')
const extractReactIntl = require('./extract-react-intl')
// eslint-disable-next-line @typescript-eslint/no-require-imports, @typescript-eslint/no-var-requires
const fn = require('./dist').default

const writeJson = (outputPath, obj) => {
return writeJsonFile(`${outputPath}.json`, obj, { indent: 2 })
}

const writeYaml = (outputPath, obj) => {
return pify(fs.writeFile)(`${outputPath}.yml`, yaml.safeDump(obj), 'utf8')
}

const isJson = ext => ext === 'json'

function loadLocaleFiles(locales, buildDir, ext) {
const oldLocaleMaps = {}

try {
mkdirp.sync(buildDir)
} catch (error) {}

for (const locale of locales) {
const file = path.resolve(buildDir, `${locale}.${ext}`)
// Initialize json file
try {
const output = isJson(ext) ? JSON.stringify({}) : yaml.safeDump({})
fs.writeFileSync(file, output, { flag: 'wx' })
} catch (error) {
if (error.code !== 'EEXIST') {
throw error
}
}

let messages = isJson(ext)
? loadJsonFile.sync(file)
: yaml.safeLoad(fs.readFileSync(file, 'utf8'), { json: true })

messages = flatten(messages)

oldLocaleMaps[locale] = {}
for (const messageKey of Object.keys(messages)) {
const message = messages[messageKey]
if (message && typeof message === 'string' && message !== '') {
oldLocaleMaps[locale][messageKey] = messages[messageKey]
}
}
}

return oldLocaleMaps
}

// eslint-disable-next-line max-lines-per-function
module.exports = async (locales, pattern, buildDir, opts) => {
if (!Array.isArray(locales)) {
throw new TypeError(`Expected a Array, got ${typeof locales}`)
}

if (typeof pattern !== 'string') {
throw new TypeError(`Expected a string, got ${typeof pattern}`)
}

if (typeof buildDir !== 'string') {
throw new TypeError(`Expected a string, got ${typeof buildDir}`)
}

const jsonOpts = { format: 'json', flat: true }
const yamlOpts = { format: 'yaml', flat: false }
const defautlOpts =
opts && opts.format && !isJson(opts.format) ? yamlOpts : jsonOpts

opts = { defaultLocale: 'en', ...defautlOpts, ...opts }

const ext = isJson(opts.format) ? 'json' : 'yml'

const { defaultLocale, moduleName } = opts

const oldLocaleMaps = loadLocaleFiles(locales, buildDir, ext)

delete opts.defaultLocale

const extractorOptions = { defaultLocale, ...opts }

if (moduleName) {
extractorOptions.moduleSourceName = moduleName
}

const newLocaleMaps = await extractReactIntl(
locales,
pattern,
extractorOptions
)

return Promise.all(
locales.map(locale => {
// If the default locale, overwrite the origin file
let localeMap =
locale === defaultLocale
? // Create a clone so we can use only current valid messages below
{ ...oldLocaleMaps[locale], ...newLocaleMaps[locale] }
: { ...newLocaleMaps[locale], ...oldLocaleMaps[locale] }
// Only keep existing keys
localeMap = pick(localeMap, Object.keys(newLocaleMaps[locale]))

const fomattedLocaleMap = opts.flat
? sortKeys(localeMap, { deep: true })
: unflatten(sortKeys(localeMap), { object: true })

const fn = isJson(opts.format) ? writeJson : writeYaml

return fn(path.resolve(buildDir, locale), fomattedLocaleMap)
})
)
}
module.exports = fn
12 changes: 12 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
module.exports = {
testPathIgnorePatterns: [
'<rootDir>[/\\\\](dist|compiled|node_modules)[/\\\\]'
],
testEnvironment: 'node',
preset: 'ts-jest',
globals: {
'ts-jest': {
diagnostics: false
}
}
}
22 changes: 18 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@
"add-contributor": "all-contributors add",
"fmt": "prettier --write '**/*.{json,js,md}'",
"example": "./cli.js -l=en,ja -o example/i18n -d en 'example/**/*.js'",
"lint": "eslint index.js cli.js ./extract-react-intl/index.js",
"build": "tsc",
"lint": "eslint src/**/*.ts --fix --cache",
"test": "npm run lint && jest"
},
"bin": {
"extract-react-intl-messages": "cli.js",
"extract-messages": "cli.js"
},
"files": [
"extract-react-intl/index.js",
"dist",
"index.js",
"cli.js"
],
Expand Down Expand Up @@ -56,10 +57,21 @@
"write-json-file": "^4.1.1"
},
"devDependencies": {
"@akameco/tsconfig": "^0.3.0",
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/preset-env": "^7.5.5",
"@babel/preset-flow": "^7.0.0",
"@babel/preset-react": "^7.0.0",
"@types/flat": "^0.0.28",
"@types/jest": "^24.0.18",
"@types/js-yaml": "^3.12.1",
"@types/lodash.merge": "^4.6.6",
"@types/lodash.mergewith": "^4.6.6",
"@types/lodash.pick": "^4.4.6",
"@types/mkdirp": "^0.5.2",
"@types/pify": "^3.0.2",
"@types/temp-write": "^4.0.0",
"@types/tempy": "^0.3.0",
"all-contributors-cli": "^6.8.1",
"babel-core": "7.0.0-bridge.0",
"babel-jest": "^24.8.0",
Expand All @@ -71,9 +83,11 @@
"lint-staged": "^9.2.1",
"prettier": "^1.18.2",
"react": "^16.8.6",
"react-intl": "^3.1.10",
"react-intl": "^3.1.11",
"temp-write": "^4.0.0",
"tempy": "^0.3.0"
"tempy": "^0.3.0",
"ts-jest": "^24.0.2",
"typescript": "^3.5.3"
},
"lint-staged": {
"*.{js}": [
Expand Down
8 changes: 0 additions & 8 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ $ extract-messages --help
-f, --format json|yaml [default: json]
--flat json [default: true] | yaml [default: false]
--default-locale default locale [default: en]
--module-name module source name from where components are imported [default: react-intl]

Example
$ extract-messages --locales=ja,en --output app/translations 'app/**/*.js'
Expand Down Expand Up @@ -171,13 +170,6 @@ If format is `yaml`, set to `false`.
Be careful if `false`.
See [this issue](https://github.com/akameco/extract-react-intl-messages/issues/3).

##### moduleName

Type: `string`<br>
Default: `react-intl`

Set from where _defineMessages_, `<FormatterMessage />` and `<FormattedHTML />` are imported.

##### babel-plugin-react-intl's Options

See https://github.com/formatjs/formatjs/tree/master/packages/babel-plugin-react-intl#options
Expand Down
6 changes: 6 additions & 0 deletions src/babel__core.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import babel from '@babel/core'

declare module '@babel/core' {
function resolvePlugin(name: string, dirname: string): string | null
function resolvePreset(name: string, dirname: string): string | null
}
Loading

0 comments on commit 06537fa

Please sign in to comment.