@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 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 when you prefer to pre-compute a manifest at build time. The JSON matches the runtime manifest structure exposed by the handlers.
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
- This uses the defaults (`./src/app` → `./yak-routes-manifest.json`). Customize if needed:
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 handler checks these locations automatically:
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. Checks `./yak-routes-manifest.json`, `./.next/yak-routes-manifest.json`, and `./public/yak-routes-manifest.json` by default.
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 (wrapping `createYakHandler`). When `routes`/`getRoutes` are omitted it auto-scans `./src/app` and `./src/pages` (override with `appDir`/`pagesDir`, and narrow results via `routeFilter?: { include?: RegExp[]; exclude?: RegExp[] }`). In production, automatically falls back to pre-built manifests.
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
- let output = "./yak-routes-manifest.json";
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 should be used in production environments where filesystem scanning
6
- * is not available (e.g., Vercel serverless functions).
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;AAgBnC;;;;;;;;;;;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;AA6FD,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"}
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
- * On Vercel/serverless, files in `public/` are served via CDN and NOT available
9
- * on the function's filesystem. The manifest must be in the project root or
10
- * another location that gets bundled with the serverless function.
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
- "./.next/yak-routes-manifest.json",
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 should be used in production environments where filesystem scanning
21
- * is not available (e.g., Vercel serverless functions).
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 ? manifestPath : DEFAULT_MANIFEST_PATHS.join(", ");
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 scan routes from filesystem, with production-safe fallback.
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 if directory doesn't exist
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(`App directory not found: ${targetDir}\n\n` +
89
- `This typically happens in production (Vercel, etc.) where source files aren't deployed.\n\n` +
90
- `Solutions:\n` +
91
- `1. Generate a route manifest at build time:\n` +
92
- ` Add to your build script: yak-nextjs generate-manifest\n\n` +
93
- `2. Provide routes explicitly:\n` +
94
- ` createNextYakHandler({ routes: [...] })\n\n` +
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 () => applyRouteFilters(tryLoadRoutes(config.appDir ?? "./src/app"), config.routeFilter);
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yak-io/nextjs",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
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",