@schematics/angular 20.2.0-next.2 → 20.2.0-rc.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/ai-config/files/__rulesName__.template +49 -0
- package/ai-config/index.d.ts +10 -0
- package/ai-config/index.js +55 -0
- package/ai-config/schema.d.ts +21 -0
- package/ai-config/schema.js +15 -0
- package/ai-config/schema.json +39 -0
- package/application/index.js +26 -39
- package/collection.json +5 -0
- package/library/index.js +25 -40
- package/migrations/karma/karma-config-analyzer.d.ts +27 -0
- package/migrations/karma/karma-config-analyzer.js +131 -0
- package/migrations/karma/karma-config-comparer.d.ts +63 -0
- package/migrations/karma/karma-config-comparer.js +89 -0
- package/migrations/karma/migration.d.ts +9 -0
- package/migrations/karma/migration.js +62 -0
- package/migrations/migration-collection.json +5 -0
- package/migrations/replace-provide-server-rendering-import/migration.js +13 -48
- package/migrations/use-application-builder/migration.js +5 -142
- package/migrations/use-application-builder/stylesheet-updates.d.ts +36 -0
- package/migrations/use-application-builder/stylesheet-updates.js +219 -0
- package/ng-new/index.js +3 -0
- package/ng-new/schema.d.ts +14 -0
- package/ng-new/schema.js +11 -1
- package/ng-new/schema.json +10 -3
- package/package.json +4 -4
- package/service-worker/index.js +2 -2
- package/third_party/github.com/Microsoft/TypeScript/lib/typescript.js +1 -1
- package/utility/dependency.d.ts +47 -1
- package/utility/dependency.js +55 -0
- package/utility/latest-versions/package.json +1 -1
- package/utility/latest-versions.js +3 -3
- package/workspace/files/package.json.template +2 -0
|
@@ -0,0 +1,219 @@
|
|
|
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.dev/license
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.hasLessStylesheets = hasLessStylesheets;
|
|
11
|
+
exports.hasPostcssConfiguration = hasPostcssConfiguration;
|
|
12
|
+
exports.updateStyleImports = updateStyleImports;
|
|
13
|
+
const posix_1 = require("node:path/posix");
|
|
14
|
+
const css_import_lexer_1 = require("./css-import-lexer");
|
|
15
|
+
/** A list of all supported SASS style extensions.
|
|
16
|
+
* Order of extension is important and matches Sass behavior.
|
|
17
|
+
*/
|
|
18
|
+
const SASS_EXTENSIONS = ['.scss', '.sass', '.css'];
|
|
19
|
+
/** The prefix used to indicate a SASS partial file. */
|
|
20
|
+
const SASS_PARTIAL_PREFIX = '_';
|
|
21
|
+
/**
|
|
22
|
+
* Searches the schematic tree for files that have a `.less` extension.
|
|
23
|
+
* This is used to determine if the `less` package should be added as a dependency.
|
|
24
|
+
*
|
|
25
|
+
* @param tree A Schematics tree instance to search.
|
|
26
|
+
* @returns `true` if Less stylesheet files are found; otherwise, `false`.
|
|
27
|
+
*/
|
|
28
|
+
function hasLessStylesheets(tree) {
|
|
29
|
+
const directories = [tree.getDir('/')];
|
|
30
|
+
let current;
|
|
31
|
+
while ((current = directories.pop())) {
|
|
32
|
+
for (const path of current.subfiles) {
|
|
33
|
+
if (path.endsWith('.less')) {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
for (const path of current.subdirs) {
|
|
38
|
+
if (path === 'node_modules' || path.startsWith('.')) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
directories.push(current.dir(path));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Searches for a PostCSS configuration file within the workspace root or any of the project roots.
|
|
48
|
+
* This is used to determine if the `postcss` package should be added as a dependency.
|
|
49
|
+
*
|
|
50
|
+
* @param tree A Schematics tree instance to search.
|
|
51
|
+
* @param workspace A Workspace to check for projects.
|
|
52
|
+
* @returns `true` if a PostCSS configuration file is found; otherwise, `false`.
|
|
53
|
+
*/
|
|
54
|
+
function hasPostcssConfiguration(tree, workspace) {
|
|
55
|
+
const projectRoots = [...workspace.projects.values()].map((p) => p.root).filter(Boolean);
|
|
56
|
+
const searchDirectories = new Set(['', ...projectRoots]);
|
|
57
|
+
for (const dir of searchDirectories) {
|
|
58
|
+
if (tree.exists((0, posix_1.join)(dir, 'postcss.config.json')) ||
|
|
59
|
+
tree.exists((0, posix_1.join)(dir, '.postcssrc.json'))) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Recursively visits all stylesheet files in a directory and yields their path and content.
|
|
67
|
+
*
|
|
68
|
+
* @param directory The directory to visit.
|
|
69
|
+
*/
|
|
70
|
+
function* visitStylesheets(directory) {
|
|
71
|
+
for (const path of directory.subfiles) {
|
|
72
|
+
if (path.endsWith('.css') || path.endsWith('.scss') || path.endsWith('.sass')) {
|
|
73
|
+
const entry = directory.file(path);
|
|
74
|
+
if (entry) {
|
|
75
|
+
yield [entry.path, entry.content.toString()];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (const path of directory.subdirs) {
|
|
80
|
+
if (path === 'node_modules' || path.startsWith('.')) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
yield* visitStylesheets(directory.dir(path));
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Determines if a Sass import is likely intended to be relative to the workspace root.
|
|
88
|
+
* This is considered true if the import cannot be resolved relative to the containing file,
|
|
89
|
+
* but can be resolved relative to the workspace root.
|
|
90
|
+
*
|
|
91
|
+
* @param specifier The import specifier to check.
|
|
92
|
+
* @param filePath The path of the file containing the import.
|
|
93
|
+
* @param tree A Schematics tree instance.
|
|
94
|
+
* @param fromImport Whether the specifier is from an `@import` rule.
|
|
95
|
+
* @returns `true` if the import is likely workspace-relative; otherwise, `false`.
|
|
96
|
+
*/
|
|
97
|
+
function isWorkspaceRelativeSassImport(specifier, filePath, tree, fromImport) {
|
|
98
|
+
const relativeBase = (0, posix_1.dirname)(filePath);
|
|
99
|
+
const potentialWorkspacePaths = [...potentialSassImports(specifier, '/', fromImport)];
|
|
100
|
+
if (potentialWorkspacePaths.some((p) => tree.exists(p))) {
|
|
101
|
+
const potentialRelativePaths = [...potentialSassImports(specifier, relativeBase, fromImport)];
|
|
102
|
+
return potentialRelativePaths.every((p) => !tree.exists(p));
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Analyzes a single stylesheet's content for import patterns that need to be updated.
|
|
108
|
+
*
|
|
109
|
+
* @param filePath The path of the stylesheet file.
|
|
110
|
+
* @param content The content of the stylesheet file.
|
|
111
|
+
* @param tree A Schematics tree instance.
|
|
112
|
+
* @returns A `StylesheetAnalysis` object containing the results of the analysis.
|
|
113
|
+
*/
|
|
114
|
+
function analyzeStylesheet(filePath, content, tree) {
|
|
115
|
+
const isSass = filePath.endsWith('.scss') || filePath.endsWith('.sass');
|
|
116
|
+
const analysis = {
|
|
117
|
+
needsWorkspaceIncludePath: false,
|
|
118
|
+
externalDependencies: new Set(),
|
|
119
|
+
contentChanges: [],
|
|
120
|
+
};
|
|
121
|
+
for (const { start, specifier, fromUse } of (0, css_import_lexer_1.findImports)(content, isSass)) {
|
|
122
|
+
if (specifier.startsWith('~')) {
|
|
123
|
+
analysis.contentChanges.push({ start: start + 1, length: 1 });
|
|
124
|
+
}
|
|
125
|
+
else if (specifier.startsWith('^')) {
|
|
126
|
+
analysis.contentChanges.push({ start: start + 1, length: 1 });
|
|
127
|
+
analysis.externalDependencies.add(specifier.slice(1));
|
|
128
|
+
}
|
|
129
|
+
else if (isSass && isWorkspaceRelativeSassImport(specifier, filePath, tree, !fromUse)) {
|
|
130
|
+
analysis.needsWorkspaceIncludePath = true;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return analysis;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* The main orchestrator function for updating stylesheets.
|
|
137
|
+
* It iterates through all stylesheets in a project, analyzes them, and applies the necessary
|
|
138
|
+
* changes to the files and the build configuration.
|
|
139
|
+
*
|
|
140
|
+
* @param tree A Schematics tree instance.
|
|
141
|
+
* @param projectSourceRoot The source root of the project being updated.
|
|
142
|
+
* @param buildTarget The build target of the project being updated.
|
|
143
|
+
*/
|
|
144
|
+
function updateStyleImports(tree, projectSourceRoot, buildTarget) {
|
|
145
|
+
const allExternalDeps = new Set();
|
|
146
|
+
let projectNeedsIncludePath = false;
|
|
147
|
+
for (const [path, content] of visitStylesheets(tree.getDir(projectSourceRoot))) {
|
|
148
|
+
const { needsWorkspaceIncludePath, externalDependencies, contentChanges } = analyzeStylesheet(path, content, tree);
|
|
149
|
+
if (needsWorkspaceIncludePath) {
|
|
150
|
+
projectNeedsIncludePath = true;
|
|
151
|
+
}
|
|
152
|
+
for (const dep of externalDependencies) {
|
|
153
|
+
allExternalDeps.add(dep);
|
|
154
|
+
}
|
|
155
|
+
if (contentChanges.length > 0) {
|
|
156
|
+
const updater = tree.beginUpdate(path);
|
|
157
|
+
// Apply changes in reverse to avoid index shifting
|
|
158
|
+
for (const change of contentChanges.sort((a, b) => b.start - a.start)) {
|
|
159
|
+
updater.remove(change.start, change.length);
|
|
160
|
+
}
|
|
161
|
+
tree.commitUpdate(updater);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (projectNeedsIncludePath) {
|
|
165
|
+
buildTarget.options ??= {};
|
|
166
|
+
const styleOptions = (buildTarget.options['stylePreprocessorOptions'] ??= {});
|
|
167
|
+
const includePaths = (styleOptions['includePaths'] ??= []);
|
|
168
|
+
if (Array.isArray(includePaths)) {
|
|
169
|
+
includePaths.push('.');
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (allExternalDeps.size > 0) {
|
|
173
|
+
buildTarget.options ??= {};
|
|
174
|
+
const externalDeps = (buildTarget.options['externalDependencies'] ??=
|
|
175
|
+
[]);
|
|
176
|
+
if (Array.isArray(externalDeps)) {
|
|
177
|
+
externalDeps.push(...allExternalDeps);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* A helper generator that yields potential Sass import candidates for a given filename and extensions.
|
|
183
|
+
*
|
|
184
|
+
* @param directory The directory in which to resolve the candidates.
|
|
185
|
+
* @param filename The base filename of the import.
|
|
186
|
+
* @param extensions The file extensions to try.
|
|
187
|
+
* @param fromImport Whether the specifier is from an `@import` rule.
|
|
188
|
+
* @returns An iterable of potential import file paths.
|
|
189
|
+
*/
|
|
190
|
+
function* yieldSassImportCandidates(directory, filename, extensions, fromImport) {
|
|
191
|
+
if (fromImport) {
|
|
192
|
+
for (const ext of extensions) {
|
|
193
|
+
yield (0, posix_1.join)(directory, filename + '.import' + ext);
|
|
194
|
+
yield (0, posix_1.join)(directory, SASS_PARTIAL_PREFIX + filename + '.import' + ext);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
for (const ext of extensions) {
|
|
198
|
+
yield (0, posix_1.join)(directory, filename + ext);
|
|
199
|
+
yield (0, posix_1.join)(directory, SASS_PARTIAL_PREFIX + filename + ext);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Generates a sequence of potential file paths that the Sass compiler would attempt to resolve
|
|
204
|
+
* for a given import specifier, following the official Sass resolution algorithm.
|
|
205
|
+
* Based on https://github.com/sass/dart-sass/blob/44d6bb6ac72fe6b93f5bfec371a1fffb18e6b76d/lib/src/importer/utils.dart
|
|
206
|
+
*
|
|
207
|
+
* @param specifier The import specifier to resolve.
|
|
208
|
+
* @param base The base path from which to resolve the specifier.
|
|
209
|
+
* @param fromImport Whether the specifier is from an `@import` rule.
|
|
210
|
+
* @returns An iterable of potential file paths.
|
|
211
|
+
*/
|
|
212
|
+
function* potentialSassImports(specifier, base, fromImport) {
|
|
213
|
+
const directory = (0, posix_1.join)(base, (0, posix_1.dirname)(specifier));
|
|
214
|
+
const extension = (0, posix_1.extname)(specifier);
|
|
215
|
+
const hasStyleExtension = SASS_EXTENSIONS.includes(extension);
|
|
216
|
+
const filename = (0, posix_1.basename)(specifier, hasStyleExtension ? extension : undefined);
|
|
217
|
+
const extensionsToTry = hasStyleExtension ? [extension] : SASS_EXTENSIONS;
|
|
218
|
+
yield* yieldSassImportCandidates(directory, filename, extensionsToTry, fromImport);
|
|
219
|
+
}
|
package/ng-new/index.js
CHANGED
|
@@ -46,6 +46,9 @@ function default_1(options) {
|
|
|
46
46
|
(0, schematics_1.mergeWith)((0, schematics_1.apply)((0, schematics_1.empty)(), [
|
|
47
47
|
(0, schematics_1.schematic)('workspace', workspaceOptions),
|
|
48
48
|
options.createApplication ? (0, schematics_1.schematic)('application', applicationOptions) : schematics_1.noop,
|
|
49
|
+
(0, schematics_1.schematic)('ai-config', {
|
|
50
|
+
tool: options.aiConfig?.length ? options.aiConfig : undefined,
|
|
51
|
+
}),
|
|
49
52
|
(0, schematics_1.move)(options.directory),
|
|
50
53
|
])),
|
|
51
54
|
(_host, context) => {
|
package/ng-new/schema.d.ts
CHANGED
|
@@ -5,6 +5,11 @@
|
|
|
5
5
|
* the initial project, such as routing, styling, and testing.
|
|
6
6
|
*/
|
|
7
7
|
export type Schema = {
|
|
8
|
+
/**
|
|
9
|
+
* Specifies which AI tools to generate configuration files for. These file are used to
|
|
10
|
+
* improve the outputs of AI tools by following the best practices.
|
|
11
|
+
*/
|
|
12
|
+
aiConfig?: AiConfig[];
|
|
8
13
|
/**
|
|
9
14
|
* Configure the initial Git commit for the new repository.
|
|
10
15
|
*/
|
|
@@ -111,6 +116,15 @@ export type Schema = {
|
|
|
111
116
|
*/
|
|
112
117
|
zoneless?: boolean;
|
|
113
118
|
};
|
|
119
|
+
export declare enum AiConfig {
|
|
120
|
+
Claude = "claude",
|
|
121
|
+
Copilot = "copilot",
|
|
122
|
+
Cursor = "cursor",
|
|
123
|
+
Gemini = "gemini",
|
|
124
|
+
Jetbrains = "jetbrains",
|
|
125
|
+
None = "none",
|
|
126
|
+
Windsurf = "windsurf"
|
|
127
|
+
}
|
|
114
128
|
/**
|
|
115
129
|
* Configure the initial Git commit for the new repository.
|
|
116
130
|
*/
|
package/ng-new/schema.js
CHANGED
|
@@ -2,7 +2,17 @@
|
|
|
2
2
|
// THIS FILE IS AUTOMATICALLY GENERATED. TO UPDATE THIS FILE YOU NEED TO CHANGE THE
|
|
3
3
|
// CORRESPONDING JSON SCHEMA FILE, THEN RUN devkit-admin build (or bazel build ...).
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
-
exports.ViewEncapsulation = exports.Style = exports.PackageManager = void 0;
|
|
5
|
+
exports.ViewEncapsulation = exports.Style = exports.PackageManager = exports.AiConfig = void 0;
|
|
6
|
+
var AiConfig;
|
|
7
|
+
(function (AiConfig) {
|
|
8
|
+
AiConfig["Claude"] = "claude";
|
|
9
|
+
AiConfig["Copilot"] = "copilot";
|
|
10
|
+
AiConfig["Cursor"] = "cursor";
|
|
11
|
+
AiConfig["Gemini"] = "gemini";
|
|
12
|
+
AiConfig["Jetbrains"] = "jetbrains";
|
|
13
|
+
AiConfig["None"] = "none";
|
|
14
|
+
AiConfig["Windsurf"] = "windsurf";
|
|
15
|
+
})(AiConfig || (exports.AiConfig = AiConfig = {}));
|
|
6
16
|
/**
|
|
7
17
|
* The package manager used to install dependencies.
|
|
8
18
|
*/
|
package/ng-new/schema.json
CHANGED
|
@@ -141,9 +141,16 @@
|
|
|
141
141
|
},
|
|
142
142
|
"zoneless": {
|
|
143
143
|
"description": "Create an initial application that does not utilize `zone.js`.",
|
|
144
|
-
"
|
|
145
|
-
|
|
146
|
-
|
|
144
|
+
"type": "boolean"
|
|
145
|
+
},
|
|
146
|
+
"aiConfig": {
|
|
147
|
+
"type": "array",
|
|
148
|
+
"uniqueItems": true,
|
|
149
|
+
"description": "Specifies which AI tools to generate configuration files for. These file are used to improve the outputs of AI tools by following the best practices.",
|
|
150
|
+
"items": {
|
|
151
|
+
"type": "string",
|
|
152
|
+
"enum": ["none", "gemini", "copilot", "claude", "cursor", "jetbrains", "windsurf"]
|
|
153
|
+
}
|
|
147
154
|
}
|
|
148
155
|
},
|
|
149
156
|
"required": ["name", "version"]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schematics/angular",
|
|
3
|
-
"version": "20.2.0-
|
|
3
|
+
"version": "20.2.0-rc.0",
|
|
4
4
|
"description": "Schematics specific to Angular",
|
|
5
5
|
"homepage": "https://github.com/angular/angular-cli",
|
|
6
6
|
"keywords": [
|
|
@@ -22,15 +22,15 @@
|
|
|
22
22
|
},
|
|
23
23
|
"schematics": "./collection.json",
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@angular-devkit/core": "20.2.0-
|
|
26
|
-
"@angular-devkit/schematics": "20.2.0-
|
|
25
|
+
"@angular-devkit/core": "20.2.0-rc.0",
|
|
26
|
+
"@angular-devkit/schematics": "20.2.0-rc.0",
|
|
27
27
|
"jsonc-parser": "3.3.1"
|
|
28
28
|
},
|
|
29
29
|
"repository": {
|
|
30
30
|
"type": "git",
|
|
31
31
|
"url": "https://github.com/angular/angular-cli.git"
|
|
32
32
|
},
|
|
33
|
-
"packageManager": "pnpm@
|
|
33
|
+
"packageManager": "pnpm@10.14.0",
|
|
34
34
|
"engines": {
|
|
35
35
|
"node": "^20.19.0 || ^22.12.0 || >=24.0.0",
|
|
36
36
|
"npm": "^6.11.0 || ^7.5.6 || >=8.0.0",
|
package/service-worker/index.js
CHANGED
|
@@ -47,7 +47,7 @@ const ts = __importStar(require("../third_party/github.com/Microsoft/TypeScript/
|
|
|
47
47
|
const utility_1 = require("../utility");
|
|
48
48
|
const ast_utils_1 = require("../utility/ast-utils");
|
|
49
49
|
const change_1 = require("../utility/change");
|
|
50
|
-
const
|
|
50
|
+
const dependency_1 = require("../utility/dependency");
|
|
51
51
|
const ng_ast_utils_1 = require("../utility/ng-ast-utils");
|
|
52
52
|
const paths_1 = require("../utility/paths");
|
|
53
53
|
const project_targets_1 = require("../utility/project-targets");
|
|
@@ -56,7 +56,7 @@ const util_1 = require("../utility/standalone/util");
|
|
|
56
56
|
const workspace_models_1 = require("../utility/workspace-models");
|
|
57
57
|
function addDependencies() {
|
|
58
58
|
return (host) => {
|
|
59
|
-
const coreDep = (0,
|
|
59
|
+
const coreDep = (0, dependency_1.getDependency)(host, '@angular/core');
|
|
60
60
|
if (!coreDep) {
|
|
61
61
|
throw new schematics_1.SchematicsException('Could not find "@angular/core" version.');
|
|
62
62
|
}
|
|
@@ -2285,7 +2285,7 @@ module.exports = __toCommonJS(typescript_exports);
|
|
|
2285
2285
|
|
|
2286
2286
|
// src/compiler/corePublic.ts
|
|
2287
2287
|
var versionMajorMinor = "5.9";
|
|
2288
|
-
var version = "5.9.
|
|
2288
|
+
var version = "5.9.2";
|
|
2289
2289
|
var Comparison = /* @__PURE__ */ ((Comparison3) => {
|
|
2290
2290
|
Comparison3[Comparison3["LessThan"] = -1] = "LessThan";
|
|
2291
2291
|
Comparison3[Comparison3["EqualTo"] = 0] = "EqualTo";
|
package/utility/dependency.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Use of this source code is governed by an MIT-style license that can be
|
|
6
6
|
* found in the LICENSE file at https://angular.dev/license
|
|
7
7
|
*/
|
|
8
|
-
import { Rule } from '@angular-devkit/schematics';
|
|
8
|
+
import { Rule, Tree } from '@angular-devkit/schematics';
|
|
9
9
|
/**
|
|
10
10
|
* An enum used to specify the type of a dependency found within a package manifest
|
|
11
11
|
* file (`package.json`).
|
|
@@ -55,6 +55,32 @@ export declare enum ExistingBehavior {
|
|
|
55
55
|
*/
|
|
56
56
|
Replace = 1
|
|
57
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Represents a dependency found in a package manifest.
|
|
60
|
+
*/
|
|
61
|
+
export interface Dependency {
|
|
62
|
+
/**
|
|
63
|
+
* The type of the dependency.
|
|
64
|
+
*/
|
|
65
|
+
type: DependencyType;
|
|
66
|
+
/**
|
|
67
|
+
* The name of the package.
|
|
68
|
+
*/
|
|
69
|
+
name: string;
|
|
70
|
+
/**
|
|
71
|
+
* The version specifier of the package.
|
|
72
|
+
*/
|
|
73
|
+
version: string;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Gets information about a dependency from a `package.json` file.
|
|
77
|
+
*
|
|
78
|
+
* @param tree The schematic's virtual file system representation.
|
|
79
|
+
* @param name The name of the package to check.
|
|
80
|
+
* @param packageJsonPath The path to the `package.json` file. Defaults to `/package.json`.
|
|
81
|
+
* @returns An object containing the dependency's type and version, or null if not found.
|
|
82
|
+
*/
|
|
83
|
+
export declare function getDependency(tree: Tree, name: string, packageJsonPath?: string): Dependency | null;
|
|
58
84
|
/**
|
|
59
85
|
* Adds a package as a dependency to a `package.json`. By default the `package.json` located
|
|
60
86
|
* at the schematic's root will be used. The `manifestPath` option can be used to explicitly specify
|
|
@@ -94,3 +120,23 @@ export declare function addDependency(name: string, specifier: string, options?:
|
|
|
94
120
|
*/
|
|
95
121
|
existing?: ExistingBehavior;
|
|
96
122
|
}): Rule;
|
|
123
|
+
/**
|
|
124
|
+
* Removes a package from the package.json in the project root.
|
|
125
|
+
*
|
|
126
|
+
* @param name The name of the package to remove.
|
|
127
|
+
* @param options An optional object that can contain a path of a manifest file to modify.
|
|
128
|
+
* @returns A Schematics {@link Rule}
|
|
129
|
+
*/
|
|
130
|
+
export declare function removeDependency(name: string, options?: {
|
|
131
|
+
/**
|
|
132
|
+
* The path of the package manifest file (`package.json`) that will be modified.
|
|
133
|
+
* Defaults to `/package.json`.
|
|
134
|
+
*/
|
|
135
|
+
packageJsonPath?: string;
|
|
136
|
+
/**
|
|
137
|
+
* The dependency installation behavior to use to determine whether a
|
|
138
|
+
* {@link NodePackageInstallTask} should be scheduled after removing the dependency.
|
|
139
|
+
* Defaults to {@link InstallBehavior.Auto}.
|
|
140
|
+
*/
|
|
141
|
+
install?: InstallBehavior;
|
|
142
|
+
}): Rule;
|
package/utility/dependency.js
CHANGED
|
@@ -41,7 +41,9 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
41
41
|
})();
|
|
42
42
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
43
|
exports.ExistingBehavior = exports.InstallBehavior = exports.DependencyType = void 0;
|
|
44
|
+
exports.getDependency = getDependency;
|
|
44
45
|
exports.addDependency = addDependency;
|
|
46
|
+
exports.removeDependency = removeDependency;
|
|
45
47
|
const tasks_1 = require("@angular-devkit/schematics/tasks");
|
|
46
48
|
const path = __importStar(require("node:path"));
|
|
47
49
|
const installTasks = new WeakMap();
|
|
@@ -97,6 +99,28 @@ var ExistingBehavior;
|
|
|
97
99
|
*/
|
|
98
100
|
ExistingBehavior[ExistingBehavior["Replace"] = 1] = "Replace";
|
|
99
101
|
})(ExistingBehavior || (exports.ExistingBehavior = ExistingBehavior = {}));
|
|
102
|
+
/**
|
|
103
|
+
* Gets information about a dependency from a `package.json` file.
|
|
104
|
+
*
|
|
105
|
+
* @param tree The schematic's virtual file system representation.
|
|
106
|
+
* @param name The name of the package to check.
|
|
107
|
+
* @param packageJsonPath The path to the `package.json` file. Defaults to `/package.json`.
|
|
108
|
+
* @returns An object containing the dependency's type and version, or null if not found.
|
|
109
|
+
*/
|
|
110
|
+
function getDependency(tree, name, packageJsonPath = '/package.json') {
|
|
111
|
+
const manifest = tree.readJson(packageJsonPath);
|
|
112
|
+
for (const type of [DependencyType.Default, DependencyType.Dev, DependencyType.Peer]) {
|
|
113
|
+
const section = manifest[type];
|
|
114
|
+
if (section?.[name]) {
|
|
115
|
+
return {
|
|
116
|
+
type,
|
|
117
|
+
name,
|
|
118
|
+
version: section[name],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
100
124
|
/**
|
|
101
125
|
* Adds a package as a dependency to a `package.json`. By default the `package.json` located
|
|
102
126
|
* at the schematic's root will be used. The `manifestPath` option can be used to explicitly specify
|
|
@@ -153,3 +177,34 @@ function addDependency(name, specifier, options = {}) {
|
|
|
153
177
|
}
|
|
154
178
|
};
|
|
155
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Removes a package from the package.json in the project root.
|
|
182
|
+
*
|
|
183
|
+
* @param name The name of the package to remove.
|
|
184
|
+
* @param options An optional object that can contain a path of a manifest file to modify.
|
|
185
|
+
* @returns A Schematics {@link Rule}
|
|
186
|
+
*/
|
|
187
|
+
function removeDependency(name, options = {}) {
|
|
188
|
+
const { packageJsonPath = '/package.json', install = InstallBehavior.Auto } = options;
|
|
189
|
+
return (tree, context) => {
|
|
190
|
+
const manifest = tree.readJson(packageJsonPath);
|
|
191
|
+
let wasRemoved = false;
|
|
192
|
+
for (const type of [DependencyType.Default, DependencyType.Dev, DependencyType.Peer]) {
|
|
193
|
+
const dependencySection = manifest[type];
|
|
194
|
+
if (dependencySection?.[name]) {
|
|
195
|
+
delete dependencySection[name];
|
|
196
|
+
wasRemoved = true;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
if (wasRemoved) {
|
|
200
|
+
tree.overwrite(packageJsonPath, JSON.stringify(manifest, null, 2));
|
|
201
|
+
const installPaths = installTasks.get(context) ?? new Set();
|
|
202
|
+
if (install === InstallBehavior.Always ||
|
|
203
|
+
(install === InstallBehavior.Auto && !installPaths.has(packageJsonPath))) {
|
|
204
|
+
context.addTask(new tasks_1.NodePackageInstallTask({ workingDirectory: path.dirname(packageJsonPath) }));
|
|
205
|
+
installPaths.add(packageJsonPath);
|
|
206
|
+
installTasks.set(context, installPaths);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
}
|
|
@@ -16,7 +16,7 @@ exports.latestVersions = {
|
|
|
16
16
|
// As Angular CLI works with same minor versions of Angular Framework, a tilde match for the current
|
|
17
17
|
Angular: '^20.2.0-next.0',
|
|
18
18
|
NgPackagr: '^20.2.0-next.0',
|
|
19
|
-
DevkitBuildAngular: '^20.2.0-
|
|
20
|
-
AngularBuild: '^20.2.0-
|
|
21
|
-
AngularSSR: '^20.2.0-
|
|
19
|
+
DevkitBuildAngular: '^20.2.0-rc.0',
|
|
20
|
+
AngularBuild: '^20.2.0-rc.0',
|
|
21
|
+
AngularSSR: '^20.2.0-rc.0',
|
|
22
22
|
};
|