Skip to content

Commit 61e0896

Browse files
committed
Release 14.0.0
1 parent 5dbc62d commit 61e0896

File tree

171 files changed

+1722
-1329
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

171 files changed

+1722
-1329
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Contributing to ojet-cli
22

3-
*Copyright (c) 2014, 2022 Oracle and/or its affiliates
3+
*Copyright (c) 2014, 2023 Oracle and/or its affiliates
44
Licensed under The Universal Permissive License (UPL), Version 1.0
55
as shown at https://oss.oracle.com/licenses/upl/*
66

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ojet-cli
22

3-
Copyright (c) 2022 Oracle and/or its affiliates.
3+
Copyright (c) 2023 Oracle and/or its affiliates.
44

55
Licensed under The Universal Permissive License (UPL), Version 1.0
66
as shown at https://oss.oracle.com/licenses/upl/

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# @oracle/ojet-cli 13.1.0
1+
# @oracle/ojet-cli 14.0.0
22

33
## About the module
44
This module contains a command line interface for Oracle JET web and hybrid mobile application development.
@@ -64,11 +64,11 @@ Or view help on adding a plugin:
6464
ojet help add plugin
6565
```
6666

67-
For more information on the Oracle JET CLI, refer to the [Oracle JET Developers Guide](http://www.oracle.com/pls/topic/lookup?ctx=jet1310&id=homepage).
67+
For more information on the Oracle JET CLI, refer to the [Oracle JET Developers Guide](http://www.oracle.com/pls/topic/lookup?ctx=jet1400&id=homepage).
6868

6969
## [Contributing](https://github.com/oracle/ojet-cli/blob/master/CONTRIBUTING.md)
7070
Oracle JET is an open source project. Pull Requests are currently not being accepted. See [CONTRIBUTING](https://github.com/oracle/ojet-cli/blob/master/CONTRIBUTING.md) for details.
7171

7272
## [License](https://github.com/oracle/ojet-cli/blob/master/LICENSE)
73-
Copyright (c) 2022 Oracle and/or its affiliates and released under the
73+
Copyright (c) 2023 Oracle and/or its affiliates and released under the
7474
[Universal Permissive License (UPL)](https://oss.oracle.com/licenses/upl/), Version 1.0

RELEASENOTES.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
11
## Release Notes for ojet-cli ##
22

3+
### 14.0.0
4+
* node-sass updated to 7.0.1
5+
* strict mode is now enabled by default in generated tsconfig.json files
6+
* oraclejet-serve.js and oraclejet-build.js are no longer read or processed. Users should use other options in oraclejetconfig.json or the user hook system to set similar settings to what is found in oraclejet-serve.js and oraclejet-build.js. The same configuration objects formerly found in oraclejet-serve.js and oraclejet-build.js can be found in the 'opts' section of the context object passed into the before_build and before_serve hooks.
7+
* Add a "before_injection" hook that runs after all copying but before output files are modified by injectors
8+
* Hybrid build/serve capability based on Cordova is deprecated as of 10.1.0 and is planned for removal in version 15.0.0
9+
* Add 'webpackLibraries' and 'typescriptLibraries' propety to oraclejetconfig.json to facilitate maintenance of third-party libraries needed by Webpack and Typescript, respectively
10+
* Update default typescript version to 4.8.4. If you see a message warning about the wrong typescript version during build, please check your application's package.json to ensure that it is installing 4.8.4
11+
* When creating a vcomponent component, the template type now defaults to 'function' instead of 'class' if the value of the --vcomponent flag is not specified.
12+
* The CLI now installs itself within an application's node_modules for easy use of npx to issue ojet commands
13+
* A fix was made where the 'strict' typescript setting may not have been passed in to the compiler. If a project sees new typescript compilation failures, 'strict' mode as set in tsconfig.json may be the issue
14+
315
### 13.1.0
416

517
* In index.html, the injected <script> type will be changed to 'module' for CDN bundle config loading if 'cdn' and 'bundles-config-esm.js' is selected in path_mapping.json, to support the new self-locating JET CDN bundle configuration file
618
* Hybrid build/serve capability based on Cordova is deprecated as of 10.1.0 and is planned for removal in version 15.0.0
719

8-
920
### 13.0.0
1021

1122
* Metadata to support API documentation is now emitted for vcomponents during build

common/component.js

Lines changed: 118 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
Copyright (c) 2015, 2022, Oracle and/or its affiliates.
2+
Copyright (c) 2015, 2023, Oracle and/or its affiliates.
33
Licensed under The Universal Permissive License (UPL), Version 1.0
44
as shown at https://oss.oracle.com/licenses/upl/
55
@@ -31,6 +31,7 @@ module.exports = {
3131
const componentThemeTemplateSrc = _getComponentThemeTemplatePath('theme');
3232
const componentDestDirectory = _getComponentDestPath(generator);
3333
const pack = generator.options.pack;
34+
// eslint-disable-next-line max-len
3435
// avoid overwrite component
3536
if (fs.existsSync(componentDestDirectory)) {
3637
utils.log.error(`Component with name '${componentName}' already exists.`);
@@ -40,6 +41,28 @@ module.exports = {
4041
}
4142
fs.ensureDirSync(componentDestDirectory);
4243
fs.copySync(componentTemplateSrc, componentDestDirectory);
44+
// Rename loader.ts in destination directory to index.ts for loaderless
45+
// components--the contents are the same:
46+
if (_isVComponent(generator) && !_withLoader({ generator, pack })) {
47+
const loaderFilePath = path.join(componentDestDirectory, 'loader.ts');
48+
const indexFilePath = path.join(componentDestDirectory, 'index.ts');
49+
if (fs.existsSync(loaderFilePath)) {
50+
fs.renameSync(loaderFilePath, indexFilePath);
51+
}
52+
}
53+
// Loaderless components should have @ojmetadata main "@pack-name@/@component-name@"
54+
// as part of the comment to ensure TSC inputs the main attribute into the component.json
55+
// file with appropriate pack and component name. Otherwise, remove it.
56+
if (_isVComponent(generator) && _withLoader({ generator, pack })) {
57+
const filesToModify = ['@component@-functional-template.tsx', '@component@.tsx'];
58+
filesToModify.forEach((file) => {
59+
const filePath = path.join(componentDestDirectory, file);
60+
const regex = /@ojmetadata\s*main\s*"@pack-name@\/@component-name@"/gm;
61+
let fileContent = fs.readFileSync(filePath, { encoding: 'utf-8' });
62+
fileContent = fileContent.replace(regex, '');
63+
fs.writeFileSync(filePath, fileContent);
64+
});
65+
}
4366
if (_isResourceComponent(generator)) {
4467
const fileContent = constants.RESOURCE_COMPONENT_INDEX_FILE_CONTENT;
4568
fs.writeFileSync(path.join(componentDestDirectory, `index.${utils.isTypescriptApplication() ? 'ts' : 'js'}`), fileContent);
@@ -85,6 +108,7 @@ module.exports = {
85108
validateComponentName: (generator) => {
86109
const componentName = _getComponentName(generator);
87110
const pack = generator.options.pack;
111+
// eslint-disable-next-line max-len
88112
let errorMessage;
89113
if (componentName === undefined || componentName === null) {
90114
errorMessage = 'Invalid component name: must not be null or undefined.';
@@ -101,6 +125,12 @@ module.exports = {
101125
} else if (pack && !fs.existsSync(_getPathToJETPack(generator, pack))) {
102126
errorMessage = 'Invalid pack name: please provide an existing JET pack';
103127
utils.log.error(errorMessage);
128+
} else if (!pack && !_withLoader({ generator, pack }) && _isVComponent(generator)) {
129+
errorMessage = 'Cannot create a loaderless component without a pack.';
130+
utils.log.error(errorMessage);
131+
} else if (!_withLoader({ generator, pack }) && !_isVComponent(generator)) {
132+
errorMessage = 'Cannot create a loaderless CCA component.';
133+
utils.log.error(errorMessage);
104134
}
105135
},
106136

@@ -126,6 +156,10 @@ module.exports = {
126156
*/
127157
logSuccessMessage: (generator) => {
128158
utils.log(commonMessages.appendJETPrefix(`Add component '${_getComponentName(generator)}' finished.`));
159+
// Log out a message on what do to generate API docs for vcomponents only.
160+
if (_isVComponent(generator)) {
161+
utils.log(`To generate API docs for '${_getComponentName(generator)}', run 'ojet add docgen' before building it.`);
162+
}
129163
},
130164

131165
/**
@@ -359,8 +393,8 @@ function _renameComponentTemplatePrefixFile(componentDir, file, componentName) {
359393
/**
360394
* ## _updatePackInfo
361395
*
362-
* Add component to packs dependencies and set pack of component
363-
* to the provided pack
396+
* Add component to packs dependencies (and contents, if monopack)
397+
* and set pack of component to the provided pack
364398
*
365399
* @param {object} generator object with build options
366400
* @param {string} pack name of JET pack that the component belongs to
@@ -374,6 +408,10 @@ function _updatePackInfo({ generator, pack }) {
374408
}
375409
// add component to dependencies of pack
376410
_addComponentToPackDependencies({ generator, pack });
411+
// add component to contents if pack is mono-pack:
412+
if (_isMonoPack({ generator, pack })) {
413+
_addComponentToPackContents({ generator, pack });
414+
}
377415
}
378416

379417
/**
@@ -393,7 +431,8 @@ function _updateVComponentPack({ generator, pack, strip }) {
393431
const packRegex = new RegExp('@ojmetadata pack "@pack-name@"');
394432
vComponentContent = vComponentContent.replace(packRegex, '');
395433
} else {
396-
vComponentContent = vComponentContent.replace('@pack-name@', pack);
434+
const packRegex = new RegExp('@pack-name@', 'g');
435+
vComponentContent = vComponentContent.replace(packRegex, pack);
397436
}
398437
fs.outputFileSync(vComponentPath, vComponentContent);
399438
}
@@ -447,8 +486,8 @@ function _addComponentToPackDependencies({ generator, pack }) {
447486
constants.COMPONENT_JSON);
448487
const packComponentJson = fs.readJSONSync(packComponentJsonPath);
449488
const hasDependenciesToken = utils.loadToolingUtil().hasDependenciesToken(packComponentJson);
450-
if (!hasDependenciesToken) {
451-
// Only add component to dependnecies if the component.json does not have the dependencies
489+
if (!hasDependenciesToken && !_isMonoPack({ generator, pack })) {
490+
// Only add component to dependencies if the component.json does not have the dependencies
452491
// token. If it does, the build will take care of adding all JET pack dependencies at build time
453492
packComponentJson.dependencies = {
454493
...(packComponentJson.dependencies || {}),
@@ -458,6 +497,27 @@ function _addComponentToPackDependencies({ generator, pack }) {
458497
}
459498
}
460499

500+
/**
501+
* ## _addComponentToPackContents
502+
*
503+
* @param {object} options.generator
504+
* @param {object} options.pack
505+
*/
506+
function _addComponentToPackContents({ generator, pack }) {
507+
const componentName = _getComponentName(generator);
508+
const packComponentJsonPath = path.join(
509+
_getPathToJETPack(generator, pack),
510+
constants.COMPONENT_JSON);
511+
const packComponentJson = fs.readJSONSync(packComponentJsonPath);
512+
const contentItem = _isResourceComponent(generator) ? { name: `${componentName}`, type: constants.RESOURCE_COMPONENT } : { name: `${componentName}` };
513+
if (packComponentJson.contents && Array.isArray(packComponentJson.contents)) {
514+
packComponentJson.contents.push(contentItem);
515+
} else {
516+
packComponentJson.contents = [contentItem];
517+
}
518+
fs.writeJSONSync(packComponentJsonPath, packComponentJson, { spaces: 2 });
519+
}
520+
461521
/**
462522
* ## _addComponentToTsconfigPathMapping
463523
*
@@ -508,11 +568,62 @@ function _isResourceComponent(generator) {
508568
return generator.options.type === constants.RESOURCE_COMPONENT;
509569
}
510570

571+
/**
572+
* ## _isMonoPack
573+
*
574+
* @param {object} options.generator
575+
* @param {object} options.pack
576+
* @returns {boolean}
577+
*/
578+
function _isMonoPack({ generator, pack }) {
579+
if (pack) {
580+
const packComponentJsonPath = path.join(
581+
_getPathToJETPack(generator, pack),
582+
constants.COMPONENT_JSON
583+
);
584+
const packComponentJson = fs.readJSONSync(packComponentJsonPath);
585+
return packComponentJson.type === constants.MONO_PACK;
586+
}
587+
return false;
588+
}
589+
590+
/**
591+
* ## _withLoader
592+
*
593+
* @param {object} options.generator
594+
* @param {object} options.pack
595+
* @returns {boolean}
596+
*/
597+
function _withLoader({ generator, pack }) {
598+
if (generator.options.withLoader === false ||
599+
(_isMonoPack({ generator, pack }) && _isVComponent(generator))) {
600+
// Ensure that the withLoader attribute in options object is false.
601+
// This is because it can happen that the user creates the vcomponent
602+
// in a mono-pack, which should default to a loaderless component, whether
603+
// the withLoader flag is used or otherwise:
604+
if (generator.options.withLoader === undefined) {
605+
// eslint-disable-next-line no-param-reassign
606+
generator.options.withLoader = false;
607+
}
608+
return generator.options.withLoader;
609+
}
610+
return true;
611+
}
612+
613+
/**
614+
* ## _filterTsxTemplates
615+
*
616+
* @param {object} generator object with build options
617+
* @param {object} destPath
618+
*/
511619
function _filterTsxTemplates(generator, destPath) {
512620
const componentName = _getComponentName(generator);
513621
const pathToClassBasedTemplate = path.join(destPath, `${componentName}.tsx`);
514622
const pathToFunctionalBasedTemplate = path.join(destPath, `${componentName}-functional-template.tsx`);
515-
if (generator.options.vcomponent === 'function' || generator.options.vcomponent === 'functional') {
623+
if (generator.options.vcomponent === 'class') {
624+
// do nothing--file begins as class based with root name
625+
} else if (generator.options.vcomponent) {
626+
// do function/functional by default
516627
// <componentName>.tsx now has functional based template after overwriting it
517628
// with <componentName-functional>.tsx contents. We need to do this because,
518629
// once the chosen template is vcomponent, then we need to use the functional

common/hookRunner.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
Copyright (c) 2015, 2022, Oracle and/or its affiliates.
2+
Copyright (c) 2015, 2023, Oracle and/or its affiliates.
33
Licensed under The Universal Permissive License (UPL), Version 1.0
44
as shown at https://oss.oracle.com/licenses/upl/
55

common/index.js

Lines changed: 41 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
Copyright (c) 2015, 2022, Oracle and/or its affiliates.
2+
Copyright (c) 2015, 2023, Oracle and/or its affiliates.
33
Licensed under The Universal Permissive License (UPL), Version 1.0
44
as shown at https://oss.oracle.com/licenses/upl/
55
@@ -33,46 +33,42 @@ module.exports =
3333
writeCommonTemplates: function _writeCommonTemplates(generator) {
3434
const templateSrc = path.resolve(__dirname, '../template/common');
3535
const templateDest = path.resolve('.');
36-
return new Promise((resolve, reject) => {
37-
function filter(src, dest) {
38-
const isOracleJetConfigJson = path.basename(src) === constants.APP_CONFIG_JSON;
39-
const isVDOMTemplate = utils.isVDOMTemplate(generator);
40-
if (isVDOMTemplate && isOracleJetConfigJson) {
41-
// for vdom templates, update the oracljetconfig.json to
42-
// support the new architecture
43-
const oraclejetConfigJson = fs.readJSONSync(src);
44-
oraclejetConfigJson[constants.APPLICATION_ARCHITECTURE] = constants.VDOM_ARCHITECTURE;
45-
oraclejetConfigJson.paths.source.javascript = '.';
46-
oraclejetConfigJson.paths.source.typescript = '.';
47-
oraclejetConfigJson.paths.source.styles = 'styles';
48-
oraclejetConfigJson.paths.source.components = 'components';
49-
oraclejetConfigJson.paths.source.exchangeComponents = 'exchange_components';
50-
fs.writeJSONSync(dest, oraclejetConfigJson, { spaces: 2 });
51-
return false;
52-
} else if (isOracleJetConfigJson) {
53-
// for none-vdom templates, update oraclejetconfig.json
54-
// to indicate that architecture is mvvm (model-view-view-model)
55-
const oraclejetConfigJson = fs.readJSONSync(src);
56-
oraclejetConfigJson[constants.APPLICATION_ARCHITECTURE] = constants.MVVM_ARCHITECTURE;
57-
fs.writeJSONSync(dest, oraclejetConfigJson, { spaces: 2 });
58-
return false;
59-
}
60-
return true;
36+
function filter(src, dest) {
37+
const isOracleJetConfigJson = path.basename(src) === constants.APP_CONFIG_JSON;
38+
const isVDOMTemplate = utils.isVDOMTemplate(generator);
39+
if (isVDOMTemplate && isOracleJetConfigJson) {
40+
// for vdom templates, update the oracljetconfig.json to
41+
// support the new architecture
42+
const oraclejetConfigJson = fs.readJSONSync(src);
43+
oraclejetConfigJson[constants.APPLICATION_ARCHITECTURE] = constants.VDOM_ARCHITECTURE;
44+
oraclejetConfigJson.paths.source.javascript = '.';
45+
oraclejetConfigJson.paths.source.typescript = '.';
46+
oraclejetConfigJson.paths.source.styles = 'styles';
47+
oraclejetConfigJson.paths.source.components = 'components';
48+
oraclejetConfigJson.paths.source.exchangeComponents = 'exchange_components';
49+
fs.writeJSONSync(dest, oraclejetConfigJson, { spaces: 2 });
50+
return false;
51+
} else if (isOracleJetConfigJson) {
52+
// for none-vdom templates, update oraclejetconfig.json
53+
// to indicate that architecture is mvvm (model-view-view-model)
54+
const oraclejetConfigJson = fs.readJSONSync(src);
55+
oraclejetConfigJson[constants.APPLICATION_ARCHITECTURE] = constants.MVVM_ARCHITECTURE;
56+
fs.writeJSONSync(dest, oraclejetConfigJson, { spaces: 2 });
57+
return false;
6158
}
62-
try {
63-
fs.copySync(templateSrc, templateDest, { filter });
64-
resolve();
65-
} catch (error) {
66-
reject(error);
67-
}
68-
});
59+
return true;
60+
}
61+
try {
62+
fs.copySync(templateSrc, templateDest, { filter });
63+
return Promise.resolve();
64+
} catch (error) {
65+
return Promise.reject(error);
66+
}
6967
},
7068

7169
updatePackageJSON: function _updatePacakgeJSON(generator) {
72-
return new Promise((resolve) => {
73-
_updateJSON(generator, 'package.json');
74-
resolve(generator);
75-
});
70+
_updateJSON(generator, 'package.json');
71+
return Promise.resolve(generator);
7672
},
7773

7874
validateAppDirNotExistsOrIsEmpty: function _validateAppDirNotExistsOrIsEmpty(generator) {
@@ -117,16 +113,13 @@ module.exports =
117113
},
118114

119115
validateArgs: function _validateArgs(generator) {
120-
return new Promise((resolve, reject) => {
121-
const args = generator.arguments;
122-
const validLength = _getValidArgLength(generator.options.namespace);
116+
const args = generator.arguments;
117+
const validLength = _getValidArgLength(generator.options.namespace);
123118

124-
if (args.length > validLength) {
125-
reject(commonMessages.error(`Invalid additional arguments: ${args.splice(validLength)}`, 'validateArgs'));
126-
} else {
127-
resolve(generator);
128-
}
129-
});
119+
if (args.length > validLength) {
120+
return Promise.reject(commonMessages.error(`Invalid additional arguments: ${args.splice(validLength)}`, 'validateArgs'));
121+
}
122+
return Promise.resolve(generator);
130123
},
131124

132125
validateFlags: function _validateFlags(generator) {
@@ -239,6 +232,8 @@ function _customizeVDOMTemplateTsconfigForWebpack() {
239232
tsconfigJson.compilerOptions.typeRoots.unshift('./types');
240233
tsconfigJson.compilerOptions.resolveJsonModule = true;
241234
tsconfigJson.compilerOptions.esModuleInterop = true;
235+
tsconfigJson.compilerOptions.removeComments = true;
236+
tsconfigJson.compilerOptions.strict = true;
242237
tsconfigJson.compilerOptions.paths.react = [
243238
preactCompat
244239
];

0 commit comments

Comments
 (0)