From 3f80bfe0028204fd674c310d2845ab7ca5ecc94d Mon Sep 17 00:00:00 2001 From: Huan Date: Sun, 12 Sep 2021 17:53:53 +0800 Subject: [PATCH] Enbale ESM --- .eslintrc.js => .eslintrc.cjs | 0 .github/workflows/npm.yml | 30 +++-- README.md | 4 +- .../event-hot-handler.spec.ts | 6 +- .../event-hot-handler.ts | 6 +- examples/ding-dong-bot.ts | 2 +- examples/message-awaiter-bot.ts | 2 +- package.json | 44 ++++--- scripts/generate-package-json.sh | 20 ++++ scripts/generate-version.sh | 18 --- scripts/npm-pack-testing.sh | 43 ++++++- src/config.ts | 12 +- src/contrib/chatops.ts | 2 +- src/contrib/ding-dong/ding-dong.spec.ts | 8 +- src/contrib/ding-dong/ding-dong.ts | 9 +- src/contrib/ding-dong/mod.ts | 11 +- src/contrib/friendship-accepter.spec.ts | 6 +- src/contrib/friendship-accepter.ts | 4 +- src/contrib/heartbeat/get-emoji.ts | 8 +- src/contrib/heartbeat/heartbeat.ts | 12 +- src/contrib/heartbeat/mod.ts | 4 +- src/contrib/heartbeat/options.spec.ts | 12 +- src/contrib/heartbeat/options.ts | 6 +- src/contrib/heartbeat/say-emoji.ts | 12 +- src/contrib/message-awaiter.ts | 2 +- src/contrib/qr-code-terminal.ts | 4 +- .../many-to-many-room-connector.ts | 6 +- .../many-to-one-room-connector.ts | 6 +- src/contrib/room-connector/mod.ts | 29 +++-- .../one-to-many-room-connector.ts | 6 +- .../source-to-target-room-connector.ts | 8 +- src/contrib/room-inviter.spec.ts | 6 +- src/contrib/room-inviter.ts | 14 +-- src/finders/mod.ts | 17 ++- src/mappers/message-mapper.ts | 4 +- src/mappers/mod.ts | 6 +- src/matchers/contact-matcher.spec.ts | 8 +- src/matchers/language-matcher.spec.ts | 6 +- src/matchers/language-matcher.ts | 4 +- src/matchers/message-matcher.spec.ts | 8 +- src/matchers/mod.ts | 35 ++++-- src/matchers/room-matcher.spec.ts | 9 +- src/matchers/string-matcher.spec.ts | 6 +- src/mod.spec.ts | 10 +- src/mod.ts | 110 +++++++++++------- src/package-json.spec.ts | 10 ++ src/package-json.ts | 11 ++ src/talkers/contact-talker.spec.ts | 32 ++--- src/talkers/contact-talker.ts | 2 +- src/talkers/message-talker.spec.ts | 24 ++-- src/talkers/message-talker.ts | 2 +- src/talkers/mod.ts | 23 +++- src/talkers/room-talker.spec.ts | 81 ++++++------- src/talkers/room-talker.ts | 2 +- src/types/mod.ts | 11 +- src/typings.d.ts | 1 + src/validate-plugin.spec.ts | 10 +- src/version.spec.ts | 9 -- src/version.ts | 6 - tests/fixtures/smoke-testing.ts | 2 +- tests/integration.spec.ts | 6 +- tsconfig.cjs.json | 7 ++ tsconfig.json | 2 +- 63 files changed, 506 insertions(+), 320 deletions(-) rename .eslintrc.js => .eslintrc.cjs (100%) rename {src/contrib => deprecated}/event-hot-handler.spec.ts (78%) rename {src/contrib => deprecated}/event-hot-handler.ts (93%) create mode 100755 scripts/generate-package-json.sh delete mode 100755 scripts/generate-version.sh create mode 100755 src/package-json.spec.ts create mode 100644 src/package-json.ts delete mode 100755 src/version.spec.ts delete mode 100644 src/version.ts create mode 100644 tsconfig.cjs.json 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 115fb06..fc6e93e 100644 --- a/.github/workflows/npm.yml +++ b/.github/workflows/npm.yml @@ -7,16 +7,20 @@ jobs: name: Build strategy: matrix: - os: [ubuntu-latest] - node: [12] + os: + - ubuntu-latest + node: + - 16 runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 + uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} + cache: npm + cache-dependency-path: package.json - name: Install Dependencies run: npm install @@ -30,15 +34,17 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - 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 @@ -52,13 +58,15 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - 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 Package JSON + run: ./scripts/generate-package-json.sh - name: Generate Version run: ./scripts/generate-version.sh diff --git a/README.md b/README.md index a5f4473..5068737 100644 --- a/README.md +++ b/README.md @@ -249,7 +249,7 @@ const config: RoomInviterConfig = { wechaty.use(RoomInviter(config)) ``` -### 9 EventHotHandler +### ~~9 EventHotHandler~~ DEPRECATED after v0.15 Hot reloading event handler module files. @@ -325,6 +325,8 @@ We are listing those powerful Wechaty Plugins outside the contrib as in the foll ### master v0.15 1. Add `SourceToTargetRoomConnector` to connect a source room to a target room by forward messages to target room. +1. Support ES Modules + 1. Deprecated `EventHotHandler` due to ESM ### v0.14 master diff --git a/src/contrib/event-hot-handler.spec.ts b/deprecated/event-hot-handler.spec.ts similarity index 78% rename from src/contrib/event-hot-handler.spec.ts rename to deprecated/event-hot-handler.spec.ts index fc81607..c2a7969 100755 --- a/src/contrib/event-hot-handler.spec.ts +++ b/deprecated/event-hot-handler.spec.ts @@ -1,11 +1,11 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm -import test from 'tstest' +import { test } from 'tstest' import { Wechaty } from 'wechaty' import { PuppetMock } from 'wechaty-puppet-mock' -import { EventHotHandler } from './event-hot-handler' +import { EventHotHandler } from './event-hot-handler.js' test('EventHotHandler perfect restart testing', async t => { const wechaty = new Wechaty({ puppet: new PuppetMock() }) diff --git a/src/contrib/event-hot-handler.ts b/deprecated/event-hot-handler.ts similarity index 93% rename from src/contrib/event-hot-handler.ts rename to deprecated/event-hot-handler.ts index 3ee8513..f734cb7 100644 --- a/src/contrib/event-hot-handler.ts +++ b/deprecated/event-hot-handler.ts @@ -9,7 +9,7 @@ import { log, } from 'wechaty' -import { WechatyEventName } from 'wechaty/dist/src/events/wechaty-events' +import type { WechatyEventName } from 'wechaty/dist/src/events/wechaty-events' import { callerResolve, @@ -84,13 +84,13 @@ async function addEventHandler ( log.error('WechatyPluginContrib', 'EventHotHandler EventHotHandlerPlugin(%s) listener(%s) exception%s', wechaty, eventName, e, ) - wechaty.emit('error', e) + wechaty.emit('error', e as Error) } }) } catch (e) { log.error('WechatyPluginContrib', 'EventHotHandler EventHotHandlerPlugin() eventName(%s) hotImport(%s) rejection: %s', eventName, absoluteFilename, e, ) - wechaty.emit('error', e) + wechaty.emit('error', e as Error) } } diff --git a/examples/ding-dong-bot.ts b/examples/ding-dong-bot.ts index 5b80c85..35f12d7 100644 --- a/examples/ding-dong-bot.ts +++ b/examples/ding-dong-bot.ts @@ -22,7 +22,7 @@ import { DingDong, EventLogger, QRCodeTerminal, -} from '../src/mod' // from 'wechaty-plugin-contrib' +} from '../src/mod.js' // from 'wechaty-plugin-contrib' const bot = new Wechaty({ name : 'ding-dong-bot', diff --git a/examples/message-awaiter-bot.ts b/examples/message-awaiter-bot.ts index e5e431d..737b0b0 100644 --- a/examples/message-awaiter-bot.ts +++ b/examples/message-awaiter-bot.ts @@ -23,7 +23,7 @@ import { EventLogger, QRCodeTerminal, MessageAwaiter, -} from '../src/mod' // from 'wechaty-plugin-contrib' +} from '../src/mod.js' // from 'wechaty-plugin-contrib' const bot = new Wechaty({ name: 'message-awaiter-bot', diff --git a/package.json b/package.json index 95e4f2c..02ab2cb 100644 --- a/package.json +++ b/package.json @@ -2,11 +2,18 @@ "name": "wechaty-plugin-contrib", "version": "0.15.5", "description": "Wechaty Plugin Ecosystem Contrib Package", - "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": { - "node": ">= 12", - "wechaty": ">=0.56" + "wechaty": ">=0.69", + "wechaty-puppet": ">=0.43", + "node": ">=14" }, "directories": { "test": "tests" @@ -17,14 +24,16 @@ "qrcode-terminal": "^0.12.0" }, "devDependencies": { - "@chatie/eslint-config": "^0.12.4", + "@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/mustache": "^4.1.2", + "npm-run-all": "^4.1.5", "pkg-jq": "^0.2.11", "shx": "^0.3.3", - "tstest": "^0.4.10", + "tstest": "^0.5.16", + "typescript": "^4.4.3", "wechaty": "^0.65.6", "wechaty-mocker": "^0.7.3", "wechaty-puppet-mock": "^0.29.10" @@ -33,17 +42,18 @@ "wechaty": "*" }, "scripts": { + "build": "tsc && tsc -p tsconfig.cjs.json", "clean": "shx rm -fr dist/*", - "dist": "npm run clean && tsc", - "pack": "npm pack", + "dist": "npm-run-all clean build dist:commonjs", + "dist:commonjs": "jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json", "lint": "npm run lint:es && npm run lint:ts && npm run 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\" 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": "blue-tape -r ts-node/register \"src/**/*.spec.ts\" \"src/*.spec.ts\" \"tests/*.spec.ts\" \"tests/**/*.spec.ts\"", + "test:unit": "tap --node-arg=--loader=ts-node/esm --node-arg=--no-warnings \"src/**/*.spec.ts\" \"src/*.spec.ts\" \"tests/*.spec.ts\" \"tests/**/*.spec.ts\"", "lint:es": "eslint --ignore-pattern tests/fixtures/ '{bin,examples,scripts,src,tests}/**/*.ts'" }, "repository": { @@ -66,6 +76,14 @@ "pre-push": "npx git-scripts-pre-push" } }, + "files": [ + "bin/", + "dist/", + "src/" + ], + "tap": { + "check-coverage": false + }, "publishConfig": { "tag": "next" } diff --git a/scripts/generate-package-json.sh b/scripts/generate-package-json.sh new file mode 100755 index 0000000..790f924 --- /dev/null +++ b/scripts/generate-package-json.sh @@ -0,0 +1,20 @@ +#!/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 +} + +VERSION=$(npx pkg-jq -r .version) + +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 86a8912..0a85b58 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,12 +18,45 @@ mv ./*-*.*.*.tgz "$TMPDIR" cp tests/fixtures/smoke-testing.ts "$TMPDIR" cd $TMPDIR + npm init -y -npm install *-*.*.*.tgz \ - @chatie/tsconfig \ +npm install --production *-*.*.*.tgz \ + @types/node \ + @chatie/tsconfig@$NPM_TAG \ + pkg-jq \ + "wechaty-puppet@$NPM_TAG" \ "wechaty@$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 \ @@ -31,4 +64,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 ab998f1..4afa1f7 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,2 +1,10 @@ -export { VERSION } from './version' -export { log } from 'wechaty' +/// +import { log } from 'wechaty' +import { packageJson } from './package-json.js' + +const VERSION = packageJson.version || '0.0.0' + +export { + log, + VERSION, +} diff --git a/src/contrib/chatops.ts b/src/contrib/chatops.ts index e46e274..4d6e6d8 100644 --- a/src/contrib/chatops.ts +++ b/src/contrib/chatops.ts @@ -13,7 +13,7 @@ import { import { MessageMatcherOptions, messageMatcher, -} from '../matchers/mod' +} from '../matchers/mod.js' export interface ChatOpsConfig { /** diff --git a/src/contrib/ding-dong/ding-dong.spec.ts b/src/contrib/ding-dong/ding-dong.spec.ts index a72aa32..a1e5c50 100755 --- a/src/contrib/ding-dong/ding-dong.spec.ts +++ b/src/contrib/ding-dong/ding-dong.spec.ts @@ -1,9 +1,9 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm -import test from 'tstest' +import { test } from 'tstest' // import sinon from 'sinon' -import { +import type { // Wechaty, Message, } from 'wechaty' @@ -14,7 +14,7 @@ import { import { isMatchConfig, DingDongConfigObject, -} from './ding-dong' +} from './ding-dong.js' test('isMatchConfig {mention: true}', async t => { for await (const fixture of createFixture()) { diff --git a/src/contrib/ding-dong/ding-dong.ts b/src/contrib/ding-dong/ding-dong.ts index e0ab7ac..326d2bc 100644 --- a/src/contrib/ding-dong/ding-dong.ts +++ b/src/contrib/ding-dong/ding-dong.ts @@ -7,11 +7,14 @@ import { Wechaty, WechatyPlugin, Message, - log, } from 'wechaty' -import * as matchers from '../../matchers/mod' -import * as talkers from '../../talkers/mod' +import { + log, +} from '../../config.js' + +import * as matchers from '../../matchers/mod.js' +import * as talkers from '../../talkers/mod.js' export interface DingDongConfigObject { /** diff --git a/src/contrib/ding-dong/mod.ts b/src/contrib/ding-dong/mod.ts index 3f11d82..cdb9685 100644 --- a/src/contrib/ding-dong/mod.ts +++ b/src/contrib/ding-dong/mod.ts @@ -1,4 +1,11 @@ -export { +import { DingDong, DingDongConfig, -} from './ding-dong' +} from './ding-dong.js' + +export type { + DingDongConfig, +} +export { + DingDong, +} diff --git a/src/contrib/friendship-accepter.spec.ts b/src/contrib/friendship-accepter.spec.ts index 83bf8ed..c8aa65b 100755 --- a/src/contrib/friendship-accepter.spec.ts +++ b/src/contrib/friendship-accepter.spec.ts @@ -1,7 +1,7 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm -import test from 'tstest' +import { test } from 'tstest' test('matchKeywordConfig()', async t => { - t.skip('tbw') + await t.skip('tbw') }) diff --git a/src/contrib/friendship-accepter.ts b/src/contrib/friendship-accepter.ts index c229d3c..1e4892b 100644 --- a/src/contrib/friendship-accepter.ts +++ b/src/contrib/friendship-accepter.ts @@ -12,11 +12,11 @@ import { import { StringMatcherOptions, stringMatcher, -} from '../matchers/mod' +} from '../matchers/mod.js' import { contactTalker, ContactTalkerOptions, -} from '../talkers/mod' +} from '../talkers/mod.js' export interface FriendshipAccepterConfig { greeting?: ContactTalkerOptions, diff --git a/src/contrib/heartbeat/get-emoji.ts b/src/contrib/heartbeat/get-emoji.ts index 68329fd..7088af3 100644 --- a/src/contrib/heartbeat/get-emoji.ts +++ b/src/contrib/heartbeat/get-emoji.ts @@ -1,14 +1,14 @@ -import { +import type { Wechaty, } from 'wechaty' import { log, -} from '../../config' +} from '../../config.js' -import { +import type { EmojiOption, -} from './options' +} from './options.js' export async function getEmoji ( event : string, diff --git a/src/contrib/heartbeat/heartbeat.ts b/src/contrib/heartbeat/heartbeat.ts index ec92967..8541918 100644 --- a/src/contrib/heartbeat/heartbeat.ts +++ b/src/contrib/heartbeat/heartbeat.ts @@ -2,7 +2,7 @@ * Author: Huan LI https://github.com/huan * Date: May 2020 */ -import { +import type { Wechaty, WechatyPlugin, Sayable, @@ -10,21 +10,21 @@ import { import { log, -} from '../../config' +} from '../../config.js' import { roomFinder, contactFinder, -} from '../../finders/mod' +} from '../../finders/mod.js' import { HeartbeatConfig, buildConfig, -} from './options' -import { sayEmoji } from './say-emoji' +} from './options.js' +import { sayEmoji } from './say-emoji.js' function heart () { - let timer: undefined | NodeJS.Timer + let timer: undefined | ReturnType const cleanTimer = () => { if (timer) { diff --git a/src/contrib/heartbeat/mod.ts b/src/contrib/heartbeat/mod.ts index 7b73e87..456aad6 100644 --- a/src/contrib/heartbeat/mod.ts +++ b/src/contrib/heartbeat/mod.ts @@ -1,2 +1,2 @@ -export { Heartbeat } from './heartbeat' -export { HeartbeatConfig } from './options' +export { Heartbeat } from './heartbeat.js' +export type { HeartbeatConfig } from './options.js' diff --git a/src/contrib/heartbeat/options.spec.ts b/src/contrib/heartbeat/options.spec.ts index 039e02b..eb4c94c 100755 --- a/src/contrib/heartbeat/options.spec.ts +++ b/src/contrib/heartbeat/options.spec.ts @@ -1,13 +1,13 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm -import test from 'tstest' +import { test } from 'tstest' import { buildConfig, // HeartbeatConfig, -} from './options' +} from './options.js' -test('buildConfig()', async (t) => { +test('buildConfig()', async t => { const EXPECTED_CONFIG = { contact: 'filehelper', emoji: { @@ -20,7 +20,7 @@ test('buildConfig()', async (t) => { t.deepEqual(result, EXPECTED_CONFIG, 'should get default config') }) -test('buildConfig(config)', async (t) => { +test('buildConfig(config)', async t => { const CONFIG = { emoji: { heartbeat : '[爱心]', @@ -47,7 +47,7 @@ test('buildConfig(config)', async (t) => { t.deepEqual(result, EXPECTED_CONFIG, 'should get merged config') }) -test('buildConfig({ room: "id" })', async (t) => { +test('buildConfig({ room: "id" })', async t => { const ROOM_ID = '43214123@chatroom' const CONFIG = { diff --git a/src/contrib/heartbeat/options.ts b/src/contrib/heartbeat/options.ts index 0d1fe64..868e559 100644 --- a/src/contrib/heartbeat/options.ts +++ b/src/contrib/heartbeat/options.ts @@ -1,11 +1,11 @@ -import { +import type { Wechaty, } from 'wechaty' -import { +import type { RoomFinderOptions, ContactFinderOptions, -} from '../../finders/mod' +} from '../../finders/mod.js' type HeartbeatFunction = (wechaty: Wechaty) => string | Promise export type EmojiOption = string | HeartbeatFunction diff --git a/src/contrib/heartbeat/say-emoji.ts b/src/contrib/heartbeat/say-emoji.ts index 26a3dbf..1b6da2d 100644 --- a/src/contrib/heartbeat/say-emoji.ts +++ b/src/contrib/heartbeat/say-emoji.ts @@ -1,9 +1,9 @@ -import { Sayable } from 'wechaty' +import type { Sayable } from 'wechaty' -import { log } from '../../config' +import { log } from '../../config.js' -import { EmojiOption } from './options' -import { getEmoji } from './get-emoji' +import type { EmojiOption } from './options.js' +import { getEmoji } from './get-emoji.js' export function sayEmoji ( event : string, @@ -17,7 +17,7 @@ export function sayEmoji ( return } - const wechaty = talkerList[0].wechaty + const wechaty = talkerList[0]!.wechaty const emojiText = await getEmoji(event, wechaty, emojiOption) if (!emojiText) { @@ -33,7 +33,7 @@ export function sayEmoji ( try { await talker.say(emojiText) } catch (e) { - wechaty.emit('error', e) + wechaty.emit('error', e as Error) } } diff --git a/src/contrib/message-awaiter.ts b/src/contrib/message-awaiter.ts index 8b36509..4fdc9ad 100644 --- a/src/contrib/message-awaiter.ts +++ b/src/contrib/message-awaiter.ts @@ -9,7 +9,7 @@ import { log, } from 'wechaty' -import * as matchers from '../matchers/mod' +import * as matchers from '../matchers/mod.js' type MessageAwaiterArgs = { contact?: matchers.ContactMatcherOptions, diff --git a/src/contrib/qr-code-terminal.ts b/src/contrib/qr-code-terminal.ts index fa77ebb..2c5f87b 100644 --- a/src/contrib/qr-code-terminal.ts +++ b/src/contrib/qr-code-terminal.ts @@ -9,7 +9,7 @@ import { log, } from 'wechaty' -import { generate } from 'qrcode-terminal' +import qrTerminal from 'qrcode-terminal' export interface QRCodeTerminalConfig { small?: boolean, @@ -27,7 +27,7 @@ export function QRCodeTerminal ( wechaty.on('scan', function onScan (qrcode: string, status: ScanStatus) { if (status === ScanStatus.Waiting || status === ScanStatus.Timeout) { - generate(qrcode, { + qrTerminal.generate(qrcode, { small: config.small, }) diff --git a/src/contrib/room-connector/many-to-many-room-connector.ts b/src/contrib/room-connector/many-to-many-room-connector.ts index d9b3bf9..4f4496d 100644 --- a/src/contrib/room-connector/many-to-many-room-connector.ts +++ b/src/contrib/room-connector/many-to-many-room-connector.ts @@ -13,14 +13,14 @@ import { import { MessageMatcherOptions, messageMatcher, -} from '../../matchers/mod' +} from '../../matchers/mod.js' import { messageMapper, MessageMapperOptions, -} from '../../mappers/mod' +} from '../../mappers/mod.js' import { roomTalker, -} from '../../talkers/mod' +} from '../../talkers/mod.js' export interface ManyToManyRoomConnectorConfig { /** diff --git a/src/contrib/room-connector/many-to-one-room-connector.ts b/src/contrib/room-connector/many-to-one-room-connector.ts index 297a4ee..90a4e34 100644 --- a/src/contrib/room-connector/many-to-one-room-connector.ts +++ b/src/contrib/room-connector/many-to-one-room-connector.ts @@ -13,14 +13,14 @@ import { import { MessageMatcherOptions, messageMatcher, -} from '../../matchers/mod' +} from '../../matchers/mod.js' import { messageMapper, MessageMapperOptions, -} from '../../mappers/mod' +} from '../../mappers/mod.js' import { roomTalker, -} from '../../talkers/mod' +} from '../../talkers/mod.js' export interface ManyToOneRoomConnectorConfig { /** diff --git a/src/contrib/room-connector/mod.ts b/src/contrib/room-connector/mod.ts index 43223f6..30f338e 100644 --- a/src/contrib/room-connector/mod.ts +++ b/src/contrib/room-connector/mod.ts @@ -1,16 +1,29 @@ -export { +import { OneToManyRoomConnector, OneToManyRoomConnectorConfig, -} from './one-to-many-room-connector' -export { +} from './one-to-many-room-connector.js' +import { ManyToOneRoomConnector, ManyToOneRoomConnectorConfig, -} from './many-to-one-room-connector' -export { +} from './many-to-one-room-connector.js' +import { ManyToManyRoomConnector, ManyToManyRoomConnectorConfig, -} from './many-to-many-room-connector' -export { +} from './many-to-many-room-connector.js' +import { SourceToTargetRoomConnector, SourceToTargetRoomConnectorConfig, -} from './source-to-target-room-connector' +} from './source-to-target-room-connector.js' + +export type { + ManyToManyRoomConnectorConfig, + ManyToOneRoomConnectorConfig, + OneToManyRoomConnectorConfig, + SourceToTargetRoomConnectorConfig, +} +export { + ManyToManyRoomConnector, + ManyToOneRoomConnector, + OneToManyRoomConnector, + SourceToTargetRoomConnector, +} diff --git a/src/contrib/room-connector/one-to-many-room-connector.ts b/src/contrib/room-connector/one-to-many-room-connector.ts index cb41245..bb345d0 100644 --- a/src/contrib/room-connector/one-to-many-room-connector.ts +++ b/src/contrib/room-connector/one-to-many-room-connector.ts @@ -13,14 +13,14 @@ import { import { MessageMatcherOptions, messageMatcher, -} from '../../matchers/mod' +} from '../../matchers/mod.js' import { messageMapper, MessageMapperOptions, -} from '../../mappers/mod' +} from '../../mappers/mod.js' import { roomTalker, -} from '../../talkers/mod' +} from '../../talkers/mod.js' export interface OneToManyRoomConnectorConfig { /** diff --git a/src/contrib/room-connector/source-to-target-room-connector.ts b/src/contrib/room-connector/source-to-target-room-connector.ts index d8afadc..985dc71 100644 --- a/src/contrib/room-connector/source-to-target-room-connector.ts +++ b/src/contrib/room-connector/source-to-target-room-connector.ts @@ -15,18 +15,18 @@ import { messageMatcher, RoomMatcherOptions, roomMatcher, -} from '../../matchers/mod' +} from '../../matchers/mod.js' import { messageMapper, MessageMapperOptions, -} from '../../mappers/mod' +} from '../../mappers/mod.js' import { roomTalker, -} from '../../talkers/mod' +} from '../../talkers/mod.js' import { RoomFinderOptions, roomFinder, -} from '../../finders/room-finder' +} from '../../finders/room-finder.js' export interface SourceToTargetRoomConnectorConfig { /** diff --git a/src/contrib/room-inviter.spec.ts b/src/contrib/room-inviter.spec.ts index 0eb2250..4ab96b8 100755 --- a/src/contrib/room-inviter.spec.ts +++ b/src/contrib/room-inviter.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 { test } from 'tstest' // import sinon from 'sinon' test('RoomInviter()', async t => { - t.skip('tbw') + await t.skip('tbw') }) diff --git a/src/contrib/room-inviter.ts b/src/contrib/room-inviter.ts index e5f79d3..e225b40 100644 --- a/src/contrib/room-inviter.ts +++ b/src/contrib/room-inviter.ts @@ -15,15 +15,15 @@ import { RoomTalkerOptions, contactTalker, roomTalker, -} from '../talkers/mod' +} from '../talkers/mod.js' import { StringMatcherOptions, stringMatcher, -} from '../matchers/mod' +} from '../matchers/mod.js' import { RoomFinderOptions, roomFinder, -} from '../finders/mod' +} from '../finders/mod.js' export interface RoomInviterConfig { password : StringMatcherOptions, @@ -60,8 +60,8 @@ export function RoomInviter ( if (!(room.id in welcomeId)) { return } for (const contact of inviteeList) { - if (contact.id in welcomeId[room.id]) { - delete welcomeId[room.id][contact.id] + if (contact.id in welcomeId[room.id]!) { + delete welcomeId[room.id]![contact.id] /** * Huan(202008): Sleep 15 seconds before greeting: * 1. The group members need some time to sync with server before they can see the invitee has joined @@ -129,7 +129,7 @@ async function selectRoomWithLeastMembers (roomList: Room[]): Promise { let info = '' for (let i = 0; i < roomList.length; i++) { - const topic = await roomList[i].topic() + const topic = await roomList[i]!.topic() const num = roomMemberNumList[i] info += `${topic}(${num}),` @@ -140,5 +140,5 @@ async function selectRoomWithLeastMembers (roomList: Room[]): Promise { const minNum = Math.min(...roomMemberNumList) const minIdx = roomMemberNumList.indexOf(minNum) - return roomList[minIdx] + return roomList[minIdx]! } diff --git a/src/finders/mod.ts b/src/finders/mod.ts index 6e6c176..ae7fcde 100644 --- a/src/finders/mod.ts +++ b/src/finders/mod.ts @@ -1,11 +1,20 @@ /** * Finders */ -export { +import { ContactFinderOptions, contactFinder, -} from './contact-finder' -export { +} from './contact-finder.js' +import { RoomFinderOptions, roomFinder, -} from './room-finder' +} from './room-finder.js' + +export type { + ContactFinderOptions, + RoomFinderOptions, +} +export { + contactFinder, + roomFinder, +} diff --git a/src/mappers/message-mapper.ts b/src/mappers/message-mapper.ts index e25f278..f19a8bd 100644 --- a/src/mappers/message-mapper.ts +++ b/src/mappers/message-mapper.ts @@ -3,9 +3,9 @@ import { log, } from 'wechaty' -import { +import type { SayableMessage, -} from '../types/mod' +} from '../types/mod.js' type MessageMapperFunction = (message: Message) => SayableMessage | SayableMessage[] diff --git a/src/mappers/mod.ts b/src/mappers/mod.ts index 1cd2c85..a893475 100644 --- a/src/mappers/mod.ts +++ b/src/mappers/mod.ts @@ -1,9 +1,11 @@ import { MessageMapperOptions, messageMapper, -} from './message-mapper' +} from './message-mapper.js' -export { +export type { MessageMapperOptions, +} +export { messageMapper, } diff --git a/src/matchers/contact-matcher.spec.ts b/src/matchers/contact-matcher.spec.ts index c7bf7a7..1352d59 100755 --- a/src/matchers/contact-matcher.spec.ts +++ b/src/matchers/contact-matcher.spec.ts @@ -1,9 +1,9 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm -import test from 'tstest' +import { test } from 'tstest' +import type { Contact } from 'wechaty' -import { contactMatcher } from './contact-matcher' -import { Contact } from 'wechaty' +import { contactMatcher } from './contact-matcher.js' test('contactMatcher() smoke testing', async t => { const matcher = contactMatcher(/test/i) diff --git a/src/matchers/language-matcher.spec.ts b/src/matchers/language-matcher.spec.ts index f3108a1..e229c53 100755 --- a/src/matchers/language-matcher.spec.ts +++ b/src/matchers/language-matcher.spec.ts @@ -1,12 +1,12 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm -import test from 'tstest' +import { test } from 'tstest' import { detectLanguage, includeLanguage, languageMatcher, -} from './language-matcher' +} from './language-matcher.js' test('detectLanguage()', async t => { const ENGLISH_TEXT = 'hello' diff --git a/src/matchers/language-matcher.ts b/src/matchers/language-matcher.ts index 0df36c9..d681387 100644 --- a/src/matchers/language-matcher.ts +++ b/src/matchers/language-matcher.ts @@ -1,8 +1,8 @@ import { log, -} from 'wechaty' +} from '../config.js' -const languageMonitor = require('language-monitor') +import languageMonitor from 'language-monitor' type LanguageCode = 'chinese' | 'danish' diff --git a/src/matchers/message-matcher.spec.ts b/src/matchers/message-matcher.spec.ts index ba00257..7133f58 100755 --- a/src/matchers/message-matcher.spec.ts +++ b/src/matchers/message-matcher.spec.ts @@ -1,9 +1,9 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm -import test from 'tstest' +import { test } from 'tstest' -import { messageMatcher } from './message-matcher' -import { Message } from 'wechaty' +import type { Message } from 'wechaty' +import { messageMatcher } from './message-matcher.js' test('messageMatcher() smoke testing', async t => { const matcher = messageMatcher(/test/i) diff --git a/src/matchers/mod.ts b/src/matchers/mod.ts index 719b22f..8a3ea0f 100644 --- a/src/matchers/mod.ts +++ b/src/matchers/mod.ts @@ -1,23 +1,38 @@ /** * Matchers */ -export { +import { MessageMatcherOptions, messageMatcher, -} from './message-matcher' -export { +} from './message-matcher.js' +import { RoomMatcherOptions, roomMatcher, -} from './room-matcher' -export { +} from './room-matcher.js' +import { ContactMatcherOptions, contactMatcher, -} from './contact-matcher' -export { +} from './contact-matcher.js' +import { StringMatcherOptions, stringMatcher, -} from './string-matcher' -export { +} from './string-matcher.js' +import { + LanguageMatcherOptions, + languageMatcher, +} from './language-matcher.js' + +export type { + ContactMatcherOptions, LanguageMatcherOptions, + MessageMatcherOptions, + RoomMatcherOptions, + StringMatcherOptions, +} +export { + contactMatcher, languageMatcher, -} from './language-matcher' + messageMatcher, + roomMatcher, + stringMatcher, +} diff --git a/src/matchers/room-matcher.spec.ts b/src/matchers/room-matcher.spec.ts index 98a9375..18ec765 100755 --- a/src/matchers/room-matcher.spec.ts +++ b/src/matchers/room-matcher.spec.ts @@ -1,9 +1,10 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm -import test from 'tstest' +import { test } from 'tstest' -import { roomMatcher } from './room-matcher' -import { Room } from 'wechaty' +import type { Room } from 'wechaty' + +import { roomMatcher } from './room-matcher.js' test('roomMatcher() smoke testing', async t => { const matcher = roomMatcher(/test/i) diff --git a/src/matchers/string-matcher.spec.ts b/src/matchers/string-matcher.spec.ts index 405b7c0..5f0a9cf 100755 --- a/src/matchers/string-matcher.spec.ts +++ b/src/matchers/string-matcher.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 { test } from 'tstest' -import { stringMatcher } from './string-matcher' +import { stringMatcher } from './string-matcher.js' test('stringMatcher() smoke testing', async t => { const matcher = stringMatcher() diff --git a/src/mod.spec.ts b/src/mod.spec.ts index b680ccf..2b0cab7 100755 --- a/src/mod.spec.ts +++ b/src/mod.spec.ts @@ -1,10 +1,10 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm -import test from 'tstest' +import { test } from 'tstest' -import * as contrib from './mod' +import * as contrib from './mod.js' -test('Make sure the module export list is expected', async (t) => { +test('Make sure the module export list is expected', async t => { t.ok(contrib.DingDong, 'should has #1 DingDong') t.ok(contrib.EventLogger, 'should has #2 EventLogger') t.ok(contrib.QRCodeTerminal, 'should has #3 QRCodeTerminal') @@ -15,5 +15,5 @@ test('Make sure the module export list is expected', async (t) => { t.ok(contrib.ManyToManyRoomConnector, 'should has #6.3 ManyToManyRoomConnector') t.ok(contrib.FriendshipAccepter, 'should has #7 FriendshipAccepter') t.ok(contrib.RoomInviter, 'should has #8 RoomInviter') - t.ok(contrib.EventHotHandler, 'should has #9 EventHotHandler') + // t.ok(contrib.EventHotHandler, 'should has #9 EventHotHandler') }) diff --git a/src/mod.ts b/src/mod.ts index 3fb0838..82b8369 100644 --- a/src/mod.ts +++ b/src/mod.ts @@ -1,35 +1,24 @@ -import * as finders from './finders/mod' -import * as matchers from './matchers/mod' -import * as talkers from './talkers/mod' -import * as mappers from './mappers/mod' -import * as types from './types/mod' +import * as finders from './finders/mod.js' +import * as matchers from './matchers/mod.js' +import * as talkers from './talkers/mod.js' +import * as mappers from './mappers/mod.js' +import * as types from './types/mod.js' -/** - * Plugin utility helper functions - */ -export { - finders, - matchers, - mappers, - talkers, - types, -} +import { VERSION } from './config.js' -export { VERSION } from './config' - -export { +import { validatePlugin, -} from './validate-plugin' +} from './validate-plugin.js' -export { +import { DingDong, DingDongConfig, -} from './contrib/ding-dong/mod' -export { +} from './contrib/ding-dong/mod.js' +import { Heartbeat, HeartbeatConfig, -} from './contrib/heartbeat/mod' -export { +} from './contrib/heartbeat/mod.js' +import { OneToManyRoomConnector, OneToManyRoomConnectorConfig, ManyToOneRoomConnector, @@ -38,34 +27,71 @@ export { ManyToManyRoomConnectorConfig, SourceToTargetRoomConnector, SourceToTargetRoomConnectorConfig, -} from './contrib/room-connector/mod' -export { +} from './contrib/room-connector/mod.js' +import { QRCodeTerminal, QRCodeTerminalConfig, -} from './contrib/qr-code-terminal' -export { +} from './contrib/qr-code-terminal.js' +import { EventLogger, EventLoggerConfig, -} from './contrib/event-logger' -export { +} from './contrib/event-logger.js' +import { ChatOps, ChatOpsConfig, -} from './contrib/chatops' -export { +} from './contrib/chatops.js' +import { FriendshipAccepter, FriendshipAccepterConfig, -} from './contrib/friendship-accepter' -export { +} from './contrib/friendship-accepter.js' +import { RoomInviter, RoomInviterConfig, -} from './contrib/room-inviter' -export { - EventHotHandler, - EventHotHandlerConfig, -} from './contrib/event-hot-handler' -export { +} from './contrib/room-inviter.js' +import { RoomInvitationAccepter, -} from './contrib/room-invitation-accepter' +} from './contrib/room-invitation-accepter.js' +import { + MessageAwaiter, +} from './contrib/message-awaiter.js' + +export type { + ChatOpsConfig, + DingDongConfig, + EventLoggerConfig, + FriendshipAccepterConfig, + HeartbeatConfig, + ManyToManyRoomConnectorConfig, + ManyToOneRoomConnectorConfig, + OneToManyRoomConnectorConfig, + QRCodeTerminalConfig, + RoomInviterConfig, + SourceToTargetRoomConnectorConfig, +} export { + ChatOps, + DingDong, + EventLogger, + FriendshipAccepter, + Heartbeat, + ManyToManyRoomConnector, + ManyToOneRoomConnector, MessageAwaiter, -} from './contrib/message-awaiter' + OneToManyRoomConnector, + QRCodeTerminal, + RoomInvitationAccepter, + RoomInviter, + SourceToTargetRoomConnector, + validatePlugin, + VERSION, +} +/** + * Plugin utility helper functions + */ +export { + finders, + matchers, + mappers, + talkers, + types, +} 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/talkers/contact-talker.spec.ts b/src/talkers/contact-talker.spec.ts index 2e66f48..318a535 100755 --- a/src/talkers/contact-talker.spec.ts +++ b/src/talkers/contact-talker.spec.ts @@ -1,14 +1,16 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm -import test from 'tstest' -import sinon from 'sinon' +import { + test, + sinon, +} from 'tstest' -import { Contact } from 'wechaty' +import type { Contact } from 'wechaty' import { contactTalker, ContactTalkerOptions, -} from './contact-talker' +} from './contact-talker.js' test('contactTalker()', async t => { const spy1 = sinon.spy() @@ -30,19 +32,19 @@ test('contactTalker()', async t => { } as any as Contact await contactTalker(OPTIONS_TEXT)(mockContact) - t.true(spy4.called, 'should called the contact.say') - t.equal(spy4.args[0][0], EXPECTED_TEXT, 'should say the expected text') + t.ok(spy4.called, 'should called the contact.say') + t.equal(spy4.args[0]![0], EXPECTED_TEXT, 'should say the expected text') await contactTalker(OPTIONS_FUNCTION)(mockContact) - t.true(spy1.called, 'should called the function') - t.equal(spy1.args[0][0], mockContact, 'should called the function with contact') + t.ok(spy1.called, 'should called the function') + t.equal(spy1.args[0]![0], mockContact, 'should called the function with contact') const talkContact = contactTalker(OPTIONS_FUNCTION_LIST) await talkContact(mockContact) - t.true(spy2.called, 'should called the functions 1') - t.true(spy3.called, 'should called the functions 2') - t.equal(spy2.args[0][0], mockContact, 'should called the functions 1 with contact') - t.equal(spy3.args[0][0], mockContact, 'should called the functions 2 with contact') + t.ok(spy2.called, 'should called the functions 1') + t.ok(spy3.called, 'should called the functions 2') + t.equal(spy2.args[0]![0], mockContact, 'should called the functions 1 with contact') + t.equal(spy3.args[0]![0], mockContact, 'should called the functions 2 with contact') }) test('contactTalker() with mustache', async t => { @@ -63,6 +65,6 @@ test('contactTalker() with mustache', async t => { const talkContact = contactTalker(OPTIONS_TEXT) await talkContact(mockContact, undefined, view) - t.true(spy.called, 'should called the contact.say') - t.equal(spy.args[0][0], EXPECTED_TEXT, 'should say the expected text') + t.ok(spy.called, 'should called the contact.say') + t.equal(spy.args[0]![0], EXPECTED_TEXT, 'should say the expected text') }) diff --git a/src/talkers/contact-talker.ts b/src/talkers/contact-talker.ts index b3ed5db..9b76fee 100644 --- a/src/talkers/contact-talker.ts +++ b/src/talkers/contact-talker.ts @@ -5,7 +5,7 @@ import { } from 'wechaty' import Mustache from 'mustache' -import * as types from '../types/mod' +import type * as types from '../types/mod.js' type ContactTalkerFunction = (contact: Contact, room?: Room) => types.SayableMessage | Promise type ContactTalkerOption = types.SayableMessage | ContactTalkerFunction diff --git a/src/talkers/message-talker.spec.ts b/src/talkers/message-talker.spec.ts index 6e37aef..96a2d51 100755 --- a/src/talkers/message-talker.spec.ts +++ b/src/talkers/message-talker.spec.ts @@ -1,16 +1,16 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm -import test from 'tstest' +import { test } from 'tstest' import sinon from 'sinon' -import { +import type { Message, } from 'wechaty' import { messageTalker, MessageTalkerOptions, -} from './message-talker' +} from './message-talker.js' test('messageTalker()', async t => { const spy2 = sinon.spy() @@ -32,18 +32,18 @@ test('messageTalker()', async t => { let talkMessage = messageTalker(OPTIONS_TEXT) spy4.resetHistory() await talkMessage(mockMessage) - t.true(spy4.called, 'should called the contact.say') - t.equal(spy4.args[0][0], EXPECTED_TEXT, 'should say the expected text') + t.ok(spy4.called, 'should called the contact.say') + t.equal(spy4.args[0]![0], EXPECTED_TEXT, 'should say the expected text') talkMessage = messageTalker(OPTIONS_FUNCTION_LIST) spy2.resetHistory() spy3.resetHistory() await talkMessage(mockMessage) - t.true(spy2.called, 'should called the functions 1') - t.equal(spy2.args[0][0], mockMessage, 'should called the functions 1/1 with mockMessage') + t.ok(spy2.called, 'should called the functions 1') + t.equal(spy2.args[0]![0], mockMessage, 'should called the functions 1/1 with mockMessage') - t.true(spy3.called, 'should called the functions 2') - t.equal(spy3.args[0][0], mockMessage, 'should called the functions 2/1 with contact') + t.ok(spy3.called, 'should called the functions 2') + t.equal(spy3.args[0]![0], mockMessage, 'should called the functions 2/1 with contact') }) test('messageTalker() with mustache', async t => { @@ -64,6 +64,6 @@ test('messageTalker() with mustache', async t => { const talkMessage = messageTalker(OPTIONS_TEXT) await talkMessage(mockMessage, view) - t.true(spy.called, 'should called the contact.say') - t.equal(spy.args[0][0], EXPECTED_TEXT, 'should say the expected text') + t.ok(spy.called, 'should called the contact.say') + t.equal(spy.args[0]![0], EXPECTED_TEXT, 'should say the expected text') }) diff --git a/src/talkers/message-talker.ts b/src/talkers/message-talker.ts index e798591..bbf8bfd 100644 --- a/src/talkers/message-talker.ts +++ b/src/talkers/message-talker.ts @@ -5,7 +5,7 @@ import { } from 'wechaty' import Mustache from 'mustache' -import * as mapper from '../mappers/message-mapper' +import * as mapper from '../mappers/message-mapper.js' export type MessageTalkerOptions = mapper.MessageMapperOptions diff --git a/src/talkers/mod.ts b/src/talkers/mod.ts index 25b0f5d..e3c1efb 100644 --- a/src/talkers/mod.ts +++ b/src/talkers/mod.ts @@ -1,15 +1,26 @@ /** * Talkers */ -export { +import { RoomTalkerOptions, roomTalker, -} from './room-talker' -export { +} from './room-talker.js' +import { ContactTalkerOptions, contactTalker, -} from './contact-talker' -export { +} from './contact-talker.js' +import { + MessageTalkerOptions, + messageTalker, +} from './message-talker.js' + +export type { + ContactTalkerOptions, MessageTalkerOptions, + RoomTalkerOptions, +} +export { + contactTalker, messageTalker, -} from './message-talker' + roomTalker, +} diff --git a/src/talkers/room-talker.spec.ts b/src/talkers/room-talker.spec.ts index 7d78aab..7450001 100755 --- a/src/talkers/room-talker.spec.ts +++ b/src/talkers/room-talker.spec.ts @@ -1,14 +1,17 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm -import test from 'tstest' +import { test } from 'tstest' import sinon from 'sinon' -import { Contact, Room } from 'wechaty' +import type { + Contact, + Room, +} from 'wechaty' import { roomTalker, RoomTalkerOptions, -} from './room-talker' +} from './room-talker.js' test('roomTalker()', async t => { const spy2 = sinon.spy() @@ -31,21 +34,21 @@ test('roomTalker()', async t => { let talkRoom = roomTalker(OPTIONS_TEXT) spy4.resetHistory() await talkRoom(mockRoom, mockContact) - t.true(spy4.called, 'should called the contact.say') - t.equal(spy4.args[0][0], EXPECTED_TEXT, 'should say the expected text') - t.equal(spy4.args[0][1], mockContact, 'should pass contact to say') + t.ok(spy4.called, 'should called the contact.say') + t.equal(spy4.args[0]![0], EXPECTED_TEXT, 'should say the expected text') + t.equal(spy4.args[0]![1], mockContact, 'should pass contact to say') talkRoom = roomTalker(OPTIONS_FUNCTION_LIST) spy2.resetHistory() spy3.resetHistory() await talkRoom(mockRoom, mockContact) - t.true(spy2.called, 'should called the functions 1') - t.equal(spy2.args[0][0], mockRoom, 'should called the functions 1/1 with mockRoom') - t.equal(spy2.args[0][1], mockContact, 'should called the functions 1/2 with mockContact') + t.ok(spy2.called, 'should called the functions 1') + t.equal(spy2.args[0]![0], mockRoom, 'should called the functions 1/1 with mockRoom') + t.equal(spy2.args[0]![1], mockContact, 'should called the functions 1/2 with mockContact') - t.true(spy3.called, 'should called the functions 2') - t.equal(spy3.args[0][0], mockRoom, 'should called the functions 2/1 with contact') - t.equal(spy3.args[0][1], mockContact, 'should called the functions 2/2 with mockContact') + t.ok(spy3.called, 'should called the functions 2') + t.equal(spy3.args[0]![0], mockRoom, 'should called the functions 2/1 with contact') + t.equal(spy3.args[0]![1], mockContact, 'should called the functions 2/2 with mockContact') }) test('roomTalker() with mustache', async t => { @@ -67,9 +70,9 @@ test('roomTalker() with mustache', async t => { const talkRoom = roomTalker(OPTIONS_TEXT) await talkRoom(mockRoom, mockContact, view) - t.true(spy.called, 'should called the contact.say') - t.equal(spy.args[0][0], EXPECTED_TEXT, 'should say the expected text') - t.equal(spy.args[0][1], mockContact, 'should say with mockContact') + t.ok(spy.called, 'should called the contact.say') + t.equal(spy.args[0]![0], EXPECTED_TEXT, 'should say the expected text') + t.equal(spy.args[0]![1], mockContact, 'should say with mockContact') }) test('roomTalker() with room list', async t => { @@ -103,32 +106,32 @@ test('roomTalker() with room list', async t => { let talkRoom = roomTalker(OPTIONS_TEXT) spy4.resetHistory() await talkRoom([mockRoom1, mockRoom2], [mockContact1, mockContact2]) - t.true(spy4.calledOnce, 'should called the room1.say once') - t.equal(spy4.args[0][0], EXPECTED_TEXT, 'should say the expected text') - t.equal(spy4.args[0][1], mockContact1, 'should pass contact1 to say') - t.equal(spy4.args[0][2], mockContact2, 'should pass contact2 to say') - t.true(spy5.calledOnce, 'should called the room2.say once') - t.equal(spy5.args[0][0], EXPECTED_TEXT, 'should say the expected text') - t.equal(spy5.args[0][1], mockContact1, 'should pass contact1 to say') - t.equal(spy5.args[0][2], mockContact2, 'should pass contact2 to say') + t.ok(spy4.calledOnce, 'should called the room1.say once') + t.equal(spy4.args[0]![0], EXPECTED_TEXT, 'should say the expected text') + t.equal(spy4.args[0]![1], mockContact1, 'should pass contact1 to say') + t.equal(spy4.args[0]![2], mockContact2, 'should pass contact2 to say') + t.ok(spy5.calledOnce, 'should called the room2.say once') + t.equal(spy5.args[0]![0], EXPECTED_TEXT, 'should say the expected text') + t.equal(spy5.args[0]![1], mockContact1, 'should pass contact1 to say') + t.equal(spy5.args[0]![2], mockContact2, 'should pass contact2 to say') talkRoom = roomTalker(OPTIONS_FUNCTION_LIST) spy2.resetHistory() spy3.resetHistory() await talkRoom([mockRoom1, mockRoom2], [mockContact1, mockContact2]) - t.true(spy2.called, 'should called the functions 1') - t.equal(spy2.args[0][0], mockRoom1, 'should called the functions 1/1 with mockRoom1') - t.equal(spy2.args[0][1], mockContact1, 'should called the functions 1/2 with mockContact1') - t.equal(spy2.args[0][2], mockContact2, 'should called the functions 1/3 with mockContact2') - t.equal(spy2.args[1][0], mockRoom2, 'should called the functions 1/1 with mockRoom2') - t.equal(spy2.args[1][1], mockContact1, 'should called the functions 1/2 with mockContact1') - t.equal(spy2.args[1][2], mockContact2, 'should called the functions 1/3 with mockContact2') - - t.true(spy3.called, 'should called the functions 2') - t.equal(spy3.args[0][0], mockRoom1, 'should called the functions 2/1 with mockRoom1') - t.equal(spy3.args[0][1], mockContact1, 'should called the functions 2/2 with mockContact1') - t.equal(spy3.args[0][2], mockContact2, 'should called the functions 2/3 with mockContact2') - t.equal(spy3.args[1][0], mockRoom2, 'should called the functions 2/1 with mockRoom2') - t.equal(spy3.args[1][1], mockContact1, 'should called the functions 2/2 with mockContact1') - t.equal(spy3.args[1][2], mockContact2, 'should called the functions 2/3 with mockContact2') + t.ok(spy2.called, 'should called the functions 1') + t.equal(spy2.args[0]![0], mockRoom1, 'should called the functions 1/1 with mockRoom1') + t.equal(spy2.args[0]![1], mockContact1, 'should called the functions 1/2 with mockContact1') + t.equal(spy2.args[0]![2], mockContact2, 'should called the functions 1/3 with mockContact2') + t.equal(spy2.args[1]![0], mockRoom2, 'should called the functions 1/1 with mockRoom2') + t.equal(spy2.args[1]![1], mockContact1, 'should called the functions 1/2 with mockContact1') + t.equal(spy2.args[1]![2], mockContact2, 'should called the functions 1/3 with mockContact2') + + t.ok(spy3.called, 'should called the functions 2') + t.equal(spy3.args[0]![0], mockRoom1, 'should called the functions 2/1 with mockRoom1') + t.equal(spy3.args[0]![1], mockContact1, 'should called the functions 2/2 with mockContact1') + t.equal(spy3.args[0]![2], mockContact2, 'should called the functions 2/3 with mockContact2') + t.equal(spy3.args[1]![0], mockRoom2, 'should called the functions 2/1 with mockRoom2') + t.equal(spy3.args[1]![1], mockContact1, 'should called the functions 2/2 with mockContact1') + t.equal(spy3.args[1]![2], mockContact2, 'should called the functions 2/3 with mockContact2') }) diff --git a/src/talkers/room-talker.ts b/src/talkers/room-talker.ts index ec7b0e2..c6e019d 100644 --- a/src/talkers/room-talker.ts +++ b/src/talkers/room-talker.ts @@ -6,7 +6,7 @@ import { } from 'wechaty' import Mustache from 'mustache' -import * as types from '../types/mod' +import type * as types from '../types/mod.js' type RoomTalkerFunction = (room: Room, contact?: Contact) => types.SayableMessage | Promise type RoomTalkerOption = types.SayableMessage | RoomTalkerFunction diff --git a/src/types/mod.ts b/src/types/mod.ts index fdec33d..f9ca857 100644 --- a/src/types/mod.ts +++ b/src/types/mod.ts @@ -1,4 +1,11 @@ -export { +import { + SayableMessage, + toSayableMessage, +} from './sayable-message.js' + +export type { SayableMessage, +} +export { toSayableMessage, -} from './sayable-message' +} diff --git a/src/typings.d.ts b/src/typings.d.ts index cde2fe9..125716a 100644 --- a/src/typings.d.ts +++ b/src/typings.d.ts @@ -1 +1,2 @@ declare module 'qrcode-terminal' +declare module 'language-monitor' diff --git a/src/validate-plugin.spec.ts b/src/validate-plugin.spec.ts index 4b5cc20..68b7cdf 100755 --- a/src/validate-plugin.spec.ts +++ b/src/validate-plugin.spec.ts @@ -1,10 +1,10 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm -import test from 'tstest' +import { test } from 'tstest' -import { validatePlugin } from './validate-plugin' +import { validatePlugin } from './validate-plugin.js' -test('validatePlugin() pass', async (t) => { +test('validatePlugin() pass', async t => { function Test () { return function TestPlugin () { @@ -14,7 +14,7 @@ test('validatePlugin() pass', async (t) => { t.doesNotThrow(() => validatePlugin(Test), 'should pass a valid plugin') }) -test('validatePlugin() fail', async (t) => { +test('validatePlugin() fail', async t => { function Test () { return function TestXXX () { } diff --git a/src/version.spec.ts b/src/version.spec.ts deleted file mode 100755 index 40a5d4b..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 156a8b8..9fdf45d 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-plugin-contrib' diff --git a/tests/integration.spec.ts b/tests/integration.spec.ts index b5565ae..02cd6d5 100755 --- a/tests/integration.spec.ts +++ b/tests/integration.spec.ts @@ -1,10 +1,10 @@ -#!/usr/bin/env ts-node +#!/usr/bin/env -S node --no-warnings --loader ts-node/esm import { test, } from 'tstest' -import * as plugins from '../src/mod' +import * as plugins from '../src/mod.js' import { Wechaty, @@ -14,7 +14,7 @@ import { PuppetMock, } from 'wechaty-puppet-mock' -test('integration testing', async (t) => { +test('integration testing', async t => { const bot = Wechaty.instance({ puppet: new PuppetMock(), }).use(plugins.DingDong()) 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/",