bucket.js 138 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528
  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.
  15. var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
  16. if (k2 === undefined) k2 = k;
  17. var desc = Object.getOwnPropertyDescriptor(m, k);
  18. if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
  19. desc = { enumerable: true, get: function() { return m[k]; } };
  20. }
  21. Object.defineProperty(o, k2, desc);
  22. }) : (function(o, m, k, k2) {
  23. if (k2 === undefined) k2 = k;
  24. o[k2] = m[k];
  25. }));
  26. var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
  27. Object.defineProperty(o, "default", { enumerable: true, value: v });
  28. }) : function(o, v) {
  29. o["default"] = v;
  30. });
  31. var __importStar = (this && this.__importStar) || function (mod) {
  32. if (mod && mod.__esModule) return mod;
  33. var result = {};
  34. if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
  35. __setModuleDefault(result, mod);
  36. return result;
  37. };
  38. var __importDefault = (this && this.__importDefault) || function (mod) {
  39. return (mod && mod.__esModule) ? mod : { "default": mod };
  40. };
  41. Object.defineProperty(exports, "__esModule", { value: true });
  42. exports.Bucket = exports.BucketExceptionMessages = exports.AvailableServiceObjectMethods = exports.BucketActionToHTTPMethod = void 0;
  43. const index_js_1 = require("./nodejs-common/index.js");
  44. const paginator_1 = require("@google-cloud/paginator");
  45. const promisify_1 = require("@google-cloud/promisify");
  46. const fs = __importStar(require("fs"));
  47. const mime_1 = __importDefault(require("mime"));
  48. const path = __importStar(require("path"));
  49. const p_limit_1 = __importDefault(require("p-limit"));
  50. const util_1 = require("util");
  51. const async_retry_1 = __importDefault(require("async-retry"));
  52. const util_js_1 = require("./util.js");
  53. const acl_js_1 = require("./acl.js");
  54. const file_js_1 = require("./file.js");
  55. const iam_js_1 = require("./iam.js");
  56. const notification_js_1 = require("./notification.js");
  57. const storage_js_1 = require("./storage.js");
  58. const signer_js_1 = require("./signer.js");
  59. const stream_1 = require("stream");
  60. const url_1 = require("url");
  61. var BucketActionToHTTPMethod;
  62. (function (BucketActionToHTTPMethod) {
  63. BucketActionToHTTPMethod["list"] = "GET";
  64. })(BucketActionToHTTPMethod || (exports.BucketActionToHTTPMethod = BucketActionToHTTPMethod = {}));
  65. var AvailableServiceObjectMethods;
  66. (function (AvailableServiceObjectMethods) {
  67. AvailableServiceObjectMethods[AvailableServiceObjectMethods["setMetadata"] = 0] = "setMetadata";
  68. AvailableServiceObjectMethods[AvailableServiceObjectMethods["delete"] = 1] = "delete";
  69. })(AvailableServiceObjectMethods || (exports.AvailableServiceObjectMethods = AvailableServiceObjectMethods = {}));
  70. var BucketExceptionMessages;
  71. (function (BucketExceptionMessages) {
  72. BucketExceptionMessages["PROVIDE_SOURCE_FILE"] = "You must provide at least one source file.";
  73. BucketExceptionMessages["DESTINATION_FILE_NOT_SPECIFIED"] = "A destination file must be specified.";
  74. BucketExceptionMessages["CHANNEL_ID_REQUIRED"] = "An ID is required to create a channel.";
  75. BucketExceptionMessages["TOPIC_NAME_REQUIRED"] = "A valid topic name is required.";
  76. BucketExceptionMessages["CONFIGURATION_OBJECT_PREFIX_REQUIRED"] = "A configuration object with a prefix is required.";
  77. BucketExceptionMessages["SPECIFY_FILE_NAME"] = "A file name must be specified.";
  78. BucketExceptionMessages["METAGENERATION_NOT_PROVIDED"] = "A metageneration must be provided.";
  79. BucketExceptionMessages["SUPPLY_NOTIFICATION_ID"] = "You must supply a notification ID.";
  80. })(BucketExceptionMessages || (exports.BucketExceptionMessages = BucketExceptionMessages = {}));
  81. /**
  82. * @callback Crc32cGeneratorToStringCallback
  83. * A method returning the CRC32C as a base64-encoded string.
  84. *
  85. * @returns {string}
  86. *
  87. * @example
  88. * Hashing the string 'data' should return 'rth90Q=='
  89. *
  90. * ```js
  91. * const buffer = Buffer.from('data');
  92. * crc32c.update(buffer);
  93. * crc32c.toString(); // 'rth90Q=='
  94. * ```
  95. **/
  96. /**
  97. * @callback Crc32cGeneratorValidateCallback
  98. * A method validating a base64-encoded CRC32C string.
  99. *
  100. * @param {string} [value] base64-encoded CRC32C string to validate
  101. * @returns {boolean}
  102. *
  103. * @example
  104. * Should return `true` if the value matches, `false` otherwise
  105. *
  106. * ```js
  107. * const buffer = Buffer.from('data');
  108. * crc32c.update(buffer);
  109. * crc32c.validate('DkjKuA=='); // false
  110. * crc32c.validate('rth90Q=='); // true
  111. * ```
  112. **/
  113. /**
  114. * @callback Crc32cGeneratorUpdateCallback
  115. * A method for passing `Buffer`s for CRC32C generation.
  116. *
  117. * @param {Buffer} [data] data to update CRC32C value with
  118. * @returns {undefined}
  119. *
  120. * @example
  121. * Hashing buffers from 'some ' and 'text\n'
  122. *
  123. * ```js
  124. * const buffer1 = Buffer.from('some ');
  125. * crc32c.update(buffer1);
  126. *
  127. * const buffer2 = Buffer.from('text\n');
  128. * crc32c.update(buffer2);
  129. *
  130. * crc32c.toString(); // 'DkjKuA=='
  131. * ```
  132. **/
  133. /**
  134. * @typedef {object} CRC32CValidator
  135. * @property {Crc32cGeneratorToStringCallback}
  136. * @property {Crc32cGeneratorValidateCallback}
  137. * @property {Crc32cGeneratorUpdateCallback}
  138. */
  139. /**
  140. * A function that generates a CRC32C Validator. Defaults to {@link CRC32C}
  141. *
  142. * @name Bucket#crc32cGenerator
  143. * @type {CRC32CValidator}
  144. */
  145. /**
  146. * Get and set IAM policies for your bucket.
  147. *
  148. * @name Bucket#iam
  149. * @mixes Iam
  150. *
  151. * See {@link https://cloud.google.com/storage/docs/access-control/iam#short_title_iam_management| Cloud Storage IAM Management}
  152. * See {@link https://cloud.google.com/iam/docs/granting-changing-revoking-access| Granting, Changing, and Revoking Access}
  153. * See {@link https://cloud.google.com/iam/docs/understanding-roles| IAM Roles}
  154. *
  155. * @example
  156. * ```
  157. * const {Storage} = require('@google-cloud/storage');
  158. * const storage = new Storage();
  159. * const bucket = storage.bucket('albums');
  160. *
  161. * //-
  162. * // Get the IAM policy for your bucket.
  163. * //-
  164. * bucket.iam.getPolicy(function(err, policy) {
  165. * console.log(policy);
  166. * });
  167. *
  168. * //-
  169. * // If the callback is omitted, we'll return a Promise.
  170. * //-
  171. * bucket.iam.getPolicy().then(function(data) {
  172. * const policy = data[0];
  173. * const apiResponse = data[1];
  174. * });
  175. *
  176. * ```
  177. * @example <caption>include:samples/iam.js</caption>
  178. * region_tag:storage_view_bucket_iam_members
  179. * Example of retrieving a bucket's IAM policy:
  180. *
  181. * @example <caption>include:samples/iam.js</caption>
  182. * region_tag:storage_add_bucket_iam_member
  183. * Example of adding to a bucket's IAM policy:
  184. *
  185. * @example <caption>include:samples/iam.js</caption>
  186. * region_tag:storage_remove_bucket_iam_member
  187. * Example of removing from a bucket's IAM policy:
  188. */
  189. /**
  190. * Cloud Storage uses access control lists (ACLs) to manage object and
  191. * bucket access. ACLs are the mechanism you use to share objects with other
  192. * users and allow other users to access your buckets and objects.
  193. *
  194. * An ACL consists of one or more entries, where each entry grants permissions
  195. * to an entity. Permissions define the actions that can be performed against
  196. * an object or bucket (for example, `READ` or `WRITE`); the entity defines
  197. * who the permission applies to (for example, a specific user or group of
  198. * users).
  199. *
  200. * The `acl` object on a Bucket instance provides methods to get you a list of
  201. * the ACLs defined on your bucket, as well as set, update, and delete them.
  202. *
  203. * Buckets also have
  204. * {@link https://cloud.google.com/storage/docs/access-control/lists#default| default ACLs}
  205. * for all created files. Default ACLs specify permissions that all new
  206. * objects added to the bucket will inherit by default. You can add, delete,
  207. * get, and update entities and permissions for these as well with
  208. * {@link Bucket#acl.default}.
  209. *
  210. * See {@link http://goo.gl/6qBBPO| About Access Control Lists}
  211. * See {@link https://cloud.google.com/storage/docs/access-control/lists#default| Default ACLs}
  212. *
  213. * @name Bucket#acl
  214. * @mixes Acl
  215. * @property {Acl} default Cloud Storage Buckets have
  216. * {@link https://cloud.google.com/storage/docs/access-control/lists#default| default ACLs}
  217. * for all created files. You can add, delete, get, and update entities and
  218. * permissions for these as well. The method signatures and examples are all
  219. * the same, after only prefixing the method call with `default`.
  220. *
  221. * @example
  222. * ```
  223. * const {Storage} = require('@google-cloud/storage');
  224. * const storage = new Storage();
  225. *
  226. * //-
  227. * // Make a bucket's contents publicly readable.
  228. * //-
  229. * const myBucket = storage.bucket('my-bucket');
  230. *
  231. * const options = {
  232. * entity: 'allUsers',
  233. * role: storage.acl.READER_ROLE
  234. * };
  235. *
  236. * myBucket.acl.add(options, function(err, aclObject) {});
  237. *
  238. * //-
  239. * // If the callback is omitted, we'll return a Promise.
  240. * //-
  241. * myBucket.acl.add(options).then(function(data) {
  242. * const aclObject = data[0];
  243. * const apiResponse = data[1];
  244. * });
  245. *
  246. * ```
  247. * @example <caption>include:samples/acl.js</caption>
  248. * region_tag:storage_print_bucket_acl
  249. * Example of printing a bucket's ACL:
  250. *
  251. * @example <caption>include:samples/acl.js</caption>
  252. * region_tag:storage_print_bucket_acl_for_user
  253. * Example of printing a bucket's ACL for a specific user:
  254. *
  255. * @example <caption>include:samples/acl.js</caption>
  256. * region_tag:storage_add_bucket_owner
  257. * Example of adding an owner to a bucket:
  258. *
  259. * @example <caption>include:samples/acl.js</caption>
  260. * region_tag:storage_remove_bucket_owner
  261. * Example of removing an owner from a bucket:
  262. *
  263. * @example <caption>include:samples/acl.js</caption>
  264. * region_tag:storage_add_bucket_default_owner
  265. * Example of adding a default owner to a bucket:
  266. *
  267. * @example <caption>include:samples/acl.js</caption>
  268. * region_tag:storage_remove_bucket_default_owner
  269. * Example of removing a default owner from a bucket:
  270. */
  271. /**
  272. * The API-formatted resource description of the bucket.
  273. *
  274. * Note: This is not guaranteed to be up-to-date when accessed. To get the
  275. * latest record, call the `getMetadata()` method.
  276. *
  277. * @name Bucket#metadata
  278. * @type {object}
  279. */
  280. /**
  281. * The bucket's name.
  282. * @name Bucket#name
  283. * @type {string}
  284. */
  285. /**
  286. * Get {@link File} objects for the files currently in the bucket as a
  287. * readable object stream.
  288. *
  289. * @method Bucket#getFilesStream
  290. * @param {GetFilesOptions} [query] Query object for listing files.
  291. * @returns {ReadableStream} A readable stream that emits {@link File} instances.
  292. *
  293. * @example
  294. * ```
  295. * const {Storage} = require('@google-cloud/storage');
  296. * const storage = new Storage();
  297. * const bucket = storage.bucket('albums');
  298. *
  299. * bucket.getFilesStream()
  300. * .on('error', console.error)
  301. * .on('data', function(file) {
  302. * // file is a File object.
  303. * })
  304. * .on('end', function() {
  305. * // All files retrieved.
  306. * });
  307. *
  308. * //-
  309. * // If you anticipate many results, you can end a stream early to prevent
  310. * // unnecessary processing and API requests.
  311. * //-
  312. * bucket.getFilesStream()
  313. * .on('data', function(file) {
  314. * this.end();
  315. * });
  316. *
  317. * //-
  318. * // If you're filtering files with a delimiter, you should use
  319. * // {@link Bucket#getFiles} and set `autoPaginate: false` in order to
  320. * // preserve the `apiResponse` argument.
  321. * //-
  322. * const prefixes = [];
  323. *
  324. * function callback(err, files, nextQuery, apiResponse) {
  325. * prefixes = prefixes.concat(apiResponse.prefixes);
  326. *
  327. * if (nextQuery) {
  328. * bucket.getFiles(nextQuery, callback);
  329. * } else {
  330. * // prefixes = The finished array of prefixes.
  331. * }
  332. * }
  333. *
  334. * bucket.getFiles({
  335. * autoPaginate: false,
  336. * delimiter: '/'
  337. * }, callback);
  338. * ```
  339. */
  340. /**
  341. * Create a Bucket object to interact with a Cloud Storage bucket.
  342. *
  343. * @class
  344. * @hideconstructor
  345. *
  346. * @param {Storage} storage A {@link Storage} instance.
  347. * @param {string} name The name of the bucket.
  348. * @param {object} [options] Configuration object.
  349. * @param {string} [options.userProject] User project.
  350. *
  351. * @example
  352. * ```
  353. * const {Storage} = require('@google-cloud/storage');
  354. * const storage = new Storage();
  355. * const bucket = storage.bucket('albums');
  356. * ```
  357. */
  358. class Bucket extends index_js_1.ServiceObject {
  359. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  360. getFilesStream(query) {
  361. // placeholder body, overwritten in constructor
  362. return new stream_1.Readable();
  363. }
  364. constructor(storage, name, options) {
  365. var _a, _b, _c, _d;
  366. options = options || {};
  367. // Allow for "gs://"-style input, and strip any trailing slashes.
  368. name = name.replace(/^gs:\/\//, '').replace(/\/+$/, '');
  369. const requestQueryObject = {};
  370. if ((_a = options === null || options === void 0 ? void 0 : options.preconditionOpts) === null || _a === void 0 ? void 0 : _a.ifGenerationMatch) {
  371. requestQueryObject.ifGenerationMatch =
  372. options.preconditionOpts.ifGenerationMatch;
  373. }
  374. if ((_b = options === null || options === void 0 ? void 0 : options.preconditionOpts) === null || _b === void 0 ? void 0 : _b.ifGenerationNotMatch) {
  375. requestQueryObject.ifGenerationNotMatch =
  376. options.preconditionOpts.ifGenerationNotMatch;
  377. }
  378. if ((_c = options === null || options === void 0 ? void 0 : options.preconditionOpts) === null || _c === void 0 ? void 0 : _c.ifMetagenerationMatch) {
  379. requestQueryObject.ifMetagenerationMatch =
  380. options.preconditionOpts.ifMetagenerationMatch;
  381. }
  382. if ((_d = options === null || options === void 0 ? void 0 : options.preconditionOpts) === null || _d === void 0 ? void 0 : _d.ifMetagenerationNotMatch) {
  383. requestQueryObject.ifMetagenerationNotMatch =
  384. options.preconditionOpts.ifMetagenerationNotMatch;
  385. }
  386. const userProject = options.userProject;
  387. if (typeof userProject === 'string') {
  388. requestQueryObject.userProject = userProject;
  389. }
  390. const methods = {
  391. /**
  392. * Create a bucket.
  393. *
  394. * @method Bucket#create
  395. * @param {CreateBucketRequest} [metadata] Metadata to set for the bucket.
  396. * @param {CreateBucketCallback} [callback] Callback function.
  397. * @returns {Promise<CreateBucketResponse>}
  398. *
  399. * @example
  400. * ```
  401. * const {Storage} = require('@google-cloud/storage');
  402. * const storage = new Storage();
  403. * const bucket = storage.bucket('albums');
  404. * bucket.create(function(err, bucket, apiResponse) {
  405. * if (!err) {
  406. * // The bucket was created successfully.
  407. * }
  408. * });
  409. *
  410. * //-
  411. * // If the callback is omitted, we'll return a Promise.
  412. * //-
  413. * bucket.create().then(function(data) {
  414. * const bucket = data[0];
  415. * const apiResponse = data[1];
  416. * });
  417. * ```
  418. */
  419. create: {
  420. reqOpts: {
  421. qs: requestQueryObject,
  422. },
  423. },
  424. /**
  425. * IamDeleteBucketOptions Configuration options.
  426. * @property {boolean} [ignoreNotFound = false] Ignore an error if
  427. * the bucket does not exist.
  428. * @property {string} [userProject] The ID of the project which will be
  429. * billed for the request.
  430. */
  431. /**
  432. * @typedef {array} DeleteBucketResponse
  433. * @property {object} 0 The full API response.
  434. */
  435. /**
  436. * @callback DeleteBucketCallback
  437. * @param {?Error} err Request error, if any.
  438. * @param {object} apiResponse The full API response.
  439. */
  440. /**
  441. * Delete the bucket.
  442. *
  443. * See {@link https://cloud.google.com/storage/docs/json_api/v1/buckets/delete| Buckets: delete API Documentation}
  444. *
  445. * @method Bucket#delete
  446. * @param {DeleteBucketOptions} [options] Configuration options.
  447. * @param {boolean} [options.ignoreNotFound = false] Ignore an error if
  448. * the bucket does not exist.
  449. * @param {string} [options.userProject] The ID of the project which will be
  450. * billed for the request.
  451. * @param {DeleteBucketCallback} [callback] Callback function.
  452. * @returns {Promise<DeleteBucketResponse>}
  453. *
  454. * @example
  455. * ```
  456. * const {Storage} = require('@google-cloud/storage');
  457. * const storage = new Storage();
  458. * const bucket = storage.bucket('albums');
  459. * bucket.delete(function(err, apiResponse) {});
  460. *
  461. * //-
  462. * // If the callback is omitted, we'll return a Promise.
  463. * //-
  464. * bucket.delete().then(function(data) {
  465. * const apiResponse = data[0];
  466. * });
  467. *
  468. * ```
  469. * @example <caption>include:samples/buckets.js</caption>
  470. * region_tag:storage_delete_bucket
  471. * Another example:
  472. */
  473. delete: {
  474. reqOpts: {
  475. qs: requestQueryObject,
  476. },
  477. },
  478. /**
  479. * @typedef {object} BucketExistsOptions Configuration options for Bucket#exists().
  480. * @property {string} [userProject] The ID of the project which will be
  481. * billed for the request.
  482. */
  483. /**
  484. * @typedef {array} BucketExistsResponse
  485. * @property {boolean} 0 Whether the {@link Bucket} exists.
  486. */
  487. /**
  488. * @callback BucketExistsCallback
  489. * @param {?Error} err Request error, if any.
  490. * @param {boolean} exists Whether the {@link Bucket} exists.
  491. */
  492. /**
  493. * Check if the bucket exists.
  494. *
  495. * @method Bucket#exists
  496. * @param {BucketExistsOptions} [options] Configuration options.
  497. * @param {string} [options.userProject] The ID of the project which will be
  498. * billed for the request.
  499. * @param {BucketExistsCallback} [callback] Callback function.
  500. * @returns {Promise<BucketExistsResponse>}
  501. *
  502. * @example
  503. * ```
  504. * const {Storage} = require('@google-cloud/storage');
  505. * const storage = new Storage();
  506. * const bucket = storage.bucket('albums');
  507. *
  508. * bucket.exists(function(err, exists) {});
  509. *
  510. * //-
  511. * // If the callback is omitted, we'll return a Promise.
  512. * //-
  513. * bucket.exists().then(function(data) {
  514. * const exists = data[0];
  515. * });
  516. * ```
  517. */
  518. exists: {
  519. reqOpts: {
  520. qs: requestQueryObject,
  521. },
  522. },
  523. /**
  524. * @typedef {object} [GetBucketOptions] Configuration options for Bucket#get()
  525. * @property {boolean} [autoCreate] Automatically create the object if
  526. * it does not exist. Default: `false`
  527. * @property {string} [userProject] The ID of the project which will be
  528. * billed for the request.
  529. */
  530. /**
  531. * @typedef {array} GetBucketResponse
  532. * @property {Bucket} 0 The {@link Bucket}.
  533. * @property {object} 1 The full API response.
  534. */
  535. /**
  536. * @callback GetBucketCallback
  537. * @param {?Error} err Request error, if any.
  538. * @param {Bucket} bucket The {@link Bucket}.
  539. * @param {object} apiResponse The full API response.
  540. */
  541. /**
  542. * Get a bucket if it exists.
  543. *
  544. * You may optionally use this to "get or create" an object by providing
  545. * an object with `autoCreate` set to `true`. Any extra configuration that
  546. * is normally required for the `create` method must be contained within
  547. * this object as well.
  548. *
  549. * @method Bucket#get
  550. * @param {GetBucketOptions} [options] Configuration options.
  551. * @param {boolean} [options.autoCreate] Automatically create the object if
  552. * it does not exist. Default: `false`
  553. * @param {string} [options.userProject] The ID of the project which will be
  554. * billed for the request.
  555. * @param {GetBucketCallback} [callback] Callback function.
  556. * @returns {Promise<GetBucketResponse>}
  557. *
  558. * @example
  559. * ```
  560. * const {Storage} = require('@google-cloud/storage');
  561. * const storage = new Storage();
  562. * const bucket = storage.bucket('albums');
  563. *
  564. * bucket.get(function(err, bucket, apiResponse) {
  565. * // `bucket.metadata` has been populated.
  566. * });
  567. *
  568. * //-
  569. * // If the callback is omitted, we'll return a Promise.
  570. * //-
  571. * bucket.get().then(function(data) {
  572. * const bucket = data[0];
  573. * const apiResponse = data[1];
  574. * });
  575. * ```
  576. */
  577. get: {
  578. reqOpts: {
  579. qs: requestQueryObject,
  580. },
  581. },
  582. /**
  583. * @typedef {array} GetBucketMetadataResponse
  584. * @property {object} 0 The bucket metadata.
  585. * @property {object} 1 The full API response.
  586. */
  587. /**
  588. * @callback GetBucketMetadataCallback
  589. * @param {?Error} err Request error, if any.
  590. * @param {object} metadata The bucket metadata.
  591. * @param {object} apiResponse The full API response.
  592. */
  593. /**
  594. * @typedef {object} GetBucketMetadataOptions Configuration options for Bucket#getMetadata().
  595. * @property {string} [userProject] The ID of the project which will be
  596. * billed for the request.
  597. */
  598. /**
  599. * Get the bucket's metadata.
  600. *
  601. * To set metadata, see {@link Bucket#setMetadata}.
  602. *
  603. * See {@link https://cloud.google.com/storage/docs/json_api/v1/buckets/get| Buckets: get API Documentation}
  604. *
  605. * @method Bucket#getMetadata
  606. * @param {GetBucketMetadataOptions} [options] Configuration options.
  607. * @param {string} [options.userProject] The ID of the project which will be
  608. * billed for the request.
  609. * @param {GetBucketMetadataCallback} [callback] Callback function.
  610. * @returns {Promise<GetBucketMetadataResponse>}
  611. *
  612. * @example
  613. * ```
  614. * const {Storage} = require('@google-cloud/storage');
  615. * const storage = new Storage();
  616. * const bucket = storage.bucket('albums');
  617. *
  618. * bucket.getMetadata(function(err, metadata, apiResponse) {});
  619. *
  620. * //-
  621. * // If the callback is omitted, we'll return a Promise.
  622. * //-
  623. * bucket.getMetadata().then(function(data) {
  624. * const metadata = data[0];
  625. * const apiResponse = data[1];
  626. * });
  627. *
  628. * ```
  629. * @example <caption>include:samples/requesterPays.js</caption>
  630. * region_tag:storage_get_requester_pays_status
  631. * Example of retrieving the requester pays status of a bucket:
  632. */
  633. getMetadata: {
  634. reqOpts: {
  635. qs: requestQueryObject,
  636. },
  637. },
  638. /**
  639. * @typedef {object} SetBucketMetadataOptions Configuration options for Bucket#setMetadata().
  640. * @property {string} [userProject] The ID of the project which will be
  641. * billed for the request.
  642. */
  643. /**
  644. * @typedef {array} SetBucketMetadataResponse
  645. * @property {object} apiResponse The full API response.
  646. */
  647. /**
  648. * @callback SetBucketMetadataCallback
  649. * @param {?Error} err Request error, if any.
  650. * @param {object} metadata The bucket metadata.
  651. */
  652. /**
  653. * Set the bucket's metadata.
  654. *
  655. * See {@link https://cloud.google.com/storage/docs/json_api/v1/buckets/patch| Buckets: patch API Documentation}
  656. *
  657. * @method Bucket#setMetadata
  658. * @param {object<string, *>} metadata The metadata you wish to set.
  659. * @param {SetBucketMetadataOptions} [options] Configuration options.
  660. * @param {string} [options.userProject] The ID of the project which will be
  661. * billed for the request.
  662. * @param {SetBucketMetadataCallback} [callback] Callback function.
  663. * @returns {Promise<SetBucketMetadataResponse>}
  664. *
  665. * @example
  666. * ```
  667. * const {Storage} = require('@google-cloud/storage');
  668. * const storage = new Storage();
  669. * const bucket = storage.bucket('albums');
  670. *
  671. * //-
  672. * // Set website metadata field on the bucket.
  673. * //-
  674. * const metadata = {
  675. * website: {
  676. * mainPageSuffix: 'http://example.com',
  677. * notFoundPage: 'http://example.com/404.html'
  678. * }
  679. * };
  680. *
  681. * bucket.setMetadata(metadata, function(err, apiResponse) {});
  682. *
  683. * //-
  684. * // Enable versioning for your bucket.
  685. * //-
  686. * bucket.setMetadata({
  687. * versioning: {
  688. * enabled: true
  689. * }
  690. * }, function(err, apiResponse) {});
  691. *
  692. * //-
  693. * // Enable KMS encryption for objects within this bucket.
  694. * //-
  695. * bucket.setMetadata({
  696. * encryption: {
  697. * defaultKmsKeyName: 'projects/grape-spaceship-123/...'
  698. * }
  699. * }, function(err, apiResponse) {});
  700. *
  701. * //-
  702. * // Set the default event-based hold value for new objects in this
  703. * // bucket.
  704. * //-
  705. * bucket.setMetadata({
  706. * defaultEventBasedHold: true
  707. * }, function(err, apiResponse) {});
  708. *
  709. * //-
  710. * // Remove object lifecycle rules.
  711. * //-
  712. * bucket.setMetadata({
  713. * lifecycle: null
  714. * }, function(err, apiResponse) {});
  715. *
  716. * //-
  717. * // If the callback is omitted, we'll return a Promise.
  718. * //-
  719. * bucket.setMetadata(metadata).then(function(data) {
  720. * const apiResponse = data[0];
  721. * });
  722. * ```
  723. */
  724. setMetadata: {
  725. reqOpts: {
  726. qs: requestQueryObject,
  727. },
  728. },
  729. };
  730. super({
  731. parent: storage,
  732. baseUrl: '/b',
  733. id: name,
  734. createMethod: storage.createBucket.bind(storage),
  735. methods,
  736. });
  737. this.name = name;
  738. this.storage = storage;
  739. this.userProject = options.userProject;
  740. this.acl = new acl_js_1.Acl({
  741. request: this.request.bind(this),
  742. pathPrefix: '/acl',
  743. });
  744. this.acl.default = new acl_js_1.Acl({
  745. request: this.request.bind(this),
  746. pathPrefix: '/defaultObjectAcl',
  747. });
  748. this.crc32cGenerator =
  749. options.crc32cGenerator || this.storage.crc32cGenerator;
  750. this.iam = new iam_js_1.Iam(this);
  751. this.getFilesStream = paginator_1.paginator.streamify('getFiles');
  752. this.instanceRetryValue = storage.retryOptions.autoRetry;
  753. this.instancePreconditionOpts = options === null || options === void 0 ? void 0 : options.preconditionOpts;
  754. }
  755. /**
  756. * The bucket's Cloud Storage URI (`gs://`)
  757. *
  758. * @example
  759. * ```ts
  760. * const {Storage} = require('@google-cloud/storage');
  761. * const storage = new Storage();
  762. * const bucket = storage.bucket('my-bucket');
  763. *
  764. * // `gs://my-bucket`
  765. * const href = bucket.cloudStorageURI.href;
  766. * ```
  767. */
  768. get cloudStorageURI() {
  769. const uri = new url_1.URL('gs://');
  770. uri.host = this.name;
  771. return uri;
  772. }
  773. /**
  774. * @typedef {object} AddLifecycleRuleOptions Configuration options for Bucket#addLifecycleRule().
  775. * @property {boolean} [append=true] The new rules will be appended to any
  776. * pre-existing rules.
  777. */
  778. /**
  779. *
  780. * @typedef {object} LifecycleRule The new lifecycle rule to be added to objects
  781. * in this bucket.
  782. * @property {string|object} action The action to be taken upon matching of
  783. * all the conditions 'delete', 'setStorageClass', or 'AbortIncompleteMultipartUpload'.
  784. * **Note**: For configuring a raw-formatted rule object to be passed as `action`
  785. * please refer to the [examples]{@link https://cloud.google.com/storage/docs/managing-lifecycles#configexamples}.
  786. * @property {object} condition Condition a bucket must meet before the
  787. * action occurs on the bucket. Refer to following supported [conditions]{@link https://cloud.google.com/storage/docs/lifecycle#conditions}.
  788. * @property {string} [storageClass] When using the `setStorageClass`
  789. * action, provide this option to dictate which storage class the object
  790. * should update to. Please see
  791. * [SetStorageClass option documentation]{@link https://cloud.google.com/storage/docs/lifecycle#setstorageclass} for supported transitions.
  792. */
  793. /**
  794. * Add an object lifecycle management rule to the bucket.
  795. *
  796. * By default, an Object Lifecycle Management rule provided to this method
  797. * will be included to the existing policy. To replace all existing rules,
  798. * supply the `options` argument, setting `append` to `false`.
  799. *
  800. * To add multiple rules, pass a list to the `rule` parameter. Calling this
  801. * function multiple times asynchronously does not guarantee that all rules
  802. * are added correctly.
  803. *
  804. * See {@link https://cloud.google.com/storage/docs/lifecycle| Object Lifecycle Management}
  805. * See {@link https://cloud.google.com/storage/docs/json_api/v1/buckets/patch| Buckets: patch API Documentation}
  806. *
  807. * @param {LifecycleRule|LifecycleRule[]} rule The new lifecycle rule or rules to be added to objects
  808. * in this bucket.
  809. * @param {string|object} rule.action The action to be taken upon matching of
  810. * all the conditions 'delete', 'setStorageClass', or 'AbortIncompleteMultipartUpload'.
  811. * **Note**: For configuring a raw-formatted rule object to be passed as `action`
  812. * please refer to the [examples]{@link https://cloud.google.com/storage/docs/managing-lifecycles#configexamples}.
  813. * @param {object} rule.condition Condition a bucket must meet before the
  814. * action occurson the bucket. Refer to followitn supported [conditions]{@link https://cloud.google.com/storage/docs/lifecycle#conditions}.
  815. * @param {string} [rule.storageClass] When using the `setStorageClass`
  816. * action, provide this option to dictate which storage class the object
  817. * should update to.
  818. * @param {AddLifecycleRuleOptions} [options] Configuration object.
  819. * @param {boolean} [options.append=true] Append the new rule to the existing
  820. * policy.
  821. * @param {SetBucketMetadataCallback} [callback] Callback function.
  822. * @returns {Promise<SetBucketMetadataResponse>}
  823. *
  824. * @example
  825. * ```
  826. * const {Storage} = require('@google-cloud/storage');
  827. * const storage = new Storage();
  828. * const bucket = storage.bucket('albums');
  829. *
  830. * //-
  831. * // Automatically have an object deleted from this bucket once it is 3 years
  832. * // of age.
  833. * //-
  834. * bucket.addLifecycleRule({
  835. * action: 'delete',
  836. * condition: {
  837. * age: 365 * 3 // Specified in days.
  838. * }
  839. * }, function(err, apiResponse) {
  840. * if (err) {
  841. * // Error handling omitted.
  842. * }
  843. *
  844. * const lifecycleRules = bucket.metadata.lifecycle.rule;
  845. *
  846. * // Iterate over the Object Lifecycle Management rules on this bucket.
  847. * lifecycleRules.forEach(lifecycleRule => {});
  848. * });
  849. *
  850. * //-
  851. * // By default, the rule you provide will be added to the existing policy.
  852. * // Optionally, you can disable this behavior to replace all of the
  853. * // pre-existing rules.
  854. * //-
  855. * const options = {
  856. * append: false
  857. * };
  858. *
  859. * bucket.addLifecycleRule({
  860. * action: 'delete',
  861. * condition: {
  862. * age: 365 * 3 // Specified in days.
  863. * }
  864. * }, options, function(err, apiResponse) {
  865. * if (err) {
  866. * // Error handling omitted.
  867. * }
  868. *
  869. * // All rules have been replaced with the new "delete" rule.
  870. *
  871. * // Iterate over the Object Lifecycle Management rules on this bucket.
  872. * lifecycleRules.forEach(lifecycleRule => {});
  873. * });
  874. *
  875. * //-
  876. * // For objects created before 2018, "downgrade" the storage class.
  877. * //-
  878. * bucket.addLifecycleRule({
  879. * action: 'setStorageClass',
  880. * storageClass: 'COLDLINE',
  881. * condition: {
  882. * createdBefore: new Date('2018')
  883. * }
  884. * }, function(err, apiResponse) {});
  885. *
  886. * //-
  887. * // Delete objects created before 2016 which have the Coldline storage
  888. * // class.
  889. * //-
  890. * bucket.addLifecycleRule({
  891. * action: 'delete',
  892. * condition: {
  893. * matchesStorageClass: [
  894. * 'COLDLINE'
  895. * ],
  896. * createdBefore: new Date('2016')
  897. * }
  898. * }, function(err, apiResponse) {});
  899. *
  900. * //-
  901. * // Delete object that has a noncurrent timestamp that is at least 100 days.
  902. * //-
  903. * bucket.addLifecycleRule({
  904. * action: 'delete',
  905. * condition: {
  906. * daysSinceNoncurrentTime: 100
  907. * }
  908. * }, function(err, apiResponse) {});
  909. *
  910. * //-
  911. * // Delete object that has a noncurrent timestamp before 2020-01-01.
  912. * //-
  913. * bucket.addLifecycleRule({
  914. * action: 'delete',
  915. * condition: {
  916. * noncurrentTimeBefore: new Date('2020-01-01')
  917. * }
  918. * }, function(err, apiResponse) {});
  919. *
  920. * //-
  921. * // Delete object that has a customTime that is at least 100 days.
  922. * //-
  923. * bucket.addLifecycleRule({
  924. * action: 'delete',
  925. * condition: {
  926. * daysSinceCustomTime: 100
  927. * }
  928. * }, function(err, apiResponse) ());
  929. *
  930. * //-
  931. * // Delete object that has a customTime before 2020-01-01.
  932. * //-
  933. * bucket.addLifecycleRule({
  934. * action: 'delete',
  935. * condition: {
  936. * customTimeBefore: new Date('2020-01-01')
  937. * }
  938. * }, function(err, apiResponse) {});
  939. * ```
  940. */
  941. addLifecycleRule(rule, optionsOrCallback, callback) {
  942. let options = {};
  943. if (typeof optionsOrCallback === 'function') {
  944. callback = optionsOrCallback;
  945. }
  946. else if (optionsOrCallback) {
  947. options = optionsOrCallback;
  948. }
  949. options = options || {};
  950. const rules = Array.isArray(rule) ? rule : [rule];
  951. for (const curRule of rules) {
  952. if (curRule.condition.createdBefore instanceof Date) {
  953. curRule.condition.createdBefore = curRule.condition.createdBefore
  954. .toISOString()
  955. .replace(/T.+$/, '');
  956. }
  957. if (curRule.condition.customTimeBefore instanceof Date) {
  958. curRule.condition.customTimeBefore = curRule.condition.customTimeBefore
  959. .toISOString()
  960. .replace(/T.+$/, '');
  961. }
  962. if (curRule.condition.noncurrentTimeBefore instanceof Date) {
  963. curRule.condition.noncurrentTimeBefore =
  964. curRule.condition.noncurrentTimeBefore
  965. .toISOString()
  966. .replace(/T.+$/, '');
  967. }
  968. }
  969. if (options.append === false) {
  970. this.setMetadata({ lifecycle: { rule: rules } }, options, callback);
  971. return;
  972. }
  973. // The default behavior appends the previously-defined lifecycle rules with
  974. // the new ones just passed in by the user.
  975. this.getMetadata((err, metadata) => {
  976. var _a, _b;
  977. if (err) {
  978. callback(err);
  979. return;
  980. }
  981. const currentLifecycleRules = Array.isArray((_a = metadata.lifecycle) === null || _a === void 0 ? void 0 : _a.rule)
  982. ? (_b = metadata.lifecycle) === null || _b === void 0 ? void 0 : _b.rule
  983. : [];
  984. this.setMetadata({
  985. lifecycle: { rule: currentLifecycleRules.concat(rules) },
  986. }, options, callback);
  987. });
  988. }
  989. /**
  990. * @typedef {object} CombineOptions
  991. * @property {string} [kmsKeyName] Resource name of the Cloud KMS key, of
  992. * the form
  993. * `projects/my-project/locations/location/keyRings/my-kr/cryptoKeys/my-key`,
  994. * that will be used to encrypt the object. Overwrites the object
  995. * metadata's `kms_key_name` value, if any.
  996. * @property {string} [userProject] The ID of the project which will be
  997. * billed for the request.
  998. */
  999. /**
  1000. * @callback CombineCallback
  1001. * @param {?Error} err Request error, if any.
  1002. * @param {File} newFile The new {@link File}.
  1003. * @param {object} apiResponse The full API response.
  1004. */
  1005. /**
  1006. * @typedef {array} CombineResponse
  1007. * @property {File} 0 The new {@link File}.
  1008. * @property {object} 1 The full API response.
  1009. */
  1010. /**
  1011. * Combine multiple files into one new file.
  1012. *
  1013. * See {@link https://cloud.google.com/storage/docs/json_api/v1/objects/compose| Objects: compose API Documentation}
  1014. *
  1015. * @throws {Error} if a non-array is provided as sources argument.
  1016. * @throws {Error} if no sources are provided.
  1017. * @throws {Error} if no destination is provided.
  1018. *
  1019. * @param {string[]|File[]} sources The source files that will be
  1020. * combined.
  1021. * @param {string|File} destination The file you would like the
  1022. * source files combined into.
  1023. * @param {CombineOptions} [options] Configuration options.
  1024. * @param {string} [options.kmsKeyName] Resource name of the Cloud KMS key, of
  1025. * the form
  1026. * `projects/my-project/locations/location/keyRings/my-kr/cryptoKeys/my-key`,
  1027. * that will be used to encrypt the object. Overwrites the object
  1028. * metadata's `kms_key_name` value, if any.
  1029. * @param {string} [options.userProject] The ID of the project which will be
  1030. * billed for the request.
  1031. * @param {CombineCallback} [callback] Callback function.
  1032. * @returns {Promise<CombineResponse>}
  1033. *
  1034. * @example
  1035. * ```
  1036. * const logBucket = storage.bucket('log-bucket');
  1037. *
  1038. * const sources = [
  1039. * logBucket.file('2013-logs.txt'),
  1040. * logBucket.file('2014-logs.txt')
  1041. * ];
  1042. *
  1043. * const allLogs = logBucket.file('all-logs.txt');
  1044. *
  1045. * logBucket.combine(sources, allLogs, function(err, newFile, apiResponse) {
  1046. * // newFile === allLogs
  1047. * });
  1048. *
  1049. * //-
  1050. * // If the callback is omitted, we'll return a Promise.
  1051. * //-
  1052. * logBucket.combine(sources, allLogs).then(function(data) {
  1053. * const newFile = data[0];
  1054. * const apiResponse = data[1];
  1055. * });
  1056. * ```
  1057. */
  1058. combine(sources, destination, optionsOrCallback, callback) {
  1059. var _a;
  1060. if (!Array.isArray(sources) || sources.length === 0) {
  1061. throw new Error(BucketExceptionMessages.PROVIDE_SOURCE_FILE);
  1062. }
  1063. if (!destination) {
  1064. throw new Error(BucketExceptionMessages.DESTINATION_FILE_NOT_SPECIFIED);
  1065. }
  1066. let options = {};
  1067. if (typeof optionsOrCallback === 'function') {
  1068. callback = optionsOrCallback;
  1069. }
  1070. else if (optionsOrCallback) {
  1071. options = optionsOrCallback;
  1072. }
  1073. this.disableAutoRetryConditionallyIdempotent_(this.methods.setMetadata, // Not relevant but param is required
  1074. AvailableServiceObjectMethods.setMetadata, // Same as above
  1075. options);
  1076. const convertToFile = (file) => {
  1077. if (file instanceof file_js_1.File) {
  1078. return file;
  1079. }
  1080. return this.file(file);
  1081. };
  1082. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1083. sources = sources.map(convertToFile);
  1084. const destinationFile = convertToFile(destination);
  1085. callback = callback || index_js_1.util.noop;
  1086. if (!destinationFile.metadata.contentType) {
  1087. const destinationContentType = mime_1.default.getType(destinationFile.name) || undefined;
  1088. if (destinationContentType) {
  1089. destinationFile.metadata.contentType = destinationContentType;
  1090. }
  1091. }
  1092. let maxRetries = this.storage.retryOptions.maxRetries;
  1093. if ((((_a = destinationFile === null || destinationFile === void 0 ? void 0 : destinationFile.instancePreconditionOpts) === null || _a === void 0 ? void 0 : _a.ifGenerationMatch) ===
  1094. undefined &&
  1095. options.ifGenerationMatch === undefined &&
  1096. this.storage.retryOptions.idempotencyStrategy ===
  1097. storage_js_1.IdempotencyStrategy.RetryConditional) ||
  1098. this.storage.retryOptions.idempotencyStrategy ===
  1099. storage_js_1.IdempotencyStrategy.RetryNever) {
  1100. maxRetries = 0;
  1101. }
  1102. if (options.ifGenerationMatch === undefined) {
  1103. Object.assign(options, destinationFile.instancePreconditionOpts, options);
  1104. }
  1105. // Make the request from the destination File object.
  1106. destinationFile.request({
  1107. method: 'POST',
  1108. uri: '/compose',
  1109. maxRetries,
  1110. json: {
  1111. destination: {
  1112. contentType: destinationFile.metadata.contentType,
  1113. contentEncoding: destinationFile.metadata.contentEncoding,
  1114. },
  1115. sourceObjects: sources.map(source => {
  1116. const sourceObject = {
  1117. name: source.name,
  1118. };
  1119. if (source.metadata && source.metadata.generation) {
  1120. sourceObject.generation = parseInt(source.metadata.generation.toString());
  1121. }
  1122. return sourceObject;
  1123. }),
  1124. },
  1125. qs: options,
  1126. }, (err, resp) => {
  1127. this.storage.retryOptions.autoRetry = this.instanceRetryValue;
  1128. if (err) {
  1129. callback(err, null, resp);
  1130. return;
  1131. }
  1132. callback(null, destinationFile, resp);
  1133. });
  1134. }
  1135. /**
  1136. * See a {@link https://cloud.google.com/storage/docs/json_api/v1/objects/watchAll| Objects: watchAll request body}.
  1137. *
  1138. * @typedef {object} CreateChannelConfig
  1139. * @property {string} address The address where notifications are
  1140. * delivered for this channel.
  1141. * @property {string} [delimiter] Returns results in a directory-like mode.
  1142. * @property {number} [maxResults] Maximum number of `items` plus `prefixes`
  1143. * to return in a single page of responses.
  1144. * @property {string} [pageToken] A previously-returned page token
  1145. * representing part of the larger set of results to view.
  1146. * @property {string} [prefix] Filter results to objects whose names begin
  1147. * with this prefix.
  1148. * @property {string} [projection=noAcl] Set of properties to return.
  1149. * @property {string} [userProject] The ID of the project which will be
  1150. * billed for the request.
  1151. * @property {boolean} [versions=false] If `true`, lists all versions of an object
  1152. * as distinct results.
  1153. */
  1154. /**
  1155. * @typedef {object} CreateChannelOptions
  1156. * @property {string} [userProject] The ID of the project which will be
  1157. * billed for the request.
  1158. */
  1159. /**
  1160. * @typedef {array} CreateChannelResponse
  1161. * @property {Channel} 0 The new {@link Channel}.
  1162. * @property {object} 1 The full API response.
  1163. */
  1164. /**
  1165. * @callback CreateChannelCallback
  1166. * @param {?Error} err Request error, if any.
  1167. * @param {Channel} channel The new {@link Channel}.
  1168. * @param {object} apiResponse The full API response.
  1169. */
  1170. /**
  1171. * Create a channel that will be notified when objects in this bucket changes.
  1172. *
  1173. * @throws {Error} If an ID is not provided.
  1174. * @throws {Error} If an address is not provided.
  1175. *
  1176. * See {@link https://cloud.google.com/storage/docs/json_api/v1/objects/watchAll| Objects: watchAll API Documentation}
  1177. *
  1178. * @param {string} id The ID of the channel to create.
  1179. * @param {CreateChannelConfig} config Configuration for creating channel.
  1180. * @param {string} config.address The address where notifications are
  1181. * delivered for this channel.
  1182. * @param {string} [config.delimiter] Returns results in a directory-like mode.
  1183. * @param {number} [config.maxResults] Maximum number of `items` plus `prefixes`
  1184. * to return in a single page of responses.
  1185. * @param {string} [config.pageToken] A previously-returned page token
  1186. * representing part of the larger set of results to view.
  1187. * @param {string} [config.prefix] Filter results to objects whose names begin
  1188. * with this prefix.
  1189. * @param {string} [config.projection=noAcl] Set of properties to return.
  1190. * @param {string} [config.userProject] The ID of the project which will be
  1191. * billed for the request.
  1192. * @param {boolean} [config.versions=false] If `true`, lists all versions of an object
  1193. * as distinct results.
  1194. * @param {CreateChannelOptions} [options] Configuration options.
  1195. * @param {string} [options.userProject] The ID of the project which will be
  1196. * billed for the request.
  1197. * @param {CreateChannelCallback} [callback] Callback function.
  1198. * @returns {Promise<CreateChannelResponse>}
  1199. *
  1200. * @example
  1201. * ```
  1202. * const {Storage} = require('@google-cloud/storage');
  1203. * const storage = new Storage();
  1204. * const bucket = storage.bucket('albums');
  1205. * const id = 'new-channel-id';
  1206. *
  1207. * const config = {
  1208. * address: 'https://...'
  1209. * };
  1210. *
  1211. * bucket.createChannel(id, config, function(err, channel, apiResponse) {
  1212. * if (!err) {
  1213. * // Channel created successfully.
  1214. * }
  1215. * });
  1216. *
  1217. * //-
  1218. * // If the callback is omitted, we'll return a Promise.
  1219. * //-
  1220. * bucket.createChannel(id, config).then(function(data) {
  1221. * const channel = data[0];
  1222. * const apiResponse = data[1];
  1223. * });
  1224. * ```
  1225. */
  1226. createChannel(id, config, optionsOrCallback, callback) {
  1227. if (typeof id !== 'string') {
  1228. throw new Error(BucketExceptionMessages.CHANNEL_ID_REQUIRED);
  1229. }
  1230. let options = {};
  1231. if (typeof optionsOrCallback === 'function') {
  1232. callback = optionsOrCallback;
  1233. }
  1234. else if (optionsOrCallback) {
  1235. options = optionsOrCallback;
  1236. }
  1237. this.request({
  1238. method: 'POST',
  1239. uri: '/o/watch',
  1240. json: Object.assign({
  1241. id,
  1242. type: 'web_hook',
  1243. }, config),
  1244. qs: options,
  1245. }, (err, apiResponse) => {
  1246. if (err) {
  1247. callback(err, null, apiResponse);
  1248. return;
  1249. }
  1250. const resourceId = apiResponse.resourceId;
  1251. const channel = this.storage.channel(id, resourceId);
  1252. channel.metadata = apiResponse;
  1253. callback(null, channel, apiResponse);
  1254. });
  1255. }
  1256. /**
  1257. * Metadata to set for the Notification.
  1258. *
  1259. * @typedef {object} CreateNotificationOptions
  1260. * @property {object} [customAttributes] An optional list of additional
  1261. * attributes to attach to each Cloud PubSub message published for this
  1262. * notification subscription.
  1263. * @property {string[]} [eventTypes] If present, only send notifications about
  1264. * listed event types. If empty, sent notifications for all event types.
  1265. * @property {string} [objectNamePrefix] If present, only apply this
  1266. * notification configuration to object names that begin with this prefix.
  1267. * @property {string} [payloadFormat] The desired content of the Payload.
  1268. * Defaults to `JSON_API_V1`.
  1269. *
  1270. * Acceptable values are:
  1271. * - `JSON_API_V1`
  1272. *
  1273. * - `NONE`
  1274. * @property {string} [userProject] The ID of the project which will be
  1275. * billed for the request.
  1276. */
  1277. /**
  1278. * @callback CreateNotificationCallback
  1279. * @param {?Error} err Request error, if any.
  1280. * @param {Notification} notification The new {@link Notification}.
  1281. * @param {object} apiResponse The full API response.
  1282. */
  1283. /**
  1284. * @typedef {array} CreateNotificationResponse
  1285. * @property {Notification} 0 The new {@link Notification}.
  1286. * @property {object} 1 The full API response.
  1287. */
  1288. /**
  1289. * Creates a notification subscription for the bucket.
  1290. *
  1291. * See {@link https://cloud.google.com/storage/docs/json_api/v1/notifications/insert| Notifications: insert}
  1292. *
  1293. * @param {Topic|string} topic The Cloud PubSub topic to which this
  1294. * subscription publishes. If the project ID is omitted, the current
  1295. * project ID will be used.
  1296. *
  1297. * Acceptable formats are:
  1298. * - `projects/grape-spaceship-123/topics/my-topic`
  1299. *
  1300. * - `my-topic`
  1301. * @param {CreateNotificationOptions} [options] Metadata to set for the
  1302. * notification.
  1303. * @param {object} [options.customAttributes] An optional list of additional
  1304. * attributes to attach to each Cloud PubSub message published for this
  1305. * notification subscription.
  1306. * @param {string[]} [options.eventTypes] If present, only send notifications about
  1307. * listed event types. If empty, sent notifications for all event types.
  1308. * @param {string} [options.objectNamePrefix] If present, only apply this
  1309. * notification configuration to object names that begin with this prefix.
  1310. * @param {string} [options.payloadFormat] The desired content of the Payload.
  1311. * Defaults to `JSON_API_V1`.
  1312. *
  1313. * Acceptable values are:
  1314. * - `JSON_API_V1`
  1315. *
  1316. * - `NONE`
  1317. * @param {string} [options.userProject] The ID of the project which will be
  1318. * billed for the request.
  1319. * @param {CreateNotificationCallback} [callback] Callback function.
  1320. * @returns {Promise<CreateNotificationResponse>}
  1321. * @throws {Error} If a valid topic is not provided.
  1322. * @see Notification#create
  1323. *
  1324. * @example
  1325. * ```
  1326. * const {Storage} = require('@google-cloud/storage');
  1327. * const storage = new Storage();
  1328. * const myBucket = storage.bucket('my-bucket');
  1329. *
  1330. * const callback = function(err, notification, apiResponse) {
  1331. * if (!err) {
  1332. * // The notification was created successfully.
  1333. * }
  1334. * };
  1335. *
  1336. * myBucket.createNotification('my-topic', callback);
  1337. *
  1338. * //-
  1339. * // Configure the nofiication by providing Notification metadata.
  1340. * //-
  1341. * const metadata = {
  1342. * objectNamePrefix: 'prefix-'
  1343. * };
  1344. *
  1345. * myBucket.createNotification('my-topic', metadata, callback);
  1346. *
  1347. * //-
  1348. * // If the callback is omitted, we'll return a Promise.
  1349. * //-
  1350. * myBucket.createNotification('my-topic').then(function(data) {
  1351. * const notification = data[0];
  1352. * const apiResponse = data[1];
  1353. * });
  1354. *
  1355. * ```
  1356. * @example <caption>include:samples/createNotification.js</caption>
  1357. * region_tag:storage_create_bucket_notifications
  1358. * Another example:
  1359. */
  1360. createNotification(topic, optionsOrCallback, callback) {
  1361. let options = {};
  1362. if (typeof optionsOrCallback === 'function') {
  1363. callback = optionsOrCallback;
  1364. }
  1365. else if (optionsOrCallback) {
  1366. options = optionsOrCallback;
  1367. }
  1368. const topicIsObject = topic !== null && typeof topic === 'object';
  1369. if (topicIsObject && index_js_1.util.isCustomType(topic, 'pubsub/topic')) {
  1370. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  1371. topic = topic.name;
  1372. }
  1373. if (typeof topic !== 'string') {
  1374. throw new Error(BucketExceptionMessages.TOPIC_NAME_REQUIRED);
  1375. }
  1376. const body = Object.assign({ topic }, options);
  1377. if (body.topic.indexOf('projects') !== 0) {
  1378. body.topic = 'projects/{{projectId}}/topics/' + body.topic;
  1379. }
  1380. body.topic = `//pubsub.${this.storage.universeDomain}/` + body.topic;
  1381. if (!body.payloadFormat) {
  1382. body.payloadFormat = 'JSON_API_V1';
  1383. }
  1384. const query = {};
  1385. if (body.userProject) {
  1386. query.userProject = body.userProject;
  1387. delete body.userProject;
  1388. }
  1389. this.request({
  1390. method: 'POST',
  1391. uri: '/notificationConfigs',
  1392. json: (0, util_js_1.convertObjKeysToSnakeCase)(body),
  1393. qs: query,
  1394. maxRetries: 0, //explicitly set this value since this is a non-idempotent function
  1395. }, (err, apiResponse) => {
  1396. if (err) {
  1397. callback(err, null, apiResponse);
  1398. return;
  1399. }
  1400. const notification = this.notification(apiResponse.id);
  1401. notification.metadata = apiResponse;
  1402. callback(null, notification, apiResponse);
  1403. });
  1404. }
  1405. /**
  1406. * @typedef {object} DeleteFilesOptions Query object. See {@link Bucket#getFiles}
  1407. * for all of the supported properties.
  1408. * @property {boolean} [force] Suppress errors until all files have been
  1409. * processed.
  1410. */
  1411. /**
  1412. * @callback DeleteFilesCallback
  1413. * @param {?Error|?Error[]} err Request error, if any, or array of errors from
  1414. * files that were not able to be deleted.
  1415. * @param {object} [apiResponse] The full API response.
  1416. */
  1417. /**
  1418. * Iterate over the bucket's files, calling `file.delete()` on each.
  1419. *
  1420. * <strong>This is not an atomic request.</strong> A delete attempt will be
  1421. * made for each file individually. Any one can fail, in which case only a
  1422. * portion of the files you intended to be deleted would have.
  1423. *
  1424. * Operations are performed in parallel, up to 10 at once. The first error
  1425. * breaks the loop and will execute the provided callback with it. Specify
  1426. * `{ force: true }` to suppress the errors until all files have had a chance
  1427. * to be processed.
  1428. *
  1429. * File preconditions cannot be passed to this function. It will not retry unless
  1430. * the idempotency strategy is set to retry always.
  1431. *
  1432. * The `query` object passed as the first argument will also be passed to
  1433. * {@link Bucket#getFiles}.
  1434. *
  1435. * See {@link https://cloud.google.com/storage/docs/json_api/v1/objects/delete| Objects: delete API Documentation}
  1436. *
  1437. * @param {DeleteFilesOptions} [query] Query object. See {@link Bucket#getFiles}
  1438. * @param {boolean} [query.force] Suppress errors until all files have been
  1439. * processed.
  1440. * @param {DeleteFilesCallback} [callback] Callback function.
  1441. * @returns {Promise}
  1442. *
  1443. * @example
  1444. * ```
  1445. * const {Storage} = require('@google-cloud/storage');
  1446. * const storage = new Storage();
  1447. * const bucket = storage.bucket('albums');
  1448. *
  1449. * //-
  1450. * // Delete all of the files in the bucket.
  1451. * //-
  1452. * bucket.deleteFiles(function(err) {});
  1453. *
  1454. * //-
  1455. * // By default, if a file cannot be deleted, this method will stop deleting
  1456. * // files from your bucket. You can override this setting with `force:
  1457. * // true`.
  1458. * //-
  1459. * bucket.deleteFiles({
  1460. * force: true
  1461. * }, function(errors) {
  1462. * // `errors`:
  1463. * // Array of errors if any occurred, otherwise null.
  1464. * });
  1465. *
  1466. * //-
  1467. * // The first argument to this method acts as a query to
  1468. * // {@link Bucket#getFiles}. As an example, you can delete files
  1469. * // which match a prefix.
  1470. * //-
  1471. * bucket.deleteFiles({
  1472. * prefix: 'images/'
  1473. * }, function(err) {
  1474. * if (!err) {
  1475. * // All files in the `images` directory have been deleted.
  1476. * }
  1477. * });
  1478. *
  1479. * //-
  1480. * // If the callback is omitted, we'll return a Promise.
  1481. * //-
  1482. * bucket.deleteFiles().then(function() {});
  1483. * ```
  1484. */
  1485. deleteFiles(queryOrCallback, callback) {
  1486. let query = {};
  1487. if (typeof queryOrCallback === 'function') {
  1488. callback = queryOrCallback;
  1489. }
  1490. else if (queryOrCallback) {
  1491. query = queryOrCallback;
  1492. }
  1493. const MAX_PARALLEL_LIMIT = 10;
  1494. const MAX_QUEUE_SIZE = 1000;
  1495. const errors = [];
  1496. const deleteFile = (file) => {
  1497. return file.delete(query).catch(err => {
  1498. if (!query.force) {
  1499. throw err;
  1500. }
  1501. errors.push(err);
  1502. });
  1503. };
  1504. (async () => {
  1505. try {
  1506. let promises = [];
  1507. const limit = (0, p_limit_1.default)(MAX_PARALLEL_LIMIT);
  1508. const filesStream = this.getFilesStream(query);
  1509. for await (const curFile of filesStream) {
  1510. if (promises.length >= MAX_QUEUE_SIZE) {
  1511. await Promise.all(promises);
  1512. promises = [];
  1513. }
  1514. promises.push(limit(() => deleteFile(curFile)).catch(e => {
  1515. filesStream.destroy();
  1516. throw e;
  1517. }));
  1518. }
  1519. await Promise.all(promises);
  1520. callback(errors.length > 0 ? errors : null);
  1521. }
  1522. catch (e) {
  1523. callback(e);
  1524. return;
  1525. }
  1526. })();
  1527. }
  1528. /**
  1529. * @deprecated
  1530. * @typedef {array} DeleteLabelsResponse
  1531. * @property {object} 0 The full API response.
  1532. */
  1533. /**
  1534. * @deprecated
  1535. * @callback DeleteLabelsCallback
  1536. * @param {?Error} err Request error, if any.
  1537. * @param {object} metadata Bucket's metadata.
  1538. */
  1539. /**
  1540. * @deprecated Use setMetadata directly
  1541. * Delete one or more labels from this bucket.
  1542. *
  1543. * @param {string|string[]} [labels] The labels to delete. If no labels are
  1544. * provided, all of the labels are removed.
  1545. * @param {DeleteLabelsCallback} [callback] Callback function.
  1546. * @param {DeleteLabelsOptions} [options] Options, including precondition options
  1547. * @returns {Promise<DeleteLabelsResponse>}
  1548. *
  1549. * @example
  1550. * ```
  1551. * const {Storage} = require('@google-cloud/storage');
  1552. * const storage = new Storage();
  1553. * const bucket = storage.bucket('albums');
  1554. *
  1555. * //-
  1556. * // Delete all of the labels from this bucket.
  1557. * //-
  1558. * bucket.deleteLabels(function(err, apiResponse) {});
  1559. *
  1560. * //-
  1561. * // Delete a single label.
  1562. * //-
  1563. * bucket.deleteLabels('labelone', function(err, apiResponse) {});
  1564. *
  1565. * //-
  1566. * // Delete a specific set of labels.
  1567. * //-
  1568. * bucket.deleteLabels([
  1569. * 'labelone',
  1570. * 'labeltwo'
  1571. * ], function(err, apiResponse) {});
  1572. *
  1573. * //-
  1574. * // If the callback is omitted, we'll return a Promise.
  1575. * //-
  1576. * bucket.deleteLabels().then(function(data) {
  1577. * const apiResponse = data[0];
  1578. * });
  1579. * ```
  1580. */
  1581. deleteLabels(labelsOrCallbackOrOptions, optionsOrCallback, callback) {
  1582. let labels = new Array();
  1583. let options = {};
  1584. if (typeof labelsOrCallbackOrOptions === 'function') {
  1585. callback = labelsOrCallbackOrOptions;
  1586. }
  1587. else if (typeof labelsOrCallbackOrOptions === 'string') {
  1588. labels = [labelsOrCallbackOrOptions];
  1589. }
  1590. else if (Array.isArray(labelsOrCallbackOrOptions)) {
  1591. labels = labelsOrCallbackOrOptions;
  1592. }
  1593. else if (labelsOrCallbackOrOptions) {
  1594. options = labelsOrCallbackOrOptions;
  1595. }
  1596. if (typeof optionsOrCallback === 'function') {
  1597. callback = optionsOrCallback;
  1598. }
  1599. else if (optionsOrCallback) {
  1600. options = optionsOrCallback;
  1601. }
  1602. const deleteLabels = (labels) => {
  1603. const nullLabelMap = labels.reduce((nullLabelMap, labelKey) => {
  1604. nullLabelMap[labelKey] = null;
  1605. return nullLabelMap;
  1606. }, {});
  1607. if ((options === null || options === void 0 ? void 0 : options.ifMetagenerationMatch) !== undefined) {
  1608. this.setLabels(nullLabelMap, options, callback);
  1609. }
  1610. else {
  1611. this.setLabels(nullLabelMap, callback);
  1612. }
  1613. };
  1614. if (labels.length === 0) {
  1615. this.getLabels((err, labels) => {
  1616. if (err) {
  1617. callback(err);
  1618. return;
  1619. }
  1620. deleteLabels(Object.keys(labels));
  1621. });
  1622. }
  1623. else {
  1624. deleteLabels(labels);
  1625. }
  1626. }
  1627. /**
  1628. * @typedef {array} DisableRequesterPaysResponse
  1629. * @property {object} 0 The full API response.
  1630. */
  1631. /**
  1632. * @callback DisableRequesterPaysCallback
  1633. * @param {?Error} err Request error, if any.
  1634. * @param {object} apiResponse The full API response.
  1635. */
  1636. /**
  1637. * <div class="notice">
  1638. * <strong>Early Access Testers Only</strong>
  1639. * <p>
  1640. * This feature is not yet widely-available.
  1641. * </p>
  1642. * </div>
  1643. *
  1644. * Disable `requesterPays` functionality from this bucket.
  1645. *
  1646. * @param {DisableRequesterPaysCallback} [callback] Callback function.
  1647. * @param {DisableRequesterPaysOptions} [options] Options, including precondition options
  1648. * @returns {Promise<DisableRequesterPaysCallback>}
  1649. *
  1650. * @example
  1651. * ```
  1652. * const {Storage} = require('@google-cloud/storage');
  1653. * const storage = new Storage();
  1654. * const bucket = storage.bucket('albums');
  1655. *
  1656. * bucket.disableRequesterPays(function(err, apiResponse) {
  1657. * if (!err) {
  1658. * // requesterPays functionality disabled successfully.
  1659. * }
  1660. * });
  1661. *
  1662. * //-
  1663. * // If the callback is omitted, we'll return a Promise.
  1664. * //-
  1665. * bucket.disableRequesterPays().then(function(data) {
  1666. * const apiResponse = data[0];
  1667. * });
  1668. *
  1669. * ```
  1670. * @example <caption>include:samples/requesterPays.js</caption>
  1671. * region_tag:storage_disable_requester_pays
  1672. * Example of disabling requester pays:
  1673. */
  1674. disableRequesterPays(optionsOrCallback, callback) {
  1675. let options = {};
  1676. if (typeof optionsOrCallback === 'function') {
  1677. callback = optionsOrCallback;
  1678. }
  1679. else if (optionsOrCallback) {
  1680. options = optionsOrCallback;
  1681. }
  1682. this.setMetadata({
  1683. billing: {
  1684. requesterPays: false,
  1685. },
  1686. }, options, callback);
  1687. }
  1688. /**
  1689. * Configuration object for enabling logging.
  1690. *
  1691. * @typedef {object} EnableLoggingOptions
  1692. * @property {string|Bucket} [bucket] The bucket for the log entries. By
  1693. * default, the current bucket is used.
  1694. * @property {string} prefix A unique prefix for log object names.
  1695. */
  1696. /**
  1697. * Enable logging functionality for this bucket. This will make two API
  1698. * requests, first to grant Cloud Storage WRITE permission to the bucket, then
  1699. * to set the appropriate configuration on the Bucket's metadata.
  1700. *
  1701. * @param {EnableLoggingOptions} config Configuration options.
  1702. * @param {string|Bucket} [config.bucket] The bucket for the log entries. By
  1703. * default, the current bucket is used.
  1704. * @param {string} config.prefix A unique prefix for log object names.
  1705. * @param {SetBucketMetadataCallback} [callback] Callback function.
  1706. * @returns {Promise<SetBucketMetadataResponse>}
  1707. *
  1708. * @example
  1709. * ```
  1710. * const {Storage} = require('@google-cloud/storage');
  1711. * const storage = new Storage();
  1712. * const bucket = storage.bucket('albums');
  1713. *
  1714. * const config = {
  1715. * prefix: 'log'
  1716. * };
  1717. *
  1718. * bucket.enableLogging(config, function(err, apiResponse) {
  1719. * if (!err) {
  1720. * // Logging functionality enabled successfully.
  1721. * }
  1722. * });
  1723. *
  1724. * ```
  1725. * @example
  1726. * Optionally, provide a destination bucket.
  1727. * ```
  1728. * const config = {
  1729. * prefix: 'log',
  1730. * bucket: 'destination-bucket'
  1731. * };
  1732. *
  1733. * bucket.enableLogging(config, function(err, apiResponse) {});
  1734. * ```
  1735. *
  1736. * @example
  1737. * If the callback is omitted, we'll return a Promise.
  1738. * ```
  1739. * bucket.enableLogging(config).then(function(data) {
  1740. * const apiResponse = data[0];
  1741. * });
  1742. * ```
  1743. */
  1744. enableLogging(config, callback) {
  1745. if (!config ||
  1746. typeof config === 'function' ||
  1747. typeof config.prefix === 'undefined') {
  1748. throw new Error(BucketExceptionMessages.CONFIGURATION_OBJECT_PREFIX_REQUIRED);
  1749. }
  1750. let logBucket = this.id;
  1751. if (config.bucket && config.bucket instanceof Bucket) {
  1752. logBucket = config.bucket.id;
  1753. }
  1754. else if (config.bucket && typeof config.bucket === 'string') {
  1755. logBucket = config.bucket;
  1756. }
  1757. const options = {};
  1758. if (config === null || config === void 0 ? void 0 : config.ifMetagenerationMatch) {
  1759. options.ifMetagenerationMatch = config.ifMetagenerationMatch;
  1760. }
  1761. if (config === null || config === void 0 ? void 0 : config.ifMetagenerationNotMatch) {
  1762. options.ifMetagenerationNotMatch = config.ifMetagenerationNotMatch;
  1763. }
  1764. (async () => {
  1765. try {
  1766. const [policy] = await this.iam.getPolicy();
  1767. policy.bindings.push({
  1768. members: ['group:cloud-storage-analytics@google.com'],
  1769. role: 'roles/storage.objectCreator',
  1770. });
  1771. await this.iam.setPolicy(policy);
  1772. this.setMetadata({
  1773. logging: {
  1774. logBucket,
  1775. logObjectPrefix: config.prefix,
  1776. },
  1777. }, options, callback);
  1778. }
  1779. catch (e) {
  1780. callback(e);
  1781. return;
  1782. }
  1783. })();
  1784. }
  1785. /**
  1786. * @typedef {array} EnableRequesterPaysResponse
  1787. * @property {object} 0 The full API response.
  1788. */
  1789. /**
  1790. * @callback EnableRequesterPaysCallback
  1791. * @param {?Error} err Request error, if any.
  1792. * @param {object} apiResponse The full API response.
  1793. */
  1794. /**
  1795. * <div class="notice">
  1796. * <strong>Early Access Testers Only</strong>
  1797. * <p>
  1798. * This feature is not yet widely-available.
  1799. * </p>
  1800. * </div>
  1801. *
  1802. * Enable `requesterPays` functionality for this bucket. This enables you, the
  1803. * bucket owner, to have the requesting user assume the charges for the access
  1804. * to your bucket and its contents.
  1805. *
  1806. * @param {EnableRequesterPaysCallback | EnableRequesterPaysOptions} [optionsOrCallback]
  1807. * Callback function or precondition options.
  1808. * @returns {Promise<EnableRequesterPaysResponse>}
  1809. *
  1810. * @example
  1811. * ```
  1812. * const {Storage} = require('@google-cloud/storage');
  1813. * const storage = new Storage();
  1814. * const bucket = storage.bucket('albums');
  1815. *
  1816. * bucket.enableRequesterPays(function(err, apiResponse) {
  1817. * if (!err) {
  1818. * // requesterPays functionality enabled successfully.
  1819. * }
  1820. * });
  1821. *
  1822. * //-
  1823. * // If the callback is omitted, we'll return a Promise.
  1824. * //-
  1825. * bucket.enableRequesterPays().then(function(data) {
  1826. * const apiResponse = data[0];
  1827. * });
  1828. *
  1829. * ```
  1830. * @example <caption>include:samples/requesterPays.js</caption>
  1831. * region_tag:storage_enable_requester_pays
  1832. * Example of enabling requester pays:
  1833. */
  1834. enableRequesterPays(optionsOrCallback, cb) {
  1835. let options = {};
  1836. if (typeof optionsOrCallback === 'function') {
  1837. cb = optionsOrCallback;
  1838. }
  1839. else if (optionsOrCallback) {
  1840. options = optionsOrCallback;
  1841. }
  1842. this.setMetadata({
  1843. billing: {
  1844. requesterPays: true,
  1845. },
  1846. }, options, cb);
  1847. }
  1848. /**
  1849. * Create a {@link File} object. See {@link File} to see how to handle
  1850. * the different use cases you may have.
  1851. *
  1852. * @param {string} name The name of the file in this bucket.
  1853. * @param {FileOptions} [options] Configuration options.
  1854. * @param {string|number} [options.generation] Only use a specific revision of
  1855. * this file.
  1856. * @param {string} [options.encryptionKey] A custom encryption key. See
  1857. * {@link https://cloud.google.com/storage/docs/encryption#customer-supplied| Customer-supplied Encryption Keys}.
  1858. * @param {string} [options.kmsKeyName] The name of the Cloud KMS key that will
  1859. * be used to encrypt the object. Must be in the format:
  1860. * `projects/my-project/locations/location/keyRings/my-kr/cryptoKeys/my-key`.
  1861. * KMS key ring must use the same location as the bucket.
  1862. * @param {string} [options.userProject] The ID of the project which will be
  1863. * billed for all requests made from File object.
  1864. * @returns {File}
  1865. *
  1866. * @example
  1867. * ```
  1868. * const {Storage} = require('@google-cloud/storage');
  1869. * const storage = new Storage();
  1870. * const bucket = storage.bucket('albums');
  1871. * const file = bucket.file('my-existing-file.png');
  1872. * ```
  1873. */
  1874. file(name, options) {
  1875. if (!name) {
  1876. throw Error(BucketExceptionMessages.SPECIFY_FILE_NAME);
  1877. }
  1878. return new file_js_1.File(this, name, options);
  1879. }
  1880. /**
  1881. * @typedef {array} GetFilesResponse
  1882. * @property {File[]} 0 Array of {@link File} instances.
  1883. * @param {object} nextQuery 1 A query object to receive more results.
  1884. * @param {object} apiResponse 2 The full API response.
  1885. */
  1886. /**
  1887. * @callback GetFilesCallback
  1888. * @param {?Error} err Request error, if any.
  1889. * @param {File[]} files Array of {@link File} instances.
  1890. * @param {object} nextQuery A query object to receive more results.
  1891. * @param {object} apiResponse The full API response.
  1892. */
  1893. /**
  1894. * Query object for listing files.
  1895. *
  1896. * @typedef {object} GetFilesOptions
  1897. * @property {boolean} [autoPaginate=true] Have pagination handled
  1898. * automatically.
  1899. * @property {string} [delimiter] Results will contain only objects whose
  1900. * names, aside from the prefix, do not contain delimiter. Objects whose
  1901. * names, aside from the prefix, contain delimiter will have their name
  1902. * truncated after the delimiter, returned in `apiResponse.prefixes`.
  1903. * Duplicate prefixes are omitted.
  1904. * @property {string} [endOffset] Filter results to objects whose names are
  1905. * lexicographically before endOffset. If startOffset is also set, the objects
  1906. * listed have names between startOffset (inclusive) and endOffset (exclusive).
  1907. * @property {boolean} [includeFoldersAsPrefixes] If true, includes folders and
  1908. * managed folders in the set of prefixes returned by the query. Only applicable if
  1909. * delimiter is set to / and autoPaginate is set to false.
  1910. * See: https://cloud.google.com/storage/docs/managed-folders
  1911. * @property {boolean} [includeTrailingDelimiter] If true, objects that end in
  1912. * exactly one instance of delimiter have their metadata included in items[]
  1913. * in addition to the relevant part of the object name appearing in prefixes[].
  1914. * @property {string} [prefix] Filter results to objects whose names begin
  1915. * with this prefix.
  1916. * @property {string} [matchGlob] A glob pattern used to filter results,
  1917. * for example foo*bar
  1918. * @property {number} [maxApiCalls] Maximum number of API calls to make.
  1919. * @property {number} [maxResults] Maximum number of items plus prefixes to
  1920. * return per call.
  1921. * Note: By default will handle pagination automatically
  1922. * if more than 1 page worth of results are requested per call.
  1923. * When `autoPaginate` is set to `false` the smaller of `maxResults`
  1924. * or 1 page of results will be returned per call.
  1925. * @property {string} [pageToken] A previously-returned page token
  1926. * representing part of the larger set of results to view.
  1927. * @property {boolean} [softDeleted] If true, only soft-deleted object versions will be
  1928. * listed as distinct results in order of generation number. Note `soft_deleted` and
  1929. * `versions` cannot be set to true simultaneously.
  1930. * @property {string} [startOffset] Filter results to objects whose names are
  1931. * lexicographically equal to or after startOffset. If endOffset is also set,
  1932. * the objects listed have names between startOffset (inclusive) and endOffset (exclusive).
  1933. * @property {string} [userProject] The ID of the project which will be
  1934. * billed for the request.
  1935. * @property {boolean} [versions] If true, returns File objects scoped to
  1936. * their versions.
  1937. */
  1938. /**
  1939. * Get {@link File} objects for the files currently in the bucket.
  1940. *
  1941. * See {@link https://cloud.google.com/storage/docs/json_api/v1/objects/list| Objects: list API Documentation}
  1942. *
  1943. * @param {GetFilesOptions} [query] Query object for listing files.
  1944. * @param {boolean} [query.autoPaginate=true] Have pagination handled
  1945. * automatically.
  1946. * @param {string} [query.delimiter] Results will contain only objects whose
  1947. * names, aside from the prefix, do not contain delimiter. Objects whose
  1948. * names, aside from the prefix, contain delimiter will have their name
  1949. * truncated after the delimiter, returned in `apiResponse.prefixes`.
  1950. * Duplicate prefixes are omitted.
  1951. * @param {string} [query.endOffset] Filter results to objects whose names are
  1952. * lexicographically before endOffset. If startOffset is also set, the objects
  1953. * listed have names between startOffset (inclusive) and endOffset (exclusive).
  1954. * @param {boolean} [query.includeFoldersAsPrefixes] If true, includes folders and
  1955. * managed folders in the set of prefixes returned by the query. Only applicable if
  1956. * delimiter is set to / and autoPaginate is set to false.
  1957. * See: https://cloud.google.com/storage/docs/managed-folders
  1958. * @param {boolean} [query.includeTrailingDelimiter] If true, objects that end in
  1959. * exactly one instance of delimiter have their metadata included in items[]
  1960. * in addition to the relevant part of the object name appearing in prefixes[].
  1961. * @param {string} [query.prefix] Filter results to objects whose names begin
  1962. * with this prefix.
  1963. * @param {number} [query.maxApiCalls] Maximum number of API calls to make.
  1964. * @param {number} [query.maxResults] Maximum number of items plus prefixes to
  1965. * return per call.
  1966. * Note: By default will handle pagination automatically
  1967. * if more than 1 page worth of results are requested per call.
  1968. * When `autoPaginate` is set to `false` the smaller of `maxResults`
  1969. * or 1 page of results will be returned per call.
  1970. * @param {string} [query.pageToken] A previously-returned page token
  1971. * representing part of the larger set of results to view.
  1972. * @param {boolean} [query.softDeleted] If true, only soft-deleted object versions will be
  1973. * listed as distinct results in order of generation number. Note `soft_deleted` and
  1974. * `versions` cannot be set to true simultaneously.
  1975. * @param {string} [query.startOffset] Filter results to objects whose names are
  1976. * lexicographically equal to or after startOffset. If endOffset is also set,
  1977. * the objects listed have names between startOffset (inclusive) and endOffset (exclusive).
  1978. * @param {string} [query.userProject] The ID of the project which will be
  1979. * billed for the request.
  1980. * @param {boolean} [query.versions] If true, returns File objects scoped to
  1981. * their versions.
  1982. * @param {GetFilesCallback} [callback] Callback function.
  1983. * @returns {Promise<GetFilesResponse>}
  1984. *
  1985. * @example
  1986. * ```
  1987. * const {Storage} = require('@google-cloud/storage');
  1988. * const storage = new Storage();
  1989. * const bucket = storage.bucket('albums');
  1990. *
  1991. * bucket.getFiles(function(err, files) {
  1992. * if (!err) {
  1993. * // files is an array of File objects.
  1994. * }
  1995. * });
  1996. *
  1997. * //-
  1998. * // If your bucket has versioning enabled, you can get all of your files
  1999. * // scoped to their generation.
  2000. * //-
  2001. * bucket.getFiles({
  2002. * versions: true
  2003. * }, function(err, files) {
  2004. * // Each file is scoped to its generation.
  2005. * });
  2006. *
  2007. * //-
  2008. * // To control how many API requests are made and page through the results
  2009. * // manually, set `autoPaginate` to `false`.
  2010. * //-
  2011. * const callback = function(err, files, nextQuery, apiResponse) {
  2012. * if (nextQuery) {
  2013. * // More results exist.
  2014. * bucket.getFiles(nextQuery, callback);
  2015. * }
  2016. *
  2017. * // The `metadata` property is populated for you with the metadata at the
  2018. * // time of fetching.
  2019. * files[0].metadata;
  2020. *
  2021. * // However, in cases where you are concerned the metadata could have
  2022. * // changed, use the `getMetadata` method.
  2023. * files[0].getMetadata(function(err, metadata) {});
  2024. * };
  2025. *
  2026. * bucket.getFiles({
  2027. * autoPaginate: false
  2028. * }, callback);
  2029. *
  2030. * //-
  2031. * // If the callback is omitted, we'll return a Promise.
  2032. * //-
  2033. * bucket.getFiles().then(function(data) {
  2034. * const files = data[0];
  2035. * });
  2036. *
  2037. * ```
  2038. * @example
  2039. * <h6>Simulating a File System</h6><p>With `autoPaginate: false`, it's possible to iterate over files which incorporate a common structure using a delimiter.</p><p>Consider the following remote objects:</p><ol><li>"a"</li><li>"a/b/c/d"</li><li>"b/d/e"</li></ol><p>Using a delimiter of `/` will return a single file, "a".</p><p>`apiResponse.prefixes` will return the "sub-directories" that were found:</p><ol><li>"a/"</li><li>"b/"</li></ol>
  2040. * ```
  2041. * bucket.getFiles({
  2042. * autoPaginate: false,
  2043. * delimiter: '/'
  2044. * }, function(err, files, nextQuery, apiResponse) {
  2045. * // files = [
  2046. * // {File} // File object for file "a"
  2047. * // ]
  2048. *
  2049. * // apiResponse.prefixes = [
  2050. * // 'a/',
  2051. * // 'b/'
  2052. * // ]
  2053. * });
  2054. * ```
  2055. *
  2056. * @example
  2057. * Using prefixes, it's now possible to simulate a file system with follow-up requests.
  2058. * ```
  2059. * bucket.getFiles({
  2060. * autoPaginate: false,
  2061. * delimiter: '/',
  2062. * prefix: 'a/'
  2063. * }, function(err, files, nextQuery, apiResponse) {
  2064. * // No files found within "directory" a.
  2065. * // files = []
  2066. *
  2067. * // However, a "sub-directory" was found.
  2068. * // This prefix can be used to continue traversing the "file system".
  2069. * // apiResponse.prefixes = [
  2070. * // 'a/b/'
  2071. * // ]
  2072. * });
  2073. * ```
  2074. *
  2075. * @example <caption>include:samples/files.js</caption>
  2076. * region_tag:storage_list_files
  2077. * Another example:
  2078. *
  2079. * @example <caption>include:samples/files.js</caption>
  2080. * region_tag:storage_list_files_with_prefix
  2081. * Example of listing files, filtered by a prefix:
  2082. */
  2083. getFiles(queryOrCallback, callback) {
  2084. let query = typeof queryOrCallback === 'object' ? queryOrCallback : {};
  2085. if (!callback) {
  2086. callback = queryOrCallback;
  2087. }
  2088. query = Object.assign({}, query);
  2089. this.request({
  2090. uri: '/o',
  2091. qs: query,
  2092. }, (err, resp) => {
  2093. if (err) {
  2094. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  2095. callback(err, null, null, resp);
  2096. return;
  2097. }
  2098. const itemsArray = resp.items ? resp.items : [];
  2099. const files = itemsArray.map((file) => {
  2100. const options = {};
  2101. if (query.fields) {
  2102. const fileInstance = file;
  2103. return fileInstance;
  2104. }
  2105. if (query.versions) {
  2106. options.generation = file.generation;
  2107. }
  2108. if (file.kmsKeyName) {
  2109. options.kmsKeyName = file.kmsKeyName;
  2110. }
  2111. const fileInstance = this.file(file.name, options);
  2112. fileInstance.metadata = file;
  2113. return fileInstance;
  2114. });
  2115. let nextQuery = null;
  2116. if (resp.nextPageToken) {
  2117. nextQuery = Object.assign({}, query, {
  2118. pageToken: resp.nextPageToken,
  2119. });
  2120. }
  2121. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  2122. callback(null, files, nextQuery, resp);
  2123. });
  2124. }
  2125. /**
  2126. * @deprecated
  2127. * @typedef {object} GetLabelsOptions Configuration options for Bucket#getLabels().
  2128. * @param {string} [userProject] The ID of the project which will be
  2129. * billed for the request.
  2130. */
  2131. /**
  2132. * @deprecated
  2133. * @typedef {array} GetLabelsResponse
  2134. * @property {object} 0 Object of labels currently set on this bucket.
  2135. */
  2136. /**
  2137. * @deprecated
  2138. * @callback GetLabelsCallback
  2139. * @param {?Error} err Request error, if any.
  2140. * @param {object} labels Object of labels currently set on this bucket.
  2141. */
  2142. /**
  2143. * @deprecated Use getMetadata directly.
  2144. * Get the labels currently set on this bucket.
  2145. *
  2146. * @param {object} [options] Configuration options.
  2147. * @param {string} [options.userProject] The ID of the project which will be
  2148. * billed for the request.
  2149. * @param {GetLabelsCallback} [callback] Callback function.
  2150. * @returns {Promise<GetLabelsCallback>}
  2151. *
  2152. * @example
  2153. * ```
  2154. * const {Storage} = require('@google-cloud/storage');
  2155. * const storage = new Storage();
  2156. * const bucket = storage.bucket('albums');
  2157. *
  2158. * bucket.getLabels(function(err, labels) {
  2159. * if (err) {
  2160. * // Error handling omitted.
  2161. * }
  2162. *
  2163. * // labels = {
  2164. * // label: 'labelValue',
  2165. * // ...
  2166. * // }
  2167. * });
  2168. *
  2169. * //-
  2170. * // If the callback is omitted, we'll return a Promise.
  2171. * //-
  2172. * bucket.getLabels().then(function(data) {
  2173. * const labels = data[0];
  2174. * });
  2175. * ```
  2176. */
  2177. getLabels(optionsOrCallback, callback) {
  2178. let options = {};
  2179. if (typeof optionsOrCallback === 'function') {
  2180. callback = optionsOrCallback;
  2181. }
  2182. else if (optionsOrCallback) {
  2183. options = optionsOrCallback;
  2184. }
  2185. this.getMetadata(options, (err, metadata) => {
  2186. if (err) {
  2187. callback(err, null);
  2188. return;
  2189. }
  2190. callback(null, (metadata === null || metadata === void 0 ? void 0 : metadata.labels) || {});
  2191. });
  2192. }
  2193. /**
  2194. * @typedef {object} GetNotificationsOptions Configuration options for Bucket#getNotification().
  2195. * @property {string} [userProject] The ID of the project which will be
  2196. * billed for the request.
  2197. */
  2198. /**
  2199. * @callback GetNotificationsCallback
  2200. * @param {?Error} err Request error, if any.
  2201. * @param {Notification[]} notifications Array of {@link Notification}
  2202. * instances.
  2203. * @param {object} apiResponse The full API response.
  2204. */
  2205. /**
  2206. * @typedef {array} GetNotificationsResponse
  2207. * @property {Notification[]} 0 Array of {@link Notification} instances.
  2208. * @property {object} 1 The full API response.
  2209. */
  2210. /**
  2211. * Retrieves a list of notification subscriptions for a given bucket.
  2212. *
  2213. * See {@link https://cloud.google.com/storage/docs/json_api/v1/notifications/list| Notifications: list}
  2214. *
  2215. * @param {GetNotificationsOptions} [options] Configuration options.
  2216. * @param {string} [options.userProject] The ID of the project which will be
  2217. * billed for the request.
  2218. * @param {GetNotificationsCallback} [callback] Callback function.
  2219. * @returns {Promise<GetNotificationsResponse>}
  2220. *
  2221. * @example
  2222. * ```
  2223. * const {Storage} = require('@google-cloud/storage');
  2224. * const storage = new Storage();
  2225. * const bucket = storage.bucket('my-bucket');
  2226. *
  2227. * bucket.getNotifications(function(err, notifications, apiResponse) {
  2228. * if (!err) {
  2229. * // notifications is an array of Notification objects.
  2230. * }
  2231. * });
  2232. *
  2233. * //-
  2234. * // If the callback is omitted, we'll return a Promise.
  2235. * //-
  2236. * bucket.getNotifications().then(function(data) {
  2237. * const notifications = data[0];
  2238. * const apiResponse = data[1];
  2239. * });
  2240. *
  2241. * ```
  2242. * @example <caption>include:samples/listNotifications.js</caption>
  2243. * region_tag:storage_list_bucket_notifications
  2244. * Another example:
  2245. */
  2246. getNotifications(optionsOrCallback, callback) {
  2247. let options = {};
  2248. if (typeof optionsOrCallback === 'function') {
  2249. callback = optionsOrCallback;
  2250. }
  2251. else if (optionsOrCallback) {
  2252. options = optionsOrCallback;
  2253. }
  2254. this.request({
  2255. uri: '/notificationConfigs',
  2256. qs: options,
  2257. }, (err, resp) => {
  2258. if (err) {
  2259. callback(err, null, resp);
  2260. return;
  2261. }
  2262. const itemsArray = resp.items ? resp.items : [];
  2263. const notifications = itemsArray.map((notification) => {
  2264. const notificationInstance = this.notification(notification.id);
  2265. notificationInstance.metadata = notification;
  2266. return notificationInstance;
  2267. });
  2268. callback(null, notifications, resp);
  2269. });
  2270. }
  2271. /**
  2272. * @typedef {array} GetSignedUrlResponse
  2273. * @property {object} 0 The signed URL.
  2274. */
  2275. /**
  2276. * @callback GetSignedUrlCallback
  2277. * @param {?Error} err Request error, if any.
  2278. * @param {object} url The signed URL.
  2279. */
  2280. /**
  2281. * @typedef {object} GetBucketSignedUrlConfig
  2282. * @property {string} action Only listing objects within a bucket (HTTP: GET) is supported for bucket-level signed URLs.
  2283. * @property {*} expires A timestamp when this link will expire. Any value
  2284. * given is passed to `new Date()`.
  2285. * Note: 'v4' supports maximum duration of 7 days (604800 seconds) from now.
  2286. * @property {string} [version='v2'] The signing version to use, either
  2287. * 'v2' or 'v4'.
  2288. * @property {boolean} [virtualHostedStyle=false] Use virtual hosted-style
  2289. * URLs ('https://mybucket.storage.googleapis.com/...') instead of path-style
  2290. * ('https://storage.googleapis.com/mybucket/...'). Virtual hosted-style URLs
  2291. * should generally be preferred instaed of path-style URL.
  2292. * Currently defaults to `false` for path-style, although this may change in a
  2293. * future major-version release.
  2294. * @property {string} [cname] The cname for this bucket, i.e.,
  2295. * "https://cdn.example.com".
  2296. * See [reference]{@link https://cloud.google.com/storage/docs/access-control/signed-urls#example}
  2297. * @property {object} [extensionHeaders] If these headers are used, the
  2298. * server will check to make sure that the client provides matching
  2299. * values. See {@link https://cloud.google.com/storage/docs/access-control/signed-urls#about-canonical-extension-headers| Canonical extension headers}
  2300. * for the requirements of this feature, most notably:
  2301. * - The header name must be prefixed with `x-goog-`
  2302. * - The header name must be all lowercase
  2303. *
  2304. * Note: Multi-valued header passed as an array in the extensionHeaders
  2305. * object is converted into a string, delimited by `,` with
  2306. * no space. Requests made using the signed URL will need to
  2307. * delimit multi-valued headers using a single `,` as well, or
  2308. * else the server will report a mismatched signature.
  2309. * @property {object} [queryParams] Additional query parameters to include
  2310. * in the signed URL.
  2311. */
  2312. /**
  2313. * Get a signed URL to allow limited time access to a bucket.
  2314. *
  2315. * In Google Cloud Platform environments, such as Cloud Functions and App
  2316. * Engine, you usually don't provide a `keyFilename` or `credentials` during
  2317. * instantiation. In those environments, we call the
  2318. * {@link https://cloud.google.com/iam/docs/reference/credentials/rest/v1/projects.serviceAccounts/signBlob| signBlob API}
  2319. * to create a signed URL. That API requires either the
  2320. * `https://www.googleapis.com/auth/iam` or
  2321. * `https://www.googleapis.com/auth/cloud-platform` scope, so be sure they are
  2322. * enabled.
  2323. *
  2324. * See {@link https://cloud.google.com/storage/docs/access-control/signed-urls| Signed URLs Reference}
  2325. *
  2326. * @throws {Error} if an expiration timestamp from the past is given.
  2327. *
  2328. * @param {GetBucketSignedUrlConfig} config Configuration object.
  2329. * @param {string} config.action Currently only supports "list" (HTTP: GET).
  2330. * @param {*} config.expires A timestamp when this link will expire. Any value
  2331. * given is passed to `new Date()`.
  2332. * Note: 'v4' supports maximum duration of 7 days (604800 seconds) from now.
  2333. * @param {string} [config.version='v2'] The signing version to use, either
  2334. * 'v2' or 'v4'.
  2335. * @param {boolean} [config.virtualHostedStyle=false] Use virtual hosted-style
  2336. * URLs ('https://mybucket.storage.googleapis.com/...') instead of path-style
  2337. * ('https://storage.googleapis.com/mybucket/...'). Virtual hosted-style URLs
  2338. * should generally be preferred instaed of path-style URL.
  2339. * Currently defaults to `false` for path-style, although this may change in a
  2340. * future major-version release.
  2341. * @param {string} [config.cname] The cname for this bucket, i.e.,
  2342. * "https://cdn.example.com".
  2343. * See [reference]{@link https://cloud.google.com/storage/docs/access-control/signed-urls#example}
  2344. * @param {object} [config.extensionHeaders] If these headers are used, the
  2345. * server will check to make sure that the client provides matching
  2346. * values. See {@link https://cloud.google.com/storage/docs/access-control/signed-urls#about-canonical-extension-headers| Canonical extension headers}
  2347. * for the requirements of this feature, most notably:
  2348. * - The header name must be prefixed with `x-goog-`
  2349. * - The header name must be all lowercase
  2350. *
  2351. * Note: Multi-valued header passed as an array in the extensionHeaders
  2352. * object is converted into a string, delimited by `,` with
  2353. * no space. Requests made using the signed URL will need to
  2354. * delimit multi-valued headers using a single `,` as well, or
  2355. * else the server will report a mismatched signature.
  2356. * @property {object} [config.queryParams] Additional query parameters to include
  2357. * in the signed URL.
  2358. * @param {GetSignedUrlCallback} [callback] Callback function.
  2359. * @returns {Promise<GetSignedUrlResponse>}
  2360. *
  2361. * @example
  2362. * ```
  2363. * const {Storage} = require('@google-cloud/storage');
  2364. * const storage = new Storage();
  2365. * const myBucket = storage.bucket('my-bucket');
  2366. *
  2367. * //-
  2368. * // Generate a URL that allows temporary access to list files in a bucket.
  2369. * //-
  2370. * const request = require('request');
  2371. *
  2372. * const config = {
  2373. * action: 'list',
  2374. * expires: '03-17-2025'
  2375. * };
  2376. *
  2377. * bucket.getSignedUrl(config, function(err, url) {
  2378. * if (err) {
  2379. * console.error(err);
  2380. * return;
  2381. * }
  2382. *
  2383. * // The bucket is now available to be listed from this URL.
  2384. * request(url, function(err, resp) {
  2385. * // resp.statusCode = 200
  2386. * });
  2387. * });
  2388. *
  2389. * //-
  2390. * // If the callback is omitted, we'll return a Promise.
  2391. * //-
  2392. * bucket.getSignedUrl(config).then(function(data) {
  2393. * const url = data[0];
  2394. * });
  2395. * ```
  2396. */
  2397. getSignedUrl(cfg, callback) {
  2398. const method = BucketActionToHTTPMethod[cfg.action];
  2399. const signConfig = {
  2400. method,
  2401. expires: cfg.expires,
  2402. version: cfg.version,
  2403. cname: cfg.cname,
  2404. extensionHeaders: cfg.extensionHeaders || {},
  2405. queryParams: cfg.queryParams || {},
  2406. host: cfg.host,
  2407. signingEndpoint: cfg.signingEndpoint,
  2408. };
  2409. if (!this.signer) {
  2410. this.signer = new signer_js_1.URLSigner(this.storage.authClient, this, undefined, this.storage);
  2411. }
  2412. this.signer
  2413. .getSignedUrl(signConfig)
  2414. .then(signedUrl => callback(null, signedUrl), callback);
  2415. }
  2416. /**
  2417. * @callback BucketLockCallback
  2418. * @param {?Error} err Request error, if any.
  2419. * @param {object} apiResponse The full API response.
  2420. */
  2421. /**
  2422. * Lock a previously-defined retention policy. This will prevent changes to
  2423. * the policy.
  2424. *
  2425. * @throws {Error} if a metageneration is not provided.
  2426. *
  2427. * @param {number|string} metageneration The bucket's metageneration. This is
  2428. * accesssible from calling {@link File#getMetadata}.
  2429. * @param {BucketLockCallback} [callback] Callback function.
  2430. * @returns {Promise<BucketLockResponse>}
  2431. *
  2432. * @example
  2433. * ```
  2434. * const storage = require('@google-cloud/storage')();
  2435. * const bucket = storage.bucket('albums');
  2436. *
  2437. * const metageneration = 2;
  2438. *
  2439. * bucket.lock(metageneration, function(err, apiResponse) {});
  2440. *
  2441. * //-
  2442. * // If the callback is omitted, we'll return a Promise.
  2443. * //-
  2444. * bucket.lock(metageneration).then(function(data) {
  2445. * const apiResponse = data[0];
  2446. * });
  2447. * ```
  2448. */
  2449. lock(metageneration, callback) {
  2450. const metatype = typeof metageneration;
  2451. if (metatype !== 'number' && metatype !== 'string') {
  2452. throw new Error(BucketExceptionMessages.METAGENERATION_NOT_PROVIDED);
  2453. }
  2454. this.request({
  2455. method: 'POST',
  2456. uri: '/lockRetentionPolicy',
  2457. qs: {
  2458. ifMetagenerationMatch: metageneration,
  2459. },
  2460. }, callback);
  2461. }
  2462. /**
  2463. * @typedef {array} MakeBucketPrivateResponse
  2464. * @property {File[]} 0 List of files made private.
  2465. */
  2466. /**
  2467. * @callback MakeBucketPrivateCallback
  2468. * @param {?Error} err Request error, if any.
  2469. * @param {File[]} files List of files made private.
  2470. */
  2471. /**
  2472. * @typedef {object} MakeBucketPrivateOptions
  2473. * @property {boolean} [includeFiles=false] Make each file in the bucket
  2474. * private.
  2475. * @property {Metadata} [metadata] Define custom metadata properties to define
  2476. * along with the operation.
  2477. * @property {boolean} [force] Queue errors occurred while making files
  2478. * private until all files have been processed.
  2479. * @property {string} [userProject] The ID of the project which will be
  2480. * billed for the request.
  2481. */
  2482. /**
  2483. * Make the bucket listing private.
  2484. *
  2485. * You may also choose to make the contents of the bucket private by
  2486. * specifying `includeFiles: true`. This will automatically run
  2487. * {@link File#makePrivate} for every file in the bucket.
  2488. *
  2489. * When specifying `includeFiles: true`, use `force: true` to delay execution
  2490. * of your callback until all files have been processed. By default, the
  2491. * callback is executed after the first error. Use `force` to queue such
  2492. * errors until all files have been processed, after which they will be
  2493. * returned as an array as the first argument to your callback.
  2494. *
  2495. * NOTE: This may cause the process to be long-running and use a high number
  2496. * of requests. Use with caution.
  2497. *
  2498. * See {@link https://cloud.google.com/storage/docs/json_api/v1/buckets/patch| Buckets: patch API Documentation}
  2499. *
  2500. * @param {MakeBucketPrivateOptions} [options] Configuration options.
  2501. * @param {boolean} [options.includeFiles=false] Make each file in the bucket
  2502. * private.
  2503. * @param {Metadata} [options.metadata] Define custom metadata properties to define
  2504. * along with the operation.
  2505. * @param {boolean} [options.force] Queue errors occurred while making files
  2506. * private until all files have been processed.
  2507. * @param {string} [options.userProject] The ID of the project which will be
  2508. * billed for the request.
  2509. * @param {MakeBucketPrivateCallback} [callback] Callback function.
  2510. * @returns {Promise<MakeBucketPrivateResponse>}
  2511. *
  2512. * @example
  2513. * ```
  2514. * const {Storage} = require('@google-cloud/storage');
  2515. * const storage = new Storage();
  2516. * const bucket = storage.bucket('albums');
  2517. *
  2518. * //-
  2519. * // Make the bucket private.
  2520. * //-
  2521. * bucket.makePrivate(function(err) {});
  2522. *
  2523. * //-
  2524. * // Make the bucket and its contents private.
  2525. * //-
  2526. * const opts = {
  2527. * includeFiles: true
  2528. * };
  2529. *
  2530. * bucket.makePrivate(opts, function(err, files) {
  2531. * // `err`:
  2532. * // The first error to occur, otherwise null.
  2533. * //
  2534. * // `files`:
  2535. * // Array of files successfully made private in the bucket.
  2536. * });
  2537. *
  2538. * //-
  2539. * // Make the bucket and its contents private, using force to suppress errors
  2540. * // until all files have been processed.
  2541. * //-
  2542. * const opts = {
  2543. * includeFiles: true,
  2544. * force: true
  2545. * };
  2546. *
  2547. * bucket.makePrivate(opts, function(errors, files) {
  2548. * // `errors`:
  2549. * // Array of errors if any occurred, otherwise null.
  2550. * //
  2551. * // `files`:
  2552. * // Array of files successfully made private in the bucket.
  2553. * });
  2554. *
  2555. * //-
  2556. * // If the callback is omitted, we'll return a Promise.
  2557. * //-
  2558. * bucket.makePrivate(opts).then(function(data) {
  2559. * const files = data[0];
  2560. * });
  2561. * ```
  2562. */
  2563. makePrivate(optionsOrCallback, callback) {
  2564. var _a, _b, _c, _d;
  2565. const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
  2566. callback =
  2567. typeof optionsOrCallback === 'function' ? optionsOrCallback : callback;
  2568. options.private = true;
  2569. const query = {
  2570. predefinedAcl: 'projectPrivate',
  2571. };
  2572. if (options.userProject) {
  2573. query.userProject = options.userProject;
  2574. }
  2575. if ((_a = options.preconditionOpts) === null || _a === void 0 ? void 0 : _a.ifGenerationMatch) {
  2576. query.ifGenerationMatch = options.preconditionOpts.ifGenerationMatch;
  2577. }
  2578. if ((_b = options.preconditionOpts) === null || _b === void 0 ? void 0 : _b.ifGenerationNotMatch) {
  2579. query.ifGenerationNotMatch =
  2580. options.preconditionOpts.ifGenerationNotMatch;
  2581. }
  2582. if ((_c = options.preconditionOpts) === null || _c === void 0 ? void 0 : _c.ifMetagenerationMatch) {
  2583. query.ifMetagenerationMatch =
  2584. options.preconditionOpts.ifMetagenerationMatch;
  2585. }
  2586. if ((_d = options.preconditionOpts) === null || _d === void 0 ? void 0 : _d.ifMetagenerationNotMatch) {
  2587. query.ifMetagenerationNotMatch =
  2588. options.preconditionOpts.ifMetagenerationNotMatch;
  2589. }
  2590. // You aren't allowed to set both predefinedAcl & acl properties on a bucket
  2591. // so acl must explicitly be nullified.
  2592. const metadata = { ...options.metadata, acl: null };
  2593. this.setMetadata(metadata, query, (err) => {
  2594. if (err) {
  2595. callback(err);
  2596. }
  2597. const internalCall = () => {
  2598. if (options.includeFiles) {
  2599. return (0, util_1.promisify)(this.makeAllFilesPublicPrivate_).call(this, options);
  2600. }
  2601. return Promise.resolve([]);
  2602. };
  2603. internalCall()
  2604. .then(files => callback(null, files))
  2605. .catch(callback);
  2606. });
  2607. }
  2608. /**
  2609. * @typedef {object} MakeBucketPublicOptions
  2610. * @property {boolean} [includeFiles=false] Make each file in the bucket
  2611. * private.
  2612. * @property {boolean} [force] Queue errors occurred while making files
  2613. * private until all files have been processed.
  2614. */
  2615. /**
  2616. * @callback MakeBucketPublicCallback
  2617. * @param {?Error} err Request error, if any.
  2618. * @param {File[]} files List of files made public.
  2619. */
  2620. /**
  2621. * @typedef {array} MakeBucketPublicResponse
  2622. * @property {File[]} 0 List of files made public.
  2623. */
  2624. /**
  2625. * Make the bucket publicly readable.
  2626. *
  2627. * You may also choose to make the contents of the bucket publicly readable by
  2628. * specifying `includeFiles: true`. This will automatically run
  2629. * {@link File#makePublic} for every file in the bucket.
  2630. *
  2631. * When specifying `includeFiles: true`, use `force: true` to delay execution
  2632. * of your callback until all files have been processed. By default, the
  2633. * callback is executed after the first error. Use `force` to queue such
  2634. * errors until all files have been processed, after which they will be
  2635. * returned as an array as the first argument to your callback.
  2636. *
  2637. * NOTE: This may cause the process to be long-running and use a high number
  2638. * of requests. Use with caution.
  2639. *
  2640. * See {@link https://cloud.google.com/storage/docs/json_api/v1/buckets/patch| Buckets: patch API Documentation}
  2641. *
  2642. * @param {MakeBucketPublicOptions} [options] Configuration options.
  2643. * @param {boolean} [options.includeFiles=false] Make each file in the bucket
  2644. * private.
  2645. * @param {boolean} [options.force] Queue errors occurred while making files
  2646. * private until all files have been processed.
  2647. * @param {MakeBucketPublicCallback} [callback] Callback function.
  2648. * @returns {Promise<MakeBucketPublicResponse>}
  2649. *
  2650. * @example
  2651. * ```
  2652. * const {Storage} = require('@google-cloud/storage');
  2653. * const storage = new Storage();
  2654. * const bucket = storage.bucket('albums');
  2655. *
  2656. * //-
  2657. * // Make the bucket publicly readable.
  2658. * //-
  2659. * bucket.makePublic(function(err) {});
  2660. *
  2661. * //-
  2662. * // Make the bucket and its contents publicly readable.
  2663. * //-
  2664. * const opts = {
  2665. * includeFiles: true
  2666. * };
  2667. *
  2668. * bucket.makePublic(opts, function(err, files) {
  2669. * // `err`:
  2670. * // The first error to occur, otherwise null.
  2671. * //
  2672. * // `files`:
  2673. * // Array of files successfully made public in the bucket.
  2674. * });
  2675. *
  2676. * //-
  2677. * // Make the bucket and its contents publicly readable, using force to
  2678. * // suppress errors until all files have been processed.
  2679. * //-
  2680. * const opts = {
  2681. * includeFiles: true,
  2682. * force: true
  2683. * };
  2684. *
  2685. * bucket.makePublic(opts, function(errors, files) {
  2686. * // `errors`:
  2687. * // Array of errors if any occurred, otherwise null.
  2688. * //
  2689. * // `files`:
  2690. * // Array of files successfully made public in the bucket.
  2691. * });
  2692. *
  2693. * //-
  2694. * // If the callback is omitted, we'll return a Promise.
  2695. * //-
  2696. * bucket.makePublic(opts).then(function(data) {
  2697. * const files = data[0];
  2698. * });
  2699. * ```
  2700. */
  2701. makePublic(optionsOrCallback, callback) {
  2702. const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
  2703. callback =
  2704. typeof optionsOrCallback === 'function' ? optionsOrCallback : callback;
  2705. const req = { public: true, ...options };
  2706. this.acl
  2707. .add({
  2708. entity: 'allUsers',
  2709. role: 'READER',
  2710. })
  2711. .then(() => {
  2712. return this.acl.default.add({
  2713. entity: 'allUsers',
  2714. role: 'READER',
  2715. });
  2716. })
  2717. .then(() => {
  2718. if (req.includeFiles) {
  2719. return (0, util_1.promisify)(this.makeAllFilesPublicPrivate_).call(this, req);
  2720. }
  2721. return [];
  2722. })
  2723. .then(files => callback(null, files), callback);
  2724. }
  2725. /**
  2726. * Get a reference to a Cloud Pub/Sub Notification.
  2727. *
  2728. * @param {string} id ID of notification.
  2729. * @returns {Notification}
  2730. * @see Notification
  2731. *
  2732. * @example
  2733. * ```
  2734. * const {Storage} = require('@google-cloud/storage');
  2735. * const storage = new Storage();
  2736. * const bucket = storage.bucket('my-bucket');
  2737. * const notification = bucket.notification('1');
  2738. * ```
  2739. */
  2740. notification(id) {
  2741. if (!id) {
  2742. throw new Error(BucketExceptionMessages.SUPPLY_NOTIFICATION_ID);
  2743. }
  2744. return new notification_js_1.Notification(this, id);
  2745. }
  2746. /**
  2747. * Remove an already-existing retention policy from this bucket, if it is not
  2748. * locked.
  2749. *
  2750. * @param {SetBucketMetadataCallback} [callback] Callback function.
  2751. * @param {SetBucketMetadataOptions} [options] Options, including precondition options
  2752. * @returns {Promise<SetBucketMetadataResponse>}
  2753. *
  2754. * @example
  2755. * ```
  2756. * const storage = require('@google-cloud/storage')();
  2757. * const bucket = storage.bucket('albums');
  2758. *
  2759. * bucket.removeRetentionPeriod(function(err, apiResponse) {});
  2760. *
  2761. * //-
  2762. * // If the callback is omitted, we'll return a Promise.
  2763. * //-
  2764. * bucket.removeRetentionPeriod().then(function(data) {
  2765. * const apiResponse = data[0];
  2766. * });
  2767. * ```
  2768. */
  2769. removeRetentionPeriod(optionsOrCallback, callback) {
  2770. const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
  2771. callback =
  2772. typeof optionsOrCallback === 'function' ? optionsOrCallback : callback;
  2773. this.setMetadata({
  2774. retentionPolicy: null,
  2775. }, options, callback);
  2776. }
  2777. /**
  2778. * Makes request and applies userProject query parameter if necessary.
  2779. *
  2780. * @private
  2781. *
  2782. * @param {object} reqOpts - The request options.
  2783. * @param {function} callback - The callback function.
  2784. */
  2785. request(reqOpts, callback) {
  2786. if (this.userProject && (!reqOpts.qs || !reqOpts.qs.userProject)) {
  2787. reqOpts.qs = { ...reqOpts.qs, userProject: this.userProject };
  2788. }
  2789. return super.request(reqOpts, callback);
  2790. }
  2791. /**
  2792. * @deprecated
  2793. * @typedef {array} SetLabelsResponse
  2794. * @property {object} 0 The bucket metadata.
  2795. */
  2796. /**
  2797. * @deprecated
  2798. * @callback SetLabelsCallback
  2799. * @param {?Error} err Request error, if any.
  2800. * @param {object} metadata The bucket metadata.
  2801. */
  2802. /**
  2803. * @deprecated
  2804. * @typedef {object} SetLabelsOptions Configuration options for Bucket#setLabels().
  2805. * @property {string} [userProject] The ID of the project which will be
  2806. * billed for the request.
  2807. */
  2808. /**
  2809. * @deprecated Use setMetadata directly.
  2810. * Set labels on the bucket.
  2811. *
  2812. * This makes an underlying call to {@link Bucket#setMetadata}, which
  2813. * is a PATCH request. This means an individual label can be overwritten, but
  2814. * unmentioned labels will not be touched.
  2815. *
  2816. * @param {object<string, string>} labels Labels to set on the bucket.
  2817. * @param {SetLabelsOptions} [options] Configuration options.
  2818. * @param {string} [options.userProject] The ID of the project which will be
  2819. * billed for the request.
  2820. * @param {SetLabelsCallback} [callback] Callback function.
  2821. * @returns {Promise<SetLabelsResponse>}
  2822. *
  2823. * @example
  2824. * ```
  2825. * const {Storage} = require('@google-cloud/storage');
  2826. * const storage = new Storage();
  2827. * const bucket = storage.bucket('albums');
  2828. *
  2829. * const labels = {
  2830. * labelone: 'labelonevalue',
  2831. * labeltwo: 'labeltwovalue'
  2832. * };
  2833. *
  2834. * bucket.setLabels(labels, function(err, metadata) {
  2835. * if (!err) {
  2836. * // Labels set successfully.
  2837. * }
  2838. * });
  2839. *
  2840. * //-
  2841. * // If the callback is omitted, we'll return a Promise.
  2842. * //-
  2843. * bucket.setLabels(labels).then(function(data) {
  2844. * const metadata = data[0];
  2845. * });
  2846. * ```
  2847. */
  2848. setLabels(labels, optionsOrCallback, callback) {
  2849. const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
  2850. callback =
  2851. typeof optionsOrCallback === 'function' ? optionsOrCallback : callback;
  2852. callback = callback || index_js_1.util.noop;
  2853. this.setMetadata({ labels }, options, callback);
  2854. }
  2855. setMetadata(metadata, optionsOrCallback, cb) {
  2856. const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
  2857. cb =
  2858. typeof optionsOrCallback === 'function'
  2859. ? optionsOrCallback
  2860. : cb;
  2861. this.disableAutoRetryConditionallyIdempotent_(this.methods.setMetadata, AvailableServiceObjectMethods.setMetadata, options);
  2862. super
  2863. .setMetadata(metadata, options)
  2864. .then(resp => cb(null, ...resp))
  2865. .catch(cb)
  2866. .finally(() => {
  2867. this.storage.retryOptions.autoRetry = this.instanceRetryValue;
  2868. });
  2869. }
  2870. /**
  2871. * Lock all objects contained in the bucket, based on their creation time. Any
  2872. * attempt to overwrite or delete objects younger than the retention period
  2873. * will result in a `PERMISSION_DENIED` error.
  2874. *
  2875. * An unlocked retention policy can be modified or removed from the bucket via
  2876. * {@link File#removeRetentionPeriod} and {@link File#setRetentionPeriod}. A
  2877. * locked retention policy cannot be removed or shortened in duration for the
  2878. * lifetime of the bucket. Attempting to remove or decrease period of a locked
  2879. * retention policy will result in a `PERMISSION_DENIED` error. You can still
  2880. * increase the policy.
  2881. *
  2882. * @param {*} duration In seconds, the minimum retention time for all objects
  2883. * contained in this bucket.
  2884. * @param {SetBucketMetadataCallback} [callback] Callback function.
  2885. * @param {SetBucketMetadataCallback} [options] Options, including precondition options.
  2886. * @returns {Promise<SetBucketMetadataResponse>}
  2887. *
  2888. * @example
  2889. * ```
  2890. * const storage = require('@google-cloud/storage')();
  2891. * const bucket = storage.bucket('albums');
  2892. *
  2893. * const DURATION_SECONDS = 15780000; // 6 months.
  2894. *
  2895. * //-
  2896. * // Lock the objects in this bucket for 6 months.
  2897. * //-
  2898. * bucket.setRetentionPeriod(DURATION_SECONDS, function(err, apiResponse) {});
  2899. *
  2900. * //-
  2901. * // If the callback is omitted, we'll return a Promise.
  2902. * //-
  2903. * bucket.setRetentionPeriod(DURATION_SECONDS).then(function(data) {
  2904. * const apiResponse = data[0];
  2905. * });
  2906. * ```
  2907. */
  2908. setRetentionPeriod(duration, optionsOrCallback, callback) {
  2909. const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
  2910. callback =
  2911. typeof optionsOrCallback === 'function' ? optionsOrCallback : callback;
  2912. this.setMetadata({
  2913. retentionPolicy: {
  2914. retentionPeriod: duration.toString(),
  2915. },
  2916. }, options, callback);
  2917. }
  2918. /**
  2919. *
  2920. * @typedef {object} Cors
  2921. * @property {number} [maxAgeSeconds] The number of seconds the browser is
  2922. * allowed to make requests before it must repeat the preflight request.
  2923. * @property {string[]} [method] HTTP method allowed for cross origin resource
  2924. * sharing with this bucket.
  2925. * @property {string[]} [origin] an origin allowed for cross origin resource
  2926. * sharing with this bucket.
  2927. * @property {string[]} [responseHeader] A header allowed for cross origin
  2928. * resource sharing with this bucket.
  2929. */
  2930. /**
  2931. * This can be used to set the CORS configuration on the bucket.
  2932. *
  2933. * The configuration will be overwritten with the value passed into this.
  2934. *
  2935. * @param {Cors[]} corsConfiguration The new CORS configuration to set
  2936. * @param {number} [corsConfiguration.maxAgeSeconds] The number of seconds the browser is
  2937. * allowed to make requests before it must repeat the preflight request.
  2938. * @param {string[]} [corsConfiguration.method] HTTP method allowed for cross origin resource
  2939. * sharing with this bucket.
  2940. * @param {string[]} [corsConfiguration.origin] an origin allowed for cross origin resource
  2941. * sharing with this bucket.
  2942. * @param {string[]} [corsConfiguration.responseHeader] A header allowed for cross origin
  2943. * resource sharing with this bucket.
  2944. * @param {SetBucketMetadataCallback} [callback] Callback function.
  2945. * @param {SetBucketMetadataOptions} [options] Options, including precondition options.
  2946. * @returns {Promise<SetBucketMetadataResponse>}
  2947. *
  2948. * @example
  2949. * ```
  2950. * const storage = require('@google-cloud/storage')();
  2951. * const bucket = storage.bucket('albums');
  2952. *
  2953. * const corsConfiguration = [{maxAgeSeconds: 3600}]; // 1 hour
  2954. * bucket.setCorsConfiguration(corsConfiguration);
  2955. *
  2956. * //-
  2957. * // If the callback is omitted, we'll return a Promise.
  2958. * //-
  2959. * bucket.setCorsConfiguration(corsConfiguration).then(function(data) {
  2960. * const apiResponse = data[0];
  2961. * });
  2962. * ```
  2963. */
  2964. setCorsConfiguration(corsConfiguration, optionsOrCallback, callback) {
  2965. const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
  2966. callback =
  2967. typeof optionsOrCallback === 'function' ? optionsOrCallback : callback;
  2968. this.setMetadata({
  2969. cors: corsConfiguration,
  2970. }, options, callback);
  2971. }
  2972. /**
  2973. * @typedef {object} SetBucketStorageClassOptions
  2974. * @property {string} [userProject] - The ID of the project which will be
  2975. * billed for the request.
  2976. */
  2977. /**
  2978. * @callback SetBucketStorageClassCallback
  2979. * @param {?Error} err Request error, if any.
  2980. */
  2981. /**
  2982. * Set the default storage class for new files in this bucket.
  2983. *
  2984. * See {@link https://cloud.google.com/storage/docs/storage-classes| Storage Classes}
  2985. *
  2986. * @param {string} storageClass The new storage class. (`standard`,
  2987. * `nearline`, `coldline`, or `archive`).
  2988. * **Note:** The storage classes `multi_regional`, `regional`, and
  2989. * `durable_reduced_availability` are now legacy and will be deprecated in
  2990. * the future.
  2991. * @param {object} [options] Configuration options.
  2992. * @param {string} [options.userProject] - The ID of the project which will be
  2993. * billed for the request.
  2994. * @param {SetStorageClassCallback} [callback] Callback function.
  2995. * @returns {Promise}
  2996. *
  2997. * @example
  2998. * ```
  2999. * const {Storage} = require('@google-cloud/storage');
  3000. * const storage = new Storage();
  3001. * const bucket = storage.bucket('albums');
  3002. *
  3003. * bucket.setStorageClass('nearline', function(err, apiResponse) {
  3004. * if (err) {
  3005. * // Error handling omitted.
  3006. * }
  3007. *
  3008. * // The storage class was updated successfully.
  3009. * });
  3010. *
  3011. * //-
  3012. * // If the callback is omitted, we'll return a Promise.
  3013. * //-
  3014. * bucket.setStorageClass('nearline').then(function() {});
  3015. * ```
  3016. */
  3017. setStorageClass(storageClass, optionsOrCallback, callback) {
  3018. const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
  3019. callback =
  3020. typeof optionsOrCallback === 'function' ? optionsOrCallback : callback;
  3021. // In case we get input like `storageClass`, convert to `storage_class`.
  3022. storageClass = storageClass
  3023. .replace(/-/g, '_')
  3024. .replace(/([a-z])([A-Z])/g, (_, low, up) => {
  3025. return low + '_' + up;
  3026. })
  3027. .toUpperCase();
  3028. this.setMetadata({ storageClass }, options, callback);
  3029. }
  3030. /**
  3031. * Set a user project to be billed for all requests made from this Bucket
  3032. * object and any files referenced from this Bucket object.
  3033. *
  3034. * @param {string} userProject The user project.
  3035. *
  3036. * @example
  3037. * ```
  3038. * const {Storage} = require('@google-cloud/storage');
  3039. * const storage = new Storage();
  3040. * const bucket = storage.bucket('albums');
  3041. *
  3042. * bucket.setUserProject('grape-spaceship-123');
  3043. * ```
  3044. */
  3045. setUserProject(userProject) {
  3046. this.userProject = userProject;
  3047. const methods = [
  3048. 'create',
  3049. 'delete',
  3050. 'exists',
  3051. 'get',
  3052. 'getMetadata',
  3053. 'setMetadata',
  3054. ];
  3055. methods.forEach(method => {
  3056. const methodConfig = this.methods[method];
  3057. if (typeof methodConfig === 'object') {
  3058. if (typeof methodConfig.reqOpts === 'object') {
  3059. Object.assign(methodConfig.reqOpts.qs, { userProject });
  3060. }
  3061. else {
  3062. methodConfig.reqOpts = {
  3063. qs: { userProject },
  3064. };
  3065. }
  3066. }
  3067. });
  3068. }
  3069. /**
  3070. * @typedef {object} UploadOptions Configuration options for Bucket#upload().
  3071. * @property {string|File} [destination] The place to save
  3072. * your file. If given a string, the file will be uploaded to the bucket
  3073. * using the string as a filename. When given a File object, your local
  3074. * file will be uploaded to the File object's bucket and under the File
  3075. * object's name. Lastly, when this argument is omitted, the file is uploaded
  3076. * to your bucket using the name of the local file.
  3077. * @property {string} [encryptionKey] A custom encryption key. See
  3078. * {@link https://cloud.google.com/storage/docs/encryption#customer-supplied| Customer-supplied Encryption Keys}.
  3079. * @property {boolean} [gzip] Automatically gzip the file. This will set
  3080. * `options.metadata.contentEncoding` to `gzip`.
  3081. * @property {string} [kmsKeyName] The name of the Cloud KMS key that will
  3082. * be used to encrypt the object. Must be in the format:
  3083. * `projects/my-project/locations/location/keyRings/my-kr/cryptoKeys/my-key`.
  3084. * @property {object} [metadata] See an
  3085. * {@link https://cloud.google.com/storage/docs/json_api/v1/objects/insert#request_properties_JSON| Objects: insert request body}.
  3086. * @property {string} [offset] The starting byte of the upload stream, for
  3087. * resuming an interrupted upload. Defaults to 0.
  3088. * @property {string} [predefinedAcl] Apply a predefined set of access
  3089. * controls to this object.
  3090. *
  3091. * Acceptable values are:
  3092. * - **`authenticatedRead`** - Object owner gets `OWNER` access, and
  3093. * `allAuthenticatedUsers` get `READER` access.
  3094. *
  3095. * - **`bucketOwnerFullControl`** - Object owner gets `OWNER` access, and
  3096. * project team owners get `OWNER` access.
  3097. *
  3098. * - **`bucketOwnerRead`** - Object owner gets `OWNER` access, and project
  3099. * team owners get `READER` access.
  3100. *
  3101. * - **`private`** - Object owner gets `OWNER` access.
  3102. *
  3103. * - **`projectPrivate`** - Object owner gets `OWNER` access, and project
  3104. * team members get access according to their roles.
  3105. *
  3106. * - **`publicRead`** - Object owner gets `OWNER` access, and `allUsers`
  3107. * get `READER` access.
  3108. * @property {boolean} [private] Make the uploaded file private. (Alias for
  3109. * `options.predefinedAcl = 'private'`)
  3110. * @property {boolean} [public] Make the uploaded file public. (Alias for
  3111. * `options.predefinedAcl = 'publicRead'`)
  3112. * @property {boolean} [resumable=true] Resumable uploads are automatically
  3113. * enabled and must be shut off explicitly by setting to false.
  3114. * @property {number} [timeout=60000] Set the HTTP request timeout in
  3115. * milliseconds. This option is not available for resumable uploads.
  3116. * Default: `60000`
  3117. * @property {string} [uri] The URI for an already-created resumable
  3118. * upload. See {@link File#createResumableUpload}.
  3119. * @property {string} [userProject] The ID of the project which will be
  3120. * billed for the request.
  3121. * @property {string|boolean} [validation] Possible values: `"md5"`,
  3122. * `"crc32c"`, or `false`. By default, data integrity is validated with an
  3123. * MD5 checksum for maximum reliability. CRC32c will provide better
  3124. * performance with less reliability. You may also choose to skip
  3125. * validation completely, however this is **not recommended**.
  3126. */
  3127. /**
  3128. * @typedef {array} UploadResponse
  3129. * @property {object} 0 The uploaded {@link File}.
  3130. * @property {object} 1 The full API response.
  3131. */
  3132. /**
  3133. * @callback UploadCallback
  3134. * @param {?Error} err Request error, if any.
  3135. * @param {object} file The uploaded {@link File}.
  3136. * @param {object} apiResponse The full API response.
  3137. */
  3138. /**
  3139. * Upload a file to the bucket. This is a convenience method that wraps
  3140. * {@link File#createWriteStream}.
  3141. *
  3142. * Resumable uploads are enabled by default
  3143. *
  3144. * See {@link https://cloud.google.com/storage/docs/json_api/v1/how-tos/upload#uploads| Upload Options (Simple or Resumable)}
  3145. * See {@link https://cloud.google.com/storage/docs/json_api/v1/objects/insert| Objects: insert API Documentation}
  3146. *
  3147. * @param {string} pathString The fully qualified path to the file you
  3148. * wish to upload to your bucket.
  3149. * @param {UploadOptions} [options] Configuration options.
  3150. * @param {string|File} [options.destination] The place to save
  3151. * your file. If given a string, the file will be uploaded to the bucket
  3152. * using the string as a filename. When given a File object, your local
  3153. * file will be uploaded to the File object's bucket and under the File
  3154. * object's name. Lastly, when this argument is omitted, the file is uploaded
  3155. * to your bucket using the name of the local file.
  3156. * @param {string} [options.encryptionKey] A custom encryption key. See
  3157. * {@link https://cloud.google.com/storage/docs/encryption#customer-supplied| Customer-supplied Encryption Keys}.
  3158. * @param {boolean} [options.gzip] Automatically gzip the file. This will set
  3159. * `options.metadata.contentEncoding` to `gzip`.
  3160. * @param {string} [options.kmsKeyName] The name of the Cloud KMS key that will
  3161. * be used to encrypt the object. Must be in the format:
  3162. * `projects/my-project/locations/location/keyRings/my-kr/cryptoKeys/my-key`.
  3163. * @param {object} [options.metadata] See an
  3164. * {@link https://cloud.google.com/storage/docs/json_api/v1/objects/insert#request_properties_JSON| Objects: insert request body}.
  3165. * @param {string} [options.offset] The starting byte of the upload stream, for
  3166. * resuming an interrupted upload. Defaults to 0.
  3167. * @param {string} [options.predefinedAcl] Apply a predefined set of access
  3168. * controls to this object.
  3169. * Acceptable values are:
  3170. * - **`authenticatedRead`** - Object owner gets `OWNER` access, and
  3171. * `allAuthenticatedUsers` get `READER` access.
  3172. *
  3173. * - **`bucketOwnerFullControl`** - Object owner gets `OWNER` access, and
  3174. * project team owners get `OWNER` access.
  3175. *
  3176. * - **`bucketOwnerRead`** - Object owner gets `OWNER` access, and project
  3177. * team owners get `READER` access.
  3178. *
  3179. * - **`private`** - Object owner gets `OWNER` access.
  3180. *
  3181. * - **`projectPrivate`** - Object owner gets `OWNER` access, and project
  3182. * team members get access according to their roles.
  3183. *
  3184. * - **`publicRead`** - Object owner gets `OWNER` access, and `allUsers`
  3185. * get `READER` access.
  3186. * @param {boolean} [options.private] Make the uploaded file private. (Alias for
  3187. * `options.predefinedAcl = 'private'`)
  3188. * @param {boolean} [options.public] Make the uploaded file public. (Alias for
  3189. * `options.predefinedAcl = 'publicRead'`)
  3190. * @param {boolean} [options.resumable=true] Resumable uploads are automatically
  3191. * enabled and must be shut off explicitly by setting to false.
  3192. * @param {number} [options.timeout=60000] Set the HTTP request timeout in
  3193. * milliseconds. This option is not available for resumable uploads.
  3194. * Default: `60000`
  3195. * @param {string} [options.uri] The URI for an already-created resumable
  3196. * upload. See {@link File#createResumableUpload}.
  3197. * @param {string} [options.userProject] The ID of the project which will be
  3198. * billed for the request.
  3199. * @param {string|boolean} [options.validation] Possible values: `"md5"`,
  3200. * `"crc32c"`, or `false`. By default, data integrity is validated with an
  3201. * MD5 checksum for maximum reliability. CRC32c will provide better
  3202. * performance with less reliability. You may also choose to skip
  3203. * validation completely, however this is **not recommended**.
  3204. * @param {UploadCallback} [callback] Callback function.
  3205. * @returns {Promise<UploadResponse>}
  3206. *
  3207. * @example
  3208. * ```
  3209. * const {Storage} = require('@google-cloud/storage');
  3210. * const storage = new Storage();
  3211. * const bucket = storage.bucket('albums');
  3212. *
  3213. * //-
  3214. * // Upload a file from a local path.
  3215. * //-
  3216. * bucket.upload('/local/path/image.png', function(err, file, apiResponse) {
  3217. * // Your bucket now contains:
  3218. * // - "image.png" (with the contents of `/local/path/image.png')
  3219. *
  3220. * // `file` is an instance of a File object that refers to your new file.
  3221. * });
  3222. *
  3223. *
  3224. * //-
  3225. * // It's not always that easy. You will likely want to specify the filename
  3226. * // used when your new file lands in your bucket.
  3227. * //
  3228. * // You may also want to set metadata or customize other options.
  3229. * //-
  3230. * const options = {
  3231. * destination: 'new-image.png',
  3232. * validation: 'crc32c',
  3233. * metadata: {
  3234. * metadata: {
  3235. * event: 'Fall trip to the zoo'
  3236. * }
  3237. * }
  3238. * };
  3239. *
  3240. * bucket.upload('local-image.png', options, function(err, file) {
  3241. * // Your bucket now contains:
  3242. * // - "new-image.png" (with the contents of `local-image.png')
  3243. *
  3244. * // `file` is an instance of a File object that refers to your new file.
  3245. * });
  3246. *
  3247. * //-
  3248. * // You can also have a file gzip'd on the fly.
  3249. * //-
  3250. * bucket.upload('index.html', { gzip: true }, function(err, file) {
  3251. * // Your bucket now contains:
  3252. * // - "index.html" (automatically compressed with gzip)
  3253. *
  3254. * // Downloading the file with `file.download` will automatically decode
  3255. * the
  3256. * // file.
  3257. * });
  3258. *
  3259. * //-
  3260. * // You may also re-use a File object, {File}, that references
  3261. * // the file you wish to create or overwrite.
  3262. * //-
  3263. * const options = {
  3264. * destination: bucket.file('existing-file.png'),
  3265. * resumable: false
  3266. * };
  3267. *
  3268. * bucket.upload('local-img.png', options, function(err, newFile) {
  3269. * // Your bucket now contains:
  3270. * // - "existing-file.png" (with the contents of `local-img.png')
  3271. *
  3272. * // Note:
  3273. * // The `newFile` parameter is equal to `file`.
  3274. * });
  3275. *
  3276. * //-
  3277. * // To use
  3278. * // <a
  3279. * href="https://cloud.google.com/storage/docs/encryption#customer-supplied">
  3280. * // Customer-supplied Encryption Keys</a>, provide the `encryptionKey`
  3281. * option.
  3282. * //-
  3283. * const crypto = require('crypto');
  3284. * const encryptionKey = crypto.randomBytes(32);
  3285. *
  3286. * bucket.upload('img.png', {
  3287. * encryptionKey: encryptionKey
  3288. * }, function(err, newFile) {
  3289. * // `img.png` was uploaded with your custom encryption key.
  3290. *
  3291. * // `newFile` is already configured to use the encryption key when making
  3292. * // operations on the remote object.
  3293. *
  3294. * // However, to use your encryption key later, you must create a `File`
  3295. * // instance with the `key` supplied:
  3296. * const file = bucket.file('img.png', {
  3297. * encryptionKey: encryptionKey
  3298. * });
  3299. *
  3300. * // Or with `file#setEncryptionKey`:
  3301. * const file = bucket.file('img.png');
  3302. * file.setEncryptionKey(encryptionKey);
  3303. * });
  3304. *
  3305. * //-
  3306. * // If the callback is omitted, we'll return a Promise.
  3307. * //-
  3308. * bucket.upload('local-image.png').then(function(data) {
  3309. * const file = data[0];
  3310. * });
  3311. *
  3312. * To upload a file from a URL, use {@link File#createWriteStream}.
  3313. *
  3314. * ```
  3315. * @example <caption>include:samples/files.js</caption>
  3316. * region_tag:storage_upload_file
  3317. * Another example:
  3318. *
  3319. * @example <caption>include:samples/encryption.js</caption>
  3320. * region_tag:storage_upload_encrypted_file
  3321. * Example of uploading an encrypted file:
  3322. */
  3323. upload(pathString, optionsOrCallback, callback) {
  3324. var _a, _b;
  3325. const upload = (numberOfRetries) => {
  3326. const returnValue = (0, async_retry_1.default)(async (bail) => {
  3327. await new Promise((resolve, reject) => {
  3328. var _a, _b;
  3329. if (numberOfRetries === 0 &&
  3330. ((_b = (_a = newFile === null || newFile === void 0 ? void 0 : newFile.storage) === null || _a === void 0 ? void 0 : _a.retryOptions) === null || _b === void 0 ? void 0 : _b.autoRetry)) {
  3331. newFile.storage.retryOptions.autoRetry = false;
  3332. }
  3333. const writable = newFile.createWriteStream(options);
  3334. if (options.onUploadProgress) {
  3335. writable.on('progress', options.onUploadProgress);
  3336. }
  3337. fs.createReadStream(pathString)
  3338. .on('error', bail)
  3339. .pipe(writable)
  3340. .on('error', err => {
  3341. if (this.storage.retryOptions.autoRetry &&
  3342. this.storage.retryOptions.retryableErrorFn(err)) {
  3343. return reject(err);
  3344. }
  3345. else {
  3346. return bail(err);
  3347. }
  3348. })
  3349. .on('finish', () => {
  3350. return resolve();
  3351. });
  3352. });
  3353. }, {
  3354. retries: numberOfRetries,
  3355. factor: this.storage.retryOptions.retryDelayMultiplier,
  3356. maxTimeout: this.storage.retryOptions.maxRetryDelay * 1000, //convert to milliseconds
  3357. maxRetryTime: this.storage.retryOptions.totalTimeout * 1000, //convert to milliseconds
  3358. });
  3359. if (!callback) {
  3360. return returnValue;
  3361. }
  3362. else {
  3363. return returnValue
  3364. .then(() => {
  3365. if (callback) {
  3366. return callback(null, newFile, newFile.metadata);
  3367. }
  3368. })
  3369. .catch(callback);
  3370. }
  3371. };
  3372. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  3373. if (global['GCLOUD_SANDBOX_ENV']) {
  3374. return;
  3375. }
  3376. let options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
  3377. callback =
  3378. typeof optionsOrCallback === 'function' ? optionsOrCallback : callback;
  3379. options = Object.assign({
  3380. metadata: {},
  3381. }, options);
  3382. // Do not retry if precondition option ifGenerationMatch is not set
  3383. // because this is a file operation
  3384. let maxRetries = this.storage.retryOptions.maxRetries;
  3385. if ((((_a = options === null || options === void 0 ? void 0 : options.preconditionOpts) === null || _a === void 0 ? void 0 : _a.ifGenerationMatch) === undefined &&
  3386. ((_b = this.instancePreconditionOpts) === null || _b === void 0 ? void 0 : _b.ifGenerationMatch) === undefined &&
  3387. this.storage.retryOptions.idempotencyStrategy ===
  3388. storage_js_1.IdempotencyStrategy.RetryConditional) ||
  3389. this.storage.retryOptions.idempotencyStrategy ===
  3390. storage_js_1.IdempotencyStrategy.RetryNever) {
  3391. maxRetries = 0;
  3392. }
  3393. let newFile;
  3394. if (options.destination instanceof file_js_1.File) {
  3395. newFile = options.destination;
  3396. }
  3397. else if (options.destination !== null &&
  3398. typeof options.destination === 'string') {
  3399. // Use the string as the name of the file.
  3400. newFile = this.file(options.destination, {
  3401. encryptionKey: options.encryptionKey,
  3402. kmsKeyName: options.kmsKeyName,
  3403. preconditionOpts: this.instancePreconditionOpts,
  3404. });
  3405. }
  3406. else {
  3407. // Resort to using the name of the incoming file.
  3408. const destination = path.basename(pathString);
  3409. newFile = this.file(destination, {
  3410. encryptionKey: options.encryptionKey,
  3411. kmsKeyName: options.kmsKeyName,
  3412. preconditionOpts: this.instancePreconditionOpts,
  3413. });
  3414. }
  3415. upload(maxRetries);
  3416. }
  3417. /**
  3418. * @private
  3419. *
  3420. * @typedef {object} MakeAllFilesPublicPrivateOptions
  3421. * @property {boolean} [force] Suppress errors until all files have been
  3422. * processed.
  3423. * @property {boolean} [private] Make files private.
  3424. * @property {boolean} [public] Make files public.
  3425. * @property {string} [userProject] The ID of the project which will be
  3426. * billed for the request.
  3427. */
  3428. /**
  3429. * @private
  3430. *
  3431. * @callback SetBucketMetadataCallback
  3432. * @param {?Error} err Request error, if any.
  3433. * @param {File[]} files Files that were updated.
  3434. */
  3435. /**
  3436. * @typedef {array} MakeAllFilesPublicPrivateResponse
  3437. * @property {File[]} 0 List of files affected.
  3438. */
  3439. /**
  3440. * Iterate over all of a bucket's files, calling `file.makePublic()` (public)
  3441. * or `file.makePrivate()` (private) on each.
  3442. *
  3443. * Operations are performed in parallel, up to 10 at once. The first error
  3444. * breaks the loop, and will execute the provided callback with it. Specify
  3445. * `{ force: true }` to suppress the errors.
  3446. *
  3447. * @private
  3448. *
  3449. * @param {MakeAllFilesPublicPrivateOptions} [options] Configuration options.
  3450. * @param {boolean} [options.force] Suppress errors until all files have been
  3451. * processed.
  3452. * @param {boolean} [options.private] Make files private.
  3453. * @param {boolean} [options.public] Make files public.
  3454. * @param {string} [options.userProject] The ID of the project which will be
  3455. * billed for the request.
  3456. * @param {MakeAllFilesPublicPrivateCallback} callback Callback function.
  3457. *
  3458. * @return {Promise<MakeAllFilesPublicPrivateResponse>}
  3459. */
  3460. makeAllFilesPublicPrivate_(optionsOrCallback, callback) {
  3461. const MAX_PARALLEL_LIMIT = 10;
  3462. const errors = [];
  3463. const updatedFiles = [];
  3464. const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
  3465. callback =
  3466. typeof optionsOrCallback === 'function' ? optionsOrCallback : callback;
  3467. const processFile = async (file) => {
  3468. try {
  3469. await (options.public ? file.makePublic() : file.makePrivate(options));
  3470. updatedFiles.push(file);
  3471. }
  3472. catch (e) {
  3473. if (!options.force) {
  3474. throw e;
  3475. }
  3476. errors.push(e);
  3477. }
  3478. };
  3479. this.getFiles(options)
  3480. .then(([files]) => {
  3481. const limit = (0, p_limit_1.default)(MAX_PARALLEL_LIMIT);
  3482. const promises = files.map(file => {
  3483. return limit(() => processFile(file));
  3484. });
  3485. return Promise.all(promises);
  3486. })
  3487. .then(() => callback(errors.length > 0 ? errors : null, updatedFiles), err => callback(err, updatedFiles));
  3488. }
  3489. getId() {
  3490. return this.id;
  3491. }
  3492. disableAutoRetryConditionallyIdempotent_(
  3493. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  3494. coreOpts,
  3495. // eslint-disable-next-line @typescript-eslint/no-explicit-any
  3496. methodType, localPreconditionOptions) {
  3497. var _a, _b;
  3498. if (typeof coreOpts === 'object' &&
  3499. ((_b = (_a = coreOpts === null || coreOpts === void 0 ? void 0 : coreOpts.reqOpts) === null || _a === void 0 ? void 0 : _a.qs) === null || _b === void 0 ? void 0 : _b.ifMetagenerationMatch) === undefined &&
  3500. (localPreconditionOptions === null || localPreconditionOptions === void 0 ? void 0 : localPreconditionOptions.ifMetagenerationMatch) === undefined &&
  3501. (methodType === AvailableServiceObjectMethods.setMetadata ||
  3502. methodType === AvailableServiceObjectMethods.delete) &&
  3503. this.storage.retryOptions.idempotencyStrategy ===
  3504. storage_js_1.IdempotencyStrategy.RetryConditional) {
  3505. this.storage.retryOptions.autoRetry = false;
  3506. }
  3507. else if (this.storage.retryOptions.idempotencyStrategy ===
  3508. storage_js_1.IdempotencyStrategy.RetryNever) {
  3509. this.storage.retryOptions.autoRetry = false;
  3510. }
  3511. }
  3512. }
  3513. exports.Bucket = Bucket;
  3514. /*! Developer Documentation
  3515. *
  3516. * These methods can be auto-paginated.
  3517. */
  3518. paginator_1.paginator.extend(Bucket, 'getFiles');
  3519. /*! Developer Documentation
  3520. *
  3521. * All async methods (except for streams) will return a Promise in the event
  3522. * that a callback is omitted.
  3523. */
  3524. (0, promisify_1.promisifyAll)(Bucket, {
  3525. exclude: ['cloudStorageURI', 'request', 'file', 'notification'],
  3526. });