From 801062cac7a8a6c47b0c01070ce8baaaa11f92fe Mon Sep 17 00:00:00 2001 From: Tyler Stark Date: Tue, 6 Sep 2022 15:55:22 -0500 Subject: [PATCH 1/4] Support Params as inputs in eventTrigger The api of the manifest changed in firebase-functions@3.23. Some inputs have been updated to be `T | Expression`. --- package-lock.json | 14 +++++++------- package.json | 2 +- spec/v2.spec.ts | 14 ++++++++++++++ src/cloudevent/mocks/database/helpers.ts | 9 ++++++--- src/cloudevent/mocks/helpers.ts | 10 +++++++++- src/cloudevent/mocks/storage/index.ts | 4 +++- 6 files changed, 40 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index b175af3..e6f11f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@types/mocha": "^5.2.7", "chai": "^4.2.0", "firebase-admin": "^10.1.0", - "firebase-functions": "^3.22.0", + "firebase-functions": "^3.23.0", "firebase-tools": "^8.9.2", "mocha": "^6.2.2", "prettier": "^1.19.1", @@ -5195,9 +5195,9 @@ } }, "node_modules/firebase-functions": { - "version": "3.22.0", - "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.22.0.tgz", - "integrity": "sha512-d1BxBpT95MhvVqXkpLWDvWbyuX7e2l69cFAiqG3U1XQDaMV88bM9S+Zg7H8i9pitEGFr+76ErjKgrY0n+g3ZDA==", + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.23.0.tgz", + "integrity": "sha512-/jujnNChTWIuoXK3IPNGYu1zjXF1fYRy88uYbkrJhs3dhK6EdXZi0rX6JUEOCB7h6IkRQvbio+bvtaoI7h+4Lg==", "dev": true, "dependencies": { "@types/cors": "^2.8.5", @@ -17226,9 +17226,9 @@ } }, "firebase-functions": { - "version": "3.22.0", - "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.22.0.tgz", - "integrity": "sha512-d1BxBpT95MhvVqXkpLWDvWbyuX7e2l69cFAiqG3U1XQDaMV88bM9S+Zg7H8i9pitEGFr+76ErjKgrY0n+g3ZDA==", + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.23.0.tgz", + "integrity": "sha512-/jujnNChTWIuoXK3IPNGYu1zjXF1fYRy88uYbkrJhs3dhK6EdXZi0rX6JUEOCB7h6IkRQvbio+bvtaoI7h+4Lg==", "dev": true, "requires": { "@types/cors": "^2.8.5", diff --git a/package.json b/package.json index ab2a6c1..0ecfa5d 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "@types/mocha": "^5.2.7", "chai": "^4.2.0", "firebase-admin": "^10.1.0", - "firebase-functions": "^3.22.0", + "firebase-functions": "^3.23.0", "firebase-tools": "^8.9.2", "mocha": "^6.2.2", "prettier": "^1.19.1", diff --git a/spec/v2.spec.ts b/spec/v2.spec.ts index 896b139..e752721 100644 --- a/spec/v2.spec.ts +++ b/spec/v2.spec.ts @@ -33,6 +33,7 @@ import { eventarc, https, } from 'firebase-functions/v2'; +import { defineString } from 'firebase-functions/v2/params'; import { makeDataSnapshot } from '../src/providers/database'; describe('v2', () => { @@ -372,6 +373,19 @@ describe('v2', () => { expect(cloudEvent.ref).equal('foo/bar/baz'); }); + it('should resolve default ref given StringParam', () => { + process.env.rtdb_ref = 'foo/StringParam/baz'; + const referenceOptions = { + ref: '', + instance: 'instance-1', + }; + const cloudFn = database.onValueCreated(referenceOptions, handler); + cloudFn.__endpoint.eventTrigger.eventFilterPathPatterns.ref = defineString('rtdb_ref'); + const cloudFnWrap = wrapV2(cloudFn); + const cloudEvent = cloudFnWrap().cloudEvent; + expect(cloudEvent.ref).equal('foo/StringParam/baz'); + }); + it('should resolve using params', () => { const referenceOptions = { ref: 'users/{user}', diff --git a/src/cloudevent/mocks/database/helpers.ts b/src/cloudevent/mocks/database/helpers.ts index b4855c8..ea33597 100644 --- a/src/cloudevent/mocks/database/helpers.ts +++ b/src/cloudevent/mocks/database/helpers.ts @@ -1,10 +1,11 @@ import { CloudFunction, database } from 'firebase-functions/v2'; +import { Expression } from 'firebase-functions/v2/params'; import { DeepPartial } from '../../types'; import { exampleDataSnapshot, exampleDataSnapshotChange, } from '../../../providers/database'; -import { getBaseCloudEvent } from '../helpers'; +import { extractStringFromStringOrStringParam, getBaseCloudEvent } from '../helpers'; import { Change } from 'firebase-functions'; import { makeDataSnapshot } from '../../../providers/database'; @@ -117,18 +118,20 @@ export function getCommonDatabaseFields( > > ) { - const instance = + const instanceOrExpression = (cloudEventPartial?.instance as string) || cloudFunction.__endpoint?.eventTrigger?.eventFilterPathPatterns?.instance || cloudFunction.__endpoint?.eventTrigger?.eventFilters?.instance || 'instance-1'; + const instance = extractStringFromStringOrStringParam(instanceOrExpression); const firebaseDatabaseHost = (cloudEventPartial?.firebaseDatabaseHost as string) || 'firebaseDatabaseHost'; - const rawRef = + const rawRefOrExpression = (cloudEventPartial?.ref as string) || cloudFunction?.__endpoint?.eventTrigger?.eventFilterPathPatterns?.ref || '/foo/bar'; + const rawRef = extractStringFromStringOrStringParam(rawRefOrExpression); const location = (cloudEventPartial?.location as string) || 'us-central1'; const params: Record = cloudEventPartial?.params || {}; const ref = extractRef(rawRef, params); diff --git a/src/cloudevent/mocks/helpers.ts b/src/cloudevent/mocks/helpers.ts index a56e4c8..9a38454 100644 --- a/src/cloudevent/mocks/helpers.ts +++ b/src/cloudevent/mocks/helpers.ts @@ -1,4 +1,5 @@ import { CloudEvent, CloudFunction } from 'firebase-functions/v2'; +import { Expression } from 'firebase-functions/v2/params'; export const APP_ID = '__APP_ID__'; export const PROJECT_ID = '42'; @@ -10,7 +11,7 @@ export function getEventType(cloudFunction: CloudFunction): string { export function getEventFilters( cloudFunction: CloudFunction -): Record { +): Record> { return cloudFunction?.__endpoint?.eventTrigger?.eventFilters || {}; } @@ -27,6 +28,13 @@ export function getBaseCloudEvent>( } as EventType; } +export function extractStringFromStringOrStringParam(stringOrExpression: string | Expression) { + if (typeof stringOrExpression === 'string') { + return stringOrExpression; + } + return stringOrExpression?.value(); +} + function makeEventId(): string { return ( Math.random() diff --git a/src/cloudevent/mocks/storage/index.ts b/src/cloudevent/mocks/storage/index.ts index cf89374..c9448c2 100644 --- a/src/cloudevent/mocks/storage/index.ts +++ b/src/cloudevent/mocks/storage/index.ts @@ -3,6 +3,7 @@ import { CloudFunction, CloudEvent } from 'firebase-functions/v2'; import { StorageEvent } from 'firebase-functions/v2/storage'; import { FILENAME, + extractStringFromStringOrStringParam, getBaseCloudEvent, getEventFilters, getEventType, @@ -14,10 +15,11 @@ export const storageV1: MockCloudEventAbstractFactory = { cloudFunction: CloudFunction, cloudEventPartial?: DeepPartial ): StorageEvent { - const bucket = + const bucketOrExpression = cloudEventPartial?.bucket || getEventFilters(cloudFunction)?.bucket || 'bucket_name'; + const bucket = extractStringFromStringOrStringParam(bucketOrExpression); const source = cloudEventPartial?.source || `//storage.googleapis.com/projects/_/buckets/${bucket}`; From cbe6e254ebad02595dd48005443e42ac410be1c4 Mon Sep 17 00:00:00 2001 From: Tyler Stark Date: Tue, 6 Sep 2022 16:02:35 -0500 Subject: [PATCH 2/4] prettier --- spec/v2.spec.ts | 4 +++- src/cloudevent/mocks/database/helpers.ts | 5 ++++- src/cloudevent/mocks/helpers.ts | 6 ++++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/spec/v2.spec.ts b/spec/v2.spec.ts index e752721..65d2b5f 100644 --- a/spec/v2.spec.ts +++ b/spec/v2.spec.ts @@ -380,7 +380,9 @@ describe('v2', () => { instance: 'instance-1', }; const cloudFn = database.onValueCreated(referenceOptions, handler); - cloudFn.__endpoint.eventTrigger.eventFilterPathPatterns.ref = defineString('rtdb_ref'); + cloudFn.__endpoint.eventTrigger.eventFilterPathPatterns.ref = defineString( + 'rtdb_ref' + ); const cloudFnWrap = wrapV2(cloudFn); const cloudEvent = cloudFnWrap().cloudEvent; expect(cloudEvent.ref).equal('foo/StringParam/baz'); diff --git a/src/cloudevent/mocks/database/helpers.ts b/src/cloudevent/mocks/database/helpers.ts index ea33597..a4b8fbc 100644 --- a/src/cloudevent/mocks/database/helpers.ts +++ b/src/cloudevent/mocks/database/helpers.ts @@ -5,7 +5,10 @@ import { exampleDataSnapshot, exampleDataSnapshotChange, } from '../../../providers/database'; -import { extractStringFromStringOrStringParam, getBaseCloudEvent } from '../helpers'; +import { + extractStringFromStringOrStringParam, + getBaseCloudEvent, +} from '../helpers'; import { Change } from 'firebase-functions'; import { makeDataSnapshot } from '../../../providers/database'; diff --git a/src/cloudevent/mocks/helpers.ts b/src/cloudevent/mocks/helpers.ts index 9a38454..f5b9f23 100644 --- a/src/cloudevent/mocks/helpers.ts +++ b/src/cloudevent/mocks/helpers.ts @@ -11,7 +11,7 @@ export function getEventType(cloudFunction: CloudFunction): string { export function getEventFilters( cloudFunction: CloudFunction -): Record> { +): Record> { return cloudFunction?.__endpoint?.eventTrigger?.eventFilters || {}; } @@ -28,7 +28,9 @@ export function getBaseCloudEvent>( } as EventType; } -export function extractStringFromStringOrStringParam(stringOrExpression: string | Expression) { +export function extractStringFromStringOrStringParam( + stringOrExpression: string | Expression +) { if (typeof stringOrExpression === 'string') { return stringOrExpression; } From 5c501a5eb2d7ee62c22ddd23a002b57fee318cc1 Mon Sep 17 00:00:00 2001 From: Tyler Stark Date: Tue, 6 Sep 2022 21:56:45 -0500 Subject: [PATCH 3/4] Updates per PR feedback --- package.json | 2 +- src/cloudevent/mocks/database/helpers.ts | 9 +++------ src/cloudevent/mocks/helpers.ts | 2 +- src/cloudevent/mocks/storage/index.ts | 4 ++-- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 0ecfa5d..81f1956 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ }, "peerDependencies": { "firebase-admin": ">=6.0.0", - "firebase-functions": ">=3.22.0", + "firebase-functions": ">=3.23.0", "jest": ">=28.0.0" }, "engines": { diff --git a/src/cloudevent/mocks/database/helpers.ts b/src/cloudevent/mocks/database/helpers.ts index a4b8fbc..5fd76ae 100644 --- a/src/cloudevent/mocks/database/helpers.ts +++ b/src/cloudevent/mocks/database/helpers.ts @@ -5,10 +5,7 @@ import { exampleDataSnapshot, exampleDataSnapshotChange, } from '../../../providers/database'; -import { - extractStringFromStringOrStringParam, - getBaseCloudEvent, -} from '../helpers'; +import { resolveStringExpression, getBaseCloudEvent } from '../helpers'; import { Change } from 'firebase-functions'; import { makeDataSnapshot } from '../../../providers/database'; @@ -126,7 +123,7 @@ export function getCommonDatabaseFields( cloudFunction.__endpoint?.eventTrigger?.eventFilterPathPatterns?.instance || cloudFunction.__endpoint?.eventTrigger?.eventFilters?.instance || 'instance-1'; - const instance = extractStringFromStringOrStringParam(instanceOrExpression); + const instance = resolveStringExpression(instanceOrExpression); const firebaseDatabaseHost = (cloudEventPartial?.firebaseDatabaseHost as string) || 'firebaseDatabaseHost'; @@ -134,7 +131,7 @@ export function getCommonDatabaseFields( (cloudEventPartial?.ref as string) || cloudFunction?.__endpoint?.eventTrigger?.eventFilterPathPatterns?.ref || '/foo/bar'; - const rawRef = extractStringFromStringOrStringParam(rawRefOrExpression); + const rawRef = resolveStringExpression(rawRefOrExpression); const location = (cloudEventPartial?.location as string) || 'us-central1'; const params: Record = cloudEventPartial?.params || {}; const ref = extractRef(rawRef, params); diff --git a/src/cloudevent/mocks/helpers.ts b/src/cloudevent/mocks/helpers.ts index f5b9f23..3c8563b 100644 --- a/src/cloudevent/mocks/helpers.ts +++ b/src/cloudevent/mocks/helpers.ts @@ -28,7 +28,7 @@ export function getBaseCloudEvent>( } as EventType; } -export function extractStringFromStringOrStringParam( +export function resolveStringExpression( stringOrExpression: string | Expression ) { if (typeof stringOrExpression === 'string') { diff --git a/src/cloudevent/mocks/storage/index.ts b/src/cloudevent/mocks/storage/index.ts index c9448c2..ce0ec35 100644 --- a/src/cloudevent/mocks/storage/index.ts +++ b/src/cloudevent/mocks/storage/index.ts @@ -3,7 +3,7 @@ import { CloudFunction, CloudEvent } from 'firebase-functions/v2'; import { StorageEvent } from 'firebase-functions/v2/storage'; import { FILENAME, - extractStringFromStringOrStringParam, + resolveStringExpression, getBaseCloudEvent, getEventFilters, getEventType, @@ -19,7 +19,7 @@ export const storageV1: MockCloudEventAbstractFactory = { cloudEventPartial?.bucket || getEventFilters(cloudFunction)?.bucket || 'bucket_name'; - const bucket = extractStringFromStringOrStringParam(bucketOrExpression); + const bucket = resolveStringExpression(bucketOrExpression); const source = cloudEventPartial?.source || `//storage.googleapis.com/projects/_/buckets/${bucket}`; From fff9b598158d9578dfccbc4ece7b48a6fb622119 Mon Sep 17 00:00:00 2001 From: Tyler Stark Date: Wed, 7 Sep 2022 14:36:34 -0500 Subject: [PATCH 4/4] Adding another test for TernaryExpression --- spec/v2.spec.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/spec/v2.spec.ts b/spec/v2.spec.ts index 65d2b5f..f66bd4c 100644 --- a/spec/v2.spec.ts +++ b/spec/v2.spec.ts @@ -388,6 +388,24 @@ describe('v2', () => { expect(cloudEvent.ref).equal('foo/StringParam/baz'); }); + it.skip('should resolve default ref given TernaryExpression', () => { + const ref1 = defineString('rtdb_ref_1'); + process.env.rtdb_ref_1 = 'foo/StringParam/1'; + const ref2 = defineString('rtdb_ref_2'); + process.env.rtdb_ref_2 = 'foo/StringParam/2'; + const referenceOptions = { + ref: '', + instance: 'instance-1', + }; + const cloudFn = database.onValueCreated(referenceOptions, handler); + cloudFn.__endpoint.eventTrigger.eventFilterPathPatterns.ref = ref1 + .equals('aa') + .then('rtdb_ref_1', 'rtdb_ref_2'); + const cloudFnWrap = wrapV2(cloudFn); + const cloudEvent = cloudFnWrap().cloudEvent; + expect(cloudEvent.ref).equal('rtdb_ref_2'); + }); + it('should resolve using params', () => { const referenceOptions = { ref: 'users/{user}',