Skip to content

Commit 1b71fcc

Browse files
authored
feat: add ability to create a File object from URL (#2432)
* feat: add ability to create a File object from URL * fixes * linter fixes
1 parent 6e81e05 commit 1b71fcc

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

src/file.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,9 @@ export class RequestError extends Error {
479479
}
480480

481481
const SEVEN_DAYS = 7 * 24 * 60 * 60;
482+
const GS_UTIL_URL_REGEX = /(gs):\/\/([a-z0-9_.-]+)\/(.+)/g;
483+
const HTTPS_PUBLIC_URL_REGEX =
484+
/(https):\/\/(storage\.googleapis\.com)\/([a-z0-9_.-]+)\/(.+)/g;
482485

483486
export enum FileExceptionMessages {
484487
EXPIRATION_TIME_NA = 'An expiration time is not available.',
@@ -2358,6 +2361,35 @@ class File extends ServiceObject<File, FileMetadata> {
23582361
return this;
23592362
}
23602363

2364+
/**
2365+
* Gets a reference to a Cloud Storage {@link File} file from the provided URL in string format.
2366+
* @param {string} publicUrlOrGsUrl the URL as a string. Must be of the format gs://bucket/file
2367+
* or https://storage.googleapis.com/bucket/file.
2368+
* @param {Storage} storageInstance an instance of a Storage object.
2369+
* @param {FileOptions} [options] Configuration options
2370+
* @returns {File}
2371+
*/
2372+
static from(
2373+
publicUrlOrGsUrl: string,
2374+
storageInstance: Storage,
2375+
options?: FileOptions
2376+
): File {
2377+
const gsMatches = [...publicUrlOrGsUrl.matchAll(GS_UTIL_URL_REGEX)];
2378+
const httpsMatches = [...publicUrlOrGsUrl.matchAll(HTTPS_PUBLIC_URL_REGEX)];
2379+
2380+
if (gsMatches.length > 0) {
2381+
const bucket = new Bucket(storageInstance, gsMatches[0][1]);
2382+
return new File(bucket, gsMatches[0][2], options);
2383+
} else if (httpsMatches.length > 0) {
2384+
const bucket = new Bucket(storageInstance, httpsMatches[0][2]);
2385+
return new File(bucket, httpsMatches[0][3], options);
2386+
} else {
2387+
throw new Error(
2388+
'URL string must be of format gs://bucket/file or https://storage.googleapis.com/bucket/file'
2389+
);
2390+
}
2391+
}
2392+
23612393
get(options?: GetFileOptions): Promise<GetResponse<File>>;
23622394
get(callback: InstanceResponseCallback<File>): void;
23632395
get(options: GetFileOptions, callback: InstanceResponseCallback<File>): void;

test/file.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5168,4 +5168,49 @@ describe('File', () => {
51685168
file.setUserProject(userProject);
51695169
});
51705170
});
5171+
5172+
describe('from', () => {
5173+
it('should create a File object from a gs:// formatted URL', () => {
5174+
const gsUrl = 'gs://mybucket/myfile';
5175+
const result = File.from(gsUrl, STORAGE);
5176+
5177+
assert(result);
5178+
assert(result.bucket.name, 'mybucket');
5179+
assert(result.name, 'myfile');
5180+
});
5181+
5182+
it('should create a File object from a gs:// formatted URL including a folder', () => {
5183+
const gsUrl = 'gs://mybucket/myfolder/myfile';
5184+
const result = File.from(gsUrl, STORAGE);
5185+
5186+
assert(result);
5187+
assert(result.bucket.name, 'mybucket');
5188+
assert(result.name, 'myfolder/myfile');
5189+
});
5190+
5191+
it('should create a File object from a https:// formatted URL', () => {
5192+
const httpsUrl = 'https://storage.googleapis.com/mybucket/myfile';
5193+
const result = File.from(httpsUrl, STORAGE);
5194+
5195+
assert(result);
5196+
assert(result.bucket.name, 'mybucket');
5197+
assert(result.name, 'myfile');
5198+
});
5199+
5200+
it('should create a File object from a https:// formatted URL including a folder', () => {
5201+
const httpsUrl =
5202+
'https://storage.googleapis.com/mybucket/myfolder/myfile';
5203+
const result = File.from(httpsUrl, STORAGE);
5204+
5205+
assert(result);
5206+
assert(result.bucket.name, 'mybucket');
5207+
assert(result.name, 'myfolder/myfile');
5208+
});
5209+
5210+
it('should throw an error when invoked with an incorrectly formatted URL', () => {
5211+
const invalidUrl = 'https://storage.com/mybucket/myfile';
5212+
5213+
assert.throws(() => File.from(invalidUrl, STORAGE));
5214+
});
5215+
});
51715216
});

0 commit comments

Comments
 (0)