diff --git a/packages/auto-catalog/rollup.config.ts b/packages/auto-catalog/rollup.config.ts index 9fbc1ee8b0b1..d9cf5ece9973 100644 --- a/packages/auto-catalog/rollup.config.ts +++ b/packages/auto-catalog/rollup.config.ts @@ -7,6 +7,7 @@ export default [ "@vuepress/shared", "@vuepress/utils", "vuepress-shared/node", + "vuepress-plugin-components", "vuepress-plugin-sass-palette", ], }), diff --git a/packages/blog2/src/node/category.ts b/packages/blog2/src/node/category.ts index ea55fadf3d35..bf4ad86f7fa5 100644 --- a/packages/blog2/src/node/category.ts +++ b/packages/blog2/src/node/category.ts @@ -1,5 +1,5 @@ import { createPage } from "@vuepress/core"; -import { removeLeadingSlash } from "@vuepress/shared"; +import { isFunction, isString, removeLeadingSlash } from "@vuepress/shared"; import { logger } from "./utils.js"; import type { App, Page } from "@vuepress/core"; @@ -52,13 +52,13 @@ export const prepareCategory = ( }, index ) => { - if (typeof key !== "string" || !key) { + if (!isString(key) || !key) { logger.error(`Invalid 'key' option ${key} in 'category[${index}]'`); return null; } - if (typeof getter !== "function") { + if (!isFunction(getter)) { logger.error( `Invalid 'getter' option in 'category[${index}]', it should be a function!` ); @@ -70,13 +70,12 @@ export const prepareCategory = ( const categoryMap: CategoryMap = {}; const pageKeys: string[] = []; - const getItemPath = - typeof itemPath === "function" - ? itemPath - : (name: string): string => - (itemPath || "") - .replace(/:key/g, slugify(key)) - .replace(/:name/g, slugify(name)); + const getItemPath = isFunction(itemPath) + ? itemPath + : (name: string): string => + (itemPath || "") + .replace(/:key/g, slugify(key)) + .replace(/:name/g, slugify(name)); for (const localePath in pageMap) { if (path) { diff --git a/packages/blog2/src/node/type.ts b/packages/blog2/src/node/type.ts index c1c118a51327..af274ad0b627 100644 --- a/packages/blog2/src/node/type.ts +++ b/packages/blog2/src/node/type.ts @@ -1,5 +1,5 @@ import { createPage } from "@vuepress/core"; -import { removeLeadingSlash } from "@vuepress/shared"; +import { isString, removeLeadingSlash } from "@vuepress/shared"; import { logger } from "./utils.js"; import type { App } from "@vuepress/core"; @@ -48,7 +48,7 @@ export const prepareType = ( }, index ) => { - if (typeof key !== "string" || !key) { + if (!isString(key) || !key) { logger.error(`Invalid 'key' option ${key} in 'category[${index}]'`); return null; diff --git a/packages/components/rollup.config.ts b/packages/components/rollup.config.ts index 52083db02fb7..2df03ee4b74d 100644 --- a/packages/components/rollup.config.ts +++ b/packages/components/rollup.config.ts @@ -27,7 +27,13 @@ export default [ dtsExternal: [/\.scss$/], }), ...rollupTypescript("client/components/BiliBili", { - external: ["@vueuse/core", "vue", "vuepress-shared/client", /\.scss$/], + external: [ + "@vueuse/core", + "@vuepress/shared", + "vue", + "vuepress-shared/client", + /\.scss$/, + ], dtsExternal: [/\.scss$/], }), ...rollupTypescript("client/components/BackToTop", { @@ -74,11 +80,17 @@ export default [ dtsExternal: [/\.scss$/], }), ...rollupTypescript("client/components/StackBlitz", { - external: ["@vueuse/core", "vue", /\.scss$/], + external: ["@vueuse/core", "@vuepress/shared", "vue", /\.scss$/], dtsExternal: [/\.scss$/], }), ...rollupTypescript("client/components/YouTube", { - external: ["@vueuse/core", "@vuepress/client", "vue", /\.scss$/], + external: [ + "@vueuse/core", + "@vuepress/shared", + "@vuepress/client", + "vue", + /\.scss$/, + ], dtsExternal: [/\.scss$/], }), ...rollupTypescript("client/components/VideoPlayer", { diff --git a/packages/components/src/client/composables/size.ts b/packages/components/src/client/composables/size.ts index 1f88106befe3..a191d7d7ee73 100644 --- a/packages/components/src/client/composables/size.ts +++ b/packages/components/src/client/composables/size.ts @@ -1,10 +1,12 @@ +import { isString } from "@vuepress/shared"; import { useEventListener } from "@vueuse/core"; import { computed, onMounted, isRef, ref, unref, watch } from "vue"; + import type { MaybeRef } from "@vueuse/core"; import type { Ref } from "vue"; const getValue = (value: string | number): string => - typeof value === "string" ? value : `${value}px`; + isString(value) ? value : `${value}px`; export interface SizeOptions { width: string | number | undefined; @@ -27,7 +29,7 @@ export const useSize = ( const height = ref("auto"); const getRadio = (radio: number | string | undefined): number => { - if (typeof radio === "string") { + if (isString(radio)) { const [width, height] = radio.split(":"); const parsedRadio = Number(width) / Number(height); diff --git a/packages/components/src/client/utils/pdf.ts b/packages/components/src/client/utils/pdf.ts index c9d01c1919ca..0f5672351743 100644 --- a/packages/components/src/client/utils/pdf.ts +++ b/packages/components/src/client/utils/pdf.ts @@ -1,7 +1,3 @@ -import { withBase } from "@vuepress/client"; -import { ensureEndingSlash } from "@vuepress/shared"; -import { checkIsMobile, checkIsSafari } from "vuepress-shared/client"; - /** * Fork and edited from https://github.com/pipwerks/PDFObject/blob/master/pdfobject.js * @@ -16,6 +12,10 @@ import { checkIsMobile, checkIsSafari } from "vuepress-shared/client"; * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +import { withBase } from "@vuepress/client"; +import { ensureEndingSlash, isString } from "@vuepress/shared"; +import { checkIsMobile, checkIsSafari } from "vuepress-shared/client"; + declare const PDFJS_URL: string | null; export interface ViewPDFOptions { @@ -164,7 +164,7 @@ export const viewPDF = ( // Modern versions of Firefox come bundled with PDFJS isFirefoxWithPDFJS); - if (typeof url !== "string") { + if (!isString(url)) { logError("URL is not valid"); return null; diff --git a/packages/components/src/node/define.ts b/packages/components/src/node/define.ts index 78f157de73e6..e8bdfb17f839 100644 --- a/packages/components/src/node/define.ts +++ b/packages/components/src/node/define.ts @@ -1,3 +1,4 @@ +import { isString } from "@vuepress/shared"; import { getLocales } from "vuepress-shared/node"; import { backToTopLocales, @@ -24,8 +25,7 @@ export const getDefine = }); if (options.components?.includes("FontIcon")) - result["ICON_PREFIX"] = - typeof prefix === "string" ? prefix : getIconPrefix(assets); + result["ICON_PREFIX"] = isString(prefix) ? prefix : getIconPrefix(assets); if (options.components?.includes("PDF")) { result["PDF_LOCALES"] = getLocales({ diff --git a/packages/components/src/node/prepare.ts b/packages/components/src/node/prepare.ts index 63284d7ec3e0..f4fea419a972 100644 --- a/packages/components/src/node/prepare.ts +++ b/packages/components/src/node/prepare.ts @@ -1,3 +1,4 @@ +import { isPlainObject, isString } from "@vuepress/shared"; import { CLIENT_FOLDER, logger } from "./utils.js"; import type { App } from "@vuepress/core"; @@ -101,7 +102,7 @@ useStyleTag(\`${content}\`, { id: "icon-assets" }); } }); - if (typeof rootComponents.addThis === "string") { + if (isString(rootComponents.addThis)) { shouldImportUseScriptTag = true; setup += `\ useScriptTag(\`//s7.addthis.com/js/300/addthis_widget.js#pubid=${rootComponents.addThis}\`); @@ -122,7 +123,7 @@ import BackToTop from "${CLIENT_FOLDER}components/BackToTop.js"; `; } - if (typeof rootComponents.notice === "object") { + if (isPlainObject(rootComponents.notice)) { shouldImportH = true; configImport += `\ import Notice from "${CLIENT_FOLDER}components/Notice.js"; diff --git a/packages/copy-code2/package.json b/packages/copy-code2/package.json index 38be93c0af7e..afeb4d7d8c05 100644 --- a/packages/copy-code2/package.json +++ b/packages/copy-code2/package.json @@ -50,6 +50,7 @@ }, "dependencies": { "@vuepress/client": "2.0.0-beta.60", + "@vuepress/shared": "2.0.0-beta.60", "@vuepress/utils": "2.0.0-beta.60", "balloon-css": "^1.2.0", "vue": "^3.2.45", diff --git a/packages/copy-code2/rollup.config.ts b/packages/copy-code2/rollup.config.ts index f70b5b3f08a1..9696f62a4c38 100644 --- a/packages/copy-code2/rollup.config.ts +++ b/packages/copy-code2/rollup.config.ts @@ -14,6 +14,7 @@ export default [ ...rollupTypescript("client/config", { external: [ "@vuepress/client", + "@vuepress/shared", "balloon-css/balloon.css", "vue", "vue-router", diff --git a/packages/copy-code2/src/client/composables/setup.ts b/packages/copy-code2/src/client/composables/setup.ts index 583b2be58e4e..53a719d54ed9 100644 --- a/packages/copy-code2/src/client/composables/setup.ts +++ b/packages/copy-code2/src/client/composables/setup.ts @@ -25,6 +25,7 @@ * © 2019 GitHub, Inc. */ +import { isArray, isString } from "@vuepress/shared"; import { onMounted, watch } from "vue"; import { useRoute } from "vue-router"; import { Message, useLocaleConfig } from "vuepress-shared/client"; @@ -79,11 +80,11 @@ export const setupCopyCode = (): void => { const generateCopyButton = (): void => { setTimeout(() => { - if (typeof copyCodeSelector === "string") + if (isString(copyCodeSelector)) document .querySelectorAll(copyCodeSelector) .forEach(insertCopyButton); - else if (Array.isArray(copyCodeSelector)) + else if (isArray(copyCodeSelector)) copyCodeSelector.forEach((item) => { document .querySelectorAll(item) diff --git a/packages/copyright2/rollup.config.ts b/packages/copyright2/rollup.config.ts index 96046c70d4b1..eda241656d63 100644 --- a/packages/copyright2/rollup.config.ts +++ b/packages/copyright2/rollup.config.ts @@ -2,7 +2,12 @@ import { rollupTypescript } from "../../scripts/rollup.js"; export default [ ...rollupTypescript("node/index", { - external: ["@vuepress/core", "@vuepress/utils", "vuepress-shared/node"], + external: [ + "@vuepress/core", + "@vuepress/shared", + "@vuepress/utils", + "vuepress-shared/node", + ], dtsExternal: ["vuepress-shared"], }), ...rollupTypescript("client/config", { diff --git a/packages/copyright2/src/client/composables/setup.ts b/packages/copyright2/src/client/composables/setup.ts index 4c3cf91d671a..7d73f0a9b59e 100644 --- a/packages/copyright2/src/client/composables/setup.ts +++ b/packages/copyright2/src/client/composables/setup.ts @@ -1,5 +1,5 @@ import { usePageFrontmatter, usePageData } from "@vuepress/client"; -import { isLinkHttp, removeEndingSlash } from "@vuepress/shared"; +import { isLinkHttp, isPlainObject, removeEndingSlash } from "@vuepress/shared"; import { useEventListener } from "@vueuse/core"; import { computed, onMounted, watchEffect } from "vue"; import { useRoute } from "vue-router"; @@ -39,7 +39,7 @@ export const setupCopyright = (): void => { if (!enabled.value) return false; if ( - typeof frontmatterOptions === "object" && + isPlainObject(frontmatterOptions) && "disableCopy" in frontmatterOptions ) return frontmatterOptions.disableCopy; @@ -53,7 +53,7 @@ export const setupCopyright = (): void => { if (!enabled.value) return false; if ( - typeof frontmatterOptions === "object" && + isPlainObject(frontmatterOptions) && "disableSelection" in frontmatterOptions ) return frontmatterOptions.disableSelection; diff --git a/packages/copyright2/src/node/plugins.ts b/packages/copyright2/src/node/plugins.ts index c831be987af1..3e6a74e06052 100644 --- a/packages/copyright2/src/node/plugins.ts +++ b/packages/copyright2/src/node/plugins.ts @@ -1,3 +1,4 @@ +import { isFunction } from "@vuepress/shared"; import { getDirname, path } from "@vuepress/utils"; import { getLocales } from "vuepress-shared/node"; @@ -45,10 +46,9 @@ export const copyrightPlugin = }), extendsPage: (page: Page>): void => { - const authorText = typeof author === "function" ? author(page) : author; + const authorText = isFunction(author) ? author(page) : author; - const licenseText = - typeof license === "function" ? license(page) : license; + const licenseText = isFunction(license) ? license(page) : license; page.data.copyright = { ...(authorText ? { author: authorText } : {}), diff --git a/packages/feed2/src/node/json/index.ts b/packages/feed2/src/node/json/index.ts index abf04f155218..d7fc65a35c92 100644 --- a/packages/feed2/src/node/json/index.ts +++ b/packages/feed2/src/node/json/index.ts @@ -1,4 +1,5 @@ /* eslint-disable @typescript-eslint/naming-convention */ +import { isArray } from "@vuepress/shared"; import { stripTags } from "vuepress-shared/node"; import type { Feed } from "../feed.js"; @@ -65,7 +66,7 @@ export const renderJSON = (feed: Feed): string => { feedItem.date_modified = item.lastUpdated.toISOString(); // author - if (Array.isArray(item.author)) + if (isArray(item.author)) feedItem.authors = item.author .filter((author) => author.name) .map((author) => formatAuthor(author)); diff --git a/packages/feed2/src/node/page.ts b/packages/feed2/src/node/page.ts index c0704f019056..7d10b1026e23 100644 --- a/packages/feed2/src/node/page.ts +++ b/packages/feed2/src/node/page.ts @@ -1,3 +1,4 @@ +import { isArray, isFunction, isPlainObject } from "@vuepress/shared"; import { getAuthor, getCategory, @@ -46,22 +47,20 @@ export class FeedPage { } get title(): string { - if (typeof this.getter.title === "function") - return this.getter.title(this.page); + if (isFunction(this.getter.title)) return this.getter.title(this.page); return this.pageFeedOptions.title || this.page.title; } /** real url */ get link(): string { - if (typeof this.getter.link === "function") - return this.getter.link(this.page); + if (isFunction(this.getter.link)) return this.getter.link(this.page); return resolveUrl(this.options.hostname, this.base, this.page.path); } get description(): string | null { - if (typeof this.getter.description === "function") + if (isFunction(this.getter.description)) return this.getter.description(this.page); if (this.pageFeedOptions.description) @@ -75,13 +74,12 @@ export class FeedPage { } get author(): FeedAuthor[] { - if (typeof this.getter.author === "function") - return this.getter.author(this.page); + if (isFunction(this.getter.author)) return this.getter.author(this.page); - if (Array.isArray(this.pageFeedOptions.author)) + if (isArray(this.pageFeedOptions.author)) return this.pageFeedOptions.author; - if (typeof this.pageFeedOptions.author === "object") + if (isPlainObject(this.pageFeedOptions.author)) return [this.pageFeedOptions.author]; return this.frontmatter.author === false @@ -94,13 +92,13 @@ export class FeedPage { } get category(): FeedCategory[] | null { - if (typeof this.getter.category === "function") + if (isFunction(this.getter.category)) return this.getter.category(this.page); - if (Array.isArray(this.pageFeedOptions.category)) + if (isArray(this.pageFeedOptions.category)) return this.pageFeedOptions.category; - if (typeof this.pageFeedOptions.category === "object") + if (isPlainObject(this.pageFeedOptions.category)) return [this.pageFeedOptions.category]; const { categories, category = categories } = this.frontmatter; @@ -109,7 +107,7 @@ export class FeedPage { } get enclosure(): FeedEnclosure | null { - if (typeof this.getter.enclosure === "function") + if (isFunction(this.getter.enclosure)) return this.getter.enclosure(this.page); if (this.image) @@ -126,7 +124,7 @@ export class FeedPage { } get pubDate(): Date | null { - if (typeof this.getter.publishDate === "function") + if (isFunction(this.getter.publishDate)) return this.getter.publishDate(this.page); const { time, date = time } = this.page.frontmatter; @@ -141,7 +139,7 @@ export class FeedPage { } get lastUpdated(): Date { - if (typeof this.getter.lastUpdateDate === "function") + if (isFunction(this.getter.lastUpdateDate)) return this.getter.lastUpdateDate(this.page); const { updatedTime } = this.page.data.git || {}; @@ -150,8 +148,7 @@ export class FeedPage { } get content(): string { - if (typeof this.getter.content === "function") - return this.getter.content(this.page); + if (isFunction(this.getter.content)) return this.getter.content(this.page); if (this.pageFeedOptions.content) return this.pageFeedOptions.content; @@ -159,8 +156,7 @@ export class FeedPage { } get image(): string | null { - if (typeof this.getter.image === "function") - return this.getter.image(this.page); + if (isFunction(this.getter.image)) return this.getter.image(this.page); const { banner, cover } = this.frontmatter; @@ -195,20 +191,20 @@ export class FeedPage { } get contributor(): FeedContributor[] { - if (typeof this.getter.contributor === "function") + if (isFunction(this.getter.contributor)) return this.getter.contributor(this.page); - if (Array.isArray(this.pageFeedOptions.contributor)) + if (isArray(this.pageFeedOptions.contributor)) return this.pageFeedOptions.contributor; - if (typeof this.pageFeedOptions.contributor === "object") + if (isPlainObject(this.pageFeedOptions.contributor)) return [this.pageFeedOptions.contributor]; return this.author; } get copyright(): string | null { - if (typeof this.getter.copyright === "function") + if (isFunction(this.getter.copyright)) return this.getter.copyright(this.page); if (this.frontmatter.copyright) return this.frontmatter.copyright; diff --git a/packages/md-enhance/src/node/markdown-it/playground/ts.ts b/packages/md-enhance/src/node/markdown-it/playground/ts.ts index bade85ed14d3..227a939fbafd 100644 --- a/packages/md-enhance/src/node/markdown-it/playground/ts.ts +++ b/packages/md-enhance/src/node/markdown-it/playground/ts.ts @@ -1,3 +1,4 @@ +import { isPlainObject } from "@vuepress/shared"; import { deepMerge } from "vuepress-shared/node"; import { compressToEncodedURIComponent } from "./ventors/lzstring.js"; import { optionDeclarations } from "./ventors/optionDelcarations.js"; @@ -24,7 +25,7 @@ export const getURL = ( const { type } = item; - if (typeof type === "object") { + if (isPlainObject(type)) { const result = type[value as keyof typeof type]; return result?.toString() || ""; diff --git a/packages/md-enhance/src/node/plugin.ts b/packages/md-enhance/src/node/plugin.ts index 6c41e41b8b2a..c684ce189c95 100644 --- a/packages/md-enhance/src/node/plugin.ts +++ b/packages/md-enhance/src/node/plugin.ts @@ -13,6 +13,7 @@ import { stylize } from "@mdit/plugin-stylize"; import { sub } from "@mdit/plugin-sub"; import { sup } from "@mdit/plugin-sup"; import { tasklist } from "@mdit/plugin-tasklist"; +import { isArray, isPlainObject } from "@vuepress/shared"; import { useSassPalettePlugin } from "vuepress-plugin-sass-palette"; import { addCustomElement, @@ -123,19 +124,19 @@ export const mdEnhancePlugin = // eslint-disable-next-line @typescript-eslint/naming-convention "\\idotsint": "\\int\\!\\cdots\\!\\int", }, - ...(typeof options.katex === "object" ? options.katex : {}), + ...(isPlainObject(options.katex) ? options.katex : {}), }; const mathjaxInstance = options.mathjax === false ? null : createMathjaxInstance( - typeof options.mathjax === "object" ? options.mathjax : {} + isPlainObject(options.mathjax) ? options.mathjax : {} ); const revealPlugins = - typeof options.presentation === "object" && - Array.isArray(options.presentation.plugins) + isPlainObject(options.presentation) && + isArray(options.presentation.plugins) ? options.presentation.plugins : []; @@ -150,23 +151,17 @@ export const mdEnhancePlugin = MARKDOWN_ENHANCE_DELAY: options.delay || 800, CODE_DEMO_OPTIONS: { ...CODE_DEMO_DEFAULT_SETTING, - ...(typeof options.demo === "object" ? options.demo : {}), + ...(isPlainObject(options.demo) ? options.demo : {}), }, - MERMAID_OPTIONS: - typeof options.mermaid === "object" ? options.mermaid : {}, + MERMAID_OPTIONS: isPlainObject(options.mermaid) ? options.mermaid : {}, REVEAL_CONFIG: - typeof options.presentation === "object" && - typeof options.presentation.revealConfig === "object" + isPlainObject(options.presentation) && + isPlainObject(options.presentation.revealConfig) ? options.presentation.revealConfig : {}, - VUE_PLAYGROUND_OPTIONS: - typeof options.vuePlayground === "object" - ? deepMerge( - {}, - DEFAULT_VUE_PLAYGROUND_OPTIONS, - options.vuePlayground - ) - : DEFAULT_VUE_PLAYGROUND_OPTIONS, + VUE_PLAYGROUND_OPTIONS: isPlainObject(options.vuePlayground) + ? deepMerge({}, DEFAULT_VUE_PLAYGROUND_OPTIONS, options.vuePlayground) + : DEFAULT_VUE_PLAYGROUND_OPTIONS, }), extendsBundlerOptions: (config: unknown, app): void => { @@ -255,7 +250,7 @@ export const mdEnhancePlugin = // syntax if (getStatus("gfm")) md.options.linkify = true; if (getStatus("attrs")) - md.use(attrs, typeof options.attrs === "object" ? options.attrs : {}); + md.use(attrs, isPlainObject(options.attrs) ? options.attrs : {}); if (getStatus("align")) md.use(align); if (getStatus("container")) md.use(hint, locales); if (getStatus("imgLazyload")) md.use(imgLazyload); @@ -263,7 +258,7 @@ export const mdEnhancePlugin = if (imgMarkEnable) md.use( imgMark, - typeof options.imgMark === "object" ? options.imgMark : {} + isPlainObject(options.imgMark) ? options.imgMark : {} ); if (getStatus("imgSize")) md.use(imgSize); if (getStatus("sup")) md.use(sup); @@ -272,7 +267,7 @@ export const mdEnhancePlugin = if (getStatus("mark")) md.use(mark); if (tasklistEnable) md.use(tasklist, [ - typeof options.tasklist === "object" ? options.tasklist : {}, + isPlainObject(options.tasklist) ? options.tasklist : {}, ]); // additional functions @@ -288,7 +283,7 @@ export const mdEnhancePlugin = if (getStatus("include")) md.use(include, { currentPath: (env: MarkdownEnv) => env.filePath, - ...(typeof options.include === "object" ? options.include : {}), + ...(isPlainObject(options.include) ? options.include : {}), }); if (getStatus("stylize")) md.use(stylize, { @@ -320,7 +315,7 @@ export const mdEnhancePlugin = } if (mermaidEnable) md.use(mermaid); if (presentationEnable) md.use(presentation); - if (typeof options.playground === "object") { + if (isPlainObject(options.playground)) { const { presets = [], config = {} } = options.playground; presets.forEach((preset) => { @@ -328,7 +323,7 @@ export const mdEnhancePlugin = md.use(playground, getTSPlaygroundPreset(config.ts || {})); else if (preset === "vue") md.use(playground, getVuePlaygroundPreset(config.vue || {})); - else if (typeof preset === "object") md.use(playground, preset); + else if (isPlainObject(preset)) md.use(playground, preset); }); } if (vuePlaygroundEnable) md.use(vuePlayground); diff --git a/packages/photo-swipe/package.json b/packages/photo-swipe/package.json index 271fe2b6405f..c9bb20b61877 100644 --- a/packages/photo-swipe/package.json +++ b/packages/photo-swipe/package.json @@ -52,6 +52,7 @@ }, "dependencies": { "@vuepress/client": "2.0.0-beta.60", + "@vuepress/shared": "2.0.0-beta.60", "@vuepress/utils": "2.0.0-beta.60", "@vueuse/core": "^9.9.0", "photoswipe": "^5.3.4", diff --git a/packages/photo-swipe/rollup.config.ts b/packages/photo-swipe/rollup.config.ts index 24d3fab3f19d..ca318fd79816 100644 --- a/packages/photo-swipe/rollup.config.ts +++ b/packages/photo-swipe/rollup.config.ts @@ -12,6 +12,7 @@ export default [ ...rollupTypescript("client/config", { external: [ "@vuepress/client", + "@vuepress/shared", "@vueuse/core", "photoswipe", "vue", diff --git a/packages/photo-swipe/src/client/utils/index.ts b/packages/photo-swipe/src/client/utils/index.ts index 737912686fd9..6bedd48ba4e5 100644 --- a/packages/photo-swipe/src/client/utils/index.ts +++ b/packages/photo-swipe/src/client/utils/index.ts @@ -1,3 +1,5 @@ +import { isString } from "@vuepress/shared"; + import type { DataSourceItem } from "photoswipe"; export const getImageInfo = (image: HTMLImageElement): DataSourceItem => ({ @@ -15,14 +17,13 @@ export interface PhotoSwipeImages { export const getImages = ( selector: string | string[] ): Promise => { - const images = - typeof selector === "string" - ? Array.from(document.querySelectorAll(selector)) - : selector - .map((item) => - Array.from(document.querySelectorAll(item)) - ) - .flat(); + const images = isString(selector) + ? Array.from(document.querySelectorAll(selector)) + : selector + .map((item) => + Array.from(document.querySelectorAll(item)) + ) + .flat(); return Promise.all( images.map( diff --git a/packages/pwa2/src/node/injectHead.ts b/packages/pwa2/src/node/injectHead.ts index 5bff83b9d386..284e685e700c 100644 --- a/packages/pwa2/src/node/injectHead.ts +++ b/packages/pwa2/src/node/injectHead.ts @@ -1,3 +1,5 @@ +import { isPlainObject } from "@vuepress/shared"; + import type { HeadConfig } from "@vuepress/core"; import type { PWAOptions } from "./options.js"; @@ -54,10 +56,7 @@ export const injectLinksToHead = ( }); setMeta("theme-color", options.themeColor || "#46bd87"); - if ( - typeof options.apple === "object" && - (options.apple.icon || fallBackIcon) - ) { + if (isPlainObject(options.apple) && (options.apple.icon || fallBackIcon)) { setLink("apple-touch-icon", options.apple.icon || fallBackIcon); setMeta("apple-mobile-web-app-capable", "yes"); setMeta( @@ -74,10 +73,7 @@ export const injectLinksToHead = ( setMeta("apple-mobile-web-app-status-bar-style", "black"); } - if ( - typeof options.msTile === "object" && - (options.msTile.image || fallBackIcon) - ) { + if (isPlainObject(options.msTile) && (options.msTile.image || fallBackIcon)) { setMeta("msapplication-TileImage", options.msTile.image || fallBackIcon); setMeta( "msapplication-TileColor", diff --git a/packages/redirect/src/node/generate.ts b/packages/redirect/src/node/generate.ts index d9044e741d55..98d05e061cfd 100644 --- a/packages/redirect/src/node/generate.ts +++ b/packages/redirect/src/node/generate.ts @@ -1,4 +1,6 @@ import { + isArray, + isFunction, isLinkHttp, removeEndingSlash, removeLeadingSlash, @@ -20,15 +22,14 @@ export const generateHTML = async ( pages, } = app; - const config = - typeof options.config === "function" - ? options.config(app) - : options.config || {}; + const config = isFunction(options.config) + ? options.config(app) + : options.config || {}; const redirectMap = Object.fromEntries( (, RedirectPluginFrontmatterOption>[]>pages) .map<[string, string][]>(({ frontmatter, path }) => - Array.isArray(frontmatter.redirectFrom) + isArray(frontmatter.redirectFrom) ? frontmatter.redirectFrom.map((from) => [ from.replace(/\/$/, "/index.html"), path, diff --git a/packages/sass-palette/package.json b/packages/sass-palette/package.json index d62ad212c12f..51a6840980aa 100644 --- a/packages/sass-palette/package.json +++ b/packages/sass-palette/package.json @@ -54,6 +54,7 @@ "pnpm": ">=7" }, "dependencies": { + "@vuepress/shared": "2.0.0-beta.60", "@vuepress/utils": "2.0.0-beta.60", "chokidar": "^3.5.3", "sass": "^1.57.1", diff --git a/packages/sass-palette/rollup.config.ts b/packages/sass-palette/rollup.config.ts index 7d237b76b1ed..465d0990dde9 100644 --- a/packages/sass-palette/rollup.config.ts +++ b/packages/sass-palette/rollup.config.ts @@ -1,5 +1,10 @@ import { rollupTypescript } from "../../scripts/rollup.js"; export default rollupTypescript("node/index", { - external: ["@vuepress/utils", "chokidar", "vuepress-shared/node"], + external: [ + "@vuepress/shared", + "@vuepress/utils", + "chokidar", + "vuepress-shared/node", + ], }); diff --git a/packages/sass-palette/src/node/inject.ts b/packages/sass-palette/src/node/inject.ts index d13ae144b8cb..5cd29d795ecc 100644 --- a/packages/sass-palette/src/node/inject.ts +++ b/packages/sass-palette/src/node/inject.ts @@ -1,3 +1,4 @@ +import { isFunction, isString } from "@vuepress/shared"; import { getBundlerName, mergeViteConfig } from "vuepress-shared/node"; import type { App } from "@vuepress/core"; @@ -53,12 +54,11 @@ export const injectConfigModule = ( source: string, file: string ): Promise => { - const originalContent = - typeof originalAdditionalData === "string" - ? `${originalAdditionalData}${source}` - : typeof originalAdditionalData === "function" - ? await originalAdditionalData(source, file) - : source; + const originalContent = isString(originalAdditionalData) + ? `${originalAdditionalData}${source}` + : isFunction(originalAdditionalData) + ? await originalAdditionalData(source, file) + : source; return originalContent.match( new RegExp(`@use\\s+["']@sass-palette\\/${id}-config["'];`) @@ -85,12 +85,11 @@ export const injectConfigModule = ( content: string, loaderContext: LoaderContext ): string => { - const originalContent = - typeof additionalData === "string" - ? `${additionalData}${content}` - : typeof additionalData === "function" - ? additionalData(content, loaderContext) - : content; + const originalContent = isString(additionalData) + ? `${additionalData}${content}` + : isFunction(additionalData) + ? additionalData(content, loaderContext) + : content; return originalContent.match( new RegExp(`@use\\s+["']@sass-palette\\/${id}-config["'];`) diff --git a/packages/search-pro/package.json b/packages/search-pro/package.json index 61125d6b2345..a80a4cc11cb9 100644 --- a/packages/search-pro/package.json +++ b/packages/search-pro/package.json @@ -49,6 +49,7 @@ }, "dependencies": { "@vuepress/client": "2.0.0-beta.60", + "@vuepress/shared": "2.0.0-beta.60", "@vuepress/utils": "2.0.0-beta.60", "@vueuse/core": "^9.9.0", "body-scroll-lock": "^3.1.5", diff --git a/packages/search-pro/rollup.config.ts b/packages/search-pro/rollup.config.ts index 087156657627..e2a9922bab94 100644 --- a/packages/search-pro/rollup.config.ts +++ b/packages/search-pro/rollup.config.ts @@ -15,6 +15,7 @@ export default [ ...rollupTypescript("client/components/SearchResult", { external: [ "@vuepress/client", + "@vuepress/shared", "@vueuse/core", "body-scroll-lock", "vue", @@ -30,6 +31,7 @@ export default [ external: [ /^@temp\//, "@vuepress/client", + "@vueuse/core", "vue", "vuepress-plugin-search-pro/result", "vuepress-shared/client", diff --git a/packages/search-pro/src/client/components/SearchResult.ts b/packages/search-pro/src/client/components/SearchResult.ts index 4567bd19550c..2b47966db426 100644 --- a/packages/search-pro/src/client/components/SearchResult.ts +++ b/packages/search-pro/src/client/components/SearchResult.ts @@ -1,4 +1,5 @@ import { useRouteLocale } from "@vuepress/client"; +import { isPlainObject, isString } from "@vuepress/shared"; import { useEventListener } from "@vueuse/core"; import { disableBodyScroll, clearAllBodyScrollLocks } from "body-scroll-lock"; import { @@ -106,19 +107,16 @@ export default defineComponent({ }; const getVNodes = (display: Word[]): (VNode | string)[] => - display.map((word) => - typeof word === "string" ? word : h(word[0], word[1]) - ); + display.map((word) => (isString(word) ? word : h(word[0], word[1]))); const getDisplay = (matchedItem: MatchedItem): (VNode | string)[] => { if (matchedItem.type === "custom") { const formatterConfig = searchProClientCustomFiledConfig[matchedItem.index] || "$content"; - const [prefix, suffix = ""] = - typeof formatterConfig === "object" - ? formatterConfig[routeLocale.value].split("$content") - : formatterConfig.split("$content"); + const [prefix, suffix = ""] = isPlainObject(formatterConfig) + ? formatterConfig[routeLocale.value].split("$content") + : formatterConfig.split("$content"); return getVNodes([prefix, ...matchedItem.display, suffix]); } diff --git a/packages/search-pro/src/node/generateIndex.ts b/packages/search-pro/src/node/generateIndex.ts index 2953ba78ab95..ea0c59dfa3bd 100644 --- a/packages/search-pro/src/node/generateIndex.ts +++ b/packages/search-pro/src/node/generateIndex.ts @@ -1,3 +1,4 @@ +import { isArray } from "@vuepress/shared"; import { load } from "cheerio"; import type { Page } from "@vuepress/core"; @@ -118,7 +119,7 @@ export const generatePageIndex = ( .map(({ getter }, index) => { const result = getter(page); - return Array.isArray(result) + return isArray(result) ? [index.toString(), result] : result ? [index.toString(), [result]] diff --git a/packages/seo2/src/node/info.ts b/packages/seo2/src/node/info.ts index 657a5c98c081..bca3ee47af57 100644 --- a/packages/seo2/src/node/info.ts +++ b/packages/seo2/src/node/info.ts @@ -1,5 +1,10 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { removeEndingSlash } from "@vuepress/shared"; +import { + isArray, + isFunction, + isString, + removeEndingSlash, +} from "@vuepress/shared"; import { getAuthor, getDate } from "vuepress-shared/node"; import { getCover, getImages, getLocales, resolveUrl } from "./utils.js"; @@ -42,9 +47,9 @@ export const getOGP = ( const { updatedTime } = git; const modifiedTime = updatedTime ? new Date(updatedTime).toISOString() : ""; - const articleTags: string[] = Array.isArray(tags) + const articleTags: string[] = isArray(tags) ? tags - : typeof tag === "string" + : isString(tag) ? [tag] : []; @@ -148,9 +153,9 @@ export const getCanonicalLink = ( page: ExtendPage, options: SeoOptions ): string | null => - typeof options.canonical === "function" + isFunction(options.canonical) ? options.canonical(page) - : typeof options.canonical === "string" + : isString(options.canonical) ? `${removeEndingSlash(options.canonical)}${page.path}` : null; diff --git a/packages/seo2/src/node/utils.ts b/packages/seo2/src/node/utils.ts index 8156fe42c792..a301febb2986 100644 --- a/packages/seo2/src/node/utils.ts +++ b/packages/seo2/src/node/utils.ts @@ -1,5 +1,6 @@ import { isLinkHttp, + isString, removeEndingSlash, removeLeadingSlash, } from "@vuepress/shared"; @@ -23,8 +24,7 @@ export const getLocales = ( Object.entries(locales) .map(([localePath, value]) => ({ localePath, lang: value.lang })) .filter( - (item): item is LocaleConfig => - typeof item.lang === "string" && item.lang !== lang + (item): item is LocaleConfig => isString(item.lang) && item.lang !== lang ); export const getCover = ( diff --git a/packages/shared/src/client/composables/component.ts b/packages/shared/src/client/composables/component.ts index 6da4658cad82..ae56d3639ead 100644 --- a/packages/shared/src/client/composables/component.ts +++ b/packages/shared/src/client/composables/component.ts @@ -1,13 +1,15 @@ +import { isPlainObject } from "@vuepress/shared"; import { capitalize, camelize, getCurrentInstance } from "vue"; + import type { App } from "vue"; export const hasGlobalComponent = (name: string, app?: App): boolean => { const instance = app ? app._instance : getCurrentInstance(); return ( - typeof instance?.appContext.components === "object" && - (name in instance.appContext.components || - camelize(name) in instance.appContext.components || - capitalize(camelize(name)) in instance.appContext.components) + isPlainObject(instance?.appContext.components) && + (name in instance!.appContext.components || + camelize(name) in instance!.appContext.components || + capitalize(camelize(name)) in instance!.appContext.components) ); }; diff --git a/packages/shared/src/node/bundler/customElement.ts b/packages/shared/src/node/bundler/customElement.ts index e160993b9b73..2691788308eb 100644 --- a/packages/shared/src/node/bundler/customElement.ts +++ b/packages/shared/src/node/bundler/customElement.ts @@ -1,3 +1,4 @@ +import { isString } from "@vuepress/shared"; import { colors } from "@vuepress/utils"; import { getBundlerName } from "./getBundler.js"; import { HTML_TAGS, SVG_TAGS } from "../utils/index.js"; @@ -43,8 +44,9 @@ export const addCustomElement = ( { app, config }: CustomElementCommonOptions, customElement: string[] | string | RegExp ): void => { - const customElements = - typeof customElement === "string" ? [customElement] : customElement; + const customElements = isString(customElement) + ? [customElement] + : customElement; const bundlerName = getBundlerName(app); // for vite diff --git a/packages/shared/src/node/bundler/vite/mergeViteConfig.ts b/packages/shared/src/node/bundler/vite/mergeViteConfig.ts index 8a22d7a8dd17..ddd8db17ec84 100644 --- a/packages/shared/src/node/bundler/vite/mergeViteConfig.ts +++ b/packages/shared/src/node/bundler/vite/mergeViteConfig.ts @@ -51,6 +51,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +import { isArray, isString } from "@vuepress/shared"; + interface Alias { find: string | RegExp; replacement: string; @@ -75,18 +77,14 @@ const isObject = (value: unknown): value is Record => Object.prototype.toString.call(value) === "[object Object]"; const arraify = (target: T | T[]): T[] => - Array.isArray(target) ? target : [target]; + isArray(target) ? target : [target]; const normalizeSingleAlias = ({ find, replacement, customResolver, }: Alias): Alias => { - if ( - typeof find === "string" && - find.endsWith("/") && - replacement.endsWith("/") - ) { + if (isString(find) && find.endsWith("/") && replacement.endsWith("/")) { find = find.slice(0, find.length - 1); replacement = replacement.slice(0, replacement.length - 1); } @@ -102,7 +100,7 @@ const normalizeSingleAlias = ({ }; const normalizeAlias = (aliasOption: AliasOptions): Alias[] => - Array.isArray(aliasOption) + isArray(aliasOption) ? aliasOption.map(normalizeSingleAlias) : Object.keys(aliasOption).map((find) => normalizeSingleAlias({ @@ -163,7 +161,7 @@ const mergeConfigRecursively = ( continue; } - if (Array.isArray(existing) || Array.isArray(value)) { + if (isArray(existing) || isArray(value)) { merged[key] = [...arraify(existing), ...arraify(value)]; continue; } diff --git a/packages/shared/src/node/bundler/vite/viteHelper.ts b/packages/shared/src/node/bundler/vite/viteHelper.ts index b85161886656..5ac7a28e69d0 100644 --- a/packages/shared/src/node/bundler/vite/viteHelper.ts +++ b/packages/shared/src/node/bundler/vite/viteHelper.ts @@ -1,3 +1,4 @@ +import { isString } from "@vuepress/shared"; import { mergeViteConfig } from "./mergeViteConfig.js"; import { getBundlerName } from "../getBundler.js"; import { detectPackageManager } from "../../utils/index.js"; @@ -35,7 +36,7 @@ export const addViteOptimizeDepsInclude = ( bundlerConfig.viteOptions || {}, { optimizeDeps: { - include: typeof module === "string" ? [module] : module, + include: isString(module) ? [module] : module, }, } ); @@ -60,7 +61,7 @@ export const addViteOptimizeDepsExclude = ( bundlerConfig.viteOptions || {}, { optimizeDeps: { - exclude: typeof module === "string" ? [module] : module, + exclude: isString(module) ? [module] : module, }, } ); @@ -85,7 +86,7 @@ export const addViteSsrExternal = ( bundlerConfig.viteOptions || {}, { ssr: { - external: typeof module === "string" ? [module] : module, + external: isString(module) ? [module] : module, }, } ); @@ -106,7 +107,7 @@ export const addViteSsrNoExternal = ( bundlerConfig.viteOptions || {}, { ssr: { - noExternal: typeof module === "string" ? [module] : module, + noExternal: isString(module) ? [module] : module, }, } ); diff --git a/packages/shared/src/node/page/excerpt.ts b/packages/shared/src/node/page/excerpt.ts index cd95ef6de8a8..074c5a078af5 100644 --- a/packages/shared/src/node/page/excerpt.ts +++ b/packages/shared/src/node/page/excerpt.ts @@ -1,4 +1,4 @@ -import { isLinkHttp, removeEndingSlash } from "@vuepress/shared"; +import { isArray, isLinkHttp, removeEndingSlash } from "@vuepress/shared"; import { load } from "cheerio"; import matter from "gray-matter"; import { HTML_TAGS, SVG_TAGS } from "../utils/index.js"; @@ -113,7 +113,7 @@ const handleNodes = ( base: string, isCustomElement: (tagName: string) => boolean ): AnyNode[] => - Array.isArray(nodes) + isArray(nodes) ? nodes .map((node) => handleNode(node, base, isCustomElement)) .filter((node): node is AnyNode => node !== null) diff --git a/packages/shared/src/node/utils/dayjs/de-at.ts b/packages/shared/src/node/utils/dayjs/de-at.ts index 4d47fae43376..99e61feee7b2 100644 --- a/packages/shared/src/node/utils/dayjs/de-at.ts +++ b/packages/shared/src/node/utils/dayjs/de-at.ts @@ -1,4 +1,6 @@ // German (Austria) [de-at] +import { isArray } from "@vuepress/shared"; + import type dayjs from "dayjs"; import type { Locale } from "./locale.js"; @@ -23,7 +25,7 @@ const relativeTimeFormatter = ( ): string => { let l = texts[key]; - if (Array.isArray(l)) l = l[withoutSuffix ? 0 : 1]; + if (isArray(l)) l = l[withoutSuffix ? 0 : 1]; return l.replace("%d", number); }; diff --git a/packages/shared/src/node/utils/dayjs/de.ts b/packages/shared/src/node/utils/dayjs/de.ts index 66bec6b36190..3683342c9e56 100644 --- a/packages/shared/src/node/utils/dayjs/de.ts +++ b/packages/shared/src/node/utils/dayjs/de.ts @@ -1,6 +1,9 @@ // German [de] +import { isArray } from "@vuepress/shared"; + import type dayjs from "dayjs"; import type { Locale } from "./locale.js"; + const texts = { s: "ein paar Sekunden", m: ["eine Minute", "einer Minute"], @@ -22,7 +25,7 @@ const relativeTimeFormatter = ( ): string => { let l = texts[key]; - if (Array.isArray(l)) l = l[withoutSuffix ? 0 : 1]; + if (isArray(l)) l = l[withoutSuffix ? 0 : 1]; return l.replace("%d", number); }; diff --git a/packages/shared/src/shared/utils/deepMerge.ts b/packages/shared/src/shared/utils/deepMerge.ts index 6ecc908bc5cf..d63c4373e9eb 100644 --- a/packages/shared/src/shared/utils/deepMerge.ts +++ b/packages/shared/src/shared/utils/deepMerge.ts @@ -1,3 +1,5 @@ +import { isArray, isPlainObject } from "@vuepress/shared"; + // eslint-disable-next-line @typescript-eslint/no-explicit-any type IAnyObject = Record; @@ -17,14 +19,14 @@ export const deepMerge = < Object.keys(assignObject).forEach((property) => { if ( - typeof originObject[property] === "object" && - !Array.isArray(originObject[property]) && - typeof assignObject[property] === "object" && - !Array.isArray(assignObject[property]) + isPlainObject(originObject[property]) && + !isArray(originObject[property]) && + isPlainObject(assignObject[property]) && + !isArray(assignObject[property]) ) deepMerge(originObject[property], assignObject[property]); - else if (typeof assignObject[property] === "object") - if (Array.isArray(assignObject[property])) + else if (isPlainObject(assignObject[property])) + if (isArray(assignObject[property])) (originObject as IAnyObject)[property] = [ ...(assignObject[property] as unknown[]), ]; diff --git a/packages/shared/src/shared/utils/info.ts b/packages/shared/src/shared/utils/info.ts index c6fd75e40172..dd8a6aec3bd8 100644 --- a/packages/shared/src/shared/utils/info.ts +++ b/packages/shared/src/shared/utils/info.ts @@ -1,3 +1,5 @@ +import { isArray, isString, isPlainObject } from "@vuepress/shared"; + import type { Author, AuthorInfo } from "../types/index.js"; export const getAuthor = ( @@ -5,15 +7,13 @@ export const getAuthor = ( canDisable = false ): AuthorInfo[] => { if (author) { - if (Array.isArray(author)) { - return author.map((item) => - typeof item === "string" ? { name: item } : item - ); + if (isArray(author)) { + return author.map((item) => (isString(item) ? { name: item } : item)); } - if (typeof author === "string") return [{ name: author }]; + if (isString(author)) return [{ name: author }]; - if (typeof author === "object" && author.name) return [author]; + if (isPlainObject(author) && author.name) return [author]; console.error( `Expect 'author' to be \`AuthorInfo[] | AuthorInfo | string[] | string ${ @@ -33,8 +33,8 @@ export const getStringArray = ( optionName?: string ): string[] => { if (value) { - if (Array.isArray(value)) return value; - if (typeof value === "string") return [value]; + if (isArray(value)) return value; + if (isString(value)) return [value]; console.error( `Expect ${ diff --git a/packages/shared/src/shared/utils/url.ts b/packages/shared/src/shared/utils/url.ts index 6f6e1353b8f9..8b6293e6ffe0 100644 --- a/packages/shared/src/shared/utils/url.ts +++ b/packages/shared/src/shared/utils/url.ts @@ -1,8 +1,10 @@ +import { isString } from "@vuepress/shared"; + /** * check if a variable is a valid url */ export const isUrl = (test: unknown): boolean => { - if (typeof test !== "string" || test === "") return false; + if (!isString(test) || test === "") return false; // url Math const result = /^(?:\w+:)?\/\/(\S+)$/u.exec(test); @@ -25,4 +27,4 @@ export const isUrl = (test: unknown): boolean => { * Whether a variable is a valid absolute url */ export const isAbsoluteUrl = (test: unknown): boolean => - typeof test === "string" && test.startsWith("/"); + isString(test) && test.startsWith("/"); diff --git a/packages/theme/src/client/components/PageFooter.ts b/packages/theme/src/client/components/PageFooter.ts index 53b89bb741fe..f8d4ae7da364 100644 --- a/packages/theme/src/client/components/PageFooter.ts +++ b/packages/theme/src/client/components/PageFooter.ts @@ -1,3 +1,4 @@ +import { isString } from "@vuepress/shared"; import { usePageFrontmatter } from "@vuepress/client"; import { computed, defineComponent, h } from "vue"; @@ -33,7 +34,7 @@ export default defineComponent({ return footer === false ? false - : typeof footer === "string" + : isString(footer) ? footer : themeLocale.value.footer || ""; }); diff --git a/packages/theme/src/client/modules/encrypt/composables/path.ts b/packages/theme/src/client/modules/encrypt/composables/path.ts index 7acc1bb42a0b..eede26a0c450 100644 --- a/packages/theme/src/client/modules/encrypt/composables/path.ts +++ b/packages/theme/src/client/modules/encrypt/composables/path.ts @@ -1,3 +1,4 @@ +import { isPlainObject } from "@vuepress/shared"; import { useStorage, useSessionStorage } from "@vueuse/core"; import { computed } from "vue"; import { useRoute } from "vue-router"; @@ -26,7 +27,7 @@ export const usePathEncrypt = (): PathEncrypt => { ); const getPathMatchedKeys = (path: string): string[] => - typeof encryptData.value.config === "object" + isPlainObject(encryptData.value.config) ? Object.keys(encryptData.value.config) .filter((key) => decodeURI(path).startsWith(key)) .sort((a, b) => b.length - a.length) diff --git a/packages/theme/src/client/modules/info/components/PageViewInfo.ts b/packages/theme/src/client/modules/info/components/PageViewInfo.ts index 0b92a77f09d3..bda5d15a1c48 100644 --- a/packages/theme/src/client/modules/info/components/PageViewInfo.ts +++ b/packages/theme/src/client/modules/info/components/PageViewInfo.ts @@ -1,4 +1,5 @@ import { withBase } from "@vuepress/client"; +import { isString } from "@vuepress/shared"; import { defineComponent, h, onMounted, watch, ref } from "vue"; import { useRoute } from "vue-router"; @@ -78,10 +79,9 @@ export default defineComponent({ { class: "waline-pageview-count", /** visitorID */ - "data-path": - typeof props.pageview === "string" - ? props.pageview - : withBase(route.path), + "data-path": isString(props.pageview) + ? props.pageview + : withBase(route.path), }, "..." ), diff --git a/packages/theme/src/node/compact/helper-v1.ts b/packages/theme/src/node/compact/helper-v1.ts index eb750f9d6ea9..cab6b2a0fe9c 100644 --- a/packages/theme/src/node/compact/helper-v1.ts +++ b/packages/theme/src/node/compact/helper-v1.ts @@ -1,3 +1,4 @@ +import { isArray, isFunction, isPlainObject, isString } from "@vuepress/shared"; import { colors } from "@vuepress/utils"; import { defineHopeConfig } from "./helper-v2.js"; import { convertThemeOptions } from "./theme.js"; @@ -67,7 +68,7 @@ const checkMarkdownOptions = ( options.code = options.code ?? {}; - if (typeof options.code === "object") + if (isPlainObject(options.code)) options.code.lineNumbers = options["lineNumbers"] as boolean; delete options["lineNumbers"]; @@ -130,15 +131,15 @@ If you want to change the slugify function anyway, set the following options sep const checkPluginOptions = (plugins: unknown): PluginConfig => { // check plugin array - if (Array.isArray(plugins)) + if (isArray(plugins)) return plugins.flat().filter((item): item is Plugin => { - if (typeof item === "function") return true; + if (isFunction(item)) return true; - if (typeof item === "object") { + if (isPlainObject(item)) { const { name } = item as Plugin & Record; // check name - if (typeof name !== "string") { + if (!isString(name)) { logger.error( 'VuePress2 requires "name" option in plugins and it should strict equal it\'s package name.' ); @@ -225,7 +226,7 @@ const checkPluginOptions = (plugins: unknown): PluginConfig => { }); // check whether plugins is an object - if (typeof plugins === "object") { + if (isPlainObject(plugins)) { logger.error( `${colors.magenta('object format "plugins"')} is ${colors.red( "no longer supported" diff --git a/packages/theme/src/node/compact/helper-v2.ts b/packages/theme/src/node/compact/helper-v2.ts index 73078ec3a829..feaa60c34498 100644 --- a/packages/theme/src/node/compact/helper-v2.ts +++ b/packages/theme/src/node/compact/helper-v2.ts @@ -1,3 +1,4 @@ +import { isFunction, isPlainObject } from "@vuepress/shared"; import { colors } from "@vuepress/utils"; import { convertThemeOptions } from "./theme.js"; import { deprecatedMsg } from "./utils.js"; @@ -118,12 +119,12 @@ export default { ); // check themeConfig - if ("themeConfig" in config && typeof config["themeConfig"] === "object") { + if ("themeConfig" in config && isPlainObject(config["themeConfig"])) { config.theme = hopeThemeLegacy(config["themeConfig"] as ThemeOptions); } // check theme - if (typeof config.theme !== "function") config.theme = hopeThemeLegacy({}); + if (!isFunction(config.theme)) config.theme = hopeThemeLegacy({}); return config; }; diff --git a/packages/theme/src/node/compact/navbar.ts b/packages/theme/src/node/compact/navbar.ts index 3b5de0603ae8..8befffa3e9a4 100644 --- a/packages/theme/src/node/compact/navbar.ts +++ b/packages/theme/src/node/compact/navbar.ts @@ -1,3 +1,4 @@ +import { isArray, isPlainObject, isString } from "@vuepress/shared"; import { deprecatedLogger } from "./utils.js"; import { logger } from "../utils.js"; @@ -10,9 +11,9 @@ import type { const handleNavbarOptions = (config: unknown[]): NavbarOptions => config .map((item) => { - if (typeof item === "string") return item; + if (isString(item)) return item; - if (typeof item === "object" && item) { + if (isPlainObject(item) && item) { deprecatedLogger({ options: item as Record, deprecatedOption: "items", @@ -21,7 +22,7 @@ const handleNavbarOptions = (config: unknown[]): NavbarOptions => }); // @ts-ignore - if (Array.isArray(item.children)) + if (isArray(item.children)) // @ts-ignore handleNavbarOptions(item.children as unknown[]); @@ -39,7 +40,7 @@ export const convertNavbarOptions = ( config: unknown ): NavbarOptions | false => { if (config === false) return false; - if (Array.isArray(config)) return handleNavbarOptions(config); + if (isArray(config)) return handleNavbarOptions(config); logger.error('"navbar" config should be an array'); diff --git a/packages/theme/src/node/compact/sidebar.ts b/packages/theme/src/node/compact/sidebar.ts index dd2ff87ed6bf..322e99cf6da3 100644 --- a/packages/theme/src/node/compact/sidebar.ts +++ b/packages/theme/src/node/compact/sidebar.ts @@ -1,3 +1,4 @@ +import { isArray, isPlainObject, isString } from "@vuepress/shared"; import { droppedLogger, deprecatedLogger } from "./utils.js"; import { logger } from "../utils.js"; @@ -10,9 +11,9 @@ import type { const handleArraySidebarOptions = (config: unknown[]): SidebarArrayOptions => config .map((item) => { - if (typeof item === "string") return item; + if (isString(item)) return item; - if (typeof item === "object") { + if (isPlainObject(item)) { const convertConfig: [string, string][] = [ ["title", "text"], ["path", "link"], @@ -35,7 +36,7 @@ const handleArraySidebarOptions = (config: unknown[]): SidebarArrayOptions => ); // @ts-ignore - if (Array.isArray(item.children)) + if (isArray(item.children)) // @ts-ignore handleArraySidebarOptions(item.children as unknown[]); @@ -53,15 +54,14 @@ export const convertSidebarOptions = ( config: unknown ): SidebarOptions | false => { if (config === false) return false; - if (Array.isArray(config)) return handleArraySidebarOptions(config); + if (isArray(config)) return handleArraySidebarOptions(config); - if (typeof config === "object" && config) + if (isPlainObject(config) && config) return Object.fromEntries( Object.entries(config).map< [string, SidebarArrayOptions | "structure" | false] >(([key, value]) => { - if (Array.isArray(value)) - return [key, handleArraySidebarOptions(value)]; + if (isArray(value)) return [key, handleArraySidebarOptions(value)]; if (value === "structure" || value === false) return [key, <"structure" | false>value]; diff --git a/packages/theme/src/node/compact/theme.ts b/packages/theme/src/node/compact/theme.ts index 18bdf6dbf4df..ebfedf2c4dbe 100644 --- a/packages/theme/src/node/compact/theme.ts +++ b/packages/theme/src/node/compact/theme.ts @@ -1,3 +1,5 @@ +import { isArray, isPlainObject } from "@vuepress/shared"; + import { convertNavbarOptions } from "./navbar.js"; import { convertSidebarOptions } from "./sidebar.js"; import { droppedLogger, deprecatedLogger } from "./utils.js"; @@ -101,7 +103,7 @@ const handleBlogOptions = (blogOptions: Record): void => { * @deprecated You should use V2 standard options and avoid using it */ const handleFooterOptions = (options: Record): void => { - if (typeof options["footer"] === "object" && options["footer"]) { + if (isPlainObject(options["footer"]) && options["footer"]) { const footer = options["footer"]; if ("copyright" in footer) { @@ -165,13 +167,13 @@ export const convertThemeOptions = ( handleFooterOptions(themeOptions); // handle blog - if (typeof themeOptions["blog"] === "object" && themeOptions["blog"]) { + if (isPlainObject(themeOptions["blog"]) && themeOptions["blog"]) { handleBlogOptions(themeOptions["blog"] as Record); if (!plugins["blog"]) plugins["blog"] = true; } // handle component - if (Array.isArray(plugins["components"])) { + if (isArray(plugins["components"])) { logger.warn( '"plugins.components" no longer accpets array, please set it to "plugin.components.components" instead.' ); @@ -190,7 +192,7 @@ export const convertThemeOptions = ( scope: "themeConfig", }); - if (typeof themeOptions["encrypt"] === "object" && themeOptions["encrypt"]) { + if (isPlainObject(themeOptions["encrypt"]) && themeOptions["encrypt"]) { // handle encrypt const encrypt = themeOptions["encrypt"] as Record; @@ -212,10 +214,7 @@ export const convertThemeOptions = ( } } - if ( - "locales" in themeOptions && - typeof themeOptions["locales"] === "object" - ) { + if ("locales" in themeOptions && isPlainObject(themeOptions["locales"])) { Object.values(themeOptions["locales"]!).forEach( (localeConfig: Record) => { DEPRECATED_THEME_OPTIONS.forEach(([deprecatedOption, newOption]) => @@ -244,7 +243,7 @@ export const convertThemeOptions = ( handleFooterOptions(localeConfig); // handle blog - if (typeof localeConfig["blog"] === "object" && localeConfig["blog"]) { + if (isPlainObject(localeConfig["blog"]) && localeConfig["blog"]) { handleBlogOptions(localeConfig["blog"] as Record); if (!plugins["blog"]) plugins["blog"] = true; } diff --git a/packages/theme/src/node/config/encrypt.ts b/packages/theme/src/node/config/encrypt.ts index 99f84ea8b2a8..646ef94bae83 100644 --- a/packages/theme/src/node/config/encrypt.ts +++ b/packages/theme/src/node/config/encrypt.ts @@ -1,3 +1,4 @@ +import { isArray, isString } from "@vuepress/shared"; import { hashSync } from "bcrypt-ts/node"; import { logger } from "../utils.js"; @@ -10,12 +11,11 @@ export const getEncryptConfig = (encrypt: EncryptOptions): EncryptConfig => { // handle global token if (encrypt.admin) - if (typeof encrypt.admin === "string") - result.admin = [hashSync(encrypt.admin)]; - else if (Array.isArray(encrypt.admin)) + if (isString(encrypt.admin)) result.admin = [hashSync(encrypt.admin)]; + else if (isArray(encrypt.admin)) result.admin = encrypt.admin .map((globalToken) => { - if (typeof globalToken === "string") return hashSync(globalToken); + if (isString(globalToken)) return hashSync(globalToken); logger.error(`You config "themeConfig.encrypt.admin", but your config is invalid. @@ -35,12 +35,12 @@ export const getEncryptConfig = (encrypt: EncryptOptions): EncryptConfig => { result.config = Object.fromEntries( Object.entries(encrypt.config) .map<[string, string[]] | null>(([key, tokens]) => { - if (typeof tokens === "string") return [key, [hashSync(tokens)]]; + if (isString(tokens)) return [key, [hashSync(tokens)]]; - if (Array.isArray(tokens)) { + if (isArray(tokens)) { const encryptedTokens = tokens .map((token) => { - if (typeof token === "string") return hashSync(token); + if (isString(token)) return hashSync(token); logger.error(`You config "themeConfig.encrypt.config", but your config is invalid. diff --git a/packages/theme/src/node/config/socialMedia.ts b/packages/theme/src/node/config/socialMedia.ts index c955ba74a402..a1a280e99e7b 100644 --- a/packages/theme/src/node/config/socialMedia.ts +++ b/packages/theme/src/node/config/socialMedia.ts @@ -1,3 +1,4 @@ +import { isArray, isString } from "@vuepress/shared"; import { fs } from "@vuepress/utils"; import { logger, TEMPLATE_FOLDER } from "../utils.js"; @@ -12,7 +13,7 @@ export const checkSocialMediaIcons = ( key: string, value: string | [string, string] ): string | false => { - if (typeof value === "string") { + if (isString(value)) { const templatePath = `${TEMPLATE_FOLDER}socialMediaIcons/${key.toLocaleLowerCase()}.svg`; if (fs.existsSync(templatePath)) { @@ -26,7 +27,7 @@ export const checkSocialMediaIcons = ( return false; } - if (Array.isArray(value)) { + if (isArray(value)) { // it’s a svg string if (value[1].startsWith(" ({ - key, - path: path || `/${key}/`, - })) || [] - : [], + blogType: isPlainObject(plugins.blog) + ? plugins.blog?.type?.map(({ key, path }) => ({ + key, + path: path || `/${key}/`, + })) || [] + : [], hasMultipleLanguages: Object.keys(locales).length > 1, supportPageview: Boolean( plugins.comment && plugins.comment.provider === "Waline" diff --git a/packages/theme/src/node/frontmatter/check.ts b/packages/theme/src/node/frontmatter/check.ts index 0868fdcc2a56..ebed45af22c5 100644 --- a/packages/theme/src/node/frontmatter/check.ts +++ b/packages/theme/src/node/frontmatter/check.ts @@ -1,3 +1,4 @@ +import { isString } from "@vuepress/shared"; import { logger } from "@vuepress/utils"; import { getCategory, getTag } from "vuepress-shared/node"; @@ -59,7 +60,7 @@ export const checkFrontmatter = (page: Page, isDebug: boolean): void => { // check string values ["title", "shortTitle", "containerClass"].forEach((key) => { - if (key in frontmatter && typeof frontmatter[key] !== "string") { + if (key in frontmatter && !isString(frontmatter[key])) { logger.warn( `"${key}" property in Page FrontMatter should be string.${ filePathRelative ? `\nFound in ${filePathRelative}` : "" diff --git a/packages/theme/src/node/plugins/autoCatalog.ts b/packages/theme/src/node/plugins/autoCatalog.ts index c7bf85d128fc..bd906aae1ae6 100644 --- a/packages/theme/src/node/plugins/autoCatalog.ts +++ b/packages/theme/src/node/plugins/autoCatalog.ts @@ -1,3 +1,4 @@ +import { isPlainObject } from "@vuepress/shared"; import { autoCatalogPlugin } from "vuepress-plugin-auto-catalog"; import type { Plugin } from "@vuepress/core"; @@ -11,5 +12,5 @@ export const getAutoCatalogPlugin = ( ): Plugin | null => { if (autoCatalog === false) return null; - return autoCatalogPlugin(typeof autoCatalog === "object" ? autoCatalog : {}); + return autoCatalogPlugin(isPlainObject(autoCatalog) ? autoCatalog : {}); }; diff --git a/packages/theme/src/node/plugins/components.ts b/packages/theme/src/node/plugins/components.ts index fbf77f040d5c..5fccc4f5a85d 100644 --- a/packages/theme/src/node/plugins/components.ts +++ b/packages/theme/src/node/plugins/components.ts @@ -1,3 +1,4 @@ +import { isString } from "@vuepress/shared"; import { componentsPlugin } from "vuepress-plugin-components"; import type { ComponentOptions } from "vuepress-plugin-components"; @@ -26,9 +27,7 @@ export const getComponentsPlugin = ( fontIcon: { ...(options.iconAssets ? { assets: options.iconAssets } : {}), }, - ...(typeof options.iconPrefix === "string" - ? { prefix: options.iconPrefix } - : {}), + ...(isString(options.iconPrefix) ? { prefix: options.iconPrefix } : {}), ...componentOptions, }, rootComponents: { diff --git a/packages/theme/src/node/plugins/copyright.ts b/packages/theme/src/node/plugins/copyright.ts index 0c195a56cff7..fcd3a1594bbd 100644 --- a/packages/theme/src/node/plugins/copyright.ts +++ b/packages/theme/src/node/plugins/copyright.ts @@ -1,3 +1,4 @@ +import { isPlainObject } from "@vuepress/shared"; import { copyrightPlugin } from "vuepress-plugin-copyright2"; import { getAuthor } from "vuepress-shared/node"; @@ -21,6 +22,6 @@ export const getCopyrightPlugin = ( getAuthor(page.frontmatter.author)?.[0]?.name || getAuthor(themeData.author)?.[0]?.name || "", - ...(typeof options === "object" ? options : { global: true }), + ...(isPlainObject(options) ? options : { global: true }), }); }; diff --git a/packages/theme/src/node/plugins/pwa.ts b/packages/theme/src/node/plugins/pwa.ts index 52b2482df052..e0e40a1f4334 100644 --- a/packages/theme/src/node/plugins/pwa.ts +++ b/packages/theme/src/node/plugins/pwa.ts @@ -1,3 +1,4 @@ +import { isPlainObject } from "@vuepress/shared"; import { pwaPlugin } from "vuepress-plugin-pwa2"; import type { Plugin } from "@vuepress/core"; @@ -9,5 +10,5 @@ export const getPWAPlugin = ( ): Plugin | null => { if (!options) return null; - return pwaPlugin(typeof options === "object" ? options : {}, legacy); + return pwaPlugin(isPlainObject(options) ? options : {}, legacy); }; diff --git a/packages/theme/src/node/plugins/seo.ts b/packages/theme/src/node/plugins/seo.ts index f28a7f61689a..5e619a80df87 100644 --- a/packages/theme/src/node/plugins/seo.ts +++ b/packages/theme/src/node/plugins/seo.ts @@ -1,3 +1,4 @@ +import { isPlainObject } from "@vuepress/shared"; import { seoPlugin } from "vuepress-plugin-seo2"; import type { Page, Plugin } from "@vuepress/core"; @@ -10,7 +11,7 @@ export const getSEOPlugin = ( legacy = false ): Plugin | null => { if (seo === false) return null; - const seoOptions = typeof seo === "object" ? seo : {}; + const seoOptions = isPlainObject(seo) ? seo : {}; // disable seo if `hostname` is not set and no options for seo plugin if (!Object.keys(seoOptions).length && !hostname) return null; diff --git a/packages/theme/src/node/plugins/sitemap.ts b/packages/theme/src/node/plugins/sitemap.ts index ee357ee2a2a4..4121d8fef130 100644 --- a/packages/theme/src/node/plugins/sitemap.ts +++ b/packages/theme/src/node/plugins/sitemap.ts @@ -1,3 +1,4 @@ +import { isPlainObject } from "@vuepress/shared"; import { sitemapPlugin } from "vuepress-plugin-sitemap2"; import type { Plugin } from "@vuepress/core"; @@ -10,7 +11,7 @@ export const getSitemapPlugin = ( ): Plugin | null => { if (options === false) return null; - const sitemapOptions = typeof options === "object" ? options : {}; + const sitemapOptions = isPlainObject(options) ? options : {}; // disable sitemap if `hostname` is not set and no options for sitemap plugin if (!Object.keys(sitemapOptions).length && !hostname) return null; diff --git a/packages/theme/src/node/plugins/use.ts b/packages/theme/src/node/plugins/use.ts index 5889823d266f..d95a2c1bc9c5 100644 --- a/packages/theme/src/node/plugins/use.ts +++ b/packages/theme/src/node/plugins/use.ts @@ -1,3 +1,4 @@ +import { isPlainObject } from "@vuepress/shared"; import { useReadingTimePlugin } from "vuepress-plugin-reading-time2"; import { useSassPalettePlugin } from "vuepress-plugin-sass-palette"; @@ -39,7 +40,7 @@ export const usePlugin = ( if (plugins.readingTime !== false) useReadingTimePlugin( app, - typeof plugins.readingTime === "object" ? plugins.readingTime : {} + isPlainObject(plugins.readingTime) ? plugins.readingTime : {} ); useSassPalettePlugin(app, { diff --git a/packages/theme/src/node/prepare/sidebar/sidebar.ts b/packages/theme/src/node/prepare/sidebar/sidebar.ts index baea1a72b10a..cf5fd7081bba 100644 --- a/packages/theme/src/node/prepare/sidebar/sidebar.ts +++ b/packages/theme/src/node/prepare/sidebar/sidebar.ts @@ -1,4 +1,9 @@ -import { ensureEndingSlash, removeLeadingSlash } from "@vuepress/shared"; +import { + ensureEndingSlash, + isArray, + isPlainObject, + removeLeadingSlash, +} from "@vuepress/shared"; import { getSidebarInfo } from "./info.js"; import { getSorter } from "./sorter.js"; @@ -20,7 +25,7 @@ const getGeneratePaths = ( ): string[] => { const result: string[] = []; - if (!Array.isArray(sidebarConfig)) { + if (!isArray(sidebarConfig)) { logger.error( `Expecting array, but getting invalid sidebar config${ prefix ? ` under ${prefix}` : "" @@ -32,7 +37,7 @@ const getGeneratePaths = ( sidebarConfig.forEach((item) => { // it’s a sidebar group config - if (typeof item === "object" && "children" in item) { + if (isPlainObject(item) && "children" in item) { const childPrefix = `${prefix}${item.prefix || ""}`; // the children needs to be generated @@ -66,12 +71,11 @@ export const getSidebarData = ( // exact generate sidebar paths Object.entries(themeData.locales).forEach(([localePath, { sidebar }]) => { - if (Array.isArray(sidebar)) - generatePaths.push(...getGeneratePaths(sidebar)); - else if (typeof sidebar === "object") + if (isArray(sidebar)) generatePaths.push(...getGeneratePaths(sidebar)); + else if (isPlainObject(sidebar)) Object.entries(sidebar).forEach(([prefix, config]) => { if (config === "structure") generatePaths.push(prefix); - else if (Array.isArray(config)) + else if (isArray(config)) generatePaths.push( ...getGeneratePaths(config).map((item) => `${prefix}${item}`) ); diff --git a/packages/theme/src/node/prepare/sidebar/sorter.ts b/packages/theme/src/node/prepare/sidebar/sorter.ts index 0fb6cec33bee..d4bacdae5223 100644 --- a/packages/theme/src/node/prepare/sidebar/sorter.ts +++ b/packages/theme/src/node/prepare/sidebar/sorter.ts @@ -1,3 +1,5 @@ +import { isArray, isFunction, isString } from "@vuepress/shared"; + import type { SidebarInfo, SidebarSorter, @@ -122,15 +124,15 @@ const sortKeyMap: Record = { const availableKeywords = Object.keys(sortKeyMap); export const getSorter = (sorter?: SidebarSorter): SidebarSorterFunction[] => { - if (typeof sorter === "string" && availableKeywords.includes(sorter)) + if (isString(sorter) && availableKeywords.includes(sorter)) return [sortKeyMap[sorter]]; - if (typeof sorter === "function") return [sorter]; + if (isFunction(sorter)) return [sorter]; - if (Array.isArray(sorter)) { + if (isArray(sorter)) { const result = sorter - .map((item) => (typeof item === "string" ? sortKeyMap[item] : item)) - .filter((item) => typeof item === "function"); + .map((item) => (isString(item) ? sortKeyMap[item] : item)) + .filter((item) => isFunction(item)); if (result.length) return result; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 47e175fb298e..09ece0a982e3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -995,6 +995,7 @@ importers: specifiers: '@vuepress/client': 2.0.0-beta.60 '@vuepress/core': 2.0.0-beta.60 + '@vuepress/shared': 2.0.0-beta.60 '@vuepress/utils': 2.0.0-beta.60 balloon-css: ^1.2.0 vue: ^3.2.45 @@ -1003,6 +1004,7 @@ importers: vuepress-shared: workspace:* dependencies: '@vuepress/client': 2.0.0-beta.60 + '@vuepress/shared': 2.0.0-beta.60 '@vuepress/utils': 2.0.0-beta.60 balloon-css: 1.2.0 vue: 3.2.45 @@ -1181,6 +1183,7 @@ importers: specifiers: '@vuepress/client': 2.0.0-beta.60 '@vuepress/core': 2.0.0-beta.60 + '@vuepress/shared': 2.0.0-beta.60 '@vuepress/utils': 2.0.0-beta.60 '@vueuse/core': ^9.9.0 photoswipe: ^5.3.4 @@ -1190,6 +1193,7 @@ importers: vuepress-shared: workspace:* dependencies: '@vuepress/client': 2.0.0-beta.60 + '@vuepress/shared': 2.0.0-beta.60 '@vuepress/utils': 2.0.0-beta.60 '@vueuse/core': 9.9.0_vue@3.2.45 photoswipe: 5.3.4 @@ -1274,11 +1278,13 @@ importers: '@vuepress/bundler-vite': 2.0.0-beta.60 '@vuepress/bundler-webpack': 2.0.0-beta.60 '@vuepress/core': 2.0.0-beta.60 + '@vuepress/shared': 2.0.0-beta.60 '@vuepress/utils': 2.0.0-beta.60 chokidar: ^3.5.3 sass: ^1.57.1 vuepress-shared: workspace:* dependencies: + '@vuepress/shared': 2.0.0-beta.60 '@vuepress/utils': 2.0.0-beta.60 chokidar: 3.5.3 sass: 1.57.1 @@ -1293,6 +1299,7 @@ importers: '@types/body-scroll-lock': ^3.1.0 '@vuepress/client': 2.0.0-beta.60 '@vuepress/core': 2.0.0-beta.60 + '@vuepress/shared': 2.0.0-beta.60 '@vuepress/utils': 2.0.0-beta.60 '@vueuse/core': ^9.9.0 body-scroll-lock: ^3.1.5 @@ -1304,6 +1311,7 @@ importers: vuepress-shared: workspace:* dependencies: '@vuepress/client': 2.0.0-beta.60 + '@vuepress/shared': 2.0.0-beta.60 '@vuepress/utils': 2.0.0-beta.60 '@vueuse/core': 9.9.0_vue@3.2.45 body-scroll-lock: 3.1.5