Ratchet up linting for functions package a little bit (#431)

This commit is contained in:
Marshall Polaris 2022-06-05 22:50:27 -07:00 committed by GitHub
parent e712a054ae
commit 9e66daa861
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 77 additions and 64 deletions

View File

@ -9,17 +9,27 @@ module.exports = {
{ {
files: ['**/*.ts'], files: ['**/*.ts'],
plugins: ['@typescript-eslint'], plugins: ['@typescript-eslint'],
extends: ['plugin:@typescript-eslint/recommended'],
parser: '@typescript-eslint/parser', parser: '@typescript-eslint/parser',
parserOptions: { parserOptions: {
tsconfigRootDir: __dirname, tsconfigRootDir: __dirname,
project: ['./tsconfig.json'], project: ['./tsconfig.json'],
}, },
rules: {
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-extra-semi': 'off',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
},
],
},
}, },
], ],
rules: { rules: {
'no-extra-semi': 'off',
'no-unused-vars': 'off',
'no-constant-condition': ['error', { checkLoops: false }],
'lodash/import-scope': [2, 'member'], 'lodash/import-scope': [2, 'member'],
}, },
} }

View File

@ -27,7 +27,6 @@ export class APIError {
this.msg = msg this.msg = msg
this.details = details this.details = details
} }
toJson() {}
} }
export const parseCredentials = async (req: Request): Promise<Credentials> => { export const parseCredentials = async (req: Request): Promise<Credentials> => {

View File

@ -24,9 +24,12 @@ const bucket = 'gs://manifold-firestore-backup'
export const backupDb = functions.pubsub export const backupDb = functions.pubsub
.schedule('every 24 hours') .schedule('every 24 hours')
.onRun((context) => { .onRun((_context) => {
const projectId = process.env.GCP_PROJECT || process.env.GCLOUD_PROJECT const projectId = process.env.GCP_PROJECT || process.env.GCLOUD_PROJECT
const databaseName = client.databasePath(projectId!, '(default)') if (projectId == null) {
throw new Error('No project ID environment variable set.')
}
const databaseName = client.databasePath(projectId, '(default)')
return client return client
.exportDocuments({ .exportDocuments({

View File

@ -2,10 +2,10 @@ import * as admin from 'firebase-admin'
import fetch from './fetch' import fetch from './fetch'
export const callCloudFunction = (functionName: string, data: {} = {}) => { export const callCloudFunction = (functionName: string, data: unknown = {}) => {
const projectId = admin.instanceId().app.options.projectId const projectId = admin.instanceId().app.options.projectId
let url = `https://us-central1-${projectId}.cloudfunctions.net/${functionName}` const url = `https://us-central1-${projectId}.cloudfunctions.net/${functionName}`
return fetch(url, { return fetch(url, {
method: 'POST', method: 'POST',

View File

@ -22,17 +22,18 @@ export const createFold = functions.runWith({ minInstances: 1 }).https.onCall(
const creator = await getUser(userId) const creator = await getUser(userId)
if (!creator) return { status: 'error', message: 'User not found' } if (!creator) return { status: 'error', message: 'User not found' }
let { name, about, tags } = data let { name, about } = data
if (!name || typeof name !== 'string') if (!name || typeof name !== 'string')
return { status: 'error', message: 'Name must be a non-empty string' } return { status: 'error', message: 'Name must be a non-empty string' }
name = name.trim().slice(0, 140) name = name.trim().slice(0, 140)
if (typeof about !== 'string') if (typeof about !== 'string')
return { status: 'error', message: 'About must be a string' } return { status: 'error', message: 'About must be a string' }
about = about.trim().slice(0, 140) about = about.trim().slice(0, 140)
const { tags } = data
if (!Array.isArray(tags)) if (!Array.isArray(tags))
return { status: 'error', message: 'Tags must be an array of strings' } return { status: 'error', message: 'Tags must be an array of strings' }

View File

@ -72,7 +72,7 @@ export const createNotification = async (
sourceType === 'answer' || sourceType === 'answer' ||
sourceType === 'contract' sourceType === 'contract'
) { ) {
let reasonTextPretext = getReasonTextFromReason(sourceType, reason) const reasonTextPretext = getReasonTextFromReason(sourceType, reason)
const notifyContractCreator = async ( const notifyContractCreator = async (
userToReasonTexts: user_to_reason_texts userToReasonTexts: user_to_reason_texts

View File

@ -3,7 +3,7 @@ import { Answer } from '../../common/answer'
import { Bet } from '../../common/bet' import { Bet } from '../../common/bet'
import { getProbability } from '../../common/calculate' import { getProbability } from '../../common/calculate'
import { Comment } from '../../common/comment' import { Comment } from '../../common/comment'
import { Contract, FreeResponseContract } from '../../common/contract' import { Contract } from '../../common/contract'
import { DPM_CREATOR_FEE } from '../../common/fees' import { DPM_CREATOR_FEE } from '../../common/fees'
import { PrivateUser, User } from '../../common/user' import { PrivateUser, User } from '../../common/user'
import { formatMoney, formatPercent } from '../../common/util/format' import { formatMoney, formatPercent } from '../../common/util/format'

View File

@ -40,7 +40,7 @@ async function sendMarketCloseEmails() {
.filter((x) => !!x) as Contract[] .filter((x) => !!x) as Contract[]
}) })
for (let contract of contracts) { for (const contract of contracts) {
console.log( console.log(
'sending close email for', 'sending close email for',
contract.slug, contract.slug,

View File

@ -2,7 +2,7 @@ import * as functions from 'firebase-functions'
export const onFoldDelete = functions.firestore export const onFoldDelete = functions.firestore
.document('folds/{foldId}') .document('folds/{foldId}')
.onDelete(async (change, context) => { .onDelete(async (change, _context) => {
const snapshot = await change.ref.collection('followers').get() const snapshot = await change.ref.collection('followers').get()
// Delete followers sub-collection. // Delete followers sub-collection.

View File

@ -52,25 +52,25 @@ async function cacheUserViews(userId: string) {
console.log(viewCounts, lastViewTime) console.log(viewCounts, lastViewTime)
} }
async function deleteCache() { // async function deleteCache() {
console.log('Deleting view cache') // console.log('Deleting view cache')
const users = await getValues<User>(firestore.collection('users')) // const users = await getValues<User>(firestore.collection('users'))
await batchedWaitAll( // await batchedWaitAll(
users.map((user) => async () => { // users.map((user) => async () => {
console.log('Deleting view cache for', user.username) // console.log('Deleting view cache for', user.username)
await firestore.doc(`private-users/${user.id}/cache/viewCounts`).delete() // await firestore.doc(`private-users/${user.id}/cache/viewCounts`).delete()
await firestore // await firestore
.doc(`private-users/${user.id}/cache/lastViewTime`) // .doc(`private-users/${user.id}/cache/lastViewTime`)
.delete() // .delete()
await firestore // await firestore
.doc(`private-users/${user.id}/cache/contractScores`) // .doc(`private-users/${user.id}/cache/contractScores`)
.delete() // .delete()
await firestore.doc(`private-users/${user.id}/cache/wordScores`).delete() // await firestore.doc(`private-users/${user.id}/cache/wordScores`).delete()
}) // })
) // )
} // }
if (require.main === module) { if (require.main === module) {
cacheViews().then(() => process.exit()) cacheViews().then(() => process.exit())

View File

@ -1,5 +1,3 @@
import * as admin from 'firebase-admin'
import { initAdmin } from './script-init' import { initAdmin } from './script-init'
initAdmin() initAdmin()

View File

@ -11,7 +11,7 @@ async function main() {
const snap = await firestore.collection('users').get() const snap = await firestore.collection('users').get()
const users = snap.docs.map((d) => d.data() as User) const users = snap.docs.map((d) => d.data() as User)
for (let user of users) { for (const user of users) {
const fbUser = await admin.auth().getUser(user.id) const fbUser = await admin.auth().getUser(user.id)
const email = fbUser.email const email = fbUser.email
const { username } = user const { username } = user

View File

@ -6,7 +6,7 @@ import { DocumentSnapshot, Transaction } from 'firebase-admin/firestore'
export type DocumentValue = { export type DocumentValue = {
doc: DocumentSnapshot doc: DocumentSnapshot
field: string field: string
val: any val: unknown
} }
export type DocumentCorrespondence = [DocumentSnapshot, DocumentSnapshot[]] export type DocumentCorrespondence = [DocumentSnapshot, DocumentSnapshot[]]
export type DocumentDiff = { export type DocumentDiff = {
@ -20,9 +20,9 @@ export function findDiffs(
destPath: string destPath: string
) { ) {
const diffs: DocumentDiff[] = [] const diffs: DocumentDiff[] = []
for (let [srcDoc, destDocs] of docs) { for (const [srcDoc, destDocs] of docs) {
const srcVal = srcDoc.get(srcPath) const srcVal = srcDoc.get(srcPath)
for (let destDoc of destDocs) { for (const destDoc of destDocs) {
const destVal = destDoc.get(destPath) const destVal = destDoc.get(destPath)
if (destVal !== srcVal) { if (destVal !== srcVal) {
diffs.push({ diffs.push({

View File

@ -18,7 +18,7 @@ async function migrateBet(contractRef: DocRef, bet: Bet) {
await contractRef.collection('bets').doc(id).update({ shares }) await contractRef.collection('bets').doc(id).update({ shares })
} }
async function migrateContract(contractRef: DocRef, contract: Contract) { async function migrateContract(contractRef: DocRef) {
const bets = await contractRef const bets = await contractRef
.collection('bets') .collection('bets')
.get() .get()
@ -48,7 +48,7 @@ async function migrateContracts() {
console.log('contract', contract.question, 'bets', bets.length) console.log('contract', contract.question, 'bets', bets.length)
for (const bet of bets) await migrateBet(contractRef, bet) for (const bet of bets) await migrateBet(contractRef, bet)
await migrateContract(contractRef, contract) await migrateContract(contractRef)
} }
} }

View File

@ -57,7 +57,7 @@ async function recalculateContract(contractRef: DocRef, isCommit = false) {
: 0 : 0
} }
for (let bet of bets) { for (const bet of bets) {
const shares = bet.sale const shares = bet.sale
? getSoldBetPayout(bet) ? getSoldBetPayout(bet)
: bet.isSold : bet.isSold
@ -139,7 +139,7 @@ async function main() {
!snap.empty ? [firestore.doc(`contracts/${snap.docs[0].id}`)] : [] !snap.empty ? [firestore.doc(`contracts/${snap.docs[0].id}`)] : []
) )
for (let contractRef of contractRefs) { for (const contractRef of contractRefs) {
await recalculateContract(contractRef, isCommit).catch((e) => await recalculateContract(contractRef, isCommit).catch((e) =>
console.log('error: ', e, 'id=', contractRef.id) console.log('error: ', e, 'id=', contractRef.id)
) )

View File

@ -100,7 +100,7 @@ async function recalculateContract(
console.log('start', { pool, totalBets, totalShares }) console.log('start', { pool, totalBets, totalShares })
for (let bet of bets) { for (const bet of bets) {
if (bet.sale) { if (bet.sale) {
const soldBet = bets.find((b) => b.id === bet.sale?.betId) const soldBet = bets.find((b) => b.id === bet.sale?.betId)
if (!soldBet) throw new Error('invalid sold bet' + bet.sale.betId) if (!soldBet) throw new Error('invalid sold bet' + bet.sale.betId)

View File

@ -64,6 +64,7 @@ export const initAdmin = (env?: string) => {
return return
} }
console.log(`Initializing connection to ${env} Firebase...`) console.log(`Initializing connection to ${env} Firebase...`)
/* eslint-disable-next-line @typescript-eslint/no-var-requires */
const serviceAccount = require(keyPath) const serviceAccount = require(keyPath)
admin.initializeApp({ admin.initializeApp({
credential: admin.credential.cert(serviceAccount), credential: admin.credential.cert(serviceAccount),

View File

@ -6,7 +6,6 @@ import { User } from '../../common/user'
import { Bet } from '../../common/bet' import { Bet } from '../../common/bet'
import { getSellBetInfo } from '../../common/sell-bet' import { getSellBetInfo } from '../../common/sell-bet'
import { addObjects, removeUndefinedProps } from '../../common/util/object' import { addObjects, removeUndefinedProps } from '../../common/util/object'
import { Fees } from '../../common/fees'
export const sellBet = functions.runWith({ minInstances: 1 }).https.onCall( export const sellBet = functions.runWith({ minInstances: 1 }).https.onCall(
async ( async (
@ -50,7 +49,8 @@ export const sellBet = functions.runWith({ minInstances: 1 }).https.onCall(
if (!betSnap.exists) return { status: 'error', message: 'Invalid bet' } if (!betSnap.exists) return { status: 'error', message: 'Invalid bet' }
const bet = betSnap.data() as Bet const bet = betSnap.data() as Bet
if (userId !== bet.userId) return { status: 'error', message: 'Not authorized' } if (userId !== bet.userId)
return { status: 'error', message: 'Not authorized' }
if (bet.isSold) return { status: 'error', message: 'Bet already sold' } if (bet.isSold) return { status: 'error', message: 'Bet already sold' }
const newBetDoc = firestore const newBetDoc = firestore

View File

@ -6,7 +6,8 @@ import { PrivateUser } from '../../common/user'
export const unsubscribe = functions export const unsubscribe = functions
.runWith({ minInstances: 1 }) .runWith({ minInstances: 1 })
.https.onRequest(async (req, res) => { .https.onRequest(async (req, res) => {
let { id, type } = req.query as { id: string; type: string } const id = req.query.id as string
let type = req.query.type as string
if (!id || !type) { if (!id || !type) {
res.status(400).send('Empty id or type parameter.') res.status(400).send('Empty id or type parameter.')
return return

View File

@ -31,7 +31,7 @@ const MAX_BATCHES = 50
const getUserBatches = async () => { const getUserBatches = async () => {
const users = shuffle(await getValues<User>(firestore.collection('users'))) const users = shuffle(await getValues<User>(firestore.collection('users')))
let userBatches: User[][] = [] const userBatches: User[][] = []
for (let i = 0; i < users.length; i += BATCH_SIZE) { for (let i = 0; i < users.length; i += BATCH_SIZE) {
userBatches.push(users.slice(i, i + BATCH_SIZE)) userBatches.push(users.slice(i, i + BATCH_SIZE))
} }
@ -197,18 +197,18 @@ function getActivityScore(contract: Contract, viewTime: number | undefined) {
return isNew ? newMappedScore : mappedScore return isNew ? newMappedScore : mappedScore
} }
function getLastViewedScore(viewTime: number | undefined) { // function getLastViewedScore(viewTime: number | undefined) {
if (viewTime === undefined) { // if (viewTime === undefined) {
return 1 // return 1
} // }
const daysAgo = (Date.now() - viewTime) / DAY_MS // const daysAgo = (Date.now() - viewTime) / DAY_MS
if (daysAgo < 0.5) { // if (daysAgo < 0.5) {
const frac = logInterpolation(0, 0.5, daysAgo) // const frac = logInterpolation(0, 0.5, daysAgo)
return 0.5 + 0.25 * frac // return 0.5 + 0.25 * frac
} // }
const frac = logInterpolation(0.5, 14, daysAgo) // const frac = logInterpolation(0.5, 14, daysAgo)
return 0.75 + 0.25 * frac // return 0.75 + 0.25 * frac
} // }

View File

@ -71,9 +71,9 @@ const computeTotalPool = async (
return sum(pools) return sum(pools)
} }
const computeVolume = async (contract: Contract) => { // const computeVolume = async (contract: Contract) => {
const bets = await getValues<Bet>( // const bets = await getValues<Bet>(
firestore.collection(`contracts/${contract.id}/bets`) // firestore.collection(`contracts/${contract.id}/bets`)
) // )
return sumBy(bets, (bet) => Math.abs(bet.amount)) // return sumBy(bets, (bet) => Math.abs(bet.amount))
} // }