valaxy 0.28.0-beta.2 → 0.28.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/addons/index.ts +19 -0
- package/client/components/ClientOnly.ts +1 -1
- package/client/components/ValaxyDecrypt.vue +2 -1
- package/client/components/ValaxyFootnoteTooltip.vue +13 -2
- package/client/components/ValaxyGalleryDecrypt.vue +1 -1
- package/client/composables/features/medium-zoom.ts +51 -1
- package/client/define/client-component.ts +45 -0
- package/client/define/index.ts +1 -0
- package/client/utils/time.ts +6 -4
- package/dist/node/cli/index.mjs +1 -1
- package/dist/node/index.mjs +1 -1
- package/dist/shared/{valaxy.DXqMwOZX.mjs → valaxy.CAIbzGO-.mjs} +39 -29
- package/package.json +6 -6
package/client/addons/index.ts
CHANGED
|
@@ -6,6 +6,25 @@ export function isEmptyAddon(addon: any) {
|
|
|
6
6
|
return addon && addon.name === emptyAddonName
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* Cast a module namespace import to a plain type, breaking Rollup's
|
|
11
|
+
* static binding analysis on `import * as ns` namespace objects.
|
|
12
|
+
*
|
|
13
|
+
* The identity return is intentional — the cast alone is enough to
|
|
14
|
+
* suppress `IMPORT_IS_UNDEFINED` warnings when accessing addon-specific
|
|
15
|
+
* exports that don't exist in the empty addon fallback module.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import * as addonArtalk from 'valaxy-addon-artalk'
|
|
20
|
+
* const mod = getAddonModule<typeof import('valaxy-addon-artalk')>(addonArtalk)
|
|
21
|
+
* mod.useArtalkWithOptions?.()
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function getAddonModule<T = Record<string, any>>(addon: any): T {
|
|
25
|
+
return addon
|
|
26
|
+
}
|
|
27
|
+
|
|
9
28
|
export default {
|
|
10
29
|
name,
|
|
11
30
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
+
import { isClient } from '@vueuse/core'
|
|
2
3
|
import { runContentUpdated, useDecrypt, useFrontmatter } from 'valaxy'
|
|
3
4
|
import { computed, defineComponent, h, ref } from 'vue'
|
|
4
5
|
|
|
@@ -61,7 +62,7 @@ const ValaxyDeprecatedContent = defineComponent({
|
|
|
61
62
|
},
|
|
62
63
|
})
|
|
63
64
|
|
|
64
|
-
const hasWarning = computed(() => location.protocol !== 'https:')
|
|
65
|
+
const hasWarning = computed(() => isClient && location.protocol !== 'https:')
|
|
65
66
|
</script>
|
|
66
67
|
|
|
67
68
|
<template>
|
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { Tooltip } from 'floating-vue'
|
|
3
|
-
|
|
3
|
+
import { onMounted, ref } from 'vue'
|
|
4
|
+
|
|
5
|
+
// floating-vue Tooltip generates different DOM during SSR vs client hydration.
|
|
6
|
+
// Only mount the Tooltip after the component is mounted on the client to avoid mismatches.
|
|
7
|
+
// During SSR and initial client render, a plain <span> is shown instead.
|
|
8
|
+
const mounted = ref(false)
|
|
9
|
+
onMounted(() => {
|
|
10
|
+
mounted.value = true
|
|
11
|
+
})
|
|
4
12
|
</script>
|
|
5
13
|
|
|
6
14
|
<template>
|
|
7
|
-
<Tooltip class="inline-block" :distance="8">
|
|
15
|
+
<Tooltip v-if="mounted" class="inline-block" :distance="8">
|
|
8
16
|
<slot />
|
|
9
17
|
|
|
10
18
|
<template #popper>
|
|
11
19
|
<slot name="popper" />
|
|
12
20
|
</template>
|
|
13
21
|
</Tooltip>
|
|
22
|
+
<span v-else class="inline-block">
|
|
23
|
+
<slot />
|
|
24
|
+
</span>
|
|
14
25
|
</template>
|
|
@@ -11,13 +11,63 @@ export function useMediumZoom() {
|
|
|
11
11
|
|
|
12
12
|
if (mediumZoomConfig.enable) {
|
|
13
13
|
onMounted(() => {
|
|
14
|
-
mediumZoom(
|
|
14
|
+
const zoom = mediumZoom(
|
|
15
15
|
mediumZoomConfig.selector || '.markdown-body img',
|
|
16
16
|
{
|
|
17
17
|
background: 'var(--medium-zoom-c-bg, rgba(0, 0, 0, 0.8))',
|
|
18
18
|
...mediumZoomConfig.options,
|
|
19
19
|
},
|
|
20
20
|
)
|
|
21
|
+
|
|
22
|
+
// Fix blurry images after zoom animation completes.
|
|
23
|
+
// medium-zoom uses CSS transform: scale() which causes browsers (especially
|
|
24
|
+
// Chrome) to render scaled images at lower quality.
|
|
25
|
+
// After the open animation, we replace the transform with actual dimensions
|
|
26
|
+
// to force full-resolution rendering. Before closing, we restore the original
|
|
27
|
+
// transform so the close animation works correctly.
|
|
28
|
+
// @see https://github.com/francoischalifour/medium-zoom/issues/151
|
|
29
|
+
let savedStyles: { transform: string, width: string, height: string } | null = null
|
|
30
|
+
|
|
31
|
+
zoom.on('opened', () => {
|
|
32
|
+
const zoomed = document.querySelector('.medium-zoom-image--opened') as HTMLElement | null
|
|
33
|
+
if (!zoomed)
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
const { transform } = zoomed.style
|
|
37
|
+
const scaleMatch = transform.match(/scale\(([^)]+)\)/)
|
|
38
|
+
if (!scaleMatch)
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
const scale = Number.parseFloat(scaleMatch[1])
|
|
42
|
+
if (!scale || scale === 1)
|
|
43
|
+
return
|
|
44
|
+
|
|
45
|
+
savedStyles = {
|
|
46
|
+
transform,
|
|
47
|
+
width: zoomed.style.width,
|
|
48
|
+
height: zoomed.style.height,
|
|
49
|
+
}
|
|
50
|
+
const rect = zoomed.getBoundingClientRect()
|
|
51
|
+
|
|
52
|
+
// Replace scale transform with actual width/height
|
|
53
|
+
zoomed.style.transform = transform.replace(/scale\([^)]+\)/, 'scale(1)')
|
|
54
|
+
zoomed.style.width = `${rect.width}px`
|
|
55
|
+
zoomed.style.height = `${rect.height}px`
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
zoom.on('close', () => {
|
|
59
|
+
if (!savedStyles)
|
|
60
|
+
return
|
|
61
|
+
|
|
62
|
+
const zoomed = document.querySelector('.medium-zoom-image--opened') as HTMLElement | null
|
|
63
|
+
if (zoomed) {
|
|
64
|
+
// Restore original styles for close animation
|
|
65
|
+
zoomed.style.transform = savedStyles.transform
|
|
66
|
+
zoomed.style.width = savedStyles.width
|
|
67
|
+
zoomed.style.height = savedStyles.height
|
|
68
|
+
}
|
|
69
|
+
savedStyles = null
|
|
70
|
+
})
|
|
21
71
|
})
|
|
22
72
|
}
|
|
23
73
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { Component } from 'vue'
|
|
2
|
+
import { defineAsyncComponent, defineComponent, h, onMounted, ref } from 'vue'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Define a component that only renders on the client side.
|
|
6
|
+
*
|
|
7
|
+
* Useful for wrapping browser-only third-party libraries that access
|
|
8
|
+
* `window`, `document`, or other browser APIs not available during SSR/SSG.
|
|
9
|
+
*
|
|
10
|
+
* @param loader - Dynamic import function, e.g. `() => import('some-lib')`
|
|
11
|
+
* @param args - Optional tuple of `[props, children]` to pass to the component
|
|
12
|
+
* @param cb - Optional callback invoked with the resolved component module
|
|
13
|
+
*/
|
|
14
|
+
export function defineClientComponent(
|
|
15
|
+
loader: () => Promise<Component | { default: Component }>,
|
|
16
|
+
args?: [Record<string, any>?, (Record<string, any> | (() => any))?],
|
|
17
|
+
cb?: (component: any) => void,
|
|
18
|
+
) {
|
|
19
|
+
const [props, children] = args ?? []
|
|
20
|
+
|
|
21
|
+
const AsyncComp = defineAsyncComponent(async () => {
|
|
22
|
+
const comp = await loader()
|
|
23
|
+
if (cb)
|
|
24
|
+
cb(comp)
|
|
25
|
+
return comp
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
return defineComponent({
|
|
29
|
+
name: 'ValaxyClientComponent',
|
|
30
|
+
setup(_, { slots }) {
|
|
31
|
+
const show = ref(false)
|
|
32
|
+
onMounted(() => {
|
|
33
|
+
show.value = true
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
return () => {
|
|
37
|
+
if (!show.value)
|
|
38
|
+
return slots.fallback?.() ?? null
|
|
39
|
+
|
|
40
|
+
const childContent = typeof children === 'function' ? children() : children
|
|
41
|
+
return h(AsyncComp, props, childContent)
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
})
|
|
45
|
+
}
|
package/client/define/index.ts
CHANGED
package/client/utils/time.ts
CHANGED
|
@@ -48,9 +48,11 @@ export function orderByMeta(posts: Post[], orderBy: 'date' | 'updated' = 'date',
|
|
|
48
48
|
return posts.sort((a, b) => {
|
|
49
49
|
const aDate = +new Date(a[orderBy] || a.date || '')
|
|
50
50
|
const bDate = +new Date(b[orderBy] || b.date || '')
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
const diff = desc ? bDate - aDate : aDate - bDate
|
|
52
|
+
// Stable sort: when dates are equal, use path as tie-breaker
|
|
53
|
+
// to ensure consistent order between SSR and client hydration
|
|
54
|
+
if (diff !== 0)
|
|
55
|
+
return diff
|
|
56
|
+
return (a.path || '') < (b.path || '') ? -1 : (a.path || '') > (b.path || '') ? 1 : 0
|
|
55
57
|
})
|
|
56
58
|
}
|
package/dist/node/cli/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import 'node:process';
|
|
2
2
|
import 'yargs';
|
|
3
3
|
import 'yargs/helpers';
|
|
4
|
-
export { c as cli, I as registerDevCommand, W as run, Z as startValaxyDev } from '../../shared/valaxy.
|
|
4
|
+
export { c as cli, I as registerDevCommand, W as run, Z as startValaxyDev } from '../../shared/valaxy.CAIbzGO-.mjs';
|
|
5
5
|
import 'node:os';
|
|
6
6
|
import 'node:path';
|
|
7
7
|
import 'consola';
|
package/dist/node/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { A as ALL_ROUTE, E as EXCERPT_SEPARATOR, G as GLOBAL_STATE, P as PATHNAME_PROTOCOL_RE, V as ViteValaxyPlugins, b as build, c as cli, a as createServer, d as createValaxyPlugin, e as customElements, f as defaultSiteConfig, g as defaultValaxyConfig, h as defaultViteConfig, i as defineAddon, j as defineConfig, k as defineSiteConfig, l as defineTheme, m as defineValaxyAddon, n as defineValaxyConfig, o as defineValaxyTheme, p as encryptContent, q as generateClientRedirects, r as getGitTimestamp, s as getIndexHtml, t as getServerInfoText, u as isExternal, v as isInstalledGlobally, w as isKatexEnabled, x as isKatexPluginNeeded, y as isMathJaxEnabled, z as isPath, B as loadConfigFromFile, C as mergeValaxyConfig, D as mergeViteConfigs, F as postProcessForSSG, H as processValaxyOptions, I as registerDevCommand, J as resolveAddonsConfig, K as resolveImportPath, L as resolveImportUrl, M as resolveOptions, N as resolveSiteConfig, O as resolveSiteConfigFromRoot, Q as resolveThemeConfigFromRoot, R as resolveThemeValaxyConfig, S as resolveUserThemeConfig, T as resolveValaxyConfig, U as resolveValaxyConfigFromRoot, W as run, X as ssgBuild, Y as ssgBuildLegacy, Z as startValaxyDev, _ as toAtFS, $ as transformObject, a0 as version } from '../shared/valaxy.
|
|
1
|
+
export { A as ALL_ROUTE, E as EXCERPT_SEPARATOR, G as GLOBAL_STATE, P as PATHNAME_PROTOCOL_RE, V as ViteValaxyPlugins, b as build, c as cli, a as createServer, d as createValaxyPlugin, e as customElements, f as defaultSiteConfig, g as defaultValaxyConfig, h as defaultViteConfig, i as defineAddon, j as defineConfig, k as defineSiteConfig, l as defineTheme, m as defineValaxyAddon, n as defineValaxyConfig, o as defineValaxyTheme, p as encryptContent, q as generateClientRedirects, r as getGitTimestamp, s as getIndexHtml, t as getServerInfoText, u as isExternal, v as isInstalledGlobally, w as isKatexEnabled, x as isKatexPluginNeeded, y as isMathJaxEnabled, z as isPath, B as loadConfigFromFile, C as mergeValaxyConfig, D as mergeViteConfigs, F as postProcessForSSG, H as processValaxyOptions, I as registerDevCommand, J as resolveAddonsConfig, K as resolveImportPath, L as resolveImportUrl, M as resolveOptions, N as resolveSiteConfig, O as resolveSiteConfigFromRoot, Q as resolveThemeConfigFromRoot, R as resolveThemeValaxyConfig, S as resolveUserThemeConfig, T as resolveValaxyConfig, U as resolveValaxyConfigFromRoot, W as run, X as ssgBuild, Y as ssgBuildLegacy, Z as startValaxyDev, _ as toAtFS, $ as transformObject, a0 as version } from '../shared/valaxy.CAIbzGO-.mjs';
|
|
2
2
|
import 'node:path';
|
|
3
3
|
import 'fs-extra';
|
|
4
4
|
import 'consola/utils';
|
|
@@ -1675,7 +1675,7 @@ async function setupMarkdownPlugins(md, options, base = "/") {
|
|
|
1675
1675
|
return md;
|
|
1676
1676
|
}
|
|
1677
1677
|
|
|
1678
|
-
const version = "0.28.0-beta.
|
|
1678
|
+
const version = "0.28.0-beta.4";
|
|
1679
1679
|
|
|
1680
1680
|
const GLOBAL_STATE = {
|
|
1681
1681
|
valaxyApp: void 0,
|
|
@@ -2363,7 +2363,8 @@ function createConfigPlugin(options) {
|
|
|
2363
2363
|
function getDefine(_options) {
|
|
2364
2364
|
return {
|
|
2365
2365
|
__VUE_PROD_DEVTOOLS__: false,
|
|
2366
|
-
__INTLIFY_PROD_DEVTOOLS__: false
|
|
2366
|
+
__INTLIFY_PROD_DEVTOOLS__: false,
|
|
2367
|
+
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false
|
|
2367
2368
|
};
|
|
2368
2369
|
}
|
|
2369
2370
|
async function getAlias(options) {
|
|
@@ -3543,11 +3544,19 @@ async function createUnocssPlugin(options) {
|
|
|
3543
3544
|
);
|
|
3544
3545
|
let config = {};
|
|
3545
3546
|
const configDeps = [];
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3547
|
+
const loadResults = await Promise.all(
|
|
3548
|
+
configFiles.map(async (configFile) => {
|
|
3549
|
+
if (await fs.exists(configFile)) {
|
|
3550
|
+
const uConfig = await jiti.import(configFile, { default: true });
|
|
3551
|
+
return { configFile, uConfig };
|
|
3552
|
+
}
|
|
3553
|
+
return null;
|
|
3554
|
+
})
|
|
3555
|
+
);
|
|
3556
|
+
for (const result of loadResults) {
|
|
3557
|
+
if (result) {
|
|
3558
|
+
config = defu(config, result.uConfig);
|
|
3559
|
+
configDeps.push(result.configFile);
|
|
3551
3560
|
}
|
|
3552
3561
|
}
|
|
3553
3562
|
config = await loadSetups(roots, "unocss.ts", {}, config, true);
|
|
@@ -3564,15 +3573,22 @@ function defineValaxyAddon(addonFunc) {
|
|
|
3564
3573
|
const defineAddon = defineValaxyAddon;
|
|
3565
3574
|
async function resolveAddonsConfig(addons, options) {
|
|
3566
3575
|
let valaxyConfig = {};
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
3571
|
-
|
|
3572
|
-
|
|
3576
|
+
const results = await Promise.all(
|
|
3577
|
+
addons.map(async (addon) => {
|
|
3578
|
+
const addonConfigPath = path$1.resolve(addon.root, "valaxy.config.ts");
|
|
3579
|
+
if (!await fs.exists(addonConfigPath))
|
|
3580
|
+
return null;
|
|
3581
|
+
const { config, configFile } = await resolveValaxyConfigFromRoot(addon.root, options);
|
|
3582
|
+
if (!config)
|
|
3583
|
+
return null;
|
|
3584
|
+
return { addon, config, configFile };
|
|
3585
|
+
})
|
|
3586
|
+
);
|
|
3587
|
+
for (const result of results) {
|
|
3588
|
+
if (!result)
|
|
3573
3589
|
continue;
|
|
3574
|
-
addon.configFile = configFile;
|
|
3575
|
-
valaxyConfig = mergeValaxyConfig(config, valaxyConfig);
|
|
3590
|
+
result.addon.configFile = result.configFile;
|
|
3591
|
+
valaxyConfig = mergeValaxyConfig(result.config, valaxyConfig);
|
|
3576
3592
|
}
|
|
3577
3593
|
return valaxyConfig;
|
|
3578
3594
|
}
|
|
@@ -4280,7 +4296,7 @@ async function createRouterPlugin(valaxyApp) {
|
|
|
4280
4296
|
}
|
|
4281
4297
|
const path = route.components.get("default") || "";
|
|
4282
4298
|
if (path.endsWith(".md")) {
|
|
4283
|
-
const md = fs.
|
|
4299
|
+
const md = await fs.readFile(path, "utf-8");
|
|
4284
4300
|
const { data, excerpt, content } = matter(md, matterOptions);
|
|
4285
4301
|
const mdFm = data;
|
|
4286
4302
|
const lastUpdated = options.config.siteConfig.lastUpdated;
|
|
@@ -4432,6 +4448,13 @@ async function ViteValaxyPlugins(valaxyApp, serverOptions = {}) {
|
|
|
4432
4448
|
// https://github.com/loicduong/vite-plugin-vue-layouts-next
|
|
4433
4449
|
Layouts({
|
|
4434
4450
|
layoutsDirs: roots.map((root) => `${root}/layouts`),
|
|
4451
|
+
// In SSG builds, layout components must be imported synchronously so that
|
|
4452
|
+
// the client-side hydration tree matches the server-rendered HTML. Without
|
|
4453
|
+
// this, non-default layouts (post, home, etc.) are lazy-loaded and haven't
|
|
4454
|
+
// resolved when hydration starts, causing a mismatch. The old vite-ssg
|
|
4455
|
+
// library handled this by setting VITE_SSG=true; the built-in SSG engine
|
|
4456
|
+
// needs an explicit importMode override instead.
|
|
4457
|
+
...options.mode === "build" ? { importMode: () => "sync" } : {},
|
|
4435
4458
|
...valaxyConfig.layouts
|
|
4436
4459
|
}),
|
|
4437
4460
|
// https://github.com/antfu/unplugin-vue-components
|
|
@@ -5636,19 +5659,6 @@ async function initServer(valaxyApp, viteConfig) {
|
|
|
5636
5659
|
process.exit(1);
|
|
5637
5660
|
}
|
|
5638
5661
|
}
|
|
5639
|
-
if (import.meta.hot) {
|
|
5640
|
-
await import.meta.hot.data.stopping;
|
|
5641
|
-
let reload = async () => {
|
|
5642
|
-
consola.info("HMR: Stop Server");
|
|
5643
|
-
await GLOBAL_STATE.server?.close();
|
|
5644
|
-
};
|
|
5645
|
-
import.meta.hot.on("vite:beforeFullReload", () => {
|
|
5646
|
-
const stopping = reload();
|
|
5647
|
-
reload = () => Promise.resolve();
|
|
5648
|
-
if (import.meta.hot)
|
|
5649
|
-
import.meta.hot.data.stopping = stopping;
|
|
5650
|
-
});
|
|
5651
|
-
}
|
|
5652
5662
|
|
|
5653
5663
|
async function execBuild({ ssg, ssgEngine, root, output, log }) {
|
|
5654
5664
|
setEnvProd();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "valaxy",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.28.0-beta.
|
|
4
|
+
"version": "0.28.0-beta.4",
|
|
5
5
|
"description": "📄 Vite & Vue powered static blog generator.",
|
|
6
6
|
"author": {
|
|
7
7
|
"email": "me@yunyoujun.cn",
|
|
@@ -90,13 +90,13 @@
|
|
|
90
90
|
"fs-extra": "^11.3.4",
|
|
91
91
|
"fuse.js": "^7.1.0",
|
|
92
92
|
"gray-matter": "^4.0.3",
|
|
93
|
-
"hookable": "^6.0
|
|
93
|
+
"hookable": "^6.1.0",
|
|
94
94
|
"html-to-text": "^9.0.5",
|
|
95
95
|
"jiti": "^2.6.1",
|
|
96
96
|
"js-base64": "^3.7.8",
|
|
97
97
|
"js-yaml": "^4.1.1",
|
|
98
98
|
"katex": "^0.16.38",
|
|
99
|
-
"lru-cache": "^11.2.
|
|
99
|
+
"lru-cache": "^11.2.7",
|
|
100
100
|
"markdown-it": "^14.1.1",
|
|
101
101
|
"markdown-it-anchor": "^9.2.0",
|
|
102
102
|
"markdown-it-async": "^2.2.0",
|
|
@@ -140,8 +140,8 @@
|
|
|
140
140
|
"vue-i18n": "^11.3.0",
|
|
141
141
|
"vue-router": "^5.0.3",
|
|
142
142
|
"yargs": "^18.0.0",
|
|
143
|
-
"@valaxyjs/devtools": "0.28.0-beta.
|
|
144
|
-
"@valaxyjs/utils": "0.28.0-beta.
|
|
143
|
+
"@valaxyjs/devtools": "0.28.0-beta.4",
|
|
144
|
+
"@valaxyjs/utils": "0.28.0-beta.4"
|
|
145
145
|
},
|
|
146
146
|
"devDependencies": {
|
|
147
147
|
"@mdit-vue/plugin-component": "^3.0.2",
|
|
@@ -164,7 +164,7 @@
|
|
|
164
164
|
"@types/yargs": "^17.0.35",
|
|
165
165
|
"gh-pages": "^6.3.0",
|
|
166
166
|
"https-localhost": "^4.7.1",
|
|
167
|
-
"nanoid": "^5.1.
|
|
167
|
+
"nanoid": "^5.1.7",
|
|
168
168
|
"rollup-plugin-visualizer": "^7.0.1",
|
|
169
169
|
"unbuild": "^3.6.1"
|
|
170
170
|
},
|