unplugin-vue-router
Advanced tools
Comparing version 0.3.2 to 0.3.3
import * as esbuild from 'esbuild'; | ||
import { O as Options } from './options-ccb73a7b.js'; | ||
import { O as Options } from './options-72c4a647.js'; | ||
import 'vue-router'; | ||
@@ -4,0 +4,0 @@ |
@@ -132,3 +132,3 @@ "use strict"; | ||
return ""; | ||
return getFileBasedRouteName(node.parent) + "/" + node.value.rawSegment; | ||
return getFileBasedRouteName(node.parent) + "/" + (node.value.rawSegment === "index" ? "" : node.value.rawSegment); | ||
} | ||
@@ -146,3 +146,4 @@ function mergeRouteRecordOverride(a, b) { | ||
if (key === "alias") { | ||
merged[key] = [...a[key] || [], ...b[key] || []]; | ||
const newAlias = []; | ||
merged[key] = newAlias.concat(a.alias || [], b.alias || []); | ||
} else if (key === "meta") { | ||
@@ -177,6 +178,8 @@ merged[key] = mergeDeep(a[key] || {}, b[key] || {}); | ||
// src/core/treeNodeValue.ts | ||
var EDITS_OVERRIDE_NAME = "@@edits"; | ||
var _TreeNodeValueBase = class { | ||
constructor(rawSegment, parent, pathSegment = rawSegment, subSegments = [rawSegment]) { | ||
constructor(rawSegment, parent, pathSegment = rawSegment, subSegments = [pathSegment]) { | ||
this._overrides = /* @__PURE__ */ new Map(); | ||
this.includeLoaderGuard = false; | ||
this.components = /* @__PURE__ */ new Map(); | ||
this._type = 0; | ||
@@ -188,3 +191,2 @@ this.rawSegment = rawSegment; | ||
this.path = (!parentPath || parentPath === "/") && this.pathSegment === "" ? "/" : joinPath((parent == null ? void 0 : parent.path) || "", this.pathSegment); | ||
this.filePaths = /* @__PURE__ */ new Map(); | ||
} | ||
@@ -202,3 +204,3 @@ toString() { | ||
return [...this._overrides.entries()].sort( | ||
([nameA], [nameB]) => nameA === nameB ? 0 : nameA < nameB ? -1 : 1 | ||
([nameA], [nameB]) => nameA === nameB ? 0 : nameA !== EDITS_OVERRIDE_NAME && (nameA < nameB || nameB === EDITS_OVERRIDE_NAME) ? -1 : 1 | ||
).reduce((acc, [_path, routeBlock]) => { | ||
@@ -211,2 +213,15 @@ return mergeRouteRecordOverride(acc, routeBlock); | ||
} | ||
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) { | ||
console.log("add edit", routeBlock); | ||
return this.mergeOverride(EDITS_OVERRIDE_NAME, routeBlock); | ||
} | ||
}; | ||
@@ -228,3 +243,3 @@ var TreeNodeValueStatic = class extends _TreeNodeValueBase { | ||
if (!segment || segment === "index") { | ||
return new TreeNodeValueStatic("", parent); | ||
return new TreeNodeValueStatic(segment, parent, ""); | ||
} | ||
@@ -343,3 +358,3 @@ const [pathSegment, params, subSegments] = parseSegment(segment); | ||
if (isComponent) { | ||
child.value.filePaths.set(viewName, filePath); | ||
child.value.components.set(viewName, filePath); | ||
} | ||
@@ -359,2 +374,9 @@ if (tail) { | ||
} | ||
delete() { | ||
if (!this.parent) { | ||
throw new Error("Cannot delete the root node."); | ||
} | ||
this.parent.children.delete(this.value.rawSegment); | ||
this.parent = void 0; | ||
} | ||
remove(path) { | ||
@@ -373,3 +395,3 @@ const { tail, segment, viewName, isComponent } = splitFilePath( | ||
child.remove(tail); | ||
if (child.children.size === 0 && child.value.filePaths.size === 0) { | ||
if (child.children.size === 0 && child.value.components.size === 0) { | ||
this.children.delete(segment); | ||
@@ -379,5 +401,5 @@ } | ||
if (isComponent) { | ||
child.value.filePaths.delete(viewName); | ||
child.value.components.delete(viewName); | ||
} | ||
if (child.children.size === 0 && child.value.filePaths.size === 0) { | ||
if (child.children.size === 0 && child.value.components.size === 0) { | ||
this.children.delete(segment); | ||
@@ -398,7 +420,11 @@ } | ||
} | ||
get meta() { | ||
const overrideMeta = __spreadValues({}, this.value.overrides.meta); | ||
get metaAsObject() { | ||
const meta = __spreadValues({}, this.value.overrides.meta); | ||
if (this.value.includeLoaderGuard) { | ||
overrideMeta._loaderGuard = true; | ||
meta._loaderGuard = true; | ||
} | ||
return meta; | ||
} | ||
get meta() { | ||
const overrideMeta = this.metaAsObject; | ||
return Object.keys(overrideMeta).length > 0 ? JSON.stringify(overrideMeta, null, 2) : ""; | ||
@@ -418,10 +444,30 @@ } | ||
isRoot() { | ||
return this.value.path === "/" && !this.value.filePaths.size; | ||
return this.value.path === "/" && !this.value.components.size; | ||
} | ||
toString() { | ||
return `${this.value}${this.value.filePaths.size > 1 || this.value.filePaths.size === 1 && !this.value.filePaths.get("default") ? ` \u2388(${Array.from(this.value.filePaths.keys()).join(", ")})` : ""}${this.hasDefinePage ? " \u2691 definePage()" : ""}`; | ||
return `${this.value}${this.value.components.size > 1 || 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); | ||
} | ||
removeChild(filePath) { | ||
if (this.map.has(filePath)) { | ||
this.map.get(filePath).delete(); | ||
this.map.delete(filePath); | ||
} | ||
} | ||
}; | ||
function createPrefixTree(options) { | ||
return new TreeNode(options, ""); | ||
return new PrefixTree(options); | ||
} | ||
@@ -468,3 +514,3 @@ function splitFilePath(filePath, options) { | ||
} | ||
return (node.value.filePaths.size ? ` '${node.name}': ${generateRouteRecordInfo(node)}, | ||
return (node.value.components.size ? ` '${node.name}': ${generateRouteRecordInfo(node)}, | ||
` : "") + (node.children.size > 0 ? node.getSortedChildren().map(generateRouteNamedMap).join("\n") : ""); | ||
@@ -498,6 +544,7 @@ } | ||
const indentStr = " ".repeat((indent + 1) * 2); | ||
const overrides = node.value.overrides; | ||
const routeRecord = `${startIndent}{ | ||
${indentStr}path: '${node.path}', | ||
${indentStr}${node.value.filePaths.size ? `name: '${node.name}',` : "/* no name */"} | ||
${indentStr}${node.value.filePaths.size ? generateRouteRecordComponent( | ||
${indentStr}${node.value.components.size ? `name: '${node.name}',` : "/* no name */"} | ||
${indentStr}${node.value.components.size ? generateRouteRecordComponent( | ||
node, | ||
@@ -508,4 +555,5 @@ indentStr, | ||
) : "/* no component */"} | ||
${indentStr}${node.value.overrides.props != null ? `props: ${node.value.overrides.props},` : "/* no props */"} | ||
${indentStr}${node.children.size > 0 ? `children: [ | ||
${overrides.props != null ? indentStr + `props: ${overrides.props}, | ||
` : ""}${overrides.alias != null ? indentStr + `alias: ${JSON.stringify(overrides.alias)}, | ||
` : ""}${indentStr}${node.children.size > 0 ? `children: [ | ||
${node.getSortedChildren().map((child) => generateRouteRecord(child, options, importList, indent + 2)).join(",\n")} | ||
@@ -516,3 +564,3 @@ ${indentStr}],` : "/* no children */"}${formatMeta(node, indentStr)} | ||
const definePageDataList = []; | ||
for (const [name, filePath] of node.value.filePaths) { | ||
for (const [name, filePath] of node.value.components) { | ||
const pageDataImport = `_definePage_${name}_${importList.size}`; | ||
@@ -532,3 +580,3 @@ definePageDataList.push(pageDataImport); | ||
function generateRouteRecordComponent(node, indentStr, importMode, importList) { | ||
const files = Array.from(node.value.filePaths); | ||
const files = Array.from(node.value.components); | ||
const isDefaultExport = files.length === 1 && files[0][0] === "default"; | ||
@@ -556,3 +604,3 @@ return isDefaultExport ? `component: ${generatePageImport(files[0][1], importMode, importList)},` : `components: { | ||
function generateImportList(node, indentStr) { | ||
const files = Array.from(node.value.filePaths); | ||
const files = Array.from(node.value.components); | ||
return `[ | ||
@@ -629,3 +677,3 @@ ${files.map(([_key, path]) => `${indentStr} () => import('${path}')`).join(",\n")} | ||
console.error( | ||
`\u26A0\uFE0F unplugin-vue-router: Invalid "lang" of <${block.type}> in ${filePath}. Supported languages are: json5, json, yaml, yml.` | ||
`\u26A0\uFE0F unplugin-vue-router: Language "${lang}" for <${block.type}> is not supported. Supported languages are: json5, json, yaml, yml. Found in in ${filePath}.` | ||
); | ||
@@ -869,3 +917,4 @@ } | ||
const isExtractingDefinePage = MACRO_DEFINE_PAGE_QUERY.test(id); | ||
const { script, scriptSetup, setupAst } = sfc; | ||
const { script, scriptSetup, getSetupAst } = sfc; | ||
const setupAst = getSetupAst(); | ||
const definePageNodes = ((setupAst == null ? void 0 : setupAst.body) || []).map((node) => { | ||
@@ -908,3 +957,4 @@ if (node.type === "ExpressionStatement") | ||
return; | ||
const { setupAst } = sfc; | ||
const { getSetupAst } = sfc; | ||
const setupAst = getSetupAst(); | ||
const definePageNodes = ((_a = setupAst == null ? void 0 : setupAst.body) != null ? _a : []).map((node) => { | ||
@@ -977,2 +1027,71 @@ if (node.type === "ExpressionStatement") | ||
// src/core/extendRoutes.ts | ||
var EditableTreeNode = class { | ||
constructor(node) { | ||
this.node = node; | ||
} | ||
delete() { | ||
return this.node.delete(); | ||
} | ||
insert(path, filePath) { | ||
const node = this.node.insert(path, filePath); | ||
return new EditableTreeNode(node); | ||
} | ||
get parent() { | ||
return this.node.parent && new EditableTreeNode(this.node.parent); | ||
} | ||
get files() { | ||
return this.node.value.components; | ||
} | ||
get name() { | ||
return this.node.name; | ||
} | ||
set name(name) { | ||
this.node.value.addEditOverride({ name }); | ||
} | ||
get isPassThrough() { | ||
return this.node.value.components.size === 0; | ||
} | ||
get meta() { | ||
return this.node.metaAsObject; | ||
} | ||
set meta(meta) { | ||
this.node.value.addEditOverride({ meta }); | ||
} | ||
get path() { | ||
return this.node.path; | ||
} | ||
get alias() { | ||
return this.node.value.overrides.alias; | ||
} | ||
addAlias(alias) { | ||
this.node.value.addEditOverride({ alias }); | ||
} | ||
get params() { | ||
return this.node.params; | ||
} | ||
get fullPath() { | ||
return this.node.fullPath; | ||
} | ||
*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(); | ||
} | ||
*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 | ||
@@ -983,3 +1102,3 @@ function createRoutesContext(options) { | ||
const routeTree = createPrefixTree(options); | ||
const routeMap = /* @__PURE__ */ new Map(); | ||
const editableRoutes = new EditableTreeNode(routeTree); | ||
function log(...args) { | ||
@@ -992,2 +1111,3 @@ if (options.logs) { | ||
async function scanPages() { | ||
var _a; | ||
if (options.extensions.length < 1) { | ||
@@ -1022,2 +1142,5 @@ throw new Error( | ||
); | ||
for (const route of editableRoutes) { | ||
await ((_a = options.extendRoute) == null ? void 0 : _a.call(options, route)); | ||
} | ||
await _writeConfigFiles(); | ||
@@ -1035,24 +1158,25 @@ } | ||
} | ||
async function addPage({ filePath: path, routePath }) { | ||
log(`added "${routePath}" for "${path}"`); | ||
const node = routeTree.insert( | ||
routePath, | ||
(0, import_pathe2.resolve)(root, path) | ||
); | ||
await writeRouteInfoToNode(node, path); | ||
routeMap.set(path, node); | ||
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: path, routePath }) { | ||
log(`updated "${routePath}" for "${path}"`); | ||
const node = routeMap.get(path); | ||
async function updatePage({ filePath, routePath }) { | ||
var _a; | ||
log(`updated "${routePath}" for "${filePath}"`); | ||
const node = routeTree.getChild(filePath); | ||
if (!node) { | ||
console.warn(`Cannot update "${path}": Not found.`); | ||
console.warn(`Cannot update "${filePath}": Not found.`); | ||
return; | ||
} | ||
writeRouteInfoToNode(node, path); | ||
await writeRouteInfoToNode(node, filePath); | ||
await ((_a = options.extendRoute) == null ? void 0 : _a.call(options, new EditableTreeNode(node))); | ||
} | ||
function removePage({ filePath: path, routePath }) { | ||
log(`remove "${routePath}" for "${path}"`); | ||
routeTree.remove(routePath); | ||
routeMap.delete(path); | ||
function removePage({ filePath, routePath }) { | ||
log(`remove "${routePath}" for "${filePath}"`); | ||
routeTree.removeChild(filePath); | ||
} | ||
@@ -1065,3 +1189,3 @@ function setupWatcher(watcher) { | ||
}).on("add", async (ctx) => { | ||
await addPage(ctx); | ||
await addPage(ctx, true); | ||
writeConfigFiles(); | ||
@@ -1108,2 +1232,5 @@ }).on("unlink", async (ctx) => { | ||
log("\u{1F4BE} writing..."); | ||
if (options.beforeWriteFiles) { | ||
await options.beforeWriteFiles(editableRoutes); | ||
} | ||
logTree(routeTree, log); | ||
@@ -1174,3 +1301,11 @@ if (dts) { | ||
if (options.extensions) { | ||
options.extensions.sort((a, b) => b.length - a.length); | ||
options.extensions = options.extensions.map((ext) => { | ||
if (!ext.startsWith(".")) { | ||
console.warn( | ||
`[unplugin-vue-router]: Invalid extension "${ext}". Extensions must start with a dot.` | ||
); | ||
return "." + ext; | ||
} | ||
return ext; | ||
}).sort((a, b) => b.length - a.length); | ||
} | ||
@@ -1177,0 +1312,0 @@ return __spreadProps(__spreadValues(__spreadValues({}, DEFAULT_OPTIONS), options), { |
import * as unplugin from 'unplugin'; | ||
import { R as ResolvedOptions, S as ServerContext, O as Options } from './options-ccb73a7b.js'; | ||
export { T as TreeNode, b as TreeNodeValueParam, d as TreeNodeValueStatic, c as createPrefixTree, a as createTreeNodeValue } from './options-ccb73a7b.js'; | ||
import { L as LiteralStringUnion } from './defineLoader-6f6b8cea.js'; | ||
export { b as _DataLoader, D as _DefineLoaderOptions, g as getFileBasedRouteName, a as getPascalCaseRouteName } from './defineLoader-6f6b8cea.js'; | ||
import { R as ResolvedOptions, S as ServerContext, L as LiteralStringUnion, O as Options } from './options-72c4a647.js'; | ||
export { T as TreeNode, d as TreeNodeValueParam, e as TreeNodeValueStatic, c as createPrefixTree, b as createTreeNodeValue, g as getFileBasedRouteName, a as getPascalCaseRouteName } from './options-72c4a647.js'; | ||
import { RouteParamsRaw, RouteParams, RouteMeta, RouteLocationNormalized, RouteRecordName, RouteLocationNormalizedLoaded, RouteQueryAndHash, RouteLocationOptions, RouteLocation, NavigationGuardNext, NavigationFailure, Router, RouteLocationRaw, RouterLinkProps as RouterLinkProps$1 } from 'vue-router'; | ||
import { Ref, AllowedComponentProps, ComponentCustomProps, VNodeProps, UnwrapRef, VNode, ComputedRef } from 'vue'; | ||
export { a as _DataLoader, D as _DefineLoaderOptions } from './defineLoader-b1055382.js'; | ||
@@ -9,0 +8,0 @@ declare function createRoutesContext(options: ResolvedOptions): { |
@@ -150,3 +150,3 @@ "use strict"; | ||
}).join(""); | ||
if (node.value.filePaths.size && node.children.has("index")) { | ||
if (node.value.components.size && node.children.has("index")) { | ||
name += "Parent"; | ||
@@ -160,3 +160,3 @@ } | ||
return ""; | ||
return getFileBasedRouteName(node.parent) + "/" + node.value.rawSegment; | ||
return getFileBasedRouteName(node.parent) + "/" + (node.value.rawSegment === "index" ? "" : node.value.rawSegment); | ||
} | ||
@@ -174,3 +174,4 @@ function mergeRouteRecordOverride(a, b) { | ||
if (key === "alias") { | ||
merged[key] = [...a[key] || [], ...b[key] || []]; | ||
const newAlias = []; | ||
merged[key] = newAlias.concat(a.alias || [], b.alias || []); | ||
} else if (key === "meta") { | ||
@@ -205,6 +206,8 @@ merged[key] = mergeDeep(a[key] || {}, b[key] || {}); | ||
// src/core/treeNodeValue.ts | ||
var EDITS_OVERRIDE_NAME = "@@edits"; | ||
var _TreeNodeValueBase = class { | ||
constructor(rawSegment, parent, pathSegment = rawSegment, subSegments = [rawSegment]) { | ||
constructor(rawSegment, parent, pathSegment = rawSegment, subSegments = [pathSegment]) { | ||
this._overrides = /* @__PURE__ */ new Map(); | ||
this.includeLoaderGuard = false; | ||
this.components = /* @__PURE__ */ new Map(); | ||
this._type = 0; | ||
@@ -216,3 +219,2 @@ this.rawSegment = rawSegment; | ||
this.path = (!parentPath || parentPath === "/") && this.pathSegment === "" ? "/" : joinPath((parent == null ? void 0 : parent.path) || "", this.pathSegment); | ||
this.filePaths = /* @__PURE__ */ new Map(); | ||
} | ||
@@ -230,3 +232,3 @@ toString() { | ||
return [...this._overrides.entries()].sort( | ||
([nameA], [nameB]) => nameA === nameB ? 0 : nameA < nameB ? -1 : 1 | ||
([nameA], [nameB]) => nameA === nameB ? 0 : nameA !== EDITS_OVERRIDE_NAME && (nameA < nameB || nameB === EDITS_OVERRIDE_NAME) ? -1 : 1 | ||
).reduce((acc, [_path, routeBlock]) => { | ||
@@ -239,2 +241,15 @@ return mergeRouteRecordOverride(acc, routeBlock); | ||
} | ||
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) { | ||
console.log("add edit", routeBlock); | ||
return this.mergeOverride(EDITS_OVERRIDE_NAME, routeBlock); | ||
} | ||
}; | ||
@@ -256,3 +271,3 @@ var TreeNodeValueStatic = class extends _TreeNodeValueBase { | ||
if (!segment || segment === "index") { | ||
return new TreeNodeValueStatic("", parent); | ||
return new TreeNodeValueStatic(segment, parent, ""); | ||
} | ||
@@ -371,3 +386,3 @@ const [pathSegment, params, subSegments] = parseSegment(segment); | ||
if (isComponent) { | ||
child.value.filePaths.set(viewName, filePath); | ||
child.value.components.set(viewName, filePath); | ||
} | ||
@@ -387,2 +402,9 @@ if (tail) { | ||
} | ||
delete() { | ||
if (!this.parent) { | ||
throw new Error("Cannot delete the root node."); | ||
} | ||
this.parent.children.delete(this.value.rawSegment); | ||
this.parent = void 0; | ||
} | ||
remove(path) { | ||
@@ -401,3 +423,3 @@ const { tail, segment, viewName, isComponent } = splitFilePath( | ||
child.remove(tail); | ||
if (child.children.size === 0 && child.value.filePaths.size === 0) { | ||
if (child.children.size === 0 && child.value.components.size === 0) { | ||
this.children.delete(segment); | ||
@@ -407,5 +429,5 @@ } | ||
if (isComponent) { | ||
child.value.filePaths.delete(viewName); | ||
child.value.components.delete(viewName); | ||
} | ||
if (child.children.size === 0 && child.value.filePaths.size === 0) { | ||
if (child.children.size === 0 && child.value.components.size === 0) { | ||
this.children.delete(segment); | ||
@@ -426,7 +448,11 @@ } | ||
} | ||
get meta() { | ||
const overrideMeta = __spreadValues({}, this.value.overrides.meta); | ||
get metaAsObject() { | ||
const meta = __spreadValues({}, this.value.overrides.meta); | ||
if (this.value.includeLoaderGuard) { | ||
overrideMeta._loaderGuard = true; | ||
meta._loaderGuard = true; | ||
} | ||
return meta; | ||
} | ||
get meta() { | ||
const overrideMeta = this.metaAsObject; | ||
return Object.keys(overrideMeta).length > 0 ? JSON.stringify(overrideMeta, null, 2) : ""; | ||
@@ -446,10 +472,30 @@ } | ||
isRoot() { | ||
return this.value.path === "/" && !this.value.filePaths.size; | ||
return this.value.path === "/" && !this.value.components.size; | ||
} | ||
toString() { | ||
return `${this.value}${this.value.filePaths.size > 1 || this.value.filePaths.size === 1 && !this.value.filePaths.get("default") ? ` \u2388(${Array.from(this.value.filePaths.keys()).join(", ")})` : ""}${this.hasDefinePage ? " \u2691 definePage()" : ""}`; | ||
return `${this.value}${this.value.components.size > 1 || 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); | ||
} | ||
removeChild(filePath) { | ||
if (this.map.has(filePath)) { | ||
this.map.get(filePath).delete(); | ||
this.map.delete(filePath); | ||
} | ||
} | ||
}; | ||
function createPrefixTree(options) { | ||
return new TreeNode(options, ""); | ||
return new PrefixTree(options); | ||
} | ||
@@ -496,3 +542,3 @@ function splitFilePath(filePath, options) { | ||
} | ||
return (node.value.filePaths.size ? ` '${node.name}': ${generateRouteRecordInfo(node)}, | ||
return (node.value.components.size ? ` '${node.name}': ${generateRouteRecordInfo(node)}, | ||
` : "") + (node.children.size > 0 ? node.getSortedChildren().map(generateRouteNamedMap).join("\n") : ""); | ||
@@ -526,6 +572,7 @@ } | ||
const indentStr = " ".repeat((indent + 1) * 2); | ||
const overrides = node.value.overrides; | ||
const routeRecord = `${startIndent}{ | ||
${indentStr}path: '${node.path}', | ||
${indentStr}${node.value.filePaths.size ? `name: '${node.name}',` : "/* no name */"} | ||
${indentStr}${node.value.filePaths.size ? generateRouteRecordComponent( | ||
${indentStr}${node.value.components.size ? `name: '${node.name}',` : "/* no name */"} | ||
${indentStr}${node.value.components.size ? generateRouteRecordComponent( | ||
node, | ||
@@ -536,4 +583,5 @@ indentStr, | ||
) : "/* no component */"} | ||
${indentStr}${node.value.overrides.props != null ? `props: ${node.value.overrides.props},` : "/* no props */"} | ||
${indentStr}${node.children.size > 0 ? `children: [ | ||
${overrides.props != null ? indentStr + `props: ${overrides.props}, | ||
` : ""}${overrides.alias != null ? indentStr + `alias: ${JSON.stringify(overrides.alias)}, | ||
` : ""}${indentStr}${node.children.size > 0 ? `children: [ | ||
${node.getSortedChildren().map((child) => generateRouteRecord(child, options, importList, indent + 2)).join(",\n")} | ||
@@ -544,3 +592,3 @@ ${indentStr}],` : "/* no children */"}${formatMeta(node, indentStr)} | ||
const definePageDataList = []; | ||
for (const [name, filePath] of node.value.filePaths) { | ||
for (const [name, filePath] of node.value.components) { | ||
const pageDataImport = `_definePage_${name}_${importList.size}`; | ||
@@ -560,3 +608,3 @@ definePageDataList.push(pageDataImport); | ||
function generateRouteRecordComponent(node, indentStr, importMode, importList) { | ||
const files = Array.from(node.value.filePaths); | ||
const files = Array.from(node.value.components); | ||
const isDefaultExport = files.length === 1 && files[0][0] === "default"; | ||
@@ -584,3 +632,3 @@ return isDefaultExport ? `component: ${generatePageImport(files[0][1], importMode, importList)},` : `components: { | ||
function generateImportList(node, indentStr) { | ||
const files = Array.from(node.value.filePaths); | ||
const files = Array.from(node.value.components); | ||
return `[ | ||
@@ -657,3 +705,3 @@ ${files.map(([_key, path]) => `${indentStr} () => import('${path}')`).join(",\n")} | ||
console.error( | ||
`\u26A0\uFE0F unplugin-vue-router: Invalid "lang" of <${block.type}> in ${filePath}. Supported languages are: json5, json, yaml, yml.` | ||
`\u26A0\uFE0F unplugin-vue-router: Language "${lang}" for <${block.type}> is not supported. Supported languages are: json5, json, yaml, yml. Found in in ${filePath}.` | ||
); | ||
@@ -897,3 +945,4 @@ } | ||
const isExtractingDefinePage = MACRO_DEFINE_PAGE_QUERY.test(id); | ||
const { script, scriptSetup, setupAst } = sfc; | ||
const { script, scriptSetup, getSetupAst } = sfc; | ||
const setupAst = getSetupAst(); | ||
const definePageNodes = ((setupAst == null ? void 0 : setupAst.body) || []).map((node) => { | ||
@@ -936,3 +985,4 @@ if (node.type === "ExpressionStatement") | ||
return; | ||
const { setupAst } = sfc; | ||
const { getSetupAst } = sfc; | ||
const setupAst = getSetupAst(); | ||
const definePageNodes = ((_a = setupAst == null ? void 0 : setupAst.body) != null ? _a : []).map((node) => { | ||
@@ -1005,2 +1055,71 @@ if (node.type === "ExpressionStatement") | ||
// src/core/extendRoutes.ts | ||
var EditableTreeNode = class { | ||
constructor(node) { | ||
this.node = node; | ||
} | ||
delete() { | ||
return this.node.delete(); | ||
} | ||
insert(path, filePath) { | ||
const node = this.node.insert(path, filePath); | ||
return new EditableTreeNode(node); | ||
} | ||
get parent() { | ||
return this.node.parent && new EditableTreeNode(this.node.parent); | ||
} | ||
get files() { | ||
return this.node.value.components; | ||
} | ||
get name() { | ||
return this.node.name; | ||
} | ||
set name(name) { | ||
this.node.value.addEditOverride({ name }); | ||
} | ||
get isPassThrough() { | ||
return this.node.value.components.size === 0; | ||
} | ||
get meta() { | ||
return this.node.metaAsObject; | ||
} | ||
set meta(meta) { | ||
this.node.value.addEditOverride({ meta }); | ||
} | ||
get path() { | ||
return this.node.path; | ||
} | ||
get alias() { | ||
return this.node.value.overrides.alias; | ||
} | ||
addAlias(alias) { | ||
this.node.value.addEditOverride({ alias }); | ||
} | ||
get params() { | ||
return this.node.params; | ||
} | ||
get fullPath() { | ||
return this.node.fullPath; | ||
} | ||
*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(); | ||
} | ||
*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 | ||
@@ -1011,3 +1130,3 @@ function createRoutesContext(options) { | ||
const routeTree = createPrefixTree(options); | ||
const routeMap = /* @__PURE__ */ new Map(); | ||
const editableRoutes = new EditableTreeNode(routeTree); | ||
function log(...args) { | ||
@@ -1020,2 +1139,3 @@ if (options.logs) { | ||
async function scanPages() { | ||
var _a; | ||
if (options.extensions.length < 1) { | ||
@@ -1050,2 +1170,5 @@ throw new Error( | ||
); | ||
for (const route of editableRoutes) { | ||
await ((_a = options.extendRoute) == null ? void 0 : _a.call(options, route)); | ||
} | ||
await _writeConfigFiles(); | ||
@@ -1063,24 +1186,25 @@ } | ||
} | ||
async function addPage({ filePath: path, routePath }) { | ||
log(`added "${routePath}" for "${path}"`); | ||
const node = routeTree.insert( | ||
routePath, | ||
(0, import_pathe2.resolve)(root, path) | ||
); | ||
await writeRouteInfoToNode(node, path); | ||
routeMap.set(path, node); | ||
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: path, routePath }) { | ||
log(`updated "${routePath}" for "${path}"`); | ||
const node = routeMap.get(path); | ||
async function updatePage({ filePath, routePath }) { | ||
var _a; | ||
log(`updated "${routePath}" for "${filePath}"`); | ||
const node = routeTree.getChild(filePath); | ||
if (!node) { | ||
console.warn(`Cannot update "${path}": Not found.`); | ||
console.warn(`Cannot update "${filePath}": Not found.`); | ||
return; | ||
} | ||
writeRouteInfoToNode(node, path); | ||
await writeRouteInfoToNode(node, filePath); | ||
await ((_a = options.extendRoute) == null ? void 0 : _a.call(options, new EditableTreeNode(node))); | ||
} | ||
function removePage({ filePath: path, routePath }) { | ||
log(`remove "${routePath}" for "${path}"`); | ||
routeTree.remove(routePath); | ||
routeMap.delete(path); | ||
function removePage({ filePath, routePath }) { | ||
log(`remove "${routePath}" for "${filePath}"`); | ||
routeTree.removeChild(filePath); | ||
} | ||
@@ -1093,3 +1217,3 @@ function setupWatcher(watcher) { | ||
}).on("add", async (ctx) => { | ||
await addPage(ctx); | ||
await addPage(ctx, true); | ||
writeConfigFiles(); | ||
@@ -1136,2 +1260,5 @@ }).on("unlink", async (ctx) => { | ||
log("\u{1F4BE} writing..."); | ||
if (options.beforeWriteFiles) { | ||
await options.beforeWriteFiles(editableRoutes); | ||
} | ||
logTree(routeTree, log); | ||
@@ -1202,3 +1329,11 @@ if (dts) { | ||
if (options.extensions) { | ||
options.extensions.sort((a, b) => b.length - a.length); | ||
options.extensions = options.extensions.map((ext) => { | ||
if (!ext.startsWith(".")) { | ||
console.warn( | ||
`[unplugin-vue-router]: Invalid extension "${ext}". Extensions must start with a dot.` | ||
); | ||
return "." + ext; | ||
} | ||
return ext; | ||
}).sort((a, b) => b.length - a.length); | ||
} | ||
@@ -1205,0 +1340,0 @@ return __spreadProps(__spreadValues(__spreadValues({}, DEFAULT_OPTIONS), options), { |
@@ -1,2 +0,2 @@ | ||
export { D as DEFAULT_OPTIONS, O as Options, R as ResolvedOptions, f as RoutesFolder, e as RoutesFolderOption, S as ServerContext, g as _OptionsImportMode, _ as _RoutesFolder, r as resolveOptions } from './options-ccb73a7b.js'; | ||
export { D as DEFAULT_OPTIONS, O as Options, R as ResolvedOptions, h as RoutesFolder, f as RoutesFolderOption, S as ServerContext, i as _OptionsImportMode, _ as _RoutesFolder, r as resolveOptions } from './options-72c4a647.js'; | ||
import 'vue-router'; |
@@ -52,3 +52,3 @@ "use strict"; | ||
return ""; | ||
return getFileBasedRouteName(node.parent) + "/" + node.value.rawSegment; | ||
return getFileBasedRouteName(node.parent) + "/" + (node.value.rawSegment === "index" ? "" : node.value.rawSegment); | ||
} | ||
@@ -84,3 +84,11 @@ | ||
if (options.extensions) { | ||
options.extensions.sort((a, b) => b.length - a.length); | ||
options.extensions = options.extensions.map((ext) => { | ||
if (!ext.startsWith(".")) { | ||
console.warn( | ||
`[unplugin-vue-router]: Invalid extension "${ext}". Extensions must start with a dot.` | ||
); | ||
return "." + ext; | ||
} | ||
return ext; | ||
}).sort((a, b) => b.length - a.length); | ||
} | ||
@@ -87,0 +95,0 @@ return __spreadProps(__spreadValues(__spreadValues({}, DEFAULT_OPTIONS), options), { |
import * as rollup from 'rollup'; | ||
import { O as Options } from './options-ccb73a7b.js'; | ||
import { O as Options } from './options-72c4a647.js'; | ||
import 'vue-router'; | ||
@@ -4,0 +4,0 @@ |
@@ -132,3 +132,3 @@ "use strict"; | ||
return ""; | ||
return getFileBasedRouteName(node.parent) + "/" + node.value.rawSegment; | ||
return getFileBasedRouteName(node.parent) + "/" + (node.value.rawSegment === "index" ? "" : node.value.rawSegment); | ||
} | ||
@@ -146,3 +146,4 @@ function mergeRouteRecordOverride(a, b) { | ||
if (key === "alias") { | ||
merged[key] = [...a[key] || [], ...b[key] || []]; | ||
const newAlias = []; | ||
merged[key] = newAlias.concat(a.alias || [], b.alias || []); | ||
} else if (key === "meta") { | ||
@@ -177,6 +178,8 @@ merged[key] = mergeDeep(a[key] || {}, b[key] || {}); | ||
// src/core/treeNodeValue.ts | ||
var EDITS_OVERRIDE_NAME = "@@edits"; | ||
var _TreeNodeValueBase = class { | ||
constructor(rawSegment, parent, pathSegment = rawSegment, subSegments = [rawSegment]) { | ||
constructor(rawSegment, parent, pathSegment = rawSegment, subSegments = [pathSegment]) { | ||
this._overrides = /* @__PURE__ */ new Map(); | ||
this.includeLoaderGuard = false; | ||
this.components = /* @__PURE__ */ new Map(); | ||
this._type = 0; | ||
@@ -188,3 +191,2 @@ this.rawSegment = rawSegment; | ||
this.path = (!parentPath || parentPath === "/") && this.pathSegment === "" ? "/" : joinPath((parent == null ? void 0 : parent.path) || "", this.pathSegment); | ||
this.filePaths = /* @__PURE__ */ new Map(); | ||
} | ||
@@ -202,3 +204,3 @@ toString() { | ||
return [...this._overrides.entries()].sort( | ||
([nameA], [nameB]) => nameA === nameB ? 0 : nameA < nameB ? -1 : 1 | ||
([nameA], [nameB]) => nameA === nameB ? 0 : nameA !== EDITS_OVERRIDE_NAME && (nameA < nameB || nameB === EDITS_OVERRIDE_NAME) ? -1 : 1 | ||
).reduce((acc, [_path, routeBlock]) => { | ||
@@ -211,2 +213,15 @@ return mergeRouteRecordOverride(acc, routeBlock); | ||
} | ||
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) { | ||
console.log("add edit", routeBlock); | ||
return this.mergeOverride(EDITS_OVERRIDE_NAME, routeBlock); | ||
} | ||
}; | ||
@@ -228,3 +243,3 @@ var TreeNodeValueStatic = class extends _TreeNodeValueBase { | ||
if (!segment || segment === "index") { | ||
return new TreeNodeValueStatic("", parent); | ||
return new TreeNodeValueStatic(segment, parent, ""); | ||
} | ||
@@ -343,3 +358,3 @@ const [pathSegment, params, subSegments] = parseSegment(segment); | ||
if (isComponent) { | ||
child.value.filePaths.set(viewName, filePath); | ||
child.value.components.set(viewName, filePath); | ||
} | ||
@@ -359,2 +374,9 @@ if (tail) { | ||
} | ||
delete() { | ||
if (!this.parent) { | ||
throw new Error("Cannot delete the root node."); | ||
} | ||
this.parent.children.delete(this.value.rawSegment); | ||
this.parent = void 0; | ||
} | ||
remove(path) { | ||
@@ -373,3 +395,3 @@ const { tail, segment, viewName, isComponent } = splitFilePath( | ||
child.remove(tail); | ||
if (child.children.size === 0 && child.value.filePaths.size === 0) { | ||
if (child.children.size === 0 && child.value.components.size === 0) { | ||
this.children.delete(segment); | ||
@@ -379,5 +401,5 @@ } | ||
if (isComponent) { | ||
child.value.filePaths.delete(viewName); | ||
child.value.components.delete(viewName); | ||
} | ||
if (child.children.size === 0 && child.value.filePaths.size === 0) { | ||
if (child.children.size === 0 && child.value.components.size === 0) { | ||
this.children.delete(segment); | ||
@@ -398,7 +420,11 @@ } | ||
} | ||
get meta() { | ||
const overrideMeta = __spreadValues({}, this.value.overrides.meta); | ||
get metaAsObject() { | ||
const meta = __spreadValues({}, this.value.overrides.meta); | ||
if (this.value.includeLoaderGuard) { | ||
overrideMeta._loaderGuard = true; | ||
meta._loaderGuard = true; | ||
} | ||
return meta; | ||
} | ||
get meta() { | ||
const overrideMeta = this.metaAsObject; | ||
return Object.keys(overrideMeta).length > 0 ? JSON.stringify(overrideMeta, null, 2) : ""; | ||
@@ -418,10 +444,30 @@ } | ||
isRoot() { | ||
return this.value.path === "/" && !this.value.filePaths.size; | ||
return this.value.path === "/" && !this.value.components.size; | ||
} | ||
toString() { | ||
return `${this.value}${this.value.filePaths.size > 1 || this.value.filePaths.size === 1 && !this.value.filePaths.get("default") ? ` \u2388(${Array.from(this.value.filePaths.keys()).join(", ")})` : ""}${this.hasDefinePage ? " \u2691 definePage()" : ""}`; | ||
return `${this.value}${this.value.components.size > 1 || 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); | ||
} | ||
removeChild(filePath) { | ||
if (this.map.has(filePath)) { | ||
this.map.get(filePath).delete(); | ||
this.map.delete(filePath); | ||
} | ||
} | ||
}; | ||
function createPrefixTree(options) { | ||
return new TreeNode(options, ""); | ||
return new PrefixTree(options); | ||
} | ||
@@ -468,3 +514,3 @@ function splitFilePath(filePath, options) { | ||
} | ||
return (node.value.filePaths.size ? ` '${node.name}': ${generateRouteRecordInfo(node)}, | ||
return (node.value.components.size ? ` '${node.name}': ${generateRouteRecordInfo(node)}, | ||
` : "") + (node.children.size > 0 ? node.getSortedChildren().map(generateRouteNamedMap).join("\n") : ""); | ||
@@ -498,6 +544,7 @@ } | ||
const indentStr = " ".repeat((indent + 1) * 2); | ||
const overrides = node.value.overrides; | ||
const routeRecord = `${startIndent}{ | ||
${indentStr}path: '${node.path}', | ||
${indentStr}${node.value.filePaths.size ? `name: '${node.name}',` : "/* no name */"} | ||
${indentStr}${node.value.filePaths.size ? generateRouteRecordComponent( | ||
${indentStr}${node.value.components.size ? `name: '${node.name}',` : "/* no name */"} | ||
${indentStr}${node.value.components.size ? generateRouteRecordComponent( | ||
node, | ||
@@ -508,4 +555,5 @@ indentStr, | ||
) : "/* no component */"} | ||
${indentStr}${node.value.overrides.props != null ? `props: ${node.value.overrides.props},` : "/* no props */"} | ||
${indentStr}${node.children.size > 0 ? `children: [ | ||
${overrides.props != null ? indentStr + `props: ${overrides.props}, | ||
` : ""}${overrides.alias != null ? indentStr + `alias: ${JSON.stringify(overrides.alias)}, | ||
` : ""}${indentStr}${node.children.size > 0 ? `children: [ | ||
${node.getSortedChildren().map((child) => generateRouteRecord(child, options, importList, indent + 2)).join(",\n")} | ||
@@ -516,3 +564,3 @@ ${indentStr}],` : "/* no children */"}${formatMeta(node, indentStr)} | ||
const definePageDataList = []; | ||
for (const [name, filePath] of node.value.filePaths) { | ||
for (const [name, filePath] of node.value.components) { | ||
const pageDataImport = `_definePage_${name}_${importList.size}`; | ||
@@ -532,3 +580,3 @@ definePageDataList.push(pageDataImport); | ||
function generateRouteRecordComponent(node, indentStr, importMode, importList) { | ||
const files = Array.from(node.value.filePaths); | ||
const files = Array.from(node.value.components); | ||
const isDefaultExport = files.length === 1 && files[0][0] === "default"; | ||
@@ -556,3 +604,3 @@ return isDefaultExport ? `component: ${generatePageImport(files[0][1], importMode, importList)},` : `components: { | ||
function generateImportList(node, indentStr) { | ||
const files = Array.from(node.value.filePaths); | ||
const files = Array.from(node.value.components); | ||
return `[ | ||
@@ -629,3 +677,3 @@ ${files.map(([_key, path]) => `${indentStr} () => import('${path}')`).join(",\n")} | ||
console.error( | ||
`\u26A0\uFE0F unplugin-vue-router: Invalid "lang" of <${block.type}> in ${filePath}. Supported languages are: json5, json, yaml, yml.` | ||
`\u26A0\uFE0F unplugin-vue-router: Language "${lang}" for <${block.type}> is not supported. Supported languages are: json5, json, yaml, yml. Found in in ${filePath}.` | ||
); | ||
@@ -869,3 +917,4 @@ } | ||
const isExtractingDefinePage = MACRO_DEFINE_PAGE_QUERY.test(id); | ||
const { script, scriptSetup, setupAst } = sfc; | ||
const { script, scriptSetup, getSetupAst } = sfc; | ||
const setupAst = getSetupAst(); | ||
const definePageNodes = ((setupAst == null ? void 0 : setupAst.body) || []).map((node) => { | ||
@@ -908,3 +957,4 @@ if (node.type === "ExpressionStatement") | ||
return; | ||
const { setupAst } = sfc; | ||
const { getSetupAst } = sfc; | ||
const setupAst = getSetupAst(); | ||
const definePageNodes = ((_a = setupAst == null ? void 0 : setupAst.body) != null ? _a : []).map((node) => { | ||
@@ -977,2 +1027,71 @@ if (node.type === "ExpressionStatement") | ||
// src/core/extendRoutes.ts | ||
var EditableTreeNode = class { | ||
constructor(node) { | ||
this.node = node; | ||
} | ||
delete() { | ||
return this.node.delete(); | ||
} | ||
insert(path, filePath) { | ||
const node = this.node.insert(path, filePath); | ||
return new EditableTreeNode(node); | ||
} | ||
get parent() { | ||
return this.node.parent && new EditableTreeNode(this.node.parent); | ||
} | ||
get files() { | ||
return this.node.value.components; | ||
} | ||
get name() { | ||
return this.node.name; | ||
} | ||
set name(name) { | ||
this.node.value.addEditOverride({ name }); | ||
} | ||
get isPassThrough() { | ||
return this.node.value.components.size === 0; | ||
} | ||
get meta() { | ||
return this.node.metaAsObject; | ||
} | ||
set meta(meta) { | ||
this.node.value.addEditOverride({ meta }); | ||
} | ||
get path() { | ||
return this.node.path; | ||
} | ||
get alias() { | ||
return this.node.value.overrides.alias; | ||
} | ||
addAlias(alias) { | ||
this.node.value.addEditOverride({ alias }); | ||
} | ||
get params() { | ||
return this.node.params; | ||
} | ||
get fullPath() { | ||
return this.node.fullPath; | ||
} | ||
*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(); | ||
} | ||
*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 | ||
@@ -983,3 +1102,3 @@ function createRoutesContext(options) { | ||
const routeTree = createPrefixTree(options); | ||
const routeMap = /* @__PURE__ */ new Map(); | ||
const editableRoutes = new EditableTreeNode(routeTree); | ||
function log(...args) { | ||
@@ -992,2 +1111,3 @@ if (options.logs) { | ||
async function scanPages() { | ||
var _a; | ||
if (options.extensions.length < 1) { | ||
@@ -1022,2 +1142,5 @@ throw new Error( | ||
); | ||
for (const route of editableRoutes) { | ||
await ((_a = options.extendRoute) == null ? void 0 : _a.call(options, route)); | ||
} | ||
await _writeConfigFiles(); | ||
@@ -1035,24 +1158,25 @@ } | ||
} | ||
async function addPage({ filePath: path, routePath }) { | ||
log(`added "${routePath}" for "${path}"`); | ||
const node = routeTree.insert( | ||
routePath, | ||
(0, import_pathe2.resolve)(root, path) | ||
); | ||
await writeRouteInfoToNode(node, path); | ||
routeMap.set(path, node); | ||
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: path, routePath }) { | ||
log(`updated "${routePath}" for "${path}"`); | ||
const node = routeMap.get(path); | ||
async function updatePage({ filePath, routePath }) { | ||
var _a; | ||
log(`updated "${routePath}" for "${filePath}"`); | ||
const node = routeTree.getChild(filePath); | ||
if (!node) { | ||
console.warn(`Cannot update "${path}": Not found.`); | ||
console.warn(`Cannot update "${filePath}": Not found.`); | ||
return; | ||
} | ||
writeRouteInfoToNode(node, path); | ||
await writeRouteInfoToNode(node, filePath); | ||
await ((_a = options.extendRoute) == null ? void 0 : _a.call(options, new EditableTreeNode(node))); | ||
} | ||
function removePage({ filePath: path, routePath }) { | ||
log(`remove "${routePath}" for "${path}"`); | ||
routeTree.remove(routePath); | ||
routeMap.delete(path); | ||
function removePage({ filePath, routePath }) { | ||
log(`remove "${routePath}" for "${filePath}"`); | ||
routeTree.removeChild(filePath); | ||
} | ||
@@ -1065,3 +1189,3 @@ function setupWatcher(watcher) { | ||
}).on("add", async (ctx) => { | ||
await addPage(ctx); | ||
await addPage(ctx, true); | ||
writeConfigFiles(); | ||
@@ -1108,2 +1232,5 @@ }).on("unlink", async (ctx) => { | ||
log("\u{1F4BE} writing..."); | ||
if (options.beforeWriteFiles) { | ||
await options.beforeWriteFiles(editableRoutes); | ||
} | ||
logTree(routeTree, log); | ||
@@ -1174,3 +1301,11 @@ if (dts) { | ||
if (options.extensions) { | ||
options.extensions.sort((a, b) => b.length - a.length); | ||
options.extensions = options.extensions.map((ext) => { | ||
if (!ext.startsWith(".")) { | ||
console.warn( | ||
`[unplugin-vue-router]: Invalid extension "${ext}". Extensions must start with a dot.` | ||
); | ||
return "." + ext; | ||
} | ||
return ext; | ||
}).sort((a, b) => b.length - a.length); | ||
} | ||
@@ -1177,0 +1312,0 @@ return __spreadProps(__spreadValues(__spreadValues({}, DEFAULT_OPTIONS), options), { |
import { Router, RouteLocationNormalized, RouteRecordRaw } from 'vue-router'; | ||
import { b as DataLoader, A as Awaitable } from './defineLoader-6f6b8cea.js'; | ||
export { D as DefineLoaderOptions, d as _defineLoader, s as _stopDataFetchingScope } from './defineLoader-6f6b8cea.js'; | ||
import './options-ccb73a7b.js'; | ||
import { a as DataLoader } from './defineLoader-b1055382.js'; | ||
export { D as DefineLoaderOptions, d as _defineLoader, s as _stopDataFetchingScope } from './defineLoader-b1055382.js'; | ||
import { A as Awaitable } from './options-72c4a647.js'; | ||
import 'vue'; | ||
@@ -40,5 +40,5 @@ | ||
*/ | ||
declare const _definePage: (route: Partial<Omit<RouteRecordRaw, 'children' | 'components' | 'component'>>) => Partial<Omit<RouteRecordRaw, "children" | "components" | "component">>; | ||
declare const _definePage: (route: Partial<Omit<RouteRecordRaw, 'children' | 'components' | 'component'>>) => Partial<Omit<RouteRecordRaw, "components" | "component" | "children">>; | ||
declare function _mergeRouteRecord(main: RouteRecordRaw, ...routeRecords: Partial<RouteRecordRaw>[]): RouteRecordRaw; | ||
export { DataLoader, HasDataLoaderMeta as _HasDataLoaderMeta, _definePage, _mergeRouteRecord, setupDataFetchingGuard as _setupDataFetchingGuard }; |
@@ -312,4 +312,9 @@ "use strict"; | ||
const meta = Object.assign({}, acc.meta, routeRecord.meta); | ||
const alias = [].concat( | ||
acc.alias || [], | ||
routeRecord.alias || [] | ||
); | ||
Object.assign(acc, routeRecord); | ||
acc.meta = meta; | ||
acc.alias = alias; | ||
return acc; | ||
@@ -316,0 +321,0 @@ }, main); |
import * as vite from 'vite'; | ||
import { O as Options } from './options-ccb73a7b.js'; | ||
import { O as Options } from './options-72c4a647.js'; | ||
import 'vue-router'; | ||
@@ -4,0 +4,0 @@ |
229
dist/vite.js
@@ -132,3 +132,3 @@ "use strict"; | ||
return ""; | ||
return getFileBasedRouteName(node.parent) + "/" + node.value.rawSegment; | ||
return getFileBasedRouteName(node.parent) + "/" + (node.value.rawSegment === "index" ? "" : node.value.rawSegment); | ||
} | ||
@@ -146,3 +146,4 @@ function mergeRouteRecordOverride(a, b) { | ||
if (key === "alias") { | ||
merged[key] = [...a[key] || [], ...b[key] || []]; | ||
const newAlias = []; | ||
merged[key] = newAlias.concat(a.alias || [], b.alias || []); | ||
} else if (key === "meta") { | ||
@@ -177,6 +178,8 @@ merged[key] = mergeDeep(a[key] || {}, b[key] || {}); | ||
// src/core/treeNodeValue.ts | ||
var EDITS_OVERRIDE_NAME = "@@edits"; | ||
var _TreeNodeValueBase = class { | ||
constructor(rawSegment, parent, pathSegment = rawSegment, subSegments = [rawSegment]) { | ||
constructor(rawSegment, parent, pathSegment = rawSegment, subSegments = [pathSegment]) { | ||
this._overrides = /* @__PURE__ */ new Map(); | ||
this.includeLoaderGuard = false; | ||
this.components = /* @__PURE__ */ new Map(); | ||
this._type = 0; | ||
@@ -188,3 +191,2 @@ this.rawSegment = rawSegment; | ||
this.path = (!parentPath || parentPath === "/") && this.pathSegment === "" ? "/" : joinPath((parent == null ? void 0 : parent.path) || "", this.pathSegment); | ||
this.filePaths = /* @__PURE__ */ new Map(); | ||
} | ||
@@ -202,3 +204,3 @@ toString() { | ||
return [...this._overrides.entries()].sort( | ||
([nameA], [nameB]) => nameA === nameB ? 0 : nameA < nameB ? -1 : 1 | ||
([nameA], [nameB]) => nameA === nameB ? 0 : nameA !== EDITS_OVERRIDE_NAME && (nameA < nameB || nameB === EDITS_OVERRIDE_NAME) ? -1 : 1 | ||
).reduce((acc, [_path, routeBlock]) => { | ||
@@ -211,2 +213,15 @@ return mergeRouteRecordOverride(acc, routeBlock); | ||
} | ||
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) { | ||
console.log("add edit", routeBlock); | ||
return this.mergeOverride(EDITS_OVERRIDE_NAME, routeBlock); | ||
} | ||
}; | ||
@@ -228,3 +243,3 @@ var TreeNodeValueStatic = class extends _TreeNodeValueBase { | ||
if (!segment || segment === "index") { | ||
return new TreeNodeValueStatic("", parent); | ||
return new TreeNodeValueStatic(segment, parent, ""); | ||
} | ||
@@ -343,3 +358,3 @@ const [pathSegment, params, subSegments] = parseSegment(segment); | ||
if (isComponent) { | ||
child.value.filePaths.set(viewName, filePath); | ||
child.value.components.set(viewName, filePath); | ||
} | ||
@@ -359,2 +374,9 @@ if (tail) { | ||
} | ||
delete() { | ||
if (!this.parent) { | ||
throw new Error("Cannot delete the root node."); | ||
} | ||
this.parent.children.delete(this.value.rawSegment); | ||
this.parent = void 0; | ||
} | ||
remove(path) { | ||
@@ -373,3 +395,3 @@ const { tail, segment, viewName, isComponent } = splitFilePath( | ||
child.remove(tail); | ||
if (child.children.size === 0 && child.value.filePaths.size === 0) { | ||
if (child.children.size === 0 && child.value.components.size === 0) { | ||
this.children.delete(segment); | ||
@@ -379,5 +401,5 @@ } | ||
if (isComponent) { | ||
child.value.filePaths.delete(viewName); | ||
child.value.components.delete(viewName); | ||
} | ||
if (child.children.size === 0 && child.value.filePaths.size === 0) { | ||
if (child.children.size === 0 && child.value.components.size === 0) { | ||
this.children.delete(segment); | ||
@@ -398,7 +420,11 @@ } | ||
} | ||
get meta() { | ||
const overrideMeta = __spreadValues({}, this.value.overrides.meta); | ||
get metaAsObject() { | ||
const meta = __spreadValues({}, this.value.overrides.meta); | ||
if (this.value.includeLoaderGuard) { | ||
overrideMeta._loaderGuard = true; | ||
meta._loaderGuard = true; | ||
} | ||
return meta; | ||
} | ||
get meta() { | ||
const overrideMeta = this.metaAsObject; | ||
return Object.keys(overrideMeta).length > 0 ? JSON.stringify(overrideMeta, null, 2) : ""; | ||
@@ -418,10 +444,30 @@ } | ||
isRoot() { | ||
return this.value.path === "/" && !this.value.filePaths.size; | ||
return this.value.path === "/" && !this.value.components.size; | ||
} | ||
toString() { | ||
return `${this.value}${this.value.filePaths.size > 1 || this.value.filePaths.size === 1 && !this.value.filePaths.get("default") ? ` \u2388(${Array.from(this.value.filePaths.keys()).join(", ")})` : ""}${this.hasDefinePage ? " \u2691 definePage()" : ""}`; | ||
return `${this.value}${this.value.components.size > 1 || 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); | ||
} | ||
removeChild(filePath) { | ||
if (this.map.has(filePath)) { | ||
this.map.get(filePath).delete(); | ||
this.map.delete(filePath); | ||
} | ||
} | ||
}; | ||
function createPrefixTree(options) { | ||
return new TreeNode(options, ""); | ||
return new PrefixTree(options); | ||
} | ||
@@ -468,3 +514,3 @@ function splitFilePath(filePath, options) { | ||
} | ||
return (node.value.filePaths.size ? ` '${node.name}': ${generateRouteRecordInfo(node)}, | ||
return (node.value.components.size ? ` '${node.name}': ${generateRouteRecordInfo(node)}, | ||
` : "") + (node.children.size > 0 ? node.getSortedChildren().map(generateRouteNamedMap).join("\n") : ""); | ||
@@ -498,6 +544,7 @@ } | ||
const indentStr = " ".repeat((indent + 1) * 2); | ||
const overrides = node.value.overrides; | ||
const routeRecord = `${startIndent}{ | ||
${indentStr}path: '${node.path}', | ||
${indentStr}${node.value.filePaths.size ? `name: '${node.name}',` : "/* no name */"} | ||
${indentStr}${node.value.filePaths.size ? generateRouteRecordComponent( | ||
${indentStr}${node.value.components.size ? `name: '${node.name}',` : "/* no name */"} | ||
${indentStr}${node.value.components.size ? generateRouteRecordComponent( | ||
node, | ||
@@ -508,4 +555,5 @@ indentStr, | ||
) : "/* no component */"} | ||
${indentStr}${node.value.overrides.props != null ? `props: ${node.value.overrides.props},` : "/* no props */"} | ||
${indentStr}${node.children.size > 0 ? `children: [ | ||
${overrides.props != null ? indentStr + `props: ${overrides.props}, | ||
` : ""}${overrides.alias != null ? indentStr + `alias: ${JSON.stringify(overrides.alias)}, | ||
` : ""}${indentStr}${node.children.size > 0 ? `children: [ | ||
${node.getSortedChildren().map((child) => generateRouteRecord(child, options, importList, indent + 2)).join(",\n")} | ||
@@ -516,3 +564,3 @@ ${indentStr}],` : "/* no children */"}${formatMeta(node, indentStr)} | ||
const definePageDataList = []; | ||
for (const [name, filePath] of node.value.filePaths) { | ||
for (const [name, filePath] of node.value.components) { | ||
const pageDataImport = `_definePage_${name}_${importList.size}`; | ||
@@ -532,3 +580,3 @@ definePageDataList.push(pageDataImport); | ||
function generateRouteRecordComponent(node, indentStr, importMode, importList) { | ||
const files = Array.from(node.value.filePaths); | ||
const files = Array.from(node.value.components); | ||
const isDefaultExport = files.length === 1 && files[0][0] === "default"; | ||
@@ -556,3 +604,3 @@ return isDefaultExport ? `component: ${generatePageImport(files[0][1], importMode, importList)},` : `components: { | ||
function generateImportList(node, indentStr) { | ||
const files = Array.from(node.value.filePaths); | ||
const files = Array.from(node.value.components); | ||
return `[ | ||
@@ -629,3 +677,3 @@ ${files.map(([_key, path]) => `${indentStr} () => import('${path}')`).join(",\n")} | ||
console.error( | ||
`\u26A0\uFE0F unplugin-vue-router: Invalid "lang" of <${block.type}> in ${filePath}. Supported languages are: json5, json, yaml, yml.` | ||
`\u26A0\uFE0F unplugin-vue-router: Language "${lang}" for <${block.type}> is not supported. Supported languages are: json5, json, yaml, yml. Found in in ${filePath}.` | ||
); | ||
@@ -869,3 +917,4 @@ } | ||
const isExtractingDefinePage = MACRO_DEFINE_PAGE_QUERY.test(id); | ||
const { script, scriptSetup, setupAst } = sfc; | ||
const { script, scriptSetup, getSetupAst } = sfc; | ||
const setupAst = getSetupAst(); | ||
const definePageNodes = ((setupAst == null ? void 0 : setupAst.body) || []).map((node) => { | ||
@@ -908,3 +957,4 @@ if (node.type === "ExpressionStatement") | ||
return; | ||
const { setupAst } = sfc; | ||
const { getSetupAst } = sfc; | ||
const setupAst = getSetupAst(); | ||
const definePageNodes = ((_a = setupAst == null ? void 0 : setupAst.body) != null ? _a : []).map((node) => { | ||
@@ -977,2 +1027,71 @@ if (node.type === "ExpressionStatement") | ||
// src/core/extendRoutes.ts | ||
var EditableTreeNode = class { | ||
constructor(node) { | ||
this.node = node; | ||
} | ||
delete() { | ||
return this.node.delete(); | ||
} | ||
insert(path, filePath) { | ||
const node = this.node.insert(path, filePath); | ||
return new EditableTreeNode(node); | ||
} | ||
get parent() { | ||
return this.node.parent && new EditableTreeNode(this.node.parent); | ||
} | ||
get files() { | ||
return this.node.value.components; | ||
} | ||
get name() { | ||
return this.node.name; | ||
} | ||
set name(name) { | ||
this.node.value.addEditOverride({ name }); | ||
} | ||
get isPassThrough() { | ||
return this.node.value.components.size === 0; | ||
} | ||
get meta() { | ||
return this.node.metaAsObject; | ||
} | ||
set meta(meta) { | ||
this.node.value.addEditOverride({ meta }); | ||
} | ||
get path() { | ||
return this.node.path; | ||
} | ||
get alias() { | ||
return this.node.value.overrides.alias; | ||
} | ||
addAlias(alias) { | ||
this.node.value.addEditOverride({ alias }); | ||
} | ||
get params() { | ||
return this.node.params; | ||
} | ||
get fullPath() { | ||
return this.node.fullPath; | ||
} | ||
*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(); | ||
} | ||
*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 | ||
@@ -983,3 +1102,3 @@ function createRoutesContext(options) { | ||
const routeTree = createPrefixTree(options); | ||
const routeMap = /* @__PURE__ */ new Map(); | ||
const editableRoutes = new EditableTreeNode(routeTree); | ||
function log(...args) { | ||
@@ -992,2 +1111,3 @@ if (options.logs) { | ||
async function scanPages() { | ||
var _a; | ||
if (options.extensions.length < 1) { | ||
@@ -1022,2 +1142,5 @@ throw new Error( | ||
); | ||
for (const route of editableRoutes) { | ||
await ((_a = options.extendRoute) == null ? void 0 : _a.call(options, route)); | ||
} | ||
await _writeConfigFiles(); | ||
@@ -1035,24 +1158,25 @@ } | ||
} | ||
async function addPage({ filePath: path, routePath }) { | ||
log(`added "${routePath}" for "${path}"`); | ||
const node = routeTree.insert( | ||
routePath, | ||
(0, import_pathe2.resolve)(root, path) | ||
); | ||
await writeRouteInfoToNode(node, path); | ||
routeMap.set(path, node); | ||
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: path, routePath }) { | ||
log(`updated "${routePath}" for "${path}"`); | ||
const node = routeMap.get(path); | ||
async function updatePage({ filePath, routePath }) { | ||
var _a; | ||
log(`updated "${routePath}" for "${filePath}"`); | ||
const node = routeTree.getChild(filePath); | ||
if (!node) { | ||
console.warn(`Cannot update "${path}": Not found.`); | ||
console.warn(`Cannot update "${filePath}": Not found.`); | ||
return; | ||
} | ||
writeRouteInfoToNode(node, path); | ||
await writeRouteInfoToNode(node, filePath); | ||
await ((_a = options.extendRoute) == null ? void 0 : _a.call(options, new EditableTreeNode(node))); | ||
} | ||
function removePage({ filePath: path, routePath }) { | ||
log(`remove "${routePath}" for "${path}"`); | ||
routeTree.remove(routePath); | ||
routeMap.delete(path); | ||
function removePage({ filePath, routePath }) { | ||
log(`remove "${routePath}" for "${filePath}"`); | ||
routeTree.removeChild(filePath); | ||
} | ||
@@ -1065,3 +1189,3 @@ function setupWatcher(watcher) { | ||
}).on("add", async (ctx) => { | ||
await addPage(ctx); | ||
await addPage(ctx, true); | ||
writeConfigFiles(); | ||
@@ -1108,2 +1232,5 @@ }).on("unlink", async (ctx) => { | ||
log("\u{1F4BE} writing..."); | ||
if (options.beforeWriteFiles) { | ||
await options.beforeWriteFiles(editableRoutes); | ||
} | ||
logTree(routeTree, log); | ||
@@ -1174,3 +1301,11 @@ if (dts) { | ||
if (options.extensions) { | ||
options.extensions.sort((a, b) => b.length - a.length); | ||
options.extensions = options.extensions.map((ext) => { | ||
if (!ext.startsWith(".")) { | ||
console.warn( | ||
`[unplugin-vue-router]: Invalid extension "${ext}". Extensions must start with a dot.` | ||
); | ||
return "." + ext; | ||
} | ||
return ext; | ||
}).sort((a, b) => b.length - a.length); | ||
} | ||
@@ -1177,0 +1312,0 @@ return __spreadProps(__spreadValues(__spreadValues({}, DEFAULT_OPTIONS), options), { |
import * as webpack from 'webpack'; | ||
import { O as Options } from './options-ccb73a7b.js'; | ||
import { O as Options } from './options-72c4a647.js'; | ||
import 'vue-router'; | ||
@@ -4,0 +4,0 @@ |
@@ -132,3 +132,3 @@ "use strict"; | ||
return ""; | ||
return getFileBasedRouteName(node.parent) + "/" + node.value.rawSegment; | ||
return getFileBasedRouteName(node.parent) + "/" + (node.value.rawSegment === "index" ? "" : node.value.rawSegment); | ||
} | ||
@@ -146,3 +146,4 @@ function mergeRouteRecordOverride(a, b) { | ||
if (key === "alias") { | ||
merged[key] = [...a[key] || [], ...b[key] || []]; | ||
const newAlias = []; | ||
merged[key] = newAlias.concat(a.alias || [], b.alias || []); | ||
} else if (key === "meta") { | ||
@@ -177,6 +178,8 @@ merged[key] = mergeDeep(a[key] || {}, b[key] || {}); | ||
// src/core/treeNodeValue.ts | ||
var EDITS_OVERRIDE_NAME = "@@edits"; | ||
var _TreeNodeValueBase = class { | ||
constructor(rawSegment, parent, pathSegment = rawSegment, subSegments = [rawSegment]) { | ||
constructor(rawSegment, parent, pathSegment = rawSegment, subSegments = [pathSegment]) { | ||
this._overrides = /* @__PURE__ */ new Map(); | ||
this.includeLoaderGuard = false; | ||
this.components = /* @__PURE__ */ new Map(); | ||
this._type = 0; | ||
@@ -188,3 +191,2 @@ this.rawSegment = rawSegment; | ||
this.path = (!parentPath || parentPath === "/") && this.pathSegment === "" ? "/" : joinPath((parent == null ? void 0 : parent.path) || "", this.pathSegment); | ||
this.filePaths = /* @__PURE__ */ new Map(); | ||
} | ||
@@ -202,3 +204,3 @@ toString() { | ||
return [...this._overrides.entries()].sort( | ||
([nameA], [nameB]) => nameA === nameB ? 0 : nameA < nameB ? -1 : 1 | ||
([nameA], [nameB]) => nameA === nameB ? 0 : nameA !== EDITS_OVERRIDE_NAME && (nameA < nameB || nameB === EDITS_OVERRIDE_NAME) ? -1 : 1 | ||
).reduce((acc, [_path, routeBlock]) => { | ||
@@ -211,2 +213,15 @@ return mergeRouteRecordOverride(acc, routeBlock); | ||
} | ||
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) { | ||
console.log("add edit", routeBlock); | ||
return this.mergeOverride(EDITS_OVERRIDE_NAME, routeBlock); | ||
} | ||
}; | ||
@@ -228,3 +243,3 @@ var TreeNodeValueStatic = class extends _TreeNodeValueBase { | ||
if (!segment || segment === "index") { | ||
return new TreeNodeValueStatic("", parent); | ||
return new TreeNodeValueStatic(segment, parent, ""); | ||
} | ||
@@ -343,3 +358,3 @@ const [pathSegment, params, subSegments] = parseSegment(segment); | ||
if (isComponent) { | ||
child.value.filePaths.set(viewName, filePath); | ||
child.value.components.set(viewName, filePath); | ||
} | ||
@@ -359,2 +374,9 @@ if (tail) { | ||
} | ||
delete() { | ||
if (!this.parent) { | ||
throw new Error("Cannot delete the root node."); | ||
} | ||
this.parent.children.delete(this.value.rawSegment); | ||
this.parent = void 0; | ||
} | ||
remove(path) { | ||
@@ -373,3 +395,3 @@ const { tail, segment, viewName, isComponent } = splitFilePath( | ||
child.remove(tail); | ||
if (child.children.size === 0 && child.value.filePaths.size === 0) { | ||
if (child.children.size === 0 && child.value.components.size === 0) { | ||
this.children.delete(segment); | ||
@@ -379,5 +401,5 @@ } | ||
if (isComponent) { | ||
child.value.filePaths.delete(viewName); | ||
child.value.components.delete(viewName); | ||
} | ||
if (child.children.size === 0 && child.value.filePaths.size === 0) { | ||
if (child.children.size === 0 && child.value.components.size === 0) { | ||
this.children.delete(segment); | ||
@@ -398,7 +420,11 @@ } | ||
} | ||
get meta() { | ||
const overrideMeta = __spreadValues({}, this.value.overrides.meta); | ||
get metaAsObject() { | ||
const meta = __spreadValues({}, this.value.overrides.meta); | ||
if (this.value.includeLoaderGuard) { | ||
overrideMeta._loaderGuard = true; | ||
meta._loaderGuard = true; | ||
} | ||
return meta; | ||
} | ||
get meta() { | ||
const overrideMeta = this.metaAsObject; | ||
return Object.keys(overrideMeta).length > 0 ? JSON.stringify(overrideMeta, null, 2) : ""; | ||
@@ -418,10 +444,30 @@ } | ||
isRoot() { | ||
return this.value.path === "/" && !this.value.filePaths.size; | ||
return this.value.path === "/" && !this.value.components.size; | ||
} | ||
toString() { | ||
return `${this.value}${this.value.filePaths.size > 1 || this.value.filePaths.size === 1 && !this.value.filePaths.get("default") ? ` \u2388(${Array.from(this.value.filePaths.keys()).join(", ")})` : ""}${this.hasDefinePage ? " \u2691 definePage()" : ""}`; | ||
return `${this.value}${this.value.components.size > 1 || 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); | ||
} | ||
removeChild(filePath) { | ||
if (this.map.has(filePath)) { | ||
this.map.get(filePath).delete(); | ||
this.map.delete(filePath); | ||
} | ||
} | ||
}; | ||
function createPrefixTree(options) { | ||
return new TreeNode(options, ""); | ||
return new PrefixTree(options); | ||
} | ||
@@ -468,3 +514,3 @@ function splitFilePath(filePath, options) { | ||
} | ||
return (node.value.filePaths.size ? ` '${node.name}': ${generateRouteRecordInfo(node)}, | ||
return (node.value.components.size ? ` '${node.name}': ${generateRouteRecordInfo(node)}, | ||
` : "") + (node.children.size > 0 ? node.getSortedChildren().map(generateRouteNamedMap).join("\n") : ""); | ||
@@ -498,6 +544,7 @@ } | ||
const indentStr = " ".repeat((indent + 1) * 2); | ||
const overrides = node.value.overrides; | ||
const routeRecord = `${startIndent}{ | ||
${indentStr}path: '${node.path}', | ||
${indentStr}${node.value.filePaths.size ? `name: '${node.name}',` : "/* no name */"} | ||
${indentStr}${node.value.filePaths.size ? generateRouteRecordComponent( | ||
${indentStr}${node.value.components.size ? `name: '${node.name}',` : "/* no name */"} | ||
${indentStr}${node.value.components.size ? generateRouteRecordComponent( | ||
node, | ||
@@ -508,4 +555,5 @@ indentStr, | ||
) : "/* no component */"} | ||
${indentStr}${node.value.overrides.props != null ? `props: ${node.value.overrides.props},` : "/* no props */"} | ||
${indentStr}${node.children.size > 0 ? `children: [ | ||
${overrides.props != null ? indentStr + `props: ${overrides.props}, | ||
` : ""}${overrides.alias != null ? indentStr + `alias: ${JSON.stringify(overrides.alias)}, | ||
` : ""}${indentStr}${node.children.size > 0 ? `children: [ | ||
${node.getSortedChildren().map((child) => generateRouteRecord(child, options, importList, indent + 2)).join(",\n")} | ||
@@ -516,3 +564,3 @@ ${indentStr}],` : "/* no children */"}${formatMeta(node, indentStr)} | ||
const definePageDataList = []; | ||
for (const [name, filePath] of node.value.filePaths) { | ||
for (const [name, filePath] of node.value.components) { | ||
const pageDataImport = `_definePage_${name}_${importList.size}`; | ||
@@ -532,3 +580,3 @@ definePageDataList.push(pageDataImport); | ||
function generateRouteRecordComponent(node, indentStr, importMode, importList) { | ||
const files = Array.from(node.value.filePaths); | ||
const files = Array.from(node.value.components); | ||
const isDefaultExport = files.length === 1 && files[0][0] === "default"; | ||
@@ -556,3 +604,3 @@ return isDefaultExport ? `component: ${generatePageImport(files[0][1], importMode, importList)},` : `components: { | ||
function generateImportList(node, indentStr) { | ||
const files = Array.from(node.value.filePaths); | ||
const files = Array.from(node.value.components); | ||
return `[ | ||
@@ -629,3 +677,3 @@ ${files.map(([_key, path]) => `${indentStr} () => import('${path}')`).join(",\n")} | ||
console.error( | ||
`\u26A0\uFE0F unplugin-vue-router: Invalid "lang" of <${block.type}> in ${filePath}. Supported languages are: json5, json, yaml, yml.` | ||
`\u26A0\uFE0F unplugin-vue-router: Language "${lang}" for <${block.type}> is not supported. Supported languages are: json5, json, yaml, yml. Found in in ${filePath}.` | ||
); | ||
@@ -869,3 +917,4 @@ } | ||
const isExtractingDefinePage = MACRO_DEFINE_PAGE_QUERY.test(id); | ||
const { script, scriptSetup, setupAst } = sfc; | ||
const { script, scriptSetup, getSetupAst } = sfc; | ||
const setupAst = getSetupAst(); | ||
const definePageNodes = ((setupAst == null ? void 0 : setupAst.body) || []).map((node) => { | ||
@@ -908,3 +957,4 @@ if (node.type === "ExpressionStatement") | ||
return; | ||
const { setupAst } = sfc; | ||
const { getSetupAst } = sfc; | ||
const setupAst = getSetupAst(); | ||
const definePageNodes = ((_a = setupAst == null ? void 0 : setupAst.body) != null ? _a : []).map((node) => { | ||
@@ -977,2 +1027,71 @@ if (node.type === "ExpressionStatement") | ||
// src/core/extendRoutes.ts | ||
var EditableTreeNode = class { | ||
constructor(node) { | ||
this.node = node; | ||
} | ||
delete() { | ||
return this.node.delete(); | ||
} | ||
insert(path, filePath) { | ||
const node = this.node.insert(path, filePath); | ||
return new EditableTreeNode(node); | ||
} | ||
get parent() { | ||
return this.node.parent && new EditableTreeNode(this.node.parent); | ||
} | ||
get files() { | ||
return this.node.value.components; | ||
} | ||
get name() { | ||
return this.node.name; | ||
} | ||
set name(name) { | ||
this.node.value.addEditOverride({ name }); | ||
} | ||
get isPassThrough() { | ||
return this.node.value.components.size === 0; | ||
} | ||
get meta() { | ||
return this.node.metaAsObject; | ||
} | ||
set meta(meta) { | ||
this.node.value.addEditOverride({ meta }); | ||
} | ||
get path() { | ||
return this.node.path; | ||
} | ||
get alias() { | ||
return this.node.value.overrides.alias; | ||
} | ||
addAlias(alias) { | ||
this.node.value.addEditOverride({ alias }); | ||
} | ||
get params() { | ||
return this.node.params; | ||
} | ||
get fullPath() { | ||
return this.node.fullPath; | ||
} | ||
*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(); | ||
} | ||
*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 | ||
@@ -983,3 +1102,3 @@ function createRoutesContext(options) { | ||
const routeTree = createPrefixTree(options); | ||
const routeMap = /* @__PURE__ */ new Map(); | ||
const editableRoutes = new EditableTreeNode(routeTree); | ||
function log(...args) { | ||
@@ -992,2 +1111,3 @@ if (options.logs) { | ||
async function scanPages() { | ||
var _a; | ||
if (options.extensions.length < 1) { | ||
@@ -1022,2 +1142,5 @@ throw new Error( | ||
); | ||
for (const route of editableRoutes) { | ||
await ((_a = options.extendRoute) == null ? void 0 : _a.call(options, route)); | ||
} | ||
await _writeConfigFiles(); | ||
@@ -1035,24 +1158,25 @@ } | ||
} | ||
async function addPage({ filePath: path, routePath }) { | ||
log(`added "${routePath}" for "${path}"`); | ||
const node = routeTree.insert( | ||
routePath, | ||
(0, import_pathe2.resolve)(root, path) | ||
); | ||
await writeRouteInfoToNode(node, path); | ||
routeMap.set(path, node); | ||
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: path, routePath }) { | ||
log(`updated "${routePath}" for "${path}"`); | ||
const node = routeMap.get(path); | ||
async function updatePage({ filePath, routePath }) { | ||
var _a; | ||
log(`updated "${routePath}" for "${filePath}"`); | ||
const node = routeTree.getChild(filePath); | ||
if (!node) { | ||
console.warn(`Cannot update "${path}": Not found.`); | ||
console.warn(`Cannot update "${filePath}": Not found.`); | ||
return; | ||
} | ||
writeRouteInfoToNode(node, path); | ||
await writeRouteInfoToNode(node, filePath); | ||
await ((_a = options.extendRoute) == null ? void 0 : _a.call(options, new EditableTreeNode(node))); | ||
} | ||
function removePage({ filePath: path, routePath }) { | ||
log(`remove "${routePath}" for "${path}"`); | ||
routeTree.remove(routePath); | ||
routeMap.delete(path); | ||
function removePage({ filePath, routePath }) { | ||
log(`remove "${routePath}" for "${filePath}"`); | ||
routeTree.removeChild(filePath); | ||
} | ||
@@ -1065,3 +1189,3 @@ function setupWatcher(watcher) { | ||
}).on("add", async (ctx) => { | ||
await addPage(ctx); | ||
await addPage(ctx, true); | ||
writeConfigFiles(); | ||
@@ -1108,2 +1232,5 @@ }).on("unlink", async (ctx) => { | ||
log("\u{1F4BE} writing..."); | ||
if (options.beforeWriteFiles) { | ||
await options.beforeWriteFiles(editableRoutes); | ||
} | ||
logTree(routeTree, log); | ||
@@ -1174,3 +1301,11 @@ if (dts) { | ||
if (options.extensions) { | ||
options.extensions.sort((a, b) => b.length - a.length); | ||
options.extensions = options.extensions.map((ext) => { | ||
if (!ext.startsWith(".")) { | ||
console.warn( | ||
`[unplugin-vue-router]: Invalid extension "${ext}". Extensions must start with a dot.` | ||
); | ||
return "." + ext; | ||
} | ||
return ext; | ||
}).sort((a, b) => b.length - a.length); | ||
} | ||
@@ -1177,0 +1312,0 @@ return __spreadProps(__spreadValues(__spreadValues({}, DEFAULT_OPTIONS), options), { |
{ | ||
"name": "unplugin-vue-router", | ||
"version": "0.3.2", | ||
"packageManager": "pnpm@7.21.0", | ||
"version": "0.3.3", | ||
"packageManager": "pnpm@7.26.2", | ||
"description": "File based typed routing for Vue Router", | ||
@@ -81,10 +81,10 @@ "keywords": [ | ||
"@rollup/pluginutils": "^5.0.2", | ||
"@vue-macros/common": "^0.13.6", | ||
"ast-walker-scope": "^0.3.1", | ||
"@vue-macros/common": "^1.0.0", | ||
"ast-walker-scope": "^0.4.0", | ||
"chokidar": "^3.5.3", | ||
"fast-glob": "^3.2.12", | ||
"json5": "^2.2.3", | ||
"local-pkg": "^0.4.2", | ||
"mlly": "^1.0.0", | ||
"pathe": "^1.0.0", | ||
"local-pkg": "^0.4.3", | ||
"mlly": "^1.1.0", | ||
"pathe": "^1.1.0", | ||
"scule": "^1.0.0", | ||
@@ -114,12 +114,12 @@ "unplugin": "^1.0.1", | ||
"p-series": "^3.0.0", | ||
"prettier": "^2.8.2", | ||
"rimraf": "^3.0.2", | ||
"rollup": "^3.9.1", | ||
"prettier": "^2.8.3", | ||
"rimraf": "^4.1.2", | ||
"rollup": "^3.12.0", | ||
"semver": "^7.3.8", | ||
"ts-expect": "^1.3.0", | ||
"tsup": "^6.5.0", | ||
"typescript": "^4.9.4", | ||
"unplugin-auto-import": "^0.12.1", | ||
"typescript": "^4.9.5", | ||
"unplugin-auto-import": "^0.13.0", | ||
"vite": "^4.0.4", | ||
"vitest": "^0.26.3", | ||
"vitest": "^0.28.3", | ||
"vue": "^3.2.45", | ||
@@ -126,0 +126,0 @@ "vue-router": "^4.1.6", |
@@ -215,5 +215,7 @@ # unplugin-vue-router | ||
// list of glob files to exclude from the routes generation | ||
// e.g. ['**/__*'] will exclude all files starting with `__` | ||
// e.g. ['**/__*'] will exclude all files and folders starting with `__` | ||
// e.g. ['**/__*/**/*'] will exclude all files within folders starting with `__` | ||
// e.g. ['*.component.vue'] will exclude components ending with `.component.vue` | ||
// note you can exclude patterns with a leading `!`: | ||
// '!__not-ignored', -> __not-ignored will still be used as a page | ||
exclude: [], | ||
@@ -220,0 +222,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 2 instances in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1444319
43
40213
583
43
13
+ Added@vue-macros/common@1.15.0(transitive)
+ Addedast-kit@1.3.1(transitive)
+ Addedast-walker-scope@0.4.2(transitive)
+ Addedlocal-pkg@0.5.1(transitive)
+ Addedmagic-string-ast@0.6.3(transitive)
- Removed@vue-macros/common@0.13.8(transitive)
- Removedast-walker-scope@0.3.1(transitive)
- Removedmagic-string@0.27.0(transitive)
Updated@vue-macros/common@^1.0.0
Updatedast-walker-scope@^0.4.0
Updatedlocal-pkg@^0.4.3
Updatedmlly@^1.1.0
Updatedpathe@^1.1.0