@schematics/angular 17.3.0 → 18.0.0-next.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/app-shell/index.js +33 -55
- package/application/schema.json +7 -4
- package/guard/implements-files/__name@dasherize__.guard.ts.template +4 -5
- package/guard/index.js +1 -1
- package/library/index.js +3 -3
- package/migrations/update-17/replace-nguniversal-engines.js +2 -2
- package/module/index.js +3 -6
- package/ng-new/index.js +0 -3
- package/ng-new/schema.d.ts +0 -4
- package/ng-new/schema.json +0 -6
- package/package.json +5 -6
- package/service-worker/index.js +11 -12
- package/utility/latest-versions/package.json +1 -1
- package/utility/latest-versions.js +3 -3
- package/utility/ng-ast-utils.js +14 -8
- package/utility/paths.js +3 -6
- package/workspace/files/tsconfig.json.template +1 -2
- package/private/components.d.ts +0 -8
- package/private/components.js +0 -16
- package/private/standalone.d.ts +0 -55
- package/private/standalone.js +0 -393
package/app-shell/index.js
CHANGED
|
@@ -6,34 +6,13 @@
|
|
|
6
6
|
* Use of this source code is governed by an MIT-style license that can be
|
|
7
7
|
* found in the LICENSE file at https://angular.io/license
|
|
8
8
|
*/
|
|
9
|
-
var
|
|
10
|
-
|
|
11
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
-
}
|
|
15
|
-
Object.defineProperty(o, k2, desc);
|
|
16
|
-
}) : (function(o, m, k, k2) {
|
|
17
|
-
if (k2 === undefined) k2 = k;
|
|
18
|
-
o[k2] = m[k];
|
|
19
|
-
}));
|
|
20
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
-
}) : function(o, v) {
|
|
23
|
-
o["default"] = v;
|
|
24
|
-
});
|
|
25
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
26
|
-
if (mod && mod.__esModule) return mod;
|
|
27
|
-
var result = {};
|
|
28
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
29
|
-
__setModuleDefault(result, mod);
|
|
30
|
-
return result;
|
|
9
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
31
11
|
};
|
|
32
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
-
const core_1 = require("@angular-devkit/core");
|
|
34
13
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
35
|
-
const
|
|
36
|
-
const
|
|
14
|
+
const posix_1 = require("node:path/posix");
|
|
15
|
+
const typescript_1 = __importDefault(require("../third_party/github.com/Microsoft/TypeScript/lib/typescript"));
|
|
37
16
|
const ast_utils_1 = require("../utility/ast-utils");
|
|
38
17
|
const change_1 = require("../utility/change");
|
|
39
18
|
const ng_ast_utils_1 = require("../utility/ng-ast-utils");
|
|
@@ -43,18 +22,18 @@ const workspace_models_1 = require("../utility/workspace-models");
|
|
|
43
22
|
const APP_SHELL_ROUTE = 'shell';
|
|
44
23
|
function getSourceFile(host, path) {
|
|
45
24
|
const content = host.readText(path);
|
|
46
|
-
const source =
|
|
25
|
+
const source = typescript_1.default.createSourceFile(path, content, typescript_1.default.ScriptTarget.Latest, true);
|
|
47
26
|
return source;
|
|
48
27
|
}
|
|
49
28
|
function getServerModulePath(host, sourceRoot, mainPath) {
|
|
50
|
-
const mainSource = getSourceFile(host, (0,
|
|
29
|
+
const mainSource = getSourceFile(host, (0, posix_1.join)(sourceRoot, mainPath));
|
|
51
30
|
const allNodes = (0, ast_utils_1.getSourceNodes)(mainSource);
|
|
52
|
-
const expNode = allNodes.find((node) =>
|
|
31
|
+
const expNode = allNodes.find((node) => typescript_1.default.isExportDeclaration(node));
|
|
53
32
|
if (!expNode) {
|
|
54
33
|
return null;
|
|
55
34
|
}
|
|
56
35
|
const relativePath = expNode.moduleSpecifier;
|
|
57
|
-
const modulePath = (0,
|
|
36
|
+
const modulePath = (0, posix_1.join)(sourceRoot, `${relativePath.text}.ts`);
|
|
58
37
|
return modulePath;
|
|
59
38
|
}
|
|
60
39
|
function getComponentTemplateInfo(host, componentPath) {
|
|
@@ -72,8 +51,8 @@ function getComponentTemplate(host, compPath, tmplInfo) {
|
|
|
72
51
|
}
|
|
73
52
|
else if (tmplInfo.templateUrlProp) {
|
|
74
53
|
const templateUrl = tmplInfo.templateUrlProp.initializer.text;
|
|
75
|
-
const dir = (0,
|
|
76
|
-
const templatePath = (0,
|
|
54
|
+
const dir = (0, posix_1.dirname)(compPath);
|
|
55
|
+
const templatePath = (0, posix_1.join)(dir, templateUrl);
|
|
77
56
|
try {
|
|
78
57
|
template = host.readText(templatePath);
|
|
79
58
|
}
|
|
@@ -82,16 +61,15 @@ function getComponentTemplate(host, compPath, tmplInfo) {
|
|
|
82
61
|
return template;
|
|
83
62
|
}
|
|
84
63
|
function getBootstrapComponentPath(host, mainPath) {
|
|
85
|
-
const mainSource = getSourceFile(host, mainPath);
|
|
86
|
-
const bootstrapAppCall = (0, standalone_1.findBootstrapApplicationCall)(mainSource);
|
|
87
64
|
let bootstrappingFilePath;
|
|
88
65
|
let bootstrappingSource;
|
|
89
66
|
let componentName;
|
|
90
|
-
if (
|
|
67
|
+
if ((0, ng_ast_utils_1.isStandaloneApp)(host, mainPath)) {
|
|
91
68
|
// Standalone Application
|
|
92
|
-
|
|
69
|
+
const bootstrapCall = (0, util_1.findBootstrapApplicationCall)(host, mainPath);
|
|
70
|
+
componentName = bootstrapCall.arguments[0].getText();
|
|
93
71
|
bootstrappingFilePath = mainPath;
|
|
94
|
-
bootstrappingSource =
|
|
72
|
+
bootstrappingSource = getSourceFile(host, mainPath);
|
|
95
73
|
}
|
|
96
74
|
else {
|
|
97
75
|
// NgModule Application
|
|
@@ -105,15 +83,15 @@ function getBootstrapComponentPath(host, mainPath) {
|
|
|
105
83
|
bootstrappingFilePath = modulePath;
|
|
106
84
|
}
|
|
107
85
|
const componentRelativeFilePath = (0, ast_utils_1.getSourceNodes)(bootstrappingSource)
|
|
108
|
-
.filter(
|
|
86
|
+
.filter(typescript_1.default.isImportDeclaration)
|
|
109
87
|
.filter((imp) => {
|
|
110
|
-
return (0, ast_utils_1.findNode)(imp,
|
|
88
|
+
return (0, ast_utils_1.findNode)(imp, typescript_1.default.SyntaxKind.Identifier, componentName);
|
|
111
89
|
})
|
|
112
90
|
.map((imp) => {
|
|
113
91
|
const pathStringLiteral = imp.moduleSpecifier;
|
|
114
92
|
return pathStringLiteral.text;
|
|
115
93
|
})[0];
|
|
116
|
-
return (0,
|
|
94
|
+
return (0, posix_1.join)((0, posix_1.dirname)(bootstrappingFilePath), componentRelativeFilePath + '.ts');
|
|
117
95
|
}
|
|
118
96
|
// end helper functions.
|
|
119
97
|
function validateProject(mainPath) {
|
|
@@ -193,12 +171,12 @@ function addRouterModule(mainPath) {
|
|
|
193
171
|
}
|
|
194
172
|
function getMetadataProperty(metadata, propertyName) {
|
|
195
173
|
const properties = metadata.properties;
|
|
196
|
-
const property = properties.filter(
|
|
174
|
+
const property = properties.filter(typescript_1.default.isPropertyAssignment).filter((prop) => {
|
|
197
175
|
const name = prop.name;
|
|
198
176
|
switch (name.kind) {
|
|
199
|
-
case
|
|
177
|
+
case typescript_1.default.SyntaxKind.Identifier:
|
|
200
178
|
return name.getText() === propertyName;
|
|
201
|
-
case
|
|
179
|
+
case typescript_1.default.SyntaxKind.StringLiteral:
|
|
202
180
|
return name.text === propertyName;
|
|
203
181
|
}
|
|
204
182
|
return false;
|
|
@@ -225,7 +203,7 @@ function addServerRoutes(options) {
|
|
|
225
203
|
(0, change_1.applyToUpdateRecorder)(recorder, [routesChange]);
|
|
226
204
|
}
|
|
227
205
|
const imports = (0, ast_utils_1.getSourceNodes)(moduleSource)
|
|
228
|
-
.filter((node) => node.kind ===
|
|
206
|
+
.filter((node) => node.kind === typescript_1.default.SyntaxKind.ImportDeclaration)
|
|
229
207
|
.sort((a, b) => a.getStart() - b.getStart());
|
|
230
208
|
const insertPosition = imports[imports.length - 1].getEnd();
|
|
231
209
|
const routeText = `\n\nconst routes: Routes = [ { path: '${APP_SHELL_ROUTE}', component: AppShellComponent }];`;
|
|
@@ -254,7 +232,7 @@ function addStandaloneServerRoute(options) {
|
|
|
254
232
|
if (!project) {
|
|
255
233
|
throw new schematics_1.SchematicsException(`Project name "${options.project}" doesn't not exist.`);
|
|
256
234
|
}
|
|
257
|
-
const configFilePath = (0,
|
|
235
|
+
const configFilePath = (0, posix_1.join)(project.sourceRoot ?? 'src', 'app/app.config.server.ts');
|
|
258
236
|
if (!host.exists(configFilePath)) {
|
|
259
237
|
throw new schematics_1.SchematicsException(`Cannot find "${configFilePath}".`);
|
|
260
238
|
}
|
|
@@ -268,28 +246,28 @@ function addStandaloneServerRoute(options) {
|
|
|
268
246
|
}
|
|
269
247
|
}
|
|
270
248
|
configSourceFile = getSourceFile(host, configFilePath);
|
|
271
|
-
const providersLiteral = (0, ast_utils_1.findNodes)(configSourceFile,
|
|
249
|
+
const providersLiteral = (0, ast_utils_1.findNodes)(configSourceFile, typescript_1.default.isPropertyAssignment).find((n) => typescript_1.default.isArrayLiteralExpression(n.initializer) && n.name.getText() === 'providers')?.initializer;
|
|
272
250
|
if (!providersLiteral) {
|
|
273
251
|
throw new schematics_1.SchematicsException(`Cannot find the "providers" configuration in "${configFilePath}".`);
|
|
274
252
|
}
|
|
275
253
|
// Add route to providers literal.
|
|
276
|
-
const newProvidersLiteral =
|
|
254
|
+
const newProvidersLiteral = typescript_1.default.factory.updateArrayLiteralExpression(providersLiteral, [
|
|
277
255
|
...providersLiteral.elements,
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
256
|
+
typescript_1.default.factory.createObjectLiteralExpression([
|
|
257
|
+
typescript_1.default.factory.createPropertyAssignment('provide', typescript_1.default.factory.createIdentifier('ROUTES')),
|
|
258
|
+
typescript_1.default.factory.createPropertyAssignment('multi', typescript_1.default.factory.createIdentifier('true')),
|
|
259
|
+
typescript_1.default.factory.createPropertyAssignment('useValue', typescript_1.default.factory.createArrayLiteralExpression([
|
|
260
|
+
typescript_1.default.factory.createObjectLiteralExpression([
|
|
261
|
+
typescript_1.default.factory.createPropertyAssignment('path', typescript_1.default.factory.createIdentifier(`'${APP_SHELL_ROUTE}'`)),
|
|
262
|
+
typescript_1.default.factory.createPropertyAssignment('component', typescript_1.default.factory.createIdentifier('AppShellComponent')),
|
|
285
263
|
], true),
|
|
286
264
|
], true)),
|
|
287
265
|
], true),
|
|
288
266
|
]);
|
|
289
267
|
const recorder = host.beginUpdate(configFilePath);
|
|
290
268
|
recorder.remove(providersLiteral.getStart(), providersLiteral.getWidth());
|
|
291
|
-
const printer =
|
|
292
|
-
recorder.insertRight(providersLiteral.getStart(), printer.printNode(
|
|
269
|
+
const printer = typescript_1.default.createPrinter();
|
|
270
|
+
recorder.insertRight(providersLiteral.getStart(), printer.printNode(typescript_1.default.EmitHint.Unspecified, newProvidersLiteral, configSourceFile));
|
|
293
271
|
// Add AppShellComponent import
|
|
294
272
|
const appShellImportChange = (0, ast_utils_1.insertImport)(configSourceFile, configFilePath, 'AppShellComponent', './app-shell/app-shell.component');
|
|
295
273
|
(0, change_1.applyToUpdateRecorder)(recorder, [appShellImportChange]);
|
package/application/schema.json
CHANGED
|
@@ -59,18 +59,21 @@
|
|
|
59
59
|
"message": "Which stylesheet format would you like to use?",
|
|
60
60
|
"type": "list",
|
|
61
61
|
"items": [
|
|
62
|
-
{
|
|
62
|
+
{
|
|
63
|
+
"value": "css",
|
|
64
|
+
"label": "CSS [ https://developer.mozilla.org/docs/Web/CSS ]"
|
|
65
|
+
},
|
|
63
66
|
{
|
|
64
67
|
"value": "scss",
|
|
65
|
-
"label": "SCSS
|
|
68
|
+
"label": "Sass (SCSS) [ https://sass-lang.com/documentation/syntax#scss ]"
|
|
66
69
|
},
|
|
67
70
|
{
|
|
68
71
|
"value": "sass",
|
|
69
|
-
"label": "Sass
|
|
72
|
+
"label": "Sass (Indented) [ https://sass-lang.com/documentation/syntax#the-indented-syntax ]"
|
|
70
73
|
},
|
|
71
74
|
{
|
|
72
75
|
"value": "less",
|
|
73
|
-
"label": "Less
|
|
76
|
+
"label": "Less [ http://lesscss.org ]"
|
|
74
77
|
}
|
|
75
78
|
]
|
|
76
79
|
},
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Injectable } from '@angular/core';
|
|
2
2
|
import { <%= routerImports %> } from '@angular/router';
|
|
3
|
-
import { Observable } from 'rxjs';
|
|
4
3
|
|
|
5
4
|
@Injectable({
|
|
6
5
|
providedIn: 'root'
|
|
@@ -8,24 +7,24 @@ import { Observable } from 'rxjs';
|
|
|
8
7
|
export class <%= classify(name) %>Guard implements <%= implementations %> {
|
|
9
8
|
<% if (implements.includes('CanActivate')) { %>canActivate(
|
|
10
9
|
route: ActivatedRouteSnapshot,
|
|
11
|
-
state: RouterStateSnapshot):
|
|
10
|
+
state: RouterStateSnapshot): MaybeAsync<GuardResult> {
|
|
12
11
|
return true;
|
|
13
12
|
}
|
|
14
13
|
<% } %><% if (implements.includes('CanActivateChild')) { %>canActivateChild(
|
|
15
14
|
childRoute: ActivatedRouteSnapshot,
|
|
16
|
-
state: RouterStateSnapshot):
|
|
15
|
+
state: RouterStateSnapshot): MaybeAsync<GuardResult> {
|
|
17
16
|
return true;
|
|
18
17
|
}
|
|
19
18
|
<% } %><% if (implements.includes('CanDeactivate')) { %>canDeactivate(
|
|
20
19
|
component: unknown,
|
|
21
20
|
currentRoute: ActivatedRouteSnapshot,
|
|
22
21
|
currentState: RouterStateSnapshot,
|
|
23
|
-
nextState?: RouterStateSnapshot):
|
|
22
|
+
nextState?: RouterStateSnapshot): MaybeAsync<GuardResult> {
|
|
24
23
|
return true;
|
|
25
24
|
}
|
|
26
25
|
<% } %><% if (implements.includes('CanMatch')) { %>canMatch(
|
|
27
26
|
route: Route,
|
|
28
|
-
segments: UrlSegment[]):
|
|
27
|
+
segments: UrlSegment[]): MaybeAsync<GuardResult> {
|
|
29
28
|
return true;
|
|
30
29
|
}<% } %>
|
|
31
30
|
}
|
package/guard/index.js
CHANGED
|
@@ -26,7 +26,7 @@ function default_1(options) {
|
|
|
26
26
|
.map((implement) => (implement === 'CanDeactivate' ? 'CanDeactivate<unknown>' : implement))
|
|
27
27
|
.join(', ');
|
|
28
28
|
const commonRouterNameImports = ['ActivatedRouteSnapshot', 'RouterStateSnapshot'];
|
|
29
|
-
const routerNamedImports = [...options.implements, '
|
|
29
|
+
const routerNamedImports = [...options.implements, 'MaybeAsync', 'GuardResult'];
|
|
30
30
|
if (options.implements.includes(schema_1.Implement.CanMatch)) {
|
|
31
31
|
routerNamedImports.push('Route', 'UrlSegment');
|
|
32
32
|
if (options.implements.length > 1) {
|
package/library/index.js
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* found in the LICENSE file at https://angular.io/license
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
const core_1 = require("@angular-devkit/core");
|
|
11
10
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
12
11
|
const tasks_1 = require("@angular-devkit/schematics/tasks");
|
|
12
|
+
const posix_1 = require("node:path/posix");
|
|
13
13
|
const dependencies_1 = require("../utility/dependencies");
|
|
14
14
|
const json_file_1 = require("../utility/json-file");
|
|
15
15
|
const latest_versions_1 = require("../utility/latest-versions");
|
|
@@ -110,8 +110,8 @@ function default_1(options) {
|
|
|
110
110
|
folderName = schematics_1.strings.dasherize(folderName);
|
|
111
111
|
}
|
|
112
112
|
const libDir = options.projectRoot !== undefined
|
|
113
|
-
? (0,
|
|
114
|
-
: (0,
|
|
113
|
+
? (0, posix_1.join)(options.projectRoot)
|
|
114
|
+
: (0, posix_1.join)(newProjectRoot, folderName);
|
|
115
115
|
const distRoot = `dist/${folderName}`;
|
|
116
116
|
const sourceDir = `${libDir}/src/lib`;
|
|
117
117
|
const templateSource = (0, schematics_1.apply)((0, schematics_1.url)('./files'), [
|
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* found in the LICENSE file at https://angular.io/license
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
const core_1 = require("@angular-devkit/core");
|
|
11
10
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
11
|
+
const posix_1 = require("node:path/posix");
|
|
12
12
|
const utility_1 = require("../../utility");
|
|
13
13
|
const dependencies_1 = require("../../utility/dependencies");
|
|
14
14
|
const latest_versions_1 = require("../../utility/latest-versions");
|
|
@@ -80,7 +80,7 @@ function default_1() {
|
|
|
80
80
|
// Check if file is importing tokens
|
|
81
81
|
if (content.includes('@nguniversal/express-engine/tokens')) {
|
|
82
82
|
hasExpressTokens ||= true;
|
|
83
|
-
let tokensFileRelativePath = (0,
|
|
83
|
+
let tokensFileRelativePath = (0, posix_1.relative)((0, posix_1.dirname)(path), tokensFilePath);
|
|
84
84
|
if (tokensFileRelativePath.charAt(0) !== '.') {
|
|
85
85
|
tokensFileRelativePath = './' + tokensFileRelativePath;
|
|
86
86
|
}
|
package/module/index.js
CHANGED
|
@@ -30,8 +30,8 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
30
30
|
return result;
|
|
31
31
|
};
|
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
-
const core_1 = require("@angular-devkit/core");
|
|
34
33
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
34
|
+
const posix_1 = require("node:path/posix");
|
|
35
35
|
const ts = __importStar(require("../third_party/github.com/Microsoft/TypeScript/lib/typescript"));
|
|
36
36
|
const ast_utils_1 = require("../utility/ast-utils");
|
|
37
37
|
const change_1 = require("../utility/change");
|
|
@@ -41,10 +41,7 @@ const validation_1 = require("../utility/validation");
|
|
|
41
41
|
const workspace_1 = require("../utility/workspace");
|
|
42
42
|
const schema_1 = require("./schema");
|
|
43
43
|
function buildRelativeModulePath(options, modulePath) {
|
|
44
|
-
const importModulePath = (0,
|
|
45
|
-
(options.flat ? '' : schematics_1.strings.dasherize(options.name) + '/') +
|
|
46
|
-
schematics_1.strings.dasherize(options.name) +
|
|
47
|
-
'.module');
|
|
44
|
+
const importModulePath = (0, posix_1.join)(options.path ?? '', options.flat ? '' : schematics_1.strings.dasherize(options.name), schematics_1.strings.dasherize(options.name) + '.module');
|
|
48
45
|
return (0, find_module_1.buildRelativePath)(modulePath, importModulePath);
|
|
49
46
|
}
|
|
50
47
|
function addImportToNgModule(options) {
|
|
@@ -94,7 +91,7 @@ function getRoutingModulePath(host, modulePath) {
|
|
|
94
91
|
const routingModulePath = modulePath.endsWith(find_module_1.ROUTING_MODULE_EXT)
|
|
95
92
|
? modulePath
|
|
96
93
|
: modulePath.replace(find_module_1.MODULE_EXT, find_module_1.ROUTING_MODULE_EXT);
|
|
97
|
-
return host.exists(routingModulePath) ?
|
|
94
|
+
return host.exists(routingModulePath) ? routingModulePath : undefined;
|
|
98
95
|
}
|
|
99
96
|
function buildRoute(options, modulePath) {
|
|
100
97
|
const relativeModulePath = buildRelativeModulePath(options, modulePath);
|
package/ng-new/index.js
CHANGED
|
@@ -53,9 +53,6 @@ function default_1(options) {
|
|
|
53
53
|
workingDirectory: options.directory,
|
|
54
54
|
packageManager: options.packageManager,
|
|
55
55
|
}));
|
|
56
|
-
if (options.linkCli) {
|
|
57
|
-
packageTask = context.addTask(new tasks_1.NodePackageLinkTask('@angular/cli', options.directory), [packageTask]);
|
|
58
|
-
}
|
|
59
56
|
}
|
|
60
57
|
if (!options.skipGit) {
|
|
61
58
|
const commit = typeof options.commit == 'object' ? options.commit : options.commit ? {} : false;
|
package/ng-new/schema.d.ts
CHANGED
|
@@ -26,10 +26,6 @@ export interface Schema {
|
|
|
26
26
|
* is created and referenced in the component TypeScript file.
|
|
27
27
|
*/
|
|
28
28
|
inlineTemplate?: boolean;
|
|
29
|
-
/**
|
|
30
|
-
* Link the CLI to the global version (internal development only).
|
|
31
|
-
*/
|
|
32
|
-
linkCli?: boolean;
|
|
33
29
|
/**
|
|
34
30
|
* Create a workspace without any testing frameworks. (Use for learning purposes only.)
|
|
35
31
|
*/
|
package/ng-new/schema.json
CHANGED
|
@@ -24,12 +24,6 @@
|
|
|
24
24
|
"type": "boolean",
|
|
25
25
|
"default": false
|
|
26
26
|
},
|
|
27
|
-
"linkCli": {
|
|
28
|
-
"description": "Link the CLI to the global version (internal development only).",
|
|
29
|
-
"type": "boolean",
|
|
30
|
-
"default": false,
|
|
31
|
-
"visible": false
|
|
32
|
-
},
|
|
33
27
|
"skipGit": {
|
|
34
28
|
"description": "Do not initialize a git repository.",
|
|
35
29
|
"type": "boolean",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schematics/angular",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "18.0.0-next.0",
|
|
4
4
|
"description": "Schematics specific to Angular",
|
|
5
5
|
"homepage": "https://github.com/angular/angular-cli",
|
|
6
6
|
"keywords": [
|
|
@@ -18,13 +18,12 @@
|
|
|
18
18
|
"./utility": "./utility/index.js",
|
|
19
19
|
"./utility/*": "./utility/*.js",
|
|
20
20
|
"./migrations/migration-collection.json": "./migrations/migration-collection.json",
|
|
21
|
-
"./*": "./*.js"
|
|
22
|
-
"./private/components": "./private/components.js"
|
|
21
|
+
"./*": "./*.js"
|
|
23
22
|
},
|
|
24
23
|
"schematics": "./collection.json",
|
|
25
24
|
"dependencies": {
|
|
26
|
-
"@angular-devkit/core": "
|
|
27
|
-
"@angular-devkit/schematics": "
|
|
25
|
+
"@angular-devkit/core": "18.0.0-next.0",
|
|
26
|
+
"@angular-devkit/schematics": "18.0.0-next.0",
|
|
28
27
|
"jsonc-parser": "3.2.1"
|
|
29
28
|
},
|
|
30
29
|
"repository": {
|
|
@@ -32,7 +31,7 @@
|
|
|
32
31
|
"url": "https://github.com/angular/angular-cli.git"
|
|
33
32
|
},
|
|
34
33
|
"engines": {
|
|
35
|
-
"node": "^18.
|
|
34
|
+
"node": "^18.19.1 || >=20.11.1",
|
|
36
35
|
"npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
|
|
37
36
|
"yarn": ">= 1.13.0"
|
|
38
37
|
},
|
package/service-worker/index.js
CHANGED
|
@@ -32,7 +32,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
33
|
const core_1 = require("@angular-devkit/core");
|
|
34
34
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
35
|
-
const standalone_1 = require("../private/standalone");
|
|
36
35
|
const ts = __importStar(require("../third_party/github.com/Microsoft/TypeScript/lib/typescript"));
|
|
37
36
|
const utility_1 = require("../utility");
|
|
38
37
|
const ast_utils_1 = require("../utility/ast-utils");
|
|
@@ -41,6 +40,8 @@ const dependencies_1 = require("../utility/dependencies");
|
|
|
41
40
|
const ng_ast_utils_1 = require("../utility/ng-ast-utils");
|
|
42
41
|
const paths_1 = require("../utility/paths");
|
|
43
42
|
const project_targets_1 = require("../utility/project-targets");
|
|
43
|
+
const app_config_1 = require("../utility/standalone/app_config");
|
|
44
|
+
const util_1 = require("../utility/standalone/util");
|
|
44
45
|
const workspace_models_1 = require("../utility/workspace-models");
|
|
45
46
|
function addDependencies() {
|
|
46
47
|
return (host) => {
|
|
@@ -77,17 +78,15 @@ function updateAppModule(mainPath) {
|
|
|
77
78
|
return host;
|
|
78
79
|
};
|
|
79
80
|
}
|
|
80
|
-
function addProvideServiceWorker(mainPath) {
|
|
81
|
+
function addProvideServiceWorker(projectName, mainPath) {
|
|
81
82
|
return (host) => {
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
addImport(host, updatedFilePath, 'isDevMode', '@angular/core');
|
|
90
|
-
return host;
|
|
83
|
+
const bootstrapCall = (0, util_1.findBootstrapApplicationCall)(host, mainPath);
|
|
84
|
+
const appConfig = (0, app_config_1.findAppConfig)(bootstrapCall, host, mainPath)?.filePath || mainPath;
|
|
85
|
+
addImport(host, appConfig, 'isDevMode', '@angular/core');
|
|
86
|
+
return (0, utility_1.addRootProvider)(projectName, ({ code, external }) => code `${external('provideServiceWorker', '@angular/service-worker')}('ngsw-worker.js', {
|
|
87
|
+
enabled: !isDevMode(),
|
|
88
|
+
registrationStrategy: 'registerWhenStable:30000'
|
|
89
|
+
})`);
|
|
91
90
|
};
|
|
92
91
|
}
|
|
93
92
|
function getTsSourceFile(host, path) {
|
|
@@ -141,7 +140,7 @@ function default_1(options) {
|
|
|
141
140
|
(0, schematics_1.move)(project.root),
|
|
142
141
|
])),
|
|
143
142
|
(0, ng_ast_utils_1.isStandaloneApp)(host, browserEntryPoint)
|
|
144
|
-
? addProvideServiceWorker(browserEntryPoint)
|
|
143
|
+
? addProvideServiceWorker(options.project, browserEntryPoint)
|
|
145
144
|
: updateAppModule(browserEntryPoint),
|
|
146
145
|
]);
|
|
147
146
|
};
|
|
@@ -13,7 +13,7 @@ exports.latestVersions = {
|
|
|
13
13
|
// but ts_library doesn't support JSON inputs.
|
|
14
14
|
...require('./latest-versions/package.json')['dependencies'],
|
|
15
15
|
// As Angular CLI works with same minor versions of Angular Framework, a tilde match for the current
|
|
16
|
-
Angular: '^
|
|
17
|
-
DevkitBuildAngular: '^
|
|
18
|
-
AngularSSR: '^
|
|
16
|
+
Angular: '^18.0.0-next.0',
|
|
17
|
+
DevkitBuildAngular: '^18.0.0-next.0',
|
|
18
|
+
AngularSSR: '^18.0.0-next.0',
|
|
19
19
|
};
|
package/utility/ng-ast-utils.js
CHANGED
|
@@ -31,12 +31,11 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
31
31
|
};
|
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
33
|
exports.isStandaloneApp = exports.getAppModulePath = exports.findBootstrapModuleCall = void 0;
|
|
34
|
-
const core_1 = require("@angular-devkit/core");
|
|
35
34
|
const schematics_1 = require("@angular-devkit/schematics");
|
|
36
|
-
const
|
|
37
|
-
const standalone_1 = require("../private/standalone");
|
|
35
|
+
const posix_1 = require("node:path/posix");
|
|
38
36
|
const ts = __importStar(require("../third_party/github.com/Microsoft/TypeScript/lib/typescript"));
|
|
39
37
|
const ast_utils_1 = require("../utility/ast-utils");
|
|
38
|
+
const util_1 = require("./standalone/util");
|
|
40
39
|
function findBootstrapModuleCall(host, mainPath) {
|
|
41
40
|
const mainText = host.readText(mainPath);
|
|
42
41
|
const source = ts.createSourceFile(mainPath, mainText, ts.ScriptTarget.Latest, true);
|
|
@@ -83,14 +82,21 @@ function findBootstrapModulePath(host, mainPath) {
|
|
|
83
82
|
}
|
|
84
83
|
function getAppModulePath(host, mainPath) {
|
|
85
84
|
const moduleRelativePath = findBootstrapModulePath(host, mainPath);
|
|
86
|
-
const mainDir = (0,
|
|
87
|
-
const modulePath = (0,
|
|
85
|
+
const mainDir = (0, posix_1.dirname)(mainPath);
|
|
86
|
+
const modulePath = (0, posix_1.join)(mainDir, `${moduleRelativePath}.ts`);
|
|
88
87
|
return modulePath;
|
|
89
88
|
}
|
|
90
89
|
exports.getAppModulePath = getAppModulePath;
|
|
91
90
|
function isStandaloneApp(host, mainPath) {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
try {
|
|
92
|
+
(0, util_1.findBootstrapApplicationCall)(host, mainPath);
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
if (error instanceof schematics_1.SchematicsException) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
throw error;
|
|
100
|
+
}
|
|
95
101
|
}
|
|
96
102
|
exports.isStandaloneApp = isStandaloneApp;
|
package/utility/paths.js
CHANGED
|
@@ -8,14 +8,11 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.relativePathToWorkspaceRoot = void 0;
|
|
11
|
-
const
|
|
11
|
+
const posix_1 = require("node:path/posix");
|
|
12
12
|
function relativePathToWorkspaceRoot(projectRoot) {
|
|
13
|
-
|
|
14
|
-
if (normalizedPath.length === 0 || !normalizedPath[0]) {
|
|
13
|
+
if (!projectRoot) {
|
|
15
14
|
return '.';
|
|
16
15
|
}
|
|
17
|
-
|
|
18
|
-
return normalizedPath.map(() => '..').join('/');
|
|
19
|
-
}
|
|
16
|
+
return (0, posix_1.relative)((0, posix_1.join)('/', projectRoot), '/') || '.';
|
|
20
17
|
}
|
|
21
18
|
exports.relativePathToWorkspaceRoot = relativePathToWorkspaceRoot;
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
"compileOnSave": false,
|
|
4
4
|
"compilerOptions": {
|
|
5
5
|
"outDir": "./dist/out-tsc",<% if (strict) { %>
|
|
6
|
-
"forceConsistentCasingInFileNames": true,
|
|
7
6
|
"strict": true,
|
|
8
7
|
"noImplicitOverride": true,
|
|
9
8
|
"noPropertyAccessFromIndexSignature": true,
|
|
@@ -14,7 +13,7 @@
|
|
|
14
13
|
"sourceMap": true,
|
|
15
14
|
"declaration": false,
|
|
16
15
|
"experimentalDecorators": true,
|
|
17
|
-
"moduleResolution": "
|
|
16
|
+
"moduleResolution": "bundler",
|
|
18
17
|
"importHelpers": true,
|
|
19
18
|
"target": "ES2022",
|
|
20
19
|
"module": "ES2022",
|
package/private/components.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright Google LLC All Rights Reserved.
|
|
4
|
-
*
|
|
5
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
-
* found in the LICENSE file at https://angular.io/license
|
|
7
|
-
*/
|
|
8
|
-
export { addModuleImportToStandaloneBootstrap, addFunctionalProvidersToStandaloneBootstrap, callsProvidersFunction, findBootstrapApplicationCall, importsProvidersFrom, } from './standalone';
|
package/private/components.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @license
|
|
4
|
-
* Copyright Google LLC All Rights Reserved.
|
|
5
|
-
*
|
|
6
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
7
|
-
* found in the LICENSE file at https://angular.io/license
|
|
8
|
-
*/
|
|
9
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
-
exports.importsProvidersFrom = exports.findBootstrapApplicationCall = exports.callsProvidersFunction = exports.addFunctionalProvidersToStandaloneBootstrap = exports.addModuleImportToStandaloneBootstrap = void 0;
|
|
11
|
-
var standalone_1 = require("./standalone");
|
|
12
|
-
Object.defineProperty(exports, "addModuleImportToStandaloneBootstrap", { enumerable: true, get: function () { return standalone_1.addModuleImportToStandaloneBootstrap; } });
|
|
13
|
-
Object.defineProperty(exports, "addFunctionalProvidersToStandaloneBootstrap", { enumerable: true, get: function () { return standalone_1.addFunctionalProvidersToStandaloneBootstrap; } });
|
|
14
|
-
Object.defineProperty(exports, "callsProvidersFunction", { enumerable: true, get: function () { return standalone_1.callsProvidersFunction; } });
|
|
15
|
-
Object.defineProperty(exports, "findBootstrapApplicationCall", { enumerable: true, get: function () { return standalone_1.findBootstrapApplicationCall; } });
|
|
16
|
-
Object.defineProperty(exports, "importsProvidersFrom", { enumerable: true, get: function () { return standalone_1.importsProvidersFrom; } });
|
package/private/standalone.d.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright Google LLC All Rights Reserved.
|
|
4
|
-
*
|
|
5
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
-
* found in the LICENSE file at https://angular.io/license
|
|
7
|
-
*/
|
|
8
|
-
import { Tree } from '@angular-devkit/schematics';
|
|
9
|
-
import ts from '../third_party/github.com/Microsoft/TypeScript/lib/typescript';
|
|
10
|
-
/**
|
|
11
|
-
* Checks whether the providers from a module are being imported in a `bootstrapApplication` call.
|
|
12
|
-
* @param tree File tree of the project.
|
|
13
|
-
* @param filePath Path of the file in which to check.
|
|
14
|
-
* @param className Class name of the module to search for.
|
|
15
|
-
* @deprecated Private utility that will be removed. Use `addRootImport` or `addRootProvider` from
|
|
16
|
-
* `@schematics/angular/utility` instead.
|
|
17
|
-
*/
|
|
18
|
-
export declare function importsProvidersFrom(tree: Tree, filePath: string, className: string): boolean;
|
|
19
|
-
/**
|
|
20
|
-
* Checks whether a providers function is being called in a `bootstrapApplication` call.
|
|
21
|
-
* @param tree File tree of the project.
|
|
22
|
-
* @param filePath Path of the file in which to check.
|
|
23
|
-
* @param functionName Name of the function to search for.
|
|
24
|
-
* @deprecated Private utility that will be removed. Use `addRootImport` or `addRootProvider` from
|
|
25
|
-
* `@schematics/angular/utility` instead.
|
|
26
|
-
*/
|
|
27
|
-
export declare function callsProvidersFunction(tree: Tree, filePath: string, functionName: string): boolean;
|
|
28
|
-
/**
|
|
29
|
-
* Adds an `importProvidersFrom` call to the `bootstrapApplication` call.
|
|
30
|
-
* @param tree File tree of the project.
|
|
31
|
-
* @param filePath Path to the file that should be updated.
|
|
32
|
-
* @param moduleName Name of the module that should be imported.
|
|
33
|
-
* @param modulePath Path from which to import the module.
|
|
34
|
-
* @deprecated Private utility that will be removed. Use `addRootImport` or `addRootProvider` from
|
|
35
|
-
* `@schematics/angular/utility` instead.
|
|
36
|
-
*/
|
|
37
|
-
export declare function addModuleImportToStandaloneBootstrap(tree: Tree, filePath: string, moduleName: string, modulePath: string): void;
|
|
38
|
-
/**
|
|
39
|
-
* Adds a providers function call to the `bootstrapApplication` call.
|
|
40
|
-
* @param tree File tree of the project.
|
|
41
|
-
* @param filePath Path to the file that should be updated.
|
|
42
|
-
* @param functionName Name of the function that should be called.
|
|
43
|
-
* @param importPath Path from which to import the function.
|
|
44
|
-
* @param args Arguments to use when calling the function.
|
|
45
|
-
* @return The file path that the provider was added to.
|
|
46
|
-
* @deprecated Private utility that will be removed. Use `addRootImport` or `addRootProvider` from
|
|
47
|
-
* `@schematics/angular/utility` instead.
|
|
48
|
-
*/
|
|
49
|
-
export declare function addFunctionalProvidersToStandaloneBootstrap(tree: Tree, filePath: string, functionName: string, importPath: string, args?: ts.Expression[]): string;
|
|
50
|
-
/**
|
|
51
|
-
* Finds the call to `bootstrapApplication` within a file.
|
|
52
|
-
* @deprecated Private utility that will be removed. Use `addRootImport` or `addRootProvider` from
|
|
53
|
-
* `@schematics/angular/utility` instead.
|
|
54
|
-
*/
|
|
55
|
-
export declare function findBootstrapApplicationCall(sourceFile: ts.SourceFile): ts.CallExpression | null;
|
package/private/standalone.js
DELETED
|
@@ -1,393 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* @license
|
|
4
|
-
* Copyright Google LLC All Rights Reserved.
|
|
5
|
-
*
|
|
6
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
7
|
-
* found in the LICENSE file at https://angular.io/license
|
|
8
|
-
*/
|
|
9
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
10
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
|
-
};
|
|
12
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
-
exports.findBootstrapApplicationCall = exports.addFunctionalProvidersToStandaloneBootstrap = exports.addModuleImportToStandaloneBootstrap = exports.callsProvidersFunction = exports.importsProvidersFrom = void 0;
|
|
14
|
-
const schematics_1 = require("@angular-devkit/schematics");
|
|
15
|
-
const path_1 = require("path");
|
|
16
|
-
const typescript_1 = __importDefault(require("../third_party/github.com/Microsoft/TypeScript/lib/typescript"));
|
|
17
|
-
const ast_utils_1 = require("../utility/ast-utils");
|
|
18
|
-
const change_1 = require("../utility/change");
|
|
19
|
-
/**
|
|
20
|
-
* Checks whether the providers from a module are being imported in a `bootstrapApplication` call.
|
|
21
|
-
* @param tree File tree of the project.
|
|
22
|
-
* @param filePath Path of the file in which to check.
|
|
23
|
-
* @param className Class name of the module to search for.
|
|
24
|
-
* @deprecated Private utility that will be removed. Use `addRootImport` or `addRootProvider` from
|
|
25
|
-
* `@schematics/angular/utility` instead.
|
|
26
|
-
*/
|
|
27
|
-
function importsProvidersFrom(tree, filePath, className) {
|
|
28
|
-
const sourceFile = createSourceFile(tree, filePath);
|
|
29
|
-
const bootstrapCall = findBootstrapApplicationCall(sourceFile);
|
|
30
|
-
const appConfig = bootstrapCall ? findAppConfig(bootstrapCall, tree, filePath) : null;
|
|
31
|
-
const importProvidersFromCall = appConfig ? findImportProvidersFromCall(appConfig.node) : null;
|
|
32
|
-
return !!importProvidersFromCall?.arguments.some((arg) => typescript_1.default.isIdentifier(arg) && arg.text === className);
|
|
33
|
-
}
|
|
34
|
-
exports.importsProvidersFrom = importsProvidersFrom;
|
|
35
|
-
/**
|
|
36
|
-
* Checks whether a providers function is being called in a `bootstrapApplication` call.
|
|
37
|
-
* @param tree File tree of the project.
|
|
38
|
-
* @param filePath Path of the file in which to check.
|
|
39
|
-
* @param functionName Name of the function to search for.
|
|
40
|
-
* @deprecated Private utility that will be removed. Use `addRootImport` or `addRootProvider` from
|
|
41
|
-
* `@schematics/angular/utility` instead.
|
|
42
|
-
*/
|
|
43
|
-
function callsProvidersFunction(tree, filePath, functionName) {
|
|
44
|
-
const sourceFile = createSourceFile(tree, filePath);
|
|
45
|
-
const bootstrapCall = findBootstrapApplicationCall(sourceFile);
|
|
46
|
-
const appConfig = bootstrapCall ? findAppConfig(bootstrapCall, tree, filePath) : null;
|
|
47
|
-
const providersLiteral = appConfig ? findProvidersLiteral(appConfig.node) : null;
|
|
48
|
-
return !!providersLiteral?.elements.some((el) => typescript_1.default.isCallExpression(el) &&
|
|
49
|
-
typescript_1.default.isIdentifier(el.expression) &&
|
|
50
|
-
el.expression.text === functionName);
|
|
51
|
-
}
|
|
52
|
-
exports.callsProvidersFunction = callsProvidersFunction;
|
|
53
|
-
/**
|
|
54
|
-
* Adds an `importProvidersFrom` call to the `bootstrapApplication` call.
|
|
55
|
-
* @param tree File tree of the project.
|
|
56
|
-
* @param filePath Path to the file that should be updated.
|
|
57
|
-
* @param moduleName Name of the module that should be imported.
|
|
58
|
-
* @param modulePath Path from which to import the module.
|
|
59
|
-
* @deprecated Private utility that will be removed. Use `addRootImport` or `addRootProvider` from
|
|
60
|
-
* `@schematics/angular/utility` instead.
|
|
61
|
-
*/
|
|
62
|
-
function addModuleImportToStandaloneBootstrap(tree, filePath, moduleName, modulePath) {
|
|
63
|
-
const sourceFile = createSourceFile(tree, filePath);
|
|
64
|
-
const bootstrapCall = findBootstrapApplicationCall(sourceFile);
|
|
65
|
-
const addImports = (file, recorder) => {
|
|
66
|
-
const sourceText = file.getText();
|
|
67
|
-
[
|
|
68
|
-
(0, ast_utils_1.insertImport)(file, sourceText, moduleName, modulePath),
|
|
69
|
-
(0, ast_utils_1.insertImport)(file, sourceText, 'importProvidersFrom', '@angular/core'),
|
|
70
|
-
].forEach((change) => {
|
|
71
|
-
if (change instanceof change_1.InsertChange) {
|
|
72
|
-
recorder.insertLeft(change.pos, change.toAdd);
|
|
73
|
-
}
|
|
74
|
-
});
|
|
75
|
-
};
|
|
76
|
-
if (!bootstrapCall) {
|
|
77
|
-
throw new schematics_1.SchematicsException(`Could not find bootstrapApplication call in ${filePath}`);
|
|
78
|
-
}
|
|
79
|
-
const importProvidersCall = typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier('importProvidersFrom'), [], [typescript_1.default.factory.createIdentifier(moduleName)]);
|
|
80
|
-
// If there's only one argument, we have to create a new object literal.
|
|
81
|
-
if (bootstrapCall.arguments.length === 1) {
|
|
82
|
-
const recorder = tree.beginUpdate(filePath);
|
|
83
|
-
addNewAppConfigToCall(bootstrapCall, importProvidersCall, recorder);
|
|
84
|
-
addImports(sourceFile, recorder);
|
|
85
|
-
tree.commitUpdate(recorder);
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
// If the config is a `mergeApplicationProviders` call, add another config to it.
|
|
89
|
-
if (isMergeAppConfigCall(bootstrapCall.arguments[1])) {
|
|
90
|
-
const recorder = tree.beginUpdate(filePath);
|
|
91
|
-
addNewAppConfigToCall(bootstrapCall.arguments[1], importProvidersCall, recorder);
|
|
92
|
-
addImports(sourceFile, recorder);
|
|
93
|
-
tree.commitUpdate(recorder);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
// Otherwise attempt to merge into the current config.
|
|
97
|
-
const appConfig = findAppConfig(bootstrapCall, tree, filePath);
|
|
98
|
-
if (!appConfig) {
|
|
99
|
-
throw new schematics_1.SchematicsException(`Could not statically analyze config in bootstrapApplication call in ${filePath}`);
|
|
100
|
-
}
|
|
101
|
-
const { filePath: configFilePath, node: config } = appConfig;
|
|
102
|
-
const recorder = tree.beginUpdate(configFilePath);
|
|
103
|
-
const importCall = findImportProvidersFromCall(config);
|
|
104
|
-
addImports(config.getSourceFile(), recorder);
|
|
105
|
-
if (importCall) {
|
|
106
|
-
// If there's an `importProvidersFrom` call already, add the module to it.
|
|
107
|
-
recorder.insertRight(importCall.arguments[importCall.arguments.length - 1].getEnd(), `, ${moduleName}`);
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
const providersLiteral = findProvidersLiteral(config);
|
|
111
|
-
if (providersLiteral) {
|
|
112
|
-
// If there's a `providers` array, add the import to it.
|
|
113
|
-
addElementToArray(providersLiteral, importProvidersCall, recorder);
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
// Otherwise add a `providers` array to the existing object literal.
|
|
117
|
-
addProvidersToObjectLiteral(config, importProvidersCall, recorder);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
tree.commitUpdate(recorder);
|
|
121
|
-
}
|
|
122
|
-
exports.addModuleImportToStandaloneBootstrap = addModuleImportToStandaloneBootstrap;
|
|
123
|
-
/**
|
|
124
|
-
* Adds a providers function call to the `bootstrapApplication` call.
|
|
125
|
-
* @param tree File tree of the project.
|
|
126
|
-
* @param filePath Path to the file that should be updated.
|
|
127
|
-
* @param functionName Name of the function that should be called.
|
|
128
|
-
* @param importPath Path from which to import the function.
|
|
129
|
-
* @param args Arguments to use when calling the function.
|
|
130
|
-
* @return The file path that the provider was added to.
|
|
131
|
-
* @deprecated Private utility that will be removed. Use `addRootImport` or `addRootProvider` from
|
|
132
|
-
* `@schematics/angular/utility` instead.
|
|
133
|
-
*/
|
|
134
|
-
function addFunctionalProvidersToStandaloneBootstrap(tree, filePath, functionName, importPath, args = []) {
|
|
135
|
-
const sourceFile = createSourceFile(tree, filePath);
|
|
136
|
-
const bootstrapCall = findBootstrapApplicationCall(sourceFile);
|
|
137
|
-
const addImports = (file, recorder) => {
|
|
138
|
-
const change = (0, ast_utils_1.insertImport)(file, file.getText(), functionName, importPath);
|
|
139
|
-
if (change instanceof change_1.InsertChange) {
|
|
140
|
-
recorder.insertLeft(change.pos, change.toAdd);
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
if (!bootstrapCall) {
|
|
144
|
-
throw new schematics_1.SchematicsException(`Could not find bootstrapApplication call in ${filePath}`);
|
|
145
|
-
}
|
|
146
|
-
const providersCall = typescript_1.default.factory.createCallExpression(typescript_1.default.factory.createIdentifier(functionName), undefined, args);
|
|
147
|
-
// If there's only one argument, we have to create a new object literal.
|
|
148
|
-
if (bootstrapCall.arguments.length === 1) {
|
|
149
|
-
const recorder = tree.beginUpdate(filePath);
|
|
150
|
-
addNewAppConfigToCall(bootstrapCall, providersCall, recorder);
|
|
151
|
-
addImports(sourceFile, recorder);
|
|
152
|
-
tree.commitUpdate(recorder);
|
|
153
|
-
return filePath;
|
|
154
|
-
}
|
|
155
|
-
// If the config is a `mergeApplicationProviders` call, add another config to it.
|
|
156
|
-
if (isMergeAppConfigCall(bootstrapCall.arguments[1])) {
|
|
157
|
-
const recorder = tree.beginUpdate(filePath);
|
|
158
|
-
addNewAppConfigToCall(bootstrapCall.arguments[1], providersCall, recorder);
|
|
159
|
-
addImports(sourceFile, recorder);
|
|
160
|
-
tree.commitUpdate(recorder);
|
|
161
|
-
return filePath;
|
|
162
|
-
}
|
|
163
|
-
// Otherwise attempt to merge into the current config.
|
|
164
|
-
const appConfig = findAppConfig(bootstrapCall, tree, filePath);
|
|
165
|
-
if (!appConfig) {
|
|
166
|
-
throw new schematics_1.SchematicsException(`Could not statically analyze config in bootstrapApplication call in ${filePath}`);
|
|
167
|
-
}
|
|
168
|
-
const { filePath: configFilePath, node: config } = appConfig;
|
|
169
|
-
const recorder = tree.beginUpdate(configFilePath);
|
|
170
|
-
const providersLiteral = findProvidersLiteral(config);
|
|
171
|
-
addImports(config.getSourceFile(), recorder);
|
|
172
|
-
if (providersLiteral) {
|
|
173
|
-
// If there's a `providers` array, add the import to it.
|
|
174
|
-
addElementToArray(providersLiteral, providersCall, recorder);
|
|
175
|
-
}
|
|
176
|
-
else {
|
|
177
|
-
// Otherwise add a `providers` array to the existing object literal.
|
|
178
|
-
addProvidersToObjectLiteral(config, providersCall, recorder);
|
|
179
|
-
}
|
|
180
|
-
tree.commitUpdate(recorder);
|
|
181
|
-
return configFilePath;
|
|
182
|
-
}
|
|
183
|
-
exports.addFunctionalProvidersToStandaloneBootstrap = addFunctionalProvidersToStandaloneBootstrap;
|
|
184
|
-
/**
|
|
185
|
-
* Finds the call to `bootstrapApplication` within a file.
|
|
186
|
-
* @deprecated Private utility that will be removed. Use `addRootImport` or `addRootProvider` from
|
|
187
|
-
* `@schematics/angular/utility` instead.
|
|
188
|
-
*/
|
|
189
|
-
function findBootstrapApplicationCall(sourceFile) {
|
|
190
|
-
const localName = findImportLocalName(sourceFile, 'bootstrapApplication', '@angular/platform-browser');
|
|
191
|
-
if (!localName) {
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
let result = null;
|
|
195
|
-
sourceFile.forEachChild(function walk(node) {
|
|
196
|
-
if (typescript_1.default.isCallExpression(node) &&
|
|
197
|
-
typescript_1.default.isIdentifier(node.expression) &&
|
|
198
|
-
node.expression.text === localName) {
|
|
199
|
-
result = node;
|
|
200
|
-
}
|
|
201
|
-
if (!result) {
|
|
202
|
-
node.forEachChild(walk);
|
|
203
|
-
}
|
|
204
|
-
});
|
|
205
|
-
return result;
|
|
206
|
-
}
|
|
207
|
-
exports.findBootstrapApplicationCall = findBootstrapApplicationCall;
|
|
208
|
-
/** Find a call to `importProvidersFrom` within an application config. */
|
|
209
|
-
function findImportProvidersFromCall(config) {
|
|
210
|
-
const importProvidersName = findImportLocalName(config.getSourceFile(), 'importProvidersFrom', '@angular/core');
|
|
211
|
-
const providersLiteral = findProvidersLiteral(config);
|
|
212
|
-
if (providersLiteral && importProvidersName) {
|
|
213
|
-
for (const element of providersLiteral.elements) {
|
|
214
|
-
// Look for an array element that calls the `importProvidersFrom` function.
|
|
215
|
-
if (typescript_1.default.isCallExpression(element) &&
|
|
216
|
-
typescript_1.default.isIdentifier(element.expression) &&
|
|
217
|
-
element.expression.text === importProvidersName) {
|
|
218
|
-
return element;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
return null;
|
|
223
|
-
}
|
|
224
|
-
/** Finds the `providers` array literal within an application config. */
|
|
225
|
-
function findProvidersLiteral(config) {
|
|
226
|
-
for (const prop of config.properties) {
|
|
227
|
-
if (typescript_1.default.isPropertyAssignment(prop) &&
|
|
228
|
-
typescript_1.default.isIdentifier(prop.name) &&
|
|
229
|
-
prop.name.text === 'providers' &&
|
|
230
|
-
typescript_1.default.isArrayLiteralExpression(prop.initializer)) {
|
|
231
|
-
return prop.initializer;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
return null;
|
|
235
|
-
}
|
|
236
|
-
/**
|
|
237
|
-
* Resolves the node that defines the app config from a bootstrap call.
|
|
238
|
-
* @param bootstrapCall Call for which to resolve the config.
|
|
239
|
-
* @param tree File tree of the project.
|
|
240
|
-
* @param filePath File path of the bootstrap call.
|
|
241
|
-
*/
|
|
242
|
-
function findAppConfig(bootstrapCall, tree, filePath) {
|
|
243
|
-
if (bootstrapCall.arguments.length > 1) {
|
|
244
|
-
const config = bootstrapCall.arguments[1];
|
|
245
|
-
if (typescript_1.default.isObjectLiteralExpression(config)) {
|
|
246
|
-
return { filePath, node: config };
|
|
247
|
-
}
|
|
248
|
-
if (typescript_1.default.isIdentifier(config)) {
|
|
249
|
-
return resolveAppConfigFromIdentifier(config, tree, filePath);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
return null;
|
|
253
|
-
}
|
|
254
|
-
/**
|
|
255
|
-
* Resolves the app config from an identifier referring to it.
|
|
256
|
-
* @param identifier Identifier referring to the app config.
|
|
257
|
-
* @param tree File tree of the project.
|
|
258
|
-
* @param bootstapFilePath Path of the bootstrap call.
|
|
259
|
-
*/
|
|
260
|
-
function resolveAppConfigFromIdentifier(identifier, tree, bootstapFilePath) {
|
|
261
|
-
const sourceFile = identifier.getSourceFile();
|
|
262
|
-
for (const node of sourceFile.statements) {
|
|
263
|
-
// Only look at relative imports. This will break if the app uses a path
|
|
264
|
-
// mapping to refer to the import, but in order to resolve those, we would
|
|
265
|
-
// need knowledge about the entire program.
|
|
266
|
-
if (!typescript_1.default.isImportDeclaration(node) ||
|
|
267
|
-
!node.importClause?.namedBindings ||
|
|
268
|
-
!typescript_1.default.isNamedImports(node.importClause.namedBindings) ||
|
|
269
|
-
!typescript_1.default.isStringLiteralLike(node.moduleSpecifier) ||
|
|
270
|
-
!node.moduleSpecifier.text.startsWith('.')) {
|
|
271
|
-
continue;
|
|
272
|
-
}
|
|
273
|
-
for (const specifier of node.importClause.namedBindings.elements) {
|
|
274
|
-
if (specifier.name.text !== identifier.text) {
|
|
275
|
-
continue;
|
|
276
|
-
}
|
|
277
|
-
// Look for a variable with the imported name in the file. Note that ideally we would use
|
|
278
|
-
// the type checker to resolve this, but we can't because these utilities are set up to
|
|
279
|
-
// operate on individual files, not the entire program.
|
|
280
|
-
const filePath = (0, path_1.join)((0, path_1.dirname)(bootstapFilePath), node.moduleSpecifier.text + '.ts');
|
|
281
|
-
const importedSourceFile = createSourceFile(tree, filePath);
|
|
282
|
-
const resolvedVariable = findAppConfigFromVariableName(importedSourceFile, (specifier.propertyName || specifier.name).text);
|
|
283
|
-
if (resolvedVariable) {
|
|
284
|
-
return { filePath, node: resolvedVariable };
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
const variableInSameFile = findAppConfigFromVariableName(sourceFile, identifier.text);
|
|
289
|
-
return variableInSameFile ? { filePath: bootstapFilePath, node: variableInSameFile } : null;
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* Finds an app config within the top-level variables of a file.
|
|
293
|
-
* @param sourceFile File in which to search for the config.
|
|
294
|
-
* @param variableName Name of the variable containing the config.
|
|
295
|
-
*/
|
|
296
|
-
function findAppConfigFromVariableName(sourceFile, variableName) {
|
|
297
|
-
for (const node of sourceFile.statements) {
|
|
298
|
-
if (typescript_1.default.isVariableStatement(node)) {
|
|
299
|
-
for (const decl of node.declarationList.declarations) {
|
|
300
|
-
if (typescript_1.default.isIdentifier(decl.name) &&
|
|
301
|
-
decl.name.text === variableName &&
|
|
302
|
-
decl.initializer &&
|
|
303
|
-
typescript_1.default.isObjectLiteralExpression(decl.initializer)) {
|
|
304
|
-
return decl.initializer;
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
return null;
|
|
310
|
-
}
|
|
311
|
-
/**
|
|
312
|
-
* Finds the local name of an imported symbol. Could be the symbol name itself or its alias.
|
|
313
|
-
* @param sourceFile File within which to search for the import.
|
|
314
|
-
* @param name Actual name of the import, not its local alias.
|
|
315
|
-
* @param moduleName Name of the module from which the symbol is imported.
|
|
316
|
-
*/
|
|
317
|
-
function findImportLocalName(sourceFile, name, moduleName) {
|
|
318
|
-
for (const node of sourceFile.statements) {
|
|
319
|
-
// Only look for top-level imports.
|
|
320
|
-
if (!typescript_1.default.isImportDeclaration(node) ||
|
|
321
|
-
!typescript_1.default.isStringLiteral(node.moduleSpecifier) ||
|
|
322
|
-
node.moduleSpecifier.text !== moduleName) {
|
|
323
|
-
continue;
|
|
324
|
-
}
|
|
325
|
-
// Filter out imports that don't have the right shape.
|
|
326
|
-
if (!node.importClause ||
|
|
327
|
-
!node.importClause.namedBindings ||
|
|
328
|
-
!typescript_1.default.isNamedImports(node.importClause.namedBindings)) {
|
|
329
|
-
continue;
|
|
330
|
-
}
|
|
331
|
-
// Look through the elements of the declaration for the specific import.
|
|
332
|
-
for (const element of node.importClause.namedBindings.elements) {
|
|
333
|
-
if ((element.propertyName || element.name).text === name) {
|
|
334
|
-
// The local name is always in `name`.
|
|
335
|
-
return element.name.text;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
return null;
|
|
340
|
-
}
|
|
341
|
-
/** Creates a source file from a file path within a project. */
|
|
342
|
-
function createSourceFile(tree, filePath) {
|
|
343
|
-
return typescript_1.default.createSourceFile(filePath, tree.readText(filePath), typescript_1.default.ScriptTarget.Latest, true);
|
|
344
|
-
}
|
|
345
|
-
/**
|
|
346
|
-
* Creates a new app config object literal and adds it to a call expression as an argument.
|
|
347
|
-
* @param call Call to which to add the config.
|
|
348
|
-
* @param expression Expression that should inserted into the new config.
|
|
349
|
-
* @param recorder Recorder to which to log the change.
|
|
350
|
-
*/
|
|
351
|
-
function addNewAppConfigToCall(call, expression, recorder) {
|
|
352
|
-
const newCall = typescript_1.default.factory.updateCallExpression(call, call.expression, call.typeArguments, [
|
|
353
|
-
...call.arguments,
|
|
354
|
-
typescript_1.default.factory.createObjectLiteralExpression([
|
|
355
|
-
typescript_1.default.factory.createPropertyAssignment('providers', typescript_1.default.factory.createArrayLiteralExpression([expression])),
|
|
356
|
-
], true),
|
|
357
|
-
]);
|
|
358
|
-
recorder.remove(call.getStart(), call.getWidth());
|
|
359
|
-
recorder.insertRight(call.getStart(), typescript_1.default.createPrinter().printNode(typescript_1.default.EmitHint.Unspecified, newCall, call.getSourceFile()));
|
|
360
|
-
}
|
|
361
|
-
/**
|
|
362
|
-
* Adds an element to an array literal expression.
|
|
363
|
-
* @param node Array to which to add the element.
|
|
364
|
-
* @param element Element to be added.
|
|
365
|
-
* @param recorder Recorder to which to log the change.
|
|
366
|
-
*/
|
|
367
|
-
function addElementToArray(node, element, recorder) {
|
|
368
|
-
const newLiteral = typescript_1.default.factory.updateArrayLiteralExpression(node, [...node.elements, element]);
|
|
369
|
-
recorder.remove(node.getStart(), node.getWidth());
|
|
370
|
-
recorder.insertRight(node.getStart(), typescript_1.default.createPrinter().printNode(typescript_1.default.EmitHint.Unspecified, newLiteral, node.getSourceFile()));
|
|
371
|
-
}
|
|
372
|
-
/**
|
|
373
|
-
* Adds a `providers` property to an object literal.
|
|
374
|
-
* @param node Literal to which to add the `providers`.
|
|
375
|
-
* @param expression Provider that should be part of the generated `providers` array.
|
|
376
|
-
* @param recorder Recorder to which to log the change.
|
|
377
|
-
*/
|
|
378
|
-
function addProvidersToObjectLiteral(node, expression, recorder) {
|
|
379
|
-
const newOptionsLiteral = typescript_1.default.factory.updateObjectLiteralExpression(node, [
|
|
380
|
-
...node.properties,
|
|
381
|
-
typescript_1.default.factory.createPropertyAssignment('providers', typescript_1.default.factory.createArrayLiteralExpression([expression])),
|
|
382
|
-
]);
|
|
383
|
-
recorder.remove(node.getStart(), node.getWidth());
|
|
384
|
-
recorder.insertRight(node.getStart(), typescript_1.default.createPrinter().printNode(typescript_1.default.EmitHint.Unspecified, newOptionsLiteral, node.getSourceFile()));
|
|
385
|
-
}
|
|
386
|
-
/** Checks whether a node is a call to `mergeApplicationConfig`. */
|
|
387
|
-
function isMergeAppConfigCall(node) {
|
|
388
|
-
if (!typescript_1.default.isCallExpression(node)) {
|
|
389
|
-
return false;
|
|
390
|
-
}
|
|
391
|
-
const localName = findImportLocalName(node.getSourceFile(), 'mergeApplicationConfig', '@angular/core');
|
|
392
|
-
return !!localName && typescript_1.default.isIdentifier(node.expression) && node.expression.text === localName;
|
|
393
|
-
}
|