|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437 |
- import {
- appendExtensionListToPattern,
- asRoutePath,
- joinPath,
- logTree,
- mergeRouteRecordOverride,
- resolveOptions,
- throttle,
- trimExtension,
- warn
- } from "./chunk-QKES2MQB.mjs";
- import {
- __spreadValues
- } from "./chunk-E3WVRKG7.mjs";
-
- // src/index.ts
- import { createUnplugin } from "unplugin";
-
- // src/core/treeNodeValue.ts
- var EDITS_OVERRIDE_NAME = "@@edits";
- var _TreeNodeValueBase = class {
- constructor(rawSegment, parent, pathSegment = rawSegment, subSegments = [pathSegment]) {
- /**
- * Overrides defined by each file. The map is necessary to handle named views.
- */
- this._overrides = /* @__PURE__ */ new Map();
- /**
- * Should we add the loader guard to the route record.
- */
- this.includeLoaderGuard = false;
- /**
- * View name (Vue Router feature) mapped to their corresponding file. By default, the view name is `default` unless
- * specified with a `@` e.g. `index@aux.vue` will have a view name of `aux`.
- */
- this.components = /* @__PURE__ */ new Map();
- this._type = 0;
- this.rawSegment = rawSegment;
- this.pathSegment = pathSegment;
- this.subSegments = subSegments;
- const parentPath = parent == null ? void 0 : parent.path;
- this.path = // both the root record and the index record have a path of /
- (!parentPath || parentPath === "/") && this.pathSegment === "" ? "/" : joinPath((parent == null ? void 0 : parent.path) || "", this.pathSegment);
- }
- toString() {
- return this.pathSegment || "<index>";
- }
- isParam() {
- return !!(this._type & 1 /* param */);
- }
- isStatic() {
- return this._type === 0 /* static */;
- }
- get overrides() {
- return [...this._overrides.entries()].sort(
- ([nameA], [nameB]) => nameA === nameB ? 0 : (
- // EDITS_OVERRIDE_NAME should always be last
- nameA !== EDITS_OVERRIDE_NAME && (nameA < nameB || nameB === EDITS_OVERRIDE_NAME) ? -1 : 1
- )
- ).reduce((acc, [_path, routeBlock]) => {
- return mergeRouteRecordOverride(acc, routeBlock);
- }, {});
- }
- setOverride(path, routeBlock) {
- this._overrides.set(path, routeBlock || {});
- }
- /**
- * Remove all overrides for a given key.
- *
- * @param key - key to remove from the override
- */
- removeOverride(key) {
- this._overrides.forEach((routeBlock) => {
- delete routeBlock[key];
- });
- }
- mergeOverride(path, routeBlock) {
- const existing = this._overrides.get(path) || {};
- this._overrides.set(path, mergeRouteRecordOverride(existing, routeBlock));
- }
- addEditOverride(routeBlock) {
- return this.mergeOverride(EDITS_OVERRIDE_NAME, routeBlock);
- }
- setEditOverride(key, value) {
- if (!this._overrides.has(EDITS_OVERRIDE_NAME)) {
- this._overrides.set(EDITS_OVERRIDE_NAME, {});
- }
- const existing = this._overrides.get(EDITS_OVERRIDE_NAME);
- existing[key] = value;
- }
- };
- var TreeNodeValueStatic = class extends _TreeNodeValueBase {
- constructor(rawSegment, parent, pathSegment = rawSegment) {
- super(rawSegment, parent, pathSegment);
- this._type = 0 /* static */;
- }
- };
- var TreeNodeValueParam = class extends _TreeNodeValueBase {
- constructor(rawSegment, parent, params, pathSegment, subSegments) {
- super(rawSegment, parent, pathSegment, subSegments);
- this._type = 1 /* param */;
- this.params = params;
- }
- };
- function createTreeNodeValue(segment, parent) {
- if (!segment || segment === "index") {
- return new TreeNodeValueStatic(segment, parent, "");
- }
- const [pathSegment, params, subSegments] = parseSegment(segment);
- if (params.length) {
- return new TreeNodeValueParam(
- segment,
- parent,
- params,
- pathSegment,
- subSegments
- );
- }
- return new TreeNodeValueStatic(segment, parent, pathSegment);
- }
- function parseSegment(segment) {
- let buffer = "";
- let state = 0 /* static */;
- const params = [];
- let pathSegment = "";
- const subSegments = [];
- let currentTreeRouteParam = createEmptyRouteParam();
- function consumeBuffer() {
- if (state === 0 /* static */) {
- pathSegment += buffer;
- subSegments.push(buffer);
- } else if (state === 3 /* modifier */) {
- currentTreeRouteParam.paramName = buffer;
- currentTreeRouteParam.modifier = currentTreeRouteParam.optional ? currentTreeRouteParam.repeatable ? "*" : "?" : currentTreeRouteParam.repeatable ? "+" : "";
- buffer = "";
- pathSegment += `:${currentTreeRouteParam.paramName}${currentTreeRouteParam.isSplat ? "(.*)" : ""}${currentTreeRouteParam.modifier}`;
- params.push(currentTreeRouteParam);
- subSegments.push(currentTreeRouteParam);
- currentTreeRouteParam = createEmptyRouteParam();
- }
- buffer = "";
- }
- for (let pos = 0; pos < segment.length; pos++) {
- const c = segment[pos];
- if (state === 0 /* static */) {
- if (c === "[") {
- consumeBuffer();
- state = 1 /* paramOptional */;
- } else {
- buffer += c === "." ? "/" : c;
- }
- } else if (state === 1 /* paramOptional */) {
- if (c === "[") {
- currentTreeRouteParam.optional = true;
- } else if (c === ".") {
- currentTreeRouteParam.isSplat = true;
- pos += 2;
- } else {
- buffer += c;
- }
- state = 2 /* param */;
- } else if (state === 2 /* param */) {
- if (c === "]") {
- if (currentTreeRouteParam.optional) {
- pos++;
- }
- state = 3 /* modifier */;
- } else if (c === ".") {
- currentTreeRouteParam.isSplat = true;
- pos += 2;
- } else {
- buffer += c;
- }
- } else if (state === 3 /* modifier */) {
- if (c === "+") {
- currentTreeRouteParam.repeatable = true;
- } else {
- pos--;
- }
- consumeBuffer();
- state = 0 /* static */;
- }
- }
- if (state === 2 /* param */ || state === 1 /* paramOptional */) {
- throw new Error(`Invalid segment: "${segment}"`);
- }
- if (buffer) {
- consumeBuffer();
- }
- return [pathSegment, params, subSegments];
- }
- function createEmptyRouteParam() {
- return {
- paramName: "",
- modifier: "",
- optional: false,
- repeatable: false,
- isSplat: false
- };
- }
-
- // src/core/tree.ts
- var TreeNode = class {
- constructor(options, filePath, parent) {
- /**
- * children of the node
- */
- this.children = /* @__PURE__ */ new Map();
- /**
- * Should this page import the page info
- */
- this.hasDefinePage = false;
- this.options = options;
- this.parent = parent;
- this.value = createTreeNodeValue(filePath, parent == null ? void 0 : parent.value);
- }
- /**
- * Adds a path to the tree. `path` cannot start with a `/`.
- *
- * @param path - path segment to insert. **It must contain the file extension** this allows to
- * differentiate between folders and files.
- * @param filePath - file path, defaults to path for convenience and testing
- */
- insert(path, filePath = path) {
- const { tail, segment, viewName, isComponent } = splitFilePath(
- path,
- this.options
- );
- if (!this.children.has(segment)) {
- this.children.set(segment, new TreeNode(this.options, segment, this));
- }
- const child = this.children.get(segment);
- if (isComponent) {
- child.value.components.set(viewName, filePath);
- }
- if (tail) {
- return child.insert(tail, filePath);
- }
- return child;
- }
- setCustomRouteBlock(path, routeBlock) {
- this.value.setOverride(path, routeBlock);
- }
- getSortedChildren() {
- return Array.from(this.children.values()).sort(
- (a, b) => a.path.localeCompare(b.path)
- );
- }
- /**
- * Delete and detach itself from the tree.
- */
- delete() {
- if (!this.parent) {
- throw new Error("Cannot delete the root node.");
- }
- this.parent.children.delete(this.value.rawSegment);
- this.parent = void 0;
- }
- /**
- * Remove a route from the tree. The path shouldn't start with a `/` but it can be a nested one. e.g. `foo/bar.vue`.
- * The `path` should be relative to the page folder.
- *
- * @param path - path segment of the file
- */
- remove(path) {
- const { tail, segment, viewName, isComponent } = splitFilePath(
- path,
- this.options
- );
- const child = this.children.get(segment);
- if (!child) {
- throw new Error(
- `Cannot Delete "${path}". "${segment}" not found at "${this.path}".`
- );
- }
- if (tail) {
- child.remove(tail);
- if (child.children.size === 0 && child.value.components.size === 0) {
- this.children.delete(segment);
- }
- } else {
- if (isComponent) {
- child.value.components.delete(viewName);
- }
- if (child.children.size === 0 && child.value.components.size === 0) {
- this.children.delete(segment);
- }
- }
- }
- /**
- * Returns the route path of the node without parent paths. If the path was overridden, it returns the override.
- */
- get path() {
- var _a, _b;
- return (_b = this.value.overrides.path) != null ? _b : (((_a = this.parent) == null ? void 0 : _a.isRoot()) ? "/" : "") + this.value.pathSegment;
- }
- /**
- * Returns the route path of the node including parent paths.
- */
- get fullPath() {
- var _a;
- return (_a = this.value.overrides.path) != null ? _a : this.value.path;
- }
- /**
- * Returns the route name of the node. If the name was overridden, it returns the override.
- */
- get name() {
- return this.value.overrides.name || this.options.getRouteName(this);
- }
- /**
- * Returns the meta property as an object.
- */
- get metaAsObject() {
- const meta = __spreadValues({}, this.value.overrides.meta);
- if (this.value.includeLoaderGuard) {
- meta._loaderGuard = true;
- }
- return meta;
- }
- /**
- * Returns the JSON string of the meta object of the node. If the meta was overridden, it returns the override. If
- * there is no override, it returns an empty string.
- */
- get meta() {
- const overrideMeta = this.metaAsObject;
- return Object.keys(overrideMeta).length > 0 ? JSON.stringify(overrideMeta, null, 2) : "";
- }
- get params() {
- const params = this.value.isParam() ? [...this.value.params] : [];
- let node = this.parent;
- while (node) {
- if (node.value.isParam()) {
- params.unshift(...node.value.params);
- }
- node = node.parent;
- }
- return params;
- }
- /**
- * Returns wether this tree node is the root node of the tree.
- *
- * @returns true if the node is the root node
- */
- isRoot() {
- return this.value.path === "/" && !this.value.components.size;
- }
- toString() {
- return `${this.value}${// either we have multiple names
- this.value.components.size > 1 || // or we have one name and it's not default
- this.value.components.size === 1 && !this.value.components.get("default") ? ` \u2388(${Array.from(this.value.components.keys()).join(", ")})` : ""}${this.hasDefinePage ? " \u2691 definePage()" : ""}`;
- }
- };
- var PrefixTree = class extends TreeNode {
- constructor(options) {
- super(options, "");
- this.map = /* @__PURE__ */ new Map();
- }
- insert(path, filePath = path) {
- const node = super.insert(path, filePath);
- this.map.set(filePath, node);
- return node;
- }
- getChild(filePath) {
- return this.map.get(filePath);
- }
- /**
- *
- * @param filePath -
- */
- removeChild(filePath) {
- if (this.map.has(filePath)) {
- this.map.get(filePath).delete();
- this.map.delete(filePath);
- }
- }
- };
- function createPrefixTree(options) {
- return new PrefixTree(options);
- }
- function splitFilePath(filePath, options) {
- const slashPos = filePath.indexOf("/");
- let head = slashPos < 0 ? filePath : filePath.slice(0, slashPos);
- const tail = slashPos < 0 ? "" : filePath.slice(slashPos + 1);
- let segment = head;
- if (!tail) {
- segment = trimExtension(head, options.extensions);
- }
- let viewName = "default";
- const namedSeparatorPos = segment.indexOf("@");
- if (namedSeparatorPos > 0) {
- viewName = segment.slice(namedSeparatorPos + 1);
- segment = segment.slice(0, namedSeparatorPos);
- }
- const isComponent = segment !== head;
- return {
- segment,
- tail,
- viewName,
- isComponent
- };
- }
-
- // src/core/context.ts
- import { promises as fs3 } from "fs";
-
- // src/codegen/generateRouteParams.ts
- function generateRouteParams(node, isRaw) {
- const nodeParams = node.params;
- return node.params.length > 0 ? `{ ${node.params.map(
- (param) => `${param.paramName}${param.optional ? "?" : ""}: ` + (param.modifier === "+" ? `ParamValueOneOrMore<${isRaw}>` : param.modifier === "*" ? `ParamValueZeroOrMore<${isRaw}>` : param.modifier === "?" ? `ParamValueZeroOrOne<${isRaw}>` : `ParamValue<${isRaw}>`)
- ).join(", ")} }` : (
- // no params allowed
- "Record<never, never>"
- );
- }
-
- // src/codegen/generateRouteMap.ts
- function generateRouteNamedMap(node) {
- if (node.isRoot()) {
- return `export interface RouteNamedMap {
- ${node.getSortedChildren().map(generateRouteNamedMap).join("")}}`;
- }
- return (
- // if the node has a filePath, it's a component, it has a routeName and it should be referenced in the RouteNamedMap
- // otherwise it should be skipped to avoid navigating to a route that doesn't render anything
- (node.value.components.size ? ` '${node.name}': ${generateRouteRecordInfo(node)},
- ` : "") + (node.children.size > 0 ? node.getSortedChildren().map(generateRouteNamedMap).join("\n") : "")
- );
- }
- function generateRouteRecordInfo(node) {
- return `RouteRecordInfo<'${node.name}', '${node.fullPath}', ${generateRouteParams(node, true)}, ${generateRouteParams(node, false)}>`;
- }
-
- // src/core/moduleConstants.ts
- var MODULE_VUE_ROUTER = "vue-router/auto";
- var MODULE_ROUTES_PATH = `${MODULE_VUE_ROUTER}/routes`;
- var VIRTUAL_PREFIX = "virtual:";
- var ROUTE_BLOCK_ID = `${VIRTUAL_PREFIX}/vue-router/auto/route-block`;
- function getVirtualId(id) {
- return id.startsWith(VIRTUAL_PREFIX) ? id.slice(VIRTUAL_PREFIX.length) : null;
- }
- var routeBlockQueryRE = /\?vue&type=route/;
- function asVirtualId(id) {
- return VIRTUAL_PREFIX + id;
- }
-
- // src/codegen/generateRouteRecords.ts
- function generateRouteRecord(node, options, importList, indent = 0) {
- if (node.value.path === "/" && indent === 0) {
- return `[
- ${node.getSortedChildren().map((child) => generateRouteRecord(child, options, importList, indent + 1)).join(",\n")}
- ]`;
- }
- const startIndent = " ".repeat(indent * 2);
- const indentStr = " ".repeat((indent + 1) * 2);
- const overrides = node.value.overrides;
- const routeRecord = `${startIndent}{
- ${indentStr}path: '${node.path}',
- ${indentStr}${node.value.components.size ? `name: '${node.name}',` : `/* internal name: '${node.name}' */`}
- ${// component
- indentStr}${node.value.components.size ? generateRouteRecordComponent(
- node,
- indentStr,
- options.importMode,
- importList
- ) : "/* no component */"}
- ${overrides.props != null ? indentStr + `props: ${overrides.props},
- ` : ""}${overrides.alias != null ? indentStr + `alias: ${JSON.stringify(overrides.alias)},
- ` : ""}${// children
- indentStr}${node.children.size > 0 ? `children: [
- ${node.getSortedChildren().map((child) => generateRouteRecord(child, options, importList, indent + 2)).join(",\n")}
- ${indentStr}],` : "/* no children */"}${formatMeta(node, indentStr)}
- ${startIndent}}`;
- if (node.hasDefinePage) {
- const definePageDataList = [];
- for (const [name, filePath] of node.value.components) {
- const pageDataImport = `_definePage_${name}_${importList.size}`;
- definePageDataList.push(pageDataImport);
- importList.set(pageDataImport, `${filePath}?definePage&vue`);
- }
- if (definePageDataList.length) {
- return ` _mergeRouteRecord(
- ${routeRecord},
- ${definePageDataList.join(",\n")}
- )`;
- }
- }
- return routeRecord;
- }
- function generateRouteRecordComponent(node, indentStr, importMode, importList) {
- const files = Array.from(node.value.components);
- const isDefaultExport = files.length === 1 && files[0][0] === "default";
- return isDefaultExport ? `component: ${generatePageImport(files[0][1], importMode, importList)},` : (
- // files has at least one entry
- `components: {
- ${files.map(
- ([key, path]) => `${indentStr + " "}'${key}': ${generatePageImport(
- path,
- importMode,
- importList
- )}`
- ).join(",\n")}
- ${indentStr}},`
- );
- }
- function generatePageImport(filepath, importMode, importList) {
- const mode = typeof importMode === "function" ? importMode(filepath) : importMode;
- if (mode === "async") {
- return `() => import('${filepath}')`;
- } else {
- const importName = `_page_${importList.size}`;
- importList.set(importName, filepath);
- return importName;
- }
- }
- function generateImportList(node, indentStr) {
- const files = Array.from(node.value.components);
- return `[
- ${files.map(([_key, path]) => `${indentStr} () => import('${path}')`).join(",\n")}
- ${indentStr}]`;
- }
- var LOADER_GUARD_RE = /['"]_loaderGuard['"]:.*$/;
- function formatMeta(node, indent) {
- const meta = node.meta;
- const formatted = meta && meta.split("\n").map(
- (line) => indent + line.replace(
- LOADER_GUARD_RE,
- "[_HasDataLoaderMeta]: " + generateImportList(node, indent + " ") + ","
- )
- ).join("\n");
- return formatted ? "\n" + indent + "meta: " + formatted.trimStart() : "";
- }
-
- // src/core/context.ts
- import fg from "fast-glob";
- import { resolve } from "pathe";
-
- // src/core/customBlock.ts
- import { parse } from "@vue/compiler-sfc";
- import { promises as fs } from "fs";
- import JSON5 from "json5";
- import { parse as YAMLParser } from "yaml";
- async function getRouteBlock(path, options) {
- const content = await fs.readFile(path, "utf8");
- const parsedSFC = await parse(content, { pad: "space" }).descriptor;
- const blockStr = parsedSFC == null ? void 0 : parsedSFC.customBlocks.find((b) => b.type === "route");
- if (!blockStr)
- return;
- let result = parseCustomBlock(blockStr, path, options);
- if (result) {
- if (result.path != null && !result.path.startsWith("/")) {
- warn(`Overridden path must start with "/". Found in "${path}".`);
- }
- }
- return result;
- }
- function parseCustomBlock(block, filePath, options) {
- var _a;
- const lang = (_a = block.lang) != null ? _a : options.routeBlockLang;
- if (lang === "json5") {
- try {
- return JSON5.parse(block.content);
- } catch (err) {
- warn(
- `Invalid JSON5 format of <${block.type}> content in ${filePath}
- ${err.message}`
- );
- }
- } else if (lang === "json") {
- try {
- return JSON.parse(block.content);
- } catch (err) {
- warn(
- `Invalid JSON format of <${block.type}> content in ${filePath}
- ${err.message}`
- );
- }
- } else if (lang === "yaml" || lang === "yml") {
- try {
- return YAMLParser(block.content);
- } catch (err) {
- warn(
- `Invalid YAML format of <${block.type}> content in ${filePath}
- ${err.message}`
- );
- }
- } else {
- warn(
- `Language "${lang}" for <${block.type}> is not supported. Supported languages are: json5, json, yaml, yml. Found in in ${filePath}.`
- );
- }
- }
-
- // src/core/RoutesFolderWatcher.ts
- import chokidar from "chokidar";
- import { normalize } from "pathe";
- var RoutesFolderWatcher = class {
- constructor(routesFolder, options) {
- this.src = routesFolder.src;
- this.pathPrefix = routesFolder.path || "";
- this.options = options;
- this.watcher = chokidar.watch(this.src, {
- ignoreInitial: true,
- // disableGlobbing: true,
- ignorePermissionErrors: true,
- ignored: options.exclude
- // useFsEvents: true,
- // TODO: allow user options
- });
- }
- on(event, handler) {
- this.watcher.on(event, (filePath) => {
- filePath = normalize(filePath);
- if (this.options.extensions.every(
- (extension) => !filePath.endsWith(extension)
- )) {
- return;
- }
- handler({
- filePath,
- routePath: asRoutePath(
- { src: this.src, path: this.pathPrefix },
- filePath
- )
- });
- });
- return this;
- }
- close() {
- this.watcher.close();
- }
- };
-
- // src/codegen/generateDTS.ts
- function generateDTS({
- vueRouterModule,
- routesModule,
- routeNamedMap
- }) {
- return `// Generated by unplugin-vue-router. \u203C\uFE0F DO NOT MODIFY THIS FILE \u203C\uFE0F
- // It's recommended to commit this file.
- // Make sure to add this file to your tsconfig.json file as an "includes" or "files" entry.
-
- /// <reference types="unplugin-vue-router/client" />
-
- import type {
- // type safe route locations
- RouteLocationTypedList,
- RouteLocationResolvedTypedList,
- RouteLocationNormalizedTypedList,
- RouteLocationNormalizedLoadedTypedList,
- RouteLocationAsString,
- RouteLocationAsRelativeTypedList,
- RouteLocationAsPathTypedList,
-
- // helper types
- // route definitions
- RouteRecordInfo,
- ParamValue,
- ParamValueOneOrMore,
- ParamValueZeroOrMore,
- ParamValueZeroOrOne,
-
- // vue-router extensions
- _RouterTyped,
- RouterLinkTyped,
- NavigationGuard,
- UseLinkFnTyped,
-
- // data fetching
- _DataLoader,
- _DefineLoaderOptions,
- } from 'unplugin-vue-router'
-
- declare module '${routesModule}' {
- ${routeNamedMap}
- }
-
- declare module '${vueRouterModule}' {
- import type { RouteNamedMap } from '${routesModule}'
-
- export type RouterTyped = _RouterTyped<RouteNamedMap>
-
- /**
- * Type safe version of \`RouteLocationNormalized\` (the type of \`to\` and \`from\` in navigation guards).
- * Allows passing the name of the route to be passed as a generic.
- */
- export type RouteLocationNormalized<Name extends keyof RouteNamedMap = keyof RouteNamedMap> = RouteLocationNormalizedTypedList<RouteNamedMap>[Name]
-
- /**
- * Type safe version of \`RouteLocationNormalizedLoaded\` (the return type of \`useRoute()\`).
- * Allows passing the name of the route to be passed as a generic.
- */
- export type RouteLocationNormalizedLoaded<Name extends keyof RouteNamedMap = keyof RouteNamedMap> = RouteLocationNormalizedLoadedTypedList<RouteNamedMap>[Name]
-
- /**
- * Type safe version of \`RouteLocationResolved\` (the returned route of \`router.resolve()\`).
- * Allows passing the name of the route to be passed as a generic.
- */
- export type RouteLocationResolved<Name extends keyof RouteNamedMap = keyof RouteNamedMap> = RouteLocationResolvedTypedList<RouteNamedMap>[Name]
-
- /**
- * Type safe version of \`RouteLocation\` . Allows passing the name of the route to be passed as a generic.
- */
- export type RouteLocation<Name extends keyof RouteNamedMap = keyof RouteNamedMap> = RouteLocationTypedList<RouteNamedMap>[Name]
-
- /**
- * Type safe version of \`RouteLocationRaw\` . Allows passing the name of the route to be passed as a generic.
- */
- export type RouteLocationRaw<Name extends keyof RouteNamedMap = keyof RouteNamedMap> =
- | RouteLocationAsString<RouteNamedMap>
- | RouteLocationAsRelativeTypedList<RouteNamedMap>[Name]
- | RouteLocationAsPathTypedList<RouteNamedMap>[Name]
-
- /**
- * Generate a type safe params for a route location. Requires the name of the route to be passed as a generic.
- */
- export type RouteParams<Name extends keyof RouteNamedMap> = RouteNamedMap[Name]['params']
- /**
- * Generate a type safe raw params for a route location. Requires the name of the route to be passed as a generic.
- */
- export type RouteParamsRaw<Name extends keyof RouteNamedMap> = RouteNamedMap[Name]['paramsRaw']
-
- export function useRouter(): RouterTyped
- export function useRoute<Name extends keyof RouteNamedMap = keyof RouteNamedMap>(name?: Name): RouteLocationNormalizedLoadedTypedList<RouteNamedMap>[Name]
-
- export const useLink: UseLinkFnTyped<RouteNamedMap>
-
- export function onBeforeRouteLeave(guard: NavigationGuard<RouteNamedMap>): void
- export function onBeforeRouteUpdate(guard: NavigationGuard<RouteNamedMap>): void
-
- export const RouterLink: RouterLinkTyped<RouteNamedMap>
-
- // Experimental Data Fetching
-
- export function defineLoader<
- P extends Promise<any>,
- Name extends keyof RouteNamedMap = keyof RouteNamedMap,
- isLazy extends boolean = false,
- >(
- name: Name,
- loader: (route: RouteLocationNormalizedLoaded<Name>) => P,
- options?: _DefineLoaderOptions<isLazy>,
- ): _DataLoader<Awaited<P>, isLazy>
- export function defineLoader<
- P extends Promise<any>,
- isLazy extends boolean = false,
- >(
- loader: (route: RouteLocationNormalizedLoaded) => P,
- options?: _DefineLoaderOptions<isLazy>,
- ): _DataLoader<Awaited<P>, isLazy>
-
- export {
- _definePage as definePage,
- _HasDataLoaderMeta as HasDataLoaderMeta,
- _setupDataFetchingGuard as setupDataFetchingGuard,
- _stopDataFetchingScope as stopDataFetchingScope,
- } from 'unplugin-vue-router/runtime'
- }
-
- declare module 'vue-router' {
- import type { RouteNamedMap } from '${routesModule}'
-
- export interface TypesConfig {
- beforeRouteUpdate: NavigationGuard<RouteNamedMap>
- beforeRouteLeave: NavigationGuard<RouteNamedMap>
-
- $route: RouteLocationNormalizedLoadedTypedList<RouteNamedMap>[keyof RouteNamedMap]
- $router: _RouterTyped<RouteNamedMap>
-
- RouterLink: RouterLinkTyped<RouteNamedMap>
- }
- }
- `;
- }
-
- // src/codegen/vueRouterModule.ts
- function generateVueRouterProxy(routesModule, options) {
- return `
- import { routes } from '${routesModule}'
- import { createRouter as _createRouter } from 'vue-router'
-
- export * from 'vue-router'
- export {
- _defineLoader as defineLoader,
- _definePage as definePage,
- _HasDataLoaderMeta as HasDataLoaderMeta,
- _setupDataFetchingGuard as setupDataFetchingGuard,
- _stopDataFetchingScope as stopDataFetchingScope,
- } from 'unplugin-vue-router/runtime'
-
- export function createRouter(options) {
- const { extendRoutes } = options
- // use Object.assign for better browser support
- const router = _createRouter(Object.assign(
- options,
- { routes: typeof extendRoutes === 'function' ? extendRoutes(routes) : routes },
- ))
-
- return router
- }
- `;
- }
-
- // src/data-fetching/parse.ts
- import { promises as fs2 } from "fs";
- import { findExports } from "mlly";
- async function hasNamedExports(file) {
- const code = await fs2.readFile(file, "utf8");
- const exportedNames = findExports(code).filter(
- (e) => e.type !== "default" && e.type !== "star"
- );
- return exportedNames.length > 0;
- }
-
- // src/core/definePage.ts
- import {
- getTransformResult,
- isCallOf,
- parseSFC,
- MagicString,
- checkInvalidScopeReference
- } from "@vue-macros/common";
- import { walkAST } from "ast-walker-scope";
- var MACRO_DEFINE_PAGE = "definePage";
- var MACRO_DEFINE_PAGE_QUERY = /[?&]definePage\b/;
- function definePageTransform({
- code,
- id
- }) {
- if (!code.includes(MACRO_DEFINE_PAGE))
- return;
- const sfc = parseSFC(code, id);
- if (!sfc.scriptSetup)
- return;
- const isExtractingDefinePage = MACRO_DEFINE_PAGE_QUERY.test(id);
- const { script, scriptSetup, getSetupAst } = sfc;
- const setupAst = getSetupAst();
- const definePageNodes = ((setupAst == null ? void 0 : setupAst.body) || []).map((node) => {
- if (node.type === "ExpressionStatement")
- node = node.expression;
- return isCallOf(node, MACRO_DEFINE_PAGE) ? node : null;
- }).filter((node) => !!node);
- if (!definePageNodes.length) {
- return isExtractingDefinePage ? (
- // e.g. index.vue?definePage that contains a commented `definePage()
- "export default {}"
- ) : (
- // e.g. index.vue that contains a commented `definePage()
- null
- );
- } else if (definePageNodes.length > 1) {
- throw new SyntaxError(`duplicate definePage() call`);
- }
- const definePageNode = definePageNodes[0];
- const setupOffset = scriptSetup.loc.start.offset;
- if (isExtractingDefinePage) {
- const s = new MagicString(code);
- const routeRecord = definePageNode.arguments[0];
- const scriptBindings = (setupAst == null ? void 0 : setupAst.body) ? getIdentifiers(setupAst.body) : [];
- checkInvalidScopeReference(routeRecord, MACRO_DEFINE_PAGE, scriptBindings);
- s.remove(setupOffset + routeRecord.end, code.length);
- s.remove(0, setupOffset + routeRecord.start);
- s.prepend(`export default `);
- return getTransformResult(s, id);
- } else {
- const s = new MagicString(code);
- s.remove(
- setupOffset + definePageNode.start,
- setupOffset + definePageNode.end
- );
- return getTransformResult(s, id);
- }
- }
- function extractDefinePageNameAndPath(sfcCode, id) {
- var _a;
- if (!sfcCode.includes(MACRO_DEFINE_PAGE))
- return;
- const sfc = parseSFC(sfcCode, id);
- if (!sfc.scriptSetup)
- return;
- const { getSetupAst } = sfc;
- const setupAst = getSetupAst();
- const definePageNodes = ((_a = setupAst == null ? void 0 : setupAst.body) != null ? _a : []).map((node) => {
- if (node.type === "ExpressionStatement")
- node = node.expression;
- return isCallOf(node, MACRO_DEFINE_PAGE) ? node : null;
- }).filter((node) => !!node);
- if (!definePageNodes.length) {
- return;
- } else if (definePageNodes.length > 1) {
- throw new SyntaxError(`duplicate definePage() call`);
- }
- const definePageNode = definePageNodes[0];
- const routeRecord = definePageNode.arguments[0];
- if (routeRecord.type !== "ObjectExpression") {
- throw new SyntaxError(
- `[${id}]: definePage() expects an object expression as its only argument`
- );
- }
- const routeInfo = {};
- for (const prop of routeRecord.properties) {
- if (prop.type === "ObjectProperty" && prop.key.type === "Identifier") {
- if (prop.key.name === "name") {
- if (prop.value.type !== "StringLiteral") {
- warn(`route name must be a string literal. Found in "${id}".`);
- } else {
- routeInfo.name = prop.value.value;
- }
- } else if (prop.key.name === "path") {
- if (prop.value.type !== "StringLiteral") {
- warn(`route path must be a string literal. Found in "${id}".`);
- } else {
- routeInfo.path = prop.value.value;
- }
- }
- }
- }
- return routeInfo;
- }
- var getIdentifiers = (stmts) => {
- let ids = [];
- walkAST(
- {
- type: "Program",
- body: stmts,
- directives: [],
- sourceType: "module",
- sourceFile: ""
- },
- {
- enter(node) {
- if (node.type === "BlockStatement") {
- this.skip();
- }
- },
- leave(node) {
- if (node.type !== "Program")
- return;
- ids = Object.keys(this.scope);
- }
- }
- );
- return ids;
- };
-
- // src/core/extendRoutes.ts
- var EditableTreeNode = class {
- // private _parent?: EditableTreeNode
- constructor(node) {
- this.node = node;
- }
- /**
- * Remove and detach the current route node from the tree. Subsequently, its children will be removed as well.
- */
- delete() {
- return this.node.delete();
- }
- /**
- * Inserts a new route as a child of this route. This route cannot use `definePage()`. If it was meant to be included,
- * add it to the `routesFolder` option.
- */
- insert(path, filePath) {
- const extDotIndex = filePath.lastIndexOf(".");
- const ext = filePath.slice(extDotIndex);
- if (!path.endsWith(ext)) {
- path += ext;
- }
- let addBackLeadingSlash = false;
- if (path.startsWith("/")) {
- path = path.slice(1);
- addBackLeadingSlash = !this.node.isRoot();
- }
- const node = this.node.insert(path, filePath);
- const editable = new EditableTreeNode(node);
- if (addBackLeadingSlash) {
- editable.path = "/" + node.path;
- }
- return editable;
- }
- /**
- * Get an editable version of the parent node if it exists.
- */
- get parent() {
- return this.node.parent && new EditableTreeNode(this.node.parent);
- }
- /**
- * Return a Map of the files associated to the current route. The key of the map represents the name of the view (Vue
- * Router feature) while the value is the file path. By default, the name of the view is `default`.
- */
- get components() {
- return this.node.value.components;
- }
- /**
- * Name of the route. Note that **all routes are named** but when the final `routes` array is generated, routes
- * without a `component` will not include their `name` property to avoid accidentally navigating to them and display
- * nothing. {@see isPassThrough}
- */
- get name() {
- return this.node.name;
- }
- /**
- * Override the name of the route.
- */
- set name(name) {
- this.node.value.addEditOverride({ name });
- }
- /**
- * Whether the route is a pass-through route. A pass-through route is a route that does not have a component and is
- * used to group other routes under the same prefix `path` and/or `meta` properties.
- */
- get isPassThrough() {
- return this.node.value.components.size === 0;
- }
- /**
- * Meta property of the route as an object. Note this property is readonly and will be serialized as JSON. It won't contain the meta properties defined with `definePage()` as it could contain expressions **but it does contain the meta properties defined with `<route>` blocks**.
- */
- get meta() {
- return this.node.metaAsObject;
- }
- /**
- * Override the meta property of the route. This will discard any other meta property defined with `<route>` blocks or
- * through other means.
- */
- set meta(meta) {
- this.node.value.removeOverride("meta");
- this.node.value.setEditOverride("meta", meta);
- }
- /**
- * Add meta properties to the route keeping the existing ones. The passed object will be deeply merged with the
- * existing meta object if any. Note that the meta property is later on serialized as JSON so you can't pass functions
- * or any other non-serializable value.
- */
- addToMeta(meta) {
- this.node.value.addEditOverride({ meta });
- }
- /**
- * Path of the route without parent paths.
- */
- get path() {
- return this.node.path;
- }
- /**
- * Override the path of the route. You must ensure `params` match with the existing path.
- */
- set path(path) {
- if (!path.startsWith("/")) {
- warn(
- `Only absolute paths are supported. Make sure that "${path}" starts with a slash "/".`
- );
- return;
- }
- this.node.value.addEditOverride({ path });
- }
- /**
- * Alias of the route.
- */
- get alias() {
- return this.node.value.overrides.alias;
- }
- /**
- * Add an alias to the route.
- *
- * @param alias - Alias to add to the route
- */
- addAlias(alias) {
- this.node.value.addEditOverride({ alias });
- }
- /**
- * Array of the route params and all of its parent's params.
- */
- get params() {
- return this.node.params;
- }
- /**
- * Path of the route including parent paths.
- */
- get fullPath() {
- return this.node.fullPath;
- }
- /**
- * DFS traversal of the tree.
- * @example
- * ```ts
- * for (const node of tree) {
- * // ...
- * }
- * ```
- */
- *traverseDFS() {
- if (!this.node.isRoot()) {
- yield this;
- }
- for (const [_name, child] of this.node.children) {
- yield* new EditableTreeNode(child).traverseDFS();
- }
- }
- *[Symbol.iterator]() {
- yield* this.traverseBFS();
- }
- /**
- * BFS traversal of the tree as a generator.
- *
- * @example
- * ```ts
- * for (const node of tree) {
- * // ...
- * }
- * ```
- */
- *traverseBFS() {
- for (const [_name, child] of this.node.children) {
- yield new EditableTreeNode(child);
- }
- for (const [_name, child] of this.node.children) {
- yield* new EditableTreeNode(child).traverseBFS();
- }
- }
- };
-
- // src/core/context.ts
- function createRoutesContext(options) {
- const { dts: preferDTS, root, routesFolder } = options;
- const dts = preferDTS === false ? false : preferDTS === true ? resolve(root, "typed-router.d.ts") : resolve(root, preferDTS);
- const routeTree = createPrefixTree(options);
- const editableRoutes = new EditableTreeNode(routeTree);
- function log(...args) {
- if (options.logs) {
- console.log(...args);
- }
- }
- const watchers = [];
- async function scanPages(startWatchers = true) {
- var _a;
- if (options.extensions.length < 1) {
- throw new Error(
- '"extensions" cannot be empty. Please specify at least one extension.'
- );
- }
- if (watchers.length > 0) {
- return;
- }
- const globalPattern = appendExtensionListToPattern(
- options.filePatterns,
- options.extensions
- );
- await Promise.all(
- routesFolder.map((folder) => {
- if (startWatchers) {
- watchers.push(setupWatcher(new RoutesFolderWatcher(folder, options)));
- }
- const pattern = folder.filePatterns ? appendExtensionListToPattern(
- folder.filePatterns,
- // also override the extensions if the folder has a custom extensions
- folder.extensions || options.extensions
- ) : globalPattern;
- return fg(pattern, {
- cwd: folder.src,
- // TODO: do they return the symbolic link path or the original file?
- // followSymbolicLinks: false,
- ignore: folder.exclude || options.exclude
- }).then((files) => files.map((file) => resolve(folder.src, file))).then(
- (files) => Promise.all(
- files.map(
- (file) => addPage({
- routePath: asRoutePath(folder, file),
- filePath: file
- })
- )
- )
- );
- })
- );
- for (const route of editableRoutes) {
- await ((_a = options.extendRoute) == null ? void 0 : _a.call(options, route));
- }
- await _writeConfigFiles();
- }
- async function writeRouteInfoToNode(node, path) {
- const content = await fs3.readFile(path, "utf8");
- node.hasDefinePage = content.includes("definePage");
- const [definedPageNameAndPath, routeBlock] = await Promise.all([
- extractDefinePageNameAndPath(content, path),
- getRouteBlock(path, options)
- ]);
- node.setCustomRouteBlock(path, __spreadValues(__spreadValues({}, routeBlock), definedPageNameAndPath));
- node.value.includeLoaderGuard = options.dataFetching && await hasNamedExports(path);
- }
- async function addPage({ filePath, routePath }, triggerExtendRoute = false) {
- var _a;
- log(`added "${routePath}" for "${filePath}"`);
- const node = routeTree.insert(routePath, filePath);
- await writeRouteInfoToNode(node, filePath);
- if (triggerExtendRoute) {
- await ((_a = options.extendRoute) == null ? void 0 : _a.call(options, new EditableTreeNode(node)));
- }
- }
- async function updatePage({ filePath, routePath }) {
- var _a;
- log(`updated "${routePath}" for "${filePath}"`);
- const node = routeTree.getChild(filePath);
- if (!node) {
- console.warn(`Cannot update "${filePath}": Not found.`);
- return;
- }
- await writeRouteInfoToNode(node, filePath);
- await ((_a = options.extendRoute) == null ? void 0 : _a.call(options, new EditableTreeNode(node)));
- }
- function removePage({ filePath, routePath }) {
- log(`remove "${routePath}" for "${filePath}"`);
- routeTree.removeChild(filePath);
- }
- function setupWatcher(watcher) {
- log(`\u{1F916} Scanning files in ${watcher.src}`);
- return watcher.on("change", async (ctx) => {
- await updatePage(ctx);
- writeConfigFiles();
- }).on("add", async (ctx) => {
- await addPage(ctx, true);
- writeConfigFiles();
- }).on("unlink", async (ctx) => {
- await removePage(ctx);
- writeConfigFiles();
- });
- }
- function generateRoutes() {
- const importList = /* @__PURE__ */ new Map();
- const routesExport = `export const routes = ${generateRouteRecord(
- routeTree,
- options,
- importList
- )}`;
- let imports = "";
- if (true) {
- imports += `import { _HasDataLoaderMeta, _mergeRouteRecord } from 'unplugin-vue-router/runtime'
- `;
- }
- for (const [name, path] of importList) {
- imports += `import ${name} from '${path}'
- `;
- }
- if (imports) {
- imports += "\n";
- }
- return `${imports}${routesExport}
- `;
- }
- function generateDTS2() {
- return generateDTS({
- vueRouterModule: MODULE_VUE_ROUTER,
- routesModule: MODULE_ROUTES_PATH,
- routeNamedMap: generateRouteNamedMap(routeTree).split("\n").filter((line) => line).map((line) => " " + line).join("\n")
- });
- }
- function generateVueRouterProxy2() {
- return generateVueRouterProxy(MODULE_ROUTES_PATH, options);
- }
- let lastDTS;
- async function _writeConfigFiles() {
- log("\u{1F4BE} writing...");
- if (options.beforeWriteFiles) {
- await options.beforeWriteFiles(editableRoutes);
- }
- logTree(routeTree, log);
- if (dts) {
- const content = generateDTS2();
- if (lastDTS !== content) {
- await fs3.writeFile(dts, content, "utf-8");
- lastDTS = content;
- server == null ? void 0 : server.invalidate(MODULE_ROUTES_PATH);
- server == null ? void 0 : server.invalidate(MODULE_VUE_ROUTER);
- server == null ? void 0 : server.reload();
- }
- }
- }
- const writeConfigFiles = throttle(_writeConfigFiles, 500, 100);
- function stopWatcher() {
- if (watchers.length) {
- if (options.logs) {
- console.log("\u{1F6D1} stopping watcher");
- }
- watchers.forEach((watcher) => watcher.close());
- }
- }
- let server;
- function setServerContext(_server) {
- server = _server;
- }
- return {
- scanPages,
- writeConfigFiles,
- setServerContext,
- stopWatcher,
- generateRoutes,
- generateVueRouterProxy: generateVueRouterProxy2,
- definePageTransform(code, id) {
- return definePageTransform({
- code,
- id
- });
- }
- };
- }
-
- // src/core/vite/index.ts
- function createViteContext(server) {
- function invalidate(path) {
- const { moduleGraph } = server;
- const foundModule = moduleGraph.getModuleById(asVirtualId(path));
- if (foundModule) {
- moduleGraph.invalidateModule(foundModule);
- }
- return !!foundModule;
- }
- function reload() {
- if (server.ws) {
- server.ws.send({
- type: "full-reload",
- path: "*"
- });
- }
- }
- return {
- invalidate,
- reload
- };
- }
-
- // src/index.ts
- import { createFilter } from "@rollup/pluginutils";
- import { join } from "pathe";
- var src_default = createUnplugin((opt = {}, meta) => {
- const options = resolveOptions(opt);
- const ctx = createRoutesContext(options);
- function getVirtualId2(id) {
- if (options._inspect)
- return id;
- return getVirtualId(id);
- }
- function asVirtualId2(id) {
- if (options._inspect)
- return id;
- return asVirtualId(id);
- }
- const pageFilePattern = `**/*` + (options.extensions.length === 1 ? options.extensions[0] : `.{${options.extensions.map((extension) => extension.replace(".", "")).join(",")}}`);
- const filterPageComponents = createFilter(
- [
- ...options.routesFolder.map(
- (routeOption) => join(routeOption.src, pageFilePattern)
- ),
- // importing the definePage block
- /definePage\&vue$/
- ],
- options.exclude
- );
- return {
- name: "unplugin-vue-router",
- enforce: "pre",
- resolveId(id) {
- if (id === MODULE_ROUTES_PATH) {
- return asVirtualId2(id);
- }
- if (id === MODULE_VUE_ROUTER) {
- return asVirtualId2(id);
- }
- if (routeBlockQueryRE.test(id)) {
- return ROUTE_BLOCK_ID;
- }
- },
- buildStart() {
- return ctx.scanPages(true);
- },
- buildEnd() {
- ctx.stopWatcher();
- },
- // we only need to transform page components
- transformInclude(id) {
- return filterPageComponents(id);
- },
- transform(code, id) {
- return ctx.definePageTransform(code, id);
- },
- // loadInclude is necessary for webpack
- loadInclude(id) {
- if (id === ROUTE_BLOCK_ID)
- return true;
- const resolvedId = getVirtualId2(id);
- return resolvedId === MODULE_ROUTES_PATH || resolvedId === MODULE_VUE_ROUTER;
- },
- load(id) {
- if (id === ROUTE_BLOCK_ID) {
- return {
- code: `export default {}`,
- map: null
- };
- }
- const resolvedId = getVirtualId2(id);
- if (resolvedId === MODULE_ROUTES_PATH) {
- return ctx.generateRoutes();
- }
- if (resolvedId === MODULE_VUE_ROUTER) {
- return ctx.generateVueRouterProxy();
- }
- },
- // improves DX
- vite: {
- configureServer(server) {
- ctx.setServerContext(createViteContext(server));
- }
- }
- };
- });
- var VueRouterExports = [
- "useRoute",
- "useRouter",
- "defineLoader",
- "onBeforeRouteUpdate",
- "onBeforeRouteLeave"
- // NOTE: the typing seems broken locally, so instead we export it directly from unplugin-vue-router/runtime
- // 'definePage',
- ];
- var VueRouterAutoImports = {
- "vue-router/auto": VueRouterExports,
- "unplugin-vue-router/runtime": [["_definePage", "definePage"]]
- };
-
- export {
- TreeNodeValueStatic,
- TreeNodeValueParam,
- createTreeNodeValue,
- TreeNode,
- createPrefixTree,
- EditableTreeNode,
- createRoutesContext,
- src_default,
- VueRouterExports,
- VueRouterAutoImports
- };
|