From 803f44d73206064ebc72b261a7c9db5d6ef057bc Mon Sep 17 00:00:00 2001 From: Ben Moroze Date: Thu, 13 Oct 2022 16:55:04 -0400 Subject: [PATCH] Release 13.1.0 --- README.md | 4 +- RELEASENOTES.md | 2 +- lib/addtypescript.js | 2 +- lib/addwebpack.js | 1 + lib/buildCommon/copyLocalComponent.js | 66 +++++++ lib/buildCommon/stripLocalComponentJson.js | 207 +++++++++++++++++---- lib/indexHtmlInjector.js | 11 +- lib/injectorUtil.js | 5 +- lib/svg.js | 17 +- lib/templates/pack/component.json | 2 +- lib/util.js | 5 +- lib/webpack/utils.js | 9 +- lib/webpack/webpack.common.js | 4 + package.json | 4 +- 14 files changed, 283 insertions(+), 56 deletions(-) diff --git a/README.md b/README.md index f4bce1f..18200e5 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# @oracle/oraclejet-tooling 13.0.0 +# @oracle/oraclejet-tooling 13.1.0 ## About the tooling API This tooling API contains methods to build and serve Oracle JET web and hybrid mobile apps. It is intended to be used with task running tools such as grunt or gulp. The APIs can also be invoked directly. @@ -6,7 +6,7 @@ This tooling API contains methods to build and serve Oracle JET web and hybrid m This is an open source project maintained by Oracle Corp. ## Installation -This module will be automatically installed when you scaffold a web or hybrid mobile app following the [Oracle JET Developers Guide](http://www.oracle.com/pls/topic/lookup?ctx=jet1300&id=homepage). +This module will be automatically installed when you scaffold a web or hybrid mobile app following the [Oracle JET Developers Guide](http://www.oracle.com/pls/topic/lookup?ctx=jet1310&id=homepage). ## [Contributing](https://github.com/oracle/oraclejet-tooling/blob/master/CONTRIBUTING.md) Oracle JET is an open source project. Pull Requests are currently not being accepted. See diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 95e8cd0..79638ed 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -1,6 +1,6 @@ ## Release Notes for oraclejet-tooling ## -### 13.0.0 +### 13.1.0 ### 11.0.0 * oraclejet-tooling now requires node 12.21 or later diff --git a/lib/addtypescript.js b/lib/addtypescript.js index eda6551..a73bb83 100644 --- a/lib/addtypescript.js +++ b/lib/addtypescript.js @@ -35,7 +35,7 @@ function installTypescipt(options) { util.log('Installing Typescript'); const installer = util.getInstallerCommand({ options }); - const command = `${installer.installer} ${installer.verbs.install} typescript@${CONSTANTS.TYPESCRIPT_VERSION} ts-creator@~1.2.5 yargs-parser@~13.1.2 --save-dev --save-exact`; + const command = `${installer.installer} ${installer.verbs.install} typescript@${CONSTANTS.TYPESCRIPT_VERSION} yargs-parser@~13.1.2 --save-dev --save-exact`; return util.exec(command); } diff --git a/lib/addwebpack.js b/lib/addwebpack.js index bcfac2b..6d91c24 100644 --- a/lib/addwebpack.js +++ b/lib/addwebpack.js @@ -36,6 +36,7 @@ function installWebpack(options) { const command = ` ${installer.installer} ${installer.verbs.install} webpack@${CONSTANTS.WEBPACK_VERSION} + @types/node@18.8.3 webpack-dev-server style-loader css-loader diff --git a/lib/buildCommon/copyLocalComponent.js b/lib/buildCommon/copyLocalComponent.js index f4a8297..4d4b855 100644 --- a/lib/buildCommon/copyLocalComponent.js +++ b/lib/buildCommon/copyLocalComponent.js @@ -211,6 +211,7 @@ class ComponentStager { fs.removeSync(destPath); util.ensureDir(destPath); fs.copySync(srcPath, destPath, { dereference: true }); + generateRootIndexFile(srcPath, destPath); } stageComponentToReleaseLocation() { const { srcPath, destPathRelease } = this; @@ -219,6 +220,7 @@ class ComponentStager { const resourcesPath = path.join(srcPath, 'resources'); if (util.fsExistsSync(resourcesPath)) { fs.copySync(resourcesPath, path.join(destPathRelease, 'resources'), { dereference: true }); + generateRootIndexFile(srcPath, destPathRelease); } const cssFiles = glob.sync('**/*.css', { cwd: srcPath }); cssFiles.forEach((cssFilePath) => { @@ -299,4 +301,68 @@ function generateComponentStager({ context, componentJson, srcPath, destPath }) return new ComponentStager({ context, srcPath, destPath }); } +/** + * ## generateRootIndexFile + * + * Generate an root index file under the web/../resources/nls folder: + * + * @param {string} options.destPath + */ +function generateRootIndexFile(srcPath, destPath) { + const pathToNlsFolder = path.join(destPath, 'resources', 'nls'); + const pathToNlsRootFolder = path.join(pathToNlsFolder, 'root'); + const pathToNlsRootFolderInSrc = path.join(srcPath, 'resources', 'nls', 'root'); + // Get the array of contents under the nls/root folder, which is the string file: + util.getFiles(pathToNlsRootFolder).forEach((file) => { + const pathToComponentStringFile = path.join(pathToNlsFolder, 'root', file); + const pathToRootIndexFileInWeb = path.join(pathToNlsFolder, file); + const pathToRootIndexFileInSrc = path.join(srcPath, 'resources', 'nls', file); + if (fs.existsSync(pathToNlsRootFolderInSrc) && !(fs.existsSync(pathToRootIndexFileInSrc))) { + // eslint-disable-next-line max-len + const fileContent = getModifiedComponentStringFileContent(pathToComponentStringFile, pathToNlsFolder); + fs.writeFileSync(pathToRootIndexFileInWeb, fileContent); + // Delete the web/../nls/root/ folder as it is no londer needed: + if (fs.existsSync(pathToComponentStringFile)) { + fs.removeSync(pathToComponentStringFile); + } + // Delete the web/../nls/root folder if empty as it is no londer needed: + if (fs.readdirSync(pathToNlsRootFolder).length === 0) { + fs.removeSync(pathToNlsRootFolder); + } + } + }); +} + +/** + * ## getModifiedComponentStringFileContent + * + * Modifies the component string file content + * + * @param {string} pathToComponentStringFile + * @param {string} pathToNlsFolder + */ +function getModifiedComponentStringFileContent(pathToComponentStringFile, pathToNlsFolder) { + // eslint-disable-next-line max-len + const componentStringFileContent = fs.readFileSync(pathToComponentStringFile, { encoding: 'utf-8' }); + // The retrieved file content in the form: + // export = {componentName: {sampleString: 'Details...'}}. Therefore, the retrieved + // object content will be componentName: {sampleString: 'Details...'}. + const regex = /{(?.*)}/gms; + const match = regex.exec(componentStringFileContent); + // Modify the exported content to export = {root : {componentName: {sampleString: 'Details...'}}}. + let modifiedStringFileContent = `\n "root": {${match.groups.exportedObjectContent} },`; + // Go through the nls folder and check if there are any other languages chosen for translation. + // If there are any, add them as part of the exported object in the form: + // "": true. In the case German and French are the included languages, + // then the added items will be: "de":true, "fr":true. + const nlsFolderContents = fs.readdirSync(pathToNlsFolder); + nlsFolderContents.forEach((content) => { + const pathToNlsFolderContent = path.join(pathToNlsFolder, content); + if (content !== 'root' && fs.lstatSync(pathToNlsFolderContent).isDirectory()) { + modifiedStringFileContent = modifiedStringFileContent.concat(` \n "${content}": true,`); + } + }); + return componentStringFileContent.replace(`${match.groups.exportedObjectContent}`, `${modifiedStringFileContent}\n`); +} + module.exports = copyLocalComponent; diff --git a/lib/buildCommon/stripLocalComponentJson.js b/lib/buildCommon/stripLocalComponentJson.js index d07a67c..71f62ab 100644 --- a/lib/buildCommon/stripLocalComponentJson.js +++ b/lib/buildCommon/stripLocalComponentJson.js @@ -16,39 +16,37 @@ const CONSTANTS = require('../constants'); * Stripping implementation exported to buildCommon.js: */ function stripLocalComponentJson(context) { - return new Promise((resolve) => { - const componentsCache = util.getComponentsCache(); - util.getLocalCompositeComponents().forEach((_component) => { - let pathToComponentJSON; - let modifiedComponentJSON; - let jsonFileContent; - const { builtPath, componentJson } = componentsCache[_component]; - // Modify the component.json in staging by stripping the unwanted attributes and - // sub-properties during run-time. This stripped json file is then included in - // the web/../min/loader.js file. The original contents of the json file are restored in - // restoreLocalCcaComponentJson after minification. Also, if the passed component is a - // pack, we will need to iterate through its component dependencies. Failure to do so - // will result in having non-stripped metadata in the component's min/loader.js file: - if (util.isJETPack({ pack: _component, componentJson })) { - const dependenciesFromCache = Object.getOwnPropertyNames(componentJson.dependencies); - dependenciesFromCache.forEach((component) => { - const componentData = componentsCache[component]; - pathToComponentJSON = path.join(componentData.builtPath, CONSTANTS.JET_COMPONENT_JSON); - if (fs.readdirSync(componentData.builtPath).includes('loader.js')) { - jsonFileContent = fs.readJSONSync(pathToComponentJSON); - modifiedComponentJSON = getStrippedComponentJson(jsonFileContent); - fs.writeJsonSync(pathToComponentJSON, modifiedComponentJSON); - } - }); - } else { - pathToComponentJSON = path.join(builtPath, CONSTANTS.JET_COMPONENT_JSON); - jsonFileContent = fs.readJSONSync(pathToComponentJSON); - modifiedComponentJSON = getStrippedComponentJson(jsonFileContent); - fs.writeJsonSync(pathToComponentJSON, modifiedComponentJSON); - } - }); - resolve(context); + const componentsCache = util.getComponentsCache(); + util.getLocalCompositeComponents().forEach((_component) => { + let pathToComponentJSON; + let modifiedComponentJSON; + let jsonFileContent; + const { builtPath, componentJson } = componentsCache[_component]; + // Modify the component.json in staging by stripping the unwanted attributes and + // sub-properties during run-time. This stripped json file is then included in + // the web/../min/loader.js file. The original contents of the json file are restored in + // restoreLocalCcaComponentJson after minification. Also, if the passed component is a + // pack, we will need to iterate through its component dependencies. Failure to do so + // will result in having non-stripped metadata in the component's min/loader.js file: + if (util.isJETPack({ pack: _component, componentJson })) { + const dependenciesFromCache = Object.getOwnPropertyNames(componentJson.dependencies); + dependenciesFromCache.forEach((component) => { + const componentData = componentsCache[component]; + pathToComponentJSON = path.join(componentData.builtPath, CONSTANTS.JET_COMPONENT_JSON); + if (fs.readdirSync(componentData.builtPath).includes('loader.js')) { + jsonFileContent = fs.readJSONSync(pathToComponentJSON); + modifiedComponentJSON = getStrippedComponentJson(jsonFileContent); + fs.writeJsonSync(pathToComponentJSON, modifiedComponentJSON); + } + }); + } else { + pathToComponentJSON = path.join(builtPath, CONSTANTS.JET_COMPONENT_JSON); + jsonFileContent = fs.readJSONSync(pathToComponentJSON); + modifiedComponentJSON = getStrippedComponentJson(jsonFileContent); + fs.writeJsonSync(pathToComponentJSON, modifiedComponentJSON); + } }); + return Promise.resolve(context); } /** @@ -92,8 +90,12 @@ function deleteUnrequiredTopLevelAttributes(json, requiredAttributes) { if (attributes) { attributes.forEach((attribute) => { if (!requiredAttributes.has(attribute)) { - // eslint-disable-next-line no-param-reassign - delete json[attribute]; + if (attribute === 'extension') { + stripExtensionSubAttribute(json[attribute], json, attribute); + } else { + // eslint-disable-next-line no-param-reassign + delete json[attribute]; + } } }); } @@ -140,8 +142,7 @@ function stripTopLevelAttributes(componentJSON, requiredTopLevelAttributes) { const subAttributes = getAttributes(componentJSON[topLevelAttribute]); if (subAttributes) { subAttributes.forEach((subAttribute) => { - const subAttributeObject = componentJSON[topLevelAttribute][subAttribute]; - stripSubAttribute(subAttributeObject, componentJSON[topLevelAttribute], subAttribute); + stripSubAttributes(componentJSON[topLevelAttribute][subAttribute]); }); // Delete the resulting object if empty: if (isEmpty(componentJSON[topLevelAttribute])) { @@ -153,14 +154,28 @@ function stripTopLevelAttributes(componentJSON, requiredTopLevelAttributes) { }); } +/** + * + * @param {object} attributeObject + * + * Strip the sub-attributes from the top level componentJson + * properties. Go through the passed object recursively and + * remove the unrequired sub-attributes. + */ +function stripSubAttributes(attributeObject) { + const attributes = getAttributes(attributeObject); + attributes.forEach((attribute) => { + stripSubAttribute(attributeObject[attribute], attributeObject, attribute); + }); +} + /** * * @param {string} attributeName * @param {object} attributeObject * @param {object} subAttributeObject -- attributeObject[attributeName] - * @returns {Boolean} * - * Strip the sub-attributes. Go throught the passed object recursively and + * Strip the sub-attributes. Go through the passed object recursively and * remove the unrequired sub-attributes. */ function stripSubAttribute(subAttributeObject, attributeObject, attributeName) { @@ -169,10 +184,21 @@ function stripSubAttribute(subAttributeObject, attributeObject, attributeName) { delete attributeObject[attributeName]; return; } + + if (attributeName === 'extension') { + stripExtensionSubAttribute(subAttributeObject, attributeObject, attributeName); + if (isEmpty(subAttributeObject)) { + // eslint-disable-next-line no-param-reassign + delete attributeObject[attributeName]; + } + return; + } + const attributes = getAttributes(subAttributeObject); if (!attributes) { return; } + attributes.forEach((attribute) => { stripSubAttribute(subAttributeObject[attribute], subAttributeObject, attribute); }); @@ -195,7 +221,13 @@ function isNeededSubAttribute(subAttribute) { 'value', 'binding', 'writeback', - 'internalName' + 'internalName', + 'consume', + 'provide', + 'name', + 'default', + 'transform', + 'extension' ]); if (requiredSubAttributes.has(subAttribute)) { return true; @@ -203,6 +235,73 @@ function isNeededSubAttribute(subAttribute) { return false; } +/** + * + * @param {string} subAttribute + * @returns {Boolean} + * + * Checks if the passed attribute is a needed non-required sub-attribute. + */ +function isNeededExtensionSubAttribute(subAttribute) { + const nonRequiredSubAttributes = new Set([ + 'description', + 'displayName', + 'tags', + 'coverImage', + 'screenshots', + 'jet', + 'vbdt', + 'audits', + 'package', + 'docUrl', + 'itemProperties', + 'webelement', + 'readme', + 'unsupportedBrowsers', + 'businessApprovals', + 'uxSpecs', + 'unsupportedThemes', + 'defaultColumns', + 'minColumns', + 'itemProperties', + 'slotData', + 'exceptionStatus', + 'catalog', + 'oracle', + 'themes' + ]); + if (nonRequiredSubAttributes.has(subAttribute)) { + return false; + } + return true; +} + +/** + * + * @param {string} attributeName + * @param {object} attributeObject + * @param {object} subAttributeObject -- attributeObject[attributeName] + * + * Strip the extension sub-attributes. Go through the passed object recursively and + * remove the unrequired sub-attributes. + */ +function stripExtensionSubAttribute(subAttributeObject, attributeObject, attributeName) { + if (!isNeededExtensionSubAttribute(attributeName)) { + // eslint-disable-next-line no-param-reassign + delete attributeObject[attributeName]; + return; + } + const attributes = getAttributes(subAttributeObject); + if (!attributes) { + return; + } + + attributes.forEach((attribute) => { + stripExtensionSubAttribute(subAttributeObject[attribute], subAttributeObject, attribute); + }); + deleteExtensionSubAttribute(subAttributeObject, attributeObject, attributeName); +} + /** * * @param {string} parentAttributeName @@ -232,6 +331,36 @@ function deleteAttribute(childAttributeObject, parentAttributeObject, parentAttr } } +/** + * + * @param {string} parentAttributeName + * @param {object} parentAttributeObject + * @param {object} childAttributeObject -- parentAttributeObject[parentAttributeName] + * @returns {Boolean} + * + * Deletes the unrequired attribute at RT: + */ +// eslint-disable-next-line max-len +function deleteExtensionSubAttribute(childAttributeObject, parentAttributeObject, parentAttributeName) { + const attributes = getAttributes(childAttributeObject); + if (attributes) { + attributes.forEach((attribute) => { + if (!isNeededExtensionSubAttribute(attribute) && !isObject(childAttributeObject[attribute])) { + // eslint-disable-next-line no-param-reassign + delete childAttributeObject[attribute]; + } + if (isEmpty(childAttributeObject)) { + // eslint-disable-next-line no-param-reassign + delete parentAttributeObject[parentAttributeName]; + } + }); + if (isEmpty(childAttributeObject)) { + // eslint-disable-next-line no-param-reassign + delete parentAttributeObject[parentAttributeName]; + } + } +} + /** * * @param {object} json diff --git a/lib/indexHtmlInjector.js b/lib/indexHtmlInjector.js index 15a2a9b..f608740 100644 --- a/lib/indexHtmlInjector.js +++ b/lib/indexHtmlInjector.js @@ -242,12 +242,15 @@ function _createRequireScriptElementString(masterJson) { } else { scriptSrc = `${configPaths.src.javascript}/libs/require/require.js`; } - return injectorUtil.createScriptElementString(scriptSrc); + return injectorUtil.createScriptElementString(scriptSrc, null); } function _createCDNBundleScriptElementString(masterJson) { if (masterJson) { - return injectorUtil.createScriptElementString(`${masterJson.cdns.jet.prefix}/${masterJson.cdns.jet.config}`); + if (masterJson.cdns.jet.config && masterJson.cdns.jet.config.indexOf('bundles-config-esm') > -1) { + return injectorUtil.createScriptElementString(`${masterJson.cdns.jet.prefix}/${masterJson.cdns.jet.config}`, 'module'); + } + return injectorUtil.createScriptElementString(`${masterJson.cdns.jet.prefix}/${masterJson.cdns.jet.config}`, null); } return null; } @@ -255,12 +258,12 @@ function _createCDNBundleScriptElementString(masterJson) { function _createBundleScriptElementString() { const configPaths = util.getConfiguredPaths(); const bundleName = util.getBundleName().full; - return injectorUtil.createScriptElementString(`${configPaths.src.javascript}/${bundleName}`); + return injectorUtil.createScriptElementString(`${configPaths.src.javascript}/${bundleName}`, null); } function _createMainSscriptElementString() { const configPaths = util.getConfiguredPaths(); - return injectorUtil.createScriptElementString(`${configPaths.src.javascript}/main.js`); + return injectorUtil.createScriptElementString(`${configPaths.src.javascript}/main.js`, null); } function _replaceTokenWithScripts({ diff --git a/lib/injectorUtil.js b/lib/injectorUtil.js index 25ee913..c4b113b 100644 --- a/lib/injectorUtil.js +++ b/lib/injectorUtil.js @@ -57,6 +57,7 @@ function _replaceInjectorTokens({ content, pattern, replace, eol, startTag, endT return injectResult; } -function _createScriptElementString(scriptSrc) { - return ``; +function _createScriptElementString(scriptSrc, type) { + const scriptType = type === null ? 'text/javascript' : type; + return ``; } diff --git a/lib/svg.js b/lib/svg.js index e39af95..54d5598 100644 --- a/lib/svg.js +++ b/lib/svg.js @@ -28,7 +28,22 @@ function _svgMin(context) { fileResult.forEach((file) => { const src = util.readFileSync(file.src); const result = optimize(src, opts.options); - if (result.error) reject(result.error); + if (result.error) { + // The returned result object--which can be of type OptimizedError or + // OptimizedSvg--includes attributes error (with the error message) and + // modernError (giving more info about the error--plus the message--and + // other details like where the error is originated). Therefore, passing + // result.modernError is more ideal in this case after adding the file + // causing the error in its message + // Source: https://unpkg.com/browse/@types/svgo@2.6.3/index.d.ts#L724. + if (result.modernError) { + result.modernError.message = `${result.modernError.message} Error caused by file: ${file.src}`; + reject(result.modernError); + } else { + result.error = `${result.error} Error caused by file: ${file.src}`; + reject(result.error); + } + } fs.outputFileSync(path.resolve(file.dest), result.data); }); resolve(context); diff --git a/lib/templates/pack/component.json b/lib/templates/pack/component.json index 186aef1..12c9f68 100644 --- a/lib/templates/pack/component.json +++ b/lib/templates/pack/component.json @@ -1,7 +1,7 @@ { "name": "@pack@", "version": "1.0.0", - "jetVersion": "13.0.0", + "jetVersion": "13.1.0", "type": "pack", "displayName": "A user friendly, translatable name of the pack.", "description": "A translatable high-level description for the pack.", diff --git a/lib/util.js b/lib/util.js index fe66788..7434683 100644 --- a/lib/util.js +++ b/lib/util.js @@ -1031,9 +1031,12 @@ util.getInstallerCommand = ({ options }) => { installerCmd = _config('installer'); } - return installerCmd === 'yarn' ? { installer: 'yarn', verbs: { install: 'add' } } : { installer: 'npm', verbs: { install: 'install' } }; + const useCI = util.hasProperty(options, 'ci'); + const npmInstallCmd = useCI ? 'ci' : 'install'; + return installerCmd === 'yarn' ? { installer: 'yarn', verbs: { install: 'add' } } : { installer: 'npm', verbs: { install: npmInstallCmd } }; }; + /** * ## getOraclejetConfigJson * diff --git a/lib/webpack/utils.js b/lib/webpack/utils.js index 8c06137..5eac455 100644 --- a/lib/webpack/utils.js +++ b/lib/webpack/utils.js @@ -17,6 +17,7 @@ const localComponentsPath = path.resolve( configPaths.components ); const oracleJetDistPath = path.join(ojetUtils.getOraclejetPath(), 'dist'); +const oracleJetPreactThemePath = path.join(oracleJetDistPath, 'js', 'libs', 'oraclejet-preact', 'amd'); const oracleJetDistCssPath = path.join(oracleJetDistPath, 'css'); const oracleJetDistJsLibsPath = path.join(oracleJetDistPath, 'js/libs'); const pathToSrcHTML = path.resolve(configPaths.src.common, 'index.html'); @@ -28,6 +29,7 @@ const htmlEndInjectorTokenPattern = /()/g; const htmlTokenResources = { css: { redwood: `./${configPaths.src.styles}/redwood/oj-redwood-min.css`, + preact: `./${configPaths.src.styles}/theme-redwood/theme.css` }, injector: { theme: `./${configPaths.src.styles}/redwood/oj-redwood-min.css`, @@ -37,6 +39,7 @@ const htmlTokenTEmplates = { css: '', injector: '' }; +const preactThemePath = htmlTokenTEmplates.css.replace('%s', htmlTokenResources.css.preact); // eslint-disable-next-line no-unused-vars function htmlTokenReplacementFunction(match, $1, type, file, $4, index, input) { // those formal parameters could be: @@ -57,8 +60,10 @@ function htmlTokenReplacementFunction(match, $1, type, file, $4, index, input) { return ''; } const url = htmlTokenResources[type][file]; + // This ensures that preact link is injected into the index.html: + const themeStyleLinks = `${htmlTokenTEmplates[type].replace('%s', url)}\n\t\t${preactThemePath}`; // $1==='@@' <--EQ--> $4===undefined - return ($4 === undefined ? url : htmlTokenTEmplates[type].replace('%s', url)); + return ($4 === undefined ? url : themeStyleLinks); } function isWebComponent(resourcePath) { @@ -89,7 +94,6 @@ function modifySrcIndexHTML() { // Same link tag will be used for replacing the matched comment tags below. // The link is : const redwoodMinPath = htmlTokenReplacementFunction(undefined, undefined, 'css', 'redwood', '-->', undefined); - // Replace with link to redwood-min.css: // eslint-disable-next-line no-useless-escape const regexCSS = /()?/g; @@ -166,6 +170,7 @@ module.exports = { oracleJetDistPath, oracleJetDistCssPath, oracleJetDistJsLibsPath, + oracleJetPreactThemePath, htmlTokenPattern, htmlEndInjectorTokenPattern, htmlTokenReplacementFunction, diff --git a/lib/webpack/webpack.common.js b/lib/webpack/webpack.common.js index 9492390..0f0ad1f 100644 --- a/lib/webpack/webpack.common.js +++ b/lib/webpack/webpack.common.js @@ -135,6 +135,10 @@ module.exports = { 'common' ), to: path.resolve(configPaths.staging.web, configPaths.src.styles, 'common'), + }, + { + from: path.join(webpackUtils.oracleJetPreactThemePath, 'Theme-redwood'), + to: path.resolve(configPaths.staging.web, configPaths.src.styles, 'theme-redwood'), }], }), // This plugin sets options for the ojL10n-loader (in this case, just the locale name) diff --git a/package.json b/package.json index 7752b25..feb1bf9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@oracle/oraclejet-tooling", - "version": "13.0.0", + "version": "13.1.0", "license": "UPL-1.0", "description": "Programmatic API to build and serve Oracle JET web and mobile applications", "keywords": [ @@ -23,7 +23,7 @@ "lodash.union": "~4.6.0", "lodash.mergewith": "~4.6.2", "requirejs": "~2.3.6", - "terser": "~5.8.0", + "terser": "~5.14.2", "gaze": "~1.1.2", "express": "~4.17.1", "connect-livereload": "~0.6.0",