diff --git a/.eslintrc.js b/.eslintrc.js index 9d2e19f64c..c3d03a4f68 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -28,17 +28,21 @@ module.exports = { rules: { // Following checks are temporarily disabled. We shall incrementally enable them in the // future, fixing any violations as we go. - "@typescript-eslint/no-explicit-any": 0, - "@typescript-eslint/no-use-before-define": 0, - "@typescript-eslint/explicit-function-return-type": 0, - "@typescript-eslint/camelcase": 0, - "@typescript-eslint/no-non-null-assertion": 0, - "@typescript-eslint/no-var-requires": 0, - "@typescript-eslint/ban-types": 0, - "no-useless-escape": 0, - "no-prototype-builtins": 0, + '@typescript-eslint/no-non-null-assertion': 0, + + // Disabled checks + '@typescript-eslint/no-explicit-any': 0, + '@typescript-eslint/no-use-before-define': 0, // Required checks - "indent": ["error", 2] + 'indent': ['error', 2], + '@typescript-eslint/explicit-function-return-type': [ + 'error', + { + 'allowExpressions': true, + 'allowTypedFunctionExpressions': true, + 'allowHigherOrderFunctions': true + } + ], } }; diff --git a/src/auth/action-code-settings-builder.ts b/src/auth/action-code-settings-builder.ts index 3b1441e3fe..159e78af48 100644 --- a/src/auth/action-code-settings-builder.ts +++ b/src/auth/action-code-settings-builder.ts @@ -169,7 +169,7 @@ export class ActionCodeSettingsBuilder { }; // Remove all null and undefined fields from request. for (const key in request) { - if (request.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(request, key)) { if (typeof request[key] === 'undefined' || request[key] === null) { delete request[key]; } diff --git a/src/auth/auth-api-request.ts b/src/auth/auth-api-request.ts index 847cda75ff..8b3d521e31 100755 --- a/src/auth/auth-api-request.ts +++ b/src/auth/auth-api-request.ts @@ -187,7 +187,7 @@ class TenantAwareAuthResourceUrlBuilder extends AuthResourceUrlBuilder { * * @param {any} request The providerUserInfo request object. */ -function validateProviderUserInfo(request: any) { +function validateProviderUserInfo(request: any): void { const validKeys = { rawId: true, providerId: true, @@ -247,7 +247,7 @@ function validateProviderUserInfo(request: any) { * @param {any} request The create/edit request object. * @param {boolean=} uploadAccountRequest Whether to validate as an uploadAccount request. */ -function validateCreateEditRequest(request: any, uploadAccountRequest = false) { +function validateCreateEditRequest(request: any, uploadAccountRequest = false): void { // Hash set of whitelisted parameters. const validKeys = { displayName: true, @@ -370,7 +370,7 @@ function validateCreateEditRequest(request: any, uploadAccountRequest = false) { const invalidClaims: string[] = []; // Check for any invalid claims. RESERVED_CLAIMS.forEach((blacklistedClaim) => { - if (developerClaims.hasOwnProperty(blacklistedClaim)) { + if (Object.prototype.hasOwnProperty.call(developerClaims, blacklistedClaim)) { invalidClaims.push(blacklistedClaim); } }); diff --git a/src/auth/auth-config.ts b/src/auth/auth-config.ts index ed84a8f2d5..95527eb1a7 100755 --- a/src/auth/auth-config.ts +++ b/src/auth/auth-config.ts @@ -179,10 +179,10 @@ export class EmailSignInConfig implements EmailSignInProviderConfig { public static buildServerRequest(options: EmailSignInProviderConfig): EmailSignInConfigServerRequest { const request: EmailSignInConfigServerRequest = {}; EmailSignInConfig.validate(options); - if (options.hasOwnProperty('enabled')) { + if (Object.prototype.hasOwnProperty.call(options, 'enabled')) { request.allowPasswordSignup = options.enabled; } - if (options.hasOwnProperty('passwordRequired')) { + if (Object.prototype.hasOwnProperty.call(options, 'passwordRequired')) { request.enableEmailLinkSignin = !options.passwordRequired; } return request; @@ -193,7 +193,7 @@ export class EmailSignInConfig implements EmailSignInProviderConfig { * * @param {any} options The options object to validate. */ - private static validate(options: EmailSignInProviderConfig) { + private static validate(options: EmailSignInProviderConfig): void { // TODO: Validate the request. const validKeys = { enabled: true, @@ -349,7 +349,7 @@ export class SAMLConfig implements SAMLAuthProviderConfig { * @param {SAMLAuthProviderRequest} options The options object to validate. * @param {boolean=} ignoreMissingFields Whether to ignore missing fields. */ - public static validate(options: SAMLAuthProviderRequest, ignoreMissingFields = false) { + public static validate(options: SAMLAuthProviderRequest, ignoreMissingFields = false): void { const validKeys = { enabled: true, displayName: true, @@ -590,7 +590,7 @@ export class OIDCConfig implements OIDCAuthProviderConfig { * @param {OIDCAuthProviderRequest} options The options object to validate. * @param {boolean=} ignoreMissingFields Whether to ignore missing fields. */ - public static validate(options: OIDCAuthProviderRequest, ignoreMissingFields = false) { + public static validate(options: OIDCAuthProviderRequest, ignoreMissingFields = false): void { const validKeys = { enabled: true, displayName: true, diff --git a/src/auth/auth.ts b/src/auth/auth.ts index b838802a0f..a79b83c597 100755 --- a/src/auth/auth.ts +++ b/src/auth/auth.ts @@ -444,7 +444,7 @@ export class BaseAuth { providerConfigs, }; // Delete result.pageToken if undefined. - if (response.hasOwnProperty('nextPageToken')) { + if (Object.prototype.hasOwnProperty.call(response, 'nextPageToken')) { result.pageToken = response.nextPageToken; } return result; diff --git a/src/auth/credential.ts b/src/auth/credential.ts index cb878ff554..43de4d3ed3 100644 --- a/src/auth/credential.ts +++ b/src/auth/credential.ts @@ -132,6 +132,7 @@ export class ServiceAccountCredential implements Credential { ].join(' '), }; + // eslint-disable-next-line @typescript-eslint/no-var-requires const jwt = require('jsonwebtoken'); // This method is actually synchronous so we can capture and return the buffer. return jwt.sign(claims, this.privateKey, { @@ -189,6 +190,7 @@ class ServiceAccount { throw new FirebaseAppError(AppErrorCodes.INVALID_CREDENTIAL, errorMessage); } + // eslint-disable-next-line @typescript-eslint/no-var-requires const forge = require('node-forge'); try { forge.pki.privateKeyFromPem(this.privateKey); @@ -386,7 +388,7 @@ export function isApplicationDefault(credential?: Credential): boolean { * @param key Name of the property to copy. * @param alt Alternative name of the property to copy. */ -function copyAttr(to: {[key: string]: any}, from: {[key: string]: any}, key: string, alt: string) { +function copyAttr(to: {[key: string]: any}, from: {[key: string]: any}, key: string, alt: string): void { const tmp = from[key] || from[alt]; if (typeof tmp !== 'undefined') { to[key] = tmp; diff --git a/src/auth/tenant.ts b/src/auth/tenant.ts index 4f947aff74..0b2ed1dca9 100755 --- a/src/auth/tenant.ts +++ b/src/auth/tenant.ts @@ -95,7 +95,7 @@ export class Tenant { * @param {any} request The tenant options object to validate. * @param {boolean} createRequest Whether this is a create request. */ - private static validate(request: any, createRequest: boolean) { + private static validate(request: any, createRequest: boolean): void { const validKeys = { displayName: true, emailSignInConfig: true, diff --git a/src/auth/token-generator.ts b/src/auth/token-generator.ts index f2949a7051..96188af944 100644 --- a/src/auth/token-generator.ts +++ b/src/auth/token-generator.ts @@ -101,7 +101,7 @@ export class ServiceAccountSigner implements CryptoSigner { * @inheritDoc */ public sign(buffer: Buffer): Promise { - const crypto = require('crypto'); + const crypto = require('crypto'); // eslint-disable-line @typescript-eslint/no-var-requires const sign = crypto.createSign('RSA-SHA256'); sign.update(buffer); return Promise.resolve(sign.sign(this.credential.privateKey)); @@ -285,7 +285,7 @@ export class FirebaseTokenGenerator { if (typeof developerClaims !== 'undefined') { for (const key in developerClaims) { /* istanbul ignore else */ - if (developerClaims.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(developerClaims, key)) { if (BLACKLISTED_CLAIMS.indexOf(key) !== -1) { throw new FirebaseAuthError( AuthClientErrorCode.INVALID_ARGUMENT, @@ -311,6 +311,7 @@ export class FirebaseTokenGenerator { uid, }; if (this.tenantId) { + // eslint-disable-next-line @typescript-eslint/camelcase body.tenant_id = this.tenantId; } if (Object.keys(claims).length > 0) { @@ -324,9 +325,9 @@ export class FirebaseTokenGenerator { }); } - private encodeSegment(segment: object | Buffer) { + private encodeSegment(segment: object | Buffer): string { const buffer: Buffer = (segment instanceof Buffer) ? segment : Buffer.from(JSON.stringify(segment)); - return toWebSafeBase64(buffer).replace(/\=+$/, ''); + return toWebSafeBase64(buffer).replace(/=+$/, ''); } /** diff --git a/src/auth/token-verifier.ts b/src/auth/token-verifier.ts index cd5138d63f..cc0c4f4c02 100644 --- a/src/auth/token-verifier.ts +++ b/src/auth/token-verifier.ts @@ -214,7 +214,7 @@ export class FirebaseTokenVerifier { } return this.fetchPublicKeys().then((publicKeys) => { - if (!publicKeys.hasOwnProperty(header.kid)) { + if (!Object.prototype.hasOwnProperty.call(publicKeys, header.kid)) { return Promise.reject( new FirebaseAuthError( AuthClientErrorCode.INVALID_ARGUMENT, @@ -299,7 +299,7 @@ export class FirebaseTokenVerifier { // error responses. throw new HttpError(resp); } - if (resp.headers.hasOwnProperty('cache-control')) { + if (Object.prototype.hasOwnProperty.call(resp.headers, 'cache-control')) { const cacheControlHeader: string = resp.headers['cache-control']; const parts = cacheControlHeader.split(','); parts.forEach((part) => { diff --git a/src/database/database.ts b/src/database/database.ts index 379167a694..3da2a356ba 100644 --- a/src/database/database.ts +++ b/src/database/database.ts @@ -77,8 +77,8 @@ export class DatabaseService implements FirebaseServiceInterface { let db: Database = this.INTERNAL.databases[dbUrl]; if (typeof db === 'undefined') { - const rtdb = require('@firebase/database'); - const { version } = require('../../package.json'); + const rtdb = require('@firebase/database'); // eslint-disable-line @typescript-eslint/no-var-requires + const { version } = require('../../package.json'); // eslint-disable-line @typescript-eslint/no-var-requires db = rtdb.initStandalone(this.appInternal, dbUrl, version).instance; const rulesClient = new DatabaseRulesClient(this.app, dbUrl); diff --git a/src/firebase-app.ts b/src/firebase-app.ts index aba82b6cd0..da50651eb3 100644 --- a/src/firebase-app.ts +++ b/src/firebase-app.ts @@ -189,7 +189,7 @@ export class FirebaseAppInternals { * * @param {function(string)} listener The listener that will be called with each new token. */ - public addAuthTokenListener(listener: (token: string) => void) { + public addAuthTokenListener(listener: (token: string) => void): void { this.tokenListeners_.push(listener); if (this.cachedToken_) { listener(this.cachedToken_.accessToken); @@ -201,7 +201,7 @@ export class FirebaseAppInternals { * * @param {function(string)} listener The listener to remove. */ - public removeAuthTokenListener(listener: (token: string) => void) { + public removeAuthTokenListener(listener: (token: string) => void): void { this.tokenListeners_ = this.tokenListeners_.filter((other) => other !== listener); } diff --git a/src/firebase-namespace.ts b/src/firebase-namespace.ts index caf58d439d..433659af84 100644 --- a/src/firebase-namespace.ts +++ b/src/firebase-namespace.ts @@ -237,7 +237,7 @@ export class FirebaseNamespaceInternals { * @param {FirebaseApp} app The FirebaseApp instance whose app hooks to call. * @param {string} eventName The event name representing which app hooks to call. */ - private callAppHooks_(app: FirebaseApp, eventName: string) { + private callAppHooks_(app: FirebaseApp, eventName: string): void { Object.keys(this.serviceFactories).forEach((serviceName) => { if (this.appHooks_[serviceName]) { this.appHooks_[serviceName](eventName, app); @@ -340,6 +340,8 @@ export class FirebaseNamespace { const fn: FirebaseServiceNamespace = (app?: FirebaseApp) => { return this.ensureApp(app).database(); }; + + // eslint-disable-next-line @typescript-eslint/no-var-requires return Object.assign(fn, require('@firebase/database')); } @@ -375,6 +377,8 @@ export class FirebaseNamespace { let fn: FirebaseServiceNamespace = (app?: FirebaseApp) => { return this.ensureApp(app).firestore(); }; + + // eslint-disable-next-line @typescript-eslint/no-var-requires const firestore = require('@google-cloud/firestore'); fn = Object.assign(fn, firestore.Firestore); diff --git a/src/firestore/firestore.ts b/src/firestore/firestore.ts index c733321da7..89e7fe2771 100644 --- a/src/firestore/firestore.ts +++ b/src/firestore/firestore.ts @@ -73,12 +73,13 @@ export function getFirestoreOptions(app: FirebaseApp): Settings { const projectId: string | null = utils.getExplicitProjectId(app); const credential = app.options.credential; + // eslint-disable-next-line @typescript-eslint/no-var-requires const { version: firebaseVersion } = require('../../package.json'); if (credential instanceof ServiceAccountCredential) { return { credentials: { - private_key: credential.privateKey, - client_email: credential.clientEmail, + private_key: credential.privateKey, // eslint-disable-line @typescript-eslint/camelcase + client_email: credential.clientEmail, // eslint-disable-line @typescript-eslint/camelcase }, // When the SDK is initialized with ServiceAccountCredentials an explicit projectId is // guaranteed to be available. diff --git a/src/index.d.ts b/src/index.d.ts index 8ee67a49fe..af8a938766 100755 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -18,6 +18,8 @@ import { Bucket } from '@google-cloud/storage'; import * as _firestore from '@google-cloud/firestore'; import { Agent } from 'http'; +/* eslint-disable @typescript-eslint/ban-types */ + /** * `admin` is a global namespace from which all Firebase Admin * services are accessed. diff --git a/src/messaging/messaging-types.ts b/src/messaging/messaging-types.ts index bd25f164cb..27891d27ed 100644 --- a/src/messaging/messaging-types.ts +++ b/src/messaging/messaging-types.ts @@ -297,7 +297,7 @@ export interface SendResponse { * * @param {Message} Message An object to be validated. */ -export function validateMessage(message: Message) { +export function validateMessage(message: Message): void { if (!validator.isNonNullObject(message)) { throw new FirebaseMessagingError( MessagingClientErrorCode.INVALID_PAYLOAD, 'Message must be a non-null object'); @@ -337,7 +337,7 @@ export function validateMessage(message: Message) { * @param {object} map An object to be validated. * @param {string} label A label to be included in the errors thrown. */ -function validateStringMap(map: {[key: string]: any} | undefined, label: string) { +function validateStringMap(map: {[key: string]: any} | undefined, label: string): void { if (typeof map === 'undefined') { return; } else if (!validator.isNonNullObject(map)) { @@ -357,7 +357,7 @@ function validateStringMap(map: {[key: string]: any} | undefined, label: string) * * @param {WebpushConfig} config An object to be validated. */ -function validateWebpushConfig(config: WebpushConfig | undefined) { +function validateWebpushConfig(config: WebpushConfig | undefined): void { if (typeof config === 'undefined') { return; } else if (!validator.isNonNullObject(config)) { @@ -374,7 +374,7 @@ function validateWebpushConfig(config: WebpushConfig | undefined) { * * @param {ApnsConfig} config An object to be validated. */ -function validateApnsConfig(config: ApnsConfig | undefined) { +function validateApnsConfig(config: ApnsConfig | undefined): void { if (typeof config === 'undefined') { return; } else if (!validator.isNonNullObject(config)) { @@ -391,7 +391,7 @@ function validateApnsConfig(config: ApnsConfig | undefined) { * * @param {ApnsFcmOptions} fcmOptions An object to be validated. */ -function validateApnsFcmOptions(fcmOptions: ApnsFcmOptions | undefined) { +function validateApnsFcmOptions(fcmOptions: ApnsFcmOptions | undefined): void { if (typeof fcmOptions === 'undefined') { return; } else if (!validator.isNonNullObject(fcmOptions)) { @@ -429,7 +429,7 @@ function validateApnsFcmOptions(fcmOptions: ApnsFcmOptions | undefined) { * * @param {FcmOptions} fcmOptions An object to be validated. */ -function validateFcmOptions(fcmOptions: FcmOptions | undefined) { +function validateFcmOptions(fcmOptions: FcmOptions | undefined): void { if (typeof fcmOptions === 'undefined') { return; } else if (!validator.isNonNullObject(fcmOptions)) { @@ -448,7 +448,7 @@ function validateFcmOptions(fcmOptions: FcmOptions | undefined) { * * @param {Notification} notification An object to be validated. */ -function validateNotification(notification: Notification | undefined) { +function validateNotification(notification: Notification | undefined): void { if (typeof notification === 'undefined') { return; } else if (!validator.isNonNullObject(notification)) { @@ -479,7 +479,7 @@ function validateNotification(notification: Notification | undefined) { * * @param {ApnsPayload} payload An object to be validated. */ -function validateApnsPayload(payload: ApnsPayload | undefined) { +function validateApnsPayload(payload: ApnsPayload | undefined): void { if (typeof payload === 'undefined') { return; } else if (!validator.isNonNullObject(payload)) { @@ -495,7 +495,7 @@ function validateApnsPayload(payload: ApnsPayload | undefined) { * * @param {Aps} aps An object to be validated. */ -function validateAps(aps: Aps) { +function validateAps(aps: Aps): void { if (typeof aps === 'undefined') { return; } else if (!validator.isNonNullObject(aps)) { @@ -537,7 +537,7 @@ function validateAps(aps: Aps) { } } -function validateApsSound(sound: string | CriticalSound | undefined) { +function validateApsSound(sound: string | CriticalSound | undefined): void { if (typeof sound === 'undefined' || validator.isNonEmptyString(sound)) { return; } else if (!validator.isNonNullObject(sound)) { @@ -583,7 +583,7 @@ function validateApsSound(sound: string | CriticalSound | undefined) { * * @param {string | ApsAlert} alert An alert string or an object to be validated. */ -function validateApsAlert(alert: string | ApsAlert | undefined) { +function validateApsAlert(alert: string | ApsAlert | undefined): void { if (typeof alert === 'undefined' || validator.isString(alert)) { return; } else if (!validator.isNonNullObject(alert)) { @@ -632,7 +632,7 @@ function validateApsAlert(alert: string | ApsAlert | undefined) { * * @param {AndroidConfig} config An object to be validated. */ -function validateAndroidConfig(config: AndroidConfig | undefined) { +function validateAndroidConfig(config: AndroidConfig | undefined): void { if (typeof config === 'undefined') { return; } else if (!validator.isNonNullObject(config)) { @@ -667,7 +667,7 @@ function validateAndroidConfig(config: AndroidConfig | undefined) { * * @param {AndroidNotification} notification An object to be validated. */ -function validateAndroidNotification(notification: AndroidNotification | undefined) { +function validateAndroidNotification(notification: AndroidNotification | undefined): void { if (typeof notification === 'undefined') { return; } else if (!validator.isNonNullObject(notification)) { @@ -767,7 +767,7 @@ function validateAndroidNotification(notification: AndroidNotification | undefin * * @param {LightSettings} lightSettings An object to be validated. */ -function validateLightSettings(lightSettings?: LightSettings) { +function validateLightSettings(lightSettings?: LightSettings): void { if (typeof lightSettings === 'undefined') { return; } else if (!validator.isNonNullObject(lightSettings)) { @@ -824,7 +824,7 @@ function validateLightSettings(lightSettings?: LightSettings) { * * @param {AndroidFcmOptions} fcmOptions An object to be validated. */ -function validateAndroidFcmOptions(fcmOptions: AndroidFcmOptions | undefined) { +function validateAndroidFcmOptions(fcmOptions: AndroidFcmOptions | undefined): void { if (typeof fcmOptions === 'undefined') { return; } else if (!validator.isNonNullObject(fcmOptions)) { diff --git a/src/messaging/messaging.ts b/src/messaging/messaging.ts index faee5f29a1..6cabb1104b 100644 --- a/src/messaging/messaging.ts +++ b/src/messaging/messaging.ts @@ -32,6 +32,8 @@ import { import * as utils from '../utils'; import * as validator from '../utils/validator'; +/* eslint-disable @typescript-eslint/camelcase */ + // FCM endpoints const FCM_SEND_HOST = 'fcm.googleapis.com'; const FCM_SEND_PATH = '/fcm/send'; @@ -718,7 +720,7 @@ export class Messaging implements FirebaseServiceInterface { private validateMessagingPayloadAndOptionsTypes( payload: MessagingPayload, options: MessagingOptions, - ) { + ): void { // Validate the payload is an object if (!validator.isNonNullObject(payload)) { throw new FirebaseMessagingError( @@ -744,7 +746,7 @@ export class Messaging implements FirebaseServiceInterface { * @return {MessagingPayload} A copy of the provided payload with whitelisted properties switched * from camelCase to underscore_case. */ - private validateMessagingPayload(payload: MessagingPayload) { + private validateMessagingPayload(payload: MessagingPayload): MessagingPayload { const payloadCopy: MessagingPayload = deepCopy(payload); const payloadKeys = Object.keys(payloadCopy); @@ -772,7 +774,7 @@ export class Messaging implements FirebaseServiceInterface { ); } - const validatePayload = (payloadKey: string, value: DataMessagePayload | NotificationMessagePayload) => { + const validatePayload = (payloadKey: string, value: DataMessagePayload | NotificationMessagePayload): void => { // Validate each top-level key in the payload is an object if (!validator.isNonNullObject(value)) { throw new FirebaseMessagingError( @@ -835,7 +837,7 @@ export class Messaging implements FirebaseServiceInterface { * @return {MessagingOptions} A copy of the provided options with whitelisted properties switched * from camelCase to underscore_case. */ - private validateMessagingOptions(options: MessagingOptions) { + private validateMessagingOptions(options: MessagingOptions): MessagingOptions { const optionsCopy: MessagingOptions = deepCopy(options); // Validate the options object does not contain blacklisted properties @@ -917,7 +919,7 @@ export class Messaging implements FirebaseServiceInterface { registrationTokenOrTokens: string | string[], methodName: string, errorInfo: ErrorInfo = MessagingClientErrorCode.INVALID_ARGUMENT, - ) { + ): void { if (!validator.isNonEmptyArray(registrationTokenOrTokens) && !validator.isNonEmptyString(registrationTokenOrTokens)) { throw new FirebaseMessagingError( @@ -940,7 +942,7 @@ export class Messaging implements FirebaseServiceInterface { registrationTokenOrTokens: string | string[], methodName: string, errorInfo: ErrorInfo = MessagingClientErrorCode.INVALID_ARGUMENT, - ) { + ): void { if (validator.isArray(registrationTokenOrTokens)) { // Validate the array contains no more than 1,000 registration tokens. if (registrationTokenOrTokens.length > 1000) { @@ -975,7 +977,7 @@ export class Messaging implements FirebaseServiceInterface { topic: string | string[], methodName: string, errorInfo: ErrorInfo = MessagingClientErrorCode.INVALID_ARGUMENT, - ) { + ): void { if (!validator.isNonEmptyString(topic)) { throw new FirebaseMessagingError( errorInfo, @@ -996,7 +998,7 @@ export class Messaging implements FirebaseServiceInterface { topic: string, methodName: string, errorInfo: ErrorInfo = MessagingClientErrorCode.INVALID_ARGUMENT, - ) { + ): void { if (!validator.isTopic(topic)) { throw new FirebaseMessagingError( errorInfo, @@ -1013,7 +1015,7 @@ export class Messaging implements FirebaseServiceInterface { * * @return {string} The normalized topic name. */ - private normalizeTopic(topic: string) { + private normalizeTopic(topic: string): string { if (!/^\/topics\//.test(topic)) { topic = `/topics/${ topic }`; } diff --git a/src/project-management/android-app.ts b/src/project-management/android-app.ts index e51ace8ba3..0cbd8951fc 100644 --- a/src/project-management/android-app.ts +++ b/src/project-management/android-app.ts @@ -46,7 +46,7 @@ export class AndroidApp { assertServerResponse( validator.isNonEmptyString(responseData[requiredField]), responseData, - `getMetadata()\'s responseData.${requiredField} must be a non-empty string.`); + `getMetadata()'s responseData.${requiredField} must be a non-empty string.`); }); const metadata: AndroidAppMetadata = { @@ -89,7 +89,7 @@ export class AndroidApp { assertServerResponse( validator.isNonEmptyString(certificateJson[requiredField]), responseData, - `getShaCertificates()\'s responseData.certificates[].${requiredField} must be a ` + `getShaCertificates()'s responseData.certificates[].${requiredField} must be a ` + `non-empty string.`); }); @@ -128,7 +128,7 @@ export class AndroidApp { assertServerResponse( validator.isBase64String(base64ConfigFileContents), responseData, - `getConfig()\'s responseData.configFileContents must be a base64 string.`); + `getConfig()'s responseData.configFileContents must be a base64 string.`); return Buffer.from(base64ConfigFileContents, 'base64').toString('utf8'); }); diff --git a/src/project-management/ios-app.ts b/src/project-management/ios-app.ts index 46672a9306..18acb47ae1 100644 --- a/src/project-management/ios-app.ts +++ b/src/project-management/ios-app.ts @@ -46,7 +46,7 @@ export class IosApp { assertServerResponse( validator.isNonEmptyString(responseData[requiredField]), responseData, - `getMetadata()\'s responseData.${requiredField} must be a non-empty string.`); + `getMetadata()'s responseData.${requiredField} must be a non-empty string.`); }); const metadata: IosAppMetadata = { @@ -81,7 +81,7 @@ export class IosApp { assertServerResponse( validator.isBase64String(base64ConfigFileContents), responseData, - `getConfig()\'s responseData.configFileContents must be a base64 string.`); + `getConfig()'s responseData.configFileContents must be a base64 string.`); return Buffer.from(base64ConfigFileContents, 'base64').toString('utf8'); }); diff --git a/src/project-management/project-management-api-request.ts b/src/project-management/project-management-api-request.ts index 6acd692cdd..c7528f9157 100644 --- a/src/project-management/project-management-api-request.ts +++ b/src/project-management/project-management-api-request.ts @@ -64,7 +64,7 @@ export class ProjectManagementRequestHandler { `https://${PROJECT_MANAGEMENT_HOST_AND_PORT}${PROJECT_MANAGEMENT_BETA_PATH}`; private readonly httpClient: AuthorizedHttpClient; - private static wrapAndRethrowHttpError(errStatusCode: number, errText?: string) { + private static wrapAndRethrowHttpError(errStatusCode: number, errText?: string): void { let errorCode: ProjectManagementErrorCode; let errorMessage: string; diff --git a/src/project-management/project-management.ts b/src/project-management/project-management.ts index 218e0a5977..dfe6be3a3f 100644 --- a/src/project-management/project-management.ts +++ b/src/project-management/project-management.ts @@ -261,7 +261,7 @@ export class ProjectManagement implements FirebaseServiceInterface { assertServerResponse( validator.isNonNullObject(responseData), responseData, - `${callerName}\'s responseData must be a non-null object.`); + `${callerName}'s responseData must be a non-null object.`); if (responseData.apps) { assertServerResponse( diff --git a/src/storage/storage.ts b/src/storage/storage.ts index 6b3ddcaef1..afd3b003de 100644 --- a/src/storage/storage.ts +++ b/src/storage/storage.ts @@ -79,8 +79,8 @@ export class Storage implements FirebaseServiceInterface { // guaranteed to be available. projectId: projectId!, credentials: { - private_key: credential.privateKey, - client_email: credential.clientEmail, + private_key: credential.privateKey, // eslint-disable-line @typescript-eslint/camelcase + client_email: credential.clientEmail, // eslint-disable-line @typescript-eslint/camelcase }, }); } else if (isApplicationDefault(app.options.credential)) { diff --git a/src/utils/api-request.ts b/src/utils/api-request.ts index 661cc50477..9f1b8c18ca 100644 --- a/src/utils/api-request.ts +++ b/src/utils/api-request.ts @@ -213,7 +213,7 @@ export function defaultRetryConfig(): RetryConfig { * * @param retry The configuration to be validated. */ -function validateRetryConfig(retry: RetryConfig) { +function validateRetryConfig(retry: RetryConfig): void { if (!validator.isNumber(retry.maxRetries) || retry.maxRetries < 0) { throw new FirebaseAppError( AppErrorCodes.INVALID_ARGUMENT, 'maxRetries must be a non-negative integer'); @@ -481,7 +481,7 @@ class AsyncHttpCall { } } - private execute() { + private execute(): void { const transport: any = this.options.protocol === 'https:' ? https : http; const req: http.ClientRequest = transport.request(this.options, (res: http.IncomingMessage) => { this.handleResponse(res, req); @@ -508,7 +508,7 @@ class AsyncHttpCall { req.end(this.entity); } - private handleResponse(res: http.IncomingMessage, req: http.ClientRequest) { + private handleResponse(res: http.IncomingMessage, req: http.ClientRequest): void { if (req.aborted) { return; } @@ -572,7 +572,7 @@ class AsyncHttpCall { const encodings = ['gzip', 'compress', 'deflate']; if (res.headers['content-encoding'] && encodings.indexOf(res.headers['content-encoding']) !== -1) { // Add the unzipper to the body stream processing pipeline. - const zlib: typeof zlibmod = require('zlib'); + const zlib: typeof zlibmod = require('zlib'); // eslint-disable-line @typescript-eslint/no-var-requires respStream = respStream.pipe(zlib.createUnzip()); // Remove the content-encoding in order to not confuse downstream operations. delete res.headers['content-encoding']; @@ -581,9 +581,9 @@ class AsyncHttpCall { } private handleMultipartResponse( - response: LowLevelResponse, respStream: Readable, boundary: string) { + response: LowLevelResponse, respStream: Readable, boundary: string): void { - const dicer = require('dicer'); + const dicer = require('dicer'); // eslint-disable-line @typescript-eslint/no-var-requires const multipartParser = new dicer({boundary}); const responseBuffer: Buffer[] = []; multipartParser.on('part', (part: any) => { @@ -607,7 +607,7 @@ class AsyncHttpCall { respStream.pipe(multipartParser); } - private handleRegularResponse(response: LowLevelResponse, respStream: Readable) { + private handleRegularResponse(response: LowLevelResponse, respStream: Readable): void { const responseBuffer: Buffer[] = []; respStream.on('data', (chunk: Buffer) => { responseBuffer.push(chunk); @@ -631,7 +631,7 @@ class AsyncHttpCall { * Finalizes the current HTTP call in-flight by either resolving or rejecting the associated * promise. In the event of an error, adds additional useful information to the returned error. */ - private finalizeResponse(response: LowLevelResponse) { + private finalizeResponse(response: LowLevelResponse): void { if (response.status >= 200 && response.status < 300) { this.resolve(response); } else { @@ -652,7 +652,7 @@ class AsyncHttpCall { message: string, code?: string | null, request?: http.ClientRequest | null, - response?: LowLevelResponse) { + response?: LowLevelResponse): void { const error = new Error(message); this.enhanceAndReject(error, code, request, response); @@ -662,7 +662,7 @@ class AsyncHttpCall { error: any, code?: string | null, request?: http.ClientRequest | null, - response?: LowLevelResponse) { + response?: LowLevelResponse): void { this.reject(this.enhanceError(error, code, request, response)); } @@ -778,7 +778,7 @@ class HttpRequestConfigImpl implements HttpRequestConfig { const parsedUrl = new url.URL(fullUrl); const dataObj = this.data as {[key: string]: string}; for (const key in dataObj) { - if (dataObj.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(dataObj, key)) { parsedUrl.searchParams.append(key, dataObj[key]); } } diff --git a/src/utils/deep-copy.ts b/src/utils/deep-copy.ts index 2cff483604..72a791d30a 100644 --- a/src/utils/deep-copy.ts +++ b/src/utils/deep-copy.ts @@ -69,7 +69,7 @@ export function deepExtend(target: any, source: any): any { } for (const prop in source) { - if (!source.hasOwnProperty(prop)) { + if (!Object.prototype.hasOwnProperty.call(source, prop)) { continue; } target[prop] = deepExtend(target[prop], source[prop]); diff --git a/src/utils/index.ts b/src/utils/index.ts index f0d7eee394..f6e2f41232 100755 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -151,7 +151,7 @@ export function generateUpdateMask(obj: {[key: string]: any}): string[] { return updateMask; } for (const key in obj) { - if (obj.hasOwnProperty(key) && typeof obj[key] !== 'undefined') { + if (Object.prototype.hasOwnProperty.call(obj, key) && typeof obj[key] !== 'undefined') { const maskList = generateUpdateMask(obj[key]); if (maskList.length > 0) { maskList.forEach((mask) => { diff --git a/src/utils/validator.ts b/src/utils/validator.ts index 8edc54a97e..9c24d78211 100644 --- a/src/utils/validator.ts +++ b/src/utils/validator.ts @@ -198,7 +198,7 @@ export function isURL(urlStr: any): boolean { return false; } // Lookup illegal characters. - const re = /[^a-z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\.\-\_\~\%]/i; + const re = /[^a-z0-9:/?#[\]@!$&'()*+,;=.\-_~%]/i; if (re.test(urlStr)) { return false; } @@ -213,12 +213,12 @@ export function isURL(urlStr: any): boolean { } // Validate hostname: Can contain letters, numbers, underscore and dashes separated by a dot. // Each zone must not start with a hyphen or underscore. - if (!hostname || !/^[a-zA-Z0-9]+[\w\-]*([\.]?[a-zA-Z0-9]+[\w\-]*)*$/.test(hostname)) { + if (!hostname || !/^[a-zA-Z0-9]+[\w-]*([.]?[a-zA-Z0-9]+[\w-]*)*$/.test(hostname)) { return false; } // Allow for pathnames: (/chars+)*/? // Where chars can be a combination of: a-z A-Z 0-9 - _ . ~ ! $ & ' ( ) * + , ; = : @ % - const pathnameRe = /^(\/[\w\-\.\~\!\$\'\(\)\*\+\,\;\=\:\@\%]+)*\/?$/; + const pathnameRe = /^(\/[\w\-.~!$'()*+,;=:@%]+)*\/?$/; // Validate pathname. if (pathname && pathname !== '/' && diff --git a/test/integration/auth.spec.ts b/test/integration/auth.spec.ts index 9e43c92abd..3bd65422cd 100755 --- a/test/integration/auth.spec.ts +++ b/test/integration/auth.spec.ts @@ -32,9 +32,7 @@ import { AuthProviderConfig } from '../../src/auth/auth-config'; import { deepExtend, deepCopy } from '../../src/utils/deep-copy'; import { User, FirebaseAuth } from '@firebase/auth-types'; -/* tslint:disable:no-var-requires */ -const chalk = require('chalk'); -/* tslint:enable:no-var-requires */ +const chalk = require('chalk'); // eslint-disable-line @typescript-eslint/no-var-requires chai.should(); chai.use(chaiAsPromised); @@ -292,7 +290,7 @@ describe('admin.auth', () => { .then((decodedIdToken: {[key: string]: any}) => { // Confirm expected claims set on the user's ID token. for (const key in customClaims) { - if (customClaims.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(customClaims, key)) { expect(decodedIdToken[key]).to.equal(customClaims[key]); } } @@ -316,7 +314,7 @@ describe('admin.auth', () => { .then((decodedIdToken: {[key: string]: any}) => { // Confirm all custom claims are cleared. for (const key in customClaims) { - if (customClaims.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(customClaims, key)) { expect(decodedIdToken[key]).to.be.undefined; } } @@ -969,7 +967,7 @@ describe('admin.auth', () => { enableRequestSigning: true, }; - const removeTempConfigs = () => { + const removeTempConfigs = (): Promise => { return Promise.all([ admin.auth().deleteProviderConfig(authProviderConfig1.providerId).catch(() => {/* empty */}), admin.auth().deleteProviderConfig(authProviderConfig2.providerId).catch(() => {/* empty */}), @@ -1101,7 +1099,7 @@ describe('admin.auth', () => { clientId: 'CLIENT_ID2', }; - const removeTempConfigs = () => { + const removeTempConfigs = (): Promise => { return Promise.all([ admin.auth().deleteProviderConfig(authProviderConfig1.providerId).catch(() => {/* empty */}), admin.auth().deleteProviderConfig(authProviderConfig2.providerId).catch(() => {/* empty */}), @@ -1619,7 +1617,7 @@ function testImportAndSignInUser( * @return {Promise} A promise that resolves when the user is deleted * or is found not to exist. */ -function deletePhoneNumberUser(phoneNumber: string) { +function deletePhoneNumberUser(phoneNumber: string): Promise { return admin.auth().getUserByPhoneNumber(phoneNumber) .then((userRecord) => { return safeDelete(userRecord.uid); @@ -1638,7 +1636,7 @@ function deletePhoneNumberUser(phoneNumber: string) { * * @return {Promise} A promise that resolves when test preparations are ready. */ -function cleanup() { +function cleanup(): Promise { // Delete any existing users that could affect the test outcome. const promises: Array> = [ deletePhoneNumberUser(testPhoneNumber), @@ -1729,9 +1727,9 @@ function safeDelete(uid: string): Promise { * @param {[key: string]: any} expected object. * @param {[key: string]: any} actual object. */ -function assertDeepEqualUnordered(expected: {[key: string]: any}, actual: {[key: string]: any}) { +function assertDeepEqualUnordered(expected: {[key: string]: any}, actual: {[key: string]: any}): void { for (const key in expected) { - if (expected.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(expected, key)) { expect(actual[key]) .to.deep.equal(expected[key]); } diff --git a/test/integration/database.spec.ts b/test/integration/database.spec.ts index 1419313416..7fed7be2a0 100644 --- a/test/integration/database.spec.ts +++ b/test/integration/database.spec.ts @@ -19,9 +19,8 @@ import * as chai from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; import {defaultApp, nullApp, nonNullApp, cmdArgs, databaseUrl} from './setup'; -/* tslint:disable:no-var-requires */ +// eslint-disable-next-line @typescript-eslint/no-var-requires const chalk = require('chalk'); -/* tslint:enable:no-var-requires */ chai.should(); chai.use(chaiAsPromised); @@ -178,7 +177,7 @@ describe('admin.database', () => { // eslint-disable-next-line @typescript-eslint/no-unused-vars function addValueEventListener( db: admin.database.Database, - callback: (s: admin.database.DataSnapshot | null) => any) { + callback: (s: admin.database.DataSnapshot | null) => any): void { const eventType: admin.database.EventType = 'value'; db.ref().on(eventType, callback); } diff --git a/test/integration/project-management.spec.ts b/test/integration/project-management.spec.ts index 9fbf4c73e0..de26f4aaf2 100644 --- a/test/integration/project-management.spec.ts +++ b/test/integration/project-management.spec.ts @@ -264,21 +264,21 @@ function deleteAllShaCertificates(androidApp: admin.projectManagement.AndroidApp /** * @return {string} Dot-separated string that can be used as a unique package name or bundle ID. */ -function generateUniqueAppNamespace() { +function generateUniqueAppNamespace(): string { return APP_NAMESPACE_PREFIX + generateRandomString(APP_NAMESPACE_SUFFIX_LENGTH); } /** * @return {string} Dot-separated string that can be used as a unique app display name. */ -function generateUniqueAppDisplayName() { +function generateUniqueAppDisplayName(): string { return APP_DISPLAY_NAME_PREFIX + generateRandomString(APP_DISPLAY_NAME_SUFFIX_LENGTH); } /** * @return {string} string that can be used as a unique project display name. */ -function generateUniqueProjectDisplayName() { +function generateUniqueProjectDisplayName(): string { return PROJECT_DISPLAY_NAME_PREFIX + generateRandomString(PROJECT_DISPLAY_NAME_SUFFIX_LENGTH); } diff --git a/test/integration/security-rules.spec.ts b/test/integration/security-rules.spec.ts index ce86ed932e..648b74c787 100644 --- a/test/integration/security-rules.spec.ts +++ b/test/integration/security-rules.spec.ts @@ -47,11 +47,11 @@ describe('admin.securityRules', () => { const rulesetsToDelete: string[] = []; - function scheduleForDelete(ruleset: admin.securityRules.Ruleset) { + function scheduleForDelete(ruleset: admin.securityRules.Ruleset): void { rulesetsToDelete.push(ruleset.name); } - function unscheduleForDelete(ruleset: admin.securityRules.Ruleset) { + function unscheduleForDelete(ruleset: admin.securityRules.Ruleset): void { rulesetsToDelete.splice(rulesetsToDelete.indexOf(ruleset.name), 1); } @@ -296,7 +296,7 @@ describe('admin.securityRules', () => { }); }); - function verifyFirestoreRuleset(ruleset: admin.securityRules.Ruleset) { + function verifyFirestoreRuleset(ruleset: admin.securityRules.Ruleset): void { expect(ruleset.name).to.match(RULESET_NAME_PATTERN); const createTime = new Date(ruleset.createTime); expect(ruleset.createTime).equals(createTime.toUTCString()); diff --git a/test/integration/setup.ts b/test/integration/setup.ts index 8b5dfcda71..a3558ae6b2 100644 --- a/test/integration/setup.ts +++ b/test/integration/setup.ts @@ -21,9 +21,8 @@ import path = require('path'); import {random} from 'lodash'; import { Credential, GoogleOAuthAccessToken } from '../../src/auth/credential'; -/* tslint:disable:no-var-requires */ +// eslint-disable-next-line @typescript-eslint/no-var-requires const chalk = require('chalk'); -/* tslint:enable:no-var-requires */ export let databaseUrl: string; export let storageBucket: string; diff --git a/test/integration/typescript/src/example.test.ts b/test/integration/typescript/src/example.test.ts index 25676d96be..67a1ce6272 100644 --- a/test/integration/typescript/src/example.test.ts +++ b/test/integration/typescript/src/example.test.ts @@ -21,6 +21,7 @@ import {Firestore} from '@google-cloud/firestore'; import * as admin from 'firebase-admin'; +// eslint-disable-next-line @typescript-eslint/no-var-requires const serviceAccount = require('../mock.key.json'); describe('Init App', () => { diff --git a/test/integration/typescript/src/example.ts b/test/integration/typescript/src/example.ts index 9e75838efa..0b254517d1 100644 --- a/test/integration/typescript/src/example.ts +++ b/test/integration/typescript/src/example.ts @@ -16,7 +16,7 @@ import * as firebase from 'firebase-admin'; -export function initApp(serviceAcct: any, name: string) { +export function initApp(serviceAcct: any, name: string): firebase.app.App { return firebase.initializeApp({ credential: firebase.credential.cert(serviceAcct), databaseURL: 'https://mock.firebaseio.com' @@ -26,7 +26,7 @@ export function initApp(serviceAcct: any, name: string) { export function addValueEventListener( // Check for type compilation db: firebase.database.Database, - callback: (s: firebase.database.DataSnapshot) => any) { + callback: (s: firebase.database.DataSnapshot) => any): void { const eventType: firebase.database.EventType = 'value'; db.ref().on(eventType, callback); } diff --git a/test/resources/mocks.ts b/test/resources/mocks.ts index c2c3dd3aa1..7c73e8fe54 100644 --- a/test/resources/mocks.ts +++ b/test/resources/mocks.ts @@ -81,8 +81,8 @@ export const appOptionsAuthDB: FirebaseAppOptions = { export class MockCredential implements Credential { public getAccessToken(): Promise { return Promise.resolve({ - access_token: 'mock-token', - expires_in: 3600, + access_token: 'mock-token', // eslint-disable-line @typescript-eslint/camelcase + expires_in: 3600, // eslint-disable-line @typescript-eslint/camelcase }); } } @@ -144,9 +144,8 @@ export const refreshToken = { type: 'refreshToken', }; -/* tslint:disable:no-var-requires */ +// eslint-disable-next-line @typescript-eslint/no-var-requires export const certificateObject = require('./mock.key.json'); -/* tslint:enable:no-var-requires */ // Randomly generated key pairs that don't correspond to anything related to Firebase or GCP export const keyPairs = [ diff --git a/test/unit/auth/auth-api-request.spec.ts b/test/unit/auth/auth-api-request.spec.ts index 5b4cd722ff..6c225b817a 100755 --- a/test/unit/auth/auth-api-request.spec.ts +++ b/test/unit/auth/auth-api-request.spec.ts @@ -547,7 +547,7 @@ describe('FIREBASE_AUTH_SET_ACCOUNT_INFO', () => { expect(() => { const claims = { sub: 'sub', - auth_time: 'time', + auth_time: 'time', // eslint-disable-line @typescript-eslint/camelcase }; return requestValidator({localId: '1234', customAttributes: JSON.stringify(claims)}); }).to.throw(`Developer claims "auth_time", "sub" are reserved and cannot be specified.`); diff --git a/test/unit/auth/auth.spec.ts b/test/unit/auth/auth.spec.ts index fc75b0d2dc..5c453d18e8 100755 --- a/test/unit/auth/auth.spec.ts +++ b/test/unit/auth/auth.spec.ts @@ -73,7 +73,7 @@ interface EmailActionTest { * @return {object} A sample valid server response as returned from getAccountInfo * endpoint. */ -function getValidGetAccountInfoResponse(tenantId?: string) { +function getValidGetAccountInfoResponse(tenantId?: string): {kind: string; users: any[]} { const userResponse: any = { localId: 'abcdefghijklmnopqrstuvwxyz', email: 'user@gmail.com', @@ -123,7 +123,7 @@ function getValidGetAccountInfoResponse(tenantId?: string) { * @param {any} serverResponse Raw getAccountInfo response. * @return {Object} The corresponding user record. */ -function getValidUserRecord(serverResponse: any) { +function getValidUserRecord(serverResponse: any): UserRecord { return new UserRecord(serverResponse.users[0]); } @@ -140,13 +140,13 @@ function getDecodedIdToken(uid: string, authTime: Date, tenantId?: string): Deco return { iss: 'https://securetoken.google.com/project123456789', aud: 'project123456789', - auth_time: Math.floor(authTime.getTime() / 1000), + auth_time: Math.floor(authTime.getTime() / 1000), // eslint-disable-line @typescript-eslint/camelcase sub: uid, iat: Math.floor(authTime.getTime() / 1000), exp: Math.floor(authTime.getTime() / 1000 + 3600), firebase: { identities: {}, - sign_in_provider: 'custom', + sign_in_provider: 'custom', // eslint-disable-line @typescript-eslint/camelcase tenant: tenantId, }, }; @@ -165,13 +165,13 @@ function getDecodedSessionCookie(uid: string, authTime: Date, tenantId?: string) return { iss: 'https://session.firebase.google.com/project123456789', aud: 'project123456789', - auth_time: Math.floor(authTime.getTime() / 1000), + auth_time: Math.floor(authTime.getTime() / 1000), // eslint-disable-line @typescript-eslint/camelcase sub: uid, iat: Math.floor(authTime.getTime() / 1000), exp: Math.floor(authTime.getTime() / 1000 + 3600), firebase: { identities: {}, - sign_in_provider: 'custom', + sign_in_provider: 'custom', // eslint-disable-line @typescript-eslint/camelcase tenant: tenantId, }, }; diff --git a/test/unit/auth/credential.spec.ts b/test/unit/auth/credential.spec.ts index 368d983f0c..881dcb7525 100644 --- a/test/unit/auth/credential.spec.ts +++ b/test/unit/auth/credential.spec.ts @@ -42,6 +42,8 @@ chai.should(); chai.use(sinonChai); chai.use(chaiAsPromised); +/* eslint-disable @typescript-eslint/camelcase */ + const expect = chai.expect; const GCLOUD_CREDENTIAL_SUFFIX = 'gcloud/application_default_credentials.json'; diff --git a/test/unit/auth/token-generator.spec.ts b/test/unit/auth/token-generator.spec.ts index 6e28929014..3a6dbe4df4 100644 --- a/test/unit/auth/token-generator.spec.ts +++ b/test/unit/auth/token-generator.spec.ts @@ -84,6 +84,7 @@ describe('CryptoSigner', () => { const payload = Buffer.from('test'); const cert = new ServiceAccountCredential(mocks.certificateObject); + // eslint-disable-next-line @typescript-eslint/no-var-requires const crypto = require('crypto'); const rsa = crypto.createSign('RSA-SHA256'); rsa.update(payload); @@ -400,6 +401,7 @@ describe('FirebaseTokenGenerator', () => { }; if (tokenGenerator.tenantId) { + // eslint-disable-next-line @typescript-eslint/camelcase expected.tenant_id = tokenGenerator.tenantId; } @@ -428,6 +430,7 @@ describe('FirebaseTokenGenerator', () => { }; if (tokenGenerator.tenantId) { + // eslint-disable-next-line @typescript-eslint/camelcase expected.tenant_id = tokenGenerator.tenantId; } diff --git a/test/unit/auth/token-verifier.spec.ts b/test/unit/auth/token-verifier.spec.ts index 8de2ca54a3..bf95f96380 100644 --- a/test/unit/auth/token-verifier.spec.ts +++ b/test/unit/auth/token-verifier.spec.ts @@ -88,7 +88,7 @@ function mockFetchPublicKeysWithErrorResponse(): nock.Scope { .get('/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com') .reply(200, { error: 'message', - error_description: 'description', + error_description: 'description', // eslint-disable-line @typescript-eslint/camelcase }); } diff --git a/test/unit/firebase-app.spec.ts b/test/unit/firebase-app.spec.ts index 001d959bcf..d28cdd166d 100644 --- a/test/unit/firebase-app.spec.ts +++ b/test/unit/firebase-app.spec.ts @@ -70,8 +70,8 @@ describe('FirebaseApp', () => { beforeEach(() => { getTokenStub = sinon.stub(ServiceAccountCredential.prototype, 'getAccessToken').resolves({ - access_token: 'mock-access-token', - expires_in: 3600, + access_token: 'mock-access-token', // eslint-disable-line @typescript-eslint/camelcase + expires_in: 3600, // eslint-disable-line @typescript-eslint/camelcase }); clock = sinon.useFakeTimers(1000); @@ -667,8 +667,8 @@ describe('FirebaseApp', () => { it('returns a valid token given a well-formed custom credential implementation', () => { const oracle: GoogleOAuthAccessToken = { - access_token: 'This is a custom token', - expires_in: ONE_HOUR_IN_SECONDS, + access_token: 'This is a custom token', // eslint-disable-line @typescript-eslint/camelcase + expires_in: ONE_HOUR_IN_SECONDS, // eslint-disable-line @typescript-eslint/camelcase }; const credential = { getAccessToken: () => Promise.resolve(oracle), @@ -761,8 +761,8 @@ describe('FirebaseApp', () => { // Restore the stubbed getAccessToken() method. getTokenStub.restore(); getTokenStub = sinon.stub(ServiceAccountCredential.prototype, 'getAccessToken').resolves({ - access_token: 'mock-access-token', - expires_in: 3600, + access_token: 'mock-access-token', // eslint-disable-line @typescript-eslint/camelcase + expires_in: 3600, // eslint-disable-line @typescript-eslint/camelcase }); return mockApp.INTERNAL.getToken().then((token2) => { @@ -914,8 +914,8 @@ describe('FirebaseApp', () => { getTokenStub.restore(); expect(mockApp.options.credential).to.exist; getTokenStub = sinon.stub(mockApp.options.credential!, 'getAccessToken').resolves({ - access_token: utils.generateRandomAccessToken(), - expires_in: 3 * 60 + 10, + access_token: utils.generateRandomAccessToken(), // eslint-disable-line @typescript-eslint/camelcase + expires_in: 3 * 60 + 10, // eslint-disable-line @typescript-eslint/camelcase }); // Expect the call count to initially be zero. expect(getTokenStub.callCount).to.equal(0); diff --git a/test/unit/firebase.spec.ts b/test/unit/firebase.spec.ts index bdbd4d787a..4471ed630e 100644 --- a/test/unit/firebase.spec.ts +++ b/test/unit/firebase.spec.ts @@ -40,8 +40,8 @@ describe('Firebase', () => { before(() => { getTokenStub = sinon.stub(ServiceAccountCredential.prototype, 'getAccessToken').resolves({ - access_token: 'mock-access-token', - expires_in: 3600, + access_token: 'mock-access-token', // eslint-disable-line @typescript-eslint/camelcase + expires_in: 3600, // eslint-disable-line @typescript-eslint/camelcase }); }); @@ -150,8 +150,8 @@ describe('Firebase', () => { getTokenStub.restore(); getTokenStub = sinon.stub(RefreshTokenCredential.prototype, 'getAccessToken') .resolves({ - access_token: 'mock-access-token', - expires_in: 3600, + access_token: 'mock-access-token', // eslint-disable-line @typescript-eslint/camelcase + expires_in: 3600, // eslint-disable-line @typescript-eslint/camelcase }); firebaseAdmin.initializeApp({ credential: firebaseAdmin.credential.refreshToken(mocks.refreshToken), diff --git a/test/unit/firestore/firestore.spec.ts b/test/unit/firestore/firestore.spec.ts index df72549b40..482211ffa0 100644 --- a/test/unit/firestore/firestore.spec.ts +++ b/test/unit/firestore/firestore.spec.ts @@ -38,6 +38,7 @@ describe('Firestore', () => { + 'credentials. Must initialize the SDK with a certificate credential or application default ' + 'credentials to use Cloud Firestore API.'; + // eslint-disable-next-line @typescript-eslint/no-var-requires const { version: firebaseVersion } = require('../../../package.json'); const defaultCredentialApps = [ { diff --git a/test/unit/messaging/batch-requests.spec.ts b/test/unit/messaging/batch-requests.spec.ts index 9bc11532a0..bcfee5ef74 100644 --- a/test/unit/messaging/batch-requests.spec.ts +++ b/test/unit/messaging/batch-requests.spec.ts @@ -33,6 +33,7 @@ chai.use(chaiAsPromised); const expect = chai.expect; function parseHttpRequest(text: string | Buffer): any { + // eslint-disable-next-line @typescript-eslint/no-var-requires const httpMessageParser = require('http-message-parser'); return httpMessageParser(text); } @@ -241,7 +242,7 @@ describe('BatchRequestClient', () => { }); }); - function checkOutgoingRequest(stub: sinon.SinonStub, requests: SubRequest[]) { + function checkOutgoingRequest(stub: sinon.SinonStub, requests: SubRequest[]): void { expect(stub).to.have.been.calledOnce; const args: HttpRequestConfig = stub.getCall(0).args[0]; expect(args.method).to.equal('POST'); diff --git a/test/unit/messaging/messaging.spec.ts b/test/unit/messaging/messaging.spec.ts index 286f5d2702..9bd41b374e 100644 --- a/test/unit/messaging/messaging.spec.ts +++ b/test/unit/messaging/messaging.spec.ts @@ -158,6 +158,8 @@ function mockErrorResponse( }); } +/* eslint-disable @typescript-eslint/camelcase */ + function mockSendToDeviceStringRequest(mockFailure = false): nock.Scope { let deviceResult: object = { message_id: `0:${ mocks.messaging.messageId }` }; if (mockFailure) { @@ -299,7 +301,7 @@ function mockTopicSubscriptionRequestWithError( }); } -function disableRetries(messaging: Messaging) { +function disableRetries(messaging: Messaging): void { (messaging as any).messagingRequestHandler.httpClient.retry = null; } @@ -561,13 +563,13 @@ describe('Messaging', () => { describe('sendAll()', () => { const validMessage: Message = {token: 'a'}; - function checkSendResponseSuccess(response: SendResponse, messageId: string) { + function checkSendResponseSuccess(response: SendResponse, messageId: string): void { expect(response.success).to.be.true; expect(response.messageId).to.equal(messageId); expect(response.error).to.be.undefined; } - function checkSendResponseFailure(response: SendResponse, code: string, msg?: string) { + function checkSendResponseFailure(response: SendResponse, code: string, msg?: string): void { expect(response.success).to.be.false; expect(response.messageId).to.be.undefined; expect(response.error).to.have.property('code', code); @@ -1108,13 +1110,13 @@ describe('Messaging', () => { ).should.eventually.be.rejected.and.have.property('code', 'app/invalid-credential'); }); - function checkSendResponseSuccess(response: SendResponse, messageId: string) { + function checkSendResponseSuccess(response: SendResponse, messageId: string): void { expect(response.success).to.be.true; expect(response.messageId).to.equal(messageId); expect(response.error).to.be.undefined; } - function checkSendResponseFailure(response: SendResponse, code: string, msg?: string) { + function checkSendResponseFailure(response: SendResponse, code: string, msg?: string): void { expect(response.success).to.be.false; expect(response.messageId).to.be.undefined; expect(response.error).to.have.property('code', code); @@ -3596,7 +3598,7 @@ describe('Messaging', () => { }); }); - function tokenSubscriptionTests(methodName: string) { + function tokenSubscriptionTests(methodName: string): void { const invalidRegistrationTokensArgumentError = 'Registration token(s) provided to ' + `${methodName}() must be a non-empty string or a non-empty array`; diff --git a/test/unit/project-management/android-app.spec.ts b/test/unit/project-management/android-app.spec.ts index 2fed6622ed..d38c2600b7 100644 --- a/test/unit/project-management/android-app.spec.ts +++ b/test/unit/project-management/android-app.spec.ts @@ -132,7 +132,7 @@ describe('AndroidApp', () => { .should.eventually.be.rejected .and.have.property( 'message', - `getMetadata()\'s responseData.${requiredField} must be a non-empty string. ` + `getMetadata()'s responseData.${requiredField} must be a non-empty string. ` + `Response data: ${JSON.stringify(partialApiResponse, null, 2)}`); }); }); @@ -250,7 +250,7 @@ describe('AndroidApp', () => { .should.eventually.be.rejected .and.have.property( 'message', - `getShaCertificates()\'s responseData.certificates[].${requiredField} must be a ` + `getShaCertificates()'s responseData.certificates[].${requiredField} must be a ` + 'non-empty string. Response data: ' + JSON.stringify(partialApiResponse, null, 2)); }); @@ -357,7 +357,7 @@ describe('AndroidApp', () => { .should.eventually.be.rejected .and.have.property( 'message', - `getConfig()\'s responseData.configFileContents must be a base64 string. ` + `getConfig()'s responseData.configFileContents must be a base64 string. ` + `Response data: ${JSON.stringify(apiResponse, null, 2)}`); }); diff --git a/test/unit/project-management/ios-app.spec.ts b/test/unit/project-management/ios-app.spec.ts index 3f84e3713b..ec300ea554 100644 --- a/test/unit/project-management/ios-app.spec.ts +++ b/test/unit/project-management/ios-app.spec.ts @@ -131,7 +131,7 @@ describe('IosApp', () => { .should.eventually.be.rejected .and.have.property( 'message', - `getMetadata()\'s responseData.${requiredField} must be a non-empty string. ` + `getMetadata()'s responseData.${requiredField} must be a non-empty string. ` + `Response data: ${JSON.stringify(partialApiResponse, null, 2)}`); }); }); @@ -204,7 +204,7 @@ describe('IosApp', () => { .should.eventually.be.rejected .and.have.property( 'message', - `getConfig()\'s responseData.configFileContents must be a base64 string. ` + `getConfig()'s responseData.configFileContents must be a base64 string. ` + `Response data: ${JSON.stringify(apiResponse, null, 2)}`); }); diff --git a/test/unit/project-management/project-management-api-request.spec.ts b/test/unit/project-management/project-management-api-request.spec.ts index 59d91b69f5..f2978b4a34 100644 --- a/test/unit/project-management/project-management-api-request.spec.ts +++ b/test/unit/project-management/project-management-api-request.spec.ts @@ -84,7 +84,7 @@ describe('ProjectManagementRequestHandler', () => { return mockApp.delete(); }); - function testHttpErrors(callback: () => Promise) { + function testHttpErrors(callback: () => Promise): void { const errorCodeMap: any = { 400: 'project-management/invalid-argument', 401: 'project-management/authentication-error', @@ -94,7 +94,7 @@ describe('ProjectManagementRequestHandler', () => { 503: 'project-management/service-unavailable', }; Object.keys(errorCodeMap).forEach((errorCode) => { - if (!errorCodeMap.hasOwnProperty(errorCode)) { + if (!Object.prototype.hasOwnProperty.call(errorCodeMap, errorCode)) { return; } it(`should throw for HTTP ${errorCode} errors`, () => { diff --git a/test/unit/utils.ts b/test/unit/utils.ts index 6f6dac1a1a..12bc260b65 100644 --- a/test/unit/utils.ts +++ b/test/unit/utils.ts @@ -29,7 +29,7 @@ import { HttpError, HttpResponse } from '../../src/utils/api-request'; * @param {object} options The options for the FirebaseApp instance to create. * @return {FirebaseApp} A new FirebaseApp instance with the provided options. */ -export function createAppWithOptions(options: object) { +export function createAppWithOptions(options: object): FirebaseApp { const mockFirebaseNamespaceInternals = new FirebaseNamespace().INTERNAL; return new FirebaseApp(options as FirebaseAppOptions, mocks.appName, mockFirebaseNamespaceInternals); } diff --git a/test/unit/utils/api-request.spec.ts b/test/unit/utils/api-request.spec.ts index 7a04df15a6..3052d01e81 100644 --- a/test/unit/utils/api-request.spec.ts +++ b/test/unit/utils/api-request.spec.ts @@ -66,7 +66,7 @@ function mockRequestWithHttpError( statusCode = 400, responseContentType = 'application/json', response: any = mockErrorResponse, -) { +): nock.Scope { if (responseContentType === 'text/html') { response = mockTextErrorResponse; } @@ -86,7 +86,7 @@ function mockRequestWithHttpError( * * @return {Object} A nock response object. */ -function mockRequestWithError(err: any) { +function mockRequestWithError(err: any): nock.Scope { return nock('https://' + mockHost) .get(mockPath) .replyWithError(err); @@ -346,6 +346,8 @@ describe('HttpClient', () => { mockedRequests.push(scope); const client = new HttpClient(); const httpAgent = new Agent(); + + // eslint-disable-next-line @typescript-eslint/no-var-requires const https = require('https'); transportSpy = sinon.spy(https, 'request'); return client.send({ @@ -1224,6 +1226,8 @@ describe('AuthorizedHttpClient', () => { beforeEach(() => { const options = mockApp.options; options.httpAgent = new Agent(); + + // eslint-disable-next-line @typescript-eslint/no-var-requires const https = require('https'); transportSpy = sinon.spy(https, 'request'); mockAppWithAgent = mocks.appWithOptions(options); diff --git a/test/unit/utils/index.spec.ts b/test/unit/utils/index.spec.ts index 8413a8e979..705afab3a9 100755 --- a/test/unit/utils/index.spec.ts +++ b/test/unit/utils/index.spec.ts @@ -48,7 +48,7 @@ describe('addReadonlyGetter()', () => { expect(() => { obj.foo = false; - }).to.throw(/Cannot assign to read only property \'foo\' of/); + }).to.throw(/Cannot assign to read only property 'foo' of/); }); it('should make the new property enumerable', () => {