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.
- package/lib/runtime/loader.js +69 -4
- package/lib/runtime/manifest.d.ts +15 -3
- package/package.json +1 -1
package/lib/runtime/loader.js
CHANGED
|
@@ -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 (
|
|
69
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|