Skip to content
This repository was archived by the owner on Mar 3, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions src/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,10 @@ export interface MoveOptions {
userProject?: string;
}

export type RenameOptions = MoveOptions;
export type RenameResponse = MoveResponse;
export type RenameCallback = MoveCallback;

export type RotateEncryptionKeyOptions = string | Buffer | EncryptionKeyOptions;

export interface EncryptionKeyOptions {
Expand Down Expand Up @@ -3233,6 +3237,103 @@ class File extends ServiceObject<File> {
});
}

rename(
destinationFile: string | File,
options?: RenameOptions
): Promise<RenameResponse>;
rename(destinationFile: string | File, callback: RenameCallback): void;
rename(
destinationFile: string | File,
options: RenameOptions,
callback: RenameCallback
): void;
/**
* @typedef {array} RenameResponse
* @property {File} 0 The destination File.
* @property {object} 1 The full API response.
*/
/**
* @callback RenameCallback
* @param {?Error} err Request error, if any.
* @param {?File} destinationFile The destination File.
* @param {object} apiResponse The full API response.
*/
/**
* @typedef {object} RenameOptions Configuration options for File#move(). See an
* [Object
* resource](https://cloud.google.com/storage/docs/json_api/v1/objects#resource).
* @param {string} [userProject] The ID of the project which will be
* billed for the request.
*/
/**
* Rename this file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should explain probably what "move()" does, that this is not an atomic operation, and also that this is an alias for "move()".

* @param {string|File} destinationFile Destination file.
* @param {RenameCallback} [callback] Callback function.
* @returns {Promise<RenameResponse>}
*
* @example
* const {Storage} = require('@google-cloud/storage');
* const storage = new Storage();
*
* //-
* // You can pass in a string or a File object.
* //
* // For all of the below examples, assume we are working with the following
* // Bucket and File objects.
* //-
*
* const bucket = storage.bucket('my-bucket');
* const file = bucket.file('my-image.png');
*
* //-
* // You can pass in a string for the destinationFile.
* //-
* file.rename('renamed-image.png', function(err, renamedFile, apiResponse) {
* // `my-bucket` no longer contains:
* // - "my-image.png"
* // but contains instead:
* // - "renamed-image.png"
*
* // `renamedFile` is an instance of a File object that refers to your
* // renamed file.
* });
*
* //-
* // You can pass in a File object.
* //-
* const anotherFile = anotherBucket.file('my-awesome-image.png');
*
* file.rename(anotherFile, function(err, renamedFile, apiResponse) {
* // `my-bucket` no longer contains:
* // - "my-image.png"
*
* // Note:
* // The `renamedFile` parameter is equal to `anotherFile`.
* });
*
* //-
* // If the callback is omitted, we'll return a Promise.
* //-
* file.rename('my-renamed-image.png').then(function(data) {
* const renamedFile = data[0];
* const apiResponse = data[1];
* });
*/
rename(
destinationFile: string | File,
optionsOrCallback?: RenameOptions | RenameCallback,
callback?: RenameCallback
): Promise<RenameResponse> | void {
const options =
typeof optionsOrCallback === 'object' ? optionsOrCallback : {};
callback =
typeof optionsOrCallback === 'function' ? optionsOrCallback : callback;

callback = callback || util.noop;

this.move(destinationFile, options, callback);
}

request(reqOpts: DecorateRequestOptions): Promise<[ResponseBody, Metadata]>;
request(
reqOpts: DecorateRequestOptions,
Expand Down
17 changes: 17 additions & 0 deletions system-test/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1948,6 +1948,23 @@ describe('storage', () => {
})
);

it(
'file#rename',
doubleTest((options: GetFileOptions, done: SaveCallback) => {
const newFile = bucketNonAllowList.file(generateName());

file.rename(newFile, options, err => {
if (err) {
done(err);
return;
}

// Re-create the file. The tests need it.
file.save('newcontent', options, done);
});
})
);

it(
'file#setMetadata',
doubleTest(
Expand Down
35 changes: 35 additions & 0 deletions test/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import {
SignedPostPolicyV4Output,
GenerateSignedPostPolicyV4Options,
STORAGE_POST_POLICY_BASE_URL,
MoveOptions,
} from '../src/file';

let promisified = false;
Expand Down Expand Up @@ -3679,6 +3680,40 @@ describe('File', () => {
});
});

describe('rename', () => {
it('should correctly call File#move', done => {
const newFileName = 'renamed-file.txt';
const options = {};
file.move = (dest: string, opts: MoveOptions, cb: Function) => {
assert.strictEqual(dest, newFileName);
assert.strictEqual(opts, options);
assert.strictEqual(cb, done);
cb();
};
file.rename(newFileName, options, done);
});

it('should accept File object', done => {
const newFileObject = new File(BUCKET, 'renamed-file.txt');
const options = {};
file.move = (dest: string, opts: MoveOptions, cb: Function) => {
assert.strictEqual(dest, newFileObject);
assert.strictEqual(opts, options);
assert.strictEqual(cb, done);
cb();
};
file.rename(newFileObject, options, done);
});

it('should not require options', done => {
file.move = (dest: string, opts: MoveOptions, cb: Function) => {
assert.deepStrictEqual(opts, {});
cb();
};
file.rename('new-name', done);
});
});

describe('request', () => {
it('should call the parent request function', () => {
const options = {};
Expand Down