config.ts 6.1 KB
Newer Older
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
1
/**
2
 *   Wechaty - https://github.com/wechaty/wechaty
3
 *
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
4
 *   @copyright 2016-2018 Huan LI <zixia@zixia.net>
5 6 7 8 9 10 11 12 13 14 15 16
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
17
 *
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
18
 */
19
// tslint:disable-next-line:no-reference
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
20
/// <reference path="./typings.d.ts" />
21

22 23 24
import fs    from 'fs'
import os    from 'os'
import path  from 'path'
25

Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
26 27
import qrImage    from 'qr-image'
import Raven      from 'raven'
28
import readPkgUp  from 'read-pkg-up'
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
29

Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
30 31 32
import { log }      from 'brolog'
import { FileBox }  from 'file-box'

33
import {
34
  PuppetModuleName,
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
35
  PUPPET_NAME_DEFAULT,
36 37
}                      from './puppet-config'
import { VERSION }      from './version'
38

39 40
const pkg = readPkgUp.sync({ cwd: __dirname })!.package

41 42 43 44 45 46
/**
 * Raven.io
 */
Raven.disableConsoleAlerts()

Raven
47 48 49 50 51 52 53 54
  .config(
    isProduction()
      && 'https://f6770399ee65459a82af82650231b22c:d8d11b283deb441e807079b8bb2c45cd@sentry.io/179672',
    {
      release: VERSION,
      tags: {
        git_commit: '',
        platform: process.env.WECHATY_DOCKER
55 56
          ? 'docker'
          : os.platform(),
57
      },
58
    },
59 60
  )
  .install()
61 62 63 64 65 66 67 68 69 70 71 72

/*
try {
    doSomething(a[0])
} catch (e) {
    Raven.captureException(e)
}

Raven.context(function () {
  doSomething(a[0])
})
 */
73

74
const logLevel = process.env.WECHATY_LOG
75
if (logLevel) {
76
  log.level(logLevel.toLowerCase() as any)
Huan (李卓桓)'s avatar
wip...  
Huan (李卓桓) 已提交
77
  log.silly('Config', 'WECHATY_LOG set level to %s', logLevel)
78 79 80 81 82
}

/**
 * to handle unhandled exceptions
 */
Huan (李卓桓)'s avatar
wip...  
Huan (李卓桓) 已提交
83
if (log.level() === 'verbose' || log.level() === 'silly') {
84 85 86 87 88 89
  log.info('Config', 'registering process.on("unhandledRejection") for development/debug')
  process.on('unhandledRejection', (reason, promise) => {
    log.error('Config', '###########################')
    log.error('Config', 'unhandledRejection: %s %s', reason, promise)
    log.error('Config', '###########################')
    promise.catch(err => {
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
90
      log.error('Config', 'process.on(unhandledRejection) promise.catch(%s)', err.message)
91 92 93
      console.error('Config', err) // I don't know if log.error has similar full trace print support like console.error
    })
  })
94
}
95

Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
96
export interface DefaultSetting {
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
97 98
  DEFAULT_HEAD     : number,
  DEFAULT_PORT     : number,
99
  // DEFAULT_PUPPET   : PuppetName,
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
100
  DEFAULT_APIHOST  : string,
101
  // DEFAULT_PROFILE  : string,
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
102 103
  DEFAULT_TOKEN    : string,
  DEFAULT_PROTOCOL : string,
104
}
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
105

Huan (李卓桓)'s avatar
wip...  
Huan (李卓桓) 已提交
106
const DEFAULT_SETTING = pkg.wechaty as DefaultSetting
107

Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
108
export class Config {
109

Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
110
  public default = DEFAULT_SETTING
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
111

112 113
  public apihost = process.env.WECHATY_APIHOST    || DEFAULT_SETTING.DEFAULT_APIHOST
  public head    = ('WECHATY_HEAD' in process.env) ? (!!process.env.WECHATY_HEAD) : (!!(DEFAULT_SETTING.DEFAULT_HEAD))
114

115
  public systemPuppetName (): PuppetModuleName {
116
    return (
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
117
      process.env.WECHATY_PUPPET || PUPPET_NAME_DEFAULT
118
    ).toLowerCase() as PuppetModuleName
119
  }
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
120

121 122 123 124 125 126
  // DEPRECATED: Use WECHATY_NAME instead
  public profile = process.env.WECHATY_PROFILE

  public name    = process.env.WECHATY_NAME || process.env.WECHATY_PROFILE  // replace WECHATY_PROFILE

  public token   = process.env.WECHATY_TOKEN      // DO NOT set DEFAULT, because sometimes user do not want to connect to io cloud service
127
  public debug   = !!(process.env.WECHATY_DEBUG)
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
128

129 130
  public httpPort = process.env.PORT || process.env.WECHATY_PORT || DEFAULT_SETTING.DEFAULT_PORT
  public docker = !!(process.env.WECHATY_DOCKER)
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
131

132
  // private _puppetInstance: Puppet | null = null
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
133

134
  constructor () {
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
135 136
    log.verbose('Config', 'constructor()')
    this.validApiHost(this.apihost)
137 138 139 140

    if (this.profile) {
      log.warn('Config', 'constructor() WECHATY_PROFILE is DEPRECATED, use WECHATY_NAME instead.')
    }
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
141
  }
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
142

143
  public gitRevision (): string | null {
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
144 145 146 147 148 149 150 151 152 153
    const dotGitPath  = path.join(__dirname, '..', '.git') // only for ts-node, not for dist
    // const gitLogArgs  = ['log', '--oneline', '-1']
    // TODO: use git rev-parse HEAD ?
    const gitArgs  = ['rev-parse', 'HEAD']

    try {
      // Make sure this is a Wechaty repository
      fs.statSync(dotGitPath).isDirectory()

      const ss = require('child_process')
154
        .spawnSync('git', gitArgs, { cwd:  __dirname })
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
155 156 157 158 159 160

      if (ss.status !== 0) {
        throw new Error(ss.error)
      }

      const revision = ss.stdout
161 162 163
        .toString()
        .trim()
        .slice(0, 7)
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
164 165 166 167 168 169 170 171 172
      return revision

    } catch (e) { /* fall safe */
      /**
       *  1. .git not exist
       *  2. git log fail
       */
      log.silly('Wechaty', 'version() form development environment is not availble: %s', e.message)
      return null
173
    }
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
174
  }
175

176
  public validApiHost (apihost: string): boolean {
177
    if (/^[a-zA-Z0-9.\-_]+:?[0-9]*$/.test(apihost)) {
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
178 179 180
      return true
    }
    throw new Error('validApiHost() fail for ' + apihost)
181
  }
182

183 184
}

185 186
export const CHATIE_OFFICIAL_ACCOUNT_ID = 'gh_051c89260e5d'

187
export function qrCodeForChatie (): FileBox {
188 189 190 191 192 193 194 195
  const CHATIE_OFFICIAL_ACCOUNT_QRCODE = 'http://weixin.qq.com/r/qymXj7DEO_1ErfTs93y5'
  const name                           = 'qrcode-for-chatie.png'
  const type                           = 'png'

  const qrStream = qrImage.image(CHATIE_OFFICIAL_ACCOUNT_QRCODE, { type })
  return FileBox.fromStream(qrStream, name)
}

Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
196 197 198
// http://jkorpela.fi/chars/spaces.html
// String.fromCharCode(8197)
export const FOUR_PER_EM_SPACE = String.fromCharCode(0x2005)
江子健 已提交
199 200
// mobile: \u2005, PC、mac: \u0020
export const AT_SEPRATOR_REGEX = /[\u2005\u0020]/
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
201

202
export function qrcodeValueToImageUrl (qrcodeValue: string): string {
203 204 205
  return [
    'https://api.qrserver.com/v1/create-qr-code/?data=',
    encodeURIComponent(qrcodeValue),
Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
206
    '&size=220x220&margin=20',
207 208 209
  ].join('')
}

210
export function isProduction (): boolean {
211 212 213 214
  return process.env.NODE_ENV === 'production'
      || process.env.NODE_ENV === 'prod'
}

215
export {
Huan (李卓桓)'s avatar
wip...  
Huan (李卓桓) 已提交
216
  log,
217
  Raven,
218
  VERSION,
219 220
}

Huan (李卓桓)'s avatar
Huan (李卓桓) 已提交
221
export const config = new Config()