mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-05-07 10:14:35 +00:00
fix(frontend-lib): harden URL input parsing
- Extract URL input parsing and formatting into tested helpers - Preserve pasted HTTP URLs, paths, query strings, and explicit ports - Add Vitest coverage for URL input edge cases
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vue-tsc -b && vite build",
|
"build": "vue-tsc -b && vite build",
|
||||||
|
"test": "vitest run",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -43,6 +44,7 @@
|
|||||||
"typescript": "~5.6.3",
|
"typescript": "~5.6.3",
|
||||||
"vite": "^5.4.21",
|
"vite": "^5.4.21",
|
||||||
"vite-plugin-dts": "^4.3.0",
|
"vite-plugin-dts": "^4.3.0",
|
||||||
|
"vitest": "^2.1.9",
|
||||||
"vue-tsc": "^2.1.10"
|
"vue-tsc": "^2.1.10"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import InputGroup from 'primevue/inputgroup'
|
|||||||
import InputGroupAddon from 'primevue/inputgroupaddon'
|
import InputGroupAddon from 'primevue/inputgroupaddon'
|
||||||
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { buildUrlInputValue, getHostInputValue, parseHostInputOnBlur, parseUrlInput } from '../modules/url-input'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
placeholder?: string
|
placeholder?: string
|
||||||
@@ -32,73 +33,11 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const parseUrl = (val: string | null | undefined): { proto: string; host: string; port: number | null } => {
|
const internalValue = ref(parseUrlInput(url.value, props.protos))
|
||||||
const getValidPort = (portStr: string, proto: string) => {
|
|
||||||
const p = parseInt(portStr)
|
|
||||||
return isNaN(p) ? (props.protos[proto] ?? 11010) : p
|
|
||||||
}
|
|
||||||
const parseByPattern = (input: string) => {
|
|
||||||
const trimmed = input.trim()
|
|
||||||
if (!trimmed) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
const match = trimmed.match(/^(\w+):\/\/(.*)$/)
|
|
||||||
const proto = match ? match[1] : 'tcp'
|
|
||||||
const rest = match ? match[2] : trimmed
|
|
||||||
const authority = rest.split(/[/?#]/)[0]
|
|
||||||
if (!authority) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
const hostAndMaybePort = authority.includes('@') ? authority.slice(authority.lastIndexOf('@') + 1) : authority
|
|
||||||
if (hostAndMaybePort.startsWith('[')) {
|
|
||||||
const ipv6End = hostAndMaybePort.indexOf(']')
|
|
||||||
if (ipv6End > 0) {
|
|
||||||
const host = hostAndMaybePort.slice(0, ipv6End + 1)
|
|
||||||
const remain = hostAndMaybePort.slice(ipv6End + 1)
|
|
||||||
// null = no explicit port in URL; do not fabricate a default
|
|
||||||
const port: number | null = remain.startsWith(':') ? getValidPort(remain.slice(1), proto) : null
|
|
||||||
return { proto, host, port }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const portMatch = hostAndMaybePort.match(/^(.*):(\d+)$/)
|
|
||||||
const host = portMatch ? portMatch[1] : hostAndMaybePort
|
|
||||||
// null = no explicit port in URL; buildUrlValue will omit the port entirely,
|
|
||||||
// preserving the protocol's implied standard port (e.g. 443 for wss://).
|
|
||||||
const port: number | null = portMatch ? parseInt(portMatch[2]) : null
|
|
||||||
return { proto, host, port }
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!val) {
|
|
||||||
return { proto: 'tcp', host: '', port: props.protos['tcp'] ?? 11010 }
|
|
||||||
}
|
|
||||||
const parsedByPattern = parseByPattern(val)
|
|
||||||
if (parsedByPattern) {
|
|
||||||
return parsedByPattern
|
|
||||||
}
|
|
||||||
return { proto: 'tcp', host: '', port: null }
|
|
||||||
}
|
|
||||||
|
|
||||||
const internalValue = ref(parseUrl(url.value))
|
|
||||||
const defaultHost = '0.0.0.0'
|
const defaultHost = '0.0.0.0'
|
||||||
|
|
||||||
const buildUrlValue = (value: { proto: string, host: string, port: number | null }, forceDefaultHost = false) => {
|
|
||||||
const proto = value.proto || 'tcp'
|
|
||||||
const rawHost = (value.host ?? '').trim()
|
|
||||||
const host = rawHost || (forceDefaultHost ? defaultHost : '')
|
|
||||||
if (!host) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
// Omit port when the protocol uses no port (protos value = 0), or when the
|
|
||||||
// original URL had no explicit port (port === null) – avoids overwriting an
|
|
||||||
// implicit standard port (e.g. 443 for wss) with an EasyTier default (11012).
|
|
||||||
if (props.protos[proto] === 0 || value.port === null) {
|
|
||||||
return `${proto}://${host}`
|
|
||||||
}
|
|
||||||
return `${proto}://${host}:${value.port}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const syncUrlFromInternal = (forceDefaultHost = false) => {
|
const syncUrlFromInternal = (forceDefaultHost = false) => {
|
||||||
const nextUrl = buildUrlValue(internalValue.value, forceDefaultHost)
|
const nextUrl = buildUrlInputValue(internalValue.value, props.protos, forceDefaultHost)
|
||||||
if (!nextUrl || nextUrl === url.value) {
|
if (!nextUrl || nextUrl === url.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -107,6 +46,10 @@ const syncUrlFromInternal = (forceDefaultHost = false) => {
|
|||||||
|
|
||||||
const onHostBlur = () => {
|
const onHostBlur = () => {
|
||||||
hostFocused.value = false
|
hostFocused.value = false
|
||||||
|
const parsedHost = parseHostInputOnBlur(internalValue.value.host ?? '', internalValue.value.proto, props.protos)
|
||||||
|
if (parsedHost) {
|
||||||
|
internalValue.value = parsedHost
|
||||||
|
}
|
||||||
syncUrlFromInternal(true)
|
syncUrlFromInternal(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,12 +66,20 @@ const isNoPortProto = computed(() => {
|
|||||||
return props.protos[internalValue.value.proto] === 0
|
return props.protos[internalValue.value.proto] === 0
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const hostInputValue = computed({
|
||||||
|
get: () => getHostInputValue(internalValue.value),
|
||||||
|
set: (value: string) => {
|
||||||
|
internalValue.value.host = value
|
||||||
|
internalValue.value.suffix = undefined
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
// Sync from external
|
// Sync from external
|
||||||
watch(() => url.value, (newVal) => {
|
watch(() => url.value, (newVal) => {
|
||||||
if (hostFocused.value) {
|
if (hostFocused.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const parsed = parseUrl(newVal)
|
const parsed = parseUrlInput(newVal, props.protos)
|
||||||
const internalHost = internalValue.value.host ?? ''
|
const internalHost = internalValue.value.host ?? ''
|
||||||
const sameHost = parsed.host === internalHost || (!internalHost.trim() && parsed.host === defaultHost)
|
const sameHost = parsed.host === internalHost || (!internalHost.trim() && parsed.host === defaultHost)
|
||||||
if (parsed.proto !== internalValue.value.proto ||
|
if (parsed.proto !== internalValue.value.proto ||
|
||||||
@@ -140,6 +91,9 @@ watch(() => url.value, (newVal) => {
|
|||||||
|
|
||||||
// Sync to external
|
// Sync to external
|
||||||
watch(internalValue, () => {
|
watch(internalValue, () => {
|
||||||
|
if (hostFocused.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
syncUrlFromInternal(false)
|
syncUrlFromInternal(false)
|
||||||
}, { deep: true })
|
}, { deep: true })
|
||||||
|
|
||||||
@@ -165,6 +119,8 @@ const onProtoChange = (newProto: string) => {
|
|||||||
internalValue.value.port = newDefault
|
internalValue.value.port = newDefault
|
||||||
}
|
}
|
||||||
internalValue.value.proto = newProto
|
internalValue.value.proto = newProto
|
||||||
|
internalValue.value.suffix = undefined
|
||||||
|
internalValue.value.hasExplicitPort = true
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -174,7 +130,7 @@ const onProtoChange = (newProto: string) => {
|
|||||||
<AutoComplete :model-value="internalValue.proto" :suggestions="filteredProtos" dropdown
|
<AutoComplete :model-value="internalValue.proto" :suggestions="filteredProtos" dropdown
|
||||||
class="max-w-32 proto-autocomplete-in-group" @complete="searchProtos"
|
class="max-w-32 proto-autocomplete-in-group" @complete="searchProtos"
|
||||||
@update:model-value="onProtoChange" />
|
@update:model-value="onProtoChange" />
|
||||||
<InputText v-model="internalValue.host" :placeholder="placeholder || '0.0.0.0'" class="grow"
|
<InputText v-model="hostInputValue" :placeholder="placeholder || '0.0.0.0'" class="grow"
|
||||||
@focus="onHostFocus" @blur="onHostBlur" />
|
@focus="onHostFocus" @blur="onHostBlur" />
|
||||||
<template v-if="!isNoPortProto">
|
<template v-if="!isNoPortProto">
|
||||||
<InputGroupAddon>
|
<InputGroupAddon>
|
||||||
@@ -204,7 +160,7 @@ const onProtoChange = (newProto: string) => {
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<label>{{ t('web.common.address') || 'Address' }}</label>
|
<label>{{ t('web.common.address') || 'Address' }}</label>
|
||||||
<InputText v-model="internalValue.host" :placeholder="placeholder || '0.0.0.0'" class="w-full"
|
<InputText v-model="hostInputValue" :placeholder="placeholder || '0.0.0.0'" class="w-full"
|
||||||
@focus="onHostFocus" @blur="onHostBlur" />
|
@focus="onHostFocus" @blur="onHostBlur" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!isNoPortProto" class="flex flex-col gap-2">
|
<div v-if="!isNoPortProto" class="flex flex-col gap-2">
|
||||||
|
|||||||
@@ -0,0 +1,184 @@
|
|||||||
|
import { describe, expect, it } from 'vitest'
|
||||||
|
import { buildUrlInputValue, getHostInputValue, parseHostInputOnBlur, parseUrlInput, type ProtoPorts } from './url-input'
|
||||||
|
|
||||||
|
const protos: ProtoPorts = {
|
||||||
|
tcp: 11010,
|
||||||
|
udp: 11010,
|
||||||
|
wg: 11011,
|
||||||
|
ws: 11011,
|
||||||
|
wss: 11012,
|
||||||
|
quic: 11012,
|
||||||
|
faketcp: 11013,
|
||||||
|
http: 80,
|
||||||
|
https: 443,
|
||||||
|
txt: 0,
|
||||||
|
srv: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
function normalizeUrl(input: string, defaultProto = 'tcp') {
|
||||||
|
return buildUrlInputValue(parseUrlInput(input, protos, defaultProto), protos, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('parseUrlInput', () => {
|
||||||
|
it.each([
|
||||||
|
['https://raw.githubusercontent.com/aaa/bb/cc.txt', {
|
||||||
|
proto: 'https',
|
||||||
|
host: 'raw.githubusercontent.com',
|
||||||
|
port: null,
|
||||||
|
suffix: '/aaa/bb/cc.txt',
|
||||||
|
hasExplicitPort: false,
|
||||||
|
}],
|
||||||
|
['https://host:4443/path?x=1#hash', {
|
||||||
|
proto: 'https',
|
||||||
|
host: 'host',
|
||||||
|
port: 4443,
|
||||||
|
suffix: '/path?x=1#hash',
|
||||||
|
hasExplicitPort: true,
|
||||||
|
}],
|
||||||
|
['[::1]:11010/path', {
|
||||||
|
proto: 'tcp',
|
||||||
|
host: '[::1]',
|
||||||
|
port: 11010,
|
||||||
|
suffix: '/path',
|
||||||
|
hasExplicitPort: true,
|
||||||
|
}],
|
||||||
|
[' http://host/path ', {
|
||||||
|
proto: 'http',
|
||||||
|
host: 'host',
|
||||||
|
port: null,
|
||||||
|
suffix: '/path',
|
||||||
|
hasExplicitPort: false,
|
||||||
|
}],
|
||||||
|
])('parses %s', (input, expected) => {
|
||||||
|
expect(parseUrlInput(input, protos)).toEqual(expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('parses IPv6 host without an explicit port', () => {
|
||||||
|
expect(parseUrlInput('[::1]', protos)).toEqual({
|
||||||
|
proto: 'tcp',
|
||||||
|
host: '[::1]',
|
||||||
|
port: null,
|
||||||
|
suffix: '',
|
||||||
|
hasExplicitPort: false,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
['host:', 'host'],
|
||||||
|
['host:notaport', 'host'],
|
||||||
|
])('falls back to the default port for invalid port input %s', (input, host) => {
|
||||||
|
expect(parseUrlInput(input, protos)).toEqual({
|
||||||
|
proto: 'tcp',
|
||||||
|
host,
|
||||||
|
port: 11010,
|
||||||
|
suffix: '',
|
||||||
|
hasExplicitPort: false,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('keeps the explicit proto for an input without authority', () => {
|
||||||
|
expect(parseUrlInput('https://', protos)).toEqual({
|
||||||
|
proto: 'https',
|
||||||
|
host: '',
|
||||||
|
port: null,
|
||||||
|
suffix: '',
|
||||||
|
hasExplicitPort: false,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('buildUrlInputValue', () => {
|
||||||
|
it.each([
|
||||||
|
['https://host', 'https://host'],
|
||||||
|
['http://host', 'http://host'],
|
||||||
|
['https://host:4443/path', 'https://host:4443/path'],
|
||||||
|
['https://host:443/path', 'https://host:443/path'],
|
||||||
|
['tcp://host', 'tcp://host'],
|
||||||
|
['wss://host', 'wss://host'],
|
||||||
|
['http://host/path?x=1#hash', 'http://host/path?x=1#hash'],
|
||||||
|
['https://host?x=1', 'https://host?x=1'],
|
||||||
|
['https://host#hash', 'https://host#hash'],
|
||||||
|
['txt://example.com/path.txt', 'txt://example.com/path.txt'],
|
||||||
|
['srv://_easytier._tcp.example.com', 'srv://_easytier._tcp.example.com'],
|
||||||
|
['custom://host/path', 'custom://host/path'],
|
||||||
|
])('normalizes %s to %s', (input, expected) => {
|
||||||
|
expect(normalizeUrl(input)).toBe(expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns null for empty host unless default host is forced', () => {
|
||||||
|
const parsed = parseUrlInput('', protos)
|
||||||
|
|
||||||
|
expect(buildUrlInputValue(parsed, protos, false)).toBeNull()
|
||||||
|
expect(buildUrlInputValue(parsed, protos, true)).toBe('tcp://0.0.0.0:11010')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('does not build a broken URL for a protocol without authority', () => {
|
||||||
|
const parsed = parseUrlInput('https://', protos)
|
||||||
|
|
||||||
|
expect(buildUrlInputValue(parsed, protos, false)).toBeNull()
|
||||||
|
expect(buildUrlInputValue(parsed, protos, true)).toBe('https://0.0.0.0')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('parseHostInputOnBlur', () => {
|
||||||
|
it('infers https for a pasted host:port/path when the current proto is tcp', () => {
|
||||||
|
const parsed = parseHostInputOnBlur('raw.githubusercontent.com:4443/aaa/bb/cc.txt', 'tcp', protos)
|
||||||
|
|
||||||
|
expect(parsed).toEqual({
|
||||||
|
proto: 'https',
|
||||||
|
host: 'raw.githubusercontent.com',
|
||||||
|
port: 4443,
|
||||||
|
suffix: '/aaa/bb/cc.txt',
|
||||||
|
hasExplicitPort: true,
|
||||||
|
})
|
||||||
|
expect(buildUrlInputValue(parsed!, protos, true)).toBe('https://raw.githubusercontent.com:4443/aaa/bb/cc.txt')
|
||||||
|
})
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
['raw.githubusercontent.com/aaa/bb/cc.txt', 'tcp', 'https://raw.githubusercontent.com/aaa/bb/cc.txt'],
|
||||||
|
['raw.githubusercontent.com:4443/aaa/bb/cc.txt', 'https', 'https://raw.githubusercontent.com:4443/aaa/bb/cc.txt'],
|
||||||
|
['https://raw.githubusercontent.com:4443/aaa/bb/cc.txt', 'tcp', 'https://raw.githubusercontent.com:4443/aaa/bb/cc.txt'],
|
||||||
|
[' https://raw.githubusercontent.com/aaa/bb/cc.txt ', 'tcp', 'https://raw.githubusercontent.com/aaa/bb/cc.txt'],
|
||||||
|
])('normalizes pasted host input %s with current proto %s', (input, currentProto, expected) => {
|
||||||
|
const parsed = parseHostInputOnBlur(input, currentProto, protos)
|
||||||
|
|
||||||
|
expect(buildUrlInputValue(parsed!, protos, true)).toBe(expected)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('keeps ordinary host:port input on the current tcp protocol', () => {
|
||||||
|
const parsed = parseHostInputOnBlur('example.com:11010', 'tcp', protos)
|
||||||
|
|
||||||
|
expect(buildUrlInputValue(parsed!, protos, true)).toBe('tcp://example.com:11010')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('returns null for a simple host without port or suffix', () => {
|
||||||
|
expect(parseHostInputOnBlur('example.com', 'tcp', protos)).toBeNull()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('getHostInputValue', () => {
|
||||||
|
it('shows host and suffix while keeping the port in the port field', () => {
|
||||||
|
const parsed = parseUrlInput('https://raw.githubusercontent.com:4443/aaa/bb/cc.txt', protos)
|
||||||
|
|
||||||
|
expect(getHostInputValue(parsed)).toBe('raw.githubusercontent.com/aaa/bb/cc.txt')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('shows query and hash in the host input suffix', () => {
|
||||||
|
const parsed = parseUrlInput('https://host/path?x=1#hash', protos)
|
||||||
|
|
||||||
|
expect(getHostInputValue(parsed)).toBe('host/path?x=1#hash')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('round trip scenarios', () => {
|
||||||
|
it.each([
|
||||||
|
['https://raw.githubusercontent.com/aaa/bb/cc.txt'],
|
||||||
|
['https://raw.githubusercontent.com:4443/aaa/bb/cc.txt'],
|
||||||
|
['http://host/path?x=1#hash'],
|
||||||
|
['tcp://example.com:11010'],
|
||||||
|
['txt://example.com/path.txt'],
|
||||||
|
['srv://_easytier._tcp.example.com'],
|
||||||
|
])('keeps %s stable after parse and build', (input) => {
|
||||||
|
expect(normalizeUrl(input)).toBe(input)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
export interface UrlInputParts {
|
||||||
|
proto: string
|
||||||
|
host: string
|
||||||
|
port: number | null
|
||||||
|
suffix?: string
|
||||||
|
hasExplicitPort?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ProtoPorts = Record<string, number>
|
||||||
|
|
||||||
|
const fallbackProto = 'tcp'
|
||||||
|
const fallbackPort = 11010
|
||||||
|
const defaultHost = '0.0.0.0'
|
||||||
|
|
||||||
|
function defaultPortFor(protos: ProtoPorts, proto: string) {
|
||||||
|
return protos[proto] ?? fallbackPort
|
||||||
|
}
|
||||||
|
|
||||||
|
function getValidPort(portStr: string, protos: ProtoPorts, proto: string) {
|
||||||
|
const p = parseInt(portStr)
|
||||||
|
return isNaN(p) ? defaultPortFor(protos, proto) : p
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseUrlInput(val: string | null | undefined, protos: ProtoPorts, defaultProto = fallbackProto): UrlInputParts {
|
||||||
|
const parseByPattern = (input: string) => {
|
||||||
|
const trimmed = input.trim()
|
||||||
|
if (!trimmed) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const match = trimmed.match(/^(\w+):\/\/(.*)$/)
|
||||||
|
const proto = match ? match[1] : defaultProto
|
||||||
|
const rest = match ? match[2] : trimmed
|
||||||
|
const suffixStart = rest.search(/[/?#]/)
|
||||||
|
const authority = suffixStart >= 0 ? rest.slice(0, suffixStart) : rest
|
||||||
|
const suffix = suffixStart >= 0 ? rest.slice(suffixStart) : ''
|
||||||
|
if (!authority) {
|
||||||
|
return { proto, host: '', port: null, suffix, hasExplicitPort: false }
|
||||||
|
}
|
||||||
|
|
||||||
|
const hostAndMaybePort = authority.includes('@') ? authority.slice(authority.lastIndexOf('@') + 1) : authority
|
||||||
|
if (hostAndMaybePort.startsWith('[')) {
|
||||||
|
const ipv6End = hostAndMaybePort.indexOf(']')
|
||||||
|
if (ipv6End > 0) {
|
||||||
|
const host = hostAndMaybePort.slice(0, ipv6End + 1)
|
||||||
|
const remain = hostAndMaybePort.slice(ipv6End + 1)
|
||||||
|
const hasExplicitPort = remain.startsWith(':')
|
||||||
|
const port = hasExplicitPort ? getValidPort(remain.slice(1), protos, proto) : null
|
||||||
|
return { proto, host, port, suffix, hasExplicitPort }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const portMatch = hostAndMaybePort.match(/^(.*):(\d+)$/)
|
||||||
|
if (portMatch) {
|
||||||
|
return { proto, host: portMatch[1], port: parseInt(portMatch[2]), suffix, hasExplicitPort: true }
|
||||||
|
}
|
||||||
|
|
||||||
|
const invalidPortMatch = hostAndMaybePort.match(/^([^:]+):[^:]*$/)
|
||||||
|
const host = invalidPortMatch ? invalidPortMatch[1] : hostAndMaybePort
|
||||||
|
const port = invalidPortMatch ? defaultPortFor(protos, proto) : null
|
||||||
|
return { proto, host, port, suffix, hasExplicitPort: false }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!val) {
|
||||||
|
return { proto: defaultProto, host: '', port: defaultPortFor(protos, defaultProto) }
|
||||||
|
}
|
||||||
|
const parsedByPattern = parseByPattern(val)
|
||||||
|
if (parsedByPattern) {
|
||||||
|
return parsedByPattern
|
||||||
|
}
|
||||||
|
return { proto: defaultProto, host: '', port: defaultPortFor(protos, defaultProto) }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function buildUrlInputValue(value: UrlInputParts, protos: ProtoPorts, forceDefaultHost = false) {
|
||||||
|
const proto = value.proto || fallbackProto
|
||||||
|
const rawHost = (value.host ?? '').trim()
|
||||||
|
const host = rawHost || (forceDefaultHost ? defaultHost : '')
|
||||||
|
if (!host) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (protos[proto] === 0 || value.port === null) {
|
||||||
|
return `${proto}://${host}${value.suffix ?? ''}`
|
||||||
|
}
|
||||||
|
|
||||||
|
let port = value.port
|
||||||
|
if (isNaN(parseInt(port as any))) {
|
||||||
|
port = defaultPortFor(protos, proto)
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${proto}://${host}:${port}${value.suffix ?? ''}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseHostInputOnBlur(rawHost: string, currentProto: string, protos: ProtoPorts) {
|
||||||
|
const inferredProto = rawHost.includes('/') && currentProto === fallbackProto ? 'https' : currentProto
|
||||||
|
const parsedHost = parseUrlInput(rawHost, protos, inferredProto)
|
||||||
|
if (parsedHost.host && (parsedHost.proto !== currentProto || parsedHost.hasExplicitPort || parsedHost.suffix)) {
|
||||||
|
return parsedHost
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getHostInputValue(value: UrlInputParts) {
|
||||||
|
return `${value.host ?? ''}${value.suffix ?? ''}`
|
||||||
|
}
|
||||||
Generated
+271
-4
@@ -59,7 +59,7 @@ importers:
|
|||||||
devDependencies:
|
devDependencies:
|
||||||
'@antfu/eslint-config':
|
'@antfu/eslint-config':
|
||||||
specifier: ^3.7.3
|
specifier: ^3.7.3
|
||||||
version: 3.16.0(@typescript-eslint/utils@8.42.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3))(@vue/compiler-sfc@3.5.21)(eslint-plugin-format@0.1.3(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)
|
version: 3.16.0(@typescript-eslint/utils@8.42.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3))(@vue/compiler-sfc@3.5.21)(eslint-plugin-format@0.1.3(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)(vitest@2.1.9(@types/node@22.18.1))
|
||||||
'@intlify/unplugin-vue-i18n':
|
'@intlify/unplugin-vue-i18n':
|
||||||
specifier: ^5.2.0
|
specifier: ^5.2.0
|
||||||
version: 5.3.1(@vue/compiler-dom@3.5.21)(eslint@9.35.0(jiti@2.5.1))(rollup@4.50.1)(typescript@5.6.3)(vue-i18n@10.0.8(vue@3.5.21(typescript@5.6.3)))(vue@3.5.21(typescript@5.6.3))
|
version: 5.3.1(@vue/compiler-dom@3.5.21)(eslint@9.35.0(jiti@2.5.1))(rollup@4.50.1)(typescript@5.6.3)(vue-i18n@10.0.8(vue@3.5.21(typescript@5.6.3)))(vue@3.5.21(typescript@5.6.3))
|
||||||
@@ -287,6 +287,9 @@ importers:
|
|||||||
vite-plugin-dts:
|
vite-plugin-dts:
|
||||||
specifier: ^4.3.0
|
specifier: ^4.3.0
|
||||||
version: 4.5.4(@types/node@22.18.1)(rollup@4.50.1)(typescript@5.6.3)(vite@5.4.21(@types/node@22.18.1))
|
version: 4.5.4(@types/node@22.18.1)(rollup@4.50.1)(typescript@5.6.3)(vite@5.4.21(@types/node@22.18.1))
|
||||||
|
vitest:
|
||||||
|
specifier: ^2.1.9
|
||||||
|
version: 2.1.9(@types/node@22.18.1)
|
||||||
vue-tsc:
|
vue-tsc:
|
||||||
specifier: ^2.1.10
|
specifier: ^2.1.10
|
||||||
version: 2.2.12(typescript@5.6.3)
|
version: 2.2.12(typescript@5.6.3)
|
||||||
@@ -1674,6 +1677,35 @@ packages:
|
|||||||
vitest:
|
vitest:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@vitest/expect@2.1.9':
|
||||||
|
resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==}
|
||||||
|
|
||||||
|
'@vitest/mocker@2.1.9':
|
||||||
|
resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==}
|
||||||
|
peerDependencies:
|
||||||
|
msw: ^2.4.9
|
||||||
|
vite: ^5.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
msw:
|
||||||
|
optional: true
|
||||||
|
vite:
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
'@vitest/pretty-format@2.1.9':
|
||||||
|
resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==}
|
||||||
|
|
||||||
|
'@vitest/runner@2.1.9':
|
||||||
|
resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==}
|
||||||
|
|
||||||
|
'@vitest/snapshot@2.1.9':
|
||||||
|
resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==}
|
||||||
|
|
||||||
|
'@vitest/spy@2.1.9':
|
||||||
|
resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==}
|
||||||
|
|
||||||
|
'@vitest/utils@2.1.9':
|
||||||
|
resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==}
|
||||||
|
|
||||||
'@volar/language-core@2.4.15':
|
'@volar/language-core@2.4.15':
|
||||||
resolution: {integrity: sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==}
|
resolution: {integrity: sha512-3VHw+QZU0ZG9IuQmzT68IyN4hZNd9GchGPhbD9+pa8CVv7rnoOZwo7T8weIbrRmihqy3ATpdfXFnqRrfPVK6CA==}
|
||||||
|
|
||||||
@@ -2073,6 +2105,10 @@ packages:
|
|||||||
argparse@2.0.1:
|
argparse@2.0.1:
|
||||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||||
|
|
||||||
|
assertion-error@2.0.1:
|
||||||
|
resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
ast-kit@1.4.3:
|
ast-kit@1.4.3:
|
||||||
resolution: {integrity: sha512-MdJqjpodkS5J149zN0Po+HPshkTdUyrvF7CKTafUgv69vBSPtncrj+3IiUgqdd7ElIEkbeXCsEouBUwLrw9Ilg==}
|
resolution: {integrity: sha512-MdJqjpodkS5J149zN0Po+HPshkTdUyrvF7CKTafUgv69vBSPtncrj+3IiUgqdd7ElIEkbeXCsEouBUwLrw9Ilg==}
|
||||||
engines: {node: '>=16.14.0'}
|
engines: {node: '>=16.14.0'}
|
||||||
@@ -2135,6 +2171,10 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
esbuild: '>=0.18'
|
esbuild: '>=0.18'
|
||||||
|
|
||||||
|
cac@6.7.14:
|
||||||
|
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
call-bind-apply-helpers@1.0.2:
|
call-bind-apply-helpers@1.0.2:
|
||||||
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
|
resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -2153,6 +2193,10 @@ packages:
|
|||||||
ccount@2.0.1:
|
ccount@2.0.1:
|
||||||
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
|
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
|
||||||
|
|
||||||
|
chai@5.3.3:
|
||||||
|
resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==}
|
||||||
|
engines: {node: '>=18'}
|
||||||
|
|
||||||
chalk@4.1.2:
|
chalk@4.1.2:
|
||||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -2164,6 +2208,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-aYeC/jDgSEx8SHWZvANYMioYMZ2KX02W6f6uVfyteuCGcadDLcYVHdfdygsTQkQ4TKn5lghoojAsPj5pu0SnvQ==}
|
resolution: {integrity: sha512-aYeC/jDgSEx8SHWZvANYMioYMZ2KX02W6f6uVfyteuCGcadDLcYVHdfdygsTQkQ4TKn5lghoojAsPj5pu0SnvQ==}
|
||||||
engines: {pnpm: '>=8'}
|
engines: {pnpm: '>=8'}
|
||||||
|
|
||||||
|
check-error@2.1.3:
|
||||||
|
resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==}
|
||||||
|
engines: {node: '>= 16'}
|
||||||
|
|
||||||
chokidar@3.6.0:
|
chokidar@3.6.0:
|
||||||
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
|
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
|
||||||
engines: {node: '>= 8.10.0'}
|
engines: {node: '>= 8.10.0'}
|
||||||
@@ -2252,6 +2300,10 @@ packages:
|
|||||||
decode-named-character-reference@1.2.0:
|
decode-named-character-reference@1.2.0:
|
||||||
resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==}
|
resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==}
|
||||||
|
|
||||||
|
deep-eql@5.0.2:
|
||||||
|
resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
deep-is@0.1.4:
|
deep-is@0.1.4:
|
||||||
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
|
resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
|
||||||
|
|
||||||
@@ -2329,6 +2381,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
|
resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
es-module-lexer@1.7.0:
|
||||||
|
resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==}
|
||||||
|
|
||||||
es-object-atoms@1.1.1:
|
es-object-atoms@1.1.1:
|
||||||
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
|
resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -2597,6 +2652,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
|
resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
|
||||||
engines: {node: '>=16.17'}
|
engines: {node: '>=16.17'}
|
||||||
|
|
||||||
|
expect-type@1.3.0:
|
||||||
|
resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==}
|
||||||
|
engines: {node: '>=12.0.0'}
|
||||||
|
|
||||||
exsolve@1.0.7:
|
exsolve@1.0.7:
|
||||||
resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==}
|
resolution: {integrity: sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==}
|
||||||
|
|
||||||
@@ -3018,6 +3077,9 @@ packages:
|
|||||||
longest-streak@3.1.0:
|
longest-streak@3.1.0:
|
||||||
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
|
resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
|
||||||
|
|
||||||
|
loupe@3.2.1:
|
||||||
|
resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==}
|
||||||
|
|
||||||
lru-cache@10.4.3:
|
lru-cache@10.4.3:
|
||||||
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
|
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
|
||||||
|
|
||||||
@@ -3371,6 +3433,10 @@ packages:
|
|||||||
pathe@2.0.3:
|
pathe@2.0.3:
|
||||||
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
|
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
|
||||||
|
|
||||||
|
pathval@2.0.1:
|
||||||
|
resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==}
|
||||||
|
engines: {node: '>= 14.16'}
|
||||||
|
|
||||||
perfect-debounce@1.0.0:
|
perfect-debounce@1.0.0:
|
||||||
resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
|
resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
|
||||||
|
|
||||||
@@ -3613,6 +3679,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
|
|
||||||
|
siginfo@2.0.0:
|
||||||
|
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
|
||||||
|
|
||||||
signal-exit@3.0.7:
|
signal-exit@3.0.7:
|
||||||
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
|
||||||
|
|
||||||
@@ -3665,6 +3734,12 @@ packages:
|
|||||||
resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==}
|
resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==}
|
||||||
engines: {node: '>=12.0.0'}
|
engines: {node: '>=12.0.0'}
|
||||||
|
|
||||||
|
stackback@0.0.2:
|
||||||
|
resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==}
|
||||||
|
|
||||||
|
std-env@3.10.0:
|
||||||
|
resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==}
|
||||||
|
|
||||||
string-argv@0.3.2:
|
string-argv@0.3.2:
|
||||||
resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
|
resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==}
|
||||||
engines: {node: '>=0.6.19'}
|
engines: {node: '>=0.6.19'}
|
||||||
@@ -3754,9 +3829,27 @@ packages:
|
|||||||
thenify@3.3.1:
|
thenify@3.3.1:
|
||||||
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
|
resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
|
||||||
|
|
||||||
|
tinybench@2.9.0:
|
||||||
|
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
|
||||||
|
|
||||||
|
tinyexec@0.3.2:
|
||||||
|
resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
|
||||||
|
|
||||||
tinyexec@1.0.1:
|
tinyexec@1.0.1:
|
||||||
resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==}
|
resolution: {integrity: sha512-5uC6DDlmeqiOwCPmK9jMSdOuZTh8bU39Ys6yidB+UTt5hfZUPGAypSgFRiEp+jbi9qH40BLDvy85jIU88wKSqw==}
|
||||||
|
|
||||||
|
tinypool@1.1.1:
|
||||||
|
resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==}
|
||||||
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
|
|
||||||
|
tinyrainbow@1.2.0:
|
||||||
|
resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==}
|
||||||
|
engines: {node: '>=14.0.0'}
|
||||||
|
|
||||||
|
tinyspy@3.0.2:
|
||||||
|
resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==}
|
||||||
|
engines: {node: '>=14.0.0'}
|
||||||
|
|
||||||
to-regex-range@5.0.1:
|
to-regex-range@5.0.1:
|
||||||
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
|
||||||
engines: {node: '>=8.0'}
|
engines: {node: '>=8.0'}
|
||||||
@@ -3976,6 +4069,11 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0
|
vite: ^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0
|
||||||
|
|
||||||
|
vite-node@2.1.9:
|
||||||
|
resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==}
|
||||||
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
vite-plugin-dts@4.5.4:
|
vite-plugin-dts@4.5.4:
|
||||||
resolution: {integrity: sha512-d4sOM8M/8z7vRXHHq/ebbblfaxENjogAAekcfcDCCwAyvGqnPrc7f4NZbvItS+g4WTgerW0xDwSz5qz11JT3vg==}
|
resolution: {integrity: sha512-d4sOM8M/8z7vRXHHq/ebbblfaxENjogAAekcfcDCCwAyvGqnPrc7f4NZbvItS+g4WTgerW0xDwSz5qz11JT3vg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -4051,6 +4149,31 @@ packages:
|
|||||||
terser:
|
terser:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
vitest@2.1.9:
|
||||||
|
resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==}
|
||||||
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
|
hasBin: true
|
||||||
|
peerDependencies:
|
||||||
|
'@edge-runtime/vm': '*'
|
||||||
|
'@types/node': ^18.0.0 || >=20.0.0
|
||||||
|
'@vitest/browser': 2.1.9
|
||||||
|
'@vitest/ui': 2.1.9
|
||||||
|
happy-dom: '*'
|
||||||
|
jsdom: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@edge-runtime/vm':
|
||||||
|
optional: true
|
||||||
|
'@types/node':
|
||||||
|
optional: true
|
||||||
|
'@vitest/browser':
|
||||||
|
optional: true
|
||||||
|
'@vitest/ui':
|
||||||
|
optional: true
|
||||||
|
happy-dom:
|
||||||
|
optional: true
|
||||||
|
jsdom:
|
||||||
|
optional: true
|
||||||
|
|
||||||
vscode-uri@3.1.0:
|
vscode-uri@3.1.0:
|
||||||
resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
|
resolution: {integrity: sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==}
|
||||||
|
|
||||||
@@ -4123,6 +4246,11 @@ packages:
|
|||||||
engines: {node: '>= 8'}
|
engines: {node: '>= 8'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
why-is-node-running@2.3.0:
|
||||||
|
resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==}
|
||||||
|
engines: {node: '>=8'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
word-wrap@1.2.5:
|
word-wrap@1.2.5:
|
||||||
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -4181,7 +4309,7 @@ snapshots:
|
|||||||
|
|
||||||
'@alloc/quick-lru@5.2.0': {}
|
'@alloc/quick-lru@5.2.0': {}
|
||||||
|
|
||||||
'@antfu/eslint-config@3.16.0(@typescript-eslint/utils@8.42.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3))(@vue/compiler-sfc@3.5.21)(eslint-plugin-format@0.1.3(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)':
|
'@antfu/eslint-config@3.16.0(@typescript-eslint/utils@8.42.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3))(@vue/compiler-sfc@3.5.21)(eslint-plugin-format@0.1.3(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)(vitest@2.1.9(@types/node@22.18.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@antfu/install-pkg': 1.1.0
|
'@antfu/install-pkg': 1.1.0
|
||||||
'@clack/prompts': 0.9.1
|
'@clack/prompts': 0.9.1
|
||||||
@@ -4190,7 +4318,7 @@ snapshots:
|
|||||||
'@stylistic/eslint-plugin': 2.13.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)
|
'@stylistic/eslint-plugin': 2.13.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)
|
||||||
'@typescript-eslint/eslint-plugin': 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3))(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)
|
'@typescript-eslint/eslint-plugin': 8.42.0(@typescript-eslint/parser@8.42.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3))(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)
|
||||||
'@typescript-eslint/parser': 8.42.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)
|
'@typescript-eslint/parser': 8.42.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)
|
||||||
'@vitest/eslint-plugin': 1.3.9(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)
|
'@vitest/eslint-plugin': 1.3.9(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)(vitest@2.1.9(@types/node@22.18.1))
|
||||||
eslint: 9.35.0(jiti@2.5.1)
|
eslint: 9.35.0(jiti@2.5.1)
|
||||||
eslint-config-flat-gitignore: 1.0.1(eslint@9.35.0(jiti@2.5.1))
|
eslint-config-flat-gitignore: 1.0.1(eslint@9.35.0(jiti@2.5.1))
|
||||||
eslint-flat-config-utils: 1.1.0
|
eslint-flat-config-utils: 1.1.0
|
||||||
@@ -5387,16 +5515,57 @@ snapshots:
|
|||||||
vite: 5.4.21(@types/node@22.18.1)
|
vite: 5.4.21(@types/node@22.18.1)
|
||||||
vue: 3.5.21(typescript@5.6.3)
|
vue: 3.5.21(typescript@5.6.3)
|
||||||
|
|
||||||
'@vitest/eslint-plugin@1.3.9(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)':
|
'@vitest/eslint-plugin@1.3.9(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)(vitest@2.1.9(@types/node@22.18.1))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/scope-manager': 8.42.0
|
'@typescript-eslint/scope-manager': 8.42.0
|
||||||
'@typescript-eslint/utils': 8.42.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)
|
'@typescript-eslint/utils': 8.42.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.6.3)
|
||||||
eslint: 9.35.0(jiti@2.5.1)
|
eslint: 9.35.0(jiti@2.5.1)
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
typescript: 5.6.3
|
typescript: 5.6.3
|
||||||
|
vitest: 2.1.9(@types/node@22.18.1)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
|
'@vitest/expect@2.1.9':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/spy': 2.1.9
|
||||||
|
'@vitest/utils': 2.1.9
|
||||||
|
chai: 5.3.3
|
||||||
|
tinyrainbow: 1.2.0
|
||||||
|
|
||||||
|
'@vitest/mocker@2.1.9(vite@5.4.21(@types/node@22.18.1))':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/spy': 2.1.9
|
||||||
|
estree-walker: 3.0.3
|
||||||
|
magic-string: 0.30.18
|
||||||
|
optionalDependencies:
|
||||||
|
vite: 5.4.21(@types/node@22.18.1)
|
||||||
|
|
||||||
|
'@vitest/pretty-format@2.1.9':
|
||||||
|
dependencies:
|
||||||
|
tinyrainbow: 1.2.0
|
||||||
|
|
||||||
|
'@vitest/runner@2.1.9':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/utils': 2.1.9
|
||||||
|
pathe: 1.1.2
|
||||||
|
|
||||||
|
'@vitest/snapshot@2.1.9':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/pretty-format': 2.1.9
|
||||||
|
magic-string: 0.30.18
|
||||||
|
pathe: 1.1.2
|
||||||
|
|
||||||
|
'@vitest/spy@2.1.9':
|
||||||
|
dependencies:
|
||||||
|
tinyspy: 3.0.2
|
||||||
|
|
||||||
|
'@vitest/utils@2.1.9':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/pretty-format': 2.1.9
|
||||||
|
loupe: 3.2.1
|
||||||
|
tinyrainbow: 1.2.0
|
||||||
|
|
||||||
'@volar/language-core@2.4.15':
|
'@volar/language-core@2.4.15':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@volar/source-map': 2.4.15
|
'@volar/source-map': 2.4.15
|
||||||
@@ -5971,6 +6140,8 @@ snapshots:
|
|||||||
|
|
||||||
argparse@2.0.1: {}
|
argparse@2.0.1: {}
|
||||||
|
|
||||||
|
assertion-error@2.0.1: {}
|
||||||
|
|
||||||
ast-kit@1.4.3:
|
ast-kit@1.4.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/parser': 7.28.4
|
'@babel/parser': 7.28.4
|
||||||
@@ -6035,6 +6206,8 @@ snapshots:
|
|||||||
esbuild: 0.25.9
|
esbuild: 0.25.9
|
||||||
load-tsconfig: 0.2.5
|
load-tsconfig: 0.2.5
|
||||||
|
|
||||||
|
cac@6.7.14: {}
|
||||||
|
|
||||||
call-bind-apply-helpers@1.0.2:
|
call-bind-apply-helpers@1.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
@@ -6048,6 +6221,14 @@ snapshots:
|
|||||||
|
|
||||||
ccount@2.0.1: {}
|
ccount@2.0.1: {}
|
||||||
|
|
||||||
|
chai@5.3.3:
|
||||||
|
dependencies:
|
||||||
|
assertion-error: 2.0.1
|
||||||
|
check-error: 2.1.3
|
||||||
|
deep-eql: 5.0.2
|
||||||
|
loupe: 3.2.1
|
||||||
|
pathval: 2.0.1
|
||||||
|
|
||||||
chalk@4.1.2:
|
chalk@4.1.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
ansi-styles: 4.3.0
|
ansi-styles: 4.3.0
|
||||||
@@ -6059,6 +6240,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@kurkle/color': 0.3.4
|
'@kurkle/color': 0.3.4
|
||||||
|
|
||||||
|
check-error@2.1.3: {}
|
||||||
|
|
||||||
chokidar@3.6.0:
|
chokidar@3.6.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
anymatch: 3.1.3
|
anymatch: 3.1.3
|
||||||
@@ -6139,6 +6322,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
character-entities: 2.0.2
|
character-entities: 2.0.2
|
||||||
|
|
||||||
|
deep-eql@5.0.2: {}
|
||||||
|
|
||||||
deep-is@0.1.4: {}
|
deep-is@0.1.4: {}
|
||||||
|
|
||||||
default-browser-id@5.0.0: {}
|
default-browser-id@5.0.0: {}
|
||||||
@@ -6199,6 +6384,8 @@ snapshots:
|
|||||||
|
|
||||||
es-errors@1.3.0: {}
|
es-errors@1.3.0: {}
|
||||||
|
|
||||||
|
es-module-lexer@1.7.0: {}
|
||||||
|
|
||||||
es-object-atoms@1.1.1:
|
es-object-atoms@1.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
es-errors: 1.3.0
|
es-errors: 1.3.0
|
||||||
@@ -6615,6 +6802,8 @@ snapshots:
|
|||||||
signal-exit: 4.1.0
|
signal-exit: 4.1.0
|
||||||
strip-final-newline: 3.0.0
|
strip-final-newline: 3.0.0
|
||||||
|
|
||||||
|
expect-type@1.3.0: {}
|
||||||
|
|
||||||
exsolve@1.0.7: {}
|
exsolve@1.0.7: {}
|
||||||
|
|
||||||
extend-shallow@2.0.1:
|
extend-shallow@2.0.1:
|
||||||
@@ -6978,6 +7167,8 @@ snapshots:
|
|||||||
|
|
||||||
longest-streak@3.1.0: {}
|
longest-streak@3.1.0: {}
|
||||||
|
|
||||||
|
loupe@3.2.1: {}
|
||||||
|
|
||||||
lru-cache@10.4.3: {}
|
lru-cache@10.4.3: {}
|
||||||
|
|
||||||
lru-cache@5.1.1:
|
lru-cache@5.1.1:
|
||||||
@@ -7503,6 +7694,8 @@ snapshots:
|
|||||||
|
|
||||||
pathe@2.0.3: {}
|
pathe@2.0.3: {}
|
||||||
|
|
||||||
|
pathval@2.0.1: {}
|
||||||
|
|
||||||
perfect-debounce@1.0.0: {}
|
perfect-debounce@1.0.0: {}
|
||||||
|
|
||||||
picocolors@1.1.1: {}
|
picocolors@1.1.1: {}
|
||||||
@@ -7739,6 +7932,8 @@ snapshots:
|
|||||||
|
|
||||||
shebang-regex@3.0.0: {}
|
shebang-regex@3.0.0: {}
|
||||||
|
|
||||||
|
siginfo@2.0.0: {}
|
||||||
|
|
||||||
signal-exit@3.0.7: {}
|
signal-exit@3.0.7: {}
|
||||||
|
|
||||||
signal-exit@4.1.0: {}
|
signal-exit@4.1.0: {}
|
||||||
@@ -7786,6 +7981,10 @@ snapshots:
|
|||||||
|
|
||||||
stable-hash-x@0.2.0: {}
|
stable-hash-x@0.2.0: {}
|
||||||
|
|
||||||
|
stackback@0.0.2: {}
|
||||||
|
|
||||||
|
std-env@3.10.0: {}
|
||||||
|
|
||||||
string-argv@0.3.2: {}
|
string-argv@0.3.2: {}
|
||||||
|
|
||||||
string-width@4.2.3:
|
string-width@4.2.3:
|
||||||
@@ -7896,8 +8095,18 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
any-promise: 1.3.0
|
any-promise: 1.3.0
|
||||||
|
|
||||||
|
tinybench@2.9.0: {}
|
||||||
|
|
||||||
|
tinyexec@0.3.2: {}
|
||||||
|
|
||||||
tinyexec@1.0.1: {}
|
tinyexec@1.0.1: {}
|
||||||
|
|
||||||
|
tinypool@1.1.1: {}
|
||||||
|
|
||||||
|
tinyrainbow@1.2.0: {}
|
||||||
|
|
||||||
|
tinyspy@3.0.2: {}
|
||||||
|
|
||||||
to-regex-range@5.0.1:
|
to-regex-range@5.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-number: 7.0.0
|
is-number: 7.0.0
|
||||||
@@ -8200,6 +8409,24 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
vite: 5.4.21(@types/node@22.18.1)
|
vite: 5.4.21(@types/node@22.18.1)
|
||||||
|
|
||||||
|
vite-node@2.1.9(@types/node@22.18.1):
|
||||||
|
dependencies:
|
||||||
|
cac: 6.7.14
|
||||||
|
debug: 4.4.1
|
||||||
|
es-module-lexer: 1.7.0
|
||||||
|
pathe: 1.1.2
|
||||||
|
vite: 5.4.21(@types/node@22.18.1)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@types/node'
|
||||||
|
- less
|
||||||
|
- lightningcss
|
||||||
|
- sass
|
||||||
|
- sass-embedded
|
||||||
|
- stylus
|
||||||
|
- sugarss
|
||||||
|
- supports-color
|
||||||
|
- terser
|
||||||
|
|
||||||
vite-plugin-dts@4.5.4(@types/node@22.18.1)(rollup@4.50.1)(typescript@5.6.3)(vite@5.4.21(@types/node@22.18.1)):
|
vite-plugin-dts@4.5.4(@types/node@22.18.1)(rollup@4.50.1)(typescript@5.6.3)(vite@5.4.21(@types/node@22.18.1)):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@microsoft/api-extractor': 7.52.11(@types/node@22.18.1)
|
'@microsoft/api-extractor': 7.52.11(@types/node@22.18.1)
|
||||||
@@ -8291,6 +8518,41 @@ snapshots:
|
|||||||
'@types/node': 22.18.1
|
'@types/node': 22.18.1
|
||||||
fsevents: 2.3.3
|
fsevents: 2.3.3
|
||||||
|
|
||||||
|
vitest@2.1.9(@types/node@22.18.1):
|
||||||
|
dependencies:
|
||||||
|
'@vitest/expect': 2.1.9
|
||||||
|
'@vitest/mocker': 2.1.9(vite@5.4.21(@types/node@22.18.1))
|
||||||
|
'@vitest/pretty-format': 2.1.9
|
||||||
|
'@vitest/runner': 2.1.9
|
||||||
|
'@vitest/snapshot': 2.1.9
|
||||||
|
'@vitest/spy': 2.1.9
|
||||||
|
'@vitest/utils': 2.1.9
|
||||||
|
chai: 5.3.3
|
||||||
|
debug: 4.4.1
|
||||||
|
expect-type: 1.3.0
|
||||||
|
magic-string: 0.30.18
|
||||||
|
pathe: 1.1.2
|
||||||
|
std-env: 3.10.0
|
||||||
|
tinybench: 2.9.0
|
||||||
|
tinyexec: 0.3.2
|
||||||
|
tinypool: 1.1.1
|
||||||
|
tinyrainbow: 1.2.0
|
||||||
|
vite: 5.4.21(@types/node@22.18.1)
|
||||||
|
vite-node: 2.1.9(@types/node@22.18.1)
|
||||||
|
why-is-node-running: 2.3.0
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/node': 22.18.1
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- less
|
||||||
|
- lightningcss
|
||||||
|
- msw
|
||||||
|
- sass
|
||||||
|
- sass-embedded
|
||||||
|
- stylus
|
||||||
|
- sugarss
|
||||||
|
- supports-color
|
||||||
|
- terser
|
||||||
|
|
||||||
vscode-uri@3.1.0: {}
|
vscode-uri@3.1.0: {}
|
||||||
|
|
||||||
vue-chartjs@5.3.2(chart.js@4.5.0)(vue@3.5.21(typescript@5.6.3)):
|
vue-chartjs@5.3.2(chart.js@4.5.0)(vue@3.5.21(typescript@5.6.3)):
|
||||||
@@ -8360,6 +8622,11 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
isexe: 2.0.0
|
isexe: 2.0.0
|
||||||
|
|
||||||
|
why-is-node-running@2.3.0:
|
||||||
|
dependencies:
|
||||||
|
siginfo: 2.0.0
|
||||||
|
stackback: 0.0.2
|
||||||
|
|
||||||
word-wrap@1.2.5: {}
|
word-wrap@1.2.5: {}
|
||||||
|
|
||||||
wrap-ansi@7.0.0:
|
wrap-ansi@7.0.0:
|
||||||
|
|||||||
Reference in New Issue
Block a user