firebase-tools 11.2.0 → 11.3.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.
@@ -104,7 +104,7 @@ class Proxied {
104
104
  return this.proxy;
105
105
  }
106
106
  }
107
- async function resolveDeveloperNodeModule(frb, name) {
107
+ async function resolveDeveloperNodeModule(name) {
108
108
  const pkg = requirePackageJson();
109
109
  if (!pkg) {
110
110
  new types_1.EmulatorLog("SYSTEM", "missing-package-json", "").log();
@@ -130,20 +130,20 @@ async function resolveDeveloperNodeModule(frb, name) {
130
130
  logDebug(`Resolved module ${name}`, moduleResolution);
131
131
  return moduleResolution;
132
132
  }
133
- async function assertResolveDeveloperNodeModule(frb, name) {
134
- const resolution = await resolveDeveloperNodeModule(frb, name);
133
+ async function assertResolveDeveloperNodeModule(name) {
134
+ const resolution = await resolveDeveloperNodeModule(name);
135
135
  if (!(resolution.installed && resolution.declared && resolution.resolution && resolution.version)) {
136
136
  throw new Error(`Assertion failure: could not fully resolve ${name}: ${JSON.stringify(resolution)}`);
137
137
  }
138
138
  return resolution;
139
139
  }
140
- async function verifyDeveloperNodeModules(frb) {
140
+ async function verifyDeveloperNodeModules() {
141
141
  const modBundles = [
142
142
  { name: "firebase-admin", isDev: false, minVersion: "8.9.0" },
143
143
  { name: "firebase-functions", isDev: false, minVersion: "3.13.1" },
144
144
  ];
145
145
  for (const modBundle of modBundles) {
146
- const resolution = await resolveDeveloperNodeModule(frb, modBundle.name);
146
+ const resolution = await resolveDeveloperNodeModule(modBundle.name);
147
147
  if (!resolution.declared) {
148
148
  new types_1.EmulatorLog("SYSTEM", "missing-module", "", modBundle).log();
149
149
  return false;
@@ -240,8 +240,8 @@ function initializeNetworkFiltering() {
240
240
  });
241
241
  logDebug("Outgoing network have been stubbed.", results);
242
242
  }
243
- async function initializeFirebaseFunctionsStubs(frb) {
244
- const firebaseFunctionsResolution = await assertResolveDeveloperNodeModule(frb, "firebase-functions");
243
+ async function initializeFirebaseFunctionsStubs() {
244
+ const firebaseFunctionsResolution = await assertResolveDeveloperNodeModule("firebase-functions");
245
245
  const firebaseFunctionsRoot = (0, functionsEmulatorShared_1.findModuleRoot)("firebase-functions", firebaseFunctionsResolution.resolution);
246
246
  const httpsProviderResolution = path.join(firebaseFunctionsRoot, "lib/providers/https");
247
247
  const httpsProviderV1Resolution = path.join(firebaseFunctionsRoot, "lib/v1/providers/https");
@@ -343,10 +343,10 @@ function initializeRuntimeConfig() {
343
343
  }
344
344
  }
345
345
  }
346
- async function initializeFirebaseAdminStubs(frb) {
347
- const adminResolution = await assertResolveDeveloperNodeModule(frb, "firebase-admin");
346
+ async function initializeFirebaseAdminStubs() {
347
+ const adminResolution = await assertResolveDeveloperNodeModule("firebase-admin");
348
348
  const localAdminModule = require(adminResolution.resolution);
349
- const functionsResolution = await assertResolveDeveloperNodeModule(frb, "firebase-functions");
349
+ const functionsResolution = await assertResolveDeveloperNodeModule("firebase-functions");
350
350
  const localFunctionsModule = require(functionsResolution.resolution);
351
351
  const defaultConfig = getDefaultConfig();
352
352
  const adminModuleProxy = new Proxied(localAdminModule);
@@ -360,7 +360,7 @@ async function initializeFirebaseAdminStubs(frb) {
360
360
  new types_1.EmulatorLog("SYSTEM", "default-admin-app-used", `config=${defaultAppOptions}`, {
361
361
  opts: defaultAppOptions,
362
362
  }).log();
363
- const defaultApp = makeProxiedFirebaseApp(frb, adminModuleTarget.initializeApp(defaultAppOptions));
363
+ const defaultApp = makeProxiedFirebaseApp(adminModuleTarget.initializeApp(defaultAppOptions));
364
364
  logDebug("initializeApp(DEFAULT)", defaultAppOptions);
365
365
  localFunctionsModule.app.setEmulatedAdminApp(defaultApp);
366
366
  if (process.env[constants_1.Constants.FIREBASE_AUTH_EMULATOR_HOST]) {
@@ -405,7 +405,7 @@ async function initializeFirebaseAdminStubs(frb) {
405
405
  adminResolution,
406
406
  });
407
407
  }
408
- function makeProxiedFirebaseApp(frb, original) {
408
+ function makeProxiedFirebaseApp(original) {
409
409
  const appProxy = new Proxied(original);
410
410
  return appProxy
411
411
  .when("firestore", (target) => {
@@ -450,8 +450,8 @@ function warnAboutStorageProd() {
450
450
  }
451
451
  new types_1.EmulatorLog("WARN_ONCE", "runtime-status", "The Firebase Storage emulator is not running, so calls to Firebase Storage will affect production.").log();
452
452
  }
453
- async function initializeFunctionsConfigHelper(frb) {
454
- const functionsResolution = await assertResolveDeveloperNodeModule(frb, "firebase-functions");
453
+ async function initializeFunctionsConfigHelper() {
454
+ const functionsResolution = await assertResolveDeveloperNodeModule("firebase-functions");
455
455
  const localFunctionsModule = require(functionsResolution.resolution);
456
456
  logDebug("Checked functions.config()", {
457
457
  config: localFunctionsModule.config(),
@@ -485,34 +485,9 @@ async function initializeFunctionsConfigHelper(frb) {
485
485
  function rawBodySaver(req, res, buf) {
486
486
  req.rawBody = buf;
487
487
  }
488
- async function processHTTPS(trigger, frb) {
488
+ async function processHTTPS(trigger) {
489
489
  const ephemeralServer = express();
490
- const functionRouter = express.Router();
491
- const socketPath = frb.socketPath;
492
- if (!socketPath) {
493
- new types_1.EmulatorLog("FATAL", "runtime-error", "Called processHTTPS with no socketPath").log();
494
- return;
495
- }
496
490
  await new Promise((resolveEphemeralServer, rejectEphemeralServer) => {
497
- const handler = async (req, res) => {
498
- try {
499
- logDebug(`Ephemeral server handling ${req.method} request`);
500
- res.on("finish", () => {
501
- instance.close((err) => {
502
- if (err) {
503
- rejectEphemeralServer(err);
504
- }
505
- else {
506
- resolveEphemeralServer();
507
- }
508
- });
509
- });
510
- await runHTTPS(trigger, [req, res]);
511
- }
512
- catch (err) {
513
- rejectEphemeralServer(err);
514
- }
515
- };
516
491
  ephemeralServer.enable("trust proxy");
517
492
  ephemeralServer.use(bodyParser.json({
518
493
  limit: "10mb",
@@ -532,13 +507,39 @@ async function processHTTPS(trigger, frb) {
532
507
  limit: "10mb",
533
508
  verify: rawBodySaver,
534
509
  }));
535
- functionRouter.all("*", handler);
536
- ephemeralServer.use([`/`, `/*`], functionRouter);
537
- logDebug(`Attempting to listen to socketPath: ${socketPath}`);
538
- const instance = ephemeralServer.listen(socketPath, () => {
539
- new types_1.EmulatorLog("SYSTEM", "runtime-status", "ready", { state: "ready" }).log();
510
+ let server;
511
+ function closeServer() {
512
+ if (server) {
513
+ server.close((err) => {
514
+ if (err) {
515
+ rejectEphemeralServer(err);
516
+ }
517
+ else {
518
+ resolveEphemeralServer();
519
+ }
520
+ });
521
+ }
522
+ }
523
+ ephemeralServer.get("/__/health", (req, res) => {
524
+ res.status(200).send();
525
+ });
526
+ ephemeralServer.all("/favicon.ico|/robots.txt", (req, res) => {
527
+ res.on("finish", closeServer);
528
+ res.status(404).send();
529
+ });
530
+ ephemeralServer.all(`/*`, async (req, res) => {
531
+ try {
532
+ logDebug(`Ephemeral server handling ${req.method} request`);
533
+ res.on("finish", closeServer);
534
+ await runHTTPS(trigger, [req, res]);
535
+ }
536
+ catch (err) {
537
+ rejectEphemeralServer(err);
538
+ }
540
539
  });
541
- instance.on("error", rejectEphemeralServer);
540
+ logDebug(`Attempting to listen to port: ${process.env.PORT}`);
541
+ server = ephemeralServer.listen(process.env.PORT);
542
+ server.on("error", rejectEphemeralServer);
542
543
  });
543
544
  }
544
545
  async function processBackground(trigger, frb, signature) {
@@ -591,7 +592,7 @@ async function runHTTPS(trigger, args) {
591
592
  return trigger(args[0], args[1]);
592
593
  });
593
594
  }
594
- async function moduleResolutionDetective(frb, error) {
595
+ async function moduleResolutionDetective(error) {
595
596
  const clues = {
596
597
  tsconfigJSON: await requireAsync("./tsconfig.json", { paths: [process.cwd()] }).catch(noOp),
597
598
  packageJSON: await requireAsync("./package.json", { paths: [process.cwd()] }).catch(noOp),
@@ -640,7 +641,7 @@ async function invokeTrigger(trigger, frb) {
640
641
  await processBackground(trigger, frb, FUNCTION_SIGNATURE);
641
642
  break;
642
643
  case "http":
643
- await processHTTPS(trigger, frb);
644
+ await processHTTPS(trigger);
644
645
  break;
645
646
  }
646
647
  if (timeoutId) {
@@ -649,7 +650,7 @@ async function invokeTrigger(trigger, frb) {
649
650
  clearInterval(timerId);
650
651
  new types_1.EmulatorLog("INFO", "runtime-status", `Finished "${FUNCTION_TARGET_NAME}" in ~${Math.max(seconds, 1)}s`).log();
651
652
  }
652
- async function initializeRuntime(frb) {
653
+ async function initializeRuntime() {
653
654
  FUNCTION_DEBUG_MODE = process.env.FUNCTION_DEBUG_MODE || "";
654
655
  if (!FUNCTION_DEBUG_MODE) {
655
656
  FUNCTION_TARGET_NAME = process.env.FUNCTION_TARGET || "";
@@ -663,19 +664,18 @@ async function initializeRuntime(frb) {
663
664
  await flushAndExit(1);
664
665
  }
665
666
  }
666
- logDebug(`Disabled runtime features: ${JSON.stringify(frb.disabled_features)}`);
667
- const verified = await verifyDeveloperNodeModules(frb);
667
+ const verified = await verifyDeveloperNodeModules();
668
668
  if (!verified) {
669
669
  new types_1.EmulatorLog("INFO", "runtime-status", `Your functions could not be parsed due to an issue with your node_modules (see above)`).log();
670
670
  return;
671
671
  }
672
672
  initializeRuntimeConfig();
673
673
  initializeNetworkFiltering();
674
- await initializeFunctionsConfigHelper(frb);
675
- await initializeFirebaseFunctionsStubs(frb);
676
- await initializeFirebaseAdminStubs(frb);
674
+ await initializeFunctionsConfigHelper();
675
+ await initializeFirebaseFunctionsStubs();
676
+ await initializeFirebaseAdminStubs();
677
677
  }
678
- async function loadTriggers(frb, serializedFunctionTrigger) {
678
+ async function loadTriggers(serializedFunctionTrigger) {
679
679
  let triggerModule;
680
680
  if (serializedFunctionTrigger) {
681
681
  triggerModule = eval(serializedFunctionTrigger)();
@@ -686,7 +686,7 @@ async function loadTriggers(frb, serializedFunctionTrigger) {
686
686
  }
687
687
  catch (err) {
688
688
  if (err.code !== "ERR_REQUIRE_ESM") {
689
- await moduleResolutionDetective(frb, err);
689
+ await moduleResolutionDetective(err);
690
690
  throw err;
691
691
  }
692
692
  const modulePath = require.resolve(process.cwd());
@@ -716,9 +716,8 @@ async function handleMessage(message) {
716
716
  }
717
717
  if (!functionModule) {
718
718
  try {
719
- await initializeRuntime(runtimeArgs.frb);
720
719
  const serializedTriggers = runtimeArgs.opts ? runtimeArgs.opts.serializedTriggers : undefined;
721
- functionModule = await loadTriggers(runtimeArgs.frb, serializedTriggers);
720
+ functionModule = await loadTriggers(serializedTriggers);
722
721
  }
723
722
  catch (e) {
724
723
  logDebug(e);
@@ -752,7 +751,7 @@ async function handleMessage(message) {
752
751
  await flushAndExit(1);
753
752
  }
754
753
  }
755
- function main() {
754
+ async function main() {
756
755
  let lastSignal = new Date().getTime();
757
756
  let signalCount = 0;
758
757
  process.on("SIGINT", () => {
@@ -766,10 +765,7 @@ function main() {
766
765
  process.exit(1);
767
766
  }
768
767
  });
769
- logDebug("Functions runtime initialized.", {
770
- cwd: process.cwd(),
771
- node_version: process.versions.node,
772
- });
768
+ await initializeRuntime();
773
769
  let messageHandlePromise = Promise.resolve();
774
770
  process.on("message", (message) => {
775
771
  messageHandlePromise = messageHandlePromise
@@ -784,5 +780,15 @@ function main() {
784
780
  });
785
781
  }
786
782
  if (require.main === module) {
787
- main();
783
+ main()
784
+ .then(() => {
785
+ logDebug("Functions runtime initialized.", {
786
+ cwd: process.cwd(),
787
+ node_version: process.versions.node,
788
+ });
789
+ })
790
+ .catch((err) => {
791
+ new types_1.EmulatorLog("FATAL", "runtime-error", err.message || err, err).log();
792
+ return flushAndExit(1);
793
+ });
788
794
  }
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.toBackendInfo = exports.getSecretLocalPath = exports.getSignatureType = exports.formatHost = exports.findModuleRoot = exports.waitForBody = exports.getServiceFromEventType = exports.getFunctionService = exports.getTemporarySocketPath = exports.getEmulatedTriggersFromDefinitions = exports.emulatedFunctionsByRegion = exports.emulatedFunctionsFromEndpoints = exports.prepareEndpoints = exports.EmulatedTrigger = exports.HttpConstants = void 0;
4
- const _ = require("lodash");
5
4
  const os = require("os");
6
5
  const path = require("path");
7
6
  const fs = require("fs");
7
+ const crypto_1 = require("crypto");
8
+ const _ = require("lodash");
8
9
  const backend = require("../deploy/functions/backend");
9
10
  const constants_1 = require("./constants");
10
11
  const proto_1 = require("../gcp/proto");
@@ -142,12 +143,13 @@ function getEmulatedTriggersFromDefinitions(definitions, module) {
142
143
  }, {});
143
144
  }
144
145
  exports.getEmulatedTriggersFromDefinitions = getEmulatedTriggersFromDefinitions;
145
- function getTemporarySocketPath(pid, cwd) {
146
+ function getTemporarySocketPath() {
147
+ const rand = (0, crypto_1.randomBytes)(8).toString("hex");
146
148
  if (process.platform === "win32") {
147
- return path.join("\\\\?\\pipe", cwd, pid.toString());
149
+ return path.join("\\\\?\\pipe", `fire_emu_${rand}`);
148
150
  }
149
151
  else {
150
- return path.join(os.tmpdir(), `fire_emu_${pid.toString()}.sock`);
152
+ return path.join(os.tmpdir(), `fire_emu_${rand}.sock`);
151
153
  }
152
154
  }
153
155
  exports.getTemporarySocketPath = getTemporarySocketPath;
@@ -239,7 +241,7 @@ function formatHost(info) {
239
241
  }
240
242
  exports.formatHost = formatHost;
241
243
  function getSignatureType(def) {
242
- if (def.httpsTrigger) {
244
+ if (def.httpsTrigger || def.blockingTrigger) {
243
245
  return "http";
244
246
  }
245
247
  return def.platform === "gcfv2" ? "cloudevent" : "event";
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RuntimeWorkerPool = exports.RuntimeWorker = exports.RuntimeWorkerState = void 0;
4
+ const http = require("http");
4
5
  const uuid = require("uuid");
5
6
  const types_1 = require("./types");
6
- const functionsEmulatorShared_1 = require("./functionsEmulatorShared");
7
7
  const events_1 = require("events");
8
8
  const emulatorLogger_1 = require("./emulatorLogger");
9
9
  const error_1 = require("../error");
@@ -42,30 +42,19 @@ class RuntimeWorker {
42
42
  }
43
43
  execute(frb, opts) {
44
44
  const execFrb = Object.assign({}, frb);
45
- if (!execFrb.socketPath) {
46
- execFrb.socketPath = (0, functionsEmulatorShared_1.getTemporarySocketPath)(this.runtime.pid, this.runtime.cwd);
47
- this.log(`Assigning socketPath: ${execFrb.socketPath}`);
48
- }
49
45
  const args = { frb: execFrb, opts };
50
46
  this.state = RuntimeWorkerState.BUSY;
51
- this.lastArgs = args;
52
47
  this.runtime.send(args);
53
48
  }
54
49
  get state() {
55
50
  return this._state;
56
51
  }
57
52
  set state(state) {
58
- if (state === RuntimeWorkerState.BUSY) {
59
- this.socketReady = types_1.EmulatorLog.waitForLog(this.runtime.events, "SYSTEM", "runtime-status", (el) => {
60
- return el.data.state === "ready";
61
- });
62
- }
63
53
  if (state === RuntimeWorkerState.IDLE) {
64
54
  for (const l of this.logListeners) {
65
55
  this.runtime.events.removeListener("log", l);
66
56
  }
67
57
  this.logListeners = [];
68
- this.socketReady = undefined;
69
58
  }
70
59
  if (state === RuntimeWorkerState.FINISHED) {
71
60
  this.runtime.events.removeAllListeners();
@@ -94,9 +83,40 @@ class RuntimeWorker {
94
83
  this.stateEvents.once(RuntimeWorkerState.FINISHED, listener);
95
84
  });
96
85
  }
97
- waitForSocketReady() {
98
- return (this.socketReady ||
99
- Promise.reject(new Error("Cannot call waitForSocketReady() if runtime is not BUSY")));
86
+ isSocketReady() {
87
+ return new Promise((resolve, reject) => {
88
+ const req = http
89
+ .request({
90
+ method: "GET",
91
+ path: "/__/health",
92
+ socketPath: this.runtime.socketPath,
93
+ }, () => resolve())
94
+ .end();
95
+ req.on("error", (error) => {
96
+ reject(error);
97
+ });
98
+ });
99
+ }
100
+ async waitForSocketReady() {
101
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
102
+ const timeout = new Promise((resolve, reject) => {
103
+ setTimeout(() => {
104
+ reject(new error_1.FirebaseError("Failed to load function."));
105
+ }, 7000);
106
+ });
107
+ while (true) {
108
+ try {
109
+ await Promise.race([this.isSocketReady(), timeout]);
110
+ break;
111
+ }
112
+ catch (err) {
113
+ if (["ECONNREFUSED", "ENOENT"].includes(err === null || err === void 0 ? void 0 : err.code)) {
114
+ await sleep(100);
115
+ continue;
116
+ }
117
+ throw err;
118
+ }
119
+ }
100
120
  }
101
121
  log(msg) {
102
122
  emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.FUNCTIONS).log("DEBUG", `[worker-${this.key}-${this.id}]: ${msg}`);
@@ -324,7 +324,7 @@ function sendFileBytes(md, data, req, res) {
324
324
  res.setHeader("Accept-Ranges", "bytes");
325
325
  res.setHeader("Content-Type", md.contentType);
326
326
  res.setHeader("Content-Disposition", md.contentDisposition);
327
- res.setHeader("Content-Encoding", md.contentEncoding);
327
+ res.setHeader("Content-Encoding", isGZipped ? "identity" : md.contentEncoding);
328
328
  res.setHeader("ETag", md.etag);
329
329
  res.setHeader("Cache-Control", md.cacheControl);
330
330
  res.setHeader("x-goog-generation", `${md.generation}`);
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.detectEtagChanges = exports.saveEtags = void 0;
4
+ function saveEtags(rc, projectId, instances) {
5
+ rc.setEtags(projectId, "extensionInstances", etagsMap(instances));
6
+ }
7
+ exports.saveEtags = saveEtags;
8
+ function detectEtagChanges(rc, projectId, instances) {
9
+ const lastDeployedEtags = rc.getEtags(projectId).extensionInstances;
10
+ const currentEtags = etagsMap(instances);
11
+ if (!lastDeployedEtags || !Object.keys(lastDeployedEtags).length) {
12
+ return [];
13
+ }
14
+ const changedExtensionInstances = Object.entries(lastDeployedEtags)
15
+ .filter(([instanceName, etag]) => etag !== currentEtags[instanceName])
16
+ .map((i) => i[0]);
17
+ const newExtensionInstances = Object.keys(currentEtags).filter((instanceName) => !lastDeployedEtags[instanceName]);
18
+ return newExtensionInstances.concat(changedExtensionInstances);
19
+ }
20
+ exports.detectEtagChanges = detectEtagChanges;
21
+ function etagsMap(instances) {
22
+ return instances.reduce((acc, i) => {
23
+ if (i.etag) {
24
+ acc[i.instanceId] = i.etag;
25
+ }
26
+ return acc;
27
+ }, {});
28
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.paramsFlagDeprecationWarning = exports.displayWarningsForDeploy = exports.displayWarningPrompts = void 0;
3
+ exports.outOfBandChangesWarning = exports.paramsFlagDeprecationWarning = exports.displayWarningsForDeploy = exports.displayWarningPrompts = void 0;
4
4
  const { marked } = require("marked");
5
5
  const clc = require("cli-color");
6
6
  const types_1 = require("./types");
@@ -75,3 +75,9 @@ function paramsFlagDeprecationWarning() {
75
75
  "See https://firebase.google.com/docs/extensions/manifest for more details");
76
76
  }
77
77
  exports.paramsFlagDeprecationWarning = paramsFlagDeprecationWarning;
78
+ function outOfBandChangesWarning(instanceIds) {
79
+ logger_1.logger.warn("The following instances may have been changed in the Firebase console or by another machine since the last deploy from this machine.\n\t" +
80
+ clc.bold(instanceIds.join("\n\t")) +
81
+ "\nIf you proceed with this deployment, those changes will be overwritten. To avoid this, run `firebase ext:export` to sync these changes to your local extensions manifest.");
82
+ }
83
+ exports.outOfBandChangesWarning = outOfBandChangesWarning;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.loadFirebaseEnvs = exports.loadUserEnvs = exports.hasUserEnvs = exports.parseStrict = exports.validateKey = exports.KeyValidationError = exports.parse = void 0;
3
+ exports.loadFirebaseEnvs = exports.loadUserEnvs = exports.writeUserEnvs = exports.hasUserEnvs = exports.parseStrict = exports.validateKey = exports.KeyValidationError = exports.parse = void 0;
4
4
  const clc = require("cli-color");
5
5
  const fs = require("fs");
6
6
  const path = require("path");
@@ -145,6 +145,10 @@ function hasUserEnvs({ functionsSource, projectId, projectAlias, isEmulator, })
145
145
  return findEnvfiles(functionsSource, projectId, projectAlias, isEmulator).length > 0;
146
146
  }
147
147
  exports.hasUserEnvs = hasUserEnvs;
148
+ function writeUserEnvs(toWrite, envOpts) {
149
+ throw new error_1.FirebaseError("Persisting user-defined parameters to .env files is not yet implemented.");
150
+ }
151
+ exports.writeUserEnvs = writeUserEnvs;
148
152
  function loadUserEnvs({ functionsSource, projectId, projectAlias, isEmulator, }) {
149
153
  var _a;
150
154
  const envFiles = findEnvfiles(functionsSource, projectId, projectAlias, isEmulator);
@@ -70,7 +70,7 @@ async function setVariablesRecursive(projectId, configId, varPath, val) {
70
70
  catch (e) {
71
71
  }
72
72
  }
73
- if (_.isPlainObject(parsed)) {
73
+ if (typeof parsed === "object" && parsed !== null) {
74
74
  return Promise.all(Object.entries(parsed).map(([key, item]) => {
75
75
  const newVarPath = varPath ? [varPath, key].join("/") : key;
76
76
  return setVariablesRecursive(projectId, configId, newVarPath, item);
package/lib/gcp/rules.js CHANGED
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.testRuleset = exports.updateOrCreateRelease = exports.updateRelease = exports.createRelease = exports.createRuleset = exports.deleteRuleset = exports.getRulesetId = exports.listAllRulesets = exports.listRulesets = exports.getRulesetContent = exports.listAllReleases = exports.listReleases = exports.getLatestRulesetName = void 0;
4
- const _ = require("lodash");
5
4
  const api_1 = require("../api");
6
5
  const apiv2_1 = require("../apiv2");
7
6
  const logger_1 = require("../logger");
@@ -51,7 +50,7 @@ async function listAllReleases(projectId) {
51
50
  }
52
51
  pageToken = response.nextPageToken;
53
52
  } while (pageToken);
54
- return _.orderBy(releases, ["createTime"], ["desc"]);
53
+ return releases.sort((a, b) => b.createTime.localeCompare(a.createTime));
55
54
  }
56
55
  exports.listAllReleases = listAllReleases;
57
56
  async function getRulesetContent(name) {
@@ -90,7 +89,7 @@ async function listAllRulesets(projectId) {
90
89
  }
91
90
  pageToken = response.nextPageToken;
92
91
  } while (pageToken);
93
- return _.orderBy(rulesets, ["createTime"], ["desc"]);
92
+ return rulesets.sort((a, b) => b.createTime.localeCompare(a.createTime));
94
93
  }
95
94
  exports.listAllRulesets = listAllRulesets;
96
95
  function getRulesetId(ruleset) {
@@ -48,7 +48,7 @@ function listVariables(configPath) {
48
48
  retryCodes: [500, 503],
49
49
  })
50
50
  .then((resp) => {
51
- return Promise.resolve(resp.body.variables);
51
+ return Promise.resolve(resp.body.variables || []);
52
52
  });
53
53
  }
54
54
  function getVariable(varPath) {
@@ -43,7 +43,7 @@ async function getChannel(project = "-", site, channelId) {
43
43
  return res.body;
44
44
  }
45
45
  catch (e) {
46
- if (e.status === 404) {
46
+ if (e instanceof error_1.FirebaseError && e.status === 404) {
47
47
  return null;
48
48
  }
49
49
  throw e;
@@ -51,23 +51,22 @@ async function getChannel(project = "-", site, channelId) {
51
51
  }
52
52
  exports.getChannel = getChannel;
53
53
  async function listChannels(project = "-", site) {
54
- var _a, _b;
55
54
  const channels = [];
56
55
  let nextPageToken = "";
57
56
  for (;;) {
58
57
  try {
59
58
  const res = await apiClient.get(`/projects/${project}/sites/${site}/channels`, { queryParams: { pageToken: nextPageToken, pageSize: 10 } });
60
- const c = (_a = res.body) === null || _a === void 0 ? void 0 : _a.channels;
59
+ const c = res.body.channels;
61
60
  if (c) {
62
61
  channels.push(...c);
63
62
  }
64
- nextPageToken = ((_b = res.body) === null || _b === void 0 ? void 0 : _b.nextPageToken) || "";
63
+ nextPageToken = res.body.nextPageToken || "";
65
64
  if (!nextPageToken) {
66
65
  return channels;
67
66
  }
68
67
  }
69
68
  catch (e) {
70
- if (e.status === 404) {
69
+ if (e instanceof error_1.FirebaseError && e.status === 404) {
71
70
  throw new error_1.FirebaseError(`could not find channels for site "${site}"`, {
72
71
  original: e,
73
72
  });
@@ -116,23 +115,22 @@ async function createRelease(site, channel, version) {
116
115
  }
117
116
  exports.createRelease = createRelease;
118
117
  async function listSites(project) {
119
- var _a, _b;
120
118
  const sites = [];
121
119
  let nextPageToken = "";
122
120
  for (;;) {
123
121
  try {
124
122
  const res = await apiClient.get(`/projects/${project}/sites`, { queryParams: { pageToken: nextPageToken, pageSize: 10 } });
125
- const c = (_a = res.body) === null || _a === void 0 ? void 0 : _a.sites;
123
+ const c = res.body.sites;
126
124
  if (c) {
127
125
  sites.push(...c);
128
126
  }
129
- nextPageToken = ((_b = res.body) === null || _b === void 0 ? void 0 : _b.nextPageToken) || "";
127
+ nextPageToken = res.body.nextPageToken || "";
130
128
  if (!nextPageToken) {
131
129
  return sites;
132
130
  }
133
131
  }
134
132
  catch (e) {
135
- if (e.status === 404) {
133
+ if (e instanceof error_1.FirebaseError && e.status === 404) {
136
134
  throw new error_1.FirebaseError(`could not find sites for project "${project}"`, {
137
135
  original: e,
138
136
  });
@@ -148,7 +146,7 @@ async function getSite(project, site) {
148
146
  return res.body;
149
147
  }
150
148
  catch (e) {
151
- if (e.status === 404) {
149
+ if (e instanceof error_1.FirebaseError && e.status === 404) {
152
150
  throw new error_1.FirebaseError(`could not find site "${site}" for project "${project}"`, {
153
151
  original: e,
154
152
  });
@@ -158,7 +156,7 @@ async function getSite(project, site) {
158
156
  }
159
157
  exports.getSite = getSite;
160
158
  async function createSite(project, site, appId = "") {
161
- const res = await apiClient.post(`/projects/${project}/sites`, { appId: appId }, { queryParams: { site_id: site } });
159
+ const res = await apiClient.post(`/projects/${project}/sites`, { appId: appId }, { queryParams: { siteId: site } });
162
160
  return res.body;
163
161
  }
164
162
  exports.createSite = createSite;
@@ -16,8 +16,8 @@ const DURATIONS = {
16
16
  };
17
17
  exports.MAX_DURATION = 30 * Duration.DAY;
18
18
  exports.DEFAULT_DURATION = 7 * Duration.DAY;
19
- function calculateChannelExpireTTL(flag) {
20
- const match = exports.DURATION_REGEX.exec(flag || "");
19
+ function calculateChannelExpireTTL(flag = "") {
20
+ const match = exports.DURATION_REGEX.exec(flag);
21
21
  if (!match) {
22
22
  throw new error_1.FirebaseError(`"expires" flag must be a duration string (e.g. 24h or 7d) at most 30d`);
23
23
  }
@@ -1,7 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getFirebaseProject = exports.listFirebaseProjects = exports.getAvailableCloudProjectPage = exports.getFirebaseProjectPage = exports.addFirebaseToCloudProject = exports.createCloudProject = exports.promptAvailableProjectId = exports.getOrPromptProject = exports.addFirebaseToCloudProjectAndLog = exports.createFirebaseProjectAndLog = exports.PROJECTS_CREATE_QUESTIONS = exports.ProjectParentResourceType = void 0;
4
- const _ = require("lodash");
5
4
  const clc = require("cli-color");
6
5
  const ora = require("ora");
7
6
  const apiv2_1 = require("../apiv2");
@@ -110,15 +109,15 @@ async function selectProjectByPrompting() {
110
109
  return await getFirebaseProject(projectId);
111
110
  }
112
111
  async function selectProjectFromList(projects = []) {
113
- let choices = projects
112
+ const choices = projects
114
113
  .filter((p) => !!p)
115
114
  .map((p) => {
116
115
  return {
117
116
  name: p.projectId + (p.displayName ? ` (${p.displayName})` : ""),
118
117
  value: p.projectId,
119
118
  };
120
- });
121
- choices = _.orderBy(choices, ["name"], ["asc"]);
119
+ })
120
+ .sort((a, b) => a.name.localeCompare(b.name));
122
121
  if (choices.length >= 25) {
123
122
  utils.logBullet(`Don't want to scroll through all your projects? If you know your project ID, ` +
124
123
  `you can initialize it directly using ${clc.bold("firebase init --project <project_id>")}.\n`);
@@ -151,7 +150,7 @@ async function promptAvailableProjectId() {
151
150
  });
152
151
  }
153
152
  else {
154
- let choices = projects
153
+ const choices = projects
155
154
  .filter((p) => !!p)
156
155
  .map((p) => {
157
156
  const projectId = getProjectId(p);
@@ -159,8 +158,8 @@ async function promptAvailableProjectId() {
159
158
  name: projectId + (p.displayName ? ` (${p.displayName})` : ""),
160
159
  value: projectId,
161
160
  };
162
- });
163
- choices = _.orderBy(choices, ["name"], ["asc"]);
161
+ })
162
+ .sort((a, b) => a.name.localeCompare(b.name));
164
163
  return await (0, prompt_1.promptOnce)({
165
164
  type: "list",
166
165
  name: "id",