diff --git a/src/bucket.ts b/src/bucket.ts index e4c53cbcd..e349da723 100644 --- a/src/bucket.ts +++ b/src/bucket.ts @@ -18,7 +18,7 @@ import * as arrify from 'arrify'; import * as async from 'async'; -import {ServiceObject, util, DeleteCallback} from '@google-cloud/common'; +import {ExistsCallback, ServiceObject, Metadata, util, DeleteCallback, InstanceResponseCallback, GetConfig, GetMetadataCallback} from '@google-cloud/common'; import {paginator} from '@google-cloud/paginator'; import {promisifyAll} from '@google-cloud/promisify'; import * as extend from 'extend'; @@ -45,7 +45,7 @@ interface CreateNotificationQuery { userProject?: string; } -interface MetadataRequest { +interface MetadataOptions { predefinedAcl: string; userProject?: string; } @@ -59,7 +59,7 @@ interface BucketOptions { * watchAll request * body](https://cloud.google.com/storage/docs/json_api/v1/objects/watchAll). */ -interface WatchAllRequest { +interface WatchAllOptions { delimiter: string; maxResults: number; pageToken: string; @@ -72,7 +72,7 @@ interface WatchAllRequest { /** * Query object for listing files. * - * @typedef {object} GetFilesRequest + * @typedef {object} GetFilesOptions * @property {boolean} [autoPaginate=true] Have pagination handled * automatically. * @property {string} [delimiter] Results will contain only objects whose @@ -94,7 +94,7 @@ interface WatchAllRequest { * @property {boolean} [versions] If true, returns File objects scoped to * their versions. */ -export interface GetFilesRequest { +export interface GetFilesOptions { autoPaginate?: boolean; delimiter?: string; directory?: string; @@ -128,7 +128,7 @@ export interface CombineOptions { * @param {object} apiResponse The full API response. */ export interface CombineCallback { - (err: Error|null, newFile: File|null, apiResponse: object); + (err: Error|null, newFile: File|null, apiResponse: request.Response); } /** @@ -136,7 +136,7 @@ export interface CombineCallback { * @property {File} 0 The new {@link File}. * @property {object} 1 The full API response. */ -export type CombineResponse = [File, object]; +export type CombineResponse = [File, request.Response]; /** * See a [Objects: @@ -147,7 +147,7 @@ export type CombineResponse = [File, object]; * @property {string} address The address where notifications are * delivered for this channel. */ -export interface CreateChannelConfig extends WatchAllRequest { +export interface CreateChannelConfig extends WatchAllOptions { address: string; } @@ -165,7 +165,7 @@ export interface CreateChannelOptions { * @property {Channel} 0 The new {@link Channel}. * @property {object} 1 The full API response. */ -export type CreateChannelResponse = [Channel, object]; +export type CreateChannelResponse = [Channel, request.Response]; /** * @callback CreateChannelCallback @@ -174,13 +174,13 @@ export type CreateChannelResponse = [Channel, object]; * @param {object} apiResponse The full API response. */ export interface CreateChannelCallback { - (err: Error|null, channel: Channel|null, apiResponse: object); + (err: Error|null, channel: Channel|null, apiResponse: request.Response); } /** * Metadata to set for the Notification. * - * @typedef {object} CreateNotificationRequest + * @typedef {object} CreateNotificationOptions * @property {object} [customAttributes] An optional list of additional * attributes to attach to each Cloud PubSub message published for this * notification subscription. @@ -198,7 +198,7 @@ export interface CreateChannelCallback { * @property {string} [userProject] The ID of the project which will be * billed for the request. */ -export interface CreateNotificationRequest { +export interface CreateNotificationOptions { customAttributes?: {[key: string]: string}; eventTypes?: string[]; objectNamePrefix?: string; @@ -213,7 +213,8 @@ export interface CreateNotificationRequest { * @param {object} apiResponse The full API response. */ export interface CreateNotificationCallback { - (err: Error|null, notification: Notification|null, apiResponse: object); + (err: Error|null, notification: Notification|null, + apiResponse: request.Response); } /** @@ -221,22 +222,22 @@ export interface CreateNotificationCallback { * @property {Notification} 0 The new {@link Notification}. * @property {object} 1 The full API response. */ -export type CreateNotificationResponse = [Notification, object]; +export type CreateNotificationResponse = [Notification, request.Response]; /** - * @typedef {object} DeleteBucketRequest Configuration options. - * @param {string} userProject The ID of the project which will be + * @typedef {object} DeleteBucketOptions Configuration options. + * @param {string} [userProject] The ID of the project which will be * billed for the request. */ -export interface DeleteBucketRequest { - userProject: string; +export interface DeleteBucketOptions { + userProject?: string; } /** * @typedef {array} DeleteBucketResponse * @property {object} 0 The full API response. */ -export type DeleteBucketResponse = [object]; +export type DeleteBucketResponse = [request.Response]; /** * @callback DeleteBucketCallback @@ -244,16 +245,16 @@ export type DeleteBucketResponse = [object]; * @param {object} apiResponse The full API response. */ export interface DeleteBucketCallback extends DeleteCallback { - (err: Error|null, apiResponse: object); + (err: Error|null, apiResponse: request.Response); } /** - * @typedef {object} DeleteFilesRequest Query object. See {@link Bucket#getFiles} + * @typedef {object} DeleteFilesOptions Query object. See {@link Bucket#getFiles} * for all of the supported properties. * @property {boolean} [force] Suppress errors until all files have been * processed. */ -export interface DeleteFilesRequest extends GetFilesRequest { +export interface DeleteFilesOptions extends GetFilesOptions { force?: boolean; } @@ -271,7 +272,7 @@ export interface DeleteFilesCallback { * @typedef {array} DeleteLabelsResponse * @property {object} 0 The full API response. */ -export type DeleteLabelsResponse = [object]; +export type DeleteLabelsResponse = [request.Response]; /** * @callback DeleteLabelsCallback @@ -283,41 +284,41 @@ export interface DeleteLabelsCallback { } /** - * @typedef {array} DisableRequesterPaysResponse + * @typedef {array} DisableOptionserPaysResponse * @property {object} 0 The full API response. */ -export type DisableRequesterPaysResponse = [object]; +export type DisableOptionserPaysResponse = [request.Response]; /** - * @callback DisableRequesterPaysCallback + * @callback DisableOptionserPaysCallback * @param {?Error} err Request error, if any. * @param {object} apiResponse The full API response. */ -export interface DisableRequesterPaysCallback { +export interface DisableOptionserPaysCallback { (err: Error|null, apiResponse?: object); } /** - * @typedef {array} EnableRequesterPaysResponse + * @typedef {array} EnableOptionserPaysResponse * @property {object} 0 The full API response. */ -export type EnableRequesterPaysResponse = [object]; +export type EnableOptionserPaysResponse = [request.Response]; /** - * @callback EnableRequesterPaysCallback + * @callback EnableOptionserPaysCallback * @param {?Error} err Request error, if any. * @param {object} apiResponse The full API response. */ -export interface EnableRequesterPaysCallback { - (err: Error|null, apiResponse: object); +export interface EnableOptionserPaysCallback { + (err: Error|null, apiResponse: request.Response); } /** - * @typedef {object} BucketExistsRequest Configuration options for Bucket#exists(). + * @typedef {object} BucketExistsOptions Configuration options for Bucket#exists(). * @param {string} [userProject] The ID of the project which will be * billed for the request. */ -export interface BucketExistsRequest { +export interface BucketExistsOptions { userProject?: string; } @@ -332,11 +333,114 @@ export type BucketExistsResponse = [boolean]; * @param {?Error} err Request error, if any. * @param {boolean} exists Whether the {@link Bucket} exists. */ -export interface BucketExistsCallback { - (err: Error); - (err: null, exists: boolean); +export interface BucketExistsCallback extends ExistsCallback {} + +/** + * @typedef {object} [GetBucketOptions] Configuration options for Bucket#get() + * @property {boolean} [autoCreate] Automatically create the object if + * it does not exist. Default: `false` + * @property {string} [userProject] The ID of the project which will be + * billed for the request. + */ +export interface GetBucketOptions extends GetConfig { + userProject?: string; +} + +/** + * @typedef {array} GetBucketResponse + * @property {Bucket} 0 The {@link Bucket}. + * @property {object} 1 The full API response. + */ +export type GetBucketResponse = [Bucket, request.Response]; + +/** + * @callback GetBucketCallback + * @param {?Error} err Request error, if any. + * @param {Bucket} bucket The {@link Bucket}. + * @param {object} apiResponse The full API response. + */ +export interface GetBucketCallback extends InstanceResponseCallback { + (err: Error|null, bucket: Bucket|null, apiResponse: request.Response); +} + +/** + * @typedef {object} GetLabelsOptions Configuration options for Bucket#getLabels(). + * @param {string} [userProject] The ID of the project which will be + * billed for the request. + */ +export interface GetLabelsOptions { + userProject?: string; +} + +/** + * @typedef {array} GetLabelsResponse + * @property {object} 0 Object of labels currently set on this bucket. + */ +export type GetLabelsResponse = [request.Response]; + +/** + * @callback GetLabelsCallback + * @param {?Error} err Request error, if any. + * @param {object} labels Object of labels currently set on this bucket. + */ +export interface GetLabelsCallback { + (err: Error|null, labels: object|null); +} + +/** + * @typedef {array} GetBucketMetadataResponse + * @property {object} 0 The bucket metadata. + * @property {object} 1 The full API response. + */ +export type GetBucketMetadataResponse = [object, request.Response]; + +/** + * @callback GetBucketMetadataCallback + * @param {?Error} err Request error, if any. + * @param {object} metadata The bucket metadata. + * @param {object} apiResponse The full API response. + */ +export interface GetBucketMetadataCallback extends GetMetadataCallback { + (err: Error|null, metadata: Metadata|null, apiResponse: request.Response); } +/** + * @typedef {object} GetBucketMetadataOptions Configuration options for Bucket#getMetadata(). + * @property {string} [userProject] The ID of the project which will be + * billed for the request. + */ +export interface GetBucketMetadataOptions { + userProject?: string; +} + +/** + * @typedef {object} GetNotificationOptions Configuration options for Bucket#getNotification(). + * @property {string} [userProject] The ID of the project which will be + * billed for the request. + */ +export interface GetNotificationsOptions { + userProject?: string; +} + +/** + * @callback GetNotificationsCallback + * @param {?Error} err Request error, if any. + * @param {Notification[]} notifications Array of {@link Notification} + * instances. + * @param {object} apiResponse The full API response. + */ +export interface GetNotificationsCallback { + (err: Error|null, notifications: Notification[]|null, + apiResponse: request.Response); +} + +/** + * @typedef {array} GetNotificationsResponse + * @property {Notification[]} 0 Array of {@link Notification} instances. + * @property {object} 1 The full API response. + */ +export type GetNotificationsResponse = [Notification[], request.Response]; + /** * The size of a file (in bytes) must be greater than this number to * automatically trigger a resumable upload. @@ -518,7 +622,7 @@ class Bucket extends ServiceObject { * readable object stream. * * @method Bucket#getFilesStream - * @param {GetFilesRequest} [query] Query object for listing files. + * @param {GetFilesOptions} [query] Query object for listing files. * @returns {ReadableStream} A readable stream that emits {@link File} instances. * * @example @@ -557,7 +661,7 @@ class Bucket extends ServiceObject { * Create a bucket. * * @method Bucket#create - * @param {CreateBucketRequest} [metadata] Metadata to set for the bucket. + * @param {CreateBucketOptions} [metadata] Metadata to set for the bucket. * @param {CreateBucketCallback} [callback] Callback function. * @returns {Promise} * @@ -656,10 +760,14 @@ class Bucket extends ServiceObject { options: CombineOptions): Promise; combine( sources: string[]|File[], destination: string|File, - options: CombineOptions, callback); + options: CombineOptions, callback: CombineCallback): void; + combine( + sources: string[]|File[], destination: string|File, + callback: CombineCallback): void; combine( sources: string[]|File[], destination: string|File, - options: CombineOptions, callback?): Promise|void { + optionsOrCallback?: CombineOptions|CombineCallback, + callback?: CombineCallback): Promise|void { if (!is.array(sources) || sources.length < 2) { throw new Error('You must provide at least two source files.'); } @@ -668,12 +776,14 @@ class Bucket extends ServiceObject { throw new Error('A destination file must be specified.'); } - if (is.fn(options)) { - callback = options; - options = {}; + let options: CombineOptions = {}; + if (typeof optionsOrCallback === 'function') { + callback = optionsOrCallback; + } else if (optionsOrCallback) { + options = optionsOrCallback; } - const convertToFile = (file: string|File) => { + const convertToFile = (file: string|File): File => { if (file instanceof File) { return file; } @@ -682,25 +792,25 @@ class Bucket extends ServiceObject { // tslint:disable-next-line:no-any sources = (sources as any).map(convertToFile); - destination = convertToFile(destination); + const destinationFile = convertToFile(destination); callback = callback || util.noop; - if (!destination.metadata.contentType) { - const destinationContentType = mime.contentType(destination.name); + if (!destinationFile.metadata.contentType) { + const destinationContentType = mime.contentType(destinationFile.name); if (destinationContentType) { - destination.metadata.contentType = destinationContentType; + destinationFile.metadata.contentType = destinationContentType; } } // Make the request from the destination File object. - destination.request( + destinationFile.request( { method: 'POST', uri: '/compose', json: { destination: { - contentType: destination.metadata.contentType, + contentType: destinationFile.metadata.contentType, }, // tslint:disable-next-line:no-any sourceObjects: (sources as any).map(source => { @@ -723,7 +833,7 @@ class Bucket extends ServiceObject { return; } - callback!(null, destination, resp); + callback!(null, destinationFile, resp); }); } @@ -769,13 +879,14 @@ class Bucket extends ServiceObject { id: string, config: CreateChannelConfig, options?: CreateChannelOptions): Promise; createChannel( - id: string, config: CreateChannelConfig, callback: CreateChannelCallback); + id: string, config: CreateChannelConfig, + callback: CreateChannelCallback): void; createChannel( id: string, config: CreateChannelConfig, options: CreateChannelOptions, - callback: CreateChannelCallback); + callback: CreateChannelCallback): void; createChannel( id: string, config: CreateChannelConfig, - options?: CreateChannelOptions|CreateChannelCallback, + optionsOrCallback?: CreateChannelOptions|CreateChannelCallback, callback?: CreateChannelCallback): Promise|void { if (!is.string(id)) { throw new Error('An ID is required to create a channel.'); @@ -785,9 +896,11 @@ class Bucket extends ServiceObject { throw new Error('An address is required to create a channel.'); } - if (typeof options === 'function') { - callback = options; - options = {}; + let options: CreateChannelOptions = {}; + if (typeof optionsOrCallback === 'function') { + callback = optionsOrCallback; + } else if (optionsOrCallback) { + options = optionsOrCallback; } this.request( @@ -830,7 +943,7 @@ class Bucket extends ServiceObject { * - `projects/grape-spaceship-123/topics/my-topic` * * - `my-topic` - * @param {CreateNotificationRequest} [options] Metadata to set for the + * @param {CreateNotificationOptions} [options] Metadata to set for the * notification. * @param {CreateNotificationCallback} [callback] Callback function. * @returns {Promise} @@ -871,20 +984,22 @@ class Bucket extends ServiceObject { * region_tag:storage_create_notification * Another example: */ - createNotification(topic: string, options?: CreateNotificationRequest): + createNotification(topic: string, options?: CreateNotificationOptions): Promise; createNotification( - topic: string, options: CreateNotificationRequest, - callback: CreateNotificationCallback); - createNotification(topic: string, callback: CreateNotificationCallback); + topic: string, options: CreateNotificationOptions, + callback: CreateNotificationCallback): void; + createNotification(topic: string, callback: CreateNotificationCallback): void; createNotification( topic: string, - options?: CreateNotificationRequest|CreateNotificationCallback, + optionsOrCallback?: CreateNotificationOptions|CreateNotificationCallback, callback?: CreateNotificationCallback): Promise|void { - if (typeof options === 'function') { - callback = options; - options = {}; + let options: CreateNotificationOptions = {}; + if (typeof optionsOrCallback === 'function') { + callback = optionsOrCallback; + } else if (optionsOrCallback) { + options = optionsOrCallback; } if (is.object(topic) && util.isCustomType(topic, 'pubsub/topic')) { @@ -941,9 +1056,7 @@ class Bucket extends ServiceObject { * * @see [Buckets: delete API Documentation]{@link https://cloud.google.com/storage/docs/json_api/v1/buckets/delete} * - * @param {object} [options] Configuration options. - * @param {string} [options.userProject] The ID of the project which will be - * billed for the request. + * @param {DeleteBucketOptions} [options] Configuration options. * @param {DeleteBucketCallback} [callback] Callback function. * @returns {Promise} * @@ -964,15 +1077,17 @@ class Bucket extends ServiceObject { * region_tag:storage_delete_bucket * Another example: */ - delete(options?: DeleteBucketRequest): Promise; - delete(callback: DeleteBucketCallback); - delete(options: DeleteBucketRequest, callback: DeleteBucketCallback); + delete(options?: DeleteBucketOptions): Promise; + delete(callback: DeleteBucketCallback): void; + delete(options: DeleteBucketOptions, callback: DeleteBucketCallback): void; delete( - options?: DeleteBucketRequest|DeleteBucketCallback, + optionsOrCallback?: DeleteBucketOptions|DeleteBucketCallback, callback?: DeleteBucketCallback): Promise|void { - if (typeof options === 'function') { - callback = options; - options = {} as DeleteBucketRequest; + let options: DeleteBucketOptions = {}; + if (typeof optionsOrCallback === 'function') { + callback = optionsOrCallback; + } else if (optionsOrCallback) { + options = optionsOrCallback; } this.request( @@ -1001,7 +1116,7 @@ class Bucket extends ServiceObject { * * @see [Objects: delete API Documentation]{@link https://cloud.google.com/storage/docs/json_api/v1/objects/delete} * - * @param {DeleteFilesRequest} [query] Query object. See {@link Bucket#getFiles} + * @param {DeleteFilesOptions} [query] Query object. See {@link Bucket#getFiles} * @param {DeleteFilesCallback} [callback] Callback function. * @returns {Promise} * @@ -1045,32 +1160,32 @@ class Bucket extends ServiceObject { * //- * bucket.deleteFiles().then(function() {}); */ - deleteFiles(query?: DeleteFilesRequest): Promise; - deleteFiles(callback: DeleteFilesCallback); - deleteFiles(query: DeleteFilesRequest, callback: DeleteFilesCallback); + deleteFiles(query?: DeleteFilesOptions): Promise; + deleteFiles(callback: DeleteFilesCallback): void; + deleteFiles(query: DeleteFilesOptions, callback: DeleteFilesCallback): void; deleteFiles( - query?: DeleteFilesRequest|DeleteFilesCallback, + queryOrCallback?: DeleteFilesOptions|DeleteFilesCallback, callback?: DeleteFilesCallback): Promise|void { - if (typeof query === 'function') { - callback = query; - query = {} as DeleteFilesRequest; + let query: DeleteFilesOptions = {}; + if (typeof queryOrCallback === 'function') { + callback = queryOrCallback; + } else if (queryOrCallback) { + query = queryOrCallback; } - const req = query || {} as DeleteFilesRequest; - const MAX_PARALLEL_LIMIT = 10; const errors = [] as Error[]; - this.getFiles(req, (err, files) => { + this.getFiles(query, (err, files) => { if (err) { callback!(err, {}); return; } const deleteFile = (file, callback) => { - file.delete(req, (err: Error) => { + file.delete(query, (err: Error) => { if (err) { - if (req.force) { + if (query.force) { errors.push(err); callback!(); return; @@ -1136,18 +1251,18 @@ class Bucket extends ServiceObject { * }); */ deleteLabels(labels?: string|string[]): Promise; - deleteLabels(callback: DeleteLabelsCallback); - deleteLabels(labels: string|string[], callback: DeleteLabelsCallback); + deleteLabels(callback: DeleteLabelsCallback): void; + deleteLabels(labels: string|string[], callback: DeleteLabelsCallback): void; deleteLabels( - labels?: string|string[]|DeleteLabelsCallback, + labelsOrCallback?: string|string[]|DeleteLabelsCallback, callback?: DeleteLabelsCallback): Promise|void { - if (typeof labels === 'function') { - callback = labels; - labels = [] as string[]; + let labels = new Array(); + if (typeof labelsOrCallback === 'function') { + callback = labelsOrCallback; + } else if (labelsOrCallback) { + labels = arrify(labelsOrCallback); } - labels = arrify(labels); - const deleteLabels = labels => { const nullLabelMap = labels.reduce((nullLabelMap, labelKey) => { nullLabelMap[labelKey] = null; @@ -1164,7 +1279,7 @@ class Bucket extends ServiceObject { return; } - deleteLabels(Object.keys(labels)); + deleteLabels(Object.keys(labels!)); }); } else { deleteLabels(labels); @@ -1181,15 +1296,15 @@ class Bucket extends ServiceObject { * * Disable `requesterPays` functionality from this bucket. * - * @param {DisableRequesterPaysCallback} [callback] Callback function. - * @returns {Promise} + * @param {DisableOptionserPaysCallback} [callback] Callback function. + * @returns {Promise} * * @example * const {Storage} = require('@google-cloud/storage'); * const storage = new Storage(); * const bucket = storage.bucket('albums'); * - * bucket.disableRequesterPays(function(err, apiResponse) { + * bucket.disableOptionserPays(function(err, apiResponse) { * if (!err) { * // requesterPays functionality disabled successfully. * } @@ -1198,7 +1313,7 @@ class Bucket extends ServiceObject { * //- * // If the callback is omitted, we'll return a Promise. * //- - * bucket.disableRequesterPays().then(function(data) { + * bucket.disableOptionserPays().then(function(data) { * const apiResponse = data[0]; * }); * @@ -1206,10 +1321,10 @@ class Bucket extends ServiceObject { * region_tag:storage_disable_requester_pays * Example of disabling requester pays: */ - disableRequesterPays(): Promise; - disableRequesterPays(callback: DisableRequesterPaysCallback); - disableRequesterPays(callback?: DisableRequesterPaysCallback): - Promise|void { + disableOptionserPays(): Promise; + disableOptionserPays(callback: DisableOptionserPaysCallback): void; + disableOptionserPays(callback?: DisableOptionserPaysCallback): + Promise|void { this.setMetadata( { billing: { @@ -1231,15 +1346,15 @@ class Bucket extends ServiceObject { * bucket owner, to have the requesting user assume the charges for the access * to your bucket and its contents. * - * @param {EnableRequesterPaysCallback} [callback] Callback function. - * @returns {Promise} + * @param {EnableOptionserPaysCallback} [callback] Callback function. + * @returns {Promise} * * @example * const {Storage} = require('@google-cloud/storage'); * const storage = new Storage(); * const bucket = storage.bucket('albums'); * - * bucket.enableRequesterPays(function(err, apiResponse) { + * bucket.enableOptionserPays(function(err, apiResponse) { * if (!err) { * // requesterPays functionality enabled successfully. * } @@ -1248,7 +1363,7 @@ class Bucket extends ServiceObject { * //- * // If the callback is omitted, we'll return a Promise. * //- - * bucket.enableRequesterPays().then(function(data) { + * bucket.enableOptionserPays().then(function(data) { * const apiResponse = data[0]; * }); * @@ -1256,10 +1371,10 @@ class Bucket extends ServiceObject { * region_tag:storage_enable_requester_pays * Example of enabling requester pays: */ - enableRequesterPays(): Promise; - enableRequesterPays(callback: EnableRequesterPaysCallback); - enableRequesterPays(callback?: EnableRequesterPaysCallback): - Promise|void { + enableOptionserPays(): Promise; + enableOptionserPays(callback: EnableOptionserPaysCallback): void; + enableOptionserPays(callback?: EnableOptionserPaysCallback): + Promise|void { this.setMetadata( { billing: { @@ -1272,7 +1387,7 @@ class Bucket extends ServiceObject { /** * Check if the bucket exists. * - * @param {BucketExistsRequest} [options] Configuration options. + * @param {BucketExistsOptions} [options] Configuration options. * @param {BucketExistsCallback} [callback] Callback function. * @returns {Promise} * @@ -1290,18 +1405,20 @@ class Bucket extends ServiceObject { * const exists = data[0]; * }); */ - exists(options?: BucketExistsRequest): Promise; - exists(callback: BucketExistsCallback); - exists(options: BucketExistsRequest, callback: BucketExistsCallback); + exists(options?: BucketExistsOptions): Promise; + exists(callback: BucketExistsCallback): void; + exists(options: BucketExistsOptions, callback: BucketExistsCallback): void; exists( - options?: BucketExistsRequest|BucketExistsCallback, + optionsOrCallback?: BucketExistsOptions|BucketExistsCallback, callback?: BucketExistsCallback): Promise|void { - if (typeof options === 'function') { - callback = options; - options = {} as BucketExistsRequest; + let options: BucketExistsOptions = {}; + if (typeof optionsOrCallback === 'function') { + callback = optionsOrCallback; + } else if (optionsOrCallback) { + options = optionsOrCallback; } - options = options || {} as BucketExistsRequest; + options = options || {} as BucketExistsOptions; this.get(options, err => { if (err) { @@ -1341,7 +1458,7 @@ class Bucket extends ServiceObject { * const bucket = storage.bucket('albums'); * const file = bucket.file('my-existing-file.png'); */ - file(name: string, options?: FileOptions) { + file(name: string, options?: FileOptions): File { if (!name) { throw Error('A file name must be specified.'); } @@ -1349,17 +1466,6 @@ class Bucket extends ServiceObject { return new File(this, name, options); } - /** - * @typedef {array} GetBucketResponse - * @property {Bucket} 0 The {@link Bucket}. - * @property {object} 1 The full API response. - */ - /** - * @callback GetBucketCallback - * @param {?Error} err Request error, if any. - * @param {Bucket} bucket The {@link Bucket}. - * @param {object} apiResponse The full API response. - */ /** * Get a bucket if it exists. * @@ -1368,11 +1474,7 @@ class Bucket extends ServiceObject { * normally required for the `create` method must be contained within this * object as well. * - * @param {object} [options] Configuration options. - * @param {boolean} [options.autoCreate] Automatically create the object if - * it does not exist. Default: `false` - * @param {string} [options.userProject] The ID of the project which will be - * billed for the request. + * @param {GetBucketOptions} [options] Configuration options. * @param {GetBucketCallback} [callback] Callback function. * @returns {Promise} * @@ -1393,29 +1495,33 @@ class Bucket extends ServiceObject { * const apiResponse = data[1]; * }); */ - get(options, callback?) { - if (is.fn(options)) { - callback = options; - options = {}; + get(options?: GetBucketOptions): Promise; + get(callback: GetBucketCallback): void; + get(options: GetBucketOptions, callback: GetBucketCallback): void; + get(optionsOrCallback?: GetBucketOptions|GetBucketCallback, + callback?: GetBucketCallback): Promise|void { + let options: GetBucketOptions = {}; + if (typeof optionsOrCallback === 'function') { + callback = optionsOrCallback; + } else if (optionsOrCallback) { + options = optionsOrCallback; } - options = options || {}; - const autoCreate = options.autoCreate; delete options.autoCreate; const onCreate = (err, bucket, apiResponse) => { if (err) { if (err.code === 409) { - this.get(options, callback); + this.get(options, callback!); return; } - callback(err, null, apiResponse); + callback!(err, null, apiResponse); return; } - callback(null, bucket, apiResponse); + callback!(null, bucket, apiResponse); }; this.getMetadata(options, (err, metadata) => { @@ -1433,11 +1539,11 @@ class Bucket extends ServiceObject { return; } - callback(err, null, metadata); + callback!(err, null, metadata); return; } - callback(null, this, metadata); + callback!(null, this, metadata); }); } @@ -1455,7 +1561,7 @@ class Bucket extends ServiceObject { * * @see [Objects: list API Documentation]{@link https://cloud.google.com/storage/docs/json_api/v1/objects/list} * - * @param {GetFilesRequest} [query] Query object for listing files. + * @param {GetFilesOptions} [query] Query object for listing files. * @param {GetFilesCallback} [callback] Callback function. * @returns {Promise} * @@ -1518,7 +1624,7 @@ class Bucket extends ServiceObject { * region_tag:storage_list_files_with_prefix * Example of listing files, filtered by a prefix: */ - getFiles(query: GetFilesRequest, callback?) { + getFiles(query: GetFilesOptions, callback?) { if (!callback) { callback = query; query = {}; @@ -1570,15 +1676,6 @@ class Bucket extends ServiceObject { }); } - /** - * @typedef {array} GetLabelsResponse - * @property {object} 0 Object of labels currently set on this bucket. - */ - /** - * @callback GetLabelsCallback - * @param {?Error} err Request error, if any. - * @param {object} labels Object of labels currently set on this bucket. - */ /** * Get the labels currently set on this bucket. * @@ -1611,33 +1708,29 @@ class Bucket extends ServiceObject { * const labels = data[0]; * }); */ - getLabels(options, callback?) { - if (is.fn(options)) { - callback = options; - options = {}; + getLabels(options: GetLabelsOptions): Promise; + getLabels(callback: GetLabelsCallback): void; + getLabels(options: GetLabelsOptions, callback: GetLabelsCallback): void; + getLabels( + optionsOrCallback?: GetLabelsOptions|GetLabelsCallback, + callback?: GetLabelsCallback): Promise|void { + let options: GetLabelsOptions = {}; + if (typeof optionsOrCallback === 'function') { + callback = optionsOrCallback; + } else if (optionsOrCallback) { + options = optionsOrCallback; } this.getMetadata(options, (err, metadata) => { if (err) { - callback(err); + callback!(err, null); return; } - callback(null, metadata.labels || {}); + callback!(null, metadata.labels || {}); }); } - /** - * @typedef {array} GetBucketMetadataResponse - * @property {object} 0 The bucket metadata. - * @property {object} 1 The full API response. - */ - /** - * @callback GetBucketMetadataCallback - * @param {?Error} err Request error, if any. - * @param {object} files The bucket metadata. - * @param {object} apiResponse The full API response. - */ /** * Get the bucket's metadata. * @@ -1645,9 +1738,7 @@ class Bucket extends ServiceObject { * * @see [Buckets: get API Documentation]{@link https://cloud.google.com/storage/docs/json_api/v1/buckets/get} * - * @param {object} [options] Configuration options. - * @param {string} [options.userProject] The ID of the project which will be - * billed for the request. + * @param {GetBucketMetadataOptions} [options] Configuration options. * @param {GetBucketMetadataCallback} [callback] Callback function. * @returns {Promise} * @@ -1670,10 +1761,21 @@ class Bucket extends ServiceObject { * region_tag:storage_get_requester_pays_status * Example of retrieving the requester pays status of a bucket: */ - getMetadata(options, callback?) { - if (is.fn(options)) { - callback = options; - options = {}; + getMetadata(options?: GetBucketMetadataOptions): + Promise; + getMetadata(callback: GetBucketMetadataCallback): void; + getMetadata( + options: GetBucketMetadataOptions, + callback: GetBucketMetadataCallback): void; + getMetadata( + optionsOrCallback?: GetBucketMetadataOptions|GetBucketMetadataCallback, + callback?: GetBucketMetadataCallback): Promise| + void { + let options: GetBucketMetadataOptions = {}; + if (typeof optionsOrCallback === 'function') { + callback = optionsOrCallback; + } else if (optionsOrCallback) { + options = optionsOrCallback; } this.request( @@ -1683,36 +1785,22 @@ class Bucket extends ServiceObject { }, (err, resp) => { if (err) { - callback(err, null, resp); + callback!(err, null, resp); return; } this.metadata = resp; - callback(null, this.metadata, resp); + callback!(null, this.metadata, resp); }); } - /** - * @typedef {array} GetNotificationsResponse - * @property {Notification[]} 0 Array of {@link Notification} instances. - * @property {object} 1 The full API response. - */ - /** - * @callback GetNotificationsCallback - * @param {?Error} err Request error, if any. - * @param {Notification[]} notifications Array of {@link Notification} - * instances. - * @param {object} apiResponse The full API response. - */ /** * Retrieves a list of notification subscriptions for a given bucket. * * @see [Notifications: list]{@link https://cloud.google.com/storage/docs/json_api/v1/notifications/list} * - * @param {object} [options] Configuration options. - * @param {string} [options.userProject] The ID of the project which will be - * billed for the request. + * @param {GetNotificationsOptions} [options] Configuration options. * @param {GetNotificationsCallback} [callback] Callback function. * @returns {Promise} * @@ -1739,10 +1827,21 @@ class Bucket extends ServiceObject { * region_tag:storage_list_notifications * Another example: */ - getNotifications(options, callback?) { - if (is.fn(options)) { - callback = options; - options = {}; + getNotifications(options?: GetNotificationsOptions): + Promise; + getNotifications(callback: GetNotificationsCallback): void; + getNotifications( + options: GetNotificationsOptions, + callback: GetNotificationsCallback): void; + getNotifications( + optionsOrCallback?: GetNotificationsOptions|GetNotificationsCallback, + callback?: GetNotificationsCallback): Promise| + void { + let options: GetNotificationsOptions = {}; + if (typeof optionsOrCallback === 'function') { + callback = optionsOrCallback; + } else if (optionsOrCallback) { + options = optionsOrCallback; } this.request( @@ -1752,7 +1851,7 @@ class Bucket extends ServiceObject { }, (err, resp) => { if (err) { - callback(err, null, resp); + callback!(err, null, resp); return; } @@ -1762,7 +1861,7 @@ class Bucket extends ServiceObject { return notificationInstance; }); - callback(null, notifications, resp); + callback!(null, notifications, resp); }); } @@ -1862,9 +1961,9 @@ class Bucket extends ServiceObject { options.private = true; const setPredefinedAcl = done => { - const query = { + const query: MetadataOptions = { predefinedAcl: 'projectPrivate', - } as MetadataRequest; + }; if (options.userProject) { query.userProject = options.userProject;