-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
120 lines (95 loc) · 3.49 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import fs from 'fs'
import path from 'path'
import through from 'through2'
import { transform } from 'babel-core'
import { PluginError, File, log, replaceExtension } from 'gulp-util'
module.exports = (opts) => {
const messages = []
const cwd = process.cwd()
const options = opts || {}
const name = 'gulp-react-intl-messages'
const filename = options.filename || `${name}.json`
/**
* Buffers react-intl messages into an array. Should not emit 'readable' or
* 'data' events until flushing the stream.
*
* @param {Object} file Vinyl
* @param {String} enc Encoding
* @param {Function} callback Process current file
*/
function bufferMessages (file, enc, callback) {
const msg = (text) => {
if (!options.silent) {
log(`[${name}] ${text}`)
}
}
const hasReactIntl = (plugin) => {
return typeof plugin === 'string' && /react-intl$/.test(plugin)
}
const getBabelConfig = () => {
const pkgPath = path.join(cwd, 'package.json')
const brcPath = path.join(cwd, '.babelrc')
try {
const pkg = require(pkgPath)
if (pkg.babel) {
msg(`Using babel options found at ${pkgPath}`)
return pkg.babel
}
} catch (error) { /* Ignore error */ }
msg(`No babel options found at ${pkgPath}`)
try {
const babelrcFile = fs.readFileSync(brcPath)
const babelrc = JSON.parse(babelrcFile)
msg(`Using babel options found at ${brcPath}`)
return babelrc
} catch (error) {
let errMsg = `Invalid JSON from ${brcPath}: ${error.message}`
if (error.code === 'ENOENT') {
errMsg = `No babel options found at ${brcPath}`
}
msg(errMsg)
msg('Using default of { plugins: ["react-intl"] }')
return { plugins: ['react-intl'] }
}
}
if (file.isNull()) {
return callback()
}
if (file.isStream()) {
return callback(new PluginError(name, 'Streaming not supported.'))
}
if (!options.babel) {
msg('No options.babel passed')
options.babel = getBabelConfig()
}
if (!options.babel.plugins) {
options.babel.plugins = []
}
if (!Array.isArray(options.babel.plugins)) {
return callback(new PluginError(name, 'options.babel.plugins must be an array: See https://babeljs.io/docs/usage/api/#options'))
}
if (!options.babel.plugins.some(hasReactIntl)) {
options.babel.plugins.push('react-intl')
}
try {
const trans = transform(file.contents.toString(), options.babel)
const msgs = trans.metadata['react-intl'].messages
if (msgs.length) {
messages.push(...msgs)
}
} catch (error) {
return callback(new PluginError(name, error))
}
callback()
}
function flush (callback) {
if (messages.length) {
this.push(new File({
path: path.join(cwd, replaceExtension(filename, '.json')),
contents: Buffer.from(JSON.stringify(messages, null, '\t'))
}))
}
callback()
}
return through.obj(bufferMessages, flush)
}