From 46f838b3799193283bbfc01355e405908ebfe1e3 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 3 May 2021 15:22:30 +1000 Subject: [PATCH 1/5] Add few tsconfig rules --- tsconfig.json | 13 +++++++------ web-chat/src/App.tsx | 2 +- web-chat/tsconfig.json | 5 ++++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/tsconfig.json b/tsconfig.json index 5c85161103..ac42bdb78f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -14,18 +14,19 @@ "strict": true /* Enable all strict type-checking options. */, /* Strict Type-Checking Options */ - // "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, - // "strictNullChecks": true /* Enable strict null checks. */, - // "strictFunctionTypes": true /* Enable strict checking of function types. */, - // "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, - // "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, - // "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, + "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */, + "strictNullChecks": true /* Enable strict null checks. */, + "strictFunctionTypes": true /* Enable strict checking of function types. */, + "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */, + "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */, + "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */, /* Additional Checks */ "noUnusedLocals": true /* Report errors on unused locals. */, "noUnusedParameters": true /* Report errors on unused parameters. */, "noImplicitReturns": true /* Report error when not all code paths in function return a value. */, "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */, + "forceConsistentCasingInFileNames": true, /* Debugging Options */ "traceResolution": false /* Report module resolution log messages. */, diff --git a/web-chat/src/App.tsx b/web-chat/src/App.tsx index 64ef9bc25f..5f4a890d3b 100644 --- a/web-chat/src/App.tsx +++ b/web-chat/src/App.tsx @@ -1,6 +1,6 @@ import { multiaddr } from 'multiaddr'; import PeerId from 'peer-id'; -import React, { useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; import './App.css'; import { ChatMessage } from 'waku-chat/chat_message'; import { WakuMessage } from 'waku/waku_message'; diff --git a/web-chat/tsconfig.json b/web-chat/tsconfig.json index 669bc8f97d..01588d1cdd 100644 --- a/web-chat/tsconfig.json +++ b/web-chat/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { - "target": "es5", + "incremental": true, + "target": "es2017", "lib": ["dom", "dom.iterable", "esnext"], "allowJs": true, "skipLibCheck": true, @@ -8,6 +9,8 @@ "allowSyntheticDefaultImports": true, "strict": true, "forceConsistentCasingInFileNames": true, + "noUnusedLocals": true, + "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, "module": "esnext", "moduleResolution": "node", From 3c8a63cfcd8d713b50e639daec5562b7a371caca Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 3 May 2021 15:25:53 +1000 Subject: [PATCH 2/5] Format json files --- .vscode/extensions.json | 2 +- .vscode/launch.json | 3 ++- package.json | 4 ++-- tsconfig.module.json | 4 +--- web-chat/package.json | 4 ++-- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 439ccd5b5f..b04681624f 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -3,6 +3,6 @@ "dbaeumer.vscode-eslint", "esbenp.prettier-vscode", "eamodio.gitlens", - "streetsidesoftware.code-spell-checker", + "streetsidesoftware.code-spell-checker" ] } diff --git a/.vscode/launch.json b/.vscode/launch.json index 171e54aae2..708ac0f6e6 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -25,5 +25,6 @@ "outputCapture": "std", "skipFiles": ["/**/*.js"] // "smartStep": true - }] + } + ] } diff --git a/package.json b/package.json index 1962cdd94b..7e0b9105d5 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "build:main": "tsc -p tsconfig.json", "build:module": "tsc -p tsconfig.module.json", "fix": "run-s fix:*", - "fix:prettier": "prettier \"src/**/*.ts\" --write", + "fix:prettier": "prettier \"src/**/*.ts\" \"./*.json\" --write", "fix:lint": "eslint src --ext .ts --fix", "pretest": "run-s pretest:*", "pretest:1-init-git-submodules": "[ -f './nim-waku/build/wakunode2' ] || git submodule update --init --recursive", @@ -22,7 +22,7 @@ "chat": "ts-node src/chat/index.ts", "test": "run-s build test:*", "test:lint": "eslint src --ext .ts", - "test:prettier": "prettier \"src/**/*.ts\" --list-different", + "test:prettier": "prettier \"src/**/*.ts\" \"./*.json\" --list-different", "test:spelling": "cspell \"{README.md,.github/*.md,src/**/*.ts}\"", "test:unit": "nyc --silent mocha --exit # TODO: Remove `--exit` and fix hanging processes", "proto": "run-s proto:*", diff --git a/tsconfig.module.json b/tsconfig.module.json index dfb74fa3a3..79be3a5c40 100644 --- a/tsconfig.module.json +++ b/tsconfig.module.json @@ -5,7 +5,5 @@ "outDir": "build/module", "module": "esnext" }, - "exclude": [ - "node_modules/**" - ] + "exclude": ["node_modules/**"] } diff --git a/web-chat/package.json b/web-chat/package.json index d24b47d8c8..f70a570cc6 100644 --- a/web-chat/package.json +++ b/web-chat/package.json @@ -35,9 +35,9 @@ "fix": "run-s fix:*", "test": "run-s build test:*", "test:lint": "eslint src --ext .ts --ext .tsx", - "test:prettier": "prettier \"src/**/*.{ts,tsx}\" --list-different", + "test:prettier": "prettier \"src/**/*.{ts,tsx}\" \"./*.json\" --list-different", "test:spelling": "cspell \"{README.md,.github/*.md,src/**/*.{ts,tsx},public/**/*.html}\"", - "fix:prettier": "prettier \"src/**/*.{ts,tsx}\" --write", + "fix:prettier": "prettier \"src/**/*.{ts,tsx}\" \"./*.json\" --write", "fix:lint": "eslint src --ext .ts --ext .tsx --fix", "js-waku:build": "cd ../; npm run build", "predeploy": "run-s js-waku:build build", From 9e30627e2bb33e4dffa2a750817520d5c66e4a02 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 3 May 2021 15:52:38 +1000 Subject: [PATCH 3/5] Force return types to be specified Makes it easier to use the library. Best to enforce this early on. --- .eslintrc.json | 1 + src/chat/index.ts | 4 +-- src/lib/delay.ts | 2 +- src/lib/waku.ts | 15 +++++++---- src/lib/waku_relay/get_relay_peers.ts | 2 +- src/lib/waku_relay/index.spec.ts | 13 ++++------ src/lib/waku_relay/index.ts | 4 +-- src/lib/waku_relay/relay_heartbeat.ts | 4 +-- src/test_utils/async_fs.ts | 4 +-- src/test_utils/log_file.ts | 7 ++++-- src/test_utils/nim_waku.ts | 36 +++++++++++++++------------ 11 files changed, 51 insertions(+), 41 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 27db61f841..4c45bf5290 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -15,6 +15,7 @@ ], "globals": { "BigInt": true, "console": true, "WebAssembly": true }, "rules": { + "@typescript-eslint/explicit-function-return-type": ["error"], "@typescript-eslint/explicit-module-boundary-types": "off", "eslint-comments/disable-enable-pair": [ "error", diff --git a/src/chat/index.ts b/src/chat/index.ts index 70b5925b12..f3a46627ab 100644 --- a/src/chat/index.ts +++ b/src/chat/index.ts @@ -13,7 +13,7 @@ import { ChatMessage } from './chat_message'; const ChatContentTopic = 'dingpu'; -(async function () { +(async function (): Promise { const opts = processArguments(); const waku = await Waku.create({ @@ -124,7 +124,7 @@ function processArguments(): Options { return opts; } -function printMessage(chatMsg: ChatMessage) { +function printMessage(chatMsg: ChatMessage): void { const timestamp = chatMsg.timestamp.toLocaleString([], { month: 'short', day: 'numeric', diff --git a/src/lib/delay.ts b/src/lib/delay.ts index 98eaa4f54d..59d8019117 100644 --- a/src/lib/delay.ts +++ b/src/lib/delay.ts @@ -1,3 +1,3 @@ -export function delay(ms: number) { +export function delay(ms: number): Promise { return new Promise((resolve) => setTimeout(resolve, ms)); } diff --git a/src/lib/waku.ts b/src/lib/waku.ts index 0fba0e37ae..d00e04e337 100644 --- a/src/lib/waku.ts +++ b/src/lib/waku.ts @@ -98,16 +98,21 @@ export default class Waku { * Dials to the provided peer. * @param peer The peer to dial */ - async dial(peer: PeerId | Multiaddr | string) { - await this.libp2p.dialProtocol(peer, [RelayCodec, StoreCodec]); + async dial( + peer: PeerId | Multiaddr | string + ): Promise<{ + stream: import('libp2p-interfaces/src/stream-muxer/types').MuxedStream; + protocol: string; + }> { + return this.libp2p.dialProtocol(peer, [RelayCodec, StoreCodec]); } - addPeerToAddressBook(peerId: PeerId, multiaddr: Multiaddr[]) { + addPeerToAddressBook(peerId: PeerId, multiaddr: Multiaddr[]): void { this.libp2p.peerStore.addressBook.set(peerId, multiaddr); } - async stop() { - await this.libp2p.stop(); + async stop(): Promise { + return this.libp2p.stop(); } /** diff --git a/src/lib/waku_relay/get_relay_peers.ts b/src/lib/waku_relay/get_relay_peers.ts index 2331da24f5..5f5922ad22 100644 --- a/src/lib/waku_relay/get_relay_peers.ts +++ b/src/lib/waku_relay/get_relay_peers.ts @@ -18,7 +18,7 @@ export function getRelayPeers( router: Gossipsub, topic: string, count: number, - filter: (id: string) => boolean = () => true + filter: (id: string) => boolean = (): boolean => true ): Set { const peersInTopic = router.topics.get(topic); if (!peersInTopic) { diff --git a/src/lib/waku_relay/index.spec.ts b/src/lib/waku_relay/index.spec.ts index 427af3c661..2e8eada2e5 100644 --- a/src/lib/waku_relay/index.spec.ts +++ b/src/lib/waku_relay/index.spec.ts @@ -32,10 +32,7 @@ describe('Waku Relay', () => { }), ]); - await waku1.addPeerToAddressBook( - waku2.libp2p.peerId, - waku2.libp2p.multiaddrs - ); + waku1.addPeerToAddressBook(waku2.libp2p.peerId, waku2.libp2p.multiaddrs); await Promise.all([ new Promise((resolve) => @@ -133,7 +130,7 @@ describe('Waku Relay', () => { await waku.relay.send(message); - let msgs = []; + let msgs: WakuMessage[] = []; while (msgs.length === 0) { await delay(200); @@ -143,7 +140,7 @@ describe('Waku Relay', () => { expect(msgs[0].contentTopic).to.equal(message.contentTopic); expect(msgs[0].version).to.equal(message.version); - const payload = Buffer.from(msgs[0].payload); + const payload = Buffer.from(msgs[0].payload!); expect(Buffer.compare(payload, message.payload!)).to.equal(0); }); @@ -216,7 +213,7 @@ describe('Waku Relay', () => { await delay(1000); await waku.relay.send(message); - let msgs = []; + let msgs: WakuMessage[] = []; while (msgs.length === 0) { console.log('Waiting for messages'); @@ -227,7 +224,7 @@ describe('Waku Relay', () => { expect(msgs[0].contentTopic).to.equal(message.contentTopic); expect(msgs[0].version).to.equal(message.version); - const payload = Buffer.from(msgs[0].payload); + const payload = Buffer.from(msgs[0].payload!); expect(Buffer.compare(payload, message.payload!)).to.equal(0); }); diff --git a/src/lib/waku_relay/index.ts b/src/lib/waku_relay/index.ts index 7b92441ace..dccec6eeae 100644 --- a/src/lib/waku_relay/index.ts +++ b/src/lib/waku_relay/index.ts @@ -78,7 +78,7 @@ export class WakuRelay extends Gossipsub { * @override * @returns {void} */ - start() { + start(): void { super.start(); super.subscribe(constants.RelayDefaultTopic); } @@ -89,7 +89,7 @@ export class WakuRelay extends Gossipsub { * @param {WakuMessage} message * @returns {Promise} */ - async send(message: WakuMessage) { + async send(message: WakuMessage): Promise { const msg = message.encode(); await super.publish(constants.RelayDefaultTopic, Buffer.from(msg)); } diff --git a/src/lib/waku_relay/relay_heartbeat.ts b/src/lib/waku_relay/relay_heartbeat.ts index 0dc6995e54..21b81cb83f 100644 --- a/src/lib/waku_relay/relay_heartbeat.ts +++ b/src/lib/waku_relay/relay_heartbeat.ts @@ -31,10 +31,10 @@ export class RelayHeartbeat extends Heartbeat { this._heartbeatTimer = { _intervalId: undefined, - runPeriodically: (fn, period) => { + runPeriodically: (fn, period): void => { this._heartbeatTimer!._intervalId = setInterval(fn, period); }, - cancel: () => { + cancel: (): void => { clearTimeout(timeout); clearInterval(this._heartbeatTimer?._intervalId as NodeJS.Timeout); }, diff --git a/src/test_utils/async_fs.ts b/src/test_utils/async_fs.ts index ebc63689f9..dc671f45ba 100644 --- a/src/test_utils/async_fs.ts +++ b/src/test_utils/async_fs.ts @@ -2,14 +2,14 @@ import fs, { promises as asyncFs } from 'fs'; import { promisify } from 'util'; import { delay } from '../lib/delay'; -export const existsAsync = (filepath: string) => +export const existsAsync = (filepath: string): Promise => asyncFs.access(filepath, fs.constants.F_OK); export const openAsync = promisify(fs.open); export const mkdirAsync = asyncFs.mkdir; -export async function waitForFile(path: string) { +export async function waitForFile(path: string): Promise { let found = false; do { try { diff --git a/src/test_utils/log_file.ts b/src/test_utils/log_file.ts index f15f8c4d8d..6412f39c20 100644 --- a/src/test_utils/log_file.ts +++ b/src/test_utils/log_file.ts @@ -4,7 +4,10 @@ import { Tail } from 'tail'; import { waitForFile } from './async_fs'; -export default async function waitForLine(filepath: string, logLine: string) { +export default async function waitForLine( + filepath: string, + logLine: string +): Promise { await pTimeout(waitForFile(filepath), 2000); const options = { @@ -22,7 +25,7 @@ export default async function waitForLine(filepath: string, logLine: string) { tail.unwatch(); } -async function find(tail: Tail, line: string) { +async function find(tail: Tail, line: string): Promise { return new Promise((resolve, reject) => { tail.on('line', (data: string) => { if (data.includes(line)) { diff --git a/src/test_utils/nim_waku.ts b/src/test_utils/nim_waku.ts index f8f7efae54..b345087f2c 100644 --- a/src/test_utils/nim_waku.ts +++ b/src/test_utils/nim_waku.ts @@ -58,7 +58,7 @@ export class NimWaku { this.logPath = `${LOG_DIR}/nim-waku_${logName}.log`; } - async start(args?: Args) { + async start(args?: Args): Promise { try { await existsAsync(LOG_DIR); } catch (e) { @@ -116,7 +116,7 @@ export class NimWaku { await this.waitForLog('RPC Server started'); } - public stop() { + public stop(): void { dbg( `nim-waku ${ this.process ? this.process.pid : this.pid @@ -126,7 +126,7 @@ export class NimWaku { this.process = undefined; } - async waitForLog(msg: string) { + async waitForLog(msg: string): Promise { return waitForLine(this.logPath, msg); } @@ -134,10 +134,10 @@ export class NimWaku { * for known peers * @throws if nim-waku2 isn't started. */ - async peers() { + async peers(): Promise { this.checkProcess(); - const res = await this.rpcCall('get_waku_v2_admin_v1_peers', []); + const res = await this.rpcCall('get_waku_v2_admin_v1_peers', []); return res.result; } @@ -145,12 +145,15 @@ export class NimWaku { async info(): Promise { this.checkProcess(); - const res = await this.rpcCall('get_waku_v2_debug_v1_info', []); + const res = await this.rpcCall( + 'get_waku_v2_debug_v1_info', + [] + ); return res.result; } - async sendMessage(message: WakuMessage) { + async sendMessage(message: WakuMessage): Promise { this.checkProcess(); if (!message.payload) { @@ -162,7 +165,7 @@ export class NimWaku { contentTopic: message.contentTopic, }; - const res = await this.rpcCall('post_waku_v2_relay_v1_message', [ + const res = await this.rpcCall('post_waku_v2_relay_v1_message', [ RelayDefaultTopic, rpcMessage, ]); @@ -170,12 +173,13 @@ export class NimWaku { return res.result; } - async messages() { + async messages(): Promise { this.checkProcess(); - const res = await this.rpcCall('get_waku_v2_relay_v1_messages', [ - RelayDefaultTopic, - ]); + const res = await this.rpcCall( + 'get_waku_v2_relay_v1_messages', + [RelayDefaultTopic] + ); return res.result; } @@ -213,10 +217,10 @@ export class NimWaku { return `http://localhost:${port}/`; } - private async rpcCall( + private async rpcCall( method: string, params: Array - ) { + ): Promise<{ result: T }> { const res = await axios.post( this.rpcUrl, { @@ -233,7 +237,7 @@ export class NimWaku { return res.data; } - private checkProcess() { + private checkProcess(): void { if (!this.process) { throw "Nim Waku isn't started"; } @@ -282,7 +286,7 @@ export function strToHex(str: string): string { return hex; } -export function bufToHex(buffer: Uint8Array) { +export function bufToHex(buffer: Uint8Array): string { return Array.prototype.map .call(buffer, (x) => ('00' + x.toString(16)).slice(-2)) .join(''); From 656227d431b029d1de01a692ac523e1daf113345 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 3 May 2021 15:52:58 +1000 Subject: [PATCH 4/5] Remove null-assertion warnings for tests --- .eslintrc.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.eslintrc.json b/.eslintrc.json index 4c45bf5290..a83ecf731f 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -31,5 +31,13 @@ "error", { "ignoreDeclarationSort": true, "ignoreCase": true } ] - } + }, + "overrides": [ + { + "files": ["*.spec.ts", "**/test_utils/*.ts"], + "rules": { + "@typescript-eslint/no-non-null-assertion": "off" + } + } + ] } From de57b2691eac34e8805e15df626fb4afbca149f9 Mon Sep 17 00:00:00 2001 From: Franck Royer Date: Mon, 3 May 2021 15:54:40 +1000 Subject: [PATCH 5/5] Only the `result` property is ever used --- src/test_utils/nim_waku.ts | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/src/test_utils/nim_waku.ts b/src/test_utils/nim_waku.ts index b345087f2c..6136517112 100644 --- a/src/test_utils/nim_waku.ts +++ b/src/test_utils/nim_waku.ts @@ -137,20 +137,13 @@ export class NimWaku { async peers(): Promise { this.checkProcess(); - const res = await this.rpcCall('get_waku_v2_admin_v1_peers', []); - - return res.result; + return this.rpcCall('get_waku_v2_admin_v1_peers', []); } async info(): Promise { this.checkProcess(); - const res = await this.rpcCall( - 'get_waku_v2_debug_v1_info', - [] - ); - - return res.result; + return this.rpcCall('get_waku_v2_debug_v1_info', []); } async sendMessage(message: WakuMessage): Promise { @@ -165,23 +158,18 @@ export class NimWaku { contentTopic: message.contentTopic, }; - const res = await this.rpcCall('post_waku_v2_relay_v1_message', [ + return this.rpcCall('post_waku_v2_relay_v1_message', [ RelayDefaultTopic, rpcMessage, ]); - - return res.result; } async messages(): Promise { this.checkProcess(); - const res = await this.rpcCall( - 'get_waku_v2_relay_v1_messages', - [RelayDefaultTopic] - ); - - return res.result; + return this.rpcCall('get_waku_v2_relay_v1_messages', [ + RelayDefaultTopic, + ]); } async getPeerId(): Promise { @@ -220,7 +208,7 @@ export class NimWaku { private async rpcCall( method: string, params: Array - ): Promise<{ result: T }> { + ): Promise { const res = await axios.post( this.rpcUrl, { @@ -234,7 +222,7 @@ export class NimWaku { } ); - return res.data; + return res.data.result; } private checkProcess(): void {