diff --git a/.changeset/young-guests-deliver.md b/.changeset/young-guests-deliver.md new file mode 100644 index 00000000..8576d4b6 --- /dev/null +++ b/.changeset/young-guests-deliver.md @@ -0,0 +1,5 @@ +--- +"10up-toolkit": patch +--- + +Fix: transform file extension for .ts and .tsx assets inside block.json files diff --git a/packages/toolkit/config/webpack/plugins.js b/packages/toolkit/config/webpack/plugins.js index 1d00c6ee..4ea7c0cd 100644 --- a/packages/toolkit/config/webpack/plugins.js +++ b/packages/toolkit/config/webpack/plugins.js @@ -19,7 +19,7 @@ const { fromConfigRoot, hasProjectFile, getArgFromCLI, - maybeInsertStyleVersionHash, + transformBlockJson, } = require('../../utils'); const { isPackageInstalled } = require('../../utils/package'); @@ -164,7 +164,7 @@ module.exports = ({ noErrorOnMissing: true, to: 'blocks/[path][name][ext]', transform: (content, absoluteFilename) => { - return maybeInsertStyleVersionHash(content, absoluteFilename); + return transformBlockJson(content, absoluteFilename); }, }, useBlockAssets && { diff --git a/packages/toolkit/utils/__tests__/blocks.js b/packages/toolkit/utils/__tests__/blocks.js index 9399f8fd..94c2fffa 100644 --- a/packages/toolkit/utils/__tests__/blocks.js +++ b/packages/toolkit/utils/__tests__/blocks.js @@ -1,5 +1,5 @@ import path from 'path'; -import { maybeInsertStyleVersionHash } from '../blocks'; +import { transformBlockJson } from '../blocks'; import { getFileContentHash as getFileContentHashMock } from '../file'; jest.mock('../file', () => { @@ -10,61 +10,65 @@ jest.mock('../file', () => { return module; }); -describe('maybeInsertStyleVersionHash', () => { +describe('transformBlockJson', () => { const absoluteteFileName = path.join('dist', 'blocks', 'block.json'); it('does nothing if version is set', () => { expect( - maybeInsertStyleVersionHash( + transformBlockJson( JSON.stringify({ version: 1, style: 'file:./style.css', }), absoluteteFileName, ), - ).toEqual(JSON.stringify({ version: 1, style: 'file:./style.css' })); + ).toEqual(JSON.stringify({ version: 1, style: 'file:./style.css' }, null, 2)); }); it('does nothing if style is not set', () => { expect( - maybeInsertStyleVersionHash( + transformBlockJson( JSON.stringify({ script: 'file:./script.js', }), absoluteteFileName, ), ).toEqual( - JSON.stringify({ - script: 'file:./script.js', - }), + JSON.stringify( + { + script: 'file:./script.js', + }, + null, + 2, + ), ); }); it('does nothing if style does not start with file:', () => { expect( - maybeInsertStyleVersionHash( + transformBlockJson( JSON.stringify({ style: 'style.css', }), absoluteteFileName, ), - ).toEqual(JSON.stringify({ style: 'style.css' })); + ).toEqual(JSON.stringify({ style: 'style.css' }, null, 2)); expect( - maybeInsertStyleVersionHash( + transformBlockJson( JSON.stringify({ style: ['another-css', 'style.css'], }), absoluteteFileName, ), - ).toEqual(JSON.stringify({ style: ['another-css', 'style.css'] })); + ).toEqual(JSON.stringify({ style: ['another-css', 'style.css'] }, null, 2)); }); it('adds version if style are set but version is not', () => { getFileContentHashMock.mockReturnValue('12345678'); expect( - maybeInsertStyleVersionHash( + transformBlockJson( JSON.stringify({ style: 'file:./style.css', }), @@ -86,7 +90,7 @@ describe('maybeInsertStyleVersionHash', () => { ); expect( - maybeInsertStyleVersionHash( + transformBlockJson( JSON.stringify({ style: ['another-style', 'file:./style2.css'], }), @@ -107,4 +111,55 @@ describe('maybeInsertStyleVersionHash', () => { path.join('dist', 'blocks', 'style2.css'), ); }); + + it('transforms ts and tsx to js', () => { + expect( + transformBlockJson( + JSON.stringify({ + script: 'file:./script.ts', + editorScript: 'file:./editor.tsx', + viewScript: 'file:./view.ts', + viewScriptModule: 'file:./view.tsx', + scriptModule: 'file:./script.tsx', + }), + absoluteteFileName, + ), + ).toEqual( + JSON.stringify( + { + script: 'file:./script.js', + editorScript: 'file:./editor.js', + viewScript: 'file:./view.js', + viewScriptModule: 'file:./view.js', + scriptModule: 'file:./script.js', + }, + null, + 2, + ), + ); + expect( + transformBlockJson( + JSON.stringify({ + script: ['file:./script.ts', 'file:./script.tsx'], + editorScript: ['file:./editor.ts', 'file:./editor.tsx'], + viewScript: ['file:./view.ts', 'file:./view.tsx'], + viewScriptModule: ['file:./view.tsx', 'file:./view.ts'], + scriptModule: ['file:./script.ts', 'file:./script.tsx'], + }), + absoluteteFileName, + ), + ).toEqual( + JSON.stringify( + { + script: ['file:./script.js', 'file:./script.js'], + editorScript: ['file:./editor.js', 'file:./editor.js'], + viewScript: ['file:./view.js', 'file:./view.js'], + viewScriptModule: ['file:./view.js', 'file:./view.js'], + scriptModule: ['file:./script.js', 'file:./script.js'], + }, + null, + 2, + ), + ); + }); }); diff --git a/packages/toolkit/utils/blocks.js b/packages/toolkit/utils/blocks.js index 6a35677a..55395a7d 100644 --- a/packages/toolkit/utils/blocks.js +++ b/packages/toolkit/utils/blocks.js @@ -1,7 +1,33 @@ const path = require('path'); const { getFileContentHash } = require('./file'); -const maybeInsertStyleVersionHash = (content, absoluteFilename) => { +const JS_ASSET_KEYS = ['script', 'editorScript', 'viewScript', 'viewScriptModule', 'scriptModule']; + +/** + * Transform the asset path from `.ts or .tsx` to `.js` + * + * When a block.json file has a script or style property that points to a `.ts or .tsx` file, + * this function will transform the path to point to the `.js` file instead. + * + * @param {string|Array} asset - The asset path to transform + * @returns {string|Array} + */ +function transformTSAsset(asset) { + function replaceExtension(filePath) { + const isFilePath = filePath.startsWith('file:'); + if (!isFilePath) { + return filePath; + } + + // replace the `.ts or .tsx` extension with `.js` + const jsPath = filePath.replace(/\.tsx?$/, '.js'); + return jsPath; + } + + return Array.isArray(asset) ? asset.map(replaceExtension) : replaceExtension(asset); +} + +const transformBlockJson = (content, absoluteFilename) => { const rawMetadata = content.toString(); if (rawMetadata === '') { return content; @@ -15,31 +41,36 @@ const maybeInsertStyleVersionHash = (content, absoluteFilename) => { const isFilePath = styleArray?.some((styleName) => styleName?.startsWith('file:')); const hasVersion = version !== undefined; - if (hasVersion || !isFilePath) { - return content; - } - const absoluteDirectory = absoluteFilename.replace(/block\.json$/, ''); let styleFileContentHash = ''; - styleArray.forEach((rawStylePath) => { - if (!rawStylePath.startsWith('file:')) { - return; + if (!hasVersion && isFilePath) { + styleArray.forEach((rawStylePath) => { + if (!rawStylePath.startsWith('file:')) { + return; + } + const stylePath = rawStylePath.replace('file:', ''); + const absoluteStylePath = path.join(absoluteDirectory, stylePath); + styleFileContentHash += getFileContentHash(absoluteStylePath); + }); + } + + const newMetadata = { + ...metadata, + }; + + if (!hasVersion && styleFileContentHash) { + newMetadata.version = styleFileContentHash; + } + + JS_ASSET_KEYS.forEach((key) => { + if (metadata[key]) { + newMetadata[key] = transformTSAsset(metadata[key]); } - const stylePath = rawStylePath.replace('file:', ''); - const absoluteStylePath = path.join(absoluteDirectory, stylePath); - styleFileContentHash += getFileContentHash(absoluteStylePath); }); - return JSON.stringify( - { - ...metadata, - version: styleFileContentHash, - }, - null, - 2, - ); + return JSON.stringify(newMetadata, null, 2); }; -module.exports = { maybeInsertStyleVersionHash }; +module.exports = { transformBlockJson }; diff --git a/packages/toolkit/utils/index.js b/packages/toolkit/utils/index.js index 71ffbafd..2e985415 100644 --- a/packages/toolkit/utils/index.js +++ b/packages/toolkit/utils/index.js @@ -32,7 +32,7 @@ const { hasPackageProp, getPackagePath, getPackage, getPackageVersion } = requir const { displayWebpackStats } = require('./webpack'); -const { maybeInsertStyleVersionHash } = require('./blocks'); +const { transformBlockJson } = require('./blocks'); const { getProjectRoot, @@ -79,6 +79,6 @@ module.exports = { getTenUpScriptsPackageBuildConfig, hasWebpackConfig, displayWebpackStats, + transformBlockJson, getGitBranch, - maybeInsertStyleVersionHash, };