firebase-functions 5.0.1 → 5.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -63,6 +63,10 @@ function removeCircular(obj, refs = []) {
63
63
  * @public
64
64
  */
65
65
  function write(entry) {
66
+ const ctx = trace_1.traceContext.getStore();
67
+ if (ctx === null || ctx === void 0 ? void 0 : ctx.traceId) {
68
+ entry["logging.googleapis.com/trace"] = `projects/${process.env.GCLOUD_PROJECT}/traces/${ctx.traceId}`;
69
+ }
66
70
  common_1.UNPATCHED_CONSOLE[common_1.CONSOLE_SEVERITY[entry.severity]](JSON.stringify(removeCircular(entry)));
67
71
  }
68
72
  exports.write = write;
@@ -123,16 +127,12 @@ function entryFromArgs(severity, args) {
123
127
  if (lastArg && typeof lastArg === "object" && lastArg.constructor === Object) {
124
128
  entry = args.pop();
125
129
  }
126
- const ctx = trace_1.traceContext.getStore();
127
130
  // mimic `console.*` behavior, see https://nodejs.org/api/console.html#console_console_log_data_args
128
131
  let message = (0, util_1.format)(...args);
129
132
  if (severity === "ERROR" && !args.find((arg) => arg instanceof Error)) {
130
133
  message = new Error(message).stack || message;
131
134
  }
132
135
  const out = {
133
- "logging.googleapis.com/trace": (ctx === null || ctx === void 0 ? void 0 : ctx.traceId)
134
- ? `projects/${process.env.GCLOUD_PROJECT}/traces/${ctx.traceId}`
135
- : undefined,
136
136
  ...entry,
137
137
  severity,
138
138
  };
@@ -30,11 +30,10 @@ export declare const gcloudProject: Param<string>;
30
30
  export declare const storageBucket: Param<string>;
31
31
  /**
32
32
  * Declares a secret param, that will persist values only in Cloud Secret Manager.
33
- * Secrets are stored interally as bytestrings. Use `ParamOptions.as` to provide type
33
+ * Secrets are stored internally as bytestrings. Use `ParamOptions.as` to provide type
34
34
  * hinting during parameter resolution.
35
35
  *
36
36
  * @param name The name of the environment variable to use to load the parameter.
37
- * @param options Configuration options for the parameter.
38
37
  * @returns A parameter with a `string` return type for `.value`.
39
38
  */
40
39
  export declare function defineSecret(name: string): SecretParam;
@@ -77,11 +77,10 @@ exports.gcloudProject = new types_1.InternalExpression("GCLOUD_PROJECT", (env) =
77
77
  exports.storageBucket = new types_1.InternalExpression("STORAGE_BUCKET", (env) => { var _a; return ((_a = JSON.parse(env.FIREBASE_CONFIG)) === null || _a === void 0 ? void 0 : _a.storageBucket) || ""; });
78
78
  /**
79
79
  * Declares a secret param, that will persist values only in Cloud Secret Manager.
80
- * Secrets are stored interally as bytestrings. Use `ParamOptions.as` to provide type
80
+ * Secrets are stored internally as bytestrings. Use `ParamOptions.as` to provide type
81
81
  * hinting during parameter resolution.
82
82
  *
83
83
  * @param name The name of the environment variable to use to load the parameter.
84
- * @param options Configuration options for the parameter.
85
84
  * @returns A parameter with a `string` return type for `.value`.
86
85
  */
87
86
  function defineSecret(name) {
@@ -33,7 +33,7 @@ export declare class CompareExpression<T extends string | number | boolean | str
33
33
  type ParamValueType = "string" | "list" | "boolean" | "int" | "float" | "secret";
34
34
  /** Create a select input from a series of values. */
35
35
  export declare function select<T>(options: T[]): SelectInput<T>;
36
- /** Create a select input from a map of labels to vaues. */
36
+ /** Create a select input from a map of labels to values. */
37
37
  export declare function select<T>(optionsWithLabels: Record<string, T>): SelectInput<T>;
38
38
  /** Create a multi-select input from a series of values. */
39
39
  export declare function multiSelect(options: string[]): MultiSelectInput;
@@ -51,7 +51,7 @@ async function loadModule(functionsDir) {
51
51
  }
52
52
  }
53
53
  /* @internal */
54
- function extractStack(module, endpoints, requiredAPIs, prefix = "") {
54
+ function extractStack(module, endpoints, requiredAPIs, extensions, prefix = "") {
55
55
  for (const [name, valAsUnknown] of Object.entries(module)) {
56
56
  // We're introspecting untrusted code here. Any is appropraite
57
57
  const val = valAsUnknown;
@@ -65,12 +65,75 @@ function extractStack(module, endpoints, requiredAPIs, prefix = "") {
65
65
  requiredAPIs.push(...val.__requiredAPIs);
66
66
  }
67
67
  }
68
- else if (typeof val === "object" && val !== null) {
69
- extractStack(val, endpoints, requiredAPIs, prefix + name + "-");
68
+ else if (isFirebaseRefExtension(val)) {
69
+ extensions[val.instanceId] = {
70
+ params: convertExtensionParams(val.params),
71
+ ref: val.FIREBASE_EXTENSION_REFERENCE,
72
+ events: val.events || [],
73
+ };
74
+ }
75
+ else if (isFirebaseLocalExtension(val)) {
76
+ extensions[val.instanceId] = {
77
+ params: convertExtensionParams(val.params),
78
+ localPath: val.FIREBASE_EXTENSION_LOCAL_PATH,
79
+ events: val.events || [],
80
+ };
81
+ }
82
+ else if (isObject(val)) {
83
+ extractStack(val, endpoints, requiredAPIs, extensions, prefix + name + "-");
70
84
  }
71
85
  }
72
86
  }
73
87
  exports.extractStack = extractStack;
88
+ function toTitleCase(txt) {
89
+ return txt.charAt(0).toUpperCase() + txt.substring(1).toLowerCase();
90
+ }
91
+ function snakeToCamelCase(txt) {
92
+ let ret = txt.toLowerCase();
93
+ ret = ret.replace(/_/g, " ");
94
+ ret = ret.replace(/\w\S*/g, toTitleCase);
95
+ ret = ret.charAt(0).toLowerCase() + ret.substring(1);
96
+ return ret;
97
+ }
98
+ function convertExtensionParams(params) {
99
+ const systemPrefixes = {
100
+ FUNCTION: "firebaseextensions.v1beta.function",
101
+ V2FUNCTION: "firebaseextensions.v1beta.v2function",
102
+ };
103
+ const converted = {};
104
+ for (const [rawKey, paramVal] of Object.entries(params)) {
105
+ let key = rawKey;
106
+ if (rawKey.startsWith("_") && rawKey !== "_EVENT_ARC_REGION") {
107
+ const prefix = rawKey.substring(1).split("_")[0];
108
+ const suffix = rawKey.substring(2 + prefix.length); // 2 for underscores
109
+ key = `${systemPrefixes[prefix]}/${snakeToCamelCase(suffix)}`;
110
+ }
111
+ if (Array.isArray(paramVal)) {
112
+ converted[key] = paramVal.join(",");
113
+ }
114
+ else {
115
+ converted[key] = paramVal;
116
+ }
117
+ }
118
+ return converted;
119
+ }
120
+ function isObject(value) {
121
+ return typeof value === "object" && value !== null;
122
+ }
123
+ const isFirebaseLocalExtension = (val) => {
124
+ return (isObject(val) &&
125
+ typeof val.FIREBASE_EXTENSION_LOCAL_PATH === "string" &&
126
+ typeof val.instanceId === "string" &&
127
+ isObject(val.params) &&
128
+ (!val.events || Array.isArray(val.events)));
129
+ };
130
+ const isFirebaseRefExtension = (val) => {
131
+ return (isObject(val) &&
132
+ typeof val.FIREBASE_EXTENSION_REFERENCE === "string" &&
133
+ typeof val.instanceId === "string" &&
134
+ isObject(val.params) &&
135
+ (!val.events || Array.isArray(val.events)));
136
+ };
74
137
  /* @internal */
75
138
  function mergeRequiredAPIs(requiredAPIs) {
76
139
  const apiToReasons = {};
@@ -90,12 +153,14 @@ exports.mergeRequiredAPIs = mergeRequiredAPIs;
90
153
  async function loadStack(functionsDir) {
91
154
  const endpoints = {};
92
155
  const requiredAPIs = [];
156
+ const extensions = {};
93
157
  const mod = await loadModule(functionsDir);
94
- extractStack(mod, endpoints, requiredAPIs);
158
+ extractStack(mod, endpoints, requiredAPIs, extensions);
95
159
  const stack = {
96
160
  endpoints,
97
161
  specVersion: "v1alpha1",
98
162
  requiredAPIs: mergeRequiredAPIs(requiredAPIs),
163
+ extensions,
99
164
  };
100
165
  if (params.declaredParams.length > 0) {
101
166
  stack.params = params.declaredParams.map((p) => p.toSpec());
@@ -1,8 +1,18 @@
1
1
  import { ResetValue } from "../common/options";
2
2
  import { Expression } from "../params";
3
- import { WireParamSpec } from "../params/types";
3
+ import { WireParamSpec, SecretParam } from "../params/types";
4
4
  /**
5
- * An definition of a function as appears in the Manifest.
5
+ * A definition of an extension as appears in the Manifest.
6
+ * Exactly one of ref or localPath must be present.
7
+ */
8
+ export interface ManifestExtension {
9
+ params: Record<string, string | SecretParam>;
10
+ ref?: string;
11
+ localPath?: string;
12
+ events: string[];
13
+ }
14
+ /**
15
+ * A definition of a function as appears in the Manifest.
6
16
  *
7
17
  * @alpha
8
18
  */
@@ -83,7 +93,8 @@ export interface ManifestRequiredAPI {
83
93
  reason: string;
84
94
  }
85
95
  /**
86
- * An definition of a function deployment as appears in the Manifest.
96
+ * A definition of a function/extension deployment as appears in the Manifest.
97
+ *
87
98
  * @alpha
88
99
  */
89
100
  export interface ManifestStack {
@@ -91,6 +102,7 @@ export interface ManifestStack {
91
102
  params?: WireParamSpec<any>[];
92
103
  requiredAPIs: ManifestRequiredAPI[];
93
104
  endpoints: Record<string, ManifestEndpoint>;
105
+ extensions?: Record<string, ManifestExtension>;
94
106
  }
95
107
  /**
96
108
  * Returns the JSON representation of a ManifestStack, which has CEL
@@ -3,6 +3,6 @@ export { firebaseConfig } from "../common/config";
3
3
  * Store and retrieve project configuration data such as third-party API
4
4
  * keys or other settings. You can set configuration values using the
5
5
  * Firebase CLI as described in
6
- * [Environment Configuration](/docs/functions/config-env).
6
+ * https://firebase.google.com/docs/functions/config-env.
7
7
  */
8
8
  export declare function config(): Record<string, any>;
package/lib/v1/config.js CHANGED
@@ -35,7 +35,7 @@ exports.resetCache = resetCache;
35
35
  * Store and retrieve project configuration data such as third-party API
36
36
  * keys or other settings. You can set configuration values using the
37
37
  * Firebase CLI as described in
38
- * [Environment Configuration](/docs/functions/config-env).
38
+ * https://firebase.google.com/docs/functions/config-env.
39
39
  */
40
40
  function config() {
41
41
  // K_CONFIGURATION is only set in GCFv2
@@ -43,7 +43,7 @@ export interface GlobalOptions {
43
43
  * The minimum timeout for a 2nd gen function is 1s. The maximum timeout for a
44
44
  * function depends on the type of function: Event handling functions have a
45
45
  * maximum timeout of 540s (9 minutes). HTTPS and callable functions have a
46
- * maximum timeout of 36,00s (1 hour). Task queue functions have a maximum
46
+ * maximum timeout of 3,600s (1 hour). Task queue functions have a maximum
47
47
  * timeout of 1,800s (30 minutes).
48
48
  */
49
49
  timeoutSeconds?: number | Expression<number> | ResetValue;
@@ -43,6 +43,7 @@ exports.onAlertPublished = onAlertPublished;
43
43
  * @internal
44
44
  */
45
45
  function getEndpointAnnotation(opts, alertType, appId) {
46
+ var _a;
46
47
  const baseOpts = options.optionsToEndpoint(options.getGlobalOptions());
47
48
  const specificOpts = options.optionsToEndpoint(opts);
48
49
  const endpoint = {
@@ -59,7 +60,7 @@ function getEndpointAnnotation(opts, alertType, appId) {
59
60
  eventFilters: {
60
61
  alerttype: alertType,
61
62
  },
62
- retry: !!opts.retry,
63
+ retry: (_a = opts.retry) !== null && _a !== void 0 ? _a : false,
63
64
  },
64
65
  };
65
66
  if (appId) {
@@ -143,6 +143,7 @@ function makeChangedDatabaseEvent(event, instance, params) {
143
143
  }
144
144
  /** @internal */
145
145
  function makeEndpoint(eventType, opts, path, instance) {
146
+ var _a;
146
147
  const baseOpts = options.optionsToEndpoint(options.getGlobalOptions());
147
148
  const specificOpts = options.optionsToEndpoint(opts);
148
149
  const eventFilters = {};
@@ -166,7 +167,7 @@ function makeEndpoint(eventType, opts, path, instance) {
166
167
  eventType,
167
168
  eventFilters,
168
169
  eventFilterPathPatterns,
169
- retry: false,
170
+ retry: (_a = opts.retry) !== null && _a !== void 0 ? _a : false,
170
171
  },
171
172
  };
172
173
  }
@@ -32,7 +32,7 @@ const trace_1 = require("../trace");
32
32
  const options = require("../options");
33
33
  const onInit_1 = require("../../common/onInit");
34
34
  function onCustomEventPublished(eventTypeOrOpts, handler) {
35
- var _a;
35
+ var _a, _b;
36
36
  let opts;
37
37
  if (typeof eventTypeOrOpts === "string") {
38
38
  opts = {
@@ -61,7 +61,7 @@ function onCustomEventPublished(eventTypeOrOpts, handler) {
61
61
  eventTrigger: {
62
62
  eventType: opts.eventType,
63
63
  eventFilters: {},
64
- retry: false,
64
+ retry: (_b = opts.retry) !== null && _b !== void 0 ? _b : false,
65
65
  channel,
66
66
  },
67
67
  };
@@ -256,6 +256,7 @@ function makeChangedFirestoreEvent(event, params) {
256
256
  exports.makeChangedFirestoreEvent = makeChangedFirestoreEvent;
257
257
  /** @internal */
258
258
  function makeEndpoint(eventType, opts, document, database, namespace) {
259
+ var _a;
259
260
  const baseOpts = (0, options_1.optionsToEndpoint)((0, options_1.getGlobalOptions)());
260
261
  const specificOpts = (0, options_1.optionsToEndpoint)(opts);
261
262
  const eventFilters = {
@@ -283,7 +284,7 @@ function makeEndpoint(eventType, opts, document, database, namespace) {
283
284
  eventType,
284
285
  eventFilters,
285
286
  eventFilterPathPatterns,
286
- retry: !!opts.retry,
287
+ retry: (_a = opts.retry) !== null && _a !== void 0 ? _a : false,
287
288
  },
288
289
  };
289
290
  }
@@ -10,7 +10,7 @@ export { Request, CallableRequest, FunctionsErrorCode, HttpsError };
10
10
  /**
11
11
  * Options that can be set on an onRequest HTTPS function.
12
12
  */
13
- export interface HttpsOptions extends Omit<GlobalOptions, "region"> {
13
+ export interface HttpsOptions extends Omit<GlobalOptions, "region" | "enforceAppCheck"> {
14
14
  /**
15
15
  * If true, do not deploy or emulate this function.
16
16
  */
@@ -128,7 +128,7 @@ function onCall(optsOrHandler, handler) {
128
128
  // on the origin header of the request. If there is only one element in the
129
129
  // array, this is unnecessary.
130
130
  if (Array.isArray(origin) && origin.length === 1) {
131
- origin = origin[1];
131
+ origin = origin[0];
132
132
  }
133
133
  // onCallHandler sniffs the function length to determine which API to present.
134
134
  // fix the length to prevent api versions from being mismatched.
@@ -112,6 +112,7 @@ exports.Message = Message;
112
112
  * @typeParam T - Type representing `Message.data`'s JSON format
113
113
  */
114
114
  function onMessagePublished(topicOrOptions, handler) {
115
+ var _a;
115
116
  let topic;
116
117
  let opts;
117
118
  if (typeof topicOrOptions === "string") {
@@ -162,7 +163,7 @@ function onMessagePublished(topicOrOptions, handler) {
162
163
  eventTrigger: {
163
164
  eventType: "google.cloud.pubsub.topic.v1.messagePublished",
164
165
  eventFilters: { topic },
165
- retry: false,
166
+ retry: (_a = opts.retry) !== null && _a !== void 0 ? _a : false,
166
167
  },
167
168
  };
168
169
  (0, encoding_1.copyIfPresent)(endpoint.eventTrigger, opts, "retry", "retry");
@@ -36,6 +36,7 @@ exports.eventType = "google.firebase.remoteconfig.remoteConfig.v1.updated";
36
36
  * @returns A function that you can export and deploy.
37
37
  */
38
38
  function onConfigUpdated(optsOrHandler, handler) {
39
+ var _a;
39
40
  if (typeof optsOrHandler === "function") {
40
41
  handler = optsOrHandler;
41
42
  optsOrHandler = {};
@@ -58,7 +59,7 @@ function onConfigUpdated(optsOrHandler, handler) {
58
59
  eventTrigger: {
59
60
  eventType: exports.eventType,
60
61
  eventFilters: {},
61
- retry: !!optsOrHandler.retry,
62
+ retry: (_a = optsOrHandler.retry) !== null && _a !== void 0 ? _a : false,
62
63
  },
63
64
  };
64
65
  func.__endpoint = ep;
@@ -133,6 +133,7 @@ function onOperation(eventType, bucketOrOptsOrHandler, handler) {
133
133
  // To prevent runtime errors when FIREBASE_CONFIG env var is missing, we use getters.
134
134
  Object.defineProperty(func, "__endpoint", {
135
135
  get: () => {
136
+ var _a;
136
137
  const baseOpts = options.optionsToEndpoint(options.getGlobalOptions());
137
138
  const specificOpts = options.optionsToEndpoint(opts);
138
139
  const endpoint = {
@@ -147,7 +148,7 @@ function onOperation(eventType, bucketOrOptsOrHandler, handler) {
147
148
  eventTrigger: {
148
149
  eventType,
149
150
  eventFilters: { bucket },
150
- retry: false,
151
+ retry: (_a = opts.retry) !== null && _a !== void 0 ? _a : false,
151
152
  },
152
153
  };
153
154
  (0, encoding_1.copyIfPresent)(endpoint.eventTrigger, opts, "retry", "retry");
@@ -86,6 +86,7 @@ function onTaskDispatched(optsOrHandler, handler) {
86
86
  (0, encoding_1.copyIfPresent)(func.__endpoint.taskQueueTrigger.rateLimits, opts.rateLimits, "maxConcurrentDispatches", "maxDispatchesPerSecond");
87
87
  (0, encoding_1.convertIfPresent)(func.__endpoint.taskQueueTrigger, options.getGlobalOptions(), "invoker", "invoker", encoding_1.convertInvoker);
88
88
  (0, encoding_1.convertIfPresent)(func.__endpoint.taskQueueTrigger, opts, "invoker", "invoker", encoding_1.convertInvoker);
89
+ (0, encoding_1.copyIfPresent)(func.__endpoint.taskQueueTrigger, opts, "retry", "retry");
89
90
  func.__requiredAPIs = [
90
91
  {
91
92
  api: "cloudtasks.googleapis.com",
@@ -37,6 +37,7 @@ exports.eventType = "google.firebase.testlab.testMatrix.v1.completed";
37
37
  * @alpha
38
38
  */
39
39
  function onTestMatrixCompleted(optsOrHandler, handler) {
40
+ var _a;
40
41
  if (typeof optsOrHandler === "function") {
41
42
  handler = optsOrHandler;
42
43
  optsOrHandler = {};
@@ -59,7 +60,7 @@ function onTestMatrixCompleted(optsOrHandler, handler) {
59
60
  eventTrigger: {
60
61
  eventType: exports.eventType,
61
62
  eventFilters: {},
62
- retry: !!optsOrHandler.retry,
63
+ retry: (_a = optsOrHandler.retry) !== null && _a !== void 0 ? _a : false,
63
64
  },
64
65
  };
65
66
  func.__endpoint = ep;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-functions",
3
- "version": "5.0.1",
3
+ "version": "5.1.1",
4
4
  "description": "Firebase SDK for Cloud Functions",
5
5
  "keywords": [
6
6
  "firebase",
@@ -182,7 +182,7 @@
182
182
  "docgen:v2:gen": "api-documenter-fire markdown -i docgen/v2 -o docgen/v2/markdown --project functions && npm run docgen:v2:toc",
183
183
  "docgen:v2": "npm run build && npm run docgen:v2:extract && npm run docgen:v2:gen",
184
184
  "build:pack": "rm -rf lib && npm install && tsc -p tsconfig.release.json && npm pack",
185
- "build:release": "npm ci --production && npm install --no-save typescript firebase-admin && tsc -p tsconfig.release.json",
185
+ "build:release": "npm ci --production && npm install --no-save typescript && tsc -p tsconfig.release.json",
186
186
  "build": "tsc -p tsconfig.release.json",
187
187
  "build:watch": "npm run build -- -w",
188
188
  "format": "npm run format:ts && npm run format:other",