mozilla / blurts-server

Mozilla Monitor arms you with tools to keep your personal information safe. Find out what hackers already know about you and learn how to stay a step ahead of them.
https://monitor.mozilla.org
Mozilla Public License 2.0
699 stars 200 forks source link

Add lint:ts to lint targets in package.json (in nextjs branch)? #3057

Open pdehaan opened 1 year ago

pdehaan commented 1 year ago

Current output from nextjs branch is:

Found 57 errors in 8 files.

Errors Files

  • 2 src/app/functions/server/getBreaches.ts:14
  • 1 src/appConstants.js:60
  • 1 src/db/knexfile.js:11
  • 3 src/db/tables/breaches.js:9
  • 1 src/external/onerep.js:9
  • 10 src/utils/breachLogo.js:13
  • 13 src/utils/fxa.js:29
  • 26 src/utils/hibp.js:24
npm run lint:ts ```sh git rev-parse --short HEAD # b24622482 git rev-parse --abbrev-ref HEAD # nextjs npm run lint:ts > monitor@1.0.0 lint:ts > tsc --noEmit src/app/functions/server/getBreaches.ts:14:20 - error TS2554: Expected 0 arguments, but got 1. 14 const log = mozlog('hibp') ~~~~~~ src/app/functions/server/getBreaches.ts:31:25 - error TS2531: Object is possibly 'null'. 31 breach.LogoPath = /[^/]*$/.exec(breach.LogoPath)[0] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/appConstants.js:60:32 - error TS2367: This comparison appears to be unintentional because the types '"development" | "production" | "test"' and '"heroku"' have no overlap. 60 if (!process.env.SERVER_URL && process.env.NODE_ENV === 'heroku') { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/db/knexfile.js:11:3 - error TS2322: Type '{ rejectUnauthorized: boolean; }' is not assignable to type 'string | boolean | undefined'. 11 connectionObj.ssl = { rejectUnauthorized: false } ~~~~~~~~~~~~~~~~~ src/db/tables/breaches.js:9:20 - error TS2554: Expected 0 arguments, but got 1. 9 const log = mozlog('DB.breaches') ~~~~~~~~~~~~~ src/db/tables/breaches.js:18:6 - error TS2554: Expected 1-2 arguments, but got 0. 18 .returning() ~~~~~~~~~~~ node_modules/knex/types/index.d.ts:1094:7 1094 column: '*', ~~~~~~~~~~~ An argument for 'column' was not provided. src/db/tables/breaches.js:25:12 - error TS2314: Generic type 'Array' requires 1 type argument(s). 25 * @param {Array} hibpBreaches breaches array from HIBP API ~~~~~ src/external/onerep.js:9:20 - error TS2554: Expected 0 arguments, but got 1. 9 const log = mozlog('external.onerep') ~~~~~~~~~~~~~~~~~ src/utils/breachLogo.js:13:45 - error TS2339: Property 'Domain' does not exist on type 'object'. 13 const logoIsAvailable = logos?.has(breach.Domain) ~~~~~~ src/utils/breachLogo.js:16:68 - error TS2339: Property 'Domain' does not exist on type 'object'. 16 return `` ~~~~~~ src/utils/breachLogo.js:21:11 - error TS2339: Property 'className' does not exist on type 'String'. 21 const { className, variableName } = getColorForName(breach.Name) ~~~~~~~~~ src/utils/breachLogo.js:21:22 - error TS2339: Property 'variableName' does not exist on type 'String'. 21 const { className, variableName } = getColorForName(breach.Name) ~~~~~~~~~~~~ src/utils/breachLogo.js:21:62 - error TS2339: Property 'Name' does not exist on type 'object'. 21 const { className, variableName } = getColorForName(breach.Name) ~~~~ src/utils/breachLogo.js:25:105 - error TS2339: Property 'Name' does not exist on type 'object'. 25 return `` ~~~~ src/utils/breachLogo.js:71:33 - error TS18048: 'sum' is possibly 'undefined'. 71 .reduce((sum, codePoint) => sum + codePoint) ~~~ src/utils/breachLogo.js:71:39 - error TS18048: 'codePoint' is possibly 'undefined'. 71 .reduce((sum, codePoint) => sum + codePoint) ~~~~~~~~~ src/utils/breachLogo.js:73:3 - error TS2322: Type '{ className: string; variableName: string; }' is not assignable to type 'string'. 73 return logoColors[charValue % logoColors.length] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/utils/breachLogo.js:73:21 - error TS18048: 'charValue' is possibly 'undefined'. 73 return logoColors[charValue % logoColors.length] ~~~~~~~~~ src/utils/fxa.js:29:34 - error TS7006: Parameter 'path' implicitly has an 'any' type. 29 async function postTokenRequest (path, token) { ~~~~ src/utils/fxa.js:29:40 - error TS7006: Parameter 'token' implicitly has an 'any' type. 29 async function postTokenRequest (path, token) { ~~~~~ src/utils/fxa.js:46:48 - error TS18046: 'e' is of type 'unknown'. 46 console.error('postTokenRequest', { stack: e.stack }) ~ src/utils/fxa.js:51:34 - error TS7006: Parameter 'token' implicitly has an 'any' type. 51 async function verifyOAuthToken (token) { ~~~~~ src/utils/fxa.js:56:48 - error TS18046: 'e' is of type 'unknown'. 56 console.error('verifyOAuthToken', { stack: e.stack }) ~ src/utils/fxa.js:60:35 - error TS7006: Parameter 'token' implicitly has an 'any' type. 60 async function destroyOAuthToken (token) { ~~~~~ src/utils/fxa.js:65:49 - error TS18046: 'e' is of type 'unknown'. 65 console.error('destroyOAuthToken', { stack: e.stack }) ~ src/utils/fxa.js:69:35 - error TS7006: Parameter 'subscriber' implicitly has an 'any' type. 69 async function revokeOAuthTokens (subscriber) { ~~~~~~~~~~ src/utils/fxa.js:74:32 - error TS7006: Parameter 'accessToken' implicitly has an 'any' type. 74 async function getProfileData (accessToken) { ~~~~~~~~~~~ src/utils/fxa.js:82:45 - error TS18046: 'e' is of type 'unknown'. 82 console.warn('getProfileData', { stack: e.stack }) ~ src/utils/fxa.js:87:37 - error TS7006: Parameter 'path' implicitly has an 'any' type. 87 async function sendMetricsFlowPing (path) { ~~~~ src/utils/fxa.js:97:51 - error TS18046: 'e' is of type 'unknown'. 97 console.error('sendMetricsFlowPing', { stack: e.stack }) ~ src/utils/fxa.js:102:19 - error TS7006: Parameter 'email' implicitly has an 'any' type. 102 function getSha1 (email) { ~~~~~ src/utils/hibp.js:24:20 - error TS2554: Expected 0 arguments, but got 1. 24 const log = mozlog('hibp') ~~~~~~ src/utils/hibp.js:35:16 - error TS7023: '_throttledFetch' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions. 35 async function _throttledFetch (url, reqOptions, tryCount = 1) { ~~~~~~~~~~~~~~~ src/utils/hibp.js:35:33 - error TS7006: Parameter 'url' implicitly has an 'any' type. 35 async function _throttledFetch (url, reqOptions, tryCount = 1) { ~~~ src/utils/hibp.js:35:38 - error TS7006: Parameter 'reqOptions' implicitly has an 'any' type. 35 async function _throttledFetch (url, reqOptions, tryCount = 1) { ~~~~~~~~~~ src/utils/hibp.js:46:13 - error TS2365: Operator '>=' cannot be applied to types 'number' and 'string'. 46 if (tryCount >= HIBP_THROTTLE_MAX_TRIES) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/utils/hibp.js:50:60 - error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. 50 await new Promise(resolve => setTimeout(resolve, HIBP_THROTTLE_DELAY * tryCount)) ~~~~~~~~~~~~~~~~~~~ src/utils/hibp.js:62:21 - error TS7006: Parameter 'path' implicitly has an 'any' type. 62 async function req (path, options = {}) { ~~~~ src/utils/hibp.js:68:26 - error TS7006: Parameter 'path' implicitly has an 'any' type. 68 async function kAnonReq (path, options = {}) { ~~~~ src/utils/hibp.js:79:12 - error TS2314: Generic type 'Array' requires 1 type argument(s). 79 * @param {Array} dataClasses ~~~~~ src/utils/hibp.js:98:7 - error TS7034: Variable 'dbBreaches' implicitly has type 'any[]' in some locations where its type cannot be determined. 98 let dbBreaches = [] ~~~~~~~~~~ src/utils/hibp.js:103:12 - error TS7005: Variable 'dbBreaches' implicitly has an 'any[]' type. 103 return dbBreaches ~~~~~~~~~~ src/utils/hibp.js:129:37 - error TS7006: Parameter 'app' implicitly has an 'any' type. 129 async function loadBreachesIntoApp (app) { ~~~ src/utils/hibp.js:142:27 - error TS2531: Object is possibly 'null'. 142 breach.LogoPath = /[^/]*$/.exec(breach.LogoPath)[0] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/utils/hibp.js:164:37 - error TS7006: Parameter 'breaches' implicitly has an 'any' type. 164 async function downloadBreachIcons (breaches) { ~~~~~~~~ src/utils/hibp.js:166:10 - error TS7006: Parameter 'breach' implicitly has an 'any' type. 166 .map(breach => breach.Domain) ~~~~~~ src/utils/hibp.js:167:13 - error TS7006: Parameter 'breachDomain' implicitly has an 'any' type. 167 .filter(breachDomain => breachDomain.length > 0) ~~~~~~~~~~~~ src/utils/hibp.js:176:60 - error TS7006: Parameter 'breachDomain' implicitly has an 'any' type. 176 const logoMapElems = await Promise.all(breachDomains.map(breachDomain => { ~~~~~~~~~~~~ src/utils/hibp.js:239:12 - error TS2314: Generic type 'Array' requires 1 type argument(s). 239 * @param {Array} breaches ~~~~~ src/utils/hibp.js:240:14 - error TS2314: Generic type 'Array' requires 1 type argument(s). 240 * @returns {Array} filteredBreaches ~~~~~ src/utils/hibp.js:257:12 - error TS2314: Generic type 'Array' requires 1 type argument(s). 257 * @param {Array} allBreaches ~~~~~ src/utils/hibp.js:287:16 - error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. 287 return new Date(b.AddedDate) - new Date(a.AddedDate) ~~~~~~~~~~~~~~~~~~~~~ src/utils/hibp.js:287:40 - error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. 287 return new Date(b.AddedDate) - new Date(a.AddedDate) ~~~~~~~~~~~~~~~~~~~~~ src/utils/hibp.js:302:27 - error TS7006: Parameter 'allBreaches' implicitly has an 'any' type. 302 function getBreachByName (allBreaches, breachName) { ~~~~~~~~~~~ src/utils/hibp.js:302:40 - error TS7006: Parameter 'breachName' implicitly has an 'any' type. 302 function getBreachByName (allBreaches, breachName) { ~~~~~~~~~~ src/utils/hibp.js:305:18 - error TS7053: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type '{ covve: string; }'. 305 breachName = RENAMED_BREACHES_MAP[breachName] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ src/utils/hibp.js:307:40 - error TS7006: Parameter 'breach' implicitly has an 'any' type. 307 const foundBreach = allBreaches.find(breach => breach.Name.toLowerCase() === breachName) ~~~~~~ Found 57 errors in 8 files. Errors Files 2 src/app/functions/server/getBreaches.ts:14 1 src/appConstants.js:60 1 src/db/knexfile.js:11 3 src/db/tables/breaches.js:9 1 src/external/onerep.js:9 10 src/utils/breachLogo.js:13 13 src/utils/fxa.js:29 26 src/utils/hibp.js:24 ```

Might be easier to tweak the linters+rules now before we add too much TypeScript+Next.js and end up having to do another big refactor in the future.

https://github.com/mozilla/blurts-server/blob/b2462248203611ea8d7f32d4614ea98bc83951c6/package.json#L27-L30

-"lint": "npm run lint:css && npm run lint:js", 
+"lint": "npm run lint:css && npm run lint:js && npm run lint:ts", 
pdehaan commented 1 year ago

Also https://nextjs.org/docs/pages/building-your-application/configuring/eslint and https://nextjs.org/docs/app/api-reference/next-cli#lint

We might want to use next lint (or npx next lint depending on your usage). But currently unclear on if we need to run both tsc --noEmit AND next lint or if the latter is sufficient.

After thinking about it for a bit, I think we replace our current npm run lint:js with next lint and keep the separate tsc --noEmit script (and alias everything to npm run lint for our one script to lint CSS, JavaScript, and TypeScript).