firebase-functions 7.2.5 → 7.3.0-rc.0

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.
Files changed (76) hide show
  1. package/lib/common/api.d.ts +7 -0
  2. package/lib/common/api.js +34 -0
  3. package/lib/common/providers/https.d.ts +7 -0
  4. package/lib/common/providers/https.js +40 -1
  5. package/lib/esm/common/api.mjs +31 -0
  6. package/lib/esm/common/providers/https.mjs +40 -2
  7. package/lib/esm/lifecycle/index.mjs +55 -0
  8. package/lib/esm/runtime/loader.mjs +12 -2
  9. package/lib/esm/runtime/manifest.mjs +0 -1
  10. package/lib/esm/security/roles.mjs +17 -0
  11. package/lib/esm/v1/cloud-functions.mjs +2 -1
  12. package/lib/esm/v1/function-builder.mjs +15 -1
  13. package/lib/esm/v1/index.mjs +2 -1
  14. package/lib/esm/v1/providers/https.mjs +28 -4
  15. package/lib/esm/v2/index.doc.mjs +4 -1
  16. package/lib/esm/v2/index.mjs +4 -1
  17. package/lib/esm/v2/options.mjs +79 -3
  18. package/lib/esm/v2/providers/ai/index.mjs +2 -2
  19. package/lib/esm/v2/providers/alerts/alerts.mjs +1 -1
  20. package/lib/esm/v2/providers/database.mjs +19 -6
  21. package/lib/esm/v2/providers/dataconnect/graphql.mjs +1 -1
  22. package/lib/esm/v2/providers/dataconnect/index.mjs +1 -1
  23. package/lib/esm/v2/providers/eventarc.mjs +1 -1
  24. package/lib/esm/v2/providers/firestore.mjs +1 -1
  25. package/lib/esm/v2/providers/https.mjs +9 -23
  26. package/lib/esm/v2/providers/identity.mjs +89 -4
  27. package/lib/esm/v2/providers/pubsub.mjs +4 -4
  28. package/lib/esm/v2/providers/remoteConfig.mjs +1 -1
  29. package/lib/esm/v2/providers/scheduler.mjs +1 -1
  30. package/lib/esm/v2/providers/storage.mjs +2 -2
  31. package/lib/esm/v2/providers/tasks.mjs +2 -2
  32. package/lib/esm/v2/providers/testLab.mjs +1 -1
  33. package/lib/esm/v2/security.mjs +19 -0
  34. package/lib/lifecycle/index.d.ts +44 -0
  35. package/lib/lifecycle/index.js +59 -0
  36. package/lib/logger/common.d.ts +20 -5
  37. package/lib/params/types.d.ts +9 -3
  38. package/lib/runtime/loader.js +12 -2
  39. package/lib/runtime/manifest.d.ts +24 -3
  40. package/lib/runtime/manifest.js +0 -1
  41. package/lib/security/roles.d.ts +5 -0
  42. package/lib/security/roles.js +19 -0
  43. package/lib/v1/cloud-functions.d.ts +8 -5
  44. package/lib/v1/cloud-functions.js +2 -1
  45. package/lib/v1/function-builder.d.ts +2 -2
  46. package/lib/v1/function-builder.js +15 -1
  47. package/lib/v1/index.d.ts +1 -0
  48. package/lib/v1/index.js +2 -0
  49. package/lib/v1/providers/https.d.ts +11 -3
  50. package/lib/v1/providers/https.js +28 -3
  51. package/lib/v2/index.d.ts +4 -2
  52. package/lib/v2/index.doc.js +7 -0
  53. package/lib/v2/index.js +7 -0
  54. package/lib/v2/options.d.ts +6 -2
  55. package/lib/v2/options.js +84 -2
  56. package/lib/v2/providers/ai/index.js +2 -2
  57. package/lib/v2/providers/alerts/alerts.js +1 -1
  58. package/lib/v2/providers/database.d.ts +1 -1
  59. package/lib/v2/providers/database.js +19 -6
  60. package/lib/v2/providers/dataconnect/graphql.js +1 -1
  61. package/lib/v2/providers/dataconnect/index.js +1 -1
  62. package/lib/v2/providers/eventarc.js +1 -1
  63. package/lib/v2/providers/firestore.js +1 -1
  64. package/lib/v2/providers/https.js +8 -22
  65. package/lib/v2/providers/identity.d.ts +71 -1
  66. package/lib/v2/providers/identity.js +91 -3
  67. package/lib/v2/providers/pubsub.d.ts +3 -3
  68. package/lib/v2/providers/pubsub.js +4 -4
  69. package/lib/v2/providers/remoteConfig.js +1 -1
  70. package/lib/v2/providers/scheduler.js +1 -1
  71. package/lib/v2/providers/storage.js +2 -2
  72. package/lib/v2/providers/tasks.js +2 -2
  73. package/lib/v2/providers/testLab.js +1 -1
  74. package/lib/v2/security.d.ts +11 -0
  75. package/lib/v2/security.js +19 -0
  76. package/package.json +17 -13
