Compare commits

...
Author SHA1 Message Date
mergify[bot]andfreeze bcd8929ba3 feat: drop striped LVM volume group type from v1.9.1 (#1167) (#1168)
The LVM add-on reaches GA in v1.9.1 and only supports dm-thin.
    Gate the striped option behind a v1.9.1 feature flag, default new
    LVM storage classes to dm-thin, and reset a cloned striped type so
    older clusters keep the current behaviour.

    Related issue: harvester/harvester#11731


(cherry picked from commit 3c92a06268)

Signed-off-by: Vicente Cheng <vicente.cheng@suse.com>
Co-authored-by: freeze <1615081+Vicente-Cheng@users.noreply.github.com>
2026-09-23 16:34:58 +08:00
Harvester Bot 24834396b9 chore: bump version to 1.9.1-rc2 (#1169)
Signed-off-by: Harvester Bot <94133267+harvesterhci-io-github-bot@users.noreply.github.com>
2026-09-23 16:34:18 +08:00
mergify[bot]andfreeze 280878ebb3 ci: pin package version to the git tag for tag builds (#1165) (#1166)
Sprint tags (vX.Y.Z-dev-YYYYMMDD) only share a prefix with the
    x.y.z-dev version in package.json, so every sprint plugin reported
    the same version and the catalog image push hit "Cannot overwrite
    production image". Bump the tree to the tag before building.

    Related issue: harvester/harvester#11047


(cherry picked from commit 6256cdc97a)

Signed-off-by: Vicente Cheng <vicente.cheng@suse.com>
Co-authored-by: freeze <1615081+Vicente-Cheng@users.noreply.github.com>
2026-09-22 19:42:17 +08:00
mergify[bot]andAndy Lee 51da6a551c chore: add v1.10.0 and v1.9.1 feature flags (#1156) (#1158)
(cherry picked from commit d05ec68e16)

Signed-off-by: Andy Lee <andy.lee@suse.com>
Co-authored-by: Andy Lee <andy.lee@suse.com>
2026-09-18 16:51:15 +08:00
Harvester Bot 010dd710fc chore: bump version to 1.9.1-rc1 (#1157)
Signed-off-by: Harvester Bot <94133267+harvesterhci-io-github-bot@users.noreply.github.com>
2026-09-17 22:40:41 +08:00
Andy Leeandrenovate[bot] 788c583210 deps: update dependency qs to v6.16.0 [security] (backport #1134) (#1143)
* deps: update dependency qs to v6.16.0 [security] (#1134)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
(cherry picked from commit bbe0c4643f)

# Conflicts:
#	yarn.lock

* fix: yarn.lock conflict

Signed-off-by: Andy Lee <andy.lee@suse.com>

---------

Signed-off-by: Andy Lee <andy.lee@suse.com>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-16 09:40:35 +08:00
mergify[bot]andAndy Lee ee8f214b7f fix: avoid userpreferences PUT flood from SideNav refresh trigger (#1119) (#1155)
kickSideNav toggled a dummy favorite via addFavorite/removeFavorite, which persist through prefs/set and issue a PUT /v1/userpreferences on every toggle, flooding the backend and surfacing 500 errors. Switch to the in-memory prefs/load mutation so the SideNav still re-renders without any network request.


(cherry picked from commit cb2cef5e73)

Signed-off-by: Andy Lee <andy.lee@suse.com>
Co-authored-by: Andy Lee <andy.lee@suse.com>
2026-09-16 09:35:45 +08:00
mergify[bot]andAndy Lee 27c1e64a05 feat: change logo based on server-flavor setting (#1151) (#1154)
* feat: use prime logo when server-flavor is prime



* feat: expose server-flavor setting



* refactor: copilot review



---------


(cherry picked from commit 45116b568a)

Signed-off-by: Andy Lee <andy.lee@suse.com>
Co-authored-by: Andy Lee <andy.lee@suse.com>
2026-09-16 09:35:15 +08:00
mergify[bot]andVictor Chang 68d67a7cbc fix: require names for cloud configuration templates (#1138) (#1153)
(cherry picked from commit f42d798d10)

Signed-off-by: Victor Chang <t7902195204@gmail.com>
Co-authored-by: Victor Chang <t7902195204@gmail.com>
2026-09-16 09:29:39 +08:00
mergify[bot]andAndy Lee 6a7691456f feat: add rancher k3k addon UI page (#1137) (#1148)
* feat: add k3k addon UI



* feat: add rancher-k3k addon UI



* refactor: copilot review



* refactor: copilot review



* refactor: remove k3k edit page



* refactor: k3k addon description



---------


(cherry picked from commit 50b4cf5248)

Signed-off-by: Andy Lee <andy.lee@suse.com>
Co-authored-by: Andy Lee <andy.lee@suse.com>
2026-09-16 08:54:09 +08:00
Harvester Bot 66f6c36759 chore: bump version to 1.9.0 (#1152)
Signed-off-by: Harvester Bot <94133267+harvesterhci-io-github-bot@users.noreply.github.com>
2026-09-15 21:24:41 +08:00
Harvester Bot eb77d03b97 chore: bump version to 1.9.0-rc7 (#1132)
Signed-off-by: Harvester Bot <94133267+harvesterhci-io-github-bot@users.noreply.github.com>
2026-09-01 18:47:34 +08:00
22deb0e1f6 feat: LHv2: graduate from "Experimental" to "Preview" (#1129) (#1131)
In Harvester v1.9.0, we're moving LHv2 from "Experimental" to "Preview",
so I've added a new preview label to the settings interface.  I figure
given Experimental had the "error" color, I should make "Preview" use
the warning color, to make it a bit less alarming :-)

Related-to: https://github.com/harvester/harvester/issues/9960



(cherry picked from commit 4fa6470343)

Signed-off-by: Tim Serong <tserong@suse.com>
Co-authored-by: Tim Serong <tserong@suse.com>
Co-authored-by: Volker Theile <vtheile@suse.com>
2026-09-01 12:13:39 +10:00
mergify[bot]andAndy Lee f096147aa3 fix: vGPU doesn't display when creating harvester downstream cluster (#1123) (#1128)
* fix: vGPU doesn't display in edit VM page



* fix: align PCI passthrough action buttons height

Match the enable/disable passthrough and Actions dropdown buttons to 40px and move the selected-count label below them.



---------


(cherry picked from commit d550046189)

Signed-off-by: Andy Lee <andy.lee@suse.com>
Co-authored-by: Andy Lee <andy.lee@suse.com>
2026-08-25 16:50:27 +08:00
Harvester Bot d73a9413be chore: bump version to 1.9.0-rc6 (#1122)
Signed-off-by: Harvester Bot <94133267+harvesterhci-io-github-bot@users.noreply.github.com>
2026-08-19 18:40:46 +08:00
mergify[bot]andPo Han Huang 63ff8ce8fe feat: improve readability for vm migration UI (#1112) (#1120)
(cherry picked from commit 5f32a9ade5)

Signed-off-by: pohanhuang <pohan.huang@suse.com>
Co-authored-by: Po Han Huang <pohan.huang@suse.com>
2026-08-18 12:41:02 +08:00
mergify[bot] b3b467f7b5 fix: exclude forklift namespace from system classification (#1114) (#1118) 2026-08-17 13:37:43 +08:00
mergify[bot]andAndy Lee 20557ee788 fix: ACCESS_MODE undefined error in forklift mapping page (#1111) (#1113)
(cherry picked from commit f63be73b11)

Signed-off-by: Andy Lee <andy.lee@suse.com>
Co-authored-by: Andy Lee <andy.lee@suse.com>
2026-08-14 22:49:01 +08:00
29 changed files with 792 additions and 128 deletions
@@ -125,6 +125,13 @@ jobs:
node-version-file: '.nvmrc'
cache: 'yarn'
# Tag builds (RC, formal and sprint releases) ship the tag as the package
# version. RC/formal tags already match package.json; sprint tags
# (vX.Y.Z-dev-YYYYMMDD) only share its prefix, so pin it here for the build.
- name: Pin package version to tag
if: ${{ inputs.CI_BUILD_TAG != '' }}
run: ./scripts/bump_version.sh "${{ inputs.CI_BUILD_TAG }}"
- id: ci-build-pkg
name: Build pkg
run: ./scripts/ci-build-pkg.sh harvester
@@ -58,6 +58,12 @@ jobs:
- name: Setup Nodejs with yarn install
uses: ./.github/actions/setup
# The catalog image is tagged with the package.json version. Sprint tags
# (vX.Y.Z-dev-YYYYMMDD) only share its prefix, so pin it to the tag here.
- name: Pin package version to tag
if: ${{ github.ref_type == 'tag' }}
run: ./scripts/bump_version.sh "${{ github.ref_name }}"
- name: Build and push UI image
run: |
publish="yarn publish-pkgs -cp -r ${{ inputs.registry_target }} -o ${{ inputs.registry_user }}"
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "harvester-ui-extension",
"version": "1.9.0-rc5",
"version": "1.9.1-rc2",
"private": false,
"engines": {
"node": ">=24.0.0"
@@ -39,7 +39,7 @@
"merge": "2.1.1",
"node-forge": "1.4.0",
"nth-check": "2.1.1",
"qs": "6.15.3",
"qs": "6.16.0",
"roarr": "7.21.7",
"semver": "7.8.5",
"@vue/cli-service/html-webpack-plugin": "^5.0.0"
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.8 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.8 KiB

+21 -14
View File
@@ -10,6 +10,7 @@ import { docLink } from '../utils/feature-flags';
const CATEGORY = {
ui: [
'branding',
HCI_SETTING.SERVER_FLAVOR,
'ui-source',
'ui-index',
]
@@ -53,7 +54,7 @@ export default {
};
},
computed: { ...mapGetters({ t: 'i18n/t' }) },
computed: { ...mapGetters({ t: 'i18n/t', isHarvesterPrime: 'harvester-common/isHarvesterPrime' }) },
watch: {
settings: {
@@ -231,14 +232,21 @@ export default {
v-if="setting.customized"
class="modified"
>
Modified
{{ t('advancedSettings.tags.modified.label') }}
</span>
<span
v-if="setting.experimental"
v-clean-tooltip="t('advancedSettings.experimental')"
v-clean-tooltip="t('advancedSettings.tags.experimental.description')"
class="experimental"
>
Experimental
{{ t('advancedSettings.tags.experimental.label') }}
</span>
<span
v-if="setting.preview"
v-clean-tooltip="t('advancedSettings.tags.preview.description')"
class="preview"
>
{{ t('advancedSettings.tags.preview.label') }}
</span>
</h1>
<h2 v-clean-html="t(setting.description, getDocLinkParams(setting) || {}, true)">
@@ -262,7 +270,8 @@ export default {
v-if="!setting.hide"
class="settings-value"
>
<pre v-if="setting.kind === 'json'">{{ setting.json }}</pre>
<pre v-if="setting.id === 'branding' && isHarvesterPrime">{{ $store.getters['harvester-common/privateLabel'] }}</pre>
<pre v-else-if="setting.kind === 'json'">{{ setting.json }}</pre>
<pre v-else-if="setting.kind === 'multiline'">{{ setting.data.value || setting.data.default }}</pre>
<pre v-else-if="setting.kind === 'enum'">{{ t(setting.enum) }}</pre>
<pre v-else-if="setting.kind === 'custom' && setting.custom">{{ setting.custom }}</pre>
@@ -352,21 +361,19 @@ export default {
flex: 1;
}
.modified {
.modified,
.experimental,
.preview {
margin-left: 10px;
border: 1px solid var(--primary);
border: 1px solid;
border-radius: 5px;
padding: 2px 10px;
font-size: 12px;
}
.experimental {
margin-left: 10px;
border: 1px solid var(--error);
border-radius: 5px;
padding: 2px 10px;
font-size: 12px;
}
.modified { border-color: var(--primary); }
.experimental { border-color: var(--error); }
.preview { border-color: var(--warning); }
.no-search-match {
text-align: center;
@@ -15,7 +15,7 @@ import MappingColumn from './MappingColumn.vue';
import StorageDefaultsModal from './StorageDefaultsModal.vue';
const DEFAULT_VOLUME_MODE = VOLUME_MODE.FILE_SYSTEM;
const DEFAULT_ACCESS_MODES = [ACCESS_MODE.READ_WRITE_MANY];
const DEFAULT_ACCESS_MODE = ACCESS_MODE?.READ_WRITE_MANY ?? 'ReadWriteMany';
const props = defineProps({
providerName: { type: String, default: '' },
@@ -268,9 +268,9 @@ const buildStorageEntries = () => {
capacity: 0,
target: '',
volumeMode: DEFAULT_VOLUME_MODE,
accessModes: [...DEFAULT_ACCESS_MODES],
accessModes: [DEFAULT_ACCESS_MODE],
inheritedVolumeMode: DEFAULT_VOLUME_MODE,
inheritedAccessModes: [...DEFAULT_ACCESS_MODES],
inheritedAccessModes: [DEFAULT_ACCESS_MODE],
inheritedFromProvider: false,
overridden: false,
usedBy: [],
@@ -310,9 +310,9 @@ const buildStorageEntriesFromProvider = (datastoresData) => {
capacity: ds.capacity || 0,
target: '',
volumeMode: DEFAULT_VOLUME_MODE,
accessModes: [...DEFAULT_ACCESS_MODES],
accessModes: [DEFAULT_ACCESS_MODE],
inheritedVolumeMode: DEFAULT_VOLUME_MODE,
inheritedAccessModes: [...DEFAULT_ACCESS_MODES],
inheritedAccessModes: [DEFAULT_ACCESS_MODE],
inheritedFromProvider: false,
overridden: false,
usedBy: [],
@@ -8,16 +8,22 @@ import { useI18n } from '@shell/composables/useI18n';
import { VOLUME_MODE, ACCESS_MODE } from '../../config/types';
const VOLUME_MODE_OPTIONS = [VOLUME_MODE.FILE_SYSTEM, VOLUME_MODE.BLOCK];
const ACCESS_MODE_OPTIONS = [ACCESS_MODE.READ_WRITE_ONCE, ACCESS_MODE.READ_WRITE_MANY, ACCESS_MODE.READ_ONLY_MANY];
const {
READ_WRITE_ONCE = 'ReadWriteOnce',
READ_ONLY_MANY = 'ReadOnlyMany',
READ_WRITE_MANY = 'ReadWriteMany',
READ_WRITE_ONCE_POD = 'ReadWriteOncePod'
} = ACCESS_MODE || {};
const ACCESS_MODE_OPTIONS = [READ_WRITE_ONCE, READ_WRITE_MANY, READ_ONLY_MANY, READ_WRITE_ONCE_POD];
const props = defineProps({
storageClassName: { type: String, default: '' },
providerName: { type: String, default: '' },
showInherited: { type: Boolean, default: false },
volumeMode: { type: String, default: VOLUME_MODE.FILE_SYSTEM },
accessModes: { type: Array, default: () => [ACCESS_MODE.READ_WRITE_MANY] },
accessModes: { type: Array, default: () => ['ReadWriteMany'] },
inheritedVolumeMode: { type: String, default: VOLUME_MODE.FILE_SYSTEM },
inheritedAccessModes: { type: Array, default: () => [ACCESS_MODE.READ_WRITE_MANY] },
inheritedAccessModes: { type: Array, default: () => ['ReadWriteMany'] },
});
const emit = defineEmits(['apply', 'close']);
@@ -26,7 +32,7 @@ const store = useStore();
const { t } = useI18n(store);
const localVolumeMode = ref(props.volumeMode || VOLUME_MODE.FILE_SYSTEM);
const localAccessMode = ref(props.accessModes?.[0] || ACCESS_MODE.READ_WRITE_MANY);
const localAccessMode = ref(props.accessModes?.[0] || READ_WRITE_MANY);
const volumeModeOptions = VOLUME_MODE_OPTIONS.map((value) => ({ label: value, value }));
const accessModeOptions = ACCESS_MODE_OPTIONS.map((value) => ({ label: value, value }));
@@ -42,7 +48,7 @@ const apply = () => {
// Repopulate the dropdowns with the provider default values; the user then applies.
const reset = () => {
localVolumeMode.value = props.inheritedVolumeMode || VOLUME_MODE.FILE_SYSTEM;
localAccessMode.value = props.inheritedAccessModes?.[0] || ACCESS_MODE.READ_WRITE_MANY;
localAccessMode.value = props.inheritedAccessModes?.[0] || READ_WRITE_MANY;
};
const cancel = () => {
+4
View File
@@ -77,6 +77,10 @@ const FEATURE_FLAGS = {
'staticIPForVM',
'fsFreezeDeadline',
],
'v1.9.1': [
'lvmDmThinOnly',
],
'v1.10.0': [],
};
const generateFeatureFlags = () => {
+47 -9
View File
@@ -57,6 +57,8 @@ import {
} from './table-headers';
import { ADD_ONS } from './harvester-map';
import { registerAddonSideNav } from '../utils/dynamic-nav';
import { setVendor } from '@shell/config/private-label';
import { createCssVars } from '@shell/utils/color';
const TEMPLATE = HCI.VM_VERSION;
const MONITORING_GROUP = 'Monitoring & Logging::Monitoring';
@@ -109,15 +111,51 @@ export function init($plugin, store) {
}
};
store.dispatch('setIsSingleProduct', {
productName: PRODUCT_NAME,
logo: require(`@shell/assets/images/providers/harvester.svg`),
productNameKey: 'harvester.productLabel',
getVersionInfo: (store) => store.getters[`${ PRODUCT_NAME }/byId`]?.(HCI.SETTING, 'server-version')?.value || 'unknown',
afterLoginRoute: home,
logoRoute: home,
supportCustomLogo: true
});
store.watch(
(_state, getters) => JSON.stringify([
!!getters['harvester-common/isHarvesterPrime'],
getters['prefs/theme'] === 'dark',
getters['harvester-common/privateLabel']
]),
(value) => {
const [isHarvesterPrime, isDark, privateLabel] = JSON.parse(value);
const primeLogo = isDark ? require('../assets/images/dark/suse-virtualization.svg') : require('../assets/images/suse-virtualization.svg');
setVendor(privateLabel || '');
let primaryColorStyle = document.getElementById('harvester-prime-primary-color');
// set harvester prime primary color style to #4dd192 (Cyan Green)
if (isHarvesterPrime) {
if (!primaryColorStyle) {
primaryColorStyle = document.createElement('style');
primaryColorStyle.id = 'harvester-prime-primary-color';
document.head.appendChild(primaryColorStyle);
primaryColorStyle.sheet.insertRule('body.theme-light, body.theme-dark {}', 0);
}
const colors = createCssVars('#4dd192', isDark ? 'dark' : 'light');
const rule = primaryColorStyle.sheet.cssRules[0];
Object.entries(colors).forEach(([property, color]) => rule.style.setProperty(property.trim(), color));
} else {
primaryColorStyle?.remove();
}
const primeLabelKey = privateLabel ? 'harvester.branding.primeLabel' : 'harvester.branding.primeEmptyLabel';
store.dispatch('setIsSingleProduct', {
productName: PRODUCT_NAME,
logo: isHarvesterPrime ? primeLogo : require(`@shell/assets/images/providers/harvester.svg`),
productNameKey: isHarvesterPrime ? primeLabelKey : 'harvester.productLabel',
getVersionInfo: (store) => store.getters[`${ PRODUCT_NAME }/byId`]?.(HCI.SETTING, 'server-version')?.value || 'unknown',
afterLoginRoute: home,
logoRoute: home,
supportCustomLogo: !isHarvesterPrime
});
},
{ immediate: true }
);
}
product({
+5 -1
View File
@@ -3,6 +3,7 @@ export const HCI_SETTING = {
CONTAINERD_REGISTRY: 'containerd-registry',
LOG_LEVEL: 'log-level',
SERVER_VERSION: 'server-version',
SERVER_FLAVOR: 'server-flavor',
UI_INDEX: 'ui-index',
UPGRADE_CHECKER_ENABLED: 'upgrade-checker-enabled',
UPGRADE_CHECKER_URL: 'upgrade-checker-url',
@@ -68,6 +69,7 @@ export const HCI_ALLOWED_SETTINGS = {
kind: 'json', from: 'import', featureFlag: 'csiOnlineExpandValidation'
},
[HCI_SETTING.SERVER_VERSION]: { readOnly: true },
[HCI_SETTING.SERVER_FLAVOR]: { readOnly: true },
[HCI_SETTING.UPGRADE_CHECKER_ENABLED]: { kind: 'boolean' },
[HCI_SETTING.UPGRADE_CHECKER_URL]: { kind: 'url' },
[HCI_SETTING.HTTP_PROXY]: { kind: 'json', from: 'import' },
@@ -111,15 +113,17 @@ export const HCI_ALLOWED_SETTINGS = {
[HCI_SETTING.KUBECONFIG_DEFAULT_TOKEN_TTL_MINUTES]: { kind: 'number', featureFlag: 'kubeconfigDefaultTokenTTLMinutesSetting' },
[HCI_SETTING.LONGHORN_V2_DATA_ENGINE_ENABLED]: {
kind: 'boolean',
experimental: true,
preview: true,
featureFlag: 'longhornV2LVMSupport'
},
[HCI_SETTING.LONGHORN_V2_DATA_ENGINE_HUGEPAGE_ENABLED]: {
kind: 'boolean',
preview: true,
featureFlag: 'longhornV2HugepageSettings'
},
[HCI_SETTING.LONGHORN_V2_DATA_ENGINE_MEMORY_SIZE]: {
kind: 'number',
preview: true,
featureFlag: 'longhornV2HugepageSettings'
},
[HCI_SETTING.ADDITIONAL_GUEST_MEMORY_OVERHEAD_RATIO]: { kind: 'string', from: 'import' },
@@ -390,14 +390,17 @@ export default {
:vmi-resource="vmi"
:vmim-resource="vmim"
/>
<DashboardMetrics
<div
v-if="showVmMetrics && liveMigrationProgressEnabled"
:detail-url="VM_MIGRATION_DETAIL_URL"
graph-height="640px"
:has-summary-and-detail="false"
:vars="graphVars"
class="mb-30"
/>
class="migration-metrics-scroll mb-30"
>
<DashboardMetrics
:detail-url="VM_MIGRATION_DETAIL_URL"
graph-height="960px"
:has-summary-and-detail="false"
:vars="graphVars"
/>
</div>
<Events
v-if="liveMigrationProgressEnabled"
:resource="vmi"
@@ -436,3 +439,10 @@ export default {
</Tabbed>
</div>
</template>
<style lang="scss" scoped>
.migration-metrics-scroll {
max-height: 640px;
overflow-y: auto;
}
</style>
+164
View File
@@ -0,0 +1,164 @@
<script>
import merge from 'lodash/merge';
import jsyaml from 'js-yaml';
import { mapGetters } from 'vuex';
import { Card } from '@components/Card';
import { LabeledInput } from '@components/Form/LabeledInput';
import AsyncButton from '@shell/components/AsyncButton';
import { escapeHtml } from '@shell/utils/string';
const DEFAULT_VALUE = {
rancher: {
hostname: '',
version: '',
bootstrapPassword: '',
},
};
export default {
name: 'HarvesterEnableK3k',
emits: ['close'],
components: {
AsyncButton,
Card,
LabeledInput,
},
props: {
resources: {
type: Array,
required: true
}
},
data() {
const addon = this.resources[0];
let valuesContentJson;
try {
valuesContentJson = merge({}, DEFAULT_VALUE, jsyaml.load(addon.spec.valuesContent));
} catch (e) {
valuesContentJson = merge({}, DEFAULT_VALUE);
}
return { valuesContentJson };
},
computed: {
...mapGetters({ t: 'i18n/t' }),
buttonDisabled() {
const { rancher } = this.valuesContentJson;
return !(rancher?.hostname || '').trim() || !(rancher?.version || '').trim() || !(rancher?.bootstrapPassword || '').trim();
}
},
methods: {
close() {
this.$emit('close');
},
async enable(buttonCb) {
const addon = this.resources[0];
try {
addon.spec.valuesContent = jsyaml.dump(this.valuesContentJson);
addon.spec.enabled = true;
await addon.save();
buttonCb(true);
this.close();
} catch (err) {
addon.spec.enabled = false;
this.$store.dispatch('growl/fromError', {
title: this.t('generic.notification.title.error', { name: escapeHtml(addon.metadata.name) }),
err,
}, { root: true });
buttonCb(false);
}
}
}
};
</script>
<template>
<Card :show-highlight-border="false">
<template #title>
<h4
v-clean-html="t('harvester.addons.rancherK3k.enable.title')"
class="text-default-text"
/>
</template>
<template #body>
<div class="body">
<div class="row mb-15">
<div class="col span-6">
<LabeledInput
v-model:value="valuesContentJson.rancher.hostname"
:required="true"
:label="t('harvester.addons.rancherK3k.hostname')"
placeholder="rancher.$vip.nip.io"
/>
</div>
<div class="col span-6">
<LabeledInput
v-model:value="valuesContentJson.rancher.version"
:required="true"
:label="t('harvester.addons.rancherK3k.version')"
placeholder="v1.14.0"
/>
</div>
</div>
<div class="row mb-15">
<div class="col span-12">
<LabeledInput
v-model:value="valuesContentJson.rancher.bootstrapPassword"
:required="true"
type="password"
:label="t('harvester.addons.rancherK3k.password')"
:tooltip="t('harvester.addons.rancherK3k.passwordTooltip')"
/>
</div>
</div>
</div>
</template>
<template #actions>
<div class="buttons actions">
<button
class="btn role-secondary mr-10"
@click="close"
>
{{ t('generic.cancel') }}
</button>
<AsyncButton
mode="enable"
:disabled="buttonDisabled"
@click="enable"
/>
</div>
</template>
</Card>
</template>
<style lang="scss" scoped>
.body {
display: flex;
flex-direction: column;
min-width: 400px;
}
.actions {
width: 100%;
}
.buttons {
display: flex;
justify-content: flex-end;
width: 100%;
}
</style>
@@ -0,0 +1,167 @@
<script>
import merge from 'lodash/merge';
import jsyaml from 'js-yaml';
import { LabeledInput } from '@components/Form/LabeledInput';
import { RadioGroup } from '@components/Form/Radio';
const DEFAULT_VALUE = {
certManagerVersion: 'v1.20.2',
rancher: {
hostname: '',
version: '',
bootstrapPassword: '',
},
k3kCluster: {
servers: 1,
version: 'v1.35.4-k3s1',
storageClassName: 'harvester-longhorn',
},
};
export default {
name: 'EditAddonRancherK3k',
components: { LabeledInput, RadioGroup },
inheritAttrs: false,
props: {
value: {
type: Object,
required: true,
},
mode: {
type: String,
required: true
},
registerBeforeHook: {
type: Function,
required: true,
},
},
data() {
let valuesContentJson = {};
try {
valuesContentJson = merge({}, DEFAULT_VALUE, jsyaml.load(this.value.spec.valuesContent));
} catch (err) {
valuesContentJson = merge({}, DEFAULT_VALUE);
this.$store.dispatch('growl/fromError', {
title: this.$store.getters['i18n/t']('generic.notification.title.error'),
err: err.data || err,
}, { root: true });
}
return { valuesContentJson };
},
created() {
if (this.registerBeforeHook) {
this.registerBeforeHook(this.willSave, 'willSave');
}
},
methods: {
willSave() {
const errors = [];
if (!this.value.spec.enabled) {
return Promise.resolve();
}
if (!this.valuesContentJson.rancher.hostname) {
errors.push(this.t('validation.required', { key: this.t('harvester.addons.rancherK3k.hostname') }, true));
}
if (!this.valuesContentJson.rancher.version) {
errors.push(this.t('validation.required', { key: this.t('harvester.addons.rancherK3k.version') }, true));
}
if (!this.valuesContentJson.rancher.bootstrapPassword) {
errors.push(this.t('validation.required', { key: this.t('harvester.addons.rancherK3k.password') }, true));
}
if (errors.length > 0) {
return Promise.reject(errors);
} else {
return Promise.resolve();
}
},
},
watch: {
valuesContentJson: {
handler(neu) {
this.value.spec['valuesContent'] = jsyaml.dump(neu);
},
deep: true,
immediate: true
},
},
};
</script>
<template>
<div>
<div class="row">
<div class="col span-12">
<RadioGroup
v-model:value="value.spec.enabled"
class="mb-20"
name="model"
:mode="mode"
:options="[true,false]"
:labels="[t('generic.enabled'), t('generic.disabled')]"
/>
</div>
</div>
<template v-if="value.spec.enabled">
<div class="row mb-20">
<div class="col span-6">
<LabeledInput
v-model:value="valuesContentJson.rancher.hostname"
label-key="harvester.addons.rancherK3k.hostname"
:required="true"
:mode="mode"
placeholder="rancher.$vip.nip.io"
/>
</div>
<div class="col span-6">
<LabeledInput
v-model:value="valuesContentJson.rancher.version"
label-key="harvester.addons.rancherK3k.version"
:required="true"
:mode="mode"
placeholder="v1.14.0"
/>
</div>
</div>
<div class="row mt-20">
<div class="col span-6">
<LabeledInput
v-model:value="valuesContentJson.rancher.bootstrapPassword"
label-key="harvester.addons.rancherK3k.password"
:mode="mode"
:required="true"
type="password"
:tooltip="t('harvester.addons.rancherK3k.passwordTooltip')"
/>
</div>
</div>
</template>
</div>
</template>
<style lang="scss" scoped>
:deep() .radio-group {
display: flex;
.radio-container {
margin-right: 30px;
}
}
</style>
@@ -7,6 +7,7 @@ import NameNsDescription from '@shell/components/form/NameNsDescription';
import YamlEditor from '@shell/components/YamlEditor';
import CreateEditView from '@shell/mixins/create-edit-view';
import FormValidation from '@shell/mixins/form-validation';
import { HCI } from '@pkg/harvester/config/labels-annotations';
export default {
@@ -23,14 +24,19 @@ export default {
NameNsDescription,
},
mixins: [CreateEditView],
mixins: [CreateEditView, FormValidation],
inheritAttrs: false,
data() {
return {
config: this.value.data?.cloudInit || '',
type: this.value?.metadata?.labels?.[HCI.CLOUD_INIT] || 'user',
config: this.value.data?.cloudInit || '',
type: this.value?.metadata?.labels?.[HCI.CLOUD_INIT] || 'user',
fvFormRuleSets: [{
path: 'metadata.name',
rules: ['required'],
translationKey: 'nameNsDescription.name.label',
}],
};
},
@@ -78,6 +84,7 @@ export default {
:resource="value"
:errors="errors"
:apply-hooks="applyHooks"
:validation-passed="fvFormIsValid"
@finish="save"
@cancel="done"
@error="e=>errors=e"
@@ -86,6 +93,7 @@ export default {
:value="value"
:mode="mode"
:namespaced="true"
:rules="{ name: fvGetAndReportPathRules('metadata.name') }"
@update:value="$emit('update:value', $event)"
/>
@@ -7,8 +7,12 @@ import { allHash } from '@shell/utils/promise';
import { clone } from '@shell/utils/object';
import { HCI } from '../../../types';
import { NODE } from '@shell/config/types';
import { _CREATE, _CLONE } from '@shell/config/query-params';
import { LVM_TOPOLOGY_LABEL } from '../index.vue';
const STRIPED_TYPE = 'striped';
const DM_THIN_TYPE = 'dm-thin';
const DEFAULT_PARAMETERS = [
'type',
'vgName'
@@ -54,8 +58,17 @@ export default {
data() {
const node = (this.value.allowedTopologies?.[0]?.matchLabelExpressions || []).find((t) => t.key === LVM_TOPOLOGY_LABEL)?.values[0];
// striped is dropped once the LVM add-on reaches GA (v1.9.1); dm-thin is the only supported type.
const dmThinOnly = this.$store.getters['harvester-common/getFeatureEnabled']('lvmDmThinOnly');
const volumeGroupTypes = dmThinOnly ? [DM_THIN_TYPE] : [STRIPED_TYPE, DM_THIN_TYPE];
// Default new storage classes to dm-thin, and reset a cloned striped type that is no longer selectable.
if (dmThinOnly && [_CREATE, _CLONE].includes(this.realMode) && !volumeGroupTypes.includes(this.value.parameters.type)) {
this.value.parameters.type = DM_THIN_TYPE;
}
return {
volumeGroupTypes: ['striped', 'dm-thin'],
volumeGroupTypes,
node,
};
},
@@ -246,4 +246,27 @@ export default {
.group-actions {
display: inline;
}
// Match the enable/disable passthrough bulk-action buttons height to the .btn (40px) on the right.
:deep(.bulk .rc-button.btn-medium.bulk-action:not(.btn-sm)) {
min-height: 40px;
}
// Make the collapsed "Actions" dropdown button 40px too.
:deep(.bulk .rc-button.btn-medium.bulk-actions-dropdown:not(.btn-sm)) {
min-height: 40px;
}
// Lay the bulk row out with flex so the "N selected" label can wrap below the buttons.
:deep(.bulk) {
display: flex;
flex-wrap: wrap;
align-items: center;
}
:deep(.bulk .action-availability) {
flex-basis: 100%;
margin-left: 0;
margin-top: 6px;
}
</style>
@@ -5,6 +5,7 @@ import LabeledSelect from '@shell/components/form/LabeledSelect';
import Banner from '@components/Banner/Banner.vue';
import remove from 'lodash/remove';
import { set } from '@shell/utils/object';
import { uniq } from '@shell/utils/array';
import { HCI } from '../../../types';
import DeviceList from './DeviceList';
import CompatibilityMatrix from '../CompatibilityMatrix';
@@ -60,7 +61,15 @@ export default {
row.allowDisable = !vmDeviceNames.includes(row.metadata.name);
});
vmDevices.forEach(({ name }) => {
// When off, read from spec; otherwise the spec name is a placeholder ('provisioned'),
// so read the real allocated device names from the deviceAllocationDetails annotation.
const hostDeviceNames = this.vm.isOff ? [
...vmDevices.map(({ name }) => name),
] : [
...Object.values(this.vm?.provisionedHostDevices || {}).reduce((acc, devices) => [...acc, ...devices], []),
];
uniq(hostDeviceNames).forEach((name) => {
if (this.enabledDevices.find((device) => device?.metadata?.name === name)) {
selectedDevices.push(name);
}
+22 -1
View File
@@ -84,6 +84,8 @@ dialog:
harvester:
branding:
primeLabel: '{vendor}'
primeEmptyLabel: ''
logos:
tip: 'Upload a logo to replace the Harvester logo in the top-level navigation header. Image height should be 21 pixels with a max width of 200 pixels. Max file size is 20KB. Accepted formats: JPEG, PNG, SVG.'
favicon:
@@ -1832,6 +1834,8 @@ harvester:
'rancher-logging': rancher-logging is an add-on to collect versatile logs, events, and audits from the Harvester cluster and route them to many kinds of servers based on flows.
'rancher-monitoring': rancher-monitoring is an add-on to collect Harvester cluster and virtual machine metrics, view them on the embedded dashboard, and send alert(s) to remote servers.
'rancher-vcluster': rancher-vcluster deploys a virtual cluster (vcluster) with Rancher installed.
'k3k': k3k is an add-on to deploy the k3k controller.
'rancher-k3k': rancher-k3k deploys a k3k virtual cluster with Rancher installed.
'harvester-seeder': harvester-seeder is an add-on that uses IPMI and Redfish to discover hardware information and perform out-of-band operations.
'harvester-system/harvester-seeder': harvester-seeder is an add-on that uses IPMI and Redfish to discover hardware information and perform out-of-band operations.
'harvester-csi-driver-lvm': harvester-csi-driver-lvm is an add-on allowing users to create PVC through the LVM with local devices.
@@ -2136,6 +2140,14 @@ harvester:
hostname: Hostname
rancherVersion: Rancher Version
password: Bootstrap Password
rancherK3k:
accessRancher: Access the Rancher Dashboard
hostname: Hostname
version: Rancher Version
password: Bootstrap Password
passwordTooltip: The initial password in Rancher for the first time login.
enable:
title: Enable K3k
switchFailed: "{action} {name} failed!"
nvidiaDriverToolkit:
titles:
@@ -2417,7 +2429,15 @@ typeDescription:
harvester: "Branding allows administrators to globally re-brand the UI by customizing the Harvester product name, logos and color scheme."
advancedSettings:
experimental: 'Experimental features allow users to test and evaluate early-access functionality prior to official supported releases'
tags:
modified:
label: Modified
experimental:
label: Experimental
description: 'Experimental: The feature is incomplete but its essential functionality is operational. The feature is not recommended for use in production environments.'
preview:
label: Technical Preview
description: 'Technical Preview: The feature is almost complete and its functionality is not expected to change significantly. Explore the feature extensively before using in production environments.'
descriptions:
'harv-vlan': Default Network Interface name of the VLAN network.
'harv-backup-target': Custom backup target to store virtual machine backups.
@@ -2427,6 +2447,7 @@ advancedSettings:
'harv-containerd-registry': Containerd Registry Configuration to connect private registries.
'harv-log-level': Configure Harvester server log level. Defaults to Info.
'harv-server-version': Harvester server version.
'harv-server-flavor': "Indicates the Harvester edition: Prime or Community."
'harv-upgrade-checker-enabled': Specifies whether to enable Harvester upgrade check or not. Default is True.
'harv-upgrade-checker-url': Default Harvester upgrade check url. Only used when the <code>upgrade-checker-enabled</code> is equal to True.
'harv-ui-source': Configure how to load the UI source. The `External` option is used to load the UI from a ui-index URL, while the `Bundled` option loads the UI from the local Harvester server.
+1 -1
View File
@@ -72,7 +72,7 @@ export default {
/>
<a
v-if="scope.row.metadata.name === 'rancher-vcluster' && scope.row.spec.enabled"
v-if="['rancher-vcluster', 'rancher-k3k'].includes(scope.row.metadata.name) && scope.row.spec.enabled"
v-tooltip="t('harvester.addons.rancherVcluster.accessRancher')"
class="ml-5"
rel="nofollow noopener noreferrer"
@@ -5,6 +5,7 @@ import SYSTEM_NAMESPACES from '@shell/config/system-namespaces';
import { get } from '@shell/utils/object';
import { NAMESPACE } from '@shell/config/types';
import { PRODUCT_NAME as HARVESTER_PRODUCT } from '@pkg/harvester/config/harvester';
import { FORKLIFT_NAMESPACE } from '@pkg/harvester/config/harvester-map';
import { HCI } from '../../types';
const OBSCURE_NAMESPACE_PREFIX = [
@@ -93,6 +94,10 @@ export default class HciNamespace extends namespace {
}
get isSystem() {
if (this.metadata?.name === FORKLIFT_NAMESPACE) {
return false;
}
const systemNamespaces = ['fleet-default'];
if (systemNamespaces.includes(this.metadata.name)) {
+18 -6
View File
@@ -5,12 +5,14 @@ import HarvesterResource from './harvester';
import { HCI } from '../types';
const HARVESTER_NVIDIA_DRIVER_TOOLKIT = 'harvester-system/nvidia-driver-toolkit';
const RANCHER_VCLUSTER = 'harvester-system/rancher-vcluster';
const RANCHER_K3K_ADDON = 'rancher-k3k/rancher-k3k';
export default class HciAddonConfig extends HarvesterResource {
get availableActions() {
const out = super._availableActions;
if (this.id === 'harvester-system/rancher-vcluster') {
if (this.id === RANCHER_VCLUSTER || this.id === RANCHER_K3K_ADDON) {
const rancherDashboard = {
action: 'goToRancher',
enabled: this.spec.enabled,
@@ -57,6 +59,15 @@ export default class HciAddonConfig extends HarvesterResource {
return;
}
if (!this.spec.enabled && this.id === RANCHER_K3K_ADDON) {
this.$dispatch('promptModal', {
resources: [this],
component: 'HarvesterEnableK3k',
});
return;
}
this.spec.enabled = !this.spec.enabled;
await this.save();
} catch (err) {
@@ -69,18 +80,19 @@ export default class HciAddonConfig extends HarvesterResource {
}
goToRancher() {
const valuesContent = jsyaml.load(this.spec.valuesContent);
window.open(
`https://${ valuesContent.hostname }`,
this.rancherHostname,
'_blank',
);
}
get rancherHostname() {
const valuesContent = jsyaml.load(this.spec.valuesContent);
const valuesContent = jsyaml.load(this.spec.valuesContent) || {};
return `https://${ valuesContent.hostname }`;
// rancher-k3k nests the hostname under `rancher`, rancher-vcluster keeps it at the top level
const hostname = this.id === RANCHER_K3K_ADDON ? valuesContent.rancher?.hostname : valuesContent.hostname;
return `https://${ hostname }`;
}
get stateColor() {
@@ -1315,6 +1315,18 @@ export default class VirtVm extends HarvesterResource {
}
}
get provisionedHostDevices() {
// Rancher-provisioned VMs store hostDevices.name as a placeholder ('provisioned'); the
// real allocated PCI device names live in this annotation, keyed by resourceName.
try {
const deviceAllocationDetails = JSON.parse(this.metadata?.annotations[HCI_ANNOTATIONS.VM_DEVICE_ALLOCATION_DETAILS] || '{}');
return deviceAllocationDetails?.hostdevices || {};
} catch (error) {
return {};
}
}
get schedulingVMBackupFeatureEnabled() {
return this.$rootGetters['harvester-common/getFeatureEnabled']('schedulingVMBackup');
}
@@ -0,0 +1,14 @@
import ManagementSetting from '@shell/models/management.cattle.io.setting';
import { HCI_SETTING } from '../../config/settings';
export default class HarvesterManagementSetting extends ManagementSetting {
get _availableActions() {
const actions = super._availableActions;
if (this.$rootGetters['isStandaloneHarvester'] && this.id === HCI_SETTING.UI_PL) {
return actions.filter((action) => !['goToClone', 'promptRemove'].includes(action.action));
}
return actions;
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "harvester",
"description": "Rancher UI Extension for Harvester",
"version": "1.9.0-rc5",
"version": "1.9.1-rc2",
"private": false,
"rancher": {
"annotations": {
+14 -2
View File
@@ -63,6 +63,7 @@ export default {
return {
vendor: getVendor(),
uiPLSetting: {},
privateLabelDraft: null,
uiLogoDarkSetting: {},
uiLogoDark: '',
uiLogoLightSetting: {},
@@ -81,6 +82,17 @@ export default {
};
},
computed: {
isHarvesterPrime() {
return !!this.$store.getters['harvester-common/isHarvesterPrime'];
},
privateLabel: {
get() {
return this.privateLabelDraft ?? (this.isHarvesterPrime ? this.$store.getters['harvester-common/privateLabel'] : this.uiPLSetting.value);
},
set(value) {
this.privateLabelDraft = value;
}
},
mode() {
const schema = this.$store.getters[`management/schemaFor`](MANAGEMENT.SETTING);
@@ -112,7 +124,7 @@ export default {
this.errors.push(e);
},
async save(btnCB) {
this.uiPLSetting.value = this.uiPLSetting.value.replaceAll(/[\<>&=#()"]/gm, '');
this.uiPLSetting.value = (this.privateLabel || '').replaceAll(/[\<>&=#()"]/gm, '');
if (this.customizeLogo) {
this.uiLogoLightSetting.value = this.uiLogoLight;
this.uiLogoDarkSetting.value = this.uiLogoDark;
@@ -169,7 +181,7 @@ export default {
<div class="row mb-20">
<div class="col span-6">
<LabeledInput
v-model:value="uiPLSetting.value"
v-model:value="privateLabel"
:label="t('branding.uiPL.label')"
:mode="mode"
:maxlength="100"
+19
View File
@@ -1,4 +1,6 @@
import Parse from 'url-parse';
import { MANAGEMENT } from '@shell/config/types';
import { SETTING } from '@shell/config/settings';
import { HCI } from '../types';
import { PRODUCT_NAME } from '../config/harvester';
import { featureEnabled, getVersion } from '../utils/feature-flags';
@@ -64,6 +66,23 @@ const mutations = {
};
const getters = {
isHarvesterPrime: (_state, _getters, _rootState, rootGetters) => {
const setting = rootGetters['harvester/byId']?.(HCI.SETTING, 'server-flavor');
return (setting?.value || setting?.default) === 'prime';
},
privateLabel: (_state, getters, _rootState, rootGetters) => {
const setting = rootGetters['management/byId']?.(MANAGEMENT.SETTING, SETTING.PL);
const value = setting?.value || '';
if (getters.isHarvesterPrime && value === (setting?.default || 'Harvester')) {
return '';
}
return value;
},
getBundleId(state) {
return state.latestBundleId;
},
+7 -2
View File
@@ -1,3 +1,5 @@
import { FAVORITE_TYPES } from '@shell/store/prefs';
/**
* Dynamically toggles SideNav entries based on the enabled status of a specific Addon.
*
@@ -26,10 +28,13 @@ export function registerAddonSideNav(store, productName, {
// Toggle the trigger a few times so an early kick (fired before the SideNav
// has mounted on first login) is retried once the component is listening.
// Use the prefs/load mutation (in-memory only)
[0, 600, 1500].forEach((delay) => {
setTimeout(() => {
store.dispatch('type-map/addFavorite', TRIGGER);
setTimeout(() => store.dispatch('type-map/removeFavorite', TRIGGER), 300);
const base = (store.getters['prefs/get'](FAVORITE_TYPES) || []).filter((t) => t !== TRIGGER);
store.commit('prefs/load', { key: FAVORITE_TYPES, value: [...base, TRIGGER] });
setTimeout(() => store.commit('prefs/load', { key: FAVORITE_TYPES, value: [...base] }), 300);
}, delay);
});
};
+163 -67
View File
@@ -524,12 +524,12 @@
js-tokens "^4.0.0"
picocolors "^1.1.1"
"@babel/compat-data@^7.28.6", "@babel/compat-data@^7.29.0":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.0.tgz#00d03e8c0ac24dd9be942c5370990cbe1f17d88d"
integrity sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==
"@babel/compat-data@^7.28.6", "@babel/compat-data@^7.29.0", "@babel/compat-data@^7.29.7":
version "7.29.7"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.7.tgz#6f0237f0f36d2e51c0570a636faed9d2d0efe629"
integrity sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==
"@babel/core@^7.1.0", "@babel/core@^7.12.16", "@babel/core@^7.12.3", "@babel/core@^7.23.9", "@babel/core@^7.7.2", "@babel/core@^7.8.0":
"@babel/core@^7.1.0", "@babel/core@^7.7.2", "@babel/core@^7.8.0":
version "7.29.0"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.0.tgz#5286ad785df7f79d656e88ce86e650d16ca5f322"
integrity sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==
@@ -550,7 +550,28 @@
json5 "^2.2.3"
semver "^6.3.1"
"@babel/generator@^7.29.0", "@babel/generator@^7.29.7", "@babel/generator@^7.7.2":
"@babel/core@^7.12.16", "@babel/core@^7.12.3", "@babel/core@^7.23.9":
version "7.29.7"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.7.tgz#80c10b17248082968b57a857b91640971f2070f7"
integrity sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==
dependencies:
"@babel/code-frame" "^7.29.7"
"@babel/generator" "^7.29.7"
"@babel/helper-compilation-targets" "^7.29.7"
"@babel/helper-module-transforms" "^7.29.7"
"@babel/helpers" "^7.29.7"
"@babel/parser" "^7.29.7"
"@babel/template" "^7.29.7"
"@babel/traverse" "^7.29.7"
"@babel/types" "^7.29.7"
"@jridgewell/remapping" "^2.3.5"
convert-source-map "^2.0.0"
debug "^4.1.0"
gensync "^1.0.0-beta.2"
json5 "^2.2.3"
semver "^6.3.1"
"@babel/generator@^7.29.0":
version "7.29.7"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.7.tgz#cca0b8827e6bcf3ba176788e7f3b180ad6db2fa3"
integrity sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==
@@ -561,6 +582,17 @@
"@jridgewell/trace-mapping" "^0.3.28"
jsesc "^3.0.2"
"@babel/generator@^7.29.7", "@babel/generator@^7.29.8", "@babel/generator@^7.7.2":
version "7.29.8"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.8.tgz#4b0b887885422643339e09022148a4c4ebaa4979"
integrity sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==
dependencies:
"@babel/parser" "^7.29.8"
"@babel/types" "^7.29.8"
"@jridgewell/gen-mapping" "^0.3.12"
"@jridgewell/trace-mapping" "^0.3.28"
jsesc "^3.0.2"
"@babel/helper-annotate-as-pure@^7.14.5", "@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3", "@babel/helper-annotate-as-pure@^7.29.7":
version "7.29.7"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz#c70fe3c6ecbdc3fd2dd1b0f498428b88b82ce47f"
@@ -569,12 +601,12 @@
"@babel/types" "^7.29.7"
"@babel/helper-compilation-targets@^7.12.16", "@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.28.6":
version "7.28.6"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz#32c4a3f41f12ed1532179b108a4d746e105c2b25"
integrity sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==
version "7.29.7"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz#7a1def704302401c47f64fa85589e974ae217042"
integrity sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==
dependencies:
"@babel/compat-data" "^7.28.6"
"@babel/helper-validator-option" "^7.27.1"
"@babel/compat-data" "^7.29.7"
"@babel/helper-validator-option" "^7.29.7"
browserslist "^4.24.0"
lru-cache "^5.1.1"
semver "^6.3.1"
@@ -625,22 +657,22 @@
"@babel/traverse" "^7.29.7"
"@babel/types" "^7.29.7"
"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.27.1", "@babel/helper-module-imports@^7.28.6":
version "7.28.6"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz#60632cbd6ffb70b22823187201116762a03e2d5c"
integrity sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==
"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.27.1", "@babel/helper-module-imports@^7.28.6", "@babel/helper-module-imports@^7.29.7":
version "7.29.7"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz#ef25048a518e828d7393fac5882ddd73921d7396"
integrity sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==
dependencies:
"@babel/traverse" "^7.28.6"
"@babel/types" "^7.28.6"
"@babel/traverse" "^7.29.7"
"@babel/types" "^7.29.7"
"@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.28.6":
version "7.28.6"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz#9312d9d9e56edc35aeb6e95c25d4106b50b9eb1e"
integrity sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==
version "7.29.7"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz#b062747a5997ba138637201328bbff77960574ae"
integrity sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==
dependencies:
"@babel/helper-module-imports" "^7.28.6"
"@babel/helper-validator-identifier" "^7.28.5"
"@babel/traverse" "^7.28.6"
"@babel/helper-module-imports" "^7.29.7"
"@babel/helper-validator-identifier" "^7.29.7"
"@babel/traverse" "^7.29.7"
"@babel/helper-optimise-call-expression@^7.29.7":
version "7.29.7"
@@ -690,10 +722,10 @@
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz#bd87084ced0c796ec46bda492de6e83d29e89fc2"
integrity sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==
"@babel/helper-validator-option@^7.16.7", "@babel/helper-validator-option@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f"
integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==
"@babel/helper-validator-option@^7.16.7", "@babel/helper-validator-option@^7.27.1", "@babel/helper-validator-option@^7.29.7":
version "7.29.7"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz#cf315be940213b354eb4abcc0bd01ebe3f73bc2a"
integrity sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==
"@babel/helper-wrap-function@^7.27.1":
version "7.28.6"
@@ -722,7 +754,14 @@
js-tokens "^4.0.0"
picocolors "^1.0.0"
"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.28.0", "@babel/parser@^7.29.0", "@babel/parser@^7.29.7", "@babel/parser@^7.7.0":
"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.28.0", "@babel/parser@^7.29.0", "@babel/parser@^7.29.7", "@babel/parser@^7.29.8":
version "7.29.8"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.8.tgz#9653716a2f10c677b98fbc63d4bfb000c302cf17"
integrity sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==
dependencies:
"@babel/types" "^7.29.8"
"@babel/parser@^7.7.0":
version "7.29.7"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.7.tgz#837b87387cbf5ec5530cb634b3c622f68edb9334"
integrity sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==
@@ -888,11 +927,11 @@
"@babel/helper-plugin-utils" "^7.8.0"
"@babel/plugin-syntax-jsx@^7.12.13", "@babel/plugin-syntax-jsx@^7.2.0", "@babel/plugin-syntax-jsx@^7.27.1":
version "7.28.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz#f8ca28bbd84883b5fea0e447c635b81ba73997ee"
integrity sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==
version "7.29.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz#622c16f9ad63782fe6e83dadc7e40330744b7f1e"
integrity sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==
dependencies:
"@babel/helper-plugin-utils" "^7.28.6"
"@babel/helper-plugin-utils" "^7.29.7"
"@babel/plugin-syntax-logical-assignment-operators@^7.10.4":
version "7.10.4"
@@ -1493,7 +1532,20 @@
"@babel/parser" "^7.29.7"
"@babel/types" "^7.29.7"
"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.5", "@babel/traverse@^7.28.6", "@babel/traverse@^7.29.0", "@babel/traverse@^7.29.7", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2":
"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.5", "@babel/traverse@^7.28.6", "@babel/traverse@^7.29.0", "@babel/traverse@^7.29.7":
version "7.29.8"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.8.tgz#4111014cdc71a0f95d9471907590baa0b8a6b28a"
integrity sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==
dependencies:
"@babel/code-frame" "^7.29.7"
"@babel/generator" "^7.29.8"
"@babel/helper-globals" "^7.29.7"
"@babel/parser" "^7.29.8"
"@babel/template" "^7.29.7"
"@babel/types" "^7.29.8"
debug "^4.3.1"
"@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2":
version "7.29.7"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.7.tgz#c47b07a41b95da0907d026b5dd894d98de7d2f2d"
integrity sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==
@@ -1506,7 +1558,15 @@
"@babel/types" "^7.29.7"
debug "^4.3.1"
"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.28.2", "@babel/types@^7.28.6", "@babel/types@^7.29.0", "@babel/types@^7.29.7", "@babel/types@^7.3.3", "@babel/types@^7.4.4", "@babel/types@^7.7.0":
"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.28.2", "@babel/types@^7.28.6", "@babel/types@^7.29.7", "@babel/types@^7.29.8", "@babel/types@^7.3.3", "@babel/types@^7.4.4":
version "7.29.8"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.8.tgz#1229eef31d85156d70fa3f4cd859376d0eaf6863"
integrity sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==
dependencies:
"@babel/helper-string-parser" "^7.29.7"
"@babel/helper-validator-identifier" "^7.29.7"
"@babel/types@^7.29.0", "@babel/types@^7.7.0":
version "7.29.7"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.7.tgz#8005e31d82712ee7adaef6e23c63b71a62770a92"
integrity sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==
@@ -1679,13 +1739,20 @@
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0":
"@eslint-community/eslint-utils@^4.2.0":
version "4.9.1"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz#4e90af67bc51ddee6cdef5284edf572ec376b595"
integrity sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==
dependencies:
eslint-visitor-keys "^3.4.3"
"@eslint-community/eslint-utils@^4.4.0":
version "4.10.1"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.10.1.tgz#8911bd72b2c3640a543609e0400b8c4d2e7e7cb6"
integrity sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==
dependencies:
eslint-visitor-keys "^3.4.3"
"@eslint-community/regexpp@^4.4.0":
version "4.12.2"
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz#bccdf615bcf7b6e8db830ec0b8d21c9a25de597b"
@@ -2743,9 +2810,9 @@
"@types/json-schema" "*"
"@types/estree@*", "@types/estree@^1.0.8":
version "1.0.8"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e"
integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==
version "1.0.9"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.9.tgz#cf3f0e876d7bee15a93ab925b82bf570a3904a24"
integrity sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==
"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33":
version "4.19.8"
@@ -3812,7 +3879,12 @@ acorn@^7.1.1, acorn@^7.4.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
acorn@^8.0.4, acorn@^8.0.5, acorn@^8.11.0, acorn@^8.15.0, acorn@^8.16.0, acorn@^8.2.4, acorn@^8.9.0:
acorn@^8.0.4, acorn@^8.0.5, acorn@^8.11.0, acorn@^8.15.0, acorn@^8.16.0:
version "8.18.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.18.0.tgz#4faf01b2d6d326bfeed97aea1f52220b5f4c1940"
integrity sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==
acorn@^8.2.4, acorn@^8.9.0:
version "8.16.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.16.0.tgz#4ce79c89be40afe7afe8f3adb902a1f1ce9ac08a"
integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==
@@ -3861,7 +3933,7 @@ ajv-keywords@^5.1.0:
dependencies:
fast-deep-equal "^3.1.3"
ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5:
ajv@^6.10.0, ajv@^6.12.4:
version "6.14.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.14.0.tgz#fd067713e228210636ebb08c60bd3765d6dbe73a"
integrity sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==
@@ -3871,6 +3943,16 @@ ajv@^6.10.0, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ajv@^6.12.2, ajv@^6.12.5:
version "6.15.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.15.0.tgz#07e982c74626167aa7a2495c53817892d7139492"
integrity sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ajv@^8.0.0, ajv@^8.0.1, ajv@^8.11.0, ajv@^8.9.0:
version "8.18.0"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.18.0.tgz#8864186b6738d003eb3a933172bb3833e10cefbc"
@@ -6121,12 +6203,12 @@ end-of-stream@^1.1.0:
once "^1.4.0"
enhanced-resolve@^5.0.0, enhanced-resolve@^5.20.0:
version "5.20.1"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.20.1.tgz#eeeb3966bea62c348c40a0cc9e7912e2557d0be0"
integrity sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==
version "5.24.5"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz#b4dad3255b7545f07ba5535189868e9f85f47573"
integrity sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==
dependencies:
graceful-fs "^4.2.4"
tapable "^2.3.0"
tapable "^2.3.3"
enquirer@^2.3.5:
version "2.4.1"
@@ -7193,7 +7275,7 @@ gopd@^1.0.1, gopd@^1.2.0:
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
version "4.2.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
@@ -7300,10 +7382,10 @@ hasha@^5.0.0:
is-stream "^2.0.0"
type-fest "^0.8.0"
hasown@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
hasown@^2.0.2, hasown@^2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.4.tgz#8c62d8cb90beb2aad5d0a5b67581ad9854c3f003"
integrity sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==
dependencies:
function-bind "^1.1.2"
@@ -7742,7 +7824,14 @@ is-callable@^1.2.7:
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
is-core-module@^2.13.0, is-core-module@^2.16.1, is-core-module@^2.3.0:
is-core-module@^2.13.0, is-core-module@^2.16.1:
version "2.16.2"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.2.tgz#3e07450a8080ebce3fbf0cac494f4d2ab324e082"
integrity sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==
dependencies:
hasown "^2.0.3"
is-core-module@^2.3.0:
version "2.16.1"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4"
integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==
@@ -8592,7 +8681,7 @@ js-yaml-loader@1.2.2:
loader-utils "^1.2.3"
un-eval "^1.2.0"
js-yaml@4.1.1, js-yaml@^4.1.0, js-yaml@^4.1.1:
js-yaml@4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b"
integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==
@@ -8607,6 +8696,13 @@ js-yaml@^3.13.1:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^4.1.0, js-yaml@^4.1.1:
version "4.3.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.3.0.tgz#d1900572a7f7cf0b5f540c83673e60bad3436592"
integrity sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==
dependencies:
argparse "^2.0.1"
jsdom@^16.6.0:
version "16.7.0"
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710"
@@ -9876,9 +9972,9 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.1:
integrity sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==
picomatch@^4.0.3:
version "4.0.4"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.4.tgz#fd6f5e00a143086e074dffe4c924b8fb293b0589"
integrity sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==
version "4.0.7"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.7.tgz#6313360034ccb36b3dc61ecbdff78121f90fe21f"
integrity sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==
pirates@^4.0.4:
version "4.0.7"
@@ -10145,9 +10241,9 @@ postcss-selector-parser@^6.0.15, postcss-selector-parser@^6.0.2, postcss-selecto
util-deprecate "^1.0.2"
postcss-selector-parser@^7.0.0:
version "7.1.1"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-7.1.1.tgz#e75d2e0d843f620e5df69076166f4e16f891cb9f"
integrity sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==
version "7.1.5"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-7.1.5.tgz#ee7b090724eb60739b530660e5b402200e694a97"
integrity sha512-KvvtD7SrlBP7dlgkBghEE3r84CABm5SmV2aNcG4oCA+qDnJ/tvKonFVvwWAyyWUEwxuNawdfEAZKP9zM3oZ2Uw==
dependencies:
cssesc "^3.0.0"
util-deprecate "^1.0.2"
@@ -10329,10 +10425,10 @@ punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.0, punycode@^2.3.1:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
qs@6.15.3, qs@^6.12.3, qs@~6.15.1:
version "6.15.3"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.15.3.tgz#76852132a58ed5c7c0ef67e4441b9bb5d6061b3b"
integrity sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==
qs@6.16.0, qs@^6.12.3, qs@~6.15.1:
version "6.16.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.16.0.tgz#c22c723a28a920f3aacdce8289fabd43eccb79fd"
integrity sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==
dependencies:
es-define-property "^1.0.1"
side-channel "^1.1.1"
@@ -11461,9 +11557,9 @@ tapable@^1.0.0:
integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==
tapable@^2.0.0, tapable@^2.2.1, tapable@^2.3.0:
version "2.3.2"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.2.tgz#86755feabad08d82a26b891db044808c6ad00f15"
integrity sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==
version "2.3.3"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.3.tgz#5da7c9992c46038221267985ab28421a8879f160"
integrity sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==
terminal-link@^2.0.0:
version "2.1.1"
@@ -12576,9 +12672,9 @@ yargs@^16.0.0, yargs@^16.2.0:
yargs-parser "^20.2.2"
yargs@^17.0.0:
version "17.7.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
version "17.7.3"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.3.tgz#779dffe6bcafec596a7172e983289a588647faaa"
integrity sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==
dependencies:
cliui "^8.0.1"
escalade "^3.1.1"