firebase-tools 9.18.0 → 9.22.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 (114) hide show
  1. package/CHANGELOG.md +3 -6
  2. package/lib/api.js +3 -0
  3. package/lib/apiv2.js +8 -5
  4. package/lib/command.js +1 -1
  5. package/lib/commands/crashlytics-symbols-upload.js +146 -0
  6. package/lib/commands/deploy.js +9 -1
  7. package/lib/commands/ext-configure.js +9 -2
  8. package/lib/commands/ext-dev-deprecate.js +63 -0
  9. package/lib/commands/ext-dev-extension-delete.js +2 -1
  10. package/lib/commands/ext-dev-publish.js +10 -4
  11. package/lib/commands/ext-dev-undeprecate.js +56 -0
  12. package/lib/commands/ext-dev-unpublish.js +12 -4
  13. package/lib/commands/ext-export.js +44 -0
  14. package/lib/commands/ext-install.js +50 -13
  15. package/lib/commands/ext-uninstall.js +6 -0
  16. package/lib/commands/ext-update.js +60 -18
  17. package/lib/commands/functions-config-export.js +115 -0
  18. package/lib/commands/functions-delete.js +47 -25
  19. package/lib/commands/functions-list.js +12 -12
  20. package/lib/commands/index.js +9 -0
  21. package/lib/commands/init.js +3 -0
  22. package/lib/config.js +3 -2
  23. package/lib/deploy/extensions/args.js +2 -0
  24. package/lib/deploy/extensions/deploy.js +49 -0
  25. package/lib/deploy/extensions/deploymentSummary.js +52 -0
  26. package/lib/deploy/extensions/errors.js +31 -0
  27. package/lib/deploy/extensions/index.js +8 -0
  28. package/lib/deploy/extensions/planner.js +95 -0
  29. package/lib/deploy/extensions/prepare.js +103 -0
  30. package/lib/deploy/extensions/release.js +43 -0
  31. package/lib/deploy/extensions/secrets.js +150 -0
  32. package/lib/deploy/extensions/tasks.js +98 -0
  33. package/lib/deploy/extensions/validate.js +17 -0
  34. package/lib/deploy/functions/backend.js +93 -115
  35. package/lib/deploy/functions/checkIam.js +8 -8
  36. package/lib/deploy/functions/containerCleaner.js +82 -22
  37. package/lib/deploy/functions/deploy.js +4 -10
  38. package/lib/deploy/functions/functionsDeployHelper.js +3 -68
  39. package/lib/deploy/functions/prepare.js +62 -27
  40. package/lib/deploy/functions/pricing.js +17 -17
  41. package/lib/deploy/functions/prompts.js +22 -21
  42. package/lib/deploy/functions/release/executor.js +39 -0
  43. package/lib/deploy/functions/release/fabricator.js +422 -0
  44. package/lib/deploy/functions/release/index.js +73 -0
  45. package/lib/deploy/functions/release/planner.js +162 -0
  46. package/lib/deploy/functions/release/reporter.js +165 -0
  47. package/lib/deploy/functions/release/sourceTokenScraper.js +28 -0
  48. package/lib/deploy/functions/release/timer.js +14 -0
  49. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +129 -126
  50. package/lib/deploy/functions/runtimes/node/parseTriggers.js +41 -45
  51. package/lib/deploy/functions/triggerRegionHelper.js +40 -0
  52. package/lib/deploy/functions/validate.js +1 -24
  53. package/lib/deploy/index.js +1 -0
  54. package/lib/downloadUtils.js +37 -0
  55. package/lib/emulator/auth/apiSpec.js +1788 -403
  56. package/lib/emulator/auth/handlers.js +6 -5
  57. package/lib/emulator/auth/operations.js +439 -40
  58. package/lib/emulator/auth/server.js +32 -11
  59. package/lib/emulator/auth/state.js +205 -5
  60. package/lib/emulator/auth/widget_ui.js +2 -2
  61. package/lib/emulator/download.js +2 -31
  62. package/lib/emulator/downloadableEmulators.js +7 -7
  63. package/lib/emulator/emulatorLogger.js +0 -3
  64. package/lib/emulator/events/types.js +16 -0
  65. package/lib/emulator/functionsEmulator.js +120 -21
  66. package/lib/emulator/functionsEmulatorRuntime.js +46 -121
  67. package/lib/emulator/functionsEmulatorShared.js +51 -7
  68. package/lib/emulator/functionsEmulatorShell.js +1 -1
  69. package/lib/emulator/pubsubEmulator.js +61 -40
  70. package/lib/emulator/storage/cloudFunctions.js +37 -7
  71. package/lib/extensions/askUserForConsent.js +14 -1
  72. package/lib/extensions/askUserForParam.js +81 -4
  73. package/lib/extensions/billingMigrationHelper.js +1 -11
  74. package/lib/extensions/changelog.js +2 -1
  75. package/lib/extensions/checkProjectBilling.js +7 -7
  76. package/lib/extensions/displayExtensionInfo.js +35 -33
  77. package/lib/extensions/emulator/optionsHelper.js +3 -3
  78. package/lib/extensions/emulator/triggerHelper.js +2 -32
  79. package/lib/extensions/export.js +107 -0
  80. package/lib/extensions/extensionsApi.js +149 -97
  81. package/lib/extensions/extensionsHelper.js +36 -32
  82. package/lib/extensions/listExtensions.js +16 -11
  83. package/lib/extensions/paramHelper.js +73 -40
  84. package/lib/extensions/provisioningHelper.js +16 -3
  85. package/lib/extensions/refs.js +67 -0
  86. package/lib/extensions/secretsUtils.js +59 -0
  87. package/lib/extensions/updateHelper.js +33 -47
  88. package/lib/extensions/versionHelper.js +14 -0
  89. package/lib/extensions/warnings.js +33 -1
  90. package/lib/functional.js +64 -0
  91. package/lib/functions/env.js +26 -13
  92. package/lib/functions/runtimeConfigExport.js +137 -0
  93. package/lib/gcp/artifactregistry.js +16 -0
  94. package/lib/gcp/cloudfunctions.js +65 -35
  95. package/lib/gcp/cloudfunctionsv2.js +56 -43
  96. package/lib/gcp/cloudscheduler.js +22 -16
  97. package/lib/gcp/cloudtasks.js +143 -0
  98. package/lib/gcp/docker.js +7 -1
  99. package/lib/gcp/proto.js +2 -2
  100. package/lib/gcp/pubsub.js +1 -9
  101. package/lib/gcp/secretManager.js +132 -0
  102. package/lib/gcp/storage.js +16 -0
  103. package/lib/previews.js +1 -1
  104. package/lib/requireInteractive.js +12 -0
  105. package/lib/utils.js +30 -1
  106. package/package.json +6 -4
  107. package/schema/firebase-config.json +9 -0
  108. package/lib/deploy/functions/deploymentPlanner.js +0 -113
  109. package/lib/deploy/functions/deploymentTimer.js +0 -23
  110. package/lib/deploy/functions/errorHandler.js +0 -75
  111. package/lib/deploy/functions/release.js +0 -116
  112. package/lib/deploy/functions/tasks.js +0 -324
  113. package/lib/functions/listFunctions.js +0 -10
  114. package/lib/functionsDelete.js +0 -60
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.writeFiles = exports.displayExportInfo = exports.setSecretParamsToLatest = exports.parameterizeProject = void 0;
4
+ const clc = require("cli-color");
5
+ const refs = require("./refs");
6
+ const config_1 = require("../config");
7
+ const planner_1 = require("../deploy/extensions/planner");
8
+ const deploymentSummary_1 = require("../deploy/extensions/deploymentSummary");
9
+ const logger_1 = require("../logger");
10
+ const error_1 = require("../error");
11
+ const prompt_1 = require("../prompt");
12
+ const secretManager_1 = require("../gcp/secretManager");
13
+ const secretsUtils_1 = require("./secretsUtils");
14
+ function parameterizeProject(projectId, projectNumber, spec) {
15
+ const newParams = {};
16
+ for (const [key, val] of Object.entries(spec.params)) {
17
+ const p1 = val.replace(projectId, "${param:PROJECT_ID}");
18
+ const p2 = p1.replace(projectNumber, "${param:PROJECT_NUMBER}");
19
+ newParams[key] = p2;
20
+ }
21
+ const newSpec = Object.assign({}, spec);
22
+ newSpec.params = newParams;
23
+ return newSpec;
24
+ }
25
+ exports.parameterizeProject = parameterizeProject;
26
+ async function setSecretParamsToLatest(spec) {
27
+ const newParams = Object.assign({}, spec.params);
28
+ const extensionVersion = await planner_1.getExtensionVersion(spec);
29
+ const activeSecrets = secretsUtils_1.getActiveSecrets(extensionVersion.spec, newParams);
30
+ for (const [key, val] of Object.entries(newParams)) {
31
+ if (activeSecrets.includes(val)) {
32
+ const parsed = secretManager_1.parseSecretVersionResourceName(val);
33
+ parsed.versionId = "latest";
34
+ newParams[key] = secretManager_1.toSecretVersionResourceName(parsed);
35
+ }
36
+ }
37
+ return Object.assign(Object.assign({}, spec), { params: newParams });
38
+ }
39
+ exports.setSecretParamsToLatest = setSecretParamsToLatest;
40
+ function displayExportInfo(withRef, withoutRef) {
41
+ logger_1.logger.info("The following Extension instances will be saved locally:");
42
+ logger_1.logger.info("");
43
+ displaySpecs(withRef);
44
+ if (withoutRef.length) {
45
+ logger_1.logger.info(`Your project also has the following instances installed from local sources. These will not be saved to firebase.json:`);
46
+ for (const spec of withoutRef) {
47
+ logger_1.logger.info(spec.instanceId);
48
+ }
49
+ }
50
+ }
51
+ exports.displayExportInfo = displayExportInfo;
52
+ function displaySpecs(specs) {
53
+ for (let i = 0; i < specs.length; i++) {
54
+ const spec = specs[i];
55
+ logger_1.logger.info(`${i + 1}. ${deploymentSummary_1.humanReadable(spec)}`);
56
+ logger_1.logger.info(`Configuration will be written to 'extensions/${spec.instanceId}.env'`);
57
+ for (const p of Object.entries(spec.params)) {
58
+ logger_1.logger.info(`\t${p[0]}=${p[1]}`);
59
+ }
60
+ logger_1.logger.info("");
61
+ }
62
+ }
63
+ function writeExtensionsToFirebaseJson(have, existingConfig) {
64
+ const extensions = existingConfig.get("extensions", {});
65
+ for (const s of have) {
66
+ extensions[s.instanceId] = refs.toExtensionVersionRef(s.ref);
67
+ }
68
+ existingConfig.set("extensions", extensions);
69
+ logger_1.logger.info("Adding Extensions to " + clc.bold("firebase.json") + "...");
70
+ existingConfig.writeProjectFile("firebase.json", existingConfig.src);
71
+ }
72
+ async function writeEnvFile(spec, existingConfig, force) {
73
+ const content = Object.entries(spec.params)
74
+ .map((r) => `${r[0]}=${r[1]}`)
75
+ .join("\n");
76
+ await existingConfig.askWriteProjectFile(`extensions/${spec.instanceId}.env`, content, force);
77
+ }
78
+ async function writeFiles(have, options) {
79
+ const existingConfig = config_1.Config.load(options, true);
80
+ if (!existingConfig) {
81
+ throw new error_1.FirebaseError("Not currently in a Firebase directory. Please run `firebase init` to create a Firebase directory.");
82
+ }
83
+ if (existingConfig.has("extensions") &&
84
+ Object.keys(existingConfig.get("extensions")).length &&
85
+ !options.nonInteractive &&
86
+ !options.force) {
87
+ const currentExtensions = Object.entries(existingConfig.get("extensions"))
88
+ .map((i) => `${i[0]}: ${i[1]}`)
89
+ .join("\n\t");
90
+ const overwrite = await prompt_1.promptOnce({
91
+ type: "list",
92
+ message: `firebase.json already contains extensions:\n${currentExtensions}\nWould you like to overwrite or merge?`,
93
+ choices: [
94
+ { name: "Overwrite", value: true },
95
+ { name: "Merge", value: false },
96
+ ],
97
+ });
98
+ if (overwrite) {
99
+ existingConfig.set("extensions", {});
100
+ }
101
+ }
102
+ writeExtensionsToFirebaseJson(have, existingConfig);
103
+ for (const spec of have) {
104
+ await writeEnvFile(spec, existingConfig, options.force);
105
+ }
106
+ }
107
+ exports.writeFiles = writeFiles;
@@ -1,18 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseExtensionVersionName = exports.parseRef = exports.getExtension = exports.deleteExtension = exports.unpublishExtension = exports.publishExtensionVersion = exports.registerPublisherProfile = exports.listExtensionVersions = exports.listExtensions = exports.getExtensionVersion = exports.getSource = exports.createSource = exports.updateInstanceFromRegistry = exports.updateInstance = exports.configureInstance = exports.listInstances = exports.getInstance = exports.deleteInstance = exports.createInstance = exports.ParamType = exports.Visibility = exports.RegistryLaunchStage = void 0;
4
- const semver = require("semver");
3
+ exports.getExtension = exports.deleteExtension = exports.unpublishExtension = exports.publishExtensionVersion = exports.undeprecateExtensionVersion = exports.deprecateExtensionVersion = exports.registerPublisherProfile = exports.listExtensionVersions = exports.listExtensions = exports.getExtensionVersion = exports.getSource = exports.createSource = exports.updateInstanceFromRegistry = exports.updateInstance = exports.configureInstance = exports.listInstances = exports.getInstance = exports.deleteInstance = exports.createInstance = exports.ParamType = exports.Visibility = exports.RegistryLaunchStage = void 0;
5
4
  const yaml = require("js-yaml");
6
5
  const _ = require("lodash");
7
6
  const clc = require("cli-color");
8
7
  const marked = require("marked");
9
8
  const api = require("../api");
9
+ const refs = require("./refs");
10
10
  const logger_1 = require("../logger");
11
11
  const operationPoller = require("../operation-poller");
12
12
  const error_1 = require("../error");
13
13
  const VERSION = "v1beta";
14
14
  const PAGE_SIZE_MAX = 100;
15
- const refRegex = new RegExp(/^([^/@\n]+)\/{1}([^/@\n]+)(@{1}([a-z0-9.-]+)|)$/);
16
15
  var RegistryLaunchStage;
17
16
  (function (RegistryLaunchStage) {
18
17
  RegistryLaunchStage["EXPERIMENTAL"] = "EXPERIMENTAL";
@@ -31,8 +30,9 @@ var ParamType;
31
30
  ParamType["STRING"] = "STRING";
32
31
  ParamType["SELECT"] = "SELECT";
33
32
  ParamType["MULTISELECT"] = "MULTISELECT";
33
+ ParamType["SECRET"] = "SECRET";
34
34
  })(ParamType = exports.ParamType || (exports.ParamType = {}));
35
- async function createInstanceHelper(projectId, instanceId, config) {
35
+ async function createInstanceHelper(projectId, instanceId, config, validateOnly = false) {
36
36
  const createRes = await api.request("POST", `/${VERSION}/projects/${projectId}/instances/`, {
37
37
  auth: true,
38
38
  origin: api.extensionsOrigin,
@@ -40,7 +40,13 @@ async function createInstanceHelper(projectId, instanceId, config) {
40
40
  name: `projects/${projectId}/instances/${instanceId}`,
41
41
  config: config,
42
42
  },
43
+ query: {
44
+ validateOnly,
45
+ },
43
46
  });
47
+ if (validateOnly) {
48
+ return createRes;
49
+ }
44
50
  const pollRes = await operationPoller.pollOperation({
45
51
  apiOrigin: api.extensionsOrigin,
46
52
  apiVersion: VERSION,
@@ -50,7 +56,7 @@ async function createInstanceHelper(projectId, instanceId, config) {
50
56
  return pollRes;
51
57
  }
52
58
  async function createInstance(args) {
53
- var _a;
59
+ var _a, _b;
54
60
  const config = {
55
61
  params: args.params,
56
62
  };
@@ -61,14 +67,14 @@ async function createInstance(args) {
61
67
  config.source = { name: (_a = args.extensionSource) === null || _a === void 0 ? void 0 : _a.name };
62
68
  }
63
69
  else if (args.extensionVersionRef) {
64
- const { publisherId, extensionId, version } = parseRef(args.extensionVersionRef);
65
- config.extensionRef = `${publisherId}/${extensionId}`;
66
- config.extensionVersion = version !== null && version !== void 0 ? version : "";
70
+ const ref = refs.parse(args.extensionVersionRef);
71
+ config.extensionRef = refs.toExtensionRef(ref);
72
+ config.extensionVersion = (_b = ref.version) !== null && _b !== void 0 ? _b : "";
67
73
  }
68
74
  else {
69
75
  throw new error_1.FirebaseError("No ExtensionVersion or ExtensionSource provided but one is required.");
70
76
  }
71
- return createInstanceHelper(args.projectId, args.instanceId, config);
77
+ return createInstanceHelper(args.projectId, args.instanceId, config, args.validateOnly);
72
78
  }
73
79
  exports.createInstance = createInstance;
74
80
  async function deleteInstance(projectId, instanceId) {
@@ -115,54 +121,79 @@ async function listInstances(projectId) {
115
121
  return instances;
116
122
  }
117
123
  exports.listInstances = listInstances;
118
- async function configureInstance(projectId, instanceId, params) {
119
- const res = await patchInstance(projectId, instanceId, "config.params", {
120
- config: {
121
- params,
124
+ async function configureInstance(args) {
125
+ var _a;
126
+ const res = await patchInstance({
127
+ projectId: args.projectId,
128
+ instanceId: args.instanceId,
129
+ updateMask: "config.params",
130
+ validateOnly: (_a = args.validateOnly) !== null && _a !== void 0 ? _a : false,
131
+ data: {
132
+ config: {
133
+ params: args.params,
134
+ },
122
135
  },
123
136
  });
124
137
  return res;
125
138
  }
126
139
  exports.configureInstance = configureInstance;
127
- async function updateInstance(projectId, instanceId, extensionSource, params) {
140
+ async function updateInstance(args) {
141
+ var _a;
128
142
  const body = {
129
143
  config: {
130
- source: { name: extensionSource.name },
144
+ source: { name: args.extensionSource.name },
131
145
  },
132
146
  };
133
147
  let updateMask = "config.source.name";
134
- if (params) {
135
- body.config.params = params;
148
+ if (args.params) {
149
+ body.config.params = args.params;
136
150
  updateMask += ",config.params";
137
151
  }
138
- return await patchInstance(projectId, instanceId, updateMask, body);
152
+ return await patchInstance({
153
+ projectId: args.projectId,
154
+ instanceId: args.instanceId,
155
+ updateMask,
156
+ validateOnly: (_a = args.validateOnly) !== null && _a !== void 0 ? _a : false,
157
+ data: body,
158
+ });
139
159
  }
140
160
  exports.updateInstance = updateInstance;
141
- async function updateInstanceFromRegistry(projectId, instanceId, extRef, params) {
142
- const { publisherId, extensionId, version } = parseRef(extRef);
161
+ async function updateInstanceFromRegistry(args) {
162
+ var _a;
163
+ const ref = refs.parse(args.extRef);
143
164
  const body = {
144
165
  config: {
145
- extensionRef: `${publisherId}/${extensionId}`,
146
- extensionVersion: version,
166
+ extensionRef: refs.toExtensionRef(ref),
167
+ extensionVersion: ref.version,
147
168
  },
148
169
  };
149
170
  let updateMask = "config.extension_ref,config.extension_version";
150
- if (params) {
151
- body.config.params = params;
171
+ if (args.params) {
172
+ body.config.params = args.params;
152
173
  updateMask += ",config.params";
153
174
  }
154
- return await patchInstance(projectId, instanceId, updateMask, body);
175
+ return await patchInstance({
176
+ projectId: args.projectId,
177
+ instanceId: args.instanceId,
178
+ updateMask,
179
+ validateOnly: (_a = args.validateOnly) !== null && _a !== void 0 ? _a : false,
180
+ data: body,
181
+ });
155
182
  }
156
183
  exports.updateInstanceFromRegistry = updateInstanceFromRegistry;
157
- async function patchInstance(projectId, instanceId, updateMask, data) {
158
- const updateRes = await api.request("PATCH", `/${VERSION}/projects/${projectId}/instances/${instanceId}`, {
184
+ async function patchInstance(args) {
185
+ const updateRes = await api.request("PATCH", `/${VERSION}/projects/${args.projectId}/instances/${args.instanceId}`, {
159
186
  auth: true,
160
187
  origin: api.extensionsOrigin,
161
188
  query: {
162
- updateMask,
189
+ updateMask: args.updateMask,
190
+ validateOnly: args.validateOnly,
163
191
  },
164
- data,
192
+ data: args.data,
165
193
  });
194
+ if (args.validateOnly) {
195
+ return updateRes;
196
+ }
166
197
  const pollRes = await operationPoller.pollOperation({
167
198
  apiOrigin: api.extensionsOrigin,
168
199
  apiVersion: VERSION,
@@ -220,13 +251,13 @@ function getSource(sourceName) {
220
251
  });
221
252
  }
222
253
  exports.getSource = getSource;
223
- async function getExtensionVersion(ref) {
224
- const { publisherId, extensionId, version } = parseRef(ref);
225
- if (!version) {
226
- throw new error_1.FirebaseError(`ExtensionVersion ref "${ref}" must supply a version.`);
254
+ async function getExtensionVersion(extensionVersionRef) {
255
+ const ref = refs.parse(extensionVersionRef);
256
+ if (!ref.version) {
257
+ throw new error_1.FirebaseError(`ExtensionVersion ref "${extensionVersionRef}" must supply a version.`);
227
258
  }
228
259
  try {
229
- const res = await api.request("GET", `/${VERSION}/publishers/${publisherId}/extensions/${extensionId}/versions/${version}`, {
260
+ const res = await api.request("GET", `/${VERSION}/${refs.toExtensionVersionName(ref)}`, {
230
261
  auth: true,
231
262
  origin: api.extensionsOrigin,
232
263
  });
@@ -237,12 +268,12 @@ async function getExtensionVersion(ref) {
237
268
  }
238
269
  catch (err) {
239
270
  if (err.status === 404) {
240
- throw refNotFoundError(publisherId, extensionId, version);
271
+ throw refNotFoundError(ref);
241
272
  }
242
273
  else if (err instanceof error_1.FirebaseError) {
243
274
  throw err;
244
275
  }
245
- throw new error_1.FirebaseError(`Failed to query the extension version '${clc.bold(ref)}': ${err}`);
276
+ throw new error_1.FirebaseError(`Failed to query the extension version '${clc.bold(extensionVersionRef)}': ${err}`);
246
277
  }
247
278
  }
248
279
  exports.getExtensionVersion = getExtensionVersion;
@@ -270,7 +301,7 @@ async function listExtensions(publisherId) {
270
301
  }
271
302
  exports.listExtensions = listExtensions;
272
303
  async function listExtensionVersions(ref, filter) {
273
- const { publisherId, extensionId } = parseRef(ref);
304
+ const { publisherId, extensionId } = refs.parse(ref);
274
305
  const extensionVersions = [];
275
306
  const getNextPage = async (pageToken) => {
276
307
  const res = await api.request("GET", `/${VERSION}/publishers/${publisherId}/extensions/${extensionId}/versions`, {
@@ -302,16 +333,67 @@ async function registerPublisherProfile(projectId, publisherId) {
302
333
  return res.body;
303
334
  }
304
335
  exports.registerPublisherProfile = registerPublisherProfile;
305
- async function publishExtensionVersion(ref, packageUri, extensionRoot) {
306
- const { publisherId, extensionId, version } = parseRef(ref);
307
- if (!version) {
308
- throw new error_1.FirebaseError(`ExtensionVersion ref "${ref}" must supply a version.`);
336
+ async function deprecateExtensionVersion(extensionRef, deprecationMessage) {
337
+ const ref = refs.parse(extensionRef);
338
+ try {
339
+ const res = await api.request("POST", `/${VERSION}/${refs.toExtensionVersionName(ref)}:deprecate`, {
340
+ auth: true,
341
+ origin: api.extensionsOrigin,
342
+ data: { deprecationMessage },
343
+ });
344
+ return res.body;
345
+ }
346
+ catch (err) {
347
+ if (err.status === 403) {
348
+ throw new error_1.FirebaseError(`You are not the owner of extension '${clc.bold(extensionRef)}' and don’t have the correct permissions to deprecate this extension version.` + err, { status: err.status });
349
+ }
350
+ else if (err.status === 404) {
351
+ throw new error_1.FirebaseError(`Extension version ${clc.bold(extensionRef)} was not found.`);
352
+ }
353
+ else if (err instanceof error_1.FirebaseError) {
354
+ throw err;
355
+ }
356
+ throw new error_1.FirebaseError(`Error occurred deprecating extension version '${extensionRef}': ${err}`, {
357
+ status: err.status,
358
+ });
359
+ }
360
+ }
361
+ exports.deprecateExtensionVersion = deprecateExtensionVersion;
362
+ async function undeprecateExtensionVersion(extensionRef) {
363
+ const ref = refs.parse(extensionRef);
364
+ try {
365
+ const res = await api.request("POST", `/${VERSION}/${refs.toExtensionVersionName(ref)}:undeprecate`, {
366
+ auth: true,
367
+ origin: api.extensionsOrigin,
368
+ });
369
+ return res.body;
309
370
  }
310
- const publishRes = await api.request("POST", `/${VERSION}/publishers/${publisherId}/extensions/${extensionId}/versions:publish`, {
371
+ catch (err) {
372
+ if (err.status === 403) {
373
+ throw new error_1.FirebaseError(`You are not the owner of extension '${clc.bold(extensionRef)}' and don’t have the correct permissions to undeprecate this extension version.`, { status: err.status });
374
+ }
375
+ else if (err.status === 404) {
376
+ throw new error_1.FirebaseError(`Extension version ${clc.bold(extensionRef)} was not found.`);
377
+ }
378
+ else if (err instanceof error_1.FirebaseError) {
379
+ throw err;
380
+ }
381
+ throw new error_1.FirebaseError(`Error occurred undeprecating extension version '${extensionRef}': ${err}`, {
382
+ status: err.status,
383
+ });
384
+ }
385
+ }
386
+ exports.undeprecateExtensionVersion = undeprecateExtensionVersion;
387
+ async function publishExtensionVersion(extensionVersionRef, packageUri, extensionRoot) {
388
+ const ref = refs.parse(extensionVersionRef);
389
+ if (!ref.version) {
390
+ throw new error_1.FirebaseError(`ExtensionVersion ref "${extensionVersionRef}" must supply a version.`);
391
+ }
392
+ const publishRes = await api.request("POST", `/${VERSION}/${refs.toExtensionName(ref)}/versions:publish`, {
311
393
  auth: true,
312
394
  origin: api.extensionsOrigin,
313
395
  data: {
314
- versionId: version,
396
+ versionId: ref.version,
315
397
  packageUri,
316
398
  extensionRoot: extensionRoot !== null && extensionRoot !== void 0 ? extensionRoot : "/",
317
399
  },
@@ -325,12 +407,12 @@ async function publishExtensionVersion(ref, packageUri, extensionRoot) {
325
407
  return pollRes;
326
408
  }
327
409
  exports.publishExtensionVersion = publishExtensionVersion;
328
- async function unpublishExtension(ref) {
329
- const { publisherId, extensionId, version } = parseRef(ref);
330
- if (version) {
331
- throw new error_1.FirebaseError(`Extension reference "${ref}" must not contain a version.`);
410
+ async function unpublishExtension(extensionRef) {
411
+ const ref = refs.parse(extensionRef);
412
+ if (ref.version) {
413
+ throw new error_1.FirebaseError(`Extension reference "${extensionRef}" must not contain a version.`);
332
414
  }
333
- const url = `/${VERSION}/publishers/${publisherId}/extensions/${extensionId}:unpublish`;
415
+ const url = `/${VERSION}/${refs.toExtensionName(ref)}:unpublish`;
334
416
  try {
335
417
  await api.request("POST", url, {
336
418
  auth: true,
@@ -339,23 +421,23 @@ async function unpublishExtension(ref) {
339
421
  }
340
422
  catch (err) {
341
423
  if (err.status === 403) {
342
- throw new error_1.FirebaseError(`You are not the owner of extension '${clc.bold(ref)}' and don’t have the correct permissions to unpublish this extension.`, { status: err.status });
424
+ throw new error_1.FirebaseError(`You are not the owner of extension '${clc.bold(extensionRef)}' and don’t have the correct permissions to unpublish this extension.`, { status: err.status });
343
425
  }
344
426
  else if (err instanceof error_1.FirebaseError) {
345
427
  throw err;
346
428
  }
347
- throw new error_1.FirebaseError(`Error occurred unpublishing extension '${ref}': ${err}`, {
429
+ throw new error_1.FirebaseError(`Error occurred unpublishing extension '${extensionRef}': ${err}`, {
348
430
  status: err.status,
349
431
  });
350
432
  }
351
433
  }
352
434
  exports.unpublishExtension = unpublishExtension;
353
- async function deleteExtension(ref) {
354
- const { publisherId, extensionId, version } = parseRef(ref);
355
- if (version) {
356
- throw new error_1.FirebaseError(`Extension reference "${ref}" must not contain a version.`);
435
+ async function deleteExtension(extensionRef) {
436
+ const ref = refs.parse(extensionRef);
437
+ if (ref.version) {
438
+ throw new error_1.FirebaseError(`Extension reference "${extensionRef}" must not contain a version.`);
357
439
  }
358
- const url = `/${VERSION}/publishers/${publisherId}/extensions/${extensionId}`;
440
+ const url = `/${VERSION}/${refs.toExtensionName(ref)}`;
359
441
  try {
360
442
  await api.request("DELETE", url, {
361
443
  auth: true,
@@ -364,24 +446,24 @@ async function deleteExtension(ref) {
364
446
  }
365
447
  catch (err) {
366
448
  if (err.status === 403) {
367
- throw new error_1.FirebaseError(`You are not the owner of extension '${clc.bold(ref)}' and don’t have the correct permissions to delete this extension.`, { status: err.status });
449
+ throw new error_1.FirebaseError(`You are not the owner of extension '${clc.bold(extensionRef)}' and don’t have the correct permissions to delete this extension.`, { status: err.status });
368
450
  }
369
451
  else if (err.status === 404) {
370
- throw new error_1.FirebaseError(`Extension ${clc.bold(ref)} was not found.`);
452
+ throw new error_1.FirebaseError(`Extension ${clc.bold(extensionRef)} was not found.`);
371
453
  }
372
454
  else if (err instanceof error_1.FirebaseError) {
373
455
  throw err;
374
456
  }
375
- throw new error_1.FirebaseError(`Error occurred delete extension '${ref}': ${err}`, {
457
+ throw new error_1.FirebaseError(`Error occurred delete extension '${extensionRef}': ${err}`, {
376
458
  status: err.status,
377
459
  });
378
460
  }
379
461
  }
380
462
  exports.deleteExtension = deleteExtension;
381
- async function getExtension(ref) {
382
- const { publisherId, extensionId } = parseRef(ref);
463
+ async function getExtension(extensionRef) {
464
+ const ref = refs.parse(extensionRef);
383
465
  try {
384
- const res = await api.request("GET", `/${VERSION}/publishers/${publisherId}/extensions/${extensionId}`, {
466
+ const res = await api.request("GET", `/${VERSION}/${refs.toExtensionName(ref)}`, {
385
467
  auth: true,
386
468
  origin: api.extensionsOrigin,
387
469
  });
@@ -389,50 +471,20 @@ async function getExtension(ref) {
389
471
  }
390
472
  catch (err) {
391
473
  if (err.status === 404) {
392
- throw refNotFoundError(publisherId, extensionId);
474
+ throw refNotFoundError(ref);
393
475
  }
394
476
  else if (err instanceof error_1.FirebaseError) {
395
477
  throw err;
396
478
  }
397
- throw new error_1.FirebaseError(`Failed to query the extension '${clc.bold(ref)}': ${err}`, {
479
+ throw new error_1.FirebaseError(`Failed to query the extension '${clc.bold(extensionRef)}': ${err}`, {
398
480
  status: err.status,
399
481
  });
400
482
  }
401
483
  }
402
484
  exports.getExtension = getExtension;
403
- function refNotFoundError(publisherId, extensionId, versionId) {
404
- const versionRef = `${publisherId}/${extensionId}@${versionId}`;
405
- const extensionRef = `${publisherId}/${extensionId}`;
406
- return new error_1.FirebaseError(`The extension reference '${clc.bold(versionId ? versionRef : extensionRef)}' doesn't exist. This could happen for two reasons:\n` +
407
- ` -The publisher ID '${clc.bold(publisherId)}' doesn't exist or could be misspelled\n` +
408
- ` -The name of the ${versionId ? "extension version" : "extension"} '${clc.bold(versionId ? `${extensionId}@${versionId}` : extensionId)}' doesn't exist or could be misspelled\n\n` +
485
+ function refNotFoundError(ref) {
486
+ 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` +
487
+ ` -The publisher ID '${clc.bold(ref.publisherId)}' doesn't exist or could be misspelled\n` +
488
+ ` -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` +
409
489
  `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 });
410
490
  }
411
- function parseRef(ref) {
412
- const parts = refRegex.exec(ref);
413
- if (parts && (parts.length == 5 || parts.length == 7)) {
414
- const publisherId = parts[1];
415
- const extensionId = parts[2];
416
- const version = parts[4];
417
- if (version && !semver.valid(version) && version !== "latest") {
418
- throw new error_1.FirebaseError(`Extension reference ${ref} contains an invalid version ${version}.`);
419
- }
420
- return { publisherId, extensionId, version };
421
- }
422
- throw new error_1.FirebaseError("Extension reference must be in format '{publisher}/{extension}(@{version})'.");
423
- }
424
- exports.parseRef = parseRef;
425
- function parseExtensionVersionName(extensionVersionName) {
426
- const parts = extensionVersionName.split("/");
427
- if (parts.length !== 6 ||
428
- parts[0] !== "publishers" ||
429
- parts[2] !== "extensions" ||
430
- parts[4] !== "versions") {
431
- throw new error_1.FirebaseError("Extension version name must be in the format `publishers/<publisherID>/extensions/<extensionID>/versions/<versionID>`.");
432
- }
433
- const publisherId = parts[1];
434
- const extensionId = parts[3];
435
- const version = parts[5];
436
- return { publisherId, extensionId, version };
437
- }
438
- exports.parseExtensionVersionName = parseExtensionVersionName;