devextreme-cli 1.3.2 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +4 -2
- package/package.json +8 -3
- package/src/application.js +17 -17
- package/src/applications/application.angular.js +38 -21
- package/src/applications/application.react.js +81 -37
- package/src/applications/application.vue.js +70 -33
- package/src/commands.json +3 -0
- package/src/templates/react/application/src/{App.js → App.tsx} +0 -0
- package/src/templates/react/application/src/{Content.js → Content.tsx} +11 -9
- package/src/templates/react/application/src/UnauthenticatedContent.tsx +46 -0
- package/src/templates/react/application/src/api/{auth.js → auth.tsx} +4 -4
- package/src/templates/react/application/src/{app-info.js → app-info.tsx} +0 -0
- package/src/templates/react/application/src/{app-navigation.js → app-navigation.tsx} +0 -0
- package/src/templates/react/application/src/app-routes.tsx +24 -0
- package/src/templates/react/application/src/components/change-password-form/{change-password-form.js → ChangePasswordForm.tsx} +6 -6
- package/src/templates/react/application/src/components/create-account-form/{create-account-form.scss → CreateAccountForm.scss} +0 -0
- package/src/templates/react/application/src/components/create-account-form/{create-account-form.js → CreateAccountForm.tsx} +7 -7
- package/src/templates/react/application/src/components/footer/{footer.scss → Footer.scss} +0 -0
- package/src/templates/react/application/src/components/footer/{footer.js → Footer.tsx} +1 -1
- package/src/templates/react/application/src/components/header/{header.scss → Header.scss} +0 -0
- package/src/templates/react/application/src/components/header/{header.js → Header.tsx} +4 -3
- package/src/templates/react/application/src/components/index.tsx +7 -0
- package/src/templates/react/application/src/components/login-form/{login-form.scss → LoginForm.scss} +0 -0
- package/src/templates/react/application/src/components/login-form/{login-form.js → LoginForm.tsx} +6 -6
- package/src/templates/react/application/src/components/reset-password-form/{reset-password-form.scss → ResetPasswordForm.scss} +0 -0
- package/src/templates/react/application/src/components/reset-password-form/{reset-password-form.js → ResetPasswordForm.tsx} +7 -7
- package/src/templates/react/application/src/components/side-navigation-menu/{side-navigation-menu.scss → SideNavigationMenu.scss} +0 -0
- package/src/templates/react/application/src/components/side-navigation-menu/{side-navigation-menu.js → SideNavigationMenu.tsx} +8 -10
- package/src/templates/react/application/src/components/user-panel/{user-panel.scss → UserPanel.scss} +0 -0
- package/src/templates/react/application/src/components/user-panel/{user-panel.js → UserPanel.tsx} +8 -8
- package/src/templates/react/application/src/contexts/{auth.js → auth.tsx} +6 -5
- package/src/templates/react/application/src/contexts/navigation.tsx +35 -0
- package/src/templates/react/application/src/layouts/{index.js → index.tsx} +0 -0
- package/src/templates/react/application/src/layouts/side-nav-inner-toolbar/{side-nav-inner-toolbar.js → side-nav-inner-toolbar.tsx} +12 -9
- package/src/templates/react/application/src/layouts/side-nav-outer-toolbar/{side-nav-outer-toolbar.js → side-nav-outer-toolbar.tsx} +11 -10
- package/src/templates/react/application/src/layouts/single-card/{single-card.js → single-card.tsx} +2 -1
- package/src/templates/react/application/src/{polyfills.js → polyfills.tsx} +0 -0
- package/src/templates/react/application/src/types.tsx +53 -0
- package/src/templates/react/application/src/utils/{default-user.js → default-user.tsx} +0 -0
- package/src/templates/react/application/src/utils/{media-query.js → media-query.tsx} +4 -3
- package/src/templates/react/application/src/utils/{patches.js → patches.tsx} +1 -1
- package/src/templates/react/page/{page.js → page.tsx} +0 -0
- package/src/templates/react/sample-pages/home/{home.js → home.tsx} +0 -0
- package/src/templates/react/sample-pages/{index.js → index.tsx} +0 -0
- package/src/templates/react/sample-pages/profile/{profile.js → profile.tsx} +0 -0
- package/src/templates/react/sample-pages/tasks/{tasks.js → tasks.tsx} +1 -1
- package/src/templates/vue-v2/application/devextreme.json +2 -1
- package/src/templates/vue-v3/application/devextreme.json +2 -1
- package/src/utility/prompts/layout.js +9 -21
- package/src/utility/prompts/prompts.js +24 -8
- package/src/utility/prompts/typescript.js +18 -0
- package/src/utility/prompts/vue-version.js +9 -21
- package/src/utility/template-creator.js +11 -6
- package/src/utility/typescript-extension.js +24 -0
- package/src/templates/react/application/src/UnauthenticatedContent.js +0 -35
- package/src/templates/react/application/src/app-routes.js +0 -24
- package/src/templates/react/application/src/components/index.js +0 -7
- package/src/templates/react/application/src/contexts/navigation.js +0 -34
package/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
const args = require('minimist')(process.argv.slice(2), {
|
|
3
3
|
alias: { v: 'version' }
|
|
4
4
|
});
|
|
5
|
+
|
|
5
6
|
const commands = args['_'];
|
|
6
7
|
delete args['_'];
|
|
7
8
|
const themeBuilder = require('./src/themebuider');
|
|
@@ -34,9 +35,10 @@ if(args.help) {
|
|
|
34
35
|
process.exit();
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
|
|
39
|
+
const run = async(commands, options) => {
|
|
38
40
|
if(application.isApplicationCommand(commands[0])) {
|
|
39
|
-
application.run(commands, options, devextremeConfig.read());
|
|
41
|
+
await application.run(commands, options, devextremeConfig.read());
|
|
40
42
|
} else if(themeBuilder.isThemeBuilderCommand(commands[0])) {
|
|
41
43
|
options.command = commands[0];
|
|
42
44
|
themeBuilder.run(options);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devextreme-cli",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "DevExtreme CLI",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"devexpress",
|
|
@@ -49,13 +49,16 @@
|
|
|
49
49
|
"strip-bom": "^4.0.0"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
+
"@typescript-eslint/eslint-plugin": "^4.15.1",
|
|
52
53
|
"@typescript-eslint/parser": "^4.0.1",
|
|
53
54
|
"babel-eslint": "^10.1.0",
|
|
54
55
|
"cross-env": "^5.2.0",
|
|
55
56
|
"eslint": "^7.8.0",
|
|
56
57
|
"eslint-config-angular": "^0.5.0",
|
|
58
|
+
"eslint-config-prettier": "^8.5.0",
|
|
57
59
|
"eslint-plugin-angular": "^4.0.1",
|
|
58
60
|
"eslint-plugin-jest": "^22.5.1",
|
|
61
|
+
"eslint-plugin-prettier": "^4.0.0",
|
|
59
62
|
"eslint-plugin-react": "^7.20.6",
|
|
60
63
|
"eslint-plugin-react-hooks": "^4.1.0",
|
|
61
64
|
"eslint-plugin-unused-imports": "^1.1.5",
|
|
@@ -63,11 +66,13 @@
|
|
|
63
66
|
"eslint-stylish": "^0.2.0",
|
|
64
67
|
"jest": "^27.3.1",
|
|
65
68
|
"jest-image-snapshot": "^4.5.0",
|
|
69
|
+
"prettier": "^2.6.2",
|
|
66
70
|
"puppeteer": "^2.1.1",
|
|
67
71
|
"rimraf": "^2.6.3",
|
|
68
72
|
"tree-kill": "^1.2.1",
|
|
69
73
|
"tree-kill-promise": "^1.0.3",
|
|
70
|
-
"typescript": "^4.0.2"
|
|
74
|
+
"typescript": "^4.0.2",
|
|
75
|
+
"typescript-eslint-parser": "^22.0.0"
|
|
71
76
|
},
|
|
72
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "023ac50deaac92bd44a283079f55491f4db30049"
|
|
73
78
|
}
|
package/src/application.js
CHANGED
|
@@ -4,10 +4,10 @@ const vueApplication = require('./applications/application.vue');
|
|
|
4
4
|
const printHelp = require('./help').printHelp;
|
|
5
5
|
|
|
6
6
|
const isApplicationCommand = (command) => {
|
|
7
|
-
return [ 'new', 'add' ].
|
|
7
|
+
return [ 'new', 'add' ].includes(command);
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
-
const run = (commands, options, devextremeConfig) => {
|
|
10
|
+
const run = async(commands, options, devextremeConfig) => {
|
|
11
11
|
if(!commands[1]) {
|
|
12
12
|
console.error('Command is incomplete. Please specify parameters.');
|
|
13
13
|
printHelp(commands[0]);
|
|
@@ -15,23 +15,23 @@ const run = (commands, options, devextremeConfig) => {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
if(commands[0] === 'new') {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
if(commands[1] === 'react-app') {
|
|
24
|
-
reactApplication.create(commands[2] || 'my-app', options);
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
18
|
+
const app = commands[1];
|
|
19
|
+
const appName = commands[2] || 'my-app';
|
|
27
20
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
21
|
+
switch(app) {
|
|
22
|
+
case 'angular-app':
|
|
23
|
+
await angularApplication.create(appName, options);
|
|
24
|
+
return;
|
|
25
|
+
case 'react-app':
|
|
26
|
+
await reactApplication.create(appName, options);
|
|
27
|
+
return;
|
|
28
|
+
case 'vue-app':
|
|
29
|
+
await vueApplication.create(appName, options);
|
|
30
|
+
return;
|
|
31
|
+
default:
|
|
32
|
+
console.error(`The '${app}' application type is not valid`);
|
|
33
|
+
printHelp(commands[0]);
|
|
31
34
|
}
|
|
32
|
-
|
|
33
|
-
console.error(`The '${commands[1]}' application type is not valid`);
|
|
34
|
-
printHelp(commands[0]);
|
|
35
35
|
} else {
|
|
36
36
|
if(commands[0] === 'add') {
|
|
37
37
|
if(commands[1] === 'devextreme-angular') {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const getLayoutInfo = require('../utility/prompts/layout')
|
|
1
|
+
const getLayoutInfo = require('../utility/prompts/layout');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const moduleWorker = require('../utility/module');
|
|
4
4
|
const runCommand = require('../utility/run-command');
|
|
@@ -32,10 +32,14 @@ async function runSchematicCommand(schematicCommand, options, evaluatingOptions)
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
async function runNgCommand(commandArguments, evaluatingOptions) {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
ngCommandArguments
|
|
38
|
-
|
|
35
|
+
const hasNg = await hasSutableNgCli();
|
|
36
|
+
const npmCommandName = hasNg ? 'ng' : 'npx';
|
|
37
|
+
const ngCommandArguments = hasNg
|
|
38
|
+
? []
|
|
39
|
+
: ['-p', '@angular/cli@13.3.7', 'ng'];
|
|
40
|
+
|
|
41
|
+
ngCommandArguments.push(...commandArguments);
|
|
42
|
+
return runCommand(npmCommandName, ngCommandArguments, evaluatingOptions);
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
function localPackageExists(packageName) {
|
|
@@ -50,9 +54,24 @@ function localPackageExists(packageName) {
|
|
|
50
54
|
|
|
51
55
|
function hasSutableNgCli() {
|
|
52
56
|
return new Promise((resolve, reject) => {
|
|
57
|
+
if(globalNgCliVersion !== '') {
|
|
58
|
+
resolve(true);
|
|
59
|
+
}
|
|
60
|
+
|
|
53
61
|
exec('ng v', (err, stdout, stderr) => {
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+
if(!!err) {
|
|
63
|
+
resolve(false);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const parsingResult = parseNgCliVersion(stdout);
|
|
68
|
+
if(!parsingResult) {
|
|
69
|
+
resolve(false);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const isSupportVersion = parsingResult.compare(minNgCliVersion) >= 0
|
|
73
|
+
&& parsingResult.compare(new semver('14.0.0')) < 0;
|
|
74
|
+
if(isSupportVersion) {
|
|
56
75
|
globalNgCliVersion = parsingResult.version;
|
|
57
76
|
resolve(true);
|
|
58
77
|
} else {
|
|
@@ -70,7 +89,9 @@ const install = (options) => {
|
|
|
70
89
|
runSchematicCommand('install', { ...options, globalNgCliVersion });
|
|
71
90
|
};
|
|
72
91
|
|
|
73
|
-
const create = (appName, options) => {
|
|
92
|
+
const create = async(appName, options) => {
|
|
93
|
+
const layout = await getLayoutInfo(options.layout);
|
|
94
|
+
|
|
74
95
|
const commandArguments = [
|
|
75
96
|
'new',
|
|
76
97
|
appName,
|
|
@@ -80,22 +101,18 @@ const create = (appName, options) => {
|
|
|
80
101
|
'--skip-install=true',
|
|
81
102
|
];
|
|
82
103
|
|
|
83
|
-
|
|
84
|
-
runNgCommand(commandArguments).then(() => {
|
|
85
|
-
const appPath = path.join(process.cwd(), appName);
|
|
104
|
+
await runNgCommand(commandArguments);
|
|
86
105
|
|
|
87
|
-
|
|
88
|
-
options.updateBudgets = true;
|
|
89
|
-
options.layout = layoutInfo.layout;
|
|
90
|
-
addTemplate(appName, options, {
|
|
91
|
-
cwd: appPath
|
|
92
|
-
});
|
|
106
|
+
const appPath = path.join(process.cwd(), appName);
|
|
93
107
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
108
|
+
options.resolveConflicts = 'override';
|
|
109
|
+
options.updateBudgets = true;
|
|
110
|
+
options.layout = layout;
|
|
111
|
+
addTemplate(appName, options, {
|
|
112
|
+
cwd: appPath
|
|
98
113
|
});
|
|
114
|
+
|
|
115
|
+
changeMainTs(appPath);
|
|
99
116
|
};
|
|
100
117
|
|
|
101
118
|
const addTemplate = (appName, options, evaluatingOptions) => {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const runCommand = require('../utility/run-command');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const fs = require('fs');
|
|
4
|
-
const getLayoutInfo = require('../utility/prompts/layout')
|
|
4
|
+
const getLayoutInfo = require('../utility/prompts/layout');
|
|
5
|
+
const getTemplateTypeInfo = require('../utility/prompts/typescript');
|
|
5
6
|
const templateCreator = require('../utility/template-creator');
|
|
6
7
|
const packageManager = require('../utility/package-manager');
|
|
7
8
|
const packageJsonUtils = require('../utility/package-json-utils');
|
|
@@ -9,25 +10,39 @@ const modifyJson = require('../utility/modify-json-file');
|
|
|
9
10
|
const insertItemToArray = require('../utility/file-content').insertItemToArray;
|
|
10
11
|
const moduleUtils = require('../utility/module');
|
|
11
12
|
const stringUtils = require('../utility/string');
|
|
13
|
+
const typescriptUtils = require('../utility/typescript-extension');
|
|
12
14
|
const removeFile = require('../utility/file-operations').remove;
|
|
13
|
-
const pathToPagesIndex = path.join(process.cwd(), 'src', 'pages', 'index.js');
|
|
14
15
|
const latestVersions = require('../utility/latest-versions');
|
|
15
16
|
const defaultStyles = [
|
|
16
17
|
'devextreme/dist/css/dx.light.css',
|
|
17
18
|
'devextreme/dist/css/dx.common.css'
|
|
18
19
|
];
|
|
19
20
|
|
|
20
|
-
const
|
|
21
|
+
const getExtension = (appPath) => {
|
|
22
|
+
return fs.existsSync(path.join(appPath, 'src', 'App.tsx')) ? '.tsx' : '.js';
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const pathToPagesIndex = () => {
|
|
26
|
+
const extension = getExtension(process.cwd());
|
|
27
|
+
return path.join(process.cwd(), 'src', 'pages', `index${extension}`);
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const preparePackageJsonForTemplate = (appPath, appName, isTypeScript) => {
|
|
21
31
|
const dependencies = [
|
|
22
32
|
{ name: 'sass', version: '^1.34.1' },
|
|
23
33
|
{ name: 'devextreme-cli', version: latestVersions['devextreme-cli'], dev: true },
|
|
24
|
-
{ name: 'react-router-dom', version: '^
|
|
34
|
+
{ name: 'react-router-dom', version: '^6.3.0' },
|
|
25
35
|
];
|
|
26
36
|
const scripts = [
|
|
27
37
|
{ name: 'build-themes', value: 'devextreme build' },
|
|
28
38
|
{ name: 'postinstall', value: 'npm run build-themes' }
|
|
29
39
|
];
|
|
30
40
|
|
|
41
|
+
if(isTypeScript) {
|
|
42
|
+
dependencies.push({ name: '@types/react-router-dom', version: '^5.1.5' });
|
|
43
|
+
dependencies.push({ name: '@types/react', version: '^17.0.39' });
|
|
44
|
+
}
|
|
45
|
+
|
|
31
46
|
packageJsonUtils.addDependencies(appPath, dependencies);
|
|
32
47
|
packageJsonUtils.updateScripts(appPath, scripts);
|
|
33
48
|
packageJsonUtils.updateName(appPath, appName);
|
|
@@ -41,48 +56,66 @@ const updateJsonPropName = (path, name) => {
|
|
|
41
56
|
});
|
|
42
57
|
};
|
|
43
58
|
|
|
44
|
-
const create = (appName, options) => {
|
|
45
|
-
const
|
|
59
|
+
const create = async(appName, options) => {
|
|
60
|
+
const templateType = await getTemplateTypeInfo(options.template);
|
|
61
|
+
const layoutType = await getLayoutInfo(options.layout);
|
|
46
62
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
const templateOptions = Object.assign({}, options, {
|
|
52
|
-
project: humanizedName,
|
|
53
|
-
layout: stringUtils.classify(layoutInfo.layout)
|
|
54
|
-
});
|
|
55
|
-
modifyIndexHtml(appPath, humanizedName);
|
|
56
|
-
addTemplate(appPath, appName, templateOptions);
|
|
57
|
-
});
|
|
63
|
+
const templateOptions = Object.assign({}, options, {
|
|
64
|
+
project: stringUtils.humanize(appName),
|
|
65
|
+
layout: stringUtils.classify(layoutType),
|
|
66
|
+
isTypeScript: typescriptUtils.isTypeScript(templateType)
|
|
58
67
|
});
|
|
68
|
+
|
|
69
|
+
const commandArguments = ['-p=create-react-app', 'create-react-app', appName];
|
|
70
|
+
if(templateOptions.isTypeScript) {
|
|
71
|
+
commandArguments.push('--template typescript');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
await runCommand('npx', commandArguments);
|
|
75
|
+
|
|
76
|
+
const appPath = path.join(process.cwd(), appName);
|
|
77
|
+
|
|
78
|
+
modifyIndexHtml(appPath, templateOptions.project);
|
|
79
|
+
addTemplate(appPath, appName, templateOptions);
|
|
59
80
|
};
|
|
60
81
|
|
|
61
82
|
const modifyIndexHtml = (appPath, appName) => {
|
|
62
83
|
const indexHtmlPath = path.join(appPath, 'public', 'index.html');
|
|
63
|
-
let htmlContent = fs.readFileSync(indexHtmlPath).toString();
|
|
64
84
|
|
|
85
|
+
let htmlContent = fs.readFileSync(indexHtmlPath).toString();
|
|
65
86
|
htmlContent = htmlContent.replace(/<title>(\w+\s*)+<\/title>/, `<title>${appName}<\/title>`);
|
|
66
87
|
htmlContent = htmlContent.replace('<body>', '<body class="dx-viewport">');
|
|
88
|
+
|
|
67
89
|
fs.writeFileSync(indexHtmlPath, htmlContent);
|
|
68
90
|
};
|
|
69
91
|
|
|
92
|
+
const getCorrectPath = (extension, pathToApp, isTypeScript) => {
|
|
93
|
+
return extension === '.ts' || extension === '.tsx' ? typescriptUtils.setFileExtension(pathToApp, isTypeScript) : pathToApp;
|
|
94
|
+
};
|
|
95
|
+
|
|
70
96
|
const addTemplate = (appPath, appName, templateOptions) => {
|
|
71
|
-
const
|
|
97
|
+
const applicationTemplatePath = path.join(
|
|
98
|
+
templateCreator.getTempaltePath('react'),
|
|
99
|
+
'application'
|
|
100
|
+
);
|
|
101
|
+
|
|
72
102
|
const manifestPath = path.join(appPath, 'public', 'manifest.json');
|
|
73
|
-
const indexPath = path.join(appPath, 'src', 'index.js');
|
|
103
|
+
const indexPath = path.join(appPath, 'src', templateOptions.isTypeScript ? 'index.tsx' : 'index.js');
|
|
104
|
+
|
|
74
105
|
const styles = [
|
|
75
106
|
'./themes/generated/theme.additional.css',
|
|
76
107
|
'./themes/generated/theme.base.css',
|
|
77
108
|
'devextreme/dist/css/dx.common.css'
|
|
78
109
|
];
|
|
79
110
|
|
|
80
|
-
templateCreator.moveTemplateFilesToProject(
|
|
111
|
+
templateCreator.moveTemplateFilesToProject(applicationTemplatePath, appPath, templateOptions, getCorrectPath);
|
|
81
112
|
removeFile(path.join(appPath, 'src', 'App.css'));
|
|
113
|
+
!templateOptions.isTypeScript && removeFile(path.join(appPath, 'src', 'types.js'));
|
|
82
114
|
if(!templateOptions.empty) {
|
|
83
|
-
addSamplePages(appPath);
|
|
115
|
+
addSamplePages(appPath, templateOptions);
|
|
84
116
|
}
|
|
85
|
-
|
|
117
|
+
|
|
118
|
+
preparePackageJsonForTemplate(appPath, appName, templateOptions.isTypeScript);
|
|
86
119
|
updateJsonPropName(manifestPath, appName);
|
|
87
120
|
addPolyfills(packageJsonUtils.getPackageJsonPath(), indexPath);
|
|
88
121
|
install({}, appPath, styles);
|
|
@@ -90,7 +123,8 @@ const addTemplate = (appPath, appName, templateOptions) => {
|
|
|
90
123
|
|
|
91
124
|
const install = (options, appPath, styles) => {
|
|
92
125
|
appPath = appPath ? appPath : process.cwd();
|
|
93
|
-
|
|
126
|
+
|
|
127
|
+
const pathToMainComponent = path.join(appPath, 'src', `App${getExtension(appPath)}`);
|
|
94
128
|
addStylesToApp(pathToMainComponent, styles || defaultStyles);
|
|
95
129
|
packageJsonUtils.addDevextreme(appPath, options.dxversion, 'react');
|
|
96
130
|
|
|
@@ -119,7 +153,7 @@ const getComponentPageName = (viewName) => {
|
|
|
119
153
|
const getNavigationData = (viewName, componentName, icon) => {
|
|
120
154
|
const pagePath = stringUtils.dasherize(viewName);
|
|
121
155
|
return {
|
|
122
|
-
route: `\n {\n path: \'/${pagePath}\',\n
|
|
156
|
+
route: `\n {\n path: \'/${pagePath}\',\n element: ${componentName}\n }`,
|
|
123
157
|
navigation: `\n {\n text: \'${stringUtils.humanize(viewName)}\',\n path: \'/${pagePath}\',\n icon: \'${icon}\'\n }`
|
|
124
158
|
};
|
|
125
159
|
};
|
|
@@ -130,7 +164,7 @@ const createPathToPage = (pageName) => {
|
|
|
130
164
|
|
|
131
165
|
if(!fs.existsSync(pagesPath)) {
|
|
132
166
|
fs.mkdirSync(pagesPath);
|
|
133
|
-
|
|
167
|
+
fs.writeFileSync(pathToPagesIndex(), '');
|
|
134
168
|
}
|
|
135
169
|
|
|
136
170
|
if(!fs.existsSync(newPagePath)) {
|
|
@@ -140,27 +174,37 @@ const createPathToPage = (pageName) => {
|
|
|
140
174
|
return newPagePath;
|
|
141
175
|
};
|
|
142
176
|
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
177
|
+
const addSamplePages = (appPath, templateOptions) => {
|
|
178
|
+
const samplePageTemplatePath = path.join(
|
|
179
|
+
templateCreator.getTempaltePath('react'),
|
|
180
|
+
'sample-pages'
|
|
181
|
+
);
|
|
146
182
|
|
|
147
|
-
const addSamplePages = (appPath) => {
|
|
148
|
-
const templateSourcePath = path.join(__dirname, '..', 'templates', 'react', 'sample-pages');
|
|
149
183
|
const pagesPath = path.join(appPath, 'src', 'pages');
|
|
150
184
|
fs.mkdirSync(pagesPath);
|
|
151
|
-
templateCreator.moveTemplateFilesToProject(
|
|
185
|
+
templateCreator.moveTemplateFilesToProject(samplePageTemplatePath, pagesPath, {
|
|
186
|
+
isTypeScript: templateOptions.isTypeScript
|
|
187
|
+
}, getCorrectPath);
|
|
152
188
|
};
|
|
153
189
|
|
|
154
190
|
const addView = (pageName, options) => {
|
|
191
|
+
const pageTemplatePath = path.join(
|
|
192
|
+
templateCreator.getTempaltePath('react'),
|
|
193
|
+
'page'
|
|
194
|
+
);
|
|
195
|
+
const extension = getExtension(process.cwd());
|
|
196
|
+
|
|
155
197
|
const componentName = getComponentPageName(pageName);
|
|
156
198
|
const pathToPage = createPathToPage(pageName);
|
|
157
|
-
const
|
|
158
|
-
const
|
|
159
|
-
const navigationModulePath = path.join(process.cwd(), 'src', 'app-navigation.js');
|
|
199
|
+
const routingModulePath = path.join(process.cwd(), 'src', `app-routes${extension}`);
|
|
200
|
+
const navigationModulePath = path.join(process.cwd(), 'src', `app-navigation${extension}`);
|
|
160
201
|
const navigationData = getNavigationData(pageName, componentName, options && options.icon || 'folder');
|
|
161
202
|
|
|
162
|
-
|
|
163
|
-
|
|
203
|
+
const getCorrectExtension = (fileExtension) => {
|
|
204
|
+
return fileExtension === '.tsx' ? extension : fileExtension;
|
|
205
|
+
};
|
|
206
|
+
templateCreator.addPageToApp(pageName, pathToPage, pageTemplatePath, getCorrectExtension);
|
|
207
|
+
moduleUtils.insertExport(pathToPagesIndex(), componentName, `./${pageName}/${pageName}`);
|
|
164
208
|
moduleUtils.insertImport(routingModulePath, './pages', componentName);
|
|
165
209
|
insertItemToArray(routingModulePath, navigationData.route);
|
|
166
210
|
insertItemToArray(navigationModulePath, navigationData.navigation);
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const fs = require('fs');
|
|
3
|
-
const getLayoutInfo = require('../utility/prompts/layout')
|
|
4
|
-
const getVersionInfo = require('../utility/prompts/vue-version')
|
|
3
|
+
const getLayoutInfo = require('../utility/prompts/layout');
|
|
4
|
+
const getVersionInfo = require('../utility/prompts/vue-version');
|
|
5
|
+
const getTemplateTypeInfo = require('../utility/prompts/typescript');
|
|
5
6
|
const templateCreator = require('../utility/template-creator');
|
|
6
7
|
const packageManager = require('../utility/package-manager');
|
|
7
8
|
const packageJsonUtils = require('../utility/package-json-utils');
|
|
@@ -9,6 +10,7 @@ const runCommand = require('../utility/run-command');
|
|
|
9
10
|
const insertItemToArray = require('../utility/file-content').insertItemToArray;
|
|
10
11
|
const moduleUtils = require('../utility/module');
|
|
11
12
|
const stringUtils = require('../utility/string');
|
|
13
|
+
const typescriptUtils = require('../utility/typescript-extension');
|
|
12
14
|
const latestVersions = require('../utility/latest-versions');
|
|
13
15
|
const defaultStyles = [
|
|
14
16
|
'devextreme/dist/css/dx.light.css',
|
|
@@ -53,32 +55,42 @@ const preparePackageJsonForTemplate = (appPath, appName, version) => {
|
|
|
53
55
|
packageJsonUtils.updateName(appPath, appName);
|
|
54
56
|
};
|
|
55
57
|
|
|
56
|
-
async function createVueApp(name,
|
|
58
|
+
async function createVueApp(name, templateOptions) {
|
|
59
|
+
const { version, isTypeScript } = templateOptions;
|
|
57
60
|
const argList = ['-p', '@vue/cli', 'vue', 'create', name];
|
|
58
61
|
|
|
59
|
-
if(
|
|
60
|
-
|
|
62
|
+
if(isTypeScript) {
|
|
63
|
+
const presetPath = path.join(__dirname, '..', 'templates-ts', `vue-${version}`);
|
|
64
|
+
|
|
65
|
+
argList.push(`-p "${presetPath}"`);
|
|
61
66
|
} else {
|
|
62
|
-
|
|
67
|
+
if(version === 'v2') {
|
|
68
|
+
argList.push('-p "Default (Vue 2)"');
|
|
69
|
+
} else {
|
|
70
|
+
argList.push('-p "Default (Vue 3)"');
|
|
71
|
+
}
|
|
63
72
|
}
|
|
64
73
|
|
|
65
74
|
return runCommand('npx', argList);
|
|
66
75
|
}
|
|
67
76
|
|
|
68
77
|
const create = async(appName, options) => {
|
|
69
|
-
const
|
|
70
|
-
const
|
|
78
|
+
const version = await getVersionInfo(options.version);
|
|
79
|
+
const templateType = await getTemplateTypeInfo(options.template);
|
|
80
|
+
const layout = await getLayoutInfo(options.layout);
|
|
81
|
+
|
|
82
|
+
const templateOptions = {
|
|
83
|
+
project: stringUtils.humanize(appName),
|
|
84
|
+
layout: layout,
|
|
85
|
+
version: version,
|
|
86
|
+
isTypeScript: typescriptUtils.isTypeScript(templateType)
|
|
87
|
+
};
|
|
71
88
|
|
|
72
|
-
await createVueApp(appName,
|
|
89
|
+
await createVueApp(appName, templateOptions);
|
|
73
90
|
|
|
74
91
|
const appPath = path.join(process.cwd(), appName);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
project: humanizedName,
|
|
78
|
-
layout: layoutInfo.layout
|
|
79
|
-
});
|
|
80
|
-
modifyIndexHtml(appPath, humanizedName);
|
|
81
|
-
addTemplate(appPath, appName, templateOptions, versionInfo.version);
|
|
92
|
+
modifyIndexHtml(appPath, templateOptions.project);
|
|
93
|
+
addTemplate(appPath, appName, templateOptions);
|
|
82
94
|
};
|
|
83
95
|
|
|
84
96
|
const modifyIndexHtml = (appPath, appName) => {
|
|
@@ -90,27 +102,30 @@ const modifyIndexHtml = (appPath, appName) => {
|
|
|
90
102
|
fs.writeFileSync(indexHtmlPath, htmlContent);
|
|
91
103
|
};
|
|
92
104
|
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return fs.existsSync(jsModule) ? jsModule : path.join(appPath, 'src', 'main.ts');
|
|
105
|
+
const getCorrectPath = (extension, pathToApp) => {
|
|
106
|
+
return pathToApp;
|
|
97
107
|
};
|
|
98
108
|
|
|
99
|
-
const addTemplate = (appPath, appName, templateOptions
|
|
109
|
+
const addTemplate = (appPath, appName, templateOptions) => {
|
|
110
|
+
const { version, isTypeScript } = templateOptions;
|
|
111
|
+
|
|
100
112
|
if(!version) {
|
|
101
113
|
version = getVueVersion();
|
|
102
114
|
}
|
|
103
115
|
|
|
104
|
-
const
|
|
116
|
+
const applicationTemplatePath = path.join(
|
|
117
|
+
templateCreator.getTempaltePath(`vue-${version}`, isTypeScript),
|
|
118
|
+
'application'
|
|
119
|
+
);
|
|
105
120
|
const styles = [
|
|
106
121
|
'./themes/generated/theme.additional.css',
|
|
107
122
|
'./themes/generated/theme.base.css',
|
|
108
123
|
'devextreme/dist/css/dx.common.css'
|
|
109
124
|
];
|
|
110
125
|
|
|
111
|
-
templateCreator.moveTemplateFilesToProject(
|
|
126
|
+
templateCreator.moveTemplateFilesToProject(applicationTemplatePath, appPath, templateOptions, getCorrectPath);
|
|
112
127
|
if(!templateOptions.empty) {
|
|
113
|
-
addSamplePages(appPath,
|
|
128
|
+
addSamplePages(appPath, templateOptions);
|
|
114
129
|
}
|
|
115
130
|
preparePackageJsonForTemplate(appPath, appName, version);
|
|
116
131
|
install({}, appPath, styles);
|
|
@@ -125,21 +140,31 @@ const install = (options, appPath, styles) => {
|
|
|
125
140
|
};
|
|
126
141
|
|
|
127
142
|
const addStylesToApp = (appPath, styles) => {
|
|
128
|
-
const
|
|
143
|
+
const isTypeScript = typescriptUtils.isTypeScript(typescriptUtils.getTemplateType('vue'));
|
|
144
|
+
|
|
145
|
+
const mainModulePath = typescriptUtils.setFileExtension(
|
|
146
|
+
path.join(appPath, 'src', 'main.js'),
|
|
147
|
+
isTypeScript
|
|
148
|
+
);
|
|
129
149
|
|
|
130
150
|
styles.forEach(style => {
|
|
131
151
|
moduleUtils.insertImport(mainModulePath, style);
|
|
132
152
|
});
|
|
133
153
|
};
|
|
134
154
|
|
|
135
|
-
const addSamplePages = (appPath,
|
|
155
|
+
const addSamplePages = (appPath, templateOptions) => {
|
|
156
|
+
const { version, isTypeScript } = templateOptions;
|
|
157
|
+
|
|
136
158
|
if(!version) {
|
|
137
159
|
version = getVueVersion();
|
|
138
160
|
}
|
|
139
161
|
|
|
140
|
-
const
|
|
162
|
+
const samplePageTemplatePath = path.join(
|
|
163
|
+
templateCreator.getTempaltePath(`vue-${version}`, isTypeScript),
|
|
164
|
+
'sample-pages'
|
|
165
|
+
);
|
|
141
166
|
const pagesPath = createPathToPage(appPath);
|
|
142
|
-
templateCreator.moveTemplateFilesToProject(
|
|
167
|
+
templateCreator.moveTemplateFilesToProject(samplePageTemplatePath, pagesPath, {}, getCorrectPath);
|
|
143
168
|
};
|
|
144
169
|
|
|
145
170
|
const getComponentPageName = (viewName) => {
|
|
@@ -191,14 +216,26 @@ const createPathToPage = (appPath) => {
|
|
|
191
216
|
|
|
192
217
|
const addView = (pageName, options) => {
|
|
193
218
|
const version = getVueVersion();
|
|
219
|
+
const isTypeScript = typescriptUtils.isTypeScript(typescriptUtils.getTemplateType('vue'));
|
|
220
|
+
|
|
221
|
+
const pageTemplatePath = path.join(
|
|
222
|
+
templateCreator.getTempaltePath(`vue-${version}`, isTypeScript),
|
|
223
|
+
'page'
|
|
224
|
+
);
|
|
225
|
+
|
|
194
226
|
const componentName = getComponentPageName(pageName);
|
|
195
227
|
const pathToPage = createPathToPage(process.cwd());
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
|
|
228
|
+
const routingModulePath = typescriptUtils.setFileExtension(
|
|
229
|
+
path.join(process.cwd(), 'src', 'router.js'),
|
|
230
|
+
isTypeScript
|
|
231
|
+
);
|
|
232
|
+
const navigationModulePath = typescriptUtils.setFileExtension(
|
|
233
|
+
path.join(process.cwd(), 'src', 'app-navigation.js'),
|
|
234
|
+
isTypeScript
|
|
235
|
+
);
|
|
199
236
|
const navigationData = getNavigationData(pageName, componentName, options && options.icon || 'folder', version);
|
|
200
|
-
|
|
201
|
-
templateCreator.addPageToApp(pageName, pathToPage, pageTemplatePath);
|
|
237
|
+
const getCorrectExtension = (fileExtension) => fileExtension;
|
|
238
|
+
templateCreator.addPageToApp(pageName, pathToPage, pageTemplatePath, getCorrectExtension);
|
|
202
239
|
moduleUtils.insertImport(routingModulePath, `./views/${pageName}`, componentName, true);
|
|
203
240
|
insertItemToArray(routingModulePath, navigationData.route);
|
|
204
241
|
insertItemToArray(navigationModulePath, navigationData.navigation);
|
package/src/commands.json
CHANGED
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
}, {
|
|
19
19
|
"name": "--version",
|
|
20
20
|
"description": "Specifies whether to generate a Vue 2 or Vue 3 application. Available values: 2 (default) and 3"
|
|
21
|
+
}, {
|
|
22
|
+
"name": "--template",
|
|
23
|
+
"description": "Create template with typescsript support. Specifies for React & Vue application"
|
|
21
24
|
}]
|
|
22
25
|
}]
|
|
23
26
|
}, {
|
|
File without changes
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Switch, Route<%=^empty%>, Redirect<%=/empty%> } from 'react-router-dom';
|
|
1
|
+
import { Routes, Route, Navigate } from 'react-router-dom';
|
|
3
2
|
import appInfo from './app-info';
|
|
4
3
|
import routes from './app-routes';
|
|
5
4
|
import { <%=layout%> as SideNavBarLayout } from './layouts';
|
|
@@ -8,17 +7,19 @@ import { Footer } from './components';
|
|
|
8
7
|
export default function Content() {
|
|
9
8
|
return (
|
|
10
9
|
<SideNavBarLayout title={appInfo.title}>
|
|
11
|
-
<
|
|
12
|
-
{routes.map(({ path,
|
|
10
|
+
<Routes>
|
|
11
|
+
{routes.map(({ path, element }) => (
|
|
13
12
|
<Route
|
|
14
|
-
exact
|
|
15
13
|
key={path}
|
|
16
14
|
path={path}
|
|
17
|
-
|
|
15
|
+
element={element}
|
|
18
16
|
/>
|
|
19
|
-
))}
|
|
20
|
-
<
|
|
21
|
-
|
|
17
|
+
))}
|
|
18
|
+
<Route
|
|
19
|
+
path='*'
|
|
20
|
+
element={<Navigate to='/home' />}
|
|
21
|
+
/>
|
|
22
|
+
</Routes>
|
|
22
23
|
<Footer>
|
|
23
24
|
Copyright © 2011-{new Date().getFullYear()} {appInfo.title} Inc.
|
|
24
25
|
<br />
|
|
@@ -28,3 +29,4 @@ export default function Content() {
|
|
|
28
29
|
</SideNavBarLayout>
|
|
29
30
|
);
|
|
30
31
|
}
|
|
32
|
+
|