devextreme-cli 1.11.2 → 1.12.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/index.js CHANGED
@@ -39,6 +39,14 @@ if(args.help) {
39
39
  const run = async(commands, options) => {
40
40
  if(application.isApplicationCommand(commands[0])) {
41
41
  await application.run(commands, options, devextremeConfig.read());
42
+ } else if(application.isMigrationCommand(commands[0])) {
43
+ if(!commands[1]) {
44
+ console.error('Please specify a change name for migration.');
45
+ printHelp('migrate');
46
+ return;
47
+ }
48
+ await application.run(['migrate', commands[1], ...commands.slice(2)], options, { applicationEngine: 'angular' });
49
+ return;
42
50
  } else if(themeBuilder.isThemeBuilderCommand(commands[0])) {
43
51
  options.command = commands[0];
44
52
  themeBuilder.run(options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devextreme-cli",
3
- "version": "1.11.2",
3
+ "version": "1.12.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.92.1",
46
+ "sass": "^1.93.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": "7.1.1",
54
+ "create-vite": "7.1.3",
55
55
  "cross-env": "^5.2.1",
56
56
  "eslint": "^7.32.0",
57
57
  "eslint-config-angular": "^0.5.0",
@@ -74,5 +74,5 @@
74
74
  "typescript-eslint-parser": "^22.0.0",
75
75
  "wait-on": "8.0.5"
76
76
  },
77
- "gitHead": "04bf9bb942b69586a4ed95b47807406844296751"
77
+ "gitHead": "0a56ed4e9c13e1deb23007f0d23f974806878a7f"
78
78
  }
@@ -9,11 +9,20 @@ const isApplicationCommand = (command) => {
9
9
  return [ 'new', 'add' ].includes(command);
10
10
  };
11
11
 
12
+ const isMigrationCommand = (command) => {
13
+ return [ 'migrate' ].includes(command);
14
+ };
15
+
12
16
  const handleWrongAppType = (appType, command) => {
13
17
  console.error(`The '${appType}' application type is not valid`);
14
18
  printHelp(command);
15
19
  };
16
20
 
21
+ const handleWrongChangeName = (changeName, command) => {
22
+ console.error(`The '${changeName}' change name is not valid`);
23
+ printHelp(command);
24
+ };
25
+
17
26
  const createReact = async(appName, options, command) => {
18
27
  const reactAppType = await getReactAppType(options['app-type']);
19
28
 
@@ -30,12 +39,25 @@ const createReact = async(appName, options, command) => {
30
39
  };
31
40
 
32
41
  const run = async(commands, options, devextremeConfig) => {
42
+
33
43
  if(!commands[1]) {
34
44
  console.error('Command is incomplete. Please specify parameters.');
35
45
  printHelp(commands[0]);
36
46
  return;
37
47
  }
38
48
 
49
+ if(commands[0] === 'migrate') {
50
+ const changeName = commands[1];
51
+ switch(changeName) {
52
+ case 'angular-config-components':
53
+ await angularApplication.migrateConfigComponents(options);
54
+ return;
55
+ default:
56
+ handleWrongChangeName(changeName, commands[0]);
57
+ return;
58
+ }
59
+ }
60
+
39
61
  if(commands[0] === 'new') {
40
62
  const app = commands[1];
41
63
  const appName = commands[2] || 'my-app';
@@ -104,5 +126,6 @@ const run = async(commands, options, devextremeConfig) => {
104
126
 
105
127
  module.exports = {
106
128
  isApplicationCommand,
129
+ isMigrationCommand,
107
130
  run
108
131
  };
@@ -53,13 +53,24 @@ async function runNgCommand(commandArguments, commandOptions, commandConfig) {
53
53
  }
54
54
 
55
55
  function localPackageExists(packageName) {
56
+ // Check local node_modules first
56
57
  const nodeModulesPath = path.join(process.cwd(), 'node_modules');
57
- if(!fs.existsSync(nodeModulesPath)) {
58
- return;
58
+ if(fs.existsSync(nodeModulesPath)) {
59
+ const packageJsonPath = path.join(nodeModulesPath, packageName, 'package.json');
60
+ if(fs.existsSync(packageJsonPath)) {
61
+ return true;
62
+ }
59
63
  }
60
64
 
61
- const packageJsonPath = path.join(nodeModulesPath, packageName, 'package.json');
62
- return fs.existsSync(packageJsonPath);
65
+ // Check if globally installed by trying to resolve the package
66
+ try {
67
+ require.resolve(`${packageName}/package.json`);
68
+ return true;
69
+ } catch(e) {
70
+ // Package not found globally
71
+ }
72
+
73
+ return false;
63
74
  }
64
75
 
65
76
  const hasSutableNgCli = async() => {
@@ -152,6 +163,70 @@ const addView = (viewName, options) => {
152
163
  runSchematicCommand('add-view', schematicOptions);
153
164
  };
154
165
 
166
+ const migrateConfigComponents = async(options = {}) => {
167
+ const collectionName = 'devextreme-schematics';
168
+
169
+ // Check if devextreme-schematics is installed
170
+ if(!localPackageExists(collectionName)) {
171
+ const prompts = require('prompts');
172
+
173
+ console.log(`\nThe '${collectionName}' package is required to run this command.`);
174
+
175
+ const response = await prompts({
176
+ type: 'confirm',
177
+ name: 'install',
178
+ message: `Would you like to install '${collectionName}' now?`,
179
+ initial: true
180
+ });
181
+
182
+ if(!response.install) {
183
+ console.log('Migration cancelled. Please install devextreme-schematics manually:');
184
+ console.log(`npm install -g ${collectionName}@${schematicsVersion}`);
185
+ process.exit(1);
186
+ }
187
+
188
+ console.log(`Installing ${collectionName}@${schematicsVersion}...`);
189
+ try {
190
+ await runCommand('npm', ['install', '-g', `${collectionName}@${schematicsVersion}`], { stdio: 'inherit' });
191
+ console.log('Installation completed successfully.');
192
+ } catch(error) {
193
+ console.error('Failed to install devextreme-schematics. Please install manually:');
194
+ console.error(`npm install -g ${collectionName}@${schematicsVersion}`);
195
+ process.exit(1);
196
+ }
197
+ }
198
+
199
+ const schematicOptions = {
200
+ ...options
201
+ };
202
+
203
+ if(schematicOptions.include && typeof schematicOptions.include === 'string') {
204
+ schematicOptions.include = schematicOptions.include.split(',').map(s => s.trim());
205
+ }
206
+ if(schematicOptions.scriptInclude && typeof schematicOptions.scriptInclude === 'string') {
207
+ schematicOptions.scriptInclude = schematicOptions.scriptInclude.split(',').map(s => s.trim());
208
+ }
209
+
210
+ const commandArguments = ['schematics', `${collectionName}:migrate-config-components`];
211
+
212
+ const { [depsVersionTagOptionName]: _, ...optionsToArguments } = schematicOptions; // eslint-disable-line no-unused-vars
213
+ for(let option in optionsToArguments) {
214
+ const value = optionsToArguments[option];
215
+ if(value !== undefined && value !== null && value !== '') {
216
+ if(Array.isArray(value)) {
217
+ if(value.length > 0) {
218
+ commandArguments.push(`--${dasherize(option)}=${value.join(',')}`);
219
+ }
220
+ } else {
221
+ commandArguments.push(`--${dasherize(option)}=${value}`);
222
+ }
223
+ }
224
+ }
225
+
226
+ // Use runCommand directly with npx to work outside Angular workspace
227
+ return runCommand('npx', commandArguments, { stdio: 'inherit' });
228
+ };
229
+
155
230
  const changeMainTs = (appPath) => {
156
231
  const filePath = path.join(appPath, 'src', 'main.ts');
157
232
 
@@ -174,5 +249,6 @@ module.exports = {
174
249
  install,
175
250
  create,
176
251
  addTemplate,
177
- addView
252
+ addView,
253
+ migrateConfigComponents
178
254
  };
package/src/commands.json CHANGED
@@ -48,6 +48,24 @@
48
48
  "name": "devextreme-angular",
49
49
  "description": "Add DevExtreme to an Angular application"
50
50
  }]
51
+ }, {
52
+ "name": "migrate",
53
+ "description": "Migration commands for DevExtreme applications",
54
+ "usage": "devextreme migrate <change name> [options]",
55
+ "arguments": [{
56
+ "name": "angular-config-components",
57
+ "description": "Migrate to the latest DevExtreme configuration components.",
58
+ "options": [{
59
+ "name": "--include",
60
+ "description": "Template file glob patterns to include (default: **/*.html). You can pass multiple patterns as a comma-separated string (e.g. \"**/a.html,**/b.html\") or as an array (e.g. [\"**/a.html\",\"**/b.html\"])."
61
+ }, {
62
+ "name": "--script-include",
63
+ "description": "TypeScript/JavaScript file glob patterns to scan for inline templates (default: **/*.ts,**/*.js). You can pass multiple patterns as a comma-separated string or as an array. Pass an empty value ('' or []) to disable."
64
+ }, {
65
+ "name": "--dry",
66
+ "description": "Run in dry mode to preview changes without applying them (default: false)."
67
+ }]
68
+ }]
51
69
  }, {
52
70
  "name": "build-theme",
53
71
  "description": "Build a custom color scheme",
@@ -1,8 +1,8 @@
1
1
  const packageJson = require('../../package.json');
2
2
  module.exports = {
3
- 'devextreme': '25.1.5',
4
- 'devextreme-react': '25.1.5',
5
- 'devextreme-vue': '25.1.5',
3
+ 'devextreme': '25.1.6',
4
+ 'devextreme-react': '25.1.6',
5
+ 'devextreme-vue': '25.1.6',
6
6
  'create-vite': '7.0.0',
7
7
  'create-vue': '3.17.0',
8
8
  'create-next-app': '15.3.4',