devextreme-cli 1.3.0 → 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.
Files changed (75) hide show
  1. package/index.js +4 -2
  2. package/package.json +8 -3
  3. package/src/application.js +17 -17
  4. package/src/applications/application.angular.js +38 -21
  5. package/src/applications/application.react.js +81 -37
  6. package/src/applications/application.vue.js +73 -37
  7. package/src/commands.json +3 -0
  8. package/src/templates/react/application/src/{App.js → App.tsx} +0 -0
  9. package/src/templates/react/application/src/{Content.js → Content.tsx} +11 -9
  10. package/src/templates/react/application/src/UnauthenticatedContent.tsx +46 -0
  11. package/src/templates/react/application/src/api/{auth.js → auth.tsx} +4 -4
  12. package/src/templates/react/application/src/{app-info.js → app-info.tsx} +0 -0
  13. package/src/templates/react/application/src/{app-navigation.js → app-navigation.tsx} +0 -0
  14. package/src/templates/react/application/src/app-routes.tsx +24 -0
  15. package/src/templates/react/application/src/components/change-password-form/{change-password-form.js → ChangePasswordForm.tsx} +6 -6
  16. package/src/templates/react/application/src/components/create-account-form/{create-account-form.scss → CreateAccountForm.scss} +0 -0
  17. package/src/templates/react/application/src/components/create-account-form/{create-account-form.js → CreateAccountForm.tsx} +7 -7
  18. package/src/templates/react/application/src/components/footer/{footer.scss → Footer.scss} +0 -0
  19. package/src/templates/react/application/src/components/footer/{footer.js → Footer.tsx} +1 -1
  20. package/src/templates/react/application/src/components/header/{header.scss → Header.scss} +0 -0
  21. package/src/templates/react/application/src/components/header/{header.js → Header.tsx} +4 -3
  22. package/src/templates/react/application/src/components/index.tsx +7 -0
  23. package/src/templates/react/application/src/components/login-form/{login-form.scss → LoginForm.scss} +0 -0
  24. package/src/templates/react/application/src/components/login-form/{login-form.js → LoginForm.tsx} +6 -6
  25. package/src/templates/react/application/src/components/reset-password-form/{reset-password-form.scss → ResetPasswordForm.scss} +0 -0
  26. package/src/templates/react/application/src/components/reset-password-form/{reset-password-form.js → ResetPasswordForm.tsx} +7 -7
  27. package/src/templates/react/application/src/components/side-navigation-menu/{side-navigation-menu.scss → SideNavigationMenu.scss} +0 -0
  28. package/src/templates/react/application/src/components/side-navigation-menu/{side-navigation-menu.js → SideNavigationMenu.tsx} +8 -10
  29. package/src/templates/react/application/src/components/user-panel/{user-panel.scss → UserPanel.scss} +0 -0
  30. package/src/templates/react/application/src/components/user-panel/{user-panel.js → UserPanel.tsx} +8 -8
  31. package/src/templates/react/application/src/contexts/{auth.js → auth.tsx} +6 -5
  32. package/src/templates/react/application/src/contexts/navigation.tsx +35 -0
  33. package/src/templates/react/application/src/layouts/{index.js → index.tsx} +0 -0
  34. package/src/templates/react/application/src/layouts/side-nav-inner-toolbar/{side-nav-inner-toolbar.js → side-nav-inner-toolbar.tsx} +12 -9
  35. package/src/templates/react/application/src/layouts/side-nav-outer-toolbar/{side-nav-outer-toolbar.js → side-nav-outer-toolbar.tsx} +11 -10
  36. package/src/templates/react/application/src/layouts/single-card/{single-card.js → single-card.tsx} +2 -1
  37. package/src/templates/react/application/src/{polyfills.js → polyfills.tsx} +0 -0
  38. package/src/templates/react/application/src/types.tsx +53 -0
  39. package/src/templates/react/application/src/utils/{default-user.js → default-user.tsx} +0 -0
  40. package/src/templates/react/application/src/utils/{media-query.js → media-query.tsx} +4 -3
  41. package/src/templates/react/application/src/utils/{patches.js → patches.tsx} +1 -1
  42. package/src/templates/react/page/{page.js → page.tsx} +0 -0
  43. package/src/templates/react/sample-pages/home/{home.js → home.tsx} +0 -0
  44. package/src/templates/react/sample-pages/{index.js → index.tsx} +0 -0
  45. package/src/templates/react/sample-pages/profile/{profile.js → profile.tsx} +0 -0
  46. package/src/templates/react/sample-pages/tasks/{tasks.js → tasks.tsx} +1 -1
  47. package/src/templates/vue-v2/application/devextreme.json +2 -1
  48. package/src/templates/vue-v2/application/src/router.js +3 -3
  49. package/src/templates/vue-v2/sample-pages/{home.vue → home-page.vue} +0 -0
  50. package/src/templates/vue-v2/sample-pages/{profile.vue → profile-page.vue} +0 -0
  51. package/src/templates/vue-v2/sample-pages/{tasks.vue → tasks-page.vue} +0 -0
  52. package/src/templates/vue-v3/application/devextreme.json +2 -1
  53. package/src/templates/vue-v3/application/src/router.js +4 -4
  54. package/src/templates/vue-v3/sample-pages/{home.vue → home-page.vue} +0 -0
  55. package/src/templates/vue-v3/sample-pages/{profile.vue → profile-page.vue} +0 -0
  56. package/src/templates/vue-v3/sample-pages/{tasks.vue → tasks-page.vue} +0 -0
  57. package/src/utility/prompts/layout.js +9 -21
  58. package/src/utility/prompts/prompts.js +24 -8
  59. package/src/utility/prompts/typescript.js +18 -0
  60. package/src/utility/prompts/vue-version.js +9 -21
  61. package/src/utility/run-command.js +5 -2
  62. package/src/utility/template-creator.js +11 -6
  63. package/src/utility/typescript-extension.js +24 -0
  64. package/src/.DS_Store +0 -0
  65. package/src/templates/.DS_Store +0 -0
  66. package/src/templates/react/application/src/UnauthenticatedContent.js +0 -35
  67. package/src/templates/react/application/src/app-routes.js +0 -24
  68. package/src/templates/react/application/src/components/index.js +0 -7
  69. package/src/templates/react/application/src/contexts/navigation.js +0 -34
  70. package/src/templates/vue-v2/.DS_Store +0 -0
  71. package/src/templates/vue-v2/application/.DS_Store +0 -0
  72. package/src/templates/vue-v2/application/src/.DS_Store +0 -0
  73. package/src/templates/vue-v3/.DS_Store +0 -0
  74. package/src/templates/vue-v3/application/.DS_Store +0 -0
  75. package/src/templates/vue-v3/application/src/.DS_Store +0 -0
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
- const run = (commands, options) => {
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.0",
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": "c61a31f44439fe1b0e82449a15c4db8375af34f3"
77
+ "gitHead": "023ac50deaac92bd44a283079f55491f4db30049"
73
78
  }
@@ -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' ].indexOf(command) > -1;
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
- if(commands[1] === 'angular-app') {
19
- angularApplication.create(commands[2] || 'my-app', options);
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
- if(commands[1] === 'vue-app') {
29
- vueApplication.create(commands[2] || 'my-app', options);
30
- return;
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').getLayoutInfo;
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 ngCommandArguments = await hasSutableNgCli() ? [] : ['-p', '@angular/cli'];
36
-
37
- ngCommandArguments.push('ng', ...commandArguments);
38
- return runCommand('npx', ngCommandArguments, evaluatingOptions);
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
- const parsingResult = !stderr && parseNgCliVersion(stdout);
55
- if(parsingResult && parsingResult.compare(minNgCliVersion) < 0) {
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
- getLayoutInfo(options.layout).then(layoutInfo => {
84
- runNgCommand(commandArguments).then(() => {
85
- const appPath = path.join(process.cwd(), appName);
104
+ await runNgCommand(commandArguments);
86
105
 
87
- options.resolveConflicts = 'override';
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
- changeMainTs(appPath);
95
- }).catch((e) => {
96
- console.log(e);
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').getLayoutInfo;
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 preparePackageJsonForTemplate = (appPath, appName) => {
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: '^5.0.0' },
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 commandArguments = ['-p=create-react-app', 'create-react-app', appName];
59
+ const create = async(appName, options) => {
60
+ const templateType = await getTemplateTypeInfo(options.template);
61
+ const layoutType = await getLayoutInfo(options.layout);
46
62
 
47
- getLayoutInfo(options.layout).then((layoutInfo) => {
48
- runCommand('npx', commandArguments).then(() => {
49
- const appPath = path.join(process.cwd(), appName);
50
- const humanizedName = stringUtils.humanize(appName);
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 templateSourcePath = path.join(__dirname, '..', 'templates', 'react', 'application');
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(templateSourcePath, appPath, templateOptions);
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
- preparePackageJsonForTemplate(appPath, appName);
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
- const pathToMainComponent = path.join(appPath, 'src', 'App.js');
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 component: ${componentName}\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
- createPagesIndex();
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 createPagesIndex = () => {
144
- fs.writeFileSync(pathToPagesIndex, '');
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(templateSourcePath, pagesPath, {});
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 pageTemplatePath = path.join(__dirname, '..', 'templates', 'react', 'page');
158
- const routingModulePath = path.join(process.cwd(), 'src', 'app-routes.js');
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
- templateCreator.addPageToApp(pageName, pathToPage, pageTemplatePath);
163
- moduleUtils.insertExport(pathToPagesIndex, componentName, `./${pageName}/${pageName}`);
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').getLayoutInfo;
4
- const getVersionInfo = require('../utility/prompts/vue-version').getVersionInfo;
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,12 +10,13 @@ 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',
15
17
  'devextreme/dist/css/dx.common.css'
16
18
  ];
17
- const defaultVueVersion = 'v2';
19
+ const defaultVueVersion = 'v3';
18
20
 
19
21
  const getVueVersion = () => {
20
22
  const devextremeConfig = require('../utility/devextreme-config').read();
@@ -53,33 +55,42 @@ const preparePackageJsonForTemplate = (appPath, appName, version) => {
53
55
  packageJsonUtils.updateName(appPath, appName);
54
56
  };
55
57
 
56
- async function createVueApp(name, version) {
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(version === defaultVueVersion) {
60
- argList.push('--default');
62
+ if(isTypeScript) {
63
+ const presetPath = path.join(__dirname, '..', 'templates-ts', `vue-${version}`);
64
+
65
+ argList.push(`-p "${presetPath}"`);
61
66
  } else {
62
- argList.push('-p');
63
- argList.push('__default_vue_3__');
67
+ if(version === 'v2') {
68
+ argList.push('-p "Default (Vue 2)"');
69
+ } else {
70
+ argList.push('-p "Default (Vue 3)"');
71
+ }
64
72
  }
65
73
 
66
74
  return runCommand('npx', argList);
67
75
  }
68
76
 
69
77
  const create = async(appName, options) => {
70
- const versionInfo = await getVersionInfo(options.version);
71
- const layoutInfo = await getLayoutInfo(options.layout);
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
+ };
72
88
 
73
- await createVueApp(appName, versionInfo.version);
89
+ await createVueApp(appName, templateOptions);
74
90
 
75
91
  const appPath = path.join(process.cwd(), appName);
76
- const humanizedName = stringUtils.humanize(appName);
77
- const templateOptions = Object.assign({}, options, {
78
- project: humanizedName,
79
- layout: layoutInfo.layout
80
- });
81
- modifyIndexHtml(appPath, humanizedName);
82
- addTemplate(appPath, appName, templateOptions, versionInfo.version);
92
+ modifyIndexHtml(appPath, templateOptions.project);
93
+ addTemplate(appPath, appName, templateOptions);
83
94
  };
84
95
 
85
96
  const modifyIndexHtml = (appPath, appName) => {
@@ -91,27 +102,30 @@ const modifyIndexHtml = (appPath, appName) => {
91
102
  fs.writeFileSync(indexHtmlPath, htmlContent);
92
103
  };
93
104
 
94
- const getMainModulePath = (appPath) => {
95
- const jsModule = path.join(appPath, 'src', 'main.js');
96
-
97
- return fs.existsSync(jsModule) ? jsModule : path.join(appPath, 'src', 'main.ts');
105
+ const getCorrectPath = (extension, pathToApp) => {
106
+ return pathToApp;
98
107
  };
99
108
 
100
- const addTemplate = (appPath, appName, templateOptions, version) => {
109
+ const addTemplate = (appPath, appName, templateOptions) => {
110
+ const { version, isTypeScript } = templateOptions;
111
+
101
112
  if(!version) {
102
113
  version = getVueVersion();
103
114
  }
104
115
 
105
- const templateSourcePath = path.join(__dirname, '..', 'templates', `vue-${version}`, 'application');
116
+ const applicationTemplatePath = path.join(
117
+ templateCreator.getTempaltePath(`vue-${version}`, isTypeScript),
118
+ 'application'
119
+ );
106
120
  const styles = [
107
121
  './themes/generated/theme.additional.css',
108
122
  './themes/generated/theme.base.css',
109
123
  'devextreme/dist/css/dx.common.css'
110
124
  ];
111
125
 
112
- templateCreator.moveTemplateFilesToProject(templateSourcePath, appPath, templateOptions);
126
+ templateCreator.moveTemplateFilesToProject(applicationTemplatePath, appPath, templateOptions, getCorrectPath);
113
127
  if(!templateOptions.empty) {
114
- addSamplePages(appPath, version);
128
+ addSamplePages(appPath, templateOptions);
115
129
  }
116
130
  preparePackageJsonForTemplate(appPath, appName, version);
117
131
  install({}, appPath, styles);
@@ -126,21 +140,31 @@ const install = (options, appPath, styles) => {
126
140
  };
127
141
 
128
142
  const addStylesToApp = (appPath, styles) => {
129
- const mainModulePath = getMainModulePath(appPath);
143
+ const isTypeScript = typescriptUtils.isTypeScript(typescriptUtils.getTemplateType('vue'));
144
+
145
+ const mainModulePath = typescriptUtils.setFileExtension(
146
+ path.join(appPath, 'src', 'main.js'),
147
+ isTypeScript
148
+ );
130
149
 
131
150
  styles.forEach(style => {
132
151
  moduleUtils.insertImport(mainModulePath, style);
133
152
  });
134
153
  };
135
154
 
136
- const addSamplePages = (appPath, version) => {
155
+ const addSamplePages = (appPath, templateOptions) => {
156
+ const { version, isTypeScript } = templateOptions;
157
+
137
158
  if(!version) {
138
159
  version = getVueVersion();
139
160
  }
140
161
 
141
- const templateSourcePath = path.join(__dirname, '..', 'templates', `vue-${version}`, 'sample-pages');
162
+ const samplePageTemplatePath = path.join(
163
+ templateCreator.getTempaltePath(`vue-${version}`, isTypeScript),
164
+ 'sample-pages'
165
+ );
142
166
  const pagesPath = createPathToPage(appPath);
143
- templateCreator.moveTemplateFilesToProject(templateSourcePath, pagesPath, {});
167
+ templateCreator.moveTemplateFilesToProject(samplePageTemplatePath, pagesPath, {}, getCorrectPath);
144
168
  };
145
169
 
146
170
  const getComponentPageName = (viewName) => {
@@ -155,11 +179,11 @@ const getVueRoute = (viewName, componentName, pagePath, version) => {
155
179
  const path = `path: "/${pagePath}"`;
156
180
  const name = `name: "${stringUtils.dasherize(viewName)}"`;
157
181
 
158
- const metaPart = version === defaultVueVersion
182
+ const metaPart = version === 'v2'
159
183
  ? 'meta: { requiresAuth: true }'
160
184
  : 'meta: {\n requiresAuth: true,\n layout: defaultLayout\n }';
161
185
 
162
- const componentPart = version === defaultVueVersion
186
+ const componentPart = version === 'v2'
163
187
  ? `components:\n {\n layout: defaultLayout,\n content: ${componentName}\n }`
164
188
  : `component: ${componentName}`;
165
189
 
@@ -192,14 +216,26 @@ const createPathToPage = (appPath) => {
192
216
 
193
217
  const addView = (pageName, options) => {
194
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
+
195
226
  const componentName = getComponentPageName(pageName);
196
227
  const pathToPage = createPathToPage(process.cwd());
197
- const pageTemplatePath = path.join(__dirname, '..', 'templates', `vue-${version}`, 'page');
198
- const routingModulePath = path.join(process.cwd(), 'src', 'router.js');
199
- const navigationModulePath = path.join(process.cwd(), 'src', 'app-navigation.js');
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
+ );
200
236
  const navigationData = getNavigationData(pageName, componentName, options && options.icon || 'folder', version);
201
-
202
- templateCreator.addPageToApp(pageName, pathToPage, pageTemplatePath);
237
+ const getCorrectExtension = (fileExtension) => fileExtension;
238
+ templateCreator.addPageToApp(pageName, pathToPage, pageTemplatePath, getCorrectExtension);
203
239
  moduleUtils.insertImport(routingModulePath, `./views/${pageName}`, componentName, true);
204
240
  insertItemToArray(routingModulePath, navigationData.route);
205
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
  }, {