From 6e5f3780664614a65094dc3495198178bbc73ecc Mon Sep 17 00:00:00 2001 From: Utsav Patel Date: Fri, 14 Jun 2024 11:47:53 +0530 Subject: [PATCH 1/7] chore: converted blob index to ts --- packages/blob/src/{index.js => index.ts} | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) rename packages/blob/src/{index.js => index.ts} (82%) diff --git a/packages/blob/src/index.js b/packages/blob/src/index.ts similarity index 82% rename from packages/blob/src/index.js rename to packages/blob/src/index.ts index 2493f81fc4c65b..ad75c18cf94101 100644 --- a/packages/blob/src/index.js +++ b/packages/blob/src/index.ts @@ -1,7 +1,6 @@ -/** - * @type {Record} - */ -const cache = {}; +type BlobPart = BufferSource | Blob | string; + +const cache: Record< string, File > = {}; /** * Create a blob URL from a file. @@ -10,7 +9,7 @@ const cache = {}; * * @return {string} The blob URL. */ -export function createBlobURL( file ) { +export function createBlobURL( file: File ): string { const url = window.URL.createObjectURL( file ); cache[ url ] = file; @@ -27,7 +26,7 @@ export function createBlobURL( file ) { * * @return {File|undefined} The file for the blob URL. */ -export function getBlobByURL( url ) { +export function getBlobByURL( url: string ): File | undefined { return cache[ url ]; } @@ -40,7 +39,7 @@ export function getBlobByURL( url ) { * * @return {string|undefined} The blob type. */ -export function getBlobTypeByURL( url ) { +export function getBlobTypeByURL( url: string ): string | undefined { return getBlobByURL( url )?.type.split( '/' )[ 0 ]; // 0: media type , 1: file extension eg ( type: 'image/jpeg' ). } @@ -49,7 +48,7 @@ export function getBlobTypeByURL( url ) { * * @param {string} url The blob URL. */ -export function revokeBlobURL( url ) { +export function revokeBlobURL( url: string ): void { if ( cache[ url ] ) { window.URL.revokeObjectURL( url ); } @@ -64,7 +63,7 @@ export function revokeBlobURL( url ) { * * @return {boolean} Is the url a blob url? */ -export function isBlobURL( url ) { +export function isBlobURL( url: string | undefined ): boolean { if ( ! url || ! url.indexOf ) { return false; } @@ -94,7 +93,11 @@ export function isBlobURL( url ) { * @param {BlobPart} content File content (BufferSource | Blob | string). * @param {string} contentType (Optional) File mime type. Default is `''`. */ -export function downloadBlob( filename, content, contentType = '' ) { +export function downloadBlob( + filename: string, + content: BlobPart, + contentType: string = '' +): void { if ( ! filename || ! content ) { return; } From cafc0560ca449fb16962b76d753d393526bc2fe4 Mon Sep 17 00:00:00 2001 From: Utsav Patel Date: Fri, 14 Jun 2024 11:48:29 +0530 Subject: [PATCH 2/7] chore: converted test to ts --- packages/blob/src/test/{index.js => index.ts} | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) rename packages/blob/src/test/{index.js => index.ts} (85%) diff --git a/packages/blob/src/test/index.js b/packages/blob/src/test/index.ts similarity index 85% rename from packages/blob/src/test/index.js rename to packages/blob/src/test/index.ts index 47dcb5019ee25e..04ba9700ce5b78 100644 --- a/packages/blob/src/test/index.js +++ b/packages/blob/src/test/index.ts @@ -1,7 +1,7 @@ /** * Internal dependencies */ -import { isBlobURL, getBlobTypeByURL, downloadBlob } from '../'; +import { isBlobURL, getBlobTypeByURL, downloadBlob } from '..'; describe( 'isBlobURL', () => { it( 'returns true if the url starts with "blob:"', () => { @@ -13,6 +13,8 @@ describe( 'isBlobURL', () => { } ); it( 'returns false if the url is not defined', () => { + // calling isBlobURL without a URL is not type compliant, so ignore it + // @ts-ignore expect( isBlobURL() ).toBe( false ); } ); } ); @@ -23,6 +25,8 @@ describe( 'getBlobTypeByURL', () => { } ); it( 'returns undefined if the url is not defined', () => { + // calling getBlobTypeByURL without a URL is not type compliant, so ignore it + // @ts-ignore expect( getBlobTypeByURL() ).toBe( undefined ); } ); } ); @@ -36,17 +40,18 @@ describe( 'downloadBlob', () => { const createElementSpy = jest .spyOn( global.document, 'createElement' ) .mockReturnValue( mockAnchorElement ); + const mockBlob = jest.fn(); - const blobSpy = jest.spyOn( window, 'Blob' ).mockReturnValue( mockBlob ); + const blobSpy = jest + .spyOn( window, 'Blob' ) + .mockReturnValue( mockBlob as unknown as Blob ); jest.spyOn( document.body, 'appendChild' ); jest.spyOn( document.body, 'removeChild' ); beforeEach( () => { // Can't seem to spy on these static methods. They are `undefined`. // Possibly overwritten: https://github.com/WordPress/gutenberg/blob/trunk/packages/jest-preset-default/scripts/setup-globals.js#L5 - window.URL = { - createObjectURL, - revokeObjectURL, - }; + window.URL.createObjectURL = createObjectURL; + window.URL.revokeObjectURL = revokeObjectURL; } ); afterAll( () => { From 5da8e339ec1e79e436a19a1f55844e1911fe060c Mon Sep 17 00:00:00 2001 From: Utsav Patel Date: Fri, 14 Jun 2024 15:19:30 +0530 Subject: [PATCH 3/7] Fix: remove all param types --- packages/blob/src/index.ts | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/blob/src/index.ts b/packages/blob/src/index.ts index ad75c18cf94101..62a6671db61544 100644 --- a/packages/blob/src/index.ts +++ b/packages/blob/src/index.ts @@ -1,13 +1,11 @@ -type BlobPart = BufferSource | Blob | string; - const cache: Record< string, File > = {}; /** * Create a blob URL from a file. * - * @param {File} file The file to create a blob URL for. + * @param file The file to create a blob URL for. * - * @return {string} The blob URL. + * @return The blob URL. */ export function createBlobURL( file: File ): string { const url = window.URL.createObjectURL( file ); @@ -22,9 +20,9 @@ export function createBlobURL( file: File ): string { * `createBlobURL` and not removed by `revokeBlobURL`, otherwise it will return * `undefined`. * - * @param {string} url The blob URL. + * @param url The blob URL. * - * @return {File|undefined} The file for the blob URL. + * @return The file for the blob URL. */ export function getBlobByURL( url: string ): File | undefined { return cache[ url ]; @@ -35,9 +33,9 @@ export function getBlobByURL( url: string ): File | undefined { * `createBlobURL` and not removed by `revokeBlobURL`, otherwise it will return * `undefined`. * - * @param {string} url The blob URL. + * @param url The blob URL. * - * @return {string|undefined} The blob type. + * @return The blob type. */ export function getBlobTypeByURL( url: string ): string | undefined { return getBlobByURL( url )?.type.split( '/' )[ 0 ]; // 0: media type , 1: file extension eg ( type: 'image/jpeg' ). @@ -46,7 +44,7 @@ export function getBlobTypeByURL( url: string ): string | undefined { /** * Remove the resource and file cache from memory. * - * @param {string} url The blob URL. + * @param url The blob URL. */ export function revokeBlobURL( url: string ): void { if ( cache[ url ] ) { @@ -59,9 +57,9 @@ export function revokeBlobURL( url: string ): void { /** * Check whether a url is a blob url. * - * @param {string|undefined} url The URL. + * @param url The URL. * - * @return {boolean} Is the url a blob url? + * @return Is the url a blob url? */ export function isBlobURL( url: string | undefined ): boolean { if ( ! url || ! url.indexOf ) { @@ -89,9 +87,9 @@ export function isBlobURL( url: string | undefined ): boolean { * downloadBlob( filename, fileContent, 'application/json' ); * ``` * - * @param {string} filename File name. - * @param {BlobPart} content File content (BufferSource | Blob | string). - * @param {string} contentType (Optional) File mime type. Default is `''`. + * @param filename File name. + * @param content File content (BufferSource | Blob | string). + * @param contentType (Optional) File mime type. Default is `''`. */ export function downloadBlob( filename: string, From d19fcf1278925defb1adce6624f70767742ae592 Mon Sep 17 00:00:00 2001 From: Utsav Patel Date: Fri, 14 Jun 2024 15:20:16 +0530 Subject: [PATCH 4/7] updated: build readme for some types which is adding extra spacing --- packages/blob/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/blob/README.md b/packages/blob/README.md index 64520a98bd6a79..d315cdab5e4a48 100644 --- a/packages/blob/README.md +++ b/packages/blob/README.md @@ -61,7 +61,7 @@ _Parameters_ _Returns_ -- `File|undefined`: The file for the blob URL. +- `File | undefined`: The file for the blob URL. ### getBlobTypeByURL @@ -73,7 +73,7 @@ _Parameters_ _Returns_ -- `string|undefined`: The blob type. +- `string | undefined`: The blob type. ### isBlobURL @@ -81,7 +81,7 @@ Check whether a url is a blob url. _Parameters_ -- _url_ `string|undefined`: The URL. +- _url_ `string | undefined`: The URL. _Returns_ From 77fb562b57884b6483e701e61cae930a91f6f468 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 14 Jun 2024 14:37:48 +0200 Subject: [PATCH 5/7] Improve tests Use ts-expect-error over ts-ignore Use toBeUndefined over toBe( undefined ) --- packages/blob/src/test/index.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/blob/src/test/index.ts b/packages/blob/src/test/index.ts index 04ba9700ce5b78..605d850d403772 100644 --- a/packages/blob/src/test/index.ts +++ b/packages/blob/src/test/index.ts @@ -13,21 +13,23 @@ describe( 'isBlobURL', () => { } ); it( 'returns false if the url is not defined', () => { - // calling isBlobURL without a URL is not type compliant, so ignore it - // @ts-ignore - expect( isBlobURL() ).toBe( false ); + expect( + // @ts-expect-error This is not a valid call according to types. + isBlobURL() + ).toBe( false ); } ); } ); describe( 'getBlobTypeByURL', () => { it( 'returns undefined if the blob is not found', () => { - expect( getBlobTypeByURL( 'blob:notexisting' ) ).toBe( undefined ); + expect( getBlobTypeByURL( 'blob:notexisting' ) ).toBeUndefined(); } ); it( 'returns undefined if the url is not defined', () => { - // calling getBlobTypeByURL without a URL is not type compliant, so ignore it - // @ts-ignore - expect( getBlobTypeByURL() ).toBe( undefined ); + expect( + // @ts-expect-error This is not a valid call according to types. + getBlobTypeByURL() + ).toBeUndefined(); } ); } ); From 1510e228a5f63fd42d04a797fee1d4d9d49399b5 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 14 Jun 2024 14:51:13 +0200 Subject: [PATCH 6/7] Add changelog --- packages/blob/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/blob/CHANGELOG.md b/packages/blob/CHANGELOG.md index 50b6143dfb3e6c..51fc2b54f9fa26 100644 --- a/packages/blob/CHANGELOG.md +++ b/packages/blob/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Internal + +- Refactor to TypeScript ([#62569](https://github.com/WordPress/gutenberg/pull/62569)). + ## 4.0.0 (2024-05-31) ### Breaking Changes From 45620990057c282349eec0323ac03701eb1182a2 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Fri, 14 Jun 2024 14:57:26 +0200 Subject: [PATCH 7/7] Revert change in behavior --- packages/blob/src/test/index.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/blob/src/test/index.ts b/packages/blob/src/test/index.ts index 605d850d403772..381b04fd817a6b 100644 --- a/packages/blob/src/test/index.ts +++ b/packages/blob/src/test/index.ts @@ -52,8 +52,11 @@ describe( 'downloadBlob', () => { beforeEach( () => { // Can't seem to spy on these static methods. They are `undefined`. // Possibly overwritten: https://github.com/WordPress/gutenberg/blob/trunk/packages/jest-preset-default/scripts/setup-globals.js#L5 - window.URL.createObjectURL = createObjectURL; - window.URL.revokeObjectURL = revokeObjectURL; + // @ts-expect-error This is not a valid URL object. + window.URL = { + createObjectURL, + revokeObjectURL, + }; } ); afterAll( () => {