Skip to content
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

Update CloudEvent types #1089

Merged
merged 2 commits into from May 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh nice catch, I think I missed this field and meant to add it a while ago 🤦‍♂️

}

/**
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>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh interesting, I didn't realize that storage also uses custom extension attributes.


/** @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;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the NPE culprit. firebaseConfig() is nullable, so attempting to access storageBucket throw an exception.

opts = { ...bucketOrOpts };
delete (opts as any).bucket;
}
Expand Down