Skip to content

Commit b51ec90

Browse files
authored
Specific interface for provider enhancement (2/3) (#1022)
* adding in billing changes * removing comments & adding package refs * jsdoc comments * addressing pr comments * change handler doc string * changing to BillingEventHandler type * remove BillingEventHandler type
1 parent c633bd9 commit b51ec90

File tree

5 files changed

+269
-2
lines changed

5 files changed

+269
-2
lines changed

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@
5656
"./v2/pubsub": "./lib/v2/providers/pubsub.js",
5757
"./v2/storage": "./lib/v2/providers/storage.js",
5858
"./v2/alerts": "./lib/v2/providers/alerts/index.js",
59-
"./v2/alerts/appDistribution": "./lib/v2/providers/alerts/appDistribution.js"
59+
"./v2/alerts/appDistribution": "./lib/v2/providers/alerts/appDistribution.js",
60+
"./v2/alerts/billing": "./lib/v2/providers/alerts/billing.js"
6061
},
6162
"typesVersions": {
6263
"*": {
@@ -122,6 +123,9 @@
122123
],
123124
"v2/alerts/appDistribution": [
124125
"lib/v2/providers/alerts/appDistribution"
126+
],
127+
"v2/alerts/billing": [
128+
"lib/v2/providers/alerts/billing"
125129
]
126130
}
127131
},
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import { expect } from 'chai';
2+
import * as alerts from '../../../../src/v2/providers/alerts';
3+
import * as billing from '../../../../src/v2/providers/alerts/billing';
4+
import { FULL_ENDPOINT, FULL_OPTIONS } from '../helpers';
5+
6+
const ALERT_TYPE = 'new-alert-type';
7+
const myHandler = () => 42;
8+
9+
describe('billing', () => {
10+
describe('onPlanUpdatePublished', () => {
11+
it('should create a function with only handler', () => {
12+
const func = billing.onPlanUpdatePublished(myHandler);
13+
14+
expect(func.__endpoint).to.deep.equal({
15+
platform: 'gcfv2',
16+
labels: {},
17+
eventTrigger: {
18+
eventType: alerts.eventType,
19+
eventFilters: {
20+
alertType: billing.planUpdateAlert,
21+
},
22+
retry: false,
23+
},
24+
});
25+
});
26+
27+
it('should create a function with opts & handler', () => {
28+
const func = billing.onPlanUpdatePublished(
29+
{ ...FULL_OPTIONS },
30+
myHandler
31+
);
32+
33+
expect(func.__endpoint).to.deep.equal({
34+
...FULL_ENDPOINT,
35+
eventTrigger: {
36+
eventType: alerts.eventType,
37+
eventFilters: {
38+
alertType: billing.planUpdateAlert,
39+
},
40+
retry: false,
41+
},
42+
});
43+
});
44+
});
45+
46+
describe('onAutomatedPlanUpdatePublished', () => {
47+
it('should create a function with only handler', () => {
48+
const func = billing.onAutomatedPlanUpdatePublished(myHandler);
49+
50+
expect(func.__endpoint).to.deep.equal({
51+
platform: 'gcfv2',
52+
labels: {},
53+
eventTrigger: {
54+
eventType: alerts.eventType,
55+
eventFilters: {
56+
alertType: billing.automatedPlanUpdateAlert,
57+
},
58+
retry: false,
59+
},
60+
});
61+
});
62+
63+
it('should create a function with opts & handler', () => {
64+
const func = billing.onAutomatedPlanUpdatePublished(
65+
{ ...FULL_OPTIONS },
66+
myHandler
67+
);
68+
69+
expect(func.__endpoint).to.deep.equal({
70+
...FULL_ENDPOINT,
71+
eventTrigger: {
72+
eventType: alerts.eventType,
73+
eventFilters: {
74+
alertType: billing.automatedPlanUpdateAlert,
75+
},
76+
retry: false,
77+
},
78+
});
79+
});
80+
});
81+
82+
describe('onOperation', () => {
83+
it('should create a function with alertType only', () => {
84+
const func = billing.onOperation(ALERT_TYPE, myHandler, undefined);
85+
86+
expect(func.__endpoint).to.deep.equal({
87+
platform: 'gcfv2',
88+
labels: {},
89+
eventTrigger: {
90+
eventType: alerts.eventType,
91+
eventFilters: {
92+
alertType: ALERT_TYPE,
93+
},
94+
retry: false,
95+
},
96+
});
97+
});
98+
99+
it('should create a function with opts', () => {
100+
const func = billing.onOperation(
101+
ALERT_TYPE,
102+
{ ...FULL_OPTIONS },
103+
myHandler
104+
);
105+
106+
expect(func.__endpoint).to.deep.equal({
107+
...FULL_ENDPOINT,
108+
eventTrigger: {
109+
eventType: alerts.eventType,
110+
eventFilters: {
111+
alertType: ALERT_TYPE,
112+
},
113+
retry: false,
114+
},
115+
});
116+
});
117+
118+
it('should create a function with a run method', () => {
119+
const func = billing.onOperation(ALERT_TYPE, (event) => event, undefined);
120+
121+
const res = func.run('input' as any);
122+
123+
expect(res).to.equal('input');
124+
});
125+
});
126+
});

src/v2/providers/alerts/billing.ts

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import { getEndpointAnnotation, FirebaseAlertData } from '.';
2+
import { CloudEvent, CloudFunction } from '../../core';
3+
import * as options from '../../options';
4+
5+
/**
6+
* The internal payload object for billing plan updates.
7+
* Payload is wrapped inside a FirebaseAlertData object.
8+
*/
9+
export interface PlanUpdatePayload {
10+
['@type']: 'com.google.firebase.firebasealerts.PlanUpdatePayload';
11+
billingPlan: string;
12+
principalEmail: string;
13+
}
14+
15+
/**
16+
* The internal payload object for billing plan automated updates.
17+
* Payload is wrapped inside a FirebaseAlertData object.
18+
*/
19+
export interface PlanAutomatedUpdatePayload {
20+
['@type']: 'com.google.firebase.firebasealerts.PlanAutomatedUpdatePayload';
21+
billingPlan: string;
22+
}
23+
24+
interface WithAlertType {
25+
alertType: string;
26+
}
27+
/**
28+
* A custom CloudEvent for billing Firebase Alerts (with custom extension attributes).
29+
*/
30+
export type BillingEvent<T> = CloudEvent<FirebaseAlertData<T>, WithAlertType>;
31+
32+
/** @internal */
33+
export const planUpdateAlert = 'billing.planUpdate';
34+
/** @internal */
35+
export const automatedPlanUpdateAlert = 'billing.automatedPlanUpdate';
36+
37+
/**
38+
* Declares a function that can handle a billing plan update event.
39+
*/
40+
export function onPlanUpdatePublished(
41+
handler: (event: BillingEvent<PlanUpdatePayload>) => any | Promise<any>
42+
): CloudFunction<FirebaseAlertData<PlanUpdatePayload>>;
43+
export function onPlanUpdatePublished(
44+
opts: options.EventHandlerOptions,
45+
handler: (event: BillingEvent<PlanUpdatePayload>) => any | Promise<any>
46+
): CloudFunction<FirebaseAlertData<PlanUpdatePayload>>;
47+
export function onPlanUpdatePublished(
48+
optsOrHandler:
49+
| options.EventHandlerOptions
50+
| ((event: BillingEvent<PlanUpdatePayload>) => any | Promise<any>),
51+
handler?: (event: BillingEvent<PlanUpdatePayload>) => any | Promise<any>
52+
): CloudFunction<FirebaseAlertData<PlanUpdatePayload>> {
53+
return onOperation<PlanUpdatePayload>(
54+
planUpdateAlert,
55+
optsOrHandler,
56+
handler
57+
);
58+
}
59+
60+
/**
61+
* Declares a function that can handle an automated billing plan update event.
62+
*/
63+
export function onAutomatedPlanUpdatePublished(
64+
handler: (
65+
event: BillingEvent<PlanAutomatedUpdatePayload>
66+
) => any | Promise<any>
67+
): CloudFunction<FirebaseAlertData<PlanAutomatedUpdatePayload>>;
68+
export function onAutomatedPlanUpdatePublished(
69+
opts: options.EventHandlerOptions,
70+
handler: (
71+
event: BillingEvent<PlanAutomatedUpdatePayload>
72+
) => any | Promise<any>
73+
): CloudFunction<FirebaseAlertData<PlanAutomatedUpdatePayload>>;
74+
export function onAutomatedPlanUpdatePublished(
75+
optsOrHandler:
76+
| options.EventHandlerOptions
77+
| ((event: BillingEvent<PlanAutomatedUpdatePayload>) => any | Promise<any>),
78+
handler?: (
79+
event: BillingEvent<PlanAutomatedUpdatePayload>
80+
) => any | Promise<any>
81+
): CloudFunction<FirebaseAlertData<PlanAutomatedUpdatePayload>> {
82+
return onOperation<PlanAutomatedUpdatePayload>(
83+
automatedPlanUpdateAlert,
84+
optsOrHandler,
85+
handler
86+
);
87+
}
88+
89+
/** @internal */
90+
export function onOperation<T>(
91+
alertType: string,
92+
optsOrHandler:
93+
| options.EventHandlerOptions
94+
| ((event: BillingEvent<T>) => any | Promise<any>),
95+
handler: (event: BillingEvent<T>) => any | Promise<any>
96+
): CloudFunction<FirebaseAlertData<T>> {
97+
if (typeof optsOrHandler === 'function') {
98+
handler = optsOrHandler as (event: BillingEvent<T>) => any | Promise<any>;
99+
optsOrHandler = {};
100+
}
101+
102+
const func = (raw: CloudEvent<unknown>) => {
103+
return handler(raw as BillingEvent<T>);
104+
};
105+
106+
func.run = handler;
107+
func.__endpoint = getEndpointAnnotation(optsOrHandler, alertType);
108+
109+
return func;
110+
}

src/v2/providers/alerts/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as appDistribution from './appDistribution';
2+
import * as billing from './billing';
23

3-
export { appDistribution };
4+
export { appDistribution, billing };
45
export * from './alerts';

v2/alerts/billing.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2021 Firebase
4+
//
5+
// Permission is hereby granted, free of charge, to any person obtaining a copy
6+
// of this software and associated documentation files (the "Software"), to deal
7+
// in the Software without restriction, including without limitation the rights
8+
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
// copies of the Software, and to permit persons to whom the Software is
10+
// furnished to do so, subject to the following conditions:
11+
//
12+
// The above copyright notice and this permission notice shall be included in all
13+
// copies or substantial portions of the Software.
14+
//
15+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
// SOFTWARE.
22+
23+
// This file is not part of the firebase-functions SDK. It is used to silence the
24+
// imports eslint plugin until it can understand import paths defined by node
25+
// package exports.
26+
// For more information, see github.com/import-js/eslint-plugin-import/issues/1810

0 commit comments

Comments
 (0)