devextreme-cli 1.10.1 → 1.11.0-beta.0
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/package.json +7 -5
- package/src/application.js +40 -20
- package/src/applications/application.angular.js +42 -9
- package/src/applications/application.nextjs.js +231 -0
- package/src/applications/application.react.js +41 -25
- package/src/applications/application.vue.js +23 -6
- package/src/templates/nextjs/application/.env +1 -0
- package/src/templates/nextjs/application/devextreme.json +63 -0
- package/src/templates/nextjs/application/next.config.mjs +32 -0
- package/src/templates/nextjs/application/src/app/actions/auth.ts +76 -0
- package/src/templates/nextjs/application/src/app/auth/[type]/page.tsx +49 -0
- package/src/templates/nextjs/application/src/app/layout.tsx +17 -0
- package/src/templates/nextjs/application/src/app/lib/session.ts +47 -0
- package/src/templates/nextjs/application/src/app/pages/layout.tsx +18 -0
- package/src/templates/nextjs/application/src/app-info.tsx +5 -0
- package/src/templates/nextjs/application/src/app-navigation.tsx +21 -0
- package/src/templates/nextjs/application/src/components/change-password-form/ChangePasswordForm.tsx +86 -0
- package/src/templates/nextjs/application/src/components/create-account-form/CreateAccountForm.scss +19 -0
- package/src/templates/nextjs/application/src/components/create-account-form/CreateAccountForm.tsx +107 -0
- package/src/templates/nextjs/application/src/components/footer/Footer.scss +12 -0
- package/src/templates/nextjs/application/src/components/footer/Footer.tsx +5 -0
- package/src/templates/nextjs/application/src/components/header/Header.scss +40 -0
- package/src/templates/nextjs/application/src/components/header/Header.tsx +38 -0
- package/src/templates/nextjs/application/src/components/index.tsx +7 -0
- package/src/templates/nextjs/application/src/components/login-form/LoginForm.scss +12 -0
- package/src/templates/nextjs/application/src/components/login-form/LoginForm.tsx +101 -0
- package/src/templates/nextjs/application/src/components/reset-password-form/ResetPasswordForm.scss +12 -0
- package/src/templates/nextjs/application/src/components/reset-password-form/ResetPasswordForm.tsx +78 -0
- package/src/templates/nextjs/application/src/components/side-navigation-menu/SideNavigationMenu.scss +71 -0
- package/src/templates/nextjs/application/src/components/side-navigation-menu/SideNavigationMenu.tsx +88 -0
- package/src/templates/nextjs/application/src/components/theme-switcher/ThemeSwitcher.tsx +21 -0
- package/src/templates/nextjs/application/src/components/user-panel/UserPanel.scss +51 -0
- package/src/templates/nextjs/application/src/components/user-panel/UserPanel.tsx +55 -0
- package/src/templates/nextjs/application/src/dx-styles.scss +106 -0
- package/src/templates/nextjs/application/src/layouts/index.tsx +3 -0
- package/src/templates/nextjs/application/src/layouts/side-nav-inner-toolbar/side-nav-inner-toolbar.scss +17 -0
- package/src/templates/nextjs/application/src/layouts/side-nav-inner-toolbar/side-nav-inner-toolbar.tsx +133 -0
- package/src/templates/nextjs/application/src/layouts/side-nav-outer-toolbar/side-nav-outer-toolbar.scss +10 -0
- package/src/templates/nextjs/application/src/layouts/side-nav-outer-toolbar/side-nav-outer-toolbar.tsx +119 -0
- package/src/templates/nextjs/application/src/layouts/single-card/single-card.scss +42 -0
- package/src/templates/nextjs/application/src/layouts/single-card/single-card.tsx +16 -0
- package/src/templates/nextjs/application/src/middleware.ts +46 -0
- package/src/templates/nextjs/application/src/theme.tsx +66 -0
- package/src/templates/nextjs/application/src/themes/metadata.additional.dark.json +11 -0
- package/src/templates/nextjs/application/src/themes/metadata.additional.json +11 -0
- package/src/templates/nextjs/application/src/themes/metadata.base.dark.json +8 -0
- package/src/templates/nextjs/application/src/themes/metadata.base.json +7 -0
- package/src/templates/nextjs/application/src/types.tsx +60 -0
- package/src/templates/nextjs/application/src/utils/default-user.tsx +7 -0
- package/src/templates/nextjs/application/src/utils/media-query.tsx +56 -0
- package/src/templates/nextjs/application/src/variables.scss +53 -0
- package/src/templates/nextjs/page/page.scss +0 -0
- package/src/templates/nextjs/page/page.tsx +13 -0
- package/src/templates/nextjs/sample-pages/home/home.scss +37 -0
- package/src/templates/nextjs/sample-pages/home/page.tsx +101 -0
- package/src/templates/nextjs/sample-pages/profile/page.tsx +61 -0
- package/src/templates/nextjs/sample-pages/profile/profile.scss +19 -0
- package/src/templates/nextjs/sample-pages/tasks/page.tsx +112 -0
- package/src/templates/nextjs/sample-pages/tasks/tasks.scss +3 -0
- package/src/templates/react/application/src/App.tsx +0 -1
- package/src/templates/react/application/src/components/change-password-form/ChangePasswordForm.tsx +2 -2
- package/src/templates/react/application/src/components/create-account-form/CreateAccountForm.scss +0 -2
- package/src/templates/react/application/src/components/create-account-form/CreateAccountForm.tsx +2 -2
- package/src/templates/react/application/src/components/footer/Footer.tsx +0 -1
- package/src/templates/react/application/src/components/header/Header.scss +1 -1
- package/src/templates/react/application/src/components/header/Header.tsx +0 -1
- package/src/templates/react/application/src/components/login-form/LoginForm.scss +0 -2
- package/src/templates/react/application/src/components/login-form/LoginForm.tsx +2 -2
- package/src/templates/react/application/src/components/reset-password-form/ResetPasswordForm.scss +0 -2
- package/src/templates/react/application/src/components/reset-password-form/ResetPasswordForm.tsx +2 -2
- package/src/templates/react/application/src/components/side-navigation-menu/SideNavigationMenu.scss +3 -3
- package/src/templates/react/application/src/components/side-navigation-menu/SideNavigationMenu.tsx +1 -1
- package/src/templates/react/application/src/components/theme-switcher/ThemeSwitcher.tsx +1 -1
- package/src/templates/react/application/src/components/user-panel/UserPanel.tsx +1 -1
- package/src/templates/react/application/src/dx-styles.scss +5 -3
- package/src/templates/react/application/src/layouts/side-nav-inner-toolbar/side-nav-inner-toolbar.tsx +11 -5
- package/src/templates/react/application/src/layouts/side-nav-outer-toolbar/side-nav-outer-toolbar.tsx +11 -5
- package/src/templates/react/application/src/layouts/single-card/single-card.scss +0 -2
- package/src/templates/react/application/src/layouts/single-card/single-card.tsx +0 -1
- package/src/templates/react/application/src/types.tsx +1 -2
- package/src/templates/react/application/src/utils/media-query.tsx +3 -1
- package/src/templates/react/application/src/utils/patches.scss +4 -4
- package/src/templates/react/sample-pages/home/home.scss +0 -2
- package/src/templates/react/sample-pages/home/home.tsx +1 -1
- package/src/templates/react/sample-pages/tasks/tasks.tsx +4 -4
- package/src/templates/vue-v3/application/src/components/header-toolbar.vue +1 -1
- package/src/templates/vue-v3/application/src/dx-styles.scss +4 -3
- package/src/templates/vue-v3/sample-pages/tasks-page.vue +1 -1
- package/src/utility/extract-deps-version-tag.js +13 -0
- package/src/utility/latest-versions.js +6 -3
- package/src/utility/module.js +11 -3
- package/src/utility/prompts/react-app-type.js +17 -0
- package/src/utility/prompts/transpiler.js +17 -0
- package/src/utility/run-command.js +10 -2
- package/src/utility/template-creator.js +8 -4
- package/src/utility/typescript-extension.js +1 -1
- package/src/templates/cra-template/LICENSE +0 -21
- package/src/templates/cra-template/README.md +0 -10
- package/src/templates/cra-template/package.json +0 -26
- package/src/templates/cra-template/template/README.md +0 -70
- package/src/templates/cra-template/template/gitignore +0 -23
- package/src/templates/cra-template/template/public/favicon.ico +0 -0
- package/src/templates/cra-template/template/public/index.html +0 -43
- package/src/templates/cra-template/template/src/App.css +0 -38
- package/src/templates/cra-template/template/src/App.js +0 -25
- package/src/templates/cra-template/template/src/App.test.js +0 -9
- package/src/templates/cra-template/template/src/index.js +0 -17
- package/src/templates/cra-template/template/src/logo.svg +0 -1
- package/src/templates/cra-template/template/src/reportWebVitals.js +0 -13
- package/src/templates/cra-template/template/src/setupTests.js +0 -5
- package/src/templates/cra-template/template.json +0 -14
- package/src/templates/cra-template-typescript/LICENSE +0 -21
- package/src/templates/cra-template-typescript/README.md +0 -20
- package/src/templates/cra-template-typescript/package.json +0 -27
- package/src/templates/cra-template-typescript/template/README.md +0 -46
- package/src/templates/cra-template-typescript/template/gitignore +0 -23
- package/src/templates/cra-template-typescript/template/public/index.html +0 -43
- package/src/templates/cra-template-typescript/template/src/App.css +0 -38
- package/src/templates/cra-template-typescript/template/src/App.test.tsx +0 -10
- package/src/templates/cra-template-typescript/template/src/App.tsx +0 -26
- package/src/templates/cra-template-typescript/template/src/index.tsx +0 -19
- package/src/templates/cra-template-typescript/template/src/logo.svg +0 -1
- package/src/templates/cra-template-typescript/template/src/reportWebVitals.ts +0 -13
- package/src/templates/cra-template-typescript/template/src/setupTests.ts +0 -5
- package/src/templates/cra-template-typescript/template.json +0 -19
- package/src/templates/react/application/src/App.test.tsx +0 -13
- package/src/templates/react/application/src/matchMediaMock.tsx +0 -14
- package/src/templates/react/application/src/polyfills.tsx +0 -2
- package/src/utility/extract-tooling-version.js +0 -13
- /package/src/templates/{cra-template-typescript/template → nextjs/application}/public/logo192.png +0 -0
- /package/src/templates/{cra-template-typescript/template → nextjs/application}/public/logo512.png +0 -0
- /package/src/templates/{cra-template-typescript/template → nextjs/application}/public/manifest.json +0 -0
- /package/src/templates/{cra-template-typescript/template → nextjs/application}/public/robots.txt +0 -0
- /package/src/templates/{cra-template-typescript/template → nextjs/application}/src/index.css +0 -0
- /package/src/templates/{cra-template-typescript/template → react/application}/public/favicon.ico +0 -0
- /package/src/templates/{cra-template/template → react/application}/public/logo192.png +0 -0
- /package/src/templates/{cra-template/template → react/application}/public/logo512.png +0 -0
- /package/src/templates/{cra-template/template → react/application}/public/manifest.json +0 -0
- /package/src/templates/{cra-template/template → react/application}/public/robots.txt +0 -0
- /package/src/templates/{cra-template/template → react/application}/src/index.css +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devextreme-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0-beta.0",
|
|
4
4
|
"description": "DevExtreme CLI",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"devexpress",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"minimist": "^1.2.8",
|
|
44
44
|
"mustache": "^3.2.1",
|
|
45
45
|
"prompts": "^2.4.2",
|
|
46
|
-
"sass": "^1.
|
|
46
|
+
"sass": "^1.85.1",
|
|
47
47
|
"semver": "^5.7.2",
|
|
48
48
|
"strip-bom": "^4.0.0"
|
|
49
49
|
},
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"@typescript-eslint/eslint-plugin": "^4.33.0",
|
|
52
52
|
"@typescript-eslint/parser": "^4.33.0",
|
|
53
53
|
"babel-eslint": "^10.1.0",
|
|
54
|
+
"create-vite": "6.3.1",
|
|
54
55
|
"cross-env": "^5.2.1",
|
|
55
56
|
"eslint": "^7.32.0",
|
|
56
57
|
"eslint-config-angular": "^0.5.0",
|
|
@@ -58,7 +59,7 @@
|
|
|
58
59
|
"eslint-plugin-angular": "^4.1.0",
|
|
59
60
|
"eslint-plugin-jest": "^22.21.0",
|
|
60
61
|
"eslint-plugin-prettier": "^4.2.1",
|
|
61
|
-
"eslint-plugin-react": "^7.37.
|
|
62
|
+
"eslint-plugin-react": "^7.37.4",
|
|
62
63
|
"eslint-plugin-react-hooks": "^4.6.2",
|
|
63
64
|
"eslint-plugin-unused-imports": "^1.1.5",
|
|
64
65
|
"eslint-plugin-vue": "^7.20.0",
|
|
@@ -70,7 +71,8 @@
|
|
|
70
71
|
"tree-kill": "^1.2.2",
|
|
71
72
|
"tree-kill-promise": "^1.0.12",
|
|
72
73
|
"typescript": "^4.0.2",
|
|
73
|
-
"typescript-eslint-parser": "^22.0.0"
|
|
74
|
+
"typescript-eslint-parser": "^22.0.0",
|
|
75
|
+
"wait-on": "8.0.0"
|
|
74
76
|
},
|
|
75
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "12a211ead8510e78eb1f33b6a34664823d73a4a7"
|
|
76
78
|
}
|
package/src/application.js
CHANGED
|
@@ -1,12 +1,34 @@
|
|
|
1
1
|
const angularApplication = require('./applications/application.angular');
|
|
2
2
|
const reactApplication = require('./applications/application.react');
|
|
3
|
+
const nextjsApplication = require('./applications/application.nextjs');
|
|
3
4
|
const vueApplication = require('./applications/application.vue');
|
|
5
|
+
const getReactAppType = require('./utility/prompts/react-app-type');
|
|
4
6
|
const printHelp = require('./help').printHelp;
|
|
5
7
|
|
|
6
8
|
const isApplicationCommand = (command) => {
|
|
7
9
|
return [ 'new', 'add' ].includes(command);
|
|
8
10
|
};
|
|
9
11
|
|
|
12
|
+
const handleWrongAppType = (appType, command) => {
|
|
13
|
+
console.error(`The '${appType}' application type is not valid`);
|
|
14
|
+
printHelp(command);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const createReact = async(appName, options, command) => {
|
|
18
|
+
const reactAppType = await getReactAppType(options['app-type']);
|
|
19
|
+
|
|
20
|
+
switch(reactAppType) {
|
|
21
|
+
case 'vite':
|
|
22
|
+
await reactApplication.create(appName, options);
|
|
23
|
+
return;
|
|
24
|
+
case 'nextjs':
|
|
25
|
+
await nextjsApplication.create(appName, options);
|
|
26
|
+
return;
|
|
27
|
+
default:
|
|
28
|
+
handleWrongAppType(reactAppType, command);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
|
|
10
32
|
const run = async(commands, options, devextremeConfig) => {
|
|
11
33
|
if(!commands[1]) {
|
|
12
34
|
console.error('Command is incomplete. Please specify parameters.');
|
|
@@ -23,15 +45,15 @@ const run = async(commands, options, devextremeConfig) => {
|
|
|
23
45
|
await angularApplication.create(appName, options);
|
|
24
46
|
return;
|
|
25
47
|
case 'react-app':
|
|
26
|
-
await
|
|
48
|
+
await createReact(appName, options, commands[0]);
|
|
27
49
|
return;
|
|
28
50
|
case 'vue-app':
|
|
29
51
|
await vueApplication.create(appName, options);
|
|
30
52
|
return;
|
|
31
53
|
default:
|
|
32
|
-
|
|
33
|
-
printHelp(commands[0]);
|
|
54
|
+
handleWrongAppType(app, commands[0]);
|
|
34
55
|
}
|
|
56
|
+
|
|
35
57
|
} else {
|
|
36
58
|
if(commands[0] === 'add') {
|
|
37
59
|
if(commands[1] === 'devextreme-angular') {
|
|
@@ -40,7 +62,12 @@ const run = async(commands, options, devextremeConfig) => {
|
|
|
40
62
|
}
|
|
41
63
|
|
|
42
64
|
if(commands[1] === 'devextreme-react') {
|
|
43
|
-
|
|
65
|
+
if(nextjsApplication.isNextJsApp()) {
|
|
66
|
+
nextjsApplication.install(options);
|
|
67
|
+
} else {
|
|
68
|
+
reactApplication.install(options);
|
|
69
|
+
}
|
|
70
|
+
|
|
44
71
|
return;
|
|
45
72
|
}
|
|
46
73
|
|
|
@@ -54,23 +81,16 @@ const run = async(commands, options, devextremeConfig) => {
|
|
|
54
81
|
return;
|
|
55
82
|
}
|
|
56
83
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if(commands[1] === 'view') {
|
|
66
|
-
reactApplication.addView(commands[2], options);
|
|
67
|
-
} else {
|
|
68
|
-
console.error('Invalid command');
|
|
69
|
-
printHelp(commands[0]);
|
|
70
|
-
}
|
|
71
|
-
} else if(devextremeConfig.applicationEngine === 'vue') {
|
|
84
|
+
const app = {
|
|
85
|
+
'angular': angularApplication,
|
|
86
|
+
'react': reactApplication,
|
|
87
|
+
'nextjs': nextjsApplication,
|
|
88
|
+
'vue': vueApplication,
|
|
89
|
+
}[devextremeConfig.applicationEngine];
|
|
90
|
+
|
|
91
|
+
if(app) {
|
|
72
92
|
if(commands[1] === 'view') {
|
|
73
|
-
|
|
93
|
+
app.addView(commands[2], options);
|
|
74
94
|
} else {
|
|
75
95
|
console.error('Invalid command');
|
|
76
96
|
printHelp(commands[0]);
|
|
@@ -7,10 +7,13 @@ const fs = require('fs');
|
|
|
7
7
|
const dasherize = require('../utility/string').dasherize;
|
|
8
8
|
const ngVersion = require('../utility/ng-version');
|
|
9
9
|
const latestVersions = require('../utility/latest-versions');
|
|
10
|
-
const {
|
|
10
|
+
const { extractDepsVersionTag, depsVersionTagOptionName } = require('../utility/extract-deps-version-tag');
|
|
11
|
+
const { getPackageJsonPath } = require('../utility/package-json-utils');
|
|
12
|
+
const modifyJson = require('../utility/modify-json-file');
|
|
11
13
|
const schematicsVersion = latestVersions['devextreme-schematics'] || 'latest';
|
|
12
14
|
|
|
13
15
|
const minNgCliVersion = new semver('17.0.0');
|
|
16
|
+
const ngCliWithZoneless = new semver('20.0.0');
|
|
14
17
|
|
|
15
18
|
async function runSchematicCommand(schematicCommand, options, evaluatingOptions) {
|
|
16
19
|
const collectionName = 'devextreme-schematics';
|
|
@@ -27,7 +30,7 @@ async function runSchematicCommand(schematicCommand, options, evaluatingOptions)
|
|
|
27
30
|
|
|
28
31
|
const commandArguments = ['g', `${collectionName}:${schematicCommand}`];
|
|
29
32
|
|
|
30
|
-
const { [
|
|
33
|
+
const { [depsVersionTagOptionName]: _, ...optionsToArguments } = options; // eslint-disable-line no-unused-vars
|
|
31
34
|
for(let option in optionsToArguments) {
|
|
32
35
|
commandArguments.push(`--${dasherize(option)}=${options[option]}`);
|
|
33
36
|
}
|
|
@@ -37,12 +40,13 @@ async function runSchematicCommand(schematicCommand, options, evaluatingOptions)
|
|
|
37
40
|
|
|
38
41
|
async function runNgCommand(commandArguments, commandOptions, commandConfig) {
|
|
39
42
|
const hasNg = await hasSutableNgCli();
|
|
40
|
-
const
|
|
41
|
-
const npmCommandName = hasNg && !
|
|
43
|
+
const depsVersionTag = extractDepsVersionTag(commandOptions);
|
|
44
|
+
const npmCommandName = hasNg && !depsVersionTag ? 'ng' : 'npx';
|
|
42
45
|
const [minCliLtsVersion] = minNgCliVersion.version.split('.');
|
|
43
|
-
|
|
46
|
+
|
|
47
|
+
const ngCommandArguments = hasNg && !depsVersionTag
|
|
44
48
|
? []
|
|
45
|
-
: ['-p', `@angular/cli
|
|
49
|
+
: ['-p', `@angular/cli@${depsVersionTag || `v${minCliLtsVersion}-lts`}`, 'ng'];
|
|
46
50
|
|
|
47
51
|
ngCommandArguments.push(...commandArguments);
|
|
48
52
|
return runCommand(npmCommandName, ngCommandArguments, commandConfig);
|
|
@@ -60,6 +64,7 @@ function localPackageExists(packageName) {
|
|
|
60
64
|
|
|
61
65
|
const hasSutableNgCli = async() => {
|
|
62
66
|
const localVersion = ngVersion.getLocalNgVersion();
|
|
67
|
+
|
|
63
68
|
if(!localVersion) {
|
|
64
69
|
return false;
|
|
65
70
|
}
|
|
@@ -74,8 +79,28 @@ const install = async(options) => {
|
|
|
74
79
|
});
|
|
75
80
|
};
|
|
76
81
|
|
|
82
|
+
const bumpAngular = (appPath, versionTag) => {
|
|
83
|
+
modifyJson(getPackageJsonPath(appPath), ({ dependencies, devDependencies, ...rest }) => {
|
|
84
|
+
const bump = (section) => {
|
|
85
|
+
for(const depName in section) {
|
|
86
|
+
section[depName] = depName.startsWith('@angular') ? versionTag : section[depName];
|
|
87
|
+
}
|
|
88
|
+
return section;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
dependencies: bump(dependencies),
|
|
93
|
+
devDependencies: bump(devDependencies),
|
|
94
|
+
...rest,
|
|
95
|
+
};
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
};
|
|
99
|
+
|
|
77
100
|
const create = async(appName, options) => {
|
|
78
101
|
const layout = await getLayoutInfo(options.layout);
|
|
102
|
+
const depsVersionTag = extractDepsVersionTag(options);
|
|
103
|
+
const currentNgVersion = ngVersion.getNgCliVersion().version;
|
|
79
104
|
|
|
80
105
|
const commandArguments = [
|
|
81
106
|
'new',
|
|
@@ -84,14 +109,22 @@ const create = async(appName, options) => {
|
|
|
84
109
|
'--routing=false',
|
|
85
110
|
'--skip-tests=true',
|
|
86
111
|
'--skip-install=true',
|
|
87
|
-
'--standalone=
|
|
112
|
+
'--standalone=true',
|
|
88
113
|
'--ssr=false'
|
|
89
114
|
];
|
|
90
115
|
|
|
116
|
+
if(ngCliWithZoneless.compare(currentNgVersion) <= 0) {
|
|
117
|
+
commandArguments.push('--zoneless=false');
|
|
118
|
+
}
|
|
119
|
+
|
|
91
120
|
await runNgCommand(commandArguments, options);
|
|
92
121
|
|
|
93
122
|
const appPath = path.join(process.cwd(), appName);
|
|
94
123
|
|
|
124
|
+
if(depsVersionTag) {
|
|
125
|
+
bumpAngular(appPath, depsVersionTag);
|
|
126
|
+
}
|
|
127
|
+
|
|
95
128
|
options.resolveConflicts = 'override';
|
|
96
129
|
options.updateBudgets = true;
|
|
97
130
|
options.layout = layout;
|
|
@@ -125,9 +158,9 @@ const changeMainTs = (appPath) => {
|
|
|
125
158
|
moduleWorker.insertImport(filePath, 'devextreme/ui/themes', 'themes', true);
|
|
126
159
|
|
|
127
160
|
const fileContent = fs.readFileSync(filePath).toString();
|
|
128
|
-
const bootstrapPattern = /
|
|
161
|
+
const bootstrapPattern = /bootstrapApplication\([^)]+\)/;
|
|
129
162
|
const firstChaptStr = fileContent.match(bootstrapPattern)[0];
|
|
130
|
-
const lastChaptStr = '.catch(err => console.error(err));';
|
|
163
|
+
const lastChaptStr = '.catch((err) => console.error(err));';
|
|
131
164
|
|
|
132
165
|
fs.writeFileSync(
|
|
133
166
|
filePath,
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
const runCommand = require('../utility/run-command');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const getLayoutInfo = require('../utility/prompts/layout');
|
|
5
|
+
const getTemplateTypeInfo = require('../utility/prompts/typescript');
|
|
6
|
+
const templateCreator = require('../utility/template-creator');
|
|
7
|
+
const packageManager = require('../utility/package-manager');
|
|
8
|
+
const packageJsonUtils = require('../utility/package-json-utils');
|
|
9
|
+
const insertItemToArray = require('../utility/file-content').insertItemToArray;
|
|
10
|
+
const stringUtils = require('../utility/string');
|
|
11
|
+
const typescriptUtils = require('../utility/typescript-extension');
|
|
12
|
+
const removeFile = require('../utility/file-operations').remove;
|
|
13
|
+
const latestVersions = require('../utility/latest-versions');
|
|
14
|
+
const { extractDepsVersionTag } = require('../utility/extract-deps-version-tag');
|
|
15
|
+
const {
|
|
16
|
+
updateJsonPropName,
|
|
17
|
+
bumpReact,
|
|
18
|
+
getCorrectPath,
|
|
19
|
+
addStylesToApp,
|
|
20
|
+
getComponentPageName,
|
|
21
|
+
} = require('./application.react');
|
|
22
|
+
|
|
23
|
+
const defaultStyles = [
|
|
24
|
+
'devextreme/dist/css/dx.light.css'
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
const isNextJsApp = () => {
|
|
28
|
+
const appPath = process.cwd();
|
|
29
|
+
|
|
30
|
+
return fs.existsSync(path.join(appPath, 'next.config.ts')) || fs.existsSync(path.join(appPath, 'next.config.mjs'));
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const isTsApp = (appPath) => {
|
|
34
|
+
return fs.existsSync(path.join(appPath, 'next.config.ts'));
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const getExtension = (appPath) => {
|
|
38
|
+
return fs.existsSync(path.join(appPath, 'src/app', 'layout.tsx')) ? '.tsx' : '.jsx';
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const pathToPagesIndex = () => {
|
|
42
|
+
const extension = getExtension(process.cwd());
|
|
43
|
+
return path.join(process.cwd(), 'src', 'views', `index${extension}`);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const preparePackageJsonForTemplate = (appPath, appName) => {
|
|
47
|
+
const dependencies = [
|
|
48
|
+
{ name: 'devextreme-cli', version: latestVersions['devextreme-cli'], dev: true },
|
|
49
|
+
{ name: 'jose', version: latestVersions['jose'] },
|
|
50
|
+
];
|
|
51
|
+
const scripts = [
|
|
52
|
+
{ name: 'build-themes', value: 'devextreme build' },
|
|
53
|
+
{ name: 'postinstall', value: 'npm run build-themes' }
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
packageJsonUtils.addDependencies(appPath, dependencies);
|
|
57
|
+
packageJsonUtils.updateScripts(appPath, scripts);
|
|
58
|
+
packageJsonUtils.updateName(appPath, appName);
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const create = async(appName, options) => {
|
|
62
|
+
const templateType = await getTemplateTypeInfo(options.template);
|
|
63
|
+
const layoutType = await getLayoutInfo(options.layout);
|
|
64
|
+
|
|
65
|
+
const templateOptions = Object.assign({}, options, {
|
|
66
|
+
project: stringUtils.humanize(appName),
|
|
67
|
+
layout: stringUtils.classify(layoutType),
|
|
68
|
+
isTypeScript: typescriptUtils.isTypeScript(templateType)
|
|
69
|
+
});
|
|
70
|
+
const depsVersionTag = extractDepsVersionTag(options);
|
|
71
|
+
|
|
72
|
+
let commandArguments = [`-p=create-next-app@${depsVersionTag || latestVersions['create-next-app']}`, 'create-next-app', appName];
|
|
73
|
+
|
|
74
|
+
commandArguments = [
|
|
75
|
+
...commandArguments,
|
|
76
|
+
`${templateOptions.isTypeScript ? '--typescript' : '--javascript'}`,
|
|
77
|
+
'--eslint',
|
|
78
|
+
'--no-tailwind',
|
|
79
|
+
'--src-dir',
|
|
80
|
+
'--app',
|
|
81
|
+
'--no-turbopack',
|
|
82
|
+
'--import-alias "@/*"',
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
await runCommand('npx', commandArguments);
|
|
86
|
+
|
|
87
|
+
const appPath = path.join(process.cwd(), appName);
|
|
88
|
+
|
|
89
|
+
if(depsVersionTag) {
|
|
90
|
+
bumpReact(appPath, depsVersionTag, templateOptions.isTypeScript);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
addTemplate(appPath, appName, templateOptions);
|
|
94
|
+
modifyAppFiles(appPath, templateOptions);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const modifyAppFiles = (appPath, { project, isTypeScript }) => {
|
|
98
|
+
const entryFilePath = path.join(appPath, `src/app/layout.${isTypeScript ? 'tsx' : 'jsx'}`);
|
|
99
|
+
|
|
100
|
+
let content = fs.readFileSync(entryFilePath).toString();
|
|
101
|
+
content = content.replace(/<title>[^<]+<\/title>/, `<title>${project}<\/title>`);
|
|
102
|
+
|
|
103
|
+
fs.writeFileSync(entryFilePath, content);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const addTemplate = (appPath, appName, templateOptions) => {
|
|
107
|
+
const applicationTemplatePath = path.join(
|
|
108
|
+
templateCreator.getTempaltePath('nextjs'),
|
|
109
|
+
'application'
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const manifestPath = path.join(appPath, 'public', 'manifest.json');
|
|
113
|
+
|
|
114
|
+
const styles = [
|
|
115
|
+
'../dx-styles.scss',
|
|
116
|
+
'../themes/generated/theme.additional.css',
|
|
117
|
+
'../themes/generated/theme.additional.dark.css',
|
|
118
|
+
'../themes/generated/theme.base.css',
|
|
119
|
+
'../themes/generated/theme.base.dark.css',
|
|
120
|
+
'devextreme/dist/css/dx.common.css'
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
templateCreator.moveTemplateFilesToProject(applicationTemplatePath, appPath, templateOptions, getCorrectPath);
|
|
124
|
+
|
|
125
|
+
!templateOptions.isTypeScript && removeFile(path.join(appPath, 'src', 'types.jsx'));
|
|
126
|
+
removeFile(path.join(appPath, 'src/app', 'page.js'));
|
|
127
|
+
removeFile(path.join(appPath, 'src/app', 'layout.js'));
|
|
128
|
+
removeFile(path.join(appPath, 'src/app', 'globals.scss'));
|
|
129
|
+
|
|
130
|
+
if(!templateOptions.empty) {
|
|
131
|
+
addSamplePages(appPath, templateOptions);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
preparePackageJsonForTemplate(appPath, appName, templateOptions.isTypeScript);
|
|
135
|
+
updateJsonPropName(manifestPath, appName);
|
|
136
|
+
install({ isTypeScript: templateOptions.isTypeScript }, appPath, styles);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const getEntryFilePath = (options, appPath) => {
|
|
140
|
+
const extension = options.isTypeScript || isTsApp(appPath) ? 'ts' : 'js';
|
|
141
|
+
const srcFolder = fs.existsSync(path.join(appPath, 'src')) ? 'src' : '';
|
|
142
|
+
const isAppRouterApp = fs.existsSync(path.join(appPath, srcFolder, 'app')) && fs.lstatSync(appPath).isDirectory();
|
|
143
|
+
|
|
144
|
+
const entryFilePath = isAppRouterApp
|
|
145
|
+
? path.join('app', `layout.${extension}`)
|
|
146
|
+
: path.join('pages', `_app.${extension}`);
|
|
147
|
+
|
|
148
|
+
const jsx = fs.existsSync(path.join(appPath, srcFolder, entryFilePath + 'x')) ? 'x' : '';
|
|
149
|
+
|
|
150
|
+
return path.join(srcFolder, entryFilePath + jsx);
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const install = (options, appPath, styles) => {
|
|
154
|
+
appPath = appPath ? appPath : process.cwd();
|
|
155
|
+
|
|
156
|
+
const pathToMainComponent = path.join(appPath, getEntryFilePath(options, appPath));
|
|
157
|
+
|
|
158
|
+
addStylesToApp(pathToMainComponent, styles || defaultStyles);
|
|
159
|
+
packageJsonUtils.addDevextreme(appPath, options.dxversion, 'react');
|
|
160
|
+
|
|
161
|
+
packageManager.runInstall({ cwd: appPath });
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const getNavigationData = (viewName, componentName, icon) => {
|
|
165
|
+
const pagePath = stringUtils.dasherize(viewName);
|
|
166
|
+
return {
|
|
167
|
+
navigation: `\n {\n text: \'${stringUtils.humanize(viewName)}\',\n path: \'/pages/${pagePath}\',\n icon: \'${icon}\'\n }`
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
const createPathToPage = (pageName) => {
|
|
172
|
+
const pagesPath = path.join(process.cwd(), 'src', 'app/pages');
|
|
173
|
+
const newPageFolderPath = path.join(pagesPath, pageName);
|
|
174
|
+
|
|
175
|
+
if(!fs.existsSync(pagesPath)) {
|
|
176
|
+
fs.mkdirSync(pagesPath);
|
|
177
|
+
fs.writeFileSync(pathToPagesIndex(), '');
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if(!fs.existsSync(newPageFolderPath)) {
|
|
181
|
+
fs.mkdirSync(newPageFolderPath);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return newPageFolderPath;
|
|
185
|
+
};
|
|
186
|
+
|
|
187
|
+
const addSamplePages = (appPath, templateOptions) => {
|
|
188
|
+
const samplePageTemplatePath = path.join(
|
|
189
|
+
templateCreator.getTempaltePath('nextjs'),
|
|
190
|
+
'sample-pages'
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
const pagesPath = path.join(appPath, 'src', 'app/pages');
|
|
194
|
+
|
|
195
|
+
templateCreator.moveTemplateFilesToProject(samplePageTemplatePath, pagesPath, {
|
|
196
|
+
isTypeScript: templateOptions.isTypeScript
|
|
197
|
+
}, getCorrectPath);
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const addView = (pageName, options) => {
|
|
201
|
+
const pageTemplatePath = path.join(
|
|
202
|
+
templateCreator.getTempaltePath('nextjs'),
|
|
203
|
+
'page'
|
|
204
|
+
);
|
|
205
|
+
const extension = getExtension(process.cwd());
|
|
206
|
+
|
|
207
|
+
const componentName = getComponentPageName(pageName);
|
|
208
|
+
const pathToPage = createPathToPage(pageName);
|
|
209
|
+
const navigationModulePath = path.join(process.cwd(), 'src', `app-navigation${extension}`);
|
|
210
|
+
const navigationData = getNavigationData(pageName, componentName, options && options.icon || 'folder');
|
|
211
|
+
|
|
212
|
+
const getCorrectExtension = (fileExtension) => {
|
|
213
|
+
return fileExtension === '.tsx' ? extension : fileExtension;
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
const getPageFileName = (pageName, pageItem) => {
|
|
217
|
+
return pageItem === 'page.tsx' ? 'page' : pageName;
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
templateCreator.addPageToApp(pageName, pathToPage, pageTemplatePath, getCorrectExtension, { getPageFileName });
|
|
221
|
+
|
|
222
|
+
insertItemToArray(navigationModulePath, navigationData.navigation);
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
module.exports = {
|
|
226
|
+
isNextJsApp,
|
|
227
|
+
install,
|
|
228
|
+
create,
|
|
229
|
+
addTemplate,
|
|
230
|
+
addView
|
|
231
|
+
};
|
|
@@ -3,6 +3,7 @@ const path = require('path');
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const getLayoutInfo = require('../utility/prompts/layout');
|
|
5
5
|
const getTemplateTypeInfo = require('../utility/prompts/typescript');
|
|
6
|
+
const getTranspilerTypeInfo = require('../utility/prompts/transpiler');
|
|
6
7
|
const templateCreator = require('../utility/template-creator');
|
|
7
8
|
const packageManager = require('../utility/package-manager');
|
|
8
9
|
const packageJsonUtils = require('../utility/package-json-utils');
|
|
@@ -13,13 +14,13 @@ const stringUtils = require('../utility/string');
|
|
|
13
14
|
const typescriptUtils = require('../utility/typescript-extension');
|
|
14
15
|
const removeFile = require('../utility/file-operations').remove;
|
|
15
16
|
const latestVersions = require('../utility/latest-versions');
|
|
16
|
-
const {
|
|
17
|
+
const { extractDepsVersionTag } = require('../utility/extract-deps-version-tag');
|
|
17
18
|
const defaultStyles = [
|
|
18
19
|
'devextreme/dist/css/dx.light.css'
|
|
19
20
|
];
|
|
20
21
|
|
|
21
22
|
const getExtension = (appPath) => {
|
|
22
|
-
return fs.existsSync(path.join(appPath, 'src', 'App.tsx')) ? '.tsx' : '.
|
|
23
|
+
return fs.existsSync(path.join(appPath, 'src', 'App.tsx')) ? '.tsx' : '.jsx';
|
|
23
24
|
};
|
|
24
25
|
|
|
25
26
|
const pathToPagesIndex = () => {
|
|
@@ -27,9 +28,9 @@ const pathToPagesIndex = () => {
|
|
|
27
28
|
return path.join(process.cwd(), 'src', 'pages', `index${extension}`);
|
|
28
29
|
};
|
|
29
30
|
|
|
30
|
-
const preparePackageJsonForTemplate = (appPath, appName
|
|
31
|
+
const preparePackageJsonForTemplate = (appPath, appName) => {
|
|
31
32
|
const dependencies = [
|
|
32
|
-
{ name: 'sass', version: '^1.
|
|
33
|
+
{ name: 'sass-embedded', version: '^1.85.1' },
|
|
33
34
|
{ name: 'devextreme-cli', version: latestVersions['devextreme-cli'], dev: true },
|
|
34
35
|
{ name: 'react-router-dom', version: '^6.3.0' },
|
|
35
36
|
];
|
|
@@ -51,8 +52,25 @@ const updateJsonPropName = (path, name) => {
|
|
|
51
52
|
});
|
|
52
53
|
};
|
|
53
54
|
|
|
55
|
+
const bumpReact = (appPath, versionTag, isTypeScript) => {
|
|
56
|
+
const dependencies = [
|
|
57
|
+
{ name: 'react', version: versionTag },
|
|
58
|
+
{ name: 'react-dom', version: versionTag },
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
if(isTypeScript) {
|
|
62
|
+
dependencies.push(
|
|
63
|
+
{ name: '@types/react', version: versionTag, dev: true },
|
|
64
|
+
{ name: '@types/react-dom', version: versionTag, dev: true },
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
packageJsonUtils.addDependencies(appPath, dependencies);
|
|
69
|
+
};
|
|
70
|
+
|
|
54
71
|
const create = async(appName, options) => {
|
|
55
72
|
const templateType = await getTemplateTypeInfo(options.template);
|
|
73
|
+
const transpiler = await getTranspilerTypeInfo(options.transpiler);
|
|
56
74
|
const layoutType = await getLayoutInfo(options.layout);
|
|
57
75
|
|
|
58
76
|
const templateOptions = Object.assign({}, options, {
|
|
@@ -60,27 +78,30 @@ const create = async(appName, options) => {
|
|
|
60
78
|
layout: stringUtils.classify(layoutType),
|
|
61
79
|
isTypeScript: typescriptUtils.isTypeScript(templateType)
|
|
62
80
|
});
|
|
63
|
-
const
|
|
64
|
-
const commandArguments = [`-p=create-react-app${toolingVersion}`, 'create-react-app', appName];
|
|
81
|
+
const depsVersionTag = extractDepsVersionTag(options);
|
|
65
82
|
|
|
66
|
-
const
|
|
67
|
-
const templatePath = path.resolve(__dirname, `../templates/cra-template${templateSuffix}`);
|
|
83
|
+
const commandArguments = [`-p=create-vite@${depsVersionTag || latestVersions['create-vite']}`, 'create-vite', appName];
|
|
68
84
|
|
|
69
|
-
commandArguments.push(`--template
|
|
85
|
+
commandArguments.push(`--template react${transpiler === 'swc' ? '-swc' : ''}${templateOptions.isTypeScript ? '-ts' : ''}`);
|
|
70
86
|
|
|
71
87
|
await runCommand('npx', commandArguments);
|
|
72
88
|
|
|
73
89
|
const appPath = path.join(process.cwd(), appName);
|
|
74
90
|
|
|
75
91
|
modifyIndexHtml(appPath, templateOptions.project);
|
|
92
|
+
|
|
93
|
+
if(depsVersionTag) {
|
|
94
|
+
bumpReact(appPath, depsVersionTag, templateOptions.isTypeScript);
|
|
95
|
+
}
|
|
96
|
+
|
|
76
97
|
addTemplate(appPath, appName, templateOptions);
|
|
77
98
|
};
|
|
78
99
|
|
|
79
100
|
const modifyIndexHtml = (appPath, appName) => {
|
|
80
|
-
const indexHtmlPath = path.join(appPath, '
|
|
101
|
+
const indexHtmlPath = path.join(appPath, 'index.html');
|
|
81
102
|
|
|
82
103
|
let htmlContent = fs.readFileSync(indexHtmlPath).toString();
|
|
83
|
-
htmlContent = htmlContent.replace(/<title>
|
|
104
|
+
htmlContent = htmlContent.replace(/<title>[^<]+<\/title>/, `<title>${appName}<\/title>`);
|
|
84
105
|
htmlContent = htmlContent.replace('<body>', '<body class="dx-viewport">');
|
|
85
106
|
|
|
86
107
|
fs.writeFileSync(indexHtmlPath, htmlContent);
|
|
@@ -97,7 +118,6 @@ const addTemplate = (appPath, appName, templateOptions) => {
|
|
|
97
118
|
);
|
|
98
119
|
|
|
99
120
|
const manifestPath = path.join(appPath, 'public', 'manifest.json');
|
|
100
|
-
const indexPath = path.join(appPath, 'src', templateOptions.isTypeScript ? 'index.tsx' : 'index.js');
|
|
101
121
|
|
|
102
122
|
const styles = [
|
|
103
123
|
'./themes/generated/theme.additional.css',
|
|
@@ -108,15 +128,15 @@ const addTemplate = (appPath, appName, templateOptions) => {
|
|
|
108
128
|
];
|
|
109
129
|
|
|
110
130
|
templateCreator.moveTemplateFilesToProject(applicationTemplatePath, appPath, templateOptions, getCorrectPath);
|
|
111
|
-
|
|
112
|
-
!templateOptions.isTypeScript && removeFile(path.join(appPath, 'src', 'types.
|
|
131
|
+
|
|
132
|
+
!templateOptions.isTypeScript && removeFile(path.join(appPath, 'src', 'types.jsx'));
|
|
133
|
+
|
|
113
134
|
if(!templateOptions.empty) {
|
|
114
135
|
addSamplePages(appPath, templateOptions);
|
|
115
136
|
}
|
|
116
137
|
|
|
117
138
|
preparePackageJsonForTemplate(appPath, appName, templateOptions.isTypeScript);
|
|
118
139
|
updateJsonPropName(manifestPath, appName);
|
|
119
|
-
addPolyfills(packageJsonUtils.getPackageJsonPath(), indexPath);
|
|
120
140
|
install({}, appPath, styles);
|
|
121
141
|
};
|
|
122
142
|
|
|
@@ -130,15 +150,6 @@ const install = (options, appPath, styles) => {
|
|
|
130
150
|
packageManager.runInstall({ cwd: appPath });
|
|
131
151
|
};
|
|
132
152
|
|
|
133
|
-
const addPolyfills = (packagePath, indexPath) => {
|
|
134
|
-
const packages = [
|
|
135
|
-
{ name: 'react-app-polyfill', version: '^1.0.0' }
|
|
136
|
-
];
|
|
137
|
-
|
|
138
|
-
packageJsonUtils.addDependencies(packagePath, packages);
|
|
139
|
-
moduleUtils.insertImport(indexPath, './polyfills');
|
|
140
|
-
};
|
|
141
|
-
|
|
142
153
|
const addStylesToApp = (filePath, styles) => {
|
|
143
154
|
styles.forEach(style => {
|
|
144
155
|
moduleUtils.insertImport(filePath, style);
|
|
@@ -213,5 +224,10 @@ module.exports = {
|
|
|
213
224
|
install,
|
|
214
225
|
create,
|
|
215
226
|
addTemplate,
|
|
216
|
-
addView
|
|
227
|
+
addView,
|
|
228
|
+
updateJsonPropName,
|
|
229
|
+
bumpReact,
|
|
230
|
+
getCorrectPath,
|
|
231
|
+
addStylesToApp,
|
|
232
|
+
getComponentPageName,
|
|
217
233
|
};
|