@angular/core 19.0.0-next.5 → 19.0.0-next.7
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/fesm2022/core.mjs +434 -136
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +1 -1
- package/fesm2022/primitives/event-dispatch.mjs.map +1 -1
- package/fesm2022/primitives/signals.mjs +1 -1
- package/fesm2022/primitives/signals.mjs.map +1 -1
- package/fesm2022/rxjs-interop.mjs +25 -4
- package/fesm2022/rxjs-interop.mjs.map +1 -1
- package/fesm2022/testing.mjs +12 -11
- package/fesm2022/testing.mjs.map +1 -1
- package/index.d.ts +199 -94
- package/package.json +1 -1
- package/primitives/event-dispatch/index.d.ts +1 -1
- package/primitives/signals/index.d.ts +1 -1
- package/rxjs-interop/index.d.ts +3 -1
- package/schematics/bundles/{compiler_host-ca7ba733.js → checker-637eee78.js} +322 -426
- package/schematics/bundles/compiler_host-1e62b899.js +320 -0
- package/schematics/bundles/control-flow-migration.js +18 -17
- package/schematics/bundles/explicit-standalone-flag.js +25 -18
- package/schematics/bundles/{imports-4ac08251.js → imports-44987700.js} +1 -1
- package/schematics/bundles/inject-migration.js +10 -29
- package/schematics/bundles/leading_space-6e7a8ec6.js +30 -0
- package/schematics/bundles/{nodes-0e7d45ca.js → nodes-b12e919a.js} +2 -2
- package/schematics/bundles/pending-tasks.js +103 -0
- package/schematics/bundles/program-893e3fe7.js +20819 -0
- package/schematics/bundles/{project_tsconfig_paths-e9ccccbf.js → project_tsconfig_paths-6c9cde78.js} +1 -1
- package/schematics/bundles/route-lazy-loading.js +4 -3
- package/schematics/bundles/signal-input-migration.js +32976 -0
- package/schematics/bundles/standalone-migration.js +47 -20481
- package/schematics/collection.json +6 -0
- package/schematics/migrations.json +5 -0
- package/schematics/ng-generate/signal-input-migration/schema.json +30 -0
- package/testing/index.d.ts +3 -1
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* @license Angular v19.0.0-next.7
|
|
4
|
+
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
|
+
* License: MIT
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
var ts = require('typescript');
|
|
10
|
+
var checker = require('./checker-637eee78.js');
|
|
11
|
+
require('os');
|
|
12
|
+
var p = require('path');
|
|
13
|
+
|
|
14
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
15
|
+
|
|
16
|
+
function _interopNamespace(e) {
|
|
17
|
+
if (e && e.__esModule) return e;
|
|
18
|
+
var n = Object.create(null);
|
|
19
|
+
if (e) {
|
|
20
|
+
Object.keys(e).forEach(function (k) {
|
|
21
|
+
if (k !== 'default') {
|
|
22
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
23
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: function () { return e[k]; }
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
n["default"] = e;
|
|
31
|
+
return Object.freeze(n);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
|
|
35
|
+
var p__namespace = /*#__PURE__*/_interopNamespace(p);
|
|
36
|
+
|
|
37
|
+
/** Tracks changes that have to be made for specific files. */
|
|
38
|
+
class ChangeTracker {
|
|
39
|
+
_printer;
|
|
40
|
+
_importRemapper;
|
|
41
|
+
_changes = new Map();
|
|
42
|
+
_importManager;
|
|
43
|
+
_quotesCache = new WeakMap();
|
|
44
|
+
constructor(_printer, _importRemapper) {
|
|
45
|
+
this._printer = _printer;
|
|
46
|
+
this._importRemapper = _importRemapper;
|
|
47
|
+
this._importManager = new checker.ImportManager({
|
|
48
|
+
shouldUseSingleQuotes: (file) => this._getQuoteKind(file) === 0 /* QuoteKind.SINGLE */,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Tracks the insertion of some text.
|
|
53
|
+
* @param sourceFile File in which the text is being inserted.
|
|
54
|
+
* @param start Index at which the text is insert.
|
|
55
|
+
* @param text Text to be inserted.
|
|
56
|
+
*/
|
|
57
|
+
insertText(sourceFile, index, text) {
|
|
58
|
+
this._trackChange(sourceFile, { start: index, text });
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Replaces text within a file.
|
|
62
|
+
* @param sourceFile File in which to replace the text.
|
|
63
|
+
* @param start Index from which to replace the text.
|
|
64
|
+
* @param removeLength Length of the text being replaced.
|
|
65
|
+
* @param text Text to be inserted instead of the old one.
|
|
66
|
+
*/
|
|
67
|
+
replaceText(sourceFile, start, removeLength, text) {
|
|
68
|
+
this._trackChange(sourceFile, { start, removeLength, text });
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Replaces the text of an AST node with a new one.
|
|
72
|
+
* @param oldNode Node to be replaced.
|
|
73
|
+
* @param newNode New node to be inserted.
|
|
74
|
+
* @param emitHint Hint when formatting the text of the new node.
|
|
75
|
+
* @param sourceFileWhenPrinting File to use when printing out the new node. This is important
|
|
76
|
+
* when copying nodes from one file to another, because TypeScript might not output literal nodes
|
|
77
|
+
* without it.
|
|
78
|
+
*/
|
|
79
|
+
replaceNode(oldNode, newNode, emitHint = ts__default["default"].EmitHint.Unspecified, sourceFileWhenPrinting) {
|
|
80
|
+
const sourceFile = oldNode.getSourceFile();
|
|
81
|
+
this.replaceText(sourceFile, oldNode.getStart(), oldNode.getWidth(), this._printer.printNode(emitHint, newNode, sourceFileWhenPrinting || sourceFile));
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Removes the text of an AST node from a file.
|
|
85
|
+
* @param node Node whose text should be removed.
|
|
86
|
+
*/
|
|
87
|
+
removeNode(node) {
|
|
88
|
+
this._trackChange(node.getSourceFile(), {
|
|
89
|
+
start: node.getStart(),
|
|
90
|
+
removeLength: node.getWidth(),
|
|
91
|
+
text: '',
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Adds an import to a file.
|
|
96
|
+
* @param sourceFile File to which to add the import.
|
|
97
|
+
* @param symbolName Symbol being imported.
|
|
98
|
+
* @param moduleName Module from which the symbol is imported.
|
|
99
|
+
* @param alias Alias to use for the import.
|
|
100
|
+
*/
|
|
101
|
+
addImport(sourceFile, symbolName, moduleName, alias) {
|
|
102
|
+
if (this._importRemapper) {
|
|
103
|
+
moduleName = this._importRemapper(moduleName, sourceFile.fileName);
|
|
104
|
+
}
|
|
105
|
+
// It's common for paths to be manipulated with Node's `path` utilties which
|
|
106
|
+
// can yield a path with back slashes. Normalize them since outputting such
|
|
107
|
+
// paths will also cause TS to escape the forward slashes.
|
|
108
|
+
moduleName = normalizePath(moduleName);
|
|
109
|
+
if (!this._changes.has(sourceFile)) {
|
|
110
|
+
this._changes.set(sourceFile, []);
|
|
111
|
+
}
|
|
112
|
+
return this._importManager.addImport({
|
|
113
|
+
requestedFile: sourceFile,
|
|
114
|
+
exportSymbolName: symbolName,
|
|
115
|
+
exportModuleSpecifier: moduleName,
|
|
116
|
+
unsafeAliasOverride: alias,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Removes an import from a file.
|
|
121
|
+
* @param sourceFile File from which to remove the import.
|
|
122
|
+
* @param symbolName Original name of the symbol to be removed. Used even if the import is aliased.
|
|
123
|
+
* @param moduleName Module from which the symbol is imported.
|
|
124
|
+
*/
|
|
125
|
+
removeImport(sourceFile, symbolName, moduleName) {
|
|
126
|
+
// It's common for paths to be manipulated with Node's `path` utilties which
|
|
127
|
+
// can yield a path with back slashes. Normalize them since outputting such
|
|
128
|
+
// paths will also cause TS to escape the forward slashes.
|
|
129
|
+
moduleName = normalizePath(moduleName);
|
|
130
|
+
if (!this._changes.has(sourceFile)) {
|
|
131
|
+
this._changes.set(sourceFile, []);
|
|
132
|
+
}
|
|
133
|
+
this._importManager.removeImport(sourceFile, symbolName, moduleName);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Gets the changes that should be applied to all the files in the migration.
|
|
137
|
+
* The changes are sorted in the order in which they should be applied.
|
|
138
|
+
*/
|
|
139
|
+
recordChanges() {
|
|
140
|
+
this._recordImports();
|
|
141
|
+
return this._changes;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Clear the tracked changes
|
|
145
|
+
*/
|
|
146
|
+
clearChanges() {
|
|
147
|
+
this._changes.clear();
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Adds a change to a `ChangesByFile` map.
|
|
151
|
+
* @param file File that the change is associated with.
|
|
152
|
+
* @param change Change to be added.
|
|
153
|
+
*/
|
|
154
|
+
_trackChange(file, change) {
|
|
155
|
+
const changes = this._changes.get(file);
|
|
156
|
+
if (changes) {
|
|
157
|
+
// Insert the changes in reverse so that they're applied in reverse order.
|
|
158
|
+
// This ensures that the offsets of subsequent changes aren't affected by
|
|
159
|
+
// previous changes changing the file's text.
|
|
160
|
+
const insertIndex = changes.findIndex((current) => current.start <= change.start);
|
|
161
|
+
if (insertIndex === -1) {
|
|
162
|
+
changes.push(change);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
changes.splice(insertIndex, 0, change);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
this._changes.set(file, [change]);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/** Determines what kind of quotes to use for a specific file. */
|
|
173
|
+
_getQuoteKind(sourceFile) {
|
|
174
|
+
if (this._quotesCache.has(sourceFile)) {
|
|
175
|
+
return this._quotesCache.get(sourceFile);
|
|
176
|
+
}
|
|
177
|
+
let kind = 0 /* QuoteKind.SINGLE */;
|
|
178
|
+
for (const statement of sourceFile.statements) {
|
|
179
|
+
if (ts__default["default"].isImportDeclaration(statement) && ts__default["default"].isStringLiteral(statement.moduleSpecifier)) {
|
|
180
|
+
kind = statement.moduleSpecifier.getText()[0] === '"' ? 1 /* QuoteKind.DOUBLE */ : 0 /* QuoteKind.SINGLE */;
|
|
181
|
+
this._quotesCache.set(sourceFile, kind);
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return kind;
|
|
186
|
+
}
|
|
187
|
+
/** Records the pending import changes from the import manager. */
|
|
188
|
+
_recordImports() {
|
|
189
|
+
const { newImports, updatedImports, deletedImports } = this._importManager.finalize();
|
|
190
|
+
for (const [original, replacement] of updatedImports) {
|
|
191
|
+
this.replaceNode(original, replacement);
|
|
192
|
+
}
|
|
193
|
+
for (const node of deletedImports) {
|
|
194
|
+
this.removeNode(node);
|
|
195
|
+
}
|
|
196
|
+
for (const [sourceFile] of this._changes) {
|
|
197
|
+
const importsToAdd = newImports.get(sourceFile.fileName);
|
|
198
|
+
if (!importsToAdd) {
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
const importLines = [];
|
|
202
|
+
let lastImport = null;
|
|
203
|
+
for (const statement of sourceFile.statements) {
|
|
204
|
+
if (ts__default["default"].isImportDeclaration(statement)) {
|
|
205
|
+
lastImport = statement;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
for (const decl of importsToAdd) {
|
|
209
|
+
importLines.push(this._printer.printNode(ts__default["default"].EmitHint.Unspecified, decl, sourceFile));
|
|
210
|
+
}
|
|
211
|
+
this.insertText(sourceFile, lastImport ? lastImport.getEnd() : 0, (lastImport ? '\n' : '') + importLines.join('\n'));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/** Normalizes a path to use posix separators. */
|
|
216
|
+
function normalizePath(path) {
|
|
217
|
+
return path.replace(/\\/g, '/');
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
function parseTsconfigFile(tsconfigPath, basePath) {
|
|
221
|
+
const { config } = ts__default["default"].readConfigFile(tsconfigPath, ts__default["default"].sys.readFile);
|
|
222
|
+
const parseConfigHost = {
|
|
223
|
+
useCaseSensitiveFileNames: ts__default["default"].sys.useCaseSensitiveFileNames,
|
|
224
|
+
fileExists: ts__default["default"].sys.fileExists,
|
|
225
|
+
readDirectory: ts__default["default"].sys.readDirectory,
|
|
226
|
+
readFile: ts__default["default"].sys.readFile,
|
|
227
|
+
};
|
|
228
|
+
// Throw if incorrect arguments are passed to this function. Passing relative base paths
|
|
229
|
+
// results in root directories not being resolved and in later type checking runtime errors.
|
|
230
|
+
// More details can be found here: https://github.com/microsoft/TypeScript/issues/37731.
|
|
231
|
+
if (!p__namespace.isAbsolute(basePath)) {
|
|
232
|
+
throw Error('Unexpected relative base path has been specified.');
|
|
233
|
+
}
|
|
234
|
+
return ts__default["default"].parseJsonConfigFileContent(config, parseConfigHost, basePath, {});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Creates a TypeScript program instance for a TypeScript project within
|
|
239
|
+
* the virtual file system tree.
|
|
240
|
+
* @param tree Virtual file system tree that contains the source files.
|
|
241
|
+
* @param tsconfigPath Virtual file system path that resolves to the TypeScript project.
|
|
242
|
+
* @param basePath Base path for the virtual file system tree.
|
|
243
|
+
* @param fakeFileRead Optional file reader function. Can be used to overwrite files in
|
|
244
|
+
* the TypeScript program, or to add in-memory files (e.g. to add global types).
|
|
245
|
+
* @param additionalFiles Additional file paths that should be added to the program.
|
|
246
|
+
*/
|
|
247
|
+
function createMigrationProgram(tree, tsconfigPath, basePath, fakeFileRead, additionalFiles) {
|
|
248
|
+
const { rootNames, options, host } = createProgramOptions(tree, tsconfigPath, basePath, fakeFileRead, additionalFiles);
|
|
249
|
+
return ts__default["default"].createProgram(rootNames, options, host);
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Creates the options necessary to instantiate a TypeScript program.
|
|
253
|
+
* @param tree Virtual file system tree that contains the source files.
|
|
254
|
+
* @param tsconfigPath Virtual file system path that resolves to the TypeScript project.
|
|
255
|
+
* @param basePath Base path for the virtual file system tree.
|
|
256
|
+
* @param fakeFileRead Optional file reader function. Can be used to overwrite files in
|
|
257
|
+
* the TypeScript program, or to add in-memory files (e.g. to add global types).
|
|
258
|
+
* @param additionalFiles Additional file paths that should be added to the program.
|
|
259
|
+
* @param optionOverrides Overrides of the parsed compiler options.
|
|
260
|
+
*/
|
|
261
|
+
function createProgramOptions(tree, tsconfigPath, basePath, fakeFileRead, additionalFiles, optionOverrides) {
|
|
262
|
+
// Resolve the tsconfig path to an absolute path. This is needed as TypeScript otherwise
|
|
263
|
+
// is not able to resolve root directories in the given tsconfig. More details can be found
|
|
264
|
+
// in the following issue: https://github.com/microsoft/TypeScript/issues/37731.
|
|
265
|
+
tsconfigPath = p.resolve(basePath, tsconfigPath);
|
|
266
|
+
const parsed = parseTsconfigFile(tsconfigPath, p.dirname(tsconfigPath));
|
|
267
|
+
const options = optionOverrides ? { ...parsed.options, ...optionOverrides } : parsed.options;
|
|
268
|
+
const host = createMigrationCompilerHost(tree, options, basePath, fakeFileRead);
|
|
269
|
+
return { rootNames: parsed.fileNames.concat(additionalFiles || []), options, host };
|
|
270
|
+
}
|
|
271
|
+
function createMigrationCompilerHost(tree, options, basePath, fakeRead) {
|
|
272
|
+
const host = ts__default["default"].createCompilerHost(options, true);
|
|
273
|
+
const defaultReadFile = host.readFile;
|
|
274
|
+
// We need to overwrite the host "readFile" method, as we want the TypeScript
|
|
275
|
+
// program to be based on the file contents in the virtual file tree. Otherwise
|
|
276
|
+
// if we run multiple migrations we might have intersecting changes and
|
|
277
|
+
// source files.
|
|
278
|
+
host.readFile = (fileName) => {
|
|
279
|
+
const treeRelativePath = p.relative(basePath, fileName);
|
|
280
|
+
let result = fakeRead?.(treeRelativePath);
|
|
281
|
+
if (typeof result !== 'string') {
|
|
282
|
+
// If the relative path resolved to somewhere outside of the tree, fall back to
|
|
283
|
+
// TypeScript's default file reading function since the `tree` will throw an error.
|
|
284
|
+
result = treeRelativePath.startsWith('..')
|
|
285
|
+
? defaultReadFile.call(host, fileName)
|
|
286
|
+
: tree.read(treeRelativePath)?.toString();
|
|
287
|
+
}
|
|
288
|
+
// Strip BOM as otherwise TSC methods (Ex: getWidth) will return an offset,
|
|
289
|
+
// which breaks the CLI UpdateRecorder.
|
|
290
|
+
// See: https://github.com/angular/angular/pull/30719
|
|
291
|
+
return typeof result === 'string' ? result.replace(/^\uFEFF/, '') : undefined;
|
|
292
|
+
};
|
|
293
|
+
return host;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Checks whether a file can be migrate by our automated migrations.
|
|
297
|
+
* @param basePath Absolute path to the project.
|
|
298
|
+
* @param sourceFile File being checked.
|
|
299
|
+
* @param program Program that includes the source file.
|
|
300
|
+
*/
|
|
301
|
+
function canMigrateFile(basePath, sourceFile, program) {
|
|
302
|
+
// We shouldn't migrate .d.ts files, files from an external library or type checking files.
|
|
303
|
+
if (sourceFile.fileName.endsWith('.ngtypecheck.ts') ||
|
|
304
|
+
sourceFile.isDeclarationFile ||
|
|
305
|
+
program.isSourceFileFromExternalLibrary(sourceFile)) {
|
|
306
|
+
return false;
|
|
307
|
+
}
|
|
308
|
+
// Our migrations are set up to create a `Program` from the project's tsconfig and to migrate all
|
|
309
|
+
// the files within the program. This can include files that are outside of the Angular CLI
|
|
310
|
+
// project. We can't migrate files outside of the project, because our file system interactions
|
|
311
|
+
// go through the CLI's `Tree` which assumes that all files are within the project. See:
|
|
312
|
+
// https://github.com/angular/angular-cli/blob/0b0961c9c233a825b6e4bb59ab7f0790f9b14676/packages/angular_devkit/schematics/src/tree/host-tree.ts#L131
|
|
313
|
+
return !p.relative(basePath, sourceFile.fileName).startsWith('..');
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
exports.ChangeTracker = ChangeTracker;
|
|
317
|
+
exports.canMigrateFile = canMigrateFile;
|
|
318
|
+
exports.createMigrationProgram = createMigrationProgram;
|
|
319
|
+
exports.createProgramOptions = createProgramOptions;
|
|
320
|
+
exports.normalizePath = normalizePath;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v19.0.0-next.
|
|
3
|
+
* @license Angular v19.0.0-next.7
|
|
4
4
|
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -10,7 +10,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
10
10
|
|
|
11
11
|
var schematics = require('@angular-devkit/schematics');
|
|
12
12
|
var p = require('path');
|
|
13
|
-
var compiler_host = require('./compiler_host-
|
|
13
|
+
var compiler_host = require('./compiler_host-1e62b899.js');
|
|
14
|
+
var checker = require('./checker-637eee78.js');
|
|
14
15
|
var ts = require('typescript');
|
|
15
16
|
require('os');
|
|
16
17
|
require('fs');
|
|
@@ -278,7 +279,7 @@ class AnalyzedFile {
|
|
|
278
279
|
}
|
|
279
280
|
}
|
|
280
281
|
/** Finds all non-control flow elements from common module. */
|
|
281
|
-
class CommonCollector extends
|
|
282
|
+
class CommonCollector extends checker.RecursiveVisitor {
|
|
282
283
|
count = 0;
|
|
283
284
|
visitElement(el) {
|
|
284
285
|
if (el.attrs.length > 0) {
|
|
@@ -310,7 +311,7 @@ class CommonCollector extends compiler_host.RecursiveVisitor {
|
|
|
310
311
|
}
|
|
311
312
|
}
|
|
312
313
|
/** Finds all elements that represent i18n blocks. */
|
|
313
|
-
class i18nCollector extends
|
|
314
|
+
class i18nCollector extends checker.RecursiveVisitor {
|
|
314
315
|
elements = [];
|
|
315
316
|
visitElement(el) {
|
|
316
317
|
if (el.attrs.find((a) => a.name === 'i18n') !== undefined) {
|
|
@@ -320,7 +321,7 @@ class i18nCollector extends compiler_host.RecursiveVisitor {
|
|
|
320
321
|
}
|
|
321
322
|
}
|
|
322
323
|
/** Finds all elements with ngif structural directives. */
|
|
323
|
-
class ElementCollector extends
|
|
324
|
+
class ElementCollector extends checker.RecursiveVisitor {
|
|
324
325
|
_attributes;
|
|
325
326
|
elements = [];
|
|
326
327
|
constructor(_attributes = []) {
|
|
@@ -373,7 +374,7 @@ class ElementCollector extends compiler_host.RecursiveVisitor {
|
|
|
373
374
|
}
|
|
374
375
|
}
|
|
375
376
|
/** Finds all elements with ngif structural directives. */
|
|
376
|
-
class TemplateCollector extends
|
|
377
|
+
class TemplateCollector extends checker.RecursiveVisitor {
|
|
377
378
|
elements = [];
|
|
378
379
|
templates = new Map();
|
|
379
380
|
visitElement(el) {
|
|
@@ -587,7 +588,7 @@ function parseTemplate(template) {
|
|
|
587
588
|
// interpolated text as text nodes containing a mixture of interpolation tokens and text tokens,
|
|
588
589
|
// rather than turning them into `BoundText` nodes like the Ivy AST does. This allows us to
|
|
589
590
|
// easily get the text-only ranges without having to reconstruct the original text.
|
|
590
|
-
parsed = new
|
|
591
|
+
parsed = new checker.HtmlParser().parse(template, '', {
|
|
591
592
|
// Allows for ICUs to be parsed.
|
|
592
593
|
tokenizeExpansionForms: true,
|
|
593
594
|
// Explicitly disable blocks so that their characters are treated as plain text.
|
|
@@ -625,7 +626,7 @@ function validateMigratedTemplate(migrated, fileName) {
|
|
|
625
626
|
}
|
|
626
627
|
function validateI18nStructure(parsed, fileName) {
|
|
627
628
|
const visitor = new i18nCollector();
|
|
628
|
-
|
|
629
|
+
checker.visitAll(visitor, parsed.rootNodes);
|
|
629
630
|
const parents = visitor.elements.filter((el) => el.children.length > 0);
|
|
630
631
|
for (const p of parents) {
|
|
631
632
|
for (const el of visitor.elements) {
|
|
@@ -708,7 +709,7 @@ function getTemplates(template) {
|
|
|
708
709
|
const parsed = parseTemplate(template);
|
|
709
710
|
if (parsed.tree !== undefined) {
|
|
710
711
|
const visitor = new TemplateCollector();
|
|
711
|
-
|
|
712
|
+
checker.visitAll(visitor, parsed.tree.rootNodes);
|
|
712
713
|
// count usages of each ng-template
|
|
713
714
|
for (let [key, tmpl] of visitor.templates) {
|
|
714
715
|
const escapeKey = escapeRegExp(key.slice(1));
|
|
@@ -811,7 +812,7 @@ function canRemoveCommonModule(template) {
|
|
|
811
812
|
let removeCommonModule = false;
|
|
812
813
|
if (parsed.tree !== undefined) {
|
|
813
814
|
const visitor = new CommonCollector();
|
|
814
|
-
|
|
815
|
+
checker.visitAll(visitor, parsed.tree.rootNodes);
|
|
815
816
|
removeCommonModule = visitor.count === 0;
|
|
816
817
|
}
|
|
817
818
|
return removeCommonModule;
|
|
@@ -934,7 +935,7 @@ function generateI18nMarkers(tmpl) {
|
|
|
934
935
|
let parsed = parseTemplate(tmpl);
|
|
935
936
|
if (parsed.tree !== undefined) {
|
|
936
937
|
const visitor = new i18nCollector();
|
|
937
|
-
|
|
938
|
+
checker.visitAll(visitor, parsed.tree.rootNodes);
|
|
938
939
|
for (const [ix, el] of visitor.elements.entries()) {
|
|
939
940
|
// we only care about elements with children and i18n tags
|
|
940
941
|
// elements without children have nothing to translate
|
|
@@ -1136,7 +1137,7 @@ function migrateCase(template) {
|
|
|
1136
1137
|
}
|
|
1137
1138
|
let result = template;
|
|
1138
1139
|
const visitor = new ElementCollector(cases);
|
|
1139
|
-
|
|
1140
|
+
checker.visitAll(visitor, parsed.tree.rootNodes);
|
|
1140
1141
|
calculateNesting(visitor, hasLineBreaks(template));
|
|
1141
1142
|
// this tracks the character shift from different lengths of blocks from
|
|
1142
1143
|
// the prior directives so as to adjust for nested block replacement during
|
|
@@ -1233,7 +1234,7 @@ function migrateFor(template) {
|
|
|
1233
1234
|
}
|
|
1234
1235
|
let result = template;
|
|
1235
1236
|
const visitor = new ElementCollector(fors);
|
|
1236
|
-
|
|
1237
|
+
checker.visitAll(visitor, parsed.tree.rootNodes);
|
|
1237
1238
|
calculateNesting(visitor, hasLineBreaks(template));
|
|
1238
1239
|
// this tracks the character shift from different lengths of blocks from
|
|
1239
1240
|
// the prior directives so as to adjust for nested block replacement during
|
|
@@ -1438,7 +1439,7 @@ function migrateIf(template) {
|
|
|
1438
1439
|
}
|
|
1439
1440
|
let result = template;
|
|
1440
1441
|
const visitor = new ElementCollector(ifs);
|
|
1441
|
-
|
|
1442
|
+
checker.visitAll(visitor, parsed.tree.rootNodes);
|
|
1442
1443
|
calculateNesting(visitor, hasLineBreaks(template));
|
|
1443
1444
|
// this tracks the character shift from different lengths of blocks from
|
|
1444
1445
|
// the prior directives so as to adjust for nested block replacement during
|
|
@@ -1631,7 +1632,7 @@ function migrateSwitch(template) {
|
|
|
1631
1632
|
}
|
|
1632
1633
|
let result = template;
|
|
1633
1634
|
const visitor = new ElementCollector(switches);
|
|
1634
|
-
|
|
1635
|
+
checker.visitAll(visitor, parsed.tree.rootNodes);
|
|
1635
1636
|
calculateNesting(visitor, hasLineBreaks(template));
|
|
1636
1637
|
// this tracks the character shift from different lengths of blocks from
|
|
1637
1638
|
// the prior directives so as to adjust for nested block replacement during
|
|
@@ -1662,11 +1663,11 @@ function migrateSwitch(template) {
|
|
|
1662
1663
|
}
|
|
1663
1664
|
function assertValidSwitchStructure(children) {
|
|
1664
1665
|
for (const child of children) {
|
|
1665
|
-
if (child instanceof
|
|
1666
|
+
if (child instanceof checker.Text && child.value.trim() !== '') {
|
|
1666
1667
|
throw new Error(`Text node: "${child.value}" would result in invalid migrated @switch block structure. ` +
|
|
1667
1668
|
`@switch can only have @case or @default as children.`);
|
|
1668
1669
|
}
|
|
1669
|
-
else if (child instanceof
|
|
1670
|
+
else if (child instanceof checker.Element) {
|
|
1670
1671
|
let hasCase = false;
|
|
1671
1672
|
for (const attr of child.attrs) {
|
|
1672
1673
|
if (cases.includes(attr.name)) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v19.0.0-next.
|
|
3
|
+
* @license Angular v19.0.0-next.7
|
|
4
4
|
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -10,11 +10,12 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
10
10
|
|
|
11
11
|
var schematics = require('@angular-devkit/schematics');
|
|
12
12
|
var p = require('path');
|
|
13
|
-
var project_tsconfig_paths = require('./project_tsconfig_paths-
|
|
14
|
-
var compiler_host = require('./compiler_host-
|
|
13
|
+
var project_tsconfig_paths = require('./project_tsconfig_paths-6c9cde78.js');
|
|
14
|
+
var compiler_host = require('./compiler_host-1e62b899.js');
|
|
15
15
|
var ts = require('typescript');
|
|
16
|
-
var imports = require('./imports-
|
|
16
|
+
var imports = require('./imports-44987700.js');
|
|
17
17
|
require('@angular-devkit/core');
|
|
18
|
+
require('./checker-637eee78.js');
|
|
18
19
|
require('os');
|
|
19
20
|
require('fs');
|
|
20
21
|
require('module');
|
|
@@ -70,11 +71,11 @@ function migrateFile(sourceFile, rewriteFn) {
|
|
|
70
71
|
// It's not a decorator to migrate
|
|
71
72
|
return;
|
|
72
73
|
}
|
|
73
|
-
const [
|
|
74
|
-
if (!
|
|
74
|
+
const [decoratorArgument] = callExpression.arguments;
|
|
75
|
+
if (!decoratorArgument || !ts__default["default"].isObjectLiteralExpression(decoratorArgument)) {
|
|
75
76
|
return;
|
|
76
77
|
}
|
|
77
|
-
const properties =
|
|
78
|
+
const properties = decoratorArgument.properties;
|
|
78
79
|
const standaloneProp = getStandaloneProperty(properties);
|
|
79
80
|
// Need to take care of 3 cases
|
|
80
81
|
// - standalone: true => remove the property
|
|
@@ -85,15 +86,13 @@ function migrateFile(sourceFile, rewriteFn) {
|
|
|
85
86
|
const standaloneFalseProperty = ts__default["default"].factory.createPropertyAssignment('standalone', ts__default["default"].factory.createFalse());
|
|
86
87
|
newProperties = [...properties, standaloneFalseProperty];
|
|
87
88
|
}
|
|
88
|
-
else if (standaloneProp.value === ts__default["default"].SyntaxKind.TrueKeyword)
|
|
89
|
-
newProperties = properties.filter((p) => p !== standaloneProp.property);
|
|
90
|
-
}
|
|
89
|
+
else if (standaloneProp.value === ts__default["default"].SyntaxKind.TrueKeyword) ;
|
|
91
90
|
if (newProperties) {
|
|
92
91
|
// At this point we know that we need to add standalone: false or
|
|
93
92
|
// remove an existing standalone: true property.
|
|
94
93
|
const newPropsArr = ts__default["default"].factory.createNodeArray(newProperties);
|
|
95
94
|
const newFirstArg = ts__default["default"].factory.createObjectLiteralExpression(newPropsArr, true);
|
|
96
|
-
changeTracker.replaceNode(
|
|
95
|
+
changeTracker.replaceNode(decoratorArgument, newFirstArg);
|
|
97
96
|
}
|
|
98
97
|
});
|
|
99
98
|
});
|
|
@@ -106,16 +105,24 @@ function migrateFile(sourceFile, rewriteFn) {
|
|
|
106
105
|
}
|
|
107
106
|
function getStandaloneProperty(properties) {
|
|
108
107
|
for (const prop of properties) {
|
|
109
|
-
if (ts__default["default"].
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
108
|
+
if (ts__default["default"].isShorthandPropertyAssignment(prop) && prop.name.text) {
|
|
109
|
+
return { property: prop, value: prop.objectAssignmentInitializer };
|
|
110
|
+
}
|
|
111
|
+
if (isStandaloneProperty(prop)) {
|
|
112
|
+
if (prop.initializer.kind === ts__default["default"].SyntaxKind.TrueKeyword ||
|
|
113
|
+
prop.initializer.kind === ts__default["default"].SyntaxKind.FalseKeyword) {
|
|
114
|
+
return { property: prop, value: prop.initializer.kind };
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
return { property: prop, value: prop.initializer };
|
|
118
|
+
}
|
|
115
119
|
}
|
|
116
120
|
}
|
|
117
121
|
return undefined;
|
|
118
122
|
}
|
|
123
|
+
function isStandaloneProperty(prop) {
|
|
124
|
+
return (ts__default["default"].isPropertyAssignment(prop) && ts__default["default"].isIdentifier(prop.name) && prop.name.text === 'standalone');
|
|
125
|
+
}
|
|
119
126
|
|
|
120
127
|
function migrate() {
|
|
121
128
|
return async (tree) => {
|
|
@@ -123,7 +130,7 @@ function migrate() {
|
|
|
123
130
|
const basePath = process.cwd();
|
|
124
131
|
const allPaths = [...buildPaths, ...testPaths];
|
|
125
132
|
if (!allPaths.length) {
|
|
126
|
-
throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot run the standalone
|
|
133
|
+
throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot run the explicit-standalone-flag migration.');
|
|
127
134
|
}
|
|
128
135
|
for (const tsconfigPath of allPaths) {
|
|
129
136
|
runMigration(tree, tsconfigPath, basePath);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
/**
|
|
3
|
-
* @license Angular v19.0.0-next.
|
|
3
|
+
* @license Angular v19.0.0-next.7
|
|
4
4
|
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
5
|
* License: MIT
|
|
6
6
|
*/
|
|
@@ -10,10 +10,12 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
10
10
|
|
|
11
11
|
var schematics = require('@angular-devkit/schematics');
|
|
12
12
|
var p = require('path');
|
|
13
|
-
var compiler_host = require('./compiler_host-
|
|
13
|
+
var compiler_host = require('./compiler_host-1e62b899.js');
|
|
14
14
|
var ts = require('typescript');
|
|
15
|
-
var nodes = require('./nodes-
|
|
16
|
-
var imports = require('./imports-
|
|
15
|
+
var nodes = require('./nodes-b12e919a.js');
|
|
16
|
+
var imports = require('./imports-44987700.js');
|
|
17
|
+
var leading_space = require('./leading_space-6e7a8ec6.js');
|
|
18
|
+
require('./checker-637eee78.js');
|
|
17
19
|
require('os');
|
|
18
20
|
require('fs');
|
|
19
21
|
require('module');
|
|
@@ -28,7 +30,7 @@ var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
|
|
|
28
30
|
* Copyright Google LLC All Rights Reserved.
|
|
29
31
|
*
|
|
30
32
|
* Use of this source code is governed by an MIT-style license that can be
|
|
31
|
-
* found in the LICENSE file at https://angular.
|
|
33
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
32
34
|
*/
|
|
33
35
|
/** Names of decorators that enable DI on a class declaration. */
|
|
34
36
|
const DECORATORS_SUPPORTING_DI = new Set([
|
|
@@ -205,27 +207,6 @@ function getSuperParameters(declaration, superCall, localTypeChecker) {
|
|
|
205
207
|
});
|
|
206
208
|
return usedParams;
|
|
207
209
|
}
|
|
208
|
-
/**
|
|
209
|
-
* Gets the indentation text of a node. Can be used to
|
|
210
|
-
* output text with the same level of indentation.
|
|
211
|
-
* @param node Node for which to get the indentation level.
|
|
212
|
-
*/
|
|
213
|
-
function getNodeIndentation(node) {
|
|
214
|
-
const fullText = node.getFullText();
|
|
215
|
-
const end = fullText.indexOf(node.getText());
|
|
216
|
-
let result = '';
|
|
217
|
-
for (let i = end - 1; i > -1; i--) {
|
|
218
|
-
// Note: LF line endings are `\n` while CRLF are `\r\n`. This logic should cover both, because
|
|
219
|
-
// we start from the beginning of the node and go backwards so will always hit `\n` first.
|
|
220
|
-
if (fullText[i] !== '\n') {
|
|
221
|
-
result = fullText[i] + result;
|
|
222
|
-
}
|
|
223
|
-
else {
|
|
224
|
-
break;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
return result;
|
|
228
|
-
}
|
|
229
210
|
/** Checks whether a parameter node declares a property on its class. */
|
|
230
211
|
function parameterDeclaresProperty(node) {
|
|
231
212
|
return !!node.modifiers?.some(({ kind }) => kind === ts__default["default"].SyntaxKind.PublicKeyword ||
|
|
@@ -283,7 +264,7 @@ function findSuperCall(root) {
|
|
|
283
264
|
* Copyright Google LLC All Rights Reserved.
|
|
284
265
|
*
|
|
285
266
|
* Use of this source code is governed by an MIT-style license that can be
|
|
286
|
-
* found in the LICENSE file at https://angular.
|
|
267
|
+
* found in the LICENSE file at https://angular.dev/license
|
|
287
268
|
*/
|
|
288
269
|
/**
|
|
289
270
|
* Finds class property declarations without initializers whose constructor-based initialization
|
|
@@ -510,12 +491,12 @@ function migrateClass(node, constructor, superCall, options, removedStatements,
|
|
|
510
491
|
const superParameters = superCall
|
|
511
492
|
? getSuperParameters(constructor, superCall, localTypeChecker)
|
|
512
493
|
: null;
|
|
513
|
-
const memberIndentation =
|
|
494
|
+
const memberIndentation = leading_space.getLeadingLineWhitespaceOfNode(node.members[0]);
|
|
514
495
|
const removedStatementCount = removedStatements?.size || 0;
|
|
515
496
|
const innerReference = superCall ||
|
|
516
497
|
constructor.body?.statements.find((statement) => !removedStatements?.has(statement)) ||
|
|
517
498
|
constructor;
|
|
518
|
-
const innerIndentation =
|
|
499
|
+
const innerIndentation = leading_space.getLeadingLineWhitespaceOfNode(innerReference);
|
|
519
500
|
const propsToAdd = [];
|
|
520
501
|
const prependToConstructor = [];
|
|
521
502
|
const afterSuper = [];
|