diff --git a/functions/@types/README.md b/functions/@types/README.md new file mode 100644 index 00000000..b5ce795f --- /dev/null +++ b/functions/@types/README.md @@ -0,0 +1,7 @@ +This the folder where we put custom type declaration files for libraries that don't come with one. + +File structure must be the same as in `node_modules`: +- folders in this folder must be named with the name of the library (if the library is scoped then there must be a folder tree that matches the scope, e.g. `@google/firebase` gives a `@google` folder with a `firebase` folder inside) +- each library folder must contain a file named `index.d.ts` with the root declaration file + +Please document how the types were determined. There is no need to type more than we need. diff --git a/functions/@types/firebase-tools/index.d.ts b/functions/@types/firebase-tools/index.d.ts new file mode 100644 index 00000000..3972cd93 --- /dev/null +++ b/functions/@types/firebase-tools/index.d.ts @@ -0,0 +1,26 @@ +declare module "firebase-tools" { + export namespace firestore { + // types inferred from https://github.com/firebase/firebase-tools/blob/v5.1.1/commands/firestore-delete.js#L72 + + // overload that deletes only one collection + function _delete(path: string, options?: DeleteOptions): Promise; + + // overload that deletes all collections + function _delete( + path: undefined, + options: { allCollections: true } & DeleteOptions + ): Promise; + + type DeleteOptions = { + project: string; + allCollections?: false; // makes no sense to have this be true if a path is provided + recursive?: boolean; + shallow?: boolean; + yes: true; // makes no sense to have this not be true when calling from code (i.e. not from the CLI) + }; + + // this is required because TypeScript type declarations do not support + // keywords as function names + export { _delete as delete }; + } +} diff --git a/functions/package-lock.json b/functions/package-lock.json index aedc9e7a..628430dd 100644 --- a/functions/package-lock.json +++ b/functions/package-lock.json @@ -4444,14 +4444,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4466,20 +4464,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -4596,8 +4591,7 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -4609,7 +4603,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -4624,7 +4617,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -4736,8 +4728,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -4870,7 +4861,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -6948,11 +6938,6 @@ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" }, - "lodash.partition": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.partition/-/lodash.partition-4.6.0.tgz", - "integrity": "sha1-o45GtzRp4EILDaEhLmbUFL42S6Q=" - }, "lodash.values": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz", diff --git a/functions/package.json b/functions/package.json index 8f6e6b0b..dbc2d2fd 100644 --- a/functions/package.json +++ b/functions/package.json @@ -14,7 +14,6 @@ "firebase-admin": "5.13.1", "firebase-functions": "2.0.2", "firebase-tools": "^5.1.1", - "lodash.partition": "4.6.0", "mailgun-js": "0.20.0", "node-fetch": "2.2.0" }, diff --git a/functions/src/compute-statistics.ts b/functions/src/compute-statistics.ts index 498613d2..db52ca40 100644 --- a/functions/src/compute-statistics.ts +++ b/functions/src/compute-statistics.ts @@ -15,6 +15,7 @@ export const computeStatistics = functions.https.onRequest( if (!computeStatisticsConfigs.enabled) { return; } + const authorizationHeader = req.get("Authorization") || ""; const keyIsCorrect = authorizationHeader === `Bearer ${computeStatisticsConfigs.key}`; @@ -24,7 +25,7 @@ export const computeStatistics = functions.https.onRequest( } await firebaseTools.firestore.delete("stats", { - project: process.env.GCLOUD_PROJECT, + project: config.service_account.project_id, recursive: true, yes: true }); diff --git a/functions/src/exchange-token.ts b/functions/src/exchange-token.ts index 8ddecf6a..9eb82dc2 100644 --- a/functions/src/exchange-token.ts +++ b/functions/src/exchange-token.ts @@ -26,7 +26,7 @@ interface RequestPayload { accessToken?: string; } -const errorResponse = message => ({ error: { message } }); +const errorResponse = (message: string) => ({ error: { message } }); /** * Cannot use functions.https.onCall here because this function is called diff --git a/functions/src/import-employees-from-alibeez.ts b/functions/src/import-employees-from-alibeez.ts index b2f3669f..8bc1012f 100644 --- a/functions/src/import-employees-from-alibeez.ts +++ b/functions/src/import-employees-from-alibeez.ts @@ -1,7 +1,6 @@ import * as firebase from "firebase-admin"; import fetch from "node-fetch"; import { AlibeezConfig } from "./config"; -import partition = require("lodash.partition"); interface AlibeezEmployee { fullName: string; @@ -17,7 +16,7 @@ export interface Employee { agency: string; } -const obfuscateKey = key => { +const obfuscateKey = (key: string) => { if (key) { if (key.length > 8) { return `${key.substr(0, 4)}***`; @@ -29,6 +28,10 @@ const obfuscateKey = key => { } }; +const hasValidEmail = (employee: AlibeezEmployee) => + employee.zenikaEmail && employee.zenikaEmail.endsWith("@zenika.com"); +const hasNoValidEmail = (employee: AlibeezEmployee) => !hasValidEmail(employee); + export const importEmployeesFromAlibeez = async (config: AlibeezConfig) => { const requestRef = await firebase .firestore() @@ -56,14 +59,8 @@ export const importEmployeesFromAlibeez = async (config: AlibeezConfig) => { return; } const employees: AlibeezEmployee[] = await response.json(); - const [employeesWithValidEmail, employeesWithNoValidEmail]: [ - AlibeezEmployee[], - AlibeezEmployee[] - ] = partition( - employees, - employee => - employee.zenikaEmail && employee.zenikaEmail.endsWith("@zenika.com") - ); + const employeesWithValidEmail = employees.filter(hasValidEmail); + const employeesWithNoValidEmail = employees.filter(hasNoValidEmail); employeesWithNoValidEmail.forEach(employee => { console.info("employee with no valid email: " + employee.fullName); }); diff --git a/functions/src/save-ticks.ts b/functions/src/save-ticks.ts index e1b3ff6a..bad3bdcd 100644 --- a/functions/src/save-ticks.ts +++ b/functions/src/save-ticks.ts @@ -6,7 +6,7 @@ export interface Tick { emittedAt: firestore.Timestamp; } -const pubSubToFirestoreFunction = topic => +const pubSubToFirestoreFunction = (topic: string) => functions.pubsub.topic(topic).onPublish(event => firestore() .collection(topic) diff --git a/functions/tsconfig.json b/functions/tsconfig.json index 0603cdd4..732abcd1 100644 --- a/functions/tsconfig.json +++ b/functions/tsconfig.json @@ -7,10 +7,7 @@ "sourceMap": true, "target": "es6", "strict": true, - // noImplicitAny is not compatible with firebase-functions@^1.0.0 - // if npm run build succeeds without this line then it can be safely removed - // see also: https://github.com/firebase/firebase-functions/issues/213 - "noImplicitAny": false + "typeRoots": ["@types"] }, "compileOnSave": true, "include": ["src"]