devextreme-schematics 1.2.20 → 1.2.24

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. package/package.json +2 -2
  2. package/src/add-app-template/index.ts +30 -0
  3. package/src/add-app-template/index_spec.ts +73 -0
  4. package/src/add-layout/files/e2e/src/app.e2e-spec.ts +14 -14
  5. package/src/add-layout/files/e2e/src/app.po.ts +11 -11
  6. package/src/add-layout/files/src/app/app-navigation.ts +1 -1
  7. package/src/add-layout/files/src/app/layouts/index.ts +3 -3
  8. package/src/add-layout/files/src/app/layouts/side-nav-inner-toolbar/side-nav-inner-toolbar.component.ts +1 -1
  9. package/src/add-layout/files/src/app/layouts/side-nav-outer-toolbar/side-nav-outer-toolbar.component.ts +1 -1
  10. package/src/add-layout/files/src/app/shared/components/change-password-form/change-password-form.component.html +8 -6
  11. package/src/add-layout/files/src/app/shared/components/create-account-form/create-account-form.component.html +9 -7
  12. package/src/add-layout/files/src/app/shared/components/footer/footer.component.ts +19 -19
  13. package/src/add-layout/files/src/app/shared/components/login-form/login-form.component.html +8 -6
  14. package/src/add-layout/files/src/app/shared/components/reset-password-form/reset-password-form.component.html +8 -6
  15. package/src/add-layout/files/src/dx-styles.scss +4 -0
  16. package/src/add-layout/index.ts +386 -0
  17. package/src/add-layout/index_spec.ts +340 -0
  18. package/src/add-sample-views/files/pages/home/home.component.ts +10 -10
  19. package/src/add-sample-views/files/pages/profile/profile.component.ts +33 -33
  20. package/src/add-sample-views/index.ts +141 -0
  21. package/src/add-sample-views/index_spec.ts +74 -0
  22. package/src/add-view/index.ts +165 -0
  23. package/src/add-view/index_spec.ts +155 -0
  24. package/src/install/index.ts +86 -0
  25. package/src/install/index_spec.ts +106 -0
  26. package/src/install/schema.json +1 -1
  27. package/src/utility/array.ts +3 -0
  28. package/src/utility/change.js +1 -1
  29. package/src/utility/change.ts +66 -0
  30. package/src/utility/latest-versions.js +2 -2
  31. package/src/utility/latest-versions.ts +6 -0
  32. package/src/utility/modify-json-file.ts +13 -0
  33. package/src/utility/project.ts +25 -0
  34. package/src/utility/routing.js +4 -4
  35. package/src/utility/routing.ts +44 -0
  36. package/src/utility/source.ts +16 -0
  37. package/src/utility/string.ts +5 -0
  38. package/src/utility/styles.ts +33 -0
@@ -0,0 +1,165 @@
1
+ import {
2
+ Rule,
3
+ chain,
4
+ Tree,
5
+ SchematicsException,
6
+ externalSchematic
7
+ } from '@angular-devkit/schematics';
8
+
9
+ import {
10
+ findModuleFromOptions
11
+ } from '@schematics/angular/utility/find-module';
12
+
13
+ import {
14
+ insertItemToArray
15
+ } from '../utility/change';
16
+
17
+ import {
18
+ hasComponentInRoutes,
19
+ getRoute,
20
+ findRoutesInSource
21
+ } from '../utility/routing';
22
+
23
+ import { getSourceFile } from '../utility/source';
24
+
25
+ import { strings, basename, normalize, dirname } from '@angular-devkit/core';
26
+
27
+ import {
28
+ getProjectName,
29
+ getApplicationPath
30
+ } from '../utility/project';
31
+ import { humanize } from '../utility/string';
32
+
33
+ function getPathToFile(host: Tree, projectName: string, moduleName: string) {
34
+ const rootPath = getApplicationPath(host, projectName);
35
+
36
+ try {
37
+ return findModuleFromOptions(host, { name: moduleName, path: rootPath, module: moduleName });
38
+ } catch (error) {
39
+ return;
40
+ }
41
+ }
42
+
43
+ function addViewToNavigation(options: any) {
44
+ return (host: Tree) => {
45
+ const navigationName = 'app-navigation';
46
+ const navigationFilePath = getPathToFile(host, options.project, navigationName);
47
+
48
+ if (!navigationFilePath) {
49
+ return;
50
+ }
51
+
52
+ const source = getSourceFile(host, navigationFilePath)!;
53
+ const pagePath = strings.dasherize(options.name);
54
+ const name = strings.dasherize(basename(normalize(options.name)));
55
+ const title = humanize(name);
56
+ const navigationItem = ` {
57
+ text: '${title}',
58
+ path: '/${pagePath}',
59
+ icon: '${options.icon}'
60
+ }`;
61
+
62
+ insertItemToArray(host, navigationFilePath, source, navigationItem, { location: 'end' });
63
+
64
+ return host;
65
+ };
66
+ }
67
+
68
+ function addRedirectRoute(host: Tree, routingModulePath: string, page: string) {
69
+ const source = getSourceFile(host, routingModulePath)!;
70
+ const content = source.getText();
71
+ if (content.match(/path:\s*'\*\*'/g)) {
72
+ return;
73
+ }
74
+
75
+ const routes = findRoutesInSource(source)!;
76
+ const redirectRoute = ` {
77
+ path: '**',
78
+ redirectTo: '${strings.dasherize(page)}'
79
+ }`;
80
+
81
+ insertItemToArray(host, routingModulePath, routes, redirectRoute, { location: 'end' });
82
+ }
83
+
84
+ export function addViewToRouting(options: any) {
85
+ return (host: Tree) => {
86
+ const routingModulePath = getPathToFile(host, options.project, options.module);
87
+
88
+ if (!routingModulePath) {
89
+ throw new SchematicsException('Specified module does not exist.');
90
+ }
91
+
92
+ addRedirectRoute(host, routingModulePath, options.name);
93
+
94
+ const source = getSourceFile(host, routingModulePath)!;
95
+ const routes = findRoutesInSource(source);
96
+
97
+ if (!routes) {
98
+ throw new SchematicsException('No routes found.');
99
+ }
100
+
101
+ if (!hasComponentInRoutes(routes, options.name)) {
102
+ const route = getRoute(options.name);
103
+ insertItemToArray(host, routingModulePath, routes, route);
104
+ }
105
+ return host;
106
+ };
107
+ }
108
+
109
+ function getPathForView(name: string) {
110
+ if (name.includes('/')) {
111
+ return name;
112
+ }
113
+ return 'pages/' + name;
114
+ }
115
+
116
+ function getModuleName(addRoute: boolean, moduleName: string) {
117
+ if (!moduleName && addRoute) {
118
+ return 'app-routing';
119
+ }
120
+ return moduleName;
121
+ }
122
+
123
+ function addContentToView(options: any) {
124
+ return (host: Tree) => {
125
+ const name = strings.dasherize(basename(normalize(options.name)));
126
+ const path = `${dirname(options.name)}/${name}`;
127
+ const title = humanize(name);
128
+ const componentPath = `/${getApplicationPath(host, options.project)}${path}/${name}.component.html`;
129
+ if (host.exists(componentPath)) {
130
+ host.overwrite(
131
+ componentPath,
132
+ `<h2 class="content-block">${title}</h2>
133
+ <div class="content-block">
134
+ <div class="dx-card responsive-paddings">Put your content here</div>
135
+ </div>
136
+ `);
137
+ }
138
+ return host;
139
+ };
140
+ }
141
+
142
+ export default function(options: any): Rule {
143
+ return (host: Tree) => {
144
+ const addRoute = options.addRoute;
145
+ const project = getProjectName(host, options);
146
+ const module = getModuleName(addRoute, options.module);
147
+ const name = getPathForView(options.name);
148
+ const rules = [externalSchematic('@schematics/angular', 'component', {
149
+ name,
150
+ project,
151
+ module,
152
+ skipTests: options.skipTests,
153
+ inlineStyle: options.inlineStyle,
154
+ prefix: options.prefix
155
+ }),
156
+ addContentToView({ name, project })
157
+ ];
158
+
159
+ if (addRoute) {
160
+ rules.push(addViewToRouting({ name, project, module }));
161
+ rules.push(addViewToNavigation({ name, icon: options.icon, project }));
162
+ }
163
+ return chain(rules);
164
+ };
165
+ }
@@ -0,0 +1,155 @@
1
+ import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
2
+ import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema';
3
+ import * as path from 'path';
4
+
5
+ const collectionPath = path.join(__dirname, '../collection.json');
6
+
7
+ describe('view', () => {
8
+ const appOptions: any = {
9
+ name: 'testApp',
10
+ projectRoot: '',
11
+ inlineStyle: false,
12
+ inlineTemplate: false,
13
+ routing: true,
14
+ style: 'css',
15
+ skipTests: false,
16
+ skipPackageJson: false
17
+ };
18
+
19
+ const workspaceOptions: WorkspaceOptions = {
20
+ name: 'workspace',
21
+ version: '6.0.0'
22
+ };
23
+
24
+ const componentOptions: any = {
25
+ name: 'test',
26
+ inlineStyle: false,
27
+ inlineTemplate: false,
28
+ changeDetection: 'Default',
29
+ styleext: 'css',
30
+ skipImport: true,
31
+ module: undefined,
32
+ export: false,
33
+ project: 'testApp'
34
+ };
35
+
36
+ const angularSchematicsCollection = require.resolve('../../node_modules/@schematics/angular/collection.json');
37
+ const schematicRunner = new SchematicTestRunner('@schematics/angular', angularSchematicsCollection);
38
+ let appTree: UnitTestTree;
39
+
40
+ beforeEach(async () => {
41
+ appTree = await schematicRunner.runSchematicAsync('workspace', workspaceOptions).toPromise();
42
+ appTree = await schematicRunner.runSchematicAsync('application', appOptions, appTree).toPromise();
43
+ });
44
+
45
+ it('should create new view', async () => {
46
+ const runner = new SchematicTestRunner('schematics', collectionPath);
47
+ let tree = await runner.runSchematicAsync('add-layout', { layout: 'side-nav-outer-toolbar' }, appTree).toPromise();
48
+ tree = await runner.runSchematicAsync('add-view', componentOptions, appTree).toPromise();
49
+
50
+ expect(tree.files).toContain('/src/app/pages/test/test.component.ts');
51
+ expect(tree.files).toContain('/src/app/pages/test/test.component.html');
52
+
53
+ const content = tree.readContent('/src/app/pages/test/test.component.html');
54
+
55
+ expect(content).toMatch(/<h2 class="content-block">Test<\/h2>/);
56
+ });
57
+
58
+ it('should add view to default routing module', async () => {
59
+ const options = { ...componentOptions, addRoute: true };
60
+
61
+ const runner = new SchematicTestRunner('schematics', collectionPath);
62
+ let tree = await runner.runSchematicAsync('add-layout', { layout: 'side-nav-outer-toolbar' }, appTree).toPromise();
63
+ tree = await runner.runSchematicAsync('add-view', options, tree).toPromise();
64
+ tree = await runner.runSchematicAsync('add-view', { ...options, name: 'test2' }, tree).toPromise();
65
+ const moduleContent = tree.readContent('/src/app/app-routing.module.ts');
66
+
67
+ expect(moduleContent).toContain(`const routes: Routes = [
68
+ {
69
+ path: 'pages/test2',
70
+ component: Test2Component,
71
+ canActivate: [ AuthGuardService ]
72
+ },
73
+ {
74
+ path: 'pages/test',
75
+ component: TestComponent,
76
+ canActivate: [ AuthGuardService ]
77
+ },
78
+ {
79
+ path: 'login-form',
80
+ component: LoginFormComponent,
81
+ canActivate: [ AuthGuardService ]
82
+ },
83
+ {
84
+ path: '**',
85
+ redirectTo: 'pages/test'
86
+ }
87
+ ];`);
88
+ });
89
+
90
+ it('should add view to other routing module', async () => {
91
+ const options = { ...componentOptions, addRoute: true, module: 'test/test-routing' };
92
+
93
+ const runner = new SchematicTestRunner('schematics', collectionPath);
94
+ let tree = await runner.runExternalSchematicAsync('@schematics/angular', 'module', {
95
+ name: 'test',
96
+ routing: true,
97
+ project: 'testApp'
98
+ }, appTree).toPromise();
99
+
100
+ tree = await runner.runSchematicAsync('add-layout', {
101
+ layout: 'side-nav-outer-toolbar',
102
+ project: 'testApp',
103
+ name: 'test'
104
+ }, tree).toPromise();
105
+ tree = await runner.runSchematicAsync('add-view', options, tree).toPromise();
106
+
107
+ const moduleContent = tree.readContent('/src/app/test/test-routing.module.ts');
108
+
109
+ expect(moduleContent).toMatch(/component: TestComponent/);
110
+ expect(moduleContent).toMatch(/path: 'pages\/test'/);
111
+ expect(moduleContent).toContain('canActivate: [ AuthGuardService ]');
112
+ });
113
+
114
+ it('should add view to navigation', async () => {
115
+ const runner = new SchematicTestRunner('schematics', collectionPath);
116
+ let tree = await runner.runSchematicAsync('add-layout', { layout: 'side-nav-outer-toolbar' }, appTree).toPromise();
117
+ tree = await runner.runSchematicAsync('add-view', componentOptions, tree).toPromise();
118
+
119
+ componentOptions.name = 'some test';
120
+ componentOptions.icon = 'home';
121
+ tree = await runner.runSchematicAsync('add-view', componentOptions, tree).toPromise();
122
+
123
+ const moduleContent = tree.readContent('/src/app/app-navigation.ts');
124
+
125
+ expect(moduleContent).toMatch(/text: 'Some Test'/);
126
+ expect(moduleContent).toMatch(/icon: 'home'/);
127
+ expect(moduleContent).toMatch(/text: 'Test'/);
128
+ expect(moduleContent).toMatch(/icon: 'folder'/);
129
+
130
+ expect(moduleContent).toContain(`navigation = [
131
+ {
132
+ text: 'Test',
133
+ path: '/pages/test',
134
+ icon: 'folder'
135
+ },
136
+ {
137
+ text: 'Some Test',
138
+ path: '/pages/some-test',
139
+ icon: 'home'
140
+ }
141
+ ];`);
142
+ const pageContent = tree.readContent('/src/app/pages/some-test/some-test.component.html');
143
+ expect(pageContent).toMatch(/<h2 class="content-block">Some Test<\/h2>/);
144
+ });
145
+
146
+ it('should create new view with path', async () => {
147
+ const runner = new SchematicTestRunner('schematics', collectionPath);
148
+ componentOptions.name = 'folder/test';
149
+ let tree = await runner.runSchematicAsync('add-layout', { layout: 'side-nav-outer-toolbar' }, appTree).toPromise();
150
+ tree = await runner.runSchematicAsync('add-view', componentOptions, appTree).toPromise();
151
+
152
+ expect(tree.files).toContain('/src/app/folder/test/test.component.ts');
153
+ expect(tree.files).toContain('/src/app/folder/test/test.component.html');
154
+ });
155
+ });
@@ -0,0 +1,86 @@
1
+ import {
2
+ Rule,
3
+ Tree,
4
+ SchematicContext,
5
+ chain
6
+ } from '@angular-devkit/schematics';
7
+
8
+ import { addStylesToApp } from '../utility/styles';
9
+
10
+ import {
11
+ NodeDependencyType,
12
+ addPackageJsonDependency
13
+ } from '@schematics/angular/utility/dependencies';
14
+
15
+ import {
16
+ NodePackageInstallTask
17
+ } from '@angular-devkit/schematics/tasks';
18
+
19
+ import { latestVersions } from '../utility/latest-versions';
20
+ import { modifyJSONFile } from '../utility/modify-json-file';
21
+
22
+ export default function(options: any): Rule {
23
+ return chain([
24
+ (host: Tree) => addDevExtremeDependency(host, { dxversion: options.dxversion }),
25
+ (host: Tree) => addDevExtremeCSS(host, { project: options.project }),
26
+ (host: Tree) => reqisterJSZip(host),
27
+ (_, context: SchematicContext) => {
28
+ context.addTask(new NodePackageInstallTask());
29
+ }
30
+ ]);
31
+ }
32
+
33
+ function addDevExtremeDependency(host: Tree, options: any) {
34
+ addPackageJsonDependency(host, {
35
+ type: NodeDependencyType.Default,
36
+ name: 'devextreme',
37
+ version: options.dxversion || latestVersions['devextreme']
38
+ });
39
+ addPackageJsonDependency(host, {
40
+ type: NodeDependencyType.Default,
41
+ name: 'devextreme-angular',
42
+ version: options.dxversion || latestVersions['devextreme-angular']
43
+ });
44
+ addPackageJsonDependency(host, {
45
+ type: NodeDependencyType.Dev,
46
+ name: 'devextreme-cli',
47
+ version: latestVersions['devextreme-cli']
48
+ });
49
+ addPackageJsonDependency(host, {
50
+ type: NodeDependencyType.Dev,
51
+ name: 'devextreme-themebuilder',
52
+ version: options.dxversion || latestVersions['devextreme']
53
+ });
54
+
55
+ return host;
56
+ }
57
+
58
+ function addDevExtremeCSS(host: Tree, options: any) {
59
+ modifyJSONFile(host, './angular.json', config => {
60
+
61
+ return addStylesToApp(host, options.project, config);
62
+ });
63
+
64
+ return host;
65
+ }
66
+
67
+ function reqisterJSZip(host: Tree) {
68
+ modifyJSONFile(host, './tsconfig.app.json', config => {
69
+ const compilerOptions = config['compilerOptions'];
70
+ let paths = compilerOptions['paths'];
71
+
72
+ if (!paths) {
73
+ paths = {};
74
+ }
75
+
76
+ if (!paths['jszip']) {
77
+ paths['jszip'] = ['node_modules/jszip/dist/jszip.min.js'];
78
+ }
79
+
80
+ compilerOptions['paths'] = paths;
81
+
82
+ return config;
83
+ });
84
+
85
+ return host;
86
+ }
@@ -0,0 +1,106 @@
1
+ import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
2
+ import { Schema as WorkspaceOptions } from '@schematics/angular/workspace/schema';
3
+ import * as path from 'path';
4
+ import { latestVersions } from '../utility/latest-versions';
5
+
6
+ const collectionPath = path.join(__dirname, '../collection.json');
7
+
8
+ describe('install', () => {
9
+ // TODO: Extract workspase preparing somewhere
10
+ const appOptions: any = {
11
+ name: 'testApp',
12
+ projectRoot: '',
13
+ inlineStyle: false,
14
+ inlineTemplate: false,
15
+ routing: true,
16
+ style: 'css',
17
+ skipTests: false,
18
+ skipPackageJson: false
19
+ };
20
+
21
+ const workspaceOptions: WorkspaceOptions = {
22
+ name: 'workspace',
23
+ // TODO: use angular latest-versions module
24
+ version: '6.0.0'
25
+ };
26
+
27
+ const angularSchematicsCollection = require.resolve('../../node_modules/@schematics/angular/collection.json');
28
+ const schematicRunner = new SchematicTestRunner('@schematics/angular', angularSchematicsCollection);
29
+ let appTree: UnitTestTree;
30
+
31
+ beforeEach(async () => {
32
+ appTree = await schematicRunner.runSchematicAsync('workspace', workspaceOptions).toPromise();
33
+ appTree = await schematicRunner.runSchematicAsync('application', appOptions, appTree).toPromise();
34
+ });
35
+
36
+ it('should add devextreme dependency (default)', async () => {
37
+ const runner = new SchematicTestRunner('schematics', collectionPath);
38
+ const tree = await runner.runSchematicAsync('install', {}, appTree).toPromise();
39
+ const packageConfig = JSON.parse(tree.readContent('package.json'));
40
+
41
+ expect(packageConfig.dependencies['devextreme']).toBe(latestVersions['devextreme']);
42
+ expect(packageConfig.dependencies['devextreme-angular']).toBe(latestVersions['devextreme-angular']);
43
+ expect(packageConfig.devDependencies['devextreme-themebuilder']).toBe(latestVersions['devextreme']);
44
+ });
45
+
46
+ it('should add devextreme dependency (custom)', async () => {
47
+ const runner = new SchematicTestRunner('schematics', collectionPath);
48
+ const tree = await runner.runSchematicAsync('install', { dxversion: '18.2.5' }, appTree).toPromise();
49
+ const packageConfig = JSON.parse(tree.readContent('package.json'));
50
+
51
+ expect(packageConfig.dependencies.devextreme).toBe('18.2.5');
52
+ expect(packageConfig.devDependencies['devextreme-themebuilder']).toBe('18.2.5');
53
+ });
54
+
55
+ it('should add devextreme cli devDependency', async () => {
56
+ const runner = new SchematicTestRunner('schematics', collectionPath);
57
+ const tree = await runner.runSchematicAsync('install', { dxversion: '18.2.5' }, appTree).toPromise();
58
+ const packageConfig = JSON.parse(tree.readContent('package.json'));
59
+
60
+ expect(packageConfig.devDependencies['devextreme-cli']).toBeDefined();
61
+ });
62
+
63
+ it('should add devextreme styles', async () => {
64
+ const runner = new SchematicTestRunner('schematics', collectionPath);
65
+ const tree = await runner.runSchematicAsync('install', {}, appTree).toPromise();
66
+ const angularConfig = JSON.parse(tree.readContent('angular.json'));
67
+ const styles = angularConfig['projects']['testApp']['architect']['build']['options']['styles'];
68
+
69
+ expect(styles[0]).toBe('node_modules/devextreme/dist/css/dx.common.css');
70
+ expect(styles[1]).toBe('node_modules/devextreme/dist/css/dx.light.css');
71
+ });
72
+
73
+ it('should register jszip', async () => {
74
+ const runner = new SchematicTestRunner('schematics', collectionPath);
75
+ const tree = await runner.runSchematicAsync('install', {}, appTree).toPromise();
76
+ const tsconfig = JSON.parse(tree.readContent('tsconfig.app.json'));
77
+ const jszip = tsconfig['compilerOptions']['paths']['jszip'];
78
+
79
+ expect(jszip[0]).toBe('node_modules/jszip/dist/jszip.min.js');
80
+ });
81
+
82
+ it('should add devextreme styles to the specified project', async () => {
83
+ const secondAppOptions: any = {
84
+ name: 'testApp2',
85
+ inlineStyle: false,
86
+ inlineTemplate: false,
87
+ projectRoot: 'src2',
88
+ routing: true,
89
+ style: 'css',
90
+ skipTests: false,
91
+ skipPackageJson: false
92
+ };
93
+
94
+ appTree = await schematicRunner.runSchematicAsync('application', secondAppOptions, appTree).toPromise();
95
+
96
+ const runner = new SchematicTestRunner('schematics', collectionPath);
97
+ const tree = await runner.runSchematicAsync('install', { project: 'testApp2' }, appTree).toPromise();
98
+ const angularConfig = JSON.parse(tree.readContent('angular.json'));
99
+ const styles = angularConfig['projects']['testApp2']['architect']['build']['options']['styles'];
100
+
101
+ expect(styles[0]).toBe('node_modules/devextreme/dist/css/dx.common.css');
102
+ expect(styles[1]).toBe('node_modules/devextreme/dist/css/dx.light.css');
103
+
104
+ expect(angularConfig['projects']['testApp']['architect']['build']['options']['styles'].length).toBe(1);
105
+ });
106
+ });
@@ -7,7 +7,7 @@
7
7
  "dxversion": {
8
8
  "type": "string",
9
9
  "description": "The DevExtreme version",
10
- "default": "^21.1.5"
10
+ "default": "^21.2.4"
11
11
  },
12
12
  "project": {
13
13
  "type": "string",
@@ -0,0 +1,3 @@
1
+ export function makeArrayUnique(arr: Array<any>) {
2
+ return [...new Set(arr)];
3
+ }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- const newLine = `
3
+ const newLine = `
4
4
  `;
5
5
  function applyChanges(host, changes, filePath) {
6
6
  const recorder = host.beginUpdate(filePath);
@@ -0,0 +1,66 @@
1
+ import { Tree } from '@angular-devkit/schematics';
2
+ import { InsertChange, Change } from '@schematics/angular/utility/change';
3
+
4
+ import {
5
+ Node
6
+ } from 'typescript';
7
+
8
+ const newLine = `
9
+ `;
10
+
11
+ export function applyChanges(host: Tree, changes: Change[], filePath: string) {
12
+ const recorder = host.beginUpdate(filePath);
13
+
14
+ changes.forEach((change: InsertChange) => {
15
+ recorder.insertLeft(change.pos, change.toAdd);
16
+ });
17
+
18
+ host.commitUpdate(recorder);
19
+
20
+ return host;
21
+ }
22
+
23
+ // TODO: implement options.index
24
+ // TODO: implement spaces shift calculation
25
+ export function insertItemToArray(
26
+ host: Tree,
27
+ filePath: string,
28
+ node: Node,
29
+ item: string,
30
+ options: { location: 'start' | 'end' } = { location: 'start' }
31
+ ) {
32
+ const isItemValid = /^\s*\{[\s\S]*\}\s*$/m.test(item);
33
+ if (!isItemValid) {
34
+ return host;
35
+ }
36
+
37
+ const nodeContent = node.getText();
38
+ const nodePosition = node.getStart();
39
+ const leftBracketPosition = nodePosition + nodeContent.indexOf('[');
40
+ const rightBracketPosition = nodePosition + nodeContent.lastIndexOf(']');
41
+ let itemPosition = leftBracketPosition + 1;
42
+ let fileRecorder = host.beginUpdate(filePath);
43
+
44
+ item = newLine + item;
45
+
46
+ const isNodeEmpty = !/\[[\s\S]*\S+[\s\S]*\]/m.test(nodeContent);
47
+ if (isNodeEmpty) {
48
+ const formattedArray = `[${newLine}]`;
49
+ fileRecorder.remove(leftBracketPosition, rightBracketPosition - leftBracketPosition + 1);
50
+ fileRecorder.insertLeft(leftBracketPosition, formattedArray);
51
+ host.commitUpdate(fileRecorder);
52
+ fileRecorder = host.beginUpdate(filePath);
53
+ } else {
54
+ if (options.location === 'end') {
55
+ itemPosition = nodePosition + nodeContent.lastIndexOf('}') + 1;
56
+ item = ',' + item;
57
+ } else {
58
+ item = item + ',';
59
+ }
60
+ }
61
+
62
+ fileRecorder.insertLeft(itemPosition, item);
63
+ host.commitUpdate(fileRecorder);
64
+
65
+ return host;
66
+ }
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  // TODO: implement
4
4
  exports.latestVersions = {
5
- 'devextreme': '^21.1.5',
6
- 'devextreme-angular': '^21.1.5',
5
+ 'devextreme': '^21.2.4',
6
+ 'devextreme-angular': '^21.2.4',
7
7
  'devextreme-cli': 'latest'
8
8
  };
9
9
  //# sourceMappingURL=latest-versions.js.map
@@ -0,0 +1,6 @@
1
+ // TODO: implement
2
+ export const latestVersions = {
3
+ 'devextreme': '^21.2.4',
4
+ 'devextreme-angular': '^21.2.4',
5
+ 'devextreme-cli': 'latest'
6
+ };
@@ -0,0 +1,13 @@
1
+ import { Tree } from '@angular-devkit/schematics';
2
+
3
+ export function modifyJSONFile(host: Tree, path: string, callback: (obj: any) => any) {
4
+ let serializedConfig = host.read(path)!.toString();
5
+ serializedConfig = serializedConfig.replace(/\/\*[\S\s]+?\*\/\r?\n/g, '');
6
+ let obj = JSON.parse(serializedConfig);
7
+
8
+ obj = callback(obj);
9
+
10
+ host.overwrite(path, `${JSON.stringify(obj, null, 2)}\n`);
11
+
12
+ return host;
13
+ }
@@ -0,0 +1,25 @@
1
+ import { Tree } from '@angular-devkit/schematics';
2
+ import { getWorkspace } from '@schematics/angular/utility/config';
3
+
4
+ export function getProjectName(host: Tree, project: any) {
5
+ const projectName = project;
6
+ const workspace = getWorkspace(host);
7
+ const projects = Object.keys(workspace.projects);
8
+
9
+ return projectName && projects.indexOf(projectName) > -1 ? projectName : workspace.defaultProject;
10
+ }
11
+
12
+ export function getApplicationPath(host: Tree, projectName: string) {
13
+ const sourcePath = getSourceRootPath(host, projectName);
14
+ return sourcePath ? `${sourcePath}/app/` : 'src/app/';
15
+ }
16
+
17
+ export function getSourceRootPath(host: Tree, projectName: string) {
18
+ const project = getWorkspace(host).projects[projectName];
19
+ return project.sourceRoot || project.root;
20
+ }
21
+
22
+ export function getRootPath(host: Tree, projectName: string) {
23
+ const project = getWorkspace(host).projects[projectName];
24
+ return project.root;
25
+ }
@@ -12,10 +12,10 @@ function hasComponentInRoutes(routes, name) {
12
12
  }
13
13
  exports.hasComponentInRoutes = hasComponentInRoutes;
14
14
  function getRoute(name) {
15
- return ` {
16
- path: '${core_1.strings.dasherize(name)}',
17
- component: ${getRouteComponentName(name)},
18
- canActivate: [ AuthGuardService ]
15
+ return ` {
16
+ path: '${core_1.strings.dasherize(name)}',
17
+ component: ${getRouteComponentName(name)},
18
+ canActivate: [ AuthGuardService ]
19
19
  }`;
20
20
  }
21
21
  exports.getRoute = getRoute;