geo-ai-next 0.1.0

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 ADDED
@@ -0,0 +1,79 @@
1
+ # geo-ai-next
2
+
3
+ [![npm](https://img.shields.io/npm/v/geo-ai-next)](https://npmjs.com/package/geo-ai-next)
4
+
5
+ Part of the [GEO AI ecosystem](https://github.com/madeburo/GEO-AI). Full documentation → [geo-ai-core](https://npmjs.com/package/geo-ai-core)
6
+
7
+ Thin Next.js wrapper for [geo-ai-core](../core) — middleware and App Router route handler for serving `llms.txt` / `llms-full.txt`.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install geo-ai-next
13
+ ```
14
+
15
+ Peer dependency: `next >= 16`
16
+
17
+ ## Middleware
18
+
19
+ Intercepts `/llms.txt` and `/llms-full.txt` requests, passes everything else through:
20
+
21
+ ```typescript
22
+ // middleware.ts
23
+ import { geoAIMiddleware } from 'geo-ai-next';
24
+
25
+ export default geoAIMiddleware({
26
+ siteName: 'My Site',
27
+ siteUrl: 'https://example.com',
28
+ provider: new MyProvider(),
29
+ cache: '24h',
30
+ injectLinkHeader: true, // adds Link header to all responses
31
+ });
32
+
33
+ export const config = {
34
+ matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
35
+ };
36
+ ```
37
+
38
+ ## Route Handler
39
+
40
+ For App Router — serves llms content at any route you choose:
41
+
42
+ ```typescript
43
+ // app/llms/route.ts
44
+ import { createLlmsHandler } from 'geo-ai-next';
45
+
46
+ export const { GET } = createLlmsHandler({
47
+ siteName: 'My Site',
48
+ siteUrl: 'https://example.com',
49
+ provider: new MyProvider(),
50
+ });
51
+ ```
52
+
53
+ Type is determined by URL path (`/llms-full.txt`) or query param `?type=full`.
54
+
55
+ ## Re-exports
56
+
57
+ All public API from `geo-ai-core` is re-exported, so you don't need to install both:
58
+
59
+ ```typescript
60
+ import {
61
+ createGeoAI,
62
+ BotRulesEngine,
63
+ CrawlTracker,
64
+ SeoGenerator,
65
+ AI_BOTS,
66
+ type ContentProvider,
67
+ type Resource,
68
+ } from 'geo-ai-next';
69
+ ```
70
+
71
+ ## Requirements
72
+
73
+ - Node.js >= 20
74
+ - Next.js >= 16
75
+ - TypeScript >= 5.5 (recommended)
76
+
77
+ ## License
78
+
79
+ [GPL v2](../../LICENSE)
package/dist/index.cjs ADDED
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ AI_BOTS: () => import_geo_ai_core3.AI_BOTS,
24
+ BotRulesEngine: () => import_geo_ai_core3.BotRulesEngine,
25
+ CrawlTracker: () => import_geo_ai_core3.CrawlTracker,
26
+ CryptoService: () => import_geo_ai_core3.CryptoService,
27
+ FileCacheAdapter: () => import_geo_ai_core3.FileCacheAdapter,
28
+ LlmsGenerator: () => import_geo_ai_core3.LlmsGenerator,
29
+ MemoryCacheAdapter: () => import_geo_ai_core3.MemoryCacheAdapter,
30
+ MemoryCrawlStore: () => import_geo_ai_core3.MemoryCrawlStore,
31
+ SeoGenerator: () => import_geo_ai_core3.SeoGenerator,
32
+ createGeoAI: () => import_geo_ai_core3.createGeoAI,
33
+ createLlmsHandler: () => createLlmsHandler,
34
+ geoAIMiddleware: () => geoAIMiddleware
35
+ });
36
+ module.exports = __toCommonJS(src_exports);
37
+
38
+ // src/middleware.ts
39
+ var import_server = require("next/server");
40
+ var import_geo_ai_core = require("geo-ai-core");
41
+ function geoAIMiddleware(config) {
42
+ const core = (0, import_geo_ai_core.createGeoAI)(config);
43
+ const injectLink = config.injectLinkHeader ?? false;
44
+ return async (request) => {
45
+ const { pathname } = request.nextUrl;
46
+ if (pathname === "/llms.txt" || pathname === "/llms-full.txt") {
47
+ const isFull = pathname === "/llms-full.txt";
48
+ try {
49
+ const content = await core.generateLlms(isFull);
50
+ core.trackVisit(request).catch(() => {
51
+ });
52
+ return new import_server.NextResponse(content, {
53
+ status: 200,
54
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
55
+ });
56
+ } catch {
57
+ return new import_server.NextResponse("Internal Server Error", {
58
+ status: 500,
59
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
60
+ });
61
+ }
62
+ }
63
+ const response = import_server.NextResponse.next();
64
+ if (injectLink) {
65
+ response.headers.set("Link", core.generateLinkHeader());
66
+ }
67
+ return response;
68
+ };
69
+ }
70
+
71
+ // src/handler.ts
72
+ var import_geo_ai_core2 = require("geo-ai-core");
73
+ function createLlmsHandler(config) {
74
+ const core = (0, import_geo_ai_core2.createGeoAI)(config);
75
+ return {
76
+ async GET(request) {
77
+ const url = new URL(request.url);
78
+ const isFull = url.pathname.endsWith("/llms-full.txt") || url.searchParams.get("type") === "full";
79
+ try {
80
+ const content = await core.generateLlms(isFull);
81
+ core.trackVisit(request).catch(() => {
82
+ });
83
+ return new Response(content, {
84
+ status: 200,
85
+ headers: {
86
+ "Content-Type": "text/plain; charset=utf-8",
87
+ "Cache-Control": "public, max-age=3600"
88
+ }
89
+ });
90
+ } catch {
91
+ return new Response("Internal Server Error", {
92
+ status: 500,
93
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
94
+ });
95
+ }
96
+ }
97
+ };
98
+ }
99
+
100
+ // src/index.ts
101
+ var import_geo_ai_core3 = require("geo-ai-core");
102
+ // Annotate the CommonJS export names for ESM import in node:
103
+ 0 && (module.exports = {
104
+ AI_BOTS,
105
+ BotRulesEngine,
106
+ CrawlTracker,
107
+ CryptoService,
108
+ FileCacheAdapter,
109
+ LlmsGenerator,
110
+ MemoryCacheAdapter,
111
+ MemoryCrawlStore,
112
+ SeoGenerator,
113
+ createGeoAI,
114
+ createLlmsHandler,
115
+ geoAIMiddleware
116
+ });
117
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/middleware.ts","../src/handler.ts"],"sourcesContent":["// geo-ai-next main entry point\n\n// Next.js middleware\nexport { geoAIMiddleware } from './middleware';\nexport type { GeoAIMiddlewareConfig } from './middleware';\n\n// Next.js route handler\nexport { createLlmsHandler } from './handler';\nexport type { LlmsHandlerConfig } from './handler';\n\n// Re-export all public types, interfaces, and classes from geo-ai-core\nexport {\n createGeoAI,\n MemoryCacheAdapter,\n FileCacheAdapter,\n CrawlTracker,\n MemoryCrawlStore,\n CryptoService,\n BotRulesEngine,\n AI_BOTS,\n SeoGenerator,\n LlmsGenerator,\n} from 'geo-ai-core';\n\nexport type {\n GeoAIInstance,\n Resource,\n ProductResource,\n ResourceSection,\n ContentProvider,\n CacheAdapter,\n CrawlEntry,\n CrawlActivity,\n CrawlStore,\n CrawlTrackingConfig,\n CryptoConfig,\n GeoAIConfig,\n AiProvider,\n AiGeneratorConfig,\n AiError,\n AiBulkConfig,\n AiContext,\n} from 'geo-ai-core';\n","import { NextResponse } from 'next/server';\nimport type { NextRequest } from 'next/server';\nimport { createGeoAI } from 'geo-ai-core';\nimport type { GeoAIConfig, GeoAIInstance } from 'geo-ai-core';\n\n// ── Config ──────────────────────────────────────────────────────────\n\nexport interface GeoAIMiddlewareConfig extends GeoAIConfig {\n /** Inject Link header pointing to llms.txt on non-llms responses. Default: false */\n injectLinkHeader?: boolean;\n}\n\n// ── Middleware factory ───────────────────────────────────────────────\n\n/**\n * Creates a Next.js middleware function that intercepts `/llms.txt` and\n * `/llms-full.txt` requests, returning generated content as `text/plain`.\n * All other paths are passed through via `NextResponse.next()`.\n */\nexport function geoAIMiddleware(\n config: GeoAIMiddlewareConfig,\n): (request: NextRequest) => Promise<NextResponse> {\n const core: GeoAIInstance = createGeoAI(config);\n const injectLink = config.injectLinkHeader ?? false;\n\n return async (request: NextRequest): Promise<NextResponse> => {\n const { pathname } = request.nextUrl;\n\n // ── Match llms paths ───────────────────────────────────────────\n if (pathname === '/llms.txt' || pathname === '/llms-full.txt') {\n const isFull = pathname === '/llms-full.txt';\n\n try {\n const content = await core.generateLlms(isFull);\n\n // Fire-and-forget: track visit without blocking the response\n core.trackVisit(request as unknown as Request).catch(() => {});\n\n return new NextResponse(content, {\n status: 200,\n headers: { 'Content-Type': 'text/plain; charset=utf-8' },\n });\n } catch {\n return new NextResponse('Internal Server Error', {\n status: 500,\n headers: { 'Content-Type': 'text/plain; charset=utf-8' },\n });\n }\n }\n\n // ── Passthrough ────────────────────────────────────────────────\n const response = NextResponse.next();\n\n if (injectLink) {\n response.headers.set('Link', core.generateLinkHeader());\n }\n\n return response;\n };\n}\n","import { createGeoAI } from 'geo-ai-core';\nimport type { GeoAIConfig, GeoAIInstance } from 'geo-ai-core';\n\n// ── Config ──────────────────────────────────────────────────────────\n\nexport interface LlmsHandlerConfig extends GeoAIConfig {}\n\n// ── Route Handler factory ───────────────────────────────────────────\n\n/**\n * Creates a Next.js App Router route handler that serves llms.txt content.\n * File type is determined by URL path (`/llms-full.txt`) or query `?type=full`.\n *\n * Usage in `app/llms/route.ts`:\n * ```ts\n * export const { GET } = createLlmsHandler({ ... });\n * ```\n */\nexport function createLlmsHandler(config: LlmsHandlerConfig): {\n GET: (request: Request) => Promise<Response>;\n} {\n const core: GeoAIInstance = createGeoAI(config);\n\n return {\n async GET(request: Request): Promise<Response> {\n const url = new URL(request.url);\n const isFull =\n url.pathname.endsWith('/llms-full.txt') ||\n url.searchParams.get('type') === 'full';\n\n try {\n const content = await core.generateLlms(isFull);\n\n // Fire-and-forget: log bot visit without blocking the response\n core.trackVisit(request).catch(() => {});\n\n return new Response(content, {\n status: 200,\n headers: {\n 'Content-Type': 'text/plain; charset=utf-8',\n 'Cache-Control': 'public, max-age=3600',\n },\n });\n } catch {\n return new Response('Internal Server Error', {\n status: 500,\n headers: { 'Content-Type': 'text/plain; charset=utf-8' },\n });\n }\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,oBAA6B;AAE7B,yBAA4B;AAiBrB,SAAS,gBACd,QACiD;AACjD,QAAM,WAAsB,gCAAY,MAAM;AAC9C,QAAM,aAAa,OAAO,oBAAoB;AAE9C,SAAO,OAAO,YAAgD;AAC5D,UAAM,EAAE,SAAS,IAAI,QAAQ;AAG7B,QAAI,aAAa,eAAe,aAAa,kBAAkB;AAC7D,YAAM,SAAS,aAAa;AAE5B,UAAI;AACF,cAAM,UAAU,MAAM,KAAK,aAAa,MAAM;AAG9C,aAAK,WAAW,OAA6B,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAE7D,eAAO,IAAI,2BAAa,SAAS;AAAA,UAC/B,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,4BAA4B;AAAA,QACzD,CAAC;AAAA,MACH,QAAQ;AACN,eAAO,IAAI,2BAAa,yBAAyB;AAAA,UAC/C,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,4BAA4B;AAAA,QACzD,CAAC;AAAA,MACH;AAAA,IACF;AAGA,UAAM,WAAW,2BAAa,KAAK;AAEnC,QAAI,YAAY;AACd,eAAS,QAAQ,IAAI,QAAQ,KAAK,mBAAmB,CAAC;AAAA,IACxD;AAEA,WAAO;AAAA,EACT;AACF;;;AC3DA,IAAAA,sBAA4B;AAkBrB,SAAS,kBAAkB,QAEhC;AACA,QAAM,WAAsB,iCAAY,MAAM;AAE9C,SAAO;AAAA,IACL,MAAM,IAAI,SAAqC;AAC7C,YAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,YAAM,SACJ,IAAI,SAAS,SAAS,gBAAgB,KACtC,IAAI,aAAa,IAAI,MAAM,MAAM;AAEnC,UAAI;AACF,cAAM,UAAU,MAAM,KAAK,aAAa,MAAM;AAG9C,aAAK,WAAW,OAAO,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAEvC,eAAO,IAAI,SAAS,SAAS;AAAA,UAC3B,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,iBAAiB;AAAA,UACnB;AAAA,QACF,CAAC;AAAA,MACH,QAAQ;AACN,eAAO,IAAI,SAAS,yBAAyB;AAAA,UAC3C,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,4BAA4B;AAAA,QACzD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;AFxCA,IAAAC,sBAWO;","names":["import_geo_ai_core","import_geo_ai_core"]}
@@ -0,0 +1,31 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ import { GeoAIConfig } from 'geo-ai-core';
3
+ export { AI_BOTS, AiBulkConfig, AiContext, AiError, AiGeneratorConfig, AiProvider, BotRulesEngine, CacheAdapter, ContentProvider, CrawlActivity, CrawlEntry, CrawlStore, CrawlTracker, CrawlTrackingConfig, CryptoConfig, CryptoService, FileCacheAdapter, GeoAIConfig, GeoAIInstance, LlmsGenerator, MemoryCacheAdapter, MemoryCrawlStore, ProductResource, Resource, ResourceSection, SeoGenerator, createGeoAI } from 'geo-ai-core';
4
+
5
+ interface GeoAIMiddlewareConfig extends GeoAIConfig {
6
+ /** Inject Link header pointing to llms.txt on non-llms responses. Default: false */
7
+ injectLinkHeader?: boolean;
8
+ }
9
+ /**
10
+ * Creates a Next.js middleware function that intercepts `/llms.txt` and
11
+ * `/llms-full.txt` requests, returning generated content as `text/plain`.
12
+ * All other paths are passed through via `NextResponse.next()`.
13
+ */
14
+ declare function geoAIMiddleware(config: GeoAIMiddlewareConfig): (request: NextRequest) => Promise<NextResponse>;
15
+
16
+ interface LlmsHandlerConfig extends GeoAIConfig {
17
+ }
18
+ /**
19
+ * Creates a Next.js App Router route handler that serves llms.txt content.
20
+ * File type is determined by URL path (`/llms-full.txt`) or query `?type=full`.
21
+ *
22
+ * Usage in `app/llms/route.ts`:
23
+ * ```ts
24
+ * export const { GET } = createLlmsHandler({ ... });
25
+ * ```
26
+ */
27
+ declare function createLlmsHandler(config: LlmsHandlerConfig): {
28
+ GET: (request: Request) => Promise<Response>;
29
+ };
30
+
31
+ export { type GeoAIMiddlewareConfig, type LlmsHandlerConfig, createLlmsHandler, geoAIMiddleware };
@@ -0,0 +1,31 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ import { GeoAIConfig } from 'geo-ai-core';
3
+ export { AI_BOTS, AiBulkConfig, AiContext, AiError, AiGeneratorConfig, AiProvider, BotRulesEngine, CacheAdapter, ContentProvider, CrawlActivity, CrawlEntry, CrawlStore, CrawlTracker, CrawlTrackingConfig, CryptoConfig, CryptoService, FileCacheAdapter, GeoAIConfig, GeoAIInstance, LlmsGenerator, MemoryCacheAdapter, MemoryCrawlStore, ProductResource, Resource, ResourceSection, SeoGenerator, createGeoAI } from 'geo-ai-core';
4
+
5
+ interface GeoAIMiddlewareConfig extends GeoAIConfig {
6
+ /** Inject Link header pointing to llms.txt on non-llms responses. Default: false */
7
+ injectLinkHeader?: boolean;
8
+ }
9
+ /**
10
+ * Creates a Next.js middleware function that intercepts `/llms.txt` and
11
+ * `/llms-full.txt` requests, returning generated content as `text/plain`.
12
+ * All other paths are passed through via `NextResponse.next()`.
13
+ */
14
+ declare function geoAIMiddleware(config: GeoAIMiddlewareConfig): (request: NextRequest) => Promise<NextResponse>;
15
+
16
+ interface LlmsHandlerConfig extends GeoAIConfig {
17
+ }
18
+ /**
19
+ * Creates a Next.js App Router route handler that serves llms.txt content.
20
+ * File type is determined by URL path (`/llms-full.txt`) or query `?type=full`.
21
+ *
22
+ * Usage in `app/llms/route.ts`:
23
+ * ```ts
24
+ * export const { GET } = createLlmsHandler({ ... });
25
+ * ```
26
+ */
27
+ declare function createLlmsHandler(config: LlmsHandlerConfig): {
28
+ GET: (request: Request) => Promise<Response>;
29
+ };
30
+
31
+ export { type GeoAIMiddlewareConfig, type LlmsHandlerConfig, createLlmsHandler, geoAIMiddleware };
package/dist/index.mjs ADDED
@@ -0,0 +1,90 @@
1
+ // src/middleware.ts
2
+ import { NextResponse } from "next/server";
3
+ import { createGeoAI } from "geo-ai-core";
4
+ function geoAIMiddleware(config) {
5
+ const core = createGeoAI(config);
6
+ const injectLink = config.injectLinkHeader ?? false;
7
+ return async (request) => {
8
+ const { pathname } = request.nextUrl;
9
+ if (pathname === "/llms.txt" || pathname === "/llms-full.txt") {
10
+ const isFull = pathname === "/llms-full.txt";
11
+ try {
12
+ const content = await core.generateLlms(isFull);
13
+ core.trackVisit(request).catch(() => {
14
+ });
15
+ return new NextResponse(content, {
16
+ status: 200,
17
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
18
+ });
19
+ } catch {
20
+ return new NextResponse("Internal Server Error", {
21
+ status: 500,
22
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
23
+ });
24
+ }
25
+ }
26
+ const response = NextResponse.next();
27
+ if (injectLink) {
28
+ response.headers.set("Link", core.generateLinkHeader());
29
+ }
30
+ return response;
31
+ };
32
+ }
33
+
34
+ // src/handler.ts
35
+ import { createGeoAI as createGeoAI2 } from "geo-ai-core";
36
+ function createLlmsHandler(config) {
37
+ const core = createGeoAI2(config);
38
+ return {
39
+ async GET(request) {
40
+ const url = new URL(request.url);
41
+ const isFull = url.pathname.endsWith("/llms-full.txt") || url.searchParams.get("type") === "full";
42
+ try {
43
+ const content = await core.generateLlms(isFull);
44
+ core.trackVisit(request).catch(() => {
45
+ });
46
+ return new Response(content, {
47
+ status: 200,
48
+ headers: {
49
+ "Content-Type": "text/plain; charset=utf-8",
50
+ "Cache-Control": "public, max-age=3600"
51
+ }
52
+ });
53
+ } catch {
54
+ return new Response("Internal Server Error", {
55
+ status: 500,
56
+ headers: { "Content-Type": "text/plain; charset=utf-8" }
57
+ });
58
+ }
59
+ }
60
+ };
61
+ }
62
+
63
+ // src/index.ts
64
+ import {
65
+ createGeoAI as createGeoAI3,
66
+ MemoryCacheAdapter,
67
+ FileCacheAdapter,
68
+ CrawlTracker,
69
+ MemoryCrawlStore,
70
+ CryptoService,
71
+ BotRulesEngine,
72
+ AI_BOTS,
73
+ SeoGenerator,
74
+ LlmsGenerator
75
+ } from "geo-ai-core";
76
+ export {
77
+ AI_BOTS,
78
+ BotRulesEngine,
79
+ CrawlTracker,
80
+ CryptoService,
81
+ FileCacheAdapter,
82
+ LlmsGenerator,
83
+ MemoryCacheAdapter,
84
+ MemoryCrawlStore,
85
+ SeoGenerator,
86
+ createGeoAI3 as createGeoAI,
87
+ createLlmsHandler,
88
+ geoAIMiddleware
89
+ };
90
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/middleware.ts","../src/handler.ts","../src/index.ts"],"sourcesContent":["import { NextResponse } from 'next/server';\nimport type { NextRequest } from 'next/server';\nimport { createGeoAI } from 'geo-ai-core';\nimport type { GeoAIConfig, GeoAIInstance } from 'geo-ai-core';\n\n// ── Config ──────────────────────────────────────────────────────────\n\nexport interface GeoAIMiddlewareConfig extends GeoAIConfig {\n /** Inject Link header pointing to llms.txt on non-llms responses. Default: false */\n injectLinkHeader?: boolean;\n}\n\n// ── Middleware factory ───────────────────────────────────────────────\n\n/**\n * Creates a Next.js middleware function that intercepts `/llms.txt` and\n * `/llms-full.txt` requests, returning generated content as `text/plain`.\n * All other paths are passed through via `NextResponse.next()`.\n */\nexport function geoAIMiddleware(\n config: GeoAIMiddlewareConfig,\n): (request: NextRequest) => Promise<NextResponse> {\n const core: GeoAIInstance = createGeoAI(config);\n const injectLink = config.injectLinkHeader ?? false;\n\n return async (request: NextRequest): Promise<NextResponse> => {\n const { pathname } = request.nextUrl;\n\n // ── Match llms paths ───────────────────────────────────────────\n if (pathname === '/llms.txt' || pathname === '/llms-full.txt') {\n const isFull = pathname === '/llms-full.txt';\n\n try {\n const content = await core.generateLlms(isFull);\n\n // Fire-and-forget: track visit without blocking the response\n core.trackVisit(request as unknown as Request).catch(() => {});\n\n return new NextResponse(content, {\n status: 200,\n headers: { 'Content-Type': 'text/plain; charset=utf-8' },\n });\n } catch {\n return new NextResponse('Internal Server Error', {\n status: 500,\n headers: { 'Content-Type': 'text/plain; charset=utf-8' },\n });\n }\n }\n\n // ── Passthrough ────────────────────────────────────────────────\n const response = NextResponse.next();\n\n if (injectLink) {\n response.headers.set('Link', core.generateLinkHeader());\n }\n\n return response;\n };\n}\n","import { createGeoAI } from 'geo-ai-core';\nimport type { GeoAIConfig, GeoAIInstance } from 'geo-ai-core';\n\n// ── Config ──────────────────────────────────────────────────────────\n\nexport interface LlmsHandlerConfig extends GeoAIConfig {}\n\n// ── Route Handler factory ───────────────────────────────────────────\n\n/**\n * Creates a Next.js App Router route handler that serves llms.txt content.\n * File type is determined by URL path (`/llms-full.txt`) or query `?type=full`.\n *\n * Usage in `app/llms/route.ts`:\n * ```ts\n * export const { GET } = createLlmsHandler({ ... });\n * ```\n */\nexport function createLlmsHandler(config: LlmsHandlerConfig): {\n GET: (request: Request) => Promise<Response>;\n} {\n const core: GeoAIInstance = createGeoAI(config);\n\n return {\n async GET(request: Request): Promise<Response> {\n const url = new URL(request.url);\n const isFull =\n url.pathname.endsWith('/llms-full.txt') ||\n url.searchParams.get('type') === 'full';\n\n try {\n const content = await core.generateLlms(isFull);\n\n // Fire-and-forget: log bot visit without blocking the response\n core.trackVisit(request).catch(() => {});\n\n return new Response(content, {\n status: 200,\n headers: {\n 'Content-Type': 'text/plain; charset=utf-8',\n 'Cache-Control': 'public, max-age=3600',\n },\n });\n } catch {\n return new Response('Internal Server Error', {\n status: 500,\n headers: { 'Content-Type': 'text/plain; charset=utf-8' },\n });\n }\n },\n };\n}\n","// geo-ai-next main entry point\n\n// Next.js middleware\nexport { geoAIMiddleware } from './middleware';\nexport type { GeoAIMiddlewareConfig } from './middleware';\n\n// Next.js route handler\nexport { createLlmsHandler } from './handler';\nexport type { LlmsHandlerConfig } from './handler';\n\n// Re-export all public types, interfaces, and classes from geo-ai-core\nexport {\n createGeoAI,\n MemoryCacheAdapter,\n FileCacheAdapter,\n CrawlTracker,\n MemoryCrawlStore,\n CryptoService,\n BotRulesEngine,\n AI_BOTS,\n SeoGenerator,\n LlmsGenerator,\n} from 'geo-ai-core';\n\nexport type {\n GeoAIInstance,\n Resource,\n ProductResource,\n ResourceSection,\n ContentProvider,\n CacheAdapter,\n CrawlEntry,\n CrawlActivity,\n CrawlStore,\n CrawlTrackingConfig,\n CryptoConfig,\n GeoAIConfig,\n AiProvider,\n AiGeneratorConfig,\n AiError,\n AiBulkConfig,\n AiContext,\n} from 'geo-ai-core';\n"],"mappings":";AAAA,SAAS,oBAAoB;AAE7B,SAAS,mBAAmB;AAiBrB,SAAS,gBACd,QACiD;AACjD,QAAM,OAAsB,YAAY,MAAM;AAC9C,QAAM,aAAa,OAAO,oBAAoB;AAE9C,SAAO,OAAO,YAAgD;AAC5D,UAAM,EAAE,SAAS,IAAI,QAAQ;AAG7B,QAAI,aAAa,eAAe,aAAa,kBAAkB;AAC7D,YAAM,SAAS,aAAa;AAE5B,UAAI;AACF,cAAM,UAAU,MAAM,KAAK,aAAa,MAAM;AAG9C,aAAK,WAAW,OAA6B,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAE7D,eAAO,IAAI,aAAa,SAAS;AAAA,UAC/B,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,4BAA4B;AAAA,QACzD,CAAC;AAAA,MACH,QAAQ;AACN,eAAO,IAAI,aAAa,yBAAyB;AAAA,UAC/C,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,4BAA4B;AAAA,QACzD,CAAC;AAAA,MACH;AAAA,IACF;AAGA,UAAM,WAAW,aAAa,KAAK;AAEnC,QAAI,YAAY;AACd,eAAS,QAAQ,IAAI,QAAQ,KAAK,mBAAmB,CAAC;AAAA,IACxD;AAEA,WAAO;AAAA,EACT;AACF;;;AC3DA,SAAS,eAAAA,oBAAmB;AAkBrB,SAAS,kBAAkB,QAEhC;AACA,QAAM,OAAsBA,aAAY,MAAM;AAE9C,SAAO;AAAA,IACL,MAAM,IAAI,SAAqC;AAC7C,YAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,YAAM,SACJ,IAAI,SAAS,SAAS,gBAAgB,KACtC,IAAI,aAAa,IAAI,MAAM,MAAM;AAEnC,UAAI;AACF,cAAM,UAAU,MAAM,KAAK,aAAa,MAAM;AAG9C,aAAK,WAAW,OAAO,EAAE,MAAM,MAAM;AAAA,QAAC,CAAC;AAEvC,eAAO,IAAI,SAAS,SAAS;AAAA,UAC3B,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,iBAAiB;AAAA,UACnB;AAAA,QACF,CAAC;AAAA,MACH,QAAQ;AACN,eAAO,IAAI,SAAS,yBAAyB;AAAA,UAC3C,QAAQ;AAAA,UACR,SAAS,EAAE,gBAAgB,4BAA4B;AAAA,QACzD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;;;ACxCA;AAAA,EACE,eAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;","names":["createGeoAI","createGeoAI"]}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "geo-ai-next",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "import": "./dist/index.mjs",
9
+ "require": "./dist/index.cjs"
10
+ }
11
+ },
12
+ "main": "./dist/index.cjs",
13
+ "module": "./dist/index.mjs",
14
+ "types": "./dist/index.d.ts",
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup",
20
+ "typecheck": "tsc --noEmit"
21
+ },
22
+ "dependencies": {
23
+ "geo-ai-core": "*"
24
+ },
25
+ "engines": {
26
+ "node": ">=20"
27
+ },
28
+ "peerDependencies": {
29
+ "next": ">=16"
30
+ },
31
+ "devDependencies": {
32
+ "next": "^16.1.6",
33
+ "tsup": "^8.0.0",
34
+ "typescript": "^5.5.0"
35
+ }
36
+ }