firebase-tools 10.4.2 → 10.7.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 (108) hide show
  1. package/lib/bin/firebase.js +1 -1
  2. package/lib/command.js +4 -4
  3. package/lib/commands/deploy.js +1 -1
  4. package/lib/commands/emulators-start.js +13 -3
  5. package/lib/commands/ext-configure.js +15 -5
  6. package/lib/commands/ext-dev-emulators-start.js +5 -1
  7. package/lib/commands/ext-export.js +6 -5
  8. package/lib/commands/ext-install.js +28 -44
  9. package/lib/commands/ext-update.js +9 -1
  10. package/lib/commands/functions-delete.js +2 -5
  11. package/lib/commands/functions-secrets-destroy.js +23 -3
  12. package/lib/commands/functions-secrets-prune.js +15 -12
  13. package/lib/commands/functions-secrets-set.js +51 -4
  14. package/lib/commands/hosting-channel-deploy.js +2 -2
  15. package/lib/deploy/database/deploy.js +4 -0
  16. package/lib/deploy/database/index.js +1 -0
  17. package/lib/deploy/extensions/deploy.js +4 -4
  18. package/lib/deploy/extensions/deploymentSummary.js +8 -5
  19. package/lib/deploy/extensions/planner.js +36 -9
  20. package/lib/deploy/extensions/prepare.js +1 -1
  21. package/lib/deploy/extensions/secrets.js +2 -2
  22. package/lib/deploy/extensions/tasks.js +60 -21
  23. package/lib/deploy/functions/backend.js +17 -6
  24. package/lib/deploy/functions/build.js +162 -0
  25. package/lib/deploy/functions/checkIam.js +6 -5
  26. package/lib/deploy/functions/deploy.js +14 -15
  27. package/lib/deploy/functions/ensure.js +4 -4
  28. package/lib/deploy/functions/functionsDeployHelper.js +54 -23
  29. package/lib/deploy/functions/prepare.js +92 -39
  30. package/lib/deploy/functions/prepareFunctionsUpload.js +16 -21
  31. package/lib/deploy/functions/pricing.js +6 -3
  32. package/lib/deploy/functions/prompts.js +1 -7
  33. package/lib/deploy/functions/release/fabricator.js +44 -5
  34. package/lib/deploy/functions/release/index.js +31 -6
  35. package/lib/deploy/functions/release/planner.js +10 -8
  36. package/lib/deploy/functions/release/reporter.js +14 -11
  37. package/lib/deploy/functions/runtimes/discovery/parsing.js +12 -6
  38. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +61 -13
  39. package/lib/deploy/functions/runtimes/node/index.js +1 -1
  40. package/lib/deploy/functions/runtimes/node/parseRuntimeAndValidateSDK.js +3 -3
  41. package/lib/deploy/functions/runtimes/node/parseTriggers.js +29 -24
  42. package/lib/deploy/functions/runtimes/node/versioning.js +2 -2
  43. package/lib/deploy/functions/services/auth.js +95 -0
  44. package/lib/deploy/functions/services/index.js +41 -21
  45. package/lib/deploy/functions/services/storage.js +1 -6
  46. package/lib/deploy/functions/validate.js +8 -5
  47. package/lib/deploy/hosting/args.js +2 -0
  48. package/lib/deploy/hosting/convertConfig.js +37 -8
  49. package/lib/deploy/hosting/deploy.js +3 -3
  50. package/lib/deploy/hosting/prepare.js +2 -2
  51. package/lib/deploy/hosting/release.js +6 -2
  52. package/lib/deploy/index.js +82 -93
  53. package/lib/deploy/remoteconfig/deploy.js +4 -0
  54. package/lib/deploy/remoteconfig/index.js +3 -1
  55. package/lib/emulator/auth/operations.js +26 -20
  56. package/lib/emulator/auth/state.js +79 -43
  57. package/lib/emulator/auth/utils.js +3 -25
  58. package/lib/emulator/commandUtils.js +72 -2
  59. package/lib/emulator/controller.js +14 -5
  60. package/lib/emulator/downloadableEmulators.js +47 -24
  61. package/lib/emulator/extensions/postinstall.js +41 -0
  62. package/lib/emulator/extensions/validation.js +2 -2
  63. package/lib/emulator/extensionsEmulator.js +85 -21
  64. package/lib/emulator/functionsEmulator.js +79 -7
  65. package/lib/emulator/functionsEmulatorShared.js +36 -21
  66. package/lib/emulator/registry.js +34 -12
  67. package/lib/emulator/shared/request.js +19 -0
  68. package/lib/emulator/storage/apis/firebase.js +32 -35
  69. package/lib/emulator/storage/apis/gcloud.js +84 -66
  70. package/lib/emulator/storage/files.js +56 -52
  71. package/lib/emulator/storage/index.js +23 -3
  72. package/lib/emulator/storage/metadata.js +18 -8
  73. package/lib/emulator/storage/rules/manager.js +7 -17
  74. package/lib/emulator/storage/rules/utils.js +11 -3
  75. package/lib/emulator/storage/server.js +38 -12
  76. package/lib/ensureApiEnabled.js +8 -4
  77. package/lib/extensions/askUserForParam.js +14 -11
  78. package/lib/extensions/changelog.js +1 -1
  79. package/lib/extensions/emulator/optionsHelper.js +9 -10
  80. package/lib/extensions/emulator/specHelper.js +7 -1
  81. package/lib/extensions/emulator/triggerHelper.js +11 -14
  82. package/lib/extensions/extensionsApi.js +2 -1
  83. package/lib/extensions/extensionsHelper.js +30 -24
  84. package/lib/extensions/manifest.js +28 -8
  85. package/lib/extensions/paramHelper.js +19 -13
  86. package/lib/extensions/provisioningHelper.js +2 -2
  87. package/lib/extensions/warnings.js +3 -3
  88. package/lib/functions/env.js +10 -2
  89. package/lib/functions/events/index.js +7 -0
  90. package/lib/functions/events/v1.js +6 -0
  91. package/lib/functions/projectConfig.js +24 -3
  92. package/lib/functions/runtimeConfigExport.js +10 -6
  93. package/lib/functions/secrets.js +99 -6
  94. package/lib/gcp/cloudfunctions.js +37 -18
  95. package/lib/gcp/cloudfunctionsv2.js +41 -25
  96. package/lib/gcp/cloudtasks.js +5 -3
  97. package/lib/gcp/identityPlatform.js +44 -0
  98. package/lib/gcp/secretManager.js +2 -2
  99. package/lib/metaprogramming.js +2 -0
  100. package/lib/previews.js +1 -1
  101. package/lib/serve/hosting.js +25 -12
  102. package/lib/serve/index.js +6 -0
  103. package/lib/track.js +15 -21
  104. package/lib/utils.js +30 -1
  105. package/npm-shrinkwrap.json +44 -2
  106. package/package.json +4 -1
  107. package/schema/firebase-config.json +6 -0
  108. package/lib/emulator/storage/list.js +0 -18
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
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.EmulatedTrigger = exports.HttpConstants = void 0;
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
4
  const _ = require("lodash");
5
5
  const os = require("os");
6
6
  const path = require("path");
@@ -8,9 +8,11 @@ const fs = require("fs");
8
8
  const backend = require("../deploy/functions/backend");
9
9
  const constants_1 = require("./constants");
10
10
  const proto_1 = require("../gcp/proto");
11
- const logger_1 = require("../logger");
12
11
  const manifest_1 = require("../extensions/manifest");
13
12
  const extensionsHelper_1 = require("../extensions/extensionsHelper");
13
+ const postinstall_1 = require("./extensions/postinstall");
14
+ const services_1 = require("../deploy/functions/services");
15
+ const prepare_1 = require("../deploy/functions/prepare");
14
16
  const memoryLookup = {
15
17
  "128MB": 128,
16
18
  "256MB": 256,
@@ -33,12 +35,7 @@ class EmulatedTrigger {
33
35
  return memoryLookup[this.definition.availableMemoryMb || "128MB"] * 1024 * 1024;
34
36
  }
35
37
  get timeoutMs() {
36
- if (typeof this.definition.timeout === "number") {
37
- return this.definition.timeout * 1000;
38
- }
39
- else {
40
- return parseInt((this.definition.timeout || "60s").split("s")[0], 10) * 1000;
41
- }
38
+ return (this.definition.timeoutSeconds || 60) * 1000;
42
39
  }
43
40
  getRawFunction() {
44
41
  if (!this.module) {
@@ -49,6 +46,14 @@ class EmulatedTrigger {
49
46
  }
50
47
  }
51
48
  exports.EmulatedTrigger = EmulatedTrigger;
49
+ function prepareEndpoints(endpoints) {
50
+ const bkend = backend.of(...endpoints);
51
+ for (const ep of endpoints) {
52
+ (0, services_1.serviceForEndpoint)(ep).validateTrigger(ep, bkend);
53
+ }
54
+ (0, prepare_1.inferBlockingDetails)(bkend);
55
+ }
56
+ exports.prepareEndpoints = prepareEndpoints;
52
57
  function emulatedFunctionsFromEndpoints(endpoints) {
53
58
  const regionDefinitions = [];
54
59
  for (const endpoint of endpoints) {
@@ -62,7 +67,7 @@ function emulatedFunctionsFromEndpoints(endpoints) {
62
67
  name: endpoint.id,
63
68
  id: `${endpoint.region}-${endpoint.id}`,
64
69
  };
65
- (0, proto_1.copyIfPresent)(def, endpoint, "timeout", "availableMemoryMb", "labels", "platform", "secretEnvironmentVariables");
70
+ (0, proto_1.copyIfPresent)(def, endpoint, "availableMemoryMb", "labels", "timeoutSeconds", "platform", "secretEnvironmentVariables");
66
71
  if (backend.isHttpsTriggered(endpoint)) {
67
72
  def.httpsTrigger = endpoint.httpsTrigger;
68
73
  }
@@ -73,25 +78,20 @@ function emulatedFunctionsFromEndpoints(endpoints) {
73
78
  else if (backend.isEventTriggered(endpoint)) {
74
79
  const eventTrigger = endpoint.eventTrigger;
75
80
  if (endpoint.platform === "gcfv1") {
76
- const resourceFilter = backend.findEventFilter(endpoint, "resource");
77
- if (!resourceFilter) {
78
- logger_1.logger.debug(`Invalid event trigger ${JSON.stringify(endpoint)}, expected event filter with resource attribute. Skipping.`);
79
- continue;
80
- }
81
81
  def.eventTrigger = {
82
82
  eventType: eventTrigger.eventType,
83
- resource: resourceFilter.value,
83
+ resource: eventTrigger.eventFilters.resource,
84
84
  };
85
85
  }
86
86
  else {
87
- const [eventFilter] = endpoint.eventTrigger.eventFilters;
88
- if (!eventFilter) {
89
- logger_1.logger.debug(`Invalid event trigger ${JSON.stringify(endpoint)}, expected at least one event filter. Skipping.`);
87
+ const { resource, topic, bucket } = endpoint.eventTrigger.eventFilters;
88
+ const eventResource = resource || topic || bucket;
89
+ if (!eventResource) {
90
90
  continue;
91
91
  }
92
92
  def.eventTrigger = {
93
93
  eventType: eventTrigger.eventType,
94
- resource: eventFilter.value,
94
+ resource: eventResource,
95
95
  };
96
96
  }
97
97
  }
@@ -99,6 +99,12 @@ function emulatedFunctionsFromEndpoints(endpoints) {
99
99
  def.eventTrigger = { eventType: "pubsub", resource: "" };
100
100
  def.schedule = endpoint.scheduleTrigger;
101
101
  }
102
+ else if (backend.isBlockingTriggered(endpoint)) {
103
+ def.blockingTrigger = {
104
+ eventType: endpoint.blockingTrigger.eventType,
105
+ options: endpoint.blockingTrigger.options || {},
106
+ };
107
+ }
102
108
  else {
103
109
  }
104
110
  regionDefinitions.push(def);
@@ -146,6 +152,9 @@ function getFunctionService(def) {
146
152
  if (def.eventTrigger) {
147
153
  return (_a = def.eventTrigger.service) !== null && _a !== void 0 ? _a : getServiceFromEventType(def.eventTrigger.eventType);
148
154
  }
155
+ if (def.blockingTrigger) {
156
+ return def.blockingTrigger.eventType;
157
+ }
149
158
  return "unknown";
150
159
  }
151
160
  exports.getFunctionService = getFunctionService;
@@ -244,7 +253,7 @@ function getSecretLocalPath(backend, projectDir) {
244
253
  }
245
254
  exports.getSecretLocalPath = getSecretLocalPath;
246
255
  function toBackendInfo(e, cf3Triggers) {
247
- var _a;
256
+ var _a, _b;
248
257
  const envWithSecrets = Object.assign({}, e.env);
249
258
  for (const s of e.secretEnv) {
250
259
  envWithSecrets[s.key] = backend.secretVersionName(s);
@@ -252,10 +261,16 @@ function toBackendInfo(e, cf3Triggers) {
252
261
  let extensionVersion = e.extensionVersion;
253
262
  if (extensionVersion) {
254
263
  extensionVersion = (0, extensionsHelper_1.substituteParams)(extensionVersion, e.env);
264
+ if ((_a = extensionVersion.spec) === null || _a === void 0 ? void 0 : _a.postinstallContent) {
265
+ extensionVersion.spec.postinstallContent = (0, postinstall_1.replaceConsoleLinks)(extensionVersion.spec.postinstallContent);
266
+ }
255
267
  }
256
268
  let extensionSpec = e.extensionSpec;
257
269
  if (extensionSpec) {
258
270
  extensionSpec = (0, extensionsHelper_1.substituteParams)(extensionSpec, e.env);
271
+ if (extensionSpec === null || extensionSpec === void 0 ? void 0 : extensionSpec.postinstallContent) {
272
+ extensionSpec.postinstallContent = (0, postinstall_1.replaceConsoleLinks)(extensionSpec.postinstallContent);
273
+ }
259
274
  }
260
275
  return JSON.parse(JSON.stringify({
261
276
  directory: e.functionsDir,
@@ -264,7 +279,7 @@ function toBackendInfo(e, cf3Triggers) {
264
279
  extension: e.extension,
265
280
  extensionVersion: extensionVersion,
266
281
  extensionSpec: extensionSpec,
267
- functionTriggers: (_a = e.predefinedTriggers) !== null && _a !== void 0 ? _a : cf3Triggers,
282
+ functionTriggers: (_b = e.predefinedTriggers) !== null && _b !== void 0 ? _b : cf3Triggers,
268
283
  }));
269
284
  }
270
285
  exports.toBackendInfo = toBackendInfo;
@@ -14,11 +14,10 @@ class EmulatorRegistry {
14
14
  }
15
15
  this.set(instance.getName(), instance);
16
16
  await instance.start();
17
- const info = instance.getInfo();
18
- await portUtils.waitForPortClosed(info.port, info.host);
19
- }
20
- static registerExtensionsEmulator() {
21
- this.extensionsEmulatorRegistered = true;
17
+ if (instance.getName() !== types_1.Emulators.EXTENSIONS) {
18
+ const info = instance.getInfo();
19
+ await portUtils.waitForPortClosed(info.port, info.host);
20
+ }
22
21
  }
23
22
  static async stop(name) {
24
23
  emulatorLogger_1.EmulatorLogger.forEmulator(name).logLabeled("BULLET", name, `Stopping ${constants_1.Constants.description(name)}`);
@@ -57,7 +56,7 @@ class EmulatorRegistry {
57
56
  }
58
57
  static isRunning(emulator) {
59
58
  if (emulator === types_1.Emulators.EXTENSIONS) {
60
- return this.extensionsEmulatorRegistered && this.isRunning(types_1.Emulators.FUNCTIONS);
59
+ return this.INSTANCES.get(emulator) !== undefined && this.isRunning(types_1.Emulators.FUNCTIONS);
61
60
  }
62
61
  const instance = this.INSTANCES.get(emulator);
63
62
  return instance !== undefined;
@@ -89,12 +88,36 @@ class EmulatorRegistry {
89
88
  return `${host}:${port}`;
90
89
  }
91
90
  }
92
- static getPort(emulator) {
93
- const instance = this.INSTANCES.get(emulator);
94
- if (!instance) {
95
- return undefined;
91
+ static url(emulator, req) {
92
+ const url = new URL("http://unknown/");
93
+ if (req) {
94
+ url.protocol = req.protocol;
95
+ const host = req.headers.host;
96
+ if (host) {
97
+ url.host = host;
98
+ return url;
99
+ }
100
+ }
101
+ const info = EmulatorRegistry.getInfo(emulator);
102
+ if (info) {
103
+ if (info.host === "0.0.0.0") {
104
+ url.hostname = "127.0.0.1";
105
+ }
106
+ else if (info.host === "::") {
107
+ url.hostname = "[::1]";
108
+ }
109
+ else if (info.host.includes(":")) {
110
+ url.hostname = `[${info.host}]`;
111
+ }
112
+ else {
113
+ url.hostname = info.host;
114
+ }
115
+ url.port = info.port.toString();
116
+ }
117
+ else {
118
+ console.warn(`Cannot determine host and port of ${emulator}`);
96
119
  }
97
- return instance.getInfo().port;
120
+ return url;
98
121
  }
99
122
  static set(emulator, instance) {
100
123
  this.INSTANCES.set(emulator, instance);
@@ -104,5 +127,4 @@ class EmulatorRegistry {
104
127
  }
105
128
  }
106
129
  exports.EmulatorRegistry = EmulatorRegistry;
107
- EmulatorRegistry.extensionsEmulatorRegistered = false;
108
130
  EmulatorRegistry.INSTANCES = new Map();
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.reqBodyToBuffer = void 0;
4
+ async function reqBodyToBuffer(req) {
5
+ if (req.body instanceof Buffer) {
6
+ return Buffer.from(req.body);
7
+ }
8
+ const bufs = [];
9
+ req.on("data", (data) => {
10
+ bufs.push(data);
11
+ });
12
+ await new Promise((resolve) => {
13
+ req.on("end", () => {
14
+ resolve();
15
+ });
16
+ });
17
+ return Buffer.concat(bufs);
18
+ }
19
+ exports.reqBodyToBuffer = reqBodyToBuffer;
@@ -10,6 +10,7 @@ const registry_1 = require("../../registry");
10
10
  const multipart_1 = require("../multipart");
11
11
  const errors_1 = require("../errors");
12
12
  const upload_1 = require("../upload");
13
+ const request_1 = require("../../shared/request");
13
14
  function createFirebaseEndpoints(emulator) {
14
15
  const firebaseStorageAPI = (0, express_1.Router)();
15
16
  const { storageLayer, uploadService } = emulator;
@@ -71,7 +72,7 @@ function createFirebaseEndpoints(emulator) {
71
72
  let metadata;
72
73
  let data;
73
74
  try {
74
- ({ metadata, data } = await storageLayer.handleGetObject({
75
+ ({ metadata, data } = await storageLayer.getObject({
75
76
  bucketId: req.params.bucketId,
76
77
  decodedObjectId: decodeURIComponent(req.params.objectId),
77
78
  authorization: req.header("authorization"),
@@ -117,11 +118,11 @@ function createFirebaseEndpoints(emulator) {
117
118
  return res.json(new metadata_1.OutgoingFirebaseMetadata(metadata));
118
119
  });
119
120
  firebaseStorageAPI.get("/b/:bucketId/o", async (req, res) => {
120
- var _a, _b;
121
+ var _a, _b, _c, _d, _e;
121
122
  const maxResults = (_a = req.query.maxResults) === null || _a === void 0 ? void 0 : _a.toString();
122
- let response;
123
+ let listResponse;
123
124
  try {
124
- response = await storageLayer.handleListObjects({
125
+ listResponse = await storageLayer.listObjects({
125
126
  bucketId: req.params.bucketId,
126
127
  prefix: req.query.prefix ? req.query.prefix.toString() : "",
127
128
  delimiter: req.query.delimiter ? req.query.delimiter.toString() : "",
@@ -141,23 +142,14 @@ function createFirebaseEndpoints(emulator) {
141
142
  }
142
143
  throw err;
143
144
  }
144
- return res.json(response);
145
- });
146
- const reqBodyToBuffer = async (req) => {
147
- if (req.body instanceof Buffer) {
148
- return Buffer.from(req.body);
149
- }
150
- const bufs = [];
151
- req.on("data", (data) => {
152
- bufs.push(data);
145
+ return res.status(200).json({
146
+ nextPageToken: listResponse.nextPageToken,
147
+ prefixes: (_c = listResponse.prefixes) !== null && _c !== void 0 ? _c : [],
148
+ items: (_e = (_d = listResponse.items) === null || _d === void 0 ? void 0 : _d.map((item) => {
149
+ return { name: item.name, bucket: item.bucket };
150
+ })) !== null && _e !== void 0 ? _e : [],
153
151
  });
154
- await new Promise((resolve) => {
155
- req.on("end", () => {
156
- resolve();
157
- });
158
- });
159
- return Buffer.concat(bufs);
160
- };
152
+ });
161
153
  const handleUpload = async (req, res) => {
162
154
  if (!req.query.name) {
163
155
  res.sendStatus(400);
@@ -174,14 +166,14 @@ function createFirebaseEndpoints(emulator) {
174
166
  let metadataRaw;
175
167
  let dataRaw;
176
168
  try {
177
- ({ metadataRaw, dataRaw } = (0, multipart_1.parseObjectUploadMultipartRequest)(contentTypeHeader, await reqBodyToBuffer(req)));
169
+ ({ metadataRaw, dataRaw } = (0, multipart_1.parseObjectUploadMultipartRequest)(contentTypeHeader, await (0, request_1.reqBodyToBuffer)(req)));
178
170
  }
179
171
  catch (err) {
180
172
  if (err instanceof Error) {
181
173
  return res.status(400).json({
182
174
  error: {
183
175
  code: 400,
184
- message: err.toString(),
176
+ message: err.message,
185
177
  },
186
178
  });
187
179
  }
@@ -196,7 +188,7 @@ function createFirebaseEndpoints(emulator) {
196
188
  });
197
189
  let metadata;
198
190
  try {
199
- metadata = await storageLayer.handleUploadObject(upload);
191
+ metadata = await storageLayer.uploadObject(upload);
200
192
  }
201
193
  catch (err) {
202
194
  if (err instanceof errors_1.ForbiddenError) {
@@ -209,7 +201,7 @@ function createFirebaseEndpoints(emulator) {
209
201
  }
210
202
  throw err;
211
203
  }
212
- metadata.addDownloadToken();
204
+ metadata.addDownloadToken(false);
213
205
  return res.status(200).json(new metadata_1.OutgoingFirebaseMetadata(metadata));
214
206
  }
215
207
  const uploadCommand = req.header("x-goog-upload-command");
@@ -227,9 +219,13 @@ function createFirebaseEndpoints(emulator) {
227
219
  res.header("x-goog-upload-chunk-granularity", "10000");
228
220
  res.header("x-goog-upload-control-url", "");
229
221
  res.header("x-goog-upload-status", "active");
230
- const emulatorInfo = registry_1.EmulatorRegistry.getInfo(types_1.Emulators.STORAGE);
231
- res.header("x-goog-upload-url", `http://${req.hostname}:${emulatorInfo === null || emulatorInfo === void 0 ? void 0 : emulatorInfo.port}/v0/b/${bucketId}/o?name=${objectId}&upload_id=${upload.id}&upload_protocol=resumable`);
232
222
  res.header("x-gupload-uploadid", upload.id);
223
+ const uploadUrl = registry_1.EmulatorRegistry.url(types_1.Emulators.STORAGE, req);
224
+ uploadUrl.pathname = `/v0/b/${bucketId}/o`;
225
+ uploadUrl.searchParams.set("name", objectId);
226
+ uploadUrl.searchParams.set("upload_id", upload.id);
227
+ uploadUrl.searchParams.set("upload_protocol", "resumable");
228
+ res.header("x-goog-upload-url", uploadUrl.toString());
233
229
  return res.sendStatus(200);
234
230
  }
235
231
  if (!req.query.upload_id) {
@@ -268,7 +264,7 @@ function createFirebaseEndpoints(emulator) {
268
264
  if (uploadCommand.includes("upload")) {
269
265
  let upload;
270
266
  try {
271
- upload = uploadService.continueResumableUpload(uploadId, await reqBodyToBuffer(req));
267
+ upload = uploadService.continueResumableUpload(uploadId, await (0, request_1.reqBodyToBuffer)(req));
272
268
  }
273
269
  catch (err) {
274
270
  if (err instanceof errors_1.NotFoundError) {
@@ -299,9 +295,9 @@ function createFirebaseEndpoints(emulator) {
299
295
  }
300
296
  throw err;
301
297
  }
302
- let metadata;
298
+ let storedMetadata;
303
299
  try {
304
- metadata = await storageLayer.handleUploadObject(upload);
300
+ storedMetadata = await storageLayer.uploadObject(upload);
305
301
  }
306
302
  catch (err) {
307
303
  if (err instanceof errors_1.ForbiddenError) {
@@ -314,8 +310,9 @@ function createFirebaseEndpoints(emulator) {
314
310
  }
315
311
  throw err;
316
312
  }
317
- metadata.addDownloadToken();
318
- return res.status(200).json(new metadata_1.OutgoingFirebaseMetadata(metadata));
313
+ res.header("x-goog-upload-status", "final");
314
+ storedMetadata.addDownloadToken(false);
315
+ return res.status(200).json(new metadata_1.OutgoingFirebaseMetadata(storedMetadata));
319
316
  }
320
317
  return res.sendStatus(400);
321
318
  };
@@ -333,7 +330,7 @@ function createFirebaseEndpoints(emulator) {
333
330
  return res.sendStatus(400);
334
331
  }
335
332
  try {
336
- metadata = storageLayer.handleCreateDownloadToken({
333
+ metadata = storageLayer.createDownloadToken({
337
334
  bucketId,
338
335
  decodedObjectId,
339
336
  authorization,
@@ -356,7 +353,7 @@ function createFirebaseEndpoints(emulator) {
356
353
  }
357
354
  else {
358
355
  try {
359
- metadata = storageLayer.handleDeleteDownloadToken({
356
+ metadata = storageLayer.deleteDownloadToken({
360
357
  bucketId,
361
358
  decodedObjectId,
362
359
  token: (_b = (_a = req.query["delete_token"]) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : "",
@@ -390,7 +387,7 @@ function createFirebaseEndpoints(emulator) {
390
387
  const handleMetadataUpdate = async (req, res) => {
391
388
  let metadata;
392
389
  try {
393
- metadata = await storageLayer.handleUpdateObjectMetadata({
390
+ metadata = await storageLayer.updateObjectMetadata({
394
391
  bucketId: req.params.bucketId,
395
392
  decodedObjectId: decodeURIComponent(req.params.objectId),
396
393
  metadata: req.body,
@@ -427,7 +424,7 @@ function createFirebaseEndpoints(emulator) {
427
424
  firebaseStorageAPI.post("/b/:bucketId/o/:objectId?", handleObjectPostRequest);
428
425
  firebaseStorageAPI.delete("/b/:bucketId/o/:objectId", async (req, res) => {
429
426
  try {
430
- await storageLayer.handleDeleteObject({
427
+ await storageLayer.deleteObject({
431
428
  bucketId: req.params.bucketId,
432
429
  decodedObjectId: decodeURIComponent(req.params.objectId),
433
430
  authorization: req.header("authorization"),