UNPKG

26.6 kBJavaScriptView Raw
1"use strict";
2// Copyright 2019 Google LLC
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15Object.defineProperty(exports, "__esModule", { value: true });
16exports.AclRoleAccessorMethods = exports.Acl = void 0;
17const promisify_1 = require("@google-cloud/promisify");
18/**
19 * Attach functionality to a {@link Storage.acl} instance. This will add an
20 * object for each role group (owners, readers, and writers), with each object
21 * containing methods to add or delete a type of entity.
22 *
23 * As an example, here are a few methods that are created.
24 *
25 * myBucket.acl.readers.deleteGroup('groupId', function(err) {});
26 *
27 * myBucket.acl.owners.addUser('email@example.com', function(err, acl) {});
28 *
29 * myBucket.acl.writers.addDomain('example.com', function(err, acl) {});
30 *
31 * @private
32 */
33class AclRoleAccessorMethods {
34 constructor() {
35 this.owners = {};
36 this.readers = {};
37 this.writers = {};
38 /**
39 * An object of convenience methods to add or delete owner ACL permissions
40 * for a given entity.
41 *
42 * The supported methods include:
43 *
44 * - `myFile.acl.owners.addAllAuthenticatedUsers`
45 * - `myFile.acl.owners.deleteAllAuthenticatedUsers`
46 * - `myFile.acl.owners.addAllUsers`
47 * - `myFile.acl.owners.deleteAllUsers`
48 * - `myFile.acl.owners.addDomain`
49 * - `myFile.acl.owners.deleteDomain`
50 * - `myFile.acl.owners.addGroup`
51 * - `myFile.acl.owners.deleteGroup`
52 * - `myFile.acl.owners.addProject`
53 * - `myFile.acl.owners.deleteProject`
54 * - `myFile.acl.owners.addUser`
55 * - `myFile.acl.owners.deleteUser`
56 *
57 * @name Acl#owners
58 *
59 * @example
60 * ```
61 * const storage = require('@google-cloud/storage')();
62 * const myBucket = storage.bucket('my-bucket');
63 * const myFile = myBucket.file('my-file');
64 *
65 * //-
66 * // Add a user as an owner of a file.
67 * //-
68 * const myBucket = gcs.bucket('my-bucket');
69 * const myFile = myBucket.file('my-file');
70 * myFile.acl.owners.addUser('email@example.com', function(err, aclObject)
71 * {});
72 *
73 * //-
74 * // For reference, the above command is the same as running the following.
75 * //-
76 * myFile.acl.add({
77 * entity: 'user-email@example.com',
78 * role: gcs.acl.OWNER_ROLE
79 * }, function(err, aclObject) {});
80 *
81 * //-
82 * // If the callback is omitted, we'll return a Promise.
83 * //-
84 * myFile.acl.owners.addUser('email@example.com').then(function(data) {
85 * const aclObject = data[0];
86 * const apiResponse = data[1];
87 * });
88 * ```
89 */
90 this.owners = {};
91 /**
92 * An object of convenience methods to add or delete reader ACL permissions
93 * for a given entity.
94 *
95 * The supported methods include:
96 *
97 * - `myFile.acl.readers.addAllAuthenticatedUsers`
98 * - `myFile.acl.readers.deleteAllAuthenticatedUsers`
99 * - `myFile.acl.readers.addAllUsers`
100 * - `myFile.acl.readers.deleteAllUsers`
101 * - `myFile.acl.readers.addDomain`
102 * - `myFile.acl.readers.deleteDomain`
103 * - `myFile.acl.readers.addGroup`
104 * - `myFile.acl.readers.deleteGroup`
105 * - `myFile.acl.readers.addProject`
106 * - `myFile.acl.readers.deleteProject`
107 * - `myFile.acl.readers.addUser`
108 * - `myFile.acl.readers.deleteUser`
109 *
110 * @name Acl#readers
111 *
112 * @example
113 * ```
114 * const storage = require('@google-cloud/storage')();
115 * const myBucket = storage.bucket('my-bucket');
116 * const myFile = myBucket.file('my-file');
117 *
118 * //-
119 * // Add a user as a reader of a file.
120 * //-
121 * myFile.acl.readers.addUser('email@example.com', function(err, aclObject)
122 * {});
123 *
124 * //-
125 * // For reference, the above command is the same as running the following.
126 * //-
127 * myFile.acl.add({
128 * entity: 'user-email@example.com',
129 * role: gcs.acl.READER_ROLE
130 * }, function(err, aclObject) {});
131 *
132 * //-
133 * // If the callback is omitted, we'll return a Promise.
134 * //-
135 * myFile.acl.readers.addUser('email@example.com').then(function(data) {
136 * const aclObject = data[0];
137 * const apiResponse = data[1];
138 * });
139 * ```
140 */
141 this.readers = {};
142 /**
143 * An object of convenience methods to add or delete writer ACL permissions
144 * for a given entity.
145 *
146 * The supported methods include:
147 *
148 * - `myFile.acl.writers.addAllAuthenticatedUsers`
149 * - `myFile.acl.writers.deleteAllAuthenticatedUsers`
150 * - `myFile.acl.writers.addAllUsers`
151 * - `myFile.acl.writers.deleteAllUsers`
152 * - `myFile.acl.writers.addDomain`
153 * - `myFile.acl.writers.deleteDomain`
154 * - `myFile.acl.writers.addGroup`
155 * - `myFile.acl.writers.deleteGroup`
156 * - `myFile.acl.writers.addProject`
157 * - `myFile.acl.writers.deleteProject`
158 * - `myFile.acl.writers.addUser`
159 * - `myFile.acl.writers.deleteUser`
160 *
161 * @name Acl#writers
162 *
163 * @example
164 * ```
165 * const storage = require('@google-cloud/storage')();
166 * const myBucket = storage.bucket('my-bucket');
167 * const myFile = myBucket.file('my-file');
168 *
169 * //-
170 * // Add a user as a writer of a file.
171 * //-
172 * myFile.acl.writers.addUser('email@example.com', function(err, aclObject)
173 * {});
174 *
175 * //-
176 * // For reference, the above command is the same as running the following.
177 * //-
178 * myFile.acl.add({
179 * entity: 'user-email@example.com',
180 * role: gcs.acl.WRITER_ROLE
181 * }, function(err, aclObject) {});
182 *
183 * //-
184 * // If the callback is omitted, we'll return a Promise.
185 * //-
186 * myFile.acl.writers.addUser('email@example.com').then(function(data) {
187 * const aclObject = data[0];
188 * const apiResponse = data[1];
189 * });
190 * ```
191 */
192 this.writers = {};
193 AclRoleAccessorMethods.roles.forEach(this._assignAccessMethods.bind(this));
194 }
195 _assignAccessMethods(role) {
196 const accessMethods = AclRoleAccessorMethods.accessMethods;
197 const entities = AclRoleAccessorMethods.entities;
198 const roleGroup = role.toLowerCase() + 's';
199 // eslint-disable-next-line @typescript-eslint/no-explicit-any
200 this[roleGroup] = entities.reduce((acc, entity) => {
201 const isPrefix = entity.charAt(entity.length - 1) === '-';
202 accessMethods.forEach(accessMethod => {
203 let method = accessMethod + entity[0].toUpperCase() + entity.substring(1);
204 if (isPrefix) {
205 method = method.replace('-', '');
206 }
207 // Wrap the parent accessor method (e.g. `add` or `delete`) to avoid the
208 // more complex API of specifying an `entity` and `role`.
209 // eslint-disable-next-line @typescript-eslint/no-explicit-any
210 acc[method] = (entityId, options, callback) => {
211 let apiEntity;
212 if (typeof options === 'function') {
213 callback = options;
214 options = {};
215 }
216 if (isPrefix) {
217 apiEntity = entity + entityId;
218 }
219 else {
220 // If the entity is not a prefix, it is a special entity group
221 // that does not require further details. The accessor methods
222 // only accept a callback.
223 apiEntity = entity;
224 callback = entityId;
225 }
226 options = Object.assign({
227 entity: apiEntity,
228 role,
229 }, options);
230 const args = [options];
231 if (typeof callback === 'function') {
232 args.push(callback);
233 }
234 // eslint-disable-next-line @typescript-eslint/no-explicit-any
235 return this[accessMethod].apply(this, args);
236 };
237 });
238 return acc;
239 }, {});
240 }
241}
242exports.AclRoleAccessorMethods = AclRoleAccessorMethods;
243AclRoleAccessorMethods.accessMethods = ['add', 'delete'];
244AclRoleAccessorMethods.entities = [
245 // Special entity groups that do not require further specification.
246 'allAuthenticatedUsers',
247 'allUsers',
248 // Entity groups that require specification, e.g. `user-email@example.com`.
249 'domain-',
250 'group-',
251 'project-',
252 'user-',
253];
254AclRoleAccessorMethods.roles = ['OWNER', 'READER', 'WRITER'];
255/**
256 * Cloud Storage uses access control lists (ACLs) to manage object and
257 * bucket access. ACLs are the mechanism you use to share objects with other
258 * users and allow other users to access your buckets and objects.
259 *
260 * An ACL consists of one or more entries, where each entry grants permissions
261 * to an entity. Permissions define the actions that can be performed against an
262 * object or bucket (for example, `READ` or `WRITE`); the entity defines who the
263 * permission applies to (for example, a specific user or group of users).
264 *
265 * Where an `entity` value is accepted, we follow the format the Cloud Storage
266 * API expects.
267 *
268 * Refer to
269 * https://cloud.google.com/storage/docs/json_api/v1/defaultObjectAccessControls
270 * for the most up-to-date values.
271 *
272 * - `user-userId`
273 * - `user-email`
274 * - `group-groupId`
275 * - `group-email`
276 * - `domain-domain`
277 * - `project-team-projectId`
278 * - `allUsers`
279 * - `allAuthenticatedUsers`
280 *
281 * Examples:
282 *
283 * - The user "liz@example.com" would be `user-liz@example.com`.
284 * - The group "example@googlegroups.com" would be
285 * `group-example@googlegroups.com`.
286 * - To refer to all members of the Google Apps for Business domain
287 * "example.com", the entity would be `domain-example.com`.
288 *
289 * For more detailed information, see
290 * {@link http://goo.gl/6qBBPO| About Access Control Lists}.
291 *
292 * @constructor Acl
293 * @mixin
294 * @param {object} options Configuration options.
295 */
296class Acl extends AclRoleAccessorMethods {
297 constructor(options) {
298 super();
299 this.pathPrefix = options.pathPrefix;
300 this.request_ = options.request;
301 }
302 /**
303 * @typedef {array} AddAclResponse
304 * @property {object} 0 The Acl Objects.
305 * @property {object} 1 The full API response.
306 */
307 /**
308 * @callback AddAclCallback
309 * @param {?Error} err Request error, if any.
310 * @param {object} acl The Acl Objects.
311 * @param {object} apiResponse The full API response.
312 */
313 /**
314 * Add access controls on a {@link Bucket} or {@link File}.
315 *
316 * See {@link https://cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/insert| BucketAccessControls: insert API Documentation}
317 * See {@link https://cloud.google.com/storage/docs/json_api/v1/objectAccessControls/insert| ObjectAccessControls: insert API Documentation}
318 *
319 * @param {object} options Configuration options.
320 * @param {string} options.entity Whose permissions will be added.
321 * @param {string} options.role Permissions allowed for the defined entity.
322 * See {@link https://cloud.google.com/storage/docs/access-control Access
323 * Control}.
324 * @param {number} [options.generation] **File Objects Only** Select a specific
325 * revision of this file (as opposed to the latest version, the default).
326 * @param {string} [options.userProject] The ID of the project which will be
327 * billed for the request.
328 * @param {AddAclCallback} [callback] Callback function.
329 * @returns {Promise<AddAclResponse>}
330 *
331 * @example
332 * ```
333 * const storage = require('@google-cloud/storage')();
334 * const myBucket = storage.bucket('my-bucket');
335 * const myFile = myBucket.file('my-file');
336 *
337 * const options = {
338 * entity: 'user-useremail@example.com',
339 * role: gcs.acl.OWNER_ROLE
340 * };
341 *
342 * myBucket.acl.add(options, function(err, aclObject, apiResponse) {});
343 *
344 * //-
345 * // For file ACL operations, you can also specify a `generation` property.
346 * // Here is how you would grant ownership permissions to a user on a
347 * specific
348 * // revision of a file.
349 * //-
350 * myFile.acl.add({
351 * entity: 'user-useremail@example.com',
352 * role: gcs.acl.OWNER_ROLE,
353 * generation: 1
354 * }, function(err, aclObject, apiResponse) {});
355 *
356 * //-
357 * // If the callback is omitted, we'll return a Promise.
358 * //-
359 * myBucket.acl.add(options).then(function(data) {
360 * const aclObject = data[0];
361 * const apiResponse = data[1];
362 * });
363 *
364 * ```
365 * @example <caption>include:samples/acl.js</caption>
366 * region_tag:storage_add_file_owner
367 * Example of adding an owner to a file:
368 *
369 * @example <caption>include:samples/acl.js</caption>
370 * region_tag:storage_add_bucket_owner
371 * Example of adding an owner to a bucket:
372 *
373 * @example <caption>include:samples/acl.js</caption>
374 * region_tag:storage_add_bucket_default_owner
375 * Example of adding a default owner to a bucket:
376 */
377 add(options, callback) {
378 const query = {};
379 if (options.generation) {
380 query.generation = options.generation;
381 }
382 if (options.userProject) {
383 query.userProject = options.userProject;
384 }
385 this.request({
386 method: 'POST',
387 uri: '',
388 qs: query,
389 maxRetries: 0, //explicitly set this value since this is a non-idempotent function
390 json: {
391 entity: options.entity,
392 role: options.role.toUpperCase(),
393 },
394 }, (err, resp) => {
395 if (err) {
396 callback(err, null, resp);
397 return;
398 }
399 callback(null, this.makeAclObject_(resp), resp);
400 });
401 }
402 /**
403 * @typedef {array} RemoveAclResponse
404 * @property {object} 0 The full API response.
405 */
406 /**
407 * @callback RemoveAclCallback
408 * @param {?Error} err Request error, if any.
409 * @param {object} apiResponse The full API response.
410 */
411 /**
412 * Delete access controls on a {@link Bucket} or {@link File}.
413 *
414 * See {@link https://cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/delete| BucketAccessControls: delete API Documentation}
415 * See {@link https://cloud.google.com/storage/docs/json_api/v1/objectAccessControls/delete| ObjectAccessControls: delete API Documentation}
416 *
417 * @param {object} options Configuration object.
418 * @param {string} options.entity Whose permissions will be revoked.
419 * @param {int} [options.generation] **File Objects Only** Select a specific
420 * revision of this file (as opposed to the latest version, the default).
421 * @param {string} [options.userProject] The ID of the project which will be
422 * billed for the request.
423 * @param {RemoveAclCallback} callback The callback function.
424 * @returns {Promise<RemoveAclResponse>}
425 *
426 * @example
427 * ```
428 * const storage = require('@google-cloud/storage')();
429 * const myBucket = storage.bucket('my-bucket');
430 * const myFile = myBucket.file('my-file');
431 *
432 * myBucket.acl.delete({
433 * entity: 'user-useremail@example.com'
434 * }, function(err, apiResponse) {});
435 *
436 * //-
437 * // For file ACL operations, you can also specify a `generation` property.
438 * //-
439 * myFile.acl.delete({
440 * entity: 'user-useremail@example.com',
441 * generation: 1
442 * }, function(err, apiResponse) {});
443 *
444 * //-
445 * // If the callback is omitted, we'll return a Promise.
446 * //-
447 * myFile.acl.delete().then(function(data) {
448 * const apiResponse = data[0];
449 * });
450 *
451 * ```
452 * @example <caption>include:samples/acl.js</caption>
453 * region_tag:storage_remove_bucket_owner
454 * Example of removing an owner from a bucket:
455 *
456 * @example <caption>include:samples/acl.js</caption>
457 * region_tag:storage_remove_bucket_default_owner
458 * Example of removing a default owner from a bucket:
459 *
460 * @example <caption>include:samples/acl.js</caption>
461 * region_tag:storage_remove_file_owner
462 * Example of removing an owner from a bucket:
463 */
464 delete(options, callback) {
465 const query = {};
466 if (options.generation) {
467 query.generation = options.generation;
468 }
469 if (options.userProject) {
470 query.userProject = options.userProject;
471 }
472 this.request({
473 method: 'DELETE',
474 uri: '/' + encodeURIComponent(options.entity),
475 qs: query,
476 }, (err, resp) => {
477 callback(err, resp);
478 });
479 }
480 /**
481 * @typedef {array} GetAclResponse
482 * @property {object|object[]} 0 Single or array of Acl Objects.
483 * @property {object} 1 The full API response.
484 */
485 /**
486 * @callback GetAclCallback
487 * @param {?Error} err Request error, if any.
488 * @param {object|object[]} acl Single or array of Acl Objects.
489 * @param {object} apiResponse The full API response.
490 */
491 /**
492 * Get access controls on a {@link Bucket} or {@link File}. If
493 * an entity is omitted, you will receive an array of all applicable access
494 * controls.
495 *
496 * See {@link https://cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/get| BucketAccessControls: get API Documentation}
497 * See {@link https://cloud.google.com/storage/docs/json_api/v1/objectAccessControls/get| ObjectAccessControls: get API Documentation}
498 *
499 * @param {object|function} [options] Configuration options. If you want to
500 * receive a list of all access controls, pass the callback function as
501 * the only argument.
502 * @param {string} options.entity Whose permissions will be fetched.
503 * @param {number} [options.generation] **File Objects Only** Select a specific
504 * revision of this file (as opposed to the latest version, the default).
505 * @param {string} [options.userProject] The ID of the project which will be
506 * billed for the request.
507 * @param {GetAclCallback} [callback] Callback function.
508 * @returns {Promise<GetAclResponse>}
509 *
510 * @example
511 * ```
512 * const storage = require('@google-cloud/storage')();
513 * const myBucket = storage.bucket('my-bucket');
514 * const myFile = myBucket.file('my-file');
515 *
516 * myBucket.acl.get({
517 * entity: 'user-useremail@example.com'
518 * }, function(err, aclObject, apiResponse) {});
519 *
520 * //-
521 * // Get all access controls.
522 * //-
523 * myBucket.acl.get(function(err, aclObjects, apiResponse) {
524 * // aclObjects = [
525 * // {
526 * // entity: 'user-useremail@example.com',
527 * // role: 'owner'
528 * // }
529 * // ]
530 * });
531 *
532 * //-
533 * // For file ACL operations, you can also specify a `generation` property.
534 * //-
535 * myFile.acl.get({
536 * entity: 'user-useremail@example.com',
537 * generation: 1
538 * }, function(err, aclObject, apiResponse) {});
539 *
540 * //-
541 * // If the callback is omitted, we'll return a Promise.
542 * //-
543 * myBucket.acl.get().then(function(data) {
544 * const aclObject = data[0];
545 * const apiResponse = data[1];
546 * });
547 *
548 * ```
549 * @example <caption>include:samples/acl.js</caption>
550 * region_tag:storage_print_file_acl
551 * Example of printing a file's ACL:
552 *
553 * @example <caption>include:samples/acl.js</caption>
554 * region_tag:storage_print_file_acl_for_user
555 * Example of printing a file's ACL for a specific user:
556 *
557 * @example <caption>include:samples/acl.js</caption>
558 * region_tag:storage_print_bucket_acl
559 * Example of printing a bucket's ACL:
560 *
561 * @example <caption>include:samples/acl.js</caption>
562 * region_tag:storage_print_bucket_acl_for_user
563 * Example of printing a bucket's ACL for a specific user:
564 */
565 get(optionsOrCallback, cb) {
566 const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : null;
567 const callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : cb;
568 let path = '';
569 const query = {};
570 if (options) {
571 path = '/' + encodeURIComponent(options.entity);
572 if (options.generation) {
573 query.generation = options.generation;
574 }
575 if (options.userProject) {
576 query.userProject = options.userProject;
577 }
578 }
579 this.request({
580 uri: path,
581 qs: query,
582 }, (err, resp) => {
583 if (err) {
584 callback(err, null, resp);
585 return;
586 }
587 let results;
588 if (resp.items) {
589 results = resp.items.map(this.makeAclObject_);
590 }
591 else {
592 results = this.makeAclObject_(resp);
593 }
594 callback(null, results, resp);
595 });
596 }
597 /**
598 * @typedef {array} UpdateAclResponse
599 * @property {object} 0 The updated Acl Objects.
600 * @property {object} 1 The full API response.
601 */
602 /**
603 * @callback UpdateAclCallback
604 * @param {?Error} err Request error, if any.
605 * @param {object} acl The updated Acl Objects.
606 * @param {object} apiResponse The full API response.
607 */
608 /**
609 * Update access controls on a {@link Bucket} or {@link File}.
610 *
611 * See {@link https://cloud.google.com/storage/docs/json_api/v1/bucketAccessControls/update| BucketAccessControls: update API Documentation}
612 * See {@link https://cloud.google.com/storage/docs/json_api/v1/objectAccessControls/update| ObjectAccessControls: update API Documentation}
613 *
614 * @param {object} options Configuration options.
615 * @param {string} options.entity Whose permissions will be updated.
616 * @param {string} options.role Permissions allowed for the defined entity.
617 * See {@link Storage.acl}.
618 * @param {number} [options.generation] **File Objects Only** Select a specific
619 * revision of this file (as opposed to the latest version, the default).
620 * @param {string} [options.userProject] The ID of the project which will be
621 * billed for the request.
622 * @param {UpdateAclCallback} [callback] Callback function.
623 * @returns {Promise<UpdateAclResponse>}
624 *
625 * @example
626 * ```
627 * const storage = require('@google-cloud/storage')();
628 * const myBucket = storage.bucket('my-bucket');
629 * const myFile = myBucket.file('my-file');
630 *
631 * const options = {
632 * entity: 'user-useremail@example.com',
633 * role: gcs.acl.WRITER_ROLE
634 * };
635 *
636 * myBucket.acl.update(options, function(err, aclObject, apiResponse) {});
637 *
638 * //-
639 * // For file ACL operations, you can also specify a `generation` property.
640 * //-
641 * myFile.acl.update({
642 * entity: 'user-useremail@example.com',
643 * role: gcs.acl.WRITER_ROLE,
644 * generation: 1
645 * }, function(err, aclObject, apiResponse) {});
646 *
647 * //-
648 * // If the callback is omitted, we'll return a Promise.
649 * //-
650 * myFile.acl.update(options).then(function(data) {
651 * const aclObject = data[0];
652 * const apiResponse = data[1];
653 * });
654 * ```
655 */
656 update(options, callback) {
657 const query = {};
658 if (options.generation) {
659 query.generation = options.generation;
660 }
661 if (options.userProject) {
662 query.userProject = options.userProject;
663 }
664 this.request({
665 method: 'PUT',
666 uri: '/' + encodeURIComponent(options.entity),
667 qs: query,
668 json: {
669 role: options.role.toUpperCase(),
670 },
671 }, (err, resp) => {
672 if (err) {
673 callback(err, null, resp);
674 return;
675 }
676 callback(null, this.makeAclObject_(resp), resp);
677 });
678 }
679 /**
680 * Transform API responses to a consistent object format.
681 *
682 * @private
683 */
684 makeAclObject_(accessControlObject) {
685 const obj = {
686 entity: accessControlObject.entity,
687 role: accessControlObject.role,
688 };
689 if (accessControlObject.projectTeam) {
690 obj.projectTeam = accessControlObject.projectTeam;
691 }
692 return obj;
693 }
694 /**
695 * Patch requests up to the bucket's request object.
696 *
697 * @private
698 *
699 * @param {string} method Action.
700 * @param {string} path Request path.
701 * @param {*} query Request query object.
702 * @param {*} body Request body contents.
703 * @param {function} callback Callback function.
704 */
705 request(reqOpts, callback) {
706 reqOpts.uri = this.pathPrefix + reqOpts.uri;
707 this.request_(reqOpts, callback);
708 }
709}
710exports.Acl = Acl;
711/*! Developer Documentation
712 *
713 * All async methods (except for streams) will return a Promise in the event
714 * that a callback is omitted.
715 */
716(0, promisify_1.promisifyAll)(Acl, {
717 exclude: ['request'],
718});