author linhuiw
 *  desc import * as _ from 'lodash' ; import * as vscode from 'vscode' ; import * as fs from 'fs-extra' ; import * as path from 'path' ; import * as slash from 'slash2' ; import { pinyin } from 'pinyin-pro' ; import { TranslateAPiEnum } from './define' ; param obj param prefix export function flatten ( obj , prefix ? ) { var propName = prefix ? prefix + '.' : '' , ret = { } ; for ( var attr in obj ) { if ( _ . isArray ( obj [ attr ] ) ) { var len = obj [ attr ] . length ; ret [ attr ] = obj [ attr ] . join ( ',' ) ; } else if ( typeof obj [ attr ] === 'object' ) { _ . extend ( ret , flatten ( obj [ attr ] , propName + attr ) ) ; } else { ret [ propName + attr ] = obj [ attr ] ; } } return ret ; } /**
 * 查找当前位置的 Code
 */ export function findPositionInCode ( text , code ) { const lines = code . split ( '\n' ) ; const lineNum = lines . findIndex ( line => line . includes ( text ) ) ; if ( lineNum === - 1 ) { return null ; } let chNum = lines [ lineNum ] . indexOf ( text ) ; if ( text . startsWith ( ' ' ) ) { chNum += 1 ; } return new vscode . Position ( lineNum , chNum ) ; } export function findMatchKey ( langObj , text ) { for ( const key in langObj ) { if ( langObj [ key ] === text ) { return key ; } } return null ; } function param { string } dir return { string [ ] } export const getAllFiles = dir => fs . readdirSync ( dir ) . reduce ( ( files , file ) => { if ( file === 'node_modules' ) { return [ ... files ] ; } const name = path . join ( dir , file ) ; const isDirectory = fs . statSync ( name ) . isDirectory ( ) ; return isDirectory ? [ ... files , ... getAllFiles ( name ) ] : [ ... files , name ] ; } , [ ] ) ; /**
 * 获取文件 Json
 */ export function getLangJson ( fileName ) { const fileContent = fs . readFileSync ( fileName , { encoding : 'utf8' } ) ; let obj = fileContent . match ( /export\s*default\s*({[\s\S]+);?$/ ) [ 1 ] ; obj = obj . replace ( /\s*;\s*$/ , '' ) ; let jsObj = { } ; try { jsObj = eval ( '(' + obj + ')' ) ; } catch ( err ) { console . log ( obj ) ; console . error ( err ) ; } return jsObj ; } /**
 * 获取配置，支持从vscode和配置文件(优先)中取到配置项
 */ export const getConfiguration = text => { let value = vscode . workspace . getConfiguration ( 'vscode-i18n-linter' ) . get ( text ) ; let kiwiConfigJson = getConfigFile ( ) ; if ( ! kiwiConfigJson ) { return value ; } const config = getLangJson ( kiwiConfigJson ) ; if ( text in config ) { value = config [ text ] ; } return value ; } ; /**
 * 查找kiwi-cli配置文件
 */ export const getConfigFile = ( ) => { let kiwiConfigJson = `${ vscode . workspace . workspaceFolders [ 0 ] . uri . fsPath }/.kiwirc.js` ; if ( ! fs . existsSync ( kiwiConfigJson ) ) { kiwiConfigJson = `${ vscode . workspace . workspaceFolders [ 0 ] . uri . fsPath }/.kiwirc.ts` ; if ( ! fs . existsSync ( kiwiConfigJson ) ) { return null ; } } return kiwiConfigJson ; } ; /**
 * 查找kiwi-linter配置文件
 */ export const getKiwiLinterConfigFile = ( ) => { let kiwiConfigJson = `${ vscode . workspace . workspaceFolders [ 0 ] . uri . fsPath }/kiwi-config.json` ; if ( ! fs . existsSync ( kiwiConfigJson ) ) { return null ; } return kiwiConfigJson ; } ; /**
 * 获得项目配置信息中的 googleApiKey
 */ function getConfigByKey ( key ) { const configFile = `${ vscode . workspace . workspaceFolders [ 0 ] . uri . fsPath }/kiwi-config.json` ; let content = '' ; try { if ( fs . existsSync ( configFile ) ) { content = JSON . parse ( fs . readFileSync ( configFile , 'utf8' ) ) [ key ] ; } } catch ( error ) { console . log ( error ) ; } return content ; } param asyncOperation param times function retry ( asyncOperation , times = 1 ) { let runTimes = 1 ; const handleReject = e => { if ( runTimes ++ < times ) { return asyncOperation ( ) . catch ( handleReject ) ; } else { throw e ; } } ; return asyncOperation ( ) . catch ( handleReject ) ; } param promise param ms function withTimeout ( promise , ms ) { const timeoutPromise = new Promise ( ( resolve , reject ) => { setTimeout ( ( ) => { reject ( `Promise timed out after ${ ms } ms.` ) ; } , ms ) ; } ) ; return Promise . race ( [ promise , timeoutPromise ] ) ; } /**
 * 翻译中文
 */ export function translateText ( text , type ) { const googleApiKey = getConfigByKey ( 'googleApiKey' ) ; const { translate : googleTranslate } = require ( 'google-translate' ) ( googleApiKey ) ; const { appId , appKey } = getConfigByKey ( 'baiduApiKey' ) ; const baiduTranslate = require ( 'baidu-translate' ) ; function _translateText ( ) { return withTimeout ( new Promise ( ( resolve , reject ) => { if ( type === TranslateAPiEnum . Google ) { googleTranslate ( text , 'zh' , 'en' , ( err , translation ) => { if ( err ) { reject ( err ) ; } else { const result = translation . translatedText ? translation . translatedText . split ( '$' ) : [ ] ; resolve ( result ) ; } } ) ; } if ( type === TranslateAPiEnum . Baidu ) { baiduTranslate ( appId , appKey , 'en' , 'zh' ) ( text ) . then ( data => { if ( data && data . trans_result ) { const result = data . trans_result [ 0 ] ? data . trans_result [ 0 ] . dst . split ( '$' ) : [ ] ; resolve ( result ) ; } } ) . catch ( err => { reject ( err ) ; } ) ; } if ( type === TranslateAPiEnum . PinYin ) { const result = pinyin ( text , { toneType : 'none' } ) ; resolve ( result . split ( '$' ) ) ; } } ) , 3000 ) ; } return retry ( _translateText , 3 ) ; } /**
 * 获取多项目配置
 */ export function getTargetLangPath ( currentFilePath ) { const configFile = `${ vscode . workspace . workspaceFolders [ 0 ] . uri . fsPath }/kiwi-config.json` ; let targetLangPath = '' ; try { if ( fs . existsSync ( configFile ) ) { const { projects = [ ] } = JSON . parse ( fs . readFileSync ( configFile , 'utf8' ) ) ; for ( const config of projects ) { if ( currentFilePath . indexOf ( `/${ config . target }/` ) > - 1 ) { targetLangPath = `${ vscode . workspace . workspaceFolders [ 0 ] . uri . fsPath }/${ config . kiwiDir }/zh_CN/` ; return targetLangPath ; } } } } catch ( error ) { console . log ( error ) ; } return targetLangPath ; } /**
 * 获取当前文件对应的项目路径
 */ export function getCurrentProjectLangPath ( ) { let currentProjectLangPath = '' ; const targetLangPath = getTargetLangPath ( vscode . window . activeTextEditor . document . uri . path ) ; if ( targetLangPath ) { currentProjectLangPath = `${ targetLangPath }**/*.ts` ; } return currentProjectLangPath ; } /**
 * 获取当前文件对应的语言路径
 */ export function getLangPrefix ( ) { const langPrefix = getTargetLangPath ( vscode . window . activeTextEditor . document . uri . path ) ; return langPrefix ; } /**
 * 获取当前文件路径层级 [pageA, moudleA, componentA]
 */ export function getCurrActivePageI18nKey ( ) { const activeEditor = vscode . window . activeTextEditor ; let suggestion = [ ] ; if ( activeEditor ) { const currentFilename = activeEditor . document . fileName ; const suggestPageRegex = /\/pages\/\w+\/([^\/]+)\/([^\/\.]+)/ ; if ( currentFilename . includes ( '/pages/' ) ) { suggestion = currentFilename . match ( suggestPageRegex ) ; } if ( suggestion && suggestion . length ) { suggestion . shift ( ) ; } else { const names = slash ( currentFilename ) . split ( '/' ) as string [ ] ; const fileName = _ . last ( names ) ; const fileKey = fileName . split ( '.' ) [ 0 ] . replace ( new RegExp ( '-' , 'g' ) , '_' ) ; const dir = names [ names . length - 2 ] . replace ( new RegExp ( '-' , 'g' ) , '_' ) ; if ( dir === fileKey ) { suggestion = [ dir ] ; } else { suggestion = [ dir , fileKey ] ; } } } return suggestion ; } /**
 * 检测翻译源
 */ export function getTranslateAPiList ( ) { let apiList = [ { label : TranslateAPiEnum . PinYin , description : '拼音' } ] ; const googleApiKey = getConfigByKey ( 'googleApiKey' ) ; const { appId , appKey } = getConfigByKey ( 'baiduApiKey' ) ; if ( appId && appKey ) { apiList . push ( { label : TranslateAPiEnum . Baidu , description : '百度' } ) ; } return apiList ; }