@@ -13,7 +13,6 @@ export interface ManifestExtension {
13
13
  }
14
14
  /**
15
15
  * A definition of a function as appears in the Manifest.
16
- *
17
16
  * @alpha
18
17
  */
19
18
  export interface ManifestEndpoint {
@@ -104,22 +103,44 @@ export interface ManifestRequiredAPI {
104
103
  reason: string;
105
104
  }
106
105
  /**
107
- * A definition of a function/extension deployment as appears in the Manifest.
106
+ * A definition of a lifecycle action as appears in the Manifest.
108
107
  *
109
108
  * @alpha
110
109
  */
110
+ export interface ManifestLifecycleAction {
111
+ task?: {
112
+ function: string;
113
+ body?: Record<string, unknown>;
114
+ };
115
+ call?: {
116
+ function: string;
117
+ params?: Record<string, unknown>;
118
+ };
119
+ http?: {
120
+ function?: string;
121
+ url?: string;
122
+ method?: string;
123
+ headers?: Record<string, string>;
124
+ body?: unknown;
125
+ };
126
+ }
127
+ /**
128
+ * A definition of a function/extension deployment as appears in the Manifest.
129
+ * @alpha
130
+ */
111
131
  export interface ManifestStack {
112
132
  specVersion: "v1alpha1";
113
133
  params?: WireParamSpec<any>[];
114
134
  requiredAPIs: ManifestRequiredAPI[];
115
135
  endpoints: Record<string, ManifestEndpoint>;
116
136
  extensions?: Record<string, ManifestExtension>;
137
+ requiredRoles?: string[];
138
+ lifecycleHooks?: Record<string, ManifestLifecycleAction>;
117
139
  }
118
140
  /**
119
141
  * Returns the JSON representation of a ManifestStack, which has CEL
120
142
  * expressions in its options as object types, with its expressions
121
143
  * transformed into the actual CEL strings.
122
- *
123
144
  * @alpha
124
145
  */
125
146
  export declare function stackToWire(stack: ManifestStack): Record<string, unknown>;
@@ -7,7 +7,6 @@ const require_common_options = require('../common/options.js');
7
7
  * Returns the JSON representation of a ManifestStack, which has CEL
8
8
  * expressions in its options as object types, with its expressions
9
9
  * transformed into the actual CEL strings.
10
- *
11
10
  * @alpha
12
11
  */
13
12
  function stackToWire(stack) {
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Global set of declared IAM roles required by this codebase.
3
+ * Accumulated in-memory during manifest generation.
4
+ */
5
+ export declare const declaredRoles: Set<string>;
@@ -0,0 +1,19 @@
1
+
2
+ //#region src/security/roles.ts
3
+ /**
4
+ * Global set of declared IAM roles required by this codebase.
5
+ * Accumulated in-memory during manifest generation.
6
+ */
7
+ const declaredRoles = new Set();
8
+ /**
9
+ * Registers a role to be required by this codebase.
10
+ * Automatically deduplicates using the Set.
11
+ * @internal
12
+ */
13
+ function registerRole(role) {
14
+ declaredRoles.add(role);
15
+ }
16
+
17
+ //#endregion
18
+ exports.declaredRoles = declaredRoles;
19
+ exports.registerRole = registerRole;
@@ -49,10 +49,13 @@ export interface EventContext<Params = Record<string, string>> {
49
49
  * For more detail including token keys, see the
50
50
  * {@link https://firebase.google.com/docs/reference/rules/rules#properties | security rules reference}.
51
51
  *
52
- * This field is only populated for Realtime Database triggers and Callable
53
- * functions. For an unauthenticated user, this field is null. For Firebase
52
+ * This field is only populated for Realtime Database triggers. For an
53
+ * unauthenticated Realtime Database user, this field is `null`. For Firebase
54
54
  * admin users and event types that do not provide user information, this field
55
- * does not exist.
55
+ * is not set.
56
+ *
57
+ * Callable functions use {@link https.CallableContext.auth} instead of
58
+ * `EventContext.auth`.
56
59
  */
57
60
  auth?: {
58
61
  uid: string;
@@ -72,8 +75,8 @@ export interface EventContext<Params = Record<string, string>> {
72
75
  *
73
76
  * - `UNAUTHENTICATED`: Unauthenticated action
74
77
  *
75
- * - `null`: For event types that do not provide user information (all except
76
- * Realtime Database).
78
+ * This field is only populated for Realtime Database triggers. For event
79
+ * types that do not provide user information, this field is not set.
77
80
  */
78
81
  authType?: "ADMIN" | "USER" | "UNAUTHENTICATED";
79
82
  /**
@@ -13,6 +13,7 @@ const WILDCARD_REGEX = new RegExp("{[^/{}]*}", "g");
13
13
  /** @internal */
14
14
  function makeCloudFunction({ contextOnlyHandler, dataConstructor = (raw) => raw.data, eventType, handler, labels = {}, legacyEventType, options = {}, provider, service, triggerResource }) {
15
15
  handler = require_common_onInit.withInit(handler ?? contextOnlyHandler);
16
+ const contextOnlyHandlerWithInit = contextOnlyHandler && require_common_onInit.withInit(contextOnlyHandler);
16
17
  const cloudFunction = (data, context) => {
17
18
  if (legacyEventType && context.eventType === legacyEventType) {
18
19
  context.eventType = provider + "." + eventType;
@@ -42,7 +43,7 @@ function makeCloudFunction({ contextOnlyHandler, dataConstructor = (raw) => raw.
42
43
  }
43
44
  let promise;
44
45
  if (labels && labels["deployment-scheduled"]) {
45
- promise = contextOnlyHandler(context);
46
+ promise = contextOnlyHandlerWithInit(context);
46
47
  } else {
47
48
  const dataOrChange = dataConstructor(event);
48
49
  promise = handler(dataOrChange, context);
@@ -72,10 +72,10 @@ export declare class FunctionBuilder {
72
72
  get https(): {
73
73
  /**
74
74
  * Handle HTTP requests.
75
- * @param handler A function that takes a request and response object,
75
+ * @param optsOrHandler Options or a function that takes a request and response object,
76
76
  * same signature as an Express app.
77
77
  */
78
- onRequest: (handler: (req: https.Request, resp: express.Response) => void | Promise<void>) => import("./cloud-functions").HttpsFunction;
78
+ onRequest: (optsOrHandler: https.HttpsOptions | ((req: https.Request, resp: express.Response) => void | Promise<void>), handler?: (req: https.Request, resp: express.Response) => void | Promise<void>) => import("./cloud-functions").HttpsFunction;
79
79
  /**
80
80
  * Declares a callable method for clients to call using a Firebase SDK.
81
81
  * @param handler A method that takes a data and context and returns a value.
@@ -200,7 +200,21 @@ var FunctionBuilder = class {
200
200
  console.warn("RuntimeOptions.failurePolicy is not supported in https functions.");
201
201
  }
202
202
  return {
203
- onRequest: (handler) => require_v1_providers_https._onRequestWithOptions(handler, this.options),
203
+ onRequest: (optsOrHandler, handler) => {
204
+ let opts;
205
+ let userHandler;
206
+ if (typeof optsOrHandler === "function") {
207
+ opts = {};
208
+ userHandler = optsOrHandler;
209
+ } else {
210
+ opts = optsOrHandler;
211
+ userHandler = handler;
212
+ }
213
+ return require_v1_providers_https._onRequestWithOptions(userHandler, {
214
+ ...this.options,
215
+ ...opts
216
+ });
217
+ },
204
218
  onCall: (handler) => require_v1_providers_https._onCallWithOptions(handler, this.options)
205
219
  };
206
220
  }
package/lib/v1/index.d.ts CHANGED
@@ -21,3 +21,4 @@ export * from "./function-configuration";
21
21
  import * as params from "../params";
22
22
  export { params };
23
23
  export { onInit } from "../common/onInit";
24
+ export { requiresAPI } from "../common/api";
package/lib/v1/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const require_logger_index = require('../logger/index.js');
2
2
  const require_params_index = require('../params/index.js');
3
+ const require_common_api = require('../common/api.js');
3
4
  const require_common_options = require('../common/options.js');
4
5
  const require_common_config = require('../common/config.js');
5
6
  const require_common_app = require('../common/app.js');
@@ -97,6 +98,7 @@ Object.defineProperty(exports, 'remoteConfig', {
97
98
  return require_v1_providers_remoteConfig.remoteConfig_exports;
98
99
  }
99
100
  });
101
+ exports.requiresAPI = require_common_api.requiresAPI;
100
102
  exports.runWith = require_v1_function_builder.runWith;
101
103
  Object.defineProperty(exports, 'storage', {
102
104
  enumerable: true,
@@ -1,14 +1,22 @@
1
1
  import * as express from "express";
2
- import { CallableContext, FunctionsErrorCode, HttpsError, Request } from "../../common/providers/https";
2
+ import { CallableContext, FunctionsErrorCode, HttpsError, type CorsOption, Request } from "../../common/providers/https";
3
3
  import { HttpsFunction, Runnable } from "../cloud-functions";
4
4
  export { HttpsError };
5
5
  export type { Request, CallableContext, FunctionsErrorCode };
6
+ export interface HttpsOptions {
7
+ /**
8
+ * If true, allows CORS on requests to this function.
9
+ * If this is a `string` or `RegExp`, allows requests from domains that match the provided value.
10
+ * If this is an `Array`, allows requests from domains matching at least one entry of the array.
11
+ */
12
+ cors?: CorsOption;
13
+ }
6
14
  /**
7
15
  * Handle HTTP requests.
8
- * @param handler A function that takes a request and response object,
16
+ * @param optsOrHandler Options or a function that takes a request and response object,
9
17
  * same signature as an Express app.
10
18
  */
11
- export declare function onRequest(handler: (req: Request, resp: express.Response) => void | Promise<void>): HttpsFunction;
19
+ export declare function onRequest(optsOrHandler: HttpsOptions | ((req: Request, resp: express.Response) => void | Promise<void>), handler?: (req: Request, resp: express.Response) => void | Promise<void>): HttpsFunction;
12
20
  /**
13
21
  * Declares a callable method for clients to call using a Firebase SDK.
14
22
  * @param handler A method that takes a data and context and returns a value.
@@ -1,10 +1,13 @@
1
1
  const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.js');
2
2
  const require_runtime_manifest = require('../../runtime/manifest.js');
3
+ const require_common_debug = require('../../common/debug.js');
3
4
  const require_common_encoding = require('../../common/encoding.js');
4
5
  const require_common_onInit = require('../../common/onInit.js');
5
6
  const require_v1_cloud_functions = require('../cloud-functions.js');
6
7
  const require_common_providers_https = require('../../common/providers/https.js');
7
8
  const require_v2_trace = require('../../v2/trace.js');
9
+ let cors = require("cors");
10
+ cors = require_rolldown_runtime.__toESM(cors);
8
11
 
9
12
  //#region src/v1/providers/https.ts
10
13
  var https_exports = /* @__PURE__ */ require_rolldown_runtime.__export({
@@ -16,11 +19,20 @@ var https_exports = /* @__PURE__ */ require_rolldown_runtime.__export({
16
19
  });
17
20
  /**
18
21
  * Handle HTTP requests.
19
- * @param handler A function that takes a request and response object,
22
+ * @param optsOrHandler Options or a function that takes a request and response object,
20
23
  * same signature as an Express app.
21
24
  */
22
- function onRequest(handler) {
23
- return _onRequestWithOptions(handler, {});
25
+ function onRequest(optsOrHandler, handler) {
26
+ let opts;
27
+ let userHandler;
28
+ if (typeof optsOrHandler === "function") {
29
+ opts = {};
30
+ userHandler = optsOrHandler;
31
+ } else {
32
+ opts = optsOrHandler;
33
+ userHandler = handler;
34
+ }
35
+ return _onRequestWithOptions(userHandler, opts);
24
36
  }
25
37
  /**
26
38
  * Declares a callable method for clients to call using a Firebase SDK.
@@ -31,6 +43,19 @@ function onCall(handler) {
31
43
  }
32
44
  /** @internal */
33
45
  function _onRequestWithOptions(handler, options) {
46
+ if (require_common_debug.isDebugFeatureEnabled("enableCors") || "cors" in options) {
47
+ const userProvidedHandler = handler;
48
+ handler = (req, res) => {
49
+ return new Promise((resolve) => {
50
+ res.on("finish", resolve);
51
+ const origin = require_common_providers_https.resolveCorsOrigin(options.cors);
52
+ const middleware = (0, cors.default)({ origin });
53
+ middleware(req, res, () => {
54
+ resolve(userProvidedHandler(req, res));
55
+ });
56
+ });
57
+ };
58
+ }
34
59
  const cloudFunction = (req, res) => {
35
60
  return require_v2_trace.wrapTraceContext(require_common_onInit.withInit(require_common_providers_https.withErrorHandler(handler)))(req, res);
36
61
  };
package/lib/v2/index.d.ts CHANGED
@@ -20,14 +20,16 @@ import * as firestore from "./providers/firestore";
20
20
  import * as dataconnect from "./providers/dataconnect";
21
21
  export { alerts, database, storage, https, identity, pubsub, tasks, eventarc, scheduler, remoteConfig, testLab, firestore, dataconnect, };
22
22
  export { logger } from "../logger";
23
- export { setGlobalOptions } from "./options";
24
- export type { GlobalOptions, SupportedRegion, MemoryOption, VpcEgressSetting, IngressSetting, EventHandlerOptions, } from "./options";
23
+ export { setGlobalOptions, requiresRole } from "./options";
24
+ export { requiresAPI } from "../common/api";
25
+ export type { GlobalOptions, SupportedRegion, MemoryOption, VpcEgressSetting, IngressSetting, EventHandlerOptions, Role, } from "./options";
25
26
  export { onInit } from "./core";
26
27
  export type { CloudFunction, CloudEvent, ParamsOf } from "./core";
27
28
  export { Change } from "../common/change";
28
29
  export { traceContext } from "../common/trace";
29
30
  import * as params from "../params";
30
31
  export { params };
32
+ export { afterFirstDeploy, afterRedeploy } from "../lifecycle";
31
33
  export { config } from "../v1/config";
32
34
  import { setApp as setEmulatedAdminApp } from "../common/app";
33
35
  export declare const app: {
@@ -1,9 +1,12 @@
1
1
  const require_common_trace = require('../common/trace.js');
2
2
  const require_logger_index = require('../logger/index.js');
3
3
  const require_params_index = require('../params/index.js');
4
+ const require_common_api = require('../common/api.js');
5
+ const require_lifecycle_index = require('../lifecycle/index.js');
4
6
  const require_common_change = require('../common/change.js');
5
7
  const require_common_onInit = require('../common/onInit.js');
6
8
  const require_v1_config = require('../v1/config.js');
9
+ const require_v2_security = require('./security.js');
7
10
  const require_v2_options = require('./options.js');
8
11
  const require_v2_dataconnect_doc = require('./dataconnect.doc.js');
9
12
  const require_v2_providers_alerts_index = require('./providers/alerts/index.js');
@@ -21,6 +24,8 @@ const require_v2_providers_firestore = require('./providers/firestore.js');
21
24
  const require_v2_index = require('./index.js');
22
25
 
23
26
  exports.Change = require_common_change.Change;
27
+ exports.afterFirstDeploy = require_lifecycle_index.afterFirstDeploy;
28
+ exports.afterRedeploy = require_lifecycle_index.afterRedeploy;
24
29
  Object.defineProperty(exports, 'alerts', {
25
30
  enumerable: true,
26
31
  get: function () {
@@ -85,6 +90,8 @@ Object.defineProperty(exports, 'remoteConfig', {
85
90
  return require_v2_providers_remoteConfig.remoteConfig_exports;
86
91
  }
87
92
  });
93
+ exports.requiresAPI = require_common_api.requiresAPI;
94
+ exports.requiresRole = require_v2_security.requiresRole;
88
95
  Object.defineProperty(exports, 'scheduler', {
89
96
  enumerable: true,
90
97
  get: function () {
package/lib/v2/index.js CHANGED
@@ -1,11 +1,14 @@
1
1
  const require_common_trace = require('../common/trace.js');
2
2
  const require_logger_index = require('../logger/index.js');
3
3
  const require_params_index = require('../params/index.js');
4
+ const require_common_api = require('../common/api.js');
5
+ const require_lifecycle_index = require('../lifecycle/index.js');
4
6
  const require_common_app = require('../common/app.js');
5
7
  const require_common_change = require('../common/change.js');
6
8
  const require_common_onInit = require('../common/onInit.js');
7
9
  const require_v1_config = require('../v1/config.js');
8
10
  require('./core.js');
11
+ const require_v2_security = require('./security.js');
9
12
  const require_v2_options = require('./options.js');
10
13
  const require_v2_providers_dataconnect_index = require('./providers/dataconnect/index.js');
11
14
  const require_v2_providers_alerts_index = require('./providers/alerts/index.js');
@@ -26,6 +29,8 @@ const app = { setEmulatedAdminApp: require_common_app.setApp };
26
29
 
27
30
  //#endregion
28
31
  exports.Change = require_common_change.Change;
32
+ exports.afterFirstDeploy = require_lifecycle_index.afterFirstDeploy;
33
+ exports.afterRedeploy = require_lifecycle_index.afterRedeploy;
29
34
  Object.defineProperty(exports, 'alerts', {
30
35
  enumerable: true,
31
36
  get: function () {
@@ -90,6 +95,8 @@ Object.defineProperty(exports, 'remoteConfig', {
90
95
  return require_v2_providers_remoteConfig.remoteConfig_exports;
91
96
  }
92
97
  });
98
+ exports.requiresAPI = require_common_api.requiresAPI;
99
+ exports.requiresRole = require_v2_security.requiresRole;
93
100
  Object.defineProperty(exports, 'scheduler', {
94
101
  enumerable: true,
95
102
  get: function () {
@@ -66,8 +66,10 @@ export interface GlobalOptions {
66
66
  * HTTPS functions can specify a higher timeout.
67
67
  *
68
68
  * @remarks
69
- * The minimum timeout for a 2nd gen function is 1s. The maximum timeout for a
70
- * function depends on the type of function: Event handling functions have a
69
+ * The minimum timeout for a 2nd gen (and 1st gen) function is 0s; this has the precise
70
+ * meaning of being 'un-set' and ends up defaulting to 60s.
71
+ * The maximum timeout for a function depends on the type of function:
72
+ * Event handling functions have a
71
73
  * maximum timeout of 540s (9 minutes). HTTPS and callable functions have a
72
74
  * maximum timeout of 3,600s (1 hour). Task queue functions have a maximum
73
75
  * timeout of 1,800s (30 minutes).
@@ -203,3 +205,5 @@ export declare function __getSpec(): {
203
205
  globalOptions: GlobalOptions;
204
206
  params: ParamSpec<any>[];
205
207
  };
208
+ export { requiresRole } from "./security";
209
+ export type { Role } from "./security";
package/lib/v2/options.js CHANGED
@@ -1,9 +1,34 @@
1
1
  const require_logger_index = require('../logger/index.js');
2
+ const require_params_types = require('../params/types.js');
2
3
  const require_params_index = require('../params/index.js');
3
4
  const require_common_options = require('../common/options.js');
4
5
  const require_common_encoding = require('../common/encoding.js');
6
+ const require_common_utilities_assertions = require('../common/utilities/assertions.js');
7
+ const require_v2_security = require('./security.js');
5
8
 
6
9
  //#region src/v2/options.ts
10
+ /**
11
+ * Maximum timeout in seconds for event-handling functions (e.g. Firestore,
12
+ * Realtime Database, Pub/Sub, Storage, Eventarc, alerts, scheduler).
13
+ * See https://firebase.google.com/docs/functions/manage-functions
14
+ * @internal
15
+ */
16
+ const MAX_EVENT_TIMEOUT_SECONDS = 540;
17
+ /**
18
+ * Maximum timeout in seconds for HTTPS and callable functions.
19
+ * @internal
20
+ */
21
+ const MAX_HTTPS_TIMEOUT_SECONDS = 3600;
22
+ /**
23
+ * Maximum timeout in seconds for Task Queue functions.
24
+ * @internal
25
+ */
26
+ const MAX_TASK_TIMEOUT_SECONDS = 1800;
27
+ /**
28
+ * Maximum timeout in seconds for Identity blocking functions.
29
+ * @internal
30
+ */
31
+ const MAX_IDENTITY_TIMEOUT_SECONDS = 7;
7
32
  const MemoryOptionToMB = {
8
33
  "128MiB": 128,
9
34
  "256MiB": 256,
@@ -35,10 +60,58 @@ function getGlobalOptions() {
35
60
  return globalOptions || {};
36
61
  }
37
62
  /**
63
+ * Validate that `timeoutSeconds` (resolved with global option fallback) is
64
+ * finite and within the accepted range for the given function kind. Throws a
65
+ * plain `Error` matching the v1 `assertRuntimeOptionsValid` shape so the
66
+ * problem surfaces at function-definition time instead of at deploy time.
67
+ * `Expression`, `RESET_VALUE`, and `undefined` are skipped. Literal numbers
68
+ * are range checked, and other types are rejected.
69
+ * @internal
70
+ */
71
+ function assertTimeoutSecondsValid(opts, kind) {
72
+ const timeoutSeconds = opts.timeoutSeconds === undefined ? getGlobalOptions().timeoutSeconds : opts.timeoutSeconds;
73
+ if (typeof timeoutSeconds !== "number") {
74
+ if (timeoutSeconds === undefined || timeoutSeconds instanceof require_params_types.Expression || timeoutSeconds instanceof require_common_options.ResetValue) {
75
+ return;
76
+ }
77
+ throw new Error(`timeoutSeconds must be a number, Expression, or RESET_VALUE. Got ${typeof timeoutSeconds}.`);
78
+ }
79
+ if (!Number.isFinite(timeoutSeconds)) {
80
+ throw new Error(`timeoutSeconds must be a finite number. Got ${timeoutSeconds}.`);
81
+ }
82
+ let max;
83
+ let label;
84
+ switch (kind) {
85
+ case "event":
86
+ max = MAX_EVENT_TIMEOUT_SECONDS;
87
+ label = "event-handling";
88
+ break;
89
+ case "https":
90
+ max = MAX_HTTPS_TIMEOUT_SECONDS;
91
+ label = "HTTPS and callable";
92
+ break;
93
+ case "task":
94
+ max = MAX_TASK_TIMEOUT_SECONDS;
95
+ label = "task queue";
96
+ break;
97
+ case "identity":
98
+ max = MAX_IDENTITY_TIMEOUT_SECONDS;
99
+ label = "blocking";
100
+ break;
101
+ default: require_common_utilities_assertions.assertNever(kind);
102
+ }
103
+ if (timeoutSeconds < 0 || timeoutSeconds > max) {
104
+ throw new Error(`timeoutSeconds must be between 0 and ${max} for ${label} functions. Got ${timeoutSeconds}.`);
105
+ }
106
+ }
107
+ /**
38
108
  * Apply GlobalOptions to trigger definitions.
39
109
  * @internal
40
110
  */
41
- function optionsToTriggerAnnotations(opts) {
111
+ function optionsToTriggerAnnotations(opts, kind) {
112
+ if (kind !== undefined) {
113
+ assertTimeoutSecondsValid(opts, kind);
114
+ }
42
115
  const annotation = {};
43
116
  require_common_encoding.copyIfPresent(annotation, opts, "concurrency", "minInstances", "maxInstances", "ingressSettings", "labels", "vpcConnector", "secrets");
44
117
  const vpcEgress = opts.vpcEgress ?? opts.vpcConnectorEgressSettings;
@@ -69,7 +142,10 @@ function optionsToTriggerAnnotations(opts) {
69
142
  * Apply GlobalOptions to endpoint manifest.
70
143
  * @internal
71
144
  */
72
- function optionsToEndpoint(opts) {
145
+ function optionsToEndpoint(opts, kind) {
146
+ if (kind !== undefined) {
147
+ assertTimeoutSecondsValid(opts, kind);
148
+ }
73
149
  const endpoint = {};
74
150
  require_common_encoding.copyIfPresent(endpoint, opts, "omit", "concurrency", "minInstances", "maxInstances", "ingressSettings", "labels", "timeoutSeconds", "cpu");
75
151
  require_common_encoding.convertIfPresent(endpoint, opts, "serviceAccountEmail", "serviceAccount");
@@ -127,9 +203,15 @@ function __getSpec() {
127
203
  }
128
204
 
129
205
  //#endregion
206
+ exports.MAX_EVENT_TIMEOUT_SECONDS = MAX_EVENT_TIMEOUT_SECONDS;
207
+ exports.MAX_HTTPS_TIMEOUT_SECONDS = MAX_HTTPS_TIMEOUT_SECONDS;
208
+ exports.MAX_IDENTITY_TIMEOUT_SECONDS = MAX_IDENTITY_TIMEOUT_SECONDS;
209
+ exports.MAX_TASK_TIMEOUT_SECONDS = MAX_TASK_TIMEOUT_SECONDS;
130
210
  exports.RESET_VALUE = require_common_options.RESET_VALUE;
131
211
  exports.__getSpec = __getSpec;
212
+ exports.assertTimeoutSecondsValid = assertTimeoutSecondsValid;
132
213
  exports.getGlobalOptions = getGlobalOptions;
133
214
  exports.optionsToEndpoint = optionsToEndpoint;
134
215
  exports.optionsToTriggerAnnotations = optionsToTriggerAnnotations;
216
+ exports.requiresRole = require_v2_security.requiresRole;
135
217
  exports.setGlobalOptions = setGlobalOptions;
@@ -90,7 +90,7 @@ function beforeGenerateContent(optsOrCb, cb) {
90
90
  func.run = handler;
91
91
  func = require_v2_trace.wrapTraceContext(require_common_onInit.withInit(func));
92
92
  const baseOpts = require_v2_options.optionsToEndpoint(require_v2_options.getGlobalOptions());
93
- const specificOpts = require_v2_options.optionsToEndpoint(opts);
93
+ const specificOpts = require_v2_options.optionsToEndpoint(opts, "https");
94
94
  func.__endpoint = {
95
95
  ...require_runtime_manifest.initV2Endpoint(require_v2_options.getGlobalOptions(), opts),
96
96
  platform: "gcfv2",
@@ -165,7 +165,7 @@ function afterGenerateContent(optsOrCb, cb) {
165
165
  func.run = handler;
166
166
  func = require_v2_trace.wrapTraceContext(require_common_onInit.withInit(func));
167
167
  const baseOpts = require_v2_options.optionsToEndpoint(require_v2_options.getGlobalOptions());
168
- const specificOpts = require_v2_options.optionsToEndpoint(opts);
168
+ const specificOpts = require_v2_options.optionsToEndpoint(opts, "https");
169
169
  func.__endpoint = {
170
170
  ...require_runtime_manifest.initV2Endpoint(require_v2_options.getGlobalOptions(), opts),
171
171
  platform: "gcfv2",
@@ -21,7 +21,7 @@ function onAlertPublished(alertTypeOrOpts, handler) {
21
21
  */
22
22
  function getEndpointAnnotation(opts, alertType, appId) {
23
23
  const baseOpts = require_v2_options.optionsToEndpoint(require_v2_options.getGlobalOptions());
24
- const specificOpts = require_v2_options.optionsToEndpoint(opts);
24
+ const specificOpts = require_v2_options.optionsToEndpoint(opts, "event");
25
25
  const endpoint = {
26
26
  ...require_runtime_manifest.initV2Endpoint(require_v2_options.getGlobalOptions(), opts),
27
27
  platform: "gcfv2",
@@ -69,7 +69,7 @@ export interface ReferenceOptions<Ref extends string = string> extends options.E
69
69
  * Examples: 'my-instance-1', 'my-instance-*'
70
70
  * Note: The capture syntax cannot be used for 'instance'.
71
71
  */
72
- instance?: string;
72
+ instance?: string | Expression<string>;
73
73
  /**
74
74
  * If true, do not deploy or emulate this function.
75
75
  */
@@ -1,4 +1,6 @@
1
1
  const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.js');
2
+ const require_params_types = require('../../params/types.js');
3
+ require('../../params/index.js');
2
4
  const require_runtime_manifest = require('../../runtime/manifest.js');
3
5
  const require_common_app = require('../../common/app.js');
4
6
  const require_common_onInit = require('../../common/onInit.js');
@@ -163,10 +165,12 @@ function makeV1Context(eventType, databaseEvent) {
163
165
  /** @internal */
164
166
  function makeEndpoint(eventType, opts, path, instance) {
165
167
  const baseOpts = require_v2_options.optionsToEndpoint(require_v2_options.getGlobalOptions());
166
- const specificOpts = require_v2_options.optionsToEndpoint(opts);
168
+ const specificOpts = require_v2_options.optionsToEndpoint(opts, "event");
167
169
  const eventFilters = {};
168
170
  const eventFilterPathPatterns = { ref: path.getValue() };
169
- if (instance.hasWildcards()) {
171
+ if (instance instanceof require_params_types.Expression) {
172
+ eventFilterPathPatterns.instance = instance;
173
+ } else if (instance.hasWildcards()) {
170
174
  eventFilterPathPatterns.instance = instance.getValue();
171
175
  } else {
172
176
  eventFilters.instance = instance.getValue();
@@ -188,15 +192,24 @@ function makeEndpoint(eventType, opts, path, instance) {
188
192
  }
189
193
  };
190
194
  }
195
+ function resolveInstancePattern(instance) {
196
+ return instance instanceof require_params_types.Expression ? new require_common_utilities_path_pattern.PathPattern(instance.value()) : instance;
197
+ }
198
+ function makeInstancePattern(instance) {
199
+ return instance instanceof require_params_types.Expression ? instance : new require_common_utilities_path_pattern.PathPattern(instance);
200
+ }
201
+ function makeTypedParams(event, pathPattern, instancePattern) {
202
+ return makeParams(event, pathPattern, resolveInstancePattern(instancePattern));
203
+ }
191
204
  /** @internal */
192
205
  function onChangedOperation(eventType, referenceOrOpts, handler) {
193
206
  const { path, instance, opts } = getOpts(referenceOrOpts);
194
207
  const pathPattern = new require_common_utilities_path_pattern.PathPattern(path);
195
- const instancePattern = new require_common_utilities_path_pattern.PathPattern(instance);
208
+ const instancePattern = makeInstancePattern(instance);
196
209
  const func = (raw) => {
197
210
  const event = raw;
198
211
  const instanceUrl = getInstance(event);
199
- const params = makeParams(event, pathPattern, instancePattern);
212
+ const params = makeTypedParams(event, pathPattern, instancePattern);
200
213
  const databaseEvent = makeChangedDatabaseEvent(event, instanceUrl, params);
201
214
  const compatEvent = require_v2_compat.addV1Compat(databaseEvent, {
202
215
  context: () => makeV1Context(eventType, databaseEvent),
@@ -212,11 +225,11 @@ function onChangedOperation(eventType, referenceOrOpts, handler) {
212
225
  function onOperation(eventType, referenceOrOpts, handler) {
213
226
  const { path, instance, opts } = getOpts(referenceOrOpts);
214
227
  const pathPattern = new require_common_utilities_path_pattern.PathPattern(path);
215
- const instancePattern = new require_common_utilities_path_pattern.PathPattern(instance);
228
+ const instancePattern = makeInstancePattern(instance);
216
229
  const func = (raw) => {
217
230
  const event = raw;
218
231
  const instanceUrl = getInstance(event);
219
- const params = makeParams(event, pathPattern, instancePattern);
232
+ const params = makeTypedParams(event, pathPattern, instancePattern);
220
233
  const data = eventType === deletedEventType ? event.data.data : event.data.delta;
221
234
  const databaseEvent = makeDatabaseEvent(event, data, instanceUrl, params);
222
235
  const compatEvent = require_v2_compat.addV1Compat(databaseEvent, {
@@ -82,7 +82,7 @@ function onGraphRequest(opts) {
82
82
  })));
83
83
  const globalOpts = require_v2_options.getGlobalOptions();
84
84
  const baseOpts = require_v2_options.optionsToEndpoint(globalOpts);
85
- const specificOpts = require_v2_options.optionsToEndpoint(opts);
85
+ const specificOpts = require_v2_options.optionsToEndpoint(opts, "https");
86
86
  const endpoint = {
87
87
  ...require_runtime_manifest.initV2Endpoint(globalOpts, opts),
88
88
  platform: "gcfv2",
@@ -56,7 +56,7 @@ function getOpts(mutationOrOpts) {
56
56
  }
57
57
  function makeEndpoint(eventType, opts, service, connector, operation) {
58
58
  const baseOpts = require_v2_options.optionsToEndpoint(require_v2_options.getGlobalOptions());
59
- const specificOpts = require_v2_options.optionsToEndpoint(opts);
59
+ const specificOpts = require_v2_options.optionsToEndpoint(opts, "event");
60
60
  const eventFilters = {};
61
61
  const eventFilterPathPatterns = {};
62
62
  if (service) {
@@ -20,7 +20,7 @@ function onCustomEventPublished(eventTypeOrOpts, handler) {
20
20
  func.run = handler;
21
21
  const channel = opts.channel ?? "locations/us-central1/channels/firebase";
22
22
  const baseOpts = require_v2_options.optionsToEndpoint(require_v2_options.getGlobalOptions());
23
- const specificOpts = require_v2_options.optionsToEndpoint(opts);
23
+ const specificOpts = require_v2_options.optionsToEndpoint(opts, "event");
24
24
  const endpoint = {
25
25
  ...require_runtime_manifest.initV2Endpoint(require_v2_options.getGlobalOptions(), opts),
26
26
  platform: "gcfv2",
@@ -234,7 +234,7 @@ function makeChangedFirestoreEvent(event, params) {
234
234
  /** @internal */
235
235
  function makeEndpoint(eventType, opts, document, database, namespace) {
236
236
  const baseOpts = require_v2_options.optionsToEndpoint(require_v2_options.getGlobalOptions());
237
- const specificOpts = require_v2_options.optionsToEndpoint(opts);
237
+ const specificOpts = require_v2_options.optionsToEndpoint(opts, "event");
238
238
  const eventFilters = {
239
239
  database,
240
240
  namespace