firebase-tools 11.22.0 → 11.23.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/commands/ext-configure.js +3 -3
- package/lib/commands/ext-dev-init.js +16 -4
- package/lib/commands/ext-dev-publish.js +3 -3
- package/lib/commands/ext-dev-register.js +2 -2
- package/lib/commands/ext-info.js +3 -3
- package/lib/commands/ext-install.js +2 -2
- package/lib/commands/ext-uninstall.js +2 -2
- package/lib/commands/ext-update.js +2 -2
- package/lib/commands/hosting-channel-create.js +2 -2
- package/lib/commands/hosting-channel-delete.js +2 -2
- package/lib/commands/hosting-channel-deploy.js +2 -2
- package/lib/commands/hosting-clone.js +2 -2
- package/lib/deploy/functions/release/fabricator.js +3 -0
- package/lib/deploy/functions/runtimes/python/index.js +26 -13
- package/lib/deploy/hosting/convertConfig.js +2 -1
- package/lib/emulator/auth/apiSpec.js +17 -1
- package/lib/emulator/downloadableEmulators.js +6 -6
- package/lib/emulator/functionsEmulator.js +12 -15
- package/lib/emulator/functionsEmulatorRuntime.js +26 -42
- package/lib/emulator/functionsRuntimeWorker.js +48 -22
- package/lib/emulator/hub.js +6 -6
- package/lib/emulator/pubsubEmulator.js +12 -9
- package/lib/emulator/storage/apis/shared.js +2 -1
- package/lib/emulator/storage/cloudFunctions.js +1 -1
- package/lib/emulator/storage/files.js +18 -11
- package/lib/emulator/types.js +9 -9
- package/lib/extensions/askUserForConsent.js +4 -4
- package/lib/extensions/askUserForEventsConfig.js +2 -2
- package/lib/extensions/askUserForParam.js +2 -2
- package/lib/extensions/billingMigrationHelper.js +4 -4
- package/lib/extensions/change-log.js +4 -4
- package/lib/extensions/displayExtensionInfo.js +4 -4
- package/lib/extensions/extensionsApi.js +2 -2
- package/lib/extensions/extensionsHelper.js +6 -6
- package/lib/extensions/provisioningHelper.js +2 -2
- package/lib/extensions/updateHelper.js +2 -2
- package/lib/extensions/warnings.js +5 -5
- package/lib/frameworks/angular/index.js +6 -4
- package/lib/frameworks/index.js +38 -3
- package/lib/frameworks/lit/index.js +5 -1
- package/lib/frameworks/next/index.js +42 -16
- package/lib/frameworks/next/utils.js +1 -1
- package/lib/frameworks/preact/index.js +5 -1
- package/lib/frameworks/react/index.js +5 -1
- package/lib/frameworks/svelte/index.js +5 -1
- package/lib/frameworks/vite/index.js +6 -4
- package/lib/functions/python.js +2 -7
- package/lib/gcp/cloudfunctionsv2.js +8 -0
- package/lib/getDefaultHostingSite.js +3 -1
- package/lib/init/features/functions/index.js +10 -0
- package/lib/init/features/functions/python.js +48 -0
- package/lib/init/features/hosting/index.js +3 -2
- package/lib/projectUtils.js +2 -2
- package/lib/rc.js +4 -4
- package/npm-shrinkwrap.json +87 -79
- package/package.json +2 -2
- package/templates/extensions/extension.yaml +1 -1
- package/templates/extensions/integration-test.env +2 -0
- package/templates/extensions/integration-test.json +14 -0
- package/templates/extensions/javascript/WELCOME.md +14 -5
- package/templates/extensions/javascript/index.js +10 -10
- package/templates/extensions/javascript/integration-test.js +13 -0
- package/templates/extensions/javascript/package.lint.json +12 -4
- package/templates/extensions/javascript/package.nolint.json +11 -2
- package/templates/extensions/typescript/WELCOME.md +18 -5
- package/templates/extensions/typescript/_mocharc +10 -0
- package/templates/extensions/typescript/index.ts +16 -15
- package/templates/extensions/typescript/integration-test.ts +13 -0
- package/templates/extensions/typescript/package.lint.json +16 -4
- package/templates/extensions/typescript/package.nolint.json +12 -4
- package/templates/init/functions/javascript/_eslintrc +16 -2
- package/templates/init/functions/javascript/package.lint.json +4 -4
- package/templates/init/functions/javascript/package.nolint.json +3 -3
- package/templates/init/functions/python/_gitignore +0 -0
- package/templates/init/functions/python/main.py +13 -0
- package/templates/init/functions/python/requirements.txt +1 -0
- package/templates/init/functions/typescript/_eslintrc +1 -0
- package/templates/init/functions/typescript/package.lint.json +4 -4
- package/templates/init/functions/typescript/package.nolint.json +4 -3
|
@@ -41,6 +41,27 @@ function requireResolveAsync(moduleName, opts) {
|
|
|
41
41
|
});
|
|
42
42
|
}
|
|
43
43
|
class Proxied {
|
|
44
|
+
static getOriginal(target, key) {
|
|
45
|
+
const value = target[key];
|
|
46
|
+
if (!Proxied.isExists(value)) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
else if (Proxied.isConstructor(value) || typeof value !== "function") {
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
return value.bind(target);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
static applyOriginal(target, thisArg, argArray) {
|
|
57
|
+
return target.apply(thisArg, argArray);
|
|
58
|
+
}
|
|
59
|
+
static isConstructor(obj) {
|
|
60
|
+
return !!obj.prototype && !!obj.prototype.constructor.name;
|
|
61
|
+
}
|
|
62
|
+
static isExists(obj) {
|
|
63
|
+
return obj !== undefined;
|
|
64
|
+
}
|
|
44
65
|
constructor(original) {
|
|
45
66
|
this.original = original;
|
|
46
67
|
this.rewrites = {};
|
|
@@ -65,27 +86,6 @@ class Proxied {
|
|
|
65
86
|
},
|
|
66
87
|
});
|
|
67
88
|
}
|
|
68
|
-
static getOriginal(target, key) {
|
|
69
|
-
const value = target[key];
|
|
70
|
-
if (!Proxied.isExists(value)) {
|
|
71
|
-
return undefined;
|
|
72
|
-
}
|
|
73
|
-
else if (Proxied.isConstructor(value) || typeof value !== "function") {
|
|
74
|
-
return value;
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
return value.bind(target);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
static applyOriginal(target, thisArg, argArray) {
|
|
81
|
-
return target.apply(thisArg, argArray);
|
|
82
|
-
}
|
|
83
|
-
static isConstructor(obj) {
|
|
84
|
-
return !!obj.prototype && !!obj.prototype.constructor.name;
|
|
85
|
-
}
|
|
86
|
-
static isExists(obj) {
|
|
87
|
-
return obj !== undefined;
|
|
88
|
-
}
|
|
89
89
|
when(key, value) {
|
|
90
90
|
this.rewrites[key] = value;
|
|
91
91
|
return this;
|
|
@@ -395,7 +395,8 @@ async function initializeFirebaseAdminStubs() {
|
|
|
395
395
|
return Proxied.getOriginal(target, "storage");
|
|
396
396
|
})
|
|
397
397
|
.finalize();
|
|
398
|
-
|
|
398
|
+
const v = require.cache[adminResolution.resolution];
|
|
399
|
+
require.cache[adminResolution.resolution] = Object.assign(v, {
|
|
399
400
|
exports: proxiedAdminModule,
|
|
400
401
|
path: path.dirname(adminResolution.resolution),
|
|
401
402
|
});
|
|
@@ -472,7 +473,8 @@ async function initializeFunctionsConfigHelper() {
|
|
|
472
473
|
return proxiedConfig;
|
|
473
474
|
})
|
|
474
475
|
.finalize();
|
|
475
|
-
|
|
476
|
+
const v = require.cache[functionsResolution.resolution];
|
|
477
|
+
require.cache[functionsResolution.resolution] = Object.assign(v, {
|
|
476
478
|
exports: proxiedFunctionsModule,
|
|
477
479
|
path: path.dirname(functionsResolution.resolution),
|
|
478
480
|
});
|
|
@@ -666,18 +668,12 @@ async function main() {
|
|
|
666
668
|
});
|
|
667
669
|
app.all(`/*`, async (req, res) => {
|
|
668
670
|
try {
|
|
669
|
-
new types_1.EmulatorLog("INFO", "runtime-status", `Beginning execution of "${FUNCTION_TARGET_NAME}"`).log();
|
|
670
671
|
const trigger = FUNCTION_TARGET_NAME.split(".").reduce((mod, functionTargetPart) => {
|
|
671
672
|
return mod === null || mod === void 0 ? void 0 : mod[functionTargetPart];
|
|
672
673
|
}, functionModule);
|
|
673
674
|
if (!trigger) {
|
|
674
675
|
throw new Error(`Failed to find function ${FUNCTION_TARGET_NAME} in the loaded module`);
|
|
675
676
|
}
|
|
676
|
-
const startHrTime = process.hrtime();
|
|
677
|
-
res.on("finish", () => {
|
|
678
|
-
const elapsedHrTime = process.hrtime(startHrTime);
|
|
679
|
-
new types_1.EmulatorLog("INFO", "runtime-status", `Finished "${FUNCTION_TARGET_NAME}" in ${elapsedHrTime[0] * 1000 + elapsedHrTime[1] / 1000000}ms`).log();
|
|
680
|
-
});
|
|
681
677
|
switch (FUNCTION_SIGNATURE) {
|
|
682
678
|
case "event":
|
|
683
679
|
case "cloudevent":
|
|
@@ -699,21 +695,9 @@ async function main() {
|
|
|
699
695
|
res.status(500).send(err.message);
|
|
700
696
|
}
|
|
701
697
|
});
|
|
702
|
-
|
|
698
|
+
app.listen(process.env.PORT, () => {
|
|
703
699
|
logDebug(`Listening to port: ${process.env.PORT}`);
|
|
704
700
|
});
|
|
705
|
-
if (!FUNCTION_DEBUG_MODE) {
|
|
706
|
-
let timeout = process.env.FUNCTIONS_EMULATOR_TIMEOUT_SECONDS || "60";
|
|
707
|
-
if (timeout.endsWith("s")) {
|
|
708
|
-
timeout = timeout.slice(0, -1);
|
|
709
|
-
}
|
|
710
|
-
const timeoutMs = parseInt(timeout, 10) * 1000;
|
|
711
|
-
server.setTimeout(timeoutMs, () => {
|
|
712
|
-
new types_1.EmulatorLog("FATAL", "runtime-error", `Your function timed out after ~${timeout}s. To configure this timeout, see
|
|
713
|
-
https://firebase.google.com/docs/functions/manage-functions#set_timeout_and_memory_allocation.`).log();
|
|
714
|
-
return flushAndExit(1);
|
|
715
|
-
});
|
|
716
|
-
}
|
|
717
701
|
let messageHandlePromise = Promise.resolve();
|
|
718
702
|
process.on("message", (message) => {
|
|
719
703
|
messageHandlePromise = messageHandlePromise
|
|
@@ -15,13 +15,17 @@ var RuntimeWorkerState;
|
|
|
15
15
|
RuntimeWorkerState["FINISHING"] = "FINISHING";
|
|
16
16
|
RuntimeWorkerState["FINISHED"] = "FINISHED";
|
|
17
17
|
})(RuntimeWorkerState = exports.RuntimeWorkerState || (exports.RuntimeWorkerState = {}));
|
|
18
|
+
const FREE_WORKER_KEY = "~free~";
|
|
18
19
|
class RuntimeWorker {
|
|
19
|
-
constructor(
|
|
20
|
+
constructor(triggerId, runtime, extensionLogInfo, timeoutSeconds) {
|
|
21
|
+
this.runtime = runtime;
|
|
22
|
+
this.extensionLogInfo = extensionLogInfo;
|
|
23
|
+
this.timeoutSeconds = timeoutSeconds;
|
|
20
24
|
this.stateEvents = new events_1.EventEmitter();
|
|
21
25
|
this.logListeners = [];
|
|
22
26
|
this._state = RuntimeWorkerState.CREATED;
|
|
23
27
|
this.id = uuid.v4();
|
|
24
|
-
this.
|
|
28
|
+
this.triggerKey = triggerId || FREE_WORKER_KEY;
|
|
25
29
|
this.runtime = runtime;
|
|
26
30
|
const childProc = this.runtime.process;
|
|
27
31
|
let msgBuffer = "";
|
|
@@ -39,8 +43,14 @@ class RuntimeWorker {
|
|
|
39
43
|
stdBuffer = this.processStream(data, stdBuffer);
|
|
40
44
|
});
|
|
41
45
|
}
|
|
46
|
+
this.logger = triggerId
|
|
47
|
+
? emulatorLogger_1.EmulatorLogger.forFunction(triggerId, extensionLogInfo)
|
|
48
|
+
: emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.FUNCTIONS);
|
|
49
|
+
this.onLogs((log) => {
|
|
50
|
+
this.logger.handleRuntimeLog(log);
|
|
51
|
+
}, true);
|
|
42
52
|
childProc.on("exit", () => {
|
|
43
|
-
this.
|
|
53
|
+
this.logDebug("exited");
|
|
44
54
|
this.state = RuntimeWorkerState.FINISHED;
|
|
45
55
|
});
|
|
46
56
|
}
|
|
@@ -75,18 +85,30 @@ class RuntimeWorker {
|
|
|
75
85
|
});
|
|
76
86
|
}
|
|
77
87
|
request(req, resp, body) {
|
|
88
|
+
if (this.triggerKey !== FREE_WORKER_KEY) {
|
|
89
|
+
this.logInfo(`Beginning execution of "${this.triggerKey}"`);
|
|
90
|
+
}
|
|
91
|
+
const startHrTime = process.hrtime();
|
|
78
92
|
this.state = RuntimeWorkerState.BUSY;
|
|
79
93
|
const onFinish = () => {
|
|
94
|
+
if (this.triggerKey !== FREE_WORKER_KEY) {
|
|
95
|
+
const elapsedHrTime = process.hrtime(startHrTime);
|
|
96
|
+
this.logInfo(`Finished "${this.triggerKey}" in ${elapsedHrTime[0] * 1000 + elapsedHrTime[1] / 1000000}ms`);
|
|
97
|
+
}
|
|
80
98
|
if (this.state === RuntimeWorkerState.BUSY) {
|
|
81
99
|
this.state = RuntimeWorkerState.IDLE;
|
|
82
100
|
}
|
|
83
101
|
else if (this.state === RuntimeWorkerState.FINISHING) {
|
|
84
|
-
this.
|
|
102
|
+
this.logDebug(`IDLE --> FINISHING`);
|
|
85
103
|
this.runtime.process.kill();
|
|
86
104
|
}
|
|
87
105
|
};
|
|
88
106
|
return new Promise((resolve) => {
|
|
89
|
-
const
|
|
107
|
+
const reqOpts = Object.assign(Object.assign({}, this.runtime.conn.httpReqOpts()), { method: req.method, path: req.path, headers: req.headers });
|
|
108
|
+
if (this.timeoutSeconds) {
|
|
109
|
+
reqOpts.timeout = this.timeoutSeconds * 1000;
|
|
110
|
+
}
|
|
111
|
+
const proxy = http.request(reqOpts, (_resp) => {
|
|
90
112
|
resp.writeHead(_resp.statusCode || 200, _resp.headers);
|
|
91
113
|
const piped = _resp.pipe(resp);
|
|
92
114
|
piped.on("finish", () => {
|
|
@@ -94,7 +116,13 @@ class RuntimeWorker {
|
|
|
94
116
|
resolve();
|
|
95
117
|
});
|
|
96
118
|
});
|
|
119
|
+
proxy.on("timeout", () => {
|
|
120
|
+
this.logger.log("ERROR", `Your function timed out after ~${this.timeoutSeconds}s. To configure this timeout, see
|
|
121
|
+
https://firebase.google.com/docs/functions/manage-functions#set_timeout_and_memory_allocation.`);
|
|
122
|
+
proxy.destroy();
|
|
123
|
+
});
|
|
97
124
|
proxy.on("error", (err) => {
|
|
125
|
+
this.logger.log("ERROR", `Request to function failed: ${err}`);
|
|
98
126
|
resp.writeHead(500);
|
|
99
127
|
resp.write(JSON.stringify(err));
|
|
100
128
|
resp.end();
|
|
@@ -120,7 +148,7 @@ class RuntimeWorker {
|
|
|
120
148
|
if (state === RuntimeWorkerState.FINISHED) {
|
|
121
149
|
this.runtime.events.removeAllListeners();
|
|
122
150
|
}
|
|
123
|
-
this.
|
|
151
|
+
this.logDebug(state);
|
|
124
152
|
this._state = state;
|
|
125
153
|
this.stateEvents.emit(this._state);
|
|
126
154
|
}
|
|
@@ -163,8 +191,11 @@ class RuntimeWorker {
|
|
|
163
191
|
}
|
|
164
192
|
}
|
|
165
193
|
}
|
|
166
|
-
|
|
167
|
-
|
|
194
|
+
logDebug(msg) {
|
|
195
|
+
this.logger.log("DEBUG", `[worker-${this.triggerKey}-${this.id}]: ${msg}`);
|
|
196
|
+
}
|
|
197
|
+
logInfo(msg) {
|
|
198
|
+
this.logger.logLabeled("BULLET", "functions", msg);
|
|
168
199
|
}
|
|
169
200
|
}
|
|
170
201
|
exports.RuntimeWorker = RuntimeWorker;
|
|
@@ -185,12 +216,12 @@ class RuntimeWorkerPool {
|
|
|
185
216
|
for (const arr of this.workers.values()) {
|
|
186
217
|
arr.forEach((w) => {
|
|
187
218
|
if (w.state === RuntimeWorkerState.IDLE) {
|
|
188
|
-
this.log(`Shutting down IDLE worker (${w.
|
|
219
|
+
this.log(`Shutting down IDLE worker (${w.triggerKey})`);
|
|
189
220
|
w.state = RuntimeWorkerState.FINISHING;
|
|
190
221
|
w.runtime.process.kill();
|
|
191
222
|
}
|
|
192
223
|
else if (w.state === RuntimeWorkerState.BUSY) {
|
|
193
|
-
this.log(`Marking BUSY worker to finish (${w.
|
|
224
|
+
this.log(`Marking BUSY worker to finish (${w.triggerKey})`);
|
|
194
225
|
w.state = RuntimeWorkerState.FINISHING;
|
|
195
226
|
}
|
|
196
227
|
});
|
|
@@ -237,19 +268,14 @@ class RuntimeWorkerPool {
|
|
|
237
268
|
}
|
|
238
269
|
return;
|
|
239
270
|
}
|
|
240
|
-
addWorker(
|
|
241
|
-
|
|
242
|
-
this.
|
|
243
|
-
const
|
|
271
|
+
addWorker(trigger, runtime, extensionLogInfo) {
|
|
272
|
+
this.log(`addWorker(${this.getKey(trigger === null || trigger === void 0 ? void 0 : trigger.id)})`);
|
|
273
|
+
const disableTimeout = !(trigger === null || trigger === void 0 ? void 0 : trigger.id) || this.mode === types_1.FunctionsExecutionMode.SEQUENTIAL;
|
|
274
|
+
const worker = new RuntimeWorker(trigger === null || trigger === void 0 ? void 0 : trigger.id, runtime, extensionLogInfo, disableTimeout ? undefined : trigger === null || trigger === void 0 ? void 0 : trigger.timeoutSeconds);
|
|
275
|
+
const keyWorkers = this.getTriggerWorkers(trigger === null || trigger === void 0 ? void 0 : trigger.id);
|
|
244
276
|
keyWorkers.push(worker);
|
|
245
|
-
this.setTriggerWorkers(
|
|
246
|
-
|
|
247
|
-
? emulatorLogger_1.EmulatorLogger.forFunction(triggerId, extensionLogInfo)
|
|
248
|
-
: emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.FUNCTIONS);
|
|
249
|
-
worker.onLogs((log) => {
|
|
250
|
-
logger.handleRuntimeLog(log);
|
|
251
|
-
}, true);
|
|
252
|
-
this.log(`Adding worker with key ${worker.key}, total=${keyWorkers.length}`);
|
|
277
|
+
this.setTriggerWorkers(trigger === null || trigger === void 0 ? void 0 : trigger.id, keyWorkers);
|
|
278
|
+
this.log(`Adding worker with key ${worker.triggerKey}, total=${keyWorkers.length}`);
|
|
253
279
|
return worker;
|
|
254
280
|
}
|
|
255
281
|
getTriggerWorkers(triggerId) {
|
package/lib/emulator/hub.js
CHANGED
|
@@ -12,12 +12,6 @@ const registry_1 = require("./registry");
|
|
|
12
12
|
const ExpressBasedEmulator_1 = require("./ExpressBasedEmulator");
|
|
13
13
|
const pkg = require("../../package.json");
|
|
14
14
|
class EmulatorHub extends ExpressBasedEmulator_1.ExpressBasedEmulator {
|
|
15
|
-
constructor(args) {
|
|
16
|
-
super({
|
|
17
|
-
listen: args.listen,
|
|
18
|
-
});
|
|
19
|
-
this.args = args;
|
|
20
|
-
}
|
|
21
15
|
static readLocatorFile(projectId) {
|
|
22
16
|
const locatorPath = this.getLocatorFilePath(projectId);
|
|
23
17
|
if (!fs.existsSync(locatorPath)) {
|
|
@@ -36,6 +30,12 @@ class EmulatorHub extends ExpressBasedEmulator_1.ExpressBasedEmulator {
|
|
|
36
30
|
const filename = `hub-${projectId}.json`;
|
|
37
31
|
return path.join(dir, filename);
|
|
38
32
|
}
|
|
33
|
+
constructor(args) {
|
|
34
|
+
super({
|
|
35
|
+
listen: args.listen,
|
|
36
|
+
});
|
|
37
|
+
this.args = args;
|
|
38
|
+
}
|
|
39
39
|
async start() {
|
|
40
40
|
await super.start();
|
|
41
41
|
await this.writeLocatorFile();
|
|
@@ -13,12 +13,6 @@ const child_process_1 = require("child_process");
|
|
|
13
13
|
const PUBSUB_KILL_COMMAND = "pubsub_pids=$(ps aux | grep '[p]ubsub-emulator' | awk '{print $2}');" +
|
|
14
14
|
" if [ ! -z '$pubsub_pids' ]; then kill -9 $pubsub_pids; fi;";
|
|
15
15
|
class PubsubEmulator {
|
|
16
|
-
constructor(args) {
|
|
17
|
-
this.args = args;
|
|
18
|
-
this.logger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.PUBSUB);
|
|
19
|
-
this.triggersForTopic = new Map();
|
|
20
|
-
this.subscriptionForTopic = new Map();
|
|
21
|
-
}
|
|
22
16
|
get pubsub() {
|
|
23
17
|
if (!this._pubsub) {
|
|
24
18
|
this._pubsub = new pubsub_1.PubSub({
|
|
@@ -28,6 +22,12 @@ class PubsubEmulator {
|
|
|
28
22
|
}
|
|
29
23
|
return this._pubsub;
|
|
30
24
|
}
|
|
25
|
+
constructor(args) {
|
|
26
|
+
this.args = args;
|
|
27
|
+
this.logger = emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.PUBSUB);
|
|
28
|
+
this.triggersForTopic = new Map();
|
|
29
|
+
this.subscriptionForTopic = new Map();
|
|
30
|
+
}
|
|
31
31
|
async start() {
|
|
32
32
|
return downloadableEmulators.start(types_1.Emulators.PUBSUB, this.args);
|
|
33
33
|
}
|
|
@@ -132,20 +132,23 @@ class PubsubEmulator {
|
|
|
132
132
|
};
|
|
133
133
|
}
|
|
134
134
|
createCloudEventRequestBody(topic, message) {
|
|
135
|
+
const truncatedPublishTime = new Date(message.publishTime.getMilliseconds()).toISOString();
|
|
135
136
|
const data = {
|
|
136
137
|
message: {
|
|
137
138
|
messageId: message.id,
|
|
138
|
-
publishTime:
|
|
139
|
+
publishTime: truncatedPublishTime,
|
|
139
140
|
attributes: message.attributes,
|
|
140
141
|
orderingKey: message.orderingKey,
|
|
141
142
|
data: message.data.toString("base64"),
|
|
143
|
+
message_id: message.id,
|
|
144
|
+
publish_time: truncatedPublishTime,
|
|
142
145
|
},
|
|
143
146
|
subscription: this.subscriptionForTopic.get(topic).name,
|
|
144
147
|
};
|
|
145
148
|
return {
|
|
146
|
-
specversion: "1",
|
|
149
|
+
specversion: "1.0",
|
|
147
150
|
id: uuid.v4(),
|
|
148
|
-
time:
|
|
151
|
+
time: truncatedPublishTime,
|
|
149
152
|
type: "google.cloud.pubsub.topic.v1.messagePublished",
|
|
150
153
|
source: `//pubsub.googleapis.com/projects/${this.args.projectId}/topics/${topic}`,
|
|
151
154
|
data,
|
|
@@ -15,7 +15,8 @@ function sendFileBytes(md, data, req, res) {
|
|
|
15
15
|
}
|
|
16
16
|
res.setHeader("Accept-Ranges", "bytes");
|
|
17
17
|
res.setHeader("Content-Type", md.contentType || "application/octet-stream");
|
|
18
|
-
|
|
18
|
+
const fileName = md.name.split("/").pop();
|
|
19
|
+
res.setHeader("Content-Disposition", `${md.contentDisposition || "attachment"}; filename=${fileName}`);
|
|
19
20
|
if (didGunzip) {
|
|
20
21
|
res.setHeader("Transfer-Encoding", "chunked");
|
|
21
22
|
}
|
|
@@ -76,7 +76,7 @@ class StorageCloudFunctions {
|
|
|
76
76
|
time = typeof data.updated === "string" ? data.updated : data.updated.toISOString();
|
|
77
77
|
}
|
|
78
78
|
return {
|
|
79
|
-
specversion: "1",
|
|
79
|
+
specversion: "1.0",
|
|
80
80
|
id: uuid.v4(),
|
|
81
81
|
type: `google.cloud.storage.object.v1.${ceAction}`,
|
|
82
82
|
source: `//storage.googleapis.com/projects/_/buckets/${objectMetadataPayload.bucket}/objects/${objectMetadataPayload.name}`,
|
|
@@ -20,15 +20,15 @@ const upload_1 = require("./upload");
|
|
|
20
20
|
const track_1 = require("../../track");
|
|
21
21
|
const types_2 = require("../types");
|
|
22
22
|
class StoredFile {
|
|
23
|
-
constructor(metadata) {
|
|
24
|
-
this.metadata = metadata;
|
|
25
|
-
}
|
|
26
23
|
get metadata() {
|
|
27
24
|
return this._metadata;
|
|
28
25
|
}
|
|
29
26
|
set metadata(value) {
|
|
30
27
|
this._metadata = value;
|
|
31
28
|
}
|
|
29
|
+
constructor(metadata) {
|
|
30
|
+
this.metadata = metadata;
|
|
31
|
+
}
|
|
32
32
|
}
|
|
33
33
|
exports.StoredFile = StoredFile;
|
|
34
34
|
const TRAILING_SLASHES_PATTERN = /\/+$/;
|
|
@@ -305,7 +305,7 @@ class StorageLayer {
|
|
|
305
305
|
return this._persistence.dirPath;
|
|
306
306
|
}
|
|
307
307
|
async export(storageExportPath, options) {
|
|
308
|
-
var e_1,
|
|
308
|
+
var _a, e_1, _b, _c;
|
|
309
309
|
const bucketsList = {
|
|
310
310
|
buckets: [],
|
|
311
311
|
};
|
|
@@ -324,18 +324,25 @@ class StorageLayer {
|
|
|
324
324
|
const metadataDirPath = path.join(storageExportPath, "metadata");
|
|
325
325
|
await fse.ensureDir(metadataDirPath);
|
|
326
326
|
try {
|
|
327
|
-
for (var
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
327
|
+
for (var _d = true, _e = __asyncValues(this._files.entries()), _f; _f = await _e.next(), _a = _f.done, !_a;) {
|
|
328
|
+
_c = _f.value;
|
|
329
|
+
_d = false;
|
|
330
|
+
try {
|
|
331
|
+
const [, file] = _c;
|
|
332
|
+
const diskFileName = this._persistence.getDiskFileName(this.path(file.metadata.bucket, file.metadata.name));
|
|
333
|
+
await fse.copy(path.join(this.dirPath, diskFileName), path.join(blobsDirPath, diskFileName));
|
|
334
|
+
const metadataExportPath = path.join(metadataDirPath, encodeURIComponent(diskFileName)) + ".json";
|
|
335
|
+
await fse.writeFile(metadataExportPath, metadata_1.StoredFileMetadata.toJSON(file.metadata));
|
|
336
|
+
}
|
|
337
|
+
finally {
|
|
338
|
+
_d = true;
|
|
339
|
+
}
|
|
333
340
|
}
|
|
334
341
|
}
|
|
335
342
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
336
343
|
finally {
|
|
337
344
|
try {
|
|
338
|
-
if (
|
|
345
|
+
if (!_d && !_a && (_b = _e.return)) await _b.call(_e);
|
|
339
346
|
}
|
|
340
347
|
finally { if (e_1) throw e_1.error; }
|
|
341
348
|
}
|
package/lib/emulator/types.js
CHANGED
|
@@ -82,15 +82,6 @@ var FunctionsExecutionMode;
|
|
|
82
82
|
FunctionsExecutionMode["SEQUENTIAL"] = "sequential";
|
|
83
83
|
})(FunctionsExecutionMode = exports.FunctionsExecutionMode || (exports.FunctionsExecutionMode = {}));
|
|
84
84
|
class EmulatorLog {
|
|
85
|
-
constructor(level, type, text, data, timestamp) {
|
|
86
|
-
this.level = level;
|
|
87
|
-
this.type = type;
|
|
88
|
-
this.text = text;
|
|
89
|
-
this.data = data;
|
|
90
|
-
this.timestamp = timestamp;
|
|
91
|
-
this.timestamp = this.timestamp || new Date().toISOString();
|
|
92
|
-
this.data = this.data || {};
|
|
93
|
-
}
|
|
94
85
|
get date() {
|
|
95
86
|
if (!this.timestamp) {
|
|
96
87
|
return new Date(0);
|
|
@@ -145,6 +136,15 @@ class EmulatorLog {
|
|
|
145
136
|
}
|
|
146
137
|
return new EmulatorLog(parsedLog.level, parsedLog.type, parsedLog.text, parsedLog.data, parsedLog.timestamp);
|
|
147
138
|
}
|
|
139
|
+
constructor(level, type, text, data, timestamp) {
|
|
140
|
+
this.level = level;
|
|
141
|
+
this.type = type;
|
|
142
|
+
this.text = text;
|
|
143
|
+
this.data = data;
|
|
144
|
+
this.timestamp = timestamp;
|
|
145
|
+
this.timestamp = this.timestamp || new Date().toISOString();
|
|
146
|
+
this.data = this.data || {};
|
|
147
|
+
}
|
|
148
148
|
toString() {
|
|
149
149
|
return this.toStringCore(false);
|
|
150
150
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.promptForPublisherTOS = void 0;
|
|
4
|
-
const
|
|
4
|
+
const marked_1 = require("marked");
|
|
5
5
|
const TerminalRenderer = require("marked-terminal");
|
|
6
6
|
const error_1 = require("../error");
|
|
7
7
|
const extensionsHelper_1 = require("../extensions/extensionsHelper");
|
|
8
8
|
const prompt_1 = require("../prompt");
|
|
9
9
|
const utils = require("../utils");
|
|
10
|
-
marked.setOptions({
|
|
10
|
+
marked_1.marked.setOptions({
|
|
11
11
|
renderer: new TerminalRenderer(),
|
|
12
12
|
});
|
|
13
13
|
async function promptForPublisherTOS() {
|
|
@@ -17,11 +17,11 @@ async function promptForPublisherTOS() {
|
|
|
17
17
|
" - If you become aware or should be aware of a critical security issue in your extension, you will provide either a resolution or a written resolution plan within 48 hours.\n" +
|
|
18
18
|
" - If Google requests a critical security matter to be patched for your extension, you will respond to Google within 48 hours with either a resolution or a written resolution plan.\n" +
|
|
19
19
|
" - Google may remove your extension or terminate the agreement, if you violate any terms.";
|
|
20
|
-
utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(termsOfServiceMsg));
|
|
20
|
+
utils.logLabeledBullet(extensionsHelper_1.logPrefix, (0, marked_1.marked)(termsOfServiceMsg));
|
|
21
21
|
const consented = await (0, prompt_1.promptOnce)({
|
|
22
22
|
name: "consent",
|
|
23
23
|
type: "confirm",
|
|
24
|
-
message: marked("Do you accept the [Firebase Extensions Publisher Terms and Conditions](https://firebase.google.com/docs/extensions/alpha/terms-of-service) and acknowledge that your information will be used in accordance with [Google's Privacy Policy](https://policies.google.com/privacy?hl=en)?"),
|
|
24
|
+
message: (0, marked_1.marked)("Do you accept the [Firebase Extensions Publisher Terms and Conditions](https://firebase.google.com/docs/extensions/alpha/terms-of-service) and acknowledge that your information will be used in accordance with [Google's Privacy Policy](https://policies.google.com/privacy?hl=en)?"),
|
|
25
25
|
default: false,
|
|
26
26
|
});
|
|
27
27
|
if (!consented) {
|
|
@@ -6,7 +6,7 @@ const extensionsApi = require("../extensions/extensionsApi");
|
|
|
6
6
|
const utils = require("../utils");
|
|
7
7
|
const clc = require("colorette");
|
|
8
8
|
const logger_1 = require("../logger");
|
|
9
|
-
const
|
|
9
|
+
const marked_1 = require("marked");
|
|
10
10
|
function checkAllowedEventTypesResponse(response, validEvents) {
|
|
11
11
|
const validEventTypes = validEvents.map((e) => e.type);
|
|
12
12
|
if (response.length === 0) {
|
|
@@ -23,7 +23,7 @@ function checkAllowedEventTypesResponse(response, validEvents) {
|
|
|
23
23
|
exports.checkAllowedEventTypesResponse = checkAllowedEventTypesResponse;
|
|
24
24
|
async function askForEventsConfig(events, projectId, instanceId) {
|
|
25
25
|
var _a, _b;
|
|
26
|
-
logger_1.logger.info(`\n${clc.bold("Enable Events")}: ${marked("If you enable events, you can write custom event handlers ([https://firebase.google.com/docs/extensions/install-extensions#eventarc](https://firebase.google.com/docs/extensions/install-extensions#eventarc)) that respond to these events.\n\nYou can always enable or disable events later. Events will be emitted via Eventarc. Fees apply ([https://cloud.google.com/eventarc/pricing](https://cloud.google.com/eventarc/pricing)).")}`);
|
|
26
|
+
logger_1.logger.info(`\n${clc.bold("Enable Events")}: ${(0, marked_1.marked)("If you enable events, you can write custom event handlers ([https://firebase.google.com/docs/extensions/install-extensions#eventarc](https://firebase.google.com/docs/extensions/install-extensions#eventarc)) that respond to these events.\n\nYou can always enable or disable events later. Events will be emitted via Eventarc. Fees apply ([https://cloud.google.com/eventarc/pricing](https://cloud.google.com/eventarc/pricing)).")}`);
|
|
27
27
|
if (!(await askShouldCollectEventsConfig())) {
|
|
28
28
|
return undefined;
|
|
29
29
|
}
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getInquirerDefault = exports.promptCreateSecret = exports.askForParam = exports.ask = exports.checkResponse = exports.SecretLocation = void 0;
|
|
4
4
|
const _ = require("lodash");
|
|
5
5
|
const clc = require("colorette");
|
|
6
|
-
const
|
|
6
|
+
const marked_1 = require("marked");
|
|
7
7
|
const types_1 = require("./types");
|
|
8
8
|
const secretManagerApi = require("../gcp/secretManager");
|
|
9
9
|
const secretsUtils = require("./secretsUtils");
|
|
@@ -122,7 +122,7 @@ async function askForParam(args) {
|
|
|
122
122
|
let secretLocations = [];
|
|
123
123
|
const description = paramSpec.description || "";
|
|
124
124
|
const label = paramSpec.label.trim();
|
|
125
|
-
logger_1.logger.info(`\n${clc.bold(label)}${clc.bold(paramSpec.required ? "" : " (Optional)")}: ${marked(description).trim()}`);
|
|
125
|
+
logger_1.logger.info(`\n${clc.bold(label)}${clc.bold(paramSpec.required ? "" : " (Optional)")}: ${(0, marked_1.marked)(description).trim()}`);
|
|
126
126
|
while (!valid) {
|
|
127
127
|
switch (paramSpec.type) {
|
|
128
128
|
case types_1.ParamType.SELECT:
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.displayNode10CreateBillingNotice = exports.displayNode10UpdateBillingNotice = void 0;
|
|
4
|
-
const
|
|
4
|
+
const marked_1 = require("marked");
|
|
5
5
|
const TerminalRenderer = require("marked-terminal");
|
|
6
6
|
const error_1 = require("../error");
|
|
7
7
|
const extensionsHelper_1 = require("./extensionsHelper");
|
|
8
8
|
const prompt_1 = require("../prompt");
|
|
9
9
|
const utils = require("../utils");
|
|
10
10
|
const utils_1 = require("./utils");
|
|
11
|
-
marked.setOptions({
|
|
11
|
+
marked_1.marked.setOptions({
|
|
12
12
|
renderer: new TerminalRenderer(),
|
|
13
13
|
});
|
|
14
14
|
const urlPricingExamples = "https://cloud.google.com/functions/pricing#pricing_examples";
|
|
@@ -39,13 +39,13 @@ function hasRuntime(spec, runtime) {
|
|
|
39
39
|
}
|
|
40
40
|
function displayNode10UpdateBillingNotice(curSpec, newSpec) {
|
|
41
41
|
if (hasRuntime(curSpec, "nodejs8") && hasRuntime(newSpec, "nodejs10")) {
|
|
42
|
-
utils.logLabeledWarning(extensionsHelper_1.logPrefix, marked(billingMsgUpdate));
|
|
42
|
+
utils.logLabeledWarning(extensionsHelper_1.logPrefix, (0, marked_1.marked)(billingMsgUpdate));
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
exports.displayNode10UpdateBillingNotice = displayNode10UpdateBillingNotice;
|
|
46
46
|
async function displayNode10CreateBillingNotice(spec, prompt) {
|
|
47
47
|
if (hasRuntime(spec, "nodejs10")) {
|
|
48
|
-
utils.logLabeledWarning(extensionsHelper_1.logPrefix, marked(billingMsgCreate));
|
|
48
|
+
utils.logLabeledWarning(extensionsHelper_1.logPrefix, (0, marked_1.marked)(billingMsgCreate));
|
|
49
49
|
if (prompt) {
|
|
50
50
|
const continueUpdate = await (0, prompt_1.promptOnce)({
|
|
51
51
|
type: "confirm",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseChangelog = exports.getLocalChangelog = exports.breakingChangesInUpdate = exports.displayReleaseNotes = exports.getReleaseNotesForUpdate = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
|
-
const
|
|
5
|
+
const marked_1 = require("marked");
|
|
6
6
|
const path = require("path");
|
|
7
7
|
const semver = require("semver");
|
|
8
8
|
const TerminalRenderer = require("marked-terminal");
|
|
@@ -12,7 +12,7 @@ const localHelper_1 = require("./localHelper");
|
|
|
12
12
|
const logger_1 = require("../logger");
|
|
13
13
|
const refs = require("./refs");
|
|
14
14
|
const utils_1 = require("../utils");
|
|
15
|
-
marked.setOptions({
|
|
15
|
+
marked_1.marked.setOptions({
|
|
16
16
|
renderer: new TerminalRenderer(),
|
|
17
17
|
});
|
|
18
18
|
const EXTENSIONS_CHANGELOG = "CHANGELOG.md";
|
|
@@ -39,10 +39,10 @@ function displayReleaseNotes(releaseNotes, fromVersion) {
|
|
|
39
39
|
const table = new Table({ head: ["Version", "What's New"], style: { head: ["yellow", "bold"] } });
|
|
40
40
|
for (const [version, note] of Object.entries(releaseNotes)) {
|
|
41
41
|
if (breakingVersions.includes(version)) {
|
|
42
|
-
table.push([clc.yellow(clc.bold(version)), marked(note)]);
|
|
42
|
+
table.push([clc.yellow(clc.bold(version)), (0, marked_1.marked)(note)]);
|
|
43
43
|
}
|
|
44
44
|
else {
|
|
45
|
-
table.push([version, marked(note)]);
|
|
45
|
+
table.push([version, (0, marked_1.marked)(note)]);
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
logger_1.logger.info(clc.bold("What's new with this update:"));
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.retrieveRoleInfo = exports.printSourceDownloadLink = exports.displayExtInfo = void 0;
|
|
4
4
|
const clc = require("colorette");
|
|
5
|
-
const
|
|
5
|
+
const marked_1 = require("marked");
|
|
6
6
|
const TerminalRenderer = require("marked-terminal");
|
|
7
7
|
const utils = require("../utils");
|
|
8
8
|
const extensionsHelper_1 = require("./extensionsHelper");
|
|
@@ -11,7 +11,7 @@ const error_1 = require("../error");
|
|
|
11
11
|
const types_1 = require("./types");
|
|
12
12
|
const iam = require("../gcp/iam");
|
|
13
13
|
const secretsUtils_1 = require("./secretsUtils");
|
|
14
|
-
marked.setOptions({
|
|
14
|
+
marked_1.marked.setOptions({
|
|
15
15
|
renderer: new TerminalRenderer(),
|
|
16
16
|
});
|
|
17
17
|
const TASKS_ROLE = "cloudtasks.enqueuer";
|
|
@@ -44,7 +44,7 @@ async function displayExtInfo(extensionName, publisher, spec, published = false)
|
|
|
44
44
|
if (lines.length > 0) {
|
|
45
45
|
utils.logLabeledBullet(extensionsHelper_1.logPrefix, `information about '${clc.bold(extensionName)}':`);
|
|
46
46
|
const infoStr = lines.join("\n");
|
|
47
|
-
const formatted = marked(infoStr).replace(/\n+$/, "\n");
|
|
47
|
+
const formatted = (0, marked_1.marked)(infoStr).replace(/\n+$/, "\n");
|
|
48
48
|
logger_1.logger.info(formatted);
|
|
49
49
|
return lines;
|
|
50
50
|
}
|
|
@@ -60,7 +60,7 @@ async function displayExtInfo(extensionName, publisher, spec, published = false)
|
|
|
60
60
|
exports.displayExtInfo = displayExtInfo;
|
|
61
61
|
function printSourceDownloadLink(sourceDownloadUri) {
|
|
62
62
|
const sourceDownloadMsg = `Want to review the source code that will be installed? Download it here: ${sourceDownloadUri}`;
|
|
63
|
-
utils.logBullet(marked(sourceDownloadMsg));
|
|
63
|
+
utils.logBullet((0, marked_1.marked)(sourceDownloadMsg));
|
|
64
64
|
}
|
|
65
65
|
exports.printSourceDownloadLink = printSourceDownloadLink;
|
|
66
66
|
async function retrieveRoleInfo(role) {
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getExtension = exports.deleteExtension = exports.unpublishExtension = exports.publishExtensionVersion = exports.undeprecateExtensionVersion = exports.deprecateExtensionVersion = exports.registerPublisherProfile = exports.getPublisherProfile = exports.listExtensionVersions = exports.listExtensions = exports.getExtensionVersion = exports.getSource = exports.createSource = exports.updateInstanceFromRegistry = exports.updateInstance = exports.configureInstance = exports.listInstances = exports.getInstance = exports.deleteInstance = exports.createInstance = void 0;
|
|
4
4
|
const yaml = require("js-yaml");
|
|
5
5
|
const clc = require("colorette");
|
|
6
|
-
const
|
|
6
|
+
const marked_1 = require("marked");
|
|
7
7
|
const apiv2_1 = require("../apiv2");
|
|
8
8
|
const api_1 = require("../api");
|
|
9
9
|
const error_1 = require("../error");
|
|
@@ -478,5 +478,5 @@ function refNotFoundError(ref) {
|
|
|
478
478
|
return new error_1.FirebaseError(`The extension reference '${clc.bold(ref.version ? refs.toExtensionVersionRef(ref) : refs.toExtensionRef(ref))}' doesn't exist. This could happen for two reasons:\n` +
|
|
479
479
|
` -The publisher ID '${clc.bold(ref.publisherId)}' doesn't exist or could be misspelled\n` +
|
|
480
480
|
` -The name of the ${ref.version ? "extension version" : "extension"} '${clc.bold(ref.version ? `${ref.extensionId}@${ref.version}` : ref.extensionId)}' doesn't exist or could be misspelled\n\n` +
|
|
481
|
-
`Please correct the extension reference and try again. If you meant to install an extension from a local source, please provide a relative path prefixed with '${clc.bold("./")}', '${clc.bold("../")}', or '${clc.bold("~/")}'. Learn more about local extension installation at ${marked("[https://firebase.google.com/docs/extensions/alpha/install-extensions_community#install](https://firebase.google.com/docs/extensions/alpha/install-extensions_community#install).")}`, { status: 404 });
|
|
481
|
+
`Please correct the extension reference and try again. If you meant to install an extension from a local source, please provide a relative path prefixed with '${clc.bold("./")}', '${clc.bold("../")}', or '${clc.bold("~/")}'. Learn more about local extension installation at ${(0, marked_1.marked)("[https://firebase.google.com/docs/extensions/alpha/install-extensions_community#install](https://firebase.google.com/docs/extensions/alpha/install-extensions_community#install).")}`, { status: 404 });
|
|
482
482
|
}
|