Skip to content

Commit

Permalink
Update CloudEvent types (#1089)
Browse files Browse the repository at this point in the history
* Updates to exported CloudEvent Types.

This commit makes several updates to the exported CloudEvent types:

* Billing types include a notificationType
  * [Link](https://github.com/googleapis/google-cloudevents/blob/main/proto/google/events/firebase/firebasealerts/v1/cloud_event_payload.proto#L132-L133)
* Crashlytics have more documentation on fields
* Storage has an exported `StorageEvent` which includes the bucket.
* Storage function api references `StorageEvent` to better match to expected output.
* Fixed NPE issue for Storage without Config
* Updated more signatures to optionally expect a bucket.
  • Loading branch information
TheIronDev committed May 2, 2022
1 parent 0bac53d commit 1aa1865
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 25 deletions.
8 changes: 8 additions & 0 deletions src/v2/providers/alerts/alerts.ts
Expand Up @@ -6,13 +6,21 @@ import * as options from '../../options';
* The CloudEvent data emitted by Firebase Alerts.
*/
export interface FirebaseAlertData<T = any> {
/** Time that the event has created. */
createTime: string;
/** Time that the event has ended. Optional, only present for ongoing alerts. */
endTime: string;
/** Payload of the event, which includes the details of the specific alert. */
payload: T;
}

interface WithAlertTypeAndApp {
/** The type of the alerts that got triggered. */
alertType: string;
/**
* The Firebase App ID that’s associated with the alert. This is optional,
* and only present when the alert is targeting at a specific Firebase App.
*/
appId?: string;
}
/**
Expand Down
2 changes: 2 additions & 0 deletions src/v2/providers/alerts/appDistribution.ts
Expand Up @@ -15,7 +15,9 @@ export interface NewTesterDevicePayload {
}

interface WithAlertTypeAndApp {
/** The type of the alerts that got triggered. */
alertType: string;
/** The Firebase App ID that’s associated with the alert. */
appId: string;
}
/**
Expand Down
8 changes: 8 additions & 0 deletions src/v2/providers/alerts/billing.ts
Expand Up @@ -8,8 +8,12 @@ import * as options from '../../options';
*/
export interface PlanUpdatePayload {
['@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 */
principalEmail: string;
/** The type of the notification, e.g. upgrade, downgrade */
notificationType: string;
}

/**
Expand All @@ -18,10 +22,14 @@ export interface PlanUpdatePayload {
*/
export interface PlanAutomatedUpdatePayload {
['@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 */
notificationType: string;
}

interface WithAlertType {
/** The type of the alerts that got triggered. */
alertType: string;
}
/**
Expand Down
34 changes: 34 additions & 0 deletions src/v2/providers/alerts/crashlytics.ts
Expand Up @@ -16,6 +16,7 @@ interface Issue {
*/
export interface NewFatalIssuePayload {
['@type']: 'type.googleapis.com/google.events.firebase.firebasealerts.v1.CrashlyticsNewFatalIssuePayload';
/** Basic information of the Crashlytics issue */
issue: Issue;
}

Expand All @@ -25,6 +26,7 @@ export interface NewFatalIssuePayload {
*/
export interface NewNonfatalIssuePayload {
['@type']: 'type.googleapis.com/google.events.firebase.firebasealerts.v1.CrashlyticsNewNonfatalIssuePayload';
/** Basic information of the Crashlytics issue */
issue: Issue;
}

Expand All @@ -34,16 +36,26 @@ export interface NewNonfatalIssuePayload {
*/
export interface RegressionAlertPayload {
['@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 */
issue: Issue;
/**
* The time that the Crashlytics issues was most recently resolved before it
* began to reoccur.
*/
resolveTime: string;
}

/** Generic crashlytics trending issue interface */
interface TrendingIssueDetails {
/** The type of the Crashlytics issue, e.g. new fatal, new nonfatal, ANR */
type: string;
/** Basic information of the Crashlytics issue */
issue: Issue;
/** The number of crashes that occurred with the issue */
eventCount: number;
/** The number of distinct users that were affected by the issue */
userCount: number;
}

Expand All @@ -53,7 +65,12 @@ interface TrendingIssueDetails {
*/
export interface StabilityDigestPayload {
['@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
*/
digestDate: string;
/** A stability digest containing several trending Crashlytics issues */
trendingIssues: TrendingIssueDetails[];
}

Expand All @@ -63,10 +80,24 @@ export interface StabilityDigestPayload {
*/
export interface VelocityAlertPayload {
['@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 */
createTime: string;
/**
* The number of user sessions for the given app version that had this
* specific crash issue in the time period used to trigger the velocity alert.
*/
crashCount: number;
/**
* The percentage of user sessions for the given app version that had this
* specific crash issue in the time period used to trigger the velocity alert.
*/
crashPercentage: number;
/**
* The first app version where this issue was seen, and not necessarily the
* version that has triggered the alert.
*/
firstVersion: string;
}

Expand All @@ -76,11 +107,14 @@ export interface VelocityAlertPayload {
*/
export interface NewAnrIssuePayload {
['@type']: 'type.googleapis.com/google.events.firebase.firebasealerts.v1.CrashlyticsNewAnrIssuePayload';
/** Basic information of the Crashlytics issue */
issue: Issue;
}

interface WithAlertTypeAndApp {
/** The type of the alerts that got triggered. */
alertType: string;
/** The Firebase App ID that’s associated with the alert. */
appId: string;
}
/**
Expand Down
57 changes: 32 additions & 25 deletions src/v2/providers/storage.ts
Expand Up @@ -174,6 +174,13 @@ export interface CustomerEncryption {
keySha256?: string;
}

interface WithBucket {
/** The name of the bucket containing this object. */
bucket: string;
}

export type StorageEvent = CloudEvent<StorageObjectData, WithBucket>;

/** @internal */
export const archivedEvent = 'google.cloud.storage.object.v1.archived';
/** @internal */
Expand All @@ -191,100 +198,100 @@ export interface StorageOptions extends options.EventHandlerOptions {

/** Handle a storage object archived */
export function onObjectArchived(
handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
handler: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData>;

export function onObjectArchived(
bucket: string,
handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
handler: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData>;

export function onObjectArchived(
opts: StorageOptions,
handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
handler: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData>;

export function onObjectArchived(
buketOrOptsOrHandler:
| string
| StorageOptions
| ((event: CloudEvent<StorageObjectData>) => any | Promise<any>),
handler?: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
| ((event: StorageEvent) => any | Promise<any>),
handler?: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData> {
return onOperation(archivedEvent, buketOrOptsOrHandler, handler);
}

/** Handle a storage object finalized */
export function onObjectFinalized(
handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
handler: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData>;

export function onObjectFinalized(
bucket: string,
handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
handler: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData>;

export function onObjectFinalized(
opts: StorageOptions,
handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
handler: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData>;

export function onObjectFinalized(
buketOrOptsOrHandler:
| string
| StorageOptions
| ((event: CloudEvent<StorageObjectData>) => any | Promise<any>),
handler?: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
| ((event: StorageEvent) => any | Promise<any>),
handler?: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData> {
return onOperation(finalizedEvent, buketOrOptsOrHandler, handler);
}

/** Handle a storage object deleted */
export function onObjectDeleted(
handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
handler: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData>;

export function onObjectDeleted(
bucket: string,
handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
handler: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData>;

export function onObjectDeleted(
opts: StorageOptions,
handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
handler: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData>;

export function onObjectDeleted(
buketOrOptsOrHandler:
| string
| StorageOptions
| ((event: CloudEvent<StorageObjectData>) => any | Promise<any>),
handler?: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
| ((event: StorageEvent) => any | Promise<any>),
handler?: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData> {
return onOperation(deletedEvent, buketOrOptsOrHandler, handler);
}

/** Handle a storage object metadata updated */
export function onObjectMetadataUpdated(
handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
handler: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData>;

export function onObjectMetadataUpdated(
bucket: string,
handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
handler: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData>;

export function onObjectMetadataUpdated(
opts: StorageOptions,
handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
handler: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData>;

export function onObjectMetadataUpdated(
buketOrOptsOrHandler:
| string
| StorageOptions
| ((event: CloudEvent<StorageObjectData>) => any | Promise<any>),
handler?: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
| ((event: StorageEvent) => any | Promise<any>),
handler?: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData> {
return onOperation(metadataUpdatedEvent, buketOrOptsOrHandler, handler);
}
Expand All @@ -295,12 +302,12 @@ export function onOperation(
bucketOrOptsOrHandler:
| string
| StorageOptions
| ((event: CloudEvent<StorageObjectData>) => any | Promise<any>),
handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>
| ((event: StorageEvent) => any | Promise<any>),
handler: (event: StorageEvent) => any | Promise<any>
): CloudFunction<StorageObjectData> {
if (typeof bucketOrOptsOrHandler === 'function') {
handler = bucketOrOptsOrHandler as (
event: CloudEvent<StorageObjectData>
event: StorageEvent
) => any | Promise<any>;
bucketOrOptsOrHandler = {};
}
Expand All @@ -310,7 +317,7 @@ export function onOperation(
);

const func = (raw: CloudEvent<unknown>) => {
return handler(raw as CloudEvent<StorageObjectData>);
return handler(raw as StorageEvent);
};

func.run = handler;
Expand Down Expand Up @@ -382,7 +389,7 @@ export function getOptsAndBucket(
bucket = bucketOrOpts;
opts = {};
} else {
bucket = bucketOrOpts.bucket || firebaseConfig().storageBucket;
bucket = bucketOrOpts.bucket || firebaseConfig()?.storageBucket;
opts = { ...bucketOrOpts };
delete (opts as any).bucket;
}
Expand Down

0 comments on commit 1aa1865

Please sign in to comment.