@silvestv/migration-planificator 3.0.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/LICENSE +96 -0
- package/README.fr.md +359 -0
- package/README.md +360 -0
- package/SECURITY.md +187 -0
- package/dist/client.bundle.js +357 -0
- package/dist/src/core/app-analyzer.js +134 -0
- package/dist/src/core/ast/matchers/html/html-attribute-matcher.js +86 -0
- package/dist/src/core/ast/matchers/html/html-component-matcher.js +40 -0
- package/dist/src/core/ast/matchers/html/html-element-matcher.js +54 -0
- package/dist/src/core/ast/matchers/html/html-parser.js +58 -0
- package/dist/src/core/ast/matchers/html/html-pipe-matcher.js +95 -0
- package/dist/src/core/ast/matchers/html/html-text-matcher.js +53 -0
- package/dist/src/core/ast/matchers/html/index.js +118 -0
- package/dist/src/core/ast/matchers/index.js +377 -0
- package/dist/src/core/ast/matchers/ts/collection-matcher.js +51 -0
- package/dist/src/core/ast/matchers/ts/context-matcher.js +275 -0
- package/dist/src/core/ast/matchers/ts/decorator-matcher.js +465 -0
- package/dist/src/core/ast/matchers/ts/expression-matcher.js +237 -0
- package/dist/src/core/ast/matchers/ts/file-matcher.js +97 -0
- package/dist/src/core/ast/matchers/ts/hierarchy-matcher.js +172 -0
- package/dist/src/core/ast/matchers/ts/import-matcher.js +39 -0
- package/dist/src/core/ast/matchers/ts/index.js +53 -0
- package/dist/src/core/ast/matchers/ts/node-matcher.js +156 -0
- package/dist/src/core/ast/matchers/ts/symbol-matcher.js +281 -0
- package/dist/src/core/ast/matchers/ts/type-matcher.js +207 -0
- package/dist/src/core/ast/matchers/utils/matcher-helpers.js +37 -0
- package/dist/src/core/ast/scanner-ast.js +444 -0
- package/dist/src/core/project-detector.js +196 -0
- package/dist/src/core/project-strategy/index.js +9 -0
- package/dist/src/core/project-strategy/nx-strategy.js +130 -0
- package/dist/src/core/project-strategy/project-strategy.interface.js +2 -0
- package/dist/src/core/project-strategy/standalone-strategy.js +74 -0
- package/dist/src/core/project-strategy/strategy-factory.js +15 -0
- package/dist/src/core/rules-loader.js +89 -0
- package/dist/src/core/scan-reporter.js +316 -0
- package/dist/src/core/scanner-delta.js +339 -0
- package/dist/src/core/scanner-orchestrator.js +266 -0
- package/dist/src/core/scanner-regex.js +298 -0
- package/dist/src/core/workload/calculator.js +82 -0
- package/dist/src/core/workload/constants.js +15 -0
- package/dist/src/core/workload/grouping.js +18 -0
- package/dist/src/core/workload/hierarchy-calculator.js +127 -0
- package/dist/src/core/workload/index.js +11 -0
- package/dist/src/core/workload/metadata.js +20 -0
- package/dist/src/core/workload/special-workload.js +101 -0
- package/dist/src/core/workload/target-resolver.js +34 -0
- package/dist/src/data/angular-migration-rules.json +2337 -0
- package/dist/src/data/markdown/angular-migration-17-18.md +408 -0
- package/dist/src/data/markdown/angular-migration-18-19.md +600 -0
- package/dist/src/data/markdown/angular-migration-19-20.md +521 -0
- package/dist/src/data/rules/rearchitecture/rearchitecture-rules.json +66 -0
- package/dist/src/data/rules/to18/rules-18-obligatoire.json +374 -0
- package/dist/src/data/rules/to18/rules-18-optionnelle.json +188 -0
- package/dist/src/data/rules/to18/rules-18-recommande.json +218 -0
- package/dist/src/data/rules/to19/rules-19-obligatoire.json +348 -0
- package/dist/src/data/rules/to19/rules-19-optionnelle.json +223 -0
- package/dist/src/data/rules/to19/rules-19-recommande.json +200 -0
- package/dist/src/data/rules/to20/rules-20-obligatoire.json +556 -0
- package/dist/src/data/rules/to20/rules-20-optionnelle.json +190 -0
- package/dist/src/data/rules/to20/rules-20-recommande.json +151 -0
- package/dist/src/index.js +161 -0
- package/dist/src/models/chip-config.js +45 -0
- package/dist/src/models/interfaces/app-details.interface.js +2 -0
- package/dist/src/models/interfaces/ast-interfaces.js +5 -0
- package/dist/src/models/interfaces/ast-pattern.interface.js +2 -0
- package/dist/src/models/interfaces/client-interfaces.js +6 -0
- package/dist/src/models/interfaces/detection-stats.interface.js +2 -0
- package/dist/src/models/interfaces/html-match.interface.js +2 -0
- package/dist/src/models/interfaces/html-report-data.interface.js +2 -0
- package/dist/src/models/interfaces/lib-details.interface.js +2 -0
- package/dist/src/models/interfaces/migration-rules.interface.js +2 -0
- package/dist/src/models/interfaces/parsed-args.interface.js +2 -0
- package/dist/src/models/interfaces/project-info.interface.js +2 -0
- package/dist/src/models/interfaces/project-overview-data.interface.js +2 -0
- package/dist/src/models/interfaces/rule-match.interface.js +2 -0
- package/dist/src/models/interfaces/rule.interface.js +2 -0
- package/dist/src/models/interfaces/rules-by-priority.interface.js +2 -0
- package/dist/src/models/interfaces/scanner-comparison.interface.js +2 -0
- package/dist/src/models/interfaces/special-workload.interface.js +2 -0
- package/dist/src/models/interfaces/workload-report.interface.js +2 -0
- package/dist/src/models/types/build-block-blob.type.js +2 -0
- package/dist/src/models/types/migration-version.type.js +2 -0
- package/dist/src/models/types/project-type.type.js +2 -0
- package/dist/src/models/types/risk-level.type.js +2 -0
- package/dist/src/models/types/rule-category.type.js +2 -0
- package/dist/src/models/types/rule-priority.type.js +2 -0
- package/dist/src/models/types/rule-workload-type.type.js +2 -0
- package/dist/src/templates/landing/applications-analyzed.template.js +18 -0
- package/dist/src/templates/landing/card-app-info.template.js +63 -0
- package/dist/src/templates/landing/card-lib-info.template.js +67 -0
- package/dist/src/templates/landing/libs-analyzed.template.js +22 -0
- package/dist/src/templates/landing/nx-summary.template.js +115 -0
- package/dist/src/templates/landing/project-overview.template.js +27 -0
- package/dist/src/templates/page/index-page.template.js +95 -0
- package/dist/src/templates/page/main.template.js +83 -0
- package/dist/src/templates/page/migration-guide.template.js +175 -0
- package/dist/src/templates/page/workload-report.template.js +53 -0
- package/dist/src/templates/workload/dashboard.template.js +184 -0
- package/dist/src/templates/workload/filters-panel.template.js +215 -0
- package/dist/src/templates/workload/guide-rule-card.template.js +107 -0
- package/dist/src/templates/workload/hierarchy-nx.template.js +104 -0
- package/dist/src/templates/workload/hierarchy-shared.js +163 -0
- package/dist/src/templates/workload/hierarchy-standalone.template.js +36 -0
- package/dist/src/templates/workload/hierarchy.template.js +35 -0
- package/dist/src/templates/workload/rule-modal.template.js +280 -0
- package/dist/src/utils/core/args-parser.js +123 -0
- package/dist/src/utils/core/array-helpers.js +18 -0
- package/dist/src/utils/core/ast-helpers.js +99 -0
- package/dist/src/utils/core/file-helpers.js +109 -0
- package/dist/src/utils/core/html-helpers.js +36 -0
- package/dist/src/utils/core/index.js +28 -0
- package/dist/src/utils/core/logger.js +38 -0
- package/dist/src/utils/core/rule-helpers.js +15 -0
- package/dist/src/utils/core/workload-formatter.js +6 -0
- package/dist/src/utils/shared/array-helpers.js +25 -0
- package/dist/src/utils/shared/date-helpers.js +109 -0
- package/dist/src/utils/shared/html-helpers.js +37 -0
- package/dist/src/utils/shared/index.js +25 -0
- package/dist/src/utils/shared/rule-helpers.js +20 -0
- package/dist/src/utils/shared/time-formatters.js +76 -0
- package/dist/styles.css +2 -0
- package/package.json +107 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"key": "resource_api_http",
|
|
4
|
+
"summary": "Utiliser resource API pour gestion HTTP réactive",
|
|
5
|
+
"description": "L'API resource simplifie la gestion d'état des requêtes HTTP avec status tracking automatique (loading, resolved, error), retry intégré et invalidation réactive. Alternative moderne aux patterns Observable + AsyncPipe, particulièrement utile avec les signaux.",
|
|
6
|
+
"estimated_time_per_occurrence": 15,
|
|
7
|
+
"onFile": null,
|
|
8
|
+
"fileTypes": [
|
|
9
|
+
"*.ts"
|
|
10
|
+
],
|
|
11
|
+
"regex": "\\.(get|post|put|delete|patch)<.*>\\s*\\(",
|
|
12
|
+
"category": "reactive",
|
|
13
|
+
"auto_fixable": false,
|
|
14
|
+
"migration_command": null,
|
|
15
|
+
"risk_level": "medium",
|
|
16
|
+
"code_description": "import { resource } from '@angular/core';\n\nuserResource = resource({\n loader: () => fetch('/api/user').then(r => r.json())\n});\n\n// Template:\n@switch (userResource.status()) {\n @case ('loading') { <p>Chargement...</p> }\n @case ('resolved') { <p>{{ userResource.value() }}</p> }\n}",
|
|
17
|
+
"astPattern": {
|
|
18
|
+
"nodeType": "CallExpression",
|
|
19
|
+
"expression": {
|
|
20
|
+
"nodeType": "PropertyAccessExpression",
|
|
21
|
+
"expression": {
|
|
22
|
+
"name": [
|
|
23
|
+
"httpClient",
|
|
24
|
+
"http",
|
|
25
|
+
"this.httpClient",
|
|
26
|
+
"this.http"
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
"name": [
|
|
30
|
+
"get",
|
|
31
|
+
"post",
|
|
32
|
+
"put",
|
|
33
|
+
"delete",
|
|
34
|
+
"patch"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
"parent": {
|
|
38
|
+
"notNodeType": "CallExpression",
|
|
39
|
+
"notFunctionName": "resource"
|
|
40
|
+
},
|
|
41
|
+
"excludeContext": [
|
|
42
|
+
"StringLiteral",
|
|
43
|
+
"Comment"
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"key": "incremental_hydration",
|
|
50
|
+
"summary": "Hydratation incrémentale expérimentale",
|
|
51
|
+
"description": "L'hydratation incrémentale permet d'hydrater progressivement l'application Angular côté client, en priorisant les parties visibles et interactives. Combine @defer avec hydrate triggers (viewport, interaction, idle) pour optimiser TTI et réduire le JavaScript initial.",
|
|
52
|
+
"estimated_time_per_occurrence": 20,
|
|
53
|
+
"onFile": null,
|
|
54
|
+
"fileTypes": [
|
|
55
|
+
"*.ts",
|
|
56
|
+
"*.html"
|
|
57
|
+
],
|
|
58
|
+
"regex": "(?<![\"\\'])\\bprovideClientHydration\\s*\\(",
|
|
59
|
+
"category": "ssr",
|
|
60
|
+
"auto_fixable": false,
|
|
61
|
+
"migration_command": null,
|
|
62
|
+
"risk_level": "high",
|
|
63
|
+
"code_description": "bootstrapApplication(App, {\n providers: [\n provideClientHydration(withIncrementalHydration())\n ]\n});\n\n// Template:\n@defer (render on server; hydrate on interaction) {\n <heavy-component />\n}",
|
|
64
|
+
"astPattern": {
|
|
65
|
+
"nodeType": "CallExpression",
|
|
66
|
+
"functionName": "provideClientHydration",
|
|
67
|
+
"arguments": {
|
|
68
|
+
"missing": "withIncrementalHydration"
|
|
69
|
+
},
|
|
70
|
+
"excludeContext": [
|
|
71
|
+
"StringLiteral",
|
|
72
|
+
"Comment"
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"key": "service_worker_enhanced",
|
|
79
|
+
"summary": "Service Worker avec refreshAhead et applicationMaxAge",
|
|
80
|
+
"description": "Angular 19 ajoute refreshAhead pour pré-charger les assets avant expiration du cache et applicationMaxAge pour définir la durée de vie globale de l'app dans le cache. Améliore l'expérience offline et réduit les latences perçues.",
|
|
81
|
+
"estimated_time_per_occurrence": 10,
|
|
82
|
+
"onFile": "ngsw-config.json",
|
|
83
|
+
"fileTypes": [
|
|
84
|
+
"ngsw-config.json"
|
|
85
|
+
],
|
|
86
|
+
"regex": "^(?![\\s\\S]*(\"applicationMaxAge\"|\"refreshAhead\"))",
|
|
87
|
+
"category": "pwa",
|
|
88
|
+
"auto_fixable": false,
|
|
89
|
+
"migration_command": null,
|
|
90
|
+
"risk_level": "low",
|
|
91
|
+
"code_description": "// ngsw-config.json\n{\n \"applicationMaxAge\": \"7d\",\n \"dataGroups\": [{\n \"cacheConfig\": {\n \"maxAge\": \"1h\",\n \"refreshAhead\": \"10m\"\n }\n }]\n}",
|
|
92
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
"key": "hybrid_rendering",
|
|
96
|
+
"summary": "Rendu hybride par route (SSR/SSG/CSR)",
|
|
97
|
+
"description": "Le rendu hybride permet de définir une stratégie de rendu différente par route: Prerender pour les pages statiques, Server pour le contenu dynamique, Client pour les parties authentifiées. getPrerenderParams génère les paramètres pour le SSG dynamique.",
|
|
98
|
+
"estimated_time_per_occurrence": 30,
|
|
99
|
+
"onFile": null,
|
|
100
|
+
"fileTypes": [
|
|
101
|
+
"*.ts"
|
|
102
|
+
],
|
|
103
|
+
"regex": "export\\s+const\\s+routes\\s*:\\s*Routes",
|
|
104
|
+
"category": "ssr",
|
|
105
|
+
"auto_fixable": false,
|
|
106
|
+
"migration_command": null,
|
|
107
|
+
"risk_level": "medium",
|
|
108
|
+
"code_description": "// app.routes.server.ts\nimport { RenderMode } from '@angular/ssr';\n\nexport const serverRoutes = [\n { path: '', renderMode: RenderMode.Prerender },\n { path: 'blog/**', renderMode: RenderMode.Server },\n { path: 'admin/**', renderMode: RenderMode.Client }\n];",
|
|
109
|
+
"astPattern": {
|
|
110
|
+
"nodeType": "VariableStatement",
|
|
111
|
+
"modifiers": [
|
|
112
|
+
"export"
|
|
113
|
+
],
|
|
114
|
+
"declarations": {
|
|
115
|
+
"name": [
|
|
116
|
+
"routes",
|
|
117
|
+
"serverRoutes"
|
|
118
|
+
],
|
|
119
|
+
"initializer": {
|
|
120
|
+
"nodeType": "ArrayLiteralExpression",
|
|
121
|
+
"elements": {
|
|
122
|
+
"nodeType": "ObjectLiteralExpression",
|
|
123
|
+
"properties": {
|
|
124
|
+
"path": {
|
|
125
|
+
"exists": true
|
|
126
|
+
},
|
|
127
|
+
"renderMode": {
|
|
128
|
+
"missing": true
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
"excludeContext": [
|
|
135
|
+
"StringLiteral",
|
|
136
|
+
"Comment"
|
|
137
|
+
]
|
|
138
|
+
},
|
|
139
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
"key": "route_lazy_loading",
|
|
143
|
+
"summary": "Migration automatique vers lazy loading",
|
|
144
|
+
"description": "Le schematic route-lazy-loading convertit automatiquement les routes avec component eager loading en loadComponent avec imports dynamiques, réduisant le bundle initial. Analyse le code pour identifier les opportunités de lazy loading et applique les transformations.",
|
|
145
|
+
"estimated_time_per_occurrence": 5,
|
|
146
|
+
"onFile": null,
|
|
147
|
+
"fileTypes": [
|
|
148
|
+
"*.routes.ts",
|
|
149
|
+
"*.routing.ts",
|
|
150
|
+
"*-routing.module.ts",
|
|
151
|
+
"app-routing.ts",
|
|
152
|
+
"app.routes.ts"
|
|
153
|
+
],
|
|
154
|
+
"regex": "\\bcomponent\\s*:\\s*[A-Z]\\w+Component\\b",
|
|
155
|
+
"category": "routing",
|
|
156
|
+
"auto_fixable": false,
|
|
157
|
+
"migration_command": "ng generate @angular/core:route-lazy-loading",
|
|
158
|
+
"risk_level": "low",
|
|
159
|
+
"code_description": "// Avant:\n{ path: 'users', component: UsersComponent }\n\n// Après:\n{\n path: 'users',\n loadComponent: () => import('./users.component').then(m => m.UsersComponent)\n}",
|
|
160
|
+
"astPattern": {
|
|
161
|
+
"nodeType": "ObjectLiteralExpression",
|
|
162
|
+
"properties": {
|
|
163
|
+
"path": {
|
|
164
|
+
"exists": true
|
|
165
|
+
},
|
|
166
|
+
"component": {
|
|
167
|
+
"exists": true
|
|
168
|
+
},
|
|
169
|
+
"loadComponent": {
|
|
170
|
+
"missing": true
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
"parent": {
|
|
174
|
+
"nodeType": [
|
|
175
|
+
"VariableDeclaration",
|
|
176
|
+
"VariableStatement"
|
|
177
|
+
],
|
|
178
|
+
"name": [
|
|
179
|
+
"routes",
|
|
180
|
+
"serverRoutes",
|
|
181
|
+
"appRoutes"
|
|
182
|
+
]
|
|
183
|
+
},
|
|
184
|
+
"excludeContext": [
|
|
185
|
+
"StringLiteral",
|
|
186
|
+
"Comment"
|
|
187
|
+
]
|
|
188
|
+
},
|
|
189
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"key": "inject_function_migration",
|
|
193
|
+
"summary": "Migration constructor → inject()",
|
|
194
|
+
"description": "La fonction inject() moderne remplace l'injection par constructeur avec une syntaxie plus concise et fonctionnelle. Permet l'injection dans les propriétés de classe, élimine le besoin de déclarer les dépendances deux fois (paramètres + propriétés) et facilite le tree-shaking.",
|
|
195
|
+
"estimated_time_per_occurrence": 5,
|
|
196
|
+
"onFile": null,
|
|
197
|
+
"fileTypes": [
|
|
198
|
+
"*.ts"
|
|
199
|
+
],
|
|
200
|
+
"regex": "constructor\\s*\\([^)]*private\\s+\\w+\\s*:\\s*\\w+",
|
|
201
|
+
"category": "di",
|
|
202
|
+
"auto_fixable": false,
|
|
203
|
+
"migration_command": "ng generate @angular/core:inject",
|
|
204
|
+
"risk_level": "low",
|
|
205
|
+
"code_description": "// Avant:\nconstructor(private http: HttpClient) {}\n\n// Après:\nprivate http = inject(HttpClient);",
|
|
206
|
+
"astPattern": {
|
|
207
|
+
"nodeType": "Constructor",
|
|
208
|
+
"parameters": {
|
|
209
|
+
"hasModifier": [
|
|
210
|
+
"private",
|
|
211
|
+
"public",
|
|
212
|
+
"protected"
|
|
213
|
+
],
|
|
214
|
+
"hasType": true
|
|
215
|
+
},
|
|
216
|
+
"excludeContext": [
|
|
217
|
+
"StringLiteral",
|
|
218
|
+
"Comment"
|
|
219
|
+
]
|
|
220
|
+
},
|
|
221
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
222
|
+
}
|
|
223
|
+
]
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"key": "signal_input_migration",
|
|
4
|
+
"summary": "Migration @Input → input()",
|
|
5
|
+
"description": "Migrer les décorateurs @Input vers la nouvelle API input() basée sur les signaux pour bénéficier d'une réactivité fine-grained et d'un meilleur tree-shaking. La migration automatique via schematic gère la plupart des cas, nécessite une revue manuelle pour les inputs complexes.",
|
|
6
|
+
"estimated_time_per_occurrence": 3,
|
|
7
|
+
"onFile": null,
|
|
8
|
+
"fileTypes": [
|
|
9
|
+
"*.ts"
|
|
10
|
+
],
|
|
11
|
+
"regex": "@Input\\s*\\(\\)",
|
|
12
|
+
"category": "signals",
|
|
13
|
+
"auto_fixable": false,
|
|
14
|
+
"migration_command": "ng generate @angular/core:signal-input-migration",
|
|
15
|
+
"risk_level": "medium",
|
|
16
|
+
"code_description": "// Avant:\n@Input() name: string;\n@Input({ required: true }) age: number;\n\n// Après:\nreadonly name = input<string>();\nreadonly age = input.required<number>();",
|
|
17
|
+
"astPattern": {
|
|
18
|
+
"nodeType": "Decorator",
|
|
19
|
+
"name": "Input",
|
|
20
|
+
"parent": {
|
|
21
|
+
"nodeType": "PropertyDeclaration"
|
|
22
|
+
},
|
|
23
|
+
"excludeContext": [
|
|
24
|
+
"StringLiteral",
|
|
25
|
+
"Comment"
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"key": "signal_output_migration",
|
|
32
|
+
"summary": "Migration @Output → output()",
|
|
33
|
+
"description": "Remplacer @Output et EventEmitter par la nouvelle fonction output() qui retourne un OutputEmitterRef typé et interopérable avec les signaux. Plus performant et offre une meilleure intégration avec l'écosystème signals.",
|
|
34
|
+
"estimated_time_per_occurrence": 3,
|
|
35
|
+
"onFile": null,
|
|
36
|
+
"fileTypes": [
|
|
37
|
+
"*.ts"
|
|
38
|
+
],
|
|
39
|
+
"regex": "@Output\\s*\\(\\)",
|
|
40
|
+
"category": "signals",
|
|
41
|
+
"auto_fixable": false,
|
|
42
|
+
"migration_command": "ng generate @angular/core:output-migration",
|
|
43
|
+
"risk_level": "low",
|
|
44
|
+
"code_description": "// Avant:\n@Output() userChange = new EventEmitter<User>();\n\n// Après:\nreadonly userChange = output<User>();",
|
|
45
|
+
"astPattern": {
|
|
46
|
+
"nodeType": "Decorator",
|
|
47
|
+
"name": "Output",
|
|
48
|
+
"parent": {
|
|
49
|
+
"nodeType": "PropertyDeclaration",
|
|
50
|
+
"initializer": {
|
|
51
|
+
"nodeType": "NewExpression",
|
|
52
|
+
"expression": "EventEmitter"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"excludeContext": [
|
|
56
|
+
"StringLiteral",
|
|
57
|
+
"Comment"
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"key": "signal_queries_migration",
|
|
64
|
+
"summary": "Migration @ViewChild/@ContentChild → viewChild()/contentChild()",
|
|
65
|
+
"description": "Migrer les query decorators vers les fonctions signal-based viewChild, viewChildren, contentChild et contentChildren. Ces nouvelles APIs retournent des signaux qui se mettent à jour automatiquement quand la vue change, éliminant le besoin de ngAfterViewInit dans beaucoup de cas.",
|
|
66
|
+
"estimated_time_per_occurrence": 3,
|
|
67
|
+
"onFile": null,
|
|
68
|
+
"fileTypes": [
|
|
69
|
+
"*.ts"
|
|
70
|
+
],
|
|
71
|
+
"regex": "@(ViewChild|ViewChildren|ContentChild|ContentChildren)\\s*\\(",
|
|
72
|
+
"category": "signals",
|
|
73
|
+
"auto_fixable": false,
|
|
74
|
+
"migration_command": "ng generate @angular/core:signal-queries-migration",
|
|
75
|
+
"risk_level": "medium",
|
|
76
|
+
"code_description": "// Avant:\n@ViewChild('ref') ref: ElementRef;\n\n// Après:\nreadonly ref = viewChild<ElementRef>('ref');",
|
|
77
|
+
"astPattern": {
|
|
78
|
+
"nodeType": "Decorator",
|
|
79
|
+
"name": [
|
|
80
|
+
"ViewChild",
|
|
81
|
+
"ViewChildren",
|
|
82
|
+
"ContentChild",
|
|
83
|
+
"ContentChildren"
|
|
84
|
+
],
|
|
85
|
+
"parent": {
|
|
86
|
+
"nodeType": "PropertyDeclaration"
|
|
87
|
+
},
|
|
88
|
+
"excludeContext": [
|
|
89
|
+
"StringLiteral",
|
|
90
|
+
"Comment"
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"key": "linkedSignal_state",
|
|
97
|
+
"summary": "Utiliser linkedSignal pour état dépendant",
|
|
98
|
+
"description": "linkedSignal remplace les patterns effect + set pour gérer l'état dérivé avec reset automatique. Quand le signal source change, le signal lié est automatiquement recalculé avec la fonction computation, éliminant la logique manuelle dans effects.",
|
|
99
|
+
"estimated_time_per_occurrence": 10,
|
|
100
|
+
"onFile": null,
|
|
101
|
+
"fileTypes": [
|
|
102
|
+
"*.ts",
|
|
103
|
+
"*.spec.ts"
|
|
104
|
+
],
|
|
105
|
+
"regex": "effect\\s*\\(\\s*\\(\\)\\s*=>\\s*\\{[^}]*\\.set\\(",
|
|
106
|
+
"category": "signals",
|
|
107
|
+
"auto_fixable": false,
|
|
108
|
+
"migration_command": null,
|
|
109
|
+
"risk_level": "low",
|
|
110
|
+
"code_description": "// Avant:\nngOnInit() {\n effect(() => {\n if (this.category() !== 'all') {\n this.itemsPerPage.set(10);\n }\n });\n}\n\n// Après:\nitemsPerPage = linkedSignal({\n source: this.category,\n computation: () => 10\n});",
|
|
111
|
+
"astPattern": {
|
|
112
|
+
"nodeType": "CallExpression",
|
|
113
|
+
"functionName": "effect",
|
|
114
|
+
"arguments": {
|
|
115
|
+
"contains": {
|
|
116
|
+
"nodeType": "ArrowFunction",
|
|
117
|
+
"body": {
|
|
118
|
+
"contains": {
|
|
119
|
+
"nodeType": "CallExpression",
|
|
120
|
+
"expression": {
|
|
121
|
+
"nodeType": "PropertyAccessExpression",
|
|
122
|
+
"propertyName": [
|
|
123
|
+
"set",
|
|
124
|
+
"update"
|
|
125
|
+
]
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
"excludeContext": [
|
|
132
|
+
"StringLiteral",
|
|
133
|
+
"Comment"
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"key": "provideAppInitializer",
|
|
140
|
+
"summary": "Utiliser provideAppInitializer au lieu de APP_INITIALIZER",
|
|
141
|
+
"description": "La fonction provideAppInitializer offre une API plus simple et plus typée que le token APP_INITIALIZER multi-provider. Elle supporte automatiquement inject() et élimine le besoin de deps array, simplifiant la configuration d'initialisation.",
|
|
142
|
+
"estimated_time_per_occurrence": 5,
|
|
143
|
+
"onFile": null,
|
|
144
|
+
"fileTypes": [
|
|
145
|
+
"*.ts"
|
|
146
|
+
],
|
|
147
|
+
"regex": "provide:\\s*APP_INITIALIZER",
|
|
148
|
+
"category": "architecture",
|
|
149
|
+
"auto_fixable": false,
|
|
150
|
+
"migration_command": null,
|
|
151
|
+
"risk_level": "low",
|
|
152
|
+
"code_description": "// Avant:\n{ provide: APP_INITIALIZER, useFactory: ... }\n\n// Après:\nprovideAppInitializer(() => {\n return inject(ConfigService).load();\n})",
|
|
153
|
+
"astPattern": {
|
|
154
|
+
"nodeType": "PropertyAssignment",
|
|
155
|
+
"name": "provide",
|
|
156
|
+
"initializer": {
|
|
157
|
+
"nodeType": "Identifier",
|
|
158
|
+
"name": "APP_INITIALIZER"
|
|
159
|
+
},
|
|
160
|
+
"parent": {
|
|
161
|
+
"nodeType": "ObjectLiteralExpression",
|
|
162
|
+
"properties": {
|
|
163
|
+
"useFactory": {
|
|
164
|
+
"exists": true
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
"excludeContext": [
|
|
169
|
+
"StringLiteral",
|
|
170
|
+
"Comment"
|
|
171
|
+
]
|
|
172
|
+
},
|
|
173
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
"key": "routerOutletData",
|
|
177
|
+
"summary": "Partager données via routerOutletData",
|
|
178
|
+
"description": "routerOutletData permet de passer des données réactives du composant parent aux composants routés via le router-outlet, évitant le prop drilling ou l'utilisation de services partagés. Les données sont accessibles via le token ROUTER_OUTLET_DATA dans les composants enfants.",
|
|
179
|
+
"estimated_time_per_occurrence": 10,
|
|
180
|
+
"onFile": null,
|
|
181
|
+
"fileTypes": [
|
|
182
|
+
"*.html"
|
|
183
|
+
],
|
|
184
|
+
"regex": "<router-outlet[^>]*>",
|
|
185
|
+
"category": "routing",
|
|
186
|
+
"auto_fixable": false,
|
|
187
|
+
"migration_command": null,
|
|
188
|
+
"risk_level": "low",
|
|
189
|
+
"code_description": "// Parent:\n<router-outlet [routerOutletData]=\"sharedData\"></router-outlet>\n\n// Enfant:\ndata = inject(ROUTER_OUTLET_DATA);",
|
|
190
|
+
"astPattern": {
|
|
191
|
+
"nodeType": "Decorator",
|
|
192
|
+
"name": "Component",
|
|
193
|
+
"template": {
|
|
194
|
+
"contains": "router-outlet",
|
|
195
|
+
"notContains": "routerOutletData"
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
"doc_url": "https://angular.dev/reference/migrations"
|
|
199
|
+
}
|
|
200
|
+
]
|