Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

translation.js

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

translation.js - npm Package Compare versions

Comparing version 0.4.0 to 0.4.1

libs/APIs/_google.js

507

dist/translation.js
/*!
* translation.js v0.4.0
* translation.js v0.4.1
* https://github.com/Selection-Translator/translation.js#readme

@@ -70,2 +70,4 @@ * Copyright 2015 Milk Lee <milk.lee@qq.com>

var UNKNOWN_ERROR = 2
function Translation () {

@@ -135,23 +137,18 @@ this.APIs = {}

p.call = function (method, queryObj) {
var that = this
return new Promise(function (resolve, reject) {
var instances = that.APIs[queryObj.api]
if (!instances) {
return reject('没有注册 ' + queryObj.api + ' API。')
}
var instances = this.APIs[queryObj.api]
if (!instances) return Promise.reject('没有注册 ' + queryObj.api + ' API。')
var a = instances.shift()
instances.push(a)
a[method](queryObj).then(function (resultObj) {
if (method === 'translate') {
resultObj.api = a
}
resolve(resultObj)
var a = instances[0]
if (!a[method]) return Promise.reject(a.name + '不支持' + method + '方法。')
instances.push(instances.shift())
return a[method](queryObj)
.then(function (resultObj) {
if (method === 'translate') resultObj.api = a
return resultObj
}, function (superAgentError) {
if (superAgentError == null) {
return reject()
}
reject(analyzeErrorType(superAgentError))
if (superAgentError == null) return Promise.reject(UNKNOWN_ERROR)
return Promise.reject(analyzeErrorType(superAgentError))
})
})
}

@@ -163,4 +160,5 @@

tjs.SERVER_ERROR = SERVER_ERROR
tjs.UNKNOWN_ERROR = UNKNOWN_ERROR
// 绑定内置构造函数
// 绑定内置的翻译接口
tjs.BaiDu = __webpack_require__(1)

@@ -170,3 +168,3 @@ tjs.YouDao = __webpack_require__(4)

tjs.Google = __webpack_require__(6)
tjs.GoogleCN = __webpack_require__(7)
tjs.GoogleCN = __webpack_require__(9)

@@ -226,3 +224,3 @@ module.exports = tjs

this.type = 'BaiDu'
this.link = 'http://fanyi.baidu.com/'
this.link = 'http://fanyi.baidu.com'
}

@@ -249,20 +247,14 @@

var that = this
return new Promise(function (resolve, reject) {
superagent
.get(that.link + '/v2transapi')
.query({
from: standard2custom[queryObj.from] || 'auto',
to: standard2custom[queryObj.to] || 'zh', // 非标准接口一定要提供目标语种
query: queryObj.text,
transtype: 'hash',
simple_means_flag: 3
})
.end(function (err, res) {
if (err) {
reject(err)
} else {
resolve(that.transform(res.body, queryObj))
}
})
})
return superagent
.get(this.link + '/v2transapi')
.query({
from: standard2custom[queryObj.from] || 'auto',
to: standard2custom[queryObj.to] || 'zh', // 非标准接口一定要提供目标语种
query: queryObj.text,
transtype: 'hash',
simple_means_flag: 3
})
.then(function (res) {
return that.transform(res.body, queryObj)
})
}

@@ -301,7 +293,5 @@

try {
var detailed = []
rawRes.dict_result.simple_means.symbols[0].parts.forEach(function (v) {
detailed.push(v.part + ' ' + v.means.join(','))
obj.detailed = rawRes.dict_result.simple_means.symbols[0].parts.map(function (v) {
return v.part + ' ' + v.means.join(',')
})
obj.detailed = detailed
} catch (e) {}

@@ -324,3 +314,3 @@

/**
* 检测语种的方法, 返回的语种为百度自己格式的语种。
* 检测语种的方法
* @param {Query} queryObj

@@ -330,30 +320,13 @@ * @returns {Promise}

p.detect = function (queryObj) {
var that = this
return new Promise(function (resolve, reject) {
var from = queryObj.from
if (from) {
if (langResolve(from)) {
resolve(from)
} else {
reject(null)
return superagent
.post(this.link + '/langdetect')
.send('query=' + queryObj.text.slice(0, 73))
.then(function (res) {
var body = res.body
if (body.error === 0) {
var lang = langResolve(body.lan, true)
if (lang) return lang
}
return
}
superagent
.post(that.link + '/langdetect')
.send('query=' + queryObj.text.slice(0, 73))
.end(function (err, res) {
if (err) return reject(err)
var body = res.body
if (body.error === 0) {
var lang = langResolve(body.lan, true)
if (lang) return resolve(lang)
}
reject(null)
})
})
return null
})
}

@@ -367,5 +340,16 @@

p.audio = function (queryObj) {
return this
.detect(queryObj)
.then(function (lang) { return 'http://fanyi.baidu.com/gettts?lan=' + langResolve(lang) + '&text=' + queryObj.text + '&spd=2&source=web' })
var langPromise
if (queryObj.from) {
langPromise = Promise.resolve(langResolve(queryObj.from))
} else {
langPromise = this.detect(queryObj)
}
return langPromise
.then(function (lang) {
if (!lang) return null
var l = langResolve(lang)
return l
? this.link + '/gettts?lan=' + l + '&text=' + queryObj.text + '&spd=2&source=web'
: null
})
}

@@ -432,4 +416,14 @@

YouDao.resolve = langTransform
var TRANSLATE_PATH = '/openapi.do'
var ERROR = {
20: '有道翻译服务一次性只能翻译200个字符',
30: '有道翻译暂时无法翻译这段文本',
40: '有道翻译不支持这种语言',
50: 'api key被封禁',
60: '无词典结果'
}
YouDao.ERROR = ERROR
YouDao.TRANSLATE_PATH = TRANSLATE_PATH
/**

@@ -448,13 +442,7 @@ * 有道翻译构造函数

this.keyFrom = config.keyFrom
this.apiRoot = 'https://fanyi.youdao.com'
this.name = '有道翻译'
this.link = 'http://fanyi.youdao.com/'
this.link = 'http://fanyi.youdao.com'
this.type = 'YouDao'
this.errMsg = {
20: '有道翻译服务一次性只能翻译200个字符',
30: '有道翻译暂时无法翻译这段文本',
40: '有道翻译不支持这种语言',
50: 'api key被封禁',
60: '无词典结果'
}
}

@@ -471,21 +459,15 @@

var that = this
return new Promise(function (resolve, reject) {
request
.get('https://fanyi.youdao.com/openapi.do')
.query({
key: that.apiKey,
keyfrom: that.keyFrom,
type: 'data',
doctype: 'json',
version: '1.1',
q: queryObj.text
})
.end(function (err, res) {
if (err) {
reject(err)
} else {
resolve(that.transform(res.body, queryObj))
}
})
})
return request
.get(this.apiRoot + TRANSLATE_PATH)
.query({
key: that.apiKey,
keyfrom: that.keyFrom,
type: 'data',
doctype: 'json',
version: '1.1',
q: queryObj.text
})
.then(function (res) {
return that.transform(res.body, queryObj)
})
}

@@ -503,3 +485,3 @@

response: rawRes,
linkToResult: 'http://fanyi.youdao.com/translate?i=' + queryObj.text
linkToResult: this.link + '/translate?i=' + queryObj.text
}

@@ -511,3 +493,3 @@

if (rawRes.errorCode !== 0) {
obj.error = this.errMsg[rawRes.errorCode]
obj.error = ERROR[rawRes.errorCode]
} else {

@@ -536,19 +518,2 @@ // 详细释义

/**
* 检测语种的方法,有道没有,所以若没有提供源语种就总是返回 null
* @param {Query} queryObj
* @returns {Promise}
*/
p.detect = function (queryObj) {
return new Promise(function (resolve, reject) {
var from = queryObj.from
if (langTransform(from)) {
resolve(from)
} else {
reject(null)
}
})
}
/**
* 返回语音播放的 url

@@ -559,8 +524,5 @@ * @param queryObj

p.audio = function (queryObj) {
return this
.detect(queryObj)
.then(function (lang) {
var l = langTransform(lang)
return 'http://tts.youdao.com/fanyivoice?keyfrom=fanyi%2Eweb%2Eindex&le=' + l + '&word=' + queryObj.text
})
var lang = langTransform(queryObj.from)
if (!lang) return Promise.resolve(null)
return Promise.resolve('http://tts.youdao.com/fanyivoice?keyfrom=fanyi%2Eweb%2Eindex&le=' + lang + '&word=' + queryObj.text)
}

@@ -620,22 +582,15 @@

var that = this
return new Promise(function (resolve, reject) {
superagent
.post('http://dict.bing.com.cn/io.aspx')
.type('form')
.send({
t: 'dict',
ut: 'default',
q: queryObj.text,
ulang: 'AUTO',
tlang: 'AUTO'
})
.timeout(that.timeout)
.end(function (err, res) {
if (err) {
reject(err)
} else {
resolve(that.transform(res.text, queryObj))
}
})
})
return superagent
.post('http://dict.bing.com.cn/io.aspx')
.type('form')
.send({
t: 'dict',
ut: 'default',
q: queryObj.text,
ulang: 'AUTO',
tlang: 'AUTO'
})
.then(function (res) {
return that.transform(res.text, queryObj)
})
}

@@ -671,4 +626,3 @@

try {
var d = []
ROOT.DEF[0].SENS.forEach(function (v) {
obj.detailed = ROOT.DEF[0].SENS.map(function (v) {
var s = v.$POS + '. '

@@ -682,5 +636,4 @@ if (Array.isArray(v.SEN)) {

}
d.push(s)
return s
})
obj.detailed = d
} catch (e) {}

@@ -700,31 +653,30 @@

/**
* 使用必应翻译检测文本语种。
* @param queryObj
* @returns {Promise}
*/
p.detect = function (queryObj) {
return new Promise(function (resolve, reject) {
var from = queryObj.from
if (langTransform(from)) {
resolve(from)
} else {
reject(null)
}
})
}
module.exports = Bing
/**
* 暂时找不到必应的语音播放的接口。它网页上的语音播放没有规律可循。
* @returns {Promise}
*/
p.audio = function () {
return Promise.reject(null)
/***/ },
/* 6 */
/***/ function(module, exports, __webpack_require__) {
var _Google = __webpack_require__(7)
function Google () {
_Google.call(this)
this.name = '谷歌翻译'
this.type = 'Google'
this.apiRoot = this.link = 'https://translate.google.com'
// 若想在浏览器中使用谷歌翻译,
// 可以将 this.apiRoot 设为 'https://translate.googleapis.com'
// 这个接口是可跨域访问的
}
module.exports = Bing
Google.prototype = Object.create(_Google.prototype, {
constructor: { value: Google }
})
module.exports = Google
/***/ },
/* 6 */
/* 7 */
/***/ function(module, exports, __webpack_require__) {

@@ -736,15 +688,39 @@

var request = __webpack_require__(2)
var isEmpty = __webpack_require__(8)
var TRANSLATE_PATH = '/translate_a/single'
var AUDIO_PATH = '/translate_tts'
var ERROR = {
UNKNOWN: '发生了一个错误,可能是因为查询文本过长或请求频率太高造成的。',
NO_RESULT: '没有返回翻译结果,请稍后重试。'
}
_Google.TRANSLATE_PATH = TRANSLATE_PATH
_Google.AUDIO_PATH = AUDIO_PATH
_Google.ERROR = ERROR
/**
* 谷歌翻译
* 谷歌翻译的底层构造函数
*/
function Google () {
this.name = '谷歌翻译'
this.type = 'Google'
this.link = 'https://translate.google.com'
this.apiRoot = 'https://translate.googleapis.com'
function _Google () {
// 继承的构造函数需要提供下面的属性
// this.name
// this.type
// this.link
// this.apiRoot
}
var p = Google.prototype
// ISO839-1 Code from https://cloud.google.com/translate/docs/languages
var supportedLang = ['af', 'sq', 'am', 'ar', 'hy', 'az', 'eu', 'be', 'bn', 'bs',
'bg', 'ca', 'ceb', 'ny', 'zh-CN', 'zh-TW', 'co', 'hr', 'cs', 'da', 'nl', 'en',
'eo', 'et', 'tl', 'fi', 'fr', 'fy', 'gl', 'ka', 'de', 'el', 'gu', 'ht', 'ha',
'haw', 'iw', 'hi', 'hmn', 'hu', 'is', 'ig', 'id', 'ga', 'it', 'ja', 'jw', 'kn',
'kk', 'km', 'ko', 'ku', 'ky', 'lo', 'la', 'lv', 'lt', 'lb', 'mk', 'mg', 'ms',
'ml', 'mt', 'mi', 'mr', 'mn', 'my', 'ne', 'no', 'ps', 'fa', 'pl', 'pt', 'ma',
'ro', 'ru', 'sm', 'gd', 'sr', 'st', 'sn', 'sd', 'si', 'sk', 'sl', 'so', 'es',
'su', 'sw', 'sv', 'tg', 'ta', 'te', 'th', 'tr', 'uk', 'ur', 'uz', 'vi', 'cy',
'xh', 'yi', 'yo', 'zu']
var p = _Google.prototype
/**

@@ -756,31 +732,53 @@ * 翻译的方法

p.translate = function (queryObj) {
var acceptLanguage = queryObj.to
? queryObj.to + (queryObj.to.indexOf('-') > -1 ? ',' + queryObj.to.split('-')[0] : '')
: 'en'
acceptLanguage += ';q=0.8,en;q=0.6'
var that = this
return new Promise(function (resolve, reject) {
request
.get(this.apiRoot + '/translate_a/single')
.query('client=gtx&sl=' + (queryObj.from || 'auto') + '&tl=' + (queryObj.to || 'auto') + '&hl=zh-CN&dt=t&dt=bd&ie=UTF-8&oe=UTF-8&dj=1&source=icon&q=' + encodeURI(queryObj.text))
// {
// client : 'gtx' ,
// sl : 'auto' , // 源语言
// tl : queryObj.to || 'auto' , // 目标语言
// hl : 'zh-CN' ,
// dt : [ 't' , 'bd' ] , // 这个地方必须写成 &dt=t&dt=tl,所以没有用对象的方式声明
// dj : 1 ,
// source : 'icon' ,
// q : queryObj.text
// } )
.timeout(that.timeout)
.end(function (err, res) {
if (err) {
reject(err)
} else {
resolve(that.transform(res.body, queryObj))
}
})
})
return request
.get(this.apiRoot + TRANSLATE_PATH)
.set('Accept-Language', acceptLanguage) // it affects dict language
.query({
// for detect language, just {client: 'gtx', sl: auto, dj: 1, ie: 'UTF-8', oe: 'UTF-8', q: 'test'}
client: 'gtx',
sl: queryObj.from || 'auto', // source language
tl: queryObj.to || 'auto', // translated language
dj: 1, // ensure return json is GoogleRes structure
ie: 'UTF-8', // input string encoding
oe: 'UTF-8', // output string encoding
source: 'icon', // source
q: queryObj.text, // text to be translated
dt: ['t', 'bd'] // a list to add content to return json
// possible dt values: correspond return json key
// t: sentences
// rm: sentences[1]
// bd: dict
// at: alternative_translations
// ss: synsets
// rw: related_words
// ex: examples
// ld: ld_result
})
.then(function (res) {
return that.transform(res.body, queryObj)
})
}
/**
* Google 翻译返回的数据结构
* @typedef {Object} GoogleRes
* @property {String} src - 原字符串语种,ISO839-1 格式,如果 queryObj dt 为空,则返回 json 只有这一个字段
* @property {Object[]} sentences
* @property {{trans: String, orig: String, backend: Number}} sentences[0] trans:翻译结果,orig:被翻译的字符串
* @property {{translit: String, src_translit: String}} sentences[1] translit:翻译结果音标,src_translit:原字符串音标
* @property {{pos: String, terms: String[], entry: Object[]}[]} dict 查词结果,只有请求单个单词翻译时会有,
* 中翻英经常有,小语种经常没有 pos:词性 terms:词语列表 entry:对每个词的详解
* @property {{srclangs: String[], srclangs_confidences: Number[], extended_srclangs: String[]}} ld_result
*/
/**
* 将谷歌翻译的数据转换为统一格式
* @param rawRes
* @param {GoogleRes} rawRes
* @param queryObj

@@ -793,3 +791,2 @@ * @returns {{}}

to: queryObj.to || 'auto',
from: rawRes.src,
response: rawRes

@@ -801,24 +798,27 @@ }

if (typeof rawRes === 'string') {
obj.error = '谷歌翻译发生了一个错误,可能是因为查询文本过长造成的。'
obj.error = this.name + ERROR.UNKNOWN
} else {
// 尝试获取详细释义
try {
var d = []
rawRes.dict.forEach(function (v) {
d.push(v.pos + ':' + (v.terms.slice(0, 3) || []).join(','))
// 尝试获取详细释义
obj.detailed = rawRes.dict.map(function (v) {
return v.pos + ':' + (v.terms.slice(0, 3) || []).join(',')
})
obj.detailed = d
} catch (e) {}
// 尝试取得翻译结果
try {
var result = []
rawRes.sentences.forEach(function (v) {
result.push(v.trans)
// 尝试取得翻译结果
var sentences = rawRes.sentences.filter(function (sentence) {
return sentence.trans !== queryObj.text
})
obj.result = result
if (isEmpty(sentences)) {
obj.from = null
} else {
obj.from = rawRes.src
obj.result = sentences.map(function (sentence) {
return sentence.trans
})
}
} catch (e) {}
if (!obj.detailed && !obj.result) {
obj.error = this.name + '没有返回翻译结果,请稍后重试。'
if (isEmpty(obj.detailed) && isEmpty(obj.result)) {
obj.error = this.name + ERROR.NO_RESULT
}

@@ -835,14 +835,11 @@ }

p.detect = function (queryObj) {
var that = this
return new Promise(function (resolve, reject) {
var from = queryObj.from
var from = queryObj.from
if (from) {
return Promise.resolve(supportedLang.indexOf(from) > -1 ? from : null)
}
if (from) {
return resolve(from)
}
that
.translate(queryObj)
.then(function (result) { return resolve(result.from) }, reject)
})
return this.translate(queryObj)
.then(function (result) {
return Promise.resolve(result.from || null)
})
}

@@ -859,25 +856,49 @@

.then(function (lang) {
return encodeURI(that.apiRoot + '/translate_tts?ie=UTF-8&q=' + queryObj.text + '&tl=' + lang + '&client=gtx')
return supportedLang.indexOf(lang) > -1
? that.link + AUDIO_PATH + '?ie=UTF-8&q=' + encodeURIComponent(queryObj.text) + '&tl=' + lang + '&client=gtx'
: null
})
}
module.exports = Google
module.exports = _Google
/***/ },
/* 7 */
/* 8 */
/***/ function(module, exports) {
/**
* This things are empty
* 1. undefined, null, void 0, [], {},
* 2. object with .length === 0,
* 3. object without a own enumerable property
* @param {Object} obj
* @return Boolean
*/
module.exports = function isEmpty (obj) {
if (obj == null) return true
if (obj.length !== undefined) return obj.length === 0
return Object.keys(obj).length === 0
}
/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {
var Google = __webpack_require__(6)
var _Google = __webpack_require__(7)
function GoogleCN (config) {
var google = new Google(config)
google.name = '谷歌翻译(国内)'
google.type = 'GoogleCN'
google.link = 'https://translate.google.cn'
google.apiRoot = 'https://translate.google.cn'
return google
function GoogleCN () {
_Google.call(this)
this.name = '谷歌翻译(国内)'
this.type = 'GoogleCN'
this.apiRoot = this.link = 'https://translate.google.cn'
}
GoogleCN.prototype = Object.create(_Google.prototype, {
constructor: { value: GoogleCN }
})
module.exports = GoogleCN

@@ -884,0 +905,0 @@

@@ -47,3 +47,3 @@ /**

this.type = 'BaiDu'
this.link = 'http://fanyi.baidu.com/'
this.link = 'http://fanyi.baidu.com'
}

@@ -70,20 +70,14 @@

var that = this
return new Promise(function (resolve, reject) {
superagent
.get(that.link + '/v2transapi')
.query({
from: standard2custom[queryObj.from] || 'auto',
to: standard2custom[queryObj.to] || 'zh', // 非标准接口一定要提供目标语种
query: queryObj.text,
transtype: 'hash',
simple_means_flag: 3
})
.end(function (err, res) {
if (err) {
reject(err)
} else {
resolve(that.transform(res.body, queryObj))
}
})
})
return superagent
.get(this.link + '/v2transapi')
.query({
from: standard2custom[queryObj.from] || 'auto',
to: standard2custom[queryObj.to] || 'zh', // 非标准接口一定要提供目标语种
query: queryObj.text,
transtype: 'hash',
simple_means_flag: 3
})
.then(function (res) {
return that.transform(res.body, queryObj)
})
}

@@ -122,7 +116,5 @@

try {
var detailed = []
rawRes.dict_result.simple_means.symbols[0].parts.forEach(function (v) {
detailed.push(v.part + ' ' + v.means.join(','))
obj.detailed = rawRes.dict_result.simple_means.symbols[0].parts.map(function (v) {
return v.part + ' ' + v.means.join(',')
})
obj.detailed = detailed
} catch (e) {}

@@ -145,3 +137,3 @@

/**
* 检测语种的方法, 返回的语种为百度自己格式的语种。
* 检测语种的方法
* @param {Query} queryObj

@@ -151,30 +143,13 @@ * @returns {Promise}

p.detect = function (queryObj) {
var that = this
return new Promise(function (resolve, reject) {
var from = queryObj.from
if (from) {
if (langResolve(from)) {
resolve(from)
} else {
reject(null)
return superagent
.post(this.link + '/langdetect')
.send('query=' + queryObj.text.slice(0, 73))
.then(function (res) {
var body = res.body
if (body.error === 0) {
var lang = langResolve(body.lan, true)
if (lang) return lang
}
return
}
superagent
.post(that.link + '/langdetect')
.send('query=' + queryObj.text.slice(0, 73))
.end(function (err, res) {
if (err) return reject(err)
var body = res.body
if (body.error === 0) {
var lang = langResolve(body.lan, true)
if (lang) return resolve(lang)
}
reject(null)
})
})
return null
})
}

@@ -188,7 +163,18 @@

p.audio = function (queryObj) {
return this
.detect(queryObj)
.then(function (lang) { return 'http://fanyi.baidu.com/gettts?lan=' + langResolve(lang) + '&text=' + queryObj.text + '&spd=2&source=web' })
var langPromise
if (queryObj.from) {
langPromise = Promise.resolve(langResolve(queryObj.from))
} else {
langPromise = this.detect(queryObj)
}
return langPromise
.then(function (lang) {
if (!lang) return null
var l = langResolve(lang)
return l
? this.link + '/gettts?lan=' + l + '&text=' + queryObj.text + '&spd=2&source=web'
: null
})
}
module.exports = BaiDu

@@ -46,22 +46,15 @@ /**

var that = this
return new Promise(function (resolve, reject) {
superagent
.post('http://dict.bing.com.cn/io.aspx')
.type('form')
.send({
t: 'dict',
ut: 'default',
q: queryObj.text,
ulang: 'AUTO',
tlang: 'AUTO'
})
.timeout(that.timeout)
.end(function (err, res) {
if (err) {
reject(err)
} else {
resolve(that.transform(res.text, queryObj))
}
})
})
return superagent
.post('http://dict.bing.com.cn/io.aspx')
.type('form')
.send({
t: 'dict',
ut: 'default',
q: queryObj.text,
ulang: 'AUTO',
tlang: 'AUTO'
})
.then(function (res) {
return that.transform(res.text, queryObj)
})
}

@@ -97,4 +90,3 @@

try {
var d = []
ROOT.DEF[0].SENS.forEach(function (v) {
obj.detailed = ROOT.DEF[0].SENS.map(function (v) {
var s = v.$POS + '. '

@@ -108,5 +100,4 @@ if (Array.isArray(v.SEN)) {

}
d.push(s)
return s
})
obj.detailed = d
} catch (e) {}

@@ -126,26 +117,2 @@

/**
* 使用必应翻译检测文本语种。
* @param queryObj
* @returns {Promise}
*/
p.detect = function (queryObj) {
return new Promise(function (resolve, reject) {
var from = queryObj.from
if (langTransform(from)) {
resolve(from)
} else {
reject(null)
}
})
}
/**
* 暂时找不到必应的语音播放的接口。它网页上的语音播放没有规律可循。
* @returns {Promise}
*/
p.audio = function () {
return Promise.reject(null)
}
module.exports = Bing

@@ -1,12 +0,14 @@

var Google = require('./google')
var _Google = require('./_google')
function GoogleCN (config) {
var google = new Google(config)
google.name = '谷歌翻译(国内)'
google.type = 'GoogleCN'
google.link = 'https://translate.google.cn'
google.apiRoot = 'https://translate.google.cn'
return google
function GoogleCN () {
_Google.call(this)
this.name = '谷歌翻译(国内)'
this.type = 'GoogleCN'
this.apiRoot = this.link = 'https://translate.google.cn'
}
GoogleCN.prototype = Object.create(_Google.prototype, {
constructor: { value: GoogleCN }
})
module.exports = GoogleCN

@@ -1,128 +0,17 @@

/**
* 谷歌翻译支持几乎所有语种,并且它的语种格式就是标准的。
*/
var request = require('superagent')
var _Google = require('./_google')
/**
* 谷歌翻译
*/
function Google () {
_Google.call(this)
this.name = '谷歌翻译'
this.type = 'Google'
this.link = 'https://translate.google.com'
this.apiRoot = 'https://translate.googleapis.com'
this.apiRoot = this.link = 'https://translate.google.com'
// 若想在浏览器中使用谷歌翻译,
// 可以将 this.apiRoot 设为 'https://translate.googleapis.com'
// 这个接口是可跨域访问的
}
var p = Google.prototype
Google.prototype = Object.create(_Google.prototype, {
constructor: { value: Google }
})
/**
* 翻译的方法
* @param queryObj
* @returns {Promise}
*/
p.translate = function (queryObj) {
var that = this
return new Promise(function (resolve, reject) {
request
.get(this.apiRoot + '/translate_a/single')
.query('client=gtx&sl=' + (queryObj.from || 'auto') + '&tl=' + (queryObj.to || 'auto') + '&hl=zh-CN&dt=t&dt=bd&ie=UTF-8&oe=UTF-8&dj=1&source=icon&q=' + encodeURI(queryObj.text))
// {
// client : 'gtx' ,
// sl : 'auto' , // 源语言
// tl : queryObj.to || 'auto' , // 目标语言
// hl : 'zh-CN' ,
// dt : [ 't' , 'bd' ] , // 这个地方必须写成 &dt=t&dt=tl,所以没有用对象的方式声明
// dj : 1 ,
// source : 'icon' ,
// q : queryObj.text
// } )
.timeout(that.timeout)
.end(function (err, res) {
if (err) {
reject(err)
} else {
resolve(that.transform(res.body, queryObj))
}
})
})
}
/**
* 将谷歌翻译的数据转换为统一格式
* @param rawRes
* @param queryObj
* @returns {{}}
*/
p.transform = function (rawRes, queryObj) {
var obj = {
text: queryObj.text,
to: queryObj.to || 'auto',
from: rawRes.src,
response: rawRes
}
obj.linkToResult = this.link + '/#auto/' + obj.to + '/' + queryObj.text
if (typeof rawRes === 'string') {
obj.error = '谷歌翻译发生了一个错误,可能是因为查询文本过长造成的。'
} else {
// 尝试获取详细释义
try {
var d = []
rawRes.dict.forEach(function (v) {
d.push(v.pos + ':' + (v.terms.slice(0, 3) || []).join(','))
})
obj.detailed = d
} catch (e) {}
// 尝试取得翻译结果
try {
var result = []
rawRes.sentences.forEach(function (v) {
result.push(v.trans)
})
obj.result = result
} catch (e) {}
if (!obj.detailed && !obj.result) {
obj.error = this.name + '没有返回翻译结果,请稍后重试。'
}
}
return obj
}
/**
* 使用谷歌翻译检测文本语种。
* @param queryObj
* @returns {Promise}
*/
p.detect = function (queryObj) {
var that = this
return new Promise(function (resolve, reject) {
var from = queryObj.from
if (from) {
return resolve(from)
}
that
.translate(queryObj)
.then(function (result) { return resolve(result.from) }, reject)
})
}
/**
* 返回语音播放的 url
* @param queryObj
* @returns {Promise}
*/
p.audio = function (queryObj) {
var that = this
return this.detect(queryObj)
.then(function (lang) {
return encodeURI(that.apiRoot + '/translate_tts?ie=UTF-8&q=' + queryObj.text + '&tl=' + lang + '&client=gtx')
})
}
module.exports = Google

@@ -27,4 +27,14 @@ // @see http://fanyi.youdao.com/openapi?path=data-mode#bd

YouDao.resolve = langTransform
var TRANSLATE_PATH = '/openapi.do'
var ERROR = {
20: '有道翻译服务一次性只能翻译200个字符',
30: '有道翻译暂时无法翻译这段文本',
40: '有道翻译不支持这种语言',
50: 'api key被封禁',
60: '无词典结果'
}
YouDao.ERROR = ERROR
YouDao.TRANSLATE_PATH = TRANSLATE_PATH
/**

@@ -43,13 +53,7 @@ * 有道翻译构造函数

this.keyFrom = config.keyFrom
this.apiRoot = 'https://fanyi.youdao.com'
this.name = '有道翻译'
this.link = 'http://fanyi.youdao.com/'
this.link = 'http://fanyi.youdao.com'
this.type = 'YouDao'
this.errMsg = {
20: '有道翻译服务一次性只能翻译200个字符',
30: '有道翻译暂时无法翻译这段文本',
40: '有道翻译不支持这种语言',
50: 'api key被封禁',
60: '无词典结果'
}
}

@@ -66,21 +70,15 @@

var that = this
return new Promise(function (resolve, reject) {
request
.get('https://fanyi.youdao.com/openapi.do')
.query({
key: that.apiKey,
keyfrom: that.keyFrom,
type: 'data',
doctype: 'json',
version: '1.1',
q: queryObj.text
})
.end(function (err, res) {
if (err) {
reject(err)
} else {
resolve(that.transform(res.body, queryObj))
}
})
})
return request
.get(this.apiRoot + TRANSLATE_PATH)
.query({
key: that.apiKey,
keyfrom: that.keyFrom,
type: 'data',
doctype: 'json',
version: '1.1',
q: queryObj.text
})
.then(function (res) {
return that.transform(res.body, queryObj)
})
}

@@ -98,3 +96,3 @@

response: rawRes,
linkToResult: 'http://fanyi.youdao.com/translate?i=' + queryObj.text
linkToResult: this.link + '/translate?i=' + queryObj.text
}

@@ -106,3 +104,3 @@

if (rawRes.errorCode !== 0) {
obj.error = this.errMsg[rawRes.errorCode]
obj.error = ERROR[rawRes.errorCode]
} else {

@@ -131,19 +129,2 @@ // 详细释义

/**
* 检测语种的方法,有道没有,所以若没有提供源语种就总是返回 null
* @param {Query} queryObj
* @returns {Promise}
*/
p.detect = function (queryObj) {
return new Promise(function (resolve, reject) {
var from = queryObj.from
if (langTransform(from)) {
resolve(from)
} else {
reject(null)
}
})
}
/**
* 返回语音播放的 url

@@ -154,10 +135,7 @@ * @param queryObj

p.audio = function (queryObj) {
return this
.detect(queryObj)
.then(function (lang) {
var l = langTransform(lang)
return 'http://tts.youdao.com/fanyivoice?keyfrom=fanyi%2Eweb%2Eindex&le=' + l + '&word=' + queryObj.text
})
var lang = langTransform(queryObj.from)
if (!lang) return Promise.resolve(null)
return Promise.resolve('http://tts.youdao.com/fanyivoice?keyfrom=fanyi%2Eweb%2Eindex&le=' + lang + '&word=' + queryObj.text)
}
module.exports = YouDao

@@ -8,2 +8,4 @@ // 请求 API 接口时发生了网络错误

var UNKNOWN_ERROR = 2
function Translation () {

@@ -73,23 +75,18 @@ this.APIs = {}

p.call = function (method, queryObj) {
var that = this
return new Promise(function (resolve, reject) {
var instances = that.APIs[queryObj.api]
if (!instances) {
return reject('没有注册 ' + queryObj.api + ' API。')
}
var instances = this.APIs[queryObj.api]
if (!instances) return Promise.reject('没有注册 ' + queryObj.api + ' API。')
var a = instances.shift()
instances.push(a)
a[method](queryObj).then(function (resultObj) {
if (method === 'translate') {
resultObj.api = a
}
resolve(resultObj)
var a = instances[0]
if (!a[method]) return Promise.reject(a.name + '不支持' + method + '方法。')
instances.push(instances.shift())
return a[method](queryObj)
.then(function (resultObj) {
if (method === 'translate') resultObj.api = a
return resultObj
}, function (superAgentError) {
if (superAgentError == null) {
return reject()
}
reject(analyzeErrorType(superAgentError))
if (superAgentError == null) return Promise.reject(UNKNOWN_ERROR)
return Promise.reject(analyzeErrorType(superAgentError))
})
})
}

@@ -101,4 +98,5 @@

tjs.SERVER_ERROR = SERVER_ERROR
tjs.UNKNOWN_ERROR = UNKNOWN_ERROR
// 绑定内置构造函数
// 绑定内置的翻译接口
tjs.BaiDu = require('./APIs/baidu')

@@ -105,0 +103,0 @@ tjs.YouDao = require('./APIs/youdao')

{
"name": "translation.js",
"version": "0.4.0",
"version": "0.4.1",
"description": "集成多种翻译引擎、提供统一的翻译接口",

@@ -20,9 +20,9 @@ "main": "libs/index.js",

"dependencies": {
"superagent": "^2.3.0"
"superagent": "^3.0.0"
},
"devDependencies": {
"coveralls": "2.11.14",
"eslint": "3.9.1",
"coveralls": "2.11.15",
"eslint": "3.11.1",
"eslint-config-standard": "6.2.1",
"eslint-plugin-promise": "3.3.1",
"eslint-plugin-promise": "3.4.0",
"eslint-plugin-standard": "2.0.1",

@@ -29,0 +29,0 @@ "istanbul": "0.4.5",

@@ -6,3 +6,3 @@ # translation.js

[![dependencies Status](https://img.shields.io/david/Selection-Translator/translation.js.svg?style=flat-square)](https://david-dm.org/Selection-Translator/translation.js)
[![devDependencies Status](https://img.shields.io/david/dev/Selection-Translator/translation.js.svg?style=flat-square)](https://david-dm.org/Selection-Translator/translation.js#info=devDependencies)
[![devDependencies Status](https://img.shields.io/david/dev/Selection-Translator/translation.js.svg?style=flat-square)](https://david-dm.org/Selection-Translator/translation.js?type=dev)
[![NPM Version](https://img.shields.io/npm/v/translation.js.svg?style=flat-square)](https://www.npmjs.com/package/translation.js)

@@ -59,3 +59,3 @@

tjs.add(new tjs.Bing())
tjs.add(new tjs.YouDao({ key: 'xxx', keyFrom: 'xxx' }))
tjs.add(new tjs.YouDao({ apiKey: 'xxx', keyFrom: 'xxx' }))

@@ -62,0 +62,0 @@ // 使用有道翻译 'test'

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc