From b4e9c278d3b5a269f65e51fde98aaaf34c7816e9 Mon Sep 17 00:00:00 2001 From: Chris Svenningsen Date: Wed, 16 Sep 2020 12:31:05 -0700 Subject: [PATCH] Migrate to eslint --- .eslintignore | 5 --- .eslintrc.js | 2 +- ACKNOWLEDGMENTS.md | 26 +++++++++++ js/modules/string_to_array_buffer.d.ts | 1 + package.json | 3 +- ts/shims/Whisper.ts | 15 ++++--- ts/shims/bounceAppIcon.ts | 4 +- ts/shims/events.ts | 5 ++- ts/shims/socketStatus.ts | 2 +- ts/shims/storage.ts | 7 ++- ts/shims/textsecure.ts | 2 +- ts/shims/updateIpc.ts | 4 +- ts/storybook/Fixtures.ts | 1 + ts/test/types/Attachment_test.ts | 1 - ts/test/types/Settings_test.ts | 2 +- .../initializeAttachmentMetadata_test.ts | 9 ++-- ts/updater/common.ts | 43 +++++++++---------- ts/updater/curve.ts | 2 +- ts/updater/generateKeyPair.ts | 3 +- ts/updater/generateSignature.ts | 5 +-- ts/updater/index.ts | 2 +- ts/updater/macos.ts | 5 +-- ts/updater/signature.ts | 11 +++-- ts/updater/windows.ts | 5 +-- ts/window.d.ts | 1 + tslint.json | 4 ++ yarn.lock | 5 +++ 27 files changed, 104 insertions(+), 71 deletions(-) create mode 100644 js/modules/string_to_array_buffer.d.ts diff --git a/.eslintignore b/.eslintignore index f489510d02..17415ed2c5 100644 --- a/.eslintignore +++ b/.eslintignore @@ -31,10 +31,5 @@ webpack.config.ts # Temporarily ignored during TSLint transition # JIRA: DESKTOP-304 -ts/shims/** ts/sql/** -ts/storybook/** -ts/styleguide/** -ts/test/** ts/textsecure/** -ts/updater/** diff --git a/.eslintrc.js b/.eslintrc.js index a2110e7f4c..db193a4c13 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -139,7 +139,7 @@ module.exports = { rules, }, { - files: ['**/*.stories.tsx', 'ts/build/**'], + files: ['**/*.stories.tsx', 'ts/build/**', 'ts/test/**'], rules: { ...rules, 'import/no-extraneous-dependencies': 'off', diff --git a/ACKNOWLEDGMENTS.md b/ACKNOWLEDGMENTS.md index 197533574b..70c08b0d60 100644 --- a/ACKNOWLEDGMENTS.md +++ b/ACKNOWLEDGMENTS.md @@ -444,6 +444,32 @@ Signal Desktop makes use of the following open source projects. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +## dashdash + + # This is the MIT license + + Copyright (c) 2013 Trent Mick. All rights reserved. + Copyright (c) 2013 Joyent Inc. All rights reserved. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + ## draft-js BSD License diff --git a/js/modules/string_to_array_buffer.d.ts b/js/modules/string_to_array_buffer.d.ts new file mode 100644 index 0000000000..b5e758dfdf --- /dev/null +++ b/js/modules/string_to_array_buffer.d.ts @@ -0,0 +1 @@ +export function stringToArrayBuffer(string: string): ArrayBuffer; diff --git a/package.json b/package.json index baa2573306..d77ec78c32 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,7 @@ "config": "1.28.1", "copy-text-to-clipboard": "2.1.0", "curve25519-n": "https://github.com/scottnonnenberg-signal/node-curve25519.git#3e94f60bc54b2426476520d8d1a0aa835c25f5cc", + "dashdash": "1.14.1", "draft-js": "0.10.5", "emoji-datasource": "5.0.1", "emoji-datasource-apple": "5.0.1", @@ -163,6 +164,7 @@ "@types/chai": "4.1.2", "@types/classnames": "2.2.3", "@types/config": "0.0.34", + "@types/dashdash": "1.14.0", "@types/draft-js": "0.10.32", "@types/filesize": "3.6.0", "@types/fs-extra": "5.0.5", @@ -213,7 +215,6 @@ "core-js": "2.4.1", "cross-env": "5.2.0", "css-loader": "3.2.0", - "dashdash": "1.14.1", "electron": "8.3.4", "electron-builder": "22.3.6", "electron-mocha": "8.1.1", diff --git a/ts/shims/Whisper.ts b/ts/shims/Whisper.ts index b9517c39c5..4afbecc805 100644 --- a/ts/shims/Whisper.ts +++ b/ts/shims/Whisper.ts @@ -1,18 +1,21 @@ -export function getSearchResultsProps(attributes: any) { - // @ts-ignore +// Matching Whisper.Message API +// eslint-disable-next-line max-len +// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types +export function getSearchResultsProps(attributes: any): any { const model = new window.Whisper.Message(attributes); return model.getPropsForSearchResult(); } -export function getBubbleProps(attributes: any) { - // @ts-ignore +// Matching Whisper.Message API +// eslint-disable-next-line max-len +// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types +export function getBubbleProps(attributes: any): any { const model = new window.Whisper.Message(attributes); return model.getPropsForBubble(); } -export function showSettings() { - // @ts-ignore +export function showSettings(): void { window.showSettings(); } diff --git a/ts/shims/bounceAppIcon.ts b/ts/shims/bounceAppIcon.ts index eb19209378..b9879fb696 100644 --- a/ts/shims/bounceAppIcon.ts +++ b/ts/shims/bounceAppIcon.ts @@ -1,9 +1,9 @@ import { ipcRenderer } from 'electron'; -export function bounceAppIconStart(isCritical = false) { +export function bounceAppIconStart(isCritical = false): void { ipcRenderer.send('bounce-app-icon-start', isCritical); } -export function bounceAppIconStop() { +export function bounceAppIconStop(): void { ipcRenderer.send('bounce-app-icon-stop'); } diff --git a/ts/shims/events.ts b/ts/shims/events.ts index 1b7e33a3c9..4e52551b80 100644 --- a/ts/shims/events.ts +++ b/ts/shims/events.ts @@ -1,3 +1,6 @@ -export function trigger(name: string, param1?: any, param2?: any) { +// Matching Whisper.events.trigger API +// eslint-disable-next-line max-len +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any +export function trigger(name: string, param1?: any, param2?: any): void { window.Whisper.events.trigger(name, param1, param2); } diff --git a/ts/shims/socketStatus.ts b/ts/shims/socketStatus.ts index 2ad8978ac3..4432fe925c 100644 --- a/ts/shims/socketStatus.ts +++ b/ts/shims/socketStatus.ts @@ -1,4 +1,4 @@ -export function getSocketStatus() { +export function getSocketStatus(): number { const { getSocketStatus: getMessageReceiverStatus } = window; return getMessageReceiverStatus(); diff --git a/ts/shims/storage.ts b/ts/shims/storage.ts index 1e72f52bd1..0f1d8e91ea 100644 --- a/ts/shims/storage.ts +++ b/ts/shims/storage.ts @@ -1,7 +1,10 @@ -export function put(key: string, value: any) { +// Matching window.storage.put API +// eslint-disable-next-line max-len +// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types +export function put(key: string, value: any): void { window.storage.put(key, value); } -export async function remove(key: string) { +export async function remove(key: string): Promise { await window.storage.remove(key); } diff --git a/ts/shims/textsecure.ts b/ts/shims/textsecure.ts index e1c5cf38ac..a683a1ab01 100644 --- a/ts/shims/textsecure.ts +++ b/ts/shims/textsecure.ts @@ -2,7 +2,7 @@ export function sendStickerPackSync( packId: string, packKey: string, installed: boolean -) { +): void { const { ConversationController, textsecure, log } = window; const ourNumber = textsecure.storage.user.getNumber(); const { wrap, sendOptions } = ConversationController.prepareForSend( diff --git a/ts/shims/updateIpc.ts b/ts/shims/updateIpc.ts index a9a0e8078d..204d603f04 100644 --- a/ts/shims/updateIpc.ts +++ b/ts/shims/updateIpc.ts @@ -1,9 +1,9 @@ import { ipcRenderer } from 'electron'; -export function startUpdate() { +export function startUpdate(): void { ipcRenderer.send('start-update'); } -export function ackRender() { +export function ackRender(): void { ipcRenderer.send('show-update-dialog-ack'); } diff --git a/ts/storybook/Fixtures.ts b/ts/storybook/Fixtures.ts index 714c53f3e9..a4907f5380 100644 --- a/ts/storybook/Fixtures.ts +++ b/ts/storybook/Fixtures.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ // @ts-ignore import gif from '../../fixtures/giphy-GVNvOUpeYmI7e.gif'; // @ts-ignore diff --git a/ts/test/types/Attachment_test.ts b/ts/test/types/Attachment_test.ts index 211023c2c7..789a94ba30 100644 --- a/ts/test/types/Attachment_test.ts +++ b/ts/test/types/Attachment_test.ts @@ -3,7 +3,6 @@ import { assert } from 'chai'; import * as Attachment from '../../types/Attachment'; import * as MIME from '../../types/MIME'; import { SignalService } from '../../protobuf'; -// @ts-ignore import { stringToArrayBuffer } from '../../../js/modules/string_to_array_buffer'; describe('Attachment', () => { diff --git a/ts/test/types/Settings_test.ts b/ts/test/types/Settings_test.ts index f5e684d5e9..6d7408ae22 100644 --- a/ts/test/types/Settings_test.ts +++ b/ts/test/types/Settings_test.ts @@ -2,7 +2,7 @@ import os from 'os'; import Sinon from 'sinon'; import { assert } from 'chai'; -import * as Settings from '../../../ts/types/Settings'; +import * as Settings from '../../types/Settings'; describe('Settings', () => { let sandbox: Sinon.SinonSandbox; diff --git a/ts/test/types/message/initializeAttachmentMetadata_test.ts b/ts/test/types/message/initializeAttachmentMetadata_test.ts index b74e04dde6..c15a0b1777 100644 --- a/ts/test/types/message/initializeAttachmentMetadata_test.ts +++ b/ts/test/types/message/initializeAttachmentMetadata_test.ts @@ -1,10 +1,9 @@ import { assert } from 'chai'; -import * as Message from '../../../../ts/types/message/initializeAttachmentMetadata'; -import { IncomingMessage } from '../../../../ts/types/Message'; -import { SignalService } from '../../../../ts/protobuf'; -import * as MIME from '../../../../ts/types/MIME'; -// @ts-ignore +import * as Message from '../../../types/message/initializeAttachmentMetadata'; +import { IncomingMessage } from '../../../types/Message'; +import { SignalService } from '../../../protobuf'; +import * as MIME from '../../../types/MIME'; import { stringToArrayBuffer } from '../../../../js/modules/string_to_array_buffer'; describe('Message', () => { diff --git a/ts/updater/common.ts b/ts/updater/common.ts index 304aefb0df..0903de1c49 100644 --- a/ts/updater/common.ts +++ b/ts/updater/common.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ import { createWriteStream, statSync, @@ -6,9 +7,7 @@ import { import { join, normalize } from 'path'; import { tmpdir } from 'os'; -// @ts-ignore -import { createParser } from 'dashdash'; -// @ts-ignore +import { createParser, ParserConfiguration } from 'dashdash'; import ProxyAgent from 'proxy-agent'; import { FAILSAFE_SCHEMA, safeLoad } from 'js-yaml'; import { gt } from 'semver'; @@ -24,7 +23,6 @@ import { getTempPath } from '../../app/attachments'; import { Dialogs } from '../types/Dialogs'; import { getUserAgent } from '../util/getUserAgent'; -// @ts-ignore import * as packageJson from '../../package.json'; import { getSignatureFileName } from './signature'; import { isPathInside } from '../util/isPathInside'; @@ -70,7 +68,7 @@ export async function checkForUpdates( return null; } -export function validatePath(basePath: string, targetPath: string) { +export function validatePath(basePath: string, targetPath: string): void { const normalized = normalize(targetPath); if (!isPathInside(normalized, basePath)) { @@ -252,9 +250,9 @@ export function getUpdatesFileName(): string { if (platform === 'darwin') { return `${prefix}-mac.yml`; - } else { - return `${prefix}.yml`; } + + return `${prefix}.yml`; } const hasBeta = /beta/i; @@ -268,29 +266,27 @@ function isVersionNewer(newVersion: string): boolean { return gt(newVersion, version); } -export function getVersion(yaml: string): string | undefined { +export function getVersion(yaml: string): string | null { const info = parseYaml(yaml); - if (info && info.version) { - return info.version; - } - - return; + return info && info.version; } -const validFile = /^[A-Za-z0-9\.\-]+$/; -export function isUpdateFileNameValid(name: string) { +const validFile = /^[A-Za-z0-9.-]+$/; +export function isUpdateFileNameValid(name: string): boolean { return validFile.test(name); } -export function getUpdateFileName(yaml: string) { +// Reliant on third party parser that returns any +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function getUpdateFileName(yaml: string): any { const info = parseYaml(yaml); if (!info || !info.path) { throw new Error('getUpdateFileName: No path present in YAML file'); } - const path = info.path; + const { path } = info; if (!isUpdateFileNameValid(path)) { throw new Error( `getUpdateFileName: Path '${path}' contains invalid characters` @@ -300,6 +296,8 @@ export function getUpdateFileName(yaml: string) { return path; } +// Reliant on third party parser that returns any +// eslint-disable-next-line @typescript-eslint/no-explicit-any function parseYaml(yaml: string): any { return safeLoad(yaml, { schema: FAILSAFE_SCHEMA, json: true }); } @@ -336,7 +334,7 @@ function getBaseTempDir() { return app ? getTempPath(app.getPath('userData')) : tmpdir(); } -export async function createTempDir() { +export async function createTempDir(): Promise { const baseTempDir = getBaseTempDir(); const uniqueName = getGuid(); const targetDir = join(baseTempDir, uniqueName); @@ -345,7 +343,7 @@ export async function createTempDir() { return targetDir; } -export async function deleteTempDir(targetDir: string) { +export async function deleteTempDir(targetDir: string): Promise { const pathInfo = statSync(targetDir); if (!pathInfo.isDirectory()) { throw new Error( @@ -363,22 +361,21 @@ export async function deleteTempDir(targetDir: string) { await rimrafPromise(targetDir); } -export function getPrintableError(error: Error) { +export function getPrintableError(error: Error): Error | string { return error && error.stack ? error.stack : error; } -export function getCliOptions(options: any): T { +export function getCliOptions(options: ParserConfiguration['options']): T { const parser = createParser({ options }); const cliOptions = parser.parse(process.argv); if (cliOptions.help) { const help = parser.help().trimRight(); - // tslint:disable-next-line:no-console console.log(help); process.exit(0); } - return cliOptions; + return (cliOptions as unknown) as T; } export function setUpdateListener(performUpdateCallback: () => void): void { diff --git a/ts/updater/curve.ts b/ts/updater/curve.ts index c494de896f..e220bdaded 100644 --- a/ts/updater/curve.ts +++ b/ts/updater/curve.ts @@ -5,7 +5,7 @@ import { verifySignature, } from 'curve25519-n'; -export function keyPair() { +export function keyPair(): Record { const privateKey = randomBytes(32); const { pubKey, privKey } = generateKeyPair(privateKey); diff --git a/ts/updater/generateKeyPair.ts b/ts/updater/generateKeyPair.ts index 8a8511e1e0..b47ef770e5 100644 --- a/ts/updater/generateKeyPair.ts +++ b/ts/updater/generateKeyPair.ts @@ -1,9 +1,8 @@ +/* eslint-disable no-console */ import { getCliOptions, getPrintableError } from './common'; import { keyPair } from './curve'; import { writeHexToPath } from './signature'; -/* tslint:disable:no-console */ - const OPTIONS = [ { names: ['help', 'h'], diff --git a/ts/updater/generateSignature.ts b/ts/updater/generateSignature.ts index 68447f32fc..5a0b3a5d50 100644 --- a/ts/updater/generateSignature.ts +++ b/ts/updater/generateSignature.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ import { join, resolve } from 'path'; import { readdir as readdirCallback } from 'fs'; @@ -5,14 +6,10 @@ import pify from 'pify'; import { getCliOptions, getPrintableError } from './common'; import { writeSignature } from './signature'; - -// @ts-ignore import * as packageJson from '../../package.json'; const readdir = pify(readdirCallback); -/* tslint:disable:no-console */ - const OPTIONS = [ { names: ['help', 'h'], diff --git a/ts/updater/index.ts b/ts/updater/index.ts index ee224510bc..e1e4f512ff 100644 --- a/ts/updater/index.ts +++ b/ts/updater/index.ts @@ -12,7 +12,7 @@ export async function start( getMainWindow: () => BrowserWindow, locale?: LocaleType, logger?: LoggerType -) { +): Promise { const { platform } = process; if (initialized) { diff --git a/ts/updater/macos.ts b/ts/updater/macos.ts index 533dedbfce..c463e61c08 100644 --- a/ts/updater/macos.ts +++ b/ts/updater/macos.ts @@ -33,7 +33,7 @@ export async function start( getMainWindow: () => BrowserWindow, locale: LocaleType, logger: LoggerType -) { +): Promise { logger.info('macos/start: starting checks...'); loggerForQuitHandler = logger; @@ -214,8 +214,6 @@ async function handToAutoUpdate( autoUpdater.checkForUpdates(); } catch (error) { reject(error); - - return; } }); }); @@ -296,7 +294,6 @@ function write404( function getServerUrl(server: Server) { const address = server.address() as AddressInfo; - // tslint:disable-next-line:no-http-string return `http://127.0.0.1:${address.port}`; } function generateFileUrl(): string { diff --git a/ts/updater/signature.ts b/ts/updater/signature.ts index 37d9c52e58..21909f69f1 100644 --- a/ts/updater/signature.ts +++ b/ts/updater/signature.ts @@ -17,7 +17,7 @@ export async function generateSignature( updatePackagePath: string, version: string, privateKeyPath: string -) { +): Promise { const privateKey = await loadHexFromPath(privateKeyPath); const message = await generateMessage(updatePackagePath, version); @@ -52,7 +52,7 @@ export async function writeSignature( updatePackagePath: string, version: string, privateKeyPath: string -) { +): Promise { const signaturePath = getSignaturePath(updatePackagePath); const signature = await generateSignature( updatePackagePath, @@ -79,7 +79,7 @@ export async function _getFileHash(updatePackagePath: string): Promise { }); } -export function getSignatureFileName(fileName: string) { +export function getSignatureFileName(fileName: string): string { return `${fileName}.sig`; } @@ -105,6 +105,9 @@ export async function loadHexFromPath(target: string): Promise { return hexToBinary(hexString); } -export async function writeHexToPath(target: string, data: Buffer) { +export async function writeHexToPath( + target: string, + data: Buffer +): Promise { await writeFile(target, binaryToHex(data)); } diff --git a/ts/updater/windows.ts b/ts/updater/windows.ts index b0b15c6b33..13878b9c25 100644 --- a/ts/updater/windows.ts +++ b/ts/updater/windows.ts @@ -38,7 +38,7 @@ export async function start( getMainWindow: () => BrowserWindow, locale: LocaleType, logger: LoggerType -) { +): Promise { logger.info('windows/start: starting checks...'); loggerForQuitHandler = logger; @@ -163,7 +163,7 @@ async function install(filePath: string, logger: LoggerType): Promise { const args = ['--updated']; const options = { detached: true, - stdio: 'ignore' as 'ignore', // TypeScript considers this a plain string without help + stdio: 'ignore' as const, // TypeScript considers this a plain string without help }; try { @@ -209,7 +209,6 @@ async function spawn( emitter.on('error', reject); emitter.unref(); - // tslint:disable-next-line no-string-based-set-timeout setTimeout(resolve, 200); }); } diff --git a/ts/window.d.ts b/ts/window.d.ts index 9b300761ab..35582db95f 100644 --- a/ts/window.d.ts +++ b/ts/window.d.ts @@ -72,6 +72,7 @@ declare global { reduxActions: ReduxActions; restart: () => void; showWindow: () => void; + showSettings: () => void; setBadgeCount: (count: number) => void; storage: { put: (key: string, value: any) => void; diff --git a/tslint.json b/tslint.json index 1604296729..d62064e1da 100644 --- a/tslint.json +++ b/tslint.json @@ -190,8 +190,12 @@ "ts/protobuf/**", "ts/scripts/**", "ts/services/**", + "ts/shims/**", "ts/state/**", + "ts/storybook/**", + "ts/test/**", "ts/types/**", + "ts/updater/**", "ts/util/**" ] } diff --git a/yarn.lock b/yarn.lock index 5175d14915..0fb4e618f7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2124,6 +2124,11 @@ dependencies: "@types/node" "*" +"@types/dashdash@1.14.0": + version "1.14.0" + resolved "https://registry.yarnpkg.com/@types/dashdash/-/dashdash-1.14.0.tgz#bfa457c2688497cf0e6695dbd522c67a9232833f" + integrity sha512-dBnfu9H6TVawx85FGmVEs5lYFXNwUVxn3Nqu5FHhCAi4aPvZR35W4FEMK3ljlpM2vHPGgEnCZGARF59/QGTNJw== + "@types/debug@^4.1.4", "@types/debug@^4.1.5": version "4.1.5" resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd"