Skip to content

Commit

Permalink
Release 13.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
benm071 committed Oct 13, 2022
1 parent 5988d95 commit 803f44d
Show file tree
Hide file tree
Showing 14 changed files with 283 additions and 56 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# @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.

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
Expand Down
2 changes: 1 addition & 1 deletion RELEASENOTES.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/addtypescript.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
1 change: 1 addition & 0 deletions lib/addwebpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ function installWebpack(options) {
const command = `
${installer.installer} ${installer.verbs.install}
webpack@${CONSTANTS.WEBPACK_VERSION}
@types/[email protected]
webpack-dev-server
style-loader
css-loader
Expand Down
66 changes: 66 additions & 0 deletions lib/buildCommon/copyLocalComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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) => {
Expand Down Expand Up @@ -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/<fileName> 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 = /{(?<exportedObjectContent>.*)}/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:
// "<language>": 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;
207 changes: 168 additions & 39 deletions lib/buildCommon/stripLocalComponentJson.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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];
}
}
});
}
Expand Down Expand Up @@ -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])) {
Expand All @@ -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) {
Expand All @@ -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);
});
Expand All @@ -195,14 +221,87 @@ function isNeededSubAttribute(subAttribute) {
'value',
'binding',
'writeback',
'internalName'
'internalName',
'consume',
'provide',
'name',
'default',
'transform',
'extension'
]);
if (requiredSubAttributes.has(subAttribute)) {
return true;
}
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
Expand Down Expand Up @@ -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
Expand Down
Loading

0 comments on commit 803f44d

Please sign in to comment.