Skip to content

Commit 803f44d

Browse files
committed
Release 13.1.0
1 parent 5988d95 commit 803f44d

File tree

14 files changed

+283
-56
lines changed

14 files changed

+283
-56
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
# @oracle/oraclejet-tooling 13.0.0
1+
# @oracle/oraclejet-tooling 13.1.0
22

33
## About the tooling API
44
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.
55

66
This is an open source project maintained by Oracle Corp.
77

88
## Installation
9-
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).
9+
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).
1010

1111
## [Contributing](https://github.com/oracle/oraclejet-tooling/blob/master/CONTRIBUTING.md)
1212
Oracle JET is an open source project. Pull Requests are currently not being accepted. See

RELEASENOTES.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## Release Notes for oraclejet-tooling ##
22

3-
### 13.0.0
3+
### 13.1.0
44

55
### 11.0.0
66
* oraclejet-tooling now requires node 12.21 or later

lib/addtypescript.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ function installTypescipt(options) {
3535
util.log('Installing Typescript');
3636
const installer = util.getInstallerCommand({ options });
3737

38-
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`;
38+
const command = `${installer.installer} ${installer.verbs.install} typescript@${CONSTANTS.TYPESCRIPT_VERSION} yargs-parser@~13.1.2 --save-dev --save-exact`;
3939
return util.exec(command);
4040
}
4141

lib/addwebpack.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ function installWebpack(options) {
3636
const command = `
3737
${installer.installer} ${installer.verbs.install}
3838
webpack@${CONSTANTS.WEBPACK_VERSION}
39+
@types/node@18.8.3
3940
webpack-dev-server
4041
style-loader
4142
css-loader

lib/buildCommon/copyLocalComponent.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ class ComponentStager {
211211
fs.removeSync(destPath);
212212
util.ensureDir(destPath);
213213
fs.copySync(srcPath, destPath, { dereference: true });
214+
generateRootIndexFile(srcPath, destPath);
214215
}
215216
stageComponentToReleaseLocation() {
216217
const { srcPath, destPathRelease } = this;
@@ -219,6 +220,7 @@ class ComponentStager {
219220
const resourcesPath = path.join(srcPath, 'resources');
220221
if (util.fsExistsSync(resourcesPath)) {
221222
fs.copySync(resourcesPath, path.join(destPathRelease, 'resources'), { dereference: true });
223+
generateRootIndexFile(srcPath, destPathRelease);
222224
}
223225
const cssFiles = glob.sync('**/*.css', { cwd: srcPath });
224226
cssFiles.forEach((cssFilePath) => {
@@ -299,4 +301,68 @@ function generateComponentStager({ context, componentJson, srcPath, destPath })
299301
return new ComponentStager({ context, srcPath, destPath });
300302
}
301303

304+
/**
305+
* ## generateRootIndexFile
306+
*
307+
* Generate an root index file under the web/../resources/nls folder:
308+
*
309+
* @param {string} options.destPath
310+
*/
311+
function generateRootIndexFile(srcPath, destPath) {
312+
const pathToNlsFolder = path.join(destPath, 'resources', 'nls');
313+
const pathToNlsRootFolder = path.join(pathToNlsFolder, 'root');
314+
const pathToNlsRootFolderInSrc = path.join(srcPath, 'resources', 'nls', 'root');
315+
// Get the array of contents under the nls/root folder, which is the string file:
316+
util.getFiles(pathToNlsRootFolder).forEach((file) => {
317+
const pathToComponentStringFile = path.join(pathToNlsFolder, 'root', file);
318+
const pathToRootIndexFileInWeb = path.join(pathToNlsFolder, file);
319+
const pathToRootIndexFileInSrc = path.join(srcPath, 'resources', 'nls', file);
320+
if (fs.existsSync(pathToNlsRootFolderInSrc) && !(fs.existsSync(pathToRootIndexFileInSrc))) {
321+
// eslint-disable-next-line max-len
322+
const fileContent = getModifiedComponentStringFileContent(pathToComponentStringFile, pathToNlsFolder);
323+
fs.writeFileSync(pathToRootIndexFileInWeb, fileContent);
324+
// Delete the web/../nls/root/<fileName> folder as it is no londer needed:
325+
if (fs.existsSync(pathToComponentStringFile)) {
326+
fs.removeSync(pathToComponentStringFile);
327+
}
328+
// Delete the web/../nls/root folder if empty as it is no londer needed:
329+
if (fs.readdirSync(pathToNlsRootFolder).length === 0) {
330+
fs.removeSync(pathToNlsRootFolder);
331+
}
332+
}
333+
});
334+
}
335+
336+
/**
337+
* ## getModifiedComponentStringFileContent
338+
*
339+
* Modifies the component string file content
340+
*
341+
* @param {string} pathToComponentStringFile
342+
* @param {string} pathToNlsFolder
343+
*/
344+
function getModifiedComponentStringFileContent(pathToComponentStringFile, pathToNlsFolder) {
345+
// eslint-disable-next-line max-len
346+
const componentStringFileContent = fs.readFileSync(pathToComponentStringFile, { encoding: 'utf-8' });
347+
// The retrieved file content in the form:
348+
// export = {componentName: {sampleString: 'Details...'}}. Therefore, the retrieved
349+
// object content will be componentName: {sampleString: 'Details...'}.
350+
const regex = /{(?<exportedObjectContent>.*)}/gms;
351+
const match = regex.exec(componentStringFileContent);
352+
// Modify the exported content to export = {root : {componentName: {sampleString: 'Details...'}}}.
353+
let modifiedStringFileContent = `\n "root": {${match.groups.exportedObjectContent} },`;
354+
// Go through the nls folder and check if there are any other languages chosen for translation.
355+
// If there are any, add them as part of the exported object in the form:
356+
// "<language>": true. In the case German and French are the included languages,
357+
// then the added items will be: "de":true, "fr":true.
358+
const nlsFolderContents = fs.readdirSync(pathToNlsFolder);
359+
nlsFolderContents.forEach((content) => {
360+
const pathToNlsFolderContent = path.join(pathToNlsFolder, content);
361+
if (content !== 'root' && fs.lstatSync(pathToNlsFolderContent).isDirectory()) {
362+
modifiedStringFileContent = modifiedStringFileContent.concat(` \n "${content}": true,`);
363+
}
364+
});
365+
return componentStringFileContent.replace(`${match.groups.exportedObjectContent}`, `${modifiedStringFileContent}\n`);
366+
}
367+
302368
module.exports = copyLocalComponent;

lib/buildCommon/stripLocalComponentJson.js

Lines changed: 168 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -16,39 +16,37 @@ const CONSTANTS = require('../constants');
1616
* Stripping implementation exported to buildCommon.js:
1717
*/
1818
function stripLocalComponentJson(context) {
19-
return new Promise((resolve) => {
20-
const componentsCache = util.getComponentsCache();
21-
util.getLocalCompositeComponents().forEach((_component) => {
22-
let pathToComponentJSON;
23-
let modifiedComponentJSON;
24-
let jsonFileContent;
25-
const { builtPath, componentJson } = componentsCache[_component];
26-
// Modify the component.json in staging by stripping the unwanted attributes and
27-
// sub-properties during run-time. This stripped json file is then included in
28-
// the web/../min/loader.js file. The original contents of the json file are restored in
29-
// restoreLocalCcaComponentJson after minification. Also, if the passed component is a
30-
// pack, we will need to iterate through its component dependencies. Failure to do so
31-
// will result in having non-stripped metadata in the component's min/loader.js file:
32-
if (util.isJETPack({ pack: _component, componentJson })) {
33-
const dependenciesFromCache = Object.getOwnPropertyNames(componentJson.dependencies);
34-
dependenciesFromCache.forEach((component) => {
35-
const componentData = componentsCache[component];
36-
pathToComponentJSON = path.join(componentData.builtPath, CONSTANTS.JET_COMPONENT_JSON);
37-
if (fs.readdirSync(componentData.builtPath).includes('loader.js')) {
38-
jsonFileContent = fs.readJSONSync(pathToComponentJSON);
39-
modifiedComponentJSON = getStrippedComponentJson(jsonFileContent);
40-
fs.writeJsonSync(pathToComponentJSON, modifiedComponentJSON);
41-
}
42-
});
43-
} else {
44-
pathToComponentJSON = path.join(builtPath, CONSTANTS.JET_COMPONENT_JSON);
45-
jsonFileContent = fs.readJSONSync(pathToComponentJSON);
46-
modifiedComponentJSON = getStrippedComponentJson(jsonFileContent);
47-
fs.writeJsonSync(pathToComponentJSON, modifiedComponentJSON);
48-
}
49-
});
50-
resolve(context);
19+
const componentsCache = util.getComponentsCache();
20+
util.getLocalCompositeComponents().forEach((_component) => {
21+
let pathToComponentJSON;
22+
let modifiedComponentJSON;
23+
let jsonFileContent;
24+
const { builtPath, componentJson } = componentsCache[_component];
25+
// Modify the component.json in staging by stripping the unwanted attributes and
26+
// sub-properties during run-time. This stripped json file is then included in
27+
// the web/../min/loader.js file. The original contents of the json file are restored in
28+
// restoreLocalCcaComponentJson after minification. Also, if the passed component is a
29+
// pack, we will need to iterate through its component dependencies. Failure to do so
30+
// will result in having non-stripped metadata in the component's min/loader.js file:
31+
if (util.isJETPack({ pack: _component, componentJson })) {
32+
const dependenciesFromCache = Object.getOwnPropertyNames(componentJson.dependencies);
33+
dependenciesFromCache.forEach((component) => {
34+
const componentData = componentsCache[component];
35+
pathToComponentJSON = path.join(componentData.builtPath, CONSTANTS.JET_COMPONENT_JSON);
36+
if (fs.readdirSync(componentData.builtPath).includes('loader.js')) {
37+
jsonFileContent = fs.readJSONSync(pathToComponentJSON);
38+
modifiedComponentJSON = getStrippedComponentJson(jsonFileContent);
39+
fs.writeJsonSync(pathToComponentJSON, modifiedComponentJSON);
40+
}
41+
});
42+
} else {
43+
pathToComponentJSON = path.join(builtPath, CONSTANTS.JET_COMPONENT_JSON);
44+
jsonFileContent = fs.readJSONSync(pathToComponentJSON);
45+
modifiedComponentJSON = getStrippedComponentJson(jsonFileContent);
46+
fs.writeJsonSync(pathToComponentJSON, modifiedComponentJSON);
47+
}
5148
});
49+
return Promise.resolve(context);
5250
}
5351

5452
/**
@@ -92,8 +90,12 @@ function deleteUnrequiredTopLevelAttributes(json, requiredAttributes) {
9290
if (attributes) {
9391
attributes.forEach((attribute) => {
9492
if (!requiredAttributes.has(attribute)) {
95-
// eslint-disable-next-line no-param-reassign
96-
delete json[attribute];
93+
if (attribute === 'extension') {
94+
stripExtensionSubAttribute(json[attribute], json, attribute);
95+
} else {
96+
// eslint-disable-next-line no-param-reassign
97+
delete json[attribute];
98+
}
9799
}
98100
});
99101
}
@@ -140,8 +142,7 @@ function stripTopLevelAttributes(componentJSON, requiredTopLevelAttributes) {
140142
const subAttributes = getAttributes(componentJSON[topLevelAttribute]);
141143
if (subAttributes) {
142144
subAttributes.forEach((subAttribute) => {
143-
const subAttributeObject = componentJSON[topLevelAttribute][subAttribute];
144-
stripSubAttribute(subAttributeObject, componentJSON[topLevelAttribute], subAttribute);
145+
stripSubAttributes(componentJSON[topLevelAttribute][subAttribute]);
145146
});
146147
// Delete the resulting object if empty:
147148
if (isEmpty(componentJSON[topLevelAttribute])) {
@@ -153,14 +154,28 @@ function stripTopLevelAttributes(componentJSON, requiredTopLevelAttributes) {
153154
});
154155
}
155156

157+
/**
158+
*
159+
* @param {object} attributeObject
160+
*
161+
* Strip the sub-attributes from the top level componentJson
162+
* properties. Go through the passed object recursively and
163+
* remove the unrequired sub-attributes.
164+
*/
165+
function stripSubAttributes(attributeObject) {
166+
const attributes = getAttributes(attributeObject);
167+
attributes.forEach((attribute) => {
168+
stripSubAttribute(attributeObject[attribute], attributeObject, attribute);
169+
});
170+
}
171+
156172
/**
157173
*
158174
* @param {string} attributeName
159175
* @param {object} attributeObject
160176
* @param {object} subAttributeObject -- attributeObject[attributeName]
161-
* @returns {Boolean}
162177
*
163-
* Strip the sub-attributes. Go throught the passed object recursively and
178+
* Strip the sub-attributes. Go through the passed object recursively and
164179
* remove the unrequired sub-attributes.
165180
*/
166181
function stripSubAttribute(subAttributeObject, attributeObject, attributeName) {
@@ -169,10 +184,21 @@ function stripSubAttribute(subAttributeObject, attributeObject, attributeName) {
169184
delete attributeObject[attributeName];
170185
return;
171186
}
187+
188+
if (attributeName === 'extension') {
189+
stripExtensionSubAttribute(subAttributeObject, attributeObject, attributeName);
190+
if (isEmpty(subAttributeObject)) {
191+
// eslint-disable-next-line no-param-reassign
192+
delete attributeObject[attributeName];
193+
}
194+
return;
195+
}
196+
172197
const attributes = getAttributes(subAttributeObject);
173198
if (!attributes) {
174199
return;
175200
}
201+
176202
attributes.forEach((attribute) => {
177203
stripSubAttribute(subAttributeObject[attribute], subAttributeObject, attribute);
178204
});
@@ -195,14 +221,87 @@ function isNeededSubAttribute(subAttribute) {
195221
'value',
196222
'binding',
197223
'writeback',
198-
'internalName'
224+
'internalName',
225+
'consume',
226+
'provide',
227+
'name',
228+
'default',
229+
'transform',
230+
'extension'
199231
]);
200232
if (requiredSubAttributes.has(subAttribute)) {
201233
return true;
202234
}
203235
return false;
204236
}
205237

238+
/**
239+
*
240+
* @param {string} subAttribute
241+
* @returns {Boolean}
242+
*
243+
* Checks if the passed attribute is a needed non-required sub-attribute.
244+
*/
245+
function isNeededExtensionSubAttribute(subAttribute) {
246+
const nonRequiredSubAttributes = new Set([
247+
'description',
248+
'displayName',
249+
'tags',
250+
'coverImage',
251+
'screenshots',
252+
'jet',
253+
'vbdt',
254+
'audits',
255+
'package',
256+
'docUrl',
257+
'itemProperties',
258+
'webelement',
259+
'readme',
260+
'unsupportedBrowsers',
261+
'businessApprovals',
262+
'uxSpecs',
263+
'unsupportedThemes',
264+
'defaultColumns',
265+
'minColumns',
266+
'itemProperties',
267+
'slotData',
268+
'exceptionStatus',
269+
'catalog',
270+
'oracle',
271+
'themes'
272+
]);
273+
if (nonRequiredSubAttributes.has(subAttribute)) {
274+
return false;
275+
}
276+
return true;
277+
}
278+
279+
/**
280+
*
281+
* @param {string} attributeName
282+
* @param {object} attributeObject
283+
* @param {object} subAttributeObject -- attributeObject[attributeName]
284+
*
285+
* Strip the extension sub-attributes. Go through the passed object recursively and
286+
* remove the unrequired sub-attributes.
287+
*/
288+
function stripExtensionSubAttribute(subAttributeObject, attributeObject, attributeName) {
289+
if (!isNeededExtensionSubAttribute(attributeName)) {
290+
// eslint-disable-next-line no-param-reassign
291+
delete attributeObject[attributeName];
292+
return;
293+
}
294+
const attributes = getAttributes(subAttributeObject);
295+
if (!attributes) {
296+
return;
297+
}
298+
299+
attributes.forEach((attribute) => {
300+
stripExtensionSubAttribute(subAttributeObject[attribute], subAttributeObject, attribute);
301+
});
302+
deleteExtensionSubAttribute(subAttributeObject, attributeObject, attributeName);
303+
}
304+
206305
/**
207306
*
208307
* @param {string} parentAttributeName
@@ -232,6 +331,36 @@ function deleteAttribute(childAttributeObject, parentAttributeObject, parentAttr
232331
}
233332
}
234333

334+
/**
335+
*
336+
* @param {string} parentAttributeName
337+
* @param {object} parentAttributeObject
338+
* @param {object} childAttributeObject -- parentAttributeObject[parentAttributeName]
339+
* @returns {Boolean}
340+
*
341+
* Deletes the unrequired attribute at RT:
342+
*/
343+
// eslint-disable-next-line max-len
344+
function deleteExtensionSubAttribute(childAttributeObject, parentAttributeObject, parentAttributeName) {
345+
const attributes = getAttributes(childAttributeObject);
346+
if (attributes) {
347+
attributes.forEach((attribute) => {
348+
if (!isNeededExtensionSubAttribute(attribute) && !isObject(childAttributeObject[attribute])) {
349+
// eslint-disable-next-line no-param-reassign
350+
delete childAttributeObject[attribute];
351+
}
352+
if (isEmpty(childAttributeObject)) {
353+
// eslint-disable-next-line no-param-reassign
354+
delete parentAttributeObject[parentAttributeName];
355+
}
356+
});
357+
if (isEmpty(childAttributeObject)) {
358+
// eslint-disable-next-line no-param-reassign
359+
delete parentAttributeObject[parentAttributeName];
360+
}
361+
}
362+
}
363+
235364
/**
236365
*
237366
* @param {object} json

0 commit comments

Comments
 (0)