@yak-io/nextjs 0.3.0 → 0.3.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/README.md +40 -7
- package/dist/cli/generate-manifest.js +19 -7
- package/dist/client/YakProvider.d.ts +1 -1
- package/dist/client/YakProvider.d.ts.map +1 -1
- package/dist/server/createNextYakHandler.d.ts.map +1 -1
- package/dist/server/createNextYakHandler.js +14 -15
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/route-manifest-adapter.d.ts.map +1 -1
- package/dist/server/scan-routes.d.ts.map +1 -1
- package/dist/server/scan-routes.js +17 -5
- package/package.json +12 -10
package/README.md
CHANGED
|
@@ -46,7 +46,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
46
46
|
### 2. Unified API route
|
|
47
47
|
|
|
48
48
|
```ts
|
|
49
|
-
// app/api/yak/[...yak]/route.ts
|
|
49
|
+
// app/api/yak/[[...yak]]/route.ts
|
|
50
50
|
import { createNextYakHandler } from "@yak-io/nextjs/server";
|
|
51
51
|
|
|
52
52
|
export const { GET, POST } = createNextYakHandler({
|
|
@@ -178,11 +178,13 @@ yak-nextjs generate-manifest --pages-dir ./src/pages
|
|
|
178
178
|
yak-nextjs generate-manifest --app-dir ./app --output ./src/generated/routes.ts
|
|
179
179
|
```
|
|
180
180
|
|
|
181
|
-
## Route Manifest for Production
|
|
181
|
+
## Route Manifest for Production (Required)
|
|
182
182
|
|
|
183
|
-
|
|
183
|
+
> **Important:** This setup is required for production deployments. Skip this only if you are providing your own custom routes via the `routes` or `getRoutes` options.
|
|
184
184
|
|
|
185
|
-
|
|
185
|
+
During local development, routes are scanned directly from the filesystem. However, when you build your Next.js app for production, only the compiled `.next` output is included—source files like `./src/app` are not present at runtime, causing route discovery to fail.
|
|
186
|
+
|
|
187
|
+
### Required setup
|
|
186
188
|
|
|
187
189
|
1. Add a `prebuild` script to generate the manifest before Next.js builds:
|
|
188
190
|
|
|
@@ -195,18 +197,49 @@ During local development, routes are scanned directly from the filesystem—no s
|
|
|
195
197
|
}
|
|
196
198
|
```
|
|
197
199
|
|
|
198
|
-
|
|
200
|
+
The CLI auto-detects your directory structure. If your project uses non-standard paths, specify them explicitly:
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"scripts": {
|
|
205
|
+
"prebuild": "yak-nextjs generate-manifest --app-dir ./app --output ./app/yak.routes.ts",
|
|
206
|
+
"build": "next build"
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
| Project structure | Command |
|
|
212
|
+
|-------------------|-------------------------------------------------------|
|
|
213
|
+
| `src/app/` (default) | `yak-nextjs generate-manifest` |
|
|
214
|
+
| `app/` | `yak-nextjs generate-manifest --app-dir ./app --output ./app/yak.routes.ts` |
|
|
215
|
+
| `src/app/` + `src/pages/` | `yak-nextjs generate-manifest --pages-dir ./src/pages` |
|
|
216
|
+
| `app/` + `pages/` | `yak-nextjs generate-manifest --app-dir ./app --pages-dir ./pages --output ./app/yak.routes.ts` |
|
|
217
|
+
|
|
218
|
+
2. Add the generated file to `.gitignore`:
|
|
219
|
+
|
|
220
|
+
```gitignore
|
|
221
|
+
# Generated route manifest (use the path matching your --output)
|
|
222
|
+
src/yak.routes.ts
|
|
223
|
+
# or for root app/ directory:
|
|
224
|
+
# app/yak.routes.ts
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
3. Use the route manifest adapter in your handler:
|
|
199
228
|
|
|
200
229
|
```ts
|
|
201
|
-
// app/api/yak/[...yak]/route.ts
|
|
230
|
+
// app/api/yak/[[...yak]]/route.ts
|
|
202
231
|
import { createNextYakHandler, createRouteManifestAdapter } from "@yak-io/nextjs/server";
|
|
203
|
-
import { routes } from "@/yak.routes";
|
|
232
|
+
import { routes } from "@/yak.routes"; // Adjust path based on your tsconfig paths
|
|
204
233
|
|
|
205
234
|
export const { GET, POST } = createNextYakHandler({
|
|
206
235
|
routes: createRouteManifestAdapter({ routes }),
|
|
207
236
|
});
|
|
208
237
|
```
|
|
209
238
|
|
|
239
|
+
> **Note:** The import path depends on your `tsconfig.json` paths. Common configurations:
|
|
240
|
+
> - `src/yak.routes.ts` → `@/yak.routes` (when `@/*` maps to `./src/*`)
|
|
241
|
+
> - `app/yak.routes.ts` → `@/yak.routes` (when `@/*` maps to `./app/*`) or `../../../yak.routes`
|
|
242
|
+
|
|
210
243
|
The generated TypeScript module is imported directly, ensuring it's bundled with your serverless function automatically.
|
|
211
244
|
|
|
212
245
|
### Route filtering
|
|
@@ -70,7 +70,10 @@ function isRequiredCatchAll(segment) {
|
|
|
70
70
|
* Check if a path segment is a dynamic segment (e.g., [id])
|
|
71
71
|
*/
|
|
72
72
|
function isDynamicSegment(segment) {
|
|
73
|
-
return segment.startsWith("[") &&
|
|
73
|
+
return (segment.startsWith("[") &&
|
|
74
|
+
segment.endsWith("]") &&
|
|
75
|
+
!isOptionalCatchAll(segment) &&
|
|
76
|
+
!isRequiredCatchAll(segment));
|
|
74
77
|
}
|
|
75
78
|
/**
|
|
76
79
|
* Normalize a dynamic segment for display
|
|
@@ -88,8 +91,8 @@ function normalizeRoutePath(segments) {
|
|
|
88
91
|
// Filter out route groups - they don't appear in URLs
|
|
89
92
|
// Filter out optional catch-all segments - they match the base path
|
|
90
93
|
const urlSegments = segments
|
|
91
|
-
.filter(seg => !isRouteGroup(seg) && !isOptionalCatchAll(seg))
|
|
92
|
-
.map(seg => {
|
|
94
|
+
.filter((seg) => !isRouteGroup(seg) && !isOptionalCatchAll(seg))
|
|
95
|
+
.map((seg) => {
|
|
93
96
|
if (isDynamicSegment(seg)) {
|
|
94
97
|
return normalizeDynamicSegment(seg);
|
|
95
98
|
}
|
|
@@ -102,7 +105,7 @@ function normalizeRoutePath(segments) {
|
|
|
102
105
|
});
|
|
103
106
|
if (urlSegments.length === 0)
|
|
104
107
|
return "/";
|
|
105
|
-
return
|
|
108
|
+
return `/${urlSegments.join("/")}`;
|
|
106
109
|
}
|
|
107
110
|
/**
|
|
108
111
|
* Check if file is a page file
|
|
@@ -146,10 +149,19 @@ function scanDirectory(dirPath, segments = []) {
|
|
|
146
149
|
* File discovery helpers for legacy `pages/` directories
|
|
147
150
|
*/
|
|
148
151
|
const VALID_PAGE_EXTENSIONS = new Set([".js", ".jsx", ".ts", ".tsx", ".md", ".mdx"]);
|
|
149
|
-
const SPECIAL_PAGE_FILENAMES = new Set([
|
|
152
|
+
const SPECIAL_PAGE_FILENAMES = new Set([
|
|
153
|
+
"_app",
|
|
154
|
+
"_document",
|
|
155
|
+
"_error",
|
|
156
|
+
"404",
|
|
157
|
+
"500",
|
|
158
|
+
"middleware",
|
|
159
|
+
"_middleware",
|
|
160
|
+
]);
|
|
150
161
|
/**
|
|
151
162
|
* Recursively scan a pages directory for Next.js page routes
|
|
152
163
|
*/
|
|
164
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: recursive directory scanner with multiple file type checks
|
|
153
165
|
function scanPagesDirectory(dirPath, segments = []) {
|
|
154
166
|
const routes = [];
|
|
155
167
|
try {
|
|
@@ -200,7 +212,7 @@ function buildPagesSegments(segments, baseName) {
|
|
|
200
212
|
function parseArgs() {
|
|
201
213
|
const args = process.argv.slice(2);
|
|
202
214
|
let appDir = "./src/app";
|
|
203
|
-
let pagesDir
|
|
215
|
+
let pagesDir;
|
|
204
216
|
// Default to ./src/yak.routes.ts - TypeScript module that gets bundled
|
|
205
217
|
let output = "./src/yak.routes.ts";
|
|
206
218
|
let help = false;
|
|
@@ -305,7 +317,7 @@ function main() {
|
|
|
305
317
|
process.exit(1);
|
|
306
318
|
}
|
|
307
319
|
// Deduplicate routes by path (app router takes precedence)
|
|
308
|
-
const uniqueRoutes = Array.from(new Map(routes.map(r => [r.path, r])).values()).sort((a, b) => a.path.localeCompare(b.path));
|
|
320
|
+
const uniqueRoutes = Array.from(new Map(routes.map((r) => [r.path, r])).values()).sort((a, b) => a.path.localeCompare(b.path));
|
|
309
321
|
const outputPath = path.resolve(process.cwd(), output);
|
|
310
322
|
// Ensure output directory exists
|
|
311
323
|
const outputDir = path.dirname(outputPath);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"YakProvider.d.ts","sourceRoot":"","sources":["../../src/client/YakProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"YakProvider.d.ts","sourceRoot":"","sources":["../../src/client/YakProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAEL,KAAK,gBAAgB,IAAI,oBAAoB,EAC9C,MAAM,eAAe,CAAC;AAEvB,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAkCpD;;;;;;;;;GASG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,KAAK,CAAC,GAAG,CAAC,OAAO,CA2BtE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNextYakHandler.d.ts","sourceRoot":"","sources":["../../src/server/createNextYakHandler.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,aAAa,EACb,YAAY,EACZ,YAAY,EACb,MAAM,2BAA2B,CAAC;AAkBnC;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAgB7E;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"createNextYakHandler.d.ts","sourceRoot":"","sources":["../../src/server/createNextYakHandler.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,aAAa,EACb,YAAY,EACZ,YAAY,EACb,MAAM,2BAA2B,CAAC;AAkBnC;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAgB7E;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAa7D;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACvC,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IACvC,WAAW,CAAC,EAAE,YAAY,CAAC;CAC5B,CAAC;AAEF;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB;;;EAKhE;AA0FD,MAAM,MAAM,0BAA0B,GAAG;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC;IACvC,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;CACxC,CAAC;AAEF,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,0BAA0B,wCAK5E;AAED,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IACvC,WAAW,EAAE,YAAY,CAAC;CAC3B,CAAC;AAEF,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,yBAAyB,uCAY1E"}
|
|
@@ -51,14 +51,12 @@ export function loadRouteManifest(manifestPath) {
|
|
|
51
51
|
export function loadRoutes(manifestPath) {
|
|
52
52
|
const manifest = loadRouteManifest(manifestPath);
|
|
53
53
|
if (!manifest) {
|
|
54
|
-
const pathsChecked = manifestPath
|
|
55
|
-
? manifestPath
|
|
56
|
-
: [...DEFAULT_MANIFEST_PATHS].join(", ");
|
|
54
|
+
const pathsChecked = manifestPath ? manifestPath : [...DEFAULT_MANIFEST_PATHS].join(", ");
|
|
57
55
|
throw new Error(`Route manifest not found. Checked: ${pathsChecked}\n\n` +
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
56
|
+
"In production environments (like Vercel), route scanning requires a pre-built manifest.\n" +
|
|
57
|
+
"Generate it at build time by adding to your build script:\n\n" +
|
|
58
|
+
" yak-nextjs generate-manifest\n\n" +
|
|
59
|
+
"Or provide routes explicitly in your handler configuration.");
|
|
62
60
|
}
|
|
63
61
|
return manifest.routes;
|
|
64
62
|
}
|
|
@@ -89,12 +87,12 @@ async function tryLoadRoutes(appDir) {
|
|
|
89
87
|
return manifest.routes;
|
|
90
88
|
}
|
|
91
89
|
// Neither source nor manifest available - provide helpful error
|
|
92
|
-
throw new Error(
|
|
93
|
-
|
|
90
|
+
throw new Error("Route manifest not found.\n\n" +
|
|
91
|
+
"Generate the manifest at build time by adding to package.json:\n" +
|
|
94
92
|
` "prebuild": "yak-nextjs generate-manifest"\n\n` +
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
93
|
+
"The manifest will be created at ./src/yak-routes-manifest.json and automatically\n" +
|
|
94
|
+
"bundled with your serverless function.\n\n" +
|
|
95
|
+
"Alternatively, provide routes explicitly:\n" +
|
|
98
96
|
` createNextYakHandler({ routes: [{ path: "/", title: "Home" }] })`);
|
|
99
97
|
}
|
|
100
98
|
function resolveRouteSources(config) {
|
|
@@ -114,12 +112,12 @@ function applyRouteFilters(routes, filter) {
|
|
|
114
112
|
return routes;
|
|
115
113
|
}
|
|
116
114
|
const { include = [], exclude = [] } = filter;
|
|
117
|
-
return routes.filter(route => {
|
|
115
|
+
return routes.filter((route) => {
|
|
118
116
|
const path = route.path;
|
|
119
|
-
if (include.length > 0 && !include.some(pattern => matches(pattern, path))) {
|
|
117
|
+
if (include.length > 0 && !include.some((pattern) => matches(pattern, path))) {
|
|
120
118
|
return false;
|
|
121
119
|
}
|
|
122
|
-
if (exclude.some(pattern => matches(pattern, path))) {
|
|
120
|
+
if (exclude.some((pattern) => matches(pattern, path))) {
|
|
123
121
|
return false;
|
|
124
122
|
}
|
|
125
123
|
return true;
|
|
@@ -155,6 +153,7 @@ export function createNextYakToolsHandler(config) {
|
|
|
155
153
|
throw new Error("createNextYakToolsHandler requires either 'tools' or 'getTools'");
|
|
156
154
|
}
|
|
157
155
|
const toolSource = config.tools ?? {
|
|
156
|
+
// getTools is guaranteed to be defined here since we check above
|
|
158
157
|
getTools: config.getTools,
|
|
159
158
|
executeTool: config.executeTool,
|
|
160
159
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,OAAO,EACL,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,iBAAiB,EACjB,UAAU,GACX,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACV,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,kBAAkB,GACnB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,YAAY,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAE9E,YAAY,EACV,YAAY,EACZ,eAAe,EACf,cAAc,EACd,cAAc,EACd,YAAY,EACZ,SAAS,EACT,aAAa,EACb,UAAU,GACX,MAAM,2BAA2B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-manifest-adapter.d.ts","sourceRoot":"","sources":["../../src/server/route-manifest-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExE;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC;;;OAGG;IACH,MAAM,EAAE,SAAS,EAAE,CAAC;IAEpB;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B,CAAC;
|
|
1
|
+
{"version":3,"file":"route-manifest-adapter.d.ts","sourceRoot":"","sources":["../../src/server/route-manifest-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAExE;;GAEG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC;;;OAGG;IACH,MAAM,EAAE,SAAS,EAAE,CAAC;IAEpB;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IAEZ;;;;;;;;;;OAUG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IAEzB;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B,CAAC;AA6CF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,0BAA0B,GAAG,WAAW,CAS1F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan-routes.d.ts","sourceRoot":"","sources":["../../src/server/scan-routes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;CACjC,CAAC;
|
|
1
|
+
{"version":3,"file":"scan-routes.d.ts","sourceRoot":"","sources":["../../src/server/scan-routes.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;CACjC,CAAC;AAsOF;;GAEG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,SAAS,EAAE,CActF"}
|
|
@@ -55,7 +55,10 @@ function isRequiredCatchAll(segment) {
|
|
|
55
55
|
* Check if a path segment is a dynamic segment (e.g., [id])
|
|
56
56
|
*/
|
|
57
57
|
function isDynamicSegment(segment) {
|
|
58
|
-
return segment.startsWith("[") &&
|
|
58
|
+
return (segment.startsWith("[") &&
|
|
59
|
+
segment.endsWith("]") &&
|
|
60
|
+
!isOptionalCatchAll(segment) &&
|
|
61
|
+
!isRequiredCatchAll(segment));
|
|
59
62
|
}
|
|
60
63
|
/**
|
|
61
64
|
* Normalize a dynamic segment for display
|
|
@@ -73,8 +76,8 @@ function normalizeRoutePath(segments) {
|
|
|
73
76
|
// Filter out route groups - they don't appear in URLs
|
|
74
77
|
// Filter out optional catch-all segments - they match the base path
|
|
75
78
|
const urlSegments = segments
|
|
76
|
-
.filter(seg => !isRouteGroup(seg) && !isOptionalCatchAll(seg))
|
|
77
|
-
.map(seg => {
|
|
79
|
+
.filter((seg) => !isRouteGroup(seg) && !isOptionalCatchAll(seg))
|
|
80
|
+
.map((seg) => {
|
|
78
81
|
if (isDynamicSegment(seg)) {
|
|
79
82
|
return normalizeDynamicSegment(seg);
|
|
80
83
|
}
|
|
@@ -87,7 +90,7 @@ function normalizeRoutePath(segments) {
|
|
|
87
90
|
});
|
|
88
91
|
if (urlSegments.length === 0)
|
|
89
92
|
return "/";
|
|
90
|
-
return
|
|
93
|
+
return `/${urlSegments.join("/")}`;
|
|
91
94
|
}
|
|
92
95
|
/**
|
|
93
96
|
* Check if file is a page file
|
|
@@ -131,7 +134,16 @@ function scanAppDirectory(dirPath, segments = []) {
|
|
|
131
134
|
* File discovery helpers for legacy `pages/` directories
|
|
132
135
|
*/
|
|
133
136
|
const VALID_PAGE_EXTENSIONS = new Set([".js", ".jsx", ".ts", ".tsx", ".md", ".mdx"]);
|
|
134
|
-
const SPECIAL_PAGE_FILENAMES = new Set([
|
|
137
|
+
const SPECIAL_PAGE_FILENAMES = new Set([
|
|
138
|
+
"_app",
|
|
139
|
+
"_document",
|
|
140
|
+
"_error",
|
|
141
|
+
"404",
|
|
142
|
+
"500",
|
|
143
|
+
"middleware",
|
|
144
|
+
"_middleware",
|
|
145
|
+
]);
|
|
146
|
+
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: recursive directory scanner with multiple file type checks
|
|
135
147
|
function scanPagesDirectory(dirPath, segments = []) {
|
|
136
148
|
const routes = [];
|
|
137
149
|
try {
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yak-io/nextjs",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Next.js SDK for embedding yak chatbot with route manifest generation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
7
7
|
"author": "Yak <support@yak.io>",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
|
-
"url": "https://github.com/
|
|
10
|
+
"url": "https://github.com/388-labs/yak.git",
|
|
11
11
|
"directory": "packages/nextjs"
|
|
12
12
|
},
|
|
13
13
|
"publishConfig": {
|
|
@@ -60,8 +60,8 @@
|
|
|
60
60
|
"yak-nextjs": "./dist/cli/generate-manifest.js"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@yak-io/javascript": "0.
|
|
64
|
-
"@yak-io/react": "0.
|
|
63
|
+
"@yak-io/javascript": "0.4.1",
|
|
64
|
+
"@yak-io/react": "0.4.1"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"next": "^14.0.0 || ^15.0.0 || ^16.0.0",
|
|
@@ -69,17 +69,19 @@
|
|
|
69
69
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
|
-
"@types/node": "^24.10.
|
|
73
|
-
"@types/react": "^19.2.
|
|
72
|
+
"@types/node": "^24.10.4",
|
|
73
|
+
"@types/react": "^19.2.14",
|
|
74
74
|
"@types/react-dom": "^19.2.0",
|
|
75
|
-
"next": "^16.
|
|
76
|
-
"react": "^19.2.
|
|
77
|
-
"react-dom": "^19.2.
|
|
75
|
+
"next": "^16.1.6",
|
|
76
|
+
"react": "^19.2.4",
|
|
77
|
+
"react-dom": "^19.2.4",
|
|
78
78
|
"typescript": "^5.3.0",
|
|
79
79
|
"@repo/typescript-config": "0.0.0"
|
|
80
80
|
},
|
|
81
81
|
"scripts": {
|
|
82
82
|
"build": "tsc",
|
|
83
|
-
"check-types": "tsc --noEmit"
|
|
83
|
+
"check-types": "tsc --noEmit",
|
|
84
|
+
"lint": "biome lint ./src --fix",
|
|
85
|
+
"format": "biome format ./src --write"
|
|
84
86
|
}
|
|
85
87
|
}
|