@yak-io/nextjs 0.1.3 → 0.1.5
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 +32 -8
- package/dist/cli/generate-manifest.d.ts +1 -1
- package/dist/cli/generate-manifest.js +37 -14
- package/dist/server/createNextYakHandler.d.ts +1 -0
- package/dist/server/createNextYakHandler.d.ts.map +1 -1
- package/dist/server/createNextYakHandler.js +15 -73
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -0
- package/dist/server/route-manifest-adapter.d.ts +73 -0
- package/dist/server/route-manifest-adapter.d.ts.map +1 -0
- package/dist/server/route-manifest-adapter.js +75 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -164,29 +164,27 @@ 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 to
|
|
167
|
+
Use the CLI to generate a TypeScript module with your routes at build time.
|
|
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: `./
|
|
172
|
+
- `--output <path>` – Output file path (default: `./src/yak.routes.ts`)
|
|
173
173
|
|
|
174
174
|
**Examples:**
|
|
175
175
|
```bash
|
|
176
176
|
yak-nextjs generate-manifest
|
|
177
177
|
yak-nextjs generate-manifest --pages-dir ./src/pages
|
|
178
|
-
yak-nextjs generate-manifest --app-dir ./app --
|
|
178
|
+
yak-nextjs generate-manifest --app-dir ./app --output ./src/generated/routes.ts
|
|
179
179
|
```
|
|
180
180
|
|
|
181
181
|
## Route Manifest for Production
|
|
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
|
-
Add a `prebuild` script to generate the manifest before Next.js builds:
|
|
187
|
+
1. Add a `prebuild` script to generate the manifest before Next.js builds:
|
|
190
188
|
|
|
191
189
|
```json
|
|
192
190
|
{
|
|
@@ -197,9 +195,35 @@ Add a `prebuild` script to generate the manifest before Next.js builds:
|
|
|
197
195
|
}
|
|
198
196
|
```
|
|
199
197
|
|
|
200
|
-
|
|
198
|
+
2. Use the route manifest adapter in your handler:
|
|
199
|
+
|
|
200
|
+
```ts
|
|
201
|
+
// app/api/yak/[...yak]/route.ts
|
|
202
|
+
import { createNextYakHandler, createRouteManifestAdapter } from "@yak-io/nextjs/server";
|
|
203
|
+
import { routes } from "@/yak.routes";
|
|
204
|
+
|
|
205
|
+
export const { GET, POST } = createNextYakHandler({
|
|
206
|
+
routes: createRouteManifestAdapter({ routes }),
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
The generated TypeScript module is imported directly, ensuring it's bundled with your serverless function automatically.
|
|
211
|
+
|
|
212
|
+
### Route filtering
|
|
213
|
+
|
|
214
|
+
Use `allowedRoutes` and `disallowedRoutes` to control which routes are exposed (similar to tRPC adapter):
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
createRouteManifestAdapter({
|
|
218
|
+
routes,
|
|
219
|
+
allowedRoutes: ["/docs/*", "/pricing", "/"],
|
|
220
|
+
disallowedRoutes: ["/docs/internal/*"],
|
|
221
|
+
})
|
|
222
|
+
```
|
|
201
223
|
|
|
202
|
-
|
|
224
|
+
Pattern matching:
|
|
225
|
+
- Exact match: `"/pricing"` matches only `/pricing`
|
|
226
|
+
- Prefix match: `"/docs/*"` matches `/docs`, `/docs/getting-started`, etc.
|
|
203
227
|
|
|
204
228
|
### Alternative: explicit routes
|
|
205
229
|
|
|
@@ -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: ./
|
|
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: ./
|
|
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/yak.routes.ts - TypeScript module that gets bundled
|
|
205
|
+
let output = "./src/yak.routes.ts";
|
|
205
206
|
let help = false;
|
|
206
207
|
for (let i = 0; i < args.length; i++) {
|
|
207
208
|
const arg = args[i];
|
|
@@ -230,7 +231,7 @@ function showHelp() {
|
|
|
230
231
|
console.log(`
|
|
231
232
|
Yak Next.js Route Manifest Generator
|
|
232
233
|
|
|
233
|
-
Scans a Next.js app directory and generates a
|
|
234
|
+
Scans a Next.js app directory and generates a TypeScript module with route definitions.
|
|
234
235
|
|
|
235
236
|
Usage:
|
|
236
237
|
yak-nextjs generate-manifest [options]
|
|
@@ -238,16 +239,36 @@ 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: ./
|
|
242
|
+
--output <path> Output file path (default: ./src/yak.routes.ts)
|
|
242
243
|
--help, -h Show this help message
|
|
243
244
|
|
|
244
245
|
Examples:
|
|
245
246
|
yak-nextjs generate-manifest
|
|
246
247
|
yak-nextjs generate-manifest --app-dir ./app
|
|
247
|
-
yak-nextjs generate-manifest --
|
|
248
|
-
yak-nextjs generate-manifest --app-dir ./app --pages-dir ./pages
|
|
248
|
+
yak-nextjs generate-manifest --output ./src/generated/yak.routes.ts
|
|
249
249
|
`);
|
|
250
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Generate TypeScript module content
|
|
253
|
+
*/
|
|
254
|
+
function generateTypeScriptModule(routes) {
|
|
255
|
+
const routesJson = JSON.stringify(routes, null, 2);
|
|
256
|
+
return `/**
|
|
257
|
+
* Auto-generated by yak-nextjs generate-manifest
|
|
258
|
+
* DO NOT EDIT - This file is regenerated at build time
|
|
259
|
+
*
|
|
260
|
+
* Generated: ${new Date().toISOString()}
|
|
261
|
+
*/
|
|
262
|
+
|
|
263
|
+
import type { RouteInfo } from "@yak-io/nextjs/server";
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* All scanned routes from your Next.js application.
|
|
267
|
+
* Use with createRouteManifestAdapter for filtering options.
|
|
268
|
+
*/
|
|
269
|
+
export const routes: RouteInfo[] = ${routesJson} as const;
|
|
270
|
+
`;
|
|
271
|
+
}
|
|
251
272
|
/**
|
|
252
273
|
* Main entry point
|
|
253
274
|
*/
|
|
@@ -284,15 +305,17 @@ function main() {
|
|
|
284
305
|
process.exit(1);
|
|
285
306
|
}
|
|
286
307
|
// Deduplicate routes by path (app router takes precedence)
|
|
287
|
-
const uniqueRoutes = Array.from(new Map(routes.map(r => [r.path, r])).values());
|
|
288
|
-
const manifest = {
|
|
289
|
-
routes: uniqueRoutes.sort((a, b) => a.path.localeCompare(b.path)),
|
|
290
|
-
generated_at: new Date().toISOString(),
|
|
291
|
-
};
|
|
308
|
+
const uniqueRoutes = Array.from(new Map(routes.map(r => [r.path, r])).values()).sort((a, b) => a.path.localeCompare(b.path));
|
|
292
309
|
const outputPath = path.resolve(process.cwd(), output);
|
|
293
|
-
//
|
|
294
|
-
|
|
295
|
-
|
|
310
|
+
// Ensure output directory exists
|
|
311
|
+
const outputDir = path.dirname(outputPath);
|
|
312
|
+
if (!fs.existsSync(outputDir)) {
|
|
313
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
314
|
+
}
|
|
315
|
+
// Write TypeScript module
|
|
316
|
+
const content = generateTypeScriptModule(uniqueRoutes);
|
|
317
|
+
fs.writeFileSync(outputPath, content, "utf-8");
|
|
318
|
+
console.log(`✅ Generated route manifest with ${uniqueRoutes.length} routes`);
|
|
296
319
|
console.log(` Output: ${outputPath}`);
|
|
297
320
|
}
|
|
298
321
|
// Run the CLI
|
|
@@ -3,6 +3,7 @@ import type { RouteSourceInput, ToolSourceInput, RouteInfo, RouteManifest, ToolM
|
|
|
3
3
|
* Load a pre-built route manifest from disk (JSON file).
|
|
4
4
|
*
|
|
5
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.
|
|
6
7
|
*
|
|
7
8
|
* Generate the manifest at build time using:
|
|
8
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"}
|
|
@@ -5,19 +5,22 @@ import { scanRoutes } from "./scan-routes.js";
|
|
|
5
5
|
/**
|
|
6
6
|
* Default paths to check for pre-built route manifests (JSON files).
|
|
7
7
|
* These are read via fs.readFileSync at runtime.
|
|
8
|
+
*
|
|
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)
|
|
8
13
|
*/
|
|
9
14
|
const DEFAULT_MANIFEST_PATHS = [
|
|
10
|
-
"./
|
|
15
|
+
"./src/yak-routes-manifest.json",
|
|
11
16
|
"./yak-routes-manifest.json",
|
|
17
|
+
"./public/yak-routes-manifest.json",
|
|
12
18
|
];
|
|
13
|
-
/**
|
|
14
|
-
* Public URL path where the manifest is served from (when in public/).
|
|
15
|
-
*/
|
|
16
|
-
const PUBLIC_MANIFEST_URL = "/yak-routes-manifest.json";
|
|
17
19
|
/**
|
|
18
20
|
* Load a pre-built route manifest from disk (JSON file).
|
|
19
21
|
*
|
|
20
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.
|
|
21
24
|
*
|
|
22
25
|
* Generate the manifest at build time using:
|
|
23
26
|
* yak-nextjs generate-manifest
|
|
@@ -41,59 +44,6 @@ export function loadRouteManifest(manifestPath) {
|
|
|
41
44
|
}
|
|
42
45
|
return null;
|
|
43
46
|
}
|
|
44
|
-
/**
|
|
45
|
-
* Fetch the route manifest from the public URL.
|
|
46
|
-
* Used in serverless environments where filesystem access is not available.
|
|
47
|
-
*/
|
|
48
|
-
async function fetchRouteManifest() {
|
|
49
|
-
// Try to determine the base URL for fetching
|
|
50
|
-
const baseUrl = getBaseUrl();
|
|
51
|
-
if (!baseUrl) {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
try {
|
|
55
|
-
const url = new URL(PUBLIC_MANIFEST_URL, baseUrl);
|
|
56
|
-
const response = await fetch(url.toString(), {
|
|
57
|
-
headers: { "Accept": "application/json" },
|
|
58
|
-
cache: "no-store",
|
|
59
|
-
});
|
|
60
|
-
if (!response.ok) {
|
|
61
|
-
return null;
|
|
62
|
-
}
|
|
63
|
-
const manifest = await response.json();
|
|
64
|
-
if (manifest?.routes) {
|
|
65
|
-
return manifest;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
catch {
|
|
69
|
-
// Fetch failed
|
|
70
|
-
}
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Get the base URL for the current deployment.
|
|
75
|
-
* Supports Vercel, Netlify, and custom configurations.
|
|
76
|
-
*/
|
|
77
|
-
function getBaseUrl() {
|
|
78
|
-
// Vercel provides VERCEL_URL (without protocol)
|
|
79
|
-
if (process.env.VERCEL_URL) {
|
|
80
|
-
const protocol = process.env.VERCEL_ENV === "development" ? "http" : "https";
|
|
81
|
-
return `${protocol}://${process.env.VERCEL_URL}`;
|
|
82
|
-
}
|
|
83
|
-
// Netlify provides URL
|
|
84
|
-
if (process.env.URL) {
|
|
85
|
-
return process.env.URL;
|
|
86
|
-
}
|
|
87
|
-
// Custom base URL
|
|
88
|
-
if (process.env.NEXT_PUBLIC_BASE_URL) {
|
|
89
|
-
return process.env.NEXT_PUBLIC_BASE_URL;
|
|
90
|
-
}
|
|
91
|
-
// For local development
|
|
92
|
-
if (process.env.NODE_ENV === "development") {
|
|
93
|
-
return "http://localhost:3000";
|
|
94
|
-
}
|
|
95
|
-
return null;
|
|
96
|
-
}
|
|
97
47
|
/**
|
|
98
48
|
* Load routes from a pre-built manifest.
|
|
99
49
|
* Throws if manifest is not found.
|
|
@@ -138,22 +88,14 @@ async function tryLoadRoutes(appDir) {
|
|
|
138
88
|
if (manifest) {
|
|
139
89
|
return manifest.routes;
|
|
140
90
|
}
|
|
141
|
-
// Try fetching from public URL (works on Vercel/serverless)
|
|
142
|
-
const fetchedManifest = await fetchRouteManifest();
|
|
143
|
-
if (fetchedManifest) {
|
|
144
|
-
return fetchedManifest.routes;
|
|
145
|
-
}
|
|
146
91
|
// Neither source nor manifest available - provide helpful error
|
|
147
|
-
throw new Error(`
|
|
148
|
-
`
|
|
149
|
-
`
|
|
150
|
-
`
|
|
151
|
-
`
|
|
152
|
-
`
|
|
153
|
-
`
|
|
154
|
-
` createNextYakHandler({ routes: [{ path: "/", title: "Home" }, ...] })\n\n` +
|
|
155
|
-
`3. Use getRoutes callback:\n` +
|
|
156
|
-
` 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" }] })`);
|
|
157
99
|
}
|
|
158
100
|
function resolveRouteSources(config) {
|
|
159
101
|
if (config.routes) {
|
package/dist/server/index.d.ts
CHANGED
|
@@ -2,5 +2,7 @@ export { scanRoutes } from "./scan-routes.js";
|
|
|
2
2
|
export type { ScanRoutesOptions } from "./scan-routes.js";
|
|
3
3
|
export { createNextYakHandler, createNextYakConfigHandler, createNextYakToolsHandler, loadRouteManifest, loadRoutes, } from "./createNextYakHandler.js";
|
|
4
4
|
export type { NextYakHandlerConfig, NextYakConfigHandlerConfig, NextYakToolsHandlerConfig, NextYakRouteFilter, } from "./createNextYakHandler.js";
|
|
5
|
+
export { createRouteManifestAdapter } from "./route-manifest-adapter.js";
|
|
6
|
+
export type { RouteManifestAdapterConfig } from "./route-manifest-adapter.js";
|
|
5
7
|
export type { ToolExecutor, ToolCallPayload, ToolCallResult, ToolDefinition, ToolManifest, RouteInfo, RouteManifest, ChatConfig, } from "@yak-io/javascript/server";
|
|
6
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -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,EACN,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,iBAAiB,EACjB,UAAU,GACV,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACX,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,kBAAkB,GAClB,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EACX,YAAY,EACZ,eAAe,EACf,cAAc,EACd,cAAc,EACd,YAAY,EACZ,SAAS,EACT,aAAa,EACb,UAAU,GACV,MAAM,2BAA2B,CAAC"}
|
|
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,EACN,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,iBAAiB,EACjB,UAAU,GACV,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACX,oBAAoB,EACpB,0BAA0B,EAC1B,yBAAyB,EACzB,kBAAkB,GAClB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AACzE,YAAY,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAC;AAE9E,YAAY,EACX,YAAY,EACZ,eAAe,EACf,cAAc,EACd,cAAc,EACd,YAAY,EACZ,SAAS,EACT,aAAa,EACb,UAAU,GACV,MAAM,2BAA2B,CAAC"}
|
package/dist/server/index.js
CHANGED
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
export { scanRoutes } from "./scan-routes.js";
|
|
2
2
|
export { createNextYakHandler, createNextYakConfigHandler, createNextYakToolsHandler, loadRouteManifest, loadRoutes, } from "./createNextYakHandler.js";
|
|
3
|
+
export { createRouteManifestAdapter } from "./route-manifest-adapter.js";
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { RouteInfo, RouteSource } from "@yak-io/javascript/server";
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for creating a route manifest adapter
|
|
4
|
+
*/
|
|
5
|
+
export type RouteManifestAdapterConfig = {
|
|
6
|
+
/**
|
|
7
|
+
* The routes from the generated manifest.
|
|
8
|
+
* Import from the generated file: `import { routes } from "@/yak.routes"`
|
|
9
|
+
*/
|
|
10
|
+
routes: RouteInfo[];
|
|
11
|
+
/**
|
|
12
|
+
* Optional ID for this route source (default: "manifest")
|
|
13
|
+
*/
|
|
14
|
+
id?: string;
|
|
15
|
+
/**
|
|
16
|
+
* List of allowed route paths, e.g. ["/", "/docs", "/pricing"].
|
|
17
|
+
* Supports exact matches and prefix patterns ending with `*`.
|
|
18
|
+
* If provided, only these routes will be included.
|
|
19
|
+
* If omitted, all routes are allowed by default.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* allowedRoutes: ["/docs/*", "/pricing", "/"]
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
allowedRoutes?: string[];
|
|
27
|
+
/**
|
|
28
|
+
* List of disallowed route paths, e.g. ["/admin/*", "/internal/*"].
|
|
29
|
+
* Supports exact matches and prefix patterns ending with `*`.
|
|
30
|
+
* These routes will be excluded even if they would otherwise be allowed.
|
|
31
|
+
* Applied after allowedRoutes filtering.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```ts
|
|
35
|
+
* disallowedRoutes: ["/admin/*", "/settings/billing"]
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
disallowedRoutes?: string[];
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Create a route source adapter from an imported route manifest.
|
|
42
|
+
*
|
|
43
|
+
* This adapter allows you to use generated route manifests with optional
|
|
44
|
+
* filtering to control which routes are exposed to the chatbot.
|
|
45
|
+
*
|
|
46
|
+
* @example Basic usage - all routes
|
|
47
|
+
* ```ts
|
|
48
|
+
* import { createNextYakHandler } from "@yak-io/nextjs/server";
|
|
49
|
+
* import { createRouteManifestAdapter } from "@yak-io/nextjs/server";
|
|
50
|
+
* import { routes } from "@/yak.routes";
|
|
51
|
+
*
|
|
52
|
+
* export const { GET, POST } = createNextYakHandler({
|
|
53
|
+
* routes: createRouteManifestAdapter({ routes }),
|
|
54
|
+
* });
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @example With filtering
|
|
58
|
+
* ```ts
|
|
59
|
+
* import { createNextYakHandler } from "@yak-io/nextjs/server";
|
|
60
|
+
* import { createRouteManifestAdapter } from "@yak-io/nextjs/server";
|
|
61
|
+
* import { routes } from "@/yak.routes";
|
|
62
|
+
*
|
|
63
|
+
* export const { GET, POST } = createNextYakHandler({
|
|
64
|
+
* routes: createRouteManifestAdapter({
|
|
65
|
+
* routes,
|
|
66
|
+
* allowedRoutes: ["/docs/*", "/pricing", "/"],
|
|
67
|
+
* disallowedRoutes: ["/docs/internal/*"],
|
|
68
|
+
* }),
|
|
69
|
+
* });
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export declare function createRouteManifestAdapter(config: RouteManifestAdapterConfig): RouteSource;
|
|
73
|
+
//# sourceMappingURL=route-manifest-adapter.d.ts.map
|
|
@@ -0,0 +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;AAiDF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,0BAA0B,GACjC,WAAW,CASb"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if a route path matches a pattern.
|
|
3
|
+
* Supports exact matches and prefix patterns ending with `*`.
|
|
4
|
+
*/
|
|
5
|
+
function matchesPattern(pattern, routePath) {
|
|
6
|
+
if (pattern.endsWith("/*")) {
|
|
7
|
+
const prefix = pattern.slice(0, -1); // Remove the *
|
|
8
|
+
return routePath === prefix.slice(0, -1) || routePath.startsWith(prefix);
|
|
9
|
+
}
|
|
10
|
+
return pattern === routePath;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Filter routes based on allowed and disallowed patterns.
|
|
14
|
+
*/
|
|
15
|
+
function filterRoutes(routes, allowedRoutes, disallowedRoutes) {
|
|
16
|
+
return routes.filter((route) => {
|
|
17
|
+
const path = route.path;
|
|
18
|
+
// If allowedRoutes is set, route must match at least one pattern
|
|
19
|
+
if (allowedRoutes && allowedRoutes.length > 0) {
|
|
20
|
+
const isAllowed = allowedRoutes.some((pattern) => matchesPattern(pattern, path));
|
|
21
|
+
if (!isAllowed) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// If disallowedRoutes is set, route must not match any pattern
|
|
26
|
+
if (disallowedRoutes && disallowedRoutes.length > 0) {
|
|
27
|
+
const isDisallowed = disallowedRoutes.some((pattern) => matchesPattern(pattern, path));
|
|
28
|
+
if (isDisallowed) {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Create a route source adapter from an imported route manifest.
|
|
37
|
+
*
|
|
38
|
+
* This adapter allows you to use generated route manifests with optional
|
|
39
|
+
* filtering to control which routes are exposed to the chatbot.
|
|
40
|
+
*
|
|
41
|
+
* @example Basic usage - all routes
|
|
42
|
+
* ```ts
|
|
43
|
+
* import { createNextYakHandler } from "@yak-io/nextjs/server";
|
|
44
|
+
* import { createRouteManifestAdapter } from "@yak-io/nextjs/server";
|
|
45
|
+
* import { routes } from "@/yak.routes";
|
|
46
|
+
*
|
|
47
|
+
* export const { GET, POST } = createNextYakHandler({
|
|
48
|
+
* routes: createRouteManifestAdapter({ routes }),
|
|
49
|
+
* });
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @example With filtering
|
|
53
|
+
* ```ts
|
|
54
|
+
* import { createNextYakHandler } from "@yak-io/nextjs/server";
|
|
55
|
+
* import { createRouteManifestAdapter } from "@yak-io/nextjs/server";
|
|
56
|
+
* import { routes } from "@/yak.routes";
|
|
57
|
+
*
|
|
58
|
+
* export const { GET, POST } = createNextYakHandler({
|
|
59
|
+
* routes: createRouteManifestAdapter({
|
|
60
|
+
* routes,
|
|
61
|
+
* allowedRoutes: ["/docs/*", "/pricing", "/"],
|
|
62
|
+
* disallowedRoutes: ["/docs/internal/*"],
|
|
63
|
+
* }),
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
*/
|
|
67
|
+
export function createRouteManifestAdapter(config) {
|
|
68
|
+
const { routes, id = "manifest", allowedRoutes, disallowedRoutes } = config;
|
|
69
|
+
return {
|
|
70
|
+
id,
|
|
71
|
+
getRoutes: async () => {
|
|
72
|
+
return filterRoutes(routes, allowedRoutes, disallowedRoutes);
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|