@yak-io/nextjs 0.3.1 → 0.3.3
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/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 +9 -6
|
@@ -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.3",
|
|
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.4.
|
|
64
|
-
"@yak-io/react": "0.
|
|
63
|
+
"@yak-io/javascript": "0.4.1",
|
|
64
|
+
"@yak-io/react": "0.5.0"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"next": "^14.0.0 || ^15.0.0 || ^16.0.0",
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/node": "^24.10.4",
|
|
73
|
-
"@types/react": "^19.2.
|
|
73
|
+
"@types/react": "^19.2.14",
|
|
74
74
|
"@types/react-dom": "^19.2.0",
|
|
75
75
|
"next": "^16.1.6",
|
|
76
76
|
"react": "^19.2.4",
|
|
@@ -80,6 +80,9 @@
|
|
|
80
80
|
},
|
|
81
81
|
"scripts": {
|
|
82
82
|
"build": "tsc",
|
|
83
|
-
"check-types": "tsc --noEmit"
|
|
83
|
+
"check-types": "tsc --noEmit",
|
|
84
|
+
"test": "vitest run",
|
|
85
|
+
"lint": "biome lint ./src --fix",
|
|
86
|
+
"format": "biome format ./src --write"
|
|
84
87
|
}
|
|
85
88
|
}
|