From fa2875d656f04cdadb8cbbec4edaf9e6d61cba61 Mon Sep 17 00:00:00 2001 From: Dominik Rabij Date: Fri, 21 Feb 2025 19:11:53 +0100 Subject: [PATCH 01/14] fix(youtube-player): Remove `as any` cast --- src/youtube-player/youtube-player.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/youtube-player/youtube-player.ts b/src/youtube-player/youtube-player.ts index 398b8d8711bc..4a707c1f0204 100644 --- a/src/youtube-player/youtube-player.ts +++ b/src/youtube-player/youtube-player.ts @@ -759,7 +759,7 @@ function loadApi(nonce: string | null): void { }; script.addEventListener('load', callback); script.addEventListener('error', callback); - (script as any).src = url; + script.src = url; script.async = true; if (nonce) { From cf415ea86c454b03da52ed921414c032bb8e9c78 Mon Sep 17 00:00:00 2001 From: Dominik Rabij Date: Fri, 28 Feb 2025 10:12:28 +0100 Subject: [PATCH 02/14] fix(youtube-player): Eliminate `any` casts --- src/youtube-player/fake-youtube-player.ts | 30 +++++++++++------------ src/youtube-player/youtube-player.spec.ts | 20 ++++++++------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/youtube-player/fake-youtube-player.ts b/src/youtube-player/fake-youtube-player.ts index b48368359b2c..c4158828ed7b 100644 --- a/src/youtube-player/fake-youtube-player.ts +++ b/src/youtube-player/fake-youtube-player.ts @@ -63,7 +63,7 @@ export function createFakeYtNamespace(): FakeYtNamespace { ]); let playerConfig: YT.PlayerOptions | undefined; - const boundListeners = new Map void>>(); + const boundListeners = new Map void>>(); const playerCtorSpy = jasmine.createSpy('Player Constructor'); // The spy target function cannot be an arrow-function as this breaks when created through `new`. @@ -72,18 +72,20 @@ export function createFakeYtNamespace(): FakeYtNamespace { return playerSpy; }); - playerSpy.addEventListener.and.callFake((name: keyof YT.Events, listener: (e: any) => any) => { - if (!boundListeners.has(name)) { - boundListeners.set(name, new Set()); - } - boundListeners.get(name)!.add(listener); - }); + playerSpy.addEventListener.and.callFake( + (name: keyof YT.Events, listener: (e: unknown) => unknown) => { + if (!boundListeners.has(name)) { + boundListeners.set(name, new Set()); + } + boundListeners.get(name)!.add(listener); + }, + ); - playerSpy.removeEventListener.and.callFake((name: keyof YT.Events, listener: (e: any) => any) => { - if (boundListeners.has(name)) { - boundListeners.get(name)!.delete(listener); - } - }); + playerSpy.removeEventListener.and.callFake( + (name: keyof YT.Events, listener: (e: unknown) => unknown) => { + boundListeners.get(name)?.delete(listener); + }, + ); function eventHandlerFactory(name: keyof YT.Events) { return (arg: Object = {}) => { @@ -91,9 +93,7 @@ export function createFakeYtNamespace(): FakeYtNamespace { throw new Error(`Player not initialized before ${name} called`); } - if (boundListeners.has(name)) { - boundListeners.get(name)!.forEach(callback => callback(arg)); - } + boundListeners.get(name)?.forEach(callback => callback(arg)); }; } diff --git a/src/youtube-player/youtube-player.spec.ts b/src/youtube-player/youtube-player.spec.ts index 757baf8bf435..b0cfafebdb2a 100644 --- a/src/youtube-player/youtube-player.spec.ts +++ b/src/youtube-player/youtube-player.spec.ts @@ -10,8 +10,10 @@ import { } from './youtube-player'; import {PlaceholderImageQuality} from './youtube-player-placeholder'; +declare var window: Window; + const VIDEO_ID = 'a12345'; -const YT_LOADING_STATE_MOCK = {loading: 1, loaded: 0}; +const YT_LOADING_STATE_MOCK = {loading: 1, loaded: 0} as unknown as typeof YT; const TEST_PROVIDERS: (Provider | EnvironmentProviders)[] = [ { provide: YOUTUBE_PLAYER_CONFIG, @@ -56,7 +58,7 @@ describe('YoutubePlayer', () => { }); afterEach(() => { - (window as any).YT = undefined; + window.YT = undefined; window.onYouTubeIframeAPIReady = undefined; }); @@ -540,17 +542,17 @@ describe('YoutubePlayer', () => { let api: typeof YT; beforeEach(() => { - api = window.YT; - (window as any).YT = undefined; + api = window.YT!; + window.YT = undefined; }); afterEach(() => { - (window as any).YT = undefined; + window.YT = undefined; window.onYouTubeIframeAPIReady = undefined; }); it('waits until the api is ready before initializing', () => { - (window.YT as any) = YT_LOADING_STATE_MOCK; + window.YT = YT_LOADING_STATE_MOCK; TestBed.configureTestingModule({providers: TEST_PROVIDERS}); fixture = TestBed.createComponent(TestApp); testComponent = fixture.debugElement.componentInstance; @@ -560,7 +562,7 @@ describe('YoutubePlayer', () => { expect(playerCtorSpy).not.toHaveBeenCalled(); - window.YT = api!; + window.YT = api; window.onYouTubeIframeAPIReady!(); expect(playerCtorSpy).toHaveBeenCalledWith( @@ -585,7 +587,7 @@ describe('YoutubePlayer', () => { expect(playerCtorSpy).not.toHaveBeenCalled(); - window.YT = api!; + window.YT = api; window.onYouTubeIframeAPIReady!(); expect(spy).toHaveBeenCalled(); @@ -601,7 +603,7 @@ describe('YoutubePlayer', () => { }); afterEach(() => { - fixture = testComponent = (window as any).YT = window.onYouTubeIframeAPIReady = undefined!; + fixture = testComponent = window.YT = window.onYouTubeIframeAPIReady = undefined!; }); it('should show a placeholder', () => { From 5b393302dac0c8ded72146f3cd53ea48ce630417 Mon Sep 17 00:00:00 2001 From: Dominik Rabij Date: Fri, 28 Feb 2025 11:01:55 +0100 Subject: [PATCH 03/14] fix(universal-app): ngDevMode always defined in hydration e2e test --- src/universal-app/hydration.e2e.spec.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/universal-app/hydration.e2e.spec.ts b/src/universal-app/hydration.e2e.spec.ts index 974b1fcd289d..634f280b4a54 100644 --- a/src/universal-app/hydration.e2e.spec.ts +++ b/src/universal-app/hydration.e2e.spec.ts @@ -1,5 +1,11 @@ import {browser, by, element, ExpectedConditions} from 'protractor'; +// Expect `ngDevMode` to be always set: +declare const ngDevMode: { + hydratedComponents: number; + componentsSkippedHydration: number; +}; + describe('hydration e2e', () => { beforeEach(async () => { await browser.waitForAngularEnabled(false); @@ -27,7 +33,7 @@ async function getHydrationState() { hydratedComponents: number; componentsSkippedHydration: number; }>(() => ({ - hydratedComponents: (window as any).ngDevMode.hydratedComponents, - componentsSkippedHydration: (window as any).ngDevMode.componentsSkippedHydration, + hydratedComponents: ngDevMode.hydratedComponents, + componentsSkippedHydration: ngDevMode.componentsSkippedHydration, })); } From 87cb4516ad0c90fa9fea84780204e1295f068184 Mon Sep 17 00:00:00 2001 From: Dominik Rabij Date: Fri, 28 Feb 2025 11:12:21 +0100 Subject: [PATCH 04/14] fix(google-maps): Replace any types with unknown --- src/google-maps/map-event-manager.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/google-maps/map-event-manager.ts b/src/google-maps/map-event-manager.ts index 0a85bc8fb39f..ceb290607b90 100644 --- a/src/google-maps/map-event-manager.ts +++ b/src/google-maps/map-event-manager.ts @@ -14,7 +14,7 @@ type MapEventManagerTarget = | { addListener: ( name: string, - callback: (...args: any[]) => void, + callback: (...args: unknown[]) => void, ) => google.maps.MapsEventListener | undefined; } | undefined; @@ -22,7 +22,7 @@ type MapEventManagerTarget = /** Manages event on a Google Maps object, ensuring that events are added only when necessary. */ export class MapEventManager { /** Pending listeners that were added before the target was set. */ - private _pending: {observable: Observable; observer: Subscriber}[] = []; + private _pending: {observable: Observable; observer: Subscriber}[] = []; private _listeners: google.maps.MapsEventListener[] = []; private _targetStream = new BehaviorSubject(undefined); @@ -48,8 +48,8 @@ export class MapEventManager { return undefined; } - const listener = target.addListener(name, (event: T) => { - this._ngZone.run(() => observer.next(event)); + const listener = target.addListener(name, (event: unknown) => { + this._ngZone.run(() => observer.next(event as T)); }); // If there's an error when initializing the Maps API (e.g. a wrong API key), it will From 63efb27e47f7ce2bb86dab81844903386346b12f Mon Sep 17 00:00:00 2001 From: Dominik Rabij Date: Fri, 28 Feb 2025 11:18:09 +0100 Subject: [PATCH 05/14] fix(universal-app): Add ElementItem interface --- src/universal-app/kitchen-sink/kitchen-sink.ts | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/universal-app/kitchen-sink/kitchen-sink.ts b/src/universal-app/kitchen-sink/kitchen-sink.ts index f4050a3d4a16..ca89fb4af5e0 100644 --- a/src/universal-app/kitchen-sink/kitchen-sink.ts +++ b/src/universal-app/kitchen-sink/kitchen-sink.ts @@ -61,8 +61,15 @@ import {MatTooltipModule} from '@angular/material/tooltip'; import {YouTubePlayer} from '@angular/youtube-player'; import {Observable, of as observableOf} from 'rxjs'; -export class TableDataSource extends DataSource { - connect(): Observable { +interface ElementItem { + position: number; + name: string; + weight: number; + symbol: string; +} + +export class TableDataSource extends DataSource { + connect(): Observable> { return observableOf([ {position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H'}, {position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'}, @@ -77,7 +84,7 @@ export class TableDataSource extends DataSource { ]); } - disconnect() {} + override disconnect() {} } export const AUTOMATED_KITCHEN_SINK = new InjectionToken('AUTOMATED_KITCHEN_SINK'); From 4e5354c61d3f7e54e9b12a9cd13e198ac0613c48 Mon Sep 17 00:00:00 2001 From: Dominik Rabij Date: Fri, 28 Feb 2025 11:22:02 +0100 Subject: [PATCH 06/14] fix(material-moment-adapter): Replace any with unknowns --- .../adapter/moment-date-adapter.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/material-moment-adapter/adapter/moment-date-adapter.ts b/src/material-moment-adapter/adapter/moment-date-adapter.ts index cbf303d33958..f1b4ac96aff5 100644 --- a/src/material-moment-adapter/adapter/moment-date-adapter.ts +++ b/src/material-moment-adapter/adapter/moment-date-adapter.ts @@ -187,7 +187,7 @@ export class MomentDateAdapter extends DateAdapter { return this._createMoment().locale(this.locale); } - parse(value: any, parseFormat: string | string[]): Moment | null { + parse(value: unknown, parseFormat: string | string[]): Moment | null { if (value && typeof value == 'string') { return this._createMoment(value, parseFormat, this.locale); } @@ -223,7 +223,7 @@ export class MomentDateAdapter extends DateAdapter { * (https://www.ietf.org/rfc/rfc3339.txt) and valid Date objects into valid Moments and empty * string into null. Returns an invalid date for all other values. */ - override deserialize(value: any): Moment | null { + override deserialize(value: unknown): Moment | null { let date; if (value instanceof Date) { date = this._createMoment(value).locale(this.locale); @@ -243,7 +243,7 @@ export class MomentDateAdapter extends DateAdapter { return super.deserialize(value); } - isDateInstance(obj: any): boolean { + isDateInstance(obj: unknown): obj is Moment { return moment.isMoment(obj); } @@ -285,7 +285,7 @@ export class MomentDateAdapter extends DateAdapter { return date.seconds(); } - override parseTime(value: any, parseFormat: string | string[]): Moment | null { + override parseTime(value: unknown, parseFormat: string | string[]): Moment | null { return this.parse(value, parseFormat); } From 52fd2644860ccef93562d1807c04bccc4ee0ab24 Mon Sep 17 00:00:00 2001 From: Dominik Rabij Date: Fri, 28 Feb 2025 11:27:13 +0100 Subject: [PATCH 07/14] fix(material-luxon-adapter): Replace any with unknown --- src/material-luxon-adapter/adapter/luxon-date-adapter.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/material-luxon-adapter/adapter/luxon-date-adapter.ts b/src/material-luxon-adapter/adapter/luxon-date-adapter.ts index c465fd8d45a1..30d473b764b8 100644 --- a/src/material-luxon-adapter/adapter/luxon-date-adapter.ts +++ b/src/material-luxon-adapter/adapter/luxon-date-adapter.ts @@ -177,7 +177,7 @@ export class LuxonDateAdapter extends DateAdapter { return this._useUTC ? LuxonDateTime.utc(options) : LuxonDateTime.local(options); } - parse(value: any, parseFormat: string | string[]): LuxonDateTime | null { + parse(value: unknown, parseFormat: string | string[]): LuxonDateTime | null { const options: LuxonDateTimeOptions = this._getOptions(); if (typeof value == 'string' && value.length > 0) { @@ -245,7 +245,7 @@ export class LuxonDateAdapter extends DateAdapter { * (https://www.ietf.org/rfc/rfc3339.txt) and valid Date objects into valid DateTime and empty * string into null. Returns an invalid date for all other values. */ - override deserialize(value: any): LuxonDateTime | null { + override deserialize(value: unknown): LuxonDateTime | null { const options = this._getOptions(); let date: LuxonDateTime | undefined; if (value instanceof Date) { @@ -263,7 +263,7 @@ export class LuxonDateAdapter extends DateAdapter { return super.deserialize(value); } - isDateInstance(obj: any): boolean { + isDateInstance(obj: unknown): obj is LuxonDateTime { return obj instanceof LuxonDateTime; } @@ -315,7 +315,7 @@ export class LuxonDateAdapter extends DateAdapter { return date.second; } - override parseTime(value: any, parseFormat: string | string[]): LuxonDateTime | null { + override parseTime(value: unknown, parseFormat: string | string[]): LuxonDateTime | null { const result = this.parse(value, parseFormat); if ((!result || !this.isValid(result)) && typeof value === 'string') { From 245f18866c7534efae1bcfda67f5a1e93bac756c Mon Sep 17 00:00:00 2001 From: Dominik Rabij Date: Fri, 28 Feb 2025 11:28:40 +0100 Subject: [PATCH 08/14] fix(date-fns-adapter): Replace any with unknown --- src/material-date-fns-adapter/adapter/date-fns-adapter.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/material-date-fns-adapter/adapter/date-fns-adapter.ts b/src/material-date-fns-adapter/adapter/date-fns-adapter.ts index 29e3b9927c83..91e37fb1cc2d 100644 --- a/src/material-date-fns-adapter/adapter/date-fns-adapter.ts +++ b/src/material-date-fns-adapter/adapter/date-fns-adapter.ts @@ -161,7 +161,7 @@ export class DateFnsAdapter extends DateAdapter { return new Date(); } - parse(value: any, parseFormat: string | string[]): Date | null { + parse(value: unknown, parseFormat: string | string[]): Date | null { if (typeof value == 'string' && value.length > 0) { const iso8601Date = parseISO(value); @@ -222,7 +222,7 @@ export class DateFnsAdapter extends DateAdapter { * (https://www.ietf.org/rfc/rfc3339.txt) into valid Dates and empty string into null. Returns an * invalid date for all other values. */ - override deserialize(value: any): Date | null { + override deserialize(value: unknown): Date | null { if (typeof value === 'string') { if (!value) { return null; @@ -235,7 +235,7 @@ export class DateFnsAdapter extends DateAdapter { return super.deserialize(value); } - isDateInstance(obj: any): boolean { + isDateInstance(obj: unknown): obj is Date { return isDate(obj); } @@ -277,7 +277,7 @@ export class DateFnsAdapter extends DateAdapter { return getSeconds(date); } - override parseTime(value: any, parseFormat: string | string[]): Date | null { + override parseTime(value: unknown, parseFormat: string | string[]): Date | null { return this.parse(value, parseFormat); } From 34dedb038a5147cdda42f5940ce2437ef773e936 Mon Sep 17 00:00:00 2001 From: Dominik Rabij Date: Fri, 28 Feb 2025 12:30:57 +0100 Subject: [PATCH 09/14] fix(material-experimental/column-resize): Add NumberMatchers interface in tests --- .../column-resize/column-resize.spec.ts | 82 +++++++++---------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/src/material-experimental/column-resize/column-resize.spec.ts b/src/material-experimental/column-resize/column-resize.spec.ts index 045ad22c6d82..47ff9f13aa71 100644 --- a/src/material-experimental/column-resize/column-resize.spec.ts +++ b/src/material-experimental/column-resize/column-resize.spec.ts @@ -333,7 +333,7 @@ class ElementDataSource extends DataSource { } // There's 1px of variance between different browsers in terms of positioning. -const approximateMatcher = { +const approximateMatcher: jasmine.CustomMatcherFactories = { isApproximately: () => ({ compare: (actual: number, expected: number) => { const result = { @@ -348,6 +348,14 @@ const approximateMatcher = { }), }; +interface NumberMatchers extends jasmine.Matchers { + isApproximately(expected: number): void; + not: NumberMatchers; +} +declare global { + function expect(actual: number): NumberMatchers; +} + const testCases = [ [MatColumnResizeModule, MatResizeTest, 'opt-in table-based mat-table'], [MatColumnResizeModule, MatResizeOnPushTest, 'inside OnPush component'], @@ -409,12 +417,8 @@ describe('Material Popover Edit', () => { component.getOverlayThumbElement(2).classList.contains('mat-column-resize-overlay-thumb'), ).toBe(true); - (expect(component.getOverlayThumbElement(0).offsetHeight) as any).isApproximately( - headerRowHeight, - ); - (expect(component.getOverlayThumbElement(2).offsetHeight) as any).isApproximately( - headerRowHeight, - ); + expect(component.getOverlayThumbElement(0).offsetHeight).isApproximately(headerRowHeight); + expect(component.getOverlayThumbElement(2).offsetHeight).isApproximately(headerRowHeight); component.beginColumnResizeWithMouse(0); @@ -425,15 +429,11 @@ describe('Material Popover Edit', () => { component.getOverlayThumbElement(2).classList.contains('mat-column-resize-overlay-thumb'), ).toBe(true); - (expect(component.getOverlayThumbElement(0).offsetHeight) as any).isApproximately( - tableHeight, - ); - (expect(component.getOverlayThumbTopElement(0).offsetHeight) as any).isApproximately( - headerRowHeight, - ); - (expect(component.getOverlayThumbElement(2).offsetHeight) as any).isApproximately( + expect(component.getOverlayThumbElement(0).offsetHeight).isApproximately(tableHeight); + expect(component.getOverlayThumbTopElement(0).offsetHeight).isApproximately( headerRowHeight, ); + expect(component.getOverlayThumbElement(2).offsetHeight).isApproximately(headerRowHeight); component.completeResizeWithMouseInProgress(0); component.endHoverState(); @@ -462,15 +462,15 @@ describe('Material Popover Edit', () => { let columnPositionDelta = component.getColumnOriginPosition(1) - initialColumnPosition; // let nextColumnPositionDelta = // component.getColumnOriginPosition(2) - initialNextColumnPosition; - (expect(thumbPositionDelta) as any).isApproximately(columnPositionDelta); + expect(thumbPositionDelta).isApproximately(columnPositionDelta); // TODO: This was commented out after switching from the legacy table to the current // MDC-based table. This failed by being inaccurate by several pixels. - // (expect(nextColumnPositionDelta) as any).isApproximately(columnPositionDelta); + // expect(nextColumnPositionDelta).isApproximately(columnPositionDelta); // TODO: This was commented out after switching from the legacy table to the current // MDC-based table. This failed by being inaccurate by several pixels. - // (expect(component.getTableWidth()) as any).isApproximately(initialTableWidth + 5); - (expect(component.getColumnWidth(1)) as any).isApproximately(initialColumnWidth + 5); + // expect(component.getTableWidth()).isApproximately(initialTableWidth + 5); + expect(component.getColumnWidth(1)).isApproximately(initialColumnWidth + 5); component.updateResizeWithMouseInProgress(1); fixture.detectChanges(); @@ -478,15 +478,15 @@ describe('Material Popover Edit', () => { thumbPositionDelta = component.getOverlayThumbPosition(1) - initialThumbPosition; columnPositionDelta = component.getColumnOriginPosition(1) - initialColumnPosition; - (expect(thumbPositionDelta) as any).isApproximately(columnPositionDelta); + expect(thumbPositionDelta).isApproximately(columnPositionDelta); - (expect(component.getTableWidth()) as any).isApproximately(initialTableWidth + 1); - (expect(component.getColumnWidth(1)) as any).isApproximately(initialColumnWidth + 1); + expect(component.getTableWidth()).isApproximately(initialTableWidth + 1); + expect(component.getColumnWidth(1)).isApproximately(initialColumnWidth + 1); component.completeResizeWithMouseInProgress(1); flush(); - (expect(component.getColumnWidth(1)) as any).isApproximately(initialColumnWidth + 1); + expect(component.getColumnWidth(1)).isApproximately(initialColumnWidth + 1); component.endHoverState(); fixture.detectChanges(); @@ -508,8 +508,8 @@ describe('Material Popover Edit', () => { flush(); let thumbPositionDelta = component.getOverlayThumbPosition(1) - initialThumbPosition; - (expect(thumbPositionDelta) as any).isApproximately(5); - (expect(component.getColumnWidth(1)) as any).toBe(initialColumnWidth); + expect(thumbPositionDelta).isApproximately(5); + expect(component.getColumnWidth(1)).toBe(initialColumnWidth); component.updateResizeWithMouseInProgress(1); fixture.detectChanges(); @@ -517,14 +517,14 @@ describe('Material Popover Edit', () => { thumbPositionDelta = component.getOverlayThumbPosition(1) - initialThumbPosition; - (expect(component.getTableWidth()) as any).toBe(initialTableWidth); - (expect(component.getColumnWidth(1)) as any).toBe(initialColumnWidth); + expect(component.getTableWidth()).toBe(initialTableWidth); + expect(component.getColumnWidth(1)).toBe(initialColumnWidth); component.completeResizeWithMouseInProgress(1); flush(); - (expect(component.getTableWidth()) as any).isApproximately(initialTableWidth + 1); - (expect(component.getColumnWidth(1)) as any).isApproximately(initialColumnWidth + 1); + expect(component.getTableWidth()).isApproximately(initialTableWidth + 1); + expect(component.getColumnWidth(1)).isApproximately(initialColumnWidth + 1); component.endHoverState(); fixture.detectChanges(); @@ -562,18 +562,18 @@ describe('Material Popover Edit', () => { let thumbPositionDelta = component.getOverlayThumbPosition(1) - initialThumbPosition; let columnPositionDelta = component.getColumnOriginPosition(1) - initialColumnPosition; - (expect(thumbPositionDelta) as any).isApproximately(columnPositionDelta); + expect(thumbPositionDelta).isApproximately(columnPositionDelta); - (expect(component.getColumnWidth(1)) as any).isApproximately(initialColumnWidth + 5); + expect(component.getColumnWidth(1)).isApproximately(initialColumnWidth + 5); // TODO: This was commented out after switching from the legacy table to the current // MDC-based table. This failed by being inaccurate by several pixels. - // (expect(component.getTableWidth()) as any).isApproximately(initialTableWidth + 5); + // expect(component.getTableWidth()).isApproximately(initialTableWidth + 5); dispatchKeyboardEvent(document, 'keyup', ESCAPE); flush(); - (expect(component.getColumnWidth(1)) as any).isApproximately(initialColumnWidth); - (expect(component.getTableWidth()) as any).isApproximately(initialTableWidth); + expect(component.getColumnWidth(1)).isApproximately(initialColumnWidth); + expect(component.getTableWidth()).isApproximately(initialTableWidth); component.endHoverState(); fixture.detectChanges(); @@ -582,7 +582,7 @@ describe('Material Popover Edit', () => { it('notifies subscribers of a completed resize via ColumnResizeNotifier', fakeAsync(() => { const initialColumnWidth = component.getColumnWidth(1); - let resize: ColumnSize | null = null; + let resize: ColumnSize | null = null as ColumnSize | null; component.columnResize.columnResizeNotifier.resizeCompleted.subscribe(size => { resize = size; }); @@ -596,7 +596,7 @@ describe('Material Popover Edit', () => { fixture.detectChanges(); flush(); - expect(resize).toEqual({columnId: 'name', size: initialColumnWidth + 5} as any); + expect(resize).toEqual({columnId: 'name', size: initialColumnWidth + 5}); component.endHoverState(); fixture.detectChanges(); @@ -626,12 +626,12 @@ describe('Material Popover Edit', () => { it('performs a column resize triggered via ColumnResizeNotifier', fakeAsync(() => { // Pre-verify that we are not updating the size to the initial size. - (expect(component.getColumnWidth(1)) as any).not.isApproximately(173); + expect(component.getColumnWidth(1)).not.isApproximately(173); component.columnResize.columnResizeNotifier.resize('name', 173); flush(); - (expect(component.getColumnWidth(1)) as any).isApproximately(173); + expect(component.getColumnWidth(1)).isApproximately(173); })); }); } @@ -660,13 +660,13 @@ describe('Material Popover Edit', () => { })); it('applies the persisted size', fakeAsync(() => { - (expect(component.getColumnWidth(1)).not as any).isApproximately(300); + expect(component.getColumnWidth(1)).not.isApproximately(300); columnSizeStore.emitSize('theTable', 'name', 300); flush(); - (expect(component.getColumnWidth(1)) as any).isApproximately(300); + expect(component.getColumnWidth(1)).isApproximately(300); })); it('persists the user-triggered size update', fakeAsync(() => { @@ -689,7 +689,7 @@ describe('Material Popover Edit', () => { const {tableId, columnId, sizePx} = columnSizeStore.setSizeCalls[0]; expect(tableId).toBe('theTable'); expect(columnId).toBe('name'); - (expect(sizePx) as any).isApproximately(initialColumnWidth + 5); + expect(sizePx).isApproximately(initialColumnWidth + 5); })); it('persists the user-triggered size update (live updates off)', fakeAsync(() => { @@ -714,7 +714,7 @@ describe('Material Popover Edit', () => { const {tableId, columnId, sizePx} = columnSizeStore.setSizeCalls[0]; expect(tableId).toBe('theTable'); expect(columnId).toBe('name'); - (expect(sizePx) as any).isApproximately(initialColumnWidth + 5); + expect(sizePx).isApproximately(initialColumnWidth + 5); })); }); }); From e0a6094b96d5d327ac9e021c95224f94953134c3 Mon Sep 17 00:00:00 2001 From: Dominik Rabij Date: Fri, 21 Mar 2025 15:03:00 +0100 Subject: [PATCH 10/14] refactor(multiple): improve types --- src/google-maps/map-event-manager.ts | 10 ++--- src/universal-app/hydration.e2e.spec.ts | 17 +++++---- .../kitchen-sink/kitchen-sink.ts | 4 +- src/youtube-player/fake-youtube-player.ts | 38 ++++++++++--------- 4 files changed, 38 insertions(+), 31 deletions(-) diff --git a/src/google-maps/map-event-manager.ts b/src/google-maps/map-event-manager.ts index ceb290607b90..452536544da8 100644 --- a/src/google-maps/map-event-manager.ts +++ b/src/google-maps/map-event-manager.ts @@ -12,10 +12,10 @@ import {switchMap} from 'rxjs/operators'; type MapEventManagerTarget = | { - addListener: ( + addListener( name: string, - callback: (...args: unknown[]) => void, - ) => google.maps.MapsEventListener | undefined; + callback: (args: T) => void, + ): google.maps.MapsEventListener | undefined; } | undefined; @@ -48,8 +48,8 @@ export class MapEventManager { return undefined; } - const listener = target.addListener(name, (event: unknown) => { - this._ngZone.run(() => observer.next(event as T)); + const listener = target.addListener(name, (event: T) => { + this._ngZone.run(() => observer.next(event)); }); // If there's an error when initializing the Maps API (e.g. a wrong API key), it will diff --git a/src/universal-app/hydration.e2e.spec.ts b/src/universal-app/hydration.e2e.spec.ts index 634f280b4a54..ace95ae861dc 100644 --- a/src/universal-app/hydration.e2e.spec.ts +++ b/src/universal-app/hydration.e2e.spec.ts @@ -1,10 +1,13 @@ import {browser, by, element, ExpectedConditions} from 'protractor'; -// Expect `ngDevMode` to be always set: -declare const ngDevMode: { - hydratedComponents: number; - componentsSkippedHydration: number; -}; +declare global { + interface Window { + ngDevMode: { + hydratedComponents: number; + componentsSkippedHydration: number; + }; + } +} describe('hydration e2e', () => { beforeEach(async () => { @@ -33,7 +36,7 @@ async function getHydrationState() { hydratedComponents: number; componentsSkippedHydration: number; }>(() => ({ - hydratedComponents: ngDevMode.hydratedComponents, - componentsSkippedHydration: ngDevMode.componentsSkippedHydration, + hydratedComponents: window.ngDevMode.hydratedComponents, + componentsSkippedHydration: window.ngDevMode.componentsSkippedHydration, })); } diff --git a/src/universal-app/kitchen-sink/kitchen-sink.ts b/src/universal-app/kitchen-sink/kitchen-sink.ts index ca89fb4af5e0..dfd62bfcfafb 100644 --- a/src/universal-app/kitchen-sink/kitchen-sink.ts +++ b/src/universal-app/kitchen-sink/kitchen-sink.ts @@ -69,7 +69,7 @@ interface ElementItem { } export class TableDataSource extends DataSource { - connect(): Observable> { + connect(): Observable { return observableOf([ {position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H'}, {position: 2, name: 'Helium', weight: 4.0026, symbol: 'He'}, @@ -84,7 +84,7 @@ export class TableDataSource extends DataSource { ]); } - override disconnect() {} + disconnect() {} } export const AUTOMATED_KITCHEN_SINK = new InjectionToken('AUTOMATED_KITCHEN_SINK'); diff --git a/src/youtube-player/fake-youtube-player.ts b/src/youtube-player/fake-youtube-player.ts index c4158828ed7b..c71c329d13db 100644 --- a/src/youtube-player/fake-youtube-player.ts +++ b/src/youtube-player/fake-youtube-player.ts @@ -30,6 +30,11 @@ interface FakeYtNamespace { namespace: typeof YT; } +type ListenersStore = {[E in EventName]?: Set>}; +type Listener = NonNullable; +type ListenerArg = + Listener extends YT.PlayerEventHandler ? T : never; + export function createFakeYtNamespace(): FakeYtNamespace { const playerSpy: jasmine.SpyObj = jasmine.createSpyObj('Player', [ 'getPlayerState', @@ -63,7 +68,7 @@ export function createFakeYtNamespace(): FakeYtNamespace { ]); let playerConfig: YT.PlayerOptions | undefined; - const boundListeners = new Map void>>(); + const boundListeners: ListenersStore = {}; const playerCtorSpy = jasmine.createSpy('Player Constructor'); // The spy target function cannot be an arrow-function as this breaks when created through `new`. @@ -72,28 +77,27 @@ export function createFakeYtNamespace(): FakeYtNamespace { return playerSpy; }); - playerSpy.addEventListener.and.callFake( - (name: keyof YT.Events, listener: (e: unknown) => unknown) => { - if (!boundListeners.has(name)) { - boundListeners.set(name, new Set()); - } - boundListeners.get(name)!.add(listener); - }, - ); + playerSpy.addEventListener.and.callFake((name, listener) => { + const store: ListenersStore = boundListeners; + if (!store[name]) { + store[name] = new Set(); + } + store[name].add(listener); + }); - playerSpy.removeEventListener.and.callFake( - (name: keyof YT.Events, listener: (e: unknown) => unknown) => { - boundListeners.get(name)?.delete(listener); - }, - ); + playerSpy.removeEventListener.and.callFake((name, listener) => { + boundListeners[name]?.delete(listener); + }); - function eventHandlerFactory(name: keyof YT.Events) { - return (arg: Object = {}) => { + function eventHandlerFactory(name: EventName) { + return (arg = {} as ListenerArg) => { if (!playerConfig) { throw new Error(`Player not initialized before ${name} called`); } - boundListeners.get(name)?.forEach(callback => callback(arg)); + boundListeners[name]?.forEach(callback => + (callback as (arg: ListenerArg) => void)(arg), + ); }; } From 44be518724d30d5003697e82c73db7a7c4706045 Mon Sep 17 00:00:00 2001 From: Dominik Rabij Date: Fri, 28 Mar 2025 14:46:41 +0100 Subject: [PATCH 11/14] fix(youtube-player): fix "ban-script-src-assignments" --- package.json | 1 + patches/@angular+bazel+19.1.0-next.0.patch | 114 +++++++++++++++++++++ src/youtube-player/BUILD.bazel | 1 + src/youtube-player/package.json | 3 +- src/youtube-player/youtube-player.ts | 6 +- yarn.lock | 5 + 6 files changed, 127 insertions(+), 3 deletions(-) create mode 100644 patches/@angular+bazel+19.1.0-next.0.patch diff --git a/package.json b/package.json index 1e941ae3809e..e0bf74152035 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "@types/youtube": "^0.1.0", "rxjs": "^6.6.7", "rxjs-tslint-rules": "^4.34.8", + "safevalues": "^1.2.0", "tslib": "^2.3.1", "zone.js": "~0.15.0" }, diff --git a/patches/@angular+bazel+19.1.0-next.0.patch b/patches/@angular+bazel+19.1.0-next.0.patch new file mode 100644 index 000000000000..3780cde25486 --- /dev/null +++ b/patches/@angular+bazel+19.1.0-next.0.patch @@ -0,0 +1,114 @@ +diff --git a/node_modules/@angular/bazel/src/ng_module/ng_module.bzl b/node_modules/@angular/bazel/src/ng_module/ng_module.bzl +index 5e82bcb..3c239f8 100755 +--- a/node_modules/@angular/bazel/src/ng_module/ng_module.bzl ++++ b/node_modules/@angular/bazel/src/ng_module/ng_module.bzl +@@ -18,6 +18,7 @@ load( + "TsConfigInfo", + "compile_ts", + "js_ecma_script_module_info", ++ "js_named_module_info", + "js_module_info", + "node_modules_aspect", + "ts_providers_dict_to_struct", +@@ -151,9 +152,9 @@ def _ngc_tsconfig(ctx, files, srcs, **kwargs): + is_devmode = "devmode_manifest" in kwargs + outs = _expected_outs(ctx) + if is_devmode: +- expected_outs = outs.devmode_js ++ expected_outs = outs.devmode_js + outs.declarations + else: +- expected_outs = outs.closure_js + outs.declarations ++ expected_outs = outs.closure_js + + if not ctx.attr.type_check and ctx.attr.strict_templates: + fail("Cannot set type_check = False and strict_templates = True for ng_module()") +@@ -355,11 +356,11 @@ def _compile_action( + + def _prodmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts): + outs = _expected_outs(ctx) +- return _compile_action(ctx, inputs, outputs + outs.closure_js + outs.prod_perf_files + outs.declarations, tsconfig_file, node_opts, "prodmode") ++ return _compile_action(ctx, inputs, outputs + outs.closure_js + outs.prod_perf_files, tsconfig_file, node_opts, "prodmode") + + def _devmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts): + outs = _expected_outs(ctx) +- compile_action_outputs = outputs + outs.devmode_js + outs.dev_perf_files ++ compile_action_outputs = outputs + outs.devmode_js + outs.dev_perf_files + outs.declarations + _compile_action(ctx, inputs, compile_action_outputs, tsconfig_file, node_opts, "devmode") + + # Note: We need to define `label` and `srcs_files` as `tsc_wrapped` passes +@@ -413,9 +414,13 @@ def _ng_module_impl(ctx): + # and issue https://github.com/bazelbuild/rules_nodejs/issues/57 for more details. + ts_providers["providers"].extend([ + js_module_info( +- sources = ts_providers["typescript"]["es6_sources"], ++ sources = ts_providers["typescript"]["es5_sources"], + deps = ctx.attr.deps, + ), ++ js_named_module_info( ++ sources = ts_providers["typescript"]["es5_sources"], ++ deps = ctx.attr.deps, ++ ), + js_ecma_script_module_info( + sources = ts_providers["typescript"]["es6_sources"], + deps = ctx.attr.deps, +@@ -431,7 +436,7 @@ def _ng_module_impl(ctx): + package_name = ctx.attr.package_name, + package_path = ctx.attr.package_path, + path = path, +- files = ts_providers["typescript"]["es6_sources"], ++ files = ts_providers["typescript"]["es5_sources"], + )) + + return ts_providers_dict_to_struct(ts_providers) +diff --git a/node_modules/@angular/bazel/src/ng_package/packager.mjs b/node_modules/@angular/bazel/src/ng_package/packager.mjs +index 7184fd9..ef3e508 100755 +--- a/node_modules/@angular/bazel/src/ng_package/packager.mjs ++++ b/node_modules/@angular/bazel/src/ng_package/packager.mjs +@@ -7,7 +7,7 @@ + */ + import * as fs from 'fs'; + import * as path from 'path'; +-import { analyzeFileAndEnsureNoCrossImports } from './cross_entry_points_imports'; ++import { analyzeFileAndEnsureNoCrossImports } from './cross_entry_points_imports.mjs'; + /** + * List of known `package.json` fields which provide information about + * supported package formats and their associated entry paths. +diff --git a/node_modules/@angular/bazel/src/ngc-wrapped/index.mjs b/node_modules/@angular/bazel/src/ngc-wrapped/index.mjs +index def2972..3de33ba 100755 +--- a/node_modules/@angular/bazel/src/ngc-wrapped/index.mjs ++++ b/node_modules/@angular/bazel/src/ngc-wrapped/index.mjs +@@ -12,7 +12,7 @@ import tscw from '@bazel/concatjs/internal/tsc_wrapped/index.js'; + import * as fs from 'fs'; + import * as path from 'path'; + import ts from 'typescript'; +-import { EXT, patchNgHostWithFileNameToModuleName as patchNgHost, relativeToRootDirs } from './utils'; ++import { EXT, patchNgHostWithFileNameToModuleName as patchNgHost, relativeToRootDirs } from './utils.mjs'; + // FIXME: we should be able to add the assets to the tsconfig so FileLoader + // knows about them + const NGC_ASSETS = /\.(css|html)$/; +@@ -349,6 +349,12 @@ function gatherDiagnosticsForInputsOnly(options, bazelOpts, ngProgram) { + } + return diagnostics; + } ++ ++main(process.argv.slice(2)).then(exitCode => process.exitCode = exitCode).catch(e => { ++ console.error(e); ++ process.exitCode = 1; ++}); ++ + /** + * @deprecated + * Kept here just for compatibility with 1P tools. To be removed soon after 1P update. +diff --git a/node_modules/@angular/bazel/src/ngc-wrapped/ngc-wrapped-main.mjs b/node_modules/@angular/bazel/src/ngc-wrapped/ngc-wrapped-main.mjs +index 8efba56..be29334 100755 +--- a/node_modules/@angular/bazel/src/ngc-wrapped/ngc-wrapped-main.mjs ++++ b/node_modules/@angular/bazel/src/ngc-wrapped/ngc-wrapped-main.mjs +@@ -5,7 +5,7 @@ + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ +-import { main } from './index'; ++import { main } from './index.mjs'; + main(process.argv.slice(2)) + .then((exitCode) => (process.exitCode = exitCode)) + .catch((e) => { diff --git a/src/youtube-player/BUILD.bazel b/src/youtube-player/BUILD.bazel index aca7fc21687e..001d3068e8dc 100644 --- a/src/youtube-player/BUILD.bazel +++ b/src/youtube-player/BUILD.bazel @@ -41,6 +41,7 @@ ng_project( "//:node_modules/@angular/core", "//:node_modules/@types/youtube", "//:node_modules/rxjs", + "//:node_modules/safevalues", ], ) diff --git a/src/youtube-player/package.json b/src/youtube-player/package.json index 001df21b69bb..cdc7f392f1ac 100644 --- a/src/youtube-player/package.json +++ b/src/youtube-player/package.json @@ -23,7 +23,8 @@ "peerDependencies": { "@angular/core": "0.0.0-NG", "@angular/common": "0.0.0-NG", - "rxjs": "^6.5.3 || ^7.4.0" + "rxjs": "^6.5.3 || ^7.4.0", + "safevalues": "^1.2.0" }, "sideEffects": false, "schematics": "./schematics/collection.json", diff --git a/src/youtube-player/youtube-player.ts b/src/youtube-player/youtube-player.ts index 4a707c1f0204..c5008ceb3ae6 100644 --- a/src/youtube-player/youtube-player.ts +++ b/src/youtube-player/youtube-player.ts @@ -32,6 +32,8 @@ import { EventEmitter, } from '@angular/core'; import {isPlatformBrowser} from '@angular/common'; +import {trustedResourceUrl} from 'safevalues'; +import {setScriptSrc} from 'safevalues/dom'; import {Observable, of as observableOf, Subject, BehaviorSubject, fromEventPattern} from 'rxjs'; import {takeUntil, switchMap} from 'rxjs/operators'; import {PlaceholderImageQuality, YouTubePlayerPlaceholder} from './youtube-player-placeholder'; @@ -743,7 +745,7 @@ function loadApi(nonce: string | null): void { } // We can use `document` directly here, because this logic doesn't run outside the browser. - const url = 'https://www.youtube.com/iframe_api'; + const url = trustedResourceUrl`https://www.youtube.com/iframe_api`; const script = document.createElement('script'); const callback = (event: Event) => { script.removeEventListener('load', callback); @@ -759,7 +761,7 @@ function loadApi(nonce: string | null): void { }; script.addEventListener('load', callback); script.addEventListener('error', callback); - script.src = url; + setScriptSrc(script, url); script.async = true; if (nonce) { diff --git a/yarn.lock b/yarn.lock index 9055b5004e34..ab9c03762759 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12963,6 +12963,11 @@ safe-stable-stringify@^2.3.1: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +safevalues@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/safevalues/-/safevalues-1.2.0.tgz#f9e646d6ebf31788004ef192d2a7d646c9896bb2" + integrity sha512-zIsuhjYvJCjfsfjoim2ab6gLKFYAnTiDSJGh0cC3T44L/4kNLL90hBG2BzrXPrHA3f8Ms8FSJ1mljKH5dVR1cw== + sass-loader@16.0.5: version "16.0.5" resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-16.0.5.tgz#257bc90119ade066851cafe7f2c3f3504c7cda98" From 17d1cac4b18a9b0b6cf2553a4845c7da0cac4d1b Mon Sep 17 00:00:00 2001 From: Dominik Rabij Date: Fri, 28 Mar 2025 18:03:31 +0100 Subject: [PATCH 12/14] build: remove bazel patch that was added by accident --- patches/@angular+bazel+19.1.0-next.0.patch | 114 --------------------- 1 file changed, 114 deletions(-) delete mode 100644 patches/@angular+bazel+19.1.0-next.0.patch diff --git a/patches/@angular+bazel+19.1.0-next.0.patch b/patches/@angular+bazel+19.1.0-next.0.patch deleted file mode 100644 index 3780cde25486..000000000000 --- a/patches/@angular+bazel+19.1.0-next.0.patch +++ /dev/null @@ -1,114 +0,0 @@ -diff --git a/node_modules/@angular/bazel/src/ng_module/ng_module.bzl b/node_modules/@angular/bazel/src/ng_module/ng_module.bzl -index 5e82bcb..3c239f8 100755 ---- a/node_modules/@angular/bazel/src/ng_module/ng_module.bzl -+++ b/node_modules/@angular/bazel/src/ng_module/ng_module.bzl -@@ -18,6 +18,7 @@ load( - "TsConfigInfo", - "compile_ts", - "js_ecma_script_module_info", -+ "js_named_module_info", - "js_module_info", - "node_modules_aspect", - "ts_providers_dict_to_struct", -@@ -151,9 +152,9 @@ def _ngc_tsconfig(ctx, files, srcs, **kwargs): - is_devmode = "devmode_manifest" in kwargs - outs = _expected_outs(ctx) - if is_devmode: -- expected_outs = outs.devmode_js -+ expected_outs = outs.devmode_js + outs.declarations - else: -- expected_outs = outs.closure_js + outs.declarations -+ expected_outs = outs.closure_js - - if not ctx.attr.type_check and ctx.attr.strict_templates: - fail("Cannot set type_check = False and strict_templates = True for ng_module()") -@@ -355,11 +356,11 @@ def _compile_action( - - def _prodmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts): - outs = _expected_outs(ctx) -- return _compile_action(ctx, inputs, outputs + outs.closure_js + outs.prod_perf_files + outs.declarations, tsconfig_file, node_opts, "prodmode") -+ return _compile_action(ctx, inputs, outputs + outs.closure_js + outs.prod_perf_files, tsconfig_file, node_opts, "prodmode") - - def _devmode_compile_action(ctx, inputs, outputs, tsconfig_file, node_opts): - outs = _expected_outs(ctx) -- compile_action_outputs = outputs + outs.devmode_js + outs.dev_perf_files -+ compile_action_outputs = outputs + outs.devmode_js + outs.dev_perf_files + outs.declarations - _compile_action(ctx, inputs, compile_action_outputs, tsconfig_file, node_opts, "devmode") - - # Note: We need to define `label` and `srcs_files` as `tsc_wrapped` passes -@@ -413,9 +414,13 @@ def _ng_module_impl(ctx): - # and issue https://github.com/bazelbuild/rules_nodejs/issues/57 for more details. - ts_providers["providers"].extend([ - js_module_info( -- sources = ts_providers["typescript"]["es6_sources"], -+ sources = ts_providers["typescript"]["es5_sources"], - deps = ctx.attr.deps, - ), -+ js_named_module_info( -+ sources = ts_providers["typescript"]["es5_sources"], -+ deps = ctx.attr.deps, -+ ), - js_ecma_script_module_info( - sources = ts_providers["typescript"]["es6_sources"], - deps = ctx.attr.deps, -@@ -431,7 +436,7 @@ def _ng_module_impl(ctx): - package_name = ctx.attr.package_name, - package_path = ctx.attr.package_path, - path = path, -- files = ts_providers["typescript"]["es6_sources"], -+ files = ts_providers["typescript"]["es5_sources"], - )) - - return ts_providers_dict_to_struct(ts_providers) -diff --git a/node_modules/@angular/bazel/src/ng_package/packager.mjs b/node_modules/@angular/bazel/src/ng_package/packager.mjs -index 7184fd9..ef3e508 100755 ---- a/node_modules/@angular/bazel/src/ng_package/packager.mjs -+++ b/node_modules/@angular/bazel/src/ng_package/packager.mjs -@@ -7,7 +7,7 @@ - */ - import * as fs from 'fs'; - import * as path from 'path'; --import { analyzeFileAndEnsureNoCrossImports } from './cross_entry_points_imports'; -+import { analyzeFileAndEnsureNoCrossImports } from './cross_entry_points_imports.mjs'; - /** - * List of known `package.json` fields which provide information about - * supported package formats and their associated entry paths. -diff --git a/node_modules/@angular/bazel/src/ngc-wrapped/index.mjs b/node_modules/@angular/bazel/src/ngc-wrapped/index.mjs -index def2972..3de33ba 100755 ---- a/node_modules/@angular/bazel/src/ngc-wrapped/index.mjs -+++ b/node_modules/@angular/bazel/src/ngc-wrapped/index.mjs -@@ -12,7 +12,7 @@ import tscw from '@bazel/concatjs/internal/tsc_wrapped/index.js'; - import * as fs from 'fs'; - import * as path from 'path'; - import ts from 'typescript'; --import { EXT, patchNgHostWithFileNameToModuleName as patchNgHost, relativeToRootDirs } from './utils'; -+import { EXT, patchNgHostWithFileNameToModuleName as patchNgHost, relativeToRootDirs } from './utils.mjs'; - // FIXME: we should be able to add the assets to the tsconfig so FileLoader - // knows about them - const NGC_ASSETS = /\.(css|html)$/; -@@ -349,6 +349,12 @@ function gatherDiagnosticsForInputsOnly(options, bazelOpts, ngProgram) { - } - return diagnostics; - } -+ -+main(process.argv.slice(2)).then(exitCode => process.exitCode = exitCode).catch(e => { -+ console.error(e); -+ process.exitCode = 1; -+}); -+ - /** - * @deprecated - * Kept here just for compatibility with 1P tools. To be removed soon after 1P update. -diff --git a/node_modules/@angular/bazel/src/ngc-wrapped/ngc-wrapped-main.mjs b/node_modules/@angular/bazel/src/ngc-wrapped/ngc-wrapped-main.mjs -index 8efba56..be29334 100755 ---- a/node_modules/@angular/bazel/src/ngc-wrapped/ngc-wrapped-main.mjs -+++ b/node_modules/@angular/bazel/src/ngc-wrapped/ngc-wrapped-main.mjs -@@ -5,7 +5,7 @@ - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.dev/license - */ --import { main } from './index'; -+import { main } from './index.mjs'; - main(process.argv.slice(2)) - .then((exitCode) => (process.exitCode = exitCode)) - .catch((e) => { From cfa38853a73d1f97d68ecb257610831d00ecbcbd Mon Sep 17 00:00:00 2001 From: Dominik Rabij Date: Fri, 28 Mar 2025 18:20:48 +0100 Subject: [PATCH 13/14] build: add safevalues to pnpm-lock.yaml --- pnpm-lock.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b40505363191..b5c590ad9cb2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -54,6 +54,9 @@ importers: rxjs-tslint-rules: specifier: ^4.34.8 version: 4.34.8(tslint@6.1.3)(typescript@5.8.2) + safevalues: + specifier: ^1.2.0 + version: 1.2.0 tslib: specifier: ^2.3.1 version: 2.8.1 @@ -13488,6 +13491,10 @@ packages: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} dev: true + /safevalues@1.2.0: + resolution: {integrity: sha512-zIsuhjYvJCjfsfjoim2ab6gLKFYAnTiDSJGh0cC3T44L/4kNLL90hBG2BzrXPrHA3f8Ms8FSJ1mljKH5dVR1cw==} + dev: false + /sass-loader@16.0.5(sass@1.86.0)(webpack@5.98.0): resolution: {integrity: sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==} engines: {node: '>= 18.12.0'} From 1a172ac23c8966155ab9025592e98aaabcd8e43f Mon Sep 17 00:00:00 2001 From: Dominik Rabij Date: Fri, 28 Mar 2025 18:24:50 +0100 Subject: [PATCH 14/14] build: update npm_translate_lock after adding safevalues --- .../npm_translate_lock_MzA5NzUwNzMx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.aspect/rules/external_repository_action_cache/npm_translate_lock_MzA5NzUwNzMx b/.aspect/rules/external_repository_action_cache/npm_translate_lock_MzA5NzUwNzMx index 5f46899ce923..94b382bbd677 100755 --- a/.aspect/rules/external_repository_action_cache/npm_translate_lock_MzA5NzUwNzMx +++ b/.aspect/rules/external_repository_action_cache/npm_translate_lock_MzA5NzUwNzMx @@ -2,9 +2,9 @@ # Input hashes for repository rule npm_translate_lock(name = "npm2", pnpm_lock = "@//:pnpm-lock.yaml"). # This file should be checked into version control along with the pnpm-lock.yaml file. .npmrc=-1406867100 -package.json=130765121 +package.json=-306254715 patches/@angular__compiler-cli.patch=-65319555 -pnpm-lock.yaml=-266832367 +pnpm-lock.yaml=1755183230 pnpm-workspace.yaml=14857322 src/cdk/package.json=-908433069 -yarn.lock=230420156 +yarn.lock=-1568260908