firebase-tools 10.4.1 → 10.6.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 (57) hide show
  1. package/lib/bin/firebase.js +1 -1
  2. package/lib/commands/emulators-start.js +6 -1
  3. package/lib/commands/ext-configure.js +4 -4
  4. package/lib/commands/ext-dev-emulators-start.js +5 -1
  5. package/lib/commands/ext-install.js +5 -4
  6. package/lib/commands/ext-update.js +2 -1
  7. package/lib/commands/functions-secrets-destroy.js +23 -3
  8. package/lib/commands/functions-secrets-prune.js +15 -12
  9. package/lib/commands/functions-secrets-set.js +51 -4
  10. package/lib/deploy/functions/backend.js +1 -5
  11. package/lib/deploy/functions/checkIam.js +44 -1
  12. package/lib/deploy/functions/prepare.js +13 -3
  13. package/lib/deploy/functions/release/fabricator.js +1 -3
  14. package/lib/deploy/functions/release/index.js +21 -0
  15. package/lib/deploy/functions/release/planner.js +1 -2
  16. package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +11 -10
  17. package/lib/deploy/functions/runtimes/node/index.js +1 -1
  18. package/lib/deploy/functions/runtimes/node/parseTriggers.js +5 -19
  19. package/lib/deploy/functions/services/firebaseAlerts.js +1 -17
  20. package/lib/deploy/functions/services/index.js +2 -1
  21. package/lib/deploy/functions/services/storage.js +1 -6
  22. package/lib/emulator/auth/operations.js +21 -20
  23. package/lib/emulator/auth/state.js +79 -43
  24. package/lib/emulator/commandUtils.js +72 -2
  25. package/lib/emulator/controller.js +9 -0
  26. package/lib/emulator/downloadableEmulators.js +13 -6
  27. package/lib/emulator/extensions/postinstall.js +41 -0
  28. package/lib/emulator/functionsEmulator.js +8 -18
  29. package/lib/emulator/functionsEmulatorShared.js +41 -19
  30. package/lib/emulator/shared/request.js +19 -0
  31. package/lib/emulator/storage/apis/firebase.js +25 -33
  32. package/lib/emulator/storage/apis/gcloud.js +78 -63
  33. package/lib/emulator/storage/files.js +48 -52
  34. package/lib/emulator/storage/index.js +23 -3
  35. package/lib/emulator/storage/metadata.js +18 -8
  36. package/lib/emulator/storage/rules/manager.js +7 -17
  37. package/lib/emulator/storage/rules/utils.js +11 -3
  38. package/lib/emulator/storage/server.js +38 -12
  39. package/lib/extensions/askUserForParam.js +25 -20
  40. package/lib/extensions/emulator/optionsHelper.js +5 -7
  41. package/lib/extensions/emulator/triggerHelper.js +11 -14
  42. package/lib/extensions/extensionsApi.js +2 -1
  43. package/lib/extensions/extensionsHelper.js +11 -2
  44. package/lib/extensions/manifest.js +1 -1
  45. package/lib/extensions/paramHelper.js +23 -13
  46. package/lib/functions/env.js +10 -2
  47. package/lib/functions/runtimeConfigExport.js +10 -6
  48. package/lib/functions/secrets.js +99 -6
  49. package/lib/gcp/cloudfunctions.js +6 -13
  50. package/lib/gcp/cloudfunctionsv2.js +14 -23
  51. package/lib/gcp/cloudtasks.js +5 -3
  52. package/lib/gcp/secretManager.js +1 -1
  53. package/lib/requirePermissions.js +4 -1
  54. package/lib/utils.js +30 -1
  55. package/npm-shrinkwrap.json +2 -2
  56. package/package.json +1 -1
  57. package/lib/emulator/storage/list.js +0 -18
