firebase-functions 5.0.1 → 5.1.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.
@@ -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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-functions",
3
- "version": "5.0.1",
3
+ "version": "5.1.0",
4
4
  "description": "Firebase SDK for Cloud Functions",
5
5
  "keywords": [
6
6
  "firebase",