diff --git a/README.md b/README.md index c4a6da6..18e6bab 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,31 @@ export default defineUniPages({ 现在所有的 page 都会被自动发现! -### SFC 自定义块用于路由数据 +### 页面调用方式(1): `definePage` 宏定义路由数据 +```html + + + + + +``` + +### 页面调用方式(2):SFC 自定义块用于路由数据 通过添加一个 `` 块到 SFC 中来添加路由元数据。这将会在路由生成后直接添加到路由中,并且会覆盖。 diff --git a/packages/core/README.md b/packages/core/README.md index 07dbc03..0bdcd7d 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -44,7 +44,31 @@ export default defineUniPages({ Now all pages will be found automatically! -### SFC custom block for Route Data +### Page usage (1): `definePage` macro define page options +```html + + + + + +``` + +### Page usage (2): SFC custom block for Route Data Add route meta to the route by adding a `` block to the SFC. This will be directly added to the route after it is generated, and will override it. diff --git a/packages/core/client.d.ts b/packages/core/client.d.ts index 5766841..814f615 100644 --- a/packages/core/client.d.ts +++ b/packages/core/client.d.ts @@ -2,3 +2,7 @@ declare module 'virtual:uni-pages' { export const pages: import('.').PageMetaDatum[] export const subPackages: import('.').SubPackage[] } + +declare module globalThis { + export const definePage: import('.').DefinePage +} diff --git a/packages/core/package.json b/packages/core/package.json index de3d6e4..74415bc 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -41,19 +41,28 @@ "stub": "unbuild --stub" }, "dependencies": { + "@babel/core": "^7.24.3", + "@babel/generator": "^7.24.1", + "@babel/traverse": "^7.24.1", + "@babel/types": "^7.24.0", "@uni-helper/uni-env": "^0.1.1", "@vue/compiler-sfc": "^3.4.21", + "ast-kit": "^0.12.1", "chokidar": "^3.6.0", "debug": "^4.3.4", "fast-glob": "^3.3.2", "json5": "^2.2.3", "lodash-unified": "^1.0.3", "magic-string": "^0.30.8", + "tsx": "^4.7.1", "unconfig": "^0.3.11", "yaml": "^2.4.0" }, "devDependencies": { "@antfu/utils": "^0.7.7", + "@types/babel__core": "^7.20.5", + "@types/babel__generator": "^7.6.8", + "@types/babel__traverse": "^7.20.5", "@types/debug": "^4.1.12", "@types/node": "^20.11.24" } diff --git a/packages/core/src/child-process.ts b/packages/core/src/child-process.ts new file mode 100644 index 0000000..36eeba9 --- /dev/null +++ b/packages/core/src/child-process.ts @@ -0,0 +1,18 @@ +import type { SpawnOptionsWithoutStdio } from 'node:child_process' +import { spawn } from 'node:child_process' +import process from 'node:process' + +export function runProcess(command: string, args: string[] = [], options?: SpawnOptionsWithoutStdio) { + return new Promise((resolve, reject) => { + const child = spawn(command, args, { + env: { + ...process.env, + }, + ...options, + }) + const output = [] as string[] + child.stdout.on('data', chunk => output.push(chunk)) + child.on('close', () => resolve(output.join('').trim())) + child.on('error', error => reject(error)) + }) +} diff --git a/packages/core/src/constant.ts b/packages/core/src/constant.ts index e3eafdb..ee13441 100644 --- a/packages/core/src/constant.ts +++ b/packages/core/src/constant.ts @@ -4,3 +4,5 @@ export const RESOLVED_MODULE_ID_VIRTUAL = `\0${MODULE_ID_VIRTUAL}` export const OUTPUT_NAME = 'pages.json' export const FILE_EXTENSIONS = ['vue', 'nvue', 'uvue'] + +export const DEFINE_PAGE = 'definePage' diff --git a/packages/core/src/context.ts b/packages/core/src/context.ts index f5cc0e2..f353602 100644 --- a/packages/core/src/context.ts +++ b/packages/core/src/context.ts @@ -2,7 +2,6 @@ import path from 'node:path' import process from 'node:process' import type { FSWatcher } from 'chokidar' import type { Logger, ViteDevServer } from 'vite' -import { normalizePath } from 'vite' import { loadConfig } from 'unconfig' import { slash } from '@antfu/utils' import dbg from 'debug' @@ -10,30 +9,25 @@ import { platform } from '@uni-helper/uni-env' import type { PagesConfig } from './config/types' import type { PageMetaDatum, PagePath, ResolvedOptions, SubPageMetaDatum, UserOptions } from './types' import { writeDeclaration } from './declaration' - import { debug, invalidatePagesModule, isTargetFile, mergePageMetaDataArray, - useCachedPages, } from './utils' import { resolveOptions } from './options' import { checkPagesJsonFile, getPageFiles, writeFileSync } from './files' -import { getRouteBlock, getRouteSfcBlock } from './customBlock' import { OUTPUT_NAME } from './constant' +import { Page } from './page' let lsatPagesJson = '' -const { setCache, hasChanged } = useCachedPages() export class PageContext { private _server: ViteDevServer | undefined pagesGlobConfig: PagesConfig | undefined pagesConfigSourcePaths: string[] = [] - pagesPath: PagePath[] = [] - subPagesPath: Record = {} pageMetaData: PageMetaDatum[] = [] subPageMetaData: SubPageMetaDatum[] = [] @@ -46,6 +40,9 @@ export class PageContext { withUniPlatform = false + pages = new Map() + subPages = new Map>() + constructor(userOptions: UserOptions, viteRoot: string = process.cwd()) { this.rawOptions = userOptions this.root = slash(viteRoot) @@ -79,18 +76,34 @@ export class PageContext { return { dir, files: getPagePaths(dir, this.options) } }) - this.pagesPath = pageDirFiles.map(page => page.files).flat() - debug.pages(this.pagesPath) + const paths = pageDirFiles.map(page => page.files).flat() + debug.pages(paths) + + const pages: [string, Page][] = paths.map((path) => { + const page = this.pages.get(path.absolutePath) || new Page(this, path) + return [path.absolutePath, page] + }) + + this.pages = new Map(pages) } async scanSubPages() { - const subPagesPath: Record = {} + const paths: Record = {} + const subPages = new Map>() for (const dir of this.options.subPackages) { const pagePaths = getPagePaths(dir, this.options) - subPagesPath[dir] = pagePaths + paths[dir] = pagePaths + + const pages: [string, Page][] = pagePaths.map((path) => { + const page = this.subPages.get(dir)?.get(path.absolutePath) || new Page(this, path) + return [path.absolutePath, page] + }) + + subPages.set(dir, new Map(pages)) } - this.subPagesPath = subPagesPath - debug.subPages(this.subPagesPath) + debug.subPages(JSON.stringify(paths, null, 2)) + + this.subPages = subPages } setupViteServer(server: ViteDevServer) { @@ -167,23 +180,6 @@ export class PageContext { }) } - async parsePage(page: PagePath): Promise { - const { relativePath, absolutePath } = page - const routeSfcBlock = await getRouteSfcBlock(absolutePath) - const routeBlock = await getRouteBlock(absolutePath, routeSfcBlock, this.options) - setCache(absolutePath, routeSfcBlock) - const relativePathWithFileName = relativePath.replace(path.extname(relativePath), '') - const pageMetaDatum: PageMetaDatum = { - path: normalizePath(relativePathWithFileName), - type: routeBlock?.attr.type ?? 'page', - } - - if (routeBlock) - Object.assign(pageMetaDatum, routeBlock.content) - - return pageMetaDatum - } - /** * parse pages rules && set page type * @param pages page path array @@ -191,8 +187,13 @@ export class PageContext { * @param overrides custom page config * @returns pages rules */ - async parsePages(pages: PagePath[], type: 'main' | 'sub', overrides?: PageMetaDatum[]) { - const generatedPageMetaData = await Promise.all(pages.map(async page => await this.parsePage(page))) + async parsePages(pages: Map, type: 'main' | 'sub', overrides?: PageMetaDatum[]) { + const generatedPageMetaData: PageMetaDatum[] = [] + for (const [_, page] of pages) { + const opt = await page.getOptions() + generatedPageMetaData.push(opt) + } + const customPageMetaData = overrides || [] const result = customPageMetaData.length @@ -231,7 +232,7 @@ export class PageContext { } async mergePageMetaData() { - const pageMetaData = await this.parsePages(this.pagesPath, 'main', this.pagesGlobConfig?.pages) + const pageMetaData = await this.parsePages(this.pages, 'main', this.pagesGlobConfig?.pages) this.pageMetaData = pageMetaData debug.pages(this.pageMetaData) } @@ -240,7 +241,7 @@ export class PageContext { const subPageMaps: Record = {} const subPackages = this.pagesGlobConfig?.subPackages || [] - for (const [dir, pages] of Object.entries(this.subPagesPath)) { + for (const [dir, pages] of this.subPages) { const root = path.basename(dir) const globPackage = subPackages?.find(v => v.root === root) @@ -260,9 +261,24 @@ export class PageContext { debug.subPages(this.subPageMetaData) } + private getPageByPath(absolutePath: string) { + const page = this.pages.get(absolutePath) + if (page) + return page + + for (const [_, pages] of this.subPages) { + const subPage = pages.get(absolutePath) + if (subPage) + return subPage + } + + return undefined + } + async updatePagesJSON(filepath?: string) { if (filepath) { - if (!await hasChanged(filepath)) { + const page = this.getPageByPath(filepath) + if (page && !await page.hasChanged()) { debug.cache(`The route block on page ${filepath} did not send any changes, skipping`) return false } @@ -311,6 +327,8 @@ export class PageContext { lsatPagesJson = pagesJson this.options.onAfterWriteFile(this) + + debug.pages('updatePagesJSON DONE.') return true } @@ -328,12 +346,13 @@ export class PageContext { return JSON.stringify(this.subPageMetaData, null, 2) } - generateDeclaration() { + async generateDeclaration() { if (!this.options.dts) return debug.declaration('generating') - return writeDeclaration(this, this.options.dts) + await writeDeclaration(this, this.options.dts) + debug.declaration('done.') } } diff --git a/packages/core/src/customBlock.ts b/packages/core/src/customBlock.ts deleted file mode 100644 index 8df8fb9..0000000 --- a/packages/core/src/customBlock.ts +++ /dev/null @@ -1,88 +0,0 @@ -import fs from 'node:fs' -import JSON5 from 'json5' -import { parse as YAMLParser } from 'yaml' -import { parse as VueParser } from '@vue/compiler-sfc' -import type { SFCBlock, SFCDescriptor } from '@vue/compiler-sfc' -import { debug } from './utils' -import type { CustomBlock, ResolvedOptions } from './types' - -export async function parseSFC(code: string): Promise { - try { - return ( - VueParser(code, { - pad: 'space', - }).descriptor - // for @vue/compiler-sfc ^2.7 - || (VueParser as any)({ - source: code, - }) - ) - } - catch (error) { - throw new Error(`[vite-plugin-uni-pages] Vue3's "@vue/compiler-sfc" is required. \nOriginal error: \n${error}`) - } -} - -export function parseCustomBlock( - block: SFCBlock, - filePath: string, - options: ResolvedOptions, -): CustomBlock | undefined { - const lang = block.lang ?? options.routeBlockLang - const attr = { - type: 'page', - ...block.attrs, - } - let content: Record | undefined - debug.routeBlock(`use ${lang} parser`) - - if (lang === 'json5' || lang === 'jsonc') { - try { - content = JSON5.parse(block.content) - } - catch (err: any) { - throw new Error( - `Invalid JSON5 format of <${block.type}> content in ${filePath}\n${err.message}`, - ) - } - } - else if (lang === 'json') { - try { - content = JSON.parse(block.content) - } - catch (err: any) { - throw new Error( - `Invalid JSON format of <${block.type}> content in ${filePath}\n${err.message}`, - ) - } - } - else if (lang === 'yaml' || lang === 'yml') { - try { - content = YAMLParser(block.content) - } - catch (err: any) { - throw new Error( - `Invalid YAML format of <${block.type}> content in ${filePath}\n${err.message}`, - ) - } - } - return { - attr, - content: content ?? {}, - } -} - -export async function getRouteSfcBlock(path: string): Promise { - const content = fs.readFileSync(path, 'utf8') - - const parsedSFC = await parseSFC(content) - const blockStr = parsedSFC?.customBlocks.find(b => b.type === 'route') - - return blockStr -} - -export async function getRouteBlock(path: string, blockStr: SFCBlock | undefined, options: ResolvedOptions): Promise { - if (!blockStr) - return - return parseCustomBlock(blockStr, path, options) -} diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 3f2a07d..d04ac36 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -8,11 +8,14 @@ import chokidar from 'chokidar' import type { UserOptions } from './types' import { PageContext } from './context' import { + DEFINE_PAGE, MODULE_ID_VIRTUAL, OUTPUT_NAME, RESOLVED_MODULE_ID_VIRTUAL, } from './constant' import { checkPagesJsonFile } from './files' +import { findMacro } from './page' +import { isTargetFile, parseSFC } from './utils' export * from './config' export * from './types' @@ -21,7 +24,7 @@ export * from './context' export * from './utils' export * from './files' export * from './options' -export * from './customBlock' +export * from './page' async function restart() { return new Promise((resolve) => { @@ -78,17 +81,35 @@ export function VitePluginUniPages(userOptions: UserOptions = {}): Plugin { }, // Applet do not support custom route block, so we need to remove the route block here async transform(code: string, id: string) { - if (!/\.n?vue$/.test(id) && !code.includes('')) + if (!isTargetFile(id)) return null + + const sfc = await parseSFC(code, { filename: id }) + + const macro = findMacro(sfc.scriptSetup) + const routeBlock = sfc.customBlocks.find(block => block.type === 'route') + + if (!macro && !routeBlock) + return null + + if (macro && routeBlock) + throw new Error(`mixed ${DEFINE_PAGE}() and is not allowed`) + const s = new MagicString(code) - const routeBlockMatches = s.original.matchAll( - /]*>([\s\S]*?)<\/route>/g, - ) - - for (const match of routeBlockMatches) { - const index = match.index! - const length = match[0].length - s.remove(index, index + length) + + if (macro) + s.remove(macro.start!, macro.end!) + + if (routeBlock) { + const routeBlockMatches = s.original.matchAll( + /]*>([\s\S]*?)<\/route>/g, + ) + + for (const match of routeBlockMatches) { + const index = match.index! + const length = match[0].length + s.remove(index, index + length) + } } if (s.hasChanged()) { diff --git a/packages/core/src/page.ts b/packages/core/src/page.ts new file mode 100644 index 0000000..0b642a6 --- /dev/null +++ b/packages/core/src/page.ts @@ -0,0 +1,229 @@ +import { existsSync, readFileSync } from 'node:fs' +import { dirname, extname, join } from 'node:path' +import process from 'node:process' +import type { SFCDescriptor, SFCScriptBlock } from '@vue/compiler-sfc' +import { babelParse, isCallOf } from 'ast-kit' +import * as t from '@babel/types' +import generate from '@babel/generator' +import JSON5 from 'json5' +import { parse as YAMLParser } from 'yaml' +import { normalizePath } from 'vite' +import traverse from '@babel/traverse' +import type { PageContext } from './context' +import { debug, parseSFC } from './utils' +import type { DefinePageOptions, PageMetaDatum, PagePath, RouteBlockLang } from './types' +import { DEFINE_PAGE } from './constant' +import { runProcess } from './child-process' + +export class Page { + ctx: PageContext + + file: PagePath + + private rawOptions: string = '' + private options: PageMetaDatum | undefined + + constructor(ctx: PageContext, file: PagePath) { + this.ctx = ctx + this.file = file + } + + async getOptions(forceUpdate = false) { + if (forceUpdate || !this.options) + await this.readOptions() + + return this.options! + } + + async hasChanged() { + const { hasChanged } = await this.readOptions() + return hasChanged + } + + async readOptions() { + try { + const { relativePath, absolutePath } = this.file + + // eslint-disable-next-line unused-imports/no-unused-vars + const { path, ...others } = await readPageOptionsFromFile(absolutePath, this.ctx.options.routeBlockLang) + this.options = { + path: normalizePath(relativePath.replace(extname(relativePath), '')), + ...others, + } + + const raw = (this.options ? JSON.stringify(this.options) : '') + const hasChanged = this.rawOptions !== raw + this.rawOptions = raw + return { + options: this.options, + hasChanged, + } + } + catch (err: any) { + throw new Error(`Read page options fail in ${this.file.relativePath}\n${err.message}`) + } + } +} + +async function readPageOptionsFromFile(path: string, routeBlockLang: RouteBlockLang) { + const content = readFileSync(path, 'utf-8') + const sfc = await parseSFC(content) + + const macroOptions = await readPageOptionsFromMacro(path, sfc) + if (macroOptions) + return macroOptions + + const blockOptions = await readPageOptionsFromBlock(path, routeBlockLang, sfc) + if (blockOptions) + return blockOptions + + return {} as DefinePageOptions +} + +async function readPageOptionsFromMacro(path: string, sfc?: SFCDescriptor) { + if (!sfc) { + const content = readFileSync(path, 'utf-8') + sfc = await parseSFC(content) + } + + const { macro, imports } = findMacroWithImports(sfc.scriptSetup) + + if (!macro) + return + + if (sfc?.customBlocks.find(b => b.type === 'route')) + throw new Error(`mixed ${DEFINE_PAGE}() and is not allowed`) + + const [arg] = macro.arguments as [t.Expression] + + if (!arg) + return + + const options: DefinePageOptions = await runExpressionByTSX({ file: path, exp: arg, imports }) + + return options +} + +async function readPageOptionsFromBlock(path: string, routeBlockLang: RouteBlockLang, sfc?: SFCDescriptor) { + if (!sfc) { + const content = readFileSync(path, 'utf-8') + sfc = await parseSFC(content) + } + + const block = sfc.customBlocks.find(b => b.type === 'route') + + if (!block) + return + + const lang = (block.lang ?? routeBlockLang) as RouteBlockLang + + debug.routeBlock(`use ${lang} parser`) + + let options = {} as PageMetaDatum + + if (['json5', 'jsonc', 'json'].includes(lang)) + options = JSON5.parse(block.content) as PageMetaDatum + else if (['yaml', 'yml'].includes(lang)) + options = YAMLParser(block.content) as PageMetaDatum + + if (!options.type) + options.type = (typeof block.attrs.type === 'string') && block.attrs.type.length ? block.attrs.type : 'page' + + return options +} + +function findMacroWithImports(scriptSetup: SFCScriptBlock | null) { + const empty = { imports: [], macro: undefined } as { + imports: t.ImportDeclaration[] + macro: t.CallExpression | undefined + } + + if (!scriptSetup) + return empty + + const parsed = babelParse(scriptSetup.content, scriptSetup.lang || 'js', { + plugins: [['importAttributes', { deprecatedAssertSyntax: true }]], + }) + + const stmts = parsed.body + + const nodes = stmts + .map((raw: t.Node) => { + let node = raw + if (raw.type === 'ExpressionStatement') + node = raw.expression + return isCallOf(node, DEFINE_PAGE) ? node : undefined + }) + .filter((node): node is t.CallExpression => !!node) + + if (!nodes.length) + return empty + + if (nodes.length > 1) + throw new Error(`duplicate ${DEFINE_PAGE}() call`) + + const macro = nodes[0] + + const [arg] = macro.arguments + + if (arg && !t.isFunctionExpression(arg) && !t.isArrowFunctionExpression(arg) && !t.isObjectExpression(arg)) + throw new Error(`${DEFINE_PAGE}() only accept argument in function or object`) + + const imports = stmts + .map((node: t.Node) => (node.type === 'ImportDeclaration') ? node : undefined) + .filter((node): node is t.ImportDeclaration => !!node) + + return { + imports, + macro, + } +} + +export function findMacro(scriptSetup: SFCScriptBlock | null) { + return findMacroWithImports(scriptSetup).macro +} + +async function runExpressionByTSX(options: { file: string, exp: t.Expression, imports: t.ImportDeclaration[] }) { + const { + file, + exp, + imports, + } = options + + const tsx = join(process.cwd(), 'node_modules', '.bin', 'tsx') + + if (!existsSync(tsx)) + throw new Error(`[vite-plugin-uni-pages] "tsx" is required for function argument of definePage macro`) + + const ast = t.file(t.program([ + t.expressionStatement(exp), + ])) + + // 删除代码里的 console + traverse(ast, { + CallExpression: (path, _parent) => { + if (path.node.callee.type === 'MemberExpression' && (path.node.callee.object as any).name === 'console') + path.remove() + }, + }) + + const code = generate(ast).code + + const cwd = dirname(file) + + let script = '' + + for (const imp of imports) + script += `${generate(imp).code}\n` + + script += t.isFunctionExpression(exp) || t.isArrowFunctionExpression(exp) + ? `let fn=${code}\nPromise.resolve(fn()).then(res => console.log(JSON.stringify(res)))` + : `let obj=${code}\nconsole.log(JSON.stringify(obj))` + + const result = await runProcess(tsx, ['-e', script], { cwd }) + + debug.definePage(`\nSCRIPT: \n${script}`) + debug.definePage(`RESULT: \n${result}`) + + return JSON.parse(result) +} diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index f727612..8218605 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -12,6 +12,8 @@ export type debugType = keyof typeof debug export type ConfigSource = string | LoadConfigSource | LoadConfigSource[] +export type RouteBlockLang = 'json5' | 'jsonc' | 'json' | 'yaml' | 'yml' + export interface Options { /** @@ -68,7 +70,7 @@ export interface Options { * Set the default route block parser, or use `` in SFC route block * @default 'json5' */ - routeBlockLang: 'json5' | 'json' | 'yaml' | 'yml' + routeBlockLang: RouteBlockLang /** * minify the `pages.json` @@ -140,3 +142,17 @@ export interface SubPageMetaDatum { root: string pages: PageMetaDatum[] } + +export interface DefinePageOptions extends Partial { + /** + * 配置页面路径 + * @deprecated 无效,将会根据文件路径自动生成 + */ + path?: string +} + +export type MaybeCallable = T | (() => T | Promise) + +export declare function definePage(options: MaybeCallable): void + +export type DefinePage = typeof definePage diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index 3a5173d..a82604d 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -1,10 +1,10 @@ import Debug from 'debug' -import { type ModuleNode, type ViteDevServer, normalizePath } from 'vite' +import type { ModuleNode, ViteDevServer } from 'vite' import { groupBy } from 'lodash-unified' -import type { SFCBlock } from '@vue/compiler-sfc' +import type { SFCDescriptor, SFCParseOptions } from '@vue/compiler-sfc' +import { parse as VueParser } from '@vue/compiler-sfc' import { FILE_EXTENSIONS, RESOLVED_MODULE_ID_VIRTUAL } from './constant' import type { PageMetaDatum } from './types' -import { getRouteSfcBlock } from './customBlock' export function invalidatePagesModule(server: ViteDevServer) { const { moduleGraph } = server @@ -19,6 +19,7 @@ export function invalidatePagesModule(server: ViteDevServer) { export const debug = { hmr: Debug('vite-plugin-uni-pages:hmr'), + definePage: Debug('vite-plugin-uni-pages:definePage'), routeBlock: Debug('vite-plugin-uni-pages:routeBlock'), options: Debug('vite-plugin-uni-pages:options'), pages: Debug('vite-plugin-uni-pages:pages'), @@ -57,29 +58,21 @@ export function mergePageMetaDataArray(pageMetaData: PageMetaDatum[]) { return result } -export function useCachedPages() { - const pages = new Map() - - function parseData(block?: SFCBlock) { - return { - content: block?.loc.source.trim() ?? '', - attr: block?.attrs ?? '', - } - } - - function setCache(filePath: string, routeBlock?: SFCBlock) { - pages.set(filePath, JSON.stringify(parseData(routeBlock))) +export async function parseSFC(code: string, options?: SFCParseOptions): Promise { + try { + return ( + VueParser(code, { + pad: 'space', + ...options, + }).descriptor + // for @vue/compiler-sfc ^2.7 + || (VueParser as any)({ + source: code, + ...options, + }) + ) } - - async function hasChanged(filePath: string, routeBlock?: SFCBlock) { - if (!routeBlock) - routeBlock = await getRouteSfcBlock(normalizePath(filePath)) - - return !pages.has(filePath) || JSON.stringify(parseData(routeBlock)) !== pages.get(filePath) - } - - return { - setCache, - hasChanged, + catch (error) { + throw new Error(`[vite-plugin-uni-pages] Vue3's "@vue/compiler-sfc" is required. \nOriginal error: \n${error}`) } } diff --git a/packages/playground/package.json b/packages/playground/package.json index f4fa8b8..507f7d8 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -14,7 +14,8 @@ "@dcloudio/uni-h5": "3.0.0-alpha-4000220240302002", "@dcloudio/uni-mp-weixin": "3.0.0-alpha-4000220240302002", "vue": "^3.4.21", - "vue-i18n": "^9.10.1" + "vue-i18n": "^9.10.1", + "yaml": "^2.4.0" }, "devDependencies": { "@dcloudio/types": "^3.4.8", @@ -22,6 +23,7 @@ "@dcloudio/uni-cli-shared": "3.0.0-alpha-4000220240302002", "@dcloudio/vite-plugin-uni": "3.0.0-alpha-4000220240302002", "@uni-helper/vite-plugin-uni-pages": "workspace:*", - "postcss": "^8.4.35" + "postcss": "^8.4.35", + "tsx": "^4.7.1" } } diff --git a/packages/playground/src/pages/macros/async-function.vue b/packages/playground/src/pages/macros/async-function.vue new file mode 100644 index 0000000..b645698 --- /dev/null +++ b/packages/playground/src/pages/macros/async-function.vue @@ -0,0 +1,22 @@ + + + diff --git a/packages/playground/src/pages/macros/function.vue b/packages/playground/src/pages/macros/function.vue new file mode 100644 index 0000000..b701ed7 --- /dev/null +++ b/packages/playground/src/pages/macros/function.vue @@ -0,0 +1,21 @@ + + + diff --git a/packages/playground/src/pages/macros/import-module.vue b/packages/playground/src/pages/macros/import-module.vue new file mode 100644 index 0000000..022b377 --- /dev/null +++ b/packages/playground/src/pages/macros/import-module.vue @@ -0,0 +1,15 @@ + + + diff --git a/packages/playground/src/pages/macros/import.vue b/packages/playground/src/pages/macros/import.vue new file mode 100644 index 0000000..ea98bd6 --- /dev/null +++ b/packages/playground/src/pages/macros/import.vue @@ -0,0 +1,15 @@ + + + diff --git a/packages/playground/src/pages/macros/nested-function.vue b/packages/playground/src/pages/macros/nested-function.vue new file mode 100644 index 0000000..c0234c5 --- /dev/null +++ b/packages/playground/src/pages/macros/nested-function.vue @@ -0,0 +1,24 @@ + + + diff --git a/packages/playground/src/pages/macros/object.vue b/packages/playground/src/pages/macros/object.vue new file mode 100644 index 0000000..4b4dab4 --- /dev/null +++ b/packages/playground/src/pages/macros/object.vue @@ -0,0 +1,14 @@ + + + diff --git a/packages/playground/src/pages/macros/remove-console.vue b/packages/playground/src/pages/macros/remove-console.vue new file mode 100644 index 0000000..b5a8963 --- /dev/null +++ b/packages/playground/src/pages/macros/remove-console.vue @@ -0,0 +1,14 @@ + + + diff --git a/packages/playground/src/pages/macros/utils.ts b/packages/playground/src/pages/macros/utils.ts new file mode 100644 index 0000000..4f68b48 --- /dev/null +++ b/packages/playground/src/pages/macros/utils.ts @@ -0,0 +1,3 @@ +export function randamText() { + return Math.random().toString(36).slice(-8) +} diff --git a/packages/playground/src/pages/macros/yaml.vue b/packages/playground/src/pages/macros/yaml.vue new file mode 100644 index 0000000..01a3131 --- /dev/null +++ b/packages/playground/src/pages/macros/yaml.vue @@ -0,0 +1,20 @@ + + + + diff --git a/packages/playground/src/uni-pages.d.ts b/packages/playground/src/uni-pages.d.ts index 32a1f53..329551a 100644 --- a/packages/playground/src/uni-pages.d.ts +++ b/packages/playground/src/uni-pages.d.ts @@ -3,7 +3,7 @@ // @ts-nocheck // Generated by vite-plugin-uni-pages -export interface NavigateToOptions { +interface NavigateToOptions { url: "/pages/index" | "/pages/A-top" | "/pages/i18n" | @@ -12,13 +12,21 @@ export interface NavigateToOptions { "/pages/test" | "/pages/blog/index" | "/pages/blog/post" | + "/pages/macros/async-function" | + "/pages/macros/function" | + "/pages/macros/import-module" | + "/pages/macros/import" | + "/pages/macros/nested-function" | + "/pages/macros/object" | + "/pages/macros/remove-console" | + "/pages/macros/yaml" | "/pages-sub/index" | "/pages-sub/about/index" | "/pages-sub/about/your"; } interface RedirectToOptions extends NavigateToOptions {} -export interface SwitchTabOptions { +interface SwitchTabOptions { } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9ec156b..e2f2e3a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,12 +41,27 @@ importers: packages/core: dependencies: + '@babel/core': + specifier: ^7.24.3 + version: 7.24.3 + '@babel/generator': + specifier: ^7.24.1 + version: 7.24.1 + '@babel/traverse': + specifier: ^7.24.1 + version: 7.24.1 + '@babel/types': + specifier: ^7.24.0 + version: 7.24.0 '@uni-helper/uni-env': specifier: ^0.1.1 version: 0.1.1(typescript@5.3.3)(vitest@1.3.1) '@vue/compiler-sfc': specifier: ^3.4.21 version: 3.4.21 + ast-kit: + specifier: ^0.12.1 + version: 0.12.1 chokidar: specifier: ^3.6.0 version: 3.6.0 @@ -65,6 +80,9 @@ importers: magic-string: specifier: ^0.30.8 version: 0.30.8 + tsx: + specifier: ^4.7.1 + version: 4.7.1 unconfig: specifier: ^0.3.11 version: 0.3.11 @@ -75,6 +93,15 @@ importers: '@antfu/utils': specifier: ^0.7.7 version: 0.7.7 + '@types/babel__core': + specifier: ^7.20.5 + version: 7.20.5 + '@types/babel__generator': + specifier: ^7.6.8 + version: 7.6.8 + '@types/babel__traverse': + specifier: ^7.20.5 + version: 7.20.5 '@types/debug': specifier: ^4.1.12 version: 4.1.12 @@ -102,6 +129,9 @@ importers: vue-i18n: specifier: ^9.10.1 version: 9.10.1(vue@3.4.21) + yaml: + specifier: ^2.4.0 + version: 2.4.0 devDependencies: '@dcloudio/types': specifier: ^3.4.8 @@ -121,6 +151,9 @@ importers: postcss: specifier: ^8.4.35 version: 8.4.35 + tsx: + specifier: ^4.7.1 + version: 4.7.1 packages/schema: devDependencies: @@ -314,6 +347,13 @@ packages: '@babel/highlight': 7.23.4 chalk: 2.4.2 + /@babel/code-frame@7.24.2: + resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.24.2 + picocolors: 1.0.0 + /@babel/compat-data@7.23.5: resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} engines: {node: '>=6.9.0'} @@ -324,11 +364,11 @@ packages: dependencies: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.23.5 - '@babel/generator': 7.23.6 + '@babel/generator': 7.24.1 '@babel/helper-compilation-targets': 7.23.6 '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) '@babel/helpers': 7.24.0 - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.1 '@babel/template': 7.24.0 '@babel/traverse': 7.24.0 '@babel/types': 7.24.0 @@ -340,8 +380,30 @@ packages: transitivePeerDependencies: - supports-color - /@babel/generator@7.23.6: - resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} + /@babel/core@7.24.3: + resolution: {integrity: sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.1 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3) + '@babel/helpers': 7.24.1 + '@babel/parser': 7.24.1 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.1 + '@babel/types': 7.24.0 + convert-source-map: 2.0.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + /@babel/generator@7.24.1: + resolution: {integrity: sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.24.0 @@ -461,6 +523,19 @@ packages: '@babel/helper-split-export-declaration': 7.22.6 '@babel/helper-validator-identifier': 7.22.20 + /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.3): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 + /@babel/helper-optimise-call-expression@7.22.5: resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} engines: {node: '>=6.9.0'} @@ -547,6 +622,16 @@ packages: transitivePeerDependencies: - supports-color + /@babel/helpers@7.24.1: + resolution: {integrity: sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.1 + '@babel/types': 7.24.0 + transitivePeerDependencies: + - supports-color + /@babel/highlight@7.23.4: resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} engines: {node: '>=6.9.0'} @@ -555,8 +640,17 @@ packages: chalk: 2.4.2 js-tokens: 4.0.0 - /@babel/parser@7.24.0: - resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==} + /@babel/highlight@7.24.2: + resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.0.0 + + /@babel/parser@7.24.1: + resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==} engines: {node: '>=6.0.0'} hasBin: true dependencies: @@ -613,12 +707,21 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true - /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.0): + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.3): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + + /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.3): resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.3 '@babel/helper-plugin-utils': 7.24.0 dev: true @@ -631,6 +734,15 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.3): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.0): resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} engines: {node: '>=6.9.0'} @@ -688,6 +800,15 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.3): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.0): resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: @@ -697,6 +818,15 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.3): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.24.0): resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} engines: {node: '>=6.9.0'} @@ -716,6 +846,15 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.3): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.0): resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: @@ -725,6 +864,15 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.3): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.0): resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: @@ -734,6 +882,15 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.3): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.0): resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: @@ -743,6 +900,15 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.3): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.0): resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: @@ -752,6 +918,15 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.3): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.0): resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: @@ -761,6 +936,15 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.3): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.0): resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} engines: {node: '>=6.9.0'} @@ -781,6 +965,16 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.3): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.24.0): resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} engines: {node: '>=6.9.0'} @@ -791,6 +985,16 @@ packages: '@babel/helper-plugin-utils': 7.24.0 dev: true + /@babel/plugin-syntax-typescript@7.23.3(@babel/core@7.24.3): + resolution: {integrity: sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 + dev: true + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} engines: {node: '>=6.9.0'} @@ -1469,7 +1673,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.23.5 - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.1 '@babel/types': 7.24.0 /@babel/traverse@7.24.0: @@ -1477,12 +1681,29 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/code-frame': 7.23.5 - '@babel/generator': 7.23.6 + '@babel/generator': 7.24.1 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.24.1 + '@babel/types': 7.24.0 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + /@babel/traverse@7.24.1: + resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.1 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.1 '@babel/types': 7.24.0 debug: 4.3.4 globals: 11.12.0 @@ -1566,7 +1787,7 @@ packages: '@ampproject/remapping': 2.3.0 '@babel/code-frame': 7.23.5 '@babel/core': 7.24.0 - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.1 '@babel/types': 7.24.0 '@dcloudio/uni-i18n': 3.0.0-alpha-4000220240302002 '@dcloudio/uni-shared': 3.0.0-alpha-4000220240302002 @@ -1713,8 +1934,8 @@ packages: /@dcloudio/uni-mp-compiler@3.0.0-alpha-4000220240302002(postcss@8.4.35)(rollup@3.29.4)(vue@3.4.21): resolution: {integrity: sha512-kQ02IVWozEdA4gi0txiN0GgzBslG1f+hDeq8cehjXFb+Cpanj8l3yjaR5y2lao7iynsYc7TTMeplpxZ6DmlY6A==} dependencies: - '@babel/generator': 7.23.6 - '@babel/parser': 7.24.0 + '@babel/generator': 7.24.1 + '@babel/parser': 7.24.1 '@babel/types': 7.24.0 '@dcloudio/uni-cli-shared': 3.0.0-alpha-4000220240302002(postcss@8.4.35)(rollup@3.29.4)(vue@3.4.21) '@dcloudio/uni-shared': 3.0.0-alpha-4000220240302002 @@ -2766,7 +2987,7 @@ packages: resolution: {integrity: sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.3 '@jest/types': 27.5.1 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 @@ -3615,7 +3836,7 @@ packages: /@types/babel__core@7.20.5: resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} dependencies: - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.1 '@babel/types': 7.24.0 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 @@ -3631,7 +3852,7 @@ packages: /@types/babel__template@7.4.4: resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} dependencies: - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.1 '@babel/types': 7.24.0 dev: true @@ -4157,14 +4378,14 @@ packages: '@babel/core': 7.24.0 '@babel/helper-module-imports': 7.22.15 '@babel/helper-plugin-utils': 7.24.0 - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.1 '@vue/compiler-sfc': 3.4.21 dev: true /@vue/compiler-core@3.3.11: resolution: {integrity: sha512-h97/TGWBilnLuRaj58sxNrsUU66fwdRKLOLQ9N/5iNDfp+DZhYH9Obhe0bXxhedl8fjAgpRANpiZfbgWyruQ0w==} dependencies: - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.1 '@vue/shared': 3.3.11 estree-walker: 2.0.2 source-map-js: 1.0.2 @@ -4172,7 +4393,7 @@ packages: /@vue/compiler-core@3.4.21: resolution: {integrity: sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==} dependencies: - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.1 '@vue/shared': 3.4.21 entities: 4.5.0 estree-walker: 2.0.2 @@ -4193,7 +4414,7 @@ packages: /@vue/compiler-sfc@3.3.11: resolution: {integrity: sha512-U4iqPlHO0KQeK1mrsxCN0vZzw43/lL8POxgpzcJweopmqtoYy9nljJzWDIQS3EfjiYhfdtdk9Gtgz7MRXnz3GA==} dependencies: - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.1 '@vue/compiler-core': 3.3.11 '@vue/compiler-dom': 3.3.11 '@vue/compiler-ssr': 3.3.11 @@ -4207,7 +4428,7 @@ packages: /@vue/compiler-sfc@3.4.21: resolution: {integrity: sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==} dependencies: - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.1 '@vue/compiler-core': 3.4.21 '@vue/compiler-dom': 3.4.21 '@vue/compiler-ssr': 3.4.21 @@ -4236,7 +4457,7 @@ packages: /@vue/reactivity-transform@3.3.11: resolution: {integrity: sha512-fPGjH0wqJo68A0wQ1k158utDq/cRyZNlFoxGwNScE28aUFOKFEnCBsvyD8jHn+0kd0UKVpuGuaZEQ6r9FJRqCg==} dependencies: - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.1 '@vue/compiler-core': 3.3.11 '@vue/shared': 3.3.11 estree-walker: 2.0.2 @@ -4477,6 +4698,14 @@ packages: /assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + /ast-kit@0.12.1: + resolution: {integrity: sha512-O+33g7x6irsESUcd47KdfWUrS2F6aGp9KeVJFGj0YjIznfXpBxVGjA0w+y/1OKqX4mFOfmZ9Xpf1ixPT4n9xxw==} + engines: {node: '>=16.14.0'} + dependencies: + '@babel/parser': 7.24.1 + pathe: 1.1.2 + dev: false + /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: true @@ -4503,18 +4732,18 @@ packages: possible-typed-array-names: 1.0.0 dev: false - /babel-jest@27.5.1(@babel/core@7.24.0): + /babel-jest@27.5.1(@babel/core@7.24.3): resolution: {integrity: sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: '@babel/core': ^7.8.0 dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.3 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 '@types/babel__core': 7.20.5 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 27.5.1(@babel/core@7.24.0) + babel-preset-jest: 27.5.1(@babel/core@7.24.3) chalk: 4.1.2 graceful-fs: 4.2.11 slash: 3.0.0 @@ -4581,35 +4810,35 @@ packages: - supports-color dev: true - /babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.0): + /babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.3): resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.0 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.0) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.0) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.0) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.0) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.0) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.0) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.0) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.0) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.0) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.0) - dev: true - - /babel-preset-jest@27.5.1(@babel/core@7.24.0): + '@babel/core': 7.24.3 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.3) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.3) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.3) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.3) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.3) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.3) + dev: true + + /babel-preset-jest@27.5.1(@babel/core@7.24.3): resolution: {integrity: sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.3 babel-plugin-jest-hoist: 27.5.1 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.0) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.3) dev: true /balanced-match@1.0.2: @@ -7017,8 +7246,8 @@ packages: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.24.0 - '@babel/parser': 7.24.0 + '@babel/core': 7.24.3 + '@babel/parser': 7.24.1 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -7138,10 +7367,10 @@ packages: ts-node: optional: true dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.3 '@jest/test-sequencer': 27.5.1 '@jest/types': 27.5.1 - babel-jest: 27.5.1(@babel/core@7.24.0) + babel-jest: 27.5.1(@babel/core@7.24.3) chalk: 4.1.2 ci-info: 3.9.0 deepmerge: 4.3.1 @@ -7299,7 +7528,7 @@ packages: resolution: {integrity: sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@babel/code-frame': 7.23.5 + '@babel/code-frame': 7.24.2 '@jest/types': 27.5.1 '@types/stack-utils': 2.0.3 chalk: 4.1.2 @@ -7436,16 +7665,16 @@ packages: resolution: {integrity: sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@babel/core': 7.24.0 - '@babel/generator': 7.23.6 - '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.24.0) - '@babel/traverse': 7.24.0 + '@babel/core': 7.24.3 + '@babel/generator': 7.24.1 + '@babel/plugin-syntax-typescript': 7.23.3(@babel/core@7.24.3) + '@babel/traverse': 7.24.1 '@babel/types': 7.24.0 '@jest/transform': 27.5.1 '@jest/types': 27.5.1 '@types/babel__traverse': 7.20.5 '@types/prettier': 2.7.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.0) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.3) chalk: 4.1.2 expect: 27.5.1 graceful-fs: 4.2.11 @@ -9112,7 +9341,7 @@ packages: rollup: 3.29.4 typescript: 5.3.3 optionalDependencies: - '@babel/code-frame': 7.23.5 + '@babel/code-frame': 7.24.2 dev: true /rollup@3.29.4: @@ -9697,6 +9926,16 @@ packages: /tslib@2.6.2: resolution: {integrity: sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==} + /tsx@4.7.1: + resolution: {integrity: sha512-8d6VuibXHtlN5E3zFkgY8u4DX7Y3Z27zvvPKVmLon/D4AjuKzarkUBTLDBgj9iTQ0hg5xM7c/mYiRVM+HETf0g==} + engines: {node: '>=18.0.0'} + hasBin: true + dependencies: + esbuild: 0.19.12 + get-tsconfig: 4.7.2 + optionalDependencies: + fsevents: 2.3.3 + /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'}