From b6c75046d6575fffe0e5662f0e554ebb8c9d9254 Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Mon, 22 Aug 2022 17:13:15 -0700 Subject: [PATCH 1/2] Update eslint setup to capture more files! --- .eslintignore | 18 +++++++++--------- tsconfig.json | 6 +++++- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/.eslintignore b/.eslintignore index c939c9a1b..72d1288b0 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,11 +1,11 @@ -coverage -dev lib +dev node_modules -docgen -v1 -v2 -logger -dist -spec/fixtures -scripts/**/*.js +/coverage/ +/docgen/ +/v1/ +/v2/ +/logger/ +/dist/ +/spec/fixtures +/scripts/**/*.js diff --git a/tsconfig.json b/tsconfig.json index d32c576a3..8049f1d64 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,5 +4,9 @@ "sourceMap": true }, "extends": "./tsconfig.release.json", - "include": ["**/*.ts", ".eslintrc.js"] + "include": [ + "**/*.ts", + ".eslintrc.js", + "integration_test/**/*" + ] } From 2cc54d1e8f15e96f512c1efb6526f39fe804c3c1 Mon Sep 17 00:00:00 2001 From: Daniel Young Lee Date: Mon, 22 Aug 2022 17:28:56 -0700 Subject: [PATCH 2/2] Fix another set of eslint issues. --- .../functions/src/v1/auth-tests.ts | 68 +- .../functions/src/v1/database-tests.ts | 47 +- .../functions/src/v1/firestore-tests.ts | 30 +- .../functions/src/v1/https-tests.ts | 14 +- integration_test/functions/src/v1/index.ts | 16 +- .../functions/src/v1/pubsub-tests.ts | 62 +- .../functions/src/v1/remoteConfig-tests.ts | 39 +- .../functions/src/v1/storage-tests.ts | 20 +- .../functions/src/v1/testLab-tests.ts | 18 +- .../functions/src/v1/testLab-utils.ts | 38 +- .../functions/src/v2/https-tests.ts | 12 +- integration_test/functions/src/v2/index.ts | 6 +- spec/v1/cloud-functions.spec.ts | 239 +++--- spec/v1/config.spec.ts | 42 +- spec/v1/function-builder.spec.ts | 266 ++++--- spec/v1/providers/analytics.spec.input.ts | 64 +- spec/v1/providers/analytics.spec.ts | 244 +++---- spec/v1/providers/auth.spec.ts | 191 +++-- spec/v1/providers/database.spec.ts | 680 ++++++++---------- spec/v1/providers/firestore.spec.ts | 432 +++++------ spec/v1/providers/https.spec.ts | 119 ++- spec/v1/providers/pubsub.spec.ts | 296 ++++---- spec/v1/providers/remoteConfig.spec.ts | 106 ++- spec/v1/providers/storage.spec.ts | 446 +++++------- spec/v1/providers/tasks.spec.ts | 56 +- spec/v1/providers/testLab.spec.ts | 190 +++-- spec/v1/utils.spec.ts | 22 +- spec/v2/params.spec.ts | 146 ++-- spec/v2/providers/alerts/alerts.spec.ts | 81 +-- .../providers/alerts/appDistribution.spec.ts | 93 +-- spec/v2/providers/alerts/billing.spec.ts | 58 +- spec/v2/providers/alerts/crashlytics.spec.ts | 95 ++- spec/v2/providers/database.spec.ts | 381 +++++----- spec/v2/providers/eventarc.spec.ts | 72 +- spec/v2/providers/fixtures.ts | 40 +- spec/v2/providers/https.spec.ts | 237 +++--- spec/v2/providers/identity.spec.ts | 136 ++-- spec/v2/providers/pubsub.spec.ts | 109 +-- spec/v2/providers/storage.spec.ts | 245 +++---- spec/v2/providers/tasks.spec.ts | 62 +- src/logger/common.ts | 18 +- src/logger/compat.ts | 20 +- src/logger/index.ts | 46 +- src/v1/cloud-functions.ts | 111 ++- src/v1/config.ts | 19 +- src/v1/function-builder.ts | 167 ++--- src/v1/function-configuration.ts | 80 +-- src/v1/handler-builder.ts | 42 +- src/v1/index.ts | 34 +- src/v1/providers/analytics.ts | 145 ++-- src/v1/providers/auth.ts | 54 +- src/v1/providers/database.ts | 70 +- src/v1/providers/firestore.ts | 99 +-- src/v1/providers/https.ts | 23 +- src/v1/providers/pubsub.ts | 56 +- src/v1/providers/remoteConfig.ts | 36 +- src/v1/providers/storage.ts | 70 +- src/v1/providers/tasks.ts | 37 +- src/v1/providers/testLab.ts | 107 ++- src/v2/core.ts | 8 +- src/v2/index.ts | 36 +- src/v2/options.ts | 112 ++- src/v2/params/index.ts | 32 +- src/v2/params/types.ts | 55 +- src/v2/providers/alerts/alerts.ts | 40 +- src/v2/providers/alerts/appDistribution.ts | 65 +- src/v2/providers/alerts/billing.ts | 44 +- src/v2/providers/alerts/crashlytics.ts | 140 ++-- src/v2/providers/alerts/index.ts | 8 +- src/v2/providers/database.ts | 134 ++-- src/v2/providers/eventarc.ts | 26 +- src/v2/providers/https.ts | 68 +- src/v2/providers/identity.ts | 76 +- src/v2/providers/pubsub.ts | 30 +- src/v2/providers/storage.ts | 68 +- src/v2/providers/tasks.ts | 40 +- 76 files changed, 3353 insertions(+), 4381 deletions(-) diff --git a/integration_test/functions/src/v1/auth-tests.ts b/integration_test/functions/src/v1/auth-tests.ts index e6daf5162..5d1b6188a 100644 --- a/integration_test/functions/src/v1/auth-tests.ts +++ b/integration_test/functions/src/v1/auth-tests.ts @@ -1,7 +1,7 @@ -import * as admin from 'firebase-admin'; -import * as functions from 'firebase-functions'; -import { REGION } from '../region'; -import { expectEq, TestSuite } from '../testing'; +import * as admin from "firebase-admin"; +import * as functions from "firebase-functions"; +import { REGION } from "../region"; +import { expectEq, TestSuite } from "../testing"; import UserMetadata = admin.auth.UserRecord; export const createUserTests: any = functions @@ -11,35 +11,26 @@ export const createUserTests: any = functions const testId: string = u.displayName; functions.logger.info(`testId is ${testId}`); - return new TestSuite('auth user onCreate') - .it('should have a project as resource', (user, context) => - expectEq( - context.resource.name, - `projects/${process.env.GCLOUD_PROJECT}` - ) + return new TestSuite("auth user onCreate") + .it("should have a project as resource", (user, context) => + expectEq(context.resource.name, `projects/${process.env.GCLOUD_PROJECT}`) ) - .it('should not have a path', (user, context) => - expectEq((context as any).path, undefined) - ) + .it("should not have a path", (user, context) => expectEq((context as any).path, undefined)) - .it('should have the correct eventType', (user, context) => - expectEq(context.eventType, 'google.firebase.auth.user.create') + .it("should have the correct eventType", (user, context) => + expectEq(context.eventType, "google.firebase.auth.user.create") ) - .it('should have an eventId', (user, context) => context.eventId) + .it("should have an eventId", (user, context) => context.eventId) - .it('should have a timestamp', (user, context) => context.timestamp) + .it("should have a timestamp", (user, context) => context.timestamp) - .it('should not have auth', (user, context) => - expectEq((context as any).auth, undefined) - ) + .it("should not have auth", (user, context) => expectEq((context as any).auth, undefined)) - .it('should not have action', (user, context) => - expectEq((context as any).action, undefined) - ) + .it("should not have action", (user, context) => expectEq((context as any).action, undefined)) - .it('should have properly defined meta', (user, context) => user.metadata) + .it("should have properly defined meta", (user) => user.metadata) .run(testId, u, c); }); @@ -51,33 +42,24 @@ export const deleteUserTests: any = functions const testId: string = u.displayName; functions.logger.info(`testId is ${testId}`); - return new TestSuite('auth user onDelete') - .it('should have a project as resource', (user, context) => - expectEq( - context.resource.name, - `projects/${process.env.GCLOUD_PROJECT}` - ) + return new TestSuite("auth user onDelete") + .it("should have a project as resource", (user, context) => + expectEq(context.resource.name, `projects/${process.env.GCLOUD_PROJECT}`) ) - .it('should not have a path', (user, context) => - expectEq((context as any).path, undefined) - ) + .it("should not have a path", (user, context) => expectEq((context as any).path, undefined)) - .it('should have the correct eventType', (user, context) => - expectEq(context.eventType, 'google.firebase.auth.user.delete') + .it("should have the correct eventType", (user, context) => + expectEq(context.eventType, "google.firebase.auth.user.delete") ) - .it('should have an eventId', (user, context) => context.eventId) + .it("should have an eventId", (user, context) => context.eventId) - .it('should have a timestamp', (user, context) => context.timestamp) + .it("should have a timestamp", (user, context) => context.timestamp) - .it('should not have auth', (user, context) => - expectEq((context as any).auth, undefined) - ) + .it("should not have auth", (user, context) => expectEq((context as any).auth, undefined)) - .it('should not have action', (user, context) => - expectEq((context as any).action, undefined) - ) + .it("should not have action", (user, context) => expectEq((context as any).action, undefined)) .run(testId, u, c); }); diff --git a/integration_test/functions/src/v1/database-tests.ts b/integration_test/functions/src/v1/database-tests.ts index fe3e29f17..df9d3cdd2 100644 --- a/integration_test/functions/src/v1/database-tests.ts +++ b/integration_test/functions/src/v1/database-tests.ts @@ -1,39 +1,34 @@ -import * as admin from 'firebase-admin'; -import * as functions from 'firebase-functions'; -import { REGION } from '../region'; -import { expectEq, expectMatches, TestSuite } from '../testing'; +import * as admin from "firebase-admin"; +import * as functions from "firebase-functions"; +import { REGION } from "../region"; +import { expectEq, expectMatches, TestSuite } from "../testing"; import DataSnapshot = admin.database.DataSnapshot; -const testIdFieldName = 'testId'; +const testIdFieldName = "testId"; export const databaseTests: any = functions .region(REGION) - .database.ref('dbTests/{testId}/start') + .database.ref("dbTests/{testId}/start") .onWrite((ch, ctx) => { if (ch.after.val() === null) { functions.logger.info( - 'Event for ' + - ctx.params[testIdFieldName] + - ' is null; presuming data cleanup, so skipping.' + `Event for ${ctx.params[testIdFieldName]} is null; presuming data cleanup, so skipping.` ); return; } - return new TestSuite>('database ref onWrite') + return new TestSuite>("database ref onWrite") - .it( - 'should not have event.app', - (change, context) => !(context as any).app - ) + .it("should not have event.app", (change, context) => !(context as any).app) - .it('should give refs access to admin data', (change) => + .it("should give refs access to admin data", (change) => change.after.ref.parent - .child('adminOnly') + .child("adminOnly") .update({ allowed: 1 }) .then(() => true) ) - .it('should have a correct ref url', (change) => { + .it("should have a correct ref url", (change) => { const url = change.after.ref.toString(); return Promise.resolve() .then(() => { @@ -49,7 +44,7 @@ export const databaseTests: any = functions }); }) - .it('should have refs resources', (change, context) => + .it("should have refs resources", (change, context) => expectMatches( context.resource.name, new RegExp( @@ -58,25 +53,23 @@ export const databaseTests: any = functions ) ) - .it('should not include path', (change, context) => + .it("should not include path", (change, context) => expectEq((context as any).path, undefined) ) - .it('should have the right eventType', (change, context) => - expectEq(context.eventType, 'google.firebase.database.ref.write') + .it("should have the right eventType", (change, context) => + expectEq(context.eventType, "google.firebase.database.ref.write") ) - .it('should have eventId', (change, context) => context.eventId) + .it("should have eventId", (change, context) => context.eventId) - .it('should have timestamp', (change, context) => context.timestamp) + .it("should have timestamp", (change, context) => context.timestamp) - .it('should not have action', (change, context) => + .it("should not have action", (change, context) => expectEq((context as any).action, undefined) ) - .it('should have admin authType', (change, context) => - expectEq(context.authType, 'ADMIN') - ) + .it("should have admin authType", (change, context) => expectEq(context.authType, "ADMIN")) .run(ctx.params[testIdFieldName], ch, ctx); }); diff --git a/integration_test/functions/src/v1/firestore-tests.ts b/integration_test/functions/src/v1/firestore-tests.ts index 51a93d021..b986ca06a 100644 --- a/integration_test/functions/src/v1/firestore-tests.ts +++ b/integration_test/functions/src/v1/firestore-tests.ts @@ -1,42 +1,42 @@ -import * as admin from 'firebase-admin'; -import * as functions from 'firebase-functions'; -import { REGION } from '../region'; -import { expectDeepEq, expectEq, TestSuite } from '../testing'; +import * as admin from "firebase-admin"; +import * as functions from "firebase-functions"; +import { REGION } from "../region"; +import { expectDeepEq, expectEq, TestSuite } from "../testing"; import DocumentSnapshot = admin.firestore.DocumentSnapshot; -const testIdFieldName = 'documentId'; +const testIdFieldName = "documentId"; export const firestoreTests: any = functions .runWith({ timeoutSeconds: 540, }) .region(REGION) - .firestore.document('tests/{documentId}') + .firestore.document("tests/{documentId}") .onCreate((s, c) => { - return new TestSuite('firestore document onWrite') + return new TestSuite("firestore document onWrite") - .it('should not have event.app', (snap, context) => !(context as any).app) + .it("should not have event.app", (snap, context) => !(context as any).app) - .it('should give refs write access', (snap) => + .it("should give refs write access", (snap) => snap.ref.set({ allowed: 1 }, { merge: true }).then(() => true) ) - .it('should have well-formatted resource', (snap, context) => + .it("should have well-formatted resource", (snap, context) => expectEq( context.resource.name, `projects/${process.env.GCLOUD_PROJECT}/databases/(default)/documents/tests/${context.params.documentId}` ) ) - .it('should have the right eventType', (snap, context) => - expectEq(context.eventType, 'google.firestore.document.create') + .it("should have the right eventType", (snap, context) => + expectEq(context.eventType, "google.firestore.document.create") ) - .it('should have eventId', (snap, context) => context.eventId) + .it("should have eventId", (snap, context) => context.eventId) - .it('should have timestamp', (snap, context) => context.timestamp) + .it("should have timestamp", (snap, context) => context.timestamp) - .it('should have the correct data', (snap, context) => + .it("should have the correct data", (snap, context) => expectDeepEq(snap.data(), { test: context.params.documentId }) ) diff --git a/integration_test/functions/src/v1/https-tests.ts b/integration_test/functions/src/v1/https-tests.ts index bce05f341..5a74a1903 100644 --- a/integration_test/functions/src/v1/https-tests.ts +++ b/integration_test/functions/src/v1/https-tests.ts @@ -1,14 +1,12 @@ -import * as functions from 'firebase-functions'; -import { REGION } from '../region'; -import { expectEq, TestSuite } from '../testing'; +import * as functions from "firebase-functions"; +import { REGION } from "../region"; +import { expectEq, TestSuite } from "../testing"; export const callableTests: any = functions - .runWith({ invoker: 'private' }) + .runWith({ invoker: "private" }) .region(REGION) .https.onCall((d) => { - return new TestSuite('https onCall') - .it('should have the correct data', (data: any) => - expectEq(data?.foo, 'bar') - ) + return new TestSuite("https onCall") + .it("should have the correct data", (data: any) => expectEq(data?.foo, "bar")) .run(d.testId, d); }); diff --git a/integration_test/functions/src/v1/index.ts b/integration_test/functions/src/v1/index.ts index 6e6717b15..7c0f4dd84 100644 --- a/integration_test/functions/src/v1/index.ts +++ b/integration_test/functions/src/v1/index.ts @@ -1,8 +1,8 @@ -export * from './pubsub-tests'; -export * from './database-tests'; -export * from './auth-tests'; -export * from './firestore-tests'; -export * from './https-tests'; -export * from './remoteConfig-tests'; -export * from './storage-tests'; -export * from './testLab-tests'; +export * from "./pubsub-tests"; +export * from "./database-tests"; +export * from "./auth-tests"; +export * from "./firestore-tests"; +export * from "./https-tests"; +export * from "./remoteConfig-tests"; +export * from "./storage-tests"; +export * from "./testLab-tests"; diff --git a/integration_test/functions/src/v1/pubsub-tests.ts b/integration_test/functions/src/v1/pubsub-tests.ts index 515708e07..152ad7b6a 100644 --- a/integration_test/functions/src/v1/pubsub-tests.ts +++ b/integration_test/functions/src/v1/pubsub-tests.ts @@ -1,14 +1,14 @@ -import * as admin from 'firebase-admin'; -import * as functions from 'firebase-functions'; -import { REGION } from '../region'; -import { evaluate, expectEq, success, TestSuite } from '../testing'; +import * as admin from "firebase-admin"; +import * as functions from "firebase-functions"; +import { REGION } from "../region"; +import { evaluate, expectEq, success, TestSuite } from "../testing"; import PubsubMessage = functions.pubsub.Message; // TODO(inlined) use multiple queues to run inline. // Expected message data: {"hello": "world"} export const pubsubTests: any = functions .region(REGION) - .pubsub.topic('pubsubTests') + .pubsub.topic("pubsubTests") .onPublish((m, c) => { let testId: string; try { @@ -17,45 +17,37 @@ export const pubsubTests: any = functions /* Ignored. Covered in another test case that `event.data.json` works. */ } - return new TestSuite('pubsub onPublish') - .it('should have a topic as resource', (message, context) => - expectEq( - context.resource.name, - `projects/${process.env.GCLOUD_PROJECT}/topics/pubsubTests` - ) + return new TestSuite("pubsub onPublish") + .it("should have a topic as resource", (message, context) => + expectEq(context.resource.name, `projects/${process.env.GCLOUD_PROJECT}/topics/pubsubTests`) ) - .it('should not have a path', (message, context) => + .it("should not have a path", (message, context) => expectEq((context as any).path, undefined) ) - .it('should have the correct eventType', (message, context) => - expectEq(context.eventType, 'google.pubsub.topic.publish') + .it("should have the correct eventType", (message, context) => + expectEq(context.eventType, "google.pubsub.topic.publish") ) - .it('should have an eventId', (message, context) => context.eventId) + .it("should have an eventId", (message, context) => context.eventId) - .it('should have a timestamp', (message, context) => context.timestamp) + .it("should have a timestamp", (message, context) => context.timestamp) - .it('should not have auth', (message, context) => - expectEq((context as any).auth, undefined) - ) + .it("should not have auth", (message, context) => expectEq((context as any).auth, undefined)) - .it('should not have action', (message, context) => + .it("should not have action", (message, context) => expectEq((context as any).action, undefined) ) - .it('should have pubsub data', (message) => { - const decoded = new Buffer(message.data, 'base64').toString(); + .it("should have pubsub data", (message) => { + const decoded = new Buffer(message.data, "base64").toString(); const parsed = JSON.parse(decoded); - return evaluate( - parsed.hasOwnProperty('testId'), - 'Raw data was: ' + message.data - ); + return evaluate(parsed.hasOwnProperty("testId"), `Raw data was + ${message.data}`); }) - .it('should decode JSON payloads with the json helper', (message) => - evaluate(message.json.hasOwnProperty('testId'), message.json) + .it("should decode JSON payloads with the json helper", (message) => + evaluate(message.json.hasOwnProperty("testId"), message.json) ) .run(testId, m, c); @@ -63,17 +55,13 @@ export const pubsubTests: any = functions export const schedule: any = functions .region(REGION) - .pubsub.schedule('every 10 hours') // This is a dummy schedule, since we need to put a valid one in. + .pubsub.schedule("every 10 hours") // This is a dummy schedule, since we need to put a valid one in. // For the test, the job is triggered by the jobs:run api - .onRun(async (context) => { + .onRun(async () => { const db = admin.database(); - const snap = await db - .ref('testRuns') - .orderByChild('timestamp') - .limitToLast(1) - .once('value'); + const snap = await db.ref("testRuns").orderByChild("timestamp").limitToLast(1).once("value"); const testId = Object.keys(snap.val())[0]; - return new TestSuite('pubsub scheduleOnRun') - .it('should trigger when the scheduler fires', () => success()) + return new TestSuite("pubsub scheduleOnRun") + .it("should trigger when the scheduler fires", () => success()) .run(testId, null); }); diff --git a/integration_test/functions/src/v1/remoteConfig-tests.ts b/integration_test/functions/src/v1/remoteConfig-tests.ts index 47e70461b..416621774 100644 --- a/integration_test/functions/src/v1/remoteConfig-tests.ts +++ b/integration_test/functions/src/v1/remoteConfig-tests.ts @@ -1,30 +1,23 @@ -import * as functions from 'firebase-functions'; -import { REGION } from '../region'; -import { expectEq, TestSuite } from '../testing'; +import * as functions from "firebase-functions"; +import { REGION } from "../region"; +import { expectEq, TestSuite } from "../testing"; import TemplateVersion = functions.remoteConfig.TemplateVersion; -export const remoteConfigTests: any = functions - .region(REGION) - .remoteConfig.onUpdate((v, c) => { - return new TestSuite('remoteConfig onUpdate') - .it('should have a project as resource', (version, context) => - expectEq( - context.resource.name, - `projects/${process.env.GCLOUD_PROJECT}` - ) - ) +export const remoteConfigTests: any = functions.region(REGION).remoteConfig.onUpdate((v, c) => { + return new TestSuite("remoteConfig onUpdate") + .it("should have a project as resource", (version, context) => + expectEq(context.resource.name, `projects/${process.env.GCLOUD_PROJECT}`) + ) - .it('should have the correct eventType', (version, context) => - expectEq(context.eventType, 'google.firebase.remoteconfig.update') - ) + .it("should have the correct eventType", (version, context) => + expectEq(context.eventType, "google.firebase.remoteconfig.update") + ) - .it('should have an eventId', (version, context) => context.eventId) + .it("should have an eventId", (version, context) => context.eventId) - .it('should have a timestamp', (version, context) => context.timestamp) + .it("should have a timestamp", (version, context) => context.timestamp) - .it('should not have auth', (version, context) => - expectEq((context as any).auth, undefined) - ) + .it("should not have auth", (version, context) => expectEq((context as any).auth, undefined)) - .run(v.description, v, c); - }); + .run(v.description, v, c); +}); diff --git a/integration_test/functions/src/v1/storage-tests.ts b/integration_test/functions/src/v1/storage-tests.ts index 51b947293..6819c7a2a 100644 --- a/integration_test/functions/src/v1/storage-tests.ts +++ b/integration_test/functions/src/v1/storage-tests.ts @@ -1,6 +1,6 @@ -import * as functions from 'firebase-functions'; -import { REGION } from '../region'; -import { expectEq, TestSuite } from '../testing'; +import * as functions from "firebase-functions"; +import { REGION } from "../region"; +import { expectEq, TestSuite } from "../testing"; import ObjectMetadata = functions.storage.ObjectMetadata; export const storageTests: any = functions @@ -11,18 +11,18 @@ export const storageTests: any = functions .storage.bucket() .object() .onFinalize((s, c) => { - const testId = s.name.split('.')[0]; - return new TestSuite('storage object finalize') + const testId = s.name.split(".")[0]; + return new TestSuite("storage object finalize") - .it('should not have event.app', (data, context) => !(context as any).app) + .it("should not have event.app", (data, context) => !(context as any).app) - .it('should have the right eventType', (snap, context) => - expectEq(context.eventType, 'google.storage.object.finalize') + .it("should have the right eventType", (snap, context) => + expectEq(context.eventType, "google.storage.object.finalize") ) - .it('should have eventId', (snap, context) => context.eventId) + .it("should have eventId", (snap, context) => context.eventId) - .it('should have timestamp', (snap, context) => context.timestamp) + .it("should have timestamp", (snap, context) => context.timestamp) .run(testId, s, c); }); diff --git a/integration_test/functions/src/v1/testLab-tests.ts b/integration_test/functions/src/v1/testLab-tests.ts index 8e1986ce0..242cd21f6 100644 --- a/integration_test/functions/src/v1/testLab-tests.ts +++ b/integration_test/functions/src/v1/testLab-tests.ts @@ -1,6 +1,6 @@ -import * as functions from 'firebase-functions'; -import { REGION } from '../region'; -import { expectEq, TestSuite } from '../testing'; +import * as functions from "firebase-functions"; +import { REGION } from "../region"; +import { expectEq, TestSuite } from "../testing"; import TestMatrix = functions.testLab.TestMatrix; export const testLabTests: any = functions @@ -10,16 +10,14 @@ export const testLabTests: any = functions .region(REGION) .testLab.testMatrix() .onComplete((matrix, context) => { - return new TestSuite('test matrix complete') - .it('should have eventId', (snap, context) => context.eventId) + return new TestSuite("test matrix complete") + .it("should have eventId", (snap, context) => context.eventId) - .it('should have right eventType', (_, context) => - expectEq(context.eventType, 'google.testing.testMatrix.complete') + .it("should have right eventType", (_, context) => + expectEq(context.eventType, "google.testing.testMatrix.complete") ) - .it("should be in state 'INVALID'", (matrix, _) => - expectEq(matrix.state, 'INVALID') - ) + .it("should be in state 'INVALID'", (matrix) => expectEq(matrix.state, "INVALID")) .run(matrix?.clientInfo?.details?.testId, matrix, context); }); diff --git a/integration_test/functions/src/v1/testLab-utils.ts b/integration_test/functions/src/v1/testLab-utils.ts index 870c9b8ec..7ba32e112 100644 --- a/integration_test/functions/src/v1/testLab-utils.ts +++ b/integration_test/functions/src/v1/testLab-utils.ts @@ -1,5 +1,5 @@ -import * as admin from 'firebase-admin'; -import fetch from 'node-fetch'; +import * as admin from "firebase-admin"; +import fetch from "node-fetch"; interface AndroidDevice { androidModelId: string; @@ -8,7 +8,7 @@ interface AndroidDevice { orientation: string; } -const TESTING_API_SERVICE_NAME = 'testing.googleapis.com'; +const TESTING_API_SERVICE_NAME = "testing.googleapis.com"; /** * Creates a new TestMatrix in Test Lab which is expected to be rejected as @@ -18,11 +18,7 @@ const TESTING_API_SERVICE_NAME = 'testing.googleapis.com'; * @param testId Test id which will be encoded in client info details * @param accessToken accessToken to attach to requested for authentication */ -export async function startTestRun( - projectId: string, - testId: string, - accessToken: string -) { +export async function startTestRun(projectId: string, testId: string, accessToken: string) { const device = await fetchDefaultDevice(accessToken); return await createTestMatrix(accessToken, projectId, testId, device); } @@ -32,8 +28,8 @@ async function fetchDefaultDevice(accessToken: string): Promise { `https://${TESTING_API_SERVICE_NAME}/v1/testEnvironmentCatalog/ANDROID`, { headers: { - Authorization: 'Bearer ' + accessToken, - 'Content-Type': 'application/json', + Authorization: "Bearer " + accessToken, + "Content-Type": "application/json", }, } ); @@ -45,13 +41,13 @@ async function fetchDefaultDevice(accessToken: string): Promise { const defaultModels = models.filter( (m) => m.tags !== undefined && - m.tags.indexOf('default') > -1 && + m.tags.indexOf("default") > -1 && m.supportedVersionIds !== undefined && m.supportedVersionIds.length > 0 ); if (defaultModels.length === 0) { - throw new Error('No default device found'); + throw new Error("No default device found"); } const model = defaultModels[0]; @@ -60,8 +56,8 @@ async function fetchDefaultDevice(accessToken: string): Promise { return { androidModelId: model.id, androidVersionId: versions[versions.length - 1], - locale: 'en', - orientation: 'portrait', + locale: "en", + orientation: "portrait", } as AndroidDevice; } @@ -76,7 +72,7 @@ async function createTestMatrix( testSpecification: { androidRoboTest: { appApk: { - gcsPath: 'gs://path/to/non-existing-app.apk', + gcsPath: "gs://path/to/non-existing-app.apk", }, }, }, @@ -87,13 +83,13 @@ async function createTestMatrix( }, resultStorage: { googleCloudStorage: { - gcsPath: 'gs://' + admin.storage().bucket().name, + gcsPath: "gs://" + admin.storage().bucket().name, }, }, clientInfo: { - name: 'CloudFunctionsSDKIntegrationTest', + name: "CloudFunctionsSDKIntegrationTest", clientInfoDetails: { - key: 'testId', + key: "testId", value: testId, }, }, @@ -101,10 +97,10 @@ async function createTestMatrix( const resp = await fetch( `https://${TESTING_API_SERVICE_NAME}/v1/projects/${projectId}/testMatrices`, { - method: 'POST', + method: "POST", headers: { - Authorization: 'Bearer ' + accessToken, - 'Content-Type': 'application/json', + Authorization: "Bearer " + accessToken, + "Content-Type": "application/json", }, body: JSON.stringify(body), } diff --git a/integration_test/functions/src/v2/https-tests.ts b/integration_test/functions/src/v2/https-tests.ts index 448464ef0..b787ac602 100644 --- a/integration_test/functions/src/v2/https-tests.ts +++ b/integration_test/functions/src/v2/https-tests.ts @@ -1,10 +1,8 @@ -import { onCall } from 'firebase-functions/v2/https'; -import { expectEq, TestSuite } from '../testing'; +import { onCall } from "firebase-functions/v2/https"; +import { expectEq, TestSuite } from "../testing"; -export const callabletests = onCall({ invoker: 'private' }, (req) => { - return new TestSuite('v2 https onCall') - .it('should have the correct data', (data: any) => - expectEq(data?.foo, 'bar') - ) +export const callabletests = onCall({ invoker: "private" }, (req) => { + return new TestSuite("v2 https onCall") + .it("should have the correct data", (data: any) => expectEq(data?.foo, "bar")) .run(req.data.testId, req.data); }); diff --git a/integration_test/functions/src/v2/index.ts b/integration_test/functions/src/v2/index.ts index def01bfbb..9e3658168 100644 --- a/integration_test/functions/src/v2/index.ts +++ b/integration_test/functions/src/v2/index.ts @@ -1,5 +1,5 @@ -import { setGlobalOptions } from 'firebase-functions/v2'; -import { REGION } from '../region'; +import { setGlobalOptions } from "firebase-functions/v2"; +import { REGION } from "../region"; setGlobalOptions({ region: REGION }); -export * from './https-tests'; +export * from "./https-tests"; diff --git a/spec/v1/cloud-functions.spec.ts b/spec/v1/cloud-functions.spec.ts index f220df90a..3b228561c 100644 --- a/spec/v1/cloud-functions.spec.ts +++ b/spec/v1/cloud-functions.spec.ts @@ -20,40 +20,35 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; +import { expect } from "chai"; -import { - Event, - EventContext, - makeCloudFunction, - MakeCloudFunctionArgs, -} from '../../src/v1'; +import { Event, EventContext, makeCloudFunction, MakeCloudFunctionArgs } from "../../src/v1"; -describe('makeCloudFunction', () => { +describe("makeCloudFunction", () => { const cloudFunctionArgs: MakeCloudFunctionArgs = { - provider: 'mock.provider', - eventType: 'mock.event', - service: 'service', - triggerResource: () => 'resource', + provider: "mock.provider", + eventType: "mock.event", + service: "service", + triggerResource: () => "resource", handler: () => null, - legacyEventType: 'providers/provider/eventTypes/event', + legacyEventType: "providers/provider/eventTypes/event", }; - it('should put a __endpoint on the returned CloudFunction', () => { + it("should put a __endpoint on the returned CloudFunction", () => { const cf = makeCloudFunction({ - provider: 'mock.provider', - eventType: 'mock.event', - service: 'service', - triggerResource: () => 'resource', + provider: "mock.provider", + eventType: "mock.event", + service: "service", + triggerResource: () => "resource", handler: () => null, }); expect(cf.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", eventTrigger: { - eventType: 'mock.provider.mock.event', + eventType: "mock.provider.mock.event", eventFilters: { - resource: 'resource', + resource: "resource", }, retry: false, }, @@ -61,15 +56,15 @@ describe('makeCloudFunction', () => { }); }); - it('should have legacy event type in __endpoint if provided', () => { + it("should have legacy event type in __endpoint if provided", () => { const cf = makeCloudFunction(cloudFunctionArgs); expect(cf.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", eventTrigger: { - eventType: 'providers/provider/eventTypes/event', + eventType: "providers/provider/eventTypes/event", eventFilters: { - resource: 'resource', + resource: "resource", }, retry: false, }, @@ -77,56 +72,56 @@ describe('makeCloudFunction', () => { }); }); - it('should include converted options in __endpoint', () => { + it("should include converted options in __endpoint", () => { const cf = makeCloudFunction({ - provider: 'mock.provider', - eventType: 'mock.event', - service: 'service', - triggerResource: () => 'resource', + provider: "mock.provider", + eventType: "mock.event", + service: "service", + triggerResource: () => "resource", handler: () => null, options: { timeoutSeconds: 10, - regions: ['us-central1'], - memory: '128MB', - serviceAccount: 'foo@google.com', - secrets: ['MY_SECRET'], + regions: ["us-central1"], + memory: "128MB", + serviceAccount: "foo@google.com", + secrets: ["MY_SECRET"], }, }); expect(cf.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", timeoutSeconds: 10, - region: ['us-central1'], + region: ["us-central1"], availableMemoryMb: 128, - serviceAccountEmail: 'foo@google.com', + serviceAccountEmail: "foo@google.com", eventTrigger: { - eventType: 'mock.provider.mock.event', + eventType: "mock.provider.mock.event", eventFilters: { - resource: 'resource', + resource: "resource", }, retry: false, }, - secretEnvironmentVariables: [{ key: 'MY_SECRET' }], + secretEnvironmentVariables: [{ key: "MY_SECRET" }], labels: {}, }); }); - it('should set retry given failure policy in __endpoint', () => { + it("should set retry given failure policy in __endpoint", () => { const cf = makeCloudFunction({ - provider: 'mock.provider', - eventType: 'mock.event', - service: 'service', - triggerResource: () => 'resource', + provider: "mock.provider", + eventType: "mock.event", + service: "service", + triggerResource: () => "resource", handler: () => null, options: { failurePolicy: { retry: {} } }, }); expect(cf.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", eventTrigger: { - eventType: 'mock.provider.mock.event', + eventType: "mock.provider.mock.event", eventFilters: { - resource: 'resource', + resource: "resource", }, retry: true, }, @@ -134,30 +129,30 @@ describe('makeCloudFunction', () => { }); }); - it('should setup a scheduleTrigger in __endpoint given a schedule', () => { + it("should setup a scheduleTrigger in __endpoint given a schedule", () => { const schedule = { - schedule: 'every 5 minutes', + schedule: "every 5 minutes", retryConfig: { retryCount: 3 }, - timeZone: 'America/New_York', + timeZone: "America/New_York", }; const cf = makeCloudFunction({ - provider: 'mock.provider', - eventType: 'mock.event', - service: 'service', - triggerResource: () => 'resource', + provider: "mock.provider", + eventType: "mock.event", + service: "service", + triggerResource: () => "resource", handler: () => null, options: { schedule, }, }); expect(cf.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", scheduleTrigger: schedule, labels: {}, }); }); - it('should construct the right context for event', () => { + it("should construct the right context for event", () => { const args: any = { ...cloudFunctionArgs, handler: (data: any, context: EventContext) => context, @@ -165,30 +160,30 @@ describe('makeCloudFunction', () => { const cf = makeCloudFunction(args); const test: Event = { context: { - eventId: '00000', - timestamp: '2016-11-04T21:29:03.496Z', - eventType: 'provider.event', + eventId: "00000", + timestamp: "2016-11-04T21:29:03.496Z", + eventType: "provider.event", resource: { - service: 'provider', - name: 'resource', + service: "provider", + name: "resource", }, }, - data: 'data', + data: "data", }; return expect(cf(test.data, test.context)).to.eventually.deep.equal({ - eventId: '00000', - timestamp: '2016-11-04T21:29:03.496Z', - eventType: 'provider.event', + eventId: "00000", + timestamp: "2016-11-04T21:29:03.496Z", + eventType: "provider.event", resource: { - service: 'provider', - name: 'resource', + service: "provider", + name: "resource", }, params: {}, }); }); - it('should throw error when context.params accessed in handler environment', () => { + it("should throw error when context.params accessed in handler environment", () => { const args: any = { ...cloudFunctionArgs, handler: (data: any, context: EventContext) => context, @@ -197,25 +192,25 @@ describe('makeCloudFunction', () => { const cf = makeCloudFunction(args); const test: Event = { context: { - eventId: '00000', - timestamp: '2016-11-04T21:29:03.496Z', - eventType: 'provider.event', + eventId: "00000", + timestamp: "2016-11-04T21:29:03.496Z", + eventType: "provider.event", resource: { - service: 'provider', - name: 'resource', + service: "provider", + name: "resource", }, }, - data: 'test data', + data: "test data", }; return cf(test.data, test.context).then((result) => { expect(result).to.deep.equal({ - eventId: '00000', - timestamp: '2016-11-04T21:29:03.496Z', - eventType: 'provider.event', + eventId: "00000", + timestamp: "2016-11-04T21:29:03.496Z", + eventType: "provider.event", resource: { - service: 'provider', - name: 'resource', + service: "provider", + name: "resource", }, }); expect(() => result.params).to.throw(Error); @@ -223,46 +218,44 @@ describe('makeCloudFunction', () => { }); }); -describe('makeParams', () => { +describe("makeParams", () => { const args: MakeCloudFunctionArgs = { - provider: 'provider', - eventType: 'event', - service: 'service', - triggerResource: () => 'projects/_/instances/pid/ref/{foo}/nested/{bar}', + provider: "provider", + eventType: "event", + service: "service", + triggerResource: () => "projects/_/instances/pid/ref/{foo}/nested/{bar}", handler: (data, context) => context.params, - legacyEventType: 'legacyEvent', + legacyEventType: "legacyEvent", }; const cf = makeCloudFunction(args); - it('should construct params from the event resource of events', () => { + it("should construct params from the event resource of events", () => { const testEvent: Event = { context: { - eventId: '111', - timestamp: '2016-11-04T21:29:03.496Z', + eventId: "111", + timestamp: "2016-11-04T21:29:03.496Z", resource: { - service: 'service', - name: 'projects/_/instances/pid/ref/a/nested/b', + service: "service", + name: "projects/_/instances/pid/ref/a/nested/b", }, - eventType: 'event', + eventType: "event", }, - data: 'data', + data: "data", }; - return expect( - cf(testEvent.data, testEvent.context) - ).to.eventually.deep.equal({ - foo: 'a', - bar: 'b', + return expect(cf(testEvent.data, testEvent.context)).to.eventually.deep.equal({ + foo: "a", + bar: "b", }); }); }); -describe('makeAuth and makeAuthType', () => { +describe("makeAuth and makeAuthType", () => { const args: MakeCloudFunctionArgs = { - provider: 'google.firebase.database', - eventType: 'event', - service: 'service', - triggerResource: () => 'projects/_/instances/pid/ref/{foo}/nested/{bar}', + provider: "google.firebase.database", + eventType: "event", + service: "service", + triggerResource: () => "projects/_/instances/pid/ref/{foo}/nested/{bar}", handler: (data, context) => { return { auth: context.auth, @@ -272,9 +265,9 @@ describe('makeAuth and makeAuthType', () => { }; const cf = makeCloudFunction(args); - it('should construct correct auth and authType for admin user', () => { + it("should construct correct auth and authType for admin user", () => { const testEvent = { - data: 'data', + data: "data", context: { auth: { admin: true, @@ -282,17 +275,15 @@ describe('makeAuth and makeAuthType', () => { }, }; - return expect( - cf(testEvent.data, testEvent.context) - ).to.eventually.deep.equal({ + return expect(cf(testEvent.data, testEvent.context)).to.eventually.deep.equal({ auth: undefined, - authType: 'ADMIN', + authType: "ADMIN", }); }); - it('should construct correct auth and authType for unauthenticated user', () => { + it("should construct correct auth and authType for unauthenticated user", () => { const testEvent = { - data: 'data', + data: "data", context: { auth: { admin: false, @@ -300,41 +291,37 @@ describe('makeAuth and makeAuthType', () => { }, }; - return expect( - cf(testEvent.data, testEvent.context) - ).to.eventually.deep.equal({ + return expect(cf(testEvent.data, testEvent.context)).to.eventually.deep.equal({ auth: null, - authType: 'UNAUTHENTICATED', + authType: "UNAUTHENTICATED", }); }); - it('should construct correct auth and authType for a user', () => { + it("should construct correct auth and authType for a user", () => { const testEvent = { - data: 'data', + data: "data", context: { auth: { admin: false, variable: { - uid: 'user', - provider: 'google', + uid: "user", + provider: "google", token: { - sub: 'user', + sub: "user", }, }, }, }, }; - return expect( - cf(testEvent.data, testEvent.context) - ).to.eventually.deep.equal({ + return expect(cf(testEvent.data, testEvent.context)).to.eventually.deep.equal({ auth: { - uid: 'user', + uid: "user", token: { - sub: 'user', + sub: "user", }, }, - authType: 'USER', + authType: "USER", }); }); }); diff --git a/spec/v1/config.spec.ts b/spec/v1/config.spec.ts index 0555abc93..67bd920db 100644 --- a/spec/v1/config.spec.ts +++ b/spec/v1/config.spec.ts @@ -20,22 +20,22 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; -import * as fs from 'fs'; -import * as process from 'process'; -import Sinon = require('sinon'); +import { expect } from "chai"; +import * as fs from "fs"; +import * as process from "process"; +import Sinon = require("sinon"); -import { config, resetCache } from '../../src/v1/config'; +import { config, resetCache } from "../../src/v1/config"; -describe('config()', () => { +describe("config()", () => { let readFileSync: Sinon.SinonStub; let cwdStub: Sinon.SinonStub; before(() => { - readFileSync = Sinon.stub(fs, 'readFileSync'); - readFileSync.throws('Unexpected call'); - cwdStub = Sinon.stub(process, 'cwd'); - cwdStub.returns('/srv'); + readFileSync = Sinon.stub(fs, "readFileSync"); + readFileSync.throws("Unexpected call"); + cwdStub = Sinon.stub(process, "cwd"); + cwdStub.returns("/srv"); }); after(() => { @@ -49,29 +49,25 @@ describe('config()', () => { delete process.env.K_CONFIGURATION; }); - it('will never load in GCFv2', () => { + it("will never load in GCFv2", () => { const json = JSON.stringify({ - foo: 'bar', + foo: "bar", firebase: {}, }); - readFileSync - .withArgs('/srv/.runtimeconfig.json') - .returns(Buffer.from(json)); + readFileSync.withArgs("/srv/.runtimeconfig.json").returns(Buffer.from(json)); - process.env.K_CONFIGURATION = 'my-service'; + process.env.K_CONFIGURATION = "my-service"; expect(config).to.throw(Error, /transition to using environment variables/); }); - it('loads config values from .runtimeconfig.json', () => { + it("loads config values from .runtimeconfig.json", () => { const json = JSON.stringify({ - foo: 'bar', + foo: "bar", firebase: {}, }); - readFileSync - .withArgs('/srv/.runtimeconfig.json') - .returns(Buffer.from(json)); + readFileSync.withArgs("/srv/.runtimeconfig.json").returns(Buffer.from(json)); const loaded = config(); - expect(loaded).to.not.have.property('firebase'); - expect(loaded).to.have.property('foo', 'bar'); + expect(loaded).to.not.have.property("firebase"); + expect(loaded).to.have.property("foo", "bar"); }); }); diff --git a/spec/v1/function-builder.spec.ts b/spec/v1/function-builder.spec.ts index 936297be9..325eb9b6e 100644 --- a/spec/v1/function-builder.spec.ts +++ b/spec/v1/function-builder.spec.ts @@ -20,70 +20,70 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; +import { expect } from "chai"; -import * as functions from '../../src/v1'; +import * as functions from "../../src/v1"; -describe('FunctionBuilder', () => { +describe("FunctionBuilder", () => { before(() => { - process.env.GCLOUD_PROJECT = 'not-a-project'; + process.env.GCLOUD_PROJECT = "not-a-project"; }); after(() => { delete process.env.GCLOUD_PROJECT; }); - it('should allow supported region to be set', () => { + it("should allow supported region to be set", () => { const fn = functions - .region('us-east1') + .region("us-east1") .auth.user() .onCreate((user) => user); - expect(fn.__endpoint.region).to.deep.equal(['us-east1']); + expect(fn.__endpoint.region).to.deep.equal(["us-east1"]); }); - it('should allow multiple supported regions to be set', () => { + it("should allow multiple supported regions to be set", () => { const fn = functions - .region('us-east1', 'us-central1') + .region("us-east1", "us-central1") .auth.user() .onCreate((user) => user); - expect(fn.__endpoint.region).to.deep.equal(['us-east1', 'us-central1']); + expect(fn.__endpoint.region).to.deep.equal(["us-east1", "us-central1"]); }); - it('should allow all supported regions to be set', () => { + it("should allow all supported regions to be set", () => { const fn = functions .region( - 'us-central1', - 'us-east1', - 'us-east4', - 'europe-west1', - 'europe-west2', - 'europe-west3', - 'asia-east2', - 'asia-northeast1' + "us-central1", + "us-east1", + "us-east4", + "europe-west1", + "europe-west2", + "europe-west3", + "asia-east2", + "asia-northeast1" ) .auth.user() .onCreate((user) => user); expect(fn.__endpoint.region).to.deep.equal([ - 'us-central1', - 'us-east1', - 'us-east4', - 'europe-west1', - 'europe-west2', - 'europe-west3', - 'asia-east2', - 'asia-northeast1', + "us-central1", + "us-east1", + "us-east4", + "europe-west1", + "europe-west2", + "europe-west3", + "asia-east2", + "asia-northeast1", ]); }); - it('should allow valid runtime options to be set', () => { + it("should allow valid runtime options to be set", () => { const fn = functions .runWith({ timeoutSeconds: 90, failurePolicy: { retry: {} }, - memory: '256MB', + memory: "256MB", }) .auth.user() .onCreate((user) => user); @@ -97,7 +97,7 @@ describe('FunctionBuilder', () => { const fn = functions .runWith({ failurePolicy: true, - memory: '256MB', + memory: "256MB", timeoutSeconds: 90, }) .auth.user() @@ -106,161 +106,156 @@ describe('FunctionBuilder', () => { expect(fn.__endpoint.eventTrigger.retry).to.deep.equal(true); }); - it('should allow both supported region and valid runtime options to be set', () => { + it("should allow both supported region and valid runtime options to be set", () => { const fn = functions - .region('europe-west2') + .region("europe-west2") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) .auth.user() .onCreate((user) => user); - expect(fn.__endpoint.region).to.deep.equal(['europe-west2']); + expect(fn.__endpoint.region).to.deep.equal(["europe-west2"]); expect(fn.__endpoint.availableMemoryMb).to.deep.equal(256); expect(fn.__endpoint.timeoutSeconds).to.deep.equal(90); }); - it('should allow both valid runtime options and supported region to be set in reverse order', () => { + it("should allow both valid runtime options and supported region to be set in reverse order", () => { const fn = functions .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) - .region('europe-west1') + .region("europe-west1") .auth.user() .onCreate((user) => user); - expect(fn.__endpoint.region).to.deep.equal(['europe-west1']); + expect(fn.__endpoint.region).to.deep.equal(["europe-west1"]); expect(fn.__endpoint.availableMemoryMb).to.deep.equal(256); expect(fn.__endpoint.timeoutSeconds).to.deep.equal(90); }); - it('should fail if supported region but invalid runtime options are set (reverse order)', () => { + it("should fail if supported region but invalid runtime options are set (reverse order)", () => { expect(() => { - functions - .region('asia-northeast1') - .runWith({ timeoutSeconds: 600, memory: '256MB' }); - }).to.throw(Error, 'TimeoutSeconds'); + functions.region("asia-northeast1").runWith({ timeoutSeconds: 600, memory: "256MB" }); + }).to.throw(Error, "TimeoutSeconds"); }); - it('should throw an error if user chooses a failurePolicy which is neither an object nor a boolean', () => { + it("should throw an error if user chooses a failurePolicy which is neither an object nor a boolean", () => { expect(() => functions.runWith({ - failurePolicy: - 1234 as unknown as functions.RuntimeOptions['failurePolicy'], + failurePolicy: 1234 as unknown as functions.RuntimeOptions["failurePolicy"], }) - ).to.throw(Error, 'failurePolicy must be a boolean or an object'); + ).to.throw(Error, "failurePolicy must be a boolean or an object"); }); - it('should throw an error if user chooses a failurePolicy.retry which is not an object', () => { + it("should throw an error if user chooses a failurePolicy.retry which is not an object", () => { expect(() => functions.runWith({ - failurePolicy: { retry: 1234 as unknown as object }, + failurePolicy: { retry: 1234 as unknown as never }, }) - ).to.throw(Error, 'failurePolicy.retry'); + ).to.throw(Error, "failurePolicy.retry"); }); - it('should throw an error if user chooses an invalid memory allocation', () => { + it("should throw an error if user chooses an invalid memory allocation", () => { expect(() => { return functions.runWith({ - memory: 'unsupported', + memory: "unsupported", } as any); - }).to.throw(Error, 'memory'); + }).to.throw(Error, "memory"); expect(() => { - return functions.region('us-east1').runWith({ - memory: 'unsupported', + return functions.region("us-east1").runWith({ + memory: "unsupported", } as any); - }).to.throw(Error, 'memory'); + }).to.throw(Error, "memory"); }); - it('should throw an error if user chooses an invalid timeoutSeconds', () => { + it("should throw an error if user chooses an invalid timeoutSeconds", () => { expect(() => { return functions.runWith({ timeoutSeconds: 1000000, } as any); - }).to.throw(Error, 'TimeoutSeconds'); + }).to.throw(Error, "TimeoutSeconds"); expect(() => { - return functions.region('asia-east2').runWith({ + return functions.region("asia-east2").runWith({ timeoutSeconds: 1000000, } as any); - }).to.throw(Error, 'TimeoutSeconds'); + }).to.throw(Error, "TimeoutSeconds"); }); - it('should throw an error if user chooses no region when using .region()', () => { + it("should throw an error if user chooses no region when using .region()", () => { expect(() => { return functions.region(); - }).to.throw(Error, 'at least one region'); + }).to.throw(Error, "at least one region"); expect(() => { return functions.region().runWith({ timeoutSeconds: 500, } as any); - }).to.throw(Error, 'at least one region'); + }).to.throw(Error, "at least one region"); }); - it('should allow a ingressSettings to be set', () => { + it("should allow a ingressSettings to be set", () => { const fn = functions - .runWith({ ingressSettings: 'ALLOW_INTERNAL_ONLY' }) - .https.onRequest(() => {}); + .runWith({ ingressSettings: "ALLOW_INTERNAL_ONLY" }) + .https.onRequest(() => undefined); - expect(fn.__endpoint.ingressSettings).to.equal('ALLOW_INTERNAL_ONLY'); + expect(fn.__endpoint.ingressSettings).to.equal("ALLOW_INTERNAL_ONLY"); }); - it('should throw an error if user chooses an invalid ingressSettings', () => { + it("should throw an error if user chooses an invalid ingressSettings", () => { expect(() => { return functions.runWith({ - ingressSettings: 'INVALID_OPTION', + ingressSettings: "INVALID_OPTION", } as any); }).to.throw( Error, - `The only valid ingressSettings values are: ${functions.INGRESS_SETTINGS_OPTIONS.join( - ',' - )}` + `The only valid ingressSettings values are: ${functions.INGRESS_SETTINGS_OPTIONS.join(",")}` ); }); - it('should allow a vpcConnector to be set', () => { + it("should allow a vpcConnector to be set", () => { const fn = functions .runWith({ - vpcConnector: 'test-connector', + vpcConnector: "test-connector", }) .auth.user() .onCreate((user) => user); - expect(fn.__endpoint.vpc.connector).to.equal('test-connector'); + expect(fn.__endpoint.vpc.connector).to.equal("test-connector"); }); - it('should allow a vpcConnectorEgressSettings to be set', () => { + it("should allow a vpcConnectorEgressSettings to be set", () => { const fn = functions .runWith({ - vpcConnector: 'test-connector', - vpcConnectorEgressSettings: 'PRIVATE_RANGES_ONLY', + vpcConnector: "test-connector", + vpcConnectorEgressSettings: "PRIVATE_RANGES_ONLY", }) .auth.user() .onCreate((user) => user); - expect(fn.__endpoint.vpc.egressSettings).to.equal('PRIVATE_RANGES_ONLY'); + expect(fn.__endpoint.vpc.egressSettings).to.equal("PRIVATE_RANGES_ONLY"); }); - it('should throw an error if user chooses an invalid vpcConnectorEgressSettings', () => { + it("should throw an error if user chooses an invalid vpcConnectorEgressSettings", () => { expect(() => { return functions.runWith({ - vpcConnector: 'test-connector', - vpcConnectorEgressSettings: 'INCORRECT_OPTION', + vpcConnector: "test-connector", + vpcConnectorEgressSettings: "INCORRECT_OPTION", } as any); }).to.throw( Error, `The only valid vpcConnectorEgressSettings values are: ${functions.VPC_EGRESS_SETTINGS_OPTIONS.join( - ',' + "," )}` ); }); - it('should allow a serviceAccount to be set as-is', () => { - const serviceAccount = 'test-service-account@test.iam.gserviceaccount.com'; + it("should allow a serviceAccount to be set as-is", () => { + const serviceAccount = "test-service-account@test.iam.gserviceaccount.com"; const fn = functions .runWith({ serviceAccount, @@ -271,8 +266,8 @@ describe('FunctionBuilder', () => { expect(fn.__endpoint.serviceAccountEmail).to.equal(serviceAccount); }); - it('should allow a serviceAccount to be set with generated service account email', () => { - const serviceAccount = 'test-service-account@'; + it("should allow a serviceAccount to be set with generated service account email", () => { + const serviceAccount = "test-service-account@"; const fn = functions .runWith({ serviceAccount, @@ -283,8 +278,8 @@ describe('FunctionBuilder', () => { expect(fn.__endpoint.serviceAccountEmail).to.equal(`test-service-account@`); }); - it('should set a null serviceAccountEmail if service account is set to `default`', () => { - const serviceAccount = 'default'; + it("should set a null serviceAccountEmail if service account is set to `default`", () => { + const serviceAccount = "default"; const fn = functions .runWith({ serviceAccount, @@ -292,11 +287,11 @@ describe('FunctionBuilder', () => { .auth.user() .onCreate((user) => user); - expect(fn.__endpoint.serviceAccountEmail).to.equal('default'); + expect(fn.__endpoint.serviceAccountEmail).to.equal("default"); }); - it('should throw an error if serviceAccount is set to an invalid value', () => { - const serviceAccount = 'test-service-account'; + it("should throw an error if serviceAccount is set to an invalid value", () => { + const serviceAccount = "test-service-account"; expect(() => { functions.runWith({ serviceAccount, @@ -304,37 +299,37 @@ describe('FunctionBuilder', () => { }).to.throw(); }); - it('should allow setting 4GB memory option', () => { + it("should allow setting 4GB memory option", () => { const fn = functions .runWith({ - memory: '4GB', + memory: "4GB", }) - .region('europe-west1') + .region("europe-west1") .auth.user() .onCreate((user) => user); expect(fn.__endpoint.availableMemoryMb).to.deep.equal(4096); }); - it('should allow labels to be set', () => { + it("should allow labels to be set", () => { const fn = functions .runWith({ labels: { - 'valid-key': 'valid-value', + "valid-key": "valid-value", }, }) .auth.user() .onCreate((user) => user); expect(fn.__endpoint.labels).to.deep.equal({ - 'valid-key': 'valid-value', + "valid-key": "valid-value", }); }); - it('should throw an error if more than 58 labels are set', () => { + it("should throw an error if more than 58 labels are set", () => { const labels = {}; for (let i = 0; i < 59; i++) { - labels[`label${i}`] = 'value'; + labels[`label${i}`] = "value"; } expect(() => @@ -344,40 +339,39 @@ describe('FunctionBuilder', () => { ).to.throw(); }); - it('should throw an error if labels has a key that is too long', () => { + it("should throw an error if labels has a key that is too long", () => { expect(() => functions.runWith({ labels: { - 'a-very-long-key-that-is-more-than-the-maximum-allowed-length-for-keys': - 'value', + "a-very-long-key-that-is-more-than-the-maximum-allowed-length-for-keys": "value", }, }) ).to.throw(); }); - it('should throw an error if labels has key that is too short', () => { + it("should throw an error if labels has key that is too short", () => { expect(() => functions.runWith({ - labels: { '': 'value' }, + labels: { "": "value" }, }) ).to.throw(); }); - it('should throw an error if labels has a value that is too long', () => { + it("should throw an error if labels has a value that is too long", () => { expect(() => functions.runWith({ labels: { - key: 'a-very-long-value-that-is-more-than-the-maximum-allowed-length-for-values', + key: "a-very-long-value-that-is-more-than-the-maximum-allowed-length-for-values", }, }) ).to.throw(); }); - it('should throw an error if labels has a key that contains invalid characters', () => { + it("should throw an error if labels has a key that contains invalid characters", () => { expect(() => functions.runWith({ labels: { - Key: 'value', + Key: "value", }, }) ).to.throw(); @@ -385,7 +379,7 @@ describe('FunctionBuilder', () => { expect(() => functions.runWith({ labels: { - 'key ': 'value', + "key ": "value", }, }) ).to.throw(); @@ -393,17 +387,17 @@ describe('FunctionBuilder', () => { expect(() => functions.runWith({ labels: { - '1key': 'value', + "1key": "value", }, }) ).to.throw(); }); - it('should throw an error if labels has a value that contains invalid characters', () => { + it("should throw an error if labels has a value that contains invalid characters", () => { expect(() => functions.runWith({ labels: { - key: 'Value', + key: "Value", }, }) ).to.throw(); @@ -411,17 +405,17 @@ describe('FunctionBuilder', () => { expect(() => functions.runWith({ labels: { - 'key ': 'va lue', + "key ": "va lue", }, }) ).to.throw(); }); - it('should throw an error if a label key starts with a reserved namespace', () => { + it("should throw an error if a label key starts with a reserved namespace", () => { expect(() => functions.runWith({ labels: { - 'firebase-foo': 'value', + "firebase-foo": "value", }, }) ).to.throw(); @@ -429,54 +423,54 @@ describe('FunctionBuilder', () => { expect(() => functions.runWith({ labels: { - 'deployment-bar': 'value', + "deployment-bar": "value", }, }) ).to.throw(); }); - it('should throw an error if invoker is an empty string', () => { + it("should throw an error if invoker is an empty string", () => { expect(() => functions.runWith({ - invoker: '', + invoker: "", }) ).to.throw(); }); - it('should throw an error if invoker is an empty array', () => { + it("should throw an error if invoker is an empty array", () => { expect(() => functions.runWith({ - invoker: [''], + invoker: [""], }) ).to.throw(); }); - it('should throw an error if invoker has an empty string', () => { + it("should throw an error if invoker has an empty string", () => { expect(() => functions.runWith({ - invoker: ['service-account1', '', 'service-account2'], + invoker: ["service-account1", "", "service-account2"], }) ).to.throw(); }); - it('should throw an error if public identifier is in the invoker array', () => { + it("should throw an error if public identifier is in the invoker array", () => { expect(() => functions.runWith({ - invoker: ['service-account1', 'public', 'service-account2'], + invoker: ["service-account1", "public", "service-account2"], }) ).to.throw(); }); - it('should throw an error if private identifier is in the invoker array', () => { + it("should throw an error if private identifier is in the invoker array", () => { expect(() => functions.runWith({ - invoker: ['service-account1', 'private', 'service-account2'], + invoker: ["service-account1", "private", "service-account2"], }) ).to.throw(); }); - it('should allow valid secret config expressed using short form', () => { - const secrets = ['API_KEY']; + it("should allow valid secret config expressed using short form", () => { + const secrets = ["API_KEY"]; const fn = functions .runWith({ secrets }) .auth.user() @@ -484,31 +478,31 @@ describe('FunctionBuilder', () => { expect(fn.__endpoint.secretEnvironmentVariables).to.deep.equal([ { - key: 'API_KEY', + key: "API_KEY", }, ]); }); - it('should throw error given secrets expressed with full resource name', () => { + it("should throw error given secrets expressed with full resource name", () => { expect(() => functions.runWith({ - secrets: ['projects/my-project/secrets/API_KEY'], + secrets: ["projects/my-project/secrets/API_KEY"], }) ).to.throw(); }); - it('should throw error given invalid secret config', () => { + it("should throw error given invalid secret config", () => { expect(() => functions.runWith({ - secrets: ['ABC/efg'], + secrets: ["ABC/efg"], }) ).to.throw(); }); - it('should throw error given invalid secret with versions', () => { + it("should throw error given invalid secret with versions", () => { expect(() => functions.runWith({ - secrets: ['ABC@3'], + secrets: ["ABC@3"], }) ).to.throw(); }); diff --git a/spec/v1/providers/analytics.spec.input.ts b/spec/v1/providers/analytics.spec.input.ts index 74ad65a93..9edb62a4e 100644 --- a/spec/v1/providers/analytics.spec.input.ts +++ b/spec/v1/providers/analytics.spec.input.ts @@ -21,7 +21,7 @@ // SOFTWARE. /* tslint:disable:max-line-length */ -import { AnalyticsEvent } from '../../../src/v1/providers/analytics'; +import { AnalyticsEvent } from "../../../src/v1/providers/analytics"; // A payload, as it might arrive over the wire. Every possible field is filled out at least once. export const fullPayload = JSON.parse(`{ @@ -130,62 +130,62 @@ export const fullPayload = JSON.parse(`{ // The event data that we expect would be constructed if the payload above were to arrive. export const data: AnalyticsEvent = { - reportingDate: '20170202', - name: 'Loaded_In_Background', + reportingDate: "20170202", + name: "Loaded_In_Background", params: { - build: '1350', + build: "1350", calls_remaining: 10, fraction_calls_dropped: 0.0123456, average_call_rating: 4.5, }, - logTime: '2017-02-02T23:06:26.124Z', - previousLogTime: '2017-02-02T23:01:19.797Z', + logTime: "2017-02-02T23:06:26.124Z", + previousLogTime: "2017-02-02T23:01:19.797Z", valueInUSD: 1234.5, user: { - userId: 'abcdefghijklmnop!', + userId: "abcdefghijklmnop!", appInfo: { - appId: 'com.mobileday.MobileDay', - appInstanceId: 'E3C9939401814B9B954725A740B8C7BC', - appPlatform: 'IOS', - appStore: 'iTunes', - appVersion: '5.2.0', + appId: "com.mobileday.MobileDay", + appInstanceId: "E3C9939401814B9B954725A740B8C7BC", + appPlatform: "IOS", + appStore: "iTunes", + appVersion: "5.2.0", }, bundleInfo: { bundleSequenceId: 6034, serverTimestampOffset: 371, }, deviceInfo: { - deviceCategory: 'mobile', - deviceModel: 'iPhone7,2', + deviceCategory: "mobile", + deviceModel: "iPhone7,2", deviceTimeZoneOffsetSeconds: -21600, - mobileBrandName: 'Apple', - mobileMarketingName: 'iPhone 6', - mobileModelName: 'iPhone 6', - platformVersion: '10.2.1', - userDefaultLanguage: 'en-us', - deviceId: '599F9C00-92DC-4B5C-9464-7971F01F8370', - resettableDeviceId: '599F9C00-92DC-4B5C-9464-7971F01F8370', + mobileBrandName: "Apple", + mobileMarketingName: "iPhone 6", + mobileModelName: "iPhone 6", + platformVersion: "10.2.1", + userDefaultLanguage: "en-us", + deviceId: "599F9C00-92DC-4B5C-9464-7971F01F8370", + resettableDeviceId: "599F9C00-92DC-4B5C-9464-7971F01F8370", limitedAdTracking: true, }, - firstOpenTime: '2016-04-28T15:00:35.819Z', + firstOpenTime: "2016-04-28T15:00:35.819Z", geoInfo: { - city: 'Plano', - continent: '021', - country: 'United States', - region: 'Texas', + city: "Plano", + continent: "021", + country: "United States", + region: "Texas", }, userProperties: { build: { - setTime: '2017-02-02T23:06:26.090Z', - value: '1350', + setTime: "2017-02-02T23:06:26.090Z", + value: "1350", }, calls_remaining: { - setTime: '2017-02-02T23:06:26.094Z', - value: '10', + setTime: "2017-02-02T23:06:26.094Z", + value: "10", }, version: { - setTime: '2017-02-02T23:06:26.085Z', - value: '5.2.0', + setTime: "2017-02-02T23:06:26.085Z", + value: "5.2.0", }, }, }, diff --git a/spec/v1/providers/analytics.spec.ts b/spec/v1/providers/analytics.spec.ts index f1fa2162f..6b003d72d 100644 --- a/spec/v1/providers/analytics.spec.ts +++ b/spec/v1/providers/analytics.spec.ts @@ -20,50 +20,49 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; +import { expect } from "chai"; -import * as functions from '../../../src/v1'; -import { Event, EventContext } from '../../../src/v1/cloud-functions'; -import * as analytics from '../../../src/v1/providers/analytics'; -import * as analytics_spec_input from './analytics.spec.input'; +import * as functions from "../../../src/v1"; +import { Event } from "../../../src/v1/cloud-functions"; +import * as analytics from "../../../src/v1/providers/analytics"; +import * as analyticsSpecInput from "./analytics.spec.input"; -describe('Analytics Functions', () => { - describe('EventBuilder', () => { +describe("Analytics Functions", () => { + describe("EventBuilder", () => { before(() => { - process.env.GCLOUD_PROJECT = 'project1'; + process.env.GCLOUD_PROJECT = "project1"; }); after(() => { delete process.env.GCLOUD_PROJECT; }); - it('should allow both region and runtime options to be set', () => { + it("should allow both region and runtime options to be set", () => { const fn = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) - .analytics.event('event') + .analytics.event("event") .onLog((event) => event); - expect(fn.__endpoint.region).to.deep.equal(['us-east1']); + expect(fn.__endpoint.region).to.deep.equal(["us-east1"]); expect(fn.__endpoint.availableMemoryMb).to.deep.equal(256); expect(fn.__endpoint.timeoutSeconds).to.deep.equal(90); }); - describe('#onLog', () => { - it('should return a trigger/endpoint with appropriate values', () => { - const cloudFunction = analytics.event('first_open').onLog(() => null); + describe("#onLog", () => { + it("should return a trigger/endpoint with appropriate values", () => { + const cloudFunction = analytics.event("first_open").onLog(() => null); expect(cloudFunction.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", eventTrigger: { eventFilters: { - resource: 'projects/project1/events/first_open', + resource: "projects/project1/events/first_open", }, - eventType: - 'providers/google.firebase.analytics/eventTypes/event.log', + eventType: "providers/google.firebase.analytics/eventTypes/event.log", retry: false, }, labels: {}, @@ -71,51 +70,44 @@ describe('Analytics Functions', () => { }); }); - describe('#dataConstructor', () => { - it('should handle an event with the appropriate fields', () => { + describe("#dataConstructor", () => { + it("should handle an event with the appropriate fields", () => { const cloudFunction = analytics - .event('first_open') - .onLog( - (data: analytics.AnalyticsEvent, context: EventContext) => data - ); + .event("first_open") + .onLog((data: analytics.AnalyticsEvent) => data); // The event data delivered over the wire will be the JSON for an AnalyticsEvent: // https://firebase.google.com/docs/auth/admin/manage-users#retrieve_user_data const event: Event = { data: { userDim: { - userId: 'hi!', + userId: "hi!", }, }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: - 'providers/google.firebase.analytics/eventTypes/event.log', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "providers/google.firebase.analytics/eventTypes/event.log", resource: { - service: 'app-measurement.com', - name: 'projects/project1/events/first_open', + service: "app-measurement.com", + name: "projects/project1/events/first_open", }, }, }; - return expect( - cloudFunction(event.data, event.context) - ).to.eventually.deep.equal({ + return expect(cloudFunction(event.data, event.context)).to.eventually.deep.equal({ params: {}, user: { - userId: 'hi!', + userId: "hi!", userProperties: {}, }, }); }); - it('should remove xValues', () => { + it("should remove xValues", () => { const cloudFunction = analytics - .event('first_open') - .onLog( - (data: analytics.AnalyticsEvent, context: EventContext) => data - ); + .event("first_open") + .onLog((data: analytics.AnalyticsEvent) => data); // Incoming events will have four kinds of "xValue" fields: "intValue", // "stringValue", "doubleValue" and "floatValue". We expect those to get @@ -124,14 +116,14 @@ describe('Analytics Functions', () => { data: { eventDim: [ { - date: '20170202', - name: 'Loaded_In_Background', + date: "20170202", + name: "Loaded_In_Background", params: { build: { - stringValue: '1350', + stringValue: "1350", }, calls_remaining: { - intValue: '10', + intValue: "10", }, goats_teleported: { doubleValue: 1.1, @@ -146,31 +138,28 @@ describe('Analytics Functions', () => { userProperties: { foo: { value: { - stringValue: 'bar', + stringValue: "bar", }, }, }, }, }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: - 'providers/google.firebase.analytics/eventTypes/event.log', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "providers/google.firebase.analytics/eventTypes/event.log", resource: { - service: 'app-measurement.com', - name: 'projects/project1/events/first_open', + service: "app-measurement.com", + name: "projects/project1/events/first_open", }, }, }; - return expect( - cloudFunction(event.data, event.context) - ).to.eventually.deep.equal({ - reportingDate: '20170202', - name: 'Loaded_In_Background', + return expect(cloudFunction(event.data, event.context)).to.eventually.deep.equal({ + reportingDate: "20170202", + name: "Loaded_In_Background", params: { - build: '1350', + build: "1350", calls_remaining: 10, goats_teleported: 1.1, boat_boyancy: 133.7, @@ -178,33 +167,33 @@ describe('Analytics Functions', () => { user: { userProperties: { foo: { - value: 'bar', + value: "bar", }, }, }, }); }); - it('should change microsecond timestamps to ISO strings, and offsets to millis', () => { + it("should change microsecond timestamps to ISO strings, and offsets to millis", () => { const cloudFunction = analytics - .event('first_open') + .event("first_open") .onLog((data: analytics.AnalyticsEvent) => data); const event: Event = { data: { eventDim: [ { - date: '20170202', - name: 'Loaded_In_Background', - timestampMicros: '1489080600000000', - previousTimestampMicros: '526657020000000', + date: "20170202", + name: "Loaded_In_Background", + timestampMicros: "1489080600000000", + previousTimestampMicros: "526657020000000", }, ], userDim: { - firstOpenTimestampMicros: '577978620000000', + firstOpenTimestampMicros: "577978620000000", userProperties: { foo: { - setTimestampUsec: '514820220000000', + setTimestampUsec: "514820220000000", }, }, bundleInfo: { @@ -213,30 +202,27 @@ describe('Analytics Functions', () => { }, }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: - 'providers/google.firebase.analytics/eventTypes/event.log', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "providers/google.firebase.analytics/eventTypes/event.log", resource: { - service: 'app-measurement.com', - name: 'projects/project1/events/first_open', + service: "app-measurement.com", + name: "projects/project1/events/first_open", }, }, }; - return expect( - cloudFunction(event.data, event.context) - ).to.eventually.deep.equal({ - reportingDate: '20170202', - name: 'Loaded_In_Background', + return expect(cloudFunction(event.data, event.context)).to.eventually.deep.equal({ + reportingDate: "20170202", + name: "Loaded_In_Background", params: {}, - logTime: '2017-03-09T17:30:00.000Z', - previousLogTime: '1986-09-09T13:37:00.000Z', + logTime: "2017-03-09T17:30:00.000Z", + previousLogTime: "1986-09-09T13:37:00.000Z", user: { - firstOpenTime: '1988-04-25T13:37:00.000Z', + firstOpenTime: "1988-04-25T13:37:00.000Z", userProperties: { foo: { - setTime: '1986-04-25T13:37:00.000Z', + setTime: "1986-04-25T13:37:00.000Z", }, }, bundleInfo: { @@ -246,9 +232,9 @@ describe('Analytics Functions', () => { }); }); - it('should populate currency fields', () => { + it("should populate currency fields", () => { const cloudFunction = analytics - .event('first_open') + .event("first_open") .onLog((data: analytics.AnalyticsEvent) => data); // Incoming events will have four kinds of "xValue" fields: "intValue", @@ -264,61 +250,56 @@ describe('Analytics Functions', () => { data: { eventDim: [ { - date: '20170202', - name: 'Loaded_In_Background', + date: "20170202", + name: "Loaded_In_Background", valueInUsd: 123.4, }, ], }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: - 'providers/google.firebase.analytics/eventTypes/event.log', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "providers/google.firebase.analytics/eventTypes/event.log", resource: { - service: 'app-measurement.com', - name: 'projects/project1/events/first_open', + service: "app-measurement.com", + name: "projects/project1/events/first_open", }, }, }; - return expect( - cloudFunction(event.data, event.context) - ).to.eventually.deep.equal({ - reportingDate: '20170202', - name: 'Loaded_In_Background', + return expect(cloudFunction(event.data, event.context)).to.eventually.deep.equal({ + reportingDate: "20170202", + name: "Loaded_In_Background", params: {}, valueInUSD: 123.4, // Field renamed Usd -> USD. }); }); - it('should recognize all the fields the payload can contain', () => { + it("should recognize all the fields the payload can contain", () => { const cloudFunction = analytics - .event('first_open') + .event("first_open") .onLog((data: analytics.AnalyticsEvent) => data); // The payload in analytics_spec_input contains all possible fields at least once. - const payloadData = analytics_spec_input.fullPayload.data; - const payloadContext = analytics_spec_input.fullPayload.context; + const payloadData = analyticsSpecInput.fullPayload.data; + const payloadContext = analyticsSpecInput.fullPayload.context; - return expect( - cloudFunction(payloadData, payloadContext) - ).to.eventually.deep.equal(analytics_spec_input.data); + return expect(cloudFunction(payloadData, payloadContext)).to.eventually.deep.equal( + analyticsSpecInput.data + ); }); }); }); - describe('handler namespace', () => { - describe('#onLog', () => { - it('should return an empty endpoint', () => { - const cloudFunction = functions.handler.analytics.event.onLog( - () => null - ); + describe("handler namespace", () => { + describe("#onLog", () => { + it("should return an empty endpoint", () => { + const cloudFunction = functions.handler.analytics.event.onLog(() => null); expect(cloudFunction.__endpoint).to.be.undefined; }); - it('should handle an event with the appropriate fields', () => { + it("should handle an event with the appropriate fields", () => { const cloudFunction = functions.handler.analytics.event.onLog( - (data: analytics.AnalyticsEvent, context: EventContext) => data + (data: analytics.AnalyticsEvent) => data ); // The event data delivered over the wire will be the JSON for an AnalyticsEvent: @@ -326,27 +307,24 @@ describe('Analytics Functions', () => { const event: Event = { data: { userDim: { - userId: 'hi!', + userId: "hi!", }, }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: - 'providers/google.firebase.analytics/eventTypes/event.log', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "providers/google.firebase.analytics/eventTypes/event.log", resource: { - service: 'app-measurement.com', - name: 'projects/project1/events/first_open', + service: "app-measurement.com", + name: "projects/project1/events/first_open", }, }, }; - return expect( - cloudFunction(event.data, event.context) - ).to.eventually.deep.equal({ + return expect(cloudFunction(event.data, event.context)).to.eventually.deep.equal({ params: {}, user: { - userId: 'hi!', + userId: "hi!", userProperties: {}, }, }); @@ -354,21 +332,17 @@ describe('Analytics Functions', () => { }); }); - describe('process.env.GCLOUD_PROJECT not set', () => { - it('should not throw if __endpoint is not accessed', () => { - expect(() => analytics.event('event').onLog(() => null)).to.not.throw( - Error - ); + describe("process.env.GCLOUD_PROJECT not set", () => { + it("should not throw if __endpoint is not accessed", () => { + expect(() => analytics.event("event").onLog(() => null)).to.not.throw(Error); }); - it('should throw when __endpoint is accessed', () => { - expect( - () => analytics.event('event').onLog(() => null).__endpoint - ).to.throw(Error); + it("should throw when __endpoint is accessed", () => { + expect(() => analytics.event("event").onLog(() => null).__endpoint).to.throw(Error); }); - it('should not throw when #run is called', () => { - const cf = analytics.event('event').onLog(() => null); + it("should not throw when #run is called", () => { + const cf = analytics.event("event").onLog(() => null); expect(cf.run).to.not.throw(Error); }); diff --git a/spec/v1/providers/auth.spec.ts b/spec/v1/providers/auth.spec.ts index 8c2ca9d93..6c52bf300 100644 --- a/spec/v1/providers/auth.spec.ts +++ b/spec/v1/providers/auth.spec.ts @@ -20,39 +20,35 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; -import { UserRecord } from '../../../src/common/providers/identity'; -import * as functions from '../../../src/v1'; -import { - CloudFunction, - Event, - EventContext, -} from '../../../src/v1/cloud-functions'; -import * as auth from '../../../src/v1/providers/auth'; - -describe('Auth Functions', () => { +import { expect } from "chai"; +import { UserRecord } from "../../../src/common/providers/identity"; +import * as functions from "../../../src/v1"; +import { CloudFunction, Event } from "../../../src/v1/cloud-functions"; +import * as auth from "../../../src/v1/providers/auth"; + +describe("Auth Functions", () => { const event: Event = { data: { metadata: { - creationTime: '2016-12-15T19:37:37.059Z', - lastSignInTime: '2017-01-01T00:00:00.000Z', + creationTime: "2016-12-15T19:37:37.059Z", + lastSignInTime: "2017-01-01T00:00:00.000Z", }, }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: 'providers/firebase.auth/eventTypes/user.delete', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "providers/firebase.auth/eventTypes/user.delete", resource: { - service: 'firebaseauth.googleapis.com', - name: 'projects/project1', + service: "firebaseauth.googleapis.com", + name: "projects/project1", }, }, }; - describe('AuthBuilder', () => { + describe("AuthBuilder", () => { function expectedEndpoint(project: string, eventType: string) { return { - platform: 'gcfv1', + platform: "gcfv1", eventTrigger: { eventFilters: { resource: `projects/${project}`, @@ -64,11 +60,11 @@ describe('Auth Functions', () => { }; } - const handler = (user: UserRecord) => { + const handler = () => { return Promise.resolve(); }; - const project = 'project1'; + const project = "project1"; before(() => { process.env.GCLOUD_PROJECT = project; @@ -78,54 +74,50 @@ describe('Auth Functions', () => { delete process.env.GCLOUD_PROJECT; }); - it('should allow both region and runtime options to be set', () => { + it("should allow both region and runtime options to be set", () => { const fn = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) .auth.user() .onCreate(() => null); - expect(fn.__endpoint.region).to.deep.equal(['us-east1']); + expect(fn.__endpoint.region).to.deep.equal(["us-east1"]); expect(fn.__endpoint.availableMemoryMb).to.deep.equal(256); expect(fn.__endpoint.timeoutSeconds).to.deep.equal(90); - expect(fn.__endpoint.region).to.deep.equal(['us-east1']); + expect(fn.__endpoint.region).to.deep.equal(["us-east1"]); expect(fn.__endpoint.availableMemoryMb).to.deep.equal(256); expect(fn.__endpoint.timeoutSeconds).to.deep.equal(90); }); - describe('#onCreate', () => { - it('should return a trigger/endpoint with appropriate values', () => { + describe("#onCreate", () => { + it("should return a trigger/endpoint with appropriate values", () => { const cloudFunction = auth.user().onCreate(() => null); - expect(cloudFunction.__endpoint).to.deep.equal( - expectedEndpoint(project, 'user.create') - ); + expect(cloudFunction.__endpoint).to.deep.equal(expectedEndpoint(project, "user.create")); }); }); - describe('#onDelete', () => { - it('should return a trigger/endpoint with appropriate values', () => { + describe("#onDelete", () => { + it("should return a trigger/endpoint with appropriate values", () => { const cloudFunction = auth.user().onDelete(handler); - expect(cloudFunction.__endpoint).to.deep.equal( - expectedEndpoint(project, 'user.delete') - ); + expect(cloudFunction.__endpoint).to.deep.equal(expectedEndpoint(project, "user.delete")); }); }); - describe('beforeCreate', () => { - it('should create the function without options', () => { - const fn = auth.user().beforeCreate((u, c) => Promise.resolve()); + describe("beforeCreate", () => { + it("should create the function without options", () => { + const fn = auth.user().beforeCreate(() => Promise.resolve()); expect(fn.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", labels: {}, blockingTrigger: { - eventType: 'providers/cloud.auth/eventTypes/user.beforeCreate', + eventType: "providers/cloud.auth/eventTypes/user.beforeCreate", options: { accessToken: false, idToken: false, @@ -135,18 +127,18 @@ describe('Auth Functions', () => { }); expect(fn.__requiredAPIs).to.deep.equal([ { - api: 'identitytoolkit.googleapis.com', - reason: 'Needed for auth blocking functions', + api: "identitytoolkit.googleapis.com", + reason: "Needed for auth blocking functions", }, ]); }); - it('should create the function with options', () => { + it("should create the function with options", () => { const fn = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) .auth.user({ blockingOptions: { @@ -154,16 +146,16 @@ describe('Auth Functions', () => { refreshToken: false, }, }) - .beforeCreate((u, c) => Promise.resolve()); + .beforeCreate(() => Promise.resolve()); expect(fn.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", labels: {}, - region: ['us-east1'], + region: ["us-east1"], availableMemoryMb: 256, timeoutSeconds: 90, blockingTrigger: { - eventType: 'providers/cloud.auth/eventTypes/user.beforeCreate', + eventType: "providers/cloud.auth/eventTypes/user.beforeCreate", options: { accessToken: true, idToken: false, @@ -173,22 +165,22 @@ describe('Auth Functions', () => { }); expect(fn.__requiredAPIs).to.deep.equal([ { - api: 'identitytoolkit.googleapis.com', - reason: 'Needed for auth blocking functions', + api: "identitytoolkit.googleapis.com", + reason: "Needed for auth blocking functions", }, ]); }); }); - describe('beforeSignIn', () => { - it('should create the function without options', () => { - const fn = auth.user().beforeSignIn((u, c) => Promise.resolve()); + describe("beforeSignIn", () => { + it("should create the function without options", () => { + const fn = auth.user().beforeSignIn(() => Promise.resolve()); expect(fn.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", labels: {}, blockingTrigger: { - eventType: 'providers/cloud.auth/eventTypes/user.beforeSignIn', + eventType: "providers/cloud.auth/eventTypes/user.beforeSignIn", options: { accessToken: false, idToken: false, @@ -198,18 +190,18 @@ describe('Auth Functions', () => { }); expect(fn.__requiredAPIs).to.deep.equal([ { - api: 'identitytoolkit.googleapis.com', - reason: 'Needed for auth blocking functions', + api: "identitytoolkit.googleapis.com", + reason: "Needed for auth blocking functions", }, ]); }); - it('should create the function with options', () => { + it("should create the function with options", () => { const fn = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) .auth.user({ blockingOptions: { @@ -217,16 +209,16 @@ describe('Auth Functions', () => { refreshToken: false, }, }) - .beforeSignIn((u, c) => Promise.resolve()); + .beforeSignIn(() => Promise.resolve()); expect(fn.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", labels: {}, - region: ['us-east1'], + region: ["us-east1"], availableMemoryMb: 256, timeoutSeconds: 90, blockingTrigger: { - eventType: 'providers/cloud.auth/eventTypes/user.beforeSignIn', + eventType: "providers/cloud.auth/eventTypes/user.beforeSignIn", options: { accessToken: true, idToken: false, @@ -236,79 +228,66 @@ describe('Auth Functions', () => { }); expect(fn.__requiredAPIs).to.deep.equal([ { - api: 'identitytoolkit.googleapis.com', - reason: 'Needed for auth blocking functions', + api: "identitytoolkit.googleapis.com", + reason: "Needed for auth blocking functions", }, ]); }); }); - describe('#_dataConstructor', () => { + describe("#_dataConstructor", () => { let cloudFunctionDelete: CloudFunction; before(() => { - cloudFunctionDelete = auth - .user() - .onDelete((data: UserRecord, context: EventContext) => data); + cloudFunctionDelete = auth.user().onDelete((data: UserRecord) => data); }); - it('should handle wire format as of v5.0.0 of firebase-admin', () => { - return cloudFunctionDelete(event.data, event.context).then( - (data: any) => { - expect(data.metadata.creationTime).to.equal( - '2016-12-15T19:37:37.059Z' - ); - expect(data.metadata.lastSignInTime).to.equal( - '2017-01-01T00:00:00.000Z' - ); - } - ); + it("should handle wire format as of v5.0.0 of firebase-admin", () => { + return cloudFunctionDelete(event.data, event.context).then((data: any) => { + expect(data.metadata.creationTime).to.equal("2016-12-15T19:37:37.059Z"); + expect(data.metadata.lastSignInTime).to.equal("2017-01-01T00:00:00.000Z"); + }); }); }); }); - describe('handler namespace', () => { - describe('#onCreate', () => { - it('should return an empty endpoint', () => { + describe("handler namespace", () => { + describe("#onCreate", () => { + it("should return an empty endpoint", () => { const cloudFunction = functions.handler.auth.user.onCreate(() => null); expect(cloudFunction.__endpoint).to.be.undefined; }); }); - describe('#onDelete', () => { - const cloudFunctionDelete: CloudFunction = - functions.handler.auth.user.onDelete((data: UserRecord) => data); + describe("#onDelete", () => { + const cloudFunctionDelete: CloudFunction = functions.handler.auth.user.onDelete( + (data: UserRecord) => data + ); - it('should return an empty endpoint', () => { + it("should return an empty endpoint", () => { const cloudFunction = functions.handler.auth.user.onDelete(() => null); expect(cloudFunction.__endpoint).to.be.undefined; }); - it('should handle wire format as of v5.0.0 of firebase-admin', () => { - return cloudFunctionDelete(event.data, event.context).then( - (data: any) => { - expect(data.metadata.creationTime).to.equal( - '2016-12-15T19:37:37.059Z' - ); - expect(data.metadata.lastSignInTime).to.equal( - '2017-01-01T00:00:00.000Z' - ); - } - ); + it("should handle wire format as of v5.0.0 of firebase-admin", () => { + return cloudFunctionDelete(event.data, event.context).then((data: any) => { + expect(data.metadata.creationTime).to.equal("2016-12-15T19:37:37.059Z"); + expect(data.metadata.lastSignInTime).to.equal("2017-01-01T00:00:00.000Z"); + }); }); }); }); - describe('process.env.GCLOUD_PROJECT not set', () => { - it('should not throw if __endpoint is not accessed', () => { + describe("process.env.GCLOUD_PROJECT not set", () => { + it("should not throw if __endpoint is not accessed", () => { expect(() => auth.user().onCreate(() => null)).to.not.throw(Error); }); - it('should throw when endpoint is accessed', () => { + it("should throw when endpoint is accessed", () => { expect(() => auth.user().onCreate(() => null).__endpoint).to.throw(Error); }); - it('should not throw when #run is called', () => { + it("should not throw when #run is called", () => { const cf = auth.user().onCreate(() => null); expect(cf.run).to.not.throw(Error); }); diff --git a/spec/v1/providers/database.spec.ts b/spec/v1/providers/database.spec.ts index 2dd4e1c7f..7d7785d07 100644 --- a/spec/v1/providers/database.spec.ts +++ b/spec/v1/providers/database.spec.ts @@ -20,21 +20,21 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; -import { getApp, setApp } from '../../../src/common/app'; -import * as config from '../../../src/common/config'; -import { applyChange } from '../../../src/common/utilities/utils'; -import * as functions from '../../../src/v1'; -import * as database from '../../../src/v1/providers/database'; -import { expectType } from '../../common/metaprogramming'; - -describe('Database Functions', () => { - describe('DatabaseBuilder', () => { +import { expect } from "chai"; +import { getApp, setApp } from "../../../src/common/app"; +import * as config from "../../../src/common/config"; +import { applyChange } from "../../../src/common/utilities/utils"; +import * as functions from "../../../src/v1"; +import * as database from "../../../src/v1/providers/database"; +import { expectType } from "../../common/metaprogramming"; + +describe("Database Functions", () => { + describe("DatabaseBuilder", () => { // TODO add tests for building a data or change based on the type of operation function expectedEndpoint(resource: string, eventType: string) { return { - platform: 'gcfv1', + platform: "gcfv1", eventTrigger: { eventFilters: { resource, @@ -48,7 +48,7 @@ describe('Database Functions', () => { before(() => { config.resetCache({ - databaseURL: 'https://subdomain.apse.firebasedatabase.app', + databaseURL: "https://subdomain.apse.firebasedatabase.app", }); }); @@ -57,563 +57,510 @@ describe('Database Functions', () => { setApp(undefined); }); - it('should allow both region and runtime options to be set', () => { + it("should allow both region and runtime options to be set", () => { const fn = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) - .database.ref('/') + .database.ref("/") .onCreate((snap) => snap); - expect(fn.__endpoint.region).to.deep.equal(['us-east1']); + expect(fn.__endpoint.region).to.deep.equal(["us-east1"]); expect(fn.__endpoint.availableMemoryMb).to.deep.equal(256); expect(fn.__endpoint.timeoutSeconds).to.deep.equal(90); - expect(fn.__endpoint.region).to.deep.equal(['us-east1']); + expect(fn.__endpoint.region).to.deep.equal(["us-east1"]); expect(fn.__endpoint.availableMemoryMb).to.deep.equal(256); expect(fn.__endpoint.timeoutSeconds).to.deep.equal(90); }); - describe('#onWrite()', () => { - it('should return a endpoint with appropriate values', () => { - const func = database.ref('foo').onWrite(() => null); + describe("#onWrite()", () => { + it("should return a endpoint with appropriate values", () => { + const func = database.ref("foo").onWrite(() => null); expect(func.__endpoint).to.deep.equal( - expectedEndpoint( - 'projects/_/instances/subdomain/refs/foo', - 'ref.write' - ) + expectedEndpoint("projects/_/instances/subdomain/refs/foo", "ref.write") ); }); - it('should let developers choose a database instance', () => { + it("should let developers choose a database instance", () => { const func = database - .instance('custom') - .ref('foo') + .instance("custom") + .ref("foo") .onWrite(() => null); expect(func.__endpoint).to.deep.equal( - expectedEndpoint('projects/_/instances/custom/refs/foo', 'ref.write') + expectedEndpoint("projects/_/instances/custom/refs/foo", "ref.write") ); }); - it('should return a handler that emits events with a proper DataSnapshot', () => { + it("should return a handler that emits events with a proper DataSnapshot", () => { const event = { data: { data: null, - delta: { foo: 'bar' }, + delta: { foo: "bar" }, }, context: { - eventId: '70172329041928', - eventType: - 'providers/google.firebase.database/eventTypes/ref.write', - timestamp: '2018-04-09T07:56:12.975Z', - resource: 'projects/_/instances/subdomains/refs/users', + eventId: "70172329041928", + eventType: "providers/google.firebase.database/eventTypes/ref.write", + timestamp: "2018-04-09T07:56:12.975Z", + resource: "projects/_/instances/subdomains/refs/users", }, }; - const handler = database - .ref('/users/{id}') - .onWrite((change, context) => { - expect(change.after.val()).to.deep.equal({ foo: 'bar' }); - }); + const handler = database.ref("/users/{id}").onWrite((change) => { + expect(change.after.val()).to.deep.equal({ foo: "bar" }); + }); return handler(event.data, event.context); }); - it('Should have params of the correct type', () => { - database.ref('foo').onWrite((event, context) => { + it("Should have params of the correct type", () => { + database.ref("foo").onWrite((event, context) => { expectType>(context.params); }); - database.ref('foo/{bar}').onWrite((event, context) => { + database.ref("foo/{bar}").onWrite((event, context) => { expectType<{ bar: string }>(context.params); }); - database.ref('foo/{bar}/{baz}').onWrite((event, context) => { + database.ref("foo/{bar}/{baz}").onWrite((event, context) => { expectType<{ bar: string; baz: string }>(context.params); }); }); }); - describe('#onCreate()', () => { - it('should return a trigger/endpoint with appropriate values', () => { - const func = database.ref('foo').onCreate(() => null); + describe("#onCreate()", () => { + it("should return a trigger/endpoint with appropriate values", () => { + const func = database.ref("foo").onCreate(() => null); expect(func.__endpoint).to.deep.equal( - expectedEndpoint( - 'projects/_/instances/subdomain/refs/foo', - 'ref.create' - ) + expectedEndpoint("projects/_/instances/subdomain/refs/foo", "ref.create") ); }); - it('should let developers choose a database instance', () => { + it("should let developers choose a database instance", () => { const func = database - .instance('custom') - .ref('foo') + .instance("custom") + .ref("foo") .onCreate(() => null); expect(func.__endpoint).to.deep.equal( - expectedEndpoint('projects/_/instances/custom/refs/foo', 'ref.create') + expectedEndpoint("projects/_/instances/custom/refs/foo", "ref.create") ); }); - it('should return a handler that emits events with a proper DataSnapshot', () => { + it("should return a handler that emits events with a proper DataSnapshot", () => { const event = { data: { data: null, - delta: { foo: 'bar' }, + delta: { foo: "bar" }, }, context: { - eventId: '70172329041928', - eventType: - 'providers/google.firebase.database/eventTypes/ref.create', - timestamp: '2018-04-09T07:56:12.975Z', - resource: 'projects/_/instances/subdomains/refs/users', + eventId: "70172329041928", + eventType: "providers/google.firebase.database/eventTypes/ref.create", + timestamp: "2018-04-09T07:56:12.975Z", + resource: "projects/_/instances/subdomains/refs/users", }, }; - const handler = database - .ref('/users/{id}') - .onCreate((data, context) => { - expect(data.val()).to.deep.equal({ foo: 'bar' }); - }); + const handler = database.ref("/users/{id}").onCreate((data) => { + expect(data.val()).to.deep.equal({ foo: "bar" }); + }); return handler(event.data, event.context); }); - it('Should have params of the correct type', () => { - database.ref('foo').onCreate((event, context) => { + it("Should have params of the correct type", () => { + database.ref("foo").onCreate((event, context) => { expectType>(context.params); }); - database.ref('foo/{bar}').onCreate((event, context) => { + database.ref("foo/{bar}").onCreate((event, context) => { expectType<{ bar: string }>(context.params); }); - database.ref('foo/{bar}/{baz}').onCreate((event, context) => { + database.ref("foo/{bar}/{baz}").onCreate((event, context) => { expectType<{ bar: string; baz: string }>(context.params); }); }); }); - describe('#onUpdate()', () => { - it('should return a trigger/endpoint with appropriate values', () => { - const func = database.ref('foo').onUpdate(() => null); + describe("#onUpdate()", () => { + it("should return a trigger/endpoint with appropriate values", () => { + const func = database.ref("foo").onUpdate(() => null); expect(func.__endpoint).to.deep.equal( - expectedEndpoint( - 'projects/_/instances/subdomain/refs/foo', - 'ref.update' - ) + expectedEndpoint("projects/_/instances/subdomain/refs/foo", "ref.update") ); }); - it('should let developers choose a database instance', () => { + it("should let developers choose a database instance", () => { const func = database - .instance('custom') - .ref('foo') + .instance("custom") + .ref("foo") .onUpdate(() => null); expect(func.__endpoint).to.deep.equal( - expectedEndpoint('projects/_/instances/custom/refs/foo', 'ref.update') + expectedEndpoint("projects/_/instances/custom/refs/foo", "ref.update") ); }); - it('should return a handler that emits events with a proper DataSnapshot', () => { + it("should return a handler that emits events with a proper DataSnapshot", () => { const event = { data: { data: null, - delta: { foo: 'bar' }, + delta: { foo: "bar" }, }, context: { - eventId: '70172329041928', - eventType: - 'providers/google.firebase.database/eventTypes/ref.update', - timestamp: '2018-04-09T07:56:12.975Z', - resource: 'projects/_/instances/subdomains/refs/users', + eventId: "70172329041928", + eventType: "providers/google.firebase.database/eventTypes/ref.update", + timestamp: "2018-04-09T07:56:12.975Z", + resource: "projects/_/instances/subdomains/refs/users", }, }; - const handler = database - .ref('/users/{id}') - .onUpdate((change, context) => { - expect(change.after.val()).to.deep.equal({ foo: 'bar' }); - }); + const handler = database.ref("/users/{id}").onUpdate((change) => { + expect(change.after.val()).to.deep.equal({ foo: "bar" }); + }); return handler(event.data, event.context); }); - it('Should have params of the correct type', () => { - database.ref('foo').onUpdate((event, context) => { + it("Should have params of the correct type", () => { + database.ref("foo").onUpdate((event, context) => { expectType>(context.params); }); - database.ref('foo/{bar}').onUpdate((event, context) => { + database.ref("foo/{bar}").onUpdate((event, context) => { expectType<{ bar: string }>(context.params); }); - database.ref('foo/{bar}/{baz}').onUpdate((event, context) => { + database.ref("foo/{bar}/{baz}").onUpdate((event, context) => { expectType<{ bar: string; baz: string }>(context.params); }); }); }); - describe('#onDelete()', () => { - it('should return a trigger/endpoint with appropriate values', () => { - const func = database.ref('foo').onDelete(() => null); + describe("#onDelete()", () => { + it("should return a trigger/endpoint with appropriate values", () => { + const func = database.ref("foo").onDelete(() => null); expect(func.__endpoint).to.deep.equal( - expectedEndpoint( - 'projects/_/instances/subdomain/refs/foo', - 'ref.delete' - ) + expectedEndpoint("projects/_/instances/subdomain/refs/foo", "ref.delete") ); }); - it('should let developers choose a database instance', () => { + it("should let developers choose a database instance", () => { const func = database - .instance('custom') - .ref('foo') + .instance("custom") + .ref("foo") .onDelete(() => null); expect(func.__endpoint).to.deep.equal( - expectedEndpoint('projects/_/instances/custom/refs/foo', 'ref.delete') + expectedEndpoint("projects/_/instances/custom/refs/foo", "ref.delete") ); }); - it('should return a handler that emits events with a proper DataSnapshot', () => { + it("should return a handler that emits events with a proper DataSnapshot", () => { const event = { data: { - data: { foo: 'bar' }, + data: { foo: "bar" }, delta: null, }, context: { - eventId: '70172329041928', - eventType: - 'providers/google.firebase.database/eventTypes/ref.delete', - timestamp: '2018-04-09T07:56:12.975Z', - resource: 'projects/_/instances/subdomains/refs/users', + eventId: "70172329041928", + eventType: "providers/google.firebase.database/eventTypes/ref.delete", + timestamp: "2018-04-09T07:56:12.975Z", + resource: "projects/_/instances/subdomains/refs/users", }, }; - const handler = database - .ref('/users/{id}') - .onDelete((data, context) => { - expect(data.val()).to.deep.equal({ foo: 'bar' }); - }); + const handler = database.ref("/users/{id}").onDelete((data) => { + expect(data.val()).to.deep.equal({ foo: "bar" }); + }); return handler(event.data, event.context); }); }); - it('Should have params of the correct type', () => { - database.ref('foo').onDelete((event, context) => { + it("Should have params of the correct type", () => { + database.ref("foo").onDelete((event, context) => { expectType>(context.params); }); - database.ref('foo/{bar}').onDelete((event, context) => { + database.ref("foo/{bar}").onDelete((event, context) => { expectType<{ bar: string }>(context.params); }); - database.ref('foo/{bar}/{baz}').onDelete((event, context) => { + database.ref("foo/{bar}/{baz}").onDelete((event, context) => { expectType<{ bar: string; baz: string }>(context.params); }); }); }); - describe('handler namespace', () => { - describe('#onWrite()', () => { - it('correctly sets __endpoint to undefind', () => { + describe("handler namespace", () => { + describe("#onWrite()", () => { + it("correctly sets __endpoint to undefind", () => { const cf = functions.handler.database.ref.onWrite(() => null); expect(cf.__endpoint).to.be.undefined; }); - it('should be able to use the instance entry point', () => { - const func = functions.handler.database.instance.ref.onWrite( - () => null - ); + it("should be able to use the instance entry point", () => { + const func = functions.handler.database.instance.ref.onWrite(() => null); expect(func.__endpoint).to.be.undefined; }); - it('should return a handler that emits events with a proper DataSnapshot', () => { + it("should return a handler that emits events with a proper DataSnapshot", () => { const event = { data: { data: null, - delta: { foo: 'bar' }, + delta: { foo: "bar" }, }, context: { - eventId: '70172329041928', - eventType: - 'providers/google.firebase.database/eventTypes/ref.write', - timestamp: '2018-04-09T07:56:12.975Z', - resource: 'projects/_/instances/subdomains/refs/users', + eventId: "70172329041928", + eventType: "providers/google.firebase.database/eventTypes/ref.write", + timestamp: "2018-04-09T07:56:12.975Z", + resource: "projects/_/instances/subdomains/refs/users", }, }; - const handler = functions.handler.database.ref.onWrite( - (change, context) => { - return expect(change.after.val()).to.deep.equal({ foo: 'bar' }); - } - ); + const handler = functions.handler.database.ref.onWrite((change) => { + return expect(change.after.val()).to.deep.equal({ foo: "bar" }); + }); return handler(event.data, event.context); }); }); - describe('#onCreate()', () => { - it('correctly sets endpoint to undefined', () => { + describe("#onCreate()", () => { + it("correctly sets endpoint to undefined", () => { const cf = functions.handler.database.ref.onCreate(() => null); expect(cf.__endpoint).to.be.undefined; }); - it('should be able to use the instance entry point', () => { - const func = functions.handler.database.instance.ref.onCreate( - () => null - ); + it("should be able to use the instance entry point", () => { + const func = functions.handler.database.instance.ref.onCreate(() => null); expect(func.__endpoint).to.be.undefined; }); - it('should return a handler that emits events with a proper DataSnapshot', () => { + it("should return a handler that emits events with a proper DataSnapshot", () => { const event = { data: { data: null, - delta: { foo: 'bar' }, + delta: { foo: "bar" }, }, context: { - eventId: '70172329041928', - eventType: - 'providers/google.firebase.database/eventTypes/ref.create', - timestamp: '2018-04-09T07:56:12.975Z', - resource: 'projects/_/instances/subdomains/refs/users', + eventId: "70172329041928", + eventType: "providers/google.firebase.database/eventTypes/ref.create", + timestamp: "2018-04-09T07:56:12.975Z", + resource: "projects/_/instances/subdomains/refs/users", }, }; - const handler = functions.handler.database.ref.onCreate( - (data, context) => { - return expect(data.val()).to.deep.equal({ foo: 'bar' }); - } - ); + const handler = functions.handler.database.ref.onCreate((data) => { + return expect(data.val()).to.deep.equal({ foo: "bar" }); + }); return handler(event.data, event.context); }); }); - describe('#onUpdate()', () => { - it('correctly sets endpoint to undefined', () => { + describe("#onUpdate()", () => { + it("correctly sets endpoint to undefined", () => { const cf = functions.handler.database.ref.onUpdate(() => null); expect(cf.__endpoint).to.be.undefined; }); - it('should be able to use the instance entry point', () => { - const func = functions.handler.database.instance.ref.onUpdate( - () => null - ); + it("should be able to use the instance entry point", () => { + const func = functions.handler.database.instance.ref.onUpdate(() => null); expect(func.__endpoint).to.be.undefined; }); - it('should return a handler that emits events with a proper DataSnapshot', () => { + it("should return a handler that emits events with a proper DataSnapshot", () => { const event = { data: { data: null, - delta: { foo: 'bar' }, + delta: { foo: "bar" }, }, context: { - eventId: '70172329041928', - eventType: - 'providers/google.firebase.database/eventTypes/ref.update', - timestamp: '2018-04-09T07:56:12.975Z', - resource: 'projects/_/instances/subdomains/refs/users', + eventId: "70172329041928", + eventType: "providers/google.firebase.database/eventTypes/ref.update", + timestamp: "2018-04-09T07:56:12.975Z", + resource: "projects/_/instances/subdomains/refs/users", }, }; - const handler = functions.handler.database.ref.onUpdate( - (change, context) => { - return expect(change.after.val()).to.deep.equal({ foo: 'bar' }); - } - ); + const handler = functions.handler.database.ref.onUpdate((change) => { + return expect(change.after.val()).to.deep.equal({ foo: "bar" }); + }); return handler(event.data, event.context); }); }); - describe('#onDelete()', () => { - it('correctly sets endpoint to undefined', () => { + describe("#onDelete()", () => { + it("correctly sets endpoint to undefined", () => { const cf = functions.handler.database.ref.onDelete(() => null); expect(cf.__endpoint).to.be.undefined; }); - it('should be able to use the instance entry point', () => { - const func = functions.handler.database.instance.ref.onDelete( - () => null - ); + it("should be able to use the instance entry point", () => { + const func = functions.handler.database.instance.ref.onDelete(() => null); expect(func.__endpoint).to.be.undefined; }); - it('should return a handler that emits events with a proper DataSnapshot', () => { + it("should return a handler that emits events with a proper DataSnapshot", () => { const event = { data: { - data: { foo: 'bar' }, + data: { foo: "bar" }, delta: null, }, context: { - eventId: '70172329041928', - eventType: - 'providers/google.firebase.database/eventTypes/ref.delete', - timestamp: '2018-04-09T07:56:12.975Z', - resource: 'projects/_/instances/subdomains/refs/users', + eventId: "70172329041928", + eventType: "providers/google.firebase.database/eventTypes/ref.delete", + timestamp: "2018-04-09T07:56:12.975Z", + resource: "projects/_/instances/subdomains/refs/users", }, }; - const handler = functions.handler.database.ref.onDelete( - (data, context) => { - return expect(data.val()).to.deep.equal({ foo: 'bar' }); - } - ); + const handler = functions.handler.database.ref.onDelete((data) => { + return expect(data.val()).to.deep.equal({ foo: "bar" }); + }); return handler(event.data, event.context); }); }); }); - describe('process.env.FIREBASE_CONFIG not set', () => { - it('should not throw if __endpoint is not accessed', () => { - expect(() => database.ref('/path').onWrite(() => null)).to.not.throw( - Error - ); + describe("process.env.FIREBASE_CONFIG not set", () => { + it("should not throw if __endpoint is not accessed", () => { + expect(() => database.ref("/path").onWrite(() => null)).to.not.throw(Error); }); - it('should throw when endpoint is accessed', () => { - expect( - () => database.ref('/path').onWrite(() => null).__endpoint - ).to.throw(Error); + it("should throw when endpoint is accessed", () => { + expect(() => database.ref("/path").onWrite(() => null).__endpoint).to.throw(Error); }); - it('should not throw when #run is called', () => { - const cf = database.ref('/path').onWrite(() => null); + it("should not throw when #run is called", () => { + const cf = database.ref("/path").onWrite(() => null); expect(cf.run).to.not.throw(Error); }); }); - describe('extractInstanceAndPath', () => { - it('should return correct us-central prod instance and path strings if domain is missing', () => { + describe("extractInstanceAndPath", () => { + it("should return correct us-central prod instance and path strings if domain is missing", () => { const [instance, path] = database.extractInstanceAndPath( - 'projects/_/instances/foo/refs/bar', + "projects/_/instances/foo/refs/bar", undefined ); - expect(instance).to.equal('https://foo.firebaseio.com'); - expect(path).to.equal('/bar'); + expect(instance).to.equal("https://foo.firebaseio.com"); + expect(path).to.equal("/bar"); }); - it('should return the correct staging instance and path strings if domain is present', () => { + it("should return the correct staging instance and path strings if domain is present", () => { const [instance, path] = database.extractInstanceAndPath( - 'projects/_/instances/foo/refs/bar', - 'firebaseio-staging.com' + "projects/_/instances/foo/refs/bar", + "firebaseio-staging.com" ); - expect(instance).to.equal('https://foo.firebaseio-staging.com'); - expect(path).to.equal('/bar'); + expect(instance).to.equal("https://foo.firebaseio-staging.com"); + expect(path).to.equal("/bar"); }); - it('should return the correct instance and path strings if root path is /refs', () => { + it("should return the correct instance and path strings if root path is /refs", () => { const [instance, path] = database.extractInstanceAndPath( - 'projects/_/instances/foo/refs/refs' + "projects/_/instances/foo/refs/refs" ); - expect(instance).to.equal('https://foo.firebaseio.com'); - expect(path).to.equal('/refs'); + expect(instance).to.equal("https://foo.firebaseio.com"); + expect(path).to.equal("/refs"); }); - it('should return the correct instance and path strings if a child path contain /refs', () => { + it("should return the correct instance and path strings if a child path contain /refs", () => { const [instance, path] = database.extractInstanceAndPath( - 'projects/_/instances/foo/refs/root/refs' + "projects/_/instances/foo/refs/root/refs" ); - expect(instance).to.equal('https://foo.firebaseio.com'); - expect(path).to.equal('/root/refs'); + expect(instance).to.equal("https://foo.firebaseio.com"); + expect(path).to.equal("/root/refs"); }); - it('should return the correct multi-region instance and path strings if domain is present', () => { + it("should return the correct multi-region instance and path strings if domain is present", () => { const [instance, path] = database.extractInstanceAndPath( - 'projects/_/instances/foo/refs/bar', - 'euw1.firebasedatabase.app' + "projects/_/instances/foo/refs/bar", + "euw1.firebasedatabase.app" ); - expect(instance).to.equal('https://foo.euw1.firebasedatabase.app'); - expect(path).to.equal('/bar'); + expect(instance).to.equal("https://foo.euw1.firebasedatabase.app"); + expect(path).to.equal("/bar"); }); - it('should throw an error if the given instance name contains anything except alphanumerics and dashes', () => { + it("should throw an error if the given instance name contains anything except alphanumerics and dashes", () => { expect(() => { return database.extractInstanceAndPath( - 'projects/_/instances/a.bad.name/refs/bar', + "projects/_/instances/a.bad.name/refs/bar", undefined ); }).to.throw(Error); expect(() => { return database.extractInstanceAndPath( - 'projects/_/instances/a_different_bad_name/refs/bar', + "projects/_/instances/a_different_bad_name/refs/bar", undefined ); }).to.throw(Error); expect(() => { - return database.extractInstanceAndPath( - 'projects/_/instances/BAD!!!!/refs/bar', - undefined - ); + return database.extractInstanceAndPath("projects/_/instances/BAD!!!!/refs/bar", undefined); }).to.throw(Error); }); - it('should use the emulator host when present', () => { - process.env.FIREBASE_DATABASE_EMULATOR_HOST = 'localhost:1234'; + it("should use the emulator host when present", () => { + process.env.FIREBASE_DATABASE_EMULATOR_HOST = "localhost:1234"; const [instance, path] = database.extractInstanceAndPath( - 'projects/_/instances/foo/refs/bar', - 'firebaseio-staging.com' + "projects/_/instances/foo/refs/bar", + "firebaseio-staging.com" ); - expect(instance).to.equal('http://localhost:1234/?ns=foo'); - expect(path).to.equal('/bar'); + expect(instance).to.equal("http://localhost:1234/?ns=foo"); + expect(path).to.equal("/bar"); delete process.env.FIREBASE_DATABASE_EMULATOR_HOST; }); }); - describe('DataSnapshot', () => { + describe("DataSnapshot", () => { let subject: any; const populate = (data: any) => { const [instance, path] = database.extractInstanceAndPath( - 'projects/_/instances/other-subdomain/refs/foo', - 'firebaseio-staging.com' + "projects/_/instances/other-subdomain/refs/foo", + "firebaseio-staging.com" ); subject = new database.DataSnapshot(data, path, getApp(), instance); }; - describe('#ref: firebase.database.Reference', () => { - it('should return a ref for correct instance, not the default instance', () => { + describe("#ref: firebase.database.Reference", () => { + it("should return a ref for correct instance, not the default instance", () => { populate({}); - expect(subject.ref.toJSON()).to.equal( - 'https://other-subdomain.firebaseio-staging.com/foo' - ); + expect(subject.ref.toJSON()).to.equal("https://other-subdomain.firebaseio-staging.com/foo"); }); }); - describe('#val(): any', () => { - it('should return child values based on the child path', () => { - populate(applyChange({ a: { b: 'c' } }, { a: { d: 'e' } })); - expect(subject.child('a').val()).to.deep.equal({ b: 'c', d: 'e' }); + describe("#val(): any", () => { + it("should return child values based on the child path", () => { + populate(applyChange({ a: { b: "c" } }, { a: { d: "e" } })); + expect(subject.child("a").val()).to.deep.equal({ b: "c", d: "e" }); }); - it('should return null for children past a leaf', () => { + it("should return null for children past a leaf", () => { populate(applyChange({ a: 23 }, { b: 33 })); - expect(subject.child('a/b').val()).to.be.null; - expect(subject.child('b/c').val()).to.be.null; + expect(subject.child("a/b").val()).to.be.null; + expect(subject.child("b/c").val()).to.be.null; }); - it('should return a leaf value', () => { + it("should return a leaf value", () => { populate(23); expect(subject.val()).to.eq(23); populate({ b: 23, a: null }); - expect(subject.child('b').val()).to.eq(23); + expect(subject.child("b").val()).to.eq(23); }); - it('should coerce object into array if all keys are integers', () => { - populate({ 0: 'a', 1: 'b', 2: { c: 'd' } }); - expect(subject.val()).to.deep.equal(['a', 'b', { c: 'd' }]); - populate({ 0: 'a', 2: 'b', 3: { c: 'd' } }); - expect(subject.val()).to.deep.equal(['a', , 'b', { c: 'd' }]); - populate({ foo: { 0: 'a', 1: 'b' } }); - expect(subject.val()).to.deep.equal({ foo: ['a', 'b'] }); + it("should coerce object into array if all keys are integers", () => { + populate({ 0: "a", 1: "b", 2: { c: "d" } }); + expect(subject.val()).to.deep.equal(["a", "b", { c: "d" }]); + populate({ 0: "a", 2: "b", 3: { c: "d" } }); + expect(subject.val()).to.deep.equal(["a", undefined, "b", { c: "d" }]); + populate({ foo: { 0: "a", 1: "b" } }); + expect(subject.val()).to.deep.equal({ foo: ["a", "b"] }); }); // Regression test: zero-values (including children) were accidentally forwarded as 'null'. - it('should deal with zero-values appropriately', () => { + it("should deal with zero-values appropriately", () => { populate(0); expect(subject.val()).to.equal(0); populate({ myKey: 0 }); @@ -622,11 +569,11 @@ describe('Database Functions', () => { // Regression test: .val() was returning array of nulls when there's a property called length (BUG#37683995) it('should return correct values when data has "length" property', () => { - populate({ length: 3, foo: 'bar' }); - expect(subject.val()).to.deep.equal({ length: 3, foo: 'bar' }); + populate({ length: 3, foo: "bar" }); + expect(subject.val()).to.deep.equal({ length: 3, foo: "bar" }); }); - it('should deal with null-values appropriately', () => { + it("should deal with null-values appropriately", () => { populate(null); expect(subject.val()).to.be.null; @@ -634,7 +581,7 @@ describe('Database Functions', () => { expect(subject.val()).to.be.null; }); - it('should deal with empty object values appropriately', () => { + it("should deal with empty object values appropriately", () => { populate({}); expect(subject.val()).to.be.null; @@ -645,7 +592,7 @@ describe('Database Functions', () => { expect(subject.val()).to.be.null; }); - it('should deal with empty array values appropriately', () => { + it("should deal with empty array values appropriately", () => { populate([]); expect(subject.val()).to.be.null; @@ -666,87 +613,87 @@ describe('Database Functions', () => { }); }); - describe('#child(): DataSnapshot', () => { - it('should work with multiple calls', () => { - populate({ a: { b: { c: 'd' } } }); - expect(subject.child('a').child('b/c').val()).to.equal('d'); + describe("#child(): DataSnapshot", () => { + it("should work with multiple calls", () => { + populate({ a: { b: { c: "d" } } }); + expect(subject.child("a").child("b/c").val()).to.equal("d"); }); }); - describe('#exists(): boolean', () => { - it('should be true for an object value', () => { - populate({ a: { b: 'c' } }); - expect(subject.child('a').exists()).to.be.true; + describe("#exists(): boolean", () => { + it("should be true for an object value", () => { + populate({ a: { b: "c" } }); + expect(subject.child("a").exists()).to.be.true; }); - it('should be true for a leaf value', () => { - populate({ a: { b: 'c' } }); - expect(subject.child('a/b').exists()).to.be.true; + it("should be true for a leaf value", () => { + populate({ a: { b: "c" } }); + expect(subject.child("a/b").exists()).to.be.true; }); - it('should be false for a non-existent value', () => { - populate({ a: { b: 'c', nullChild: null } }); - expect(subject.child('d').exists()).to.be.false; - expect(subject.child('nullChild').exists()).to.be.false; + it("should be false for a non-existent value", () => { + populate({ a: { b: "c", nullChild: null } }); + expect(subject.child("d").exists()).to.be.false; + expect(subject.child("nullChild").exists()).to.be.false; }); - it('should be false for a value pathed beyond a leaf', () => { - populate({ a: { b: 'c' } }); - expect(subject.child('a/b/c').exists()).to.be.false; + it("should be false for a value pathed beyond a leaf", () => { + populate({ a: { b: "c" } }); + expect(subject.child("a/b/c").exists()).to.be.false; }); - it('should be false for an empty object value', () => { + it("should be false for an empty object value", () => { populate({ a: {} }); - expect(subject.child('a').exists()).to.be.false; + expect(subject.child("a").exists()).to.be.false; populate({ a: { child: null } }); - expect(subject.child('a').exists()).to.be.false; + expect(subject.child("a").exists()).to.be.false; populate({ a: { child: {} } }); - expect(subject.child('a').exists()).to.be.false; + expect(subject.child("a").exists()).to.be.false; }); - it('should be false for an empty array value', () => { + it("should be false for an empty array value", () => { populate({ a: [] }); - expect(subject.child('a').exists()).to.be.false; + expect(subject.child("a").exists()).to.be.false; populate({ a: [null] }); - expect(subject.child('a').exists()).to.be.false; + expect(subject.child("a").exists()).to.be.false; populate({ a: [{}] }); - expect(subject.child('a').exists()).to.be.false; + expect(subject.child("a").exists()).to.be.false; }); }); - describe('#forEach(action: (a: DataSnapshot) => boolean): boolean', () => { - it('should iterate through child snapshots', () => { - populate({ a: 'b', c: 'd' }); - let out = ''; + describe("#forEach(action: (a: DataSnapshot) => boolean): boolean", () => { + it("should iterate through child snapshots", () => { + populate({ a: "b", c: "d" }); + let out = ""; subject.forEach((snap: any) => { out += snap.val(); }); - expect(out).to.equal('bd'); + expect(out).to.equal("bd"); }); - it('should have correct key values for child snapshots', () => { - populate({ a: 'b', c: 'd' }); - let out = ''; + it("should have correct key values for child snapshots", () => { + populate({ a: "b", c: "d" }); + let out = ""; subject.forEach((snap: any) => { out += snap.key; }); - expect(out).to.equal('ac'); + expect(out).to.equal("ac"); }); - it('should not execute for leaf or null nodes', () => { + it("should not execute for leaf or null nodes", () => { populate(23); let count = 0; - const counter = (snap: any) => count++; + const counter = () => count++; expect(subject.forEach(counter)).to.equal(false); expect(count).to.eq(0); populate({ - a: 'foo', + a: "foo", nullChild: null, emptyObjectChild: {}, emptyArrayChild: [], @@ -757,46 +704,46 @@ describe('Database Functions', () => { expect(count).to.eq(1); }); - it('should cancel further enumeration if callback returns true', () => { - populate({ a: 'b', c: 'd', e: 'f', g: 'h' }); - let out = ''; + it("should cancel further enumeration if callback returns true", () => { + populate({ a: "b", c: "d", e: "f", g: "h" }); + let out = ""; const ret = subject.forEach((snap: any) => { - if (snap.val() === 'f') { + if (snap.val() === "f") { return true; } out += snap.val(); }); - expect(out).to.equal('bd'); + expect(out).to.equal("bd"); expect(ret).to.equal(true); }); - it('should not cancel further enumeration if callback returns a truthy value', () => { - populate({ a: 'b', c: 'd', e: 'f', g: 'h' }); - let out = ''; + it("should not cancel further enumeration if callback returns a truthy value", () => { + populate({ a: "b", c: "d", e: "f", g: "h" }); + let out = ""; const ret = subject.forEach((snap: any) => { out += snap.val(); return 1; }); - expect(out).to.equal('bdfh'); + expect(out).to.equal("bdfh"); expect(ret).to.equal(false); }); - it('should not cancel further enumeration if callback does not return', () => { - populate({ a: 'b', c: 'd', e: 'f', g: 'h' }); - let out = ''; + it("should not cancel further enumeration if callback does not return", () => { + populate({ a: "b", c: "d", e: "f", g: "h" }); + let out = ""; const ret = subject.forEach((snap: any) => { out += snap.val(); }); - expect(out).to.equal('bdfh'); + expect(out).to.equal("bdfh"); expect(ret).to.equal(false); }); }); - describe('#numChildren()', () => { - it('should be key count for objects', () => { + describe("#numChildren()", () => { + it("should be key count for objects", () => { populate({ - a: 'b', - c: 'd', + a: "b", + c: "d", nullChild: null, emptyObjectChild: {}, emptyArrayChild: [], @@ -804,7 +751,7 @@ describe('Database Functions', () => { expect(subject.numChildren()).to.eq(2); }); - it('should be 0 for non-objects', () => { + it("should be 0 for non-objects", () => { populate(23); expect(subject.numChildren()).to.eq(0); @@ -817,11 +764,11 @@ describe('Database Functions', () => { }); }); - describe('#hasChildren()', () => { - it('should true for objects', () => { + describe("#hasChildren()", () => { + it("should true for objects", () => { populate({ - a: 'b', - c: 'd', + a: "b", + c: "d", nullChild: null, emptyObjectChild: {}, emptyArrayChild: [], @@ -829,7 +776,7 @@ describe('Database Functions', () => { expect(subject.hasChildren()).to.be.true; }); - it('should be false for non-objects', () => { + it("should be false for non-objects", () => { populate(23); expect(subject.hasChildren()).to.be.false; @@ -842,58 +789,53 @@ describe('Database Functions', () => { }); }); - describe('#hasChild(childPath): boolean', () => { - it('should return true for a child or deep child', () => { - populate({ a: { b: 'c' }, d: 23 }); - expect(subject.hasChild('a/b')).to.be.true; - expect(subject.hasChild('d')).to.be.true; + describe("#hasChild(childPath): boolean", () => { + it("should return true for a child or deep child", () => { + populate({ a: { b: "c" }, d: 23 }); + expect(subject.hasChild("a/b")).to.be.true; + expect(subject.hasChild("d")).to.be.true; }); - it('should return false if a child is missing', () => { + it("should return false if a child is missing", () => { populate({ - a: 'b', + a: "b", nullChild: null, emptyObjectChild: {}, emptyArrayChild: [], }); - expect(subject.hasChild('c')).to.be.false; - expect(subject.hasChild('a/b')).to.be.false; - expect(subject.hasChild('nullChild')).to.be.false; - expect(subject.hasChild('emptyObjectChild')).to.be.false; - expect(subject.hasChild('emptyArrayChild')).to.be.false; - expect(subject.hasChild('c')).to.be.false; - expect(subject.hasChild('a/b')).to.be.false; + expect(subject.hasChild("c")).to.be.false; + expect(subject.hasChild("a/b")).to.be.false; + expect(subject.hasChild("nullChild")).to.be.false; + expect(subject.hasChild("emptyObjectChild")).to.be.false; + expect(subject.hasChild("emptyArrayChild")).to.be.false; + expect(subject.hasChild("c")).to.be.false; + expect(subject.hasChild("a/b")).to.be.false; }); }); - describe('#key: string', () => { - it('should return the key name', () => { - expect(subject.key).to.equal('foo'); + describe("#key: string", () => { + it("should return the key name", () => { + expect(subject.key).to.equal("foo"); }); - it('should return null for the root', () => { + it("should return null for the root", () => { const [instance, path] = database.extractInstanceAndPath( - 'projects/_/instances/foo/refs/', + "projects/_/instances/foo/refs/", undefined ); - const snapshot = new database.DataSnapshot( - null, - path, - getApp(), - instance - ); + const snapshot = new database.DataSnapshot(null, path, getApp(), instance); expect(snapshot.key).to.be.null; }); - it('should work for child paths', () => { - expect(subject.child('foo/bar').key).to.equal('bar'); + it("should work for child paths", () => { + expect(subject.child("foo/bar").key).to.equal("bar"); }); }); - describe('#toJSON(): Object', () => { - it('should return the current value', () => { + describe("#toJSON(): Object", () => { + it("should return the current value", () => { populate({ - a: 'b', + a: "b", nullChild: null, emptyObjectChild: {}, emptyArrayChild: [], @@ -901,9 +843,9 @@ describe('Database Functions', () => { expect(subject.toJSON()).to.deep.equal(subject.val()); }); - it('should be stringifyable', () => { + it("should be stringifyable", () => { populate({ - a: 'b', + a: "b", nullChild: null, emptyObjectChild: {}, emptyArrayChild: [], diff --git a/spec/v1/providers/firestore.spec.ts b/spec/v1/providers/firestore.spec.ts index bf6f356bf..21ea7a7fa 100644 --- a/spec/v1/providers/firestore.spec.ts +++ b/spec/v1/providers/firestore.spec.ts @@ -20,20 +20,20 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; -import { Timestamp } from 'firebase-admin/firestore'; +import { expect } from "chai"; +import { Timestamp } from "firebase-admin/firestore"; -import * as functions from '../../../src/v1'; -import * as firestore from '../../../src/v1/providers/firestore'; -import { expectType } from '../../common/metaprogramming'; +import * as functions from "../../../src/v1"; +import * as firestore from "../../../src/v1/providers/firestore"; +import { expectType } from "../../common/metaprogramming"; -describe('Firestore Functions', () => { +describe("Firestore Functions", () => { function constructValue(fields: any) { return { fields, - name: 'projects/pid/databases/(default)/documents/collection/123', - createTime: '2017-06-02T18:48:58.920638Z', - updateTime: '2017-07-02T18:48:58.920638Z', + name: "projects/pid/databases/(default)/documents/collection/123", + createTime: "2017-06-02T18:48:58.920638Z", + updateTime: "2017-07-02T18:48:58.920638Z", }; } @@ -42,19 +42,19 @@ describe('Firestore Functions', () => { return { data, context: { - eventId: '123', - timestamp: '2018-07-03T00:49:04.264Z', - eventType: 'google.firestore.document.create', + eventId: "123", + timestamp: "2018-07-03T00:49:04.264Z", + eventType: "google.firestore.document.create", resource: { - name: 'projects/myproj/databases/(default)/documents/tests/test1', - service: 'service', + name: "projects/myproj/databases/(default)/documents/tests/test1", + service: "service", }, ...context, }, }; } - function constructEvent(oldValue: object, value: object, eventType: string) { + function constructEvent(oldValue: object, value: object) { return { data: { oldValue, @@ -62,7 +62,7 @@ describe('Firestore Functions', () => { }, context: { resource: { - name: 'resource', + name: "resource", }, }, }; @@ -74,7 +74,7 @@ describe('Firestore Functions', () => { booleanValue: false, }, key2: { - integerValue: '111', + integerValue: "111", }, }); } @@ -85,15 +85,15 @@ describe('Firestore Functions', () => { booleanValue: true, }, key2: { - integerValue: '123', + integerValue: "123", }, }); } - describe('document builders and event types', () => { + describe("document builders and event types", () => { function expectedEndpoint(resource: string, eventType: string) { return { - platform: 'gcfv1', + platform: "gcfv1", eventTrigger: { eventFilters: { resource, @@ -106,110 +106,93 @@ describe('Firestore Functions', () => { } before(() => { - process.env.GCLOUD_PROJECT = 'project1'; + process.env.GCLOUD_PROJECT = "project1"; }); after(() => { delete process.env.GCLOUD_PROJECT; }); - it('should allow terse constructors', () => { - const resource = - 'projects/project1/databases/(default)/documents/users/{uid}'; - const cloudFunction = firestore - .document('users/{uid}') - .onWrite((snap, context) => { - expectType<{ uid: string }>(context.params); - }); + it("should allow terse constructors", () => { + const resource = "projects/project1/databases/(default)/documents/users/{uid}"; + const cloudFunction = firestore.document("users/{uid}").onWrite((snap, context) => { + expectType<{ uid: string }>(context.params); + }); - expect(cloudFunction.__endpoint).to.deep.equal( - expectedEndpoint(resource, 'document.write') - ); + expect(cloudFunction.__endpoint).to.deep.equal(expectedEndpoint(resource, "document.write")); }); - it('should allow custom namespaces', () => { - const resource = - 'projects/project1/databases/(default)/documents@v2/users/{uid}'; + it("should allow custom namespaces", () => { + const resource = "projects/project1/databases/(default)/documents@v2/users/{uid}"; const cloudFunction = firestore - .namespace('v2') - .document('users/{uid}') + .namespace("v2") + .document("users/{uid}") .onWrite((snap, context) => { expectType<{ uid: string }>(context.params); }); - expect(cloudFunction.__endpoint).to.deep.equal( - expectedEndpoint(resource, 'document.write') - ); + expect(cloudFunction.__endpoint).to.deep.equal(expectedEndpoint(resource, "document.write")); }); - it('should allow custom databases', () => { - const resource = 'projects/project1/databases/myDB/documents/users/{uid}'; + it("should allow custom databases", () => { + const resource = "projects/project1/databases/myDB/documents/users/{uid}"; const cloudFunction = firestore - .database('myDB') - .document('users/{uid}') + .database("myDB") + .document("users/{uid}") .onWrite(() => null); - expect(cloudFunction.__endpoint).to.deep.equal( - expectedEndpoint(resource, 'document.write') - ); + expect(cloudFunction.__endpoint).to.deep.equal(expectedEndpoint(resource, "document.write")); }); - it('should allow both custom database and namespace', () => { - const resource = - 'projects/project1/databases/myDB/documents@v2/users/{uid}'; + it("should allow both custom database and namespace", () => { + const resource = "projects/project1/databases/myDB/documents@v2/users/{uid}"; const cloudFunction = firestore - .database('myDB') - .namespace('v2') - .document('users/{uid}') + .database("myDB") + .namespace("v2") + .document("users/{uid}") .onWrite((snap, context) => { expectType<{ uid: string }>(context.params); }); - expect(cloudFunction.__endpoint).to.deep.equal( - expectedEndpoint(resource, 'document.write') - ); + expect(cloudFunction.__endpoint).to.deep.equal(expectedEndpoint(resource, "document.write")); }); - it('should allow both region and runtime options to be set', () => { + it("should allow both region and runtime options to be set", () => { const fn = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) - .firestore.document('doc') + .firestore.document("doc") .onCreate((snap, context) => { expectType>(context.params); }); - expect(fn.__endpoint.region).to.deep.equal(['us-east1']); + expect(fn.__endpoint.region).to.deep.equal(["us-east1"]); expect(fn.__endpoint.availableMemoryMb).to.deep.equal(256); expect(fn.__endpoint.timeoutSeconds).to.deep.equal(90); }); }); - describe('process.env.GCLOUD_PROJECT not set', () => { - it('should not throw if __endpoint is not accessed', () => { - expect(() => - firestore.document('input').onCreate(() => null) - ).to.not.throw(Error); + describe("process.env.GCLOUD_PROJECT not set", () => { + it("should not throw if __endpoint is not accessed", () => { + expect(() => firestore.document("input").onCreate(() => null)).to.not.throw(Error); }); - it('should throw when endpoint is accessed', () => { - expect( - () => firestore.document('input').onCreate(() => null).__endpoint - ).to.throw(Error); + it("should throw when endpoint is accessed", () => { + expect(() => firestore.document("input").onCreate(() => null).__endpoint).to.throw(Error); }); - it('should not throw when #run is called', () => { - const cf = firestore.document('input').onCreate(() => null); + it("should not throw when #run is called", () => { + const cf = firestore.document("input").onCreate(() => null); expect(cf.run).to.not.throw(Error); }); }); - describe('dataConstructor', () => { + describe("dataConstructor", () => { before(() => { - process.env.GCLOUD_PROJECT = 'project1'; + process.env.GCLOUD_PROJECT = "project1"; }); after(() => { @@ -217,75 +200,59 @@ describe('Firestore Functions', () => { }); it('constructs appropriate fields and getters for event.data on "document.write" events', () => { - const testFunction = firestore - .document('path') - .onWrite((change, context) => { - expect(change.before.data()).to.deep.equal({ - key1: false, - key2: 111, - }); - expect(change.before.get('key1')).to.equal(false); - expect(change.after.data()).to.deep.equal({ key1: true, key2: 123 }); - expect(change.after.get('key1')).to.equal(true); - return true; // otherwise will get warning about returning undefined + const testFunction = firestore.document("path").onWrite((change) => { + expect(change.before.data()).to.deep.equal({ + key1: false, + key2: 111, }); - const event = constructEvent( - createOldValue(), - createValue(), - 'document.write' - ); + expect(change.before.get("key1")).to.equal(false); + expect(change.after.data()).to.deep.equal({ key1: true, key2: 123 }); + expect(change.after.get("key1")).to.equal(true); + return true; // otherwise will get warning about returning undefined + }); + const event = constructEvent(createOldValue(), createValue()); return testFunction(event.data, event.context); }).timeout(5000); it('constructs appropriate fields and getters for event.data on "document.create" events', () => { - const testFunction = firestore - .document('path') - .onCreate((data, context) => { - expect(data.data()).to.deep.equal({ key1: true, key2: 123 }); - expect(data.get('key1')).to.equal(true); - return true; // otherwise will get warning about returning undefined - }); - const event = constructEvent({}, createValue(), 'document.create'); + const testFunction = firestore.document("path").onCreate((data) => { + expect(data.data()).to.deep.equal({ key1: true, key2: 123 }); + expect(data.get("key1")).to.equal(true); + return true; // otherwise will get warning about returning undefined + }); + const event = constructEvent({}, createValue()); return testFunction(event.data, event.context); }).timeout(5000); it('constructs appropriate fields and getters for event.data on "document.update" events', () => { - const testFunction = firestore - .document('path') - .onUpdate((change, context) => { - expect(change.before.data()).to.deep.equal({ - key1: false, - key2: 111, - }); - expect(change.before.get('key1')).to.equal(false); - expect(change.after.data()).to.deep.equal({ key1: true, key2: 123 }); - expect(change.after.get('key1')).to.equal(true); - return true; // otherwise will get warning about returning undefined + const testFunction = firestore.document("path").onUpdate((change) => { + expect(change.before.data()).to.deep.equal({ + key1: false, + key2: 111, }); - const event = constructEvent( - createOldValue(), - createValue(), - 'document.update' - ); + expect(change.before.get("key1")).to.equal(false); + expect(change.after.data()).to.deep.equal({ key1: true, key2: 123 }); + expect(change.after.get("key1")).to.equal(true); + return true; // otherwise will get warning about returning undefined + }); + const event = constructEvent(createOldValue(), createValue()); return testFunction(event.data, event.context); }).timeout(5000); it('constructs appropriate fields and getters for event.data on "document.delete" events', () => { - const testFunction = firestore - .document('path') - .onDelete((data, context) => { - expect(data.data()).to.deep.equal({ key1: false, key2: 111 }); - expect(data.get('key1')).to.equal(false); - return true; // otherwise will get warning about returning undefined - }); - const event = constructEvent(createOldValue(), {}, 'document.delete'); + const testFunction = firestore.document("path").onDelete((data) => { + expect(data.data()).to.deep.equal({ key1: false, key2: 111 }); + expect(data.get("key1")).to.equal(false); + return true; // otherwise will get warning about returning undefined + }); + const event = constructEvent(createOldValue(), {}); return testFunction(event.data, event.context); }).timeout(5000); }); - describe('handler namespace', () => { + describe("handler namespace", () => { before(() => { - process.env.GCLOUD_PROJECT = 'project1'; + process.env.GCLOUD_PROJECT = "project1"; }); after(() => { @@ -293,84 +260,68 @@ describe('Firestore Functions', () => { }); it('constructs correct data type on "document.write" events', () => { - const testFunction = functions.handler.firestore.document.onWrite( - (change, context) => { - expect(change.before.data()).to.deep.equal({ - key1: false, - key2: 111, - }); - expect(change.before.get('key1')).to.equal(false); - expect(change.after.data()).to.deep.equal({ key1: true, key2: 123 }); - expect(change.after.get('key1')).to.equal(true); - return true; // otherwise will get warning about returning undefined - } - ); - const event = constructEvent( - createOldValue(), - createValue(), - 'document.write' - ); + const testFunction = functions.handler.firestore.document.onWrite((change) => { + expect(change.before.data()).to.deep.equal({ + key1: false, + key2: 111, + }); + expect(change.before.get("key1")).to.equal(false); + expect(change.after.data()).to.deep.equal({ key1: true, key2: 123 }); + expect(change.after.get("key1")).to.equal(true); + return true; // otherwise will get warning about returning undefined + }); + const event = constructEvent(createOldValue(), createValue()); return testFunction(event.data, event.context); }).timeout(5000); it('constructs correct data type on "document.create" events', () => { - const testFunction = functions.handler.firestore.document.onCreate( - (data, context) => { - expect(data.data()).to.deep.equal({ key1: true, key2: 123 }); - expect(data.get('key1')).to.equal(true); - return true; // otherwise will get warning about returning undefined - } - ); - const event = constructEvent({}, createValue(), 'document.create'); + const testFunction = functions.handler.firestore.document.onCreate((data) => { + expect(data.data()).to.deep.equal({ key1: true, key2: 123 }); + expect(data.get("key1")).to.equal(true); + return true; // otherwise will get warning about returning undefined + }); + const event = constructEvent({}, createValue()); return testFunction(event.data, event.context); }).timeout(5000); it('constructs correct data type on "document.update" events', () => { - const testFunction = functions.handler.firestore.document.onUpdate( - (change) => { - expect(change.before.data()).to.deep.equal({ - key1: false, - key2: 111, - }); - expect(change.before.get('key1')).to.equal(false); - expect(change.after.data()).to.deep.equal({ key1: true, key2: 123 }); - expect(change.after.get('key1')).to.equal(true); - return true; // otherwise will get warning about returning undefined - } - ); - const event = constructEvent( - createOldValue(), - createValue(), - 'document.update' - ); + const testFunction = functions.handler.firestore.document.onUpdate((change) => { + expect(change.before.data()).to.deep.equal({ + key1: false, + key2: 111, + }); + expect(change.before.get("key1")).to.equal(false); + expect(change.after.data()).to.deep.equal({ key1: true, key2: 123 }); + expect(change.after.get("key1")).to.equal(true); + return true; // otherwise will get warning about returning undefined + }); + const event = constructEvent(createOldValue(), createValue()); return testFunction(event.data, event.context); }).timeout(5000); it('constructs correct data type on "document.delete" events', () => { - const testFunction = functions.handler.firestore.document.onDelete( - (data, context) => { - expect(data.data()).to.deep.equal({ key1: false, key2: 111 }); - expect(data.get('key1')).to.equal(false); - return true; // otherwise will get warning about returning undefined - } - ); - const event = constructEvent(createOldValue(), {}, 'document.delete'); + const testFunction = functions.handler.firestore.document.onDelete((data) => { + expect(data.data()).to.deep.equal({ key1: false, key2: 111 }); + expect(data.get("key1")).to.equal(false); + return true; // otherwise will get warning about returning undefined + }); + const event = constructEvent(createOldValue(), {}); return testFunction(event.data, event.context); }).timeout(5000); }); - describe('SnapshotConstructor', () => { - describe('#data()', () => { - it('should parse int values', () => { + describe("SnapshotConstructor", () => { + describe("#data()", () => { + it("should parse int values", () => { const snapshot = firestore.snapshotConstructor( makeEvent({ - value: constructValue({ key: { integerValue: '123' } }), + value: constructValue({ key: { integerValue: "123" } }), }) ); expect(snapshot.data()).to.deep.equal({ key: 123 }); }); - it('should parse double values', () => { + it("should parse double values", () => { const snapshot = firestore.snapshotConstructor( makeEvent({ value: constructValue({ key: { doubleValue: 12.34 } }), @@ -379,7 +330,7 @@ describe('Firestore Functions', () => { expect(snapshot.data()).to.deep.equal({ key: 12.34 }); }); - it('should parse null values', () => { + it("should parse null values", () => { const snapshot = firestore.snapshotConstructor( makeEvent({ value: constructValue({ key: { nullValue: null } }), @@ -388,7 +339,7 @@ describe('Firestore Functions', () => { expect(snapshot.data()).to.deep.equal({ key: null }); }); - it('should parse boolean values', () => { + it("should parse boolean values", () => { const snapshot = firestore.snapshotConstructor( makeEvent({ value: constructValue({ key: { booleanValue: true } }), @@ -397,20 +348,20 @@ describe('Firestore Functions', () => { expect(snapshot.data()).to.deep.equal({ key: true }); }); - it('should parse string values', () => { + it("should parse string values", () => { const snapshot = firestore.snapshotConstructor( makeEvent({ - value: constructValue({ key: { stringValue: 'foo' } }), + value: constructValue({ key: { stringValue: "foo" } }), }) ); - expect(snapshot.data()).to.deep.equal({ key: 'foo' }); + expect(snapshot.data()).to.deep.equal({ key: "foo" }); }); - it('should parse array values', () => { + it("should parse array values", () => { const raw = constructValue({ key: { arrayValue: { - values: [{ integerValue: '1' }, { integerValue: '2' }], + values: [{ integerValue: "1" }, { integerValue: "2" }], }, }, }); @@ -422,16 +373,16 @@ describe('Firestore Functions', () => { expect(snapshot.data()).to.deep.equal({ key: [1, 2] }); }); - it('should parse object values', () => { + it("should parse object values", () => { const raw = constructValue({ keyParent: { mapValue: { fields: { key1: { - stringValue: 'val1', + stringValue: "val1", }, key2: { - stringValue: 'val2', + stringValue: "val2", }, }, }, @@ -443,11 +394,11 @@ describe('Firestore Functions', () => { }) ); expect(snapshot.data()).to.deep.equal({ - keyParent: { key1: 'val1', key2: 'val2' }, + keyParent: { key1: "val1", key2: "val2" }, }); }); - it('should parse GeoPoint values', () => { + it("should parse GeoPoint values", () => { const raw = constructValue({ geoPointValue: { mapValue: { @@ -475,11 +426,10 @@ describe('Firestore Functions', () => { }); }); - it('should parse reference values', () => { + it("should parse reference values", () => { const raw = constructValue({ referenceVal: { - referenceValue: - 'projects/proj1/databases/(default)/documents/doc1/id', + referenceValue: "projects/proj1/databases/(default)/documents/doc1/id", }, }); const snapshot = firestore.snapshotConstructor( @@ -487,13 +437,13 @@ describe('Firestore Functions', () => { value: raw, }) ); - expect(snapshot.data()?.referenceVal?.path).to.equal('doc1/id'); + expect(snapshot.data()?.referenceVal?.path).to.equal("doc1/id"); }); - it('should parse timestamp values with precision to the millisecond', () => { + it("should parse timestamp values with precision to the millisecond", () => { const raw = constructValue({ timestampVal: { - timestampValue: '2017-06-13T00:58:40.349Z', + timestampValue: "2017-06-13T00:58:40.349Z", }, }); const snapshot = firestore.snapshotConstructor( @@ -502,16 +452,14 @@ describe('Firestore Functions', () => { }) ); expect(snapshot.data()).to.deep.equal({ - timestampVal: Timestamp.fromDate( - new Date('2017-06-13T00:58:40.349Z') - ), + timestampVal: Timestamp.fromDate(new Date("2017-06-13T00:58:40.349Z")), }); }); - it('should parse timestamp values with precision to the second', () => { + it("should parse timestamp values with precision to the second", () => { const raw = constructValue({ timestampVal: { - timestampValue: '2017-06-13T00:58:40Z', + timestampValue: "2017-06-13T00:58:40Z", }, }); const snapshot = firestore.snapshotConstructor( @@ -520,15 +468,15 @@ describe('Firestore Functions', () => { }) ); expect(snapshot.data()).to.deep.equal({ - timestampVal: Timestamp.fromDate(new Date('2017-06-13T00:58:40Z')), + timestampVal: Timestamp.fromDate(new Date("2017-06-13T00:58:40Z")), }); }); - it('should parse binary values', () => { + it("should parse binary values", () => { // Format defined in https://developers.google.com/discovery/v1/type-format const raw = constructValue({ binaryVal: { - bytesValue: 'Zm9vYmFy', + bytesValue: "Zm9vYmFy", }, }); const snapshot = firestore.snapshotConstructor( @@ -537,12 +485,12 @@ describe('Firestore Functions', () => { }) ); expect(snapshot.data()).to.deep.equal({ - binaryVal: Buffer.from('foobar'), + binaryVal: Buffer.from("foobar"), }); }); }); - describe('Other DocumentSnapshot methods', () => { + describe("Other DocumentSnapshot methods", () => { let snapshot: FirebaseFirestore.DocumentSnapshot; let newSnapshot: FirebaseFirestore.DocumentSnapshot; @@ -550,58 +498,58 @@ describe('Firestore Functions', () => { snapshot = firestore.snapshotConstructor( makeEvent({ value: { - fields: { key: { integerValue: '1' } }, - createTime: '2017-06-17T14:45:17.876479Z', - updateTime: '2017-08-31T18:05:26.928527Z', - readTime: '2017-07-31T18:23:26.928527Z', - name: 'projects/pid/databases/(default)/documents/collection/123', + fields: { key: { integerValue: "1" } }, + createTime: "2017-06-17T14:45:17.876479Z", + updateTime: "2017-08-31T18:05:26.928527Z", + readTime: "2017-07-31T18:23:26.928527Z", + name: "projects/pid/databases/(default)/documents/collection/123", }, }) ); newSnapshot = firestore.snapshotConstructor( makeEvent({ value: { - fields: { key: { integerValue: '2' } }, - createTime: '2017-06-17T14:45:17.876479Z', - updateTime: '2017-06-17T14:45:17.876479Z', - name: 'projects/pid/databases/(default)/documents/collection/124', + fields: { key: { integerValue: "2" } }, + createTime: "2017-06-17T14:45:17.876479Z", + updateTime: "2017-06-17T14:45:17.876479Z", + name: "projects/pid/databases/(default)/documents/collection/124", }, }) ); }); - it('should support #exists', () => { + it("should support #exists", () => { expect(snapshot.exists).to.be.true; }); - it('should support #ref', () => { - expect(snapshot.ref.path).to.equal('collection/123'); + it("should support #ref", () => { + expect(snapshot.ref.path).to.equal("collection/123"); }); - it('should support #id', () => { - expect(snapshot.id).to.equal('123'); + it("should support #id", () => { + expect(snapshot.id).to.equal("123"); }); - it('should support #createTime', () => { - expect(snapshot.createTime.seconds).to.be.a('number'); - expect(snapshot.createTime.nanoseconds).to.be.a('number'); + it("should support #createTime", () => { + expect(snapshot.createTime.seconds).to.be.a("number"); + expect(snapshot.createTime.nanoseconds).to.be.a("number"); }); - it('should support #updateTime', () => { - expect(snapshot.updateTime.seconds).to.be.a('number'); - expect(snapshot.updateTime.nanoseconds).to.be.a('number'); + it("should support #updateTime", () => { + expect(snapshot.updateTime.seconds).to.be.a("number"); + expect(snapshot.updateTime.nanoseconds).to.be.a("number"); }); - it('should support #readTime', () => { - expect(snapshot.readTime.seconds).to.be.a('number'); - expect(snapshot.readTime.nanoseconds).to.be.a('number'); - expect(newSnapshot.readTime.seconds).to.be.a('number'); - expect(newSnapshot.readTime.nanoseconds).to.be.a('number'); + it("should support #readTime", () => { + expect(snapshot.readTime.seconds).to.be.a("number"); + expect(snapshot.readTime.nanoseconds).to.be.a("number"); + expect(newSnapshot.readTime.seconds).to.be.a("number"); + expect(newSnapshot.readTime.nanoseconds).to.be.a("number"); }); }); - describe('Handle empty and non-existent documents', () => { - it('constructs non-existent DocumentSnapshot when whole document deleted', () => { + describe("Handle empty and non-existent documents", () => { + it("constructs non-existent DocumentSnapshot when whole document deleted", () => { const snapshot = firestore.snapshotConstructor( makeEvent( { @@ -609,30 +557,30 @@ describe('Firestore Functions', () => { }, { resource: { - name: 'projects/pid/databases/(default)/documents/collection/123', + name: "projects/pid/databases/(default)/documents/collection/123", }, } ) ); expect(snapshot.exists).to.be.false; - expect(snapshot.ref.path).to.equal('collection/123'); + expect(snapshot.ref.path).to.equal("collection/123"); }); - it('constructs existent DocumentSnapshot with empty data when all fields of document deleted', () => { + it("constructs existent DocumentSnapshot with empty data when all fields of document deleted", () => { const snapshot = firestore.snapshotConstructor( makeEvent({ value: { // value is not empty when document still exists - createTime: '2017-06-02T18:48:58.920638Z', - updateTime: '2017-07-02T18:48:58.920638Z', - name: 'projects/pid/databases/(default)/documents/collection/123', + createTime: "2017-06-02T18:48:58.920638Z", + updateTime: "2017-07-02T18:48:58.920638Z", + name: "projects/pid/databases/(default)/documents/collection/123", }, }) ); expect(snapshot.exists).to.be.true; - expect(snapshot.ref.path).to.equal('collection/123'); + expect(snapshot.ref.path).to.equal("collection/123"); expect(snapshot.data()).to.deep.equal({}); - expect(snapshot.get('key1')).to.equal(undefined); + expect(snapshot.get("key1")).to.equal(undefined); }); }); }); diff --git a/spec/v1/providers/https.spec.ts b/spec/v1/providers/https.spec.ts index b1a9cfa6b..4cd89d912 100644 --- a/spec/v1/providers/https.spec.ts +++ b/spec/v1/providers/https.spec.ts @@ -20,49 +20,46 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; - -import * as functions from '../../../src/v1'; -import * as https from '../../../src/v1/providers/https'; -import { - expectedResponseHeaders, - MockRequest, -} from '../../fixtures/mockrequest'; -import { runHandler } from '../../helper'; - -describe('CloudHttpsBuilder', () => { - describe('#onRequest', () => { - it('should return a trigger with appropriate values', () => { +import { expect } from "chai"; + +import * as functions from "../../../src/v1"; +import * as https from "../../../src/v1/providers/https"; +import { expectedResponseHeaders, MockRequest } from "../../fixtures/mockrequest"; +import { runHandler } from "../../helper"; + +describe("CloudHttpsBuilder", () => { + describe("#onRequest", () => { + it("should return a trigger with appropriate values", () => { const result = https.onRequest((req, resp) => { resp.send(200); }); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", httpsTrigger: {}, }); }); - it('should allow both region and runtime options to be set', () => { + it("should allow both region and runtime options to be set", () => { const fn = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', - invoker: 'private', + memory: "256MB", + invoker: "private", }) .https.onRequest(() => null); - expect(fn.__endpoint.region).to.deep.equal(['us-east1']); + expect(fn.__endpoint.region).to.deep.equal(["us-east1"]); expect(fn.__endpoint.availableMemoryMb).to.deep.equal(256); expect(fn.__endpoint.timeoutSeconds).to.deep.equal(90); - expect(fn.__endpoint.httpsTrigger.invoker).to.deep.equal(['private']); + expect(fn.__endpoint.httpsTrigger.invoker).to.deep.equal(["private"]); }); }); }); -describe('handler namespace', () => { - describe('#onRequest', () => { - it('should return an empty trigger', () => { +describe("handler namespace", () => { + describe("#onRequest", () => { + it("should return an empty trigger", () => { const result = functions.handler.https.onRequest((req, res) => { res.send(200); }); @@ -70,59 +67,59 @@ describe('handler namespace', () => { }); }); - describe('#onCall', () => { - it('should return an empty trigger', () => { + describe("#onCall", () => { + it("should return an empty trigger", () => { const result = functions.handler.https.onCall(() => null); expect(result.__endpoint).to.be.undefined; }); }); }); -describe('#onCall', () => { - it('should return a trigger/endpoint with appropriate values', () => { - const result = https.onCall((data) => { - return 'response'; +describe("#onCall", () => { + it("should return a trigger/endpoint with appropriate values", () => { + const result = https.onCall(() => { + return "response"; }); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", callableTrigger: {}, labels: {}, }); }); - it('should allow both region and runtime options to be set', () => { + it("should allow both region and runtime options to be set", () => { const fn = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) .https.onCall(() => null); - expect(fn.__endpoint.region).to.deep.equal(['us-east1']); + expect(fn.__endpoint.region).to.deep.equal(["us-east1"]); expect(fn.__endpoint.availableMemoryMb).to.deep.equal(256); expect(fn.__endpoint.timeoutSeconds).to.deep.equal(90); }); - it('has a .run method', () => { + it("has a .run method", () => { const cf = https.onCall((d, c) => { return { data: d, context: c }; }); - const data = 'data'; + const data = "data"; const context = { - instanceIdToken: 'token', + instanceIdToken: "token", auth: { - uid: 'abc', - token: 'token', + uid: "abc", + token: "token", }, }; expect(cf.run(data, context)).to.deep.equal({ data, context }); }); // Regression test for firebase-functions#947 - it('should lock to the v1 API even with function.length == 1', async () => { + it("should lock to the v1 API even with function.length == 1", async () => { let gotData: Record; const func = https.onCall((data) => { gotData = data; @@ -130,61 +127,59 @@ describe('#onCall', () => { const req = new MockRequest( { - data: { foo: 'bar' }, + data: { foo: "bar" }, }, { - 'content-type': 'application/json', + "content-type": "application/json", } ); - req.method = 'POST'; + req.method = "POST"; const response = await runHandler(func, req as any); expect(response.status).to.equal(200); - expect(gotData).to.deep.equal({ foo: 'bar' }); + expect(gotData).to.deep.equal({ foo: "bar" }); }); }); -describe('callable CORS', () => { - it('handles OPTIONS preflight', async () => { - const func = https.onCall((data, context) => { - throw new Error( - `This shouldn't have gotten called for an OPTIONS preflight.` - ); +describe("callable CORS", () => { + it("handles OPTIONS preflight", async () => { + const func = https.onCall(() => { + throw new Error(`This shouldn't have gotten called for an OPTIONS preflight.`); }); const req = new MockRequest( {}, { - 'Access-Control-Request-Method': 'POST', - 'Access-Control-Request-Headers': 'origin', - Origin: 'example.com', + "Access-Control-Request-Method": "POST", + "Access-Control-Request-Headers": "origin", + Origin: "example.com", } ); - req.method = 'OPTIONS'; + req.method = "OPTIONS"; const response = await runHandler(func, req as any); expect(response.status).to.equal(204); expect(response.body).to.be.undefined; expect(response.headers).to.deep.equal({ - 'Access-Control-Allow-Methods': 'POST', - 'Content-Length': '0', - Vary: 'Origin, Access-Control-Request-Headers', + "Access-Control-Allow-Methods": "POST", + "Content-Length": "0", + Vary: "Origin, Access-Control-Request-Headers", }); }); - it('adds CORS headers', async () => { - const func = https.onCall((data, context) => 42); + it("adds CORS headers", async () => { + const func = https.onCall(() => 42); const req = new MockRequest( { data: {}, }, { - 'content-type': 'application/json', - origin: 'example.com', + "content-type": "application/json", + origin: "example.com", } ); - req.method = 'POST'; + req.method = "POST"; const response = await runHandler(func, req as any); diff --git a/spec/v1/providers/pubsub.spec.ts b/spec/v1/providers/pubsub.spec.ts index 1809c84ec..63089bb89 100644 --- a/spec/v1/providers/pubsub.spec.ts +++ b/spec/v1/providers/pubsub.spec.ts @@ -20,37 +20,35 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; -import { Event } from '../../../src/v1'; -import * as functions from '../../../src/v1'; -import * as pubsub from '../../../src/v1/providers/pubsub'; - -describe('Pubsub Functions', () => { - describe('pubsub.Message', () => { - describe('#json', () => { - it('should return json decoded from base64', () => { +import { expect } from "chai"; +import { Event } from "../../../src/v1"; +import * as functions from "../../../src/v1"; +import * as pubsub from "../../../src/v1/providers/pubsub"; + +describe("Pubsub Functions", () => { + describe("pubsub.Message", () => { + describe("#json", () => { + it("should return json decoded from base64", () => { const message = new pubsub.Message({ - data: new Buffer('{"hello":"world"}', 'utf8').toString('base64'), + data: new Buffer('{"hello":"world"}', "utf8").toString("base64"), }); - expect(message.json.hello).to.equal('world'); + expect(message.json.hello).to.equal("world"); }); - it('should preserve passed in json', () => { + it("should preserve passed in json", () => { const message = new pubsub.Message({ - data: new Buffer('{"hello":"world"}', 'utf8').toString('base64'), - json: { goodbye: 'world' }, + data: new Buffer('{"hello":"world"}', "utf8").toString("base64"), + json: { goodbye: "world" }, }); - expect(message.json.goodbye).to.equal('world'); + expect(message.json.goodbye).to.equal("world"); }); }); - describe('#toJSON', () => { - it('should be JSON stringify-able', () => { - const encoded = new Buffer('{"hello":"world"}', 'utf8').toString( - 'base64' - ); + describe("#toJSON", () => { + it("should be JSON stringify-able", () => { + const encoded = new Buffer('{"hello":"world"}', "utf8").toString("base64"); const message = new pubsub.Message({ data: encoded, }); @@ -63,41 +61,41 @@ describe('Pubsub Functions', () => { }); }); - describe('pubsub.FunctionBuilder', () => { + describe("pubsub.FunctionBuilder", () => { before(() => { - process.env.GCLOUD_PROJECT = 'project1'; + process.env.GCLOUD_PROJECT = "project1"; }); after(() => { delete process.env.GCLOUD_PROJECT; }); - it('should allow both region and runtime options to be set', () => { + it("should allow both region and runtime options to be set", () => { const fn = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) - .pubsub.topic('toppy') + .pubsub.topic("toppy") .onPublish(() => null); - expect(fn.__endpoint.region).to.deep.equal(['us-east1']); + expect(fn.__endpoint.region).to.deep.equal(["us-east1"]); expect(fn.__endpoint.availableMemoryMb).to.deep.equal(256); expect(fn.__endpoint.timeoutSeconds).to.deep.equal(90); }); - describe('#onPublish', () => { - it('should return a trigger/endpoint with appropriate values', () => { + describe("#onPublish", () => { + it("should return a trigger/endpoint with appropriate values", () => { // Pick up project from process.env.GCLOUD_PROJECT - const result = pubsub.topic('toppy').onPublish(() => null); + const result = pubsub.topic("toppy").onPublish(() => null); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", eventTrigger: { - eventType: 'google.pubsub.topic.publish', + eventType: "google.pubsub.topic.publish", eventFilters: { - resource: 'projects/project1/topics/toppy', + resource: "projects/project1/topics/toppy", }, retry: false, }, @@ -105,31 +103,31 @@ describe('Pubsub Functions', () => { }); }); - it('should throw with improperly formatted topics', () => { - expect(() => pubsub.topic('bad/topic/format')).to.throw(Error); + it("should throw with improperly formatted topics", () => { + expect(() => pubsub.topic("bad/topic/format")).to.throw(Error); }); - it('should properly handle a new-style event', () => { - const raw = new Buffer('{"hello":"world"}', 'utf8').toString('base64'); + it("should properly handle a new-style event", () => { + const raw = new Buffer('{"hello":"world"}', "utf8").toString("base64"); const event: Event = { data: { data: raw, attributes: { - foo: 'bar', + foo: "bar", }, }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: 'google.pubsub.topic.publish', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "google.pubsub.topic.publish", resource: { - service: 'pubsub.googleapis.com', - name: 'projects/project1/topics/toppy', + service: "pubsub.googleapis.com", + name: "projects/project1/topics/toppy", }, }, }; - const result = pubsub.topic('toppy').onPublish((data, context) => { + const result = pubsub.topic("toppy").onPublish((data) => { return { raw: data.data, json: data.json, @@ -137,207 +135,201 @@ describe('Pubsub Functions', () => { }; }); - return expect( - result(event.data, event.context) - ).to.eventually.deep.equal({ + return expect(result(event.data, event.context)).to.eventually.deep.equal({ raw, - json: { hello: 'world' }, - attributes: { foo: 'bar' }, + json: { hello: "world" }, + attributes: { foo: "bar" }, }); }); }); - describe('#schedule', () => { - it('should return a trigger/endpoint with schedule', () => { - const result = pubsub - .schedule('every 5 minutes') - .onRun((context) => null); + describe("#schedule", () => { + it("should return a trigger/endpoint with schedule", () => { + const result = pubsub.schedule("every 5 minutes").onRun(() => null); expect(result.__endpoint.scheduleTrigger).to.deep.equal({ - schedule: 'every 5 minutes', + schedule: "every 5 minutes", }); }); - it('should return a trigger/endpoint with schedule and timeZone when one is chosen', () => { + it("should return a trigger/endpoint with schedule and timeZone when one is chosen", () => { const result = pubsub - .schedule('every 5 minutes') - .timeZone('America/New_York') - .onRun((context) => null); + .schedule("every 5 minutes") + .timeZone("America/New_York") + .onRun(() => null); expect(result.__endpoint.scheduleTrigger).to.deep.equal({ - schedule: 'every 5 minutes', - timeZone: 'America/New_York', + schedule: "every 5 minutes", + timeZone: "America/New_York", }); }); - it('should return a trigger/endpoint with schedule and retry config when called with retryConfig', () => { + it("should return a trigger/endpoint with schedule and retry config when called with retryConfig", () => { const retryConfig = { retryCount: 3, - maxRetryDuration: '10 minutes', - minBackoffDuration: '10 minutes', - maxBackoffDuration: '10 minutes', + maxRetryDuration: "10 minutes", + minBackoffDuration: "10 minutes", + maxBackoffDuration: "10 minutes", maxDoublings: 5, }; const result = pubsub - .schedule('every 5 minutes') + .schedule("every 5 minutes") .retryConfig(retryConfig) .onRun(() => null); expect(result.__endpoint.scheduleTrigger).to.deep.equal({ - schedule: 'every 5 minutes', + schedule: "every 5 minutes", retryConfig, }); expect(result.__endpoint.labels).to.be.empty; }); it( - 'should return a trigger/endpoint with schedule, timeZone and retry config' + - 'when called with retryConfig and timeout', + "should return a trigger/endpoint with schedule, timeZone and retry config" + + "when called with retryConfig and timeout", () => { const retryConfig = { retryCount: 3, - maxRetryDuration: '10 minutes', - minBackoffDuration: '10 minutes', - maxBackoffDuration: '10 minutes', + maxRetryDuration: "10 minutes", + minBackoffDuration: "10 minutes", + maxBackoffDuration: "10 minutes", maxDoublings: 5, }; const result = pubsub - .schedule('every 5 minutes') - .timeZone('America/New_York') + .schedule("every 5 minutes") + .timeZone("America/New_York") .retryConfig(retryConfig) .onRun(() => null); expect(result.__endpoint.scheduleTrigger).to.deep.equal({ - schedule: 'every 5 minutes', + schedule: "every 5 minutes", retryConfig, - timeZone: 'America/New_York', + timeZone: "America/New_York", }); expect(result.__endpoint.labels).to.be.empty; } ); - it('should return an appropriate trigger/endpoint when called with region and options', () => { + it("should return an appropriate trigger/endpoint when called with region and options", () => { const result = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) - .pubsub.schedule('every 5 minutes') + .pubsub.schedule("every 5 minutes") .onRun(() => null); expect(result.__endpoint.scheduleTrigger).to.deep.equal({ - schedule: 'every 5 minutes', + schedule: "every 5 minutes", }); - expect(result.__endpoint.region).to.deep.equal(['us-east1']); + expect(result.__endpoint.region).to.deep.equal(["us-east1"]); expect(result.__endpoint.availableMemoryMb).to.deep.equal(256); expect(result.__endpoint.timeoutSeconds).to.deep.equal(90); }); - it('should return an appropriate trigger/endpoint when called with region, timeZone, and options', () => { + it("should return an appropriate trigger/endpoint when called with region, timeZone, and options", () => { const result = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) - .pubsub.schedule('every 5 minutes') - .timeZone('America/New_York') + .pubsub.schedule("every 5 minutes") + .timeZone("America/New_York") .onRun(() => null); expect(result.__endpoint.scheduleTrigger).to.deep.equal({ - schedule: 'every 5 minutes', - timeZone: 'America/New_York', + schedule: "every 5 minutes", + timeZone: "America/New_York", }); - expect(result.__endpoint.region).to.deep.equal(['us-east1']); + expect(result.__endpoint.region).to.deep.equal(["us-east1"]); expect(result.__endpoint.availableMemoryMb).to.deep.equal(256); expect(result.__endpoint.timeoutSeconds).to.deep.equal(90); }); - it('should return an appropriate trigger/endpoint when called with region, options and retryConfig', () => { + it("should return an appropriate trigger/endpoint when called with region, options and retryConfig", () => { const retryConfig = { retryCount: 3, - maxRetryDuration: '10 minutes', - minBackoffDuration: '10 minutes', - maxBackoffDuration: '10 minutes', + maxRetryDuration: "10 minutes", + minBackoffDuration: "10 minutes", + maxBackoffDuration: "10 minutes", maxDoublings: 5, }; const result = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) - .pubsub.schedule('every 5 minutes') + .pubsub.schedule("every 5 minutes") .retryConfig(retryConfig) .onRun(() => null); expect(result.__endpoint.scheduleTrigger).to.deep.equal({ - schedule: 'every 5 minutes', + schedule: "every 5 minutes", retryConfig, }); - expect(result.__endpoint.region).to.deep.equal(['us-east1']); + expect(result.__endpoint.region).to.deep.equal(["us-east1"]); expect(result.__endpoint.availableMemoryMb).to.deep.equal(256); expect(result.__endpoint.timeoutSeconds).to.deep.equal(90); }); - it('should return an appropriate trigger/endpoint when called with region, options, retryConfig, and timeZone', () => { + it("should return an appropriate trigger/endpoint when called with region, options, retryConfig, and timeZone", () => { const retryConfig = { retryCount: 3, - maxRetryDuration: '10 minutes', - minBackoffDuration: '10 minutes', - maxBackoffDuration: '10 minutes', + maxRetryDuration: "10 minutes", + minBackoffDuration: "10 minutes", + maxBackoffDuration: "10 minutes", maxDoublings: 5, }; const result = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) - .pubsub.schedule('every 5 minutes') - .timeZone('America/New_York') + .pubsub.schedule("every 5 minutes") + .timeZone("America/New_York") .retryConfig(retryConfig) .onRun(() => null); expect(result.__endpoint.scheduleTrigger).to.deep.equal({ - schedule: 'every 5 minutes', - timeZone: 'America/New_York', + schedule: "every 5 minutes", + timeZone: "America/New_York", retryConfig, }); - expect(result.__endpoint.region).to.deep.equal(['us-east1']); + expect(result.__endpoint.region).to.deep.equal(["us-east1"]); expect(result.__endpoint.availableMemoryMb).to.deep.equal(256); expect(result.__endpoint.timeoutSeconds).to.deep.equal(90); }); }); }); - describe('handler namespace', () => { - describe('#onPublish', () => { - describe('#topic', () => { - it('should return an empty trigger', () => { + describe("handler namespace", () => { + describe("#onPublish", () => { + describe("#topic", () => { + it("should return an empty trigger", () => { const result = functions.handler.pubsub.topic.onPublish(() => null); expect(result.__endpoint).to.be.undefined; }); - it('should properly handle a new-style event', () => { - const raw = new Buffer('{"hello":"world"}', 'utf8').toString( - 'base64' - ); + it("should properly handle a new-style event", () => { + const raw = new Buffer('{"hello":"world"}', "utf8").toString("base64"); const event = { data: { data: raw, attributes: { - foo: 'bar', + foo: "bar", }, }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: 'google.pubsub.topic.publish', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "google.pubsub.topic.publish", resource: { - service: 'pubsub.googleapis.com', - name: 'projects/project1/topics/toppy', + service: "pubsub.googleapis.com", + name: "projects/project1/topics/toppy", }, }, }; @@ -350,67 +342,55 @@ describe('Pubsub Functions', () => { }; }); - return expect( - result(event.data, event.context) - ).to.eventually.deep.equal({ + return expect(result(event.data, event.context)).to.eventually.deep.equal({ raw, - json: { hello: 'world' }, - attributes: { foo: 'bar' }, + json: { hello: "world" }, + attributes: { foo: "bar" }, }); }); }); - describe('#schedule', () => { - it('should return an empty trigger', () => { + describe("#schedule", () => { + it("should return an empty trigger", () => { const result = functions.handler.pubsub.schedule.onRun(() => null); expect(result.__endpoint).to.be.undefined; }); - it('should return a handler with a proper event context', () => { - const raw = new Buffer('{"hello":"world"}', 'utf8').toString( - 'base64' - ); + it("should return a handler with a proper event context", () => { + const raw = new Buffer('{"hello":"world"}', "utf8").toString("base64"); const event = { data: { data: raw, attributes: { - foo: 'bar', + foo: "bar", }, }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: 'google.pubsub.topic.publish', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "google.pubsub.topic.publish", resource: { - service: 'pubsub.googleapis.com', - name: 'projects/project1/topics/toppy', + service: "pubsub.googleapis.com", + name: "projects/project1/topics/toppy", }, }, }; - const result = functions.handler.pubsub.schedule.onRun( - (context) => context.eventId - ); - return expect(result(event.data, event.context)).to.eventually.equal( - '70172329041928' - ); + const result = functions.handler.pubsub.schedule.onRun((context) => context.eventId); + return expect(result(event.data, event.context)).to.eventually.equal("70172329041928"); }); }); }); }); - describe('process.env.GCLOUD_PROJECT not set', () => { - it('should not throw if __endpoint is not accessed', () => { - expect(() => pubsub.topic('toppy').onPublish(() => null)).to.not.throw( - Error - ); + describe("process.env.GCLOUD_PROJECT not set", () => { + it("should not throw if __endpoint is not accessed", () => { + expect(() => pubsub.topic("toppy").onPublish(() => null)).to.not.throw(Error); }); - it('should throw when endpoint is accessed', () => { - expect( - () => pubsub.topic('toppy').onPublish(() => null).__endpoint - ).to.throw(Error); + it("should throw when endpoint is accessed", () => { + expect(() => pubsub.topic("toppy").onPublish(() => null).__endpoint).to.throw(Error); }); - it('should not throw when #run is called', () => { - const cf = pubsub.topic('toppy').onPublish(() => null); + it("should not throw when #run is called", () => { + const cf = pubsub.topic("toppy").onPublish(() => null); expect(cf.run).to.not.throw(Error); }); }); diff --git a/spec/v1/providers/remoteConfig.spec.ts b/spec/v1/providers/remoteConfig.spec.ts index f0367916e..b98a784ea 100644 --- a/spec/v1/providers/remoteConfig.spec.ts +++ b/spec/v1/providers/remoteConfig.spec.ts @@ -19,49 +19,45 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; +import { expect } from "chai"; -import * as functions from '../../../src/v1'; -import { - CloudFunction, - Event, - EventContext, -} from '../../../src/v1/cloud-functions'; -import * as remoteConfig from '../../../src/v1/providers/remoteConfig'; +import * as functions from "../../../src/v1"; +import { CloudFunction, Event } from "../../../src/v1/cloud-functions"; +import * as remoteConfig from "../../../src/v1/providers/remoteConfig"; -describe('RemoteConfig Functions', () => { +describe("RemoteConfig Functions", () => { function constructVersion() { return { versionNumber: 1, - updateTime: '2017-07-02T18:48:58.920638Z', + updateTime: "2017-07-02T18:48:58.920638Z", updateUser: { - name: 'Foo Bar', - email: 'foobar@gmail.com', + name: "Foo Bar", + email: "foobar@gmail.com", }, - description: 'test description', - updateOrigin: 'CONSOLE', - updateType: 'INCREMENTAL_UPDATE', + description: "test description", + updateOrigin: "CONSOLE", + updateType: "INCREMENTAL_UPDATE", }; } - describe('#onUpdate', () => { + describe("#onUpdate", () => { before(() => { - process.env.GCLOUD_PROJECT = 'project1'; + process.env.GCLOUD_PROJECT = "project1"; }); after(() => { delete process.env.GCLOUD_PROJECT; }); - it('should have the correct trigger', () => { + it("should have the correct trigger", () => { const cloudFunction = remoteConfig.onUpdate(() => null); expect(cloudFunction.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", eventTrigger: { - eventType: 'google.firebase.remoteconfig.update', + eventType: "google.firebase.remoteconfig.update", eventFilters: { - resource: 'projects/project1', + resource: "projects/project1", }, retry: false, }, @@ -69,41 +65,40 @@ describe('RemoteConfig Functions', () => { }); }); - it('should allow both region and runtime options to be set', () => { + it("should allow both region and runtime options to be set", () => { const cloudFunction = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) .remoteConfig.onUpdate(() => null); - expect(cloudFunction.__endpoint.region).to.deep.equal(['us-east1']); + expect(cloudFunction.__endpoint.region).to.deep.equal(["us-east1"]); expect(cloudFunction.__endpoint.availableMemoryMb).to.deep.equal(256); expect(cloudFunction.__endpoint.timeoutSeconds).to.deep.equal(90); }); }); - describe('unwraps TemplateVersion', () => { + describe("unwraps TemplateVersion", () => { let cloudFunctionUpdate: CloudFunction; let event: Event; before(() => { - process.env.GCLOUD_PROJECT = 'project1'; + process.env.GCLOUD_PROJECT = "project1"; cloudFunctionUpdate = remoteConfig.onUpdate( - (version: remoteConfig.TemplateVersion, context: EventContext) => - version + (version: remoteConfig.TemplateVersion) => version ); event = { data: constructVersion(), context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: 'google.firebase.remoteconfig.update', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "google.firebase.remoteconfig.update", resource: { - service: 'firebaseremoteconfig.googleapis.com', - name: 'projects/project1', + service: "firebaseremoteconfig.googleapis.com", + name: "projects/project1", }, }, }; @@ -113,51 +108,44 @@ describe('RemoteConfig Functions', () => { delete process.env.GCLOUD_PROJECT; }); - it('should unwrap the version in the event', () => { + it("should unwrap the version in the event", () => { return Promise.all([ - cloudFunctionUpdate(event.data, event.context).then( - (data: any, context: any) => { - expect(data).to.deep.equal(constructVersion()); - } - ), + cloudFunctionUpdate(event.data, event.context).then((data: any) => { + expect(data).to.deep.equal(constructVersion()); + }), ]); }); }); - describe('handler namespace', () => { - describe('#onUpdate', () => { - it('should have an empty trigger', () => { - const cloudFunction = functions.handler.remoteConfig.onUpdate( - () => null - ); + describe("handler namespace", () => { + describe("#onUpdate", () => { + it("should have an empty trigger", () => { + const cloudFunction = functions.handler.remoteConfig.onUpdate(() => null); expect(cloudFunction.__endpoint).to.be.undefined; }); - it('should correctly unwrap the event', () => { + it("should correctly unwrap the event", () => { const cloudFunctionUpdate = functions.handler.remoteConfig.onUpdate( - (version: remoteConfig.TemplateVersion, context: EventContext) => - version + (version: remoteConfig.TemplateVersion) => version ); const event: Event = { data: constructVersion(), context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: 'google.firebase.remoteconfig.update', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "google.firebase.remoteconfig.update", resource: { - service: 'firebaseremoteconfig.googleapis.com', - name: 'projects/project1', + service: "firebaseremoteconfig.googleapis.com", + name: "projects/project1", }, }, }; return Promise.all([ - cloudFunctionUpdate(event.data, event.context).then( - (data: any, context: any) => { - expect(data).to.deep.equal(constructVersion()); - } - ), + cloudFunctionUpdate(event.data, event.context).then((data: any) => { + expect(data).to.deep.equal(constructVersion()); + }), ]); }); }); diff --git a/spec/v1/providers/storage.spec.ts b/spec/v1/providers/storage.spec.ts index 12ff2b3bb..13157f155 100644 --- a/spec/v1/providers/storage.spec.ts +++ b/spec/v1/providers/storage.spec.ts @@ -20,17 +20,17 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; -import * as config from '../../../src/common/config'; -import { Event, EventContext } from '../../../src/v1'; -import * as functions from '../../../src/v1'; -import * as storage from '../../../src/v1/providers/storage'; - -describe('Storage Functions', () => { - describe('ObjectBuilder', () => { +import { expect } from "chai"; +import * as config from "../../../src/common/config"; +import { Event } from "../../../src/v1"; +import * as functions from "../../../src/v1"; +import * as storage from "../../../src/v1/providers/storage"; + +describe("Storage Functions", () => { + describe("ObjectBuilder", () => { function expectedEndpoint(bucket: string, eventType: string) { return { - platform: 'gcfv1', + platform: "gcfv1", eventTrigger: { eventFilters: { resource: `projects/_/buckets/${bucket}`, @@ -42,7 +42,7 @@ describe('Storage Functions', () => { }; } - const defaultBucket = 'bucket'; + const defaultBucket = "bucket"; before(() => { config.resetCache({ @@ -54,307 +54,269 @@ describe('Storage Functions', () => { config.resetCache(); }); - it('should allow both region and runtime options to be set', () => { + it("should allow both region and runtime options to be set", () => { const fn = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) .storage.object() .onArchive(() => null); - expect(fn.__endpoint.region).to.deep.equal(['us-east1']); + expect(fn.__endpoint.region).to.deep.equal(["us-east1"]); expect(fn.__endpoint.availableMemoryMb).to.deep.equal(256); expect(fn.__endpoint.timeoutSeconds).to.deep.equal(90); }); - describe('#onArchive', () => { - it('should return a TriggerDefinition with appropriate values', () => { + describe("#onArchive", () => { + it("should return a TriggerDefinition with appropriate values", () => { const cloudFunction = storage - .bucket('bucky') + .bucket("bucky") .object() .onArchive(() => null); - expect(cloudFunction.__endpoint).to.deep.equal( - expectedEndpoint('bucky', 'archive') - ); + expect(cloudFunction.__endpoint).to.deep.equal(expectedEndpoint("bucky", "archive")); }); - it('should use the default bucket when none is provided', () => { + it("should use the default bucket when none is provided", () => { const cloudFunction = storage.object().onArchive(() => null); - expect(cloudFunction.__endpoint).to.deep.equal( - expectedEndpoint(defaultBucket, 'archive') - ); + expect(cloudFunction.__endpoint).to.deep.equal(expectedEndpoint(defaultBucket, "archive")); }); - it('should allow fully qualified bucket names', () => { - const subjectQualified = new storage.ObjectBuilder( - () => 'projects/_/buckets/bucky', - {} - ); + it("should allow fully qualified bucket names", () => { + const subjectQualified = new storage.ObjectBuilder(() => "projects/_/buckets/bucky", {}); const result = subjectQualified.onArchive(() => null); - expect(result.__endpoint).to.deep.equal( - expectedEndpoint('bucky', 'archive') - ); + expect(result.__endpoint).to.deep.equal(expectedEndpoint("bucky", "archive")); }); - it('should throw with improperly formatted buckets', () => { + it("should throw with improperly formatted buckets", () => { expect( () => storage - .bucket('bad/bucket/format') + .bucket("bad/bucket/format") .object() .onArchive(() => null).__endpoint ).to.throw(Error); }); - it('should not mess with media links using non-literal slashes', () => { + it("should not mess with media links using non-literal slashes", () => { const cloudFunction = storage.object().onArchive((data) => { return data.mediaLink; }); const goodMediaLinkEvent: Event = { data: { mediaLink: - 'https://www.googleapis.com/storage/v1/b/mybucket.appspot.com' + - '/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media', + "https://www.googleapis.com/storage/v1/b/mybucket.appspot.com" + + "/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media", }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: 'google.storage.object.archive', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "google.storage.object.archive", resource: { - service: 'storage.googleapis.com', - name: 'projects/_/buckets/bucky', + service: "storage.googleapis.com", + name: "projects/_/buckets/bucky", }, }, }; - return cloudFunction( - goodMediaLinkEvent.data, - goodMediaLinkEvent.context - ).then((result: any, context: EventContext) => { - expect(result).equals(goodMediaLinkEvent.data.mediaLink); - }); + return cloudFunction(goodMediaLinkEvent.data, goodMediaLinkEvent.context).then( + (result: any) => { + expect(result).equals(goodMediaLinkEvent.data.mediaLink); + } + ); }); }); - describe('#onDelete', () => { - it('should return a TriggerDefinition with appropriate values', () => { + describe("#onDelete", () => { + it("should return a TriggerDefinition with appropriate values", () => { const cloudFunction = storage - .bucket('bucky') + .bucket("bucky") .object() .onDelete(() => null); - expect(cloudFunction.__endpoint).to.deep.equal( - expectedEndpoint('bucky', 'delete') - ); + expect(cloudFunction.__endpoint).to.deep.equal(expectedEndpoint("bucky", "delete")); }); - it('should use the default bucket when none is provided', () => { + it("should use the default bucket when none is provided", () => { const cloudFunction = storage.object().onDelete(() => null); - expect(cloudFunction.__endpoint).to.deep.equal( - expectedEndpoint(defaultBucket, 'delete') - ); + expect(cloudFunction.__endpoint).to.deep.equal(expectedEndpoint(defaultBucket, "delete")); }); - it('should allow fully qualified bucket names', () => { - const subjectQualified = new storage.ObjectBuilder( - () => 'projects/_/buckets/bucky', - {} - ); + it("should allow fully qualified bucket names", () => { + const subjectQualified = new storage.ObjectBuilder(() => "projects/_/buckets/bucky", {}); const result = subjectQualified.onDelete(() => null); - expect(result.__endpoint).to.deep.equal( - expectedEndpoint('bucky', 'delete') - ); + expect(result.__endpoint).to.deep.equal(expectedEndpoint("bucky", "delete")); }); - it('should throw with improperly formatted buckets', () => { + it("should throw with improperly formatted buckets", () => { const fn = storage - .bucket('bad/bucket/format') + .bucket("bad/bucket/format") .object() .onDelete(() => null); expect(() => fn.__endpoint).to.throw(Error); }); - it('should not mess with media links using non-literal slashes', () => { + it("should not mess with media links using non-literal slashes", () => { const cloudFunction = storage.object().onDelete((data) => { return data.mediaLink; }); const goodMediaLinkEvent = { data: { mediaLink: - 'https://www.googleapis.com/storage/v1/b/mybucket.appspot.com' + - '/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media', + "https://www.googleapis.com/storage/v1/b/mybucket.appspot.com" + + "/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media", }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: 'google.storage.object.delete', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "google.storage.object.delete", resource: { - service: 'storage.googleapis.com', - name: 'projects/_/buckets/bucky', + service: "storage.googleapis.com", + name: "projects/_/buckets/bucky", }, }, }; - return cloudFunction( - goodMediaLinkEvent.data, - goodMediaLinkEvent.context - ).then((result: any, context: EventContext) => { - expect(result).equals(goodMediaLinkEvent.data.mediaLink); - }); + return cloudFunction(goodMediaLinkEvent.data, goodMediaLinkEvent.context).then( + (result: any) => { + expect(result).equals(goodMediaLinkEvent.data.mediaLink); + } + ); }); }); - describe('#onFinalize', () => { - it('should return a TriggerDefinition with appropriate values', () => { + describe("#onFinalize", () => { + it("should return a TriggerDefinition with appropriate values", () => { const cloudFunction = storage - .bucket('bucky') + .bucket("bucky") .object() .onFinalize(() => null); - expect(cloudFunction.__endpoint).to.deep.equal( - expectedEndpoint('bucky', 'finalize') - ); + expect(cloudFunction.__endpoint).to.deep.equal(expectedEndpoint("bucky", "finalize")); }); - it('should use the default bucket when none is provided', () => { + it("should use the default bucket when none is provided", () => { const cloudFunction = storage.object().onFinalize(() => null); - expect(cloudFunction.__endpoint).to.deep.equal( - expectedEndpoint(defaultBucket, 'finalize') - ); + expect(cloudFunction.__endpoint).to.deep.equal(expectedEndpoint(defaultBucket, "finalize")); }); - it('should allow fully qualified bucket names', () => { - const subjectQualified = new storage.ObjectBuilder( - () => 'projects/_/buckets/bucky', - {} - ); + it("should allow fully qualified bucket names", () => { + const subjectQualified = new storage.ObjectBuilder(() => "projects/_/buckets/bucky", {}); const result = subjectQualified.onFinalize(() => null); - expect(result.__endpoint).to.deep.equal( - expectedEndpoint('bucky', 'finalize') - ); + expect(result.__endpoint).to.deep.equal(expectedEndpoint("bucky", "finalize")); }); - it('should throw with improperly formatted buckets', () => { + it("should throw with improperly formatted buckets", () => { const fn = storage - .bucket('bad/bucket/format') + .bucket("bad/bucket/format") .object() .onFinalize(() => null); expect(() => fn.__endpoint).to.throw(Error); }); - it('should not mess with media links using non-literal slashes', () => { + it("should not mess with media links using non-literal slashes", () => { const cloudFunction = storage.object().onFinalize((data) => { return data.mediaLink; }); const goodMediaLinkEvent = { data: { mediaLink: - 'https://www.googleapis.com/storage/v1/b/mybucket.appspot.com' + - '/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media', + "https://www.googleapis.com/storage/v1/b/mybucket.appspot.com" + + "/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media", }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: 'google.storage.object.finalize', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "google.storage.object.finalize", resource: { - service: 'storage.googleapis.com', - name: 'projects/_/buckets/bucky', + service: "storage.googleapis.com", + name: "projects/_/buckets/bucky", }, }, }; - return cloudFunction( - goodMediaLinkEvent.data, - goodMediaLinkEvent.context - ).then((result: any, context: EventContext) => { - expect(result).equals(goodMediaLinkEvent.data.mediaLink); - }); + return cloudFunction(goodMediaLinkEvent.data, goodMediaLinkEvent.context).then( + (result: any) => { + expect(result).equals(goodMediaLinkEvent.data.mediaLink); + } + ); }); }); - describe('#onMetadataUpdate', () => { - it('should return a TriggerDefinition with appropriate values', () => { + describe("#onMetadataUpdate", () => { + it("should return a TriggerDefinition with appropriate values", () => { const cloudFunction = storage - .bucket('bucky') + .bucket("bucky") .object() .onMetadataUpdate(() => null); - expect(cloudFunction.__endpoint).to.deep.equal( - expectedEndpoint('bucky', 'metadataUpdate') - ); + expect(cloudFunction.__endpoint).to.deep.equal(expectedEndpoint("bucky", "metadataUpdate")); }); - it('should use the default bucket when none is provided', () => { + it("should use the default bucket when none is provided", () => { const cloudFunction = storage.object().onMetadataUpdate(() => null); expect(cloudFunction.__endpoint).to.deep.equal( - expectedEndpoint(defaultBucket, 'metadataUpdate') + expectedEndpoint(defaultBucket, "metadataUpdate") ); }); - it('should allow fully qualified bucket names', () => { - const subjectQualified = new storage.ObjectBuilder( - () => 'projects/_/buckets/bucky', - {} - ); + it("should allow fully qualified bucket names", () => { + const subjectQualified = new storage.ObjectBuilder(() => "projects/_/buckets/bucky", {}); const result = subjectQualified.onMetadataUpdate(() => null); - expect(result.__endpoint).to.deep.equal( - expectedEndpoint('bucky', 'metadataUpdate') - ); + expect(result.__endpoint).to.deep.equal(expectedEndpoint("bucky", "metadataUpdate")); }); - it('should throw with improperly formatted buckets', () => { + it("should throw with improperly formatted buckets", () => { const fn = storage - .bucket('bad/bucket/format') + .bucket("bad/bucket/format") .object() .onMetadataUpdate(() => null); expect(() => fn.__endpoint).to.throw(Error); }); - it('should not mess with media links using non-literal slashes', () => { + it("should not mess with media links using non-literal slashes", () => { const cloudFunction = storage.object().onMetadataUpdate((data) => { return data.mediaLink; }); const goodMediaLinkEvent = { data: { mediaLink: - 'https://www.googleapis.com/storage/v1/b/mybucket.appspot.com' + - '/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media', + "https://www.googleapis.com/storage/v1/b/mybucket.appspot.com" + + "/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media", }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: 'google.storage.object.metadataUpdate', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "google.storage.object.metadataUpdate", resource: { - service: 'storage.googleapis.com', - name: 'projects/_/buckets/bucky', + service: "storage.googleapis.com", + name: "projects/_/buckets/bucky", }, }, }; - return cloudFunction( - goodMediaLinkEvent.data, - goodMediaLinkEvent.context - ).then((result: any, context: EventContext) => { - expect(result).equals(goodMediaLinkEvent.data.mediaLink); - }); + return cloudFunction(goodMediaLinkEvent.data, goodMediaLinkEvent.context).then( + (result: any) => { + expect(result).equals(goodMediaLinkEvent.data.mediaLink); + } + ); }); }); }); - describe('namespace handler', () => { + describe("namespace handler", () => { before(() => { process.env.FIREBASE_CONFIG = JSON.stringify({ - storageBucket: 'bucket', + storageBucket: "bucket", }); }); @@ -362,184 +324,162 @@ describe('Storage Functions', () => { delete process.env.FIREBASE_CONFIG; }); - describe('#onArchive', () => { - it('should return an empty trigger', () => { - const cloudFunction = functions.handler.storage.bucket.onArchive( - () => null - ); + describe("#onArchive", () => { + it("should return an empty trigger", () => { + const cloudFunction = functions.handler.storage.bucket.onArchive(() => null); expect(cloudFunction.__endpoint).to.be.undefined; }); - it('should not mess with media links using non-literal slashes', () => { - const cloudFunction = functions.handler.storage.object.onArchive( - (data) => { - return data.mediaLink; - } - ); + it("should not mess with media links using non-literal slashes", () => { + const cloudFunction = functions.handler.storage.object.onArchive((data) => { + return data.mediaLink; + }); const goodMediaLinkEvent = { data: { mediaLink: - 'https://www.googleapis.com/storage/v1/b/mybucket.appspot.com' + - '/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media', + "https://www.googleapis.com/storage/v1/b/mybucket.appspot.com" + + "/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media", }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: 'google.storage.object.archive', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "google.storage.object.archive", resource: { - service: 'storage.googleapis.com', - name: 'projects/_/buckets/bucky', + service: "storage.googleapis.com", + name: "projects/_/buckets/bucky", }, }, }; - return cloudFunction( - goodMediaLinkEvent.data, - goodMediaLinkEvent.context - ).then((result: any, context: EventContext) => { - expect(result).equals(goodMediaLinkEvent.data.mediaLink); - }); + return cloudFunction(goodMediaLinkEvent.data, goodMediaLinkEvent.context).then( + (result: any) => { + expect(result).equals(goodMediaLinkEvent.data.mediaLink); + } + ); }); }); - describe('#onDelete', () => { - it('should return an empty trigger', () => { - const cloudFunction = functions.handler.storage.bucket.onDelete( - () => null - ); + describe("#onDelete", () => { + it("should return an empty trigger", () => { + const cloudFunction = functions.handler.storage.bucket.onDelete(() => null); expect(cloudFunction.__endpoint).to.be.undefined; }); - it('should not mess with media links using non-literal slashes', () => { - const cloudFunction = functions.handler.storage.object.onDelete( - (data) => { - return data.mediaLink; - } - ); + it("should not mess with media links using non-literal slashes", () => { + const cloudFunction = functions.handler.storage.object.onDelete((data) => { + return data.mediaLink; + }); const goodMediaLinkEvent = { data: { mediaLink: - 'https://www.googleapis.com/storage/v1/b/mybucket.appspot.com' + - '/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media', + "https://www.googleapis.com/storage/v1/b/mybucket.appspot.com" + + "/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media", }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: 'google.storage.object.delete', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "google.storage.object.delete", resource: { - service: 'storage.googleapis.com', - name: 'projects/_/buckets/bucky', + service: "storage.googleapis.com", + name: "projects/_/buckets/bucky", }, }, }; - return cloudFunction( - goodMediaLinkEvent.data, - goodMediaLinkEvent.context - ).then((result: any, context: EventContext) => { - expect(result).equals(goodMediaLinkEvent.data.mediaLink); - }); + return cloudFunction(goodMediaLinkEvent.data, goodMediaLinkEvent.context).then( + (result: any) => { + expect(result).equals(goodMediaLinkEvent.data.mediaLink); + } + ); }); }); - describe('#onFinalize', () => { - it('should return an empty trigger', () => { - const cloudFunction = functions.handler.storage.bucket.onFinalize( - () => null - ); + describe("#onFinalize", () => { + it("should return an empty trigger", () => { + const cloudFunction = functions.handler.storage.bucket.onFinalize(() => null); expect(cloudFunction.__endpoint).to.be.undefined; }); - it('should not mess with media links using non-literal slashes', () => { - const cloudFunction = functions.handler.storage.object.onFinalize( - (data) => { - return data.mediaLink; - } - ); + it("should not mess with media links using non-literal slashes", () => { + const cloudFunction = functions.handler.storage.object.onFinalize((data) => { + return data.mediaLink; + }); const goodMediaLinkEvent = { data: { mediaLink: - 'https://www.googleapis.com/storage/v1/b/mybucket.appspot.com' + - '/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media', + "https://www.googleapis.com/storage/v1/b/mybucket.appspot.com" + + "/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media", }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: 'google.storage.object.finalize', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "google.storage.object.finalize", resource: { - service: 'storage.googleapis.com', - name: 'projects/_/buckets/bucky', + service: "storage.googleapis.com", + name: "projects/_/buckets/bucky", }, }, }; - return cloudFunction( - goodMediaLinkEvent.data, - goodMediaLinkEvent.context - ).then((result: any, context: EventContext) => { - expect(result).equals(goodMediaLinkEvent.data.mediaLink); - }); + return cloudFunction(goodMediaLinkEvent.data, goodMediaLinkEvent.context).then( + (result: any) => { + expect(result).equals(goodMediaLinkEvent.data.mediaLink); + } + ); }); }); - describe('#onMetadataUpdate', () => { - it('should return an empty trigger', () => { - const cloudFunction = functions.handler.storage.bucket.onMetadataUpdate( - () => null - ); + describe("#onMetadataUpdate", () => { + it("should return an empty trigger", () => { + const cloudFunction = functions.handler.storage.bucket.onMetadataUpdate(() => null); expect(cloudFunction.__endpoint).to.be.undefined; }); - it('should not mess with media links using non-literal slashes', () => { - const cloudFunction = functions.handler.storage.object.onMetadataUpdate( - (data) => { - return data.mediaLink; - } - ); + it("should not mess with media links using non-literal slashes", () => { + const cloudFunction = functions.handler.storage.object.onMetadataUpdate((data) => { + return data.mediaLink; + }); const goodMediaLinkEvent = { data: { mediaLink: - 'https://www.googleapis.com/storage/v1/b/mybucket.appspot.com' + - '/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media', + "https://www.googleapis.com/storage/v1/b/mybucket.appspot.com" + + "/o/nestedfolder%2Fanotherfolder%2Fmyobject.file?generation=12345&alt=media", }, context: { - eventId: '70172329041928', - timestamp: '2018-04-09T07:56:12.975Z', - eventType: 'google.storage.object.metadataUpdate', + eventId: "70172329041928", + timestamp: "2018-04-09T07:56:12.975Z", + eventType: "google.storage.object.metadataUpdate", resource: { - service: 'storage.googleapis.com', - name: 'projects/_/buckets/bucky', + service: "storage.googleapis.com", + name: "projects/_/buckets/bucky", }, }, }; - return cloudFunction( - goodMediaLinkEvent.data, - goodMediaLinkEvent.context - ).then((result: any, context: EventContext) => { - expect(result).equals(goodMediaLinkEvent.data.mediaLink); - }); + return cloudFunction(goodMediaLinkEvent.data, goodMediaLinkEvent.context).then( + (result: any) => { + expect(result).equals(goodMediaLinkEvent.data.mediaLink); + } + ); }); }); }); - describe('process.env.FIREBASE_CONFIG not set', () => { + describe("process.env.FIREBASE_CONFIG not set", () => { beforeEach(() => { (config as any).firebaseConfigCache = null; delete process.env.FIREBASE_CONFIG; }); - it('should not throw if __endpoint is not accessed', () => { + it("should not throw if __endpoint is not accessed", () => { expect(() => storage.object().onArchive(() => null)).to.not.throw(Error); }); - it('should throw when endpoint is accessed', () => { - expect(() => storage.object().onArchive(() => null).__endpoint).to.throw( - Error - ); + it("should throw when endpoint is accessed", () => { + expect(() => storage.object().onArchive(() => null).__endpoint).to.throw(Error); }); - it('should not throw when #run is called', () => { + it("should not throw when #run is called", () => { const cf = storage.object().onArchive(() => null); expect(cf.run).to.not.throw(Error); }); diff --git a/spec/v1/providers/tasks.spec.ts b/spec/v1/providers/tasks.spec.ts index 6382e00a4..e58e5810a 100644 --- a/spec/v1/providers/tasks.spec.ts +++ b/spec/v1/providers/tasks.spec.ts @@ -20,15 +20,15 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; +import { expect } from "chai"; -import * as functions from '../../../src/v1'; -import { taskQueue } from '../../../src/v1/providers/tasks'; -import { MockRequest } from '../../fixtures/mockrequest'; -import { runHandler } from '../../helper'; +import * as functions from "../../../src/v1"; +import { taskQueue } from "../../../src/v1/providers/tasks"; +import { MockRequest } from "../../fixtures/mockrequest"; +import { runHandler } from "../../helper"; -describe('#onDispatch', () => { - it('should return a trigger/endpoint with appropriate values', () => { +describe("#onDispatch", () => { + it("should return a trigger/endpoint with appropriate values", () => { const result = taskQueue({ rateLimits: { maxConcurrentDispatches: 30, @@ -41,11 +41,11 @@ describe('#onDispatch', () => { maxDoublings: 3, minBackoffSeconds: 5, }, - invoker: 'private', - }).onDispatch(() => {}); + invoker: "private", + }).onDispatch(() => undefined); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", taskQueueTrigger: { rateLimits: { maxConcurrentDispatches: 30, @@ -58,24 +58,24 @@ describe('#onDispatch', () => { maxDoublings: 3, minBackoffSeconds: 5, }, - invoker: ['private'], + invoker: ["private"], }, }); }); - it('should allow both region and runtime options to be set', () => { + it("should allow both region and runtime options to be set", () => { const fn = functions - .region('us-east1') + .region("us-east1") .runWith({ timeoutSeconds: 90, - memory: '256MB', + memory: "256MB", }) .tasks.taskQueue({ retryConfig: { maxAttempts: 5 } }) .onDispatch(() => null); expect(fn.__endpoint).to.deep.equal({ - platform: 'gcfv1', - region: ['us-east1'], + platform: "gcfv1", + region: ["us-east1"], availableMemoryMb: 256, timeoutSeconds: 90, taskQueueTrigger: { @@ -86,12 +86,12 @@ describe('#onDispatch', () => { }); }); - it('has a .run method', async () => { - const data = 'data'; + it("has a .run method", async () => { + const data = "data"; const context = { auth: { - uid: 'abc', - token: 'token' as any, + uid: "abc", + token: "token" as any, }, }; let done = false; @@ -106,7 +106,7 @@ describe('#onDispatch', () => { }); // Regression test for firebase-functions#947 - it('should lock to the v1 API even with function.length == 1', async () => { + it("should lock to the v1 API even with function.length == 1", async () => { let gotData: Record; const func = taskQueue().onDispatch((data) => { gotData = data; @@ -114,23 +114,23 @@ describe('#onDispatch', () => { const req = new MockRequest( { - data: { foo: 'bar' }, + data: { foo: "bar" }, }, { - 'content-type': 'application/json', - authorization: 'Bearer abc', + "content-type": "application/json", + authorization: "Bearer abc", } ); - req.method = 'POST'; + req.method = "POST"; const response = await runHandler(func, req as any); expect(response.status).to.equal(204); - expect(gotData).to.deep.equal({ foo: 'bar' }); + expect(gotData).to.deep.equal({ foo: "bar" }); }); }); -describe('handler namespace', () => { - it('should return an empty trigger', () => { +describe("handler namespace", () => { + it("should return an empty trigger", () => { const result = functions.handler.tasks.taskQueue.onDispatch(() => null); expect(result.__endpoint).to.be.undefined; }); diff --git a/spec/v1/providers/testLab.spec.ts b/spec/v1/providers/testLab.spec.ts index be2922e4e..e19f79cae 100644 --- a/spec/v1/providers/testLab.spec.ts +++ b/spec/v1/providers/testLab.spec.ts @@ -20,30 +20,30 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; +import { expect } from "chai"; -import * as testLab from '../../../src/v1/providers/testLab'; +import * as testLab from "../../../src/v1/providers/testLab"; -describe('Test Lab Functions', () => { - describe('#onComplete', () => { - describe('with process.env.GCLOUD_PROJECT set', () => { +describe("Test Lab Functions", () => { + describe("#onComplete", () => { + describe("with process.env.GCLOUD_PROJECT set", () => { before(() => { - process.env.GCLOUD_PROJECT = 'project1'; + process.env.GCLOUD_PROJECT = "project1"; }); after(() => { delete process.env.GCLOUD_PROJECT; }); - it('should return a trigger/endpoint with appropriate values', () => { + it("should return a trigger/endpoint with appropriate values", () => { const func = testLab.testMatrix().onComplete(() => null); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv1', + platform: "gcfv1", eventTrigger: { - eventType: 'google.testing.testMatrix.complete', + eventType: "google.testing.testMatrix.complete", eventFilters: { - resource: 'projects/project1/testMatrices/{matrix}', + resource: "projects/project1/testMatrices/{matrix}", }, retry: false, }, @@ -55,168 +55,160 @@ describe('Test Lab Functions', () => { const event = { data: { clientInfo: { - name: 'test', + name: "test", }, - invalidMatrixDetails: 'INVALID_INPUT_APK', + invalidMatrixDetails: "INVALID_INPUT_APK", resultStorage: { googleCloudStorage: { - gcsPath: 'gs://test.appspot.com', + gcsPath: "gs://test.appspot.com", }, }, - state: 'INVALID', - testMatrixId: 'matrix-375mfeu9mnw8t', - timestamp: '2019-04-15T17:43:32.538Z', + state: "INVALID", + testMatrixId: "matrix-375mfeu9mnw8t", + timestamp: "2019-04-15T17:43:32.538Z", }, context: { resource: {}, }, }; const expected = { - testMatrixId: 'matrix-375mfeu9mnw8t', - state: 'INVALID', - createTime: '2019-04-15T17:43:32.538Z', + testMatrixId: "matrix-375mfeu9mnw8t", + state: "INVALID", + createTime: "2019-04-15T17:43:32.538Z", outcomeSummary: undefined, - invalidMatrixDetails: 'INVALID_INPUT_APK', + invalidMatrixDetails: "INVALID_INPUT_APK", resultStorage: { - gcsPath: 'gs://test.appspot.com', + gcsPath: "gs://test.appspot.com", resultsUrl: undefined, toolResultsHistoryId: undefined, toolResultsExecutionId: undefined, } as testLab.ResultStorage, clientInfo: { - name: 'test', + name: "test", details: {}, } as testLab.ClientInfo, } as testLab.TestMatrix; const func = testLab.testMatrix().onComplete((matrix) => matrix); - return expect(func(event.data, event.context)).to.eventually.deep.equal( - expected - ); + return expect(func(event.data, event.context)).to.eventually.deep.equal(expected); }); it('should parse TestMatrix in "FINISHED" state', () => { const event = { data: { clientInfo: { - name: 'test', + name: "test", }, - outcomeSummary: 'FAILURE', + outcomeSummary: "FAILURE", resultStorage: { googleCloudStorage: { - gcsPath: 'gs://test.appspot.com', + gcsPath: "gs://test.appspot.com", }, toolResultsExecution: { - executionId: '6352915701487950333', - historyId: 'bh.9b6f4dac24d3049', - projectId: 'test', + executionId: "6352915701487950333", + historyId: "bh.9b6f4dac24d3049", + projectId: "test", }, toolResultsHistory: { - historyId: 'bh.9b6f4dac24d3049', - projectId: 'test', + historyId: "bh.9b6f4dac24d3049", + projectId: "test", }, - resultsUrl: 'https://path/to/results', + resultsUrl: "https://path/to/results", }, - state: 'FINISHED', - testMatrixId: 'matrix-tsgjk8pnvxhya', - timestamp: '2019-04-15T18:03:11.115Z', + state: "FINISHED", + testMatrixId: "matrix-tsgjk8pnvxhya", + timestamp: "2019-04-15T18:03:11.115Z", }, context: { resource: {}, }, }; const expected = { - testMatrixId: 'matrix-tsgjk8pnvxhya', - state: 'FINISHED', - createTime: '2019-04-15T18:03:11.115Z', - outcomeSummary: 'FAILURE', + testMatrixId: "matrix-tsgjk8pnvxhya", + state: "FINISHED", + createTime: "2019-04-15T18:03:11.115Z", + outcomeSummary: "FAILURE", invalidMatrixDetails: undefined, resultStorage: { - gcsPath: 'gs://test.appspot.com', - toolResultsHistoryId: 'bh.9b6f4dac24d3049', - toolResultsExecutionId: '6352915701487950333', - resultsUrl: 'https://path/to/results', + gcsPath: "gs://test.appspot.com", + toolResultsHistoryId: "bh.9b6f4dac24d3049", + toolResultsExecutionId: "6352915701487950333", + resultsUrl: "https://path/to/results", } as testLab.ResultStorage, clientInfo: { - name: 'test', + name: "test", details: {}, } as testLab.ClientInfo, } as testLab.TestMatrix; const func = testLab.testMatrix().onComplete((matrix) => matrix); - return expect(func(event.data, event.context)).to.eventually.deep.equal( - expected - ); + return expect(func(event.data, event.context)).to.eventually.deep.equal(expected); }); }); - describe('process.env.GCLOUD_PROJECT not set', () => { - it('should not throw if __endpoint is not accessed', () => { - expect(() => testLab.testMatrix().onComplete(() => null)).to.not.throw( - Error - ); + describe("process.env.GCLOUD_PROJECT not set", () => { + it("should not throw if __endpoint is not accessed", () => { + expect(() => testLab.testMatrix().onComplete(() => null)).to.not.throw(Error); }); - it('should throw when endpoint is accessed', () => { - expect( - () => testLab.testMatrix().onComplete(() => null).__endpoint - ).to.throw(Error); + it("should throw when endpoint is accessed", () => { + expect(() => testLab.testMatrix().onComplete(() => null).__endpoint).to.throw(Error); }); }); }); - describe('TestMatrix', () => { - describe('constructor', () => { - it('should populate basic fields', () => { + describe("TestMatrix", () => { + describe("constructor", () => { + it("should populate basic fields", () => { const expected = { - testMatrixId: 'id1', - createTime: '2019-02-08T18:50:32.178Z', - state: 'FINISHED', - outcomeSummary: 'SUCCESS', - invalidMatrixDetails: 'DETAILS_UNAVAILABLE', + testMatrixId: "id1", + createTime: "2019-02-08T18:50:32.178Z", + state: "FINISHED", + outcomeSummary: "SUCCESS", + invalidMatrixDetails: "DETAILS_UNAVAILABLE", resultStorage: new testLab.ResultStorage(), clientInfo: new testLab.ClientInfo(), } as testLab.TestMatrix; const actual = new testLab.TestMatrix({ - testMatrixId: 'id1', - timestamp: '2019-02-08T18:50:32.178Z', - state: 'FINISHED', - outcomeSummary: 'SUCCESS', - invalidMatrixDetails: 'DETAILS_UNAVAILABLE', + testMatrixId: "id1", + timestamp: "2019-02-08T18:50:32.178Z", + state: "FINISHED", + outcomeSummary: "SUCCESS", + invalidMatrixDetails: "DETAILS_UNAVAILABLE", }); expect(actual).to.deep.equal(expected); }); }); }); - describe('ClientInfo', () => { - describe('constructor', () => { - it('should populate basic fields', () => { + describe("ClientInfo", () => { + describe("constructor", () => { + it("should populate basic fields", () => { const expected = { - name: 'client', + name: "client", details: {}, } as testLab.ClientInfo; const actual = new testLab.ClientInfo({ - name: 'client', + name: "client", }); expect(actual).to.deep.equal(expected); }); - it('should populate key/value details', () => { + it("should populate key/value details", () => { const expected = { - name: 'client', + name: "client", details: { - k0: 'v0', - k1: '', + k0: "v0", + k1: "", }, } as testLab.ClientInfo; const actual = new testLab.ClientInfo({ - name: 'client', + name: "client", clientInfoDetails: [ { - key: 'k0', - value: 'v0', + key: "k0", + value: "v0", }, { - key: 'k1', + key: "k1", }, ], }); @@ -225,34 +217,34 @@ describe('Test Lab Functions', () => { }); }); - describe('ResultStorage', () => { - describe('constructor', () => { - it('should populate basic fields', () => { + describe("ResultStorage", () => { + describe("constructor", () => { + it("should populate basic fields", () => { const expected = { - gcsPath: 'path', - toolResultsHistoryId: 'h1', - toolResultsExecutionId: 'e2', - resultsUrl: 'http://example.com/', + gcsPath: "path", + toolResultsHistoryId: "h1", + toolResultsExecutionId: "e2", + resultsUrl: "http://example.com/", } as testLab.ResultStorage; const actual = new testLab.ResultStorage({ googleCloudStorage: { - gcsPath: 'path', + gcsPath: "path", }, toolResultsHistory: { - projectId: 'p1', - historyId: 'h1', + projectId: "p1", + historyId: "h1", }, toolResultsExecution: { - projectId: 'p2', - historyId: 'h2', - executionId: 'e2', + projectId: "p2", + historyId: "h2", + executionId: "e2", }, - resultsUrl: 'http://example.com/', + resultsUrl: "http://example.com/", }); expect(actual).to.deep.equal(expected); }); - it('should not throw on unset fields', () => { + it("should not throw on unset fields", () => { expect(() => new testLab.ResultStorage({})).to.not.throw(); }); }); diff --git a/spec/v1/utils.spec.ts b/spec/v1/utils.spec.ts index d79445d55..0f050ad35 100644 --- a/spec/v1/utils.spec.ts +++ b/spec/v1/utils.spec.ts @@ -20,21 +20,21 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; -import { applyChange } from '../../src/common/utilities/utils'; +import { expect } from "chai"; +import { applyChange } from "../../src/common/utilities/utils"; -describe('utils', () => { - describe('.applyChange(from: any, to: any): any', () => { - it('should return the to value for non-object values of from and to', () => { - expect(applyChange({ a: 'b' }, null)).to.eq(null); - expect(applyChange(null, { a: 'b' })).to.deep.equal({ a: 'b' }); +describe("utils", () => { + describe(".applyChange(from: any, to: any): any", () => { + it("should return the to value for non-object values of from and to", () => { + expect(applyChange({ a: "b" }, null)).to.eq(null); + expect(applyChange(null, { a: "b" })).to.deep.equal({ a: "b" }); expect(applyChange(23, null)).to.be.null; }); - it('should return the merged value of two objects', () => { - const from = { a: { b: 'foo', c: 23, d: 444 }, d: { e: 42 } }; - const to: any = { a: { b: 'bar', c: null }, d: null, e: { f: 'g' } }; - const result = { a: { b: 'bar', d: 444 }, e: { f: 'g' } }; + it("should return the merged value of two objects", () => { + const from = { a: { b: "foo", c: 23, d: 444 }, d: { e: 42 } }; + const to: any = { a: { b: "bar", c: null }, d: null, e: { f: "g" } }; + const result = { a: { b: "bar", d: 444 }, e: { f: "g" } }; expect(applyChange(from, to)).to.deep.equal(result); }); }); diff --git a/spec/v2/params.spec.ts b/spec/v2/params.spec.ts index 9885276cd..d08563f1d 100644 --- a/spec/v2/params.spec.ts +++ b/spec/v2/params.spec.ts @@ -1,4 +1,4 @@ -import { expect } from 'chai'; +import { expect } from "chai"; import { declaredParams, defineBoolean, @@ -7,12 +7,12 @@ import { defineJSON, defineList, defineString, -} from '../../src/v2/params'; -import { ListParam, Param, ParamOptions } from '../../src/v2/params/types'; +} from "../../src/v2/params"; +import { ListParam, Param, ParamOptions } from "../../src/v2/params/types"; -const TEST_PARAM = 'TEST_PARAM'; +const TEST_PARAM = "TEST_PARAM"; -describe('params', () => { +describe("params", () => { beforeEach(() => { delete process.env[TEST_PARAM]; }); @@ -32,19 +32,19 @@ describe('params', () => { tests: [ { title: "should return a '' zero value when no value and no undefined", - expect: '', + expect: "", }, { - title: 'should return the default when no value and one is provided', + title: "should return the default when no value and one is provided", env: undefined, - options: { default: 'test_val' }, - expect: 'test_val', + options: { default: "test_val" }, + expect: "test_val", }, { - title: 'should return the value over the default', - env: 'expected_val', - options: { default: 'default_val' }, - expect: 'expected_val', + title: "should return the value over the default", + env: "expected_val", + options: { default: "default_val" }, + expect: "expected_val", }, ], }, @@ -52,22 +52,22 @@ describe('params', () => { method: defineInt, tests: [ { - title: 'should return 0 zero value', + title: "should return 0 zero value", expect: 0, }, { - title: 'should coerce a matching string into an int', - env: '25', + title: "should coerce a matching string into an int", + env: "25", expect: 25, }, { - title: 'should return a matching default value', + title: "should return a matching default value", options: { default: 10 }, expect: 10, }, { - title: 'should throw when invalid value is passed', - env: 'not_a_number', + title: "should throw when invalid value is passed", + env: "not_a_number", throws: true, }, ], @@ -76,22 +76,22 @@ describe('params', () => { method: defineFloat, tests: [ { - title: 'should return 0 zero value', + title: "should return 0 zero value", expect: 0, }, { - title: 'should coerce a matching string into a float', - env: '3.14', + title: "should coerce a matching string into a float", + env: "3.14", expect: 3.14, }, { - title: 'should return a matching default value', + title: "should return a matching default value", options: { default: 10.1 }, expect: 10.1, }, { - title: 'should throw when invalid value is passed', - env: 'not_a_number', + title: "should throw when invalid value is passed", + env: "not_a_number", throws: true, }, ], @@ -100,61 +100,61 @@ describe('params', () => { method: defineBoolean, tests: [ { - title: 'should return false zero value', + title: "should return false zero value", expect: false, }, { title: 'should coerce "true" into true', - env: 'true', + env: "true", expect: true, }, { title: 'should coerce "TrUe" into true', - env: 'TrUe', + env: "TrUe", expect: true, }, { title: 'should coerce "yes" into true', - env: 'yes', + env: "yes", expect: true, }, { title: 'should coerce "1" into true', - env: '1', + env: "1", expect: true, }, { title: 'should coerce "false" into false', - env: 'false', + env: "false", options: { default: true }, expect: false, }, { title: 'should coerce "FaLsE" into false', - env: 'FaLsE', + env: "FaLsE", options: { default: true }, expect: false, }, { title: 'should coerce "no" into false', - env: 'no', + env: "no", options: { default: true }, expect: false, }, { title: 'should coerce "0" into false', - env: '0', + env: "0", options: { default: true }, expect: false, }, { - title: 'should return a matching default value', + title: "should return a matching default value", options: { default: true }, expect: true, }, { - title: 'should error with non-true/false value', - env: 'foo', + title: "should error with non-true/false value", + env: "foo", throws: true, }, ], @@ -163,24 +163,23 @@ describe('params', () => { method: defineList, tests: [ { - title: 'should return [] zero value', + title: "should return [] zero value", expect: [], }, { - title: 'should coerce comma-separated values into a string list', - env: 'first,second,third', - expect: ['first', 'second', 'third'], + title: "should coerce comma-separated values into a string list", + env: "first,second,third", + expect: ["first", "second", "third"], }, { - title: - 'should coerce a comma-and-space-separated values into a string list', - env: 'first, second, third', - expect: ['first', 'second', 'third'], + title: "should coerce a comma-and-space-separated values into a string list", + env: "first, second, third", + expect: ["first", "second", "third"], }, { - title: 'should return a matching default value', - options: { default: ['a', 'b', 'c'] }, - expect: ['a', 'b', 'c'], + title: "should return a matching default value", + options: { default: ["a", "b", "c"] }, + expect: ["a", "b", "c"], }, ], }, @@ -188,26 +187,26 @@ describe('params', () => { method: defineJSON, tests: [ { - title: 'should return {} zero value', + title: "should return {} zero value", expect: {}, }, { - title: 'should coerce objects from JSON', + title: "should coerce objects from JSON", env: '{"test":123}', expect: { test: 123 }, }, { - title: 'should coerce arrays from JSON', + title: "should coerce arrays from JSON", env: '["test",123]', - expect: ['test', 123], + expect: ["test", 123], }, { - title: 'should return a matching default value', + title: "should return a matching default value", options: { default: { test: 123 } }, expect: { test: 123 }, }, { - title: 'should throw with invalid JSON', + title: "should throw with invalid JSON", env: '{"invalid":json', throws: true, }, @@ -219,54 +218,47 @@ describe('params', () => { describe(`${group.method.name}().value`, () => { for (const test of group.tests) { it(test.title, () => { - if (typeof test.env !== 'undefined') { + if (typeof test.env !== "undefined") { process.env[TEST_PARAM] = test.env; } if (test.throws) { - expect( - () => group.method(TEST_PARAM, test.options).value - ).to.throw(); + expect(() => group.method(TEST_PARAM, test.options).value).to.throw(); } else { - expect(group.method(TEST_PARAM, test.options).value).to.deep.eq( - test.expect - ); + expect(group.method(TEST_PARAM, test.options).value).to.deep.eq(test.expect); } }); } }); } - describe('Param', () => { - describe('#toSpec()', () => { - it('should cast non-string defaults to strings', () => { - expect(new Param(TEST_PARAM, { default: 123 }).toSpec().default).to.eq( - '123' - ); + describe("Param", () => { + describe("#toSpec()", () => { + it("should cast non-string defaults to strings", () => { + expect(new Param(TEST_PARAM, { default: 123 }).toSpec().default).to.eq("123"); }); - it('should passthrough supplied options', () => { - expect( - new Param(TEST_PARAM, { description: 'hello expect' }).toSpec() - .description - ).to.eq('hello expect'); + it("should passthrough supplied options", () => { + expect(new Param(TEST_PARAM, { description: "hello expect" }).toSpec().description).to.eq( + "hello expect" + ); }); - it('ListParam should properly stringify its default', () => { + it("ListParam should properly stringify its default", () => { const spec = new ListParam(TEST_PARAM, { - default: ['a', 'b', 'c'], + default: ["a", "b", "c"], }).toSpec(); - expect(spec.default).to.eq('a,b,c'); + expect(spec.default).to.eq("a,b,c"); }); }); }); - it('should add a param to the declared params', () => { + it("should add a param to the declared params", () => { const param = defineString(TEST_PARAM); expect(declaredParams.find((p) => p === param)).to.eq(param); }); - it('should replace a samed-name param in the declared params', () => { + it("should replace a samed-name param in the declared params", () => { const oldParam = defineString(TEST_PARAM); expect(declaredParams.find((p) => p === oldParam)).to.eq(oldParam); const param = defineString(TEST_PARAM); diff --git a/spec/v2/providers/alerts/alerts.spec.ts b/spec/v2/providers/alerts/alerts.spec.ts index 24daed9e5..6cce70995 100644 --- a/spec/v2/providers/alerts/alerts.spec.ts +++ b/spec/v2/providers/alerts/alerts.spec.ts @@ -1,10 +1,10 @@ -import { expect } from 'chai'; -import * as options from '../../../../src/v2/options'; -import * as alerts from '../../../../src/v2/providers/alerts'; -import { FULL_ENDPOINT, FULL_OPTIONS } from '../fixtures'; +import { expect } from "chai"; +import * as options from "../../../../src/v2/options"; +import * as alerts from "../../../../src/v2/providers/alerts"; +import { FULL_ENDPOINT, FULL_OPTIONS } from "../fixtures"; -const ALERT_TYPE = 'new-alert-type'; -const APPID = '123456789'; +const ALERT_TYPE = "new-alert-type"; +const APPID = "123456789"; const ALERT_EVENT_FILTER = { alerttype: ALERT_TYPE, @@ -15,13 +15,13 @@ const ALERT_APP_EVENT_FILTER = { appid: APPID, }; -describe('alerts', () => { - describe('onAlertPublished', () => { - it('should create the function without opts', () => { +describe("alerts", () => { + describe("onAlertPublished", () => { + it("should create the function without opts", () => { const result = alerts.onAlertPublished(ALERT_TYPE, () => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: alerts.eventType, @@ -31,7 +31,7 @@ describe('alerts', () => { }); }); - it('should create the function with opts', () => { + it("should create the function with opts", () => { const result = alerts.onAlertPublished( { ...FULL_OPTIONS, @@ -51,18 +51,18 @@ describe('alerts', () => { }); }); - it('should have a .run method', () => { + it("should have a .run method", () => { const func = alerts.onAlertPublished(ALERT_TYPE, (event) => event); - const res = func.run('input' as any); + const res = func.run("input" as any); - expect(res).to.equal('input'); + expect(res).to.equal("input"); }); }); - describe('getEndpointAnnotation', () => { + describe("getEndpointAnnotation", () => { beforeEach(() => { - process.env.GCLOUD_PROJECT = 'aProject'; + process.env.GCLOUD_PROJECT = "aProject"; }); afterEach(() => { @@ -70,9 +70,9 @@ describe('alerts', () => { delete process.env.GCLOUD_PROJECT; }); - it('should define the endpoint without appId and opts', () => { + it("should define the endpoint without appId and opts", () => { expect(alerts.getEndpointAnnotation({}, ALERT_TYPE)).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: alerts.eventType, @@ -82,10 +82,8 @@ describe('alerts', () => { }); }); - it('should define a complex endpoint without appId', () => { - expect( - alerts.getEndpointAnnotation({ ...FULL_OPTIONS }, ALERT_TYPE) - ).to.deep.equal({ + it("should define a complex endpoint without appId", () => { + expect(alerts.getEndpointAnnotation({ ...FULL_OPTIONS }, ALERT_TYPE)).to.deep.equal({ ...FULL_ENDPOINT, eventTrigger: { eventType: alerts.eventType, @@ -95,10 +93,8 @@ describe('alerts', () => { }); }); - it('should define a complex endpoint', () => { - expect( - alerts.getEndpointAnnotation({ ...FULL_OPTIONS }, ALERT_TYPE, APPID) - ).to.deep.equal({ + it("should define a complex endpoint", () => { + expect(alerts.getEndpointAnnotation({ ...FULL_OPTIONS }, ALERT_TYPE, APPID)).to.deep.equal({ ...FULL_ENDPOINT, eventTrigger: { eventType: alerts.eventType, @@ -108,24 +104,22 @@ describe('alerts', () => { }); }); - it('should merge global & specific opts', () => { + it("should merge global & specific opts", () => { options.setGlobalOptions({ concurrency: 20, - region: 'europe-west1', + region: "europe-west1", minInstances: 1, }); const specificOpts = { - region: 'us-west1', + region: "us-west1", minInstances: 3, }; - expect( - alerts.getEndpointAnnotation(specificOpts, ALERT_TYPE, APPID) - ).to.deep.equal({ - platform: 'gcfv2', + expect(alerts.getEndpointAnnotation(specificOpts, ALERT_TYPE, APPID)).to.deep.equal({ + platform: "gcfv2", labels: {}, concurrency: 20, - region: ['us-west1'], + region: ["us-west1"], minInstances: 3, eventTrigger: { eventType: alerts.eventType, @@ -136,39 +130,38 @@ describe('alerts', () => { }); }); - describe('getOptsAndAlertTypeAndApp', () => { - it('should parse a string', () => { - const [opts, alertType, appId] = - alerts.getOptsAndAlertTypeAndApp(ALERT_TYPE); + describe("getOptsAndAlertTypeAndApp", () => { + it("should parse a string", () => { + const [opts, alertType, appId] = alerts.getOptsAndAlertTypeAndApp(ALERT_TYPE); expect(opts).to.deep.equal({}); expect(alertType).to.equal(ALERT_TYPE); expect(appId).to.be.undefined; }); - it('should parse an options object without appId', () => { + it("should parse an options object without appId", () => { const myOpts: alerts.FirebaseAlertOptions = { alertType: ALERT_TYPE, - region: 'us-west1', + region: "us-west1", }; const [opts, alertType, appId] = alerts.getOptsAndAlertTypeAndApp(myOpts); - expect(opts).to.deep.equal({ region: 'us-west1' }); + expect(opts).to.deep.equal({ region: "us-west1" }); expect(alertType).to.equal(myOpts.alertType); expect(appId).to.be.undefined; }); - it('should parse an options object with appId', () => { + it("should parse an options object with appId", () => { const myOpts: alerts.FirebaseAlertOptions = { alertType: ALERT_TYPE, appId: APPID, - region: 'us-west1', + region: "us-west1", }; const [opts, alertType, appId] = alerts.getOptsAndAlertTypeAndApp(myOpts); - expect(opts).to.deep.equal({ region: 'us-west1' }); + expect(opts).to.deep.equal({ region: "us-west1" }); expect(alertType).to.equal(myOpts.alertType); expect(appId).to.be.equal(myOpts.appId); }); diff --git a/spec/v2/providers/alerts/appDistribution.spec.ts b/spec/v2/providers/alerts/appDistribution.spec.ts index 9b699bc62..e24e4379a 100644 --- a/spec/v2/providers/alerts/appDistribution.spec.ts +++ b/spec/v2/providers/alerts/appDistribution.spec.ts @@ -1,25 +1,22 @@ -import { expect } from 'chai'; -import * as alerts from '../../../../src/v2/providers/alerts'; -import * as appDistribution from '../../../../src/v2/providers/alerts/appDistribution'; -import { FULL_ENDPOINT, FULL_OPTIONS } from '../fixtures'; +import { expect } from "chai"; +import * as alerts from "../../../../src/v2/providers/alerts"; +import * as appDistribution from "../../../../src/v2/providers/alerts/appDistribution"; +import { FULL_ENDPOINT, FULL_OPTIONS } from "../fixtures"; -const APPID = '123456789'; +const APPID = "123456789"; const myHandler = () => 42; const APP_EVENT_FILTER = { appid: APPID, }; -describe('appDistribution', () => { - describe('onNewTesterIosDevicePublished', () => { - it('should create a function with alertType & appId', () => { - const func = appDistribution.onNewTesterIosDevicePublished( - APPID, - myHandler - ); +describe("appDistribution", () => { + describe("onNewTesterIosDevicePublished", () => { + it("should create a function with alertType & appId", () => { + const func = appDistribution.onNewTesterIosDevicePublished(APPID, myHandler); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: alerts.eventType, @@ -32,11 +29,8 @@ describe('appDistribution', () => { }); }); - it('should create a function with opts', () => { - const func = appDistribution.onNewTesterIosDevicePublished( - { ...FULL_OPTIONS }, - myHandler - ); + it("should create a function with opts", () => { + const func = appDistribution.onNewTesterIosDevicePublished({ ...FULL_OPTIONS }, myHandler); expect(func.__endpoint).to.deep.equal({ ...FULL_ENDPOINT, @@ -50,7 +44,7 @@ describe('appDistribution', () => { }); }); - it('should create a function with appid in opts', () => { + it("should create a function with appid in opts", () => { const func = appDistribution.onNewTesterIosDevicePublished( { ...FULL_OPTIONS, appId: APPID }, myHandler @@ -69,11 +63,11 @@ describe('appDistribution', () => { }); }); - it('should create a function without opts or appId', () => { + it("should create a function without opts or appId", () => { const func = appDistribution.onNewTesterIosDevicePublished(myHandler); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: alerts.eventType, @@ -85,24 +79,21 @@ describe('appDistribution', () => { }); }); - it('should create a function with a run method', () => { - const func = appDistribution.onNewTesterIosDevicePublished( - APPID, - (event) => event - ); + it("should create a function with a run method", () => { + const func = appDistribution.onNewTesterIosDevicePublished(APPID, (event) => event); - const res = func.run('input' as any); + const res = func.run("input" as any); - expect(res).to.equal('input'); + expect(res).to.equal("input"); }); }); - describe('onInAppfeedbackPublished', () => { - it('should create a function with alertType & appId', () => { + describe("onInAppfeedbackPublished", () => { + it("should create a function with alertType & appId", () => { const func = appDistribution.onInAppFeedbackPublished(APPID, myHandler); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: alerts.eventType, @@ -115,11 +106,8 @@ describe('appDistribution', () => { }); }); - it('should create a function with opts', () => { - const func = appDistribution.onInAppFeedbackPublished( - { ...FULL_OPTIONS }, - myHandler - ); + it("should create a function with opts", () => { + const func = appDistribution.onInAppFeedbackPublished({ ...FULL_OPTIONS }, myHandler); expect(func.__endpoint).to.deep.equal({ ...FULL_ENDPOINT, @@ -133,7 +121,7 @@ describe('appDistribution', () => { }); }); - it('should create a function with appid in opts', () => { + it("should create a function with appid in opts", () => { const func = appDistribution.onInAppFeedbackPublished( { ...FULL_OPTIONS, appId: APPID }, myHandler @@ -152,11 +140,11 @@ describe('appDistribution', () => { }); }); - it('should create a function without opts or appId', () => { + it("should create a function without opts or appId", () => { const func = appDistribution.onInAppFeedbackPublished(myHandler); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: alerts.eventType, @@ -168,46 +156,43 @@ describe('appDistribution', () => { }); }); - it('should create a function with a run method', () => { - const func = appDistribution.onInAppFeedbackPublished( - APPID, - (event) => event - ); + it("should create a function with a run method", () => { + const func = appDistribution.onInAppFeedbackPublished(APPID, (event) => event); - const res = func.run('input' as any); + const res = func.run("input" as any); - expect(res).to.equal('input'); + expect(res).to.equal("input"); }); }); - describe('getOptsAndApp', () => { - it('should parse a string', () => { + describe("getOptsAndApp", () => { + it("should parse a string", () => { const [opts, appId] = appDistribution.getOptsAndApp(APPID); expect(opts).to.deep.equal({}); expect(appId).to.equal(APPID); }); - it('should parse an options object without appId', () => { + it("should parse an options object without appId", () => { const myOpts: appDistribution.AppDistributionOptions = { - region: 'us-west1', + region: "us-west1", }; const [opts, appId] = appDistribution.getOptsAndApp(myOpts); - expect(opts).to.deep.equal({ region: 'us-west1' }); + expect(opts).to.deep.equal({ region: "us-west1" }); expect(appId).to.be.undefined; }); - it('should parse an options object with appId', () => { + it("should parse an options object with appId", () => { const myOpts: appDistribution.AppDistributionOptions = { appId: APPID, - region: 'us-west1', + region: "us-west1", }; const [opts, appId] = appDistribution.getOptsAndApp(myOpts); - expect(opts).to.deep.equal({ region: 'us-west1' }); + expect(opts).to.deep.equal({ region: "us-west1" }); expect(appId).to.equal(APPID); }); }); diff --git a/spec/v2/providers/alerts/billing.spec.ts b/spec/v2/providers/alerts/billing.spec.ts index 4bf5f3080..b1a0fb887 100644 --- a/spec/v2/providers/alerts/billing.spec.ts +++ b/spec/v2/providers/alerts/billing.spec.ts @@ -1,18 +1,18 @@ -import { expect } from 'chai'; -import * as alerts from '../../../../src/v2/providers/alerts'; -import * as billing from '../../../../src/v2/providers/alerts/billing'; -import { FULL_ENDPOINT, FULL_OPTIONS } from '../fixtures'; +import { expect } from "chai"; +import * as alerts from "../../../../src/v2/providers/alerts"; +import * as billing from "../../../../src/v2/providers/alerts/billing"; +import { FULL_ENDPOINT, FULL_OPTIONS } from "../fixtures"; -const ALERT_TYPE = 'new-alert-type'; +const ALERT_TYPE = "new-alert-type"; const myHandler = () => 42; -describe('billing', () => { - describe('onPlanUpdatePublished', () => { - it('should create a function with only handler', () => { +describe("billing", () => { + describe("onPlanUpdatePublished", () => { + it("should create a function with only handler", () => { const func = billing.onPlanUpdatePublished(myHandler); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: alerts.eventType, @@ -24,11 +24,8 @@ describe('billing', () => { }); }); - it('should create a function with opts & handler', () => { - const func = billing.onPlanUpdatePublished( - { ...FULL_OPTIONS }, - myHandler - ); + it("should create a function with opts & handler", () => { + const func = billing.onPlanUpdatePublished({ ...FULL_OPTIONS }, myHandler); expect(func.__endpoint).to.deep.equal({ ...FULL_ENDPOINT, @@ -43,12 +40,12 @@ describe('billing', () => { }); }); - describe('onPlanAutomatedUpdatePublished', () => { - it('should create a function with only handler', () => { + describe("onPlanAutomatedUpdatePublished", () => { + it("should create a function with only handler", () => { const func = billing.onPlanAutomatedUpdatePublished(myHandler); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: alerts.eventType, @@ -60,11 +57,8 @@ describe('billing', () => { }); }); - it('should create a function with opts & handler', () => { - const func = billing.onPlanAutomatedUpdatePublished( - { ...FULL_OPTIONS }, - myHandler - ); + it("should create a function with opts & handler", () => { + const func = billing.onPlanAutomatedUpdatePublished({ ...FULL_OPTIONS }, myHandler); expect(func.__endpoint).to.deep.equal({ ...FULL_ENDPOINT, @@ -79,12 +73,12 @@ describe('billing', () => { }); }); - describe('onOperation', () => { - it('should create a function with alertType only', () => { + describe("onOperation", () => { + it("should create a function with alertType only", () => { const func = billing.onOperation(ALERT_TYPE, myHandler, undefined); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: alerts.eventType, @@ -96,12 +90,8 @@ describe('billing', () => { }); }); - it('should create a function with opts', () => { - const func = billing.onOperation( - ALERT_TYPE, - { ...FULL_OPTIONS }, - myHandler - ); + it("should create a function with opts", () => { + const func = billing.onOperation(ALERT_TYPE, { ...FULL_OPTIONS }, myHandler); expect(func.__endpoint).to.deep.equal({ ...FULL_ENDPOINT, @@ -115,12 +105,12 @@ describe('billing', () => { }); }); - it('should create a function with a run method', () => { + it("should create a function with a run method", () => { const func = billing.onOperation(ALERT_TYPE, (event) => event, undefined); - const res = func.run('input' as any); + const res = func.run("input" as any); - expect(res).to.equal('input'); + expect(res).to.equal("input"); }); }); }); diff --git a/spec/v2/providers/alerts/crashlytics.spec.ts b/spec/v2/providers/alerts/crashlytics.spec.ts index 08956d8c7..b8b62ccb4 100644 --- a/spec/v2/providers/alerts/crashlytics.spec.ts +++ b/spec/v2/providers/alerts/crashlytics.spec.ts @@ -1,36 +1,36 @@ -import { expect } from 'chai'; -import * as alerts from '../../../../src/v2/providers/alerts'; -import * as crashlytics from '../../../../src/v2/providers/alerts/crashlytics'; -import { FULL_ENDPOINT, FULL_OPTIONS } from '../fixtures'; +import { expect } from "chai"; +import * as alerts from "../../../../src/v2/providers/alerts"; +import * as crashlytics from "../../../../src/v2/providers/alerts/crashlytics"; +import { FULL_ENDPOINT, FULL_OPTIONS } from "../fixtures"; -const ALERT_TYPE = 'new-alert-type'; -const APPID = '123456789'; +const ALERT_TYPE = "new-alert-type"; +const APPID = "123456789"; const myHandler = () => 42; -describe('crashlytics', () => { +describe("crashlytics", () => { const testcases = [ { - method: 'onNewFatalIssuePublished', + method: "onNewFatalIssuePublished", event: crashlytics.newFatalIssueAlert, }, { - method: 'onNewNonfatalIssuePublished', + method: "onNewNonfatalIssuePublished", event: crashlytics.newNonfatalIssueAlert, }, { - method: 'onRegressionAlertPublished', + method: "onRegressionAlertPublished", event: crashlytics.regressionAlert, }, { - method: 'onStabilityDigestPublished', + method: "onStabilityDigestPublished", event: crashlytics.stabilityDigestAlert, }, { - method: 'onVelocityAlertPublished', + method: "onVelocityAlertPublished", event: crashlytics.velocityAlert, }, { - method: 'onNewAnrIssuePublished', + method: "onNewAnrIssuePublished", event: crashlytics.newAnrIssueAlert, }, ]; @@ -46,11 +46,11 @@ describe('crashlytics', () => { }; describe(method, () => { - it('should create a function only handler', () => { + it("should create a function only handler", () => { const func = crashlytics[method](myHandler); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: alerts.eventType, @@ -60,11 +60,11 @@ describe('crashlytics', () => { }); }); - it('should create a function with appId', () => { + it("should create a function with appId", () => { const func = crashlytics[method](APPID, myHandler); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: alerts.eventType, @@ -74,7 +74,7 @@ describe('crashlytics', () => { }); }); - it('should create a function with base opts', () => { + it("should create a function with base opts", () => { const func = crashlytics[method]({ ...FULL_OPTIONS }, myHandler); expect(func.__endpoint).to.deep.equal({ @@ -87,11 +87,8 @@ describe('crashlytics', () => { }); }); - it('should create a function with opts', () => { - const func = crashlytics[method]( - { ...FULL_OPTIONS, appId: APPID }, - myHandler - ); + it("should create a function with opts", () => { + const func = crashlytics[method]({ ...FULL_OPTIONS, appId: APPID }, myHandler); expect(func.__endpoint).to.deep.equal({ ...FULL_ENDPOINT, @@ -114,12 +111,12 @@ describe('crashlytics', () => { appid: APPID, }; - describe('onOperation', () => { - it('should create a function with alertType only', () => { + describe("onOperation", () => { + it("should create a function with alertType only", () => { const func = crashlytics.onOperation(ALERT_TYPE, myHandler, undefined); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: alerts.eventType, @@ -129,11 +126,11 @@ describe('crashlytics', () => { }); }); - it('should create a function with alertType & appId', () => { + it("should create a function with alertType & appId", () => { const func = crashlytics.onOperation(ALERT_TYPE, APPID, myHandler); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: alerts.eventType, @@ -143,12 +140,8 @@ describe('crashlytics', () => { }); }); - it('should create a function with base opts', () => { - const func = crashlytics.onOperation( - ALERT_TYPE, - { ...FULL_OPTIONS }, - myHandler - ); + it("should create a function with base opts", () => { + const func = crashlytics.onOperation(ALERT_TYPE, { ...FULL_OPTIONS }, myHandler); expect(func.__endpoint).to.deep.equal({ ...FULL_ENDPOINT, @@ -160,7 +153,7 @@ describe('crashlytics', () => { }); }); - it('should create a function with appid in opts', () => { + it("should create a function with appid in opts", () => { const func = crashlytics.onOperation( ALERT_TYPE, { ...FULL_OPTIONS, appId: APPID }, @@ -177,22 +170,18 @@ describe('crashlytics', () => { }); }); - it('should create a function with a run method', () => { - const func = crashlytics.onOperation( - ALERT_TYPE, - (event) => event, - undefined - ); + it("should create a function with a run method", () => { + const func = crashlytics.onOperation(ALERT_TYPE, (event) => event, undefined); - const res = func.run('input' as any); + const res = func.run("input" as any); - expect(res).to.equal('input'); + expect(res).to.equal("input"); }); }); - describe('getOptsAndApp', () => { - it('should parse a string', () => { - const APPID = '123456789'; + describe("getOptsAndApp", () => { + it("should parse a string", () => { + const APPID = "123456789"; const [opts, appId] = crashlytics.getOptsAndApp(APPID); @@ -200,26 +189,26 @@ describe('crashlytics', () => { expect(appId).to.equal(APPID); }); - it('should parse an options object without appId', () => { + it("should parse an options object without appId", () => { const myOpts: crashlytics.CrashlyticsOptions = { - region: 'us-west1', + region: "us-west1", }; const [opts, appId] = crashlytics.getOptsAndApp(myOpts); - expect(opts).to.deep.equal({ region: 'us-west1' }); + expect(opts).to.deep.equal({ region: "us-west1" }); expect(appId).to.be.undefined; }); - it('should parse an options object with appId', () => { + it("should parse an options object with appId", () => { const myOpts: crashlytics.CrashlyticsOptions = { - appId: '123456789', - region: 'us-west1', + appId: "123456789", + region: "us-west1", }; const [opts, appId] = crashlytics.getOptsAndApp(myOpts); - expect(opts).to.deep.equal({ region: 'us-west1' }); + expect(opts).to.deep.equal({ region: "us-west1" }); expect(appId).to.equal(myOpts.appId); }); }); diff --git a/spec/v2/providers/database.spec.ts b/spec/v2/providers/database.spec.ts index 99d2b3911..aed3b44f1 100644 --- a/spec/v2/providers/database.spec.ts +++ b/spec/v2/providers/database.spec.ts @@ -20,185 +20,184 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; -import { PathPattern } from '../../../src/common/utilities/path-pattern'; -import * as database from '../../../src/v2/providers/database'; -import { expectType } from '../../common/metaprogramming'; +import { expect } from "chai"; +import { PathPattern } from "../../../src/common/utilities/path-pattern"; +import * as database from "../../../src/v2/providers/database"; +import { expectType } from "../../common/metaprogramming"; const RAW_RTDB_EVENT: database.RawRTDBCloudEvent = { data: { - ['@type']: - 'type.googleapis.com/google.events.firebase.database.v1.ReferenceEventData', + ["@type"]: "type.googleapis.com/google.events.firebase.database.v1.ReferenceEventData", data: {}, delta: {}, }, - firebasedatabasehost: 'firebaseio.com', - instance: 'my-instance', - ref: 'foo/bar', - location: 'us-central1', - id: 'id', - source: 'source', - specversion: '1.0', - time: 'time', - type: 'type', + firebasedatabasehost: "firebaseio.com", + instance: "my-instance", + ref: "foo/bar", + location: "us-central1", + id: "id", + source: "source", + specversion: "1.0", + time: "time", + type: "type", }; -describe('database', () => { - describe('makeParams', () => { - it('should make params with basic path', () => { +describe("database", () => { + describe("makeParams", () => { + it("should make params with basic path", () => { const event: database.RawRTDBCloudEvent = { ...RAW_RTDB_EVENT, - ref: 'match_a/something/else/nothing/end/match_b', + ref: "match_a/something/else/nothing/end/match_b", }; expect( database.makeParams( event, - new PathPattern('{a}/something/else/*/end/{b}'), - new PathPattern('*') + new PathPattern("{a}/something/else/*/end/{b}"), + new PathPattern("*") ) ).to.deep.equal({ - a: 'match_a', - b: 'match_b', + a: "match_a", + b: "match_b", }); }); - it('should make params with multi segment path', () => { + it("should make params with multi segment path", () => { const event: database.RawRTDBCloudEvent = { ...RAW_RTDB_EVENT, - ref: 'something/is/a/thing/else/match_a/hello/match_b/world', + ref: "something/is/a/thing/else/match_a/hello/match_b/world", }; expect( database.makeParams( event, - new PathPattern('something/**/else/{a}/hello/{b}/world'), - new PathPattern('*') + new PathPattern("something/**/else/{a}/hello/{b}/world"), + new PathPattern("*") ) ).to.deep.equal({ - a: 'match_a', - b: 'match_b', + a: "match_a", + b: "match_b", }); }); - it('should make params with multi segment path capture', () => { + it("should make params with multi segment path capture", () => { const event: database.RawRTDBCloudEvent = { ...RAW_RTDB_EVENT, - ref: 'something/is/a/thing/else/match_a/hello/match_b/world', + ref: "something/is/a/thing/else/match_a/hello/match_b/world", }; expect( database.makeParams( event, - new PathPattern('something/{path=**}/else/{a}/hello/{b}/world'), - new PathPattern('*') + new PathPattern("something/{path=**}/else/{a}/hello/{b}/world"), + new PathPattern("*") ) ).to.deep.equal({ - path: 'is/a/thing', - a: 'match_a', - b: 'match_b', + path: "is/a/thing", + a: "match_a", + b: "match_b", }); }); - it('should make params for a full path and instance', () => { + it("should make params for a full path and instance", () => { const event: database.RawRTDBCloudEvent = { ...RAW_RTDB_EVENT, - ref: 'something/is/a/thing/else/match_a/hello/match_b/world', + ref: "something/is/a/thing/else/match_a/hello/match_b/world", }; expect( database.makeParams( event, - new PathPattern('something/{path=**}/else/{a}/hello/{b}/world'), - new PathPattern('*') + new PathPattern("something/{path=**}/else/{a}/hello/{b}/world"), + new PathPattern("*") ) ).to.deep.equal({ - path: 'is/a/thing', - a: 'match_a', - b: 'match_b', + path: "is/a/thing", + a: "match_a", + b: "match_b", }); }); }); - describe('getOpts', () => { - it('should return opts when passed in a path', () => { - expect(database.getOpts('/foo/{bar}/')).to.deep.equal({ - path: 'foo/{bar}', - instance: '*', + describe("getOpts", () => { + it("should return opts when passed in a path", () => { + expect(database.getOpts("/foo/{bar}/")).to.deep.equal({ + path: "foo/{bar}", + instance: "*", opts: {}, }); }); - it('should return opts when passed in an options object', () => { + it("should return opts when passed in an options object", () => { expect( database.getOpts({ - ref: '/foo/{bar}/', - region: 'us-central1', + ref: "/foo/{bar}/", + region: "us-central1", }) ).to.deep.equal({ - path: 'foo/{bar}', - instance: '*', + path: "foo/{bar}", + instance: "*", opts: { - region: 'us-central1', + region: "us-central1", }, }); }); }); - describe('makeEndpoint', () => { - it('should create an endpoint with an instance wildcard', () => { + describe("makeEndpoint", () => { + it("should create an endpoint with an instance wildcard", () => { const ep = database.makeEndpoint( database.writtenEventType, { - region: 'us-central1', - labels: { 1: '2' }, + region: "us-central1", + labels: { 1: "2" }, }, - new PathPattern('foo/bar'), - new PathPattern('*') + new PathPattern("foo/bar"), + new PathPattern("*") ); expect(ep).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: { - 1: '2', + 1: "2", }, - region: ['us-central1'], + region: ["us-central1"], eventTrigger: { eventType: database.writtenEventType, eventFilters: {}, eventFilterPathPatterns: { - ref: 'foo/bar', - instance: '*', + ref: "foo/bar", + instance: "*", }, retry: false, }, }); }); - it('should create an endpoint without an instance wildcard', () => { + it("should create an endpoint without an instance wildcard", () => { const ep = database.makeEndpoint( database.writtenEventType, { - region: 'us-central1', - labels: { 1: '2' }, + region: "us-central1", + labels: { 1: "2" }, }, - new PathPattern('foo/bar'), - new PathPattern('my-instance') + new PathPattern("foo/bar"), + new PathPattern("my-instance") ); expect(ep).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: { - 1: '2', + 1: "2", }, - region: ['us-central1'], + region: ["us-central1"], eventTrigger: { eventType: database.writtenEventType, eventFilters: { - instance: 'my-instance', + instance: "my-instance", }, eventFilterPathPatterns: { - ref: 'foo/bar', + ref: "foo/bar", }, retry: false, }, @@ -206,77 +205,69 @@ describe('database', () => { }); }); - describe('onChangedOperation', () => { - it('should create a function for a written event', () => { - const func = database.onChangedOperation( - database.writtenEventType, - '/foo/{bar}/', - (event) => 2 - ); + describe("onChangedOperation", () => { + it("should create a function for a written event", () => { + const func = database.onChangedOperation(database.writtenEventType, "/foo/{bar}/", () => 2); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: database.writtenEventType, eventFilters: {}, eventFilterPathPatterns: { - ref: 'foo/{bar}', - instance: '*', + ref: "foo/{bar}", + instance: "*", }, retry: false, }, }); }); - it('should create a function for a updated event', () => { - const func = database.onChangedOperation( - database.updatedEventType, - '/foo/{bar}/', - (event) => 2 - ); + it("should create a function for a updated event", () => { + const func = database.onChangedOperation(database.updatedEventType, "/foo/{bar}/", () => 2); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: database.updatedEventType, eventFilters: {}, eventFilterPathPatterns: { - ref: 'foo/{bar}', - instance: '*', + ref: "foo/{bar}", + instance: "*", }, retry: false, }, }); }); - it('should create a complex function', () => { + it("should create a complex function", () => { const func = database.onChangedOperation( database.writtenEventType, { - ref: '/foo/{path=**}/{bar}/', - instance: 'my-instance', - region: 'us-central1', - cpu: 'gcf_gen1', + ref: "/foo/{path=**}/{bar}/", + instance: "my-instance", + region: "us-central1", + cpu: "gcf_gen1", minInstances: 2, }, - (event) => 2 + () => 2 ); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', - cpu: 'gcf_gen1', + platform: "gcfv2", + cpu: "gcf_gen1", minInstances: 2, - region: ['us-central1'], + region: ["us-central1"], labels: {}, eventTrigger: { eventType: database.writtenEventType, eventFilters: { - instance: 'my-instance', + instance: "my-instance", }, eventFilterPathPatterns: { - ref: 'foo/{path=**}/{bar}', + ref: "foo/{path=**}/{bar}", }, retry: false, }, @@ -284,77 +275,69 @@ describe('database', () => { }); }); - describe('onOperation', () => { - it('should create a function for a created event', () => { - const func = database.onOperation( - database.createdEventType, - '/foo/{bar}/', - (event) => 2 - ); + describe("onOperation", () => { + it("should create a function for a created event", () => { + const func = database.onOperation(database.createdEventType, "/foo/{bar}/", () => 2); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: database.createdEventType, eventFilters: {}, eventFilterPathPatterns: { - ref: 'foo/{bar}', - instance: '*', + ref: "foo/{bar}", + instance: "*", }, retry: false, }, }); }); - it('should create a function for a deleted event', () => { - const func = database.onOperation( - database.deletedEventType, - '/foo/{bar}/', - (event) => 2 - ); + it("should create a function for a deleted event", () => { + const func = database.onOperation(database.deletedEventType, "/foo/{bar}/", () => 2); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: database.deletedEventType, eventFilters: {}, eventFilterPathPatterns: { - ref: 'foo/{bar}', - instance: '*', + ref: "foo/{bar}", + instance: "*", }, retry: false, }, }); }); - it('should create a complex function', () => { + it("should create a complex function", () => { const func = database.onOperation( database.createdEventType, { - ref: '/foo/{path=**}/{bar}/', - instance: 'my-instance', - region: 'us-central1', - cpu: 'gcf_gen1', + ref: "/foo/{path=**}/{bar}/", + instance: "my-instance", + region: "us-central1", + cpu: "gcf_gen1", minInstances: 2, }, - (event) => 2 + () => 2 ); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', - cpu: 'gcf_gen1', + platform: "gcfv2", + cpu: "gcf_gen1", minInstances: 2, - region: ['us-central1'], + region: ["us-central1"], labels: {}, eventTrigger: { eventType: database.createdEventType, eventFilters: { - instance: 'my-instance', + instance: "my-instance", }, eventFilterPathPatterns: { - ref: 'foo/{path=**}/{bar}', + ref: "foo/{path=**}/{bar}", }, retry: false, }, @@ -362,34 +345,34 @@ describe('database', () => { }); }); - describe('onValueWritten', () => { - it('should create a function with a reference', () => { - const func = database.onValueWritten('/foo/{bar}/', (event) => { + describe("onValueWritten", () => { + it("should create a function with a reference", () => { + const func = database.onValueWritten("/foo/{bar}/", (event) => { expectType<{ bar: string }>(event.params); }); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: database.writtenEventType, eventFilters: {}, eventFilterPathPatterns: { - ref: 'foo/{bar}', - instance: '*', + ref: "foo/{bar}", + instance: "*", }, retry: false, }, }); }); - it('should create a function with opts', () => { + it("should create a function with opts", () => { const func = database.onValueWritten( { - ref: '/foo/{path=**}/{bar}/', - instance: 'my-instance', - region: 'us-central1', - cpu: 'gcf_gen1', + ref: "/foo/{path=**}/{bar}/", + instance: "my-instance", + region: "us-central1", + cpu: "gcf_gen1", minInstances: 2, }, (event) => { @@ -398,18 +381,18 @@ describe('database', () => { ); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', - cpu: 'gcf_gen1', + platform: "gcfv2", + cpu: "gcf_gen1", minInstances: 2, - region: ['us-central1'], + region: ["us-central1"], labels: {}, eventTrigger: { eventType: database.writtenEventType, eventFilters: { - instance: 'my-instance', + instance: "my-instance", }, eventFilterPathPatterns: { - ref: 'foo/{path=**}/{bar}', + ref: "foo/{path=**}/{bar}", }, retry: false, }, @@ -417,34 +400,34 @@ describe('database', () => { }); }); - describe('onValueCreated', () => { - it('should create a function with a reference', () => { - const func = database.onValueCreated('/foo/{bar}/', (event) => { + describe("onValueCreated", () => { + it("should create a function with a reference", () => { + const func = database.onValueCreated("/foo/{bar}/", (event) => { expectType<{ bar: string }>(event.params); }); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: database.createdEventType, eventFilters: {}, eventFilterPathPatterns: { - ref: 'foo/{bar}', - instance: '*', + ref: "foo/{bar}", + instance: "*", }, retry: false, }, }); }); - it('should create a function with opts', () => { + it("should create a function with opts", () => { const func = database.onValueCreated( { - ref: '/foo/{path=**}/{bar}/', - instance: 'instance', - region: 'us-central1', - cpu: 'gcf_gen1', + ref: "/foo/{path=**}/{bar}/", + instance: "instance", + region: "us-central1", + cpu: "gcf_gen1", minInstances: 2, }, (event) => { @@ -456,18 +439,18 @@ describe('database', () => { ); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', - cpu: 'gcf_gen1', + platform: "gcfv2", + cpu: "gcf_gen1", minInstances: 2, - region: ['us-central1'], + region: ["us-central1"], labels: {}, eventTrigger: { eventType: database.createdEventType, eventFilters: { - instance: 'instance', + instance: "instance", }, eventFilterPathPatterns: { - ref: 'foo/{path=**}/{bar}', + ref: "foo/{path=**}/{bar}", }, retry: false, }, @@ -475,34 +458,34 @@ describe('database', () => { }); }); - describe('onValueUpdated', () => { - it('should create a function with a reference', () => { - const func = database.onValueUpdated('/foo/{bar}/', (event) => { + describe("onValueUpdated", () => { + it("should create a function with a reference", () => { + const func = database.onValueUpdated("/foo/{bar}/", (event) => { expectType<{ bar: string }>(event.params); }); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: database.updatedEventType, eventFilters: {}, eventFilterPathPatterns: { - ref: 'foo/{bar}', - instance: '*', + ref: "foo/{bar}", + instance: "*", }, retry: false, }, }); }); - it('should create a function with opts', () => { + it("should create a function with opts", () => { const func = database.onValueUpdated( { - ref: '/foo/{path=**}/{bar}/', - instance: 'my-instance', - region: 'us-central1', - cpu: 'gcf_gen1', + ref: "/foo/{path=**}/{bar}/", + instance: "my-instance", + region: "us-central1", + cpu: "gcf_gen1", minInstances: 2, }, (event) => { @@ -511,18 +494,18 @@ describe('database', () => { ); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', - cpu: 'gcf_gen1', + platform: "gcfv2", + cpu: "gcf_gen1", minInstances: 2, - region: ['us-central1'], + region: ["us-central1"], labels: {}, eventTrigger: { eventType: database.updatedEventType, eventFilters: { - instance: 'my-instance', + instance: "my-instance", }, eventFilterPathPatterns: { - ref: 'foo/{path=**}/{bar}', + ref: "foo/{path=**}/{bar}", }, retry: false, }, @@ -530,34 +513,34 @@ describe('database', () => { }); }); - describe('onValueDeleted', () => { - it('should create a function with a reference', () => { - const func = database.onValueDeleted('/foo/{bar}/', (event) => { + describe("onValueDeleted", () => { + it("should create a function with a reference", () => { + const func = database.onValueDeleted("/foo/{bar}/", (event) => { expectType<{ bar: string }>(event.params); }); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { eventType: database.deletedEventType, eventFilters: {}, eventFilterPathPatterns: { - ref: 'foo/{bar}', - instance: '*', + ref: "foo/{bar}", + instance: "*", }, retry: false, }, }); }); - it('should create a function with opts', () => { + it("should create a function with opts", () => { const func = database.onValueDeleted( { - ref: '/foo/{path=**}/{bar}/', - instance: 'my-instance', - region: 'us-central1', - cpu: 'gcf_gen1', + ref: "/foo/{path=**}/{bar}/", + instance: "my-instance", + region: "us-central1", + cpu: "gcf_gen1", minInstances: 2, }, (event) => { @@ -566,18 +549,18 @@ describe('database', () => { ); expect(func.__endpoint).to.deep.equal({ - platform: 'gcfv2', - cpu: 'gcf_gen1', + platform: "gcfv2", + cpu: "gcf_gen1", minInstances: 2, - region: ['us-central1'], + region: ["us-central1"], labels: {}, eventTrigger: { eventType: database.deletedEventType, eventFilters: { - instance: 'my-instance', + instance: "my-instance", }, eventFilterPathPatterns: { - ref: 'foo/{path=**}/{bar}', + ref: "foo/{path=**}/{bar}", }, retry: false, }, diff --git a/spec/v2/providers/eventarc.spec.ts b/spec/v2/providers/eventarc.spec.ts index 96bd48940..2cafb482a 100644 --- a/spec/v2/providers/eventarc.spec.ts +++ b/spec/v2/providers/eventarc.spec.ts @@ -20,21 +20,21 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; -import * as options from '../../../src/v2/options'; -import * as eventarc from '../../../src/v2/providers/eventarc'; -import { FULL_ENDPOINT, FULL_OPTIONS } from './fixtures'; +import { expect } from "chai"; +import * as options from "../../../src/v2/options"; +import * as eventarc from "../../../src/v2/providers/eventarc"; +import { FULL_ENDPOINT, FULL_OPTIONS } from "./fixtures"; const ENDPOINT_EVENT_TRIGGER = { - eventType: 'event-type', + eventType: "event-type", retry: false, eventFilters: {}, }; -describe('v2/eventarc', () => { - describe('onCustomEventPublished', () => { +describe("v2/eventarc", () => { + describe("onCustomEventPublished", () => { beforeEach(() => { - process.env.GCLOUD_PROJECT = 'aProject'; + process.env.GCLOUD_PROJECT = "aProject"; }); afterEach(() => { @@ -42,65 +42,65 @@ describe('v2/eventarc', () => { delete process.env.GCLOUD_PROJECT; }); - it('should create a minimal trigger/endpoint with default channel', () => { - const result = eventarc.onCustomEventPublished('event-type', () => 42); + it("should create a minimal trigger/endpoint with default channel", () => { + const result = eventarc.onCustomEventPublished("event-type", () => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_EVENT_TRIGGER, - channel: 'locations/us-central1/channels/firebase', + channel: "locations/us-central1/channels/firebase", }, }); }); - it('should create a minimal trigger/endpoint with opts', () => { + it("should create a minimal trigger/endpoint with opts", () => { const result = eventarc.onCustomEventPublished( - { eventType: 'event-type', region: 'us-west1' }, + { eventType: "event-type", region: "us-west1" }, () => 42 ); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_EVENT_TRIGGER, - channel: 'locations/us-central1/channels/firebase', + channel: "locations/us-central1/channels/firebase", }, - region: ['us-west1'], + region: ["us-west1"], }); }); - it('should create a minimal trigger with channel with opts', () => { + it("should create a minimal trigger with channel with opts", () => { const result = eventarc.onCustomEventPublished( { - eventType: 'event-type', - channel: 'locations/us-west1/channels/my-channel', - filters: { foo: 'bar' }, + eventType: "event-type", + channel: "locations/us-west1/channels/my-channel", + filters: { foo: "bar" }, }, () => 42 ); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_EVENT_TRIGGER, - channel: 'locations/us-west1/channels/my-channel', + channel: "locations/us-west1/channels/my-channel", eventFilters: { - foo: 'bar', + foo: "bar", }, }, }); }); - it('should create a complex trigger/endpoint with appropriate values', () => { + it("should create a complex trigger/endpoint with appropriate values", () => { const result = eventarc.onCustomEventPublished( { ...FULL_OPTIONS, - eventType: 'event-type', - channel: 'locations/us-west1/channels/my-channel', + eventType: "event-type", + channel: "locations/us-west1/channels/my-channel", }, () => 42 ); @@ -109,37 +109,37 @@ describe('v2/eventarc', () => { ...FULL_ENDPOINT, eventTrigger: { ...ENDPOINT_EVENT_TRIGGER, - channel: 'locations/us-west1/channels/my-channel', + channel: "locations/us-west1/channels/my-channel", }, }); }); - it('should merge options and globalOptions', () => { + it("should merge options and globalOptions", () => { options.setGlobalOptions({ concurrency: 20, - region: 'europe-west1', + region: "europe-west1", minInstances: 1, }); const result = eventarc.onCustomEventPublished( { - eventType: 'event-type', - channel: 'locations/us-west1/channels/my-channel', - region: 'us-west1', + eventType: "event-type", + channel: "locations/us-west1/channels/my-channel", + region: "us-west1", minInstances: 3, }, () => 42 ); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", concurrency: 20, minInstances: 3, - region: ['us-west1'], + region: ["us-west1"], labels: {}, eventTrigger: { ...ENDPOINT_EVENT_TRIGGER, - channel: 'locations/us-west1/channels/my-channel', + channel: "locations/us-west1/channels/my-channel", }, }); }); diff --git a/spec/v2/providers/fixtures.ts b/spec/v2/providers/fixtures.ts index 84ab2344c..b70835864 100644 --- a/spec/v2/providers/fixtures.ts +++ b/spec/v2/providers/fixtures.ts @@ -1,41 +1,41 @@ -import { ManifestEndpoint } from '../../../src/runtime/manifest'; -import * as options from '../../../src/v2/options'; +import { ManifestEndpoint } from "../../../src/runtime/manifest"; +import * as options from "../../../src/v2/options"; export const FULL_OPTIONS: options.GlobalOptions = { - region: 'us-west1', - memory: '512MiB', + region: "us-west1", + memory: "512MiB", timeoutSeconds: 60, minInstances: 1, maxInstances: 3, concurrency: 20, - vpcConnector: 'aConnector', - vpcConnectorEgressSettings: 'ALL_TRAFFIC', - serviceAccount: 'root@', - ingressSettings: 'ALLOW_ALL', - cpu: 'gcf_gen1', + vpcConnector: "aConnector", + vpcConnectorEgressSettings: "ALL_TRAFFIC", + serviceAccount: "root@", + ingressSettings: "ALLOW_ALL", + cpu: "gcf_gen1", labels: { - hello: 'world', + hello: "world", }, - secrets: ['MY_SECRET'], + secrets: ["MY_SECRET"], }; export const FULL_ENDPOINT: ManifestEndpoint = { - platform: 'gcfv2', - region: ['us-west1'], + platform: "gcfv2", + region: ["us-west1"], availableMemoryMb: 512, timeoutSeconds: 60, minInstances: 1, maxInstances: 3, concurrency: 20, vpc: { - connector: 'aConnector', - egressSettings: 'ALL_TRAFFIC', + connector: "aConnector", + egressSettings: "ALL_TRAFFIC", }, - serviceAccountEmail: 'root@', - ingressSettings: 'ALLOW_ALL', - cpu: 'gcf_gen1', + serviceAccountEmail: "root@", + ingressSettings: "ALLOW_ALL", + cpu: "gcf_gen1", labels: { - hello: 'world', + hello: "world", }, - secretEnvironmentVariables: [{ key: 'MY_SECRET' }], + secretEnvironmentVariables: [{ key: "MY_SECRET" }], }; diff --git a/spec/v2/providers/https.spec.ts b/spec/v2/providers/https.spec.ts index 882c7e854..a1c22bf0e 100644 --- a/spec/v2/providers/https.spec.ts +++ b/spec/v2/providers/https.spec.ts @@ -20,47 +20,44 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; -import * as sinon from 'sinon'; - -import * as debug from '../../../src/common/debug'; -import * as options from '../../../src/v2/options'; -import * as https from '../../../src/v2/providers/https'; -import { - expectedResponseHeaders, - MockRequest, -} from '../../fixtures/mockrequest'; -import { runHandler } from '../../helper'; -import { FULL_ENDPOINT, FULL_OPTIONS } from './fixtures'; - -describe('onRequest', () => { +import { expect } from "chai"; +import * as sinon from "sinon"; + +import * as debug from "../../../src/common/debug"; +import * as options from "../../../src/v2/options"; +import * as https from "../../../src/v2/providers/https"; +import { expectedResponseHeaders, MockRequest } from "../../fixtures/mockrequest"; +import { runHandler } from "../../helper"; +import { FULL_ENDPOINT, FULL_OPTIONS } from "./fixtures"; + +describe("onRequest", () => { beforeEach(() => { options.setGlobalOptions({}); - process.env.GCLOUD_PROJECT = 'aProject'; + process.env.GCLOUD_PROJECT = "aProject"; }); afterEach(() => { delete process.env.GCLOUD_PROJECT; }); - it('should return a minimal trigger/endpoint with appropriate values', () => { + it("should return a minimal trigger/endpoint with appropriate values", () => { const result = https.onRequest((req, res) => { res.send(200); }); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", httpsTrigger: {}, labels: {}, }); }); - it('should create a complex trigger/endpoint with appropriate values', () => { + it("should create a complex trigger/endpoint with appropriate values", () => { const result = https.onRequest( { ...FULL_OPTIONS, - region: ['us-west1', 'us-central1'], - invoker: ['service-account1@', 'service-account2@'], + region: ["us-west1", "us-central1"], + invoker: ["service-account1@", "service-account2@"], }, (req, res) => { res.send(200); @@ -70,25 +67,25 @@ describe('onRequest', () => { expect(result.__endpoint).to.deep.equal({ ...FULL_ENDPOINT, httpsTrigger: { - invoker: ['service-account1@', 'service-account2@'], + invoker: ["service-account1@", "service-account2@"], }, - region: ['us-west1', 'us-central1'], + region: ["us-west1", "us-central1"], }); }); - it('should merge options and globalOptions', () => { + it("should merge options and globalOptions", () => { options.setGlobalOptions({ concurrency: 20, - region: 'europe-west1', + region: "europe-west1", minInstances: 1, - invoker: 'public', + invoker: "public", }); const result = https.onRequest( { - region: ['us-west1', 'us-central1'], + region: ["us-west1", "us-central1"], minInstances: 3, - invoker: 'private', + invoker: "private", }, (req, res) => { res.send(200); @@ -96,20 +93,20 @@ describe('onRequest', () => { ); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", httpsTrigger: { - invoker: ['private'], + invoker: ["private"], }, concurrency: 20, minInstances: 3, - region: ['us-west1', 'us-central1'], + region: ["us-west1", "us-central1"], labels: {}, }); }); - it('should be an express handler', async () => { + it("should be an express handler", async () => { const func = https.onRequest((req, res) => { - res.send('Works'); + res.send("Works"); }); const req = new MockRequest( @@ -117,19 +114,19 @@ describe('onRequest', () => { data: {}, }, { - 'content-type': 'application/json', - origin: 'example.com', + "content-type": "application/json", + origin: "example.com", } ); - req.method = 'POST'; + req.method = "POST"; const resp = await runHandler(func, req as any); - expect(resp.body).to.equal('Works'); + expect(resp.body).to.equal("Works"); }); - it('should enforce CORS options', async () => { - const func = https.onRequest({ cors: 'example.com' }, (req, res) => { - throw new Error('Should not reach here for OPTIONS preflight'); + it("should enforce CORS options", async () => { + const func = https.onRequest({ cors: "example.com" }, () => { + throw new Error("Should not reach here for OPTIONS preflight"); }); const req = new MockRequest( @@ -137,32 +134,29 @@ describe('onRequest', () => { data: {}, }, { - 'Access-Control-Request-Method': 'POST', - 'Access-Control-Request-Headers': 'origin', - origin: 'example.com', + "Access-Control-Request-Method": "POST", + "Access-Control-Request-Headers": "origin", + origin: "example.com", } ); - req.method = 'OPTIONS'; + req.method = "OPTIONS"; const resp = await runHandler(func, req as any); expect(resp.status).to.equal(204); expect(resp.body).to.be.undefined; expect(resp.headers).to.deep.equal({ - 'Access-Control-Allow-Methods': 'GET,HEAD,PUT,PATCH,POST,DELETE', - 'Access-Control-Allow-Origin': 'example.com', - 'Content-Length': '0', - Vary: 'Origin, Access-Control-Request-Headers', + "Access-Control-Allow-Methods": "GET,HEAD,PUT,PATCH,POST,DELETE", + "Access-Control-Allow-Origin": "example.com", + "Content-Length": "0", + Vary: "Origin, Access-Control-Request-Headers", }); }); - it('should add CORS headers if debug feature is enabled', async () => { - sinon - .stub(debug, 'isDebugFeatureEnabled') - .withArgs('enableCors') - .returns(true); + it("should add CORS headers if debug feature is enabled", async () => { + sinon.stub(debug, "isDebugFeatureEnabled").withArgs("enableCors").returns(true); - const func = https.onRequest((req, res) => { - throw new Error('Should not reach here for OPTIONS preflight'); + const func = https.onRequest(() => { + throw new Error("Should not reach here for OPTIONS preflight"); }); const req = new MockRequest( @@ -170,49 +164,49 @@ describe('onRequest', () => { data: {}, }, { - 'Access-Control-Request-Method': 'POST', - 'Access-Control-Request-Headers': 'origin', - origin: 'localhost', + "Access-Control-Request-Method": "POST", + "Access-Control-Request-Headers": "origin", + origin: "localhost", } ); - req.method = 'OPTIONS'; + req.method = "OPTIONS"; const resp = await runHandler(func, req as any); expect(resp.status).to.equal(204); expect(resp.body).to.be.undefined; expect(resp.headers).to.deep.equal({ - 'Access-Control-Allow-Methods': 'GET,HEAD,PUT,PATCH,POST,DELETE', - 'Access-Control-Allow-Origin': 'localhost', - 'Content-Length': '0', - Vary: 'Origin, Access-Control-Request-Headers', + "Access-Control-Allow-Methods": "GET,HEAD,PUT,PATCH,POST,DELETE", + "Access-Control-Allow-Origin": "localhost", + "Content-Length": "0", + Vary: "Origin, Access-Control-Request-Headers", }); sinon.restore(); }); }); -describe('onCall', () => { +describe("onCall", () => { beforeEach(() => { options.setGlobalOptions({}); - process.env.GCLOUD_PROJECT = 'aProject'; + process.env.GCLOUD_PROJECT = "aProject"; }); afterEach(() => { delete process.env.GCLOUD_PROJECT; }); - it('should return a minimal trigger/endpoint with appropriate values', () => { - const result = https.onCall((request) => 42); + it("should return a minimal trigger/endpoint with appropriate values", () => { + const result = https.onCall(() => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", callableTrigger: {}, labels: {}, }); }); - it('should create a complex trigger/endpoint with appropriate values', () => { - const result = https.onCall(FULL_OPTIONS, (request) => 42); + it("should create a complex trigger/endpoint with appropriate values", () => { + const result = https.onCall(FULL_OPTIONS, () => 42); expect(result.__endpoint).to.deep.equal({ ...FULL_ENDPOINT, @@ -220,68 +214,68 @@ describe('onCall', () => { }); }); - it('should merge options and globalOptions', () => { + it("should merge options and globalOptions", () => { options.setGlobalOptions({ concurrency: 20, - region: 'europe-west1', + region: "europe-west1", minInstances: 1, }); const result = https.onCall( { - region: ['us-west1', 'us-central1'], + region: ["us-west1", "us-central1"], minInstances: 3, }, - (request) => 42 + () => 42 ); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", callableTrigger: {}, concurrency: 20, minInstances: 3, - region: ['us-west1', 'us-central1'], + region: ["us-west1", "us-central1"], labels: {}, }); }); - it('has a .run method', () => { + it("has a .run method", () => { const cf = https.onCall((request) => { return request; }); const request: any = { - data: 'data', - instanceIdToken: 'token', + data: "data", + instanceIdToken: "token", auth: { - uid: 'abc', - token: 'token', + uid: "abc", + token: "token", }, }; expect(cf.run(request)).to.deep.equal(request); }); - it('should be an express handler', async () => { - const func = https.onCall((request) => 42); + it("should be an express handler", async () => { + const func = https.onCall(() => 42); const req = new MockRequest( { data: {}, }, { - 'content-type': 'application/json', - origin: 'example.com', + "content-type": "application/json", + origin: "example.com", } ); - req.method = 'POST'; + req.method = "POST"; const resp = await runHandler(func, req as any); expect(resp.body).to.deep.equal({ result: 42 }); }); - it('should enforce CORS options', async () => { - const func = https.onCall({ cors: 'example.com' }, (request) => { - throw new Error('Should not reach here for OPTIONS preflight'); + it("should enforce CORS options", async () => { + const func = https.onCall({ cors: "example.com" }, () => { + throw new Error("Should not reach here for OPTIONS preflight"); }); const req = new MockRequest( @@ -289,71 +283,68 @@ describe('onCall', () => { data: {}, }, { - 'Access-Control-Request-Method': 'POST', - 'Access-Control-Request-Headers': 'origin', - origin: 'example.com', + "Access-Control-Request-Method": "POST", + "Access-Control-Request-Headers": "origin", + origin: "example.com", } ); - req.method = 'OPTIONS'; + req.method = "OPTIONS"; const resp = await runHandler(func, req as any); expect(resp.status).to.equal(204); expect(resp.body).to.be.undefined; expect(resp.headers).to.deep.equal({ - 'Access-Control-Allow-Methods': 'POST', - 'Access-Control-Allow-Origin': 'example.com', - 'Content-Length': '0', - Vary: 'Origin, Access-Control-Request-Headers', + "Access-Control-Allow-Methods": "POST", + "Access-Control-Allow-Origin": "example.com", + "Content-Length": "0", + Vary: "Origin, Access-Control-Request-Headers", }); }); - it('overrides CORS headers if debug feature is enabled', async () => { - sinon - .stub(debug, 'isDebugFeatureEnabled') - .withArgs('enableCors') - .returns(true); + it("overrides CORS headers if debug feature is enabled", async () => { + sinon.stub(debug, "isDebugFeatureEnabled").withArgs("enableCors").returns(true); - const func = https.onCall({ cors: 'example.com' }, (request) => { - throw new Error('Should not reach here for OPTIONS preflight'); + const func = https.onCall({ cors: "example.com" }, () => { + throw new Error("Should not reach here for OPTIONS preflight"); }); const req = new MockRequest( { data: {}, }, { - 'Access-Control-Request-Method': 'POST', - 'Access-Control-Request-Headers': 'origin', - origin: 'localhost', + "Access-Control-Request-Method": "POST", + "Access-Control-Request-Headers": "origin", + origin: "localhost", } ); - req.method = 'OPTIONS'; + req.method = "OPTIONS"; const response = await runHandler(func, req as any); expect(response.status).to.equal(204); expect(response.body).to.be.undefined; expect(response.headers).to.deep.equal({ - 'Access-Control-Allow-Methods': 'POST', - 'Access-Control-Allow-Origin': 'localhost', - 'Content-Length': '0', - Vary: 'Origin, Access-Control-Request-Headers', + "Access-Control-Allow-Methods": "POST", + "Access-Control-Allow-Origin": "localhost", + "Content-Length": "0", + Vary: "Origin, Access-Control-Request-Headers", }); sinon.restore(); }); - it('adds CORS headers', async () => { - const func = https.onCall((request) => 42); + it("adds CORS headers", async () => { + const func = https.onCall(() => 42); const req = new MockRequest( { data: {}, }, { - 'content-type': 'application/json', - origin: 'example.com', + "content-type": "application/json", + origin: "example.com", } ); - req.method = 'POST'; + req.method = "POST"; const response = await runHandler(func, req as any); @@ -363,19 +354,13 @@ describe('onCall', () => { }); // These tests pass if the code transpiles - it('allows desirable syntax', () => { + it("allows desirable syntax", () => { https.onCall( (request: https.CallableRequest) => `hello, ${request.data}!` ); - https.onCall( - (request: https.CallableRequest) => `hello, ${request.data}!` - ); - https.onCall( - (request: https.CallableRequest) => `hello, ${request.data}!` - ); - https.onCall( - (request: https.CallableRequest) => `Hello, ${request.data}` - ); + https.onCall((request: https.CallableRequest) => `hello, ${request.data}!`); + https.onCall((request: https.CallableRequest) => `hello, ${request.data}!`); + https.onCall((request: https.CallableRequest) => `Hello, ${request.data}`); https.onCall((request: https.CallableRequest) => `Hello, ${request.data}`); }); }); diff --git a/spec/v2/providers/identity.spec.ts b/spec/v2/providers/identity.spec.ts index 4c8b19d3d..5576a0021 100644 --- a/spec/v2/providers/identity.spec.ts +++ b/spec/v2/providers/identity.spec.ts @@ -19,11 +19,11 @@ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; -import * as identity from '../../../src/v2/providers/identity'; +import { expect } from "chai"; +import * as identity from "../../../src/v2/providers/identity"; const BEFORE_CREATE_TRIGGER = { - eventType: 'providers/cloud.auth/eventTypes/user.beforeCreate', + eventType: "providers/cloud.auth/eventTypes/user.beforeCreate", options: { accessToken: false, idToken: false, @@ -32,7 +32,7 @@ const BEFORE_CREATE_TRIGGER = { }; const BEFORE_SIGN_IN_TRIGGER = { - eventType: 'providers/cloud.auth/eventTypes/user.beforeSignIn', + eventType: "providers/cloud.auth/eventTypes/user.beforeSignIn", options: { accessToken: false, idToken: false, @@ -44,35 +44,35 @@ const opts: identity.BlockingOptions = { accessToken: true, refreshToken: false, minInstances: 1, - region: 'us-west1', + region: "us-west1", }; -describe('identity', () => { - describe('beforeUserCreated', () => { - it('should accept a handler', () => { - const fn = identity.beforeUserCreated((event) => Promise.resolve()); +describe("identity", () => { + describe("beforeUserCreated", () => { + it("should accept a handler", () => { + const fn = identity.beforeUserCreated(() => Promise.resolve()); expect(fn.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, blockingTrigger: BEFORE_CREATE_TRIGGER, }); expect(fn.__requiredAPIs).to.deep.equal([ { - api: 'identitytoolkit.googleapis.com', - reason: 'Needed for auth blocking functions', + api: "identitytoolkit.googleapis.com", + reason: "Needed for auth blocking functions", }, ]); }); - it('should accept options and a handler', () => { - const fn = identity.beforeUserCreated(opts, (event) => Promise.resolve()); + it("should accept options and a handler", () => { + const fn = identity.beforeUserCreated(opts, () => Promise.resolve()); expect(fn.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, minInstances: 1, - region: ['us-west1'], + region: ["us-west1"], blockingTrigger: { ...BEFORE_CREATE_TRIGGER, options: { @@ -83,40 +83,38 @@ describe('identity', () => { }); expect(fn.__requiredAPIs).to.deep.equal([ { - api: 'identitytoolkit.googleapis.com', - reason: 'Needed for auth blocking functions', + api: "identitytoolkit.googleapis.com", + reason: "Needed for auth blocking functions", }, ]); }); }); - describe('beforeUserSignedIn', () => { - it('should accept a handler', () => { - const fn = identity.beforeUserSignedIn((event) => Promise.resolve()); + describe("beforeUserSignedIn", () => { + it("should accept a handler", () => { + const fn = identity.beforeUserSignedIn(() => Promise.resolve()); expect(fn.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, blockingTrigger: BEFORE_SIGN_IN_TRIGGER, }); expect(fn.__requiredAPIs).to.deep.equal([ { - api: 'identitytoolkit.googleapis.com', - reason: 'Needed for auth blocking functions', + api: "identitytoolkit.googleapis.com", + reason: "Needed for auth blocking functions", }, ]); }); - it('should accept options and a handler', () => { - const fn = identity.beforeUserSignedIn(opts, (event) => - Promise.resolve() - ); + it("should accept options and a handler", () => { + const fn = identity.beforeUserSignedIn(opts, () => Promise.resolve()); expect(fn.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, minInstances: 1, - region: ['us-west1'], + region: ["us-west1"], blockingTrigger: { ...BEFORE_SIGN_IN_TRIGGER, options: { @@ -127,64 +125,54 @@ describe('identity', () => { }); expect(fn.__requiredAPIs).to.deep.equal([ { - api: 'identitytoolkit.googleapis.com', - reason: 'Needed for auth blocking functions', + api: "identitytoolkit.googleapis.com", + reason: "Needed for auth blocking functions", }, ]); }); }); - describe('beforeOperation', () => { - it('should handle eventType and handler for before create events', () => { - const fn = identity.beforeOperation( - 'beforeCreate', - (event) => Promise.resolve(), - undefined - ); + describe("beforeOperation", () => { + it("should handle eventType and handler for before create events", () => { + const fn = identity.beforeOperation("beforeCreate", () => Promise.resolve(), undefined); expect(fn.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, blockingTrigger: BEFORE_CREATE_TRIGGER, }); expect(fn.__requiredAPIs).to.deep.equal([ { - api: 'identitytoolkit.googleapis.com', - reason: 'Needed for auth blocking functions', + api: "identitytoolkit.googleapis.com", + reason: "Needed for auth blocking functions", }, ]); }); - it('should handle eventType and handler for before sign in events', () => { - const fn = identity.beforeOperation( - 'beforeSignIn', - (event) => Promise.resolve(), - undefined - ); + it("should handle eventType and handler for before sign in events", () => { + const fn = identity.beforeOperation("beforeSignIn", () => Promise.resolve(), undefined); expect(fn.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, blockingTrigger: BEFORE_SIGN_IN_TRIGGER, }); expect(fn.__requiredAPIs).to.deep.equal([ { - api: 'identitytoolkit.googleapis.com', - reason: 'Needed for auth blocking functions', + api: "identitytoolkit.googleapis.com", + reason: "Needed for auth blocking functions", }, ]); }); - it('should handle eventType, options, and handler for before create events', () => { - const fn = identity.beforeOperation('beforeCreate', opts, (event) => - Promise.resolve() - ); + it("should handle eventType, options, and handler for before create events", () => { + const fn = identity.beforeOperation("beforeCreate", opts, () => Promise.resolve()); expect(fn.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, minInstances: 1, - region: ['us-west1'], + region: ["us-west1"], blockingTrigger: { ...BEFORE_CREATE_TRIGGER, options: { @@ -195,22 +183,20 @@ describe('identity', () => { }); expect(fn.__requiredAPIs).to.deep.equal([ { - api: 'identitytoolkit.googleapis.com', - reason: 'Needed for auth blocking functions', + api: "identitytoolkit.googleapis.com", + reason: "Needed for auth blocking functions", }, ]); }); - it('should handle eventType, options, and handler for before sign in events', () => { - const fn = identity.beforeOperation('beforeSignIn', opts, (event) => - Promise.resolve() - ); + it("should handle eventType, options, and handler for before sign in events", () => { + const fn = identity.beforeOperation("beforeSignIn", opts, () => Promise.resolve()); expect(fn.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, minInstances: 1, - region: ['us-west1'], + region: ["us-west1"], blockingTrigger: { ...BEFORE_SIGN_IN_TRIGGER, options: { @@ -221,15 +207,15 @@ describe('identity', () => { }); expect(fn.__requiredAPIs).to.deep.equal([ { - api: 'identitytoolkit.googleapis.com', - reason: 'Needed for auth blocking functions', + api: "identitytoolkit.googleapis.com", + reason: "Needed for auth blocking functions", }, ]); }); }); - describe('getOpts', () => { - it('should parse an empty object', () => { + describe("getOpts", () => { + it("should parse an empty object", () => { const internalOpts = identity.getOpts({}); expect(internalOpts).to.deep.equal({ @@ -240,12 +226,12 @@ describe('identity', () => { }); }); - it('should parse global options', () => { - const internalOpts = identity.getOpts({ region: 'us-central1', cpu: 2 }); + it("should parse global options", () => { + const internalOpts = identity.getOpts({ region: "us-central1", cpu: 2 }); expect(internalOpts).to.deep.equal({ opts: { - region: 'us-central1', + region: "us-central1", cpu: 2, }, accessToken: false, @@ -254,9 +240,9 @@ describe('identity', () => { }); }); - it('should a full options', () => { + it("should a full options", () => { const internalOpts = identity.getOpts({ - region: 'us-central1', + region: "us-central1", cpu: 2, accessToken: true, idToken: false, @@ -265,7 +251,7 @@ describe('identity', () => { expect(internalOpts).to.deep.equal({ opts: { - region: 'us-central1', + region: "us-central1", cpu: 2, }, accessToken: true, diff --git a/spec/v2/providers/pubsub.spec.ts b/spec/v2/providers/pubsub.spec.ts index ec4dddbae..865593fb0 100644 --- a/spec/v2/providers/pubsub.spec.ts +++ b/spec/v2/providers/pubsub.spec.ts @@ -1,48 +1,45 @@ -import { expect } from 'chai'; +import { expect } from "chai"; -import { CloudEvent } from '../../../src/v2/core'; -import * as options from '../../../src/v2/options'; -import * as pubsub from '../../../src/v2/providers/pubsub'; -import { FULL_ENDPOINT, FULL_OPTIONS } from './fixtures'; +import { CloudEvent } from "../../../src/v2/core"; +import * as options from "../../../src/v2/options"; +import * as pubsub from "../../../src/v2/providers/pubsub"; +import { FULL_ENDPOINT, FULL_OPTIONS } from "./fixtures"; const EVENT_TRIGGER = { - eventType: 'google.cloud.pubsub.topic.v1.messagePublished', - resource: 'projects/aProject/topics/topic', + eventType: "google.cloud.pubsub.topic.v1.messagePublished", + resource: "projects/aProject/topics/topic", }; const ENDPOINT_EVENT_TRIGGER = { - eventType: 'google.cloud.pubsub.topic.v1.messagePublished', + eventType: "google.cloud.pubsub.topic.v1.messagePublished", eventFilters: { - topic: 'topic', + topic: "topic", }, retry: false, }; -describe('onMessagePublished', () => { +describe("onMessagePublished", () => { beforeEach(() => { options.setGlobalOptions({}); - process.env.GCLOUD_PROJECT = 'aProject'; + process.env.GCLOUD_PROJECT = "aProject"; }); afterEach(() => { delete process.env.GCLOUD_PROJECT; }); - it('should return a minimal trigger/endpoint with appropriate values', () => { - const result = pubsub.onMessagePublished('topic', () => 42); + it("should return a minimal trigger/endpoint with appropriate values", () => { + const result = pubsub.onMessagePublished("topic", () => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", eventTrigger: ENDPOINT_EVENT_TRIGGER, labels: {}, }); }); - it('should create a complex trigger/endpoint with appropriate values', () => { - const result = pubsub.onMessagePublished( - { ...FULL_OPTIONS, topic: 'topic' }, - () => 42 - ); + it("should create a complex trigger/endpoint with appropriate values", () => { + const result = pubsub.onMessagePublished({ ...FULL_OPTIONS, topic: "topic" }, () => 42); expect(result.__endpoint).to.deep.equal({ ...FULL_ENDPOINT, @@ -50,37 +47,37 @@ describe('onMessagePublished', () => { }); }); - it('should merge options and globalOptions', () => { + it("should merge options and globalOptions", () => { options.setGlobalOptions({ concurrency: 20, - region: 'europe-west1', + region: "europe-west1", minInstances: 1, }); const result = pubsub.onMessagePublished( { - topic: 'topic', - region: 'us-west1', + topic: "topic", + region: "us-west1", minInstances: 3, }, () => 42 ); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", concurrency: 20, minInstances: 3, - region: ['us-west1'], + region: ["us-west1"], labels: {}, eventTrigger: ENDPOINT_EVENT_TRIGGER, }); }); - it('should convert retry option if appropriate', () => { + it("should convert retry option if appropriate", () => { const result = pubsub.onMessagePublished( { - topic: 'topic', - region: 'us-west1', + topic: "topic", + region: "us-west1", minInstances: 3, retry: true, }, @@ -88,45 +85,45 @@ describe('onMessagePublished', () => { ); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", minInstances: 3, - region: ['us-west1'], + region: ["us-west1"], labels: {}, eventTrigger: { ...ENDPOINT_EVENT_TRIGGER, retry: true }, }); }); - it('should have a .run method', () => { - const func = pubsub.onMessagePublished('topic', (event) => event); + it("should have a .run method", () => { + const func = pubsub.onMessagePublished("topic", (event) => event); - const res = func.run('input' as any); + const res = func.run("input" as any); - expect(res).to.equal('input'); + expect(res).to.equal("input"); }); - it('should parse pubsub messages', () => { + it("should parse pubsub messages", () => { let json: unknown; const messageJSON = { - messageId: 'uuid', - data: Buffer.from(JSON.stringify({ hello: 'world' })).toString('base64'), - attributes: { key: 'value' }, - orderingKey: 'orderingKey', + messageId: "uuid", + data: Buffer.from(JSON.stringify({ hello: "world" })).toString("base64"), + attributes: { key: "value" }, + orderingKey: "orderingKey", publishTime: new Date(Date.now()).toISOString(), }; const publishData: pubsub.MessagePublishedData = { message: messageJSON as any, - subscription: 'projects/aProject/subscriptions/aSubscription', + subscription: "projects/aProject/subscriptions/aSubscription", }; const event: CloudEvent> = { - specversion: '1.0', - source: '//pubsub.googleapis.com/projects/aProject/topics/topic', - id: 'uuid', + specversion: "1.0", + source: "//pubsub.googleapis.com/projects/aProject/topics/topic", + id: "uuid", type: EVENT_TRIGGER.eventType, time: messageJSON.publishTime, data: publishData, }; - const func = pubsub.onMessagePublished('topic', (event) => { + const func = pubsub.onMessagePublished("topic", (event) => { json = event.data.message.json; return event; }); @@ -137,26 +134,30 @@ describe('onMessagePublished', () => { // Message is a class and we passed an interface. expect(eventAgain).to.deep.equal(event); - expect(json).to.deep.equal({ hello: 'world' }); + expect(json).to.deep.equal({ hello: "world" }); }); // These tests pass if the transpiler works - it('allows desirable syntax', () => { + it("allows desirable syntax", () => { pubsub.onMessagePublished( - 'topic', - (event: CloudEvent>) => {} + "topic", + // eslint-disable-next-line @typescript-eslint/no-unused-vars + (event: CloudEvent>) => undefined ); pubsub.onMessagePublished( - 'topic', - (event: CloudEvent) => {} + "topic", + // eslint-disable-next-line @typescript-eslint/no-unused-vars + (event: CloudEvent) => undefined ); pubsub.onMessagePublished( - 'topic', - (event: CloudEvent>) => {} + "topic", + // eslint-disable-next-line @typescript-eslint/no-unused-vars + (event: CloudEvent>) => undefined ); pubsub.onMessagePublished( - 'topic', - (event: CloudEvent) => {} + "topic", + // eslint-disable-next-line @typescript-eslint/no-unused-vars + (event: CloudEvent) => undefined ); }); }); diff --git a/spec/v2/providers/storage.spec.ts b/spec/v2/providers/storage.spec.ts index 4122380b5..4a2c7bb27 100644 --- a/spec/v2/providers/storage.spec.ts +++ b/spec/v2/providers/storage.spec.ts @@ -1,68 +1,68 @@ -import { expect } from 'chai'; -import * as config from '../../../src/common/config'; -import * as options from '../../../src/v2/options'; -import * as storage from '../../../src/v2/providers/storage'; -import { FULL_ENDPOINT, FULL_OPTIONS } from './fixtures'; +import { expect } from "chai"; +import * as config from "../../../src/common/config"; +import * as options from "../../../src/v2/options"; +import * as storage from "../../../src/v2/providers/storage"; +import { FULL_ENDPOINT, FULL_OPTIONS } from "./fixtures"; const ENDPOINT_EVENT_TRIGGER = { - eventType: 'event-type', + eventType: "event-type", eventFilters: { - bucket: 'some-bucket', + bucket: "some-bucket", }, retry: false, }; const DEFAULT_BUCKET_EVENT_FILTER = { - bucket: 'default-bucket', + bucket: "default-bucket", }; const SPECIFIC_BUCKET_EVENT_FILTER = { - bucket: 'my-bucket', + bucket: "my-bucket", }; -describe('v2/storage', () => { - describe('getOptsAndBucket', () => { - it('should return the default bucket with empty opts', () => { - config.resetCache({ storageBucket: 'default-bucket' }); +describe("v2/storage", () => { + describe("getOptsAndBucket", () => { + it("should return the default bucket with empty opts", () => { + config.resetCache({ storageBucket: "default-bucket" }); const [opts, bucket] = storage.getOptsAndBucket({}); config.resetCache(); expect(opts).to.deep.equal({}); - expect(bucket).to.eq('default-bucket'); + expect(bucket).to.eq("default-bucket"); }); - it('should return the default bucket with opts param', () => { - config.resetCache({ storageBucket: 'default-bucket' }); + it("should return the default bucket with opts param", () => { + config.resetCache({ storageBucket: "default-bucket" }); - const [opts, bucket] = storage.getOptsAndBucket({ region: 'us-west1' }); + const [opts, bucket] = storage.getOptsAndBucket({ region: "us-west1" }); config.resetCache(); - expect(opts).to.deep.equal({ region: 'us-west1' }); - expect(bucket).to.eq('default-bucket'); + expect(opts).to.deep.equal({ region: "us-west1" }); + expect(bucket).to.eq("default-bucket"); }); - it('should return the given bucket', () => { - const [opts, bucket] = storage.getOptsAndBucket('my-bucket'); + it("should return the given bucket", () => { + const [opts, bucket] = storage.getOptsAndBucket("my-bucket"); expect(opts).to.deep.equal({}); - expect(bucket).to.eq('my-bucket'); + expect(bucket).to.eq("my-bucket"); }); - it('should return the given bucket and opts', () => { + it("should return the given bucket and opts", () => { const [opts, bucket] = storage.getOptsAndBucket({ - bucket: 'my-bucket', - region: 'us-west1', + bucket: "my-bucket", + region: "us-west1", }); - expect(opts).to.deep.equal({ region: 'us-west1' }); - expect(bucket).to.eq('my-bucket'); + expect(opts).to.deep.equal({ region: "us-west1" }); + expect(bucket).to.eq("my-bucket"); }); }); - describe('onOperation', () => { + describe("onOperation", () => { beforeEach(() => { - process.env.GCLOUD_PROJECT = 'aProject'; + process.env.GCLOUD_PROJECT = "aProject"; }); afterEach(() => { @@ -71,56 +71,48 @@ describe('v2/storage', () => { delete process.env.GCLOUD_PROJECT; }); - it('should create a minimal trigger/endpoint with bucket', () => { - const result = storage.onOperation('event-type', 'some-bucket', () => 42); + it("should create a minimal trigger/endpoint with bucket", () => { + const result = storage.onOperation("event-type", "some-bucket", () => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: ENDPOINT_EVENT_TRIGGER, }); }); - it('should create a minimal trigger/endpoint with opts', () => { - config.resetCache({ storageBucket: 'default-bucket' }); + it("should create a minimal trigger/endpoint with opts", () => { + config.resetCache({ storageBucket: "default-bucket" }); - const result = storage.onOperation( - 'event-type', - { region: 'us-west1' }, - () => 42 - ); + const result = storage.onOperation("event-type", { region: "us-west1" }, () => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_EVENT_TRIGGER, eventFilters: DEFAULT_BUCKET_EVENT_FILTER, }, - region: ['us-west1'], + region: ["us-west1"], }); }); - it('should create a minimal trigger with bucket with opts and bucket', () => { - const result = storage.onOperation( - 'event-type', - { bucket: 'some-bucket' }, - () => 42 - ); + it("should create a minimal trigger with bucket with opts and bucket", () => { + const result = storage.onOperation("event-type", { bucket: "some-bucket" }, () => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: ENDPOINT_EVENT_TRIGGER, }); }); - it('should create a complex trigger/endpoint with appropriate values', () => { + it("should create a complex trigger/endpoint with appropriate values", () => { const result = storage.onOperation( - 'event-type', + "event-type", { ...FULL_OPTIONS, - bucket: 'some-bucket', + bucket: "some-bucket", }, () => 42 ); @@ -131,35 +123,35 @@ describe('v2/storage', () => { }); }); - it('should merge options and globalOptions', () => { + it("should merge options and globalOptions", () => { options.setGlobalOptions({ concurrency: 20, - region: 'europe-west1', + region: "europe-west1", minInstances: 1, }); const result = storage.onOperation( - 'event-type', + "event-type", { - bucket: 'some-bucket', - region: 'us-west1', + bucket: "some-bucket", + region: "us-west1", minInstances: 3, }, () => 42 ); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", concurrency: 20, minInstances: 3, - region: ['us-west1'], + region: ["us-west1"], labels: {}, eventTrigger: ENDPOINT_EVENT_TRIGGER, }); }); }); - describe('onObjectArchived', () => { + describe("onObjectArchived", () => { const ENDPOINT_ARCHIVED_TRIGGER = { ...ENDPOINT_EVENT_TRIGGER, eventType: storage.archivedEvent, @@ -169,13 +161,13 @@ describe('v2/storage', () => { config.resetCache(); }); - it('should accept only handler', () => { - config.resetCache({ storageBucket: 'default-bucket' }); + it("should accept only handler", () => { + config.resetCache({ storageBucket: "default-bucket" }); const result = storage.onObjectArchived(() => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_ARCHIVED_TRIGGER, @@ -184,11 +176,11 @@ describe('v2/storage', () => { }); }); - it('should accept bucket and handler', () => { - const result = storage.onObjectArchived('my-bucket', () => 42); + it("should accept bucket and handler", () => { + const result = storage.onObjectArchived("my-bucket", () => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_ARCHIVED_TRIGGER, @@ -197,41 +189,41 @@ describe('v2/storage', () => { }); }); - it('should accept opts and handler', () => { + it("should accept opts and handler", () => { const result = storage.onObjectArchived( - { bucket: 'my-bucket', region: 'us-west1' }, + { bucket: "my-bucket", region: "us-west1" }, () => 42 ); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_ARCHIVED_TRIGGER, eventFilters: SPECIFIC_BUCKET_EVENT_FILTER, }, - region: ['us-west1'], + region: ["us-west1"], }); }); - it('should accept opts and handler, default bucket', () => { - config.resetCache({ storageBucket: 'default-bucket' }); + it("should accept opts and handler, default bucket", () => { + config.resetCache({ storageBucket: "default-bucket" }); - const result = storage.onObjectArchived({ region: 'us-west1' }, () => 42); + const result = storage.onObjectArchived({ region: "us-west1" }, () => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_ARCHIVED_TRIGGER, eventFilters: DEFAULT_BUCKET_EVENT_FILTER, }, - region: ['us-west1'], + region: ["us-west1"], }); }); }); - describe('onObjectFinalized', () => { + describe("onObjectFinalized", () => { const ENDPOINT_FINALIZED_TRIGGER = { ...ENDPOINT_EVENT_TRIGGER, eventType: storage.finalizedEvent, @@ -241,13 +233,13 @@ describe('v2/storage', () => { config.resetCache(); }); - it('should accept only handler', () => { - config.resetCache({ storageBucket: 'default-bucket' }); + it("should accept only handler", () => { + config.resetCache({ storageBucket: "default-bucket" }); const result = storage.onObjectFinalized(() => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_FINALIZED_TRIGGER, @@ -256,11 +248,11 @@ describe('v2/storage', () => { }); }); - it('should accept bucket and handler', () => { - const result = storage.onObjectFinalized('my-bucket', () => 42); + it("should accept bucket and handler", () => { + const result = storage.onObjectFinalized("my-bucket", () => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_FINALIZED_TRIGGER, @@ -269,44 +261,41 @@ describe('v2/storage', () => { }); }); - it('should accept opts and handler', () => { + it("should accept opts and handler", () => { const result = storage.onObjectFinalized( - { bucket: 'my-bucket', region: 'us-west1' }, + { bucket: "my-bucket", region: "us-west1" }, () => 42 ); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_FINALIZED_TRIGGER, eventFilters: SPECIFIC_BUCKET_EVENT_FILTER, }, - region: ['us-west1'], + region: ["us-west1"], }); }); - it('should accept opts and handler, default bucket', () => { - config.resetCache({ storageBucket: 'default-bucket' }); + it("should accept opts and handler, default bucket", () => { + config.resetCache({ storageBucket: "default-bucket" }); - const result = storage.onObjectFinalized( - { region: 'us-west1' }, - () => 42 - ); + const result = storage.onObjectFinalized({ region: "us-west1" }, () => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_FINALIZED_TRIGGER, eventFilters: DEFAULT_BUCKET_EVENT_FILTER, }, - region: ['us-west1'], + region: ["us-west1"], }); }); }); - describe('onObjectDeleted', () => { + describe("onObjectDeleted", () => { const ENDPOINT_DELETED_TRIGGER = { ...ENDPOINT_EVENT_TRIGGER, eventType: storage.deletedEvent, @@ -316,13 +305,13 @@ describe('v2/storage', () => { config.resetCache(); }); - it('should accept only handler', () => { - config.resetCache({ storageBucket: 'default-bucket' }); + it("should accept only handler", () => { + config.resetCache({ storageBucket: "default-bucket" }); const result = storage.onObjectDeleted(() => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_DELETED_TRIGGER, @@ -331,11 +320,11 @@ describe('v2/storage', () => { }); }); - it('should accept bucket and handler', () => { - const result = storage.onObjectDeleted('my-bucket', () => 42); + it("should accept bucket and handler", () => { + const result = storage.onObjectDeleted("my-bucket", () => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_DELETED_TRIGGER, @@ -344,41 +333,38 @@ describe('v2/storage', () => { }); }); - it('should accept opts and handler', () => { - const result = storage.onObjectDeleted( - { bucket: 'my-bucket', region: 'us-west1' }, - () => 42 - ); + it("should accept opts and handler", () => { + const result = storage.onObjectDeleted({ bucket: "my-bucket", region: "us-west1" }, () => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_DELETED_TRIGGER, eventFilters: SPECIFIC_BUCKET_EVENT_FILTER, }, - region: ['us-west1'], + region: ["us-west1"], }); }); - it('should accept opts and handler, default bucket', () => { - config.resetCache({ storageBucket: 'default-bucket' }); + it("should accept opts and handler, default bucket", () => { + config.resetCache({ storageBucket: "default-bucket" }); - const result = storage.onObjectDeleted({ region: 'us-west1' }, () => 42); + const result = storage.onObjectDeleted({ region: "us-west1" }, () => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_DELETED_TRIGGER, eventFilters: DEFAULT_BUCKET_EVENT_FILTER, }, - region: ['us-west1'], + region: ["us-west1"], }); }); }); - describe('onObjectMetadataUpdated', () => { + describe("onObjectMetadataUpdated", () => { const ENDPOINT_METADATA_TRIGGER = { ...ENDPOINT_EVENT_TRIGGER, eventType: storage.metadataUpdatedEvent, @@ -388,13 +374,13 @@ describe('v2/storage', () => { config.resetCache(); }); - it('should accept only handler', () => { - config.resetCache({ storageBucket: 'default-bucket' }); + it("should accept only handler", () => { + config.resetCache({ storageBucket: "default-bucket" }); const result = storage.onObjectMetadataUpdated(() => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_METADATA_TRIGGER, @@ -403,11 +389,11 @@ describe('v2/storage', () => { }); }); - it('should accept bucket and handler', () => { - const result = storage.onObjectMetadataUpdated('my-bucket', () => 42); + it("should accept bucket and handler", () => { + const result = storage.onObjectMetadataUpdated("my-bucket", () => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_METADATA_TRIGGER, @@ -416,39 +402,36 @@ describe('v2/storage', () => { }); }); - it('should accept opts and handler', () => { + it("should accept opts and handler", () => { const result = storage.onObjectMetadataUpdated( - { bucket: 'my-bucket', region: 'us-west1' }, + { bucket: "my-bucket", region: "us-west1" }, () => 42 ); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_METADATA_TRIGGER, eventFilters: SPECIFIC_BUCKET_EVENT_FILTER, }, - region: ['us-west1'], + region: ["us-west1"], }); }); - it('should accept opts and handler, default bucket', () => { - config.resetCache({ storageBucket: 'default-bucket' }); + it("should accept opts and handler, default bucket", () => { + config.resetCache({ storageBucket: "default-bucket" }); - const result = storage.onObjectMetadataUpdated( - { region: 'us-west1' }, - () => 42 - ); + const result = storage.onObjectMetadataUpdated({ region: "us-west1" }, () => 42); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", labels: {}, eventTrigger: { ...ENDPOINT_METADATA_TRIGGER, eventFilters: DEFAULT_BUCKET_EVENT_FILTER, }, - region: ['us-west1'], + region: ["us-west1"], }); }); }); diff --git a/spec/v2/providers/tasks.spec.ts b/spec/v2/providers/tasks.spec.ts index cf4ffd019..f88c96c7a 100644 --- a/spec/v2/providers/tasks.spec.ts +++ b/spec/v2/providers/tasks.spec.ts @@ -20,35 +20,35 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { expect } from 'chai'; +import { expect } from "chai"; -import * as options from '../../../src/v2/options'; -import { onTaskDispatched, Request } from '../../../src/v2/providers/tasks'; -import { MockRequest } from '../../fixtures/mockrequest'; -import { runHandler } from '../../helper'; -import { FULL_ENDPOINT, FULL_OPTIONS } from './fixtures'; +import * as options from "../../../src/v2/options"; +import { onTaskDispatched, Request } from "../../../src/v2/providers/tasks"; +import { MockRequest } from "../../fixtures/mockrequest"; +import { runHandler } from "../../helper"; +import { FULL_ENDPOINT, FULL_OPTIONS } from "./fixtures"; -describe('onTaskDispatched', () => { +describe("onTaskDispatched", () => { beforeEach(() => { options.setGlobalOptions({}); - process.env.GCLOUD_PROJECT = 'aProject'; + process.env.GCLOUD_PROJECT = "aProject"; }); afterEach(() => { delete process.env.GCLOUD_PROJECT; }); - it('should return a minimal trigger/endpoint with appropriate values', () => { - const result = onTaskDispatched(() => {}); + it("should return a minimal trigger/endpoint with appropriate values", () => { + const result = onTaskDispatched(() => undefined); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", taskQueueTrigger: {}, labels: {}, }); }); - it('should create a complex trigger/endpoint with appropriate values', () => { + it("should create a complex trigger/endpoint with appropriate values", () => { const result = onTaskDispatched( { ...FULL_OPTIONS, @@ -63,14 +63,14 @@ describe('onTaskDispatched', () => { maxConcurrentDispatches: 5, maxDispatchesPerSecond: 10, }, - invoker: 'private', + invoker: "private", }, - () => {} + () => undefined ); expect(result.__endpoint).to.deep.equal({ ...FULL_ENDPOINT, - platform: 'gcfv2', + platform: "gcfv2", taskQueueTrigger: { retryConfig: { maxAttempts: 4, @@ -83,38 +83,38 @@ describe('onTaskDispatched', () => { maxConcurrentDispatches: 5, maxDispatchesPerSecond: 10, }, - invoker: ['private'], + invoker: ["private"], }, }); }); - it('should merge options and globalOptions', () => { + it("should merge options and globalOptions", () => { options.setGlobalOptions({ concurrency: 20, - region: 'europe-west1', + region: "europe-west1", minInstances: 1, }); const result = onTaskDispatched( { - region: 'us-west1', + region: "us-west1", minInstances: 3, }, - (request) => {} + () => undefined ); expect(result.__endpoint).to.deep.equal({ - platform: 'gcfv2', + platform: "gcfv2", taskQueueTrigger: {}, concurrency: 20, minInstances: 3, - region: ['us-west1'], + region: ["us-west1"], labels: {}, }); }); - it('has a .run method', async () => { - const request: any = { data: 'data' }; + it("has a .run method", async () => { + const request: any = { data: "data" }; const cf = onTaskDispatched((r) => { expect(r.data).to.deep.equal(request.data); }); @@ -122,27 +122,27 @@ describe('onTaskDispatched', () => { await cf.run(request); }); - it('should be an express handler', async () => { - const func = onTaskDispatched((request) => {}); + it("should be an express handler", async () => { + const func = onTaskDispatched(() => undefined); const req = new MockRequest( { data: {}, }, { - 'content-type': 'application/json', - authorization: 'Bearer abc', - origin: 'example.com', + "content-type": "application/json", + authorization: "Bearer abc", + origin: "example.com", } ); - req.method = 'POST'; + req.method = "POST"; const resp = await runHandler(func, req as any); expect(resp.status).to.equal(204); }); // These tests pass if the code transpiles - it('allows desirable syntax', () => { + it("allows desirable syntax", () => { onTaskDispatched((request: Request) => { // There should be no lint warnings that data is not a string. console.log(`hello, ${request.data}`); diff --git a/src/logger/common.ts b/src/logger/common.ts index 38d2edd54..32ef0e596 100644 --- a/src/logger/common.ts +++ b/src/logger/common.ts @@ -23,16 +23,16 @@ // Map LogSeverity types to their equivalent `console.*` method. /** @hidden */ export const CONSOLE_SEVERITY: { - [severity: string]: 'debug' | 'info' | 'warn' | 'error'; + [severity: string]: "debug" | "info" | "warn" | "error"; } = { - DEBUG: 'debug', - INFO: 'info', - NOTICE: 'info', - WARNING: 'warn', - ERROR: 'error', - CRITICAL: 'error', - ALERT: 'error', - EMERGENCY: 'error', + DEBUG: "debug", + INFO: "info", + NOTICE: "info", + WARNING: "warn", + ERROR: "error", + CRITICAL: "error", + ALERT: "error", + EMERGENCY: "error", }; // safely preserve unpatched console.* methods in case of compat require diff --git a/src/logger/compat.ts b/src/logger/compat.ts index 3971757ad..02b819ddc 100644 --- a/src/logger/compat.ts +++ b/src/logger/compat.ts @@ -20,26 +20,24 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { format } from 'util'; -import { CONSOLE_SEVERITY, UNPATCHED_CONSOLE } from './common'; +import { format } from "util"; +import { CONSOLE_SEVERITY, UNPATCHED_CONSOLE } from "./common"; /** @hidden */ function patchedConsole(severity: string): (data: any, ...args: any[]) => void { return function (data: any, ...args: any[]): void { let message = format(data, ...args); - if (severity === 'ERROR') { + if (severity === "ERROR") { message = new Error(message).stack || message; } - UNPATCHED_CONSOLE[CONSOLE_SEVERITY[severity]]( - JSON.stringify({ severity, message }) - ); + UNPATCHED_CONSOLE[CONSOLE_SEVERITY[severity]](JSON.stringify({ severity, message })); }; } // IMPORTANT -- "../logger" must be imported before monkeypatching! -console.debug = patchedConsole('DEBUG'); -console.info = patchedConsole('INFO'); -console.log = patchedConsole('INFO'); -console.warn = patchedConsole('WARNING'); -console.error = patchedConsole('ERROR'); +console.debug = patchedConsole("DEBUG"); +console.info = patchedConsole("INFO"); +console.log = patchedConsole("INFO"); +console.warn = patchedConsole("WARNING"); +console.error = patchedConsole("ERROR"); diff --git a/src/logger/index.ts b/src/logger/index.ts index 52effcbd7..e51aaa22d 100644 --- a/src/logger/index.ts +++ b/src/logger/index.ts @@ -20,23 +20,23 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { format } from 'util'; +import { format } from "util"; -import { CONSOLE_SEVERITY, UNPATCHED_CONSOLE } from './common'; +import { CONSOLE_SEVERITY, UNPATCHED_CONSOLE } from "./common"; /** * `LogSeverity` indicates the detailed severity of the log entry. See [LogSeverity](https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#logseverity). * @public */ export type LogSeverity = - | 'DEBUG' - | 'INFO' - | 'NOTICE' - | 'WARNING' - | 'ERROR' - | 'CRITICAL' - | 'ALERT' - | 'EMERGENCY'; + | "DEBUG" + | "INFO" + | "NOTICE" + | "WARNING" + | "ERROR" + | "CRITICAL" + | "ALERT" + | "EMERGENCY"; /** * `LogEntry` represents a [structured Cloud Logging](https://cloud.google.com/logging/docs/structured-logging) @@ -52,7 +52,7 @@ export interface LogEntry { /** @internal */ function removeCircular(obj: any, refs: any[] = []): any { - if (typeof obj !== 'object' || !obj) { + if (typeof obj !== "object" || !obj) { return obj; } // If the object defines its own toJSON, prefer that. @@ -60,7 +60,7 @@ function removeCircular(obj: any, refs: any[] = []): any { return obj.toJSON(); } if (refs.includes(obj)) { - return '[Circular]'; + return "[Circular]"; } else { refs.push(obj); } @@ -72,7 +72,7 @@ function removeCircular(obj: any, refs: any[] = []): any { } for (const k in obj) { if (refs.includes(obj[k])) { - returnObj[k] = '[Circular]'; + returnObj[k] = "[Circular]"; } else { returnObj[k] = removeCircular(obj[k], refs); } @@ -86,9 +86,7 @@ function removeCircular(obj: any, refs: any[] = []): any { * @public */ export function write(entry: LogEntry) { - UNPATCHED_CONSOLE[CONSOLE_SEVERITY[entry.severity]]( - JSON.stringify(removeCircular(entry)) - ); + UNPATCHED_CONSOLE[CONSOLE_SEVERITY[entry.severity]](JSON.stringify(removeCircular(entry))); } /** @@ -98,7 +96,7 @@ export function write(entry: LogEntry) { * @public */ export function debug(...args: any[]) { - write(entryFromArgs('DEBUG', args)); + write(entryFromArgs("DEBUG", args)); } /** @@ -108,7 +106,7 @@ export function debug(...args: any[]) { * @public */ export function log(...args: any[]) { - write(entryFromArgs('INFO', args)); + write(entryFromArgs("INFO", args)); } /** @@ -118,7 +116,7 @@ export function log(...args: any[]) { * @public */ export function info(...args: any[]) { - write(entryFromArgs('INFO', args)); + write(entryFromArgs("INFO", args)); } /** @@ -128,7 +126,7 @@ export function info(...args: any[]) { * @public */ export function warn(...args: any[]) { - write(entryFromArgs('WARNING', args)); + write(entryFromArgs("WARNING", args)); } /** @@ -138,19 +136,19 @@ export function warn(...args: any[]) { * @public */ export function error(...args: any[]) { - write(entryFromArgs('ERROR', args)); + write(entryFromArgs("ERROR", args)); } /** @hidden */ function entryFromArgs(severity: LogSeverity, args: any[]): LogEntry { let entry = {}; const lastArg = args[args.length - 1]; - if (lastArg && typeof lastArg == 'object' && lastArg.constructor == Object) { + if (lastArg && typeof lastArg === "object" && lastArg.constructor === Object) { entry = args.pop(); } // mimic `console.*` behavior, see https://nodejs.org/api/console.html#console_console_log_data_args - let message = format.apply(null, args); - if (severity === 'ERROR' && !args.find((arg) => arg instanceof Error)) { + let message = format(...args); + if (severity === "ERROR" && !args.find((arg) => arg instanceof Error)) { message = new Error(message).stack || message; } return { ...entry, severity, message }; diff --git a/src/v1/cloud-functions.ts b/src/v1/cloud-functions.ts index 6dd7b4643..a6edcc2a3 100644 --- a/src/v1/cloud-functions.ts +++ b/src/v1/cloud-functions.ts @@ -20,17 +20,17 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { Request, Response } from 'express'; -import { warn } from '../logger'; -import { DeploymentOptions } from './function-configuration'; +import { Request, Response } from "express"; +import { warn } from "../logger"; +import { DeploymentOptions } from "./function-configuration"; export { Request, Response }; -import { convertIfPresent, copyIfPresent } from '../common/encoding'; -import { ManifestEndpoint, ManifestRequiredAPI } from '../runtime/manifest'; +import { convertIfPresent, copyIfPresent } from "../common/encoding"; +import { ManifestEndpoint, ManifestRequiredAPI } from "../runtime/manifest"; -export { Change } from '../common/change'; +export { Change } from "../common/change"; /** @hidden */ -const WILDCARD_REGEX = new RegExp('{[^/{}]*}', 'g'); +const WILDCARD_REGEX = new RegExp("{[^/{}]*}", "g"); /** * Wire format for an event. @@ -92,7 +92,7 @@ export interface EventContext> { * * `null` For event types that do not provide user information (all except * Realtime Database). */ - authType?: 'ADMIN' | 'USER' | 'UNAUTHENTICATED'; + authType?: "ADMIN" | "USER" | "UNAUTHENTICATED"; /** * The event’s unique identifier. @@ -261,7 +261,7 @@ export function makeCloudFunction({ * v1beta1 event flow has different format for context, transform them to * new format. */ - context.eventType = provider + '.' + eventType; + context.eventType = provider + "." + eventType; context.resource = { service, name: context.resource, @@ -273,9 +273,9 @@ export function makeCloudFunction({ context, }; - if (provider === 'google.firebase.database') { + if (provider === "google.firebase.database") { context.authType = _detectAuthType(event); - if (context.authType !== 'ADMIN') { + if (context.authType !== "ADMIN") { context.auth = _makeAuth(event, context.authType); } else { delete context.auth; @@ -283,11 +283,9 @@ export function makeCloudFunction({ } if (triggerResource() == null) { - Object.defineProperty(context, 'params', { + Object.defineProperty(context, "params", { get: () => { - throw new Error( - 'context.params is not available when using the handler namespace.' - ); + throw new Error("context.params is not available when using the handler namespace."); }, }); } else { @@ -295,27 +293,27 @@ export function makeCloudFunction({ } let promise; - if (labels && labels['deployment-scheduled']) { + if (labels && labels["deployment-scheduled"]) { // Scheduled function do not have meaningful data, so exclude it promise = contextOnlyHandler(context); } else { const dataOrChange = dataConstructor(event); promise = handler(dataOrChange, context); } - if (typeof promise === 'undefined') { - warn('Function returned undefined, expected Promise or value'); + if (typeof promise === "undefined") { + warn("Function returned undefined, expected Promise or value"); } return Promise.resolve(promise); }; - Object.defineProperty(cloudFunction, '__endpoint', { + Object.defineProperty(cloudFunction, "__endpoint", { get: () => { if (triggerResource() == null) { return undefined; } const endpoint: ManifestEndpoint = { - platform: 'gcfv1', + platform: "gcfv1", ...optionsToEndpoint(options), }; @@ -323,7 +321,7 @@ export function makeCloudFunction({ endpoint.scheduleTrigger = options.schedule; } else { endpoint.eventTrigger = { - eventType: legacyEventType || provider + '.' + eventType, + eventType: legacyEventType || provider + "." + eventType, eventFilters: { resource: triggerResource(), }, @@ -343,8 +341,8 @@ export function makeCloudFunction({ if (options.schedule) { cloudFunction.__requiredAPIs = [ { - api: 'cloudscheduler.googleapis.com', - reason: 'Needed for scheduled functions.', + api: "cloudscheduler.googleapis.com", + reason: "Needed for scheduled functions.", }, ]; } @@ -371,9 +369,9 @@ function _makeParams( const params: { [option: string]: any } = {}; // Note: some tests don't set context.resource.name - const eventResourceParts = context?.resource?.name?.split?.('/'); + const eventResourceParts = context?.resource?.name?.split?.("/"); if (wildcards && eventResourceParts) { - const triggerResourceParts = triggerResource.split('/'); + const triggerResourceParts = triggerResource.split("/"); for (const wildcard of wildcards) { const wildcardNoBraces = wildcard.slice(1, -1); const position = triggerResourceParts.indexOf(wildcard); @@ -385,7 +383,7 @@ function _makeParams( /** @hidden */ function _makeAuth(event: Event, authType: string) { - if (authType === 'UNAUTHENTICATED') { + if (authType === "UNAUTHENTICATED") { return null; } return { @@ -397,60 +395,43 @@ function _makeAuth(event: Event, authType: string) { /** @hidden */ function _detectAuthType(event: Event) { if (event.context?.auth?.admin) { - return 'ADMIN'; + return "ADMIN"; } if (event.context?.auth?.variable) { - return 'USER'; + return "USER"; } - return 'UNAUTHENTICATED'; + return "UNAUTHENTICATED"; } -export function optionsToEndpoint( - options: DeploymentOptions -): ManifestEndpoint { +export function optionsToEndpoint(options: DeploymentOptions): ManifestEndpoint { const endpoint: ManifestEndpoint = {}; copyIfPresent( endpoint, options, - 'minInstances', - 'maxInstances', - 'ingressSettings', - 'labels', - 'timeoutSeconds' + "minInstances", + "maxInstances", + "ingressSettings", + "labels", + "timeoutSeconds" ); - convertIfPresent(endpoint, options, 'region', 'regions'); - convertIfPresent( - endpoint, - options, - 'serviceAccountEmail', - 'serviceAccount', - (sa) => sa - ); - convertIfPresent( - endpoint, - options, - 'secretEnvironmentVariables', - 'secrets', - (secrets) => secrets.map((secret) => ({ key: secret })) + convertIfPresent(endpoint, options, "region", "regions"); + convertIfPresent(endpoint, options, "serviceAccountEmail", "serviceAccount", (sa) => sa); + convertIfPresent(endpoint, options, "secretEnvironmentVariables", "secrets", (secrets) => + secrets.map((secret) => ({ key: secret })) ); if (options?.vpcConnector) { endpoint.vpc = { connector: options.vpcConnector }; - convertIfPresent( - endpoint.vpc, - options, - 'egressSettings', - 'vpcConnectorEgressSettings' - ); + convertIfPresent(endpoint.vpc, options, "egressSettings", "vpcConnectorEgressSettings"); } - convertIfPresent(endpoint, options, 'availableMemoryMb', 'memory', (mem) => { + convertIfPresent(endpoint, options, "availableMemoryMb", "memory", (mem) => { const memoryLookup = { - '128MB': 128, - '256MB': 256, - '512MB': 512, - '1GB': 1024, - '2GB': 2048, - '4GB': 4096, - '8GB': 8192, + "128MB": 128, + "256MB": 256, + "512MB": 512, + "1GB": 1024, + "2GB": 2048, + "4GB": 4096, + "8GB": 8192, }; return memoryLookup[mem]; }); diff --git a/src/v1/config.ts b/src/v1/config.ts index 9ff7c1d24..f2bd0d6e0 100644 --- a/src/v1/config.ts +++ b/src/v1/config.ts @@ -20,10 +20,10 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import * as fs from 'fs'; -import * as path from 'path'; +import * as fs from "fs"; +import * as path from "path"; -export { firebaseConfig } from '../common/config'; +export { firebaseConfig } from "../common/config"; let singleton: Record; @@ -45,12 +45,12 @@ export function config(): Record { // K_CONFIGURATION is only set in GCFv2 if (process.env.K_CONFIGURATION) { throw new Error( - 'functions.config() is no longer available in Cloud Functions for ' + - 'Firebase v2. Please see the latest documentation for information ' + - 'on how to transition to using environment variables' + "functions.config() is no longer available in Cloud Functions for " + + "Firebase v2. Please see the latest documentation for information " + + "on how to transition to using environment variables" ); } - if (typeof singleton === 'undefined') { + if (typeof singleton === "undefined") { init(); } return singleton; @@ -68,10 +68,9 @@ function init() { try { const configPath = - process.env.CLOUD_RUNTIME_CONFIG || - path.join(process.cwd(), '.runtimeconfig.json'); + process.env.CLOUD_RUNTIME_CONFIG || path.join(process.cwd(), ".runtimeconfig.json"); const contents = fs.readFileSync(configPath); - const parsed = JSON.parse(contents.toString('utf8')); + const parsed = JSON.parse(contents.toString("utf8")); delete parsed.firebase; singleton = parsed; return; diff --git a/src/v1/function-builder.ts b/src/v1/function-builder.ts index c81509834..41286e3c7 100644 --- a/src/v1/function-builder.ts +++ b/src/v1/function-builder.ts @@ -20,9 +20,9 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import * as express from 'express'; +import * as express from "express"; -import { CloudFunction, EventContext } from './cloud-functions'; +import { EventContext } from "./cloud-functions"; import { DeploymentOptions, INGRESS_SETTINGS_OPTIONS, @@ -32,17 +32,17 @@ import { SUPPORTED_REGIONS, VALID_MEMORY_OPTIONS, VPC_EGRESS_SETTINGS_OPTIONS, -} from './function-configuration'; -import * as analytics from './providers/analytics'; -import * as auth from './providers/auth'; -import * as database from './providers/database'; -import * as firestore from './providers/firestore'; -import * as https from './providers/https'; -import * as pubsub from './providers/pubsub'; -import * as remoteConfig from './providers/remoteConfig'; -import * as storage from './providers/storage'; -import * as tasks from './providers/tasks'; -import * as testLab from './providers/testLab'; +} from "./function-configuration"; +import * as analytics from "./providers/analytics"; +import * as auth from "./providers/auth"; +import * as database from "./providers/database"; +import * as firestore from "./providers/firestore"; +import * as https from "./providers/https"; +import * as pubsub from "./providers/pubsub"; +import * as remoteConfig from "./providers/remoteConfig"; +import * as storage from "./providers/storage"; +import * as tasks from "./providers/tasks"; +import * as testLab from "./providers/testLab"; /** * Assert that the runtime options passed in are valid. @@ -50,23 +50,13 @@ import * as testLab from './providers/testLab'; * @throws { Error } Memory and TimeoutSeconds values must be valid. */ function assertRuntimeOptionsValid(runtimeOptions: RuntimeOptions): boolean { - if ( - runtimeOptions.memory && - !VALID_MEMORY_OPTIONS.includes(runtimeOptions.memory) - ) { + if (runtimeOptions.memory && !VALID_MEMORY_OPTIONS.includes(runtimeOptions.memory)) { throw new Error( - `The only valid memory allocation values are: ${VALID_MEMORY_OPTIONS.join( - ', ' - )}` + `The only valid memory allocation values are: ${VALID_MEMORY_OPTIONS.join(", ")}` ); } - if ( - runtimeOptions.timeoutSeconds > MAX_TIMEOUT_SECONDS || - runtimeOptions.timeoutSeconds < 0 - ) { - throw new Error( - `TimeoutSeconds must be between 0 and ${MAX_TIMEOUT_SECONDS}` - ); + if (runtimeOptions.timeoutSeconds > MAX_TIMEOUT_SECONDS || runtimeOptions.timeoutSeconds < 0) { + throw new Error(`TimeoutSeconds must be between 0 and ${MAX_TIMEOUT_SECONDS}`); } if ( @@ -74,21 +64,17 @@ function assertRuntimeOptionsValid(runtimeOptions: RuntimeOptions): boolean { !INGRESS_SETTINGS_OPTIONS.includes(runtimeOptions.ingressSettings) ) { throw new Error( - `The only valid ingressSettings values are: ${INGRESS_SETTINGS_OPTIONS.join( - ',' - )}` + `The only valid ingressSettings values are: ${INGRESS_SETTINGS_OPTIONS.join(",")}` ); } if ( runtimeOptions.vpcConnectorEgressSettings && - !VPC_EGRESS_SETTINGS_OPTIONS.includes( - runtimeOptions.vpcConnectorEgressSettings - ) + !VPC_EGRESS_SETTINGS_OPTIONS.includes(runtimeOptions.vpcConnectorEgressSettings) ) { throw new Error( `The only valid vpcConnectorEgressSettings values are: ${VPC_EGRESS_SETTINGS_OPTIONS.join( - ',' + "," )}` ); } @@ -96,8 +82,8 @@ function assertRuntimeOptionsValid(runtimeOptions: RuntimeOptions): boolean { validateFailurePolicy(runtimeOptions.failurePolicy); if ( runtimeOptions.serviceAccount && - runtimeOptions.serviceAccount !== 'default' && - !runtimeOptions.serviceAccount.includes('@') + runtimeOptions.serviceAccount !== "default" && + !runtimeOptions.serviceAccount.includes("@") ) { throw new Error( `serviceAccount must be set to 'default', a service account email, or '{serviceAccountName}@'` @@ -116,12 +102,12 @@ function assertRuntimeOptionsValid(runtimeOptions: RuntimeOptions): boolean { // We reserve the 'deployment' and 'firebase' namespaces for future feature development. const reservedKeys = Object.keys(runtimeOptions.labels).filter( - (key) => key.startsWith('deployment') || key.startsWith('firebase') + (key) => key.startsWith("deployment") || key.startsWith("firebase") ); if (reservedKeys.length) { throw new Error( `Invalid labels: ${reservedKeys.join( - ', ' + ", " )}. Labels may not start with reserved names 'deployment' or 'firebase'` ); } @@ -132,7 +118,7 @@ function assertRuntimeOptionsValid(runtimeOptions: RuntimeOptions): boolean { if (invalidLengthKeys.length > 0) { throw new Error( `Invalid labels: ${invalidLengthKeys.join( - ', ' + ", " )}. Label keys must be between 1 and 63 characters in length.` ); } @@ -143,7 +129,7 @@ function assertRuntimeOptionsValid(runtimeOptions: RuntimeOptions): boolean { if (invalidLengthValues.length > 0) { throw new Error( `Invalid labels: ${invalidLengthValues.join( - ', ' + ", " )}. Label values must be less than 64 charcters.` ); } @@ -156,7 +142,7 @@ function assertRuntimeOptionsValid(runtimeOptions: RuntimeOptions): boolean { if (invalidKeys.length > 0) { throw new Error( `Invalid labels: ${invalidKeys.join( - ', ' + ", " )}. Label keys can only contain lowercase letters, international characters, numbers, _ or -, and must start with a letter.` ); } @@ -169,41 +155,29 @@ function assertRuntimeOptionsValid(runtimeOptions: RuntimeOptions): boolean { if (invalidValues.length > 0) { throw new Error( `Invalid labels: ${invalidValues.join( - ', ' + ", " )}. Label values can only contain lowercase letters, international characters, numbers, _ or -.` ); } } - if ( - typeof runtimeOptions.invoker === 'string' && - runtimeOptions.invoker.length === 0 - ) { - throw new Error( - 'Invalid service account for function invoker, must be a non-empty string' - ); + if (typeof runtimeOptions.invoker === "string" && runtimeOptions.invoker.length === 0) { + throw new Error("Invalid service account for function invoker, must be a non-empty string"); } - if ( - runtimeOptions.invoker !== undefined && - Array.isArray(runtimeOptions.invoker) - ) { + if (runtimeOptions.invoker !== undefined && Array.isArray(runtimeOptions.invoker)) { if (runtimeOptions.invoker.length === 0) { - throw new Error( - 'Invalid invoker array, must contain at least 1 service account entry' - ); + throw new Error("Invalid invoker array, must contain at least 1 service account entry"); } for (const serviceAccount of runtimeOptions.invoker) { if (serviceAccount.length === 0) { - throw new Error( - 'Invalid invoker array, a service account must be a non-empty string' - ); + throw new Error("Invalid invoker array, a service account must be a non-empty string"); } - if (serviceAccount === 'public') { + if (serviceAccount === "public") { throw new Error( "Invalid invoker array, a service account cannot be set to the 'public' identifier" ); } - if (serviceAccount === 'private') { + if (serviceAccount === "private") { throw new Error( "Invalid invoker array, a service account cannot be set to the 'private' identifier" ); @@ -212,18 +186,16 @@ function assertRuntimeOptionsValid(runtimeOptions: RuntimeOptions): boolean { } if (runtimeOptions.secrets !== undefined) { - const invalidSecrets = runtimeOptions.secrets.filter( - (s) => !/^[A-Za-z\d\-_]+$/.test(s) - ); + const invalidSecrets = runtimeOptions.secrets.filter((s) => !/^[A-Za-z\d\-_]+$/.test(s)); if (invalidSecrets.length > 0) { throw new Error( - `Invalid secrets: ${invalidSecrets.join(',')}. ` + - 'Secret must be configured using the resource id (e.g. API_KEY)' + `Invalid secrets: ${invalidSecrets.join(",")}. ` + + "Secret must be configured using the resource id (e.g. API_KEY)" ); } } - if ('allowInvalidAppCheckToken' in runtimeOptions) { + if ("allowInvalidAppCheckToken" in runtimeOptions) { throw new Error( 'runWith option "allowInvalidAppCheckToken" has been inverted and ' + 'renamed "enforceAppCheck"' @@ -234,16 +206,16 @@ function assertRuntimeOptionsValid(runtimeOptions: RuntimeOptions): boolean { } function validateFailurePolicy(policy: any) { - if (typeof policy === 'boolean' || typeof policy === 'undefined') { + if (typeof policy === "boolean" || typeof policy === "undefined") { return; } - if (typeof policy !== 'object') { + if (typeof policy !== "object") { throw new Error(`failurePolicy must be a boolean or an object.`); } const retry = policy.retry; - if (typeof retry !== 'object' || Object.keys(retry).length) { - throw new Error('failurePolicy.retry must be an empty object.'); + if (typeof retry !== "object" || Object.keys(retry).length) { + throw new Error("failurePolicy.retry must be an empty object."); } } @@ -254,7 +226,7 @@ function validateFailurePolicy(policy: any) { */ function assertRegionsAreValid(regions: string[]): boolean { if (!regions.length) { - throw new Error('You must specify at least one region'); + throw new Error("You must specify at least one region"); } return true; } @@ -310,9 +282,7 @@ export class FunctionBuilder { * @example * functions.region('us-east1', 'us-central1') */ - region( - ...regions: Array - ): FunctionBuilder { + region(...regions: Array): FunctionBuilder { if (assertRegionsAreValid(regions)) { this.options.regions = regions; return this; @@ -346,9 +316,7 @@ export class FunctionBuilder { get https() { if (this.options.failurePolicy !== undefined) { - console.warn( - 'RuntimeOptions.failurePolicy is not supported in https functions.' - ); + console.warn("RuntimeOptions.failurePolicy is not supported in https functions."); } return { @@ -357,22 +325,14 @@ export class FunctionBuilder { * @param handler A function that takes a request and response object, * same signature as an Express app. */ - onRequest: ( - handler: ( - req: https.Request, - resp: express.Response - ) => void | Promise - ) => https._onRequestWithOptions(handler, this.options), + onRequest: (handler: (req: https.Request, resp: express.Response) => void | Promise) => + https._onRequestWithOptions(handler, this.options), /** * Declares a callable method for clients to call using a Firebase SDK. * @param handler A method that takes a data and context and returns a value. */ - onCall: ( - handler: ( - data: any, - context: https.CallableContext - ) => any | Promise - ) => https._onCallWithOptions(handler, this.options), + onCall: (handler: (data: any, context: https.CallableContext) => any | Promise) => + https._onCallWithOptions(handler, this.options), }; } @@ -396,8 +356,7 @@ export class FunctionBuilder { * will pick the default database for your project. * @param instance The Realtime Database instance to use. */ - instance: (instance: string) => - database._instanceWithOptions(instance, this.options), + instance: (instance: string) => database._instanceWithOptions(instance, this.options), /** * Select Firebase Realtime Database Reference to listen to. @@ -424,8 +383,7 @@ export class FunctionBuilder { * information about the user who triggered the Cloud Function. * @param ref Path of the database to listen to. */ - ref: (path: Ref) => - database._refWithOptions(path, this.options), + ref: (path: Ref) => database._refWithOptions(path, this.options), }; } @@ -442,12 +400,10 @@ export class FunctionBuilder { firestore._documentWithOptions(path, this.options), /** @hidden */ - namespace: (namespace: string) => - firestore._namespaceWithOptions(namespace, this.options), + namespace: (namespace: string) => firestore._namespaceWithOptions(namespace, this.options), /** @hidden */ - database: (database: string) => - firestore._databaseWithOptions(database, this.options), + database: (database: string) => firestore._databaseWithOptions(database, this.options), }; } @@ -475,11 +431,7 @@ export class FunctionBuilder { version: remoteConfig.TemplateVersion, context: EventContext ) => PromiseLike | any - ) => - remoteConfig._onUpdateWithOptions( - handler, - this.options - ) as CloudFunction, + ) => remoteConfig._onUpdateWithOptions(handler, this.options), }; } @@ -491,8 +443,7 @@ export class FunctionBuilder { * which will use the default Cloud Storage for Firebase bucket. * @param bucket Name of the Google Cloud Storage bucket to listen to. */ - bucket: (bucket?: string) => - storage._bucketWithOptions(this.options, bucket), + bucket: (bucket?: string) => storage._bucketWithOptions(this.options, bucket), /** * Handle events related to Cloud Storage objects. @@ -509,8 +460,7 @@ export class FunctionBuilder { * the function. */ topic: (topic: string) => pubsub._topicWithOptions(topic, this.options), - schedule: (schedule: string) => - pubsub._scheduleWithOptions(schedule, this.options), + schedule: (schedule: string) => pubsub._scheduleWithOptions(schedule, this.options), }; } @@ -519,8 +469,7 @@ export class FunctionBuilder { /** * Handle events related to Firebase authentication users. */ - user: (userOptions?: auth.UserOptions) => - auth._userWithOptions(this.options, userOptions), + user: (userOptions?: auth.UserOptions) => auth._userWithOptions(this.options, userOptions), }; } diff --git a/src/v1/function-configuration.ts b/src/v1/function-configuration.ts index be0642cf3..ca255b58a 100644 --- a/src/v1/function-configuration.ts +++ b/src/v1/function-configuration.ts @@ -2,28 +2,28 @@ * List of all regions supported by Cloud Functions. */ export const SUPPORTED_REGIONS = [ - 'us-central1', - 'us-east1', - 'us-east4', - 'us-west2', - 'us-west3', - 'us-west4', - 'europe-central2', - 'europe-west1', - 'europe-west2', - 'europe-west3', - 'europe-west6', - 'asia-east1', - 'asia-east2', - 'asia-northeast1', - 'asia-northeast2', - 'asia-northeast3', - 'asia-south1', - 'asia-southeast1', - 'asia-southeast2', - 'northamerica-northeast1', - 'southamerica-east1', - 'australia-southeast1', + "us-central1", + "us-east1", + "us-east4", + "us-west2", + "us-west3", + "us-west4", + "europe-central2", + "europe-west1", + "europe-west2", + "europe-west3", + "europe-west6", + "asia-east1", + "asia-east2", + "asia-northeast1", + "asia-northeast2", + "asia-northeast3", + "asia-south1", + "asia-southeast1", + "asia-southeast2", + "northamerica-northeast1", + "southamerica-east1", + "australia-southeast1", ] as const; /** @@ -40,32 +40,32 @@ export const MAX_TIMEOUT_SECONDS = 540; * List of available memory options supported by Cloud Functions. */ export const VALID_MEMORY_OPTIONS = [ - '128MB', - '256MB', - '512MB', - '1GB', - '2GB', - '4GB', - '8GB', + "128MB", + "256MB", + "512MB", + "1GB", + "2GB", + "4GB", + "8GB", ] as const; /** * List of available options for VpcConnectorEgressSettings. */ export const VPC_EGRESS_SETTINGS_OPTIONS = [ - 'VPC_CONNECTOR_EGRESS_SETTINGS_UNSPECIFIED', - 'PRIVATE_RANGES_ONLY', - 'ALL_TRAFFIC', + "VPC_CONNECTOR_EGRESS_SETTINGS_UNSPECIFIED", + "PRIVATE_RANGES_ONLY", + "ALL_TRAFFIC", ] as const; /** * List of available options for IngressSettings. */ export const INGRESS_SETTINGS_OPTIONS = [ - 'INGRESS_SETTINGS_UNSPECIFIED', - 'ALLOW_ALL', - 'ALLOW_INTERNAL_ONLY', - 'ALLOW_INTERNAL_AND_GCLB', + "INGRESS_SETTINGS_UNSPECIFIED", + "ALLOW_ALL", + "ALLOW_INTERNAL_ONLY", + "ALLOW_INTERNAL_AND_GCLB", ] as const; /** @@ -89,7 +89,7 @@ export interface Schedule { } export interface FailurePolicy { - retry: {}; + retry: Record; } export const MAX_NUMBER_USER_LABELS = 58; @@ -99,7 +99,7 @@ export interface RuntimeOptions { * Which platform should host the backend. Valid options are "gcfv1" * @hidden */ - platform?: 'gcfv1'; + platform?: "gcfv1"; /** * Failure policy of the function, with boolean `true` being equivalent to @@ -140,7 +140,7 @@ export interface RuntimeOptions { /** * Specific service account for the function to run as. */ - serviceAccount?: 'default' | string; + serviceAccount?: "default" | string; /** * Ingress settings which control where this function can be called from. @@ -155,7 +155,7 @@ export interface RuntimeOptions { /** * Invoker to set access control on https functions. */ - invoker?: 'public' | 'private' | string | string[]; + invoker?: "public" | "private" | string | string[]; /* * Secrets to bind to a function instance. diff --git a/src/v1/handler-builder.ts b/src/v1/handler-builder.ts index 454ad016f..d9c964157 100644 --- a/src/v1/handler-builder.ts +++ b/src/v1/handler-builder.ts @@ -20,19 +20,19 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import * as express from 'express'; - -import { CloudFunction, EventContext, HttpsFunction } from './cloud-functions'; -import * as analytics from './providers/analytics'; -import * as auth from './providers/auth'; -import * as database from './providers/database'; -import * as firestore from './providers/firestore'; -import * as https from './providers/https'; -import * as pubsub from './providers/pubsub'; -import * as remoteConfig from './providers/remoteConfig'; -import * as storage from './providers/storage'; -import * as tasks from './providers/tasks'; -import * as testLab from './providers/testLab'; +import * as express from "express"; + +import { CloudFunction, EventContext, HttpsFunction } from "./cloud-functions"; +import * as analytics from "./providers/analytics"; +import * as auth from "./providers/auth"; +import * as database from "./providers/database"; +import * as firestore from "./providers/firestore"; +import * as https from "./providers/https"; +import * as pubsub from "./providers/pubsub"; +import * as remoteConfig from "./providers/remoteConfig"; +import * as storage from "./providers/storage"; +import * as tasks from "./providers/tasks"; +import * as testLab from "./providers/testLab"; /** * The `HandlerBuilder` class facilitates the writing of functions by developers @@ -44,7 +44,9 @@ import * as testLab from './providers/testLab'; * [`FunctionBuilder`](/docs/reference/functions/function_builder_.functionbuilder). */ export class HandlerBuilder { - constructor() {} + constructor() { + // do nothing + } /** * Create a handler for HTTPS events. @@ -74,10 +76,7 @@ export class HandlerBuilder { return func; }, onCall: ( - handler: ( - data: any, - context: https.CallableContext - ) => any | Promise + handler: (data: any, context: https.CallableContext) => any | Promise ): HttpsFunction => { const func = https._onCallWithOptions(handler, {}); func.__endpoint = undefined; @@ -101,10 +100,7 @@ export class HandlerBuilder { get taskQueue() { return { onDispatch: ( - handler: ( - data: any, - context: tasks.TaskContext - ) => void | Promise + handler: (data: any, context: tasks.TaskContext) => void | Promise ): HttpsFunction => { const builder = new tasks.TaskQueueBuilder(); const func = builder.onDispatch(handler); @@ -372,4 +368,4 @@ export class HandlerBuilder { } } -export let handler = new HandlerBuilder(); +export const handler = new HandlerBuilder(); diff --git a/src/v1/index.ts b/src/v1/index.ts index 3255dffa0..221e68014 100644 --- a/src/v1/index.ts +++ b/src/v1/index.ts @@ -21,20 +21,20 @@ // SOFTWARE. // Providers: -import * as logger from '../logger'; -import * as analytics from './providers/analytics'; -import * as auth from './providers/auth'; -import * as database from './providers/database'; -import * as firestore from './providers/firestore'; -import * as https from './providers/https'; -import * as pubsub from './providers/pubsub'; -import * as remoteConfig from './providers/remoteConfig'; -import * as storage from './providers/storage'; -import * as tasks from './providers/tasks'; -import * as testLab from './providers/testLab'; +import * as logger from "../logger"; +import * as analytics from "./providers/analytics"; +import * as auth from "./providers/auth"; +import * as database from "./providers/database"; +import * as firestore from "./providers/firestore"; +import * as https from "./providers/https"; +import * as pubsub from "./providers/pubsub"; +import * as remoteConfig from "./providers/remoteConfig"; +import * as storage from "./providers/storage"; +import * as tasks from "./providers/tasks"; +import * as testLab from "./providers/testLab"; -import { setApp as setEmulatedAdminApp } from '../common/app'; -import { handler } from './handler-builder'; +import { setApp as setEmulatedAdminApp } from "../common/app"; +import { handler } from "./handler-builder"; export { analytics, @@ -54,7 +54,7 @@ export { export const app = { setEmulatedAdminApp }; // Exported root types: -export * from './cloud-functions'; -export * from './config'; -export * from './function-builder'; -export * from './function-configuration'; +export * from "./cloud-functions"; +export * from "./config"; +export * from "./function-builder"; +export * from "./function-configuration"; diff --git a/src/v1/providers/analytics.ts b/src/v1/providers/analytics.ts index f5d68bc8c..4cf7b5d36 100644 --- a/src/v1/providers/analytics.ts +++ b/src/v1/providers/analytics.ts @@ -20,18 +20,13 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { - CloudFunction, - Event, - EventContext, - makeCloudFunction, -} from '../cloud-functions'; -import { DeploymentOptions } from '../function-configuration'; +import { CloudFunction, Event, EventContext, makeCloudFunction } from "../cloud-functions"; +import { DeploymentOptions } from "../function-configuration"; /** @hidden */ -export const provider = 'google.analytics'; +export const provider = "google.analytics"; /** @hidden */ -export const service = 'app-measurement.com'; +export const service = "app-measurement.com"; /** * Registers a function to handle analytics events. @@ -46,17 +41,12 @@ export function event(analyticsEventType: string) { } /** @hidden */ -export function _eventWithOptions( - analyticsEventType: string, - options: DeploymentOptions -) { +export function _eventWithOptions(analyticsEventType: string, options: DeploymentOptions) { return new AnalyticsEventBuilder(() => { if (!process.env.GCLOUD_PROJECT) { - throw new Error('process.env.GCLOUD_PROJECT is not set.'); + throw new Error("process.env.GCLOUD_PROJECT is not set."); } - return ( - 'projects/' + process.env.GCLOUD_PROJECT + '/events/' + analyticsEventType - ); + return "projects/" + process.env.GCLOUD_PROJECT + "/events/" + analyticsEventType; }, options); } @@ -67,10 +57,7 @@ export function _eventWithOptions( */ export class AnalyticsEventBuilder { /** @hidden */ - constructor( - private triggerResource: () => string, - private options: DeploymentOptions - ) {} + constructor(private triggerResource: () => string, private options: DeploymentOptions) {} /** * Event handler that fires every time a Firebase Analytics event occurs. @@ -81,10 +68,7 @@ export class AnalyticsEventBuilder { * @return A function that you can export and deploy. */ onLog( - handler: ( - event: AnalyticsEvent, - context: EventContext - ) => PromiseLike | any + handler: (event: AnalyticsEvent, context: EventContext) => PromiseLike | any ): CloudFunction { const dataConstructor = (raw: Event) => { return new AnalyticsEvent(raw.data); @@ -92,7 +76,7 @@ export class AnalyticsEventBuilder { return makeCloudFunction({ handler, provider, - eventType: 'event.log', + eventType: "event.log", service, legacyEventType: `providers/google.firebase.analytics/eventTypes/event.log`, triggerResource: this.triggerResource, @@ -140,25 +124,14 @@ export class AnalyticsEvent { if (wireFormat.eventDim && wireFormat.eventDim.length > 0) { // If there's an eventDim, there'll always be exactly one. const eventDim = wireFormat.eventDim[0]; - copyField(eventDim, this, 'name'); - copyField(eventDim, this, 'params', (p) => mapKeys(p, unwrapValue)); - copyFieldTo(eventDim, this, 'valueInUsd', 'valueInUSD'); - copyFieldTo(eventDim, this, 'date', 'reportingDate'); - copyTimestampToString(eventDim, this, 'timestampMicros', 'logTime'); - copyTimestampToString( - eventDim, - this, - 'previousTimestampMicros', - 'previousLogTime' - ); + copyField(eventDim, this, "name"); + copyField(eventDim, this, "params", (p) => mapKeys(p, unwrapValue)); + copyFieldTo(eventDim, this, "valueInUsd", "valueInUSD"); + copyFieldTo(eventDim, this, "date", "reportingDate"); + copyTimestampToString(eventDim, this, "timestampMicros", "logTime"); + copyTimestampToString(eventDim, this, "previousTimestampMicros", "previousLogTime"); } - copyFieldTo( - wireFormat, - this, - 'userDim', - 'user', - (dim) => new UserDimensions(dim) - ); + copyFieldTo(wireFormat, this, "userDim", "user", (dim) => new UserDimensions(dim)); } } @@ -201,39 +174,21 @@ export class UserDimensions { /** @hidden */ constructor(wireFormat: any) { // These are interfaces or primitives, no transformation needed. - copyFields(wireFormat, this, [ - 'userId', - 'deviceInfo', - 'geoInfo', - 'appInfo', - ]); + copyFields(wireFormat, this, ["userId", "deviceInfo", "geoInfo", "appInfo"]); // The following fields do need transformations of some sort. - copyTimestampToString( - wireFormat, - this, - 'firstOpenTimestampMicros', - 'firstOpenTime' - ); + copyTimestampToString(wireFormat, this, "firstOpenTimestampMicros", "firstOpenTime"); this.userProperties = {}; // With no entries in the wire format, present an empty (as opposed to absent) map. - copyField(wireFormat, this, 'userProperties', (r) => { - const entries = Object.entries(r).map(([k, v]) => [ - k, - new UserPropertyValue(v), - ]); + copyField(wireFormat, this, "userProperties", (r) => { + const entries = Object.entries(r).map(([k, v]) => [k, new UserPropertyValue(v)]); return Object.fromEntries(entries); }); - copyField( - wireFormat, - this, - 'bundleInfo', - (r) => new ExportBundleInfo(r) as any - ); + copyField(wireFormat, this, "bundleInfo", (r) => new ExportBundleInfo(r) as any); // BUG(36000368) Remove when no longer necessary /* tslint:disable:no-string-literal */ - if (!this.userId && this.userProperties['user_id']) { - this.userId = this.userProperties['user_id'].value; + if (!this.userId && this.userProperties["user_id"]) { + this.userId = this.userProperties["user_id"].value; } /* tslint:enable:no-string-literal */ } @@ -249,8 +204,8 @@ export class UserPropertyValue { /** @hidden */ constructor(wireFormat: any) { - copyField(wireFormat, this, 'value', unwrapValueAsString as any); - copyTimestampToString(wireFormat, this, 'setTimestampUsec', 'setTime'); + copyField(wireFormat, this, "value", unwrapValueAsString as any); + copyTimestampToString(wireFormat, this, "setTimestampUsec", "setTime"); } } @@ -414,30 +369,20 @@ export class ExportBundleInfo { /** @hidden */ constructor(wireFormat: any) { - copyField(wireFormat, this, 'bundleSequenceId'); - copyTimestampToMillis( - wireFormat, - this, - 'serverTimestampOffsetMicros', - 'serverTimestampOffset' - ); + copyField(wireFormat, this, "bundleSequenceId"); + copyTimestampToMillis(wireFormat, this, "serverTimestampOffsetMicros", "serverTimestampOffset"); } } /** @hidden */ -function copyFieldTo< - From extends object, - FromKey extends keyof From, - To extends object, - ToKey extends keyof To ->( +function copyFieldTo( from: From, to: To, fromField: FromKey, toField: ToKey, transform?: (val: Required[FromKey]) => Required[ToKey] ): void { - if (typeof from[fromField] === 'undefined') { + if (typeof from[fromField] === "undefined") { return; } if (transform) { @@ -448,36 +393,30 @@ function copyFieldTo< } /** @hidden */ -function copyField< - From extends object, - To extends Object, - Key extends keyof From & keyof To ->( +function copyField( from: From, to: To, field: Key, - transform: (val: Required[Key]) => Required[Key] = (from) => - from as any + transform: (val: Required[Key]) => Required[Key] = (from) => from as any ): void { copyFieldTo(from, to, field, field, transform); } /** @hidden */ -function copyFields< - From extends object, - To extends object, - Key extends keyof From & keyof To ->(from: From, to: To, fields: Key[]): void { +function copyFields( + from: From, + to: To, + fields: Key[] +): void { for (const field of fields) { copyField(from, to, field); } } -type TransformedObject< - Obj extends Object, - Transform extends (key: keyof Obj) => any -> = { [key in keyof Obj]: ReturnType }; -function mapKeys any>( +type TransformedObject any> = { + [key in keyof Obj]: ReturnType; +}; +function mapKeys any>( obj: Obj, transform: Transform ): TransformedObject { @@ -534,7 +473,7 @@ function unwrapValueAsString(wrapped: any): string { // JavaScript's 'number' type, since we prefer using idiomatic types. Note that this may lead to loss // in precision for int64 fields, so use with care. /** @hidden */ -const xValueNumberFields = ['intValue', 'floatValue', 'doubleValue']; +const xValueNumberFields = ["intValue", "floatValue", "doubleValue"]; /** @hidden */ function unwrapValue(wrapped: any): any { diff --git a/src/v1/providers/auth.ts b/src/v1/providers/auth.ts index 190441c55..249701380 100644 --- a/src/v1/providers/auth.ts +++ b/src/v1/providers/auth.ts @@ -32,7 +32,7 @@ import { userRecordConstructor, UserRecordMetadata, wrapHandler, -} from '../../common/providers/identity'; +} from "../../common/providers/identity"; import { BlockingFunction, CloudFunction, @@ -40,8 +40,8 @@ import { EventContext, makeCloudFunction, optionsToEndpoint, -} from '../cloud-functions'; -import { DeploymentOptions } from '../function-configuration'; +} from "../cloud-functions"; +import { DeploymentOptions } from "../function-configuration"; // TODO: yank in next breaking change release export { UserRecord, UserInfo, UserRecordMetadata, userRecordConstructor }; @@ -49,9 +49,9 @@ export { UserRecord, UserInfo, UserRecordMetadata, userRecordConstructor }; export { HttpsError }; /** @hidden */ -export const provider = 'google.firebase.auth'; +export const provider = "google.firebase.auth"; /** @hidden */ -export const service = 'firebaseauth.googleapis.com'; +export const service = "firebaseauth.googleapis.com"; /** * Resource level options @@ -82,16 +82,13 @@ export function user(userOptions?: UserOptions): UserBuilder { } /** @hidden */ -export function _userWithOptions( - options: DeploymentOptions, - userOptions: UserOptions -) { +export function _userWithOptions(options: DeploymentOptions, userOptions: UserOptions) { return new UserBuilder( () => { if (!process.env.GCLOUD_PROJECT) { - throw new Error('process.env.GCLOUD_PROJECT is not set.'); + throw new Error("process.env.GCLOUD_PROJECT is not set."); } - return 'projects/' + process.env.GCLOUD_PROJECT; + return "projects/" + process.env.GCLOUD_PROJECT; }, options, userOptions @@ -121,7 +118,7 @@ export class UserBuilder { onCreate( handler: (user: UserRecord, context: EventContext) => PromiseLike | any ): CloudFunction { - return this.onOperation(handler, 'user.create'); + return this.onOperation(handler, "user.create"); } /** @@ -131,41 +128,30 @@ export class UserBuilder { onDelete( handler: (user: UserRecord, context: EventContext) => PromiseLike | any ): CloudFunction { - return this.onOperation(handler, 'user.delete'); + return this.onOperation(handler, "user.delete"); } beforeCreate( handler: ( user: AuthUserRecord, context: AuthEventContext - ) => - | BeforeCreateResponse - | void - | Promise - | Promise + ) => BeforeCreateResponse | void | Promise | Promise ): BlockingFunction { - return this.beforeOperation(handler, 'beforeCreate'); + return this.beforeOperation(handler, "beforeCreate"); } beforeSignIn( handler: ( user: AuthUserRecord, context: AuthEventContext - ) => - | BeforeSignInResponse - | void - | Promise - | Promise + ) => BeforeSignInResponse | void | Promise | Promise ): BlockingFunction { - return this.beforeOperation(handler, 'beforeSignIn'); + return this.beforeOperation(handler, "beforeSignIn"); } /** @hidden */ private onOperation( - handler: ( - user: UserRecord, - context: EventContext - ) => PromiseLike | any, + handler: (user: UserRecord, context: EventContext) => PromiseLike | any, eventType: string ): CloudFunction { return makeCloudFunction({ @@ -174,6 +160,7 @@ export class UserBuilder { eventType, service, triggerResource: this.triggerResource, + // eslint-disable-next-line @typescript-eslint/unbound-method dataConstructor: UserBuilder.dataConstructor, legacyEventType: `providers/firebase.auth/eventTypes/${eventType}`, options: this.options, @@ -196,8 +183,7 @@ export class UserBuilder { ): BlockingFunction { const accessToken = this.userOptions?.blockingOptions?.accessToken || false; const idToken = this.userOptions?.blockingOptions?.idToken || false; - const refreshToken = - this.userOptions?.blockingOptions?.refreshToken || false; + const refreshToken = this.userOptions?.blockingOptions?.refreshToken || false; // Create our own function that just calls the provided function so we know for sure that // handler takes two arguments. This is something common/providers/identity depends on. @@ -208,7 +194,7 @@ export class UserBuilder { const legacyEventType = `providers/cloud.auth/eventTypes/user.${eventType}`; func.__endpoint = { - platform: 'gcfv1', + platform: "gcfv1", labels: {}, ...optionsToEndpoint(this.options), blockingTrigger: { @@ -223,8 +209,8 @@ export class UserBuilder { func.__requiredAPIs = [ { - api: 'identitytoolkit.googleapis.com', - reason: 'Needed for auth blocking functions', + api: "identitytoolkit.googleapis.com", + reason: "Needed for auth blocking functions", }, ]; diff --git a/src/v1/providers/database.ts b/src/v1/providers/database.ts index e78c27709..6d9dc087e 100644 --- a/src/v1/providers/database.ts +++ b/src/v1/providers/database.ts @@ -20,30 +20,25 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { getApp } from '../../common/app'; -import { Change } from '../../common/change'; -import { firebaseConfig } from '../../common/config'; -import { ParamsOf } from '../../common/params'; -import { DataSnapshot } from '../../common/providers/database'; -import { normalizePath } from '../../common/utilities/path'; -import { applyChange } from '../../common/utilities/utils'; -import { - CloudFunction, - Event, - EventContext, - makeCloudFunction, -} from '../cloud-functions'; -import { DeploymentOptions } from '../function-configuration'; +import { getApp } from "../../common/app"; +import { Change } from "../../common/change"; +import { firebaseConfig } from "../../common/config"; +import { ParamsOf } from "../../common/params"; +import { DataSnapshot } from "../../common/providers/database"; +import { normalizePath } from "../../common/utilities/path"; +import { applyChange } from "../../common/utilities/utils"; +import { CloudFunction, Event, EventContext, makeCloudFunction } from "../cloud-functions"; +import { DeploymentOptions } from "../function-configuration"; export { DataSnapshot }; /** @hidden */ -export const provider = 'google.firebase.database'; +export const provider = "google.firebase.database"; /** @hidden */ -export const service = 'firebaseio.com'; +export const service = "firebaseio.com"; -const databaseURLRegex = new RegExp('^https://([^.]+).'); -const emulatorDatabaseURLRegex = new RegExp('^http://.*ns=([^&]+)'); +const databaseURLRegex = new RegExp("^https://([^.]+)."); +const emulatorDatabaseURLRegex = new RegExp("^http://.*ns=([^&]+)"); /** * Registers a function that triggers on events from a specific @@ -134,10 +129,10 @@ export function _refWithOptions( const databaseURL = firebaseConfig().databaseURL; if (!databaseURL) { throw new Error( - 'Missing expected firebase config value databaseURL, ' + - 'config is actually' + + "Missing expected firebase config value databaseURL, " + + "config is actually" + JSON.stringify(firebaseConfig()) + - '\n If you are unit testing, please set process.env.FIREBASE_CONFIG' + "\n If you are unit testing, please set process.env.FIREBASE_CONFIG" ); } @@ -153,9 +148,7 @@ export function _refWithOptions( } if (!instance) { - throw new Error( - 'Invalid value for config firebase.databaseURL: ' + databaseURL - ); + throw new Error("Invalid value for config firebase.databaseURL: " + databaseURL); } return `projects/_/instances/${instance}/refs/${normalized}`; @@ -171,10 +164,7 @@ export function _refWithOptions( */ export class RefBuilder { /** @hidden */ - constructor( - private triggerResource: () => string, - private options: DeploymentOptions - ) {} + constructor(private triggerResource: () => string, private options: DeploymentOptions) {} /** * Event handler that fires every time a Firebase Realtime Database write @@ -190,7 +180,7 @@ export class RefBuilder { context: EventContext> ) => PromiseLike | any ): CloudFunction> { - return this.onOperation(handler, 'ref.write', this.changeConstructor); + return this.onOperation(handler, "ref.write", this.changeConstructor); } /** @@ -208,7 +198,7 @@ export class RefBuilder { context: EventContext> ) => PromiseLike | any ): CloudFunction> { - return this.onOperation(handler, 'ref.update', this.changeConstructor); + return this.onOperation(handler, "ref.update", this.changeConstructor); } /** @@ -232,7 +222,7 @@ export class RefBuilder { ); return new DataSnapshot(raw.data.delta, path, getApp(), dbInstance); }; - return this.onOperation(handler, 'ref.create', dataConstructor); + return this.onOperation(handler, "ref.create", dataConstructor); } /** @@ -256,7 +246,7 @@ export class RefBuilder { ); return new DataSnapshot(raw.data.data, path, getApp(), dbInstance); }; - return this.onOperation(handler, 'ref.delete', dataConstructor); + return this.onOperation(handler, "ref.delete", dataConstructor); } private onOperation( @@ -295,8 +285,7 @@ export class RefBuilder { }; } -const resourceRegex = - /^projects\/([^/]+)\/instances\/([a-zA-Z0-9-]+)\/refs(\/.+)?/; +const resourceRegex = /^projects\/([^/]+)\/instances\/([a-zA-Z0-9-]+)\/refs(\/.+)?/; /** * Utility function to extract database reference from resource string @@ -307,10 +296,7 @@ const resourceRegex = * Since region is not part of the resource name, it is provided through context. */ /** @hidden */ -export function extractInstanceAndPath( - resource: string, - domain = 'firebaseio.com' -) { +export function extractInstanceAndPath(resource: string, domain = "firebaseio.com") { const match = resource.match(new RegExp(resourceRegex)); if (!match) { throw new Error( @@ -319,10 +305,8 @@ export function extractInstanceAndPath( ); } const [, project, dbInstanceName, path] = match; - if (project !== '_') { - throw new Error( - `Expect project to be '_' in a Firebase Realtime Database event` - ); + if (project !== "_") { + throw new Error(`Expect project to be '_' in a Firebase Realtime Database event`); } const emuHost = process.env.FIREBASE_DATABASE_EMULATOR_HOST; @@ -330,7 +314,7 @@ export function extractInstanceAndPath( const dbInstance = `http://${emuHost}/?ns=${dbInstanceName}`; return [dbInstance, path]; } else { - const dbInstance = 'https://' + dbInstanceName + '.' + domain; + const dbInstance = "https://" + dbInstanceName + "." + domain; return [dbInstance, path]; } } diff --git a/src/v1/providers/firestore.ts b/src/v1/providers/firestore.ts index b0a09c72a..3ed9f3799 100644 --- a/src/v1/providers/firestore.ts +++ b/src/v1/providers/firestore.ts @@ -20,28 +20,23 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import * as firestore from 'firebase-admin/firestore'; +import * as firestore from "firebase-admin/firestore"; -import { posix } from 'path'; -import { getApp } from '../../common/app'; -import { Change } from '../../common/change'; -import { ParamsOf } from '../../common/params'; -import { dateToTimestampProto } from '../../common/utilities/encoder'; -import * as logger from '../../logger'; -import { - CloudFunction, - Event, - EventContext, - makeCloudFunction, -} from '../cloud-functions'; -import { DeploymentOptions } from '../function-configuration'; +import { posix } from "path"; +import { getApp } from "../../common/app"; +import { Change } from "../../common/change"; +import { ParamsOf } from "../../common/params"; +import { dateToTimestampProto } from "../../common/utilities/encoder"; +import * as logger from "../../logger"; +import { CloudFunction, Event, EventContext, makeCloudFunction } from "../cloud-functions"; +import { DeploymentOptions } from "../function-configuration"; /** @hidden */ -export const provider = 'google.firestore'; +export const provider = "google.firestore"; /** @hidden */ -export const service = 'firestore.googleapis.com'; +export const service = "firestore.googleapis.com"; /** @hidden */ -export const defaultDatabase = '(default)'; +export const defaultDatabase = "(default)"; let firestoreInstance: any; export type DocumentSnapshot = firestore.DocumentSnapshot; export type QueryDocumentSnapshot = firestore.QueryDocumentSnapshot; @@ -78,18 +73,12 @@ export function _databaseWithOptions( } /** @hidden */ -export function _namespaceWithOptions( - namespace: string, - options: DeploymentOptions -) { +export function _namespaceWithOptions(namespace: string, options: DeploymentOptions) { return _databaseWithOptions(defaultDatabase, options).namespace(namespace); } /** @hidden */ -export function _documentWithOptions( - path: Path, - options: DeploymentOptions -) { +export function _documentWithOptions(path: Path, options: DeploymentOptions) { return _databaseWithOptions(defaultDatabase, options).document(path); } @@ -117,17 +106,17 @@ export class NamespaceBuilder { document(path: Path) { return new DocumentBuilder(() => { if (!process.env.GCLOUD_PROJECT) { - throw new Error('process.env.GCLOUD_PROJECT is not set.'); + throw new Error("process.env.GCLOUD_PROJECT is not set."); } const database = posix.join( - 'projects', + "projects", process.env.GCLOUD_PROJECT, - 'databases', + "databases", this.database ); return posix.join( database, - this.namespace ? `documents@${this.namespace}` : 'documents', + this.namespace ? `documents@${this.namespace}` : "documents", path ); }, this.options); @@ -137,9 +126,9 @@ export class NamespaceBuilder { function _getValueProto(data: any, resource: string, valueFieldName: string) { const value = data?.[valueFieldName]; if ( - typeof value === 'undefined' || + typeof value === "undefined" || value === null || - (typeof value === 'object' && !Object.keys(value).length) + (typeof value === "object" && !Object.keys(value).length) ) { // Firestore#snapshot_ takes resource string instead of proto for a non-existent snapshot return resource; @@ -158,21 +147,16 @@ export function snapshotConstructor(event: Event): DocumentSnapshot { if (!firestoreInstance) { firestoreInstance = firestore.getFirestore(getApp()); } - const valueProto = _getValueProto( - event.data, - event.context.resource.name, - 'value' - ); - let timeString = - event?.data?.value?.readTime ?? event?.data?.value?.updateTime; + const valueProto = _getValueProto(event.data, event.context.resource.name, "value"); + let timeString = event?.data?.value?.readTime ?? event?.data?.value?.updateTime; if (!timeString) { - logger.warn('Snapshot has no readTime. Using now()'); + logger.warn("Snapshot has no readTime. Using now()"); timeString = new Date().toISOString(); } const readTime = dateToTimestampProto(timeString); - return firestoreInstance.snapshot_(valueProto, readTime, 'json'); + return firestoreInstance.snapshot_(valueProto, readTime, "json"); } /** @hidden */ @@ -181,28 +165,18 @@ export function beforeSnapshotConstructor(event: Event): DocumentSnapshot { if (!firestoreInstance) { firestoreInstance = firestore.getFirestore(getApp()); } - const oldValueProto = _getValueProto( - event.data, - event.context.resource.name, - 'oldValue' - ); + const oldValueProto = _getValueProto(event.data, event.context.resource.name, "oldValue"); const oldReadTime = dateToTimestampProto(event?.data?.oldValue?.readTime); - return firestoreInstance.snapshot_(oldValueProto, oldReadTime, 'json'); + return firestoreInstance.snapshot_(oldValueProto, oldReadTime, "json"); } function changeConstructor(raw: Event) { - return Change.fromObjects( - beforeSnapshotConstructor(raw), - snapshotConstructor(raw) - ); + return Change.fromObjects(beforeSnapshotConstructor(raw), snapshotConstructor(raw)); } export class DocumentBuilder { /** @hidden */ - constructor( - private triggerResource: () => string, - private options: DeploymentOptions - ) { + constructor(private triggerResource: () => string, private options: DeploymentOptions) { // TODO what validation do we want to do here? } @@ -213,7 +187,7 @@ export class DocumentBuilder { context: EventContext> ) => PromiseLike | any ): CloudFunction> { - return this.onOperation(handler, 'document.write', changeConstructor); + return this.onOperation(handler, "document.write", changeConstructor); } /** Respond only to document updates. */ @@ -223,7 +197,7 @@ export class DocumentBuilder { context: EventContext> ) => PromiseLike | any ): CloudFunction> { - return this.onOperation(handler, 'document.update', changeConstructor); + return this.onOperation(handler, "document.update", changeConstructor); } /** Respond only to document creations. */ @@ -233,7 +207,7 @@ export class DocumentBuilder { context: EventContext> ) => PromiseLike | any ): CloudFunction { - return this.onOperation(handler, 'document.create', snapshotConstructor); + return this.onOperation(handler, "document.create", snapshotConstructor); } /** Respond only to document deletions. */ @@ -243,18 +217,11 @@ export class DocumentBuilder { context: EventContext> ) => PromiseLike | any ): CloudFunction { - return this.onOperation( - handler, - 'document.delete', - beforeSnapshotConstructor - ); + return this.onOperation(handler, "document.delete", beforeSnapshotConstructor); } private onOperation( - handler: ( - data: T, - context: EventContext> - ) => PromiseLike | any, + handler: (data: T, context: EventContext>) => PromiseLike | any, eventType: string, dataConstructor: (raw: Event) => any ): CloudFunction { diff --git a/src/v1/providers/https.ts b/src/v1/providers/https.ts index a6af2a06d..6d44ebd3f 100644 --- a/src/v1/providers/https.ts +++ b/src/v1/providers/https.ts @@ -20,18 +20,18 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import * as express from 'express'; +import * as express from "express"; -import { convertIfPresent, convertInvoker } from '../../common/encoding'; +import { convertIfPresent, convertInvoker } from "../../common/encoding"; import { CallableContext, FunctionsErrorCode, HttpsError, onCallHandler, Request, -} from '../../common/providers/https'; -import { HttpsFunction, optionsToEndpoint, Runnable } from '../cloud-functions'; -import { DeploymentOptions } from '../function-configuration'; +} from "../../common/providers/https"; +import { HttpsFunction, optionsToEndpoint, Runnable } from "../cloud-functions"; +import { DeploymentOptions } from "../function-configuration"; export { Request, CallableContext, FunctionsErrorCode, HttpsError }; @@ -68,15 +68,15 @@ export function _onRequestWithOptions( // TODO parse the options cloudFunction.__endpoint = { - platform: 'gcfv1', + platform: "gcfv1", ...optionsToEndpoint(options), httpsTrigger: {}, }; convertIfPresent( cloudFunction.__endpoint.httpsTrigger, options, - 'invoker', - 'invoker', + "invoker", + "invoker", convertInvoker ); return cloudFunction; @@ -90,18 +90,17 @@ export function _onCallWithOptions( // onCallHandler sniffs the function length of the passed-in callback // and the user could have only tried to listen to data. Wrap their handler // in another handler to avoid accidentally triggering the v2 API - const fixedLen = (data: any, context: CallableContext) => - handler(data, context); + const fixedLen = (data: any, context: CallableContext) => handler(data, context); const func: any = onCallHandler( { enforceAppCheck: options.enforceAppCheck, - cors: { origin: true, methods: 'POST' }, + cors: { origin: true, methods: "POST" }, }, fixedLen ); func.__endpoint = { - platform: 'gcfv1', + platform: "gcfv1", labels: {}, ...optionsToEndpoint(options), callableTrigger: {}, diff --git a/src/v1/providers/pubsub.ts b/src/v1/providers/pubsub.ts index 18517bee0..2133450ba 100644 --- a/src/v1/providers/pubsub.ts +++ b/src/v1/providers/pubsub.ts @@ -20,20 +20,13 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { - CloudFunction, - EventContext, - makeCloudFunction, -} from '../cloud-functions'; -import { - DeploymentOptions, - ScheduleRetryConfig, -} from '../function-configuration'; +import { CloudFunction, EventContext, makeCloudFunction } from "../cloud-functions"; +import { DeploymentOptions, ScheduleRetryConfig } from "../function-configuration"; /** @hidden */ -export const provider = 'google.pubsub'; +export const provider = "google.pubsub"; /** @hidden */ -export const service = 'pubsub.googleapis.com'; +export const service = "pubsub.googleapis.com"; /** * Registers a Cloud Function triggered when a Google Cloud Pub/Sub message @@ -47,17 +40,14 @@ export function topic(topic: string) { } /** @hidden */ -export function _topicWithOptions( - topic: string, - options: DeploymentOptions -): TopicBuilder { - if (topic.indexOf('/') !== -1) { - throw new Error('Topic name may not have a /'); +export function _topicWithOptions(topic: string, options: DeploymentOptions): TopicBuilder { + if (topic.indexOf("/") !== -1) { + throw new Error("Topic name may not have a /"); } return new TopicBuilder(() => { if (!process.env.GCLOUD_PROJECT) { - throw new Error('process.env.GCLOUD_PROJECT is not set.'); + throw new Error("process.env.GCLOUD_PROJECT is not set."); } return `projects/${process.env.GCLOUD_PROJECT}/topics/${topic}`; }, options); @@ -70,10 +60,7 @@ export function _topicWithOptions( */ export class TopicBuilder { /** @hidden */ - constructor( - private triggerResource: () => string, - private options: DeploymentOptions - ) {} + constructor(private triggerResource: () => string, private options: DeploymentOptions) {} /** * Event handler that fires every time a Cloud Pub/Sub message is @@ -91,7 +78,7 @@ export class TopicBuilder { provider, service, triggerResource: this.triggerResource, - eventType: 'topic.publish', + eventType: "topic.publish", dataConstructor: (raw) => new Message(raw.data), options: this.options, }); @@ -115,7 +102,7 @@ export function _scheduleWithOptions( ): ScheduleBuilder { const triggerResource = () => { if (!process.env.GCLOUD_PROJECT) { - throw new Error('process.env.GCLOUD_PROJECT is not set.'); + throw new Error("process.env.GCLOUD_PROJECT is not set."); } // The CLI will append the correct topic name based on region and function name return `projects/${process.env.GCLOUD_PROJECT}/topics`; @@ -137,10 +124,7 @@ export function _scheduleWithOptions( */ export class ScheduleBuilder { /** @hidden */ - constructor( - private triggerResource: () => string, - private options: DeploymentOptions - ) {} + constructor(private triggerResource: () => string, private options: DeploymentOptions) {} retryConfig(config: ScheduleRetryConfig): ScheduleBuilder { this.options.schedule.retryConfig = config; @@ -166,9 +150,9 @@ export class ScheduleBuilder { provider, service, triggerResource: this.triggerResource, - eventType: 'topic.publish', + eventType: "topic.publish", options: this.options, - labels: { 'deployment-scheduled': 'true' }, + labels: { "deployment-scheduled": "true" }, }); return cloudFunction; } @@ -194,21 +178,15 @@ export class Message { private _json: any; constructor(data: any) { - [this.data, this.attributes, this._json] = [ - data.data, - data.attributes || {}, - data.json, - ]; + [this.data, this.attributes, this._json] = [data.data, data.attributes || {}, data.json]; } /** * The JSON data payload of this message object, if any. */ get json(): any { - if (typeof this._json === 'undefined') { - this._json = JSON.parse( - Buffer.from(this.data, 'base64').toString('utf8') - ); + if (typeof this._json === "undefined") { + this._json = JSON.parse(Buffer.from(this.data, "base64").toString("utf8")); } return this._json; diff --git a/src/v1/providers/remoteConfig.ts b/src/v1/providers/remoteConfig.ts index 9cf54d686..fba8a50cf 100644 --- a/src/v1/providers/remoteConfig.ts +++ b/src/v1/providers/remoteConfig.ts @@ -20,17 +20,13 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { - CloudFunction, - EventContext, - makeCloudFunction, -} from '../cloud-functions'; -import { DeploymentOptions } from '../function-configuration'; +import { CloudFunction, EventContext, makeCloudFunction } from "../cloud-functions"; +import { DeploymentOptions } from "../function-configuration"; /** @hidden */ -export const provider = 'google.firebase.remoteconfig'; +export const provider = "google.firebase.remoteconfig"; /** @hidden */ -export const service = 'firebaseremoteconfig.googleapis.com'; +export const service = "firebaseremoteconfig.googleapis.com"; /** * Registers a function that triggers on Firebase Remote Config template @@ -42,25 +38,19 @@ export const service = 'firebaseremoteconfig.googleapis.com'; * @return A Cloud Function that you can export and deploy. */ export function onUpdate( - handler: ( - version: TemplateVersion, - context: EventContext - ) => PromiseLike | any + handler: (version: TemplateVersion, context: EventContext) => PromiseLike | any ): CloudFunction { return _onUpdateWithOptions(handler, {}); } /** @hidden */ export function _onUpdateWithOptions( - handler: ( - version: TemplateVersion, - context: EventContext - ) => PromiseLike | any, + handler: (version: TemplateVersion, context: EventContext) => PromiseLike | any, options: DeploymentOptions ): CloudFunction { const triggerResource = () => { if (!process.env.GCLOUD_PROJECT) { - throw new Error('process.env.GCLOUD_PROJECT is not set.'); + throw new Error("process.env.GCLOUD_PROJECT is not set."); } return `projects/${process.env.GCLOUD_PROJECT}`; }; @@ -70,10 +60,7 @@ export function _onUpdateWithOptions( /** Builder used to create Cloud Functions for Remote Config. */ export class UpdateBuilder { /** @hidden */ - constructor( - private triggerResource: () => string, - private options: DeploymentOptions - ) {} + constructor(private triggerResource: () => string, private options: DeploymentOptions) {} /** * Handle all updates (including rollbacks) that affect a Remote Config @@ -82,17 +69,14 @@ export class UpdateBuilder { * version metadata as an argument. */ onUpdate( - handler: ( - version: TemplateVersion, - context: EventContext - ) => PromiseLike | any + handler: (version: TemplateVersion, context: EventContext) => PromiseLike | any ): CloudFunction { return makeCloudFunction({ handler, provider, service, triggerResource: this.triggerResource, - eventType: 'update', + eventType: "update", options: this.options, }); } diff --git a/src/v1/providers/storage.ts b/src/v1/providers/storage.ts index 8aaf8a3f8..8044f911d 100644 --- a/src/v1/providers/storage.ts +++ b/src/v1/providers/storage.ts @@ -20,18 +20,14 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { firebaseConfig } from '../../common/config'; -import { - CloudFunction, - EventContext, - makeCloudFunction, -} from '../cloud-functions'; -import { DeploymentOptions } from '../function-configuration'; +import { firebaseConfig } from "../../common/config"; +import { CloudFunction, EventContext, makeCloudFunction } from "../cloud-functions"; +import { DeploymentOptions } from "../function-configuration"; /** @hidden */ -export const provider = 'google.storage'; +export const provider = "google.storage"; /** @hidden */ -export const service = 'storage.googleapis.com'; +export const service = "storage.googleapis.com"; /** * Registers a Cloud Function scoped to a specific storage bucket. @@ -56,16 +52,13 @@ export function object() { } /** @hidden */ -export function _bucketWithOptions( - options: DeploymentOptions, - bucket?: string -): BucketBuilder { +export function _bucketWithOptions(options: DeploymentOptions, bucket?: string): BucketBuilder { const resourceGetter = () => { bucket = bucket || firebaseConfig().storageBucket; if (!bucket) { throw new Error( - 'Missing bucket name. If you are unit testing, please provide a bucket name' + - ' through `functions.storage.bucket(bucketName)`, or set process.env.FIREBASE_CONFIG.' + "Missing bucket name. If you are unit testing, please provide a bucket name" + + " through `functions.storage.bucket(bucketName)`, or set process.env.FIREBASE_CONFIG." ); } if (!/^[a-z\d][a-z\d\\._-]{1,230}[a-z\d]$/.test(bucket)) { @@ -88,10 +81,7 @@ export function _objectWithOptions(options: DeploymentOptions): ObjectBuilder { */ export class BucketBuilder { /** @hidden */ - constructor( - private triggerResource: () => string, - private options: DeploymentOptions - ) {} + constructor(private triggerResource: () => string, private options: DeploymentOptions) {} /** * Event handler which fires every time a Google Cloud Storage change occurs. @@ -111,13 +101,10 @@ export class BucketBuilder { */ export class ObjectBuilder { /** @hidden */ - constructor( - private triggerResource: () => string, - private options: DeploymentOptions - ) {} + constructor(private triggerResource: () => string, private options: DeploymentOptions) {} /** @hidden */ - onChange(handler: any): Error { + onChange(): Error { throw new Error( '"onChange" is now deprecated, please use "onArchive", "onDelete", ' + '"onFinalize", or "onMetadataUpdate".' @@ -136,12 +123,9 @@ export class ObjectBuilder { * @return A Cloud Function which you can export and deploy. */ onArchive( - handler: ( - object: ObjectMetadata, - context: EventContext - ) => PromiseLike | any + handler: (object: ObjectMetadata, context: EventContext) => PromiseLike | any ): CloudFunction { - return this.onOperation(handler, 'object.archive'); + return this.onOperation(handler, "object.archive"); } /** @@ -159,12 +143,9 @@ export class ObjectBuilder { * @return A Cloud Function which you can export and deploy. */ onDelete( - handler: ( - object: ObjectMetadata, - context: EventContext - ) => PromiseLike | any + handler: (object: ObjectMetadata, context: EventContext) => PromiseLike | any ): CloudFunction { - return this.onOperation(handler, 'object.delete'); + return this.onOperation(handler, "object.delete"); } /** @@ -181,12 +162,9 @@ export class ObjectBuilder { * @return A Cloud Function which you can export and deploy. */ onFinalize( - handler: ( - object: ObjectMetadata, - context: EventContext - ) => PromiseLike | any + handler: (object: ObjectMetadata, context: EventContext) => PromiseLike | any ): CloudFunction { - return this.onOperation(handler, 'object.finalize'); + return this.onOperation(handler, "object.finalize"); } /** @@ -199,20 +177,14 @@ export class ObjectBuilder { * @return A Cloud Function which you can export and deploy. */ onMetadataUpdate( - handler: ( - object: ObjectMetadata, - context: EventContext - ) => PromiseLike | any + handler: (object: ObjectMetadata, context: EventContext) => PromiseLike | any ): CloudFunction { - return this.onOperation(handler, 'object.metadataUpdate'); + return this.onOperation(handler, "object.metadataUpdate"); } /** @hidden */ private onOperation( - handler: ( - object: ObjectMetadata, - context: EventContext - ) => PromiseLike | any, + handler: (object: ObjectMetadata, context: EventContext) => PromiseLike | any, eventType: string ): CloudFunction { return makeCloudFunction({ @@ -260,7 +232,7 @@ export interface ObjectMetadata { /** Link to access the object, assuming you have sufficient permissions. */ selfLink?: string; - /**The object's name. */ + /** The object's name. */ name?: string; /** diff --git a/src/v1/providers/tasks.ts b/src/v1/providers/tasks.ts index 284c91262..a3f5a6122 100644 --- a/src/v1/providers/tasks.ts +++ b/src/v1/providers/tasks.ts @@ -20,23 +20,19 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import * as express from 'express'; +import * as express from "express"; -import { - convertIfPresent, - convertInvoker, - copyIfPresent, -} from '../../common/encoding'; -import { Request } from '../../common/providers/https'; +import { convertIfPresent, convertInvoker, copyIfPresent } from "../../common/encoding"; +import { Request } from "../../common/providers/https"; import { onDispatchHandler, RateLimits, RetryConfig, TaskContext, -} from '../../common/providers/tasks'; -import { ManifestEndpoint, ManifestRequiredAPI } from '../../runtime/manifest'; -import { optionsToEndpoint } from '../cloud-functions'; -import { DeploymentOptions } from '../function-configuration'; +} from "../../common/providers/tasks"; +import { ManifestEndpoint, ManifestRequiredAPI } from "../../runtime/manifest"; +import { optionsToEndpoint } from "../cloud-functions"; +import { DeploymentOptions } from "../function-configuration"; export { RetryConfig, RateLimits, TaskContext }; @@ -55,7 +51,7 @@ export interface TaskQueueOptions { * `roles/cloudtasks.enqueuer` and `roles/cloudfunctions.invoker` * will have permissions. */ - invoker?: 'private' | string | string[]; + invoker?: "private" | string | string[]; } /** @@ -102,29 +98,28 @@ export class TaskQueueBuilder { // onEnqueueHandler sniffs the function length of the passed-in callback // and the user could have only tried to listen to data. Wrap their handler // in another handler to avoid accidentally triggering the v2 API - const fixedLen = (data: any, context: TaskContext) => - handler(data, context); + const fixedLen = (data: any, context: TaskContext) => handler(data, context); const func: any = onDispatchHandler(fixedLen); func.__endpoint = { - platform: 'gcfv1', + platform: "gcfv1", ...optionsToEndpoint(this.depOpts), taskQueueTrigger: {}, }; - copyIfPresent(func.__endpoint.taskQueueTrigger, this.tqOpts, 'retryConfig'); - copyIfPresent(func.__endpoint.taskQueueTrigger, this.tqOpts, 'rateLimits'); + copyIfPresent(func.__endpoint.taskQueueTrigger, this.tqOpts, "retryConfig"); + copyIfPresent(func.__endpoint.taskQueueTrigger, this.tqOpts, "rateLimits"); convertIfPresent( func.__endpoint.taskQueueTrigger, this.tqOpts, - 'invoker', - 'invoker', + "invoker", + "invoker", convertInvoker ); func.__requiredAPIs = [ { - api: 'cloudtasks.googleapis.com', - reason: 'Needed for task queue functions', + api: "cloudtasks.googleapis.com", + reason: "Needed for task queue functions", }, ]; diff --git a/src/v1/providers/testLab.ts b/src/v1/providers/testLab.ts index e56429de2..227d701c9 100644 --- a/src/v1/providers/testLab.ts +++ b/src/v1/providers/testLab.ts @@ -20,20 +20,15 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { - CloudFunction, - Event, - EventContext, - makeCloudFunction, -} from '../cloud-functions'; -import { DeploymentOptions } from '../function-configuration'; +import { CloudFunction, Event, EventContext, makeCloudFunction } from "../cloud-functions"; +import { DeploymentOptions } from "../function-configuration"; /** @internal */ -export const PROVIDER = 'google.testing'; +export const PROVIDER = "google.testing"; /** @internal */ -export const SERVICE = 'testing.googleapis.com'; +export const SERVICE = "testing.googleapis.com"; /** @internal */ -export const TEST_MATRIX_COMPLETE_EVENT_TYPE = 'testMatrix.complete'; +export const TEST_MATRIX_COMPLETE_EVENT_TYPE = "testMatrix.complete"; /** Handle events related to Test Lab test matrices. */ export function testMatrix() { @@ -44,26 +39,20 @@ export function testMatrix() { export function _testMatrixWithOpts(opts: DeploymentOptions) { return new TestMatrixBuilder(() => { if (!process.env.GCLOUD_PROJECT) { - throw new Error('process.env.GCLOUD_PROJECT is not set.'); + throw new Error("process.env.GCLOUD_PROJECT is not set."); } - return 'projects/' + process.env.GCLOUD_PROJECT + '/testMatrices/{matrix}'; + return "projects/" + process.env.GCLOUD_PROJECT + "/testMatrices/{matrix}"; }, opts); } /** Builder used to create Cloud Functions for Test Lab test matrices events. */ export class TestMatrixBuilder { /** @internal */ - constructor( - private triggerResource: () => string, - private options: DeploymentOptions - ) {} + constructor(private triggerResource: () => string, private options: DeploymentOptions) {} /** Handle a TestMatrix that reached a final test state. */ onComplete( - handler: ( - testMatrix: TestMatrix, - context: EventContext - ) => PromiseLike | any + handler: (testMatrix: TestMatrix, context: EventContext) => PromiseLike | any ): CloudFunction { const dataConstructor = (raw: Event) => { return new TestMatrix(raw.data); @@ -127,14 +116,11 @@ export class ClientInfo { details: { [key: string]: string }; /** @internal */ - constructor(data?: { - name: string; - clientInfoDetails?: Array<{ key: string; value?: string }>; - }) { - this.name = data?.name || ''; + constructor(data?: { name: string; clientInfoDetails?: Array<{ key: string; value?: string }> }) { + this.name = data?.name || ""; this.details = {}; for (const detail of data?.clientInfoDetails || []) { - this.details[detail.key] = detail.value || ''; + this.details[detail.key] = detail.value || ""; } } } @@ -222,36 +208,36 @@ export class ResultStorage { * unsupported. */ export type InvalidMatrixDetails = - | 'DETAILS_UNAVAILABLE' - | 'MALFORMED_APK' - | 'MALFORMED_TEST_APK' - | 'NO_MANIFEST' - | 'NO_PACKAGE_NAME' - | 'INVALID_PACKAGE_NAME' - | 'TEST_SAME_AS_APP' - | 'NO_INSTRUMENTATION' - | 'NO_SIGNATURE' - | 'INSTRUMENTATION_ORCHESTRATOR_INCOMPATIBLE' - | 'NO_TEST_RUNNER_CLASS' - | 'NO_LAUNCHER_ACTIVITY' - | 'FORBIDDEN_PERMISSIONS' - | 'INVALID_ROBO_DIRECTIVES' - | 'INVALID_RESOURCE_NAME' - | 'INVALID_DIRECTIVE_ACTION' - | 'TEST_LOOP_INTENT_FILTER_NOT_FOUND' - | 'SCENARIO_LABEL_NOT_DECLARED' - | 'SCENARIO_LABEL_MALFORMED' - | 'SCENARIO_NOT_DECLARED' - | 'DEVICE_ADMIN_RECEIVER' - | 'MALFORMED_XC_TEST_ZIP' - | 'BUILT_FOR_IOS_SIMULATOR' - | 'NO_TESTS_IN_XC_TEST_ZIP' - | 'USE_DESTINATION_ARTIFACTS' - | 'TEST_NOT_APP_HOSTED' - | 'PLIST_CANNOT_BE_PARSED' - | 'NO_CODE_APK' - | 'INVALID_INPUT_APK' - | 'INVALID_APK_PREVIEW_SDK'; + | "DETAILS_UNAVAILABLE" + | "MALFORMED_APK" + | "MALFORMED_TEST_APK" + | "NO_MANIFEST" + | "NO_PACKAGE_NAME" + | "INVALID_PACKAGE_NAME" + | "TEST_SAME_AS_APP" + | "NO_INSTRUMENTATION" + | "NO_SIGNATURE" + | "INSTRUMENTATION_ORCHESTRATOR_INCOMPATIBLE" + | "NO_TEST_RUNNER_CLASS" + | "NO_LAUNCHER_ACTIVITY" + | "FORBIDDEN_PERMISSIONS" + | "INVALID_ROBO_DIRECTIVES" + | "INVALID_RESOURCE_NAME" + | "INVALID_DIRECTIVE_ACTION" + | "TEST_LOOP_INTENT_FILTER_NOT_FOUND" + | "SCENARIO_LABEL_NOT_DECLARED" + | "SCENARIO_LABEL_MALFORMED" + | "SCENARIO_NOT_DECLARED" + | "DEVICE_ADMIN_RECEIVER" + | "MALFORMED_XC_TEST_ZIP" + | "BUILT_FOR_IOS_SIMULATOR" + | "NO_TESTS_IN_XC_TEST_ZIP" + | "USE_DESTINATION_ARTIFACTS" + | "TEST_NOT_APP_HOSTED" + | "PLIST_CANNOT_BE_PARSED" + | "NO_CODE_APK" + | "INVALID_INPUT_APK" + | "INVALID_APK_PREVIEW_SDK"; /** * The state (i.e. progress) of a TestMatrix. @@ -268,12 +254,7 @@ export type InvalidMatrixDetails = * valid. E.g. the input file is not of the expected type, or is * malformed/corrupt. */ -export type TestState = - | 'VALIDATING' - | 'PENDING' - | 'FINISHED' - | 'ERROR' - | 'INVALID'; +export type TestState = "VALIDATING" | "PENDING" | "FINISHED" | "ERROR" | "INVALID"; /** * Outcome summary for a finished TestMatrix. @@ -292,4 +273,4 @@ export type TestState = * - 'SKIPPED': All tests were skipped, for instance: * - All device configurations were incompatible. */ -export type OutcomeSummary = 'SUCCESS' | 'FAILURE' | 'INCONCLUSIVE' | 'SKIPPED'; +export type OutcomeSummary = "SUCCESS" | "FAILURE" | "INCONCLUSIVE" | "SKIPPED"; diff --git a/src/v2/core.ts b/src/v2/core.ts index 4768454ce..7b79654e1 100644 --- a/src/v2/core.ts +++ b/src/v2/core.ts @@ -25,12 +25,12 @@ * @packageDocumentation */ -import { Change } from '../common/change'; -import { ManifestEndpoint } from '../runtime/manifest'; +import { Change } from "../common/change"; +import { ManifestEndpoint } from "../runtime/manifest"; export { Change }; -export { ParamsOf } from '../common/params'; +export { ParamsOf } from "../common/params"; /** * A CloudEventBase is the base of a cross-platform format for encoding a serverless event. @@ -40,7 +40,7 @@ export { ParamsOf } from '../common/params'; */ export interface CloudEvent { /** Version of the CloudEvents spec for this event. */ - readonly specversion: '1.0'; + readonly specversion: "1.0"; /** A globally unique ID for this event. */ id: string; diff --git a/src/v2/index.ts b/src/v2/index.ts index 577de40c5..e86285b77 100644 --- a/src/v2/index.ts +++ b/src/v2/index.ts @@ -28,27 +28,17 @@ * @packageDocumentation */ -import * as logger from '../logger'; -import * as alerts from './providers/alerts'; -import * as database from './providers/database'; -import * as eventarc from './providers/eventarc'; -import * as https from './providers/https'; -import * as identity from './providers/identity'; -import * as pubsub from './providers/pubsub'; -import * as storage from './providers/storage'; -import * as tasks from './providers/tasks'; +import * as logger from "../logger"; +import * as alerts from "./providers/alerts"; +import * as database from "./providers/database"; +import * as eventarc from "./providers/eventarc"; +import * as https from "./providers/https"; +import * as identity from "./providers/identity"; +import * as pubsub from "./providers/pubsub"; +import * as storage from "./providers/storage"; +import * as tasks from "./providers/tasks"; -export { - alerts, - database, - storage, - https, - identity, - pubsub, - logger, - tasks, - eventarc, -}; +export { alerts, database, storage, https, identity, pubsub, logger, tasks, eventarc }; export { setGlobalOptions, @@ -58,7 +48,7 @@ export { VpcEgressSetting, IngressSetting, EventHandlerOptions, -} from './options'; +} from "./options"; -export { CloudFunction, CloudEvent, ParamsOf } from './core'; -export { Change } from '../common/change'; +export { CloudFunction, CloudEvent, ParamsOf } from "./core"; +export { Change } from "../common/change"; diff --git a/src/v2/options.ts b/src/v2/options.ts index e55ed8e40..b47c193c3 100644 --- a/src/v2/options.ts +++ b/src/v2/options.ts @@ -25,63 +25,60 @@ * @packageDocumentation */ -import { convertIfPresent, copyIfPresent } from '../common/encoding'; -import * as logger from '../logger'; -import { ManifestEndpoint } from '../runtime/manifest'; -import { declaredParams } from './params'; -import { ParamSpec } from './params/types'; -import { HttpsOptions } from './providers/https'; +import { convertIfPresent, copyIfPresent } from "../common/encoding"; +import * as logger from "../logger"; +import { ManifestEndpoint } from "../runtime/manifest"; +import { declaredParams } from "./params"; +import { ParamSpec } from "./params/types"; +import { HttpsOptions } from "./providers/https"; /** * List of all regions supported by Cloud Functions v2 */ export type SupportedRegion = - | 'asia-northeast1' - | 'europe-north1' - | 'europe-west1' - | 'europe-west4' - | 'us-central1' - | 'us-east1' - | 'us-west1'; + | "asia-northeast1" + | "europe-north1" + | "europe-west1" + | "europe-west4" + | "us-central1" + | "us-east1" + | "us-west1"; /** * List of available memory options supported by Cloud Functions. */ export type MemoryOption = - | '128MiB' - | '256MiB' - | '512MiB' - | '1GiB' - | '2GiB' - | '4GiB' - | '8GiB' - | '16GiB' - | '32GiB'; + | "128MiB" + | "256MiB" + | "512MiB" + | "1GiB" + | "2GiB" + | "4GiB" + | "8GiB" + | "16GiB" + | "32GiB"; const MemoryOptionToMB: Record = { - '128MiB': 128, - '256MiB': 256, - '512MiB': 512, - '1GiB': 1024, - '2GiB': 2048, - '4GiB': 4096, - '8GiB': 8192, - '16GiB': 16384, - '32GiB': 32768, + "128MiB": 128, + "256MiB": 256, + "512MiB": 512, + "1GiB": 1024, + "2GiB": 2048, + "4GiB": 4096, + "8GiB": 8192, + "16GiB": 16384, + "32GiB": 32768, }; /** * List of available options for VpcConnectorEgressSettings. */ -export type VpcEgressSetting = 'PRIVATE_RANGES_ONLY' | 'ALL_TRAFFIC'; +export type VpcEgressSetting = "PRIVATE_RANGES_ONLY" | "ALL_TRAFFIC"; /** * List of available options for IngressSettings. */ -export type IngressSetting = - | 'ALLOW_ALL' - | 'ALLOW_INTERNAL_ONLY' - | 'ALLOW_INTERNAL_AND_GCLB'; +export type IngressSetting = "ALLOW_ALL" | "ALLOW_INTERNAL_ONLY" | "ALLOW_INTERNAL_AND_GCLB"; /** * GlobalOptions are options that can be set across an entire project. @@ -143,7 +140,7 @@ export interface GlobalOptions { * To revert to the CPU amounts used in gcloud or in Cloud Functions generation 1, set this * to the value "gcf_gen1" */ - cpu?: number | 'gcf_gen1'; + cpu?: number | "gcf_gen1"; /** * Connect cloud function to specified VPC connector. @@ -177,7 +174,7 @@ export interface GlobalOptions { /** * Invoker to set access control on https functions. */ - invoker?: 'public' | 'private' | string | string[]; + invoker?: "public" | "private" | string | string[]; /* * Secrets to bind to a function. @@ -201,7 +198,7 @@ let globalOptions: GlobalOptions | undefined; */ export function setGlobalOptions(options: GlobalOptions) { if (globalOptions) { - logger.warn('Calling setGlobalOptions twice leads to undefined behavior'); + logger.warn("Calling setGlobalOptions twice leads to undefined behavior"); } globalOptions = options; } @@ -218,8 +215,7 @@ export function getGlobalOptions(): GlobalOptions { /** * Additional fields that can be set on any event-handling Cloud Function. */ -export interface EventHandlerOptions - extends Omit { +export interface EventHandlerOptions extends Omit { /** Whether failed executions should be delivered again. */ retry?: boolean; } @@ -235,35 +231,31 @@ export function optionsToEndpoint( copyIfPresent( endpoint, opts, - 'concurrency', - 'minInstances', - 'maxInstances', - 'ingressSettings', - 'labels', - 'timeoutSeconds', - 'cpu' + "concurrency", + "minInstances", + "maxInstances", + "ingressSettings", + "labels", + "timeoutSeconds", + "cpu" ); - convertIfPresent(endpoint, opts, 'serviceAccountEmail', 'serviceAccount'); + convertIfPresent(endpoint, opts, "serviceAccountEmail", "serviceAccount"); if (opts.vpcConnector) { - const vpc: ManifestEndpoint['vpc'] = { connector: opts.vpcConnector }; - convertIfPresent(vpc, opts, 'egressSettings', 'vpcConnectorEgressSettings'); + const vpc: ManifestEndpoint["vpc"] = { connector: opts.vpcConnector }; + convertIfPresent(vpc, opts, "egressSettings", "vpcConnectorEgressSettings"); endpoint.vpc = vpc; } - convertIfPresent(endpoint, opts, 'availableMemoryMb', 'memory', (mem) => { + convertIfPresent(endpoint, opts, "availableMemoryMb", "memory", (mem) => { return MemoryOptionToMB[mem]; }); - convertIfPresent(endpoint, opts, 'region', 'region', (region) => { - if (typeof region === 'string') { + convertIfPresent(endpoint, opts, "region", "region", (region) => { + if (typeof region === "string") { return [region]; } return region; }); - convertIfPresent( - endpoint, - opts, - 'secretEnvironmentVariables', - 'secrets', - (secrets) => secrets.map((secret) => ({ key: secret })) + convertIfPresent(endpoint, opts, "secretEnvironmentVariables", "secrets", (secrets) => + secrets.map((secret) => ({ key: secret })) ); return endpoint; diff --git a/src/v2/params/index.ts b/src/v2/params/index.ts index 3f8a080b6..64599558d 100644 --- a/src/v2/params/index.ts +++ b/src/v2/params/index.ts @@ -34,7 +34,7 @@ import { Param, ParamOptions, StringParam, -} from './types'; +} from "./types"; export { ParamOptions }; @@ -61,10 +61,7 @@ function registerParam(param: Param) { * @param options Configuration options for the param. * @returns A Param with a `string` return type for `.value`. */ -export function defineString( - name: string, - options: ParamOptions = {} -): StringParam { +export function defineString(name: string, options: ParamOptions = {}): StringParam { const param = new StringParam(name, options); registerParam(param); return param; @@ -77,10 +74,7 @@ export function defineString( * @param options Configuration options for the param. * @returns A Param with a `boolean` return type for `.value`. */ -export function defineBoolean( - name: string, - options: ParamOptions = {} -): BooleanParam { +export function defineBoolean(name: string, options: ParamOptions = {}): BooleanParam { const param = new BooleanParam(name, options); registerParam(param); return param; @@ -93,10 +87,7 @@ export function defineBoolean( * @param options Configuration options for the param. * @returns A Param with a `number` return type for `.value`. */ -export function defineInt( - name: string, - options: ParamOptions = {} -): IntParam { +export function defineInt(name: string, options: ParamOptions = {}): IntParam { const param = new IntParam(name, options); registerParam(param); return param; @@ -109,10 +100,7 @@ export function defineInt( * @param options Configuration options for the param. * @returns A Param with a `number` return type for `.value`. */ -export function defineFloat( - name: string, - options: ParamOptions = {} -): FloatParam { +export function defineFloat(name: string, options: ParamOptions = {}): FloatParam { const param = new FloatParam(name, options); registerParam(param); return param; @@ -125,10 +113,7 @@ export function defineFloat( * @param options Configuration options for the param. * @returns A Param with a `string[]` return type for `.value`. */ -export function defineList( - name: string, - options: ParamOptions = {} -): ListParam { +export function defineList(name: string, options: ParamOptions = {}): ListParam { const param = new ListParam(name, options); registerParam(param); return param; @@ -142,10 +127,7 @@ export function defineList( * @param options Configuration options for the param. * @returns A Param with a specifiable return type for `.value`. */ -export function defineJSON( - name: string, - options: ParamOptions = {} -): JSONParam { +export function defineJSON(name: string, options: ParamOptions = {}): JSONParam { const param = new JSONParam(name, options); registerParam(param); return param; diff --git a/src/v2/params/types.ts b/src/v2/params/types.ts index d2e053dbc..99367cf48 100644 --- a/src/v2/params/types.ts +++ b/src/v2/params/types.ts @@ -21,7 +21,7 @@ // SOFTWARE. /** @hidden */ -type ParamValueType = 'string' | 'list' | 'boolean' | 'int' | 'float' | 'json'; +type ParamValueType = "string" | "list" | "boolean" | "int" | "float" | "json"; export interface ParamSpec { name: string; @@ -31,10 +31,10 @@ export interface ParamSpec { type: ParamValueType; } -export type ParamOptions = Omit, 'name' | 'type'>; +export type ParamOptions = Omit, "name" | "type">; export class Param { - static type: ParamValueType = 'string'; + static type: ParamValueType = "string"; constructor(readonly name: string, readonly options: ParamOptions = {}) {} @@ -43,7 +43,7 @@ export class Param { } get value(): any { - return this.rawValue || this.options.default || ''; + return this.rawValue || this.options.default || ""; } toString() { @@ -60,10 +60,8 @@ export class Param { ...this.options, type: (this.constructor as typeof Param).type, }; - if (this.options.default && typeof this.options.default !== 'string') { - out.default = ( - this.options.default as { toString?: () => string } | undefined - )?.toString?.(); + if (this.options.default && typeof this.options.default !== "string") { + out.default = (this.options.default as { toString?: () => string } | undefined)?.toString?.(); } return out as ParamSpec; @@ -75,13 +73,10 @@ export class StringParam extends Param { } export class IntParam extends Param { - static type: ParamValueType = 'int'; + static type: ParamValueType = "int"; get value(): number { - const intVal = parseInt( - this.rawValue || this.options.default?.toString() || '0', - 10 - ); + const intVal = parseInt(this.rawValue || this.options.default?.toString() || "0", 10); if (Number.isNaN(intVal)) { throw new Error( `unable to load param "${this.name}", value ${JSON.stringify( @@ -94,12 +89,10 @@ export class IntParam extends Param { } export class FloatParam extends Param { - static type: ParamValueType = 'float'; + static type: ParamValueType = "float"; get value(): number { - const floatVal = parseFloat( - this.rawValue || this.options.default?.toString() || '0' - ); + const floatVal = parseFloat(this.rawValue || this.options.default?.toString() || "0"); if (Number.isNaN(floatVal)) { throw new Error( `unable to load param "${this.name}", value ${JSON.stringify( @@ -112,32 +105,26 @@ export class FloatParam extends Param { } export class BooleanParam extends Param { - static type: ParamValueType = 'boolean'; + static type: ParamValueType = "boolean"; get value(): boolean { - const lowerVal = ( - this.rawValue || - this.options.default?.toString() || - 'false' - ).toLowerCase(); - if ( - !['true', 'y', 'yes', '1', 'false', 'n', 'no', '0'].includes(lowerVal) - ) { + const lowerVal = (this.rawValue || this.options.default?.toString() || "false").toLowerCase(); + if (!["true", "y", "yes", "1", "false", "n", "no", "0"].includes(lowerVal)) { throw new Error( `unable to load param "${this.name}", value ${JSON.stringify( this.rawValue )} could not be parsed as boolean` ); } - return ['true', 'y', 'yes', '1'].includes(lowerVal); + return ["true", "y", "yes", "1"].includes(lowerVal); } } export class ListParam extends Param { - static type: ParamValueType = 'list'; + static type: ParamValueType = "list"; get value(): string[] { - return typeof this.rawValue === 'string' + return typeof this.rawValue === "string" ? this.rawValue.split(/, ?/) : this.options.default || []; } @@ -145,11 +132,11 @@ export class ListParam extends Param { toSpec(): ParamSpec { const out: ParamSpec = { name: this.name, - type: 'list', + type: "list", ...this.options, }; if (this.options.default && this.options.default.length > 0) { - out.default = this.options.default.join(','); + out.default = this.options.default.join(","); } return out as ParamSpec; @@ -157,18 +144,18 @@ export class ListParam extends Param { } export class JSONParam extends Param { - static type: ParamValueType = 'json'; + static type: ParamValueType = "json"; get value(): T { if (this.rawValue) { try { - return JSON.parse(this.rawValue!) as T; + return JSON.parse(this.rawValue) as T; } catch (e) { throw new Error( `unable to load param "${this.name}", value ${this.rawValue} could not be parsed as JSON: ${e.message}` ); } - } else if (this.options?.hasOwnProperty('default')) { + } else if (this.options?.hasOwnProperty("default")) { return this.options.default; } return {} as T; diff --git a/src/v2/providers/alerts/alerts.ts b/src/v2/providers/alerts/alerts.ts index 556b2b77b..81da19adc 100644 --- a/src/v2/providers/alerts/alerts.ts +++ b/src/v2/providers/alerts/alerts.ts @@ -20,9 +20,9 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { ManifestEndpoint } from '../../../runtime/manifest'; -import { CloudEvent, CloudFunction } from '../../core'; -import * as options from '../../options'; +import { ManifestEndpoint } from "../../../runtime/manifest"; +import { CloudEvent, CloudFunction } from "../../core"; +import * as options from "../../options"; /** * The CloudEvent data emitted by Firebase Alerts. @@ -55,20 +55,20 @@ export interface AlertEvent extends CloudEvent> { } /** @internal */ -export const eventType = 'google.firebase.firebasealerts.alerts.v1.published'; +export const eventType = "google.firebase.firebasealerts.alerts.v1.published"; /** The underlying alert type of the Firebase Alerts provider. */ export type AlertType = - | 'crashlytics.newFatalIssue' - | 'crashlytics.newNonfatalIssue' - | 'crashlytics.regression' - | 'crashlytics.stabilityDigest' - | 'crashlytics.velocity' - | 'crashlytics.newAnrIssue' - | 'billing.planUpdate' - | 'billing.automatedPlanUpdate' - | 'appDistribution.newTesterIosDevice' - | 'appDistribution.inAppFeedback' + | "crashlytics.newFatalIssue" + | "crashlytics.newNonfatalIssue" + | "crashlytics.regression" + | "crashlytics.stabilityDigest" + | "crashlytics.velocity" + | "crashlytics.newAnrIssue" + | "billing.planUpdate" + | "billing.automatedPlanUpdate" + | "appDistribution.newTesterIosDevice" + | "appDistribution.inAppFeedback" | string; /** @@ -135,7 +135,7 @@ export interface FirebaseAlertOptions extends options.EventHandlerOptions { * To revert to the CPU amounts used in gcloud or in Cloud Functions generation 1, set this * to the value "gcf_gen1" */ - cpu?: number | 'gcf_gen1'; + cpu?: number | "gcf_gen1"; /** * Connect cloud function to specified VPC connector. @@ -182,7 +182,7 @@ export interface FirebaseAlertOptions extends options.EventHandlerOptions { * @param handler a function that can handle the Firebase Alert inside a CloudEvent. * @returns A function that you can export and deploy. */ -export function onAlertPublished( +export function onAlertPublished( alertType: AlertType, handler: (event: AlertEvent) => any | Promise ): CloudFunction>; @@ -193,12 +193,12 @@ export function onAlertPublished( * @param options - the alert type and other options for this cloud function. * @param handler a function that can handle the Firebase Alert inside a CloudEvent. */ -export function onAlertPublished( +export function onAlertPublished( options: FirebaseAlertOptions, handler: (event: AlertEvent) => any | Promise ): CloudFunction>; -export function onAlertPublished( +export function onAlertPublished( alertTypeOrOpts: AlertType | FirebaseAlertOptions, handler: (event: AlertEvent) => any | Promise ): CloudFunction> { @@ -226,7 +226,7 @@ export function getEndpointAnnotation( const baseOpts = options.optionsToEndpoint(options.getGlobalOptions()); const specificOpts = options.optionsToEndpoint(opts); const endpoint: ManifestEndpoint = { - platform: 'gcfv2', + platform: "gcfv2", ...baseOpts, ...specificOpts, labels: { @@ -257,7 +257,7 @@ export function getOptsAndAlertTypeAndApp( let opts: options.EventHandlerOptions; let alertType: AlertType; let appId: string | undefined; - if (typeof alertTypeOrOpts === 'string') { + if (typeof alertTypeOrOpts === "string") { alertType = alertTypeOrOpts; opts = {}; } else { diff --git a/src/v2/providers/alerts/appDistribution.ts b/src/v2/providers/alerts/appDistribution.ts index 6e519a23e..b7ff0e1d3 100644 --- a/src/v2/providers/alerts/appDistribution.ts +++ b/src/v2/providers/alerts/appDistribution.ts @@ -25,16 +25,16 @@ * @packageDocumentation */ -import { CloudEvent, CloudFunction } from '../../core'; -import * as options from '../../options'; -import { FirebaseAlertData, getEndpointAnnotation } from './alerts'; +import { CloudEvent, CloudFunction } from "../../core"; +import * as options from "../../options"; +import { FirebaseAlertData, getEndpointAnnotation } from "./alerts"; /** * The internal payload object for adding a new tester device to app distribution. * Payload is wrapped inside a `FirebaseAlertData` object. */ export interface NewTesterDevicePayload { - ['@type']: 'type.googleapis.com/google.events.firebase.firebasealerts.v1.AppDistroNewTesterIosDevicePayload'; + ["@type"]: "type.googleapis.com/google.events.firebase.firebasealerts.v1.AppDistroNewTesterIosDevicePayload"; /** Name of the tester */ testerName: string; /** Email of the tester */ @@ -50,7 +50,7 @@ export interface NewTesterDevicePayload { * Payload is wrapped inside a `FirebaseAlertData` object. */ export interface InAppFeedbackPayload { - ['@type']: 'type.googleapis.com/google.events.firebase.firebasealerts.v1.AppDistroInAppFeedbackPayload'; + ["@type"]: "type.googleapis.com/google.events.firebase.firebasealerts.v1.AppDistroInAppFeedbackPayload"; /** Resource name. Format: `projects/{project_number}/apps/{app_id}/releases/{release_id}/feedbackReports/{feedback_id}` */ feedbackReport: string; /** Deep link back to the Firebase console. */ @@ -81,8 +81,7 @@ export interface InAppFeedbackPayload { * A custom CloudEvent for Firebase Alerts (with custom extension attributes). * @typeParam T - the data type for app distribution alerts that is wrapped in a `FirebaseAlertData` object. */ -export interface AppDistributionEvent - extends CloudEvent> { +export interface AppDistributionEvent extends CloudEvent> { /** The type of the alerts that got triggered. */ alertType: string; /** The Firebase App ID that’s associated with the alert. */ @@ -90,9 +89,9 @@ export interface AppDistributionEvent } /** @internal */ -export const newTesterIosDeviceAlert = 'appDistribution.newTesterIosDevice'; +export const newTesterIosDeviceAlert = "appDistribution.newTesterIosDevice"; /** @internal */ -export const inAppFeedbackAlert = 'appDistribution.inAppFeedback'; +export const inAppFeedbackAlert = "appDistribution.inAppFeedback"; /** * Configuration for app distribution functions. @@ -155,7 +154,7 @@ export interface AppDistributionOptions extends options.EventHandlerOptions { * To revert to the CPU amounts used in gcloud or in Cloud Functions generation 1, set this * to the value "gcf_gen1" */ - cpu?: number | 'gcf_gen1'; + cpu?: number | "gcf_gen1"; /** * Connect cloud function to specified VPC connector. @@ -201,9 +200,7 @@ export interface AppDistributionOptions extends options.EventHandlerOptions { * @returns A function that you can export and deploy. */ export function onNewTesterIosDevicePublished( - handler: ( - event: AppDistributionEvent - ) => any | Promise + handler: (event: AppDistributionEvent) => any | Promise ): CloudFunction>; /** @@ -214,9 +211,7 @@ export function onNewTesterIosDevicePublished( */ export function onNewTesterIosDevicePublished( appId: string, - handler: ( - event: AppDistributionEvent - ) => any | Promise + handler: (event: AppDistributionEvent) => any | Promise ): CloudFunction>; /** @@ -227,9 +222,7 @@ export function onNewTesterIosDevicePublished( */ export function onNewTesterIosDevicePublished( opts: AppDistributionOptions, - handler: ( - event: AppDistributionEvent - ) => any | Promise + handler: (event: AppDistributionEvent) => any | Promise ): CloudFunction>; /** @@ -242,14 +235,10 @@ export function onNewTesterIosDevicePublished( appIdOrOptsOrHandler: | string | AppDistributionOptions - | (( - event: AppDistributionEvent - ) => any | Promise), - handler?: ( - event: AppDistributionEvent - ) => any | Promise + | ((event: AppDistributionEvent) => any | Promise), + handler?: (event: AppDistributionEvent) => any | Promise ): CloudFunction> { - if (typeof appIdOrOptsOrHandler === 'function') { + if (typeof appIdOrOptsOrHandler === "function") { handler = appIdOrOptsOrHandler as ( event: AppDistributionEvent ) => any | Promise; @@ -274,9 +263,7 @@ export function onNewTesterIosDevicePublished( * @returns A function that you can export and deploy. */ export function onInAppFeedbackPublished( - handler: ( - event: AppDistributionEvent - ) => any | Promise + handler: (event: AppDistributionEvent) => any | Promise ): CloudFunction>; /** @@ -287,9 +274,7 @@ export function onInAppFeedbackPublished( */ export function onInAppFeedbackPublished( appId: string, - handler: ( - event: AppDistributionEvent - ) => any | Promise + handler: (event: AppDistributionEvent) => any | Promise ): CloudFunction>; /** @@ -300,9 +285,7 @@ export function onInAppFeedbackPublished( */ export function onInAppFeedbackPublished( opts: AppDistributionOptions, - handler: ( - event: AppDistributionEvent - ) => any | Promise + handler: (event: AppDistributionEvent) => any | Promise ): CloudFunction>; /** @@ -315,14 +298,10 @@ export function onInAppFeedbackPublished( appIdOrOptsOrHandler: | string | AppDistributionOptions - | (( - event: AppDistributionEvent - ) => any | Promise), - handler?: ( - event: AppDistributionEvent - ) => any | Promise + | ((event: AppDistributionEvent) => any | Promise), + handler?: (event: AppDistributionEvent) => any | Promise ): CloudFunction> { - if (typeof appIdOrOptsOrHandler === 'function') { + if (typeof appIdOrOptsOrHandler === "function") { handler = appIdOrOptsOrHandler as ( event: AppDistributionEvent ) => any | Promise; @@ -353,7 +332,7 @@ export function getOptsAndApp( ): [options.EventHandlerOptions, string | undefined] { let opts: options.EventHandlerOptions; let appId: string | undefined; - if (typeof appIdOrOpts === 'string') { + if (typeof appIdOrOpts === "string") { opts = {}; appId = appIdOrOpts; } else { diff --git a/src/v2/providers/alerts/billing.ts b/src/v2/providers/alerts/billing.ts index 4d42af79b..f229d9417 100644 --- a/src/v2/providers/alerts/billing.ts +++ b/src/v2/providers/alerts/billing.ts @@ -25,16 +25,16 @@ * @packageDocumentation */ -import { FirebaseAlertData, getEndpointAnnotation } from '.'; -import { CloudEvent, CloudFunction } from '../../core'; -import * as options from '../../options'; +import { FirebaseAlertData, getEndpointAnnotation } from "."; +import { CloudEvent, CloudFunction } from "../../core"; +import * as options from "../../options"; /** * The internal payload object for billing plan updates. * Payload is wrapped inside a `FirebaseAlertData` object. */ export interface PlanUpdatePayload { - ['@type']: 'type.googleapis.com/google.events.firebase.firebasealerts.v1.BillingPlanUpdatePayload'; + ["@type"]: "type.googleapis.com/google.events.firebase.firebasealerts.v1.BillingPlanUpdatePayload"; /** A Firebase billing plan. */ billingPlan: string; /** The email address of the person that triggered billing plan change */ @@ -48,7 +48,7 @@ export interface PlanUpdatePayload { * Payload is wrapped inside a `FirebaseAlertData` object. */ export interface PlanAutomatedUpdatePayload { - ['@type']: 'type.googleapis.com/google.events.firebase.firebasealerts.v1.BillingPlanAutomatedUpdatePayload'; + ["@type"]: "type.googleapis.com/google.events.firebase.firebasealerts.v1.BillingPlanAutomatedUpdatePayload"; /** A Firebase billing plan. */ billingPlan: string; /** The type of the notification, e.g. upgrade, downgrade */ @@ -65,9 +65,9 @@ export interface BillingEvent extends CloudEvent> { } /** @internal */ -export const planUpdateAlert = 'billing.planUpdate'; +export const planUpdateAlert = "billing.planUpdate"; /** @internal */ -export const planAutomatedUpdateAlert = 'billing.planAutomatedUpdate'; +export const planAutomatedUpdateAlert = "billing.planAutomatedUpdate"; /** * Declares a function that can handle a billing plan update event. @@ -101,11 +101,7 @@ export function onPlanUpdatePublished( | ((event: BillingEvent) => any | Promise), handler?: (event: BillingEvent) => any | Promise ): CloudFunction> { - return onOperation( - planUpdateAlert, - optsOrHandler, - handler - ); + return onOperation(planUpdateAlert, optsOrHandler, handler); } /** @@ -114,9 +110,7 @@ export function onPlanUpdatePublished( * @returns A function that you can export and deploy. */ export function onPlanAutomatedUpdatePublished( - handler: ( - event: BillingEvent - ) => any | Promise + handler: (event: BillingEvent) => any | Promise ): CloudFunction>; /** @@ -127,9 +121,7 @@ export function onPlanAutomatedUpdatePublished( */ export function onPlanAutomatedUpdatePublished( opts: options.EventHandlerOptions, - handler: ( - event: BillingEvent - ) => any | Promise + handler: (event: BillingEvent) => any | Promise ): CloudFunction>; /** @@ -142,26 +134,18 @@ export function onPlanAutomatedUpdatePublished( optsOrHandler: | options.EventHandlerOptions | ((event: BillingEvent) => any | Promise), - handler?: ( - event: BillingEvent - ) => any | Promise + handler?: (event: BillingEvent) => any | Promise ): CloudFunction> { - return onOperation( - planAutomatedUpdateAlert, - optsOrHandler, - handler - ); + return onOperation(planAutomatedUpdateAlert, optsOrHandler, handler); } /** @internal */ export function onOperation( alertType: string, - optsOrHandler: - | options.EventHandlerOptions - | ((event: BillingEvent) => any | Promise), + optsOrHandler: options.EventHandlerOptions | ((event: BillingEvent) => any | Promise), handler: (event: BillingEvent) => any | Promise ): CloudFunction> { - if (typeof optsOrHandler === 'function') { + if (typeof optsOrHandler === "function") { handler = optsOrHandler as (event: BillingEvent) => any | Promise; optsOrHandler = {}; } diff --git a/src/v2/providers/alerts/crashlytics.ts b/src/v2/providers/alerts/crashlytics.ts index 6f814320f..69bf777e7 100644 --- a/src/v2/providers/alerts/crashlytics.ts +++ b/src/v2/providers/alerts/crashlytics.ts @@ -25,9 +25,9 @@ * @packageDocumentation */ -import { FirebaseAlertData, getEndpointAnnotation } from '.'; -import { CloudEvent, CloudFunction } from '../../core'; -import * as options from '../../options'; +import { FirebaseAlertData, getEndpointAnnotation } from "."; +import { CloudEvent, CloudFunction } from "../../core"; +import * as options from "../../options"; /** Generic Crashlytics issue interface */ export interface Issue { @@ -46,7 +46,7 @@ export interface Issue { * Payload is wrapped inside a `FirebaseAlertData` object. */ export interface NewFatalIssuePayload { - ['@type']: 'type.googleapis.com/google.events.firebase.firebasealerts.v1.CrashlyticsNewFatalIssuePayload'; + ["@type"]: "type.googleapis.com/google.events.firebase.firebasealerts.v1.CrashlyticsNewFatalIssuePayload"; /** Basic information of the Crashlytics issue */ issue: Issue; } @@ -56,7 +56,7 @@ export interface NewFatalIssuePayload { * Payload is wrapped inside a `FirebaseAlertData` object. */ export interface NewNonfatalIssuePayload { - ['@type']: 'type.googleapis.com/google.events.firebase.firebasealerts.v1.CrashlyticsNewNonfatalIssuePayload'; + ["@type"]: "type.googleapis.com/google.events.firebase.firebasealerts.v1.CrashlyticsNewNonfatalIssuePayload"; /** Basic information of the Crashlytics issue */ issue: Issue; } @@ -66,7 +66,7 @@ export interface NewNonfatalIssuePayload { * Payload is wrapped inside a `FirebaseAlertData` object. */ export interface RegressionAlertPayload { - ['@type']: 'type.googleapis.com/google.events.firebase.firebasealerts.v1.CrashlyticsRegressionAlertPayload'; + ["@type"]: "type.googleapis.com/google.events.firebase.firebasealerts.v1.CrashlyticsRegressionAlertPayload"; /** The type of the Crashlytics issue, e.g. new fatal, new nonfatal, ANR */ type: string; /** Basic information of the Crashlytics issue */ @@ -95,7 +95,7 @@ export interface TrendingIssueDetails { * Payload is wrapped inside a `FirebaseAlertData` object. */ export interface StabilityDigestPayload { - ['@type']: 'type.googleapis.com/google.events.firebase.firebasealerts.v1.CrashlyticsStabilityDigestPayload'; + ["@type"]: "type.googleapis.com/google.events.firebase.firebasealerts.v1.CrashlyticsStabilityDigestPayload"; /** * The date that the digest gets created. Issues in the digest should have the * same date as the digest date @@ -110,7 +110,7 @@ export interface StabilityDigestPayload { * Payload is wrapped inside a `FirebaseAlertData` object. */ export interface VelocityAlertPayload { - ['@type']: 'type.googleapis.com/google.events.firebase.firebasealerts.v1.CrashlyticsVelocityAlertPayload'; + ["@type"]: "type.googleapis.com/google.events.firebase.firebasealerts.v1.CrashlyticsVelocityAlertPayload"; /** Basic information of the Crashlytics issue */ issue: Issue; /** The time that the Crashlytics issue gets created */ @@ -137,7 +137,7 @@ export interface VelocityAlertPayload { * Payload is wrapped inside a `FirebaseAlertData` object. */ export interface NewAnrIssuePayload { - ['@type']: 'type.googleapis.com/google.events.firebase.firebasealerts.v1.CrashlyticsNewAnrIssuePayload'; + ["@type"]: "type.googleapis.com/google.events.firebase.firebasealerts.v1.CrashlyticsNewAnrIssuePayload"; /** Basic information of the Crashlytics issue */ issue: Issue; } @@ -154,17 +154,17 @@ export interface CrashlyticsEvent extends CloudEvent> { } /** @internal */ -export const newFatalIssueAlert = 'crashlytics.newFatalIssue'; +export const newFatalIssueAlert = "crashlytics.newFatalIssue"; /** @internal */ -export const newNonfatalIssueAlert = 'crashlytics.newNonfatalIssue'; +export const newNonfatalIssueAlert = "crashlytics.newNonfatalIssue"; /** @internal */ -export const regressionAlert = 'crashlytics.regression'; +export const regressionAlert = "crashlytics.regression"; /** @internal */ -export const stabilityDigestAlert = 'crashlytics.stabilityDigest'; +export const stabilityDigestAlert = "crashlytics.stabilityDigest"; /** @internal */ -export const velocityAlert = 'crashlytics.velocity'; +export const velocityAlert = "crashlytics.velocity"; /** @internal */ -export const newAnrIssueAlert = 'crashlytics.newAnrIssue'; +export const newAnrIssueAlert = "crashlytics.newAnrIssue"; /** * Configuration for Crashlytics functions. @@ -227,7 +227,7 @@ export interface CrashlyticsOptions extends options.EventHandlerOptions { * To revert to the CPU amounts used in gcloud or in Cloud Functions generation 1, set this * to the value "gcf_gen1" */ - cpu?: number | 'gcf_gen1'; + cpu?: number | "gcf_gen1"; /** * Connect cloud function to specified VPC connector. @@ -309,15 +309,9 @@ export function onNewFatalIssuePublished( | string | CrashlyticsOptions | ((event: CrashlyticsEvent) => any | Promise), - handler?: ( - event: CrashlyticsEvent - ) => any | Promise + handler?: (event: CrashlyticsEvent) => any | Promise ): CloudFunction> { - return onOperation( - newFatalIssueAlert, - appIdOrOptsOrHandler, - handler - ); + return onOperation(newFatalIssueAlert, appIdOrOptsOrHandler, handler); } /** @@ -326,9 +320,7 @@ export function onNewFatalIssuePublished( * @returns A function that you can export and deploy. */ export function onNewNonfatalIssuePublished( - handler: ( - event: CrashlyticsEvent - ) => any | Promise + handler: (event: CrashlyticsEvent) => any | Promise ): CloudFunction>; /** @@ -339,9 +331,7 @@ export function onNewNonfatalIssuePublished( */ export function onNewNonfatalIssuePublished( appId: string, - handler: ( - event: CrashlyticsEvent - ) => any | Promise + handler: (event: CrashlyticsEvent) => any | Promise ): CloudFunction>; /** @@ -352,9 +342,7 @@ export function onNewNonfatalIssuePublished( */ export function onNewNonfatalIssuePublished( opts: CrashlyticsOptions, - handler: ( - event: CrashlyticsEvent - ) => any | Promise + handler: (event: CrashlyticsEvent) => any | Promise ): CloudFunction>; /** @@ -367,18 +355,10 @@ export function onNewNonfatalIssuePublished( appIdOrOptsOrHandler: | string | CrashlyticsOptions - | (( - event: CrashlyticsEvent - ) => any | Promise), - handler?: ( - event: CrashlyticsEvent - ) => any | Promise + | ((event: CrashlyticsEvent) => any | Promise), + handler?: (event: CrashlyticsEvent) => any | Promise ): CloudFunction> { - return onOperation( - newNonfatalIssueAlert, - appIdOrOptsOrHandler, - handler - ); + return onOperation(newNonfatalIssueAlert, appIdOrOptsOrHandler, handler); } /** @@ -387,9 +367,7 @@ export function onNewNonfatalIssuePublished( * @returns A function that you can export and deploy. */ export function onRegressionAlertPublished( - handler: ( - event: CrashlyticsEvent - ) => any | Promise + handler: (event: CrashlyticsEvent) => any | Promise ): CloudFunction>; /** @@ -401,9 +379,7 @@ export function onRegressionAlertPublished( */ export function onRegressionAlertPublished( appId: string, - handler: ( - event: CrashlyticsEvent - ) => any | Promise + handler: (event: CrashlyticsEvent) => any | Promise ): CloudFunction>; /** @@ -415,9 +391,7 @@ export function onRegressionAlertPublished( */ export function onRegressionAlertPublished( opts: CrashlyticsOptions, - handler: ( - event: CrashlyticsEvent - ) => any | Promise + handler: (event: CrashlyticsEvent) => any | Promise ): CloudFunction>; /** @@ -431,15 +405,9 @@ export function onRegressionAlertPublished( | string | CrashlyticsOptions | ((event: CrashlyticsEvent) => any | Promise), - handler?: ( - event: CrashlyticsEvent - ) => any | Promise + handler?: (event: CrashlyticsEvent) => any | Promise ): CloudFunction> { - return onOperation( - regressionAlert, - appIdOrOptsOrHandler, - handler - ); + return onOperation(regressionAlert, appIdOrOptsOrHandler, handler); } /** @@ -448,9 +416,7 @@ export function onRegressionAlertPublished( * @returns A function that you can export and deploy. */ export function onStabilityDigestPublished( - handler: ( - event: CrashlyticsEvent - ) => any | Promise + handler: (event: CrashlyticsEvent) => any | Promise ): CloudFunction>; /** @@ -462,9 +428,7 @@ export function onStabilityDigestPublished( */ export function onStabilityDigestPublished( appId: string, - handler: ( - event: CrashlyticsEvent - ) => any | Promise + handler: (event: CrashlyticsEvent) => any | Promise ): CloudFunction>; /** @@ -476,9 +440,7 @@ export function onStabilityDigestPublished( */ export function onStabilityDigestPublished( opts: CrashlyticsOptions, - handler: ( - event: CrashlyticsEvent - ) => any | Promise + handler: (event: CrashlyticsEvent) => any | Promise ): CloudFunction>; /** @@ -492,15 +454,9 @@ export function onStabilityDigestPublished( | string | CrashlyticsOptions | ((event: CrashlyticsEvent) => any | Promise), - handler?: ( - event: CrashlyticsEvent - ) => any | Promise + handler?: (event: CrashlyticsEvent) => any | Promise ): CloudFunction> { - return onOperation( - stabilityDigestAlert, - appIdOrOptsOrHandler, - handler - ); + return onOperation(stabilityDigestAlert, appIdOrOptsOrHandler, handler); } /** @@ -545,15 +501,9 @@ export function onVelocityAlertPublished( | string | CrashlyticsOptions | ((event: CrashlyticsEvent) => any | Promise), - handler?: ( - event: CrashlyticsEvent - ) => any | Promise + handler?: (event: CrashlyticsEvent) => any | Promise ): CloudFunction> { - return onOperation( - velocityAlert, - appIdOrOptsOrHandler, - handler - ); + return onOperation(velocityAlert, appIdOrOptsOrHandler, handler); } /** @@ -602,11 +552,7 @@ export function onNewAnrIssuePublished( | ((event: CrashlyticsEvent) => any | Promise), handler?: (event: CrashlyticsEvent) => any | Promise ): CloudFunction> { - return onOperation( - newAnrIssueAlert, - appIdOrOptsOrHandler, - handler - ); + return onOperation(newAnrIssueAlert, appIdOrOptsOrHandler, handler); } /** @internal */ @@ -618,16 +564,12 @@ export function onOperation( | ((event: CrashlyticsEvent) => any | Promise), handler: (event: CrashlyticsEvent) => any | Promise ): CloudFunction> { - if (typeof appIdOrOptsOrHandler === 'function') { - handler = appIdOrOptsOrHandler as ( - event: CrashlyticsEvent - ) => any | Promise; + if (typeof appIdOrOptsOrHandler === "function") { + handler = appIdOrOptsOrHandler as (event: CrashlyticsEvent) => any | Promise; appIdOrOptsOrHandler = {}; } - const [opts, appId] = getOptsAndApp( - appIdOrOptsOrHandler as string | CrashlyticsOptions - ); + const [opts, appId] = getOptsAndApp(appIdOrOptsOrHandler); const func = (raw: CloudEvent) => { return handler(raw as CrashlyticsEvent); @@ -648,7 +590,7 @@ export function getOptsAndApp( ): [options.EventHandlerOptions, string | undefined] { let opts: options.EventHandlerOptions; let appId: string | undefined; - if (typeof appIdOrOpts === 'string') { + if (typeof appIdOrOpts === "string") { opts = {}; appId = appIdOrOpts; } else { diff --git a/src/v2/providers/alerts/index.ts b/src/v2/providers/alerts/index.ts index d16ef00fe..e43ce21e4 100644 --- a/src/v2/providers/alerts/index.ts +++ b/src/v2/providers/alerts/index.ts @@ -27,9 +27,9 @@ * @packageDocumentation */ -import * as appDistribution from './appDistribution'; -import * as billing from './billing'; -import * as crashlytics from './crashlytics'; +import * as appDistribution from "./appDistribution"; +import * as billing from "./billing"; +import * as crashlytics from "./crashlytics"; export { appDistribution, billing, crashlytics }; -export * from './alerts'; +export * from "./alerts"; diff --git a/src/v2/providers/database.ts b/src/v2/providers/database.ts index e587f7384..f0896d47f 100644 --- a/src/v2/providers/database.ts +++ b/src/v2/providers/database.ts @@ -20,34 +20,34 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { getApp } from '../../common/app'; -import { Change } from '../../common/change'; -import { ParamsOf } from '../../common/params'; -import { DataSnapshot } from '../../common/providers/database'; -import { normalizePath } from '../../common/utilities/path'; -import { PathPattern } from '../../common/utilities/path-pattern'; -import { applyChange } from '../../common/utilities/utils'; -import { ManifestEndpoint } from '../../runtime/manifest'; -import { CloudEvent, CloudFunction } from '../core'; -import * as options from '../options'; +import { getApp } from "../../common/app"; +import { Change } from "../../common/change"; +import { ParamsOf } from "../../common/params"; +import { DataSnapshot } from "../../common/providers/database"; +import { normalizePath } from "../../common/utilities/path"; +import { PathPattern } from "../../common/utilities/path-pattern"; +import { applyChange } from "../../common/utilities/utils"; +import { ManifestEndpoint } from "../../runtime/manifest"; +import { CloudEvent, CloudFunction } from "../core"; +import * as options from "../options"; export { DataSnapshot }; /** @internal */ -export const writtenEventType = 'google.firebase.database.ref.v1.written'; +export const writtenEventType = "google.firebase.database.ref.v1.written"; /** @internal */ -export const createdEventType = 'google.firebase.database.ref.v1.created'; +export const createdEventType = "google.firebase.database.ref.v1.created"; /** @internal */ -export const updatedEventType = 'google.firebase.database.ref.v1.updated'; +export const updatedEventType = "google.firebase.database.ref.v1.updated"; /** @internal */ -export const deletedEventType = 'google.firebase.database.ref.v1.deleted'; +export const deletedEventType = "google.firebase.database.ref.v1.deleted"; /** @hidden */ export interface RawRTDBCloudEventData { - ['@type']: 'type.googleapis.com/google.events.firebase.database.v1.ReferenceEventData'; + ["@type"]: "type.googleapis.com/google.events.firebase.database.v1.ReferenceEventData"; data: any; delta: any; } @@ -61,8 +61,7 @@ export interface RawRTDBCloudEvent extends CloudEvent { } /** A CloudEvent that contains a DataSnapshot or a Change */ -export interface DatabaseEvent> - extends CloudEvent { +export interface DatabaseEvent> extends CloudEvent { /** The domain of the database instance */ firebaseDatabaseHost: string; /** The instance ID portion of the fully qualified resource name */ @@ -79,8 +78,7 @@ export interface DatabaseEvent> } /** ReferenceOptions extend EventHandlerOptions with provided ref and optional instance */ -export interface ReferenceOptions - extends options.EventHandlerOptions { +export interface ReferenceOptions extends options.EventHandlerOptions { /** * Specify the handler to trigger on a database reference(s). * This value can either be a single reference or a pattern. @@ -150,7 +148,7 @@ export interface ReferenceOptions * To revert to the CPU amounts used in gcloud or in Cloud Functions generation 1, set this * to the value "gcf_gen1" */ - cpu?: number | 'gcf_gen1'; + cpu?: number | "gcf_gen1"; /** * Connect cloud function to specified VPC connector. @@ -198,9 +196,7 @@ export interface ReferenceOptions */ export function onValueWritten( ref: Ref, - handler: ( - event: DatabaseEvent, ParamsOf> - ) => any | Promise + handler: (event: DatabaseEvent, ParamsOf>) => any | Promise ): CloudFunction, ParamsOf>>; /** @@ -211,9 +207,7 @@ export function onValueWritten( */ export function onValueWritten( opts: ReferenceOptions, - handler: ( - event: DatabaseEvent, ParamsOf> - ) => any | Promise + handler: (event: DatabaseEvent, ParamsOf>) => any | Promise ): CloudFunction, ParamsOf>>; /** @@ -224,9 +218,7 @@ export function onValueWritten( */ export function onValueWritten( referenceOrOpts: Ref | ReferenceOptions, - handler: ( - event: DatabaseEvent, ParamsOf> - ) => any | Promise + handler: (event: DatabaseEvent, ParamsOf>) => any | Promise ): CloudFunction, ParamsOf>> { return onChangedOperation(writtenEventType, referenceOrOpts, handler); } @@ -239,9 +231,7 @@ export function onValueWritten( */ export function onValueCreated( ref: Ref, - handler: ( - event: DatabaseEvent> - ) => any | Promise + handler: (event: DatabaseEvent>) => any | Promise ): CloudFunction>>; /** @@ -252,9 +242,7 @@ export function onValueCreated( */ export function onValueCreated( opts: ReferenceOptions, - handler: ( - event: DatabaseEvent> - ) => any | Promise + handler: (event: DatabaseEvent>) => any | Promise ): CloudFunction>>; /** @@ -265,9 +253,7 @@ export function onValueCreated( */ export function onValueCreated( referenceOrOpts: Ref | ReferenceOptions, - handler: ( - event: DatabaseEvent> - ) => any | Promise + handler: (event: DatabaseEvent>) => any | Promise ): CloudFunction>> { return onOperation(createdEventType, referenceOrOpts, handler); } @@ -280,9 +266,7 @@ export function onValueCreated( */ export function onValueUpdated( ref: Ref, - handler: ( - event: DatabaseEvent, ParamsOf> - ) => any | Promise + handler: (event: DatabaseEvent, ParamsOf>) => any | Promise ): CloudFunction, ParamsOf>>; /** @@ -293,9 +277,7 @@ export function onValueUpdated( */ export function onValueUpdated( opts: ReferenceOptions, - handler: ( - event: DatabaseEvent, ParamsOf> - ) => any | Promise + handler: (event: DatabaseEvent, ParamsOf>) => any | Promise ): CloudFunction, ParamsOf>>; /** @@ -306,9 +288,7 @@ export function onValueUpdated( */ export function onValueUpdated( referenceOrOpts: Ref | ReferenceOptions, - handler: ( - event: DatabaseEvent, ParamsOf> - ) => any | Promise + handler: (event: DatabaseEvent, ParamsOf>) => any | Promise ): CloudFunction, ParamsOf>> { return onChangedOperation(updatedEventType, referenceOrOpts, handler); } @@ -321,9 +301,7 @@ export function onValueUpdated( */ export function onValueDeleted( ref: Ref, - handler: ( - event: DatabaseEvent> - ) => any | Promise + handler: (event: DatabaseEvent>) => any | Promise ): CloudFunction>>; /** @@ -334,9 +312,7 @@ export function onValueDeleted( */ export function onValueDeleted( opts: ReferenceOptions, - handler: ( - event: DatabaseEvent> - ) => any | Promise + handler: (event: DatabaseEvent>) => any | Promise ): CloudFunction>>; /** @@ -347,9 +323,7 @@ export function onValueDeleted( */ export function onValueDeleted( referenceOrOpts: Ref | ReferenceOptions, - handler: ( - event: DatabaseEvent> - ) => any | Promise + handler: (event: DatabaseEvent>) => any | Promise ): CloudFunction>> { // TODO - need to use event.data.delta return onOperation(deletedEventType, referenceOrOpts, handler); @@ -357,14 +331,16 @@ export function onValueDeleted( /** @internal */ export function getOpts(referenceOrOpts: string | ReferenceOptions) { - let path: string, instance: string, opts: options.EventHandlerOptions; - if (typeof referenceOrOpts === 'string') { + let path: string; + let instance: string; + let opts: options.EventHandlerOptions; + if (typeof referenceOrOpts === "string") { path = normalizePath(referenceOrOpts); - instance = '*'; + instance = "*"; opts = {}; } else { path = normalizePath(referenceOrOpts.ref); - instance = referenceOrOpts.instance || '*'; + instance = referenceOrOpts.instance || "*"; opts = { ...referenceOrOpts }; delete (opts as any).ref; delete (opts as any).instance; @@ -378,11 +354,7 @@ export function getOpts(referenceOrOpts: string | ReferenceOptions) { } /** @internal */ -export function makeParams( - event: RawRTDBCloudEvent, - path: PathPattern, - instance: PathPattern -) { +export function makeParams(event: RawRTDBCloudEvent, path: PathPattern, instance: PathPattern) { return { ...path.extractMatches(event.ref), ...instance.extractMatches(event.instance), @@ -413,12 +385,7 @@ function makeChangedDatabaseEvent( instance: string, params: Params ): DatabaseEvent, Params> { - const before = new DataSnapshot( - event.data.data, - event.ref, - getApp(), - instance - ); + const before = new DataSnapshot(event.data.data, event.ref, getApp(), instance); const after = new DataSnapshot( applyChange(event.data.data, event.data.delta), event.ref, @@ -458,7 +425,7 @@ export function makeEndpoint( : (eventFilters.instance = instance.getValue()); return { - platform: 'gcfv2', + platform: "gcfv2", ...baseOpts, ...specificOpts, labels: { @@ -478,9 +445,7 @@ export function makeEndpoint( export function onChangedOperation( eventType: string, referenceOrOpts: Ref | ReferenceOptions, - handler: ( - event: DatabaseEvent, ParamsOf> - ) => any | Promise + handler: (event: DatabaseEvent, ParamsOf>) => any | Promise ): CloudFunction, ParamsOf>> { const { path, instance, opts } = getOpts(referenceOrOpts); @@ -491,11 +456,7 @@ export function onChangedOperation( const func = (raw: CloudEvent) => { const event = raw as RawRTDBCloudEvent; const instanceUrl = `https://${event.instance}.${event.firebasedatabasehost}`; - const params = makeParams( - event, - pathPattern, - instancePattern - ) as unknown as ParamsOf; + const params = makeParams(event, pathPattern, instancePattern) as unknown as ParamsOf; const databaseEvent = makeChangedDatabaseEvent(event, instanceUrl, params); return handler(databaseEvent); }; @@ -511,9 +472,7 @@ export function onChangedOperation( export function onOperation( eventType: string, referenceOrOpts: Ref | ReferenceOptions, - handler: ( - event: DatabaseEvent> - ) => any | Promise + handler: (event: DatabaseEvent>) => any | Promise ): CloudFunction>> { const { path, instance, opts } = getOpts(referenceOrOpts); @@ -524,13 +483,8 @@ export function onOperation( const func = (raw: CloudEvent) => { const event = raw as RawRTDBCloudEvent; const instanceUrl = `https://${event.instance}.${event.firebasedatabasehost}`; - const params = makeParams( - event, - pathPattern, - instancePattern - ) as unknown as ParamsOf; - const data = - eventType === deletedEventType ? event.data.data : event.data.delta; + const params = makeParams(event, pathPattern, instancePattern) as unknown as ParamsOf; + const data = eventType === deletedEventType ? event.data.data : event.data.delta; const databaseEvent = makeDatabaseEvent(event, data, instanceUrl, params); return handler(databaseEvent); }; diff --git a/src/v2/providers/eventarc.ts b/src/v2/providers/eventarc.ts index fed753864..c1c36dab6 100644 --- a/src/v2/providers/eventarc.ts +++ b/src/v2/providers/eventarc.ts @@ -25,10 +25,10 @@ * @packageDocumentation */ -import { convertIfPresent, copyIfPresent } from '../../common/encoding'; -import { ManifestEndpoint } from '../../runtime/manifest'; -import { CloudEvent, CloudFunction } from '../core'; -import * as options from '../options'; +import { convertIfPresent, copyIfPresent } from "../../common/encoding"; +import { ManifestEndpoint } from "../../runtime/manifest"; +import { CloudEvent, CloudFunction } from "../core"; +import * as options from "../options"; /** Options that can be set on an Eventarc trigger. */ export interface EventarcTriggerOptions extends options.EventHandlerOptions { @@ -112,7 +112,7 @@ export interface EventarcTriggerOptions extends options.EventHandlerOptions { * To revert to the CPU amounts used in gcloud or in Cloud Functions generation 1, set this * to the value "gcf_gen1" */ - cpu?: number | 'gcf_gen1'; + cpu?: number | "gcf_gen1"; /** * Connect cloud function to specified VPC connector. @@ -177,12 +177,12 @@ export function onCustomEventPublished( handler: (event: CloudEvent) => any | Promise ): CloudFunction> { let opts: EventarcTriggerOptions; - if (typeof eventTypeOrOpts === 'string') { + if (typeof eventTypeOrOpts === "string") { opts = { - eventType: eventTypeOrOpts as string, + eventType: eventTypeOrOpts, }; - } else if (typeof eventTypeOrOpts === 'object') { - opts = eventTypeOrOpts as EventarcTriggerOptions; + } else if (typeof eventTypeOrOpts === "object") { + opts = eventTypeOrOpts; } const func = (raw: CloudEvent) => { return handler(raw as CloudEvent); @@ -190,13 +190,13 @@ export function onCustomEventPublished( func.run = handler; - const channel = opts.channel ?? 'locations/us-central1/channels/firebase'; + const channel = opts.channel ?? "locations/us-central1/channels/firebase"; const baseOpts = options.optionsToEndpoint(options.getGlobalOptions()); const specificOpts = options.optionsToEndpoint(opts); const endpoint: ManifestEndpoint = { - platform: 'gcfv2', + platform: "gcfv2", ...baseOpts, ...specificOpts, labels: { @@ -210,8 +210,8 @@ export function onCustomEventPublished( channel, }, }; - convertIfPresent(endpoint.eventTrigger, opts, 'eventFilters', 'filters'); - copyIfPresent(endpoint.eventTrigger, opts, 'retry'); + convertIfPresent(endpoint.eventTrigger, opts, "eventFilters", "filters"); + copyIfPresent(endpoint.eventTrigger, opts, "retry"); func.__endpoint = endpoint; diff --git a/src/v2/providers/https.ts b/src/v2/providers/https.ts index b6fae6348..3384808e2 100644 --- a/src/v2/providers/https.ts +++ b/src/v2/providers/https.ts @@ -25,28 +25,28 @@ * @packageDocumentation */ -import * as cors from 'cors'; -import * as express from 'express'; -import { convertIfPresent, convertInvoker } from '../../common/encoding'; +import * as cors from "cors"; +import * as express from "express"; +import { convertIfPresent, convertInvoker } from "../../common/encoding"; -import { isDebugFeatureEnabled } from '../../common/debug'; +import { isDebugFeatureEnabled } from "../../common/debug"; import { CallableRequest, FunctionsErrorCode, HttpsError, onCallHandler, Request, -} from '../../common/providers/https'; -import { ManifestEndpoint } from '../../runtime/manifest'; -import * as options from '../options'; -import { GlobalOptions, SupportedRegion } from '../options'; +} from "../../common/providers/https"; +import { ManifestEndpoint } from "../../runtime/manifest"; +import * as options from "../options"; +import { GlobalOptions, SupportedRegion } from "../options"; export { Request, CallableRequest, FunctionsErrorCode, HttpsError }; /** * Options that can be set on an onRequest HTTPS function. */ -export interface HttpsOptions extends Omit { +export interface HttpsOptions extends Omit { /** HTTP functions can override global options and can specify multiple regions to deploy to. */ region?: SupportedRegion | string | Array; /** If true, allows CORS on requests to this function. @@ -105,7 +105,7 @@ export interface HttpsOptions extends Omit { * To revert to the CPU amounts used in gcloud or in Cloud Functions generation 1, set this * to the value "gcf_gen1" */ - cpu?: number | 'gcf_gen1'; + cpu?: number | "gcf_gen1"; /** * Connect cloud function to specified VPC connector. @@ -139,7 +139,7 @@ export interface HttpsOptions extends Omit { /** * Invoker to set access control on https functions. */ - invoker?: 'public' | 'private' | string | string[]; + invoker?: "public" | "private" | string | string[]; /* * Secrets to bind to a function. @@ -194,10 +194,7 @@ export interface CallableFunction extends HttpsFunction { */ export function onRequest( opts: HttpsOptions, - handler: ( - request: Request, - response: express.Response - ) => void | Promise + handler: (request: Request, response: express.Response) => void | Promise ): HttpsFunction; /** * Handles HTTPS requests. @@ -205,19 +202,13 @@ export function onRequest( * @returns A function that you can export and deploy. */ export function onRequest( - handler: ( - request: Request, - response: express.Response - ) => void | Promise + handler: (request: Request, response: express.Response) => void | Promise ): HttpsFunction; export function onRequest( optsOrHandler: | HttpsOptions | ((request: Request, response: express.Response) => void | Promise), - handler?: ( - request: Request, - response: express.Response - ) => void | Promise + handler?: (request: Request, response: express.Response) => void | Promise ): HttpsFunction { let opts: HttpsOptions; if (arguments.length === 1) { @@ -230,12 +221,12 @@ export function onRequest( opts = optsOrHandler as HttpsOptions; } - if (isDebugFeatureEnabled('enableCors') || 'cors' in opts) { - const origin = isDebugFeatureEnabled('enableCors') ? true : opts.cors; + if (isDebugFeatureEnabled("enableCors") || "cors" in opts) { + const origin = isDebugFeatureEnabled("enableCors") ? true : opts.cors; const userProvidedHandler = handler; handler = (req: Request, res: express.Response): void | Promise => { return new Promise((resolve) => { - res.on('finish', resolve); + res.on("finish", resolve); cors({ origin })(req, res, () => { resolve(userProvidedHandler(req, res)); }); @@ -248,7 +239,7 @@ export function onRequest( // but optionsToTriggerAnnotations handles both cases. const specificOpts = options.optionsToEndpoint(opts as options.GlobalOptions); const endpoint: Partial = { - platform: 'gcfv2', + platform: "gcfv2", ...baseOpts, ...specificOpts, labels: { @@ -257,13 +248,7 @@ export function onRequest( }, httpsTrigger: {}, }; - convertIfPresent( - endpoint.httpsTrigger, - opts, - 'invoker', - 'invoker', - convertInvoker - ); + convertIfPresent(endpoint.httpsTrigger, opts, "invoker", "invoker", convertInvoker); (handler as HttpsFunction).__endpoint = endpoint; return handler as HttpsFunction; @@ -292,27 +277,22 @@ export function onCall>( handler?: (request: CallableRequest) => Return ): CallableFunction { let opts: CallableOptions; - if (arguments.length == 1) { + if (arguments.length === 1) { opts = {}; handler = optsOrHandler as (request: CallableRequest) => Return; } else { opts = optsOrHandler as CallableOptions; } - const origin = isDebugFeatureEnabled('enableCors') - ? true - : 'cors' in opts - ? opts.cors - : true; + const origin = isDebugFeatureEnabled("enableCors") ? true : "cors" in opts ? opts.cors : true; // onCallHandler sniffs the function length to determine which API to present. // fix the length to prevent api versions from being mismatched. const fixedLen = (req: CallableRequest) => handler(req); const func: any = onCallHandler( { - cors: { origin, methods: 'POST' }, - enforceAppCheck: - opts.enforceAppCheck ?? options.getGlobalOptions().enforceAppCheck, + cors: { origin, methods: "POST" }, + enforceAppCheck: opts.enforceAppCheck ?? options.getGlobalOptions().enforceAppCheck, }, fixedLen ); @@ -322,7 +302,7 @@ export function onCall>( // but optionsToEndpoint handles both cases. const specificOpts = options.optionsToEndpoint(opts); func.__endpoint = { - platform: 'gcfv2', + platform: "gcfv2", ...baseOpts, ...specificOpts, labels: { diff --git a/src/v2/providers/identity.ts b/src/v2/providers/identity.ts index 0521e9c71..63a1f1a92 100644 --- a/src/v2/providers/identity.ts +++ b/src/v2/providers/identity.ts @@ -33,9 +33,9 @@ import { BeforeSignInResponse, HttpsError, wrapHandler, -} from '../../common/providers/identity'; -import { BlockingFunction } from '../../v1/cloud-functions'; -import * as options from '../options'; +} from "../../common/providers/identity"; +import { BlockingFunction } from "../../v1/cloud-functions"; +import * as options from "../options"; export { AuthUserRecord, AuthBlockingEvent, HttpsError }; @@ -114,7 +114,7 @@ export interface BlockingOptions { * To revert to the CPU amounts used in gcloud or in Cloud Functions generation 1, set this * to the value "gcf_gen1" */ - cpu?: number | 'gcf_gen1'; + cpu?: number | "gcf_gen1"; /** * Connect cloud function to specified VPC connector. @@ -158,11 +158,7 @@ export interface BlockingOptions { export function beforeUserCreated( handler: ( event: AuthBlockingEvent - ) => - | BeforeCreateResponse - | Promise - | void - | Promise + ) => BeforeCreateResponse | Promise | void | Promise ): BlockingFunction; /** @@ -174,11 +170,7 @@ export function beforeUserCreated( opts: BlockingOptions, handler: ( event: AuthBlockingEvent - ) => - | BeforeCreateResponse - | Promise - | void - | Promise + ) => BeforeCreateResponse | Promise | void | Promise ): BlockingFunction; /** @@ -191,20 +183,12 @@ export function beforeUserCreated( | BlockingOptions | (( event: AuthBlockingEvent - ) => - | BeforeCreateResponse - | Promise - | void - | Promise), + ) => BeforeCreateResponse | Promise | void | Promise), handler?: ( event: AuthBlockingEvent - ) => - | BeforeCreateResponse - | Promise - | void - | Promise + ) => BeforeCreateResponse | Promise | void | Promise ): BlockingFunction { - return beforeOperation('beforeCreate', optsOrHandler, handler); + return beforeOperation("beforeCreate", optsOrHandler, handler); } /** @@ -214,11 +198,7 @@ export function beforeUserCreated( export function beforeUserSignedIn( handler: ( event: AuthBlockingEvent - ) => - | BeforeSignInResponse - | Promise - | void - | Promise + ) => BeforeSignInResponse | Promise | void | Promise ): BlockingFunction; /** @@ -230,11 +210,7 @@ export function beforeUserSignedIn( opts: BlockingOptions, handler: ( event: AuthBlockingEvent - ) => - | BeforeSignInResponse - | Promise - | void - | Promise + ) => BeforeSignInResponse | Promise | void | Promise ): BlockingFunction; /** @@ -247,20 +223,12 @@ export function beforeUserSignedIn( | BlockingOptions | (( event: AuthBlockingEvent - ) => - | BeforeSignInResponse - | Promise - | void - | Promise), + ) => BeforeSignInResponse | Promise | void | Promise), handler?: ( event: AuthBlockingEvent - ) => - | BeforeSignInResponse - | Promise - | void - | Promise + ) => BeforeSignInResponse | Promise | void | Promise ): BlockingFunction { - return beforeOperation('beforeSignIn', optsOrHandler, handler); + return beforeOperation("beforeSignIn", optsOrHandler, handler); } /** @hidden */ @@ -287,7 +255,7 @@ export function beforeOperation( | Promise | Promise ): BlockingFunction { - if (!handler || typeof optsOrHandler === 'function') { + if (!handler || typeof optsOrHandler === "function") { handler = optsOrHandler as ( event: AuthBlockingEvent ) => @@ -300,9 +268,7 @@ export function beforeOperation( optsOrHandler = {}; } - const { opts, accessToken, idToken, refreshToken } = getOpts( - optsOrHandler as BlockingOptions - ); + const { opts, accessToken, idToken, refreshToken } = getOpts(optsOrHandler); // Create our own function that just calls the provided function so we know for sure that // handler takes one argument. This is something common/providers/identity depends on. @@ -312,12 +278,10 @@ export function beforeOperation( const legacyEventType = `providers/cloud.auth/eventTypes/user.${eventType}`; /** Endpoint */ - const baseOptsEndpoint = options.optionsToEndpoint( - options.getGlobalOptions() - ); + const baseOptsEndpoint = options.optionsToEndpoint(options.getGlobalOptions()); const specificOptsEndpoint = options.optionsToEndpoint(opts); func.__endpoint = { - platform: 'gcfv2', + platform: "gcfv2", ...baseOptsEndpoint, ...specificOptsEndpoint, labels: { @@ -336,8 +300,8 @@ export function beforeOperation( func.__requiredAPIs = [ { - api: 'identitytoolkit.googleapis.com', - reason: 'Needed for auth blocking functions', + api: "identitytoolkit.googleapis.com", + reason: "Needed for auth blocking functions", }, ]; diff --git a/src/v2/providers/pubsub.ts b/src/v2/providers/pubsub.ts index 7b7993bc5..8c2ea4f73 100644 --- a/src/v2/providers/pubsub.ts +++ b/src/v2/providers/pubsub.ts @@ -25,10 +25,10 @@ * @packageDocumentation */ -import { copyIfPresent } from '../../common/encoding'; -import { ManifestEndpoint } from '../../runtime/manifest'; -import { CloudEvent, CloudFunction } from '../core'; -import * as options from '../options'; +import { copyIfPresent } from "../../common/encoding"; +import { ManifestEndpoint } from "../../runtime/manifest"; +import { CloudEvent, CloudFunction } from "../core"; +import * as options from "../options"; /** * Google Cloud Pub/Sub is a globally distributed message bus that automatically scales as you need it. @@ -94,7 +94,7 @@ export class Message { this.messageId = data.messageId; this.data = data.data; this.attributes = data.attributes || {}; - this.orderingKey = data.orderingKey || ''; + this.orderingKey = data.orderingKey || ""; this.publishTime = data.publishTime || new Date().toISOString(); this._json = data.json; } @@ -103,15 +103,11 @@ export class Message { * The JSON data payload of this message object, if any. */ get json(): T { - if (typeof this._json === 'undefined') { + if (typeof this._json === "undefined") { try { - this._json = JSON.parse( - Buffer.from(this.data, 'base64').toString('utf8') - ); + this._json = JSON.parse(Buffer.from(this.data, "base64").toString("utf8")); } catch (err) { - throw new Error( - `Unable to parse Pub/Sub message data as JSON: ${err.message}` - ); + throw new Error(`Unable to parse Pub/Sub message data as JSON: ${err.message}`); } } @@ -209,7 +205,7 @@ export interface PubSubOptions extends options.EventHandlerOptions { * To revert to the CPU amounts used in gcloud or in Cloud Functions generation 1, set this * to the value "gcf_gen1" */ - cpu?: number | 'gcf_gen1'; + cpu?: number | "gcf_gen1"; /** * Connect cloud function to specified VPC connector. @@ -283,7 +279,7 @@ export function onMessagePublished( ): CloudFunction>> { let topic: string; let opts: options.EventHandlerOptions; - if (typeof topicOrOptions === 'string') { + if (typeof topicOrOptions === "string") { topic = topicOrOptions; opts = {}; } else { @@ -307,7 +303,7 @@ export function onMessagePublished( const specificOpts = options.optionsToEndpoint(opts); const endpoint: ManifestEndpoint = { - platform: 'gcfv2', + platform: "gcfv2", ...baseOpts, ...specificOpts, labels: { @@ -315,12 +311,12 @@ export function onMessagePublished( ...specificOpts?.labels, }, eventTrigger: { - eventType: 'google.cloud.pubsub.topic.v1.messagePublished', + eventType: "google.cloud.pubsub.topic.v1.messagePublished", eventFilters: { topic }, retry: false, }, }; - copyIfPresent(endpoint.eventTrigger, opts, 'retry', 'retry'); + copyIfPresent(endpoint.eventTrigger, opts, "retry", "retry"); func.__endpoint = endpoint; return func; diff --git a/src/v2/providers/storage.ts b/src/v2/providers/storage.ts index 0087119e0..7cf3d9946 100644 --- a/src/v2/providers/storage.ts +++ b/src/v2/providers/storage.ts @@ -25,11 +25,11 @@ * @packageDocumentation */ -import { firebaseConfig } from '../../common/config'; -import { copyIfPresent } from '../../common/encoding'; -import { ManifestEndpoint } from '../../runtime/manifest'; -import { CloudEvent, CloudFunction } from '../core'; -import * as options from '../options'; +import { firebaseConfig } from "../../common/config"; +import { copyIfPresent } from "../../common/encoding"; +import { ManifestEndpoint } from "../../runtime/manifest"; +import { CloudEvent, CloudFunction } from "../core"; +import * as options from "../options"; /** * An object within Google Cloud Storage. @@ -186,14 +186,13 @@ export interface StorageEvent extends CloudEvent { } /** @internal */ -export const archivedEvent = 'google.cloud.storage.object.v1.archived'; +export const archivedEvent = "google.cloud.storage.object.v1.archived"; /** @internal */ -export const finalizedEvent = 'google.cloud.storage.object.v1.finalized'; +export const finalizedEvent = "google.cloud.storage.object.v1.finalized"; /** @internal */ -export const deletedEvent = 'google.cloud.storage.object.v1.deleted'; +export const deletedEvent = "google.cloud.storage.object.v1.deleted"; /** @internal */ -export const metadataUpdatedEvent = - 'google.cloud.storage.object.v1.metadataUpdated'; +export const metadataUpdatedEvent = "google.cloud.storage.object.v1.metadataUpdated"; /** StorageOptions extend EventHandlerOptions with a bucket name */ export interface StorageOptions extends options.EventHandlerOptions { @@ -254,7 +253,7 @@ export interface StorageOptions extends options.EventHandlerOptions { * To revert to the CPU amounts used in gcloud or in Cloud Functions generation 1, set this * to the value "gcf_gen1" */ - cpu?: number | 'gcf_gen1'; + cpu?: number | "gcf_gen1"; /** * Connect cloud function to specified VPC connector. @@ -344,10 +343,7 @@ export function onObjectArchived( * @param handler - Event handler which is run every time a Google Cloud Storage archival occurs. */ export function onObjectArchived( - bucketOrOptsOrHandler: - | string - | StorageOptions - | ((event: StorageEvent) => any | Promise), + bucketOrOptsOrHandler: string | StorageOptions | ((event: StorageEvent) => any | Promise), handler?: (event: StorageEvent) => any | Promise ): CloudFunction { return onOperation(archivedEvent, bucketOrOptsOrHandler, handler); @@ -411,10 +407,7 @@ export function onObjectFinalized( * @param handler - Event handler which is run every time a Google Cloud Storage object creation occurs. */ export function onObjectFinalized( - bucketOrOptsOrHandler: - | string - | StorageOptions - | ((event: StorageEvent) => any | Promise), + bucketOrOptsOrHandler: string | StorageOptions | ((event: StorageEvent) => any | Promise), handler?: (event: StorageEvent) => any | Promise ): CloudFunction { return onOperation(finalizedEvent, bucketOrOptsOrHandler, handler); @@ -482,10 +475,7 @@ export function onObjectDeleted( * @param handler - Event handler which is run every time a Google Cloud Storage object deletion occurs. */ export function onObjectDeleted( - bucketOrOptsOrHandler: - | string - | StorageOptions - | ((event: StorageEvent) => any | Promise), + bucketOrOptsOrHandler: string | StorageOptions | ((event: StorageEvent) => any | Promise), handler?: (event: StorageEvent) => any | Promise ): CloudFunction { return onOperation(deletedEvent, bucketOrOptsOrHandler, handler); @@ -534,10 +524,7 @@ export function onObjectMetadataUpdated( * @param handler - Event handler which is run every time a Google Cloud Storage object metadata update occurs. */ export function onObjectMetadataUpdated( - bucketOrOptsOrHandler: - | string - | StorageOptions - | ((event: StorageEvent) => any | Promise), + bucketOrOptsOrHandler: string | StorageOptions | ((event: StorageEvent) => any | Promise), handler?: (event: StorageEvent) => any | Promise ): CloudFunction { return onOperation(metadataUpdatedEvent, bucketOrOptsOrHandler, handler); @@ -546,22 +533,15 @@ export function onObjectMetadataUpdated( /** @internal */ export function onOperation( eventType: string, - bucketOrOptsOrHandler: - | string - | StorageOptions - | ((event: StorageEvent) => any | Promise), + bucketOrOptsOrHandler: string | StorageOptions | ((event: StorageEvent) => any | Promise), handler: (event: StorageEvent) => any | Promise ): CloudFunction { - if (typeof bucketOrOptsOrHandler === 'function') { - handler = bucketOrOptsOrHandler as ( - event: StorageEvent - ) => any | Promise; + if (typeof bucketOrOptsOrHandler === "function") { + handler = bucketOrOptsOrHandler as (event: StorageEvent) => any | Promise; bucketOrOptsOrHandler = {}; } - const [opts, bucket] = getOptsAndBucket( - bucketOrOptsOrHandler as string | StorageOptions - ); + const [opts, bucket] = getOptsAndBucket(bucketOrOptsOrHandler); const func = (raw: CloudEvent) => { return handler(raw as StorageEvent); @@ -576,13 +556,13 @@ export function onOperation( // SDK may attempt to read FIREBASE_CONFIG env var to fetch the default bucket name. // To prevent runtime errors when FIREBASE_CONFIG env var is missing, we use getters. - Object.defineProperty(func, '__endpoint', { + Object.defineProperty(func, "__endpoint", { get: () => { const baseOpts = options.optionsToEndpoint(options.getGlobalOptions()); const specificOpts = options.optionsToEndpoint(opts); const endpoint: ManifestEndpoint = { - platform: 'gcfv2', + platform: "gcfv2", ...baseOpts, ...specificOpts, labels: { @@ -595,7 +575,7 @@ export function onOperation( retry: false, }, }; - copyIfPresent(endpoint.eventTrigger, opts, 'retry', 'retry'); + copyIfPresent(endpoint.eventTrigger, opts, "retry", "retry"); return endpoint; }, }); @@ -609,7 +589,7 @@ export function getOptsAndBucket( ): [options.EventHandlerOptions, string] { let bucket: string; let opts: options.EventHandlerOptions; - if (typeof bucketOrOpts === 'string') { + if (typeof bucketOrOpts === "string") { bucket = bucketOrOpts; opts = {}; } else { @@ -620,8 +600,8 @@ export function getOptsAndBucket( if (!bucket) { throw new Error( - 'Missing bucket name. If you are unit testing, please provide a bucket name' + - ' by providing bucket name directly in the event handler or by setting process.env.FIREBASE_CONFIG.' + "Missing bucket name. If you are unit testing, please provide a bucket name" + + " by providing bucket name directly in the event handler or by setting process.env.FIREBASE_CONFIG." ); } if (!/^[a-z\d][a-z\d\\._-]{1,230}[a-z\d]$/.test(bucket)) { diff --git a/src/v2/providers/tasks.ts b/src/v2/providers/tasks.ts index eae3e53dd..ac5853222 100644 --- a/src/v2/providers/tasks.ts +++ b/src/v2/providers/tasks.ts @@ -25,20 +25,16 @@ * @packageDocumentation */ -import { - convertIfPresent, - convertInvoker, - copyIfPresent, -} from '../../common/encoding'; +import { convertIfPresent, convertInvoker, copyIfPresent } from "../../common/encoding"; import { AuthData, onDispatchHandler, RateLimits, Request, RetryConfig, -} from '../../common/providers/tasks'; -import * as options from '../options'; -import { HttpsFunction } from './https'; +} from "../../common/providers/tasks"; +import * as options from "../options"; +import { HttpsFunction } from "./https"; export { AuthData, RateLimits, Request, RetryConfig }; @@ -55,7 +51,7 @@ export interface TaskQueueOptions extends options.EventHandlerOptions { * `roles/cloudtasks.enqueuer` and `roles/cloudfunctions.invoker` * will have permissions. */ - invoker?: 'private' | string | string[]; + invoker?: "private" | string | string[]; /** * Region where functions should be deployed. @@ -111,7 +107,7 @@ export interface TaskQueueOptions extends options.EventHandlerOptions { * To revert to the CPU amounts used in gcloud or in Cloud Functions generation 1, set this * to the value "gcf_gen1" */ - cpu?: number | 'gcf_gen1'; + cpu?: number | "gcf_gen1"; /** * Connect cloud function to specified VPC connector. @@ -188,13 +184,11 @@ export function onTaskDispatched( handler: (request: Request) => void | Promise ): TaskQueueFunction; export function onTaskDispatched( - optsOrHandler: - | TaskQueueOptions - | ((request: Request) => void | Promise), + optsOrHandler: TaskQueueOptions | ((request: Request) => void | Promise), handler?: (request: Request) => void | Promise ): TaskQueueFunction { let opts: TaskQueueOptions; - if (arguments.length == 1) { + if (arguments.length === 1) { opts = {}; handler = optsOrHandler as (request: Request) => void | Promise; } else { @@ -211,7 +205,7 @@ export function onTaskDispatched( // but optionsToManifestEndpoint handles both cases. const specificOpts = options.optionsToEndpoint(opts as options.GlobalOptions); func.__endpoint = { - platform: 'gcfv2', + platform: "gcfv2", ...baseOpts, ...specificOpts, labels: { @@ -220,20 +214,14 @@ export function onTaskDispatched( }, taskQueueTrigger: {}, }; - copyIfPresent(func.__endpoint.taskQueueTrigger, opts, 'retryConfig'); - copyIfPresent(func.__endpoint.taskQueueTrigger, opts, 'rateLimits'); - convertIfPresent( - func.__endpoint.taskQueueTrigger, - opts, - 'invoker', - 'invoker', - convertInvoker - ); + copyIfPresent(func.__endpoint.taskQueueTrigger, opts, "retryConfig"); + copyIfPresent(func.__endpoint.taskQueueTrigger, opts, "rateLimits"); + convertIfPresent(func.__endpoint.taskQueueTrigger, opts, "invoker", "invoker", convertInvoker); func.__requiredAPIs = [ { - api: 'cloudtasks.googleapis.com', - reason: 'Needed for task queue functions', + api: "cloudtasks.googleapis.com", + reason: "Needed for task queue functions", }, ];