From 8aa07af098e38f9f1d79658cd0b31b9f49e0b9d3 Mon Sep 17 00:00:00 2001 From: "alex.saiannyi" Date: Tue, 5 Jul 2022 10:53:02 +0300 Subject: [PATCH] fix(storefront): bctheme-1145 enable using external lib for templates under organization --- CHANGELOG.md | 2 ++ lib/stencil-bundle.js | 12 ++++++++-- lib/stencil-bundle.spec.js | 24 +++++++++++++++++++ lib/template-assembler.js | 13 ++++++++-- .../component-with-external-template/a.html | 3 +++ .../component-with-external-template/b.html | 3 +++ 6 files changed, 53 insertions(+), 4 deletions(-) create mode 100644 test/_mocks/themes/component-with-external-template/a.html create mode 100644 test/_mocks/themes/component-with-external-template/b.html diff --git a/CHANGELOG.md b/CHANGELOG.md index ed45e9d4..0a220388 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ### Draft +- fix: bctheme-1145 Enable using of external lib nested into organization for templates ([954](https://github.com/bigcommerce/stencil-cli/pull/954)) + ### 5.0.0 (2022-06-07) - fix: STRF-9835 Bump paper ([947](https://github.com/bigcommerce/stencil-cli/pull/947)) diff --git a/lib/stencil-bundle.js b/lib/stencil-bundle.js index c1417dc9..ad08c3d0 100644 --- a/lib/stencil-bundle.js +++ b/lib/stencil-bundle.js @@ -163,12 +163,20 @@ class Bundle { */ async _getExternalLibs(templatePath) { const content = await fs.promises.readFile(templatePath, { encoding: 'utf-8' }); - const externalPathRegex = /{{2}>\s*(external)[^{]*?}{2}/g; + const externalPathRegex = /{{2}>\s*(['"]external)[^{]*?}{2}/g; const externalTemplatesImports = content.match(externalPathRegex); if (!externalTemplatesImports) return []; - return externalTemplatesImports.map((templateImport) => templateImport.split('/')[1]); + return externalTemplatesImports.map((templateImport) => { + const [, importPath] = templateAssembler.partialRegex.exec(templateImport); + + templateAssembler.partialRegex.lastIndex = 0; + + return importPath + .split('/templates/')[0] + .slice(templateAssembler.packageMarker.length + 1); + }); } async assembleTemplatesTask(callback) { diff --git a/lib/stencil-bundle.spec.js b/lib/stencil-bundle.spec.js index c56bfa17..f8b033e5 100644 --- a/lib/stencil-bundle.spec.js +++ b/lib/stencil-bundle.spec.js @@ -142,4 +142,28 @@ describe('Stencil Bundle', () => { expect(fs.writeFile).toHaveBeenCalledTimes(0); }); + + it('should return array with external library names', async () => { + const componentPathA = path.resolve( + process.cwd(), + 'test/_mocks/themes/component-with-external-template/a.html', + ); + const componentPathB = path.resolve( + process.cwd(), + 'test/_mocks/themes/component-with-external-template/b.html', + ); + const externalLib = 'theme-ui-components'; + const scopedExternalLib = '@bigcommerce/theme-ui-components'; + let mockLib; + + // eslint-disable-next-line no-underscore-dangle + mockLib = await bundle._getExternalLibs(componentPathB); + + expect(mockLib).toContain(externalLib); + + // eslint-disable-next-line no-underscore-dangle + mockLib = await bundle._getExternalLibs(componentPathA); + + expect(mockLib).toContain(scopedExternalLib); + }); }); diff --git a/lib/template-assembler.js b/lib/template-assembler.js index 626c96ec..1681febb 100644 --- a/lib/template-assembler.js +++ b/lib/template-assembler.js @@ -4,9 +4,10 @@ const fs = require('graceful-fs'); const path = require('path'); const upath = require('upath'); -const partialRegex = /\{\{>\s*([_|\-|a-zA-Z0-9/]+)[^{]*?}}/g; +const partialRegex = /\{\{>\s*([_|\-|a-zA-Z0-9@'"/]+)[^{]*?}}/g; const dynamicComponentRegex = /\{\{\s*?dynamicComponent\s*(?:'|")([_|\-|a-zA-Z0-9/]+)(?:'|").*?}}/g; const includeRegex = /{{2}>\s*([_|\-|a-zA-Z0-9/]+)[^{]*?}{2}/g; +const pathStringRegex = /^["'].+["']$/; const packageMarker = 'external/'; /** @@ -28,6 +29,12 @@ const replacePartialNames = (content, partialRoute) => { (__, partialName) => `{{> ${defineBaseRoute(partialRoute)}/${partialName} }}`, ); }; +const trimPartial = (partial) => { + if (pathStringRegex.test(partial)) { + return partial.slice(1, -1); + } + return partial; +}; /** * Takes a templates folder and template name. It returns simple path for custom template if it's available @@ -127,7 +134,8 @@ function getTemplatePaths(templatesFolder, templates, options, callback) { return callback(null, templatePaths); }); - function resolvePartials(templateName, cb2) { + function resolvePartials(t, cb2) { + const templateName = trimPartial(t); const templatePath = getCustomPath(templatesFolder, templateName); fs.readFile(templatePath, { encoding: 'utf-8' }, (err, content) => { @@ -253,6 +261,7 @@ function getTemplateContentSync(templatesFolder, templateFile) { } module.exports = { + packageMarker, partialRegex, dynamicComponentRegex, assemble, diff --git a/test/_mocks/themes/component-with-external-template/a.html b/test/_mocks/themes/component-with-external-template/a.html new file mode 100644 index 00000000..020dc7ee --- /dev/null +++ b/test/_mocks/themes/component-with-external-template/a.html @@ -0,0 +1,3 @@ +a + +{{> "external/@bigcommerce/theme-ui-components/templates/button"}} diff --git a/test/_mocks/themes/component-with-external-template/b.html b/test/_mocks/themes/component-with-external-template/b.html new file mode 100644 index 00000000..824706d8 --- /dev/null +++ b/test/_mocks/themes/component-with-external-template/b.html @@ -0,0 +1,3 @@ +b + +{{> "external/theme-ui-components/templates/button"}}