Compare commits

..
Author SHA1 Message Date
renovate[bot] 4542301d6e deps: update minor dependencies 2026-10-05 14:47:31 +00:00
19 changed files with 72 additions and 239 deletions
@@ -53,7 +53,7 @@ jobs:
- name: Setup Helm
uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3
with:
version: v3.8.0
version: v3.22.0
- name: Setup Nodejs with yarn install
uses: ./.github/actions/setup
@@ -78,7 +78,7 @@ jobs:
- name: Setup Helm
uses: azure/setup-helm@5119fcb9089d432beecbf79bb2c7915207344b78 # v3
with:
version: v3.8.0
version: v3.22.0
- name: Build Helm charts
run: |
+1 -1
View File
@@ -22,7 +22,7 @@
"@xterm/addon-webgl": "0.19.0",
"@xterm/addon-canvas": "0.7.0",
"node-polyfill-webpack-plugin": "^3.0.0",
"elkjs": "^0.11.0",
"elkjs": "^0.12.0",
"vue-draggable-next": "^2.2.1",
"yaml": "^2.5.1"
},
+2 -5
View File
@@ -76,15 +76,12 @@ const FEATURE_FLAGS = {
'longhornV2HugepageSettings',
'staticIPForVM',
'fsFreezeDeadline',
'highPerformanceStorage',
],
'v1.9.1': [
'lvmDmThinOnly',
'highPerformanceStorage',
],
'v1.10.0': [
'maintenanceModeConditions',
'maintenanceModeDrainTimeoutSetting',
],
'v1.10.0': [],
};
const generateFeatureFlags = () => {
+1 -1
View File
@@ -22,7 +22,7 @@ export const HCI = {
VM_NAME_PREFIX: 'harvesterhci.io/vmNamePrefix',
VM_DISPLAY_NAME: 'harvesterhci.io/vmDisplayName',
VM_RESERVED_MEMORY: 'harvesterhci.io/reservedMemory',
MAINTENANCE_STATUS: 'harvesterhci.io/maintain-status', // Deprecated >= v1.10.0
MAINTENANCE_STATUS: 'harvesterhci.io/maintain-status',
HOST_CUSTOM_NAME: 'harvesterhci.io/host-custom-name',
HOST_CONSOLE_URL: 'harvesterhci.io/host-console-url',
RESTORE_NAME: 'restore.harvesterhci.io/name',
+1 -5
View File
@@ -45,8 +45,7 @@ export const HCI_SETTING = {
MAX_HOTPLUG_RATIO: 'max-hotplug-ratio',
KUBEVIRT_MIGRATION: 'kubevirt-migration',
INSTANCE_MANAGER_RESOURCES: 'instance-manager-resources',
CLUSTER_POD_SECURITY_STANDARD: 'cluster-pod-security-standard',
MAINTENANCE_MODE_DRAIN_TIMEOUT: 'maintenance-mode-drain-timeout'
CLUSTER_POD_SECURITY_STANDARD: 'cluster-pod-security-standard'
};
export const HCI_ALLOWED_SETTINGS = {
@@ -149,9 +148,6 @@ export const HCI_ALLOWED_SETTINGS = {
},
[HCI_SETTING.CLUSTER_POD_SECURITY_STANDARD]: {
kind: 'json', from: 'import', canReset: true, featureFlag: 'clusterPodSecurityStandardSetting'
},
[HCI_SETTING.MAINTENANCE_MODE_DRAIN_TIMEOUT]: {
kind: 'number', canReset: true, featureFlag: 'maintenanceModeDrainTimeoutSetting'
}
};
@@ -15,7 +15,6 @@ import OverviewKeypairs from '../kubevirt.io.virtualmachine/VirtualMachineTabs/V
import Volume from '../../edit/kubevirt.io.virtualmachine/VirtualMachineVolume';
import Network from '../../edit/kubevirt.io.virtualmachine/VirtualMachineNetwork';
import CloudConfig from '../../edit/kubevirt.io.virtualmachine/VirtualMachineCloudConfig';
import { getBootDevices } from '../../utils/vm';
const UNDEFINED = 'n/a';
export default {
@@ -75,8 +74,18 @@ export default {
return image?.spec?.displayName || '-';
},
bootDevices() {
return getBootDevices(this?.spec?.template?.spec?.domain?.devices);
disks() {
const disks = this?.spec?.template?.spec?.domain?.devices?.disks || [];
return disks.filter((disk) => {
return !!disk.bootOrder;
}).sort((a, b) => {
if (a.bootOrder < b.bootOrder) {
return -1;
}
return 1;
});
},
cdroms() {
@@ -92,10 +101,8 @@ export default {
getDeviceType(o) {
if (o.disk) {
return 'Disk';
} else if (o.cdrom) {
return 'CD-ROM';
} else {
return 'Network';
return 'CD-ROM';
}
},
isEmpty(o) {
@@ -177,10 +184,10 @@ export default {
<div>
<ul>
<li
v-for="(device, i) in bootDevices"
v-for="(disk, i) in disks"
:key="i"
>
{{ device.bootOrder }}. {{ device.name }} ({{ getDeviceType(device) }})
{{ disk.bootOrder }}. {{ disk.name }} ({{ getDeviceType(disk) }})
</li>
</ul>
</div>
@@ -226,7 +233,6 @@ export default {
>
<Network
v-model:value="networkRows"
:network-boot-first="networkBootFirst"
:mode="mode"
/>
</Tab>
@@ -15,7 +15,6 @@ import OverviewKeypairs from '../kubevirt.io.virtualmachine/VirtualMachineTabs/V
import Volume from '../../edit/kubevirt.io.virtualmachine/VirtualMachineVolume';
import Network from '../../edit/kubevirt.io.virtualmachine/VirtualMachineNetwork';
import CloudConfig from '../../edit/kubevirt.io.virtualmachine/VirtualMachineCloudConfig';
import { getBootDevices } from '../../utils/vm';
const UNDEFINED = 'n/a';
export default {
@@ -75,8 +74,18 @@ export default {
return image?.spec?.displayName || '-';
},
bootDevices() {
return getBootDevices(this?.spec?.template?.spec?.domain?.devices);
disks() {
const disks = this?.spec?.template?.spec?.domain?.devices?.disks || [];
return disks.filter((disk) => {
return !!disk.bootOrder;
}).sort((a, b) => {
if (a.bootOrder < b.bootOrder) {
return -1;
}
return 1;
});
},
cdroms() {
@@ -92,10 +101,8 @@ export default {
getDeviceType(o) {
if (o.disk) {
return 'Disk';
} else if (o.cdrom) {
return 'CD-ROM';
} else {
return 'Network';
return 'CD-ROM';
}
},
isEmpty(o) {
@@ -177,10 +184,10 @@ export default {
<div>
<ul>
<li
v-for="(device, i) in bootDevices"
v-for="(disk, i) in disks"
:key="i"
>
{{ device.bootOrder }}. {{ device.name }} ({{ getDeviceType(device) }})
{{ disk.bootOrder }}. {{ disk.name }} ({{ getDeviceType(disk) }})
</li>
</ul>
</div>
@@ -227,7 +234,6 @@ export default {
>
<Network
v-model:value="networkRows"
:network-boot-first="networkBootFirst"
:mode="mode"
/>
</Tab>
@@ -6,7 +6,6 @@ import HarvesterIpAddress from '../../../formatters/HarvesterIpAddress';
import VMConsoleBar from '../../../components/VMConsoleBar';
import { HCI } from '../../../types';
import { getVmCPUMemoryValues } from '../../../utils/cpuMemory';
import { getBootDevices } from '../../../utils/vm';
const UNDEFINED = 'n/a';
@@ -70,8 +69,18 @@ export default {
return image?.spec?.displayName || 'N/A';
},
bootDevices() {
return getBootDevices(this.value?.spec?.template?.spec?.domain?.devices);
disks() {
const disks = this.value?.spec?.template?.spec?.domain?.devices?.disks || [];
return disks.filter((disk) => {
return !!disk.bootOrder;
}).sort((a, b) => {
if (a.bootOrder < b.bootOrder) {
return -1;
}
return 1;
});
},
cdroms() {
@@ -113,10 +122,8 @@ export default {
getDeviceType(o) {
if (o.disk) {
return 'Disk';
} else if (o.cdrom) {
return 'CD-ROM';
} else {
return 'Network';
return 'CD-ROM';
}
},
isEmpty(o) {
@@ -212,16 +219,16 @@ export default {
<div class="col span-6">
<InputOrDisplay
:name="t('harvester.virtualMachine.detail.details.bootOrder')"
:value="bootDevices"
:value="disks"
:mode="mode"
>
<template #value>
<ul>
<li
v-for="(device, i) in bootDevices"
v-for="(disk, i) in disks"
:key="i"
>
{{ device.bootOrder }}. {{ device.name }} ({{ getDeviceType(device) }})
{{ disk.bootOrder }}. {{ disk.name }} ({{ getDeviceType(disk) }})
</li>
</ul>
</template>
@@ -214,7 +214,6 @@ export default {
this['diskRows'] = diskRows;
this['networkRows'] = this.getNetworkRows(neu, { fromTemplate: false, init: false });
this['networkBootFirst'] = this.isNetworkBootFirst(neu.spec);
// getInitConfig() seeds these on created(); refresh them here too so the
// VM-wide performance panel does not go stale when the spec changes.
@@ -277,7 +276,6 @@ export default {
>
<Network
v-model:value="networkRows"
:network-boot-first="networkBootFirst"
mode="view"
:vm="value"
/>
@@ -324,7 +324,6 @@ export default {
>
<Network
v-model:value="networkRows"
v-model:network-boot-first="networkBootFirst"
:mode="mode"
/>
</Tab>
@@ -2,7 +2,6 @@
import InputOrDisplay from '@shell/components/InputOrDisplay';
import { LabeledInput } from '@components/Form/LabeledInput';
import LabeledSelect from '@shell/components/form/LabeledSelect';
import { Checkbox } from '@components/Form/Checkbox';
import { clone } from '@shell/utils/object';
import { _CREATE, _VIEW } from '@shell/config/query-params';
@@ -34,7 +33,7 @@ export default {
emits: ['update'],
components: {
LabeledInput, LabeledSelect, InputOrDisplay, Checkbox
LabeledInput, LabeledSelect, InputOrDisplay
},
props: {
@@ -170,7 +169,6 @@ export default {
this.value.isPod = true;
this.value.macAddress = '';
this.value.staticIp = '';
this.value.networkBoot = false;
} else {
this.value.isPod = false;
}
@@ -287,22 +285,6 @@ export default {
</div>
</div>
<div
v-if="!isMasquerade"
data-testid="input-hen-networkBoot"
class="row mb-20"
>
<div class="col span-12">
<Checkbox
v-model:value="value.networkBoot"
:label="t('harvester.virtualMachine.network.networkBoot.label')"
:tooltip="t('harvester.virtualMachine.network.networkBoot.tip')"
:mode="mode"
@update:value="update"
/>
</div>
</div>
<div v-if="!isMasquerade && isSingle">
<div class="row mb-20">
<a
@@ -1,6 +1,5 @@
<script>
import InfoBox from '@shell/components/InfoBox';
import { RadioGroup } from '@components/Form/Radio';
import { NETWORK_ATTACHMENT } from '@shell/config/types';
import { sortBy } from '@shell/utils/sort';
import { clone } from '@shell/utils/object';
@@ -11,11 +10,7 @@ import { HCI as HCI_ANNOTATIONS } from '../../../config/labels-annotations';
import Base from './base';
export default {
components: {
InfoBox, Base, RadioGroup
},
emits: ['update:value', 'update:networkBootFirst'],
components: { InfoBox, Base },
props: {
vm: {
@@ -40,11 +35,6 @@ export default {
isSingle: {
type: Boolean,
default: true
},
networkBootFirst: {
type: Boolean,
default: true
}
},
@@ -92,20 +82,6 @@ export default {
vmState() {
return this.vm?.stateDisplay;
},
hasNetworkBoot() {
return this.rows.some((R) => R.networkBoot);
},
networkBootOrderOptions() {
return [{
label: this.t('harvester.virtualMachine.network.networkBoot.first'),
value: true
}, {
label: this.t('harvester.virtualMachine.network.networkBoot.last'),
value: false
}];
}
},
@@ -242,22 +218,6 @@ export default {
/>
</InfoBox>
<div
v-if="hasNetworkBoot"
data-testid="input-hen-networkBootFirst"
class="mb-20"
>
<RadioGroup
:value="networkBootFirst"
name="networkBootFirst"
:label="t('harvester.virtualMachine.network.networkBoot.order')"
:options="networkBootOrderOptions"
:mode="mode"
:row="true"
@update:value="$emit('update:networkBootFirst', $event)"
/>
</div>
<button
v-if="!isView"
type="button"
@@ -791,7 +791,6 @@ export default {
>
<Network
v-model:value="networkRows"
v-model:network-boot-first="networkBootFirst"
:mode="mode"
:is-single="isSingle"
/>
-8
View File
@@ -286,7 +286,6 @@ harvester:
createTemplate: Generate Template
enableMaintenance: Enable Maintenance Mode
disableMaintenance: Disable Maintenance Mode
clearMaintenance: Clear Maintenance Mode Error
enableCPUManager: Enable CPU Manager
disableCPUManager: Disable CPU Manager
cordon: Cordon
@@ -872,12 +871,6 @@ harvester:
title: Network
addNetwork: Add Network
addPort: Add Port
networkBoot:
label: Enable network boot (PXE)
tip: Adds this interface to the VM boot order so the guest firmware can boot from the network. Requires a DHCP/TFTP (PXE) server reachable on the selected network; the management network does not provide one.
order: Network boot order
first: Before volumes
last: After volumes
cloudConfig:
title: Cloud Configuration
createTemplateTitle: 'Create {name}'
@@ -2542,7 +2535,6 @@ advancedSettings:
'harv-kubevirt-migration': 'Configure cluster-wide KubeVirt live migration parameters.'
'harv-instance-manager-resources': 'Configure resource percentage reservations for Longhorn instance manager V1 and V2. Valid instance manager CPU range between 0 - 40.'
'harv-cluster-pod-security-standard': 'Enforce Kubernetes Pod Security Standards (PSS) at the cluster level.'
'harv-maintenance-mode-drain-timeout': 'Maintenance mode drain timeout in minutes. Use 0 to disable the timeout.'
typeLabel:
kubevirt.io.virtualmachine: |-
+3 -35
View File
@@ -160,7 +160,6 @@ export default {
imageId: '',
diskRows: [],
networkRows: [],
networkBootFirst: true,
filesystemRows: [],
machineType: '',
machineTypes: [],
@@ -385,7 +384,6 @@ export default {
const diskRows = this.getDiskRows(vm, volumeBackups);
const networkRows = this.getNetworkRows(vm, { fromTemplate, init });
const networkBootFirst = this.isNetworkBootFirst(spec);
const hasCreateVolumes = this.getHasCreatedVolumes(spec) || [];
let { userData = undefined, networkData = undefined } = this.getCloudInitNoCloud(spec);
@@ -463,7 +461,6 @@ export default {
this['hasCreateVolumes'] = hasCreateVolumes;
this['networkRows'] = networkRows;
this['networkBootFirst'] = networkBootFirst;
this['imageId'] = imageId;
this['diskRows'] = diskRows;
@@ -679,29 +676,12 @@ export default {
model: I.model,
networkName: isPod ? MANAGEMENT_NETWORK : network?.multus?.networkName,
staticIp: annotations[`${ staticIpPrefix }${ I.name }`] || '',
networkBoot: !!I.bootOrder,
};
});
return out;
},
/**
* Network boot devices are placed either before or after all volumes in the boot sequence.
* Derive which one from an existing spec, so a round trip through the form keeps it.
*/
isNetworkBootFirst(spec) {
const devices = spec?.template?.spec?.domain?.devices || {};
const nicOrders = (devices.interfaces || []).map((I) => I.bootOrder).filter(Boolean);
const diskOrders = (devices.disks || []).map((D) => D.bootOrder).filter(Boolean);
if (nicOrders.length === 0 || diskOrders.length === 0) {
return true;
}
return Math.min(...nicOrders) < Math.min(...diskOrders);
},
parseVM() {
this.userData = this.getUserData({ osType: this.osType, installAgent: this.installAgent });
this.parseOther();
@@ -914,10 +894,9 @@ export default {
const disks = [];
const volumes = [];
const volumeClaimTemplates = [];
const bootOrderOffset = this.networkBootFirst ? this.networkRows.filter((R) => R.networkBoot).length : 0;
disk.forEach( (R, index) => {
const _disk = this.parseDisk(R, index + bootOrderOffset);
const _disk = this.parseDisk(R, index);
disks.push(_disk);
@@ -1175,11 +1154,9 @@ export default {
const networks = [];
const interfaces = [];
let bootOrder = this.networkBootFirst ? 1 : this.diskRows.length + 1;
networkRow.forEach( (R) => {
const _network = this.parseNetwork(R);
const _interface = this.parseInterface(R, R.networkBoot ? bootOrder++ : undefined);
const _interface = this.parseInterface(R);
networks.push(_network);
interfaces.push(_interface);
@@ -1435,7 +1412,7 @@ export default {
return arr.map( (id) => this.getSSHValue(id)).filter( (O) => O !== undefined);
},
parseInterface(R, bootOrder) {
parseInterface(R) {
const _interface = {};
const type = R.type;
@@ -1445,10 +1422,6 @@ export default {
_interface.macAddress = R.macAddress;
}
if (bootOrder) {
_interface.bootOrder = bootOrder;
}
_interface.model = R.model;
_interface.name = R.name;
@@ -1956,11 +1929,6 @@ export default {
delete merged['bridge'];
}
// boot order is owned by the form, don't inherit a stale one from the old spec
if (!iface.bootOrder) {
delete merged.bootOrder;
}
return merged;
}
+8 -66
View File
@@ -23,13 +23,6 @@ const ALLOW_SYSTEM_LABEL_KEYS = [
const HEALTHY = 'healthy';
const WARNING = 'warning';
const MAINTENANCE_MODE = 'MaintenanceMode';
const MAINTENANCE_ERROR = 'Error';
const MAINTENANCE_ENTERING_REASONS = ['Validating', 'Draining', 'Evacuating'];
const MAINTENANCE_COMPLETED = 'Completed';
// Legacy `harvesterhci.io/maintain-status` annotation values (clusters < v1.10)
const LEGACY_MAINTENANCE_RUNNING = 'running';
const LEGACY_MAINTENANCE_COMPLETED = 'completed';
export default class HciNode extends HarvesterResource {
get _availableActions() {
@@ -65,14 +58,6 @@ export default class HciNode extends HarvesterResource {
total: 1
};
const clearMaintenance = {
action: 'clearMaintenanceMode',
enabled: this.hasAction('clearMaintenanceMode'),
icon: 'icon icon-fw icon-close',
label: this.t('harvester.action.clearMaintenance'),
total: 1
};
const enableCPUManager = {
action: 'enableCPUManager',
enabled: this.cpuPinningFeatureEnabled && this.hasAction('enableCPUManager') && !this.isCPUManagerEnableInProgress && !this.isCPUManagerEnabled && !this.isEtcd, // witness node doesn't have CPU manager
@@ -118,7 +103,6 @@ export default class HciNode extends HarvesterResource {
uncordon,
enableMaintenance,
disableMaintenance,
clearMaintenance,
enableCPUManager,
disableCPUManager,
shutDown,
@@ -214,10 +198,6 @@ export default class HciNode extends HarvesterResource {
}
get stateDisplay() {
if (this.isMaintenanceModeError) {
return super.stateDisplay;
}
if (this.isEnteringMaintenance) {
return 'Entering maintenance mode';
}
@@ -266,10 +246,6 @@ export default class HciNode extends HarvesterResource {
}
get stateDescription() {
if (this.isMaintenanceModeError) {
return super.stateDescription;
}
const currentIP = this.metadata?.annotations?.[HCI_ANNOTATIONS.CURRENT_IP];
const initIP = this.metadata?.annotations?.[HCI_ANNOTATIONS.INIT_IP];
@@ -349,11 +325,7 @@ export default class HciNode extends HarvesterResource {
}
disableMaintenanceMode() {
this.doActionGrowl('disableMaintenanceMode', {});
}
clearMaintenanceMode() {
this.doActionGrowl('clearMaintenanceMode', {});
this.doAction('disableMaintenanceMode', {});
}
enableCPUManager() {
@@ -371,32 +343,11 @@ export default class HciNode extends HarvesterResource {
);
}
get maintenanceModeCondition() {
return (this.status?.conditions || []).find(
(c) => c.type === MAINTENANCE_MODE
);
}
get maintenanceModeConditionsEnabled() {
return this.$rootGetters['harvester-common/getFeatureEnabled']('maintenanceModeConditions');
}
// Clusters < v1.10 only expose the `harvesterhci.io/maintain-status` annotation
get legacyMaintenanceStatus() {
return this.metadata?.annotations?.[HCI_ANNOTATIONS.MAINTENANCE_STATUS];
}
get isMaintenanceModeError() {
return this.maintenanceModeConditionsEnabled && this.maintenanceModeCondition?.reason === MAINTENANCE_ERROR;
}
get isMigratable() {
const states = ['in-progress', 'unavailable'];
const engaged = this.maintenanceModeConditionsEnabled ? this.maintenanceModeCondition?.status === 'True' : !!this.legacyMaintenanceStatus;
return (
!engaged &&
!this.metadata?.annotations?.[HCI_ANNOTATIONS.MAINTENANCE_STATUS] &&
!this.isUnSchedulable &&
!states.includes(this.state)
);
@@ -411,26 +362,17 @@ export default class HciNode extends HarvesterResource {
}
get isEnteringMaintenance() {
if (!this.maintenanceModeConditionsEnabled) {
return this.legacyMaintenanceStatus === LEGACY_MAINTENANCE_RUNNING;
}
const cond = this.maintenanceModeCondition;
return (
cond?.status === 'True' &&
MAINTENANCE_ENTERING_REASONS.includes(cond?.reason)
this.metadata?.annotations?.[HCI_ANNOTATIONS.MAINTENANCE_STATUS] ===
'running'
);
}
get isMaintenance() {
if (!this.maintenanceModeConditionsEnabled) {
return this.legacyMaintenanceStatus === LEGACY_MAINTENANCE_COMPLETED;
}
const cond = this.maintenanceModeCondition;
return cond?.status === 'True' && cond?.reason === MAINTENANCE_COMPLETED;
return (
this.metadata?.annotations?.[HCI_ANNOTATIONS.MAINTENANCE_STATUS] ===
'completed'
);
}
get cpuPinningFeatureEnabled() {
-9
View File
@@ -11,12 +11,3 @@ export function parseVolumeClaimTemplates(data) {
}
export const EMPTY_IMAGE = 'EMPTY_IMAGE';
/**
* Disks and interfaces that take part in the boot sequence, sorted by boot order.
*/
export function getBootDevices(devices = {}) {
return [...(devices.disks || []), ...(devices.interfaces || [])]
.filter((device) => !!device.bootOrder)
.sort((a, b) => a.bootOrder - b.bootOrder);
}
+6 -16
View File
@@ -3099,16 +3099,11 @@
"@typescript-eslint/types" "8.62.0"
"@typescript-eslint/visitor-keys" "8.62.0"
"@typescript-eslint/tsconfig-utils@8.62.0":
"@typescript-eslint/tsconfig-utils@8.62.0", "@typescript-eslint/tsconfig-utils@^8.62.0":
version "8.62.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.62.0.tgz#9440a673581c6d9de308c4d5803dd52ed5d71729"
integrity sha512-y2GAdB6ykaXUvuspbYnizQc4oDDz0Tz/Yc7iWrXf9mx8vm/L/0vLHCe0tS2boG96Zy+DivnVDQ9ZUEWoHqqx1g==
"@typescript-eslint/tsconfig-utils@^8.62.0":
version "8.68.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.68.0.tgz#594d7a3c5952055b3c431fc563ca7fd1defcce18"
integrity sha512-F7zrGQfiJHojPwi8vhxZQC1tWtJzvL74cK/nqri2lk8YUXvYaYwl263xOJ69jDWPUk1hmcdoayFwk9lX09npVw==
"@typescript-eslint/type-utils@8.62.0":
version "8.62.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.62.0.tgz#6f64d813ed9f340d796baed40cdab86b8e9a491a"
@@ -3120,16 +3115,11 @@
debug "^4.4.3"
ts-api-utils "^2.5.0"
"@typescript-eslint/types@8.62.0":
"@typescript-eslint/types@8.62.0", "@typescript-eslint/types@^8.62.0":
version "8.62.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.62.0.tgz#601427c10203d9f0f34f0b3e474df735eb12b593"
integrity sha512-KvAclkktORPvM54TgLgA4z9HIV1M8zOgw9ZVNXl9f/8dLYfXYX1wkMXP7qmabpijQRV5bHJLOmoyGQbLMaUYeg==
"@typescript-eslint/types@^8.62.0":
version "8.68.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.68.0.tgz#3f9d4e62fbe5728f09403cdc7b4d58af842ac1af"
integrity sha512-9RnpsGJjrAllCMefGVVsImJM24YurhC0Q1h4UbvivtvOqXmR/vEJge2OoE++z9m6hyg8T1Q8t5SNT6tHSbrxcg==
"@typescript-eslint/typescript-estree@8.62.0":
version "8.62.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.62.0.tgz#b96b55d02e26aa09434421c3fa678e525ca09a4c"
@@ -6126,10 +6116,10 @@ element-matches@^0.1.2:
resolved "https://registry.yarnpkg.com/element-matches/-/element-matches-0.1.2.tgz#7345cb71e965bd2b12f725e524591c102198361a"
integrity sha512-yWh1otcs3OKUWDvu/IxyI36ZI3WNaRZlI0uG/DK6fu0pap0VYZ0J5pEGTk1zakme+hT0OKHwhlHc0N5TJhY6yQ==
elkjs@^0.11.0:
version "0.11.1"
resolved "https://registry.yarnpkg.com/elkjs/-/elkjs-0.11.1.tgz#d27fcdbbf5a8aeeff80420d17d1666f78cfc8544"
integrity sha512-zxxR9k+rx5ktMwT/FwyLdPCrq7xN6e4VGGHH8hA01vVYKjTFik7nHOxBnAYtrgYUB1RpAiLvA1/U2YraWxyKKg==
elkjs@^0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/elkjs/-/elkjs-0.12.0.tgz#7dc1bc71ab8f402d1b6564e2fa509ca1caee276c"
integrity sha512-YZcKynxVxYoKIOEpywEPwCFdg+BTbxQRNf3pbwdDCvc8O3kQD8bmIwSxKU1eOTVc4Xo+VG9Te+575mlfvOrhEQ==
elliptic@^6.5.3, elliptic@^6.6.1:
version "6.6.1"