devextreme-cli 1.11.0-alpha.0 → 1.11.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 +10 -9
- package/src/application.js +40 -20
- package/src/applications/application.angular.js +11 -3
- package/src/applications/application.nextjs.js +231 -0
- package/src/applications/application.react.js +16 -6
- package/src/applications/application.vue.js +6 -11
- 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/public/logo192.png +0 -0
- package/src/templates/nextjs/application/public/logo512.png +0 -0
- package/src/templates/nextjs/application/public/manifest.json +25 -0
- package/src/templates/nextjs/application/public/robots.txt +3 -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/index.css +12 -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 +2 -1
- package/src/templates/react/application/src/Content.tsx +1 -1
- package/src/templates/react/application/src/app-routes.tsx +3 -3
- package/src/templates/react/application/src/components/change-password-form/ChangePasswordForm.tsx +1 -1
- package/src/templates/react/application/src/components/create-account-form/CreateAccountForm.tsx +1 -1
- package/src/templates/react/application/src/components/header/Header.scss +1 -1
- package/src/templates/react/application/src/components/login-form/LoginForm.tsx +1 -1
- package/src/templates/react/application/src/components/side-navigation-menu/SideNavigationMenu.tsx +2 -2
- package/src/templates/react/application/src/components/user-panel/UserPanel.tsx +1 -1
- package/src/templates/react/application/src/contexts/auth-hooks.ts +8 -0
- package/src/templates/react/application/src/contexts/auth.tsx +7 -5
- package/src/templates/react/application/src/contexts/navigation-hooks.ts +22 -0
- package/src/templates/react/application/src/contexts/navigation.tsx +3 -17
- package/src/templates/react/application/src/dx-styles.scss +3 -3
- package/src/templates/react/application/src/layouts/side-nav-inner-toolbar/side-nav-inner-toolbar.tsx +3 -3
- package/src/templates/react/application/src/layouts/side-nav-outer-toolbar/side-nav-outer-toolbar.tsx +3 -3
- package/src/templates/react/application/src/types.tsx +2 -2
- package/src/templates/react/page/page.tsx +1 -1
- package/src/templates/react/sample-pages/home/home.tsx +1 -1
- package/src/templates/react/sample-pages/index.tsx +3 -3
- package/src/templates/react/sample-pages/profile/profile.tsx +1 -1
- package/src/templates/react/sample-pages/tasks/tasks.tsx +1 -1
- package/src/templates/vue-v3/application/eslint.config.js +32 -0
- package/src/templates/vue-v3/application/src/App.vue +1 -1
- package/src/templates/vue-v3/application/src/components/header-toolbar.vue +2 -2
- package/src/templates/vue-v3/application/src/dx-styles.scss +4 -3
- package/src/templates/vue-v3/application/src/layouts/side-nav-inner-toolbar.vue +2 -2
- package/src/templates/vue-v3/application/src/layouts/side-nav-outer-toolbar.vue +2 -2
- package/src/templates/vue-v3/application/src/main.js +1 -1
- package/src/templates/vue-v3/application/src/router.js +5 -5
- package/src/utility/latest-versions.js +7 -4
- package/src/utility/module.js +13 -5
- package/src/utility/prompts/react-app-type.js +17 -0
- package/src/utility/run-command.js +10 -2
- package/src/utility/template-creator.js +8 -4
- package/src/templates/vue-v3/application/vue.config.js +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devextreme-cli",
|
|
3
|
-
"version": "1.11.0
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"description": "DevExtreme CLI",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"devexpress",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"devextreme": "index.js"
|
|
15
15
|
},
|
|
16
16
|
"engines": {
|
|
17
|
-
"node": ">
|
|
18
|
-
"npm": ">6.
|
|
17
|
+
"node": ">20.19.0",
|
|
18
|
+
"npm": ">9.6.0",
|
|
19
19
|
"yarn": ">1.21"
|
|
20
20
|
},
|
|
21
21
|
"files": [
|
|
@@ -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.89.2",
|
|
47
47
|
"semver": "^5.7.2",
|
|
48
48
|
"strip-bom": "^4.0.0"
|
|
49
49
|
},
|
|
@@ -51,7 +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": "
|
|
54
|
+
"create-vite": "7.0.0",
|
|
55
55
|
"cross-env": "^5.2.1",
|
|
56
56
|
"eslint": "^7.32.0",
|
|
57
57
|
"eslint-config-angular": "^0.5.0",
|
|
@@ -59,19 +59,20 @@
|
|
|
59
59
|
"eslint-plugin-angular": "^4.1.0",
|
|
60
60
|
"eslint-plugin-jest": "^22.21.0",
|
|
61
61
|
"eslint-plugin-prettier": "^4.2.1",
|
|
62
|
-
"eslint-plugin-react": "^7.37.
|
|
62
|
+
"eslint-plugin-react": "^7.37.5",
|
|
63
63
|
"eslint-plugin-react-hooks": "^4.6.2",
|
|
64
64
|
"eslint-plugin-unused-imports": "^1.1.5",
|
|
65
65
|
"eslint-plugin-vue": "^7.20.0",
|
|
66
66
|
"eslint-stylish": "^0.2.0",
|
|
67
67
|
"jest": "^29.7.0",
|
|
68
|
-
"jest-image-snapshot": "^6.
|
|
68
|
+
"jest-image-snapshot": "^6.5.1",
|
|
69
69
|
"prettier": "^2.8.8",
|
|
70
70
|
"rimraf": "^2.7.1",
|
|
71
71
|
"tree-kill": "^1.2.2",
|
|
72
72
|
"tree-kill-promise": "^1.0.12",
|
|
73
73
|
"typescript": "^4.0.2",
|
|
74
|
-
"typescript-eslint-parser": "^22.0.0"
|
|
74
|
+
"typescript-eslint-parser": "^22.0.0",
|
|
75
|
+
"wait-on": "8.0.3"
|
|
75
76
|
},
|
|
76
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "16351e5d8d9dceee7d826668231c3e047d4df3fc"
|
|
77
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]);
|
|
@@ -13,6 +13,7 @@ const modifyJson = require('../utility/modify-json-file');
|
|
|
13
13
|
const schematicsVersion = latestVersions['devextreme-schematics'] || 'latest';
|
|
14
14
|
|
|
15
15
|
const minNgCliVersion = new semver('17.0.0');
|
|
16
|
+
const ngCliWithZoneless = new semver('20.0.0');
|
|
16
17
|
|
|
17
18
|
async function runSchematicCommand(schematicCommand, options, evaluatingOptions) {
|
|
18
19
|
const collectionName = 'devextreme-schematics';
|
|
@@ -63,6 +64,7 @@ function localPackageExists(packageName) {
|
|
|
63
64
|
|
|
64
65
|
const hasSutableNgCli = async() => {
|
|
65
66
|
const localVersion = ngVersion.getLocalNgVersion();
|
|
67
|
+
|
|
66
68
|
if(!localVersion) {
|
|
67
69
|
return false;
|
|
68
70
|
}
|
|
@@ -83,6 +85,7 @@ const bumpAngular = (appPath, versionTag) => {
|
|
|
83
85
|
for(const depName in section) {
|
|
84
86
|
section[depName] = depName.startsWith('@angular') ? versionTag : section[depName];
|
|
85
87
|
}
|
|
88
|
+
return section;
|
|
86
89
|
};
|
|
87
90
|
|
|
88
91
|
return {
|
|
@@ -96,6 +99,7 @@ const bumpAngular = (appPath, versionTag) => {
|
|
|
96
99
|
|
|
97
100
|
const create = async(appName, options) => {
|
|
98
101
|
const layout = await getLayoutInfo(options.layout);
|
|
102
|
+
const currentNgVersion = ngVersion.getNgCliVersion().version;
|
|
99
103
|
const depsVersionTag = extractDepsVersionTag(options);
|
|
100
104
|
|
|
101
105
|
const commandArguments = [
|
|
@@ -105,10 +109,14 @@ const create = async(appName, options) => {
|
|
|
105
109
|
'--routing=false',
|
|
106
110
|
'--skip-tests=true',
|
|
107
111
|
'--skip-install=true',
|
|
108
|
-
'--standalone=
|
|
112
|
+
'--standalone=true',
|
|
109
113
|
'--ssr=false'
|
|
110
114
|
];
|
|
111
115
|
|
|
116
|
+
if(ngCliWithZoneless.compare(currentNgVersion) <= 0) {
|
|
117
|
+
commandArguments.push('--zoneless=false');
|
|
118
|
+
}
|
|
119
|
+
|
|
112
120
|
await runNgCommand(commandArguments, options);
|
|
113
121
|
|
|
114
122
|
const appPath = path.join(process.cwd(), appName);
|
|
@@ -150,9 +158,9 @@ const changeMainTs = (appPath) => {
|
|
|
150
158
|
moduleWorker.insertImport(filePath, 'devextreme/ui/themes', 'themes', true);
|
|
151
159
|
|
|
152
160
|
const fileContent = fs.readFileSync(filePath).toString();
|
|
153
|
-
const bootstrapPattern = /
|
|
161
|
+
const bootstrapPattern = /bootstrapApplication\([^)]+\)/;
|
|
154
162
|
const firstChaptStr = fileContent.match(bootstrapPattern)[0];
|
|
155
|
-
const lastChaptStr = '.catch(err => console.error(err));';
|
|
163
|
+
const lastChaptStr = '.catch((err) => console.error(err));';
|
|
156
164
|
|
|
157
165
|
fs.writeFileSync(
|
|
158
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
|
+
};
|
|
@@ -52,14 +52,19 @@ const updateJsonPropName = (path, name) => {
|
|
|
52
52
|
});
|
|
53
53
|
};
|
|
54
54
|
|
|
55
|
-
const bumpReact = (appPath, versionTag) => {
|
|
55
|
+
const bumpReact = (appPath, versionTag, isTypeScript) => {
|
|
56
56
|
const dependencies = [
|
|
57
57
|
{ name: 'react', version: versionTag },
|
|
58
58
|
{ name: 'react-dom', version: versionTag },
|
|
59
|
-
{ name: '@types/react', version: versionTag, dev: true },
|
|
60
|
-
{ name: '@types/react-dom', version: versionTag, dev: true },
|
|
61
59
|
];
|
|
62
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
|
+
|
|
63
68
|
packageJsonUtils.addDependencies(appPath, dependencies);
|
|
64
69
|
};
|
|
65
70
|
|
|
@@ -86,7 +91,7 @@ const create = async(appName, options) => {
|
|
|
86
91
|
modifyIndexHtml(appPath, templateOptions.project);
|
|
87
92
|
|
|
88
93
|
if(depsVersionTag) {
|
|
89
|
-
bumpReact(appPath, depsVersionTag);
|
|
94
|
+
bumpReact(appPath, depsVersionTag, templateOptions.isTypeScript);
|
|
90
95
|
}
|
|
91
96
|
|
|
92
97
|
addTemplate(appPath, appName, templateOptions);
|
|
@@ -209,7 +214,7 @@ const addView = (pageName, options) => {
|
|
|
209
214
|
return fileExtension === '.tsx' ? extension : fileExtension;
|
|
210
215
|
};
|
|
211
216
|
templateCreator.addPageToApp(pageName, pathToPage, pageTemplatePath, getCorrectExtension);
|
|
212
|
-
moduleUtils.insertExport(pathToPagesIndex(), componentName, `./${pageName}/${pageName}
|
|
217
|
+
moduleUtils.insertExport(pathToPagesIndex(), componentName, `./${pageName}/${pageName}`, 'Page');
|
|
213
218
|
moduleUtils.insertImport(routingModulePath, './pages', componentName);
|
|
214
219
|
insertItemToArray(routingModulePath, navigationData.route);
|
|
215
220
|
insertItemToArray(navigationModulePath, navigationData.navigation);
|
|
@@ -219,5 +224,10 @@ module.exports = {
|
|
|
219
224
|
install,
|
|
220
225
|
create,
|
|
221
226
|
addTemplate,
|
|
222
|
-
addView
|
|
227
|
+
addView,
|
|
228
|
+
updateJsonPropName,
|
|
229
|
+
bumpReact,
|
|
230
|
+
getCorrectPath,
|
|
231
|
+
addStylesToApp,
|
|
232
|
+
getComponentPageName,
|
|
223
233
|
};
|
|
@@ -16,10 +16,9 @@ const defaultStyles = [
|
|
|
16
16
|
|
|
17
17
|
const preparePackageJsonForTemplate = (appPath, appName) => {
|
|
18
18
|
const dependencies = [
|
|
19
|
-
{ name: 'sass', version: '^1.
|
|
19
|
+
{ name: 'sass-embedded', version: '^1.85.1' },
|
|
20
20
|
{ name: 'vue-router', version: '^3.0.1' },
|
|
21
|
-
{ name: 'devextreme-cli', version: latestVersions['devextreme-cli'], dev: true }
|
|
22
|
-
{ name: 'sass-loader', version: '^10', dev: true }
|
|
21
|
+
{ name: 'devextreme-cli', version: latestVersions['devextreme-cli'], dev: true }
|
|
23
22
|
];
|
|
24
23
|
|
|
25
24
|
const nameDepends = dependencies.map(d => d.name);
|
|
@@ -38,18 +37,14 @@ const preparePackageJsonForTemplate = (appPath, appName) => {
|
|
|
38
37
|
};
|
|
39
38
|
|
|
40
39
|
async function createVueApp(name, depsVersionTag) {
|
|
41
|
-
const argList = ['
|
|
42
|
-
|
|
43
|
-
return runCommand('npx', argList);
|
|
40
|
+
const argList = ['create', `vue@${depsVersionTag ? depsVersionTag : latestVersions['create-vue']}`, name, '--registry', 'https://registry.npmjs.org/', '--', '--eslint', '--default', '--bare'];
|
|
41
|
+
return runCommand('npm', argList);
|
|
44
42
|
}
|
|
45
43
|
|
|
46
44
|
const bumpVue = (appPath, versionTag) => {
|
|
47
45
|
const dependencies = [
|
|
48
46
|
{ name: 'vue', version: versionTag },
|
|
49
47
|
{ name: 'vue-router', version: versionTag },
|
|
50
|
-
{ name: '@vue/cli-plugin-babel', version: versionTag, dev: true },
|
|
51
|
-
{ name: '@vue/cli-plugin-eslint', version: versionTag, dev: true },
|
|
52
|
-
{ name: '@vue/cli-service', version: versionTag, dev: true },
|
|
53
48
|
];
|
|
54
49
|
|
|
55
50
|
packageJsonUtils.addDependencies(appPath, dependencies);
|
|
@@ -78,7 +73,7 @@ const create = async(appName, options) => {
|
|
|
78
73
|
};
|
|
79
74
|
|
|
80
75
|
const modifyIndexHtml = (appPath, appName) => {
|
|
81
|
-
const indexHtmlPath = path.join(appPath, '
|
|
76
|
+
const indexHtmlPath = path.join(appPath, 'index.html');
|
|
82
77
|
let htmlContent = fs.readFileSync(indexHtmlPath).toString();
|
|
83
78
|
|
|
84
79
|
htmlContent = htmlContent.replace(/<title>(\w+\s*)+<\/title>/, `<title>${appName}<\/title>`);
|
|
@@ -175,7 +170,7 @@ const addView = (pageName, options) => {
|
|
|
175
170
|
const navigationData = getNavigationData(pageName, componentName, options && options.icon || 'folder');
|
|
176
171
|
const getCorrectExtension = (fileExtension) => fileExtension;
|
|
177
172
|
templateCreator.addPageToApp(pageName, pathToPage, pageTemplatePath, getCorrectExtension);
|
|
178
|
-
moduleUtils.insertImport(routingModulePath, `./views/${pageName}`, componentName, true);
|
|
173
|
+
moduleUtils.insertImport(routingModulePath, `./views/${pageName}.vue`, componentName, true);
|
|
179
174
|
insertItemToArray(routingModulePath, navigationData.route);
|
|
180
175
|
insertItemToArray(navigationModulePath, navigationData.navigation);
|
|
181
176
|
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
SESSION_SECRET=<your_secret_key_goes_here>
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"applicationEngine": "nextjs",
|
|
3
|
+
"build": {
|
|
4
|
+
"commands": [
|
|
5
|
+
{
|
|
6
|
+
"command": "build-theme",
|
|
7
|
+
"options": {
|
|
8
|
+
"inputFile": "src/themes/metadata.base.json",
|
|
9
|
+
"outputFile": "src/themes/generated/theme.base.css"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"command": "build-theme",
|
|
14
|
+
"options": {
|
|
15
|
+
"inputFile": "src/themes/metadata.base.dark.json",
|
|
16
|
+
"outputFile": "src/themes/generated/theme.base.dark.css"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"command": "build-theme",
|
|
21
|
+
"options": {
|
|
22
|
+
"inputFile": "src/themes/metadata.additional.json",
|
|
23
|
+
"outputFile": "src/themes/generated/theme.additional.css"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"command": "build-theme",
|
|
28
|
+
"options": {
|
|
29
|
+
"inputFile": "src/themes/metadata.additional.dark.json",
|
|
30
|
+
"outputFile": "src/themes/generated/theme.additional.dark.css"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"command": "export-theme-vars",
|
|
35
|
+
"options": {
|
|
36
|
+
"inputFile": "src/themes/metadata.base.json",
|
|
37
|
+
"outputFile": "src/themes/generated/variables.base.scss"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"command": "export-theme-vars",
|
|
42
|
+
"options": {
|
|
43
|
+
"inputFile": "src/themes/metadata.base.dark.json",
|
|
44
|
+
"outputFile": "src/themes/generated/variables.base.dark.scss"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"command": "export-theme-vars",
|
|
49
|
+
"options": {
|
|
50
|
+
"inputFile": "src/themes/metadata.additional.json",
|
|
51
|
+
"outputFile": "src/themes/generated/variables.additional.scss"
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"command": "export-theme-vars",
|
|
56
|
+
"options": {
|
|
57
|
+
"inputFile": "src/themes/metadata.additional.dark.json",
|
|
58
|
+
"outputFile": "src/themes/generated/variables.additional.dark.scss"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** @type {import('next').NextConfig} */
|
|
2
|
+
const nextConfig = {
|
|
3
|
+
async redirects() {
|
|
4
|
+
return [
|
|
5
|
+
{
|
|
6
|
+
source: '/',
|
|
7
|
+
destination: '/pages/home',
|
|
8
|
+
permanent: true,
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
source: '/login',
|
|
12
|
+
destination: '/auth/login',
|
|
13
|
+
permanent: true,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
source: '/reset-password',
|
|
17
|
+
destination: '/auth/reset-password',
|
|
18
|
+
permanent: true,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
source: '/create-account',
|
|
22
|
+
destination: '/auth/create-account',
|
|
23
|
+
permanent: true,
|
|
24
|
+
},
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
images: {
|
|
28
|
+
remotePatterns: [new URL('https://js.devexpress.com/**')]
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export default nextConfig;
|
|
Binary file
|
|
Binary file
|