@yak-io/nextjs 0.1.2 → 0.1.4
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 +6 -31
- package/dist/cli/generate-manifest.d.ts +1 -1
- package/dist/cli/generate-manifest.js +5 -3
- package/dist/server/createNextYakHandler.d.ts +3 -3
- package/dist/server/createNextYakHandler.d.ts.map +1 -1
- package/dist/server/createNextYakHandler.js +29 -24
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -164,12 +164,12 @@ Behind the scenes `@yak-io/javascript` merges every `RouteSource` into a single
|
|
|
164
164
|
yak-nextjs generate-manifest
|
|
165
165
|
```
|
|
166
166
|
|
|
167
|
-
Use the CLI
|
|
167
|
+
Use the CLI to pre-compute a manifest at build time. The JSON matches the runtime manifest structure exposed by the handlers.
|
|
168
168
|
|
|
169
169
|
**Options:**
|
|
170
170
|
- `--app-dir <path>` – Path to Next.js app directory (default: `./src/app`)
|
|
171
171
|
- `--pages-dir <path>` – Path to Next.js pages directory (optional, scanned in addition to app-dir)
|
|
172
|
-
- `--output <path>` – Output file path (default: `./yak-routes-manifest.json`)
|
|
172
|
+
- `--output <path>` – Output file path (default: `./public/yak-routes-manifest.json`)
|
|
173
173
|
|
|
174
174
|
**Examples:**
|
|
175
175
|
```bash
|
|
@@ -182,8 +182,6 @@ yak-nextjs generate-manifest --app-dir ./app --pages-dir ./pages
|
|
|
182
182
|
|
|
183
183
|
During local development, routes are scanned directly from the filesystem—no setup needed. 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.
|
|
184
184
|
|
|
185
|
-
To enable route scanning in production builds, generate a manifest at build time.
|
|
186
|
-
|
|
187
185
|
### Recommended setup
|
|
188
186
|
|
|
189
187
|
Add a `prebuild` script to generate the manifest before Next.js builds:
|
|
@@ -197,22 +195,9 @@ Add a `prebuild` script to generate the manifest before Next.js builds:
|
|
|
197
195
|
}
|
|
198
196
|
```
|
|
199
197
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
```json
|
|
203
|
-
{
|
|
204
|
-
"scripts": {
|
|
205
|
-
"prebuild": "yak-nextjs generate-manifest --app-dir ./app --output ./routes.json"
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
> **Important:** The manifest must be in the project root (not `public/`). On Vercel and other serverless platforms, files in `public/` are served via CDN and are not available on the function's filesystem.
|
|
198
|
+
That's it! The manifest is generated to `./src/yak-routes-manifest.json` and automatically bundled with your serverless function. No code changes needed in your API route.
|
|
211
199
|
|
|
212
|
-
The
|
|
213
|
-
1. `./yak-routes-manifest.json`
|
|
214
|
-
2. `./.next/yak-routes-manifest.json`
|
|
215
|
-
3. `./public/yak-routes-manifest.json` (only works in non-serverless environments)
|
|
200
|
+
The manifest is placed in `./src/` so that Next.js file tracing includes it in the serverless bundle, making it available at runtime on platforms like Vercel.
|
|
216
201
|
|
|
217
202
|
### Alternative: explicit routes
|
|
218
203
|
|
|
@@ -227,24 +212,14 @@ export const { GET, POST } = createNextYakHandler({
|
|
|
227
212
|
});
|
|
228
213
|
```
|
|
229
214
|
|
|
230
|
-
### Loading a custom manifest location
|
|
231
|
-
|
|
232
|
-
```ts
|
|
233
|
-
import { createNextYakHandler, loadRoutes } from "@yak-io/nextjs/server";
|
|
234
|
-
|
|
235
|
-
export const { GET, POST } = createNextYakHandler({
|
|
236
|
-
routes: loadRoutes("./custom/manifest.json"),
|
|
237
|
-
});
|
|
238
|
-
```
|
|
239
|
-
|
|
240
215
|
## API surface (server)
|
|
241
216
|
|
|
242
217
|
`@yak-io/nextjs/server` exports:
|
|
243
218
|
|
|
244
219
|
- `scanRoutes(directory: string, options?: { directoryType?: "app" | "pages" })` – low-level filesystem scanner (useful for precomputing manifests or composing custom sources). Only captures page routes, extracting `title` and `description` from static metadata exports.
|
|
245
|
-
- `loadRouteManifest(path?: string)` – load a pre-built JSON manifest, returns `null` if not found.
|
|
220
|
+
- `loadRouteManifest(path?: string)` – load a pre-built JSON manifest via filesystem read, returns `null` if not found.
|
|
246
221
|
- `loadRoutes(path?: string)` – load routes from a manifest, throws with helpful error if not found.
|
|
247
|
-
- `createNextYakHandler(config)` – unified GET + POST handler
|
|
222
|
+
- `createNextYakHandler(config)` – unified GET + POST handler. When `routes`/`getRoutes` are omitted it auto-scans `./src/app` (override with `appDir`). In production, automatically fetches manifest from public folder.
|
|
248
223
|
- `createNextYakConfigHandler(config)` – GET-only convenience wrapper.
|
|
249
224
|
- `createNextYakToolsHandler(config)` – POST-only wrapper.
|
|
250
225
|
- Re-exported types from `@yak-io/javascript/server` (RouteInfo, RouteManifest, ToolDefinition, ToolManifest, ToolExecutor, ChatConfig, RouteSourceInput, ToolSourceInput, etc.).
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* Options:
|
|
12
12
|
* --app-dir <path> Path to Next.js app directory (default: ./src/app)
|
|
13
13
|
* --pages-dir <path> Path to Next.js pages directory (optional, scanned in addition to app-dir)
|
|
14
|
-
* --output <path> Output file path (default: ./yak-routes-manifest.json)
|
|
14
|
+
* --output <path> Output file path (default: ./src/yak-routes-manifest.json)
|
|
15
15
|
*/
|
|
16
16
|
export {};
|
|
17
17
|
//# sourceMappingURL=generate-manifest.d.ts.map
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* Options:
|
|
12
12
|
* --app-dir <path> Path to Next.js app directory (default: ./src/app)
|
|
13
13
|
* --pages-dir <path> Path to Next.js pages directory (optional, scanned in addition to app-dir)
|
|
14
|
-
* --output <path> Output file path (default: ./yak-routes-manifest.json)
|
|
14
|
+
* --output <path> Output file path (default: ./src/yak-routes-manifest.json)
|
|
15
15
|
*/
|
|
16
16
|
import * as fs from "node:fs";
|
|
17
17
|
import * as path from "node:path";
|
|
@@ -201,7 +201,8 @@ function parseArgs() {
|
|
|
201
201
|
const args = process.argv.slice(2);
|
|
202
202
|
let appDir = "./src/app";
|
|
203
203
|
let pagesDir = undefined;
|
|
204
|
-
|
|
204
|
+
// Default to ./src/ so the file is included in Next.js serverless bundle via file tracing
|
|
205
|
+
let output = "./src/yak-routes-manifest.json";
|
|
205
206
|
let help = false;
|
|
206
207
|
for (let i = 0; i < args.length; i++) {
|
|
207
208
|
const arg = args[i];
|
|
@@ -238,7 +239,7 @@ Usage:
|
|
|
238
239
|
Options:
|
|
239
240
|
--app-dir <path> Path to Next.js app directory (default: ./src/app)
|
|
240
241
|
--pages-dir <path> Path to Next.js pages directory (optional)
|
|
241
|
-
--output <path> Output file path (default: ./yak-routes-manifest.json)
|
|
242
|
+
--output <path> Output file path (default: ./src/yak-routes-manifest.json)
|
|
242
243
|
--help, -h Show this help message
|
|
243
244
|
|
|
244
245
|
Examples:
|
|
@@ -290,6 +291,7 @@ function main() {
|
|
|
290
291
|
generated_at: new Date().toISOString(),
|
|
291
292
|
};
|
|
292
293
|
const outputPath = path.resolve(process.cwd(), output);
|
|
294
|
+
// Write JSON manifest
|
|
293
295
|
fs.writeFileSync(outputPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
294
296
|
console.log(`✅ Generated manifest with ${uniqueRoutes.length} page routes`);
|
|
295
297
|
console.log(` Output: ${outputPath}`);
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { RouteSourceInput, ToolSourceInput, RouteInfo, RouteManifest, ToolManifest, ToolExecutor } from "@yak-io/javascript/server";
|
|
2
2
|
/**
|
|
3
|
-
* Load a pre-built route manifest from disk.
|
|
3
|
+
* Load a pre-built route manifest from disk (JSON file).
|
|
4
4
|
*
|
|
5
|
-
* This
|
|
6
|
-
*
|
|
5
|
+
* This works in traditional Node.js deployments where the filesystem is available.
|
|
6
|
+
* For Vercel serverless, the manifest must be imported directly in your route file.
|
|
7
7
|
*
|
|
8
8
|
* Generate the manifest at build time using:
|
|
9
9
|
* yak-nextjs generate-manifest
|
|
@@ -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;
|
|
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,CAe7D;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,uCAW1E"}
|
|
@@ -3,22 +3,24 @@ import * as fs from "node:fs";
|
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { scanRoutes } from "./scan-routes.js";
|
|
5
5
|
/**
|
|
6
|
-
* Default paths to check for pre-built route manifests.
|
|
6
|
+
* Default paths to check for pre-built route manifests (JSON files).
|
|
7
|
+
* These are read via fs.readFileSync at runtime.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* Priority:
|
|
10
|
+
* 1. ./src/yak-routes-manifest.json - Default output, bundled by Next.js file tracing
|
|
11
|
+
* 2. ./yak-routes-manifest.json - Root fallback
|
|
12
|
+
* 3. ./public/yak-routes-manifest.json - Legacy location (doesn't work on Vercel serverless)
|
|
11
13
|
*/
|
|
12
14
|
const DEFAULT_MANIFEST_PATHS = [
|
|
15
|
+
"./src/yak-routes-manifest.json",
|
|
13
16
|
"./yak-routes-manifest.json",
|
|
14
|
-
"
|
|
15
|
-
"./public/yak-routes-manifest.json", // Only works in non-serverless environments
|
|
17
|
+
"./public/yak-routes-manifest.json",
|
|
16
18
|
];
|
|
17
19
|
/**
|
|
18
|
-
* Load a pre-built route manifest from disk.
|
|
20
|
+
* Load a pre-built route manifest from disk (JSON file).
|
|
19
21
|
*
|
|
20
|
-
* This
|
|
21
|
-
*
|
|
22
|
+
* This works in traditional Node.js deployments where the filesystem is available.
|
|
23
|
+
* For Vercel serverless, the manifest must be imported directly in your route file.
|
|
22
24
|
*
|
|
23
25
|
* Generate the manifest at build time using:
|
|
24
26
|
* yak-nextjs generate-manifest
|
|
@@ -49,7 +51,9 @@ export function loadRouteManifest(manifestPath) {
|
|
|
49
51
|
export function loadRoutes(manifestPath) {
|
|
50
52
|
const manifest = loadRouteManifest(manifestPath);
|
|
51
53
|
if (!manifest) {
|
|
52
|
-
const pathsChecked = manifestPath
|
|
54
|
+
const pathsChecked = manifestPath
|
|
55
|
+
? manifestPath
|
|
56
|
+
: [...DEFAULT_MANIFEST_PATHS].join(", ");
|
|
53
57
|
throw new Error(`Route manifest not found. Checked: ${pathsChecked}\n\n` +
|
|
54
58
|
`In production environments (like Vercel), route scanning requires a pre-built manifest.\n` +
|
|
55
59
|
`Generate it at build time by adding to your build script:\n\n` +
|
|
@@ -68,32 +72,30 @@ export function createNextYakHandler(config) {
|
|
|
68
72
|
});
|
|
69
73
|
}
|
|
70
74
|
/**
|
|
71
|
-
* Attempt to
|
|
75
|
+
* Attempt to load routes from filesystem or fetch from public URL.
|
|
72
76
|
*
|
|
73
77
|
* In development: scans the app directory directly
|
|
74
|
-
* In production (Vercel, etc.): falls back to pre-built manifest
|
|
78
|
+
* In production (Vercel, etc.): falls back to pre-built manifest via filesystem or HTTP fetch
|
|
75
79
|
*/
|
|
76
|
-
function tryLoadRoutes(appDir) {
|
|
80
|
+
async function tryLoadRoutes(appDir) {
|
|
77
81
|
const targetDir = path.resolve(process.cwd(), appDir);
|
|
78
82
|
// If the app directory exists, scan it directly (development mode)
|
|
79
83
|
if (fs.existsSync(targetDir)) {
|
|
80
84
|
return scanRoutes(appDir);
|
|
81
85
|
}
|
|
82
|
-
// In production, the source directory doesn't exist - try loading from manifest
|
|
86
|
+
// In production, the source directory doesn't exist - try loading from manifest file
|
|
83
87
|
const manifest = loadRouteManifest();
|
|
84
88
|
if (manifest) {
|
|
85
89
|
return manifest.routes;
|
|
86
90
|
}
|
|
87
91
|
// Neither source nor manifest available - provide helpful error
|
|
88
|
-
throw new Error(`
|
|
89
|
-
`
|
|
90
|
-
`
|
|
91
|
-
`
|
|
92
|
-
`
|
|
93
|
-
`
|
|
94
|
-
`
|
|
95
|
-
`3. Use getRoutes callback:\n` +
|
|
96
|
-
` createNextYakHandler({ getRoutes: async () => [...] })`);
|
|
92
|
+
throw new Error(`Route manifest not found.\n\n` +
|
|
93
|
+
`Generate the manifest at build time by adding to package.json:\n` +
|
|
94
|
+
` "prebuild": "yak-nextjs generate-manifest"\n\n` +
|
|
95
|
+
`The manifest will be created at ./src/yak-routes-manifest.json and automatically\n` +
|
|
96
|
+
`bundled with your serverless function.\n\n` +
|
|
97
|
+
`Alternatively, provide routes explicitly:\n` +
|
|
98
|
+
` createNextYakHandler({ routes: [{ path: "/", title: "Home" }] })`);
|
|
97
99
|
}
|
|
98
100
|
function resolveRouteSources(config) {
|
|
99
101
|
if (config.routes) {
|
|
@@ -102,7 +104,10 @@ function resolveRouteSources(config) {
|
|
|
102
104
|
if (config.getRoutes) {
|
|
103
105
|
return config.getRoutes;
|
|
104
106
|
}
|
|
105
|
-
return async () =>
|
|
107
|
+
return async () => {
|
|
108
|
+
const routes = await tryLoadRoutes(config.appDir ?? "./src/app");
|
|
109
|
+
return applyRouteFilters(routes, config.routeFilter);
|
|
110
|
+
};
|
|
106
111
|
}
|
|
107
112
|
function applyRouteFilters(routes, filter) {
|
|
108
113
|
if (!filter) {
|