diff --git a/.eslintrc.js b/.eslintrc.cjs similarity index 100% rename from .eslintrc.js rename to .eslintrc.cjs diff --git a/.github/workflows/npm.yml b/.github/workflows/npm.yml index 5fd1f99..3a40a7b 100644 --- a/.github/workflows/npm.yml +++ b/.github/workflows/npm.yml @@ -7,8 +7,10 @@ jobs: name: Build strategy: matrix: - os: [ubuntu-latest] - node: [12] + os: + - ubuntu-latest + node-version: + - 16 runs-on: ${{ matrix.os }} steps: @@ -17,6 +19,8 @@ jobs: uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} + cache: npm + cache-dependency-path: package.json - name: Install Dependencies run: npm install @@ -32,13 +36,15 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: 12 + node-version: 16 + cache: npm + cache-dependency-path: package.json - name: Install Dependencies run: npm install - - name: Generate Version - run: ./scripts/generate-version.sh + - name: Generate Package JSON + run: ./scripts/generate-package-json.sh - name: Pack Testing run: ./scripts/npm-pack-testing.sh @@ -54,14 +60,16 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: 12 + node-version: 16 registry-url: https://registry.npmjs.org/ + cache: npm + cache-dependency-path: package.json - name: Install Dependencies run: npm install - - name: Generate Version - run: ./scripts/generate-version.sh + - name: Generate Package JSON + run: ./scripts/generate-package-json.sh - name: Set Publish Config run: ./scripts/package-publish-config-tag.sh diff --git a/README.md b/README.md index 74b045d..785eda0 100644 --- a/README.md +++ b/README.md @@ -168,8 +168,23 @@ import { Version } from 'wechaty-vorpal-contrib' vorpalExtensionList = [ Version() ] ``` +## Contributors + +[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/0)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/0) +[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/1)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/1) +[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/2)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/2) +[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/3)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/3) +[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/4)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/4) +[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/5)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/5) +[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/6)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/6) +[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/7)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/7) + ## History +### main (Sep 20, 2021) + +1. Enable ESM Modules + ### v0.6 (July 10, 2020) 1. Upgrade to [wechaty-vorpal](https://github.com/wechaty/wechaty-vorpal)@0.6 to enhance the Command Action Functions @@ -184,17 +199,6 @@ Init the first version of Wechaty Vorpal Extensions for official Wechaty ChatOps 1. `Eval` Extension for EVAL JavaScript code from the chat window! 1. `Cash` Extension for Cross-platform Linux commands in pure ES6 -## Contributors - -[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/0)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/0) -[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/1)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/1) -[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/2)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/2) -[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/3)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/3) -[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/4)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/4) -[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/5)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/5) -[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/6)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/6) -[![contributor](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/images/7)](https://sourcerer.io/fame/huan/wechaty/wechaty-vorpal-contrib/links/7) - ## Author [Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Tencent TVP of Chatbot, \ diff --git a/examples/vorpal.ts b/examples/vorpal.ts index e7575ab..9e7489d 100644 --- a/examples/vorpal.ts +++ b/examples/vorpal.ts @@ -1,6 +1,6 @@ import { Vorpal } from 'wechaty-vorpal' -import { Cash } from '../src/contrib/cash' +import { Cash } from '../src/contrib/cash.js' async function main () { const vorpal = new Vorpal() diff --git a/package.json b/package.json index 520f10f..a4f5cfa 100644 --- a/package.json +++ b/package.json @@ -1,24 +1,33 @@ { "name": "wechaty-vorpal-contrib", - "version": "0.6.52", + "version": "0.7.2", "description": "Wechaty Chat CLI (Command Line Interface), Powered by Vorpal", - "main": "dist/src/mod.js", - "typings": "dist/src/mod.d.ts", + "type": "module", + "exports": { + ".": { + "import": "./dist/esm/src/mod.js", + "require": "./dist/cjs/src/mod.js" + } + }, + "typings": "./dist/esm/src/mod.d.ts", "engines": { + "wechaty": ">=0.69", + "node": ">=14", "wechaty-vorpal": ">=0.6.1" }, "scripts": { + "build": "tsc && tsc -p tsconfig.cjs.json", "clean": "shx rm -fr dist/*", - "dist": "npm run clean && tsc", - "pack": "npm pack", - "lint": "npm run lint:es && npm run lint:ts && npm run lint:md", + "dist": "npm-run-all clean build dist:commonjs", + "dist:commonjs": "jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json", + "lint": "npm-run-all lint:es lint:ts lint:md", "lint:md": "markdownlint README.md", - "lint:ts": "tsc --noEmit", - "example": "ts-node examples/ding-dong-bot.ts", + "lint:ts": "tsc --isolatedModules --noEmit", + "example": "cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" node examples/ding-dong-bot.ts", "start": "npm run example", - "test": "npm run lint && npm run test:unit", + "test": "npm-run-all lint test:unit", "test:pack": "bash -x scripts/npm-pack-testing.sh", - "test:unit": "tap --node-arg=--require=ts-node/register \"src/**/*.spec.ts\" \"src/*.spec.ts\" \"tests/*.spec.ts\" \"tests/**/*.spec.ts\"", + "test:unit": "cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/**/*.spec.ts\"", "lint:es": "eslint --ignore-pattern tests/fixtures/ '{bin,examples,scripts,src,tests}/**/*.ts'" }, "repository": { @@ -39,34 +48,38 @@ }, "homepage": "https://github.com/wechaty/wechaty-vorpal-contrib#readme", "devDependencies": { - "@chatie/eslint-config": "^0.12.1", + "@chatie/eslint-config": "^0.14.1", "@chatie/git-scripts": "^0.6.2", "@chatie/semver": "^0.4.7", - "@chatie/tsconfig": "^0.16.2", + "@chatie/tsconfig": "^0.20.2", "@types/ip": "^1.1.0", "@types/json-stringify-safe": "^5.0.0", - "pkg-jq": "^0.2.4", + "cross-env": "^7.0.3", + "npm-run-all": "^4.1.5", + "pkg-jq": "^0.2.11", "rxjs": "^7.3.0", "shx": "^0.3.3", "tstest": "^0.5.16", - "wechaty": "^0.62.3", - "wechaty-mocker": "^0.3.4", - "wechaty-puppet-mock": "^0.28.1", - "wechaty-vorpal": "^0.6.17" + "wechaty": "^0.69.50", + "wechaty-mocker": "^0.9.1", + "wechaty-puppet-mock": "^0.31.5" + }, + "peerDependencies": { + "wechaty-vorpal": "^0.7.4" }, "dependencies": { "cash": "^0.8.0", "ip": "^1.1.5", "json-stringify-safe": "^5.0.1", "moment": "^2.29.1", - "public-ip": "^4.0.2", - "read-pkg-up": "^7.0.1", + "public-ip": "^4.0.4", "utility-types": "^3.10.0" }, - "peerDependencies": { - "rxjs": ">=7.3", - "wechaty-vorpal": ">=0.6.17" - }, + "files": [ + "bin/", + "dist/", + "src/" + ], "git": { "scripts": { "pre-push": "npx git-scripts-pre-push" diff --git a/scripts/generate-package-json.sh b/scripts/generate-package-json.sh new file mode 100755 index 0000000..111e894 --- /dev/null +++ b/scripts/generate-package-json.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -e + +SRC_PACKAGE_JSON_TS_FILE='src/package-json.ts' + +[ -f ${SRC_PACKAGE_JSON_TS_FILE} ] || { + echo ${SRC_PACKAGE_JSON_TS_FILE}" not found" + exit 1 +} + +cat <<_SRC_ > ${SRC_PACKAGE_JSON_TS_FILE} +/** + * This file was auto generated from scripts/generate-version.sh + */ +import type { PackageJson } from 'type-fest' +export const packageJson: PackageJson = $(cat package.json) as any +_SRC_ diff --git a/scripts/generate-version.sh b/scripts/generate-version.sh deleted file mode 100755 index e8ef7f9..0000000 --- a/scripts/generate-version.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash -set -e - -SRC_VERSION_TS_FILE='src/version.ts' - -[ -f ${SRC_VERSION_TS_FILE} ] || { - echo ${SRC_VERSION_TS_FILE}" not found" - exit 1 -} - -VERSION=$(npx pkg-jq -r .version) - -cat <<_SRC_ > ${SRC_VERSION_TS_FILE} -/** - * This file was auto generated from scripts/generate-version.sh - */ -export const VERSION: string = '${VERSION}' -_SRC_ diff --git a/scripts/npm-pack-testing.sh b/scripts/npm-pack-testing.sh index b425b9b..2488940 100755 --- a/scripts/npm-pack-testing.sh +++ b/scripts/npm-pack-testing.sh @@ -3,14 +3,14 @@ set -e VERSION=$(npx pkg-jq -r .version) -if npx --package @chatie/semver semver-is-prod $VERSION; then +if npx --package @chatie/semver semver-is-prod "$VERSION"; then NPM_TAG=latest else NPM_TAG=next fi npm run dist -npm run pack +npm pack TMPDIR="/tmp/npm-pack-testing.$$" mkdir "$TMPDIR" @@ -18,13 +18,46 @@ mv ./*-*.*.*.tgz "$TMPDIR" cp tests/fixtures/smoke-testing.ts "$TMPDIR" cd $TMPDIR + npm init -y -npm install *-*.*.*.tgz \ - @chatie/tsconfig \ +npm install --production ./*-*.*.*.tgz \ + @chatie/tsconfig@$NPM_TAG \ + pkg-jq \ + "wechaty-puppet@$NPM_TAG" \ "wechaty@$NPM_TAG" \ "wechaty-vorpal@$NPM_TAG" \ + +# +# CommonJS +# +./node_modules/.bin/tsc \ + --target es6 \ + --module CommonJS \ + \ + --moduleResolution node \ + --esModuleInterop \ + --lib esnext \ + --noEmitOnError \ + --noImplicitAny \ + --skipLibCheck \ + smoke-testing.ts + +echo +echo "CommonJS: pack testing..." +node smoke-testing.js + +# +# ES Modules +# +npx pkg-jq -i '.type="module"' + + ./node_modules/.bin/tsc \ + --target es2020 \ + --module es2020 \ + \ + --moduleResolution node \ --esModuleInterop \ --lib esnext \ --noEmitOnError \ @@ -32,4 +65,6 @@ npm install *-*.*.*.tgz \ --skipLibCheck \ smoke-testing.ts +echo +echo "ES Module: pack testing..." node smoke-testing.js diff --git a/src/config.ts b/src/config.ts index 968d7af..0fb59ba 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,3 +1,14 @@ -export interface WechatyVorpalConfig { +import { packageJson } from './package-json.js' + +interface WechatyVorpalConfig { command?: string // the command name } + +const VERSION = packageJson.version || '0.0.0' + +export type { + WechatyVorpalConfig, +} +export { + VERSION, +} diff --git a/src/contrib/announce.ts b/src/contrib/announce.ts index 0695c87..cfe3c38 100644 --- a/src/contrib/announce.ts +++ b/src/contrib/announce.ts @@ -1,7 +1,7 @@ import { log, } from 'wechaty' -import { +import type { Vorpal, CommandContext, Args, @@ -30,7 +30,7 @@ async function announceAction ( ): Promise { log.verbose('WechatyVorpalContrib', 'announceAction("%s")', JSON.stringify(args)) - const announcement: string = args.announcement as string + const announcement: string = args['announcement'] as string const options = args.options as any as AnnounceOptions const room = await this.wechaty.Room.find({ id: options.room }) diff --git a/src/contrib/cash.ts b/src/contrib/cash.ts index 6f707c7..22128d5 100644 --- a/src/contrib/cash.ts +++ b/src/contrib/cash.ts @@ -1,4 +1,4 @@ -import { +import type { Vorpal, } from 'wechaty-vorpal' import { log } from 'wechaty' diff --git a/src/contrib/ddr/action.ts b/src/contrib/ddr/action.ts index 3edc783..4952003 100644 --- a/src/contrib/ddr/action.ts +++ b/src/contrib/ddr/action.ts @@ -5,18 +5,18 @@ import { log, } from 'wechaty' -import { +import type { CommandContext, Args, } from 'wechaty-vorpal' -import { Reporter } from './reporter' -import { Monitor } from './monitor' +import { Reporter } from './reporter.js' +import { Monitor } from './monitor.js' import { DEFAULT_OPTIONS, DdrOptions, -} from './ddr' +} from './ddr.js' async function action ( this: CommandContext, @@ -93,7 +93,14 @@ async function action ( } catch (e) { log.error('WechatyVorpalContrib', 'Ddr() ddr$.toPromise() rejection %s', e) - console.error(e.stack) + const name = (e as Error).name + const message = (e as Error).message + const stack = (e as Error).stack + this.log([ + name, + message, + stack, + ].join('\n')) return 1 } diff --git a/src/contrib/ddr/ddr.spec.ts b/src/contrib/ddr/ddr.spec.ts index 9a2f935..46e4040 100755 --- a/src/contrib/ddr/ddr.spec.ts +++ b/src/contrib/ddr/ddr.spec.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm import { test, @@ -10,15 +10,15 @@ import { import { createFixture, } from 'wechaty-mocker' -import { +import type { mock, } from 'wechaty-puppet-mock' import { WechatyVorpal, } from 'wechaty-vorpal' -import { Ddr } from './ddr' -import { Store } from './store' +import { Ddr } from './ddr.js' +import { Store } from './store.js' test('ddr', async t => { for await (const fixture of createFixture()) { diff --git a/src/contrib/ddr/ddr.ts b/src/contrib/ddr/ddr.ts index bbcff56..ba2b26f 100644 --- a/src/contrib/ddr/ddr.ts +++ b/src/contrib/ddr/ddr.ts @@ -5,19 +5,19 @@ import { log, } from 'wechaty' -import { +import type { Vorpal, } from 'wechaty-vorpal' -import { +import type { WechatyVorpalConfig, -} from '../../config' +} from '../../config.js' import { DEFAULT_TIMEOUT, DEFAULT_NAME, -} from './config' -import { action } from './action' +} from './config.js' +import { action } from './action.js' export interface DdrConfig extends WechatyVorpalConfig {} diff --git a/src/contrib/ddr/mod.ts b/src/contrib/ddr/mod.ts index 29f4e43..fc3c0b0 100644 --- a/src/contrib/ddr/mod.ts +++ b/src/contrib/ddr/mod.ts @@ -1,4 +1,6 @@ export { Ddr, +} from './ddr.js' +export type { DdrConfig, -} from './ddr' +} from './ddr.js' diff --git a/src/contrib/ddr/monitor.ts b/src/contrib/ddr/monitor.ts index 52ff3d6..f05075c 100644 --- a/src/contrib/ddr/monitor.ts +++ b/src/contrib/ddr/monitor.ts @@ -17,27 +17,27 @@ import { Message, log, } from 'wechaty' -import { +import type { EventMessagePayload, } from 'wechaty-puppet' -import { Reporter } from './reporter' +import { Reporter } from './reporter.js' import { toMessage$, sameRoom, isText, isNotSelf, toSeconds, -} from './utils' +} from './utils.js' import { nextState, initialState, State, -} from './reducer' -import { +} from './reducer.js' +import type { DdrOptions, -} from './ddr' -import { Store } from './store' +} from './ddr.js' +import { Store } from './store.js' class Monitor { diff --git a/src/contrib/ddr/reducer.ts b/src/contrib/ddr/reducer.ts index 59b7dbc..83512d9 100644 --- a/src/contrib/ddr/reducer.ts +++ b/src/contrib/ddr/reducer.ts @@ -1,8 +1,14 @@ -import { Message } from 'wechaty' -import { +import type { Message } from 'wechaty' +import type { DeepReadonly, } from 'utility-types' +interface Record { + id: string, + name: string, + time: number, +} + const initialState: DeepReadonly<{ meta: { time: number @@ -17,6 +23,11 @@ const initialState: DeepReadonly<{ payload: {}, } +// https://stackoverflow.com/a/43001581/1123955 +type DeepWriteable = { -readonly [P in keyof T]: DeepWriteable } + +type State = DeepWriteable + /** * Async reducer: https://stackoverflow.com/a/41243567/1123955 */ @@ -59,14 +70,9 @@ const nextState = async (stateFuture: Promise, message?: Message): Promis return newState } -// https://stackoverflow.com/a/43001581/1123955 -type DeepWriteable = { -readonly [P in keyof T]: DeepWriteable } - -export type State = DeepWriteable -export interface Record { - id: string, - name: string, - time: number, +export type { + State, + Record, } export { nextState, diff --git a/src/contrib/ddr/reporter.spec.ts b/src/contrib/ddr/reporter.spec.ts index 5147adf..a46a0fa 100755 --- a/src/contrib/ddr/reporter.spec.ts +++ b/src/contrib/ddr/reporter.spec.ts @@ -1,20 +1,20 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm import { test } from 'tstest' import { createFixture } from 'wechaty-mocker' -import { Reporter } from './reporter' -import { DEFAULT_OPTIONS } from './ddr' -import { Store } from './store' +import { Reporter } from './reporter.js' +import { DEFAULT_OPTIONS } from './ddr.js' +import { Store } from './store.js' class ReporterTest extends Reporter { - public get stateList () { return super.stateList } + override get stateList () { return super.stateList } - sum () { return super.sum() } - average () { return super.average() } - idCounterDict () { return super.idCounterDict() } + override sum () { return super.sum() } + override average () { return super.average() } + override idCounterDict () { return super.idCounterDict() } } diff --git a/src/contrib/ddr/reporter.ts b/src/contrib/ddr/reporter.ts index 5624354..2eeec11 100644 --- a/src/contrib/ddr/reporter.ts +++ b/src/contrib/ddr/reporter.ts @@ -4,12 +4,12 @@ import { State, Record, initialState, -} from './reducer' -import { Monitor } from './monitor' -import { Message } from 'wechaty' +} from './reducer.js' +import type { Monitor } from './monitor.js' +import type { Message } from 'wechaty' -import { DdrOptions } from './ddr' -import { Store } from './store' +import type { DdrOptions } from './ddr.js' +import { Store } from './store.js' class Reporter { @@ -48,7 +48,7 @@ class Reporter { protected describeDdr (state: State): string { const ddrRate = this.ddrRateDict() - const sortRecord = (a: Record, b: Record) => ddrRate[b.id] - ddrRate[a.id] + const sortRecord = (a: Record, b: Record) => ddrRate[b.id]! - ddrRate[a.id]! let rank = 0 const board = Object.values(state.payload) @@ -80,7 +80,7 @@ class Reporter { Object.keys(state.payload).forEach(id => { if (typeof id !== 'string') { return } dict[id] = id in dict - ? dict[id] + 1 + ? dict[id]! + 1 : 1 }) return dict @@ -98,7 +98,7 @@ class Reporter { [record.id]: { ...record, time: record.id in state.payload - ? record.time + state.payload[record.id].time + ? record.time + state.payload[record.id]!.time : record.time, }, }, diff --git a/src/contrib/ddr/store.ts b/src/contrib/ddr/store.ts index 71973be..ae17490 100644 --- a/src/contrib/ddr/store.ts +++ b/src/contrib/ddr/store.ts @@ -1,11 +1,11 @@ -import { Message } from 'wechaty' +import type { Message } from 'wechaty' -import { State } from './reducer' +import type { State } from './reducer.js' interface DdrStore { stateList: State[], monitor: { - timer? : NodeJS.Timer, + timer? : ReturnType, timeout? : number | string, interval? : string, } @@ -44,7 +44,7 @@ class Store { stateList: [], } } - return klass.memory[id] + return klass.memory[id]! } clear (all = false): void { diff --git a/src/contrib/ddr/utils.ts b/src/contrib/ddr/utils.ts index a738092..c0c2df4 100644 --- a/src/contrib/ddr/utils.ts +++ b/src/contrib/ddr/utils.ts @@ -8,7 +8,7 @@ import { Message, Wechaty, } from 'wechaty' -import { +import type { EventMessagePayload, } from 'wechaty-puppet' import moment from 'moment' @@ -42,11 +42,11 @@ const toSeconds = (text: number | string): number => { if (match) { if (match[2]) { // '60s' seconds = moment.duration( - parseInt(match[1], 10), + parseInt(match[1]!, 10), match[2] as any, ).asSeconds() } else { // '60' - seconds = parseInt(match[1], 10) + seconds = parseInt(match[1]!, 10) } } } else { diff --git a/src/contrib/ding.ts b/src/contrib/ding.ts index 31856e2..137c0f3 100644 --- a/src/contrib/ding.ts +++ b/src/contrib/ding.ts @@ -1,4 +1,4 @@ -import { +import type { Args, CommandContext, Vorpal, @@ -22,7 +22,7 @@ async function dingAction ( args: Args ): Promise { log.verbose('WechatyVorpalContrib', 'Ding() dingAction("%s")', JSON.stringify(args)) - if (args.data && Array.isArray(args.data)) { + if (args['data'] && Array.isArray(args['data'])) { this.log('dong:' + JSON.stringify(args)) } } diff --git a/src/contrib/eval/async-eval.spec.ts b/src/contrib/eval/async-eval.spec.ts index a7351b1..246cd39 100755 --- a/src/contrib/eval/async-eval.spec.ts +++ b/src/contrib/eval/async-eval.spec.ts @@ -1,8 +1,8 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm import { test } from 'tstest' -import { asyncEval } from './async-eval' +import { asyncEval } from './async-eval.js' test('asyncEval resolve for `this`', async function (t) { const THIS = {} as any diff --git a/src/contrib/eval/eval.ts b/src/contrib/eval/eval.ts index d1cc07f..4945fb3 100644 --- a/src/contrib/eval/eval.ts +++ b/src/contrib/eval/eval.ts @@ -1,13 +1,13 @@ import { log } from 'wechaty' -import { +import type { Args, CommandContext, Vorpal, } from 'wechaty-vorpal' import safeStringify from 'json-stringify-safe' -import { asyncEval } from './async-eval' -import { normalizeRawCommand } from './normalize-raw-command' +import { asyncEval } from './async-eval.js' +import { normalizeRawCommand } from './normalize-raw-command.js' function Eval () { log.verbose('WechatyVorpalContrib', 'Eval()') @@ -41,12 +41,21 @@ async function evalAction ( try { result = safeStringify(result, null, 2) } catch (e) { - this.log(e.stack) + log.error('WechatyVorpalContrib', 'Eval() safeStringify() rejection %s', e) + + const name = (e as Error).name + const message = (e as Error).message + const stack = (e as Error).stack + this.log([ + name, + message, + stack, + ].join('\n')) } } this.log(result) } catch (e) { - this.log(e) + this.log(e as any) } } diff --git a/src/contrib/eval/mod.ts b/src/contrib/eval/mod.ts index f82966c..8259aa0 100644 --- a/src/contrib/eval/mod.ts +++ b/src/contrib/eval/mod.ts @@ -1 +1 @@ -export { Eval } from './eval' +export { Eval } from './eval.js' diff --git a/src/contrib/eval/normalize-raw-command.spec.ts b/src/contrib/eval/normalize-raw-command.spec.ts index bb5d239..f5dd408 100755 --- a/src/contrib/eval/normalize-raw-command.spec.ts +++ b/src/contrib/eval/normalize-raw-command.spec.ts @@ -1,8 +1,8 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm import { test } from 'tstest' -import { normalizeRawCommand } from './normalize-raw-command' +import { normalizeRawCommand } from './normalize-raw-command.js' test('normalizeRawCommand', async t => { const CMD = ` diff --git a/src/contrib/find.ts b/src/contrib/find.ts index 635537d..0d6d615 100644 --- a/src/contrib/find.ts +++ b/src/contrib/find.ts @@ -5,7 +5,7 @@ import { Args, } from 'wechaty-vorpal' -import { regexFromString } from '../utils/regex-from-string' +import { regexFromString } from '../utils/regex-from-string.js' function Find () { log.verbose('WechatyVorpalContrib', 'Find()') diff --git a/src/contrib/math_master/action.ts b/src/contrib/math_master/action.ts index 814263c..d1fb190 100644 --- a/src/contrib/math_master/action.ts +++ b/src/contrib/math_master/action.ts @@ -19,23 +19,23 @@ import { log, FileBox, } from 'wechaty' -import { +import type { CommandContext, Args, } from 'wechaty-vorpal' import { TIMER_MAX, -} from './config' +} from './config.js' import { State, nextState, initialGameState, -} from './reducer' +} from './reducer.js' import { registerLeaderBoard, reportLeaderBoard, -} from './leader_board' +} from './leader_board.js' // interface MathMasterOptions {} @@ -45,7 +45,7 @@ async function action ( ): Promise { log.verbose('WechatyVorpalContrib', 'mathMasterAction("%s")', JSON.stringify(args)) - if (args.options.leaderboard) { + if (args.options['leaderboard']) { const board = reportLeaderBoard() this.stdout.next(board) return 0 diff --git a/src/contrib/math_master/leader_board.spec.ts b/src/contrib/math_master/leader_board.spec.ts index bed6ec0..2b01c52 100755 --- a/src/contrib/math_master/leader_board.spec.ts +++ b/src/contrib/math_master/leader_board.spec.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm import { test, @@ -7,9 +7,9 @@ import { import { registerLeaderBoard, reportLeaderBoard, -} from './leader_board' -import { CommandContext } from 'wechaty-vorpal' -import { Contact } from 'wechaty' +} from './leader_board.js' +import type { CommandContext } from 'wechaty-vorpal' +import type { Contact } from 'wechaty' test('leaderBoard', async t => { const ID_LIST = ['id1', 'id2', 'id3'] @@ -32,14 +32,14 @@ test('leaderBoard', async t => { await registerLeaderBoard( context, player, - SCORE_LIST[i] + SCORE_LIST[i]!, ) resultList[i] = await reportLeaderBoard() } - t.ok(resultList[0].includes('name1(3) hello'), 'should get result 0') - t.ok(resultList[1].includes('name1(3) hello\n#2 - name2(1) damn'), 'should get result 1') - t.ok(resultList[2].includes('name1(3) hello\n#2 - name3(2) \n#3 - name2(1) damn'), 'should get result 2') + t.ok(resultList[0]!.includes('name1(3) hello'), 'should get result 0') + t.ok(resultList[1]!.includes('name1(3) hello\n#2 - name2(1) damn'), 'should get result 1') + t.ok(resultList[2]!.includes('name1(3) hello\n#2 - name3(2) \n#3 - name2(1) damn'), 'should get result 2') // console.info(resultList[2]) }) diff --git a/src/contrib/math_master/leader_board.ts b/src/contrib/math_master/leader_board.ts index 53763c1..0de335e 100644 --- a/src/contrib/math_master/leader_board.ts +++ b/src/contrib/math_master/leader_board.ts @@ -1,5 +1,5 @@ -import { Contact } from 'wechaty' -import { CommandContext } from 'wechaty-vorpal' +import type { Contact } from 'wechaty' +import type { CommandContext } from 'wechaty-vorpal' interface ScoreBoard { [id: string]: { @@ -46,8 +46,8 @@ function update ( } } - if (score > scoreBoard[player.id]?.score) { - scoreBoard[player.id].score = score + if (score > scoreBoard[player.id]!.score) { + scoreBoard[player.id]!.score = score } } @@ -70,9 +70,10 @@ async function registerLeaderBoard ( 'What do you want to say now?', ].join('\n')) - if (typeof comment === 'string' && comment && comment !== '0') { + const playerScore = scoreBoard[player.id] + if (playerScore && typeof comment === 'string' && comment && comment !== '0') { scoreBoard[player.id] = { - ...scoreBoard[player.id], + ...playerScore, comment, } } diff --git a/src/contrib/math_master/math_master.spec.ts b/src/contrib/math_master/math_master.spec.ts index ac35372..4318738 100755 --- a/src/contrib/math_master/math_master.spec.ts +++ b/src/contrib/math_master/math_master.spec.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm import { test, @@ -16,7 +16,7 @@ import { WechatyVorpal, } from 'wechaty-vorpal' -import { MathMaster } from './math_master' +import { MathMaster } from './math_master.js' test('math_master', async t => { /** @@ -41,7 +41,7 @@ test('math_master', async t => { */ await wechaty.start() - const [bot, player] = mocker.createContacts(2) + const [bot, player] = mocker.createContacts(2) as [mock.ContactMock, mock.ContactMock] mocker.login(bot) /** @@ -57,7 +57,7 @@ test('math_master', async t => { const MATH_RE = /(\d+) \+ (\d+) = \?/ const match = text?.match(MATH_RE) if (match) { - const result = parseInt(match[1], 10) + parseInt(match[2], 10) + const result = parseInt(match[1]!, 10) + parseInt(match[2]!, 10) // const timeout = match[1].length * 1000 // console.info('timeout:', timeout) @@ -115,7 +115,7 @@ function expectGameScore (player: mock.ContactMock) { const match = text.match(/score is: (\d+)!/i) if (match) { - const n = parseInt(match[1], 10) + const n = parseInt(match[1]!, 10) resolve(n) } else { resolve(0) diff --git a/src/contrib/math_master/math_master.ts b/src/contrib/math_master/math_master.ts index 2623c94..dbef8f1 100644 --- a/src/contrib/math_master/math_master.ts +++ b/src/contrib/math_master/math_master.ts @@ -5,15 +5,15 @@ import { log, } from 'wechaty' -import { +import type { Vorpal, } from 'wechaty-vorpal' -import { +import type { WechatyVorpalConfig, -} from '../../config' +} from '../../config.js' -import { action } from './action' +import { action } from './action.js' export interface MathMasterConfig extends WechatyVorpalConfig {} diff --git a/src/contrib/math_master/mod.ts b/src/contrib/math_master/mod.ts index fd6a0d9..8ebda46 100644 --- a/src/contrib/math_master/mod.ts +++ b/src/contrib/math_master/mod.ts @@ -1,4 +1,6 @@ +export type { + MathMasterConfig, +} from './math_master.js' export { MathMaster, - MathMasterConfig, -} from './math_master' +} from './math_master.js' diff --git a/src/contrib/math_master/question_answer.ts b/src/contrib/math_master/question_answer.ts index 8e982fa..275829f 100644 --- a/src/contrib/math_master/question_answer.ts +++ b/src/contrib/math_master/question_answer.ts @@ -1,6 +1,6 @@ -import { types } from 'wechaty-plugin-contrib' +import type { types } from 'wechaty-plugin-contrib' -import { State } from './reducer' +import type { State } from './reducer.js' const generateQuestionAnswer = (score: number) => { const randomNumber = () => { diff --git a/src/contrib/math_master/reducer.ts b/src/contrib/math_master/reducer.ts index c363f1e..83818ee 100644 --- a/src/contrib/math_master/reducer.ts +++ b/src/contrib/math_master/reducer.ts @@ -1,14 +1,14 @@ -import { ObsIo } from 'wechaty-vorpal' -import { types } from 'wechaty-plugin-contrib' +import type { ObsIo } from 'wechaty-vorpal' +import type { types } from 'wechaty-plugin-contrib' import { generateQuestionAnswer, isCorrectAnswer, -} from './question_answer' +} from './question_answer.js' import { TIMER_MAX, SCORE_MAX, -} from './config' +} from './config.js' const initialGameState = { ...generateQuestionAnswer(0), @@ -16,6 +16,8 @@ const initialGameState = { timer : TIMER_MAX, } +type State = typeof initialGameState + const nextState = (stdout: ObsIo['stdout']) => ( state: State, value: types.SayableMessage, @@ -49,8 +51,9 @@ const nextState = (stdout: ObsIo['stdout']) => ( } } -export type State = typeof initialGameState - +export type { + State, +} export { initialGameState, nextState, diff --git a/src/contrib/url_link.ts b/src/contrib/url_link.ts index ce97011..9037313 100644 --- a/src/contrib/url_link.ts +++ b/src/contrib/url_link.ts @@ -3,7 +3,7 @@ import { UrlLink as WechatyUrlLink, UrlLinkPayload, } from 'wechaty' -import { +import type { Vorpal, CommandContext, Args, @@ -32,9 +32,9 @@ async function urlLinkAction ( ): Promise { log.verbose('WechatyVorpalContrib', 'urlLinkAction("%s")', JSON.stringify(args)) - const url: string = Array.isArray(args.url) - ? args.url[0] - : args.url + const url: string = Array.isArray(args['url']) + ? args['url'][0]! + : args['url']! const options: UrlLinkOptions = args.options const urlLink = await WechatyUrlLink.create(url) diff --git a/src/contrib/version.ts b/src/contrib/version.ts index a58c0aa..174f6d6 100644 --- a/src/contrib/version.ts +++ b/src/contrib/version.ts @@ -1,6 +1,4 @@ -import readPkgUp from 'read-pkg-up' - -import { +import type { Vorpal, CommandContext, Args, @@ -9,9 +7,11 @@ import { log, } from 'wechaty' -import { +import type { WechatyVorpalConfig, -} from '../config' +} from '../config.js' + +import { packageJson } from '../package-json.js' interface VersionConfig extends WechatyVorpalConfig {} @@ -44,29 +44,22 @@ async function versionAction ( const options = args.options as any as VersionOptions - const pkg = (await readPkgUp())?.packageJson - - if (!pkg) { - this.stderr.next('readPkgUp: packageJson not found.') - return 1 - } - if (!options.dependencies && !options.devDependencies) { - this.stdout.next(pkg.version) + this.stdout.next(packageJson.version) return 0 } - if (options.dependencies && pkg.dependencies) { + if (options.dependencies && packageJson.dependencies) { this.stdout.next( - Object.entries(pkg.dependencies) + Object.entries(packageJson.dependencies) .map(([name, version]) => `${name}@${version}`) .join('\n') ) } - if (options.devDependencies && pkg.devDependencies) { + if (options.devDependencies && packageJson.devDependencies) { this.stdout.next( - Object.entries(pkg.devDependencies) + Object.entries(packageJson.devDependencies) .map(([name, version]) => `${name}@${version}`) .join('\n') ) diff --git a/src/contrib/whoru.ts b/src/contrib/whoru.ts index b2657f3..49bc949 100644 --- a/src/contrib/whoru.ts +++ b/src/contrib/whoru.ts @@ -2,9 +2,8 @@ import os from 'os' import ip from 'ip' import publicIp from 'public-ip' -import readPkgUp from 'read-pkg-up' -import { +import type { Vorpal, CommandContext, Args, @@ -15,9 +14,11 @@ import { import moment from 'moment' import { VERSION as WECHATY_PUPPET_VERSION } from 'wechaty-puppet' -import { +import type { WechatyVorpalConfig, -} from '../config' +} from '../config.js' + +import { packageJson } from '../package-json.js' interface WhoruConfig extends WechatyVorpalConfig {} @@ -52,8 +53,6 @@ async function whoruAction ( const options = args.options as any as WhoruOptions - const pkg = (await readPkgUp())?.packageJson - const wechaty = this.wechaty const puppet = wechaty.puppet @@ -68,7 +67,7 @@ async function whoruAction ( const botAge = moment(bornDate).fromNow() const reportList = [ - `This is ${pkg?.name}@${pkg?.version}, ${pkg?.description}`, + `This is ${packageJson.name}@${packageJson.version}, ${packageJson.description}`, '', [ `I logged in WeChat as ${botName} ${botAge},`, diff --git a/src/mod.ts b/src/mod.ts index c079384..c3227b9 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -1,35 +1,55 @@ -export { +import { WechatyVorpalConfig, -} from './config' -export { VERSION } from './version' + VERSION, +} from './config.js' -export { +import { MathMaster, MathMasterConfig, -} from './contrib/math_master/mod' -export { +} from './contrib/math_master/mod.js' +import { Ddr, DdrConfig, -} from './contrib/ddr/mod' -export { Eval } from './contrib/eval/mod' +} from './contrib/ddr/mod.js' +import { Eval } from './contrib/eval/mod.js' -export { Ding } from './contrib/ding' -export { +import { Ding } from './contrib/ding.js' +import { Cash, CashConfig, -} from './contrib/cash' -export { +} from './contrib/cash.js' +import { UrlLink, -} from './contrib/url_link' -export { +} from './contrib/url_link.js' +import { Find, -} from './contrib/find' -export { +} from './contrib/find.js' +import { Announce, -} from './contrib/announce' -export { +} from './contrib/announce.js' +import { Whoru, -} from './contrib/whoru' +} from './contrib/whoru.js' +import { + Version, +} from './contrib/version.js' + +export type { + WechatyVorpalConfig, + MathMasterConfig, + DdrConfig, + CashConfig, +} export { + VERSION, + MathMaster, + Ddr, + Eval, + Ding, + Cash, + UrlLink, + Find, + Announce, + Whoru, Version, -} from './contrib/version' +} diff --git a/src/package-json.spec.ts b/src/package-json.spec.ts new file mode 100755 index 0000000..5d9cac5 --- /dev/null +++ b/src/package-json.spec.ts @@ -0,0 +1,10 @@ +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm + +import { test } from 'tstest' + +import { packageJson } from './package-json.js' + +test('Make sure the packageJson is fresh in source code', async t => { + const keyNum = Object.keys(packageJson).length + t.equal(keyNum, 0, 'packageJson should be empty in source code, only updated before publish to NPM') +}) diff --git a/src/package-json.ts b/src/package-json.ts new file mode 100644 index 0000000..0a9806f --- /dev/null +++ b/src/package-json.ts @@ -0,0 +1,11 @@ +/** + * This file will be overwrite when we publish NPM module + * by scripts/generate_version.ts + */ +import type { PackageJson } from 'type-fest' + +/** + * Huan(202108): + * The below default values is only for unit testing + */ +export const packageJson: PackageJson = {} diff --git a/src/utils/regex-from-string.spec.ts b/src/utils/regex-from-string.spec.ts index 90be2e8..a60ad0f 100755 --- a/src/utils/regex-from-string.spec.ts +++ b/src/utils/regex-from-string.spec.ts @@ -1,8 +1,8 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm import { test } from 'tstest' -import { regexFromString } from './regex-from-string' +import { regexFromString } from './regex-from-string.js' test('regexFromString()', async t => { const string = '/hello\\s{0,1}[-_.]{0,1}world|ls\\b/gim' diff --git a/src/utils/regex-from-string.ts b/src/utils/regex-from-string.ts index 87b550b..3fa69b6 100644 --- a/src/utils/regex-from-string.ts +++ b/src/utils/regex-from-string.ts @@ -2,7 +2,7 @@ function regexFromString (str: string): RegExp { const match = /^\/(.*)\/([a-z]*)$/.exec(str) if (match) { - return new RegExp(match[1], match[2]) + return new RegExp(match[1]!, match[2]!) } else { return new RegExp(str) } diff --git a/src/version.spec.ts b/src/version.spec.ts deleted file mode 100755 index efc051a..0000000 --- a/src/version.spec.ts +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env ts-node - -import { test } from 'tstest' - -import { VERSION } from './version' - -test('Make sure the VERSION is fresh in source code', async t => { - t.equal(VERSION, '0.0.0', 'version should be 0.0.0 in source code, only updated before publish to NPM') -}) diff --git a/src/version.ts b/src/version.ts deleted file mode 100644 index c36f2c5..0000000 --- a/src/version.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * This file will be overwrite when we publish NPM module - * by scripts/generate_version.ts - */ - -export const VERSION = '0.0.0' diff --git a/tests/fixtures/smoke-testing.ts b/tests/fixtures/smoke-testing.ts index 7a030b1..5b38abe 100644 --- a/tests/fixtures/smoke-testing.ts +++ b/tests/fixtures/smoke-testing.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm import { VERSION, } from 'wechaty-vorpal-contrib' diff --git a/tests/integration.spec.ts b/tests/integration.spec.ts index 789b0ba..4e02b85 100755 --- a/tests/integration.spec.ts +++ b/tests/integration.spec.ts @@ -1,4 +1,4 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm import { test, diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json new file mode 100644 index 0000000..8693cd0 --- /dev/null +++ b/tsconfig.cjs.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "module": "CommonJS", + "outDir": "dist/cjs", + }, +} diff --git a/tsconfig.json b/tsconfig.json index 728a055..bbf1a08 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "extends": "@chatie/tsconfig", "compilerOptions": { - "outDir": "dist", + "outDir": "dist/esm", }, "exclude": [ "node_modules/",