firebase-tools 11.4.2 → 11.5.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 (173) hide show
  1. package/lib/accountImporter.js +1 -1
  2. package/lib/auth.js +3 -4
  3. package/lib/bin/firebase.js +4 -4
  4. package/lib/command.js +2 -3
  5. package/lib/commands/apps-android-sha-create.js +1 -1
  6. package/lib/commands/apps-android-sha-delete.js +1 -1
  7. package/lib/commands/apps-create.js +1 -1
  8. package/lib/commands/apps-list.js +1 -1
  9. package/lib/commands/auth-export.js +1 -1
  10. package/lib/commands/auth-import.js +1 -1
  11. package/lib/commands/database-instances-list.js +1 -1
  12. package/lib/commands/database-push.js +1 -1
  13. package/lib/commands/database-remove.js +1 -1
  14. package/lib/commands/database-set.js +1 -1
  15. package/lib/commands/database-update.js +1 -1
  16. package/lib/commands/emulators-start.js +1 -1
  17. package/lib/commands/ext-dev-deprecate.js +1 -1
  18. package/lib/commands/ext-dev-emulators-exec.js +1 -1
  19. package/lib/commands/ext-dev-emulators-start.js +1 -1
  20. package/lib/commands/ext-dev-extension-delete.js +1 -1
  21. package/lib/commands/ext-dev-list.js +1 -1
  22. package/lib/commands/ext-dev-publish.js +1 -1
  23. package/lib/commands/ext-dev-register.js +1 -1
  24. package/lib/commands/ext-dev-undeprecate.js +1 -1
  25. package/lib/commands/ext-dev-unpublish.js +1 -1
  26. package/lib/commands/ext-dev-usage.js +1 -1
  27. package/lib/commands/ext-info.js +1 -1
  28. package/lib/commands/ext-install.js +2 -2
  29. package/lib/commands/ext-update.js +1 -1
  30. package/lib/commands/ext.js +1 -1
  31. package/lib/commands/firestore-delete.js +2 -2
  32. package/lib/commands/firestore-indexes-list.js +3 -3
  33. package/lib/commands/functions-config-clone.js +1 -1
  34. package/lib/commands/functions-config-export.js +1 -1
  35. package/lib/commands/functions-config-set.js +1 -1
  36. package/lib/commands/functions-config-unset.js +1 -1
  37. package/lib/commands/functions-delete.js +1 -1
  38. package/lib/commands/functions-secrets-set.js +1 -1
  39. package/lib/commands/help.js +1 -1
  40. package/lib/commands/hosting-channel-create.js +5 -5
  41. package/lib/commands/hosting-channel-delete.js +3 -3
  42. package/lib/commands/hosting-channel-deploy.js +6 -6
  43. package/lib/commands/hosting-channel-list.js +2 -2
  44. package/lib/commands/hosting-channel-open.js +2 -2
  45. package/lib/commands/hosting-clone.js +8 -8
  46. package/lib/commands/hosting-disable.js +1 -1
  47. package/lib/commands/hosting-sites-create.js +4 -4
  48. package/lib/commands/hosting-sites-delete.js +4 -4
  49. package/lib/commands/hosting-sites-list.js +2 -2
  50. package/lib/commands/init.js +5 -5
  51. package/lib/commands/login-add.js +1 -1
  52. package/lib/commands/login-ci.js +2 -2
  53. package/lib/commands/login-list.js +1 -1
  54. package/lib/commands/login-use.js +1 -1
  55. package/lib/commands/login.js +1 -1
  56. package/lib/commands/logout.js +1 -1
  57. package/lib/commands/open.js +3 -3
  58. package/lib/commands/projects-list.js +2 -2
  59. package/lib/commands/serve.js +1 -1
  60. package/lib/commands/target-apply.js +1 -1
  61. package/lib/commands/target-clear.js +1 -1
  62. package/lib/commands/target-remove.js +1 -1
  63. package/lib/commands/target.js +1 -1
  64. package/lib/commands/use.js +7 -7
  65. package/lib/config.js +1 -1
  66. package/lib/deploy/database/prepare.js +3 -3
  67. package/lib/deploy/database/release.js +3 -3
  68. package/lib/deploy/extensions/deploymentSummary.js +1 -1
  69. package/lib/deploy/extensions/errors.js +1 -1
  70. package/lib/deploy/extensions/secrets.js +1 -1
  71. package/lib/deploy/extensions/tasks.js +2 -2
  72. package/lib/deploy/firestore/deploy.js +2 -2
  73. package/lib/deploy/firestore/prepare.js +2 -2
  74. package/lib/deploy/functions/backend.js +1 -1
  75. package/lib/deploy/functions/build.js +3 -0
  76. package/lib/deploy/functions/checkIam.js +3 -3
  77. package/lib/deploy/functions/containerCleaner.js +2 -2
  78. package/lib/deploy/functions/deploy.js +2 -2
  79. package/lib/deploy/functions/ensure.js +1 -1
  80. package/lib/deploy/functions/prepare.js +1 -1
  81. package/lib/deploy/functions/prepareFunctionsUpload.js +2 -2
  82. package/lib/deploy/functions/prompts.js +1 -1
  83. package/lib/deploy/functions/release/fabricator.js +2 -2
  84. package/lib/deploy/functions/release/index.js +1 -1
  85. package/lib/deploy/functions/release/reporter.js +1 -1
  86. package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +1 -1
  87. package/lib/deploy/functions/runtimes/node/parseTriggers.js +1 -5
  88. package/lib/deploy/functions/runtimes/node/versioning.js +4 -4
  89. package/lib/deploy/functions/validate.js +1 -1
  90. package/lib/deploy/hosting/deploy.js +10 -9
  91. package/lib/deploy/hosting/uploader.js +2 -2
  92. package/lib/deploy/hosting/validate.js +2 -2
  93. package/lib/deploy/index.js +7 -7
  94. package/lib/deploy/lifecycleHooks.js +5 -2
  95. package/lib/deploy/storage/prepare.js +5 -3
  96. package/lib/deploy/storage/release.js +7 -6
  97. package/lib/emulator/commandUtils.js +1 -1
  98. package/lib/emulator/controller.js +1 -1
  99. package/lib/emulator/databaseEmulator.js +1 -1
  100. package/lib/emulator/downloadableEmulators.js +1 -1
  101. package/lib/emulator/emulatorLogger.js +1 -1
  102. package/lib/emulator/extensionsEmulator.js +2 -2
  103. package/lib/emulator/firestoreEmulator.js +1 -1
  104. package/lib/emulator/functionsEmulator.js +22 -10
  105. package/lib/emulator/loggingEmulator.js +2 -2
  106. package/lib/emulator/storage/apis/firebase.js +13 -1
  107. package/lib/emulator/storage/apis/gcloud.js +15 -8
  108. package/lib/emulator/storage/files.js +7 -2
  109. package/lib/emulator/storage/multipart.js +4 -3
  110. package/lib/emulator/storage/rules/runtime.js +1 -1
  111. package/lib/emulator/storage/rules/utils.js +4 -2
  112. package/lib/emulator/types.js +1 -0
  113. package/lib/ensureApiEnabled.js +7 -7
  114. package/lib/extensions/askUserForConsent.js +1 -1
  115. package/lib/extensions/askUserForEventsConfig.js +1 -1
  116. package/lib/extensions/askUserForParam.js +1 -1
  117. package/lib/extensions/changelog.js +2 -2
  118. package/lib/extensions/checkProjectBilling.js +2 -2
  119. package/lib/extensions/displayExtensionInfo.js +1 -1
  120. package/lib/extensions/extensionsApi.js +1 -1
  121. package/lib/extensions/extensionsHelper.js +1 -1
  122. package/lib/extensions/listExtensions.js +1 -1
  123. package/lib/extensions/manifest.js +1 -1
  124. package/lib/extensions/metricsUtils.js +1 -1
  125. package/lib/extensions/paramHelper.js +1 -1
  126. package/lib/extensions/updateHelper.js +2 -2
  127. package/lib/extensions/warnings.js +2 -2
  128. package/lib/fetchMOTD.js +1 -1
  129. package/lib/firestore/delete.js +1 -1
  130. package/lib/firestore/indexes.js +2 -2
  131. package/lib/firestore/validator.js +1 -1
  132. package/lib/functions/env.js +3 -3
  133. package/lib/functions/runtimeConfigExport.js +1 -1
  134. package/lib/functionsConfig.js +1 -1
  135. package/lib/functionsConfigClone.js +1 -1
  136. package/lib/functionsShellCommandAction.js +1 -1
  137. package/lib/gcp/cloudfunctions.js +3 -3
  138. package/lib/gcp/cloudfunctionsv2.js +5 -5
  139. package/lib/gcp/cloudscheduler.js +33 -9
  140. package/lib/gcp/cloudtasks.js +17 -1
  141. package/lib/gcp/serviceusage.js +2 -2
  142. package/lib/handlePreviewToggles.js +4 -4
  143. package/lib/hosting/implicitInit.js +1 -1
  144. package/lib/hosting/normalizedHostingConfigs.js +3 -3
  145. package/lib/index.js +2 -2
  146. package/lib/init/features/database.js +1 -1
  147. package/lib/init/features/emulators.js +1 -1
  148. package/lib/init/features/firestore/index.js +2 -2
  149. package/lib/init/features/firestore/indexes.js +1 -1
  150. package/lib/init/features/firestore/rules.js +1 -1
  151. package/lib/init/features/functions/golang.js +1 -1
  152. package/lib/init/features/functions/index.js +8 -1
  153. package/lib/init/features/hosting/github.js +9 -9
  154. package/lib/init/features/hosting/index.js +1 -1
  155. package/lib/init/features/project.js +1 -1
  156. package/lib/init/features/remoteconfig.js +1 -1
  157. package/lib/init/features/storage.js +1 -1
  158. package/lib/init/index.js +1 -1
  159. package/lib/logError.js +3 -3
  160. package/lib/management/projects.js +1 -1
  161. package/lib/parseBoltRules.js +1 -1
  162. package/lib/profileReport.js +2 -2
  163. package/lib/projectUtils.js +1 -1
  164. package/lib/rc.js +1 -1
  165. package/lib/requireAuth.js +1 -1
  166. package/lib/requireDatabaseInstance.js +2 -2
  167. package/lib/requirePermissions.js +2 -2
  168. package/lib/rulesDeploy.js +11 -12
  169. package/lib/serve/hosting.js +2 -1
  170. package/lib/utils.js +10 -10
  171. package/npm-shrinkwrap.json +14 -294
  172. package/package.json +5 -4
  173. package/templates/hosting/init.js +6 -2
@@ -29,6 +29,7 @@ class StoredFile {
29
29
  }
30
30
  }
31
31
  exports.StoredFile = StoredFile;
32
+ const TRAILING_SLASHES_PATTERN = /\/+$/;
32
33
  class StorageLayer {
33
34
  constructor(_projectId, _files, _buckets, _rulesValidator, _adminCredsValidator, _persistence, _cloudFunctions) {
34
35
  this._projectId = _projectId;
@@ -137,6 +138,7 @@ class StorageLayer {
137
138
  if (upload.status !== upload_1.UploadStatus.FINISHED) {
138
139
  throw new Error(`Unexpected upload status encountered: ${upload.status}.`);
139
140
  }
141
+ const storedMetadata = this.getMetadata(upload.bucketId, upload.objectId);
140
142
  const filePath = this.path(upload.bucketId, upload.objectId);
141
143
  const metadata = new metadata_1.StoredFileMetadata({
142
144
  name: upload.objectId,
@@ -149,7 +151,10 @@ class StorageLayer {
149
151
  customMetadata: upload.metadata.metadata,
150
152
  }, this._cloudFunctions, this._persistence.readBytes(upload.path, upload.size));
151
153
  metadata.update(upload.metadata, false);
152
- const authorized = await this._rulesValidator.validate(["b", upload.bucketId, "o", upload.objectId].join("/"), upload.bucketId, types_1.RulesetOperationMethod.CREATE, { after: metadata === null || metadata === void 0 ? void 0 : metadata.asRulesResource() }, upload.authorization);
154
+ const authorized = await this._rulesValidator.validate(["b", upload.bucketId, "o", upload.objectId].join("/"), upload.bucketId, types_1.RulesetOperationMethod.CREATE, {
155
+ before: storedMetadata === null || storedMetadata === void 0 ? void 0 : storedMetadata.asRulesResource(),
156
+ after: metadata === null || metadata === void 0 ? void 0 : metadata.asRulesResource(),
157
+ }, upload.authorization);
153
158
  if (!authorized) {
154
159
  this._persistence.deleteFile(upload.path);
155
160
  throw new errors_1.ForbiddenError();
@@ -203,7 +208,7 @@ class StorageLayer {
203
208
  async listObjects(request) {
204
209
  var _a;
205
210
  const { bucketId, prefix, delimiter, pageToken, authorization } = request;
206
- const authorized = await this._rulesValidator.validate(["b", bucketId, "o", prefix].join("/"), bucketId, types_1.RulesetOperationMethod.LIST, {}, authorization);
211
+ const authorized = await this._rulesValidator.validate(["b", bucketId, "o", prefix.replace(TRAILING_SLASHES_PATTERN, "")].join("/"), bucketId, types_1.RulesetOperationMethod.LIST, {}, authorization, delimiter);
207
212
  if (!authorized) {
208
213
  throw new errors_1.ForbiddenError();
209
214
  }
@@ -23,7 +23,8 @@ function splitBufferByDelimiter(buffer, delimiter, maxResults = -1) {
23
23
  return bufferParts;
24
24
  }
25
25
  function parseMultipartRequestBody(boundaryId, body) {
26
- const boundaryString = `--${boundaryId}`;
26
+ const cleanBoundaryId = boundaryId.replace(/^["'](.+(?=["']$))["']$/, "$1");
27
+ const boundaryString = `--${cleanBoundaryId}`;
27
28
  const bodyParts = splitBufferByDelimiter(body, boundaryString).map((buf) => {
28
29
  return Buffer.from(buf.slice(2));
29
30
  });
@@ -35,8 +36,8 @@ function parseMultipartRequestBody(boundaryId, body) {
35
36
  }
36
37
  function parseMultipartRequestBodyPart(bodyPart) {
37
38
  const sections = splitBufferByDelimiter(bodyPart, LINE_SEPARATOR, 3);
38
- const contentTypeRaw = sections[0].toString();
39
- if (!contentTypeRaw.startsWith("Content-Type: ")) {
39
+ const contentTypeRaw = sections[0].toString().toLowerCase();
40
+ if (!contentTypeRaw.startsWith("content-type: ")) {
40
41
  throw new Error(`Failed to parse multipart request body part. Missing content type.`);
41
42
  }
42
43
  const dataRaw = Buffer.from(sections[2]).slice(0, sections[2].byteLength - LINE_SEPARATOR.length);
@@ -199,6 +199,7 @@ class StorageRulesRuntime {
199
199
  service: "firebase.storage",
200
200
  path: opts.path,
201
201
  method: opts.method,
202
+ delimiter: opts.delimiter,
202
203
  variables: runtimeVariables,
203
204
  },
204
205
  };
@@ -293,7 +294,6 @@ function createRequestExpressionValue(opts) {
293
294
  segments: opts.path
294
295
  .split("/")
295
296
  .filter((s) => s)
296
- .slice(3)
297
297
  .map((simple) => ({
298
298
  simple,
299
299
  })),
@@ -5,13 +5,14 @@ const emulatorLogger_1 = require("../../emulatorLogger");
5
5
  const types_1 = require("../../types");
6
6
  function getFirebaseRulesValidator(rulesetProvider) {
7
7
  return {
8
- validate: async (path, bucketId, method, variableOverrides, authorization) => {
8
+ validate: async (path, bucketId, method, variableOverrides, authorization, delimiter) => {
9
9
  return await isPermitted({
10
10
  ruleset: rulesetProvider(bucketId),
11
11
  file: variableOverrides,
12
12
  path,
13
13
  method,
14
14
  authorization,
15
+ delimiter,
15
16
  });
16
17
  },
17
18
  };
@@ -19,7 +20,7 @@ function getFirebaseRulesValidator(rulesetProvider) {
19
20
  exports.getFirebaseRulesValidator = getFirebaseRulesValidator;
20
21
  function getAdminOnlyFirebaseRulesValidator() {
21
22
  return {
22
- validate: (_path, _bucketId, _method, _variableOverrides, _authorization) => {
23
+ validate: (_path, _bucketId, _method, _variableOverrides, _authorization, delimiter) => {
23
24
  return Promise.resolve(true);
24
25
  },
25
26
  };
@@ -42,6 +43,7 @@ async function isPermitted(opts) {
42
43
  path: opts.path,
43
44
  file: opts.file,
44
45
  token: opts.authorization ? opts.authorization.split(" ")[1] : undefined,
46
+ delimiter: opts.delimiter,
45
47
  });
46
48
  if (issues.exist()) {
47
49
  issues.all.forEach((warningOrError) => {
@@ -56,6 +56,7 @@ exports.EMULATORS_SUPPORTED_BY_USE_EMULATOR = [
56
56
  Emulators.DATABASE,
57
57
  Emulators.FIRESTORE,
58
58
  Emulators.FUNCTIONS,
59
+ Emulators.STORAGE,
59
60
  ];
60
61
  exports.ALL_EMULATORS = [
61
62
  Emulators.HUB,
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.enableApiURI = exports.ensure = exports.check = exports.POLL_SETTINGS = void 0;
4
- const cli_color_1 = require("cli-color");
4
+ const colorette_1 = require("colorette");
5
5
  const track_1 = require("./track");
6
6
  const api_1 = require("./api");
7
7
  const apiv2_1 = require("./apiv2");
@@ -21,7 +21,7 @@ async function check(projectId, apiName, prefix, silent = false) {
21
21
  });
22
22
  const isEnabled = res.body.state === "ENABLED";
23
23
  if (isEnabled && !silent) {
24
- utils.logLabeledSuccess(prefix, `required API ${(0, cli_color_1.bold)(apiName)} is enabled`);
24
+ utils.logLabeledSuccess(prefix, `required API ${(0, colorette_1.bold)(apiName)} is enabled`);
25
25
  }
26
26
  return isEnabled;
27
27
  }
@@ -34,7 +34,7 @@ async function enable(projectId, apiName) {
34
34
  }
35
35
  catch (err) {
36
36
  if ((0, error_1.isBillingError)(err)) {
37
- throw new error_1.FirebaseError(`Your project ${(0, cli_color_1.bold)(projectId)} must be on the Blaze (pay-as-you-go) plan to complete this command. Required API ${(0, cli_color_1.bold)(apiName)} can't be enabled until the upgrade is complete. To upgrade, visit the following URL:
37
+ throw new error_1.FirebaseError(`Your project ${(0, colorette_1.bold)(projectId)} must be on the Blaze (pay-as-you-go) plan to complete this command. Required API ${(0, colorette_1.bold)(apiName)} can't be enabled until the upgrade is complete. To upgrade, visit the following URL:
38
38
 
39
39
  https://console.firebase.google.com/project/${projectId}/usage/details`);
40
40
  }
@@ -54,27 +54,27 @@ async function pollCheckEnabled(projectId, apiName, prefix, silent, enablementRe
54
54
  return;
55
55
  }
56
56
  if (!silent) {
57
- utils.logLabeledBullet(prefix, `waiting for API ${(0, cli_color_1.bold)(apiName)} to activate...`);
57
+ utils.logLabeledBullet(prefix, `waiting for API ${(0, colorette_1.bold)(apiName)} to activate...`);
58
58
  }
59
59
  return pollCheckEnabled(projectId, apiName, prefix, silent, enablementRetries, pollRetries + 1);
60
60
  }
61
61
  async function enableApiWithRetries(projectId, apiName, prefix, silent, enablementRetries = 0) {
62
62
  if (enablementRetries > 1) {
63
- throw new error_1.FirebaseError(`Timed out waiting for API ${(0, cli_color_1.bold)(apiName)} to enable. Please try again in a few minutes.`);
63
+ throw new error_1.FirebaseError(`Timed out waiting for API ${(0, colorette_1.bold)(apiName)} to enable. Please try again in a few minutes.`);
64
64
  }
65
65
  await enable(projectId, apiName);
66
66
  return pollCheckEnabled(projectId, apiName, prefix, silent, enablementRetries);
67
67
  }
68
68
  async function ensure(projectId, apiName, prefix, silent = false) {
69
69
  if (!silent) {
70
- utils.logLabeledBullet(prefix, `ensuring required API ${(0, cli_color_1.bold)(apiName)} is enabled...`);
70
+ utils.logLabeledBullet(prefix, `ensuring required API ${(0, colorette_1.bold)(apiName)} is enabled...`);
71
71
  }
72
72
  const isEnabled = await check(projectId, apiName, prefix, silent);
73
73
  if (isEnabled) {
74
74
  return;
75
75
  }
76
76
  if (!silent) {
77
- utils.logLabeledWarning(prefix, `missing required API ${(0, cli_color_1.bold)(apiName)}. Enabling now...`);
77
+ utils.logLabeledWarning(prefix, `missing required API ${(0, colorette_1.bold)(apiName)}. Enabling now...`);
78
78
  }
79
79
  return enableApiWithRetries(projectId, apiName, prefix, silent);
80
80
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.promptForPublisherTOS = exports.displayApis = exports.displayRoles = exports.retrieveRoleInfo = exports.formatDescription = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const { marked } = require("marked");
6
6
  const TerminalRenderer = require("marked-terminal");
7
7
  const error_1 = require("../error");
@@ -4,7 +4,7 @@ exports.askForEventArcLocation = exports.askShouldCollectEventsConfig = exports.
4
4
  const prompt_1 = require("../prompt");
5
5
  const extensionsApi = require("../extensions/extensionsApi");
6
6
  const utils = require("../utils");
7
- const clc = require("cli-color");
7
+ const clc = require("colorette");
8
8
  const logger_1 = require("../logger");
9
9
  const { marked } = require("marked");
10
10
  function checkAllowedEventTypesResponse(response, validEvents) {
@@ -2,7 +2,7 @@
2
2
  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
- const clc = require("cli-color");
5
+ const clc = require("colorette");
6
6
  const { marked } = require("marked");
7
7
  const types_1 = require("./types");
8
8
  const secretManagerApi = require("../gcp/secretManager");
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseChangelog = exports.getLocalChangelog = exports.breakingChangesInUpdate = exports.displayReleaseNotes = exports.getReleaseNotesForUpdate = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const { marked } = require("marked");
6
6
  const path = require("path");
7
7
  const semver = require("semver");
@@ -39,7 +39,7 @@ 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.bold(version), marked(note)]);
42
+ table.push([clc.yellow(clc.bold(version)), marked(note)]);
43
43
  }
44
44
  else {
45
45
  table.push([version, marked(note)]);
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.enableBilling = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const opn = require("open");
6
6
  const cloudbilling = require("../gcp/cloudbilling");
7
7
  const error_1 = require("../error");
@@ -59,7 +59,7 @@ async function setUpBillingAccount(projectId) {
59
59
  logger_1.logger.info();
60
60
  logger_1.logger.info(`Extension require your project to be upgraded to the Blaze plan. Please visit the following link to add a billing account:`);
61
61
  logger_1.logger.info();
62
- logger_1.logger.info(clc.bold.underline(billingURL));
62
+ logger_1.logger.info(clc.bold(clc.underline(billingURL)));
63
63
  logger_1.logger.info();
64
64
  const open = await prompt.promptOnce({
65
65
  name: "open-url",
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.printSourceDownloadLink = exports.displayExtInfo = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const { marked } = require("marked");
6
6
  const TerminalRenderer = require("marked-terminal");
7
7
  const utils = require("../utils");
@@ -2,7 +2,7 @@
2
2
  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
- const clc = require("cli-color");
5
+ const clc = require("colorette");
6
6
  const { marked } = require("marked");
7
7
  const apiv2_1 = require("../apiv2");
8
8
  const api_1 = require("../api");
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.canonicalizeRefInput = exports.diagnoseAndFixProject = exports.confirm = exports.getSourceOrigin = exports.isLocalOrURLPath = exports.isLocalPath = exports.isUrlPath = exports.instanceIdExists = exports.promptForRepeatInstance = exports.promptForOfficialExtension = exports.displayReleaseNotes = exports.getPublisherProjectFromName = exports.createSourceFromLocation = exports.publishExtensionVersionFromLocalSource = exports.ensureExtensionsApiEnabled = exports.promptForValidInstanceId = exports.validateSpec = exports.validateCommandLineParams = exports.populateDefaultParams = exports.substituteParams = exports.getFirebaseProjectParams = exports.getDBInstanceFromURL = exports.resourceTypeToNiceName = exports.AUTOPOULATED_PARAM_PLACEHOLDERS = exports.EXTENSIONS_BUCKET_NAME = exports.URL_REGEX = exports.logPrefix = exports.SourceOrigin = exports.SpecParamType = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const ora = require("ora");
6
6
  const semver = require("semver");
7
7
  const { marked } = require("marked");
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.listExtensions = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const Table = require("cli-table");
6
6
  const extensionsApi_1 = require("./extensionsApi");
7
7
  const logger_1 = require("../logger");
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.showPostDeprecationNotice = exports.readInstanceParam = exports.getInstanceRef = exports.getInstanceTarget = exports.instanceExists = exports.loadConfig = exports.removeFromManifest = exports.writeLocalSecrets = exports.writeToManifest = exports.ENV_DIRECTORY = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const path = require("path");
6
6
  const refs = require("./refs");
7
7
  const config_1 = require("../config");
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildMetricsTableRow = exports.parseBucket = exports.parseTimeseriesResponse = void 0;
4
4
  const semver = require("semver");
5
- const clc = require("cli-color");
5
+ const clc = require("colorette");
6
6
  function parseTimeseriesResponse(series) {
7
7
  const ret = [];
8
8
  for (const s of series) {
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.readEnvFile = exports.promptForNewParams = exports.getParamsForUpdate = exports.getParams = exports.getParamsWithCurrentValuesAsDefaults = exports.setNewDefaults = exports.buildBindingOptionsWithBaseValue = exports.getBaseParamBindings = void 0;
4
4
  const path = require("path");
5
- const clc = require("cli-color");
5
+ const clc = require("colorette");
6
6
  const fs = require("fs-extra");
7
7
  const error_1 = require("../error");
8
8
  const logger_1 = require("../logger");
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.inferUpdateSource = exports.updateFromPublisherSource = exports.updateToVersionFromPublisherSource = exports.updateFromUrlSource = exports.updateFromLocalSource = exports.update = exports.warningUpdateToOtherSource = exports.getExistingSourceOrigin = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const semver = require("semver");
6
6
  const { marked } = require("marked");
7
7
  const error_1 = require("../error");
@@ -120,7 +120,7 @@ async function updateToVersionFromPublisherSource(projectId, instanceId, extVers
120
120
  source = await extensionsApi.getExtensionVersion(extVersionRef);
121
121
  }
122
122
  catch (err) {
123
- throw new error_1.FirebaseError(`Could not find source '${clc.bold(extVersionRef)}' because (${clc.bold(version)}) is not a published version. To update, use the latest version of this extension (${clc.bold(extension.latestVersion)}).`);
123
+ throw new error_1.FirebaseError(`Could not find source '${clc.bold(extVersionRef)}' because (${clc.bold(version || "")}) is not a published version. To update, use the latest version of this extension (${clc.bold(extension.latestVersion || "")}).`);
124
124
  }
125
125
  showUpdateVersionInfo(instanceId, existingSpec.version, source.spec.version, extVersionRef);
126
126
  warningUpdateToOtherSource(extensionsHelper_1.SourceOrigin.PUBLISHED_EXTENSION);
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.outOfBandChangesWarning = exports.paramsFlagDeprecationWarning = exports.displayWarningsForDeploy = exports.displayWarningPrompts = void 0;
4
4
  const { marked } = require("marked");
5
- const clc = require("cli-color");
5
+ const clc = require("colorette");
6
6
  const types_1 = require("./types");
7
7
  const displayExtensionInfo_1 = require("./displayExtensionInfo");
8
8
  const extensionsHelper_1 = require("./extensionsHelper");
@@ -20,7 +20,7 @@ function displayEAPWarning({ publisherId, sourceDownloadUri, githubLink, }) {
20
20
  (0, displayExtensionInfo_1.printSourceDownloadLink)(sourceDownloadUri);
21
21
  }
22
22
  function displayExperimentalWarning() {
23
- utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(`${clc.yellow.bold("Important")}: This extension is ${clc.bold("experimental")} and may not be production-ready. Its functionality might change in backward-incompatible ways before its official release, or it may be discontinued.`));
23
+ utils.logLabeledBullet(extensionsHelper_1.logPrefix, marked(`${clc.yellow(clc.bold("Important"))}: This extension is ${clc.bold("experimental")} and may not be production-ready. Its functionality might change in backward-incompatible ways before its official release, or it may be discontinued.`));
24
24
  }
25
25
  async function displayWarningPrompts(publisherId, launchStage, extensionVersion) {
26
26
  const trustedPublishers = await (0, resolveSource_1.getTrustedPublishers)();
package/lib/fetchMOTD.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.fetchMOTD = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const semver = require("semver");
6
6
  const apiv2_1 = require("./apiv2");
7
7
  const configstore_1 = require("./configstore");
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FirestoreDelete = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const ProgressBar = require("progress");
6
6
  const apiv2 = require("../apiv2");
7
7
  const firestore = require("../gcp/firestore");
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FirestoreIndexes = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const logger_1 = require("../logger");
6
6
  const utils = require("../utils");
7
7
  const validator = require("./validator");
@@ -345,7 +345,7 @@ class FirestoreIndexes {
345
345
  return result;
346
346
  }
347
347
  if (spec.indexes[0].collectionId) {
348
- utils.logBullet(clc.bold.cyan("firestore:") +
348
+ utils.logBullet(clc.bold(clc.cyan("firestore:")) +
349
349
  " your indexes indexes are specified in the v1beta1 API format. " +
350
350
  "Please upgrade to the new index API format by running " +
351
351
  clc.bold("firebase firestore:indexes") +
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.assertEnum = exports.assertHasOneOf = exports.assertHas = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const error_1 = require("../error");
6
6
  function assertHas(obj, prop) {
7
7
  const objString = clc.cyan(JSON.stringify(obj));
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.loadFirebaseEnvs = exports.loadUserEnvs = exports.writeUserEnvs = exports.hasUserEnvs = exports.parseStrict = exports.validateKey = exports.KeyValidationError = exports.parse = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const fs = require("fs");
6
6
  const path = require("path");
7
7
  const error_1 = require("../error");
@@ -173,7 +173,7 @@ function writeUserEnvs(toWrite, envOpts) {
173
173
  }
174
174
  }
175
175
  const mostSpecificEnv = path.join(functionsSource, envFiles[envFiles.length - 1]);
176
- (0, utils_1.logBullet)(clc.cyan.bold("functions: ") + `Writing new parameter values to disk: ${mostSpecificEnv}`);
176
+ (0, utils_1.logBullet)(clc.cyan(clc.bold("functions: ")) + `Writing new parameter values to disk: ${mostSpecificEnv}`);
177
177
  for (const k of Object.keys(toWrite)) {
178
178
  fs.appendFileSync(mostSpecificEnv, formatUserEnvForWrite(k, toWrite[k]));
179
179
  }
@@ -219,7 +219,7 @@ function loadUserEnvs({ functionsSource, projectId, projectAlias, isEmulator, })
219
219
  });
220
220
  }
221
221
  }
222
- (0, utils_1.logBullet)(clc.cyan.bold("functions: ") + `Loaded environment variables from ${envFiles.join(", ")}.`);
222
+ (0, utils_1.logBullet)(clc.cyan(clc.bold("functions: ")) + `Loaded environment variables from ${envFiles.join(", ")}.`);
223
223
  return envs;
224
224
  }
225
225
  exports.loadUserEnvs = loadUserEnvs;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateDotenvFilename = exports.toDotenvFormat = exports.hydrateEnvs = exports.configToEnv = exports.convertKey = exports.hydrateConfigs = exports.getProjectInfos = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const env = require("./env");
6
6
  const functionsConfig = require("../functionsConfig");
7
7
  const error_1 = require("../error");
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseUnsetArgs = exports.parseSetArgs = exports.materializeAll = exports.materializeConfig = exports.setVariablesRecursive = exports.getFirebaseConfig = exports.getAppEngineLocation = exports.idsToVarName = exports.varNameToIds = exports.ensureApi = exports.RESERVED_NAMESPACES = void 0;
4
4
  const _ = require("lodash");
5
- const clc = require("cli-color");
5
+ const clc = require("colorette");
6
6
  const api_1 = require("./api");
7
7
  const apiv2_1 = require("./apiv2");
8
8
  const ensureApiEnabled_1 = require("./ensureApiEnabled");
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.functionsConfigClone = void 0;
4
4
  const _ = require("lodash");
5
- const clc = require("cli-color");
5
+ const clc = require("colorette");
6
6
  const error_1 = require("./error");
7
7
  const functionsConfig = require("./functionsConfig");
8
8
  const runtimeconfig = require("./gcp/runtimeconfig");
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.actionFunction = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const repl = require("repl");
6
6
  const _ = require("lodash");
7
7
  const request = require("request");
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.functionFromEndpoint = exports.endpointFromFunction = exports.listAllFunctions = exports.listFunctions = exports.deleteFunction = exports.updateFunction = exports.setInvokerUpdate = exports.setInvokerCreate = exports.getIamPolicy = exports.setIamPolicy = exports.createFunction = exports.generateUploadUrl = exports.BLOCKING_LABEL = exports.CODEBASE_LABEL = exports.API_VERSION = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const error_1 = require("../error");
6
6
  const logger_1 = require("../logger");
7
7
  const backend = require("../deploy/functions/backend");
@@ -26,10 +26,10 @@ const BLOCKING_EVENT_TO_LABEL_KEY = {
26
26
  function functionsOpLogReject(funcName, type, err) {
27
27
  var _a, _b;
28
28
  if (((_b = (_a = err === null || err === void 0 ? void 0 : err.context) === null || _a === void 0 ? void 0 : _a.response) === null || _b === void 0 ? void 0 : _b.statusCode) === 429) {
29
- utils.logWarning(`${clc.bold.yellow("functions:")} got "Quota Exceeded" error while trying to ${type} ${funcName}. Waiting to retry...`);
29
+ utils.logWarning(`${clc.bold(clc.yellow("functions:"))} got "Quota Exceeded" error while trying to ${type} ${funcName}. Waiting to retry...`);
30
30
  }
31
31
  else {
32
- utils.logWarning(clc.bold.yellow("functions:") + " failed to " + type + " function " + funcName);
32
+ utils.logWarning(clc.bold(clc.yellow("functions:")) + " failed to " + type + " function " + funcName);
33
33
  }
34
34
  throw new error_1.FirebaseError(`Failed to ${type} function ${funcName}`, {
35
35
  original: err,
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.endpointFromFunction = exports.functionFromEndpoint = exports.deleteFunction = exports.updateFunction = exports.listAllFunctions = exports.listFunctions = exports.getFunction = exports.createFunction = exports.generateUploadUrl = exports.mebibytes = exports.BLOCKING_LABEL = exports.CODEBASE_LABEL = exports.API_VERSION = void 0;
4
- const clc = require("cli-color");
4
+ const clc = require("colorette");
5
5
  const apiv2_1 = require("../apiv2");
6
6
  const error_1 = require("../error");
7
7
  const api_1 = require("../api");
@@ -59,15 +59,15 @@ function mebibytes(memory) {
59
59
  exports.mebibytes = mebibytes;
60
60
  function functionsOpLogReject(funcName, type, err) {
61
61
  var _a, _b;
62
- utils.logWarning(clc.bold.yellow("functions:") + ` ${err === null || err === void 0 ? void 0 : err.message}`);
62
+ utils.logWarning(clc.bold(clc.yellow("functions:")) + ` ${err === null || err === void 0 ? void 0 : err.message}`);
63
63
  if (((_b = (_a = err === null || err === void 0 ? void 0 : err.context) === null || _a === void 0 ? void 0 : _a.response) === null || _b === void 0 ? void 0 : _b.statusCode) === 429) {
64
- utils.logWarning(`${clc.bold.yellow("functions:")} got "Quota Exceeded" error while trying to ${type} ${funcName}. Waiting to retry...`);
64
+ utils.logWarning(`${clc.bold(clc.yellow("functions:"))} got "Quota Exceeded" error while trying to ${type} ${funcName}. Waiting to retry...`);
65
65
  }
66
66
  else if (err === null || err === void 0 ? void 0 : err.message.includes("If you recently started to use Eventarc, it may take a few minutes before all necessary permissions are propagated to the Service Agent")) {
67
- utils.logWarning(`${clc.bold.yellow("functions:")} since this is your first time using functions v2, we need a little bit longer to finish setting everything up, please retry the deployment in a few minutes.`);
67
+ utils.logWarning(`${clc.bold(clc.yellow("functions:"))} since this is your first time using functions v2, we need a little bit longer to finish setting everything up, please retry the deployment in a few minutes.`);
68
68
  }
69
69
  else {
70
- utils.logWarning(clc.bold.yellow("functions:") + " failed to " + type + " function " + funcName);
70
+ utils.logWarning(clc.bold(clc.yellow("functions:")) + " failed to " + type + " function " + funcName);
71
71
  }
72
72
  throw new error_1.FirebaseError(`Failed to ${type} function ${funcName}`, {
73
73
  original: err,
@@ -9,7 +9,7 @@ const apiv2_1 = require("../apiv2");
9
9
  const backend = require("../deploy/functions/backend");
10
10
  const proto = require("./proto");
11
11
  const functional_1 = require("../functional");
12
- const VERSION = "v1beta1";
12
+ const VERSION = "v1";
13
13
  const DEFAULT_TIME_ZONE = "America/Los_Angeles";
14
14
  const apiClient = new apiv2_1.Client({ urlPrefix: api_1.cloudschedulerOrigin, apiVersion: VERSION });
15
15
  function createJob(job) {
@@ -28,7 +28,12 @@ function getJob(name) {
28
28
  }
29
29
  exports.getJob = getJob;
30
30
  function updateJob(job) {
31
- return apiClient.patch(`/${job.name}`, Object.assign({ timeZone: DEFAULT_TIME_ZONE }, job));
31
+ const fieldMasks = proto.fieldMasks(job, "pubsubTarget");
32
+ return apiClient.patch(`/${job.name}`, Object.assign({ timeZone: DEFAULT_TIME_ZONE }, job), {
33
+ queryParams: {
34
+ updateMask: fieldMasks.join(","),
35
+ },
36
+ });
32
37
  }
33
38
  exports.updateJob = updateJob;
34
39
  async function createOrReplaceJob(job) {
@@ -53,7 +58,7 @@ async function createOrReplaceJob(job) {
53
58
  if (!job.timeZone) {
54
59
  job.timeZone = DEFAULT_TIME_ZONE;
55
60
  }
56
- if (isIdentical(existingJob.body, job)) {
61
+ if (!needUpdate(existingJob.body, job)) {
57
62
  logger_1.logger.debug(`scheduler job ${jobName} is up to date, no changes required`);
58
63
  return;
59
64
  }
@@ -62,12 +67,28 @@ async function createOrReplaceJob(job) {
62
67
  return updatedJob;
63
68
  }
64
69
  exports.createOrReplaceJob = createOrReplaceJob;
65
- function isIdentical(job, otherJob) {
66
- return (job &&
67
- otherJob &&
68
- job.schedule === otherJob.schedule &&
69
- job.timeZone === otherJob.timeZone &&
70
- _.isEqual(job.retryConfig, otherJob.retryConfig));
70
+ function needUpdate(existingJob, newJob) {
71
+ if (!existingJob) {
72
+ return true;
73
+ }
74
+ if (!newJob) {
75
+ return true;
76
+ }
77
+ if (existingJob.schedule !== newJob.schedule) {
78
+ return true;
79
+ }
80
+ if (existingJob.timeZone !== newJob.timeZone) {
81
+ return true;
82
+ }
83
+ if (newJob.retryConfig) {
84
+ if (!existingJob.retryConfig) {
85
+ return true;
86
+ }
87
+ if (!_.isMatch(existingJob.retryConfig, newJob.retryConfig)) {
88
+ return true;
89
+ }
90
+ }
91
+ return false;
71
92
  }
72
93
  function jobNameForEndpoint(endpoint, appEngineLocation) {
73
94
  const id = backend.scheduleIdForFunction(endpoint);
@@ -107,6 +128,9 @@ function jobFromEndpoint(endpoint, appEngineLocation) {
107
128
  proto.convertIfPresent(job.retryConfig, endpoint.scheduleTrigger.retryConfig, "maxBackoffDuration", "maxBackoffSeconds", (0, functional_1.nullsafeVisitor)(proto.durationFromSeconds));
108
129
  proto.convertIfPresent(job.retryConfig, endpoint.scheduleTrigger.retryConfig, "minBackoffDuration", "minBackoffSeconds", (0, functional_1.nullsafeVisitor)(proto.durationFromSeconds));
109
130
  proto.convertIfPresent(job.retryConfig, endpoint.scheduleTrigger.retryConfig, "maxRetryDuration", "maxRetrySeconds", (0, functional_1.nullsafeVisitor)(proto.durationFromSeconds));
131
+ if (!Object.keys(job.retryConfig).length) {
132
+ delete job.retryConfig;
133
+ }
110
134
  }
111
135
  return job;
112
136
  }