Skip to content

Commit a54cd0b

Browse files
authored
Add v2 Remote Config Triggers (#1216)
* adding in files from lost branch * cleaning up tsdoc comments * adding alpha tags to interfaces * formatter
1 parent 3b04088 commit a54cd0b

File tree

6 files changed

+282
-9
lines changed

6 files changed

+282
-9
lines changed

CHANGELOG.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
### Breaking Changes
2+
23
- Deprecated `allowInvalidAppCheckToken` option. Instead use
34
`enforceAppCheck`.
45

56
> App Check enforcement on callable functions is disabled by default in v4.
6-
Requests containing invalid App Check tokens won't be denied unless you
7-
explicitly enable App Check enforcement using the new `enforceAppCheck` option.
8-
Furthermore, when enforcement is enabled, callable functions will deny
9-
all requests without App Check tokens.
7+
> Requests containing invalid App Check tokens won't be denied unless you
8+
> explicitly enable App Check enforcement using the new `enforceAppCheck` option.
9+
> Furthermore, when enforcement is enabled, callable functions will deny
10+
> all requests without App Check tokens.
1011
1112
- Dropped support for Node.js versions 8, 10, and 12.
1213
- Dropped support for Admin SDK versions 8 and 9.
@@ -16,9 +17,10 @@
1617
removed.
1718
- Removed `__trigger` object on function handlers.
1819
- Reorganized source code location. This affects only apps that directly import files instead of using the recommend entry points specified in the
19-
- Reworked the `apps` library and removed `lodash` as a runtime dependency.
20+
- Reworked the `apps` library and removed `lodash` as a runtime dependency.
2021

2122
### Enhancements
23+
2224
- Logs created with the `functions.logger` package in v2 functions
2325
are now annotated with each request's trace ID, making it easy to correlate
2426
log entries with the incoming request. Trace IDs are especially useful for
@@ -28,5 +30,3 @@
2830
- `functions.logger.error` now always outputs an error object and is included in Google Cloud Error Reporting.
2931
- The logging severity of Auth/App Check token validation has changed from `info` to `debug` level.
3032
- Event parameters for 2nd generation functions are now strongly typed, permitting stronger TypeScript types for matched parameters.
31-
32-

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@
5555
"./v2/eventarc": "./lib/v2/providers/eventarc.js",
5656
"./v2/identity": "./lib/v2/providers/identity.js",
5757
"./v2/database": "./lib/v2/providers/database.js",
58-
"./v2/scheduler": "./lib/v2/providers/scheduler.js"
58+
"./v2/scheduler": "./lib/v2/providers/scheduler.js",
59+
"./v2/remoteConfig": "./lib/v2/providers/remoteConfig.js"
5960
},
6061
"typesVersions": {
6162
"*": {
@@ -142,6 +143,9 @@
142143
],
143144
"v2/scheduler": [
144145
"lib/v2/providers/scheduler"
146+
],
147+
"v2/remoteConfig": [
148+
"lib/v2/providers/remoteConfig"
145149
]
146150
}
147151
},
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2022 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+
import { expect } from "chai";
24+
import * as remoteConfig from "../../../src/v2/providers/remoteConfig";
25+
import * as options from "../../../src/v2/options";
26+
27+
describe("onConfigUpdated", () => {
28+
afterEach(() => {
29+
options.setGlobalOptions({});
30+
});
31+
32+
it("should create a function with a handler", () => {
33+
const fn = remoteConfig.onConfigUpdated(() => 2);
34+
35+
expect(fn.__endpoint).to.deep.eq({
36+
platform: "gcfv2",
37+
labels: {},
38+
eventTrigger: {
39+
eventType: remoteConfig.eventType,
40+
eventFilters: {},
41+
retry: false,
42+
},
43+
});
44+
expect(fn.run(1 as any)).to.eq(2);
45+
});
46+
47+
it("should create a function with opts and a handler", () => {
48+
options.setGlobalOptions({
49+
memory: "512MiB",
50+
region: "us-west1",
51+
});
52+
53+
const fn = remoteConfig.onConfigUpdated(
54+
{
55+
region: "us-central1",
56+
retry: true,
57+
},
58+
() => 2
59+
);
60+
61+
expect(fn.__endpoint).to.deep.eq({
62+
platform: "gcfv2",
63+
availableMemoryMb: 512,
64+
region: ["us-central1"],
65+
labels: {},
66+
eventTrigger: {
67+
eventType: remoteConfig.eventType,
68+
eventFilters: {},
69+
retry: true,
70+
},
71+
});
72+
expect(fn.run(1 as any)).to.eq(2);
73+
});
74+
});

src/v2/index.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,21 @@ import * as pubsub from "./providers/pubsub";
3838
import * as scheduler from "./providers/scheduler";
3939
import * as storage from "./providers/storage";
4040
import * as tasks from "./providers/tasks";
41+
import * as remoteConfig from "./providers/remoteConfig";
4142

42-
export { alerts, database, storage, https, identity, pubsub, logger, tasks, eventarc, scheduler };
43+
export {
44+
alerts,
45+
database,
46+
storage,
47+
https,
48+
identity,
49+
pubsub,
50+
logger,
51+
tasks,
52+
eventarc,
53+
scheduler,
54+
remoteConfig,
55+
};
4356

4457
export {
4558
setGlobalOptions,

src/v2/providers/remoteConfig.ts

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
// The MIT License (MIT)
2+
//
3+
// Copyright (c) 2022 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+
import { ManifestEndpoint } from "../../runtime/manifest";
24+
import { CloudEvent, CloudFunction } from "../core";
25+
import { EventHandlerOptions, getGlobalOptions, optionsToEndpoint } from "../options";
26+
27+
/** @internal */
28+
export const eventType = "google.firebase.remoteconfig.remoteConfig.v1.updated";
29+
30+
/* All the fields associated with the person/service account that wrote a Remote Config template. */
31+
export interface ConfigUser {
32+
/* Display name. */
33+
name: string;
34+
35+
/* Email address. */
36+
email: string;
37+
38+
/* Image URL. */
39+
imageUrl: string;
40+
}
41+
42+
/* What type of update was associated with the Remote Config template version. */
43+
export type ConfigUpdateOrigin =
44+
/* Catch-all for unrecognized values. */
45+
| "REMOTE_CONFIG_UPDATE_ORIGIN_UNSPECIFIED"
46+
/* The update came from the Firebase UI. */
47+
| "CONSOLE"
48+
/* The update came from the Remote Config REST API. */
49+
| "REST_API"
50+
/* The update came from the Firebase Admin Node SDK. */
51+
| "ADMIN_SDK_NODE";
52+
53+
/* Where the Remote Config update action originated. */
54+
export type ConfigUpdateType =
55+
/* Catch-all for unrecognized enum values */
56+
| "REMOTE_CONFIG_UPDATE_TYPE_UNSPECIFIED"
57+
/* A regular incremental update */
58+
| "INCREMENTAL_UPDATE"
59+
/* A forced update. The ETag was specified as "*" in an UpdateRemoteConfigRequest request or the "Force Update" button was pressed on the console */
60+
| "FORCED_UPDATE"
61+
/* A rollback to a previous Remote Config template */
62+
| "ROLLBACK";
63+
64+
/* The data within Firebase Remote Config update events. */
65+
export interface ConfigUpdateData {
66+
/* The version number of the version's corresponding Remote Config template. */
67+
versionNumber: number;
68+
69+
/* When the Remote Config template was written to the Remote Config server. */
70+
updateTime: string;
71+
72+
/* Aggregation of all metadata fields about the account that performed the update. */
73+
updateUser: ConfigUser;
74+
75+
/* The user-provided description of the corresponding Remote Config template. */
76+
description: string;
77+
78+
/* Where the update action originated. */
79+
updateOrigin: ConfigUpdateOrigin;
80+
81+
/* What type of update was made. */
82+
updateType: ConfigUpdateType;
83+
84+
/* Only present if this version is the result of a rollback, and will be the version number of the Remote Config template that was rolled-back to. */
85+
rollbackSource: number;
86+
}
87+
88+
/**
89+
* Event handler which triggers when data is updated in a Remote Config.
90+
*
91+
* @param handler - Event handler which is run every time a Remote Config update occurs.
92+
* @returns A Cloud Function that you can export and deploy.
93+
* @alpha
94+
*/
95+
export function onConfigUpdated(
96+
handler: (event: CloudEvent<ConfigUpdateData>) => any | Promise<any>
97+
): CloudFunction<CloudEvent<ConfigUpdateData>>;
98+
99+
/**
100+
* Event handler which triggers when data is updated in a Remote Config.
101+
*
102+
* @param opts - Options that can be set on an individual event-handling function.
103+
* @param handler - Event handler which is run every time a Remote Config update occurs.
104+
* @returns A Cloud Function that you can export and deploy.
105+
* @alpha
106+
*/
107+
export function onConfigUpdated(
108+
opts: EventHandlerOptions,
109+
handler: (event: CloudEvent<ConfigUpdateData>) => any | Promise<any>
110+
): CloudFunction<CloudEvent<ConfigUpdateData>>;
111+
112+
/**
113+
* Event handler which triggers when data is updated in a Remote Config.
114+
*
115+
* @param optsOrHandler - Options or an event handler.
116+
* @param handler - Event handler which is run every time a Remote Config update occurs.
117+
* @returns A Cloud Function that you can export and deploy.
118+
* @alpha
119+
*/
120+
export function onConfigUpdated(
121+
optsOrHandler:
122+
| EventHandlerOptions
123+
| ((event: CloudEvent<ConfigUpdateData>) => any | Promise<any>),
124+
handler?: (event: CloudEvent<ConfigUpdateData>) => any | Promise<any>
125+
): CloudFunction<CloudEvent<ConfigUpdateData>> {
126+
if (typeof optsOrHandler === "function") {
127+
handler = optsOrHandler as (event: CloudEvent<ConfigUpdateData>) => any | Promise<any>;
128+
optsOrHandler = {};
129+
}
130+
131+
const baseOpts = optionsToEndpoint(getGlobalOptions());
132+
const specificOpts = optionsToEndpoint(optsOrHandler);
133+
134+
const func: any = (raw: CloudEvent<unknown>) => {
135+
return handler(raw as CloudEvent<ConfigUpdateData>);
136+
};
137+
func.run = handler;
138+
139+
const ep: ManifestEndpoint = {
140+
platform: "gcfv2",
141+
...baseOpts,
142+
...specificOpts,
143+
labels: {
144+
...baseOpts?.labels,
145+
...specificOpts?.labels,
146+
},
147+
eventTrigger: {
148+
eventType,
149+
eventFilters: {},
150+
retry: !!optsOrHandler.retry,
151+
},
152+
};
153+
func.__endpoint = ep;
154+
155+
return func;
156+
}

v2/remoteConfig.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) 2022 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)