@@ -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");
@@ -268,7 +260,7 @@ function createFirebaseEndpoints(emulator) {
268
260
  if (uploadCommand.includes("upload")) {
269
261
  let upload;
270
262
  try {
271
- upload = uploadService.continueResumableUpload(uploadId, await reqBodyToBuffer(req));
263
+ upload = uploadService.continueResumableUpload(uploadId, await (0, request_1.reqBodyToBuffer)(req));
272
264
  }
273
265
  catch (err) {
274
266
  if (err instanceof errors_1.NotFoundError) {
@@ -299,9 +291,9 @@ function createFirebaseEndpoints(emulator) {
299
291
  }
300
292
  throw err;
301
293
  }
302
- let metadata;
294
+ let storedMetadata;
303
295
  try {
304
- metadata = await storageLayer.handleUploadObject(upload);
296
+ storedMetadata = await storageLayer.uploadObject(upload);
305
297
  }
306
298
  catch (err) {
307
299
  if (err instanceof errors_1.ForbiddenError) {
@@ -314,8 +306,8 @@ function createFirebaseEndpoints(emulator) {
314
306
  }
315
307
  throw err;
316
308
  }
317
- metadata.addDownloadToken();
318
- return res.status(200).json(new metadata_1.OutgoingFirebaseMetadata(metadata));
309
+ storedMetadata.addDownloadToken(false);
310
+ return res.status(200).json(new metadata_1.OutgoingFirebaseMetadata(storedMetadata));
319
311
  }
320
312
  return res.sendStatus(400);
321
313
  };
@@ -333,7 +325,7 @@ function createFirebaseEndpoints(emulator) {
333
325
  return res.sendStatus(400);
334
326
  }
335
327
  try {
336
- metadata = storageLayer.handleCreateDownloadToken({
328
+ metadata = storageLayer.createDownloadToken({
337
329
  bucketId,
338
330
  decodedObjectId,
339
331
  authorization,
@@ -356,7 +348,7 @@ function createFirebaseEndpoints(emulator) {
356
348
  }
357
349
  else {
358
350
  try {
359
- metadata = storageLayer.handleDeleteDownloadToken({
351
+ metadata = storageLayer.deleteDownloadToken({
360
352
  bucketId,
361
353
  decodedObjectId,
362
354
  token: (_b = (_a = req.query["delete_token"]) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : "",
@@ -390,7 +382,7 @@ function createFirebaseEndpoints(emulator) {
390
382
  const handleMetadataUpdate = async (req, res) => {
391
383
  let metadata;
392
384
  try {
393
- metadata = await storageLayer.handleUpdateObjectMetadata({
385
+ metadata = await storageLayer.updateObjectMetadata({
394
386
  bucketId: req.params.bucketId,
395
387
  decodedObjectId: decodeURIComponent(req.params.objectId),
396
388
  metadata: req.body,
@@ -427,7 +419,7 @@ function createFirebaseEndpoints(emulator) {
427
419
  firebaseStorageAPI.post("/b/:bucketId/o/:objectId?", handleObjectPostRequest);
428
420
  firebaseStorageAPI.delete("/b/:bucketId/o/:objectId", async (req, res) => {
429
421
  try {
430
- await storageLayer.handleDeleteObject({
422
+ await storageLayer.deleteObject({
431
423
  bucketId: req.params.bucketId,
432
424
  decodedObjectId: decodeURIComponent(req.params.objectId),
433
425
  authorization: req.header("authorization"),
@@ -11,33 +11,34 @@ const crc_1 = require("../crc");
11
11
  const multipart_1 = require("../multipart");
12
12
  const upload_1 = require("../upload");
13
13
  const errors_1 = require("../errors");
14
+ const request_1 = require("../../shared/request");
14
15
  function createCloudEndpoints(emulator) {
15
16
  const gcloudStorageAPI = (0, express_1.Router)();
16
- const { storageLayer, uploadService } = emulator;
17
+ const { adminStorageLayer, uploadService } = emulator;
17
18
  gcloudStorageAPI.use(/.*\/b\/(.+?)\/.*/, (req, res, next) => {
18
- storageLayer.createBucket(req.params[0]);
19
+ adminStorageLayer.createBucket(req.params[0]);
19
20
  next();
20
21
  });
21
22
  gcloudStorageAPI.get("/b", async (req, res) => {
22
23
  res.json({
23
24
  kind: "storage#buckets",
24
- items: await storageLayer.listBuckets(),
25
+ items: await adminStorageLayer.listBuckets(),
25
26
  });
26
27
  });
27
28
  gcloudStorageAPI.get(["/b/:bucketId/o/:objectId", "/download/storage/v1/b/:bucketId/o/:objectId"], async (req, res) => {
28
29
  let getObjectResponse;
29
30
  try {
30
- getObjectResponse = await storageLayer.handleGetObject({
31
+ getObjectResponse = await adminStorageLayer.getObject({
31
32
  bucketId: req.params.bucketId,
32
33
  decodedObjectId: req.params.objectId,
33
- }, true);
34
+ });
34
35
  }
35
36
  catch (err) {
36
37
  if (err instanceof errors_1.NotFoundError) {
37
38
  return sendObjectNotFound(req, res);
38
39
  }
39
40
  if (err instanceof errors_1.ForbiddenError) {
40
- throw new Error("Request failed unexpectedly due to Firebase Rules.");
41
+ return res.sendStatus(403);
41
42
  }
42
43
  throw err;
43
44
  }
@@ -49,67 +50,67 @@ function createCloudEndpoints(emulator) {
49
50
  gcloudStorageAPI.patch("/b/:bucketId/o/:objectId", async (req, res) => {
50
51
  let updatedMetadata;
51
52
  try {
52
- updatedMetadata = await storageLayer.handleUpdateObjectMetadata({
53
+ updatedMetadata = await adminStorageLayer.updateObjectMetadata({
53
54
  bucketId: req.params.bucketId,
54
55
  decodedObjectId: req.params.objectId,
55
56
  metadata: req.body,
56
- }, true);
57
+ });
57
58
  }
58
59
  catch (err) {
59
60
  if (err instanceof errors_1.NotFoundError) {
60
61
  return sendObjectNotFound(req, res);
61
62
  }
62
63
  if (err instanceof errors_1.ForbiddenError) {
63
- throw new Error("Request failed unexpectedly due to Firebase Rules.");
64
+ return res.sendStatus(403);
64
65
  }
65
66
  throw err;
66
67
  }
67
68
  return res.json(new metadata_1.CloudStorageObjectMetadata(updatedMetadata));
68
69
  });
69
- gcloudStorageAPI.get("/b/:bucketId/o", (req, res) => {
70
- let maxRes = undefined;
71
- if (req.query.maxResults) {
72
- maxRes = +req.query.maxResults.toString();
73
- }
74
- const delimiter = req.query.delimiter ? req.query.delimiter.toString() : "";
75
- const pageToken = req.query.pageToken ? req.query.pageToken.toString() : undefined;
76
- const prefix = req.query.prefix ? req.query.prefix.toString() : "";
77
- const listResult = storageLayer.listItems(req.params.bucketId, prefix, delimiter, pageToken, maxRes);
78
- res.json(Object.assign(Object.assign({}, listResult), { kind: "#storage/objects" }));
70
+ gcloudStorageAPI.get("/b/:bucketId/o", async (req, res) => {
71
+ var _a;
72
+ let listResponse;
73
+ try {
74
+ listResponse = await adminStorageLayer.listObjects({
75
+ bucketId: req.params.bucketId,
76
+ prefix: req.query.prefix ? req.query.prefix.toString() : "",
77
+ delimiter: req.query.delimiter ? req.query.delimiter.toString() : "",
78
+ pageToken: req.query.pageToken ? req.query.pageToken.toString() : undefined,
79
+ maxResults: req.query.maxResults ? +req.query.maxResults.toString() : undefined,
80
+ authorization: req.header("authorization"),
81
+ });
82
+ }
83
+ catch (err) {
84
+ if (err instanceof errors_1.ForbiddenError) {
85
+ return res.sendStatus(403);
86
+ }
87
+ throw err;
88
+ }
89
+ return res.status(200).json({
90
+ kind: "#storage/objects",
91
+ nextPageToken: listResponse.nextPageToken,
92
+ prefixes: listResponse.prefixes,
93
+ items: (_a = listResponse.items) === null || _a === void 0 ? void 0 : _a.map((item) => new metadata_1.CloudStorageObjectMetadata(item)),
94
+ });
79
95
  });
80
96
  gcloudStorageAPI.delete("/b/:bucketId/o/:objectId", async (req, res) => {
81
97
  try {
82
- await storageLayer.handleDeleteObject({
98
+ await adminStorageLayer.deleteObject({
83
99
  bucketId: req.params.bucketId,
84
100
  decodedObjectId: req.params.objectId,
85
- }, true);
101
+ });
86
102
  }
87
103
  catch (err) {
88
104
  if (err instanceof errors_1.NotFoundError) {
89
105
  return sendObjectNotFound(req, res);
90
106
  }
91
107
  if (err instanceof errors_1.ForbiddenError) {
92
- throw new Error("Request failed unexpectedly due to Firebase Rules.");
108
+ return res.sendStatus(403);
93
109
  }
94
110
  throw err;
95
111
  }
96
112
  return res.sendStatus(204);
97
113
  });
98
- const reqBodyToBuffer = async (req) => {
99
- if (req.body instanceof Buffer) {
100
- return Buffer.from(req.body);
101
- }
102
- const bufs = [];
103
- req.on("data", (data) => {
104
- bufs.push(data);
105
- });
106
- await new Promise((resolve) => {
107
- req.on("end", () => {
108
- resolve();
109
- });
110
- });
111
- return Buffer.concat(bufs);
112
- };
113
114
  gcloudStorageAPI.put("/upload/storage/v1/b/:bucketId/o", async (req, res) => {
114
115
  if (!req.query.upload_id) {
115
116
  res.sendStatus(400);
@@ -118,7 +119,7 @@ function createCloudEndpoints(emulator) {
118
119
  const uploadId = req.query.upload_id.toString();
119
120
  let upload;
120
121
  try {
121
- uploadService.continueResumableUpload(uploadId, await reqBodyToBuffer(req));
122
+ uploadService.continueResumableUpload(uploadId, await (0, request_1.reqBodyToBuffer)(req));
122
123
  upload = uploadService.finalizeResumableUpload(uploadId);
123
124
  }
124
125
  catch (err) {
@@ -132,11 +133,11 @@ function createCloudEndpoints(emulator) {
132
133
  }
133
134
  let metadata;
134
135
  try {
135
- metadata = await storageLayer.handleUploadObject(upload, true);
136
+ metadata = await adminStorageLayer.uploadObject(upload);
136
137
  }
137
138
  catch (err) {
138
139
  if (err instanceof errors_1.ForbiddenError) {
139
- throw new Error("Request failed unexpectedly due to Firebase Rules.");
140
+ return res.sendStatus(403);
140
141
  }
141
142
  throw err;
142
143
  }
@@ -147,17 +148,17 @@ function createCloudEndpoints(emulator) {
147
148
  emulatorLogger_1.EmulatorLogger.forEmulator(types_1.Emulators.STORAGE).log("WARN_ONCE", "Cloud Storage ACLs are not supported in the Storage Emulator. All related methods will succeed, but have no effect.");
148
149
  let getObjectResponse;
149
150
  try {
150
- getObjectResponse = await storageLayer.handleGetObject({
151
+ getObjectResponse = await adminStorageLayer.getObject({
151
152
  bucketId: req.params.bucketId,
152
153
  decodedObjectId: req.params.objectId,
153
- }, true);
154
+ });
154
155
  }
155
156
  catch (err) {
156
157
  if (err instanceof errors_1.NotFoundError) {
157
158
  return sendObjectNotFound(req, res);
158
159
  }
159
160
  if (err instanceof errors_1.ForbiddenError) {
160
- throw new Error("Request failed unexpectedly due to Firebase Rules.");
161
+ return res.sendStatus(403);
161
162
  }
162
163
  throw err;
163
164
  }
@@ -206,15 +207,18 @@ function createCloudEndpoints(emulator) {
206
207
  let metadataRaw;
207
208
  let dataRaw;
208
209
  try {
209
- ({ metadataRaw, dataRaw } = (0, multipart_1.parseObjectUploadMultipartRequest)(contentTypeHeader, await reqBodyToBuffer(req)));
210
+ ({ metadataRaw, dataRaw } = (0, multipart_1.parseObjectUploadMultipartRequest)(contentTypeHeader, await (0, request_1.reqBodyToBuffer)(req)));
210
211
  }
211
212
  catch (err) {
212
- return res.status(400).json({
213
- error: {
214
- code: 400,
215
- message: err,
216
- },
217
- });
213
+ if (err instanceof Error) {
214
+ return res.status(400).json({
215
+ error: {
216
+ code: 400,
217
+ message: err.message,
218
+ },
219
+ });
220
+ }
221
+ throw err;
218
222
  }
219
223
  const upload = uploadService.multipartUpload({
220
224
  bucketId: req.params.bucketId,
@@ -225,11 +229,11 @@ function createCloudEndpoints(emulator) {
225
229
  });
226
230
  let metadata;
227
231
  try {
228
- metadata = await storageLayer.handleUploadObject(upload, true);
232
+ metadata = await adminStorageLayer.uploadObject(upload);
229
233
  }
230
234
  catch (err) {
231
235
  if (err instanceof errors_1.ForbiddenError) {
232
- throw new Error("Request failed unexpectedly due to Firebase Rules.");
236
+ return res.sendStatus(403);
233
237
  }
234
238
  throw err;
235
239
  }
@@ -238,34 +242,45 @@ function createCloudEndpoints(emulator) {
238
242
  gcloudStorageAPI.get("/:bucketId/:objectId(**)", async (req, res) => {
239
243
  let getObjectResponse;
240
244
  try {
241
- getObjectResponse = await storageLayer.handleGetObject({
245
+ getObjectResponse = await adminStorageLayer.getObject({
242
246
  bucketId: req.params.bucketId,
243
247
  decodedObjectId: req.params.objectId,
244
- }, true);
248
+ });
245
249
  }
246
250
  catch (err) {
247
251
  if (err instanceof errors_1.NotFoundError) {
248
252
  return sendObjectNotFound(req, res);
249
253
  }
250
254
  if (err instanceof errors_1.ForbiddenError) {
251
- throw new Error("Request failed unexpectedly due to Firebase Rules.");
255
+ return res.sendStatus(403);
252
256
  }
253
257
  throw err;
254
258
  }
255
259
  return sendFileBytes(getObjectResponse.metadata, getObjectResponse.data, req, res);
256
260
  });
257
261
  gcloudStorageAPI.post("/b/:bucketId/o/:objectId/:method(rewriteTo|copyTo)/b/:destBucketId/o/:destObjectId", (req, res, next) => {
258
- const md = storageLayer.getMetadata(req.params.bucketId, req.params.objectId);
259
- if (!md) {
260
- return sendObjectNotFound(req, res);
261
- }
262
262
  if (req.params.method === "rewriteTo" && req.query.rewriteToken) {
263
263
  return next();
264
264
  }
265
- const metadata = storageLayer.copyFile(md, req.params.destBucketId, req.params.destObjectId, req.body);
266
- if (!metadata) {
267
- res.sendStatus(400);
268
- return;
265
+ let metadata;
266
+ try {
267
+ metadata = adminStorageLayer.copyObject({
268
+ sourceBucket: req.params.bucketId,
269
+ sourceObject: req.params.objectId,
270
+ destinationBucket: req.params.destBucketId,
271
+ destinationObject: req.params.destObjectId,
272
+ incomingMetadata: req.body,
273
+ authorization: "Bearer owner",
274
+ });
275
+ }
276
+ catch (err) {
277
+ if (err instanceof errors_1.NotFoundError) {
278
+ return sendObjectNotFound(req, res);
279
+ }
280
+ if (err instanceof errors_1.ForbiddenError) {
281
+ return res.sendStatus(403);
282
+ }
283
+ throw err;
269
284
  }
270
285
  const resource = new metadata_1.CloudStorageObjectMetadata(metadata);
271
286
  res.status(200);