@angular/core 19.0.0-next.2 → 19.0.0-next.4
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 +193 -20
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives/event-dispatch.mjs +1 -1
- package/fesm2022/primitives/signals.mjs +1 -1
- package/fesm2022/rxjs-interop.mjs +1 -1
- package/fesm2022/testing.mjs +4 -4
- package/index.d.ts +113 -4
- 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 +1 -1
- package/schematics/bundles/compiler_host-ca7ba733.js +44719 -0
- package/schematics/bundles/control-flow-migration.js +1847 -0
- package/schematics/bundles/explicit-standalone-flag.js +157 -0
- package/schematics/bundles/imports-4ac08251.js +110 -0
- package/schematics/bundles/inject-migration.js +927 -0
- package/schematics/bundles/nodes-0e7d45ca.js +56 -0
- package/schematics/bundles/project_tsconfig_paths-e9ccccbf.js +90 -0
- package/schematics/bundles/route-lazy-loading.js +411 -0
- package/schematics/bundles/standalone-migration.js +22441 -0
- package/schematics/collection.json +7 -14
- package/schematics/migrations.json +4 -14
- package/testing/index.d.ts +1 -1
- package/schematics/migrations/after-render-phase/bundle.js +0 -27333
- package/schematics/migrations/http-providers/bundle.js +0 -27582
- package/schematics/migrations/invalid-two-way-bindings/bundle.js +0 -23808
- package/schematics/ng-generate/control-flow-migration/bundle.js +0 -28076
- package/schematics/ng-generate/inject-migration/bundle.js +0 -27777
- package/schematics/ng-generate/route-lazy-loading/bundle.js +0 -27478
- package/schematics/ng-generate/standalone-migration/bundle.js +0 -52161
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* @license Angular v19.0.0-next.4
|
|
4
|
+
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
|
+
* License: MIT
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
10
|
+
|
|
11
|
+
var schematics = require('@angular-devkit/schematics');
|
|
12
|
+
var p = require('path');
|
|
13
|
+
var project_tsconfig_paths = require('./project_tsconfig_paths-e9ccccbf.js');
|
|
14
|
+
var compiler_host = require('./compiler_host-ca7ba733.js');
|
|
15
|
+
var ts = require('typescript');
|
|
16
|
+
var imports = require('./imports-4ac08251.js');
|
|
17
|
+
require('@angular-devkit/core');
|
|
18
|
+
require('os');
|
|
19
|
+
require('fs');
|
|
20
|
+
require('module');
|
|
21
|
+
require('url');
|
|
22
|
+
|
|
23
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
24
|
+
|
|
25
|
+
var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
|
|
26
|
+
|
|
27
|
+
const CORE = '@angular/core';
|
|
28
|
+
const DIRECTIVE = 'Directive';
|
|
29
|
+
const COMPONENT = 'Component';
|
|
30
|
+
const PIPE = 'Pipe';
|
|
31
|
+
function migrateFile(sourceFile, rewriteFn) {
|
|
32
|
+
const changeTracker = new compiler_host.ChangeTracker(ts__default["default"].createPrinter());
|
|
33
|
+
// Check if there are any imports of the `AfterRenderPhase` enum.
|
|
34
|
+
const coreImports = imports.getNamedImports(sourceFile, CORE);
|
|
35
|
+
if (!coreImports) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const directive = imports.getImportSpecifier(sourceFile, CORE, DIRECTIVE);
|
|
39
|
+
const component = imports.getImportSpecifier(sourceFile, CORE, COMPONENT);
|
|
40
|
+
const pipe = imports.getImportSpecifier(sourceFile, CORE, PIPE);
|
|
41
|
+
if (!directive && !component && !pipe) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
ts__default["default"].forEachChild(sourceFile, function visit(node) {
|
|
45
|
+
ts__default["default"].forEachChild(node, visit);
|
|
46
|
+
// First we need to check for class declarations
|
|
47
|
+
// Decorators will come after
|
|
48
|
+
if (!ts__default["default"].isClassDeclaration(node)) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
ts__default["default"].getDecorators(node)?.forEach((decorator) => {
|
|
52
|
+
if (!ts__default["default"].isDecorator(decorator)) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const callExpression = decorator.expression;
|
|
56
|
+
if (!ts__default["default"].isCallExpression(callExpression)) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const decoratorIdentifier = callExpression.expression;
|
|
60
|
+
if (!ts__default["default"].isIdentifier(decoratorIdentifier)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Checking the identifier of the decorator by comparing to the import specifier
|
|
64
|
+
switch (decoratorIdentifier.text) {
|
|
65
|
+
case directive?.name.text:
|
|
66
|
+
case component?.name.text:
|
|
67
|
+
case pipe?.name.text:
|
|
68
|
+
break;
|
|
69
|
+
default:
|
|
70
|
+
// It's not a decorator to migrate
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const [firstArg] = callExpression.arguments;
|
|
74
|
+
if (!firstArg || !ts__default["default"].isObjectLiteralExpression(firstArg)) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const properties = firstArg.properties;
|
|
78
|
+
const standaloneProp = getStandaloneProperty(properties);
|
|
79
|
+
// Need to take care of 3 cases
|
|
80
|
+
// - standalone: true => remove the property
|
|
81
|
+
// - standalone: false => nothing
|
|
82
|
+
// - No standalone property => add a standalone: false property
|
|
83
|
+
let newProperties;
|
|
84
|
+
if (!standaloneProp) {
|
|
85
|
+
const standaloneFalseProperty = ts__default["default"].factory.createPropertyAssignment('standalone', ts__default["default"].factory.createFalse());
|
|
86
|
+
newProperties = [...properties, standaloneFalseProperty];
|
|
87
|
+
}
|
|
88
|
+
else if (standaloneProp.value === ts__default["default"].SyntaxKind.TrueKeyword) {
|
|
89
|
+
newProperties = properties.filter((p) => p !== standaloneProp.property);
|
|
90
|
+
}
|
|
91
|
+
if (newProperties) {
|
|
92
|
+
// At this point we know that we need to add standalone: false or
|
|
93
|
+
// remove an existing standalone: true property.
|
|
94
|
+
const newPropsArr = ts__default["default"].factory.createNodeArray(newProperties);
|
|
95
|
+
const newFirstArg = ts__default["default"].factory.createObjectLiteralExpression(newPropsArr, true);
|
|
96
|
+
changeTracker.replaceNode(firstArg, newFirstArg);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
// Write the changes.
|
|
101
|
+
for (const changesInFile of changeTracker.recordChanges().values()) {
|
|
102
|
+
for (const change of changesInFile) {
|
|
103
|
+
rewriteFn(change.start, change.removeLength ?? 0, change.text);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function getStandaloneProperty(properties) {
|
|
108
|
+
for (const prop of properties) {
|
|
109
|
+
if (ts__default["default"].isPropertyAssignment(prop) &&
|
|
110
|
+
ts__default["default"].isIdentifier(prop.name) &&
|
|
111
|
+
prop.name.text === 'standalone' &&
|
|
112
|
+
(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
|
+
}
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function migrate() {
|
|
121
|
+
return async (tree) => {
|
|
122
|
+
const { buildPaths, testPaths } = await project_tsconfig_paths.getProjectTsConfigPaths(tree);
|
|
123
|
+
const basePath = process.cwd();
|
|
124
|
+
const allPaths = [...buildPaths, ...testPaths];
|
|
125
|
+
if (!allPaths.length) {
|
|
126
|
+
throw new schematics.SchematicsException('Could not find any tsconfig file. Cannot run the standalone:false migration.');
|
|
127
|
+
}
|
|
128
|
+
for (const tsconfigPath of allPaths) {
|
|
129
|
+
runMigration(tree, tsconfigPath, basePath);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function runMigration(tree, tsconfigPath, basePath) {
|
|
134
|
+
const program = compiler_host.createMigrationProgram(tree, tsconfigPath, basePath);
|
|
135
|
+
const sourceFiles = program
|
|
136
|
+
.getSourceFiles()
|
|
137
|
+
.filter((sourceFile) => compiler_host.canMigrateFile(basePath, sourceFile, program));
|
|
138
|
+
for (const sourceFile of sourceFiles) {
|
|
139
|
+
let update = null;
|
|
140
|
+
const rewriter = (startPos, width, text) => {
|
|
141
|
+
if (update === null) {
|
|
142
|
+
// Lazily initialize update, because most files will not require migration.
|
|
143
|
+
update = tree.beginUpdate(p.relative(basePath, sourceFile.fileName));
|
|
144
|
+
}
|
|
145
|
+
update.remove(startPos, width);
|
|
146
|
+
if (text !== null) {
|
|
147
|
+
update.insertLeft(startPos, text);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
migrateFile(sourceFile, rewriter);
|
|
151
|
+
if (update !== null) {
|
|
152
|
+
tree.commitUpdate(update);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
exports.migrate = migrate;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* @license Angular v19.0.0-next.4
|
|
4
|
+
* (c) 2010-2024 Google LLC. https://angular.io/
|
|
5
|
+
* License: MIT
|
|
6
|
+
*/
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
var ts = require('typescript');
|
|
10
|
+
|
|
11
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
12
|
+
|
|
13
|
+
var ts__default = /*#__PURE__*/_interopDefaultLegacy(ts);
|
|
14
|
+
|
|
15
|
+
/** Gets import information about the specified identifier by using the Type checker. */
|
|
16
|
+
function getImportOfIdentifier(typeChecker, node) {
|
|
17
|
+
const symbol = typeChecker.getSymbolAtLocation(node);
|
|
18
|
+
if (!symbol || symbol.declarations === undefined || !symbol.declarations.length) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
const decl = symbol.declarations[0];
|
|
22
|
+
if (!ts__default["default"].isImportSpecifier(decl)) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
const importDecl = decl.parent.parent.parent;
|
|
26
|
+
if (!ts__default["default"].isImportDeclaration(importDecl) || !ts__default["default"].isStringLiteral(importDecl.moduleSpecifier)) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
return {
|
|
30
|
+
// Handles aliased imports: e.g. "import {Component as myComp} from ...";
|
|
31
|
+
name: decl.propertyName ? decl.propertyName.text : decl.name.text,
|
|
32
|
+
importModule: importDecl.moduleSpecifier.text,
|
|
33
|
+
node: importDecl,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Gets a top-level import specifier with a specific name that is imported from a particular module.
|
|
38
|
+
* E.g. given a file that looks like:
|
|
39
|
+
*
|
|
40
|
+
* ```
|
|
41
|
+
* import { Component, Directive } from '@angular/core';
|
|
42
|
+
* import { Foo } from './foo';
|
|
43
|
+
* ```
|
|
44
|
+
*
|
|
45
|
+
* Calling `getImportSpecifier(sourceFile, '@angular/core', 'Directive')` will yield the node
|
|
46
|
+
* referring to `Directive` in the top import.
|
|
47
|
+
*
|
|
48
|
+
* @param sourceFile File in which to look for imports.
|
|
49
|
+
* @param moduleName Name of the import's module.
|
|
50
|
+
* @param specifierName Original name of the specifier to look for. Aliases will be resolved to
|
|
51
|
+
* their original name.
|
|
52
|
+
*/
|
|
53
|
+
function getImportSpecifier(sourceFile, moduleName, specifierName) {
|
|
54
|
+
return getImportSpecifiers(sourceFile, moduleName, specifierName)[0] ?? null;
|
|
55
|
+
}
|
|
56
|
+
function getImportSpecifiers(sourceFile, moduleName, specifierOrSpecifiers) {
|
|
57
|
+
const matches = [];
|
|
58
|
+
for (const node of sourceFile.statements) {
|
|
59
|
+
if (!ts__default["default"].isImportDeclaration(node) || !ts__default["default"].isStringLiteral(node.moduleSpecifier)) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
const namedBindings = node.importClause?.namedBindings;
|
|
63
|
+
const isMatch = typeof moduleName === 'string'
|
|
64
|
+
? node.moduleSpecifier.text === moduleName
|
|
65
|
+
: moduleName.test(node.moduleSpecifier.text);
|
|
66
|
+
if (!isMatch || !namedBindings || !ts__default["default"].isNamedImports(namedBindings)) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (typeof specifierOrSpecifiers === 'string') {
|
|
70
|
+
const match = findImportSpecifier(namedBindings.elements, specifierOrSpecifiers);
|
|
71
|
+
if (match) {
|
|
72
|
+
matches.push(match);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
for (const specifierName of specifierOrSpecifiers) {
|
|
77
|
+
const match = findImportSpecifier(namedBindings.elements, specifierName);
|
|
78
|
+
if (match) {
|
|
79
|
+
matches.push(match);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return matches;
|
|
85
|
+
}
|
|
86
|
+
function getNamedImports(sourceFile, moduleName) {
|
|
87
|
+
for (const node of sourceFile.statements) {
|
|
88
|
+
if (ts__default["default"].isImportDeclaration(node) && ts__default["default"].isStringLiteral(node.moduleSpecifier)) {
|
|
89
|
+
const isMatch = typeof moduleName === 'string'
|
|
90
|
+
? node.moduleSpecifier.text === moduleName
|
|
91
|
+
: moduleName.test(node.moduleSpecifier.text);
|
|
92
|
+
const namedBindings = node.importClause?.namedBindings;
|
|
93
|
+
if (isMatch && namedBindings && ts__default["default"].isNamedImports(namedBindings)) {
|
|
94
|
+
return namedBindings;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
/** Finds an import specifier with a particular name. */
|
|
101
|
+
function findImportSpecifier(nodes, specifierName) {
|
|
102
|
+
return nodes.find((element) => {
|
|
103
|
+
const { name, propertyName } = element;
|
|
104
|
+
return propertyName ? propertyName.text === specifierName : name.text === specifierName;
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
exports.getImportOfIdentifier = getImportOfIdentifier;
|
|
109
|
+
exports.getImportSpecifier = getImportSpecifier;
|
|
110
|
+
exports.getNamedImports = getNamedImports;
|