@dsivd/prestations-ng 19.1.1 → 19.2.0-beta.2
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/CHANGELOG.md +13 -6
- package/GOOD_PRACTICES.md +150 -102
- package/UPGRADING_V18.md +1 -0
- package/UPGRADING_V19.md +43 -2
- package/dsivd-prestations-ng-19.2.0-beta.2.tgz +0 -0
- package/eslint/signal-names.mjs +66 -35
- package/fesm2022/dsivd-prestations-ng.mjs +3876 -3430
- package/fesm2022/dsivd-prestations-ng.mjs.map +1 -1
- package/package.json +1 -1
- package/schematics/utility/add-allow-synthetic-default-imports.js +2 -2
- package/schematics/utility/add-allowed-common-js-dependencies.js +2 -2
- package/schematics/utility/foehn2-bootstrap5-migration.js +20 -20
- package/schematics/utility/migrate-to-karma-coverage.js +2 -2
- package/schematics/utility/remove-emit-decorator-metadata.js +2 -2
- package/src/eslint/__tests__/signal-names.test.mjs +129 -0
- package/src/eslint/signal-names.mjs +66 -35
- package/types/dsivd-prestations-ng.d.ts +936 -906
- package/dsivd-prestations-ng-19.1.1.tgz +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## [19.2.0] - should be aligned with prestations-be 19.2.x
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
Library now runs as strict mode, which may cause some errors to appear in your project after updating.
|
|
14
|
+
Please check the [UPGRADING_V19.md](UPGRADING_V19.md) guide for more information.
|
|
15
|
+
|
|
9
16
|
## [19.1.1]
|
|
10
17
|
|
|
11
18
|
### Fixed
|
|
@@ -13,12 +20,12 @@
|
|
|
13
20
|
- [foehn-input-phone.component.ts](projects/prestations-ng/src/foehn-input/foehn-input-phone.component.ts)
|
|
14
21
|
- fixed help texts to be aligned with ch.vd.cyber.prestationsbe.validation.PhoneNumberValidator (prestations-be)
|
|
15
22
|
- dictionary keys have changed to be more explicit :
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
- foehn-input-phone.STANDARD_HELPTEXT_SWISS_FIX_AND_MOBILE
|
|
24
|
+
- foehn-input-phone.STANDARD_HELPTEXT_SWISS_FIX_ONLY
|
|
25
|
+
- foehn-input-phone.STANDARD_HELPTEXT_SWISS_MOBILE_ONLY
|
|
26
|
+
- foehn-input-phone.STANDARD_HELPTEXT_INTERNATIONAL_FIX_AND_MOBILE
|
|
27
|
+
- foehn-input-phone.STANDARD_HELPTEXT_INTERNATIONAL_FIX_ONLY
|
|
28
|
+
- foehn-input-phone.STANDARD_HELPTEXT_INTERNATIONAL_MOBILE_ONLY
|
|
22
29
|
|
|
23
30
|
## [19.1.0] - should be aligned with prestations-be 19.1.x
|
|
24
31
|
|
package/GOOD_PRACTICES.md
CHANGED
|
@@ -95,29 +95,25 @@ Ce qu'il ne faut **pas** faire :
|
|
|
95
95
|
|
|
96
96
|
```html
|
|
97
97
|
<h1>...</h1>
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
...
|
|
103
|
-
...
|
|
98
|
+
<h3>...</h3>
|
|
99
|
+
<h2>...</h2>
|
|
100
|
+
<h6>...</h6>
|
|
101
|
+
... ... ...
|
|
104
102
|
```
|
|
105
103
|
|
|
106
104
|
Ce qu'il **faut** faire :
|
|
107
105
|
|
|
108
106
|
```html
|
|
109
107
|
<h1>...</h1>
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
<section>
|
|
120
|
-
...
|
|
108
|
+
<section>
|
|
109
|
+
<h2>...</h2>
|
|
110
|
+
<h3>...</h3>
|
|
111
|
+
<h4>...</h4>
|
|
112
|
+
... ...
|
|
113
|
+
</section>
|
|
114
|
+
<h2>...</h2>
|
|
115
|
+
...
|
|
116
|
+
<section>...</section>
|
|
121
117
|
```
|
|
122
118
|
|
|
123
119
|
Quelques attributs HTML utiles :
|
|
@@ -216,32 +212,36 @@ Exemple :
|
|
|
216
212
|
|
|
217
213
|
```html
|
|
218
214
|
<ul>
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
<li>trois œufs</li>
|
|
224
|
-
<li>La génoise
|
|
225
|
-
<!-- Là on ouvre une autre liste -->
|
|
215
|
+
<li>un artichaut</li>
|
|
216
|
+
<li>
|
|
217
|
+
Les trucs pour le gâteau
|
|
218
|
+
<!-- On voit que </li> n'est pas là -->
|
|
226
219
|
<ul>
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
220
|
+
<li>trois œufs</li>
|
|
221
|
+
<li>
|
|
222
|
+
La génoise
|
|
223
|
+
<!-- Là on ouvre une autre liste -->
|
|
224
|
+
<ul>
|
|
225
|
+
<li>100g de sucre</li>
|
|
226
|
+
<li>un œuf</li>
|
|
227
|
+
<li>150g de farine</li>
|
|
228
|
+
</ul>
|
|
229
|
+
</li>
|
|
230
|
+
<!-- On ferme la liste la plus imbriquée -->
|
|
231
|
+
<li>200g de chocolat</li>
|
|
230
232
|
</ul>
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
</
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
</ol>
|
|
244
|
-
</li>
|
|
233
|
+
<!-- On ferme la liste imbriquée avec </li> -->
|
|
234
|
+
</li>
|
|
235
|
+
<li>De l'essuie-tout</li>
|
|
236
|
+
<li>
|
|
237
|
+
A faire dans l'ordre pour une belle vaisselle
|
|
238
|
+
<ol>
|
|
239
|
+
<li>Remplir le lave vaisselle</li>
|
|
240
|
+
<li>Mettre une pastille pour lave vaisselle</li>
|
|
241
|
+
<li>Fermer la porte du lave vaisselle</li>
|
|
242
|
+
<li>Lancer le lave vaisselle</li>
|
|
243
|
+
</ol>
|
|
244
|
+
</li>
|
|
245
245
|
</ul>
|
|
246
246
|
```
|
|
247
247
|
|
|
@@ -262,18 +262,18 @@ Exemple :
|
|
|
262
262
|
|
|
263
263
|
```html
|
|
264
264
|
<form>
|
|
265
|
-
|
|
266
|
-
|
|
265
|
+
<fieldset>
|
|
266
|
+
<legend>Choose your favorite monster</legend>
|
|
267
267
|
|
|
268
|
-
|
|
269
|
-
|
|
268
|
+
<input type="radio" id="kraken" name="monster" value="K" />
|
|
269
|
+
<label for="kraken">Kraken</label><br />
|
|
270
270
|
|
|
271
|
-
|
|
272
|
-
|
|
271
|
+
<input type="radio" id="sasquatch" name="monster" value="S" />
|
|
272
|
+
<label for="sasquatch">Sasquatch</label><br />
|
|
273
273
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
274
|
+
<input type="radio" id="mothman" name="monster" value="M" />
|
|
275
|
+
<label for="mothman">Mothman</label>
|
|
276
|
+
</fieldset>
|
|
277
277
|
</form>
|
|
278
278
|
```
|
|
279
279
|
|
|
@@ -331,7 +331,10 @@ avec du texte pour les non-voyants.
|
|
|
331
331
|
// ... vos composants foehn-* utilisés dans le template
|
|
332
332
|
],
|
|
333
333
|
})
|
|
334
|
-
export class PageOneComponent
|
|
334
|
+
export class PageOneComponent
|
|
335
|
+
extends AbstractPageComponent<BusinessForm>
|
|
336
|
+
implements OnInit
|
|
337
|
+
{
|
|
335
338
|
ngOnInit(): void {
|
|
336
339
|
super.ngOnInit();
|
|
337
340
|
// point (2) : ajoutera le titre h1
|
|
@@ -361,7 +364,10 @@ export class PageOneComponent extends AbstractPageComponent<BusinessForm> implem
|
|
|
361
364
|
<div class="row">
|
|
362
365
|
<div class="col-md-8">
|
|
363
366
|
<!-- point (5) : toujours avoir un <h2> en premier dans votre page -->
|
|
364
|
-
<h2>
|
|
367
|
+
<h2>
|
|
368
|
+
{{ 'La_clé_du_dictionnaire_de_votre_titre_H2_ici' |
|
|
369
|
+
fromDictionary }}
|
|
370
|
+
</h2>
|
|
365
371
|
|
|
366
372
|
<!-- [VOS COMPOSANTS FOEHN ICI] -->
|
|
367
373
|
|
|
@@ -390,13 +396,21 @@ export const routes: Routes = [
|
|
|
390
396
|
component: PageWrapperComponent,
|
|
391
397
|
data: { root: true },
|
|
392
398
|
children: [
|
|
393
|
-
{
|
|
399
|
+
{
|
|
400
|
+
path: '',
|
|
401
|
+
component: PageOneComponent,
|
|
402
|
+
canActivate: [GesdemLoaderGuard],
|
|
403
|
+
},
|
|
394
404
|
{ path: '404', component: FoehnNotfoundComponent },
|
|
395
405
|
{ path: 'erreur', component: GesdemErrorComponent },
|
|
396
406
|
{
|
|
397
407
|
path: ':reference',
|
|
398
408
|
children: [
|
|
399
|
-
{
|
|
409
|
+
{
|
|
410
|
+
path: 'page-1',
|
|
411
|
+
component: PageOneComponent,
|
|
412
|
+
data: { order: 1 },
|
|
413
|
+
},
|
|
400
414
|
// {...},
|
|
401
415
|
// ...
|
|
402
416
|
{ path: 'erreur', component: GesdemErrorComponent },
|
|
@@ -431,7 +445,9 @@ export const routes: Routes = [
|
|
|
431
445
|
{
|
|
432
446
|
path: 'welcome',
|
|
433
447
|
loadChildren: () =>
|
|
434
|
-
import('./modules/welcome/welcome.routes').then(
|
|
448
|
+
import('./modules/welcome/welcome.routes').then(
|
|
449
|
+
(m) => m.welcome_routes,
|
|
450
|
+
),
|
|
435
451
|
},
|
|
436
452
|
{
|
|
437
453
|
path: 'inscription',
|
|
@@ -443,7 +459,11 @@ export const routes: Routes = [
|
|
|
443
459
|
// {...},
|
|
444
460
|
// ...
|
|
445
461
|
// recovery link should redirect to /inscription/reference
|
|
446
|
-
{
|
|
462
|
+
{
|
|
463
|
+
path: ':reference',
|
|
464
|
+
redirectTo: 'inscription/:reference',
|
|
465
|
+
pathMatch: 'full',
|
|
466
|
+
},
|
|
447
467
|
{ path: '', redirectTo: 'welcome', pathMatch: 'full' },
|
|
448
468
|
{ path: '404', component: FoehnNotfoundComponent },
|
|
449
469
|
{ path: '**', redirectTo: '/404', pathMatch: 'full' },
|
|
@@ -475,12 +495,20 @@ export const inscription_routes: Routes = [
|
|
|
475
495
|
path: '',
|
|
476
496
|
data: { root: true },
|
|
477
497
|
children: [
|
|
478
|
-
{
|
|
498
|
+
{
|
|
499
|
+
path: '',
|
|
500
|
+
component: PageOneComponent,
|
|
501
|
+
canActivate: [GesdemLoaderGuard],
|
|
502
|
+
},
|
|
479
503
|
{ path: 'erreur', component: GesdemErrorComponent },
|
|
480
504
|
{
|
|
481
505
|
path: ':reference',
|
|
482
506
|
children: [
|
|
483
|
-
{
|
|
507
|
+
{
|
|
508
|
+
path: 'page-1',
|
|
509
|
+
component: PageOneComponent,
|
|
510
|
+
data: { order: 1 },
|
|
511
|
+
},
|
|
484
512
|
// {...},
|
|
485
513
|
// ...
|
|
486
514
|
{ path: 'erreur', component: GesdemErrorComponent },
|
|
@@ -599,7 +627,11 @@ export class InputDateComponent extends FoehnInputComponent<number[]> {
|
|
|
599
627
|
|
|
600
628
|
// point (8)
|
|
601
629
|
getValidValue(): number[] | null | undefined {
|
|
602
|
-
if (
|
|
630
|
+
if (
|
|
631
|
+
this.isEmpty(this.day) &&
|
|
632
|
+
this.isEmpty(this.month) &&
|
|
633
|
+
this.isEmpty(this.year)
|
|
634
|
+
) {
|
|
603
635
|
if (this.model_ !== undefined) {
|
|
604
636
|
return null;
|
|
605
637
|
}
|
|
@@ -607,7 +639,11 @@ export class InputDateComponent extends FoehnInputComponent<number[]> {
|
|
|
607
639
|
return undefined;
|
|
608
640
|
}
|
|
609
641
|
|
|
610
|
-
return [
|
|
642
|
+
return [
|
|
643
|
+
this.toNumber(this.year),
|
|
644
|
+
this.toNumber(this.month),
|
|
645
|
+
this.toNumber(this.day),
|
|
646
|
+
];
|
|
611
647
|
}
|
|
612
648
|
|
|
613
649
|
// ...code
|
|
@@ -694,15 +730,17 @@ Chaque `foehn-input-*` utilisé dans votre vue doit :
|
|
|
694
730
|
>
|
|
695
731
|
<!-- (facultatif) Seulement si vous souhaitez afficher un label/legend global à votre composant -->
|
|
696
732
|
@if (!!label()) {
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
733
|
+
<legend
|
|
734
|
+
[class.visually-hidden]="isLabelSrOnly()"
|
|
735
|
+
[class.vd-p]="!isLabelSrOnly()"
|
|
736
|
+
>
|
|
737
|
+
<span [innerHTML]="label()"></span>
|
|
738
|
+
@if (!required() && !hideNotRequiredExtraLabel()) {
|
|
739
|
+
<span aria-hidden="true"
|
|
740
|
+
>{{ 'foehn-input.optional' | fromDictionary }}</span
|
|
700
741
|
>
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
<span aria-hidden="true">{{ 'foehn-input.optional' | fromDictionary }}</span>
|
|
704
|
-
}
|
|
705
|
-
</legend>
|
|
742
|
+
}
|
|
743
|
+
</legend>
|
|
706
744
|
}
|
|
707
745
|
|
|
708
746
|
<!-- (obligatoire) -->
|
|
@@ -710,11 +748,11 @@ Chaque `foehn-input-*` utilisé dans votre vue doit :
|
|
|
710
748
|
|
|
711
749
|
<!-- (facultatif) Seulement si vous souhaitez pouvoir afficher un helpText global au composant -->
|
|
712
750
|
@if (helpText()) {
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
751
|
+
<small
|
|
752
|
+
[attr.id]="buildId() + 'Help'"
|
|
753
|
+
class="text-secondary"
|
|
754
|
+
[innerHTML]="helpText()"
|
|
755
|
+
></small>
|
|
718
756
|
}
|
|
719
757
|
|
|
720
758
|
<!-- ...vos foehn-input-* ici -->
|
|
@@ -769,13 +807,18 @@ Voici un exemple de page de formulaire contenant cette méthode (1) :
|
|
|
769
807
|
// ... vos composants foehn-*
|
|
770
808
|
],
|
|
771
809
|
})
|
|
772
|
-
export class VotrePageComponent
|
|
810
|
+
export class VotrePageComponent
|
|
811
|
+
extends AbstractPageComponent<BusinessForm>
|
|
812
|
+
implements OnInit
|
|
813
|
+
{
|
|
773
814
|
// vos propres dépendances : inject() au lieu du constructor
|
|
774
815
|
private readonly metaService = inject(MetaService);
|
|
775
816
|
|
|
776
817
|
ngOnInit(): void {
|
|
777
818
|
super.ngOnInit();
|
|
778
|
-
this.setPageTitle(
|
|
819
|
+
this.setPageTitle(
|
|
820
|
+
this._dictionaryService.getKeySync('votre-page.title'),
|
|
821
|
+
);
|
|
779
822
|
}
|
|
780
823
|
|
|
781
824
|
newForm(): BusinessForm {
|
|
@@ -889,37 +932,38 @@ devra lui aussi remonter l'événement.
|
|
|
889
932
|
tabindex="-1"
|
|
890
933
|
>
|
|
891
934
|
@if (label() && type() !== 'hidden') {
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
935
|
+
<label
|
|
936
|
+
[attr.for]="buildChildId()"
|
|
937
|
+
[class]="'form-label ' + (isLabelSrOnly() ? 'visually-hidden' : (labelStyleModifier() ?? ''))"
|
|
938
|
+
>
|
|
939
|
+
{{ label() }} @if (!required() && !hideNotRequiredExtraLabel()) {
|
|
940
|
+
<span aria-hidden="true"
|
|
941
|
+
>{{ 'foehn-input.optional' | fromDictionary }}</span
|
|
895
942
|
>
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
<span aria-hidden="true">{{ 'foehn-input.optional' | fromDictionary }}</span>
|
|
899
|
-
}
|
|
900
|
-
</label>
|
|
943
|
+
}
|
|
944
|
+
</label>
|
|
901
945
|
}
|
|
902
946
|
|
|
903
947
|
<foehn-validation-alerts [component]="this" />
|
|
904
948
|
|
|
905
949
|
@if (helpText()) {
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
950
|
+
<small
|
|
951
|
+
[attr.id]="buildChildId() + 'Help'"
|
|
952
|
+
class="form-text text-secondary"
|
|
953
|
+
[innerHTML]="helpText()"
|
|
954
|
+
></small>
|
|
911
955
|
}
|
|
912
956
|
|
|
913
957
|
<!-- (1) votre boucle @for + track (identifiant unique) -->
|
|
914
958
|
@for (vehicule of vehicules; track vehicule.id; let i = $index) {
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
959
|
+
<!-- (2) votre composant réutilisable -->
|
|
960
|
+
<app-vehicule-item
|
|
961
|
+
[name]="name() + '[' + i + ']'"
|
|
962
|
+
[(model)]="vehicule"
|
|
963
|
+
(modelChange)="updateVehiculesList($event, i)"
|
|
964
|
+
(userInput)="handleUserInput($event, i)"
|
|
965
|
+
(removedVehicule)="handleRemovedVehicule(i)"
|
|
966
|
+
/>
|
|
923
967
|
}
|
|
924
968
|
|
|
925
969
|
<button class="btn btn-primary mt-2" (click)="addVehicule()">
|
|
@@ -992,7 +1036,11 @@ l'événement de suppression (2).
|
|
|
992
1036
|
/>
|
|
993
1037
|
<!-- (1) Utilisation de votre liste - (2) Appel de la méthode qui sauvegardera les données dans GESDEM afin de rafraîchir les erreurs -->
|
|
994
1038
|
|
|
995
|
-
<foehn-navigation
|
|
1039
|
+
<foehn-navigation
|
|
1040
|
+
id="navigation"
|
|
1041
|
+
(onPrevious)="previous()"
|
|
1042
|
+
(onNext)="send()"
|
|
1043
|
+
/>
|
|
996
1044
|
</foehn-form>
|
|
997
1045
|
```
|
|
998
1046
|
|
|
@@ -1003,7 +1051,10 @@ formulaire et ainsi rafraîchir l'index.
|
|
|
1003
1051
|
@Component({
|
|
1004
1052
|
// ...
|
|
1005
1053
|
})
|
|
1006
|
-
export class DemandePageComponent
|
|
1054
|
+
export class DemandePageComponent
|
|
1055
|
+
extends AbstractPageComponent<BusinessForm>
|
|
1056
|
+
implements OnInit
|
|
1057
|
+
{
|
|
1007
1058
|
// ...code
|
|
1008
1059
|
|
|
1009
1060
|
handleRemovedVehicule(): void {
|
|
@@ -1066,10 +1117,7 @@ export class BusinessForm {
|
|
|
1066
1117
|
name="identification.lastName"
|
|
1067
1118
|
/>
|
|
1068
1119
|
|
|
1069
|
-
<foehn-boolean-checkbox
|
|
1070
|
-
[(model)]="form.acceptCookies"
|
|
1071
|
-
name="acceptCookies"
|
|
1072
|
-
/>
|
|
1120
|
+
<foehn-boolean-checkbox [(model)]="form.acceptCookies" name="acceptCookies" />
|
|
1073
1121
|
<!-- 1 niveau de profondeur -->
|
|
1074
1122
|
```
|
|
1075
1123
|
|
package/UPGRADING_V18.md
CHANGED
|
@@ -458,6 +458,7 @@ npm install @angular/cli@19 -g
|
|
|
458
458
|
ng update typescript@5.5
|
|
459
459
|
ng update @dsivd/prestations-ng@18
|
|
460
460
|
```
|
|
461
|
+
|
|
461
462
|
NB: You might need to use the --force option.
|
|
462
463
|
|
|
463
464
|
When asked the question "Select the migrations that you'd like to run", accept "provide-initializer" by hitting "Space" key then "Enter".
|
package/UPGRADING_V19.md
CHANGED
|
@@ -11,6 +11,9 @@ From here on, we are in the root folder of your project, for example ~/git/cybsd
|
|
|
11
11
|
|
|
12
12
|
### Spring Boot 4
|
|
13
13
|
|
|
14
|
+
NB : if the following instructions (jdk25 + latest parent + openrewrite) are not working fine, you can also try to
|
|
15
|
+
do in the reverse order : in jdk21 do the rewrite commands, then switch to jdk25 and latest parent.
|
|
16
|
+
|
|
14
17
|
You can switch to Java 25 `jdk25` + change in IntelliJ: right-click on your project > Open Module Settings > Project > set "SDK" to `jdk25` from devtools and "Language
|
|
15
18
|
level" to `25` in "Modules"
|
|
16
19
|
|
|
@@ -78,6 +81,17 @@ if you use ldap, you should replace `spring-ldap-core` by `spring-boot-starter-l
|
|
|
78
81
|
</dependency>
|
|
79
82
|
```
|
|
80
83
|
|
|
84
|
+
### ORACLE
|
|
85
|
+
|
|
86
|
+
if you use oracle, you should replace `ojdbc10` by `ojdbc17` in your `pom.xml` and let the spring boot parent set the version
|
|
87
|
+
|
|
88
|
+
```xml
|
|
89
|
+
<dependency>
|
|
90
|
+
<groupId>com.oracle.database.jdbc</groupId>
|
|
91
|
+
<artifactId>ojdbc17</artifactId>
|
|
92
|
+
</dependency>
|
|
93
|
+
```
|
|
94
|
+
|
|
81
95
|
### Jackson migration
|
|
82
96
|
|
|
83
97
|
With Spring Boot 4, Jackson 3 is now used instead of Jackson 2, so we need to replace the previous Jackson 2 classes.
|
|
@@ -857,7 +871,7 @@ ng generate @angular/core:signal-input-migration --insert-todos
|
|
|
857
871
|
[Angular migration guide: migrating to Vitest](https://angular.dev/guide/testing/migrating-to-vitest)
|
|
858
872
|
|
|
859
873
|
```bash
|
|
860
|
-
npm install --save-dev vitest jsdom
|
|
874
|
+
npm install --save-dev vitest@4.0 jsdom
|
|
861
875
|
```
|
|
862
876
|
|
|
863
877
|
In your `angular.json` file, remove `"zone.js/dist/zone-error"` from `"allowedCommonJsDependencies"`
|
|
@@ -1396,7 +1410,7 @@ npm uninstall @angular/animations
|
|
|
1396
1410
|
|
|
1397
1411
|
### Add missing `^` or `~` in `package.json` devDependencies
|
|
1398
1412
|
|
|
1399
|
-
Check you devDependencies in your `package.json` file and add `^` in front of every version number if missing excepted for `typescript` where you should add `~`. Then run:
|
|
1413
|
+
Check you devDependencies in your `package.json` file and add `^` in front of every version number if missing excepted for `typescript` and `vitest` where you should add `~`. Then run:
|
|
1400
1414
|
|
|
1401
1415
|
```bash
|
|
1402
1416
|
npm install
|
|
@@ -1416,6 +1430,25 @@ When using `IntelliJ`, you can run code inspection on your project to fix deprec
|
|
|
1416
1430
|
- IntelliJ window menu, go to: `Code > Analyze code > Run inspection by name...` (or **Ctrl+Alt+Maj+i**) and type `Deprecated symbol used`.
|
|
1417
1431
|
- Or select your project in your project panel and `right click` on it then `Analyze > Run inspection by name...` (or **Ctrl+Alt+Maj+i**) and type `Deprecated symbol used`.
|
|
1418
1432
|
|
|
1433
|
+
### Strict mode (optional when migrating large projects but recommended)
|
|
1434
|
+
|
|
1435
|
+
- In your `tsconfig.json` file, add `"strict": true` in `compilerOptions` and remove `alwaysStrict`, `noImplicitThis`, `strictBindCallApply` and `strictFunctionTypes` as they are already included in `strict` mode.
|
|
1436
|
+
- In your `tsconfig.json` file, remove `useDefineForClassFields` from `compilerOptions`.
|
|
1437
|
+
|
|
1438
|
+
Now fix your project until no more errors:
|
|
1439
|
+
|
|
1440
|
+
```bash
|
|
1441
|
+
npx tsc -b --noEmit
|
|
1442
|
+
```
|
|
1443
|
+
|
|
1444
|
+
and finally run the following commands to build, test and start your application:
|
|
1445
|
+
|
|
1446
|
+
```bash
|
|
1447
|
+
npm run build
|
|
1448
|
+
npm run test
|
|
1449
|
+
npm start
|
|
1450
|
+
```
|
|
1451
|
+
|
|
1419
1452
|
### Last but not least, check if your application is working!!!
|
|
1420
1453
|
|
|
1421
1454
|
#### Be sure your application gets a fresh start
|
|
@@ -1465,3 +1498,11 @@ See [getImtPortailApplications](https://dsigit.etat-de-vaud.ch/outils/git/projec
|
|
|
1465
1498
|
|
|
1466
1499
|
Enroll your project in Renovate bot to automatically update your dependencies.
|
|
1467
1500
|
See [Mend Renovate CE](https://dgnsiwiki.etat-de-vaud.ch/outils/dgnsiwiki/x/7QFDgg) for more information.
|
|
1501
|
+
|
|
1502
|
+
update renovate.json :
|
|
1503
|
+
|
|
1504
|
+
```json
|
|
1505
|
+
{
|
|
1506
|
+
"extends": ["local>PEE/renovate-config"]
|
|
1507
|
+
}
|
|
1508
|
+
```
|
|
Binary file
|
package/eslint/signal-names.mjs
CHANGED
|
@@ -153,6 +153,67 @@ const reExportedModulesOf = (sourceFile) =>
|
|
|
153
153
|
.filter((statement) => ts.isExportDeclaration(statement) && statement.moduleSpecifier)
|
|
154
154
|
.map((statement) => statement.moduleSpecifier.text);
|
|
155
155
|
|
|
156
|
+
const classDeclarationsOf = (sourceFile, className) =>
|
|
157
|
+
className
|
|
158
|
+
? [findClass(sourceFile, className)].filter(Boolean)
|
|
159
|
+
: sourceFile.statements.filter(ts.isClassDeclaration);
|
|
160
|
+
|
|
161
|
+
const isBarrelMiss = (className, classDeclarations) =>
|
|
162
|
+
Boolean(className) && classDeclarations.length === 0;
|
|
163
|
+
|
|
164
|
+
const collectFromReExports = (sourceFile, path, className, kinds, visited) => {
|
|
165
|
+
for (const specifier of reExportedModulesOf(sourceFile)) {
|
|
166
|
+
const target = resolveModule(specifier, path);
|
|
167
|
+
if (target) {
|
|
168
|
+
collect(target, className, kinds, visited);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const addMemberKindIfEligible = (member, kinds) => {
|
|
174
|
+
if (!member.name || !ts.isIdentifier(member.name)) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const kind = kindOfMember(member);
|
|
178
|
+
// A subclass overriding a member wins: it is collected first.
|
|
179
|
+
if (kind && !kinds.has(member.name.text)) {
|
|
180
|
+
kinds.set(member.name.text, kind);
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const collectMemberKinds = (classDeclaration, kinds) => {
|
|
185
|
+
for (const member of classDeclaration.members) {
|
|
186
|
+
addMemberKindIfEligible(member, kinds);
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const baseTargetOf = (sourceFile, path, classDeclaration) => {
|
|
191
|
+
const baseName = extendedClassNameOf(classDeclaration);
|
|
192
|
+
if (!baseName) {
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Declaration bundles are flattened: the base class often sits in the same file.
|
|
197
|
+
if (findClass(sourceFile, baseName)) {
|
|
198
|
+
return { path, className: baseName };
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const imported = importOf(sourceFile, baseName);
|
|
202
|
+
if (!imported) {
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const target = resolveModule(imported.specifier, path);
|
|
207
|
+
return target ? { path: target, className: imported.exportedName } : undefined;
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
const collectBase = (sourceFile, path, classDeclaration, kinds, visited) => {
|
|
211
|
+
const target = baseTargetOf(sourceFile, path, classDeclaration);
|
|
212
|
+
if (target) {
|
|
213
|
+
collect(target.path, target.className, kinds, visited);
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
|
|
156
217
|
const collect = (path, className, kinds, visited) => {
|
|
157
218
|
const key = `${path}::${className ?? "*"}`;
|
|
158
219
|
if (visited.has(key)) {
|
|
@@ -165,47 +226,17 @@ const collect = (path, className, kinds, visited) => {
|
|
|
165
226
|
return;
|
|
166
227
|
}
|
|
167
228
|
|
|
168
|
-
const classDeclarations = className
|
|
169
|
-
? [findClass(sourceFile, className)].filter(Boolean)
|
|
170
|
-
: sourceFile.statements.filter(ts.isClassDeclaration);
|
|
229
|
+
const classDeclarations = classDeclarationsOf(sourceFile, className);
|
|
171
230
|
|
|
172
231
|
// A barrel: the class is only re-exported from here.
|
|
173
|
-
if (className
|
|
174
|
-
|
|
175
|
-
const target = resolveModule(specifier, path);
|
|
176
|
-
if (target) {
|
|
177
|
-
collect(target, className, kinds, visited);
|
|
178
|
-
}
|
|
179
|
-
}
|
|
232
|
+
if (isBarrelMiss(className, classDeclarations)) {
|
|
233
|
+
collectFromReExports(sourceFile, path, className, kinds, visited);
|
|
180
234
|
return;
|
|
181
235
|
}
|
|
182
236
|
|
|
183
237
|
for (const classDeclaration of classDeclarations) {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
continue;
|
|
187
|
-
}
|
|
188
|
-
const kind = kindOfMember(member);
|
|
189
|
-
// A subclass overriding a member wins: it is collected first.
|
|
190
|
-
if (kind && !kinds.has(member.name.text)) {
|
|
191
|
-
kinds.set(member.name.text, kind);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
const baseName = extendedClassNameOf(classDeclaration);
|
|
196
|
-
if (!baseName) {
|
|
197
|
-
continue;
|
|
198
|
-
}
|
|
199
|
-
// Declaration bundles are flattened: the base class often sits in the same file.
|
|
200
|
-
if (findClass(sourceFile, baseName)) {
|
|
201
|
-
collect(path, baseName, kinds, visited);
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
const imported = importOf(sourceFile, baseName);
|
|
205
|
-
const target = imported && resolveModule(imported.specifier, path);
|
|
206
|
-
if (target) {
|
|
207
|
-
collect(target, imported.exportedName, kinds, visited);
|
|
208
|
-
}
|
|
238
|
+
collectMemberKinds(classDeclaration, kinds);
|
|
239
|
+
collectBase(sourceFile, path, classDeclaration, kinds, visited);
|
|
209
240
|
}
|
|
210
241
|
};
|
|
211
242
|
|