devextreme-schematics 1.15.0 → 1.16.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 +6 -6
- package/src/add-app-template/schema.json +1 -1
- package/src/install/schema.json +1 -1
- package/src/utility/latest-versions.js +2 -2
- package/src/add-app-template/index.ts +0 -56
- package/src/add-app-template/index_spec.ts +0 -73
- package/src/add-layout/index.ts +0 -447
- package/src/add-layout/index_spec.ts +0 -318
- package/src/add-sample-views/index.ts +0 -100
- package/src/add-sample-views/index_spec.ts +0 -76
- package/src/add-view/index.ts +0 -200
- package/src/add-view/index_spec.ts +0 -147
- package/src/install/index.ts +0 -97
- package/src/install/index_spec.ts +0 -104
- package/src/migrate-config-components/index.ts +0 -77
- package/src/migrate-config-components/template-migrator.ts +0 -322
- package/src/utility/angular-version.ts +0 -18
- package/src/utility/array.ts +0 -3
- package/src/utility/change.ts +0 -71
- package/src/utility/latest-versions.ts +0 -7
- package/src/utility/modify-json-file.ts +0 -16
- package/src/utility/patch.ts +0 -14
- package/src/utility/project.ts +0 -30
- package/src/utility/routing.ts +0 -44
- package/src/utility/source.ts +0 -16
- package/src/utility/string.ts +0 -5
- package/src/utility/styles.ts +0 -29
- package/src/utility/typescript-resolver.ts +0 -144
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devextreme-schematics",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.0",
|
|
4
4
|
"description": "DevExtreme schematics",
|
|
5
5
|
"author": "Developer Express Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -17,16 +17,16 @@
|
|
|
17
17
|
],
|
|
18
18
|
"schematics": "./src/collection.json",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@angular-devkit/core": "^19.2.
|
|
21
|
-
"@angular-devkit/schematics": "^19.2.
|
|
22
|
-
"@schematics/angular": "^19.2.
|
|
20
|
+
"@angular-devkit/core": "^19.2.27",
|
|
21
|
+
"@angular-devkit/schematics": "^19.2.27",
|
|
22
|
+
"@schematics/angular": "^19.2.27",
|
|
23
23
|
"parse5": "^7.3.0",
|
|
24
24
|
"picomatch": "^4.0.4",
|
|
25
|
-
"semver": "^7.8.
|
|
25
|
+
"semver": "^7.8.5"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@types/jasmine": "~3.10.19",
|
|
29
|
-
"@types/node": "20.19.
|
|
29
|
+
"@types/node": "20.19.43",
|
|
30
30
|
"@types/picomatch": "^4.0.3",
|
|
31
31
|
"@types/semver": "^7.7.1",
|
|
32
32
|
"jasmine": "^2.99.0",
|
package/src/install/schema.json
CHANGED
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.latestVersions = void 0;
|
|
4
4
|
// TODO: implement
|
|
5
5
|
exports.latestVersions = {
|
|
6
|
-
'devextreme': '
|
|
7
|
-
'devextreme-angular': '
|
|
6
|
+
'devextreme': '26.1.3',
|
|
7
|
+
'devextreme-angular': '26.1.3',
|
|
8
8
|
'devextreme-cli': 'latest',
|
|
9
9
|
'sass-embedded': '1.66.0'
|
|
10
10
|
};
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Rule,
|
|
3
|
-
chain,
|
|
4
|
-
schematic,
|
|
5
|
-
Tree,
|
|
6
|
-
} from '@angular-devkit/schematics';
|
|
7
|
-
|
|
8
|
-
import { existsSync } from 'fs';
|
|
9
|
-
import { resolve, join } from 'path';
|
|
10
|
-
|
|
11
|
-
import { spawnSync } from 'child_process';
|
|
12
|
-
|
|
13
|
-
export default function(options: any): Rule {
|
|
14
|
-
const rules = [
|
|
15
|
-
schematic('install', {
|
|
16
|
-
dxversion: options.dxversion,
|
|
17
|
-
project: options.project
|
|
18
|
-
}),
|
|
19
|
-
schematic('add-layout', {
|
|
20
|
-
layout: options.layout,
|
|
21
|
-
resolveConflicts: options.resolveConflicts,
|
|
22
|
-
project: options.project,
|
|
23
|
-
skipInstall: true,
|
|
24
|
-
updateBudgets: options.updateBudgets,
|
|
25
|
-
globalNgCliVersion: options.globalNgCliVersion
|
|
26
|
-
}),
|
|
27
|
-
// schematics installed packages with flag --ignore-scripts
|
|
28
|
-
// @angular/cli@14 add option allowScript to NodePackageInstallTask
|
|
29
|
-
(host: Tree) => {
|
|
30
|
-
postinstallScripts();
|
|
31
|
-
return host;
|
|
32
|
-
}
|
|
33
|
-
];
|
|
34
|
-
|
|
35
|
-
if (!options.empty) {
|
|
36
|
-
rules.push(schematic('add-sample-views', {
|
|
37
|
-
project: options.project
|
|
38
|
-
}));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return chain(rules);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const postinstallScripts = () => {
|
|
45
|
-
const isWin = /^win/.test(process.platform);
|
|
46
|
-
|
|
47
|
-
const sassEmbeddedPath = resolve('node_modules', 'sass-embedded');
|
|
48
|
-
const sassVendorPath = join(sassEmbeddedPath, 'dist', 'lib', 'src', 'vendor', 'dart-sass-embedded');
|
|
49
|
-
if (!existsSync(sassVendorPath)) {
|
|
50
|
-
spawnSync('npm', ['run', 'postinstall'], {
|
|
51
|
-
cwd: resolve(join('node_modules', 'sass-embedded')),
|
|
52
|
-
windowsVerbatimArguments: true,
|
|
53
|
-
shell: isWin ? false : true
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
};
|
|
@@ -1,73 +0,0 @@
|
|
|
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
|
-
const appOptions: any = {
|
|
8
|
-
name: 'testApp',
|
|
9
|
-
projectRoot: '',
|
|
10
|
-
inlineStyle: false,
|
|
11
|
-
inlineTemplate: false,
|
|
12
|
-
routing: true,
|
|
13
|
-
style: 'css',
|
|
14
|
-
skipTests: false,
|
|
15
|
-
skipPackageJson: false
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const workspaceOptions: WorkspaceOptions = {
|
|
19
|
-
name: 'workspace',
|
|
20
|
-
version: '6.0.0'
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const angularSchematicsCollection = require.resolve('../../node_modules/@schematics/angular/collection.json');
|
|
24
|
-
const schematicRunner = new SchematicTestRunner('@schematics/angular', angularSchematicsCollection);
|
|
25
|
-
let appTree: UnitTestTree;
|
|
26
|
-
|
|
27
|
-
beforeEach(async () => {
|
|
28
|
-
appTree = await schematicRunner.runSchematic('workspace', workspaceOptions);
|
|
29
|
-
appTree = await schematicRunner.runSchematic('application', appOptions, appTree);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
describe('add-app-template', () => {
|
|
33
|
-
it('should add DevExtreme', async () => {
|
|
34
|
-
const runner = new SchematicTestRunner('schematics', collectionPath);
|
|
35
|
-
const tree = await runner.runSchematic('add-app-template', { }, appTree);
|
|
36
|
-
const packageConfig = JSON.parse(tree.readContent('package.json'));
|
|
37
|
-
|
|
38
|
-
expect('devextreme' in packageConfig.dependencies).toBe(true);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
it('should consider the `project` option', async () => {
|
|
42
|
-
appTree = await schematicRunner.runSchematic('application', {
|
|
43
|
-
name: 'testApp2',
|
|
44
|
-
inlineStyle: false,
|
|
45
|
-
inlineTemplate: false,
|
|
46
|
-
routing: true,
|
|
47
|
-
style: 'scss',
|
|
48
|
-
projectRoot: 'projects/testApp2'
|
|
49
|
-
}, appTree);
|
|
50
|
-
|
|
51
|
-
const runner = new SchematicTestRunner('schematics', collectionPath);
|
|
52
|
-
const tree = await runner.runSchematic('add-app-template', {
|
|
53
|
-
project: 'testApp2'
|
|
54
|
-
}, appTree);
|
|
55
|
-
|
|
56
|
-
expect(tree.files)
|
|
57
|
-
.toContain('/devextreme.json');
|
|
58
|
-
expect(tree.files)
|
|
59
|
-
.toContain('/projects/testApp2/src/themes/metadata.base.json');
|
|
60
|
-
expect(tree.files)
|
|
61
|
-
.toContain('/projects/testApp2/src/app/pages/home/home.component.ts');
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it('should consider the `updateBudgets` option', async () => {
|
|
65
|
-
const runner = new SchematicTestRunner('schematics', collectionPath);
|
|
66
|
-
const tree = await runner.runSchematic('add-app-template', { updateBudgets: true }, appTree);
|
|
67
|
-
|
|
68
|
-
const angularContent = JSON.parse(tree.readContent('/angular.json'));
|
|
69
|
-
const budgets = angularContent.projects.testApp.architect.build.configurations.production.budgets;
|
|
70
|
-
|
|
71
|
-
expect(budgets[0].maximumWarning).toEqual('4mb');
|
|
72
|
-
});
|
|
73
|
-
});
|
package/src/add-layout/index.ts
DELETED
|
@@ -1,447 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Rule,
|
|
3
|
-
SchematicContext,
|
|
4
|
-
Tree,
|
|
5
|
-
apply,
|
|
6
|
-
url,
|
|
7
|
-
move,
|
|
8
|
-
chain,
|
|
9
|
-
filter,
|
|
10
|
-
forEach,
|
|
11
|
-
mergeWith,
|
|
12
|
-
callRule,
|
|
13
|
-
FileEntry,
|
|
14
|
-
template
|
|
15
|
-
} from '@angular-devkit/schematics';
|
|
16
|
-
|
|
17
|
-
import {
|
|
18
|
-
SourceFile
|
|
19
|
-
} from '@schematics/angular/third_party/github.com/Microsoft/TypeScript/lib/typescript';
|
|
20
|
-
|
|
21
|
-
import { strings } from '@angular-devkit/core';
|
|
22
|
-
|
|
23
|
-
import { join, basename } from 'path';
|
|
24
|
-
|
|
25
|
-
import { SemVer } from 'semver';
|
|
26
|
-
|
|
27
|
-
import {
|
|
28
|
-
getApplicationPath,
|
|
29
|
-
getSourceRootPath,
|
|
30
|
-
getProjectName
|
|
31
|
-
} from '../utility/project';
|
|
32
|
-
|
|
33
|
-
import {
|
|
34
|
-
humanize
|
|
35
|
-
} from '../utility/string';
|
|
36
|
-
|
|
37
|
-
import {
|
|
38
|
-
addStylesToApp
|
|
39
|
-
} from '../utility/styles';
|
|
40
|
-
|
|
41
|
-
import {
|
|
42
|
-
modifyJSONFile,
|
|
43
|
-
} from '../utility/modify-json-file';
|
|
44
|
-
|
|
45
|
-
import {
|
|
46
|
-
NodeDependencyType,
|
|
47
|
-
addPackageJsonDependency,
|
|
48
|
-
getPackageJsonDependency,
|
|
49
|
-
} from '@schematics/angular/utility/dependencies';
|
|
50
|
-
|
|
51
|
-
import { getSourceFile } from '../utility/source';
|
|
52
|
-
|
|
53
|
-
import {
|
|
54
|
-
applyChanges,
|
|
55
|
-
insertItemToArray
|
|
56
|
-
} from '../utility/change';
|
|
57
|
-
|
|
58
|
-
import {
|
|
59
|
-
hasComponentInRoutes,
|
|
60
|
-
getRoute,
|
|
61
|
-
findRoutesInSource
|
|
62
|
-
} from '../utility/routing';
|
|
63
|
-
|
|
64
|
-
import { insertImport } from '@schematics/angular/utility/ast-utils';
|
|
65
|
-
|
|
66
|
-
import { getWorkspace } from '@schematics/angular/utility/workspace';
|
|
67
|
-
import { Change } from '@schematics/angular/utility/change';
|
|
68
|
-
|
|
69
|
-
import { PatchNodePackageInstallTask } from '../utility/patch';
|
|
70
|
-
import { isAngularVersionHigherThan } from '../utility/angular-version';
|
|
71
|
-
|
|
72
|
-
const routes = [
|
|
73
|
-
{
|
|
74
|
-
name: 'AuthGuardService',
|
|
75
|
-
type: 'service',
|
|
76
|
-
location: './shared/services'
|
|
77
|
-
},
|
|
78
|
-
{
|
|
79
|
-
name: 'LoginFormComponent',
|
|
80
|
-
path: 'login-form',
|
|
81
|
-
type: 'component',
|
|
82
|
-
location: './shared/components'
|
|
83
|
-
},
|
|
84
|
-
{
|
|
85
|
-
name: 'ResetPasswordFormComponent',
|
|
86
|
-
path: 'reset-password',
|
|
87
|
-
type: 'component',
|
|
88
|
-
location: './shared/components'
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
name: 'CreateAccountFormComponent',
|
|
92
|
-
path: 'create-account',
|
|
93
|
-
type: 'component',
|
|
94
|
-
location: './shared/components'
|
|
95
|
-
},
|
|
96
|
-
{
|
|
97
|
-
name: 'ChangePasswordFormComponent',
|
|
98
|
-
path: 'change-password/:recoveryCode',
|
|
99
|
-
type: 'component',
|
|
100
|
-
location: './shared/components'
|
|
101
|
-
}
|
|
102
|
-
];
|
|
103
|
-
|
|
104
|
-
const projectFilesSource = './files/src';
|
|
105
|
-
const workspaceFilesSource = './files';
|
|
106
|
-
|
|
107
|
-
function addScriptSafe(scripts: any, name: string, value: string) {
|
|
108
|
-
const currentValue = scripts[name];
|
|
109
|
-
|
|
110
|
-
if (!currentValue) {
|
|
111
|
-
scripts[name] = value;
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const alterName = `origin-${name}`;
|
|
116
|
-
const safeValue = `npm run ${alterName} && ${value}`;
|
|
117
|
-
|
|
118
|
-
if (currentValue === value || currentValue === safeValue) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
scripts[alterName] = currentValue;
|
|
123
|
-
scripts[name] = safeValue;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
function addBuildThemeScript() {
|
|
127
|
-
return (host: Tree) => {
|
|
128
|
-
modifyJSONFile(host, './package.json', config => {
|
|
129
|
-
const scripts = config['scripts'];
|
|
130
|
-
|
|
131
|
-
addScriptSafe(scripts, 'build-themes', 'devextreme build');
|
|
132
|
-
addScriptSafe(scripts, 'postinstall', 'npm run build-themes');
|
|
133
|
-
|
|
134
|
-
return config;
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
return host;
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
async function addCustomThemeStyles(host: Tree, options: any, sourcePath: string = '') {
|
|
142
|
-
const projectName = await getProjectName(host, options.project);
|
|
143
|
-
modifyJSONFile(host, './angular.json', config => {
|
|
144
|
-
const stylesList = [
|
|
145
|
-
`${sourcePath}/variables.scss`,
|
|
146
|
-
`${sourcePath}/dx-styles.scss`,
|
|
147
|
-
`${sourcePath}/themes/generated/theme.additional.css`,
|
|
148
|
-
`${sourcePath}/themes/generated/theme.additional.dark.css`,
|
|
149
|
-
`${sourcePath}/themes/generated/theme.base.css`,
|
|
150
|
-
`${sourcePath}/themes/generated/theme.base.dark.css`,
|
|
151
|
-
'node_modules/devextreme/dist/css/dx.common.css'
|
|
152
|
-
];
|
|
153
|
-
|
|
154
|
-
return addStylesToApp(projectName, config, stylesList);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
return host;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
async function updateBudgets(host: Tree, options: any) {
|
|
161
|
-
const projectName = await getProjectName(host, options.project);
|
|
162
|
-
modifyJSONFile(host, './angular.json', config => {
|
|
163
|
-
const budgets: any[] = config.projects[projectName].architect.build.configurations.production.budgets;
|
|
164
|
-
|
|
165
|
-
const budget = budgets.find((item) => item.type === 'initial');
|
|
166
|
-
if (budget) {
|
|
167
|
-
budget.maximumWarning = '4mb';
|
|
168
|
-
budget.maximumError = '7mb';
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return config;
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
return host;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
async function addPolyfills(host: Tree, project: string, polyfills: string[]) {
|
|
178
|
-
const projectName = await getProjectName(host, project);
|
|
179
|
-
|
|
180
|
-
modifyJSONFile(host, './angular.json', config => {
|
|
181
|
-
const buildOptions: Record<string, any> = config.projects[projectName]['architect']['build']['options'];
|
|
182
|
-
|
|
183
|
-
if (!buildOptions.polyfills) {
|
|
184
|
-
buildOptions.polyfills = [];
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
polyfills.forEach((polyfill) => {
|
|
188
|
-
if (!buildOptions.polyfills.includes(polyfill)) {
|
|
189
|
-
buildOptions.polyfills.push(polyfill);
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
return config;
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
return host;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
function addViewportToBody(sourcePath: string = '') {
|
|
200
|
-
return (host: Tree) => {
|
|
201
|
-
const indexPath = join(sourcePath, 'index.html');
|
|
202
|
-
let indexContent = host.read(indexPath)!.toString();
|
|
203
|
-
|
|
204
|
-
indexContent = indexContent.replace(/<body>/, '<body class="dx-viewport">');
|
|
205
|
-
host.overwrite(indexPath, indexContent);
|
|
206
|
-
|
|
207
|
-
return host;
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
function modifyFileRule(path: string, callback: (source: SourceFile) => Change[]) {
|
|
212
|
-
return (host: Tree) => {
|
|
213
|
-
const source = getSourceFile(host, path);
|
|
214
|
-
|
|
215
|
-
if (!source) {
|
|
216
|
-
return host;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const changes = callback(source);
|
|
220
|
-
|
|
221
|
-
return applyChanges(host, changes, path);
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
function updateAppComponent(sourcePath: string, templateOptions: any = {}) {
|
|
226
|
-
const appMComponentPath = sourcePath + templateOptions.name + '.ts';
|
|
227
|
-
|
|
228
|
-
const importSetter = (importName: string, path: string, alias: string) => {
|
|
229
|
-
return (source: SourceFile) => {
|
|
230
|
-
return [insertImport(source, appMComponentPath, importName, path, false, alias)];
|
|
231
|
-
};
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
const rules = [
|
|
235
|
-
modifyFileRule(appMComponentPath, importSetter(
|
|
236
|
-
templateOptions.layout === 'side-nav-outer-toolbar'
|
|
237
|
-
? 'SideNavOuterToolbarComponent'
|
|
238
|
-
: 'SideNavInnerToolbarComponent',
|
|
239
|
-
'./layouts',
|
|
240
|
-
'SideNavToolbarComponent',
|
|
241
|
-
)),
|
|
242
|
-
];
|
|
243
|
-
|
|
244
|
-
return chain(rules);
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
function getComponentName(host: Tree, sourcePath: string) {
|
|
248
|
-
let name = '';
|
|
249
|
-
let index = 0;
|
|
250
|
-
|
|
251
|
-
if (!host.exists(sourcePath + 'app.component.ts') && !host.exists(sourcePath + 'app.ts')) {
|
|
252
|
-
name = 'app';
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
while (!name) {
|
|
256
|
-
index++;
|
|
257
|
-
const componentName = `app${index}`;
|
|
258
|
-
|
|
259
|
-
if (
|
|
260
|
-
!host.exists(`${sourcePath}${componentName}.component.ts`)
|
|
261
|
-
&& !host.exists(`${sourcePath}${componentName}.ts`)
|
|
262
|
-
) {
|
|
263
|
-
name = componentName;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
return name;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
function hasRouting(host: Tree, sourcePath: string) {
|
|
271
|
-
return host.exists(sourcePath + 'app.routes.ts');
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
function addPackagesToDependency(globalNgCliVersion: string) {
|
|
275
|
-
const version = new SemVer(globalNgCliVersion.replace(/\^|\~/g, ''));
|
|
276
|
-
|
|
277
|
-
return (host: Tree) => {
|
|
278
|
-
const zonejs = getPackageJsonDependency(host, 'zone.js');
|
|
279
|
-
|
|
280
|
-
addPackageJsonDependency(host, {
|
|
281
|
-
type: NodeDependencyType.Default,
|
|
282
|
-
name: '@angular/cdk',
|
|
283
|
-
version: version.raw.includes('next') || version.raw.includes('-rc')
|
|
284
|
-
? 'next' : `^${version.major}.0.0`
|
|
285
|
-
});
|
|
286
|
-
|
|
287
|
-
if (!zonejs) {
|
|
288
|
-
addPackageJsonDependency(host, {
|
|
289
|
-
type: NodeDependencyType.Default,
|
|
290
|
-
name: 'zone.js',
|
|
291
|
-
version: version.major > 18 ? '~0.15.0' : '~0.14.0'
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
return host;
|
|
296
|
-
};
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
function modifyContentByTemplate(
|
|
300
|
-
sourcePath: string = '',
|
|
301
|
-
templateSourcePath: string,
|
|
302
|
-
filePath: string | null,
|
|
303
|
-
templateOptions: any = {},
|
|
304
|
-
modifyContent?: (templateContent: string, currentContent: string, filePath: string ) => string)
|
|
305
|
-
: Rule {
|
|
306
|
-
return (host: Tree, context: SchematicContext) => {
|
|
307
|
-
const modifyIfExists = (fileEntry: FileEntry) => {
|
|
308
|
-
const fileEntryPath = join(sourcePath, fileEntry.path.toString());
|
|
309
|
-
if (!host.exists(fileEntryPath)) {
|
|
310
|
-
return fileEntry;
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
const templateContent = fileEntry.content!.toString();
|
|
314
|
-
let modifiedContent = templateContent;
|
|
315
|
-
|
|
316
|
-
const currentContent = host.read(fileEntryPath)!.toString();
|
|
317
|
-
if (modifyContent) {
|
|
318
|
-
modifiedContent = modifyContent(templateContent, currentContent, fileEntryPath);
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// NOTE: Workaround for https://github.com/angular/angular-cli/issues/11337
|
|
322
|
-
if (modifiedContent !== currentContent) {
|
|
323
|
-
host.overwrite(fileEntryPath, modifiedContent);
|
|
324
|
-
}
|
|
325
|
-
return null;
|
|
326
|
-
};
|
|
327
|
-
|
|
328
|
-
const rules = [
|
|
329
|
-
filter(path => {
|
|
330
|
-
return !filePath || join('./', path) === join('./', filePath);
|
|
331
|
-
}),
|
|
332
|
-
template(templateOptions),
|
|
333
|
-
forEach(modifyIfExists),
|
|
334
|
-
move(sourcePath)
|
|
335
|
-
];
|
|
336
|
-
|
|
337
|
-
const modifiedSource = apply(url(templateSourcePath), rules);
|
|
338
|
-
const resultRule = mergeWith(modifiedSource);
|
|
339
|
-
|
|
340
|
-
return callRule(resultRule, host, context);
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
function updateDevextremeConfig(sourcePath: string = '') {
|
|
345
|
-
const devextremeConfigPath = '/devextreme.json';
|
|
346
|
-
const templateOptions = {
|
|
347
|
-
sourcePath
|
|
348
|
-
};
|
|
349
|
-
|
|
350
|
-
const modifyConfig = (templateContent: string, currentContent: string) => {
|
|
351
|
-
const oldConfig = JSON.parse(currentContent);
|
|
352
|
-
const newConfig = JSON.parse(templateContent);
|
|
353
|
-
|
|
354
|
-
[].push.apply(oldConfig.build.commands, newConfig.build.commands);
|
|
355
|
-
|
|
356
|
-
return JSON.stringify(oldConfig, null, ' ');
|
|
357
|
-
};
|
|
358
|
-
|
|
359
|
-
return modifyContentByTemplate('./', workspaceFilesSource, devextremeConfigPath, templateOptions, modifyConfig);
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
const modifyRouting = (host: Tree, routingFilePath: string) => {
|
|
363
|
-
// TODO: Try to use the isolated host to generate the result string
|
|
364
|
-
let source = getSourceFile(host, routingFilePath)!;
|
|
365
|
-
const importChanges = [];
|
|
366
|
-
for (const route of routes) {
|
|
367
|
-
importChanges.push(insertImport(source, routingFilePath, route.name, route.location));
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
applyChanges(host, importChanges, routingFilePath);
|
|
371
|
-
for (const route of routes) {
|
|
372
|
-
if (route.type === 'component' && route.path) {
|
|
373
|
-
source = getSourceFile(host, routingFilePath)!;
|
|
374
|
-
const routeInSource = findRoutesInSource(source)!;
|
|
375
|
-
if (!hasComponentInRoutes(routeInSource, route.path)) {
|
|
376
|
-
const routeToAdd = getRoute(route.name, route.name, route.path);
|
|
377
|
-
insertItemToArray(host, routingFilePath, routeInSource, routeToAdd);
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
};
|
|
383
|
-
|
|
384
|
-
function setPostfix(host: Tree, name: string) {
|
|
385
|
-
return name + (isAngularVersionHigherThan(host, 20) ? '' : '.component');
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
export default function(options: any): Rule {
|
|
389
|
-
return async (host: Tree) => {
|
|
390
|
-
const project = await getProjectName(host, options.project);
|
|
391
|
-
const workspace = await getWorkspace(host);
|
|
392
|
-
const ngProject = workspace.projects.get(project);
|
|
393
|
-
const prefix = ngProject?.prefix;
|
|
394
|
-
const title = humanize(project);
|
|
395
|
-
const appPath = await getApplicationPath(host, project);
|
|
396
|
-
const sourcePath = await getSourceRootPath(host, project);
|
|
397
|
-
const layout = options.layout;
|
|
398
|
-
const override = options.resolveConflicts === 'override';
|
|
399
|
-
const componentName = override ? 'app' : getComponentName(host, appPath);
|
|
400
|
-
const pathToCss = sourcePath?.replace(/\/?(\w)+\/?/g, '../');
|
|
401
|
-
|
|
402
|
-
const templateOptions = {
|
|
403
|
-
name: setPostfix(host, componentName),
|
|
404
|
-
layout,
|
|
405
|
-
title,
|
|
406
|
-
strings,
|
|
407
|
-
path: pathToCss,
|
|
408
|
-
prefix
|
|
409
|
-
};
|
|
410
|
-
|
|
411
|
-
const modifyContent = (templateContent: string, currentContent: string, filePath: string) => {
|
|
412
|
-
if (basename(filePath) === 'styles.scss') {
|
|
413
|
-
return `${currentContent}\n${templateContent}`;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
if (basename(filePath) === 'app.routes.ts' && hasRouting(host, appPath)) {
|
|
417
|
-
modifyRouting(host, filePath);
|
|
418
|
-
return currentContent;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
return templateContent;
|
|
422
|
-
};
|
|
423
|
-
|
|
424
|
-
const rules = [
|
|
425
|
-
modifyContentByTemplate(sourcePath, projectFilesSource, null, templateOptions, modifyContent),
|
|
426
|
-
updateDevextremeConfig(sourcePath),
|
|
427
|
-
updateAppComponent(appPath, templateOptions),
|
|
428
|
-
addBuildThemeScript(),
|
|
429
|
-
() => addCustomThemeStyles(host, options, sourcePath) as any,
|
|
430
|
-
addViewportToBody(sourcePath),
|
|
431
|
-
addPackagesToDependency(options.globalNgCliVersion),
|
|
432
|
-
() => addPolyfills(host, options.project, ['zone.js'])
|
|
433
|
-
];
|
|
434
|
-
|
|
435
|
-
if (options.updateBudgets) {
|
|
436
|
-
rules.push(() => updateBudgets(host, options) as any);
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
if (!options.skipInstall) {
|
|
440
|
-
rules.push((_: Tree, context: SchematicContext) => {
|
|
441
|
-
context.addTask(new PatchNodePackageInstallTask());
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
return chain(rules);
|
|
446
|
-
};
|
|
447
|
-
}
|