-
Notifications
You must be signed in to change notification settings - Fork 59
Update Rtdb test sdk to allow json for CloudEvent #159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
bcfeea5
1481939
eb3d89b
77b831b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,9 @@ | ||
import { CloudEvent } from 'firebase-functions/v2'; | ||
import { CloudEvent, pubsub } from 'firebase-functions/v2'; | ||
import { CloudFunction } from 'firebase-functions/v2'; | ||
import { LIST_OF_MOCK_CLOUD_EVENT_PARTIALS } from './mocks/partials'; | ||
import { DeepPartial, MockCloudEventAbstractFactory } from './types'; | ||
import { DeepPartial } from './types'; | ||
import { database } from 'firebase-functions/v2'; | ||
import { Change } from 'firebase-functions'; | ||
import merge from 'ts-deepmerge'; | ||
|
||
/** | ||
|
@@ -17,9 +19,7 @@ export function generateCombinedCloudEvent< | |
cloudFunction, | ||
cloudEventPartial | ||
); | ||
return cloudEventPartial | ||
? (merge(generatedCloudEvent, cloudEventPartial) as EventType) | ||
: generatedCloudEvent; | ||
return mergeCloudEvents(generatedCloudEvent, cloudEventPartial); | ||
} | ||
|
||
export function generateMockCloudEvent<EventType extends CloudEvent<unknown>>( | ||
|
@@ -37,3 +37,59 @@ export function generateMockCloudEvent<EventType extends CloudEvent<unknown>>( | |
// No matches were found | ||
return null; | ||
} | ||
|
||
const IMMUTABLE_DATA_TYPES = [database.DataSnapshot, Change, pubsub.Message]; | ||
|
||
function mergeCloudEvents<EventType extends CloudEvent<unknown>>( | ||
generatedCloudEvent: EventType, | ||
cloudEventPartial: DeepPartial<EventType> | ||
) { | ||
/** | ||
* There are several CloudEvent.data types that can not be overridden with PoJson. | ||
TheIronDev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* In these circumstances, we generate the CloudEvent.data given the user supplies | ||
* in the DeepPartial<CloudEvent>. | ||
* | ||
* Because we have already extracted the user supplied data, we don't want to overwrite | ||
* the CloudEvent.data with an incompatible type. | ||
* | ||
* An example of this is a user supplying JSON for the data of the DatabaseEvents. | ||
* The returned CloudEvent should be returning DataSnapshot that uses the supplied json, | ||
* NOT the supplied JSON. | ||
*/ | ||
if (shouldDeleteUserSuppliedData(generatedCloudEvent, cloudEventPartial)) { | ||
delete cloudEventPartial.data; | ||
} | ||
return cloudEventPartial | ||
? (merge(generatedCloudEvent, cloudEventPartial) as EventType) | ||
: generatedCloudEvent; | ||
} | ||
|
||
function shouldDeleteUserSuppliedData<EventType extends CloudEvent<unknown>>( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is such a cool problem you had to solve. Good find! |
||
generatedCloudEvent: EventType, | ||
cloudEventPartial: DeepPartial<EventType> | ||
) { | ||
// Don't attempt to delete the data if there is no data. | ||
if (cloudEventPartial?.data === undefined) { | ||
return false; | ||
} | ||
/** If the user intentionally provides one of the IMMUTABLE DataTypes, DON'T delete it! */ | ||
TheIronDev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if ( | ||
IMMUTABLE_DATA_TYPES.some((type) => cloudEventPartial?.data instanceof type) | ||
) { | ||
return false; | ||
} | ||
|
||
/** If the generated CloudEvent.data is an IMMUTABLE DataTypes, then use the generated data and | ||
* delete the user supplied CloudEvent.data. | ||
*/ | ||
if ( | ||
IMMUTABLE_DATA_TYPES.some( | ||
(type) => generatedCloudEvent?.data instanceof type | ||
) | ||
) { | ||
return true; | ||
} | ||
|
||
// Otherwise, don't delete the data and allow ts-merge to handle merging the data. | ||
return false; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,10 +6,41 @@ import { | |
} from '../../../providers/database'; | ||
import { getBaseCloudEvent } from '../helpers'; | ||
import { Change } from 'firebase-functions'; | ||
import { makeDataSnapshot } from '../../../providers/database'; | ||
|
||
function getOrCreateDataSnapshot( | ||
data: database.DataSnapshot | object, | ||
TheIronDev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ref: string | ||
) { | ||
if (data instanceof database.DataSnapshot) { | ||
return data; | ||
} | ||
if (data instanceof Object) { | ||
return makeDataSnapshot(data, ref); | ||
} | ||
return exampleDataSnapshot(ref); | ||
} | ||
|
||
function getOrCreateDataSnapshotChange( | ||
data: Change<database.DataSnapshot> | any, | ||
TheIronDev marked this conversation as resolved.
Show resolved
Hide resolved
|
||
ref: string | ||
) { | ||
if (data instanceof Change) { | ||
return data; | ||
} | ||
if (data instanceof Object && data?.before && data?.after) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we want Functionally it's the difference between one LOC in:
I could see arguments in either direction. Either we're helping them write simpler code or we could require them to be explicit to avoid accidental misuse (e.g. typo in "before" or "after"). Thoughts? |
||
const beforeDataSnapshot = getOrCreateDataSnapshot(data.before, ref); | ||
const afterDataSnapshot = getOrCreateDataSnapshot(data.after, ref); | ||
return new Change(beforeDataSnapshot, afterDataSnapshot); | ||
} | ||
return exampleDataSnapshotChange(ref); | ||
} | ||
|
||
export function getDatabaseSnapshotCloudEvent( | ||
cloudFunction: CloudFunction<database.DatabaseEvent<database.DataSnapshot>>, | ||
cloudEventPartial?: DeepPartial<database.DatabaseEvent<database.DataSnapshot>> | ||
cloudEventPartial?: DeepPartial< | ||
database.DatabaseEvent<database.DataSnapshot | object> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: I personally would hoist |
||
> | ||
) { | ||
const { | ||
instance, | ||
|
@@ -19,9 +50,7 @@ export function getDatabaseSnapshotCloudEvent( | |
params, | ||
} = getCommonDatabaseFields(cloudFunction, cloudEventPartial); | ||
|
||
const data = | ||
(cloudEventPartial?.data as database.DataSnapshot) || | ||
exampleDataSnapshot(ref); | ||
const data = getOrCreateDataSnapshot(cloudEventPartial?.data, ref); | ||
|
||
return { | ||
// Spread common fields | ||
|
@@ -43,7 +72,7 @@ export function getDatabaseChangeSnapshotCloudEvent( | |
database.DatabaseEvent<Change<database.DataSnapshot>> | ||
>, | ||
cloudEventPartial?: DeepPartial< | ||
database.DatabaseEvent<Change<database.DataSnapshot>> | ||
database.DatabaseEvent<Change<database.DataSnapshot> | object> | ||
> | ||
): database.DatabaseEvent<Change<database.DataSnapshot>> { | ||
const { | ||
|
@@ -54,9 +83,7 @@ export function getDatabaseChangeSnapshotCloudEvent( | |
params, | ||
} = getCommonDatabaseFields(cloudFunction, cloudEventPartial); | ||
|
||
const data = | ||
(cloudEventPartial?.data as Change<database.DataSnapshot>) || | ||
exampleDataSnapshotChange(ref); | ||
const data = getOrCreateDataSnapshotChange(cloudEventPartial?.data, ref); | ||
|
||
return { | ||
// Spread common fields | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,7 +29,7 @@ import { DeepPartial } from './cloudevent/types'; | |
* It will subsequently invoke the cloud function it wraps with the provided {@link CloudEvent} | ||
*/ | ||
export type WrappedV2Function<T extends CloudEvent<unknown>> = ( | ||
cloudEventPartial?: DeepPartial<T> | ||
cloudEventPartial?: DeepPartial<T | object> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There's a big difference between |
||
) => any | Promise<any>; | ||
|
||
/** | ||
|
Uh oh!
There was an error while loading. Please reload this page.