diff --git a/bin/doctor.ts b/bin/doctor.ts index 291ba551a06d29c1ab1f9ba6503b2c8165c654ae..b0ec67a9e1aabfe503230090eeb429b53e0dec5c 100644 --- a/bin/doctor.ts +++ b/bin/doctor.ts @@ -20,9 +20,9 @@ import * as os from 'os' -import Config from '../src/config' -import Doctor from '../src/doctor' -import Wechaty from '../src/wechaty' +import { config } from '../src/config' +import { Doctor } from '../src/doctor' +import { Wechaty } from '../src/wechaty' const wechaty = Wechaty.instance() const doctor = new Doctor() @@ -43,7 +43,7 @@ async function main() { 1. Wechaty version: ${wechaty.version()} 2. ${os.type()} ${os.arch()} version ${os.release()} memory ${Math.floor(os.freemem() / 1024 / 1024)}/${Math.floor(os.totalmem() / 1024 / 1024)} MB - 3. Docker: ${Config.dockerMode} + 3. Docker: ${config.dockerMode} 4. Node version: ${process.version} 5. Tcp IPC TEST: ${ipcTestResult} 6. Chromedriver: ${chromedriverVersion} diff --git a/bin/io-client.ts b/bin/io-client.ts index 2ef9ed8135e1b41751500e6d39580b75557ee4da..faeacd9c17660f8430a4db288607f29601a7ca8d 100644 --- a/bin/io-client.ts +++ b/bin/io-client.ts @@ -19,7 +19,7 @@ */ import { - Config, + config, log, } from '../src/config' @@ -42,12 +42,12 @@ __________________________________________________ ` -let token = Config.token +let token = config.token if (!token) { log.error('Client', 'token not found: please set WECHATY_TOKEN in environment before run io-client') // process.exit(-1) - token = Config.DEFAULT_TOKEN + token = config.DEFAULT_TOKEN log.warn('Client', `set token to "${token}" for demo purpose`) } diff --git a/example/api-ai-bot.ts b/example/api-ai-bot.ts index 3ae282ab438c761da5fa382bbae9710a1c4bd063..13bd38c4aad583654b1597ed8e8464ae1f85a10c 100644 --- a/example/api-ai-bot.ts +++ b/example/api-ai-bot.ts @@ -41,7 +41,7 @@ import { EventEmitter } from 'events' * when you are runing with Docker or NPM instead of Git Source. */ import { - Config, + config, Wechaty, } from '../' @@ -56,7 +56,7 @@ import { const APIAI_API_KEY = '7217d7bce18c4bcfbe04ba7bdfaf9c08' const brainApiAi = ApiAi(APIAI_API_KEY) -const bot = Wechaty.instance({ profile: Config.DEFAULT_PROFILE }) +const bot = Wechaty.instance({ profile: config.DEFAULT_PROFILE }) console.log(` Welcome to api.AI Wechaty Bot. diff --git a/example/contact-bot.ts b/example/contact-bot.ts index f7714a4f0ca7e761edb5950cc76cbf75e5c504d4..cbdeb7634ca71fa56f1e64b28125f203489b1af4 100644 --- a/example/contact-bot.ts +++ b/example/contact-bot.ts @@ -28,7 +28,7 @@ const QrcodeTerminal = require('qrcode-terminal') * when you are runing with Docker or NPM instead of Git Source. */ import { - Config, + config, Contact, Wechaty, log, @@ -54,7 +54,7 @@ Please wait... I'm trying to login in... ` console.log(welcome) -const bot = Wechaty.instance({ profile: Config.DEFAULT_PROFILE }) +const bot = Wechaty.instance({ profile: config.DEFAULT_PROFILE }) bot .on('login' , function(this, user) { diff --git a/example/ding-dong-bot.ts b/example/ding-dong-bot.ts index be3ee5e1f8291699df0da2d9ed6c4c7562542355..368ee86936d1daef75f61cd9754ae8dd1cc2fbe2 100644 --- a/example/ding-dong-bot.ts +++ b/example/ding-dong-bot.ts @@ -27,7 +27,7 @@ const finis = require('finis') * when you are runing with Docker or NPM instead of Git Source. */ import { - Config, + config, Wechaty, log, MediaMessage, @@ -57,7 +57,7 @@ Please wait... I'm trying to login in... ` console.log(welcome) -const bot = Wechaty.instance({ profile: Config.DEFAULT_PROFILE }) +const bot = Wechaty.instance({ profile: config.DEFAULT_PROFILE }) bot .on('logout' , user => log.info('Bot', `${user.name()} logouted`)) diff --git a/example/friend-bot.ts b/example/friend-bot.ts index f304a4e12c70f8688a7084d7de856a25d7839dc3..b4f358479ebc09e0f5cfe8ed9c1e8d2ba3039cd7 100644 --- a/example/friend-bot.ts +++ b/example/friend-bot.ts @@ -26,10 +26,10 @@ const QrcodeTerminal = require('qrcode-terminal') * when you are runing with Docker or NPM instead of Git Source. */ import { - Wechaty, + config, Contact, - Config, log, + Wechaty, } from '../' const welcome = ` @@ -57,7 +57,7 @@ Please wait... I'm trying to login in... ` console.log(welcome) -const bot = Wechaty.instance({ profile: Config.DEFAULT_PROFILE }) +const bot = Wechaty.instance({ profile: config.DEFAULT_PROFILE }) bot .on('login' , user => log.info('Bot', `${user.name()} logined`)) diff --git a/example/gist-bot/index.ts b/example/gist-bot/index.ts index a22f430a1de31c6b9c7438892ddf2daf194a4909..eb9f8340cb0d84c01903fe1193317dd296834cd9 100644 --- a/example/gist-bot/index.ts +++ b/example/gist-bot/index.ts @@ -23,7 +23,7 @@ * when you are runing with Docker or NPM instead of Git Source. */ import { - Config, + config, Wechaty, log, } from '../../' @@ -41,7 +41,7 @@ Please wait... I'm trying to login in... ` console.log(welcome) -Wechaty.instance({ profile: Config.DEFAULT_PROFILE }) +Wechaty.instance({ profile: config.DEFAULT_PROFILE }) .on('scan', (url, code) => { if (!/201|200/.test(String(code))) { diff --git a/example/media-file-bot.ts b/example/media-file-bot.ts index 9e75ffe8c8cd3bee4aedc7bdcafdf3b3ea712d65..f64e9e4b8ea150695dc685409e3990d3754df8cf 100644 --- a/example/media-file-bot.ts +++ b/example/media-file-bot.ts @@ -32,12 +32,12 @@ import * as qrcodeTerminal from 'qrcode-terminal' * when you are runing with Docker or NPM instead of Git Source. */ import { - Config, + config, Message, MsgType, Wechaty, } from '../' -const bot = Wechaty.instance({ profile: Config.DEFAULT_PROFILE }) +const bot = Wechaty.instance({ profile: config.DEFAULT_PROFILE }) bot .on('scan', (url, code) => { diff --git a/example/room-bot.ts b/example/room-bot.ts index c8209b1d70ce03ca0ba90fdf0a536c568f5e2a7b..73e641a75bc3964e4be0894df185fb6976a081d9 100644 --- a/example/room-bot.ts +++ b/example/room-bot.ts @@ -53,7 +53,7 @@ const qrcodeTerminal = require('qrcode-terminal') * when you are runing with Docker or NPM instead of Git Source. */ import { - Config, + config, Contact, Room, Wechaty, @@ -86,7 +86,7 @@ Please wait... I'm trying to login in... ` console.log(welcome) -const bot = Wechaty.instance({ profile: Config.DEFAULT_PROFILE }) +const bot = Wechaty.instance({ profile: config.DEFAULT_PROFILE }) bot .on('scan', (url, code) => { diff --git a/example/speech-to-text-bot.ts b/example/speech-to-text-bot.ts index d61f306e62ccc039a923f88fb26601ed925d94ac..e8c49ded7fd89ee2570f3a36b9310c89e9576e12 100644 --- a/example/speech-to-text-bot.ts +++ b/example/speech-to-text-bot.ts @@ -33,13 +33,13 @@ const qrcodeTerminal = require('qrcode-terminal') * when you are runing with Docker or NPM instead of Git Source. */ import { - Config, + config, MediaMessage, MsgType, Wechaty, } from '../' -const bot = Wechaty.instance({ profile: Config.DEFAULT_PROFILE }) +const bot = Wechaty.instance({ profile: config.DEFAULT_PROFILE }) bot .on('scan', (url, code) => { diff --git a/example/tuling123-bot.ts b/example/tuling123-bot.ts index a530e98be20a8010371e7b0e66649bc95e139952..0de887dfdc7cbdd5e593550ff1b832ac73f5adc3 100644 --- a/example/tuling123-bot.ts +++ b/example/tuling123-bot.ts @@ -36,7 +36,7 @@ const Tuling123 = require('tuling123-client') * when you are runing with Docker or NPM instead of Git Source. */ import { - Config, + config, Wechaty, log, } from '../' @@ -53,7 +53,7 @@ import { const TULING123_API_KEY = '18f25157e0446df58ade098479f74b21' const tuling = new Tuling123(TULING123_API_KEY) -const bot = Wechaty.instance({ profile: Config.DEFAULT_PROFILE }) +const bot = Wechaty.instance({ profile: config.DEFAULT_PROFILE }) console.log(` Welcome to Tuling Wechaty Bot. diff --git a/index.ts b/index.ts index 65b3e986f6fc770e526647fae98a344c24c607ff..1a37dd03d3fc588fd00e5d7d3ab98a3cd6f942db 100644 --- a/index.ts +++ b/index.ts @@ -1,7 +1,7 @@ import { - Config, - Sayable, + config, log, + Sayable, } from './src/config' import Contact from './src/contact' @@ -23,7 +23,7 @@ import Wechaty from './src/wechaty' const VERSION = require('./package.json').version export { - Config, + config, Contact, FriendRequest, IoClient, diff --git a/src/config.spec.ts b/src/config.spec.ts index a60e7a28de60baf46066696f3fe2d2b9c5682068..a03e1505d621863efaa8bdc1b452a4ed6e63702c 100644 --- a/src/config.spec.ts +++ b/src/config.spec.ts @@ -18,24 +18,24 @@ */ import { test } from 'ava' -import { Config } from './config' +import { config } from './config' import { Puppet } from './puppet' test('important variables', t => { - t.true('head' in Config, 'should exist `head` in Config') - t.true('puppet' in Config, 'should exist `puppet` in Config') - t.true('apihost' in Config, 'should exist `apihost` in Config') - t.true('port' in Config, 'should exist `port` in Config') - t.true('profile' in Config, 'should exist `profile` in Config') - t.true('token' in Config, 'should exist `token` in Config') + t.true('head' in config, 'should exist `head` in Config') + t.true('puppet' in config, 'should exist `puppet` in Config') + t.true('apihost' in config, 'should exist `apihost` in Config') + t.true('port' in config, 'should exist `port` in Config') + t.true('profile' in config, 'should exist `profile` in Config') + t.true('token' in config, 'should exist `token` in Config') - t.truthy(Config.DEFAULT_PUPPET , 'should export DEFAULT_PUPPET') - t.truthy(Config.DEFAULT_PORT , 'should export DEFAULT_PORT') - t.truthy(Config.DEFAULT_PROFILE , 'should export DEFAULT_PROFILE') - t.truthy(Config.DEFAULT_HEAD , 'should export DEFAULT_HEAD') - t.truthy(Config.DEFAULT_PROTOCOL , 'should export DEFAULT_PROTOCOL') - t.truthy(Config.DEFAULT_APIHOST , 'should export DEFAULT_APIHOST') - t.truthy(Config.CMD_CHROMIUM , 'should export CMD_CHROMIUM') + t.truthy(config.DEFAULT_PUPPET , 'should export DEFAULT_PUPPET') + t.truthy(config.DEFAULT_PORT , 'should export DEFAULT_PORT') + t.truthy(config.DEFAULT_PROFILE , 'should export DEFAULT_PROFILE') + t.truthy(config.DEFAULT_HEAD , 'should export DEFAULT_HEAD') + t.truthy(config.DEFAULT_PROTOCOL , 'should export DEFAULT_PROTOCOL') + t.truthy(config.DEFAULT_APIHOST , 'should export DEFAULT_APIHOST') + t.truthy(config.CMD_CHROMIUM , 'should export CMD_CHROMIUM') }) test('validApiHost()', t => { @@ -49,12 +49,12 @@ test('validApiHost()', t => { ] OK_APIHOSTS.forEach(apihost => { t.notThrows(() => { - Config.validApiHost(apihost) + config.validApiHost(apihost) }) }, 'should not row for right apihost') ERR_APIHOSTS.forEach(apihost => { t.throws(() => { - Config.validApiHost(apihost) + config.validApiHost(apihost) }) }, 'should throw for error apihost') @@ -62,30 +62,30 @@ test('validApiHost()', t => { test('puppetInstance()', t => { t.throws(() => { - Config.puppetInstance() + config.puppetInstance() }, Error, 'should throw when not initialized') const EXPECTED = {userId: 'test'} const mockPuppet = EXPECTED - Config.puppetInstance(mockPuppet) - const instance = Config.puppetInstance() + config.puppetInstance(mockPuppet) + const instance = config.puppetInstance() t.deepEqual(instance, EXPECTED, 'should equal with initialized data') - Config.puppetInstance(null) + config.puppetInstance(null) t.throws(() => { - Config.puppetInstance() + config.puppetInstance() }, Error, 'should throw after set to null') }) test('dockerMode', t => { - t.true('dockerMode' in Config, 'should identify docker env by `dockerMode`') + t.true('dockerMode' in config, 'should identify docker env by `dockerMode`') if ('C9_PORT' in process.env) { - t.is(Config.dockerMode, false, 'should not in docker mode in Cloud9 IDE') + t.is(config.dockerMode, false, 'should not in docker mode in Cloud9 IDE') } else if (require('is-ci')) { - t.is(Config.dockerMode, false, 'should not in docker mode in Continuous Integeration System') + t.is(config.dockerMode, false, 'should not in docker mode in Continuous Integeration System') } else { // a custom running envioronment, maybe docker, maybe not } diff --git a/src/config.ts b/src/config.ts index 18b7c10daef1d3162882a52cd05a3e8927e2ee43..98db4f5ff26945e41820322992f37a22299658ac 100644 --- a/src/config.ts +++ b/src/config.ts @@ -16,7 +16,43 @@ * limitations under the License. * */ -import * as os from 'os' +import * as fs from 'fs' +import * as os from 'os' +import * as path from 'path' + +/** + * Raven.io + */ +import * as Raven from 'raven' +Raven.disableConsoleAlerts() + +Raven +.config( + process.env.NODE_ENV === 'production' + && 'https://f6770399ee65459a82af82650231b22c:d8d11b283deb441e807079b8bb2c45cd@sentry.io/179672', + { + release: require('../package.json').version, + tags: { + git_commit: 'c0deb10c4', + platform: !!process.env('WECHATY_DOCKER') + ? 'docker' + : os.platform(), + }, + }, +) +.install() + +/* +try { + doSomething(a[0]) +} catch (e) { + Raven.captureException(e) +} + +Raven.context(function () { + doSomething(a[0]) +}) + */ // const isCi = require('is-ci') // const isDocker = require('is-docker') @@ -78,22 +114,24 @@ export interface ConfigSetting { puppetInstance(): Puppet puppetInstance(empty: null): void puppetInstance(instance: Puppet): void - puppetInstance(instance?: Puppet | null): Puppet | void + puppetInstance(instance?: Puppet | null): Puppet | void, - dockerMode: boolean + gitVersion(): string | null, + npmVersion(): string, + dockerMode: boolean, } /* tslint:disable:variable-name */ /* tslint:disable:no-var-requires */ -export const Config: ConfigSetting = require('../package.json').wechaty +export const config: ConfigSetting = require('../package.json').wechaty /** * 1. ENVIRONMENT VARIABLES + PACKAGES.JSON (default) */ -Object.assign(Config, { - apihost: process.env['WECHATY_APIHOST'] || Config.DEFAULT_APIHOST, - head: process.env['WECHATY_HEAD'] || Config.DEFAULT_HEAD, - puppet: process.env['WECHATY_PUPPET'] || Config.DEFAULT_PUPPET, +Object.assign(config, { + apihost: process.env['WECHATY_APIHOST'] || config.DEFAULT_APIHOST, + head: process.env['WECHATY_HEAD'] || config.DEFAULT_HEAD, + puppet: process.env['WECHATY_PUPPET'] || config.DEFAULT_PUPPET, validApiHost, }) @@ -103,12 +141,12 @@ function validApiHost(apihost: string): boolean { } throw new Error('validApiHost() fail for ' + apihost) } -validApiHost(Config.apihost) +validApiHost(config.apihost) /** * 2. ENVIRONMENT VARIABLES (only) */ -Object.assign(Config, { +Object.assign(config, { port: process.env['WECHATY_PORT'] || null, // 0 for disable port profile: process.env['WECHATY_PROFILE'] || null, // DO NOT set DEFAULT_PROFILE, because sometimes user do not want to save session token: process.env['WECHATY_TOKEN'] || null, // DO NOT set DEFAULT, because sometimes user do not want to connect to io cloud service @@ -118,15 +156,15 @@ Object.assign(Config, { /** * 3. Service Settings */ -Object.assign(Config, { +Object.assign(config, { // get PORT form cloud service env, ie: heroku - httpPort: process.env['PORT'] || process.env['WECHATY_PORT'] || Config.DEFAULT_PORT, + httpPort: process.env['PORT'] || process.env['WECHATY_PORT'] || config.DEFAULT_PORT, }) /** * 4. Envioronment Identify */ -Object.assign(Config, { +Object.assign(config, { dockerMode: !!process.env('WECHATY_DOCKER'), isGlobal: isWechatyInstalledGlobal(), }) @@ -195,7 +233,52 @@ function puppetInstance(instance?: Puppet | null): Puppet | void { } -Object.assign(Config, { +function gitVersion(): string | null { + 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') + .spawnSync('git', gitArgs, { cwd: __dirname }) + + if (ss.status !== 0) { + throw new Error(ss.error) + } + + const revision = ss.stdout + .toString() + .trim() + .slice(0, 7) + 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 + } +} + +function npmVersion(): string { + try { + return require('../package.json').version + } catch (e) { + log.error('Wechaty', 'npmVersion() exception %s', e.message) + Raven.captureException(e) + return '0.0.0' + } +} + +Object.assign(config, { + gitVersion, + npmVersion, puppetInstance, }) @@ -236,38 +319,9 @@ export interface Sleepable { sleep(millisecond: number): Promise } -import * as Raven from 'raven' -Raven.disableConsoleAlerts() - -Raven -.config( - process.env.NODE_ENV === 'production' - && 'https://f6770399ee65459a82af82650231b22c:d8d11b283deb441e807079b8bb2c45cd@sentry.io/179672', - { - release: require('../package.json').version, - tags: { - git_commit: 'c0deb10c4', - platform: os.platform(), - }, - }, -) -.install() - -/* -try { - doSomething(a[0]) -} catch (e) { - Raven.captureException(e) -} - -Raven.context(function () { - doSomething(a[0]) -}) - */ - export { log, Raven, } -export default Config +export default config diff --git a/src/contact.ts b/src/contact.ts index 72b7726b61ca044ea0429063cef4b4cb3d9d6ca4..d38410b3964d0c189e8e7dda953a71d74d502799 100644 --- a/src/contact.ts +++ b/src/contact.ts @@ -17,7 +17,7 @@ * */ import { - Config, + config, Raven, Sayable, log, @@ -329,9 +329,9 @@ export class Contact implements Sayable { } try { - const hostname = await (Config.puppetInstance() as PuppetWeb).browser.hostname() + const hostname = await (config.puppetInstance() as PuppetWeb).browser.hostname() const avatarUrl = `http://${hostname}${this.obj.avatar}` - const cookies = await (Config.puppetInstance() as PuppetWeb).browser.readCookie() + const cookies = await (config.puppetInstance() as PuppetWeb).browser.readCookie() log.silly('Contact', 'avatar() url: %s', avatarUrl) return UtilLib.urlStream(avatarUrl, cookies) @@ -388,9 +388,9 @@ export class Contact implements Sayable { } if (!contactGetter) { - log.silly('Contact', 'get contact via ' + Config.puppetInstance().constructor.name) - contactGetter = Config.puppetInstance() - .getContact.bind(Config.puppetInstance()) + log.silly('Contact', 'get contact via ' + config.puppetInstance().constructor.name) + contactGetter = config.puppetInstance() + .getContact.bind(config.puppetInstance()) } if (!contactGetter) { throw new Error('no contatGetter') @@ -431,7 +431,7 @@ export class Contact implements Sayable { * ``` */ public self(): boolean { - const userId = Config.puppetInstance() + const userId = config.puppetInstance() .userId const selfId = this.id @@ -522,7 +522,7 @@ export class Contact implements Sayable { throw new Error('unsupport name type') } - const contactList = await Config.puppetInstance() + const contactList = await config.puppetInstance() .contactFind(filterFunction) .catch(e => { log.error('Contact', 'findAll() rejected: %s', e.message) @@ -627,7 +627,7 @@ export class Contact implements Sayable { return this.obj && this.obj.alias || null } - return Config.puppetInstance() + return config.puppetInstance() .contactAlias(this, newAlias) .then(ret => { if (ret) { diff --git a/src/friend-request.ts b/src/friend-request.ts index d459a90a204e0554c0dbf5e849e2cd33d7f001b3..4859492053a98a0f7a4bbf1f7e08b6182dce6efa 100644 --- a/src/friend-request.ts +++ b/src/friend-request.ts @@ -18,7 +18,7 @@ */ import { - Config, + config, log, } from './config' import Contact from './contact' @@ -32,7 +32,7 @@ export abstract class FriendRequest { constructor() { log.verbose('FriendRequest', 'constructor()') - if (!Config.puppetInstance()) { + if (!config.puppetInstance()) { throw new Error('no Config.puppetInstance() instanciated') } } diff --git a/src/io-client.ts b/src/io-client.ts index 57ab4eb7111666f0811c91c3daaa8ef9f0119fe7..b17453893107bb395931862ad787606185656120 100644 --- a/src/io-client.ts +++ b/src/io-client.ts @@ -25,7 +25,7 @@ import { StateSwitch } from 'state-switch' import { - Config, + config, log as globalLog, } from './config' import { Io } from './io' @@ -39,7 +39,7 @@ export class IoClient { private state = new StateSwitch<'online', 'offline'>('IoClient', 'offline', globalLog) constructor( - private token: string = Config.token || Config.DEFAULT_TOKEN, + private token: string = config.token || config.DEFAULT_TOKEN, private log: any = globalLog, ) { if (!log) { @@ -141,7 +141,7 @@ export class IoClient { return } - public initWeb(port = Config.httpPort) { + public initWeb(port = config.httpPort) { // if (process.env.DYNO) { // } const app = require('express')() diff --git a/src/io.ts b/src/io.ts index ac181a9a2e2bae39e8e580decf504114a41ed791..5d237b47b8f6c59e04a98b8b79061cf4dad07073 100644 --- a/src/io.ts +++ b/src/io.ts @@ -21,7 +21,7 @@ import * as WebSocket from 'ws' import { StateSwitch } from 'state-switch' import { - Config, + config, // WechatyEventName log, } from './config' @@ -71,8 +71,8 @@ export class Io { throw new Error('Io must has wechaty & token set') } - setting.apihost = setting.apihost || Config.apihost - setting.protocol = setting.protocol || Config.DEFAULT_PROTOCOL + setting.apihost = setting.apihost || config.apihost + setting.protocol = setting.protocol || config.DEFAULT_PROTOCOL this.uuid = setting.wechaty.uuid diff --git a/src/message.spec.ts b/src/message.spec.ts index 4d5e74ab9decafeaa35efd3ef1bd4594f1123f35..851d849db9dcfa254f66e856f264f5870a6017f6 100644 --- a/src/message.spec.ts +++ b/src/message.spec.ts @@ -19,7 +19,7 @@ import { test } from 'ava' import { - Config, + config, log, } from './config' import Message from './message' @@ -29,7 +29,7 @@ const MOCK_USER_ID = 'TEST-USER-ID' const puppet = new PuppetWeb() puppet.userId = MOCK_USER_ID -Config.puppetInstance(puppet) +config.puppetInstance(puppet) test('constructor()', t => { /* tslint:disable:max-line-length */ @@ -93,7 +93,7 @@ test.serial('ready()', async t => { }) } - Config.puppetInstance() + config.puppetInstance() .getContact = mockGetContact const m = new Message(rawData) @@ -131,7 +131,7 @@ test('findAll()', async t => { }) test('self()', t => { - Config.puppetInstance() + config.puppetInstance() const m = new Message() m.from(MOCK_USER_ID) @@ -183,11 +183,11 @@ test.serial('mentioned()', async t => { let puppet1 try { - puppet1 = Config.puppetInstance() + puppet1 = config.puppetInstance() puppet1.getContact = mockContactGetter } catch (err) { puppet1 = { getContact: mockContactGetter } - Config.puppetInstance(puppet1) + config.puppetInstance(puppet1) } const msg11 = new Message(rawObj11) const room11 = msg11.room() diff --git a/src/message.ts b/src/message.ts index ebfcda969228a75d7af3e87b3118cba64abc4889..7be0dec386c59e93e7ccbc3e40fc26109d905479 100644 --- a/src/message.ts +++ b/src/message.ts @@ -20,7 +20,7 @@ import * as fs from 'fs' import * as path from 'path' import { - Config, + config, Raven, RecommendInfo, Sayable, @@ -414,7 +414,7 @@ export class Message implements Sayable { public count() { return this._counter } public self(): boolean { - const userId = Config.puppetInstance() + const userId = config.puppetInstance() .userId const fromId = this.obj.from @@ -619,7 +619,7 @@ export class Message implements Sayable { } } - return Config.puppetInstance() + return config.puppetInstance() .send(m) } @@ -651,7 +651,7 @@ export class MediaMessage extends Message { } // FIXME: decoupling needed - this.bridge = (Config.puppetInstance() as PuppetWeb) + this.bridge = (config.puppetInstance() as PuppetWeb) .bridge } @@ -801,7 +801,7 @@ export class MediaMessage extends Message { try { await this.ready() // FIXME: decoupling needed - const cookies = await (Config.puppetInstance() as PuppetWeb).browser.readCookie() + const cookies = await (config.puppetInstance() as PuppetWeb).browser.readCookie() if (!this.obj.url) { throw new Error('no url') } diff --git a/src/puppet-web/browser-driver.ts b/src/puppet-web/browser-driver.ts index bc999bcffd61bc8f806ceb22099e07b357b99e96..0855c2c7c9935fa6b37501099a9a2c372b0e40db 100644 --- a/src/puppet-web/browser-driver.ts +++ b/src/puppet-web/browser-driver.ts @@ -27,7 +27,7 @@ import { } from 'selenium-webdriver' import { - Config, + config, HeadName, log, } from '../config' @@ -113,9 +113,9 @@ export class BrowserDriver { '--no-sandbox', ], // issue #26 for run inside docker } - if (Config.dockerMode) { + if (config.dockerMode) { log.verbose('PuppetWebBrowserDriver', 'getChromeDriver() wechaty in docker confirmed(should not show this in CI)') - options['binary'] = Config.CMD_CHROMIUM + options['binary'] = config.CMD_CHROMIUM } else { /** * https://github.com/Chatie/wechaty/pull/416 @@ -224,7 +224,7 @@ export class BrowserDriver { // , '--ssl-client-certificate-file=cert.pem' // ] - if (Config.debug) { + if (config.debug) { phantomjsArgs.push('--remote-debugger-port=8080') // XXX: be careful when in production env. phantomjsArgs.push('--webdriver-loglevel=DEBUG') // phantomjsArgs.push('--webdriver-logfile=webdriver.debug.log') diff --git a/src/puppet-web/browser.ts b/src/puppet-web/browser.ts index 7899a1ab628f3ac9bdd8e8693d87ca22fcdbd14f..2442ee047ce5c9c1fcf8e974cc70bbc8b6b36260 100644 --- a/src/puppet-web/browser.ts +++ b/src/puppet-web/browser.ts @@ -26,7 +26,7 @@ import { StateSwitch } from 'state-switch' const retryPromise = require('retry-promise').default // https://github.com/olalonde/retry-promise import { - Config, + config, HeadName, log, } from '../config' @@ -53,7 +53,7 @@ export class Browser extends EventEmitter { constructor( private setting: BrowserSetting = { - head: Config.head, + head: config.head, sessionFile: '', }, ) { diff --git a/src/puppet-web/friend-request.spec.ts b/src/puppet-web/friend-request.spec.ts index dbb0041685343ebf46a485aa65fb5e245f3b1a82..09e3f2437ef44ed15441aec0fefcfa157a6cdd02 100644 --- a/src/puppet-web/friend-request.spec.ts +++ b/src/puppet-web/friend-request.spec.ts @@ -18,13 +18,13 @@ */ import { test } from 'ava' -import Config from '../config' +import config from '../config' import Contact from '../contact' import Message from '../message' import Puppet from '../puppet' import PuppetWebFriendRequest from './friend-request' -Config.puppetInstance({ +config.puppetInstance({ userId: 'xxx', } as Puppet) diff --git a/src/puppet-web/friend-request.ts b/src/puppet-web/friend-request.ts index 59bca475d3c1673b49b02885825288665ad9e23f..556b622759b48675363d58c1eeae36906dadacf0 100644 --- a/src/puppet-web/friend-request.ts +++ b/src/puppet-web/friend-request.ts @@ -30,7 +30,7 @@ const retryPromise = require('retry-promise').default import { Contact } from '../contact' import { - Config, + config, RecommendInfo, log, } from '../config' @@ -97,7 +97,7 @@ export class PuppetWebFriendRequest extends FriendRequest { this.hello = hello } - return Config.puppetInstance() + return config.puppetInstance() .friendRequestSend(contact, hello) } @@ -108,7 +108,7 @@ export class PuppetWebFriendRequest extends FriendRequest { throw new Error('request is not a `receive` type. it is a ' + this.type + ' type') } - const ret = await Config.puppetInstance() + const ret = await config.puppetInstance() .friendRequestAccept(this.contact, this.ticket) const max = 20 diff --git a/src/puppet-web/puppet-web.ts b/src/puppet-web/puppet-web.ts index 1d62658948e8064a79b18238381540f7a6c779e7..96aef9179b3f61ac3c89044d29e761306e816368 100644 --- a/src/puppet-web/puppet-web.ts +++ b/src/puppet-web/puppet-web.ts @@ -17,7 +17,7 @@ * */ import { - Config, + config, HeadName, log, Raven, @@ -75,7 +75,7 @@ export class PuppetWeb extends Puppet { super() if (!setting.head) { - setting.head = Config.head + setting.head = config.head } this.on('watchdog', Watchdog.onFeed.bind(this)) } diff --git a/src/room.ts b/src/room.ts index 9db1a3ee79458f939bbd3f662e5c59d69d9c56fe..2d1c1a1c70fdb79dbbd993747b501154e1fcda3b 100644 --- a/src/room.ts +++ b/src/room.ts @@ -19,7 +19,7 @@ import { EventEmitter } from 'events' import { - Config, + config, Raven, Sayable, log, @@ -134,8 +134,8 @@ export class Room extends EventEmitter implements Sayable { } if (!contactGetter) { - contactGetter = Config.puppetInstance() - .getContact.bind(Config.puppetInstance()) + contactGetter = config.puppetInstance() + .getContact.bind(config.puppetInstance()) } if (!contactGetter) { throw new Error('no contactGetter') @@ -216,7 +216,7 @@ export class Room extends EventEmitter implements Sayable { m.room(this) - return Config.puppetInstance() + return config.puppetInstance() .send(m) } @@ -295,7 +295,7 @@ export class Room extends EventEmitter implements Sayable { throw new Error('contact not found') } - const n = Config.puppetInstance() + const n = config.puppetInstance() .roomAdd(this, contact) return n } @@ -306,7 +306,7 @@ export class Room extends EventEmitter implements Sayable { if (!contact) { throw new Error('contact not found') } - const n = await Config.puppetInstance() + const n = await config.puppetInstance() .roomDel(this, contact) .then(_ => this.delLocal(contact)) return n @@ -354,7 +354,7 @@ export class Room extends EventEmitter implements Sayable { if (newTopic) { log.verbose('Room', 'topic(%s)', newTopic) - Config.puppetInstance() + config.puppetInstance() .roomTopic(this, newTopic) .catch(e => { log.warn('Room', 'topic(newTopic=%s) exception: %s', @@ -408,7 +408,7 @@ export class Room extends EventEmitter implements Sayable { public owner(): Contact | null { const ownerUin = this.obj && this.obj.ownerUin - const user = Config.puppetInstance() + const user = config.puppetInstance() .user if (user && user.get('uin') === ownerUin) { @@ -547,7 +547,7 @@ export class Room extends EventEmitter implements Sayable { throw new Error('contactList not found') } - return Config.puppetInstance() + return config.puppetInstance() .roomCreate(contactList, topic) .catch(e => { log.error('Room', 'create() exception: %s', e && e.stack || e.message || e) @@ -579,7 +579,7 @@ export class Room extends EventEmitter implements Sayable { throw new Error('unsupport topic type') } - const roomList = await Config.puppetInstance() + const roomList = await config.puppetInstance() .roomFind(filterFunction) .catch(e => { log.verbose('Room', 'findAll() rejected: %s', e.message) diff --git a/src/wechaty.ts b/src/wechaty.ts index 71c5b21f3e1b9b88e80478fa98b5b9a839350a21..df189496dbc292b029cd8f1846c9d055ebdb50b1 100644 --- a/src/wechaty.ts +++ b/src/wechaty.ts @@ -17,13 +17,11 @@ * */ import { EventEmitter } from 'events' -import * as fs from 'fs' -import * as path from 'path' import { StateSwitch } from 'state-switch' import { - Config, + config, HeadName, PuppetName, Raven, @@ -103,11 +101,7 @@ export class Wechaty extends EventEmitter implements Sayable { * @private */ private state = new StateSwitch<'standby', 'ready'>('Wechaty', 'standby', log) - /** - * the npmVersion - * @private - */ - private npmVersion: string = require('../package.json').version + /** * the uuid * @private @@ -134,9 +128,9 @@ export class Wechaty extends EventEmitter implements Sayable { super() log.verbose('Wechaty', 'contructor()') - setting.head = setting.head || Config.head - setting.puppet = setting.puppet || Config.puppet - setting.profile = setting.profile || Config.profile + setting.head = setting.head || config.head + setting.puppet = setting.puppet || config.puppet + setting.profile = setting.profile || config.profile // setting.port = setting.port || Config.port @@ -166,39 +160,18 @@ export class Wechaty extends EventEmitter implements Sayable { * console.log(Wechaty.instance().version(true)) * // '0.7.9' */ - public version(forceNpm = false): string { - // TODO: use git rev-parse HEAD ? - const dotGitPath = path.join(__dirname, '..', '.git') // only for ts-node, not for dist - // TODO: use git rev-parse HEAD ? - const gitLogCmd = 'git' - const gitLogArgs = ['log', '--oneline', '-1'] - + public static version(forceNpm = false): string { if (!forceNpm) { - try { - fs.statSync(dotGitPath).isDirectory() - - const ss = require('child_process') - .spawnSync(gitLogCmd, gitLogArgs, { cwd: __dirname }) - - if (ss.status !== 0) { - throw new Error(ss.error) - } - - const revision = ss.stdout - .toString() - .trim() + const revision = config.gitVersion() + if (revision) { return `#git[${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 config.npmVersion() + } - return this.npmVersion + public version(forceNpm?) { + return Wechaty.version(forceNpm) } /** @@ -378,7 +351,7 @@ export class Wechaty extends EventEmitter implements Sayable { this.puppet = puppet // force to use base class Puppet interface for better encapsolation // set puppet instance to Wechaty Static variable, for using by Contact/Room/Message/FriendRequest etc. - Config.puppetInstance(puppet) + config.puppetInstance(puppet) await puppet.init() return puppet @@ -405,7 +378,7 @@ export class Wechaty extends EventEmitter implements Sayable { const puppetBeforeDie = this.puppet this.puppet = null - Config.puppetInstance(null) + config.puppetInstance(null) await puppetBeforeDie.quit() .catch(e => { diff --git a/test/contact.spec.ts b/test/contact.spec.ts index c2dc7484cca511e4f38721d5c7fc5f9b354fc8e1..44d6a87f8708f8e3e5f08eb1d8eb538edb9245af 100644 --- a/test/contact.spec.ts +++ b/test/contact.spec.ts @@ -17,11 +17,11 @@ * */ import { test } from 'ava' -import Config from '../src/config' +import config from '../src/config' import Contact from '../src/contact' import PuppetWeb from '../src/puppet-web' -Config.puppetInstance(new PuppetWeb()) +config.puppetInstance(new PuppetWeb()) test('Contact smoke testing', async t => { /* tslint:disable:variable-name */ diff --git a/test/docker.spec.ts b/test/docker.spec.ts index b759b2d571839a28a05772cd0b6045ee7d4d1d01..f8bf17ff932b1abe4057f2d5bb57031002cb8441 100644 --- a/test/docker.spec.ts +++ b/test/docker.spec.ts @@ -22,20 +22,20 @@ import * as fs from 'fs' // import { execSync } from 'child_process' // import * as sinon from 'sinon' -import Config from '../src/config' +import config from '../src/config' /** * need keep this !Config.dockerMode because ava need at least one test() inside. * × No tests found in test\docker.spec.js */ -if (Config.dockerMode) { +if (config.dockerMode) { test('Docker smoke testing', function(t) { // const n = execSync('ps a | grep Xvfb | grep -v grep | wc -l').toString().replace(/\n/, '', 'g') // t.is(parseInt(n), 1, 'should has Xvfb started') t.notThrows(() => { // fs.accessSync(Config.CMD_CHROMIUM, fs['X_OK']) - fs.statSync(Config.CMD_CHROMIUM).isFile() + fs.statSync(config.CMD_CHROMIUM).isFile() }, 'should exist xvfb-chrome exectable') }) diff --git a/test/puppet-web/browser.spec.ts b/test/puppet-web/browser.spec.ts index f6be2fb7ab2811435a5cecf057a964bc4709dc6e..9e83699fb46cf03ee71984c650992f94c42f8e8c 100644 --- a/test/puppet-web/browser.spec.ts +++ b/test/puppet-web/browser.spec.ts @@ -20,7 +20,7 @@ import * as fs from 'fs' import { test } from 'ava' import { - Config, + config, log, } from '../../' @@ -31,7 +31,7 @@ import { const TEST_DOMAIN = 'www.chatie.io' const TEST_URL = 'https://' + TEST_DOMAIN -const PROFILE = Config.DEFAULT_PROFILE + '-' + process.pid + '-' +const PROFILE = config.DEFAULT_PROFILE + '-' + process.pid + '-' let profileCounter = 1 test('Cookie smoke testing', async t => { @@ -105,7 +105,7 @@ test('Cookie save/load', async t => { const profileName = PROFILE + (profileCounter++) let browser = new Browser({ - head: Config.head, + head: config.head, sessionFile: profileName, }) @@ -179,7 +179,7 @@ test('Cookie save/load', async t => { */ browser = new Browser({ - head: Config.head, + head: config.head, sessionFile: profileName, }) diff --git a/test/puppet-web/puppet-web.spec.ts b/test/puppet-web/puppet-web.spec.ts index 1cf2d7b9085e9f2d80a767872eae35fad4695aa5..94fd62bf6a27e070343b9288f9e1a67347e2be75 100644 --- a/test/puppet-web/puppet-web.spec.ts +++ b/test/puppet-web/puppet-web.spec.ts @@ -19,7 +19,7 @@ import { test } from 'ava' import { - Config, + config, log, } from '../../src/config' import PuppetWeb from '../../src/puppet-web' @@ -34,7 +34,7 @@ test.serial('login/logout events', async t => { const pw = new PuppetWeb() t.truthy(pw, 'should instantiated a PuppetWeb') - Config.puppetInstance(pw) + config.puppetInstance(pw) await pw.init() t.pass('should be inited') @@ -61,7 +61,7 @@ test.serial('server/browser socketio ding', async t => { const puppet = new PuppetWeb() t.truthy(puppet, 'should instantiated a PuppetWeb') - Config.puppetInstance(puppet) + config.puppetInstance(puppet) const EXPECTED_DING_DATA = 'dingdong' diff --git a/test/room.spec.ts b/test/room.spec.ts index 04297b16cf2ea82198f09ec5e6f7ae7ccce3995d..a742f5ae22400cc4ded7f9b9d8a55304d3e3b84e 100644 --- a/test/room.spec.ts +++ b/test/room.spec.ts @@ -18,12 +18,12 @@ */ import { test } from 'ava' -import Config from '../src/config' +import config from '../src/config' import Contact from '../src/contact' import PuppetWeb from '../src/puppet-web' import Room from '../src/room' -Config.puppetInstance(new PuppetWeb()) +config.puppetInstance(new PuppetWeb()) // Room.attach(new PuppetWeb()) // test('Room smoke testing', async t => { @@ -105,11 +105,11 @@ test('Room smoking test', async t => { let puppet try { - puppet = Config.puppetInstance() + puppet = config.puppetInstance() puppet.getContact = mockContactGetter } catch (err) { puppet = { getContact: mockContactGetter } - Config.puppetInstance(puppet) + config.puppetInstance(puppet) } await r.ready() diff --git a/test/wechaty.spec.ts b/test/wechaty.spec.ts index cca2a4decdfcefc614112d2815b62a27d19115cf..e51a7d72860e599f8c62310fd1fe046d1759bd96 100644 --- a/test/wechaty.spec.ts +++ b/test/wechaty.spec.ts @@ -19,7 +19,7 @@ import { test } from 'ava' import { - Config, + config, Contact, FriendRequest, IoClient, @@ -54,8 +54,8 @@ test('Wechaty Framework', t => { }) test('Wechaty Config setting', t => { - t.truthy(Config , 'should export Config') - t.truthy(Config.DEFAULT_HEAD , 'should has DEFAULT_HEAD') - t.truthy(Config.DEFAULT_PUPPET , 'should has DEFAULT_PUPPET') - t.truthy(Config.DEFAULT_PORT , 'should has DEFAULT_PORT') + t.truthy(config , 'should export Config') + t.truthy(config.DEFAULT_HEAD , 'should has DEFAULT_HEAD') + t.truthy(config.DEFAULT_PUPPET , 'should has DEFAULT_PUPPET') + t.truthy(config.DEFAULT_PORT , 'should has DEFAULT_PORT') })