diff --git a/package.json b/package.json index af296dc4..8e52d3e3 100644 --- a/package.json +++ b/package.json @@ -68,7 +68,7 @@ "@types/masonry-layout": "^4.2.8", "@typescript-eslint/eslint-plugin": "^8.30.1", "@typescript-eslint/parser": "^8.30.1", - "@vitest/coverage-istanbul": "^4.1.10", + "@vitest/coverage-v8": "^4.1.10", "conventional-changelog-conventionalcommits": "^8.0.0", "docsify-cli": "^4.4.4", "eslint": "^9.24.0", diff --git a/src/action-handler-directive.ts b/src/action-handler-directive.ts index a9fd5008..34faf6dd 100644 --- a/src/action-handler-directive.ts +++ b/src/action-handler-directive.ts @@ -171,9 +171,14 @@ export const actionHandler = directive( return noChange; } - // istanbul ignore next -- @preserve Required by Lit Directive API but never called (update() is used instead) + // Required by Lit Directive API but never called (update() is used instead). + // The start/stop form of the coverage hint is used because the `next` form + // applies to whatever immediately follows the comment, which here is + // another comment. + /* v8 ignore start -- @preserve */ // eslint-disable-next-line @typescript-eslint/no-unused-vars render(_options?: AdvancedCameraCardActionHandlerOptions) {} + /* v8 ignore stop -- @preserve */ }, ); diff --git a/src/camera-manager/camera.ts b/src/camera-manager/camera.ts index 1937b90c..67ce76c2 100644 --- a/src/camera-manager/camera.ts +++ b/src/camera-manager/camera.ts @@ -104,6 +104,14 @@ export class Camera { this._capabilities ?? (await this._buildCapabilities(hass, options)); + // The else path is tested, but the `v8` coverage provider miscounts it: a + // missing `else` is given the count of the `if` statement minus the count + // of its body, and the engine only counts code after an `await` for the + // calls that actually paused there. Calls that took an earlier `??` value + // above skipped the `await`, which makes the first number the smaller one + // and the result negative. + // See: https://github.com/AriPerkkio/ast-v8-to-istanbul/issues/148 + /* v8 ignore else -- @preserve */ if (this._capabilities.has('trigger')) { await this._getTriggerEntities(hass, options); this._config.triggers.entities = uniq(this._config.triggers.entities); diff --git a/src/camera-manager/frigate/camera.ts b/src/camera-manager/frigate/camera.ts index 1e266918..3f20730c 100644 --- a/src/camera-manager/frigate/camera.ts +++ b/src/camera-manager/frigate/camera.ts @@ -489,7 +489,7 @@ export class FrigateCamera extends Camera { return; } - /* istanbul ignore next -- exercising the matcher is not possible when the + /* v8 ignore next -- exercising the matcher is not possible when the test uses an event watcher -- @preserve */ const request: FrigateWatcherRequest = { instanceID: config.frigate.client_id, @@ -573,7 +573,7 @@ export class FrigateCamera extends Camera { return; } - /* istanbul ignore next -- exercising the matcher is not possible when the + /* v8 ignore next -- exercising the matcher is not possible when the test uses a review watcher -- @preserve */ const request: FrigateWatcherRequest = { instanceID: config.frigate.client_id, diff --git a/src/camera-manager/frigate/engine-frigate.ts b/src/camera-manager/frigate/engine-frigate.ts index 059db247..cd97f028 100644 --- a/src/camera-manager/frigate/engine-frigate.ts +++ b/src/camera-manager/frigate/engine-frigate.ts @@ -429,7 +429,7 @@ export class FrigateCameraManagerEngine instanceID: string, cameraIDs?: Set, ): Promise => { - /* istanbul ignore next: defensive guard, instances.get() always returns + /* v8 ignore next: defensive guard, instances.get() always returns a value when iterating instances.keys() -- @preserve */ if (!cameraIDs?.size) { return; @@ -508,7 +508,7 @@ export class FrigateCameraManagerEngine instanceID: string, cameraIDs?: Set, ): Promise => { - /* istanbul ignore next: defensive guard, instances.get() always returns + /* v8 ignore next: defensive guard, instances.get() always returns a value when iterating instances.keys() -- @preserve */ if (!cameraIDs?.size) { return; @@ -1032,7 +1032,7 @@ export class FrigateCameraManagerEngine } for (const result of recordings.values()) { - /* istanbul ignore next: this engine's getRecordings() always produces + /* v8 ignore next: this engine's getRecordings() always produces FrigateRecordingQueryResults -- @preserve */ if (!FrigateQueryResultsClassifier.isFrigateRecordingQueryResults(result)) { continue; @@ -1102,7 +1102,7 @@ export class FrigateCameraManagerEngine } for (const [query, result] of results) { - /* istanbul ignore next: this engine's getRecordings() always produces + /* v8 ignore next: this engine's getRecordings() always produces FrigateRecordingQueryResults -- @preserve */ if (!FrigateQueryResultsClassifier.isFrigateRecordingQueryResults(result)) { continue; diff --git a/src/camera-manager/manager.ts b/src/camera-manager/manager.ts index 418456ca..eb6f0de8 100644 --- a/src/camera-manager/manager.ts +++ b/src/camera-manager/manager.ts @@ -187,7 +187,7 @@ export class CameraManager { const engines: Map = new Map(); const hass = this._api.getHASSManager().getHASS(); - /* istanbul ignore if: the if path cannot be reached -- @preserve */ + /* v8 ignore if: the if path cannot be reached -- @preserve */ if (!hass) { return output; } @@ -225,7 +225,7 @@ export class CameraManager { const initializationStartTime = new Date(); const hass = this._api.getHASSManager().getHASS(); - /* istanbul ignore if: the if path cannot be reached -- @preserve */ + /* v8 ignore if: the if path cannot be reached -- @preserve */ if (!hass) { return; } @@ -366,7 +366,7 @@ export class CameraManager { for (const [engine, cameraIDs] of engines) { let queries: CameraQuery[] | null = null; - /* istanbul ignore else: the else path cannot be reached -- @preserve */ + /* v8 ignore else: the else path cannot be reached -- @preserve */ if (CameraQueryClassifier.isEventQuery(partialQuery)) { queries = engine.generateDefaultEventQuery(this._store, cameraIDs, partialQuery); } else if (CameraQueryClassifier.isRecordingQuery(partialQuery)) { @@ -540,7 +540,7 @@ export class CameraManager { for (const query of queries) { const newChunkQuery = { ...query }; - /* istanbul ignore else: the else path cannot be reached -- @preserve */ + /* v8 ignore else: the else path cannot be reached -- @preserve */ if (direction === 'later') { const latestResult = getTimeFromResults('latest'); if (latestResult) { @@ -728,7 +728,7 @@ export class CameraManager { ): Promise => { let engineResult: Map> | null = null; - /* istanbul ignore else: the else path cannot be reached -- @preserve */ + /* v8 ignore else: the else path cannot be reached -- @preserve */ if (CameraQueryClassifier.isEventQuery(query)) { engineResult = (await engine.getEvents( hass, @@ -825,7 +825,7 @@ export class CameraManager { if (engine) { let media: ViewMedia[] | null = null; - /* istanbul ignore else: the else path cannot be reached -- @preserve */ + /* v8 ignore else: the else path cannot be reached -- @preserve */ if ( CameraQueryClassifier.isEventQuery(query) && QueryResultClassifier.isEventQueryResult(result) diff --git a/src/camera-manager/motioneye/engine-motioneye.ts b/src/camera-manager/motioneye/engine-motioneye.ts index 626cbf5f..9e215bb1 100644 --- a/src/camera-manager/motioneye/engine-motioneye.ts +++ b/src/camera-manager/motioneye/engine-motioneye.ts @@ -93,7 +93,7 @@ export class MotionEyeCameraManagerEngine extends BrowseMediaCameraManagerEngine parent?: RichBrowseMedia, ): BrowseMediaMetadata | null { let startDate = parent?._metadata?.startDate ?? new Date(); - /* istanbul ignore next: dateFormat is always non-null for files because + /* v8 ignore next: dateFormat is always non-null for files because Zod requires file_pattern to contain % -- @preserve */ if (dateFormat) { const extensionlessTitle = media.title.replace(/\.[^/.]+$/, ''); diff --git a/src/camera-manager/reolink/camera.ts b/src/camera-manager/reolink/camera.ts index 9d607a06..962eadb0 100644 --- a/src/camera-manager/reolink/camera.ts +++ b/src/camera-manager/reolink/camera.ts @@ -239,7 +239,7 @@ export class ReolinkCamera extends EntityCamera { reolinkPTZCapabilities.presets = ptzPresetsEntityState.attributes.options; } - /* istanbul ignore next: this path cannot be reached as ptzEntities will + /* v8 ignore next: this path cannot be reached as ptzEntities will always have contents when this function is called -- @preserve */ return Object.keys(reolinkPTZCapabilities).length ? reolinkPTZCapabilities : null; } @@ -248,7 +248,7 @@ export class ReolinkCamera extends EntityCamera { hass: HomeAssistant, entityRegistry: EntityRegistryManager, ): Promise { - /* istanbul ignore next: this path cannot be reached as an exception is + /* v8 ignore next: this path cannot be reached as an exception is thrown in initialize() if this value is not found -- @preserve */ if (!this._reolinkHostID) { return null; diff --git a/src/camera-manager/reolink/engine-reolink.ts b/src/camera-manager/reolink/engine-reolink.ts index 26bb9f63..3277aa8f 100644 --- a/src/camera-manager/reolink/engine-reolink.ts +++ b/src/camera-manager/reolink/engine-reolink.ts @@ -90,7 +90,7 @@ export class ReolinkCameraManagerEngine extends BrowseMediaCameraManagerEngine { media: BrowseMedia, parent?: RichBrowseMedia, ): BrowseMediaMetadata | null { - /* istanbul ignore next: This situation cannot happen as the directory would + /* v8 ignore next: This situation cannot happen as the directory would be rejected by _reolinkDirectoryMetadataGenerator if there was no start date -- @preserve */ if (!parent?._metadata?.startDate || media.media_class !== MEDIA_CLASS_VIDEO) { @@ -375,7 +375,7 @@ export class ReolinkCameraManagerEngine extends BrowseMediaCameraManagerEngine { engineOptions, ); for (const dayDirectory of directories ?? []) { - /* istanbul ignore next: This situation cannot happen as the directory + /* v8 ignore next: This situation cannot happen as the directory will not match without metadata -- @preserve */ if (dayDirectory._metadata?.startDate) { days.add(formatDate(dayDirectory._metadata.startDate)); diff --git a/src/card-controller/actions/actions/ptz-digital.ts b/src/card-controller/actions/actions/ptz-digital.ts index 10733065..5b0463c9 100644 --- a/src/card-controller/actions/actions/ptz-digital.ts +++ b/src/card-controller/actions/actions/ptz-digital.ts @@ -67,7 +67,7 @@ export class PTZDigitalAction extends AdvancedCameraCardAction { setInProgressForThisTarget(ptzCameraID, this._context, 'ptz', this); const singleStep = async (): Promise => { - /* istanbul ignore else: the else path cannot be reached as ptz_action + /* v8 ignore else: the else path cannot be reached as ptz_action being present is checked above -- @preserve */ if (action.ptz_action) { await api.getCameraManager().executePTZAction(ptzCameraID, action.ptz_action, { @@ -133,7 +133,7 @@ export class PTZAction extends AdvancedCameraCardAction { }); this._timer.start(ptzConfiguration.c2r_delay_between_calls_seconds, async () => { - /* istanbul ignore else: the else path cannot be reached as ptz_action + /* v8 ignore else: the else path cannot be reached as ptz_action being present is checked above -- @preserve */ if (action.ptz_action) { await api.getCameraManager().executePTZAction(ptzCameraID, action.ptz_action, { diff --git a/src/card-controller/call/tones/base.ts b/src/card-controller/call/tones/base.ts index 8b2647d6..63513ecd 100644 --- a/src/card-controller/call/tones/base.ts +++ b/src/card-controller/call/tones/base.ts @@ -53,7 +53,7 @@ export abstract class GeneratedTone implements Tone { // Current AudioContext time. Subclasses only read this from inside `_play()` // where the context is always set. protected get _currentTime(): number { - /* istanbul ignore next: _currentTime is only read by subclasses from + /* v8 ignore next: _currentTime is only read by subclasses from _play() during an active context -- @preserve */ return this._context?.currentTime ?? 0; } @@ -62,7 +62,7 @@ export abstract class GeneratedTone implements Tone { // of their pattern to loop. No-ops if the context has already been closed so // a stopped tone can never re-arm its loop. protected _scheduleNext(intervalSeconds: number): void { - /* istanbul ignore next: defensive guard against a subclass calling + /* v8 ignore next: defensive guard against a subclass calling _scheduleNext after stop() -- JS single-threading makes this unreachable from the existing subclasses -- @preserve */ if (!this._context) { @@ -78,7 +78,7 @@ export abstract class GeneratedTone implements Tone { return; } this._timer.start(intervalSeconds, () => { - /* istanbul ignore next: Timer.stop() cancels pending callbacks, so this + /* v8 ignore next: Timer.stop() cancels pending callbacks, so this re-entry guard is unreachable in practice -- @preserve */ if (!this._context) { return; @@ -89,7 +89,7 @@ export abstract class GeneratedTone implements Tone { // Plays one note: a smooth tone that rises to peak volume and then fades. protected _playNote(freq: number, when: number, envelope: ToneEnvelope): void { - /* istanbul ignore next: _playNote is only called by subclasses from + /* v8 ignore next: _playNote is only called by subclasses from _play() during an active context -- @preserve */ if (!this._context) { return; diff --git a/src/card-controller/call/tones/custom.ts b/src/card-controller/call/tones/custom.ts index 63970598..7af61e13 100644 --- a/src/card-controller/call/tones/custom.ts +++ b/src/card-controller/call/tones/custom.ts @@ -51,7 +51,7 @@ export class CustomTone implements Tone { } private _handleEnded = (): void => { - /* istanbul ignore next: stop() removes this listener before nulling + /* v8 ignore next: stop() removes this listener before nulling _audio, so the handler can't fire with a null _audio -- @preserve */ if (!this._audio) { return; @@ -64,7 +64,7 @@ export class CustomTone implements Tone { }; private _playAudio(): void { - /* istanbul ignore next: callers (start, _handleEnded) only invoke + /* v8 ignore next: callers (start, _handleEnded) only invoke _playAudio when _audio is non-null -- @preserve */ if (!this._audio) { return; diff --git a/src/card-controller/camera-triggers-manager.ts b/src/card-controller/camera-triggers-manager.ts index 6da04796..bf5e5f5d 100644 --- a/src/card-controller/camera-triggers-manager.ts +++ b/src/card-controller/camera-triggers-manager.ts @@ -242,7 +242,7 @@ export class CameraTriggersManager { } else if (ev.fidelity === 'high' && triggerAction === 'media') { // Choose the most appropriate media view based on what's available. // Priority: review > clip > snapshot - /* istanbul ignore next: the `null` case is unreachable due to `skipViewAction` above -- @preserve */ + /* v8 ignore next: the `null` case is unreachable due to `skipViewAction` above -- @preserve */ const view = ev.review ? 'review' : ev.clip @@ -251,7 +251,7 @@ export class CameraTriggersManager { ? 'snapshot' : null; - /* istanbul ignore next: unreachable due to `skipViewAction` above -- @preserve */ + /* v8 ignore next: unreachable due to `skipViewAction` above -- @preserve */ if (view) { await this._api.getViewManager().setViewByParametersWithNewQuery({ params: { diff --git a/src/card-controller/config/config-manager.ts b/src/card-controller/config/config-manager.ts index 271a8900..1a83d5f0 100644 --- a/src/card-controller/config/config-manager.ts +++ b/src/card-controller/config/config-manager.ts @@ -163,7 +163,7 @@ export class ConfigManager { } private _processOverrideConfig(): void { - /* istanbul ignore if: No (current) way to reach this code -- @preserve */ + /* v8 ignore if: No (current) way to reach this code -- @preserve */ if (!this._config) { return; } diff --git a/src/card-controller/view/item-manager.ts b/src/card-controller/view/item-manager.ts index 3fb3e99d..bbdfa450 100644 --- a/src/card-controller/view/item-manager.ts +++ b/src/card-controller/view/item-manager.ts @@ -39,7 +39,7 @@ export class ViewItemManager { try { await this._download(item); } catch (error: unknown) { - /* istanbul ignore if: catch always provides a non-null error -- @preserve */ + /* v8 ignore if: catch always provides a non-null error -- @preserve */ if (error == null) { return false; } @@ -58,7 +58,7 @@ export class ViewItemManager { if (source === ViewMediaSource.Camera && ViewItemClassifier.isMedia(item)) { return await this._api.getCameraManager().favoriteMedia(item, favorite); } - /* istanbul ignore else: this path cannot be reached -- @preserve */ + /* v8 ignore else: this path cannot be reached -- @preserve */ if (source === ViewMediaSource.Folder) { return this._api.getFoldersManager().favorite(item, favorite); } @@ -78,7 +78,6 @@ export class ViewItemManager { return ViewMediaSource.Folder; } - /* istanbul ignore next: this path cannot be reached -- @preserve */ return null; } @@ -133,12 +132,12 @@ export class ViewItemManager { ); } - /* istanbul ignore else: this path cannot be reached -- @preserve */ + /* v8 ignore else: this path cannot be reached -- @preserve */ if (ViewItemClassifier.isFolder(item)) { return toFilename(item.getTitle() ?? 'media'); } - /* istanbul ignore next: this path cannot be reached -- @preserve */ + /* v8 ignore next: this path cannot be reached -- @preserve */ return 'download'; } } diff --git a/src/card-controller/view/view-manager.ts b/src/card-controller/view/view-manager.ts index bb9d6efe..317ea192 100644 --- a/src/card-controller/view/view-manager.ts +++ b/src/card-controller/view/view-manager.ts @@ -293,7 +293,7 @@ export class ViewManager implements ViewManagerInterface { return; } - /* istanbul ignore if: the if path cannot be reached as the view is set + /* v8 ignore if: the if path cannot be reached as the view is set above -- @preserve */ if (!this._view) { return; diff --git a/src/card-controller/view/view-query-executor.ts b/src/card-controller/view/view-query-executor.ts index 93f69b37..694b4926 100644 --- a/src/card-controller/view/view-query-executor.ts +++ b/src/card-controller/view/view-query-executor.ts @@ -227,7 +227,7 @@ export class ViewQueryExecutor { const now = new Date(); const liveConfig = this._api.getConfigManager().getConfig()?.live; - /* istanbul ignore if: this if branch cannot be reached as if the config is + /* v8 ignore if: this if branch cannot be reached as if the config is empty this function is never called -- @preserve */ if (!liveConfig) { return []; diff --git a/src/components-lib/live/providers/go2rtc-experimental/sources/mjpeg.ts b/src/components-lib/live/providers/go2rtc-experimental/sources/mjpeg.ts index 94190157..51ac1807 100644 --- a/src/components-lib/live/providers/go2rtc-experimental/sources/mjpeg.ts +++ b/src/components-lib/live/providers/go2rtc-experimental/sources/mjpeg.ts @@ -10,7 +10,7 @@ export class MJPEGStreamSource extends ImageFrameStreamSource { } protected _handleFrame(data: ArrayBuffer): void { - /* istanbul ignore next: This never rejects; the catch satisfies the no-floating-promises -- @preserve */ + /* v8 ignore next: This never rejects; the catch satisfies the no-floating-promises -- @preserve */ this._showFrame(new Blob([data], { type: 'image/jpeg' })).catch(() => {}); } } diff --git a/src/components-lib/live/providers/go2rtc-experimental/sources/mp4.ts b/src/components-lib/live/providers/go2rtc-experimental/sources/mp4.ts index 3cf241e5..7a56e744 100644 --- a/src/components-lib/live/providers/go2rtc-experimental/sources/mp4.ts +++ b/src/components-lib/live/providers/go2rtc-experimental/sources/mp4.ts @@ -90,7 +90,7 @@ export class MP4StreamSource extends ImageFrameStreamSource { context.drawImage(decoder, 0, 0, canvas.width, canvas.height); canvas.toBlob((frame) => { if (frame) { - /* istanbul ignore next: This never rejects; the catch satisfies the no-floating-promises -- @preserve */ + /* v8 ignore next: This never rejects; the catch satisfies the no-floating-promises -- @preserve */ this._showFrame(frame).catch(() => {}); } }, 'image/jpeg'); diff --git a/src/components-lib/media-grid-controller.ts b/src/components-lib/media-grid-controller.ts index 8856e2e1..a5125f03 100644 --- a/src/components-lib/media-grid-controller.ts +++ b/src/components-lib/media-grid-controller.ts @@ -353,7 +353,6 @@ export class MediaGridController { const eventPath = ev.composedPath(); for (const [id, element] of this._gridContents.entries()) { - /* istanbul ignore else: the else path cannot be reached -- @preserve */ if (eventPath.includes(element)) { if (this._selected !== id) { // Fire the request but do not mutate local state. The authoritative diff --git a/src/components-lib/media-height-controller.ts b/src/components-lib/media-height-controller.ts index 71199273..ecd2dd32 100644 --- a/src/components-lib/media-height-controller.ts +++ b/src/components-lib/media-height-controller.ts @@ -101,7 +101,7 @@ export class MediaHeightController { } private _initializeRoot(): void { - /* istanbul ignore next: the absent-root path cannot be reached as root will + /* v8 ignore next: the absent-root path cannot be reached as root will always exist by the time the mutation observer is observing -- @preserve */ const children = [ ...(this._root?.querySelectorAll(this._selector) ?? []), diff --git a/src/components-lib/ptz/drag-controller.ts b/src/components-lib/ptz/drag-controller.ts index 2fe34a51..3a19de21 100644 --- a/src/components-lib/ptz/drag-controller.ts +++ b/src/components-lib/ptz/drag-controller.ts @@ -130,7 +130,7 @@ export class PTZDragController implements ReactiveController { } private _restoreGestureStyles(): void { - /* istanbul ignore next: only called when gesture is active -- @preserve */ + /* v8 ignore next: only called when gesture is active -- @preserve */ if (this._gestureElement) { this._gestureElement.style.cursor = this._savedCursor; this._gestureElement.style.touchAction = this._savedTouchAction; @@ -138,7 +138,7 @@ export class PTZDragController implements ReactiveController { } private _setCursor(grabbing: boolean): void { - /* istanbul ignore next: only called when gesture is active -- @preserve */ + /* v8 ignore next: only called when gesture is active -- @preserve */ if (this._gestureElement) { this._gestureElement.style.cursor = grabbing ? CURSOR_GRABBING : CURSOR_GRAB; } @@ -238,7 +238,7 @@ export class PTZDragController implements ReactiveController { }; private _dispatch(action: PTZAction | null, phase?: PTZActionPhase): void { - /* istanbul ignore next: all call sites guard against this -- @preserve */ + /* v8 ignore next: all call sites guard against this -- @preserve */ if (!action) { return; } diff --git a/src/components-lib/status-bar-controller.ts b/src/components-lib/status-bar-controller.ts index 7d5c0a62..315d3b00 100644 --- a/src/components-lib/status-bar-controller.ts +++ b/src/components-lib/status-bar-controller.ts @@ -122,7 +122,7 @@ export class StatusBarController { } private _getSufficientValue(item: StatusBarItem): string | null { - /* istanbul ignore else: cannot happen -- @preserve */ + /* v8 ignore else: cannot happen -- @preserve */ if (item.type === 'custom:advanced-camera-card-status-bar-icon') { return item.icon; } else if (item.type === 'custom:advanced-camera-card-status-bar-string') { diff --git a/src/components-lib/zoom/zoom-controller.ts b/src/components-lib/zoom/zoom-controller.ts index ee3da9bc..5db0346f 100644 --- a/src/components-lib/zoom/zoom-controller.ts +++ b/src/components-lib/zoom/zoom-controller.ts @@ -123,10 +123,6 @@ export class ZoomController { config?.zoom ?? ZOOM_DEFAULT_SCALE, ); - // The ZOOM_DEFAULT_SCALE fallback is not reachable: without a zoom value a - // default of 1 is assumed in _convertPercentToXYPan, which returns null at - // the default zoom, leaving `converted` unset. - /* istanbul ignore next @preserve */ const startScale = config?.zoom ?? ZOOM_DEFAULT_SCALE; this._panzoom = Panzoom(this._element, { @@ -243,23 +239,19 @@ export class ZoomController { // used fully specified by this object. It's kept as-is for completeness. return ( arefloatsApproximatelyEqual( - /* istanbul ignore next @preserve */ a.zoom ?? ZOOM_DEFAULT_SCALE, - /* istanbul ignore next @preserve */ b.zoom ?? ZOOM_DEFAULT_SCALE, ZOOM_PRECISION, ) && arefloatsApproximatelyEqual( - /* istanbul ignore next @preserve */ a.pan?.x ?? ZOOM_DEFAULT_PAN_X, - /* istanbul ignore next @preserve */ b.pan?.x ?? ZOOM_DEFAULT_PAN_X, ZOOM_PRECISION, ) && arefloatsApproximatelyEqual( - /* istanbul ignore next @preserve */ + /* v8 ignore next @preserve */ a.pan?.y ?? ZOOM_DEFAULT_PAN_Y, - /* istanbul ignore next @preserve */ + /* v8 ignore next @preserve */ b.pan?.y ?? ZOOM_DEFAULT_PAN_Y, ZOOM_PRECISION, ) @@ -436,7 +428,7 @@ export class ZoomController { // The ZOOM_DEFAULT_SCALE fallback cannot be reached: when // this._defaultSettings.zoom is undefined, convertedDefault ends up null // above and this function has already returned. - /* istanbul ignore next @preserve */ + /* v8 ignore next @preserve */ const defaultScale = this._defaultSettings.zoom ?? ZOOM_DEFAULT_SCALE; return ( diff --git a/src/ha/connection/subscription-manager.ts b/src/ha/connection/subscription-manager.ts index 7d6814df..a3df8860 100644 --- a/src/ha/connection/subscription-manager.ts +++ b/src/ha/connection/subscription-manager.ts @@ -204,7 +204,7 @@ export class HASSConnectionSubscriptionManager { } private _listenToHASS(): void { - /* istanbul ignore if: only called when transitioning from zero to one + /* v8 ignore if: only called when transitioning from zero to one request, so `_unlistenCallback` is always null here -- @preserve */ if (this._unlistenCallback) { return; @@ -296,14 +296,14 @@ export class HASSConnectionSubscriptionManager { private _runScheduledRetry(request: R): void { const registration = this._requests.get(request); - /* istanbul ignore if: unsubscribe() and `_endEra()` both stop the timer + /* v8 ignore if: unsubscribe() and `_endEra()` both stop the timer before tearing down state, so by the time we get here the request is still alive and the era is still ready -- @preserve */ if (!registration || !this._connection) { return; } - /* istanbul ignore if: the timer can only fire while its token is null (set + /* v8 ignore if: the timer can only fire while its token is null (set null by the catch that scheduled this timer) -- @preserve */ if (registration.token != null) { return; diff --git a/src/utils/concurrency/latest-value-runner.ts b/src/utils/concurrency/latest-value-runner.ts index 2bf9ec88..2748d5c9 100644 --- a/src/utils/concurrency/latest-value-runner.ts +++ b/src/utils/concurrency/latest-value-runner.ts @@ -35,7 +35,7 @@ export class LatestValueRunner { this._running = true; // The drain loop cannot reject (the operation's errors are caught within // it); the catch only satisfies the no-floating-promises rule. - /* istanbul ignore next -- @preserve */ + /* v8 ignore next -- @preserve */ this._drain().catch(() => {}); } return ran; diff --git a/src/utils/diagnostics.ts b/src/utils/diagnostics.ts index 8fd7470b..f0672e68 100644 --- a/src/utils/diagnostics.ts +++ b/src/utils/diagnostics.ts @@ -24,12 +24,12 @@ interface IntegrationDiagnostics { export const getReleaseVersion = (): string => { const releaseVersion: string = '__ADVANCED_CAMERA_CARD_RELEASE_VERSION__'; - /* istanbul ignore if: depends on rollup substitution -- @preserve */ + /* v8 ignore if: depends on rollup substitution -- @preserve */ if (releaseVersion === 'pkg') { return pkg.version; } - /* istanbul ignore if: depends on rollup substitution -- @preserve */ + /* v8 ignore if: depends on rollup substitution -- @preserve */ if (releaseVersion === 'dev') { return `dev+${pkg['gitAbbrevHash']}`; } diff --git a/src/view/unified-query-builder.ts b/src/view/unified-query-builder.ts index 3474043a..1bf444fe 100644 --- a/src/view/unified-query-builder.ts +++ b/src/view/unified-query-builder.ts @@ -54,7 +54,7 @@ export const MediaTypeSpec = { * Note on code coverage: Throughout this class, _buildBaseQueryNode and similar * methods return null only when cameraIDs is empty. Public methods guard * against empty cameraIDs before calling these internal methods, making the - * null branches unreachable. Istanbul ignore comments reference this note. + * null branches unreachable. Coverage ignore comments reference this note. */ export class UnifiedQueryBuilder { private _cameraManager: CameraManager; @@ -132,7 +132,7 @@ export class UnifiedQueryBuilder { new UnifiedQuery(), this._buildRecordingsQueryNode(cameraIDs, options), ); - /* istanbul ignore next: see class note on code coverage -- @preserve */ + /* v8 ignore next: see class note on code coverage -- @preserve */ return query.hasNodes() ? query : null; } @@ -229,14 +229,13 @@ export class UnifiedQueryBuilder { if (effectiveCameraIDs.size) { for (const mediaType of effectiveMediaTypes) { const node = this._buildFilterQueryNode(mediaType, effectiveCameraIDs, options); - /* istanbul ignore next: see class note on code coverage -- @preserve */ + /* v8 ignore next: see class note on code coverage -- @preserve */ if (node) { query.addNode(node); } } } - /* istanbul ignore next: see class note on code coverage -- @preserve */ return query.hasNodes() ? query : null; } diff --git a/src/view/view-support.ts b/src/view/view-support.ts index 2c008994..d7bac152 100644 --- a/src/view/view-support.ts +++ b/src/view/view-support.ts @@ -108,7 +108,7 @@ export const getCameraIDsWithCapabilityForView = ( }; const capability = requirements.mediaCapabilities; - /* istanbul ignore next: this path is currently unreachable given the mapping + /* v8 ignore next: this path is currently unreachable given the mapping in VIEW_REQUIREMENTS includes mediaCapabilities for all camera or 'any' related views -- @preserve */ if (!capability) { diff --git a/vite.config.ts b/vite.config.ts index 538640de..1aac3fda 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -128,8 +128,12 @@ export default defineConfig({ coverage: { exclude: EXCLUSIONS, - // Favor istanbul for coverage over v8 due to better accuracy. - provider: 'istanbul', + // 'v8' reads coverage from the JavaScript engine, so it runs about twice + // as fast as 'istanbul', which has to rewrite every source file first. + // Known gap: 'istanbul' will flag a default parameter value that no test + // ever falls back on -- 'v8' will not, but it is not worth the + // significant performance slowdown to cover this rare case. + provider: 'v8', thresholds: { perFile: true, 'src/**/*.ts': { diff --git a/yarn.lock b/yarn.lock index a7a5a5f4..c1078515 100644 --- a/yarn.lock +++ b/yarn.lock @@ -70,36 +70,6 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/compat-data@npm:7.29.7" - checksum: 10c0/47913f05e08a45a1c9df38c02b4b49e391005085b489432647a1abe112e5d9c75e3be8ea5972b7f6da4ec5d1339922ceb9ea02b8a25d4ed1cb8636e5261f344e - languageName: node - linkType: hard - -"@babel/core@npm:^7.29.0": - version: 7.29.7 - resolution: "@babel/core@npm:7.29.7" - dependencies: - "@babel/code-frame": "npm:^7.29.7" - "@babel/generator": "npm:^7.29.7" - "@babel/helper-compilation-targets": "npm:^7.29.7" - "@babel/helper-module-transforms": "npm:^7.29.7" - "@babel/helpers": "npm:^7.29.7" - "@babel/parser": "npm:^7.29.7" - "@babel/template": "npm:^7.29.7" - "@babel/traverse": "npm:^7.29.7" - "@babel/types": "npm:^7.29.7" - "@jridgewell/remapping": "npm:^2.3.5" - convert-source-map: "npm:^2.0.0" - debug: "npm:^4.1.0" - gensync: "npm:^1.0.0-beta.2" - json5: "npm:^2.2.3" - semver: "npm:^6.3.1" - checksum: 10c0/112fb09c24de7a1de64d1de2c31fe65c4e6af4cb2fb6e6d99ea5373e6fc51e75b88581c0efae4c4c68f119a02a988c7106e95011a41530a2fb8ed793c7eaa07b - languageName: node - linkType: hard - "@babel/generator@npm:^7.26.2, @babel/generator@npm:^7.29.7": version: 7.29.7 resolution: "@babel/generator@npm:7.29.7" @@ -113,19 +83,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helper-compilation-targets@npm:7.29.7" - dependencies: - "@babel/compat-data": "npm:^7.29.7" - "@babel/helper-validator-option": "npm:^7.29.7" - browserslist: "npm:^4.24.0" - lru-cache: "npm:^5.1.1" - semver: "npm:^6.3.1" - checksum: 10c0/4c15fd4c69a0a7047799a28a88460c19cede0a0ee8af994ea169114986f4af48b92c7393a4a3fee0456c11a656eece3448a6ed06354453d6c27cccf17195453b - languageName: node - linkType: hard - "@babel/helper-globals@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helper-globals@npm:7.29.7" @@ -133,29 +90,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helper-module-imports@npm:7.29.7" - dependencies: - "@babel/traverse": "npm:^7.29.7" - "@babel/types": "npm:^7.29.7" - checksum: 10c0/6adf60d97356027413342a092f818d9678c4f5caff716a33e3284b5ae14e47a9e88059d421dde4ee4894691260039a12602c0e7becadc175602194b40dfa345d - languageName: node - linkType: hard - -"@babel/helper-module-transforms@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helper-module-transforms@npm:7.29.7" - dependencies: - "@babel/helper-module-imports": "npm:^7.29.7" - "@babel/helper-validator-identifier": "npm:^7.29.7" - "@babel/traverse": "npm:^7.29.7" - peerDependencies: - "@babel/core": ^7.0.0 - checksum: 10c0/ee5a2172c24a42be696836f4b0d947489c9729d8adf5821885cf77d1ad5333e3c447368e9a71f67df1099570490553dccf9f888ef0a92a48aa63cb086bd8c7e1 - languageName: node - linkType: hard - "@babel/helper-string-parser@npm:^7.29.7": version: 7.29.7 resolution: "@babel/helper-string-parser@npm:7.29.7" @@ -184,23 +118,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-validator-option@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helper-validator-option@npm:7.29.7" - checksum: 10c0/d2a06c6d0ac40ba4a2f219fc2cab249c7a94bacdb2686273b7f9598571c908809b48468ff588915a346e6cc7296f60b581023d1d498b747fed06f779d335c2cc - languageName: node - linkType: hard - -"@babel/helpers@npm:^7.29.7": - version: 7.29.7 - resolution: "@babel/helpers@npm:7.29.7" - dependencies: - "@babel/template": "npm:^7.29.7" - "@babel/types": "npm:^7.29.7" - checksum: 10c0/218e8d10953647c9f44775f5a022b227a182674853b5ea8631889deb7e1a3e4bc870388aaecf59bb8bd92a87f9a96220ed3f70a35bffec6bcf9169ecb67891ac - languageName: node - linkType: hard - "@babel/highlight@npm:^7.23.4": version: 7.23.4 resolution: "@babel/highlight@npm:7.23.4" @@ -246,7 +163,7 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.25.9, @babel/traverse@npm:^7.29.7": +"@babel/traverse@npm:^7.25.9": version: 7.29.7 resolution: "@babel/traverse@npm:7.29.7" dependencies: @@ -271,6 +188,13 @@ __metadata: languageName: node linkType: hard +"@bcoe/v8-coverage@npm:^1.0.2": + version: 1.0.2 + resolution: "@bcoe/v8-coverage@npm:1.0.2" + checksum: 10c0/1eb1dc93cc17fb7abdcef21a6e7b867d6aa99a7ec88ec8207402b23d9083ab22a8011213f04b2cf26d535f1d22dc26139b7929e6c2134c254bd1e14ba5e678c3 + languageName: node + linkType: hard + "@colors/colors@npm:1.5.0": version: 1.5.0 resolution: "@colors/colors@npm:1.5.0" @@ -588,14 +512,7 @@ __metadata: languageName: node linkType: hard -"@istanbuljs/schema@npm:^0.1.3": - version: 0.1.3 - resolution: "@istanbuljs/schema@npm:0.1.3" - checksum: 10c0/61c5286771676c9ca3eb2bd8a7310a9c063fb6e0e9712225c8471c582d157392c88f5353581c8c9adbe0dff98892317d2fdfc56c3499aa42e0194405206a963a - languageName: node - linkType: hard - -"@jridgewell/gen-mapping@npm:^0.3.0, @jridgewell/gen-mapping@npm:^0.3.5": +"@jridgewell/gen-mapping@npm:^0.3.0": version: 0.3.5 resolution: "@jridgewell/gen-mapping@npm:0.3.5" dependencies: @@ -606,7 +523,7 @@ __metadata: languageName: node linkType: hard -"@jridgewell/gen-mapping@npm:^0.3.12, @jridgewell/gen-mapping@npm:^0.3.13": +"@jridgewell/gen-mapping@npm:^0.3.12": version: 0.3.13 resolution: "@jridgewell/gen-mapping@npm:0.3.13" dependencies: @@ -616,16 +533,6 @@ __metadata: languageName: node linkType: hard -"@jridgewell/remapping@npm:^2.3.5": - version: 2.3.5 - resolution: "@jridgewell/remapping@npm:2.3.5" - dependencies: - "@jridgewell/gen-mapping": "npm:^0.3.5" - "@jridgewell/trace-mapping": "npm:^0.3.24" - checksum: 10c0/3de494219ffeb2c5c38711d0d7bb128097edf91893090a2dbc8ee0b55d092bb7347b1fd0f478486c5eab010e855c73927b1666f2107516d472d24a73017d1194 - languageName: node - linkType: hard - "@jridgewell/resolve-uri@npm:^3.1.0": version: 3.1.2 resolution: "@jridgewell/resolve-uri@npm:3.1.2" @@ -664,16 +571,6 @@ __metadata: languageName: node linkType: hard -"@jridgewell/trace-mapping@npm:0.3.31, @jridgewell/trace-mapping@npm:^0.3.28": - version: 0.3.31 - resolution: "@jridgewell/trace-mapping@npm:0.3.31" - dependencies: - "@jridgewell/resolve-uri": "npm:^3.1.0" - "@jridgewell/sourcemap-codec": "npm:^1.4.14" - checksum: 10c0/4b30ec8cd56c5fd9a661f088230af01e0c1a3888d11ffb6b47639700f71225be21d1f7e168048d6d4f9449207b978a235c07c8f15c07705685d16dc06280e9d9 - languageName: node - linkType: hard - "@jridgewell/trace-mapping@npm:^0.3.24, @jridgewell/trace-mapping@npm:^0.3.9": version: 0.3.24 resolution: "@jridgewell/trace-mapping@npm:0.3.24" @@ -684,6 +581,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/trace-mapping@npm:^0.3.28, @jridgewell/trace-mapping@npm:^0.3.31": + version: 0.3.31 + resolution: "@jridgewell/trace-mapping@npm:0.3.31" + dependencies: + "@jridgewell/resolve-uri": "npm:^3.1.0" + "@jridgewell/sourcemap-codec": "npm:^1.4.14" + checksum: 10c0/4b30ec8cd56c5fd9a661f088230af01e0c1a3888d11ffb6b47639700f71225be21d1f7e168048d6d4f9449207b978a235c07c8f15c07705685d16dc06280e9d9 + languageName: node + linkType: hard + "@lit-labs/scoped-registry-mixin@npm:^1.0.3": version: 1.0.3 resolution: "@lit-labs/scoped-registry-mixin@npm:1.0.3" @@ -2241,23 +2148,27 @@ __metadata: languageName: node linkType: hard -"@vitest/coverage-istanbul@npm:^4.1.10": +"@vitest/coverage-v8@npm:^4.1.10": version: 4.1.10 - resolution: "@vitest/coverage-istanbul@npm:4.1.10" + resolution: "@vitest/coverage-v8@npm:4.1.10" dependencies: - "@babel/core": "npm:^7.29.0" - "@istanbuljs/schema": "npm:^0.1.3" - "@jridgewell/gen-mapping": "npm:^0.3.13" - "@jridgewell/trace-mapping": "npm:0.3.31" + "@bcoe/v8-coverage": "npm:^1.0.2" + "@vitest/utils": "npm:4.1.10" + ast-v8-to-istanbul: "npm:^1.0.0" istanbul-lib-coverage: "npm:^3.2.2" istanbul-lib-report: "npm:^3.0.1" istanbul-reports: "npm:^3.2.0" magicast: "npm:^0.5.2" obug: "npm:^2.1.1" + std-env: "npm:^4.0.0-rc.1" tinyrainbow: "npm:^3.1.0" peerDependencies: + "@vitest/browser": 4.1.10 vitest: 4.1.10 - checksum: 10c0/a426b0aff94482587a100db7e8db4e238fabf9e5bc4d33a319bd9cd4261b8972a7b3d78f2bc7cbc3d11b0b58b5d7cc487f96ab35a96c1c766c54f9b6d5eb4f78 + peerDependenciesMeta: + "@vitest/browser": + optional: true + checksum: 10c0/f607ab5610ba93ff586d1680bc6d574ee42606ddafd33d5dca14d568e1ff110bf7aea0c82d87b69003b10604d78ccdb535948704e26bbdbfdda6b27edf524486 languageName: node linkType: hard @@ -2435,7 +2346,7 @@ __metadata: "@typescript-eslint/eslint-plugin": "npm:^8.30.1" "@typescript-eslint/parser": "npm:^8.30.1" "@use-gesture/vanilla": "npm:^10.3.1" - "@vitest/coverage-istanbul": "npm:^4.1.10" + "@vitest/coverage-v8": "npm:^4.1.10" any-date-parser: "npm:^2.2.0" component-emitter: "npm:^1.3.1" compute-scroll-into-view: "npm:^3.1.1" @@ -2697,6 +2608,17 @@ __metadata: languageName: node linkType: hard +"ast-v8-to-istanbul@npm:^1.0.0": + version: 1.0.5 + resolution: "ast-v8-to-istanbul@npm:1.0.5" + dependencies: + "@jridgewell/trace-mapping": "npm:^0.3.31" + estree-walker: "npm:^3.0.3" + js-tokens: "npm:^10.0.0" + checksum: 10c0/546db141f60913846ea2e74fc163ec5b9b1b5aa4863a564ccb15fefe12988191fe029b1d91541aa2f236900c1447de53876460c179efc3dd15b1b9281d6205a6 + languageName: node + linkType: hard + "asynckit@npm:^0.4.0": version: 0.4.0 resolution: "asynckit@npm:0.4.0" @@ -2711,15 +2633,6 @@ __metadata: languageName: node linkType: hard -"baseline-browser-mapping@npm:^2.10.44": - version: 2.11.3 - resolution: "baseline-browser-mapping@npm:2.11.3" - bin: - baseline-browser-mapping: dist/cli.cjs - checksum: 10c0/163c8fd7161133afdd660d21f87b7ec4eb31ae0070dfaffa2f8b8c49929263a205b0667052814b48325fdd940b93bcaa0ce2dff3446413d2ef4ebce452b8edce - languageName: node - linkType: hard - "before-after-hook@npm:^3.0.2": version: 3.0.2 resolution: "before-after-hook@npm:3.0.2" @@ -2848,21 +2761,6 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.24.0": - version: 4.28.7 - resolution: "browserslist@npm:4.28.7" - dependencies: - baseline-browser-mapping: "npm:^2.10.44" - caniuse-lite: "npm:^1.0.30001806" - electron-to-chromium: "npm:^1.5.393" - node-releases: "npm:^2.0.51" - update-browserslist-db: "npm:^1.2.3" - bin: - browserslist: cli.js - checksum: 10c0/dc41922a9ff0d81e5492498bdab2d932e3a3222f4277814ba38ee64f4e51f26e5244a7cce0777b4cac3ceff6eb196f5cadbb2a832620973a7f9c39611f6bc78e - languageName: node - linkType: hard - "buffer-from@npm:^1.0.0": version: 1.1.2 resolution: "buffer-from@npm:1.1.2" @@ -2972,13 +2870,6 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001806": - version: 1.0.30001806 - resolution: "caniuse-lite@npm:1.0.30001806" - checksum: 10c0/9442c8afff0968e9b2ce0104a7340c1ce4a5c09f469ccb9eef10d25712ea0afe542486e5318c697c70dd502f988cfc04eaa1c9438c92ac3bcf4d708a2a17bee1 - languageName: node - linkType: hard - "chai@npm:^6.2.2": version: 6.2.2 resolution: "chai@npm:6.2.2" @@ -3722,7 +3613,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.1.0, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4": +"debug@npm:4, debug@npm:^4.3.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4": version: 4.3.4 resolution: "debug@npm:4.3.4" dependencies: @@ -4016,13 +3907,6 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.393": - version: 1.5.396 - resolution: "electron-to-chromium@npm:1.5.396" - checksum: 10c0/2ac1d007acae6466649c2ada1f147fa205d980fc01bc602da00823b64a88b4286138a71c7b145f67dfa9103f69fd884bf706395a72886358d8f231a7011a39e5 - languageName: node - linkType: hard - "embla-carousel-wheel-gestures@npm:^8.0.1": version: 8.0.1 resolution: "embla-carousel-wheel-gestures@npm:8.0.1" @@ -4158,13 +4042,6 @@ __metadata: languageName: node linkType: hard -"escalade@npm:^3.2.0": - version: 3.2.0 - resolution: "escalade@npm:3.2.0" - checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65 - languageName: node - linkType: hard - "escape-goat@npm:^2.0.0": version: 2.1.1 resolution: "escape-goat@npm:2.1.1" @@ -4792,13 +4669,6 @@ __metadata: languageName: node linkType: hard -"gensync@npm:^1.0.0-beta.2": - version: 1.0.0-beta.2 - resolution: "gensync@npm:1.0.0-beta.2" - checksum: 10c0/782aba6cba65b1bb5af3b095d96249d20edbe8df32dbf4696fd49be2583faf676173bf4809386588828e4dd76a3354fcbeb577bab1c833ccd9fc4577f26103f8 - languageName: node - linkType: hard - "get-caller-file@npm:^2.0.1, get-caller-file@npm:^2.0.5": version: 2.0.5 resolution: "get-caller-file@npm:2.0.5" @@ -5738,6 +5608,13 @@ __metadata: languageName: node linkType: hard +"js-tokens@npm:^10.0.0": + version: 10.0.0 + resolution: "js-tokens@npm:10.0.0" + checksum: 10c0/a93498747812ba3e0c8626f95f75ab29319f2a13613a0de9e610700405760931624433a0de59eb7c27ff8836e526768fb20783861b86ef89be96676f2c996b64 + languageName: node + linkType: hard + "js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -5878,15 +5755,6 @@ __metadata: languageName: node linkType: hard -"json5@npm:^2.2.3": - version: 2.2.3 - resolution: "json5@npm:2.2.3" - bin: - json5: lib/cli.js - checksum: 10c0/5a04eed94810fa55c5ea138b2f7a5c12b97c3750bc63d11e511dcecbfef758003861522a070c2272764ee0f4e3e323862f386945aeb5b85b87ee43f084ba586c - languageName: node - linkType: hard - "jsonfile@npm:^4.0.0": version: 4.0.0 resolution: "jsonfile@npm:4.0.0" @@ -7076,13 +6944,6 @@ __metadata: languageName: node linkType: hard -"node-releases@npm:^2.0.51": - version: 2.0.51 - resolution: "node-releases@npm:2.0.51" - checksum: 10c0/6cf3fe1f9eabe02ce6de67e9db77b73edc9f5625003791e1f8f239f8e2a851450a5aeb1eff2cc43cfb26312e19b26bfe07626bf428479e6a76f56553fc6148da - languageName: node - linkType: hard - "nopt@npm:^7.0.0": version: 7.2.0 resolution: "nopt@npm:7.2.0" @@ -9205,7 +9066,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^6.0.0, semver@npm:^6.2.0, semver@npm:^6.3.0, semver@npm:^6.3.1": +"semver@npm:^6.0.0, semver@npm:^6.2.0, semver@npm:^6.3.0": version: 6.3.1 resolution: "semver@npm:6.3.1" bin: @@ -10321,20 +10182,6 @@ __metadata: languageName: node linkType: hard -"update-browserslist-db@npm:^1.2.3": - version: 1.2.3 - resolution: "update-browserslist-db@npm:1.2.3" - dependencies: - escalade: "npm:^3.2.0" - picocolors: "npm:^1.1.1" - peerDependencies: - browserslist: ">= 4.21.0" - bin: - update-browserslist-db: cli.js - checksum: 10c0/13a00355ea822388f68af57410ce3255941d5fb9b7c49342c4709a07c9f230bbef7f7499ae0ca7e0de532e79a82cc0c4edbd125f1a323a1845bf914efddf8bec - languageName: node - linkType: hard - "update-notifier@npm:^4.1.0": version: 4.1.3 resolution: "update-notifier@npm:4.1.3"