vue-nnn-router 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -2
- package/README.md +22 -2
- package/README.vi.md +22 -2
- package/dist/createNnnRoutes.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/path.d.ts +3 -0
- package/dist/vue-nnn-router.cjs +2 -2
- package/dist/vue-nnn-router.cjs.map +1 -1
- package/dist/vue-nnn-router.js +251 -199
- package/dist/vue-nnn-router.js.map +1 -1
- package/package.json +12 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,12 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
**Versioning:** while in **`0.x`** the package is in early development and breaking changes may occur in any minor release. Starting from **`1.0.0`**, this package will use **semver major aligned with Vue Router** — **`vue-nnn-router` 4.x** will target **Vue Router 4.x**, and when Vue Router 5 exists, expect **`vue-nnn-router` 5.x** with a Vue Router 5 peer.
|
|
4
4
|
|
|
5
|
-
## [0.0.
|
|
5
|
+
## [0.0.2] - 2026-06-05
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Export `isRedirectKey` and `redirectDirFromNormKey` helpers.
|
|
10
|
+
- npm package metadata (`repository`, `homepage`, `bugs`).
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Runtime warnings and errors are now in English.
|
|
15
|
+
- README: `_redirect` + `prefix` guidance; updated taglines and exported helpers list.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Demo `users/add.vue` middleware no longer redirects away from `/users/add`.
|
|
20
|
+
|
|
21
|
+
## [0.0.1] - 2026-06-05
|
|
6
22
|
|
|
7
23
|
Initial public release.
|
|
8
24
|
|
|
9
|
-
- SPA file-based routing: `index.vue`, `_layout.vue`, dynamic `[param]` and `[param].vue`.
|
|
25
|
+
- SPA file-based routing: `index.vue`, `_layout.vue`, `_redirect.ts`, dynamic `[param]` and `[param].vue`.
|
|
26
|
+
- `_redirect.ts`: when a layout folder has no `index.*`, inject `{ path: "", redirect }` (relative or absolute URL).
|
|
10
27
|
- Cascading `_middleware.ts` and optional per-route `middleware` export (eager glob).
|
|
11
28
|
- Helpers: `simplifyGlobKey`, `pathNoExt`, `segmentUrlFromFs`, `mwPrefixesForPathNoExt`.
|
|
12
29
|
|
|
30
|
+
[0.0.2]: https://www.npmjs.com/package/vue-nnn-router/v/0.0.2
|
|
13
31
|
[0.0.1]: https://www.npmjs.com/package/vue-nnn-router/v/0.0.1
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# vue-nnn-router
|
|
2
2
|
|
|
3
|
-
File-based routing for **[Vue Router](https://router.vuejs.org/)** (**4.x** or **5.x**): **SPA-style** pages (`index.vue`, optional **`_layout.vue`** per folder), dynamic segments **`[param]` → `:param`**, cascading **`_middleware.ts`**, powered by a Vite **`import.meta.glob`** map (or any equivalent `Record<string, unknown>`).
|
|
3
|
+
File-based routing for **[Vue Router](https://router.vuejs.org/)** (**4.x** or **5.x**): **SPA-style** pages (`index.vue`, optional **`_layout.vue`** and **`_redirect.ts`** per folder), dynamic segments **`[param]` → `:param`**, cascading **`_middleware.ts`**, powered by a Vite **`import.meta.glob`** map (or any equivalent `Record<string, unknown>`).
|
|
4
4
|
|
|
5
5
|
**English** | [Tiếng Việt](README.vi.md)
|
|
6
6
|
|
|
@@ -76,6 +76,7 @@ pages/
|
|
|
76
76
|
users/
|
|
77
77
|
_layout.vue # layout for /users/** — must render <RouterView />
|
|
78
78
|
_middleware.ts
|
|
79
|
+
_redirect.ts # (optional) redirect /users when there is no index.vue
|
|
79
80
|
index.vue # /users
|
|
80
81
|
add.vue # /users/add
|
|
81
82
|
[id].vue # /users/:id (shorthand; same idea as users/[id]/index.vue)
|
|
@@ -86,6 +87,7 @@ pages/
|
|
|
86
87
|
- **Other basenames (`add.vue`, …):** one more segment in the URL.
|
|
87
88
|
- **`[param].*` or `[param]/` folders:** **`[id]` → `:id`** in the URL.
|
|
88
89
|
- **`_layout.vue`:** wraps child routes (same **`_`** prefix rule as **`_middleware.ts`**); nested views need **`<RouterView />`**.
|
|
90
|
+
- **`_redirect.ts`:** when a folder has **`_layout`** but **no** **`index.*`**, the library injects `{ path: "", redirect: "..." }`. `export default` is an absolute URL (`"/users/add"`) or a relative segment (`"add"`). If **`index.*`** exists, **`_redirect` is ignored**.
|
|
89
91
|
|
|
90
92
|
## Glob patterns and `routesRoot`
|
|
91
93
|
|
|
@@ -270,6 +272,24 @@ Each **leaf** `RouteRecordRaw` gets a single composed **`beforeEnter`** chain. T
|
|
|
270
272
|
|
|
271
273
|
If any guard calls `next(false)`, `throw`, or redirects with `next('/somewhere')`, later steps follow normal Vue Router rules (may never run).
|
|
272
274
|
|
|
275
|
+
### `_redirect.ts` — default child when a layout has no `index`
|
|
276
|
+
|
|
277
|
+
If a folder has **`_layout.vue`** but **no** **`index.vue`**, visiting the parent URL (e.g. `/users`) renders the layout with an empty `<RouterView />`. Add **`_redirect.ts`** next to **`_layout`** and the library injects `{ path: "", redirect: "..." }`:
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
// src/pages/users/_redirect.ts
|
|
281
|
+
export default "add"; // redirects /users → /users/add
|
|
282
|
+
|
|
283
|
+
// or an absolute URL:
|
|
284
|
+
// export default "/users/add";
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Include the file in your glob (`**/*.{ts,js}` or `**/_redirect.ts`, **eager**).
|
|
288
|
+
|
|
289
|
+
If **`index.*`** already exists, **`_redirect` is ignored** — `index` remains the default page.
|
|
290
|
+
|
|
291
|
+
**With `prefix`:** prefer a **relative** target (`"add"` → `/app/users/add` when `prefix: "app"`). An **absolute** path (`"/users/add"`) is used as-is and does **not** include `prefix`.
|
|
292
|
+
|
|
273
293
|
### Directory middleware — default export, single guard
|
|
274
294
|
|
|
275
295
|
```ts
|
|
@@ -421,7 +441,7 @@ const routes = createNnnRoutes(modules, {
|
|
|
421
441
|
|
|
422
442
|
Each generated leaf sets **`meta.nnnFile`** to the **original** glob key (before strip), which helps editors and debugger linking.
|
|
423
443
|
|
|
424
|
-
**Exported helpers:** `createSpaNnnRoutes`, `pathNoExt`, `segmentUrlFromFs`, `mwPrefixesForPathNoExt`, **`warnIfRoutesRootLikelyWrong`**, `simplifyGlobKey`, **`stripRoutesRoot`**, `normalizePath`, `pathFromSegments`, **`isMiddlewareKey`**, **`middlewareDirFromNormKey`**, **`middlewareLogicalKey`**, **`dynamicScore`**.
|
|
444
|
+
**Exported helpers:** `createSpaNnnRoutes`, `pathNoExt`, `segmentUrlFromFs`, `mwPrefixesForPathNoExt`, **`warnIfRoutesRootLikelyWrong`**, `simplifyGlobKey`, **`stripRoutesRoot`**, `normalizePath`, `pathFromSegments`, **`isMiddlewareKey`**, **`middlewareDirFromNormKey`**, **`middlewareLogicalKey`**, **`isRedirectKey`**, **`redirectDirFromNormKey`**, **`dynamicScore`**.
|
|
425
445
|
|
|
426
446
|
---
|
|
427
447
|
|
package/README.vi.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# vue-nnn-router
|
|
2
2
|
|
|
3
|
-
**Định tuyến theo thư mục** cho **[Vue Router](https://router.vuejs.org/)** (**4.x** hoặc **5.x**): SPA với **`index.vue`**, **`_layout.vue`** (tùy chọn), **`[param]` → `:param`**, middleware xếp chồng **`_middleware.ts`**, dựa trên map **`import.meta.glob`** của Vite (hoặc `Record<string, unknown>` tương đương).
|
|
3
|
+
**Định tuyến theo thư mục** cho **[Vue Router](https://router.vuejs.org/)** (**4.x** hoặc **5.x**): SPA với **`index.vue`**, **`_layout.vue`** và **`_redirect.ts`** (tùy chọn), **`[param]` → `:param`**, middleware xếp chồng **`_middleware.ts`**, dựa trên map **`import.meta.glob`** của Vite (hoặc `Record<string, unknown>` tương đương).
|
|
4
4
|
|
|
5
5
|
[Tiếng Anh](README.md) | **Tiếng Việt**
|
|
6
6
|
|
|
@@ -76,6 +76,7 @@ pages/
|
|
|
76
76
|
users/
|
|
77
77
|
_layout.vue # bọc /users/** — bắt buộc có <RouterView />
|
|
78
78
|
_middleware.ts
|
|
79
|
+
_redirect.ts # (tùy chọn) redirect /users khi không có index.vue
|
|
79
80
|
index.vue # /users
|
|
80
81
|
add.vue # /users/add
|
|
81
82
|
[id].vue # /users/:id (rút gọn; tương đương users/[id]/index.vue)
|
|
@@ -86,6 +87,7 @@ pages/
|
|
|
86
87
|
- **Basename khác (`add.vue`, …):** thêm một segment URL.
|
|
87
88
|
- **`[param]`** trong tên file hoặc thư mục → **`[id]` becomes `:id`** trong path.
|
|
88
89
|
- **`_layout.vue`:** layout cho route con (cùng quy ước **`_`** với **`_middleware.ts`**); route con render trong **`<RouterView />`**.
|
|
90
|
+
- **`_redirect.ts`:** khi thư mục có **`_layout`** nhưng **không** có **`index.*`**, lib sinh route con `{ path: "", redirect: "..." }`. `export default` là URL tuyệt đối (`"/users/add"`) hoặc tương đối (`"add"`). Nếu đã có **`index.*`** thì **`_redirect` bị bỏ qua**.
|
|
89
91
|
|
|
90
92
|
## Pattern glob và `routesRoot`
|
|
91
93
|
|
|
@@ -269,6 +271,24 @@ Vue Router chỉ có một chuỗi **`beforeEnter`** trên từng **record lá**
|
|
|
269
271
|
|
|
270
272
|
Nếu bất kỳ guard gọi `next(false)`, ném lỗi, hoặc `next('/elsewhere')` thì các bước sau có thể **không** chạy (theo luật của Vue Router).
|
|
271
273
|
|
|
274
|
+
### `_redirect.ts` — trang mặc định khi layout không có `index`
|
|
275
|
+
|
|
276
|
+
Khi thư mục có **`_layout.vue`** nhưng **không** có **`index.vue`**, vào URL cha (vd. `/users`) sẽ chỉ render layout với `<RouterView />` trống. Đặt **`_redirect.ts`** cạnh **`_layout`** để lib tự sinh `{ path: "", redirect: "..." }`:
|
|
277
|
+
|
|
278
|
+
```ts
|
|
279
|
+
// src/pages/users/_redirect.ts
|
|
280
|
+
export default "add"; // → redirect /users → /users/add
|
|
281
|
+
|
|
282
|
+
// hoặc URL tuyệt đối:
|
|
283
|
+
// export default "/users/add";
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
Glob cần nạp file này (pattern `**/*.{ts,js}` hoặc `**/_redirect.ts`, **eager**).
|
|
287
|
+
|
|
288
|
+
Nếu đã có **`index.*`**, **`_redirect` bị bỏ qua** — `index` luôn là trang mặc định.
|
|
289
|
+
|
|
290
|
+
**Khi có `prefix`:** nên dùng đích **tương đối** (`"add"` → `/app/users/add` với `prefix: "app"`). Đường dẫn **tuyệt đối** (`"/users/add"`) giữ nguyên, **không** tự thêm `prefix`.
|
|
291
|
+
|
|
272
292
|
### Middleware thư mục — `export default` một guard
|
|
273
293
|
|
|
274
294
|
```ts
|
|
@@ -421,7 +441,7 @@ Key **`.vue`** và **`_middleware.ts`** thường **không** trùng tên trong m
|
|
|
421
441
|
|
|
422
442
|
Mỗi lá route có **`meta.nnnFile`** = **key glob gốc** (trước `stripRoutesRoot`), tiện nhảy vào file trong IDE/debug.
|
|
423
443
|
|
|
424
|
-
**Export tiện ích:** `createSpaNnnRoutes`, `pathNoExt`, `segmentUrlFromFs`, `mwPrefixesForPathNoExt`, **`warnIfRoutesRootLikelyWrong`**, `simplifyGlobKey`, **`stripRoutesRoot`**, `normalizePath`, `pathFromSegments`, **`isMiddlewareKey`**, **`middlewareDirFromNormKey`**, **`middlewareLogicalKey`**, **`dynamicScore`**.
|
|
444
|
+
**Export tiện ích:** `createSpaNnnRoutes`, `pathNoExt`, `segmentUrlFromFs`, `mwPrefixesForPathNoExt`, **`warnIfRoutesRootLikelyWrong`**, `simplifyGlobKey`, **`stripRoutesRoot`**, `normalizePath`, `pathFromSegments`, **`isMiddlewareKey`**, **`middlewareDirFromNormKey`**, **`middlewareLogicalKey`**, **`isRedirectKey`**, **`redirectDirFromNormKey`**, **`dynamicScore`**.
|
|
425
445
|
|
|
426
446
|
---
|
|
427
447
|
|
|
@@ -2,6 +2,6 @@ import type { RouteRecordRaw } from "vue-router";
|
|
|
2
2
|
import type { CreateNnnRoutesOptions } from "./types";
|
|
3
3
|
export { simplifyGlobKey } from "./globUtils";
|
|
4
4
|
/**
|
|
5
|
-
* Từ map `import.meta.glob` sinh `RouteRecordRaw[]` — quy ước SPA: `index.vue`, `_layout.vue`, `[param]`.
|
|
5
|
+
* Từ map `import.meta.glob` sinh `RouteRecordRaw[]` — quy ước SPA: `index.vue`, `_layout.vue`, `_redirect.ts`, `[param]`.
|
|
6
6
|
*/
|
|
7
7
|
export declare function createNnnRoutes(globRecord: Record<string, unknown>, options?: CreateNnnRoutesOptions): RouteRecordRaw[];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { createNnnRoutes, simplifyGlobKey, } from "./createNnnRoutes";
|
|
2
2
|
export { createSpaNnnRoutes, pathNoExt, segmentUrlFromFs, mwPrefixesForPathNoExt, warnIfRoutesRootLikelyWrong, } from "./spaRoutes";
|
|
3
3
|
export type { CreateNnnRoutesOptions, NnnRouteMeta } from "./types";
|
|
4
|
-
export { normalizePath, pathFromSegments, isMiddlewareKey, middlewareLogicalKey, middlewareDirFromNormKey, stripRoutesRoot, dynamicScore, } from "./path";
|
|
4
|
+
export { normalizePath, pathFromSegments, isMiddlewareKey, middlewareLogicalKey, middlewareDirFromNormKey, isRedirectKey, redirectDirFromNormKey, stripRoutesRoot, dynamicScore, } from "./path";
|
package/dist/path.d.ts
CHANGED
|
@@ -6,5 +6,8 @@ export declare function isMiddlewareKey(key: string): boolean;
|
|
|
6
6
|
/** Thư mục chứa `_middleware` (chuỗi rỗng = ngay trong `routesRoot`). */
|
|
7
7
|
export declare function middlewareDirFromNormKey(normKey: string): string;
|
|
8
8
|
export declare function middlewareLogicalKey(prefixPath: string): string;
|
|
9
|
+
export declare function isRedirectKey(key: string): boolean;
|
|
10
|
+
/** Thư mục chứa `_redirect` (chuỗi rỗng = ngay trong `routesRoot`). */
|
|
11
|
+
export declare function redirectDirFromNormKey(normKey: string): string;
|
|
9
12
|
/** Đếm độ động (số `/:`) để ưu tiên route tĩnh trước. */
|
|
10
13
|
export declare function dynamicScore(pathPattern: string): number;
|
package/dist/vue-nnn-router.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function _(e){const t=e.replace(/\/+/g,"/").replace(/\/$/,"");return t===""||t==="/"?"/":t.startsWith("/")?t:`/${t}`}function U(e,t){const n=e.replace(/\\/g,"/").split("?")[0];let r=t?.replace(/\\/g,"/").replace(/^\.\/+/,"")??"";if(r=r.replace(/^\/+|\/+$/g,""),!r)return n;const o=`${r}/`;return n===r||n===`${r}/`?"":n.startsWith(o)?n.slice(o.length):n}function P(e,t){const n=e.length===0?"":`/${e.join("/")}`,r=[t?.replace(/^\/|\/$/g,""),n.replace(/^\//,"")].filter(Boolean).join("/"),o=r.startsWith("/")?r:`/${r}`;return _(o)}function G(e){const t=e.replace(/\\/g,"/").split("?")[0];return/^(.+\/)?_middleware\.(ts|js)$/i.test(t)}function H(e){const t=e.replace(/\\/g,"/").split("?")[0],n=/^(.*?)\/_middleware\.(ts|js)$/i.exec(t);return n?n[1]:(/^_middleware\.(ts|js)$/i.test(t),"")}function ae(e){return`${e}/_middleware`}function $(e){return(e.match(/\/:/g)||[]).length}function V(e){let t=e.replace(/\\/g,"/").split("?")[0];for(;t.startsWith("./");)t=t.slice(2);return t.replace(/^\//,"")}function T(e){return e&&typeof e=="object"&&"default"in e?e.default:e}const C=/\.(vue|tsx|jsx|ts|js)$/i,k="_layout";function ie(e){return!(!C.test(e)||/\.(ts|js)$/i.test(e)&&/_middleware\.(ts|js)$/i.test(e))}function J(e,t,n){if(n===!0||!t?.trim())return;const r=e.filter(s=>ie(s.sk));if(r.length===0)return;const o=r.filter(s=>/\.\.(?:\/|$)/.test(s.sk)).length;o>=1&&console.warn(`[vue-nnn-router] ${o}/${r.length} key route vẫn chứa ".." sau routesRoot="${t}". Đặt routesRoot khớp tiền tố thực của key glob (vd. pattern ../pages/** → routesRoot: "../pages").`)}function h(e){const t=e.replace(/\\/g,"/");return t.startsWith("[")&&t.endsWith("]")?`:${t.slice(1,-1)}`:t}function N(e){return e.replace(/\\/g,"/").split("?")[0].replace(C,"")}function X(e){const t=e.split("/").filter(Boolean),n=t.length>=1?t.slice(0,-1):[],r=[];for(let o=0;o<n.length;o++)r.push(n.slice(0,o+1).join("/"));return(r.length===0||r[0]!=="")&&r.unshift(""),r}function Y(){return{pages:new Map,dirs:new Map}}function z(e,t){let n=e;for(const r of t)n.dirs.has(r)||n.dirs.set(r,Y()),n=n.dirs.get(r);return n}function Q(e){return typeof e=="function"&&T(e)===e}function b(e){if(Q(e))return e;const t=T(e);if(typeof t=="function"||typeof t=="object"||typeof t=="string")return t;if(e!==null&&typeof e=="function")return e;throw new Error("[vue-nnn-router] Export default không hợp lệ (component Vue hoặc lazy import).")}function ce(e){return!Q(e)&&typeof e=="object"&&e!==null&&Object.prototype.hasOwnProperty.call(e,"middleware")?e.middleware:void 0}function D(e){return e==null?[]:(Array.isArray(e)?e:[e]).filter(n=>typeof n=="function")}function le(e,t,n){const r=[];for(const o of X(e)){const s=t.get(o);s&&r.push(...D(T(s)))}return r.push(...D(ce(n))),r}function I(e,t){const r=e.map(h).join("/");if(t==="index")return r;const o=h(t);return r?`${r}/${o}`:o}function Z(e,t,n){const r=n==="index"?[]:[h(n)],o=[...t.map(h)];return[...e,...o,...r]}function g(e,t){return _(P([...e],t)||"/")}function K(e,t){const n=h(e).includes(":"),r=h(t).includes(":");return n!==r?n?1:-1:e.localeCompare(t)}function x(e){return e==="/"||e===""?"home":e.replace(/^\/+|\/+$/g,"").replace(/\//g,"-").replace(/:/g,"")||"route"}function F(e,t,n,r,o){const s=le(n.pathNoExt,r,n.modIn),c=s.length===0?void 0:s.length===1?s[0]:s;return{path:e,component:b(n.modIn),beforeEnter:c,meta:{nnnFile:n.rawKey},name:x(t),_dyn:$(t),_abs:t,_fk:n.rawKey,_order:o.seq++}}function j(e,t,n){const r=[];for(const[,o]of[...e.pages.entries()].sort((s,c)=>s[0].localeCompare(c[0]))){if(o.basenameLc===k)continue;const s=Z(t,[],o.basenameLc),c=g(s,n.pf);r.push(F(I([],o.basenameLc),c,o,n.mwMap,n.sq))}for(const[o,s]of[...e.dirs.entries()].sort((c,a)=>K(c[0],a[0]))){const c=h(o);if(s.layout){const a=[...t,c],f=g(a,n.pf),m=j(s,a,n);r.push({path:c,component:b(s.layout.modIn),children:m,name:`${x(f)}-layout`,meta:{},_dyn:$(f),_abs:f,_fk:s.layout.rawKey,_order:n.sq.seq++})}else r.push(...ee(s,t,[o],n))}return r.sort((o,s)=>o._dyn!==s._dyn?o._dyn-s._dyn:String(o.path).localeCompare(String(s.path)))}function ee(e,t,n,r){const o=[];for(const[,s]of[...e.pages.entries()].sort((c,a)=>c[0].localeCompare(a[0]))){if(s.basenameLc===k)continue;const c=Z(t,n,s.basenameLc),a=g([...c],r.pf);o.push(F(I(n,s.basenameLc),a,s,r.mwMap,r.sq))}for(const[s,c]of[...e.dirs.entries()].sort((a,f)=>K(a[0],f[0])))if(c.layout){const a=I(n,s),f=[...t,...n.map(h),h(s)],m=g(f,r.pf);o.push({path:a,component:b(c.layout.modIn),children:j(c,f,r),name:`${x(m)}-layout`,meta:{},_dyn:$(m),_abs:m,_fk:c.layout.rawKey,_order:r.sq.seq++})}else o.push(...ee(c,t,[...n,s],r));return o}function te(e,t,n){const r=[];for(const[,o]of[...e.pages.entries()].sort((s,c)=>s[0].localeCompare(c[0]))){if(o.basenameLc===k)continue;const s=[...t.map(h)],c=o.basenameLc==="index"?[]:[h(o.basenameLc)],a=g([...s,...c],n.pf);r.push(F(a,a,o,n.mwMap,n.sq))}for(const[o,s]of[...e.dirs.entries()].sort((c,a)=>K(c[0],a[0]))){const c=[...t,o];if(s.layout){const a=c.map(h),f=_(g(a,n.pf));r.push({path:f,component:b(s.layout.modIn),children:j(s,a,n),name:`${x(f)}-layout`,meta:{},_dyn:$(f),_abs:f,_fk:s.layout.rawKey,_order:n.sq.seq++})}else r.push(...te(s,c,n))}return r}function ne(e){const{_dyn:t,_abs:n,_fk:r,_order:o,children:s,...c}=e;if(s&&s.length)return{...c,children:s.map(m=>ne(m))};const{meta:a,...f}=c;return a&&Object.keys(a).length===0?(delete f.meta,f):c}function ue(e){return e.map(t=>ne(t))}function R(e,t){for(const n of e)n.children&&n.children.length?R(n.children,t):t.push(n)}function fe(e,t){const n=r=>{if(r.children&&r.children.length){const o=r.children.map(n).filter(Boolean);return o.length?{...r,children:o}:null}return t.get(r._abs)===r?r:null};return e.map(n).filter(Boolean)}function re(e,t={}){const n=t.prefix?.replace(/^\/+|\/+$/g,"")??"",r=t.silent!==!0?t.logger??((...i)=>console.log(...i)):void 0,o=Object.entries(e).map(([i,l])=>({rawKey:i,sk:U(V(i),t.routesRoot),modIn:l}));J(o,t.routesRoot,t.silent);const s=new Map,c=new Map;for(const{rawKey:i,sk:l,modIn:u}of o){if(!G(l))continue;const p=H(l),d=c.get(p);d!==void 0&&d!==i&&t.silent!==!0&&console.warn(`[vue-nnn-router] Middleware trùng "${p||"/"}".`),c.set(p,i),s.set(p,u)}const a=Y();let f=0;const m=i=>{const u=N(i).split("/").filter(Boolean);return u.length?{fsDirs:u.slice(0,-1),base:u[u.length-1].toLowerCase()}:null};for(const{rawKey:i,sk:l,modIn:u}of o){if(/\.(ts|js)$/i.test(l)&&/_middleware\.(ts|js)$/i.test(l))continue;const p=m(l);if(!p||!C.test(l))continue;const{fsDirs:d,base:v}=p,B=N(l);if(v===k){const L=z(a,d);L.layout!==void 0&&L.layout.rawKey!==i&&t.silent!==!0?console.warn(`[vue-nnn-router] Trùng _layout.vue trong thư mục, giữ "${L.layout.rawKey}".`):L.layout===void 0&&(L.layout={rawKey:i,modIn:u,pathNoExt:B});continue}const O=z(a,d),q=O.pages.get(v);if(q&&q.rawKey!==i&&t.silent!==!0){console.warn(`[vue-nnn-router] Hai file trong cùng thư mục: "${v}".`);continue}q||O.pages.set(v,{basenameLc:v,rawKey:i,modIn:u,pathNoExt:B,order:f++})}const w={mwMap:s,pf:n,sq:{seq:0}};let y=[];if(a.layout){const i=_(P([],n)||"/");y=[{path:i,component:b(a.layout.modIn),children:j(a,[],w),name:"root-layout",_dyn:0,_abs:i,_fk:a.layout.rawKey,_order:w.sq.seq++}]}else{const i=[];for(const[,l]of[...a.pages.entries()].sort((u,p)=>u[0].localeCompare(p[0])))if(l.basenameLc!==k){const u=l.basenameLc==="index"?g([],n):g([h(l.basenameLc)],n);i.push(F(u,u,l,s,w.sq))}for(const[l,u]of[...a.dirs.entries()].sort((p,d)=>K(p[0],d[0])))if(u.layout){const p=[h(l)],d=_(g(p,n));i.push({path:d,component:b(u.layout.modIn),children:j(u,p,w),name:`${x(d)}-layout`,meta:{},_dyn:$(d),_abs:d,_fk:u.layout.rawKey,_order:w.sq.seq++})}else i.push(...te(u,[l],w));y=i}const W=new Map,A=[];R(y,A);const E=new Map;for(const i of A){const l=i._abs,u=E.get(l);u?u.push(i):E.set(l,[i])}const oe=t.onDuplicate==="last-wins"?"last":"first",se=t.silent===!0,M=t.onDuplicate,S=[...E.entries()].filter(([,i])=>i.length>1);if(S.length&&!se&&typeof M!="function")for(const[i,l]of S)console.warn(`[vue-nnn-router] Trùng URL "${i}": ${l.map(u=>u._fk).join(", ")}`);if(typeof M=="function")for(const[i,l]of S)M(i,l.map(u=>u._fk));for(const[,i]of E){const l=[...i].sort((p,d)=>p._order-d._order),u=oe==="last"?l[l.length-1]:l[0];W.set(u._abs,u)}if(y=fe(y,W),y=y.sort((i,l)=>String(i.path).localeCompare(String(l.path))),t.verbose===!0&&r){const i=[];R(y,i),r(pe(i))}return ue(y)}function pe(e){const t=e.map(a=>({Path:a._abs,File:a._fk}));if(!t.length)return"";const n=Math.max(4,...t.map(a=>a.Path.length)),r=Math.max(4,...t.map(a=>a.File.length)),o="-".repeat(n+r+3),s="Path".padEnd(n)+" "+"File".padEnd(r),c=t.map(a=>a.Path.padEnd(n)+" "+a.File.padEnd(r)).join(`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function _(t){const e=t.replace(/\/+/g,"/").replace(/\/$/,"");return e===""||e==="/"?"/":e.startsWith("/")?e:`/${e}`}function G(t,e){const n=t.replace(/\\/g,"/").split("?")[0];let r=e?.replace(/\\/g,"/").replace(/^\.\/+/,"")??"";if(r=r.replace(/^\/+|\/+$/g,""),!r)return n;const o=`${r}/`;return n===r||n===`${r}/`?"":n.startsWith(o)?n.slice(o.length):n}function B(t,e){const n=t.length===0?"":`/${t.join("/")}`,r=[e?.replace(/^\/|\/$/g,""),n.replace(/^\//,"")].filter(Boolean).join("/"),o=r.startsWith("/")?r:`/${r}`;return _(o)}function V(t){const e=t.replace(/\\/g,"/").split("?")[0];return/^(.+\/)?_middleware\.(ts|js)$/i.test(e)}function H(t){const e=t.replace(/\\/g,"/").split("?")[0],n=/^(.*?)\/_middleware\.(ts|js)$/i.exec(e);return n?n[1]:(/^_middleware\.(ts|js)$/i.test(e),"")}function le(t){return`${t}/_middleware`}function J(t){const e=t.replace(/\\/g,"/").split("?")[0];return/^(.+\/)?_redirect\.(ts|js)$/i.test(e)}function X(t){const e=t.replace(/\\/g,"/").split("?")[0],n=/^(.*?)\/_redirect\.(ts|js)$/i.exec(e);return n?n[1]:(/^_redirect\.(ts|js)$/i.test(e),"")}function v(t){return(t.match(/\/:/g)||[]).length}function Y(t){let e=t.replace(/\\/g,"/").split("?")[0];for(;e.startsWith("./");)e=e.slice(2);return e.replace(/^\//,"")}function S(t){return t&&typeof t=="object"&&"default"in t?t.default:t}const C=/\.(vue|tsx|jsx|ts|js)$/i,L="_layout";function ue(t){return!(!C.test(t)||/\.(ts|js)$/i.test(t)&&/_middleware\.(ts|js)$/i.test(t)||/\.(ts|js)$/i.test(t)&&/_redirect\.(ts|js)$/i.test(t))}function Q(t,e,n){if(n===!0||!e?.trim())return;const r=t.filter(s=>ue(s.sk));if(r.length===0)return;const o=r.filter(s=>/\.\.(?:\/|$)/.test(s.sk)).length;o>=1&&console.warn(`[vue-nnn-router] ${o}/${r.length} route key(s) still contain ".." after routesRoot="${e}". Set routesRoot to match the actual glob key prefix (e.g. pattern ../pages/** → routesRoot: "../pages").`)}function h(t){const e=t.replace(/\\/g,"/");return e.startsWith("[")&&e.endsWith("]")?`:${e.slice(1,-1)}`:e}function E(t){return t.replace(/\\/g,"/").split("?")[0].replace(C,"")}function Z(t){const e=t.split("/").filter(Boolean),n=e.length>=1?e.slice(0,-1):[],r=[];for(let o=0;o<n.length;o++)r.push(n.slice(0,o+1).join("/"));return(r.length===0||r[0]!=="")&&r.unshift(""),r}function ee(){return{pages:new Map,dirs:new Map}}function D(t,e){let n=t;for(const r of e)n.dirs.has(r)||n.dirs.set(r,ee()),n=n.dirs.get(r);return n}function te(t){return typeof t=="function"&&S(t)===t}function $(t){if(te(t))return t;const e=S(t);if(typeof e=="function"||typeof e=="object"||typeof e=="string")return e;if(t!==null&&typeof t=="function")return t;throw new Error("[vue-nnn-router] Invalid default export (expected a Vue component or lazy import).")}function fe(t){return!te(t)&&typeof t=="object"&&t!==null&&Object.prototype.hasOwnProperty.call(t,"middleware")?t.middleware:void 0}function U(t){return t==null?[]:(Array.isArray(t)?t:[t]).filter(n=>typeof n=="function")}function pe(t,e,n){const r=[];for(const o of Z(t)){const s=e.get(o);s&&r.push(...U(S(s)))}return r.push(...U(fe(n))),r}function P(t,e){const r=t.map(h).join("/");if(e==="index")return r;const o=h(e);return r?`${r}/${o}`:o}function ne(t,e,n){const r=n==="index"?[]:[h(n)],o=[...e.map(h)];return[...t,...o,...r]}function y(t,e){return _(B([...t],e)||"/")}function q(t,e){const n=h(t).includes(":"),r=h(e).includes(":");return n!==r?n?1:-1:t.localeCompare(e)}function j(t){return t==="/"||t===""?"home":t.replace(/^\/+|\/+$/g,"").replace(/\//g,"-").replace(/:/g,"")||"route"}function M(t,e,n,r,o){const s=pe(n.pathNoExt,r,n.modIn),c=s.length===0?void 0:s.length===1?s[0]:s;return{path:t,component:$(n.modIn),beforeEnter:c,meta:{nnnFile:n.rawKey},name:j(e),_dyn:v(e),_abs:e,_fk:n.rawKey,_order:o.seq++}}function de(t){return t.pages.has("index")}function he(t,e,n){const r=S(t);if(typeof r!="string")return null;const o=r.trim();if(!o)return null;if(o.startsWith("/"))return _(o);const s=[...e,...o.split("/").filter(Boolean)];return y(s,n)}function me(t,e,n,r){if(de(e)||!e.redirect)return;const o=y(n,r.pf),s=he(e.redirect.modIn,n,r.pf);if(!s){r.silent!==!0&&console.warn(`[vue-nnn-router] Invalid _redirect in "${e.redirect.rawKey}" (expected export default string).`);return}t.unshift({path:"",redirect:s,name:`${j(o)}-redirect`,meta:{nnnFile:e.redirect.rawKey},_dyn:0,_abs:o,_fk:e.redirect.rawKey,_order:r.sq.seq++})}function k(t,e,n){const r=[];for(const[,o]of[...t.pages.entries()].sort((s,c)=>s[0].localeCompare(c[0]))){if(o.basenameLc===L)continue;const s=ne(e,[],o.basenameLc),c=y(s,n.pf);r.push(M(P([],o.basenameLc),c,o,n.mwMap,n.sq))}for(const[o,s]of[...t.dirs.entries()].sort((c,a)=>q(c[0],a[0]))){const c=h(o);if(s.layout){const a=[...e,c],p=y(a,n.pf),w=k(s,a,n);r.push({path:c,component:$(s.layout.modIn),children:w,name:`${j(p)}-layout`,meta:{},_dyn:v(p),_abs:p,_fk:s.layout.rawKey,_order:n.sq.seq++})}else r.push(...re(s,e,[o],n))}return me(r,t,e,n),r.sort((o,s)=>o._dyn!==s._dyn?o._dyn-s._dyn:String(o.path).localeCompare(String(s.path)))}function re(t,e,n,r){const o=[];for(const[,s]of[...t.pages.entries()].sort((c,a)=>c[0].localeCompare(a[0]))){if(s.basenameLc===L)continue;const c=ne(e,n,s.basenameLc),a=y([...c],r.pf);o.push(M(P(n,s.basenameLc),a,s,r.mwMap,r.sq))}for(const[s,c]of[...t.dirs.entries()].sort((a,p)=>q(a[0],p[0])))if(c.layout){const a=P(n,s),p=[...e,...n.map(h),h(s)],w=y(p,r.pf);o.push({path:a,component:$(c.layout.modIn),children:k(c,p,r),name:`${j(w)}-layout`,meta:{},_dyn:v(w),_abs:w,_fk:c.layout.rawKey,_order:r.sq.seq++})}else o.push(...re(c,e,[...n,s],r));return o}function oe(t,e,n){const r=[];for(const[,o]of[...t.pages.entries()].sort((s,c)=>s[0].localeCompare(c[0]))){if(o.basenameLc===L)continue;const s=[...e.map(h)],c=o.basenameLc==="index"?[]:[h(o.basenameLc)],a=y([...s,...c],n.pf);r.push(M(a,a,o,n.mwMap,n.sq))}for(const[o,s]of[...t.dirs.entries()].sort((c,a)=>q(c[0],a[0]))){const c=[...e,o];if(s.layout){const a=c.map(h),p=_(y(a,n.pf));r.push({path:p,component:$(s.layout.modIn),children:k(s,a,n),name:`${j(p)}-layout`,meta:{},_dyn:v(p),_abs:p,_fk:s.layout.rawKey,_order:n.sq.seq++})}else r.push(...oe(s,c,n))}return r}function se(t){const{_dyn:e,_abs:n,_fk:r,_order:o,children:s,...c}=t;if(s&&s.length)return{...c,children:s.map(w=>se(w))};const{meta:a,...p}=c;return a&&Object.keys(a).length===0?(delete p.meta,p):c}function ye(t){return t.map(e=>se(e))}function T(t,e){for(const n of t)n.children&&n.children.length?T(n.children,e):e.push(n)}function we(t,e){const n=r=>{if(r.children&&r.children.length){const o=r.children.map(n).filter(Boolean);return o.length?{...r,children:o}:null}return e.get(r._abs)===r?r:null};return t.map(n).filter(Boolean)}function ie(t,e={}){const n=e.prefix?.replace(/^\/+|\/+$/g,"")??"",r=e.silent!==!0?e.logger??((...i)=>console.log(...i)):void 0,o=Object.entries(t).map(([i,l])=>({rawKey:i,sk:G(Y(i),e.routesRoot),modIn:l}));Q(o,e.routesRoot,e.silent);const s=new Map,c=new Map;for(const{rawKey:i,sk:l,modIn:u}of o){if(!V(l))continue;const f=H(l),d=c.get(f);d!==void 0&&d!==i&&e.silent!==!0&&console.warn(`[vue-nnn-router] Duplicate middleware for "${f||"/"}".`),c.set(f,i),s.set(f,u)}const a=ee();let p=0;const w=i=>{const u=E(i).split("/").filter(Boolean);return u.length?{fsDirs:u.slice(0,-1),base:u[u.length-1].toLowerCase()}:null};for(const{rawKey:i,sk:l,modIn:u}of o){if(/\.(ts|js)$/i.test(l)&&/_middleware\.(ts|js)$/i.test(l)||/\.(ts|js)$/i.test(l)&&/_redirect\.(ts|js)$/i.test(l))continue;const f=w(l);if(!f||!C.test(l))continue;const{fsDirs:d,base:m}=f,x=E(l);if(m===L){const K=D(a,d);K.layout!==void 0&&K.layout.rawKey!==i&&e.silent!==!0?console.warn(`[vue-nnn-router] Duplicate _layout.vue in folder, keeping "${K.layout.rawKey}".`):K.layout===void 0&&(K.layout={rawKey:i,modIn:u,pathNoExt:x});continue}const z=D(a,d),R=z.pages.get(m);if(R&&R.rawKey!==i&&e.silent!==!0){console.warn(`[vue-nnn-router] Duplicate basename in folder: "${m}".`);continue}R||z.pages.set(m,{basenameLc:m,rawKey:i,modIn:u,pathNoExt:x,order:p++})}const W=new Map;for(const{rawKey:i,sk:l,modIn:u}of o){if(!J(l))continue;const f=X(l),d=f?f.split("/").filter(Boolean):[],m=D(a,d),x=W.get(f);x!==void 0&&x!==i&&e.silent!==!0&&console.warn(`[vue-nnn-router] Duplicate _redirect for "${f||"/"}".`),W.set(f,i),m.redirect!==void 0&&m.redirect.rawKey!==i&&e.silent!==!0?console.warn(`[vue-nnn-router] Duplicate _redirect in folder, keeping "${m.redirect.rawKey}".`):m.redirect===void 0&&(m.redirect={rawKey:i,modIn:u,pathNoExt:E(l)}),!m.layout&&e.silent!==!0&&console.warn(`[vue-nnn-router] _redirect "${i}" has no _layout in the same folder — skipped when building routes.`)}const b={mwMap:s,pf:n,sq:{seq:0},silent:e.silent};let g=[];if(a.layout){const i=_(B([],n)||"/");g=[{path:i,component:$(a.layout.modIn),children:k(a,[],b),name:"root-layout",_dyn:0,_abs:i,_fk:a.layout.rawKey,_order:b.sq.seq++}]}else{const i=[];for(const[,l]of[...a.pages.entries()].sort((u,f)=>u[0].localeCompare(f[0])))if(l.basenameLc!==L){const u=l.basenameLc==="index"?y([],n):y([h(l.basenameLc)],n);i.push(M(u,u,l,s,b.sq))}for(const[l,u]of[...a.dirs.entries()].sort((f,d)=>q(f[0],d[0])))if(u.layout){const f=[h(l)],d=_(y(f,n));i.push({path:d,component:$(u.layout.modIn),children:k(u,f,b),name:`${j(d)}-layout`,meta:{},_dyn:v(d),_abs:d,_fk:u.layout.rawKey,_order:b.sq.seq++})}else i.push(...oe(u,[l],b));g=i}const A=new Map,O=[];T(g,O);const F=new Map;for(const i of O){const l=i._abs,u=F.get(l);u?u.push(i):F.set(l,[i])}const ae=e.onDuplicate==="last-wins"?"last":"first",ce=e.silent===!0,N=e.onDuplicate,I=[...F.entries()].filter(([,i])=>i.length>1);if(I.length&&!ce&&typeof N!="function")for(const[i,l]of I)console.warn(`[vue-nnn-router] Duplicate URL "${i}": ${l.map(u=>u._fk).join(", ")}`);if(typeof N=="function")for(const[i,l]of I)N(i,l.map(u=>u._fk));for(const[,i]of F){const l=[...i].sort((f,d)=>f._order-d._order),u=ae==="last"?l[l.length-1]:l[0];A.set(u._abs,u)}if(g=we(g,A),g=g.sort((i,l)=>String(i.path).localeCompare(String(l.path))),e.verbose===!0&&r){const i=[];T(g,i),r(ge(i))}return ye(g)}function ge(t){const e=t.map(a=>({Path:a._abs,File:a._fk}));if(!e.length)return"";const n=Math.max(4,...e.map(a=>a.Path.length)),r=Math.max(4,...e.map(a=>a.File.length)),o="-".repeat(n+r+3),s="Path".padEnd(n)+" "+"File".padEnd(r),c=e.map(a=>a.Path.padEnd(n)+" "+a.File.padEnd(r)).join(`
|
|
2
2
|
`);return["[vue-nnn-router]",o,s,o,c,o].join(`
|
|
3
|
-
`)}function
|
|
3
|
+
`)}function _e(t,e={}){return ie(t,e)}exports.createNnnRoutes=_e;exports.createSpaNnnRoutes=ie;exports.dynamicScore=v;exports.isMiddlewareKey=V;exports.isRedirectKey=J;exports.middlewareDirFromNormKey=H;exports.middlewareLogicalKey=le;exports.mwPrefixesForPathNoExt=Z;exports.normalizePath=_;exports.pathFromSegments=B;exports.pathNoExt=E;exports.redirectDirFromNormKey=X;exports.segmentUrlFromFs=h;exports.simplifyGlobKey=Y;exports.stripRoutesRoot=G;exports.warnIfRoutesRootLikelyWrong=Q;
|
|
4
4
|
//# sourceMappingURL=vue-nnn-router.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vue-nnn-router.cjs","sources":["../src/path.ts","../src/globUtils.ts","../src/spaRouteGenerator.ts","../src/createNnnRoutes.ts"],"sourcesContent":["export function normalizePath(path: string): string {\n const cleaned = path.replace(/\\/+/g, \"/\").replace(/\\/$/, \"\");\n if (cleaned === \"\" || cleaned === \"/\") return \"/\";\n return cleaned.startsWith(\"/\") ? cleaned : `/${cleaned}`;\n}\n\n/** Bỏ `routesRoot/` khỏi key đã qua simplifyGlobKey. */\nexport function stripRoutesRoot(normKey: string, routesRoot?: string): string {\n const k0 = normKey.replace(/\\\\/g, \"/\").split(\"?\")[0];\n let rRaw = routesRoot?.replace(/\\\\/g, \"/\").replace(/^\\.\\/+/, \"\") ?? \"\";\n rRaw = rRaw.replace(/^\\/+|\\/+$/g, \"\");\n if (!rRaw) return k0;\n const p = `${rRaw}/`;\n if (k0 === rRaw || k0 === `${rRaw}/`) return \"\";\n if (k0.startsWith(p)) return k0.slice(p.length);\n return k0;\n}\n\nexport function pathFromSegments(segments: string[], prefix?: string): string {\n const core = segments.length === 0 ? \"\" : `/${segments.join(\"/\")}`;\n const raw = [prefix?.replace(/^\\/|\\/$/g, \"\"), core.replace(/^\\//, \"\")]\n .filter(Boolean)\n .join(\"/\");\n const withSlash = raw.startsWith(\"/\") ? raw : `/${raw}`;\n return normalizePath(withSlash);\n}\n\nexport function isMiddlewareKey(key: string): boolean {\n const n = key.replace(/\\\\/g, \"/\").split(\"?\")[0];\n return /^(.+\\/)?_middleware\\.(ts|js)$/i.test(n);\n}\n\n/** Thư mục chứa `_middleware` (chuỗi rỗng = ngay trong `routesRoot`). */\nexport function middlewareDirFromNormKey(normKey: string): string {\n const n = normKey.replace(/\\\\/g, \"/\").split(\"?\")[0];\n const nested = /^(.*?)\\/_middleware\\.(ts|js)$/i.exec(n);\n if (nested) return nested[1]!;\n if (/^_middleware\\.(ts|js)$/i.test(n)) return \"\";\n return \"\";\n}\n\nexport function middlewareLogicalKey(prefixPath: string): string {\n return `${prefixPath}/_middleware`;\n}\n\n/** Đếm độ động (số `/:`) để ưu tiên route tĩnh trước. */\nexport function dynamicScore(pathPattern: string): number {\n return (pathPattern.match(/\\/:/g) || []).length;\n}\n","/** Dùng chung bởi createNnnRoutes và spaRoutes. */\n\nexport function simplifyGlobKey(key: string): string {\n let k = key.replace(/\\\\/g, \"/\").split(\"?\")[0];\n while (k.startsWith(\"./\")) k = k.slice(2);\n return k.replace(/^\\//, \"\");\n}\n\nexport function unwrapDefault(mod: unknown): unknown {\n if (mod && typeof mod === \"object\" && \"default\" in mod) {\n return (mod as { default: unknown }).default;\n }\n return mod;\n}\n","import type {\n NavigationGuardWithThis,\n RouteRecordRaw,\n} from \"vue-router\";\nimport type { CreateNnnRoutesOptions } from \"./types\";\nimport type { NnnRouteMeta } from \"./types\";\nimport {\n dynamicScore,\n isMiddlewareKey,\n middlewareDirFromNormKey,\n normalizePath,\n pathFromSegments,\n stripRoutesRoot,\n} from \"./path\";\nimport { simplifyGlobKey, unwrapDefault } from \"./globUtils\";\n\nconst PAGE_EXT = /\\.(vue|tsx|jsx|ts|js)$/i;\n\n/** Basename file layout (không phải segment URL). */\nconst LAYOUT_BASENAME = \"_layout\";\n\nfunction isLikelyRouteFileKey(sk: string): boolean {\n if (!PAGE_EXT.test(sk)) return false;\n if (/\\.(ts|js)$/i.test(sk) && /_middleware\\.(ts|js)$/i.test(sk)) return false;\n return true;\n}\n\n/** Cảnh báo khi `routesRoot` không strip được `..` trong key (lỗi cấu hình thường gặp). */\nexport function warnIfRoutesRootLikelyWrong(\n rows: readonly { sk: string }[],\n routesRoot: string | undefined,\n silent: boolean | undefined\n): void {\n if (silent === true || !routesRoot?.trim()) return;\n const targets = rows.filter((r) => isLikelyRouteFileKey(r.sk));\n if (targets.length === 0) return;\n const bad = targets.filter((r) => /\\.\\.(?:\\/|$)/.test(r.sk)).length;\n if (bad >= 1) {\n console.warn(\n `[vue-nnn-router] ${bad}/${targets.length} key route vẫn chứa \"..\" sau routesRoot=\"${routesRoot}\". ` +\n `Đặt routesRoot khớp tiền tố thực của key glob (vd. pattern ../pages/** → routesRoot: \"../pages\").`,\n );\n }\n}\n\n/** Tên segment filesystem `[slug]` hoặc basename file `[slug].vue` → `:slug` trong URL. */\nexport function segmentUrlFromFs(fsSeg: string): string {\n const s = fsSeg.replace(/\\\\/g, \"/\");\n if (s.startsWith(\"[\") && s.endsWith(\"]\")) return `:${s.slice(1, -1)}`;\n return s;\n}\n\n/** Key glob đã strip `routesRoot`; trả pathname không có ext (vd `users/add`). */\nexport function pathNoExt(strippedSk: string): string {\n return strippedSk.replace(/\\\\/g, \"/\").split(\"?\")[0].replace(PAGE_EXT, \"\");\n}\n\n/** Tiền tố cascade `_middleware.ts` SPA. */\nexport function mwPrefixesForPathNoExt(pn: string): string[] {\n const parts = pn.split(\"/\").filter(Boolean);\n const dirParts = parts.length >= 1 ? parts.slice(0, -1) : [];\n const prefixes: string[] = [];\n for (let i = 0; i < dirParts.length; i++) {\n prefixes.push(dirParts.slice(0, i + 1).join(\"/\"));\n }\n if (prefixes.length === 0 || prefixes[0] !== \"\") prefixes.unshift(\"\");\n return prefixes;\n}\n\ntype PageRec = {\n basenameLc: string;\n rawKey: string;\n modIn: unknown;\n pathNoExt: string;\n order: number;\n};\n\ntype TrieNode = {\n layout?: { rawKey: string; modIn: unknown; pathNoExt: string };\n pages: Map<string, PageRec>;\n dirs: Map<string, TrieNode>;\n};\n\nfunction trieEmpty(): TrieNode {\n return { pages: new Map(), dirs: new Map() };\n}\n\nfunction trieEnsure(root: TrieNode, fsDirs: readonly string[]): TrieNode {\n let cur = root;\n for (const d of fsDirs) {\n if (!cur.dirs.has(d)) cur.dirs.set(d, trieEmpty());\n cur = cur.dirs.get(d)!;\n }\n return cur;\n}\n\ntype Cmp = Exclude<RouteRecordRaw[\"component\"], undefined | null>;\n\nfunction lazyTop(mod: unknown): boolean {\n return typeof mod === \"function\" && unwrapDefault(mod) === mod;\n}\n\nfunction toCmp(mod: unknown): Cmp {\n if (lazyTop(mod)) return mod as Cmp;\n const x = unwrapDefault(mod);\n if (typeof x === \"function\") return x as Cmp;\n if (typeof x === \"object\" || typeof x === \"string\") return x as Cmp;\n if (mod !== null && typeof mod === \"function\") return mod as Cmp;\n throw new Error(\n \"[vue-nnn-router] Export default không hợp lệ (component Vue hoặc lazy import).\"\n );\n}\n\nfunction routeMw(mod: unknown): unknown {\n return !lazyTop(mod) &&\n typeof mod === \"object\" &&\n mod !== null &&\n Object.prototype.hasOwnProperty.call(mod, \"middleware\")\n ? (mod as { middleware?: unknown }).middleware\n : undefined;\n}\n\nfunction normGuards(g: unknown): NavigationGuardWithThis<undefined>[] {\n if (g === undefined || g === null) return [];\n const a = Array.isArray(g) ? g : [g];\n return a.filter(\n (x): x is NavigationGuardWithThis<undefined> => typeof x === \"function\"\n );\n}\n\nfunction guards(\n pagePathNoExt: string,\n mwMap: Map<string, unknown>,\n pageMod?: unknown\n) {\n const out: NavigationGuardWithThis<undefined>[] = [];\n for (const p of mwPrefixesForPathNoExt(pagePathNoExt)) {\n const mw = mwMap.get(p);\n if (!mw) continue;\n out.push(...normGuards(unwrapDefault(mw)));\n }\n out.push(...normGuards(routeMw(pageMod)));\n return out;\n}\n\n/**\n * Path con (không có `/` đầu).\n * Basename có thể `index`, `add`, hoặc **`[id]`** → **`:id`** (giống segment thư mục).\n */\nfunction vueRel(fsRawPrefixes: readonly string[], basenameLc: string): string {\n const dirs = fsRawPrefixes.map(segmentUrlFromFs);\n const j = dirs.join(\"/\");\n if (basenameLc === \"index\") return j;\n const leafSeg = segmentUrlFromFs(basenameLc);\n return j ? `${j}/${leafSeg}` : leafSeg;\n}\n\n/** URL `:param`; `mount` + segment FS + basename (kể cả `[id].vue`). */\nfunction absPiecesJoined(\n mountUrlPieces: readonly string[],\n fsRawRel: readonly string[],\n basenameLc: string\n): string[] {\n const tail =\n basenameLc === \"index\" ? [] : [segmentUrlFromFs(basenameLc)];\n const middle = [...fsRawRel.map(segmentUrlFromFs)];\n return [...mountUrlPieces, ...middle, ...tail];\n}\n\nfunction absHref(pieces: readonly string[], pf: string): string {\n return normalizePath(pathFromSegments([...pieces], pf) || \"/\");\n}\n\nfunction cmpFs(a: string, b: string): number {\n const da = segmentUrlFromFs(a).includes(\":\");\n const db = segmentUrlFromFs(b).includes(\":\");\n if (da !== db) return da ? 1 : -1;\n return a.localeCompare(b);\n}\n\ntype Built = RouteRecordRaw & {\n _dyn: number;\n _abs: string;\n _fk: string;\n _order: number;\n};\n\nfunction nm(abs: string): string {\n if (abs === \"/\" || abs === \"\") return \"home\";\n return (\n abs\n .replace(/^\\/+|\\/+$/g, \"\")\n .replace(/\\//g, \"-\")\n .replace(/:/g, \"\") || \"route\"\n );\n}\n\nfunction makeLeaf(\n routePathPattern: string,\n absDedupe: string,\n pg: PageRec,\n mwMap: Map<string, unknown>,\n sq: { seq: number }\n): Built {\n const gs = guards(pg.pathNoExt, mwMap, pg.modIn);\n const be =\n gs.length === 0 ? undefined : gs.length === 1 ? gs[0]! : gs;\n return {\n path: routePathPattern,\n component: toCmp(pg.modIn),\n beforeEnter: be,\n meta: { nnnFile: pg.rawKey } satisfies NnnRouteMeta,\n name: nm(absDedupe),\n _dyn: dynamicScore(absDedupe),\n _abs: absDedupe,\n _fk: pg.rawKey,\n _order: sq.seq++,\n };\n}\n\ntype Cfg = { mwMap: Map<string, unknown>; pf: string; sq: { seq: number } };\n\nfunction childrenInsideLayout(node: TrieNode, mountPieces: readonly string[], cfg: Cfg): Built[] {\n const acc: Built[] = [];\n\n for (const [, pg] of [...node.pages.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {\n if (pg.basenameLc === LAYOUT_BASENAME) continue;\n const pieces = absPiecesJoined(mountPieces, [], pg.basenameLc);\n const ah = absHref(pieces, cfg.pf);\n acc.push(makeLeaf(vueRel([], pg.basenameLc), ah, pg, cfg.mwMap, cfg.sq));\n }\n\n for (const [fs, cn] of [...node.dirs.entries()].sort((a, b) => cmpFs(a[0], b[0]))) {\n const segUrl = segmentUrlFromFs(fs);\n if (cn.layout) {\n const nextMount = [...mountPieces, segUrl];\n const absLay = absHref(nextMount, cfg.pf);\n const nested = childrenInsideLayout(cn, nextMount, cfg);\n acc.push({\n path: segUrl,\n component: toCmp(cn.layout!.modIn),\n children: nested,\n name: `${nm(absLay)}-layout`,\n meta: {},\n _dyn: dynamicScore(absLay),\n _abs: absLay,\n _fk: cn.layout!.rawKey,\n _order: cfg.sq.seq++,\n } as Built);\n } else {\n acc.push(...flattenNoLay(cn, mountPieces, [fs], cfg));\n }\n }\n\n return acc.sort((x, y) =>\n x._dyn !== y._dyn ? x._dyn - y._dyn : String(x.path).localeCompare(String(y.path))\n );\n}\n\nfunction flattenNoLay(\n node: TrieNode,\n mountPieces: readonly string[],\n fsRelRaw: readonly string[],\n cfg: Cfg,\n): Built[] {\n const acc: Built[] = [];\n\n for (const [, pg] of [...node.pages.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {\n if (pg.basenameLc === LAYOUT_BASENAME) continue;\n const pieces = absPiecesJoined(mountPieces, fsRelRaw, pg.basenameLc);\n const ah = absHref([...pieces], cfg.pf);\n acc.push(makeLeaf(vueRel(fsRelRaw, pg.basenameLc), ah, pg, cfg.mwMap, cfg.sq));\n }\n\n for (const [fs, cn] of [...node.dirs.entries()].sort((a, b) => cmpFs(a[0], b[0]))) {\n if (cn.layout) {\n const vrSeg = vueRel(fsRelRaw, fs);\n const mp = [...mountPieces, ...fsRelRaw.map(segmentUrlFromFs), segmentUrlFromFs(fs)];\n const ah = absHref(mp, cfg.pf);\n acc.push({\n path: vrSeg,\n component: toCmp(cn.layout!.modIn),\n children: childrenInsideLayout(cn, mp, cfg),\n name: `${nm(ah)}-layout`,\n meta: {},\n _dyn: dynamicScore(ah),\n _abs: ah,\n _fk: cn.layout!.rawKey,\n _order: cfg.sq.seq++,\n } as Built);\n } else {\n acc.push(...flattenNoLay(cn, mountPieces, [...fsRelRaw, fs], cfg));\n }\n }\n\n return acc;\n}\n\nfunction emitFlatTopSubtree(node: TrieNode, outerPieces: readonly string[], cfg: Cfg): Built[] {\n const acc: Built[] = [];\n\n for (const [, pg] of [...node.pages.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {\n if (pg.basenameLc === LAYOUT_BASENAME) continue;\n const pieces = [...outerPieces.map(segmentUrlFromFs)];\n const rest =\n pg.basenameLc === \"index\" ? [] : [segmentUrlFromFs(pg.basenameLc)];\n const ah = absHref([...pieces, ...rest], cfg.pf);\n acc.push(makeLeaf(ah, ah, pg, cfg.mwMap, cfg.sq));\n }\n\n for (const [fs, cn] of [...node.dirs.entries()].sort((a, b) => cmpFs(a[0], b[0]))) {\n const pref = [...outerPieces, fs];\n if (cn.layout) {\n const mount = pref.map(segmentUrlFromFs);\n const pathTop = normalizePath(absHref(mount, cfg.pf));\n acc.push({\n path: pathTop,\n component: toCmp(cn.layout!.modIn),\n children: childrenInsideLayout(cn, mount, cfg),\n name: `${nm(pathTop)}-layout`,\n meta: {},\n _dyn: dynamicScore(pathTop),\n _abs: pathTop,\n _fk: cn.layout!.rawKey,\n _order: cfg.sq.seq++,\n } as Built);\n } else acc.push(...emitFlatTopSubtree(cn, pref, cfg));\n }\n\n return acc;\n}\n\nfunction stripBuilt(r: Built): RouteRecordRaw {\n const { _dyn, _abs, _fk, _order, children, ...rest } = r;\n void _dyn;\n void _abs;\n void _fk;\n void _order;\n if (children && children.length) {\n return {\n ...rest,\n children: (children as Built[]).map((c) => stripBuilt(c)),\n } as RouteRecordRaw;\n }\n const { meta, ...rno } = rest;\n if (meta && Object.keys(meta).length === 0) {\n delete (rno as { meta?: unknown }).meta;\n return rno as RouteRecordRaw;\n }\n return rest as RouteRecordRaw;\n}\n\nfunction finalizeTree(xs: Built[]): RouteRecordRaw[] {\n return xs.map((r) => stripBuilt(r));\n}\n\nfunction collectLeaves(xs: Built[], into: Built[]): void {\n for (const r of xs) {\n if (r.children && r.children.length)\n collectLeaves(r.children as Built[], into);\n else into.push(r);\n }\n}\n\nfunction pruneTree(rs: Built[], keepLeaf: Map<string, Built>): Built[] {\n const recurse = (r: Built): Built | null => {\n if (r.children && r.children.length) {\n const ch = (r.children as Built[]).map(recurse).filter(Boolean) as Built[];\n return ch.length ? ({ ...r, children: ch } as Built) : null;\n }\n return keepLeaf.get(r._abs) === r ? r : null;\n };\n return rs.map(recurse).filter(Boolean) as Built[];\n}\n\n/** Public: sinh RouteRecordRaw SPA. */\nexport function createSpaNnnRoutes(\n globRecord: Record<string, unknown>,\n options: CreateNnnRoutesOptions = {},\n): RouteRecordRaw[] {\n const pf = options.prefix?.replace(/^\\/+|\\/+$/g, \"\") ?? \"\";\n const logFn =\n options.silent !== true\n ? (options.logger ?? ((...a: unknown[]) => console.log(...a)))\n : undefined;\n\n type Row = { rawKey: string; sk: string; modIn: unknown };\n const rows: Row[] = Object.entries(globRecord).map(([rawKey, modIn]) => ({\n rawKey,\n sk: stripRoutesRoot(simplifyGlobKey(rawKey), options.routesRoot),\n modIn,\n }));\n\n warnIfRoutesRootLikelyWrong(rows, options.routesRoot, options.silent);\n\n const mwMap = new Map<string, unknown>();\n const mwSeen = new Map<string, string>();\n for (const { rawKey, sk, modIn } of rows) {\n if (!isMiddlewareKey(sk)) continue;\n const d = middlewareDirFromNormKey(sk);\n const prev = mwSeen.get(d);\n if (\n prev !== undefined &&\n prev !== rawKey &&\n options.silent !== true\n ) {\n console.warn(`[vue-nnn-router] Middleware trùng \"${d || \"/\"}\".`);\n }\n mwSeen.set(d, rawKey);\n mwMap.set(d, modIn);\n }\n\n const root = trieEmpty();\n let ord = 0;\n\n const parse = (\n stripped: string,\n ): { fsDirs: string[]; base: string } | null => {\n const pn = pathNoExt(stripped);\n const parts = pn.split(\"/\").filter(Boolean);\n if (!parts.length) return null;\n return {\n fsDirs: parts.slice(0, -1),\n base: parts[parts.length - 1]!.toLowerCase(),\n };\n };\n\n for (const { rawKey, sk, modIn } of rows) {\n if (/\\.(ts|js)$/i.test(sk) && /_middleware\\.(ts|js)$/i.test(sk)) continue;\n\n const p = parse(sk);\n if (!p) continue;\n if (!PAGE_EXT.test(sk)) continue;\n\n const { fsDirs, base } = p;\n const pn = pathNoExt(sk);\n\n if (base === LAYOUT_BASENAME) {\n const n = trieEnsure(root, fsDirs);\n if (\n n.layout !== undefined &&\n n.layout.rawKey !== rawKey &&\n options.silent !== true\n ) {\n console.warn(\n `[vue-nnn-router] Trùng _layout.vue trong thư mục, giữ \"${n.layout.rawKey}\".`,\n );\n } else if (n.layout === undefined) {\n n.layout = { rawKey, modIn, pathNoExt: pn };\n }\n continue;\n }\n\n const n = trieEnsure(root, fsDirs);\n const existing = n.pages.get(base);\n if (existing && existing.rawKey !== rawKey && options.silent !== true) {\n console.warn(`[vue-nnn-router] Hai file trong cùng thư mục: \"${base}\".`);\n continue;\n }\n if (!existing) {\n n.pages.set(base, {\n basenameLc: base,\n rawKey,\n modIn,\n pathNoExt: pn,\n order: ord++,\n });\n }\n }\n\n const cfg: Cfg = { mwMap, pf: pf, sq: { seq: 0 } };\n\n let top: Built[] = [];\n\n if (root.layout) {\n const rootAbs = normalizePath(pathFromSegments([], pf) || \"/\");\n top = [\n {\n path: rootAbs,\n component: toCmp(root.layout.modIn),\n children: childrenInsideLayout(root, [], cfg),\n name: \"root-layout\",\n _dyn: 0,\n _abs: rootAbs,\n _fk: root.layout.rawKey,\n _order: cfg.sq.seq++,\n } as Built,\n ];\n } else {\n const acc: Built[] = [];\n for (const [, pg] of [...root.pages.entries()].sort((a, b) =>\n a[0].localeCompare(b[0]),\n )) {\n if (pg.basenameLc !== LAYOUT_BASENAME) {\n const h =\n pg.basenameLc === \"index\"\n ? absHref([], pf)\n : absHref([segmentUrlFromFs(pg.basenameLc)], pf);\n acc.push(makeLeaf(h, h, pg, mwMap, cfg.sq));\n }\n }\n\n for (const [fs, cn] of [...root.dirs.entries()].sort((a, b) =>\n cmpFs(a[0], b[0]),\n )) {\n if (cn.layout) {\n const mount = [segmentUrlFromFs(fs)];\n const pTop = normalizePath(absHref(mount, pf));\n acc.push({\n path: pTop,\n component: toCmp(cn.layout!.modIn),\n children: childrenInsideLayout(cn, mount, cfg),\n name: `${nm(pTop)}-layout`,\n meta: {},\n _dyn: dynamicScore(pTop),\n _abs: pTop,\n _fk: cn.layout!.rawKey,\n _order: cfg.sq.seq++,\n } as Built);\n } else acc.push(...emitFlatTopSubtree(cn, [fs], cfg));\n }\n top = acc;\n }\n\n const leavesKeep = new Map<string, Built>();\n const flatLeaves: Built[] = [];\n collectLeaves(top, flatLeaves);\n const bucket = new Map<string, Built[]>();\n for (const lf of flatLeaves) {\n const ax = lf._abs;\n const b = bucket.get(ax);\n if (b) b.push(lf);\n else bucket.set(ax, [lf]);\n }\n const mode = options.onDuplicate === \"last-wins\" ? \"last\" : \"first\";\n const silent = options.silent === true;\n const strat = options.onDuplicate;\n const dupEntries = [...bucket.entries()].filter(([, a]) => a.length > 1);\n if (dupEntries.length && !silent && typeof strat !== \"function\") {\n for (const [p, arr] of dupEntries) {\n console.warn(\n `[vue-nnn-router] Trùng URL \"${p}\": ${arr.map((x) => x._fk).join(\", \")}`,\n );\n }\n }\n if (typeof strat === \"function\") {\n for (const [p, arr] of dupEntries) strat(p, arr.map((x) => x._fk));\n }\n\n for (const [, arr] of bucket) {\n const srt = [...arr].sort((a, b) => a._order - b._order);\n const win = mode === \"last\" ? srt[srt.length - 1]! : srt[0]!;\n leavesKeep.set(win._abs, win);\n }\n\n top = pruneTree(top, leavesKeep);\n\n top = top.sort((a, b) => String(a.path).localeCompare(String(b.path)));\n\n if (options.verbose === true && logFn) {\n const afterLeaves: Built[] = [];\n collectLeaves(top, afterLeaves);\n logFn(formatSpaVerbose(afterLeaves));\n }\n\n return finalizeTree(top);\n}\n\nfunction formatSpaVerbose(leaves: Built[]): string {\n const rows = leaves.map((l) => ({\n Path: l._abs,\n File: l._fk,\n }));\n if (!rows.length) return \"\";\n const wPath = Math.max(4, ...rows.map((x) => x.Path.length));\n const wFile = Math.max(4, ...rows.map((x) => x.File.length));\n const ln = \"-\".repeat(wPath + wFile + 3);\n const h = `Path`.padEnd(wPath) + \" \" + `File`.padEnd(wFile);\n const b = rows.map((r) => r.Path.padEnd(wPath) + \" \" + r.File.padEnd(wFile)).join(\"\\n\");\n return [\"[vue-nnn-router]\", ln, h, ln, b, ln].join(\"\\n\");\n}\n","import type { RouteRecordRaw } from \"vue-router\";\nimport type { CreateNnnRoutesOptions } from \"./types\";\nimport { createSpaNnnRoutes } from \"./spaRoutes\";\n\nexport { simplifyGlobKey } from \"./globUtils\";\n\n/**\n * Từ map `import.meta.glob` sinh `RouteRecordRaw[]` — quy ước SPA: `index.vue`, `_layout.vue`, `[param]`.\n */\nexport function createNnnRoutes(\n globRecord: Record<string, unknown>,\n options: CreateNnnRoutesOptions = {}\n): RouteRecordRaw[] {\n return createSpaNnnRoutes(globRecord, options);\n}\n"],"names":["normalizePath","path","cleaned","stripRoutesRoot","normKey","routesRoot","k0","rRaw","p","pathFromSegments","segments","prefix","core","raw","withSlash","isMiddlewareKey","key","n","middlewareDirFromNormKey","nested","middlewareLogicalKey","prefixPath","dynamicScore","pathPattern","simplifyGlobKey","k","unwrapDefault","mod","PAGE_EXT","LAYOUT_BASENAME","isLikelyRouteFileKey","sk","warnIfRoutesRootLikelyWrong","rows","silent","targets","r","bad","segmentUrlFromFs","fsSeg","s","pathNoExt","strippedSk","mwPrefixesForPathNoExt","pn","parts","dirParts","prefixes","i","trieEmpty","trieEnsure","root","fsDirs","cur","d","lazyTop","toCmp","x","routeMw","normGuards","g","guards","pagePathNoExt","mwMap","pageMod","out","mw","vueRel","fsRawPrefixes","basenameLc","j","leafSeg","absPiecesJoined","mountUrlPieces","fsRawRel","tail","middle","absHref","pieces","pf","cmpFs","a","b","da","db","nm","abs","makeLeaf","routePathPattern","absDedupe","pg","sq","gs","be","childrenInsideLayout","node","mountPieces","cfg","acc","ah","fs","cn","segUrl","nextMount","absLay","flattenNoLay","y","fsRelRaw","vrSeg","mp","emitFlatTopSubtree","outerPieces","rest","pref","mount","pathTop","stripBuilt","_dyn","_abs","_fk","_order","children","c","meta","rno","finalizeTree","xs","collectLeaves","into","pruneTree","rs","keepLeaf","recurse","ch","createSpaNnnRoutes","globRecord","options","logFn","rawKey","modIn","mwSeen","prev","ord","parse","stripped","base","existing","top","rootAbs","h","pTop","leavesKeep","flatLeaves","bucket","lf","ax","mode","strat","dupEntries","arr","srt","win","afterLeaves","formatSpaVerbose","leaves","l","wPath","wFile","ln","createNnnRoutes"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vue-nnn-router.cjs","sources":["../src/path.ts","../src/globUtils.ts","../src/spaRouteGenerator.ts","../src/createNnnRoutes.ts"],"sourcesContent":["export function normalizePath(path: string): string {\n const cleaned = path.replace(/\\/+/g, \"/\").replace(/\\/$/, \"\");\n if (cleaned === \"\" || cleaned === \"/\") return \"/\";\n return cleaned.startsWith(\"/\") ? cleaned : `/${cleaned}`;\n}\n\n/** Bỏ `routesRoot/` khỏi key đã qua simplifyGlobKey. */\nexport function stripRoutesRoot(normKey: string, routesRoot?: string): string {\n const k0 = normKey.replace(/\\\\/g, \"/\").split(\"?\")[0];\n let rRaw = routesRoot?.replace(/\\\\/g, \"/\").replace(/^\\.\\/+/, \"\") ?? \"\";\n rRaw = rRaw.replace(/^\\/+|\\/+$/g, \"\");\n if (!rRaw) return k0;\n const p = `${rRaw}/`;\n if (k0 === rRaw || k0 === `${rRaw}/`) return \"\";\n if (k0.startsWith(p)) return k0.slice(p.length);\n return k0;\n}\n\nexport function pathFromSegments(segments: string[], prefix?: string): string {\n const core = segments.length === 0 ? \"\" : `/${segments.join(\"/\")}`;\n const raw = [prefix?.replace(/^\\/|\\/$/g, \"\"), core.replace(/^\\//, \"\")]\n .filter(Boolean)\n .join(\"/\");\n const withSlash = raw.startsWith(\"/\") ? raw : `/${raw}`;\n return normalizePath(withSlash);\n}\n\nexport function isMiddlewareKey(key: string): boolean {\n const n = key.replace(/\\\\/g, \"/\").split(\"?\")[0];\n return /^(.+\\/)?_middleware\\.(ts|js)$/i.test(n);\n}\n\n/** Thư mục chứa `_middleware` (chuỗi rỗng = ngay trong `routesRoot`). */\nexport function middlewareDirFromNormKey(normKey: string): string {\n const n = normKey.replace(/\\\\/g, \"/\").split(\"?\")[0];\n const nested = /^(.*?)\\/_middleware\\.(ts|js)$/i.exec(n);\n if (nested) return nested[1]!;\n if (/^_middleware\\.(ts|js)$/i.test(n)) return \"\";\n return \"\";\n}\n\nexport function middlewareLogicalKey(prefixPath: string): string {\n return `${prefixPath}/_middleware`;\n}\n\nexport function isRedirectKey(key: string): boolean {\n const n = key.replace(/\\\\/g, \"/\").split(\"?\")[0];\n return /^(.+\\/)?_redirect\\.(ts|js)$/i.test(n);\n}\n\n/** Thư mục chứa `_redirect` (chuỗi rỗng = ngay trong `routesRoot`). */\nexport function redirectDirFromNormKey(normKey: string): string {\n const n = normKey.replace(/\\\\/g, \"/\").split(\"?\")[0];\n const nested = /^(.*?)\\/_redirect\\.(ts|js)$/i.exec(n);\n if (nested) return nested[1]!;\n if (/^_redirect\\.(ts|js)$/i.test(n)) return \"\";\n return \"\";\n}\n\n/** Đếm độ động (số `/:`) để ưu tiên route tĩnh trước. */\nexport function dynamicScore(pathPattern: string): number {\n return (pathPattern.match(/\\/:/g) || []).length;\n}\n","/** Dùng chung bởi createNnnRoutes và spaRoutes. */\n\nexport function simplifyGlobKey(key: string): string {\n let k = key.replace(/\\\\/g, \"/\").split(\"?\")[0];\n while (k.startsWith(\"./\")) k = k.slice(2);\n return k.replace(/^\\//, \"\");\n}\n\nexport function unwrapDefault(mod: unknown): unknown {\n if (mod && typeof mod === \"object\" && \"default\" in mod) {\n return (mod as { default: unknown }).default;\n }\n return mod;\n}\n","import type {\n NavigationGuardWithThis,\n RouteRecordRaw,\n} from \"vue-router\";\nimport type { CreateNnnRoutesOptions } from \"./types\";\nimport type { NnnRouteMeta } from \"./types\";\nimport {\n dynamicScore,\n isMiddlewareKey,\n isRedirectKey,\n middlewareDirFromNormKey,\n normalizePath,\n pathFromSegments,\n redirectDirFromNormKey,\n stripRoutesRoot,\n} from \"./path\";\nimport { simplifyGlobKey, unwrapDefault } from \"./globUtils\";\n\nconst PAGE_EXT = /\\.(vue|tsx|jsx|ts|js)$/i;\n\n/** Basename file layout (không phải segment URL). */\nconst LAYOUT_BASENAME = \"_layout\";\n\nfunction isLikelyRouteFileKey(sk: string): boolean {\n if (!PAGE_EXT.test(sk)) return false;\n if (/\\.(ts|js)$/i.test(sk) && /_middleware\\.(ts|js)$/i.test(sk)) return false;\n if (/\\.(ts|js)$/i.test(sk) && /_redirect\\.(ts|js)$/i.test(sk)) return false;\n return true;\n}\n\n/** Cảnh báo khi `routesRoot` không strip được `..` trong key (lỗi cấu hình thường gặp). */\nexport function warnIfRoutesRootLikelyWrong(\n rows: readonly { sk: string }[],\n routesRoot: string | undefined,\n silent: boolean | undefined\n): void {\n if (silent === true || !routesRoot?.trim()) return;\n const targets = rows.filter((r) => isLikelyRouteFileKey(r.sk));\n if (targets.length === 0) return;\n const bad = targets.filter((r) => /\\.\\.(?:\\/|$)/.test(r.sk)).length;\n if (bad >= 1) {\n console.warn(\n `[vue-nnn-router] ${bad}/${targets.length} route key(s) still contain \"..\" after routesRoot=\"${routesRoot}\". ` +\n `Set routesRoot to match the actual glob key prefix (e.g. pattern ../pages/** → routesRoot: \"../pages\").`,\n );\n }\n}\n\n/** Tên segment filesystem `[slug]` hoặc basename file `[slug].vue` → `:slug` trong URL. */\nexport function segmentUrlFromFs(fsSeg: string): string {\n const s = fsSeg.replace(/\\\\/g, \"/\");\n if (s.startsWith(\"[\") && s.endsWith(\"]\")) return `:${s.slice(1, -1)}`;\n return s;\n}\n\n/** Key glob đã strip `routesRoot`; trả pathname không có ext (vd `users/add`). */\nexport function pathNoExt(strippedSk: string): string {\n return strippedSk.replace(/\\\\/g, \"/\").split(\"?\")[0].replace(PAGE_EXT, \"\");\n}\n\n/** Tiền tố cascade `_middleware.ts` SPA. */\nexport function mwPrefixesForPathNoExt(pn: string): string[] {\n const parts = pn.split(\"/\").filter(Boolean);\n const dirParts = parts.length >= 1 ? parts.slice(0, -1) : [];\n const prefixes: string[] = [];\n for (let i = 0; i < dirParts.length; i++) {\n prefixes.push(dirParts.slice(0, i + 1).join(\"/\"));\n }\n if (prefixes.length === 0 || prefixes[0] !== \"\") prefixes.unshift(\"\");\n return prefixes;\n}\n\ntype PageRec = {\n basenameLc: string;\n rawKey: string;\n modIn: unknown;\n pathNoExt: string;\n order: number;\n};\n\ntype TrieNode = {\n layout?: { rawKey: string; modIn: unknown; pathNoExt: string };\n redirect?: { rawKey: string; modIn: unknown; pathNoExt: string };\n pages: Map<string, PageRec>;\n dirs: Map<string, TrieNode>;\n};\n\nfunction trieEmpty(): TrieNode {\n return { pages: new Map(), dirs: new Map() };\n}\n\nfunction trieEnsure(root: TrieNode, fsDirs: readonly string[]): TrieNode {\n let cur = root;\n for (const d of fsDirs) {\n if (!cur.dirs.has(d)) cur.dirs.set(d, trieEmpty());\n cur = cur.dirs.get(d)!;\n }\n return cur;\n}\n\ntype Cmp = Exclude<RouteRecordRaw[\"component\"], undefined | null>;\n\nfunction lazyTop(mod: unknown): boolean {\n return typeof mod === \"function\" && unwrapDefault(mod) === mod;\n}\n\nfunction toCmp(mod: unknown): Cmp {\n if (lazyTop(mod)) return mod as Cmp;\n const x = unwrapDefault(mod);\n if (typeof x === \"function\") return x as Cmp;\n if (typeof x === \"object\" || typeof x === \"string\") return x as Cmp;\n if (mod !== null && typeof mod === \"function\") return mod as Cmp;\n throw new Error(\n \"[vue-nnn-router] Invalid default export (expected a Vue component or lazy import).\"\n );\n}\n\nfunction routeMw(mod: unknown): unknown {\n return !lazyTop(mod) &&\n typeof mod === \"object\" &&\n mod !== null &&\n Object.prototype.hasOwnProperty.call(mod, \"middleware\")\n ? (mod as { middleware?: unknown }).middleware\n : undefined;\n}\n\nfunction normGuards(g: unknown): NavigationGuardWithThis<undefined>[] {\n if (g === undefined || g === null) return [];\n const a = Array.isArray(g) ? g : [g];\n return a.filter(\n (x): x is NavigationGuardWithThis<undefined> => typeof x === \"function\"\n );\n}\n\nfunction guards(\n pagePathNoExt: string,\n mwMap: Map<string, unknown>,\n pageMod?: unknown\n) {\n const out: NavigationGuardWithThis<undefined>[] = [];\n for (const p of mwPrefixesForPathNoExt(pagePathNoExt)) {\n const mw = mwMap.get(p);\n if (!mw) continue;\n out.push(...normGuards(unwrapDefault(mw)));\n }\n out.push(...normGuards(routeMw(pageMod)));\n return out;\n}\n\n/**\n * Path con (không có `/` đầu).\n * Basename có thể `index`, `add`, hoặc **`[id]`** → **`:id`** (giống segment thư mục).\n */\nfunction vueRel(fsRawPrefixes: readonly string[], basenameLc: string): string {\n const dirs = fsRawPrefixes.map(segmentUrlFromFs);\n const j = dirs.join(\"/\");\n if (basenameLc === \"index\") return j;\n const leafSeg = segmentUrlFromFs(basenameLc);\n return j ? `${j}/${leafSeg}` : leafSeg;\n}\n\n/** URL `:param`; `mount` + segment FS + basename (kể cả `[id].vue`). */\nfunction absPiecesJoined(\n mountUrlPieces: readonly string[],\n fsRawRel: readonly string[],\n basenameLc: string\n): string[] {\n const tail =\n basenameLc === \"index\" ? [] : [segmentUrlFromFs(basenameLc)];\n const middle = [...fsRawRel.map(segmentUrlFromFs)];\n return [...mountUrlPieces, ...middle, ...tail];\n}\n\nfunction absHref(pieces: readonly string[], pf: string): string {\n return normalizePath(pathFromSegments([...pieces], pf) || \"/\");\n}\n\nfunction cmpFs(a: string, b: string): number {\n const da = segmentUrlFromFs(a).includes(\":\");\n const db = segmentUrlFromFs(b).includes(\":\");\n if (da !== db) return da ? 1 : -1;\n return a.localeCompare(b);\n}\n\ntype Built = RouteRecordRaw & {\n _dyn: number;\n _abs: string;\n _fk: string;\n _order: number;\n};\n\nfunction nm(abs: string): string {\n if (abs === \"/\" || abs === \"\") return \"home\";\n return (\n abs\n .replace(/^\\/+|\\/+$/g, \"\")\n .replace(/\\//g, \"-\")\n .replace(/:/g, \"\") || \"route\"\n );\n}\n\nfunction makeLeaf(\n routePathPattern: string,\n absDedupe: string,\n pg: PageRec,\n mwMap: Map<string, unknown>,\n sq: { seq: number }\n): Built {\n const gs = guards(pg.pathNoExt, mwMap, pg.modIn);\n const be =\n gs.length === 0 ? undefined : gs.length === 1 ? gs[0]! : gs;\n return {\n path: routePathPattern,\n component: toCmp(pg.modIn),\n beforeEnter: be,\n meta: { nnnFile: pg.rawKey } satisfies NnnRouteMeta,\n name: nm(absDedupe),\n _dyn: dynamicScore(absDedupe),\n _abs: absDedupe,\n _fk: pg.rawKey,\n _order: sq.seq++,\n };\n}\n\ntype Cfg = {\n mwMap: Map<string, unknown>;\n pf: string;\n sq: { seq: number };\n silent?: boolean;\n};\n\nfunction hasIndexPage(node: TrieNode): boolean {\n return node.pages.has(\"index\");\n}\n\n/** `export default` trong `_redirect.ts`: URL tuyệt đối (`/users/add`) hoặc tương đối (`add`). */\nfunction resolveRedirectTarget(\n modIn: unknown,\n mountPieces: readonly string[],\n pf: string,\n): string | null {\n const raw = unwrapDefault(modIn);\n if (typeof raw !== \"string\") return null;\n const t = raw.trim();\n if (!t) return null;\n if (t.startsWith(\"/\")) return normalizePath(t);\n const pieces = [...mountPieces, ...t.split(\"/\").filter(Boolean)];\n return absHref(pieces, pf);\n}\n\nfunction injectLayoutRedirect(\n acc: Built[],\n node: TrieNode,\n mountPieces: readonly string[],\n cfg: Cfg,\n): void {\n if (hasIndexPage(node) || !node.redirect) return;\n\n const layoutAbs = absHref(mountPieces, cfg.pf);\n const target = resolveRedirectTarget(node.redirect.modIn, mountPieces, cfg.pf);\n if (!target) {\n if (cfg.silent !== true) {\n console.warn(\n `[vue-nnn-router] Invalid _redirect in \"${node.redirect.rawKey}\" (expected export default string).`,\n );\n }\n return;\n }\n\n acc.unshift({\n path: \"\",\n redirect: target,\n name: `${nm(layoutAbs)}-redirect`,\n meta: { nnnFile: node.redirect.rawKey } satisfies NnnRouteMeta,\n _dyn: 0,\n _abs: layoutAbs,\n _fk: node.redirect.rawKey,\n _order: cfg.sq.seq++,\n } as Built);\n}\n\nfunction childrenInsideLayout(node: TrieNode, mountPieces: readonly string[], cfg: Cfg): Built[] {\n const acc: Built[] = [];\n\n for (const [, pg] of [...node.pages.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {\n if (pg.basenameLc === LAYOUT_BASENAME) continue;\n const pieces = absPiecesJoined(mountPieces, [], pg.basenameLc);\n const ah = absHref(pieces, cfg.pf);\n acc.push(makeLeaf(vueRel([], pg.basenameLc), ah, pg, cfg.mwMap, cfg.sq));\n }\n\n for (const [fs, cn] of [...node.dirs.entries()].sort((a, b) => cmpFs(a[0], b[0]))) {\n const segUrl = segmentUrlFromFs(fs);\n if (cn.layout) {\n const nextMount = [...mountPieces, segUrl];\n const absLay = absHref(nextMount, cfg.pf);\n const nested = childrenInsideLayout(cn, nextMount, cfg);\n acc.push({\n path: segUrl,\n component: toCmp(cn.layout!.modIn),\n children: nested,\n name: `${nm(absLay)}-layout`,\n meta: {},\n _dyn: dynamicScore(absLay),\n _abs: absLay,\n _fk: cn.layout!.rawKey,\n _order: cfg.sq.seq++,\n } as Built);\n } else {\n acc.push(...flattenNoLay(cn, mountPieces, [fs], cfg));\n }\n }\n\n injectLayoutRedirect(acc, node, mountPieces, cfg);\n\n return acc.sort((x, y) =>\n x._dyn !== y._dyn ? x._dyn - y._dyn : String(x.path).localeCompare(String(y.path))\n );\n}\n\nfunction flattenNoLay(\n node: TrieNode,\n mountPieces: readonly string[],\n fsRelRaw: readonly string[],\n cfg: Cfg,\n): Built[] {\n const acc: Built[] = [];\n\n for (const [, pg] of [...node.pages.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {\n if (pg.basenameLc === LAYOUT_BASENAME) continue;\n const pieces = absPiecesJoined(mountPieces, fsRelRaw, pg.basenameLc);\n const ah = absHref([...pieces], cfg.pf);\n acc.push(makeLeaf(vueRel(fsRelRaw, pg.basenameLc), ah, pg, cfg.mwMap, cfg.sq));\n }\n\n for (const [fs, cn] of [...node.dirs.entries()].sort((a, b) => cmpFs(a[0], b[0]))) {\n if (cn.layout) {\n const vrSeg = vueRel(fsRelRaw, fs);\n const mp = [...mountPieces, ...fsRelRaw.map(segmentUrlFromFs), segmentUrlFromFs(fs)];\n const ah = absHref(mp, cfg.pf);\n acc.push({\n path: vrSeg,\n component: toCmp(cn.layout!.modIn),\n children: childrenInsideLayout(cn, mp, cfg),\n name: `${nm(ah)}-layout`,\n meta: {},\n _dyn: dynamicScore(ah),\n _abs: ah,\n _fk: cn.layout!.rawKey,\n _order: cfg.sq.seq++,\n } as Built);\n } else {\n acc.push(...flattenNoLay(cn, mountPieces, [...fsRelRaw, fs], cfg));\n }\n }\n\n return acc;\n}\n\nfunction emitFlatTopSubtree(node: TrieNode, outerPieces: readonly string[], cfg: Cfg): Built[] {\n const acc: Built[] = [];\n\n for (const [, pg] of [...node.pages.entries()].sort((a, b) => a[0].localeCompare(b[0]))) {\n if (pg.basenameLc === LAYOUT_BASENAME) continue;\n const pieces = [...outerPieces.map(segmentUrlFromFs)];\n const rest =\n pg.basenameLc === \"index\" ? [] : [segmentUrlFromFs(pg.basenameLc)];\n const ah = absHref([...pieces, ...rest], cfg.pf);\n acc.push(makeLeaf(ah, ah, pg, cfg.mwMap, cfg.sq));\n }\n\n for (const [fs, cn] of [...node.dirs.entries()].sort((a, b) => cmpFs(a[0], b[0]))) {\n const pref = [...outerPieces, fs];\n if (cn.layout) {\n const mount = pref.map(segmentUrlFromFs);\n const pathTop = normalizePath(absHref(mount, cfg.pf));\n acc.push({\n path: pathTop,\n component: toCmp(cn.layout!.modIn),\n children: childrenInsideLayout(cn, mount, cfg),\n name: `${nm(pathTop)}-layout`,\n meta: {},\n _dyn: dynamicScore(pathTop),\n _abs: pathTop,\n _fk: cn.layout!.rawKey,\n _order: cfg.sq.seq++,\n } as Built);\n } else acc.push(...emitFlatTopSubtree(cn, pref, cfg));\n }\n\n return acc;\n}\n\nfunction stripBuilt(r: Built): RouteRecordRaw {\n const { _dyn, _abs, _fk, _order, children, ...rest } = r;\n void _dyn;\n void _abs;\n void _fk;\n void _order;\n if (children && children.length) {\n return {\n ...rest,\n children: (children as Built[]).map((c) => stripBuilt(c)),\n } as RouteRecordRaw;\n }\n const { meta, ...rno } = rest;\n if (meta && Object.keys(meta).length === 0) {\n delete (rno as { meta?: unknown }).meta;\n return rno as RouteRecordRaw;\n }\n return rest as RouteRecordRaw;\n}\n\nfunction finalizeTree(xs: Built[]): RouteRecordRaw[] {\n return xs.map((r) => stripBuilt(r));\n}\n\nfunction collectLeaves(xs: Built[], into: Built[]): void {\n for (const r of xs) {\n if (r.children && r.children.length)\n collectLeaves(r.children as Built[], into);\n else into.push(r);\n }\n}\n\nfunction pruneTree(rs: Built[], keepLeaf: Map<string, Built>): Built[] {\n const recurse = (r: Built): Built | null => {\n if (r.children && r.children.length) {\n const ch = (r.children as Built[]).map(recurse).filter(Boolean) as Built[];\n return ch.length ? ({ ...r, children: ch } as Built) : null;\n }\n return keepLeaf.get(r._abs) === r ? r : null;\n };\n return rs.map(recurse).filter(Boolean) as Built[];\n}\n\n/** Public: sinh RouteRecordRaw SPA. */\nexport function createSpaNnnRoutes(\n globRecord: Record<string, unknown>,\n options: CreateNnnRoutesOptions = {},\n): RouteRecordRaw[] {\n const pf = options.prefix?.replace(/^\\/+|\\/+$/g, \"\") ?? \"\";\n const logFn =\n options.silent !== true\n ? (options.logger ?? ((...a: unknown[]) => console.log(...a)))\n : undefined;\n\n type Row = { rawKey: string; sk: string; modIn: unknown };\n const rows: Row[] = Object.entries(globRecord).map(([rawKey, modIn]) => ({\n rawKey,\n sk: stripRoutesRoot(simplifyGlobKey(rawKey), options.routesRoot),\n modIn,\n }));\n\n warnIfRoutesRootLikelyWrong(rows, options.routesRoot, options.silent);\n\n const mwMap = new Map<string, unknown>();\n const mwSeen = new Map<string, string>();\n for (const { rawKey, sk, modIn } of rows) {\n if (!isMiddlewareKey(sk)) continue;\n const d = middlewareDirFromNormKey(sk);\n const prev = mwSeen.get(d);\n if (\n prev !== undefined &&\n prev !== rawKey &&\n options.silent !== true\n ) {\n console.warn(`[vue-nnn-router] Duplicate middleware for \"${d || \"/\"}\".`);\n }\n mwSeen.set(d, rawKey);\n mwMap.set(d, modIn);\n }\n\n const root = trieEmpty();\n let ord = 0;\n\n const parse = (\n stripped: string,\n ): { fsDirs: string[]; base: string } | null => {\n const pn = pathNoExt(stripped);\n const parts = pn.split(\"/\").filter(Boolean);\n if (!parts.length) return null;\n return {\n fsDirs: parts.slice(0, -1),\n base: parts[parts.length - 1]!.toLowerCase(),\n };\n };\n\n for (const { rawKey, sk, modIn } of rows) {\n if (/\\.(ts|js)$/i.test(sk) && /_middleware\\.(ts|js)$/i.test(sk)) continue;\n if (/\\.(ts|js)$/i.test(sk) && /_redirect\\.(ts|js)$/i.test(sk)) continue;\n\n const p = parse(sk);\n if (!p) continue;\n if (!PAGE_EXT.test(sk)) continue;\n\n const { fsDirs, base } = p;\n const pn = pathNoExt(sk);\n\n if (base === LAYOUT_BASENAME) {\n const n = trieEnsure(root, fsDirs);\n if (\n n.layout !== undefined &&\n n.layout.rawKey !== rawKey &&\n options.silent !== true\n ) {\n console.warn(\n `[vue-nnn-router] Duplicate _layout.vue in folder, keeping \"${n.layout.rawKey}\".`,\n );\n } else if (n.layout === undefined) {\n n.layout = { rawKey, modIn, pathNoExt: pn };\n }\n continue;\n }\n\n const n = trieEnsure(root, fsDirs);\n const existing = n.pages.get(base);\n if (existing && existing.rawKey !== rawKey && options.silent !== true) {\n console.warn(`[vue-nnn-router] Duplicate basename in folder: \"${base}\".`);\n continue;\n }\n if (!existing) {\n n.pages.set(base, {\n basenameLc: base,\n rawKey,\n modIn,\n pathNoExt: pn,\n order: ord++,\n });\n }\n }\n\n const redirectSeen = new Map<string, string>();\n for (const { rawKey, sk, modIn } of rows) {\n if (!isRedirectKey(sk)) continue;\n const dir = redirectDirFromNormKey(sk);\n const fsDirs = dir ? dir.split(\"/\").filter(Boolean) : [];\n const n = trieEnsure(root, fsDirs);\n const prev = redirectSeen.get(dir);\n if (prev !== undefined && prev !== rawKey && options.silent !== true) {\n console.warn(`[vue-nnn-router] Duplicate _redirect for \"${dir || \"/\"}\".`);\n }\n redirectSeen.set(dir, rawKey);\n if (\n n.redirect !== undefined &&\n n.redirect.rawKey !== rawKey &&\n options.silent !== true\n ) {\n console.warn(\n `[vue-nnn-router] Duplicate _redirect in folder, keeping \"${n.redirect.rawKey}\".`,\n );\n } else if (n.redirect === undefined) {\n n.redirect = { rawKey, modIn, pathNoExt: pathNoExt(sk) };\n }\n if (!n.layout && options.silent !== true) {\n console.warn(\n `[vue-nnn-router] _redirect \"${rawKey}\" has no _layout in the same folder — skipped when building routes.`,\n );\n }\n }\n\n const cfg: Cfg = { mwMap, pf: pf, sq: { seq: 0 }, silent: options.silent };\n\n let top: Built[] = [];\n\n if (root.layout) {\n const rootAbs = normalizePath(pathFromSegments([], pf) || \"/\");\n top = [\n {\n path: rootAbs,\n component: toCmp(root.layout.modIn),\n children: childrenInsideLayout(root, [], cfg),\n name: \"root-layout\",\n _dyn: 0,\n _abs: rootAbs,\n _fk: root.layout.rawKey,\n _order: cfg.sq.seq++,\n } as Built,\n ];\n } else {\n const acc: Built[] = [];\n for (const [, pg] of [...root.pages.entries()].sort((a, b) =>\n a[0].localeCompare(b[0]),\n )) {\n if (pg.basenameLc !== LAYOUT_BASENAME) {\n const h =\n pg.basenameLc === \"index\"\n ? absHref([], pf)\n : absHref([segmentUrlFromFs(pg.basenameLc)], pf);\n acc.push(makeLeaf(h, h, pg, mwMap, cfg.sq));\n }\n }\n\n for (const [fs, cn] of [...root.dirs.entries()].sort((a, b) =>\n cmpFs(a[0], b[0]),\n )) {\n if (cn.layout) {\n const mount = [segmentUrlFromFs(fs)];\n const pTop = normalizePath(absHref(mount, pf));\n acc.push({\n path: pTop,\n component: toCmp(cn.layout!.modIn),\n children: childrenInsideLayout(cn, mount, cfg),\n name: `${nm(pTop)}-layout`,\n meta: {},\n _dyn: dynamicScore(pTop),\n _abs: pTop,\n _fk: cn.layout!.rawKey,\n _order: cfg.sq.seq++,\n } as Built);\n } else acc.push(...emitFlatTopSubtree(cn, [fs], cfg));\n }\n top = acc;\n }\n\n const leavesKeep = new Map<string, Built>();\n const flatLeaves: Built[] = [];\n collectLeaves(top, flatLeaves);\n const bucket = new Map<string, Built[]>();\n for (const lf of flatLeaves) {\n const ax = lf._abs;\n const b = bucket.get(ax);\n if (b) b.push(lf);\n else bucket.set(ax, [lf]);\n }\n const mode = options.onDuplicate === \"last-wins\" ? \"last\" : \"first\";\n const silent = options.silent === true;\n const strat = options.onDuplicate;\n const dupEntries = [...bucket.entries()].filter(([, a]) => a.length > 1);\n if (dupEntries.length && !silent && typeof strat !== \"function\") {\n for (const [p, arr] of dupEntries) {\n console.warn(\n `[vue-nnn-router] Duplicate URL \"${p}\": ${arr.map((x) => x._fk).join(\", \")}`,\n );\n }\n }\n if (typeof strat === \"function\") {\n for (const [p, arr] of dupEntries) strat(p, arr.map((x) => x._fk));\n }\n\n for (const [, arr] of bucket) {\n const srt = [...arr].sort((a, b) => a._order - b._order);\n const win = mode === \"last\" ? srt[srt.length - 1]! : srt[0]!;\n leavesKeep.set(win._abs, win);\n }\n\n top = pruneTree(top, leavesKeep);\n\n top = top.sort((a, b) => String(a.path).localeCompare(String(b.path)));\n\n if (options.verbose === true && logFn) {\n const afterLeaves: Built[] = [];\n collectLeaves(top, afterLeaves);\n logFn(formatSpaVerbose(afterLeaves));\n }\n\n return finalizeTree(top);\n}\n\nfunction formatSpaVerbose(leaves: Built[]): string {\n const rows = leaves.map((l) => ({\n Path: l._abs,\n File: l._fk,\n }));\n if (!rows.length) return \"\";\n const wPath = Math.max(4, ...rows.map((x) => x.Path.length));\n const wFile = Math.max(4, ...rows.map((x) => x.File.length));\n const ln = \"-\".repeat(wPath + wFile + 3);\n const h = `Path`.padEnd(wPath) + \" \" + `File`.padEnd(wFile);\n const b = rows.map((r) => r.Path.padEnd(wPath) + \" \" + r.File.padEnd(wFile)).join(\"\\n\");\n return [\"[vue-nnn-router]\", ln, h, ln, b, ln].join(\"\\n\");\n}\n","import type { RouteRecordRaw } from \"vue-router\";\nimport type { CreateNnnRoutesOptions } from \"./types\";\nimport { createSpaNnnRoutes } from \"./spaRoutes\";\n\nexport { simplifyGlobKey } from \"./globUtils\";\n\n/**\n * Từ map `import.meta.glob` sinh `RouteRecordRaw[]` — quy ước SPA: `index.vue`, `_layout.vue`, `_redirect.ts`, `[param]`.\n */\nexport function createNnnRoutes(\n globRecord: Record<string, unknown>,\n options: CreateNnnRoutesOptions = {}\n): RouteRecordRaw[] {\n return createSpaNnnRoutes(globRecord, options);\n}\n"],"names":["normalizePath","path","cleaned","stripRoutesRoot","normKey","routesRoot","k0","rRaw","p","pathFromSegments","segments","prefix","core","raw","withSlash","isMiddlewareKey","key","n","middlewareDirFromNormKey","nested","middlewareLogicalKey","prefixPath","isRedirectKey","redirectDirFromNormKey","dynamicScore","pathPattern","simplifyGlobKey","k","unwrapDefault","mod","PAGE_EXT","LAYOUT_BASENAME","isLikelyRouteFileKey","sk","warnIfRoutesRootLikelyWrong","rows","silent","targets","r","bad","segmentUrlFromFs","fsSeg","s","pathNoExt","strippedSk","mwPrefixesForPathNoExt","pn","parts","dirParts","prefixes","i","trieEmpty","trieEnsure","root","fsDirs","cur","d","lazyTop","toCmp","x","routeMw","normGuards","g","guards","pagePathNoExt","mwMap","pageMod","out","mw","vueRel","fsRawPrefixes","basenameLc","j","leafSeg","absPiecesJoined","mountUrlPieces","fsRawRel","tail","middle","absHref","pieces","pf","cmpFs","a","b","da","db","nm","abs","makeLeaf","routePathPattern","absDedupe","pg","sq","gs","be","hasIndexPage","node","resolveRedirectTarget","modIn","mountPieces","t","injectLayoutRedirect","acc","cfg","layoutAbs","target","childrenInsideLayout","ah","fs","cn","segUrl","nextMount","absLay","flattenNoLay","y","fsRelRaw","vrSeg","mp","emitFlatTopSubtree","outerPieces","rest","pref","mount","pathTop","stripBuilt","_dyn","_abs","_fk","_order","children","c","meta","rno","finalizeTree","xs","collectLeaves","into","pruneTree","rs","keepLeaf","recurse","ch","createSpaNnnRoutes","globRecord","options","logFn","rawKey","mwSeen","prev","ord","parse","stripped","base","existing","redirectSeen","dir","top","rootAbs","h","pTop","leavesKeep","flatLeaves","bucket","lf","ax","mode","strat","dupEntries","arr","srt","win","afterLeaves","formatSpaVerbose","leaves","l","wPath","wFile","ln","createNnnRoutes"],"mappings":"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"}
|