@kya-os/agentshield-nextjs 0.1.7

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/index.js ADDED
@@ -0,0 +1,198 @@
1
+ 'use strict';
2
+
3
+ var server = require('next/server');
4
+ var agentshield = require('@kya-os/agentshield');
5
+ var react = require('react');
6
+
7
+ // src/middleware.ts
8
+ function createAgentShieldMiddleware(config = {}) {
9
+ const detector = new agentshield.AgentDetector(config);
10
+ if (config.events) {
11
+ Object.entries(config.events).forEach(([event, handler]) => {
12
+ detector.on(event, handler);
13
+ });
14
+ }
15
+ const {
16
+ onAgentDetected = "log",
17
+ onDetection,
18
+ skipPaths = [],
19
+ blockedResponse = {
20
+ status: 403,
21
+ message: "Access denied: Automated agent detected",
22
+ headers: { "Content-Type": "application/json" }
23
+ },
24
+ redirectUrl = "/blocked",
25
+ rewriteUrl = "/blocked"
26
+ } = config;
27
+ return async (request) => {
28
+ try {
29
+ const shouldSkip = skipPaths.some((pattern) => {
30
+ if (typeof pattern === "string") {
31
+ return request.nextUrl.pathname.startsWith(pattern);
32
+ }
33
+ return pattern.test(request.nextUrl.pathname);
34
+ });
35
+ if (shouldSkip) {
36
+ request.agentShield = { skipped: true };
37
+ return server.NextResponse.next();
38
+ }
39
+ const context = {
40
+ userAgent: request.headers.get("user-agent") ?? void 0,
41
+ ipAddress: request.ip ?? request.headers.get("x-forwarded-for") ?? void 0,
42
+ headers: Object.fromEntries(request.headers.entries()),
43
+ url: request.url,
44
+ method: request.method,
45
+ timestamp: /* @__PURE__ */ new Date()
46
+ };
47
+ const result = await detector.analyze(context);
48
+ if (result.isAgent && result.confidence >= (config.confidenceThreshold ?? 0.7)) {
49
+ if (onDetection) {
50
+ const customResponse = await onDetection(request, result);
51
+ if (customResponse) {
52
+ return customResponse;
53
+ }
54
+ }
55
+ switch (onAgentDetected) {
56
+ case "block": {
57
+ const response2 = server.NextResponse.json(
58
+ {
59
+ error: blockedResponse.message,
60
+ detected: true,
61
+ confidence: result.confidence,
62
+ timestamp: result.timestamp
63
+ },
64
+ { status: blockedResponse.status }
65
+ );
66
+ if (blockedResponse.headers) {
67
+ Object.entries(blockedResponse.headers).forEach(
68
+ ([key, value]) => {
69
+ response2.headers.set(key, value);
70
+ }
71
+ );
72
+ }
73
+ detector.emit("agent.blocked", result, context);
74
+ return response2;
75
+ }
76
+ case "redirect":
77
+ return server.NextResponse.redirect(new URL(redirectUrl, request.url));
78
+ case "rewrite":
79
+ return server.NextResponse.rewrite(new URL(rewriteUrl, request.url));
80
+ case "log":
81
+ console.warn("AgentShield: Agent detected", {
82
+ ipAddress: context.ipAddress,
83
+ userAgent: context.userAgent,
84
+ confidence: result.confidence,
85
+ reasons: result.reasons,
86
+ pathname: request.nextUrl.pathname
87
+ });
88
+ break;
89
+ case "allow":
90
+ default:
91
+ if (result.isAgent && result.confidence >= (config.confidenceThreshold ?? 0.7)) {
92
+ detector.emit("agent.allowed", result, context);
93
+ }
94
+ break;
95
+ }
96
+ }
97
+ request.agentShield = {
98
+ result,
99
+ skipped: false
100
+ };
101
+ const response = server.NextResponse.next();
102
+ response.headers.set("x-agentshield-detected", result.isAgent.toString());
103
+ response.headers.set(
104
+ "x-agentshield-confidence",
105
+ result.confidence.toString()
106
+ );
107
+ return response;
108
+ } catch (error) {
109
+ console.error("AgentShield middleware error:", error);
110
+ return server.NextResponse.next();
111
+ }
112
+ };
113
+ }
114
+ function agentShield(config = {}) {
115
+ return createAgentShieldMiddleware(config);
116
+ }
117
+ function useAgentDetection(config = {}) {
118
+ const [detector] = react.useState(() => new agentshield.AgentDetector(config));
119
+ const [isDetecting, setIsDetecting] = react.useState(false);
120
+ const [lastResult, setLastResult] = react.useState(null);
121
+ const detect = react.useCallback(async () => {
122
+ setIsDetecting(true);
123
+ try {
124
+ const context = {
125
+ userAgent: navigator.userAgent,
126
+ headers: {},
127
+ // Client-side headers are limited
128
+ timestamp: /* @__PURE__ */ new Date()
129
+ };
130
+ const result = await detector.analyze(context);
131
+ setLastResult(result);
132
+ return result;
133
+ } finally {
134
+ setIsDetecting(false);
135
+ }
136
+ }, [detector]);
137
+ return {
138
+ detect,
139
+ isDetecting,
140
+ lastResult,
141
+ detector
142
+ };
143
+ }
144
+ function useDetectionMonitor(onDetection) {
145
+ const [detectionHistory, setDetectionHistory] = react.useState(
146
+ []
147
+ );
148
+ const addDetection = react.useCallback(
149
+ (result, request) => {
150
+ setDetectionHistory((prev) => [...prev, result].slice(-100));
151
+ if (onDetection && request) {
152
+ onDetection({
153
+ result,
154
+ request,
155
+ userAgent: request.headers?.get?.("user-agent"),
156
+ ip: request.ip
157
+ });
158
+ }
159
+ },
160
+ [onDetection]
161
+ );
162
+ const clearHistory = react.useCallback(() => {
163
+ setDetectionHistory([]);
164
+ }, []);
165
+ const getStats = react.useCallback(() => {
166
+ const total = detectionHistory.length;
167
+ const detected = detectionHistory.filter((r) => r.isAgent).length;
168
+ const avgConfidence = total > 0 ? detectionHistory.reduce((sum, r) => sum + r.confidence, 0) / total : 0;
169
+ return {
170
+ total,
171
+ detected,
172
+ avgConfidence,
173
+ detectionRate: total > 0 ? detected / total : 0
174
+ };
175
+ }, [detectionHistory]);
176
+ return {
177
+ detectionHistory,
178
+ addDetection,
179
+ clearHistory,
180
+ getStats
181
+ };
182
+ }
183
+
184
+ // src/index.ts
185
+ var VERSION = "0.1.0";
186
+ /**
187
+ * @fileoverview AgentShield Next.js Integration
188
+ * @version 0.1.0
189
+ * @license MIT OR Apache-2.0
190
+ */
191
+
192
+ exports.VERSION = VERSION;
193
+ exports.agentShield = agentShield;
194
+ exports.createAgentShieldMiddleware = createAgentShieldMiddleware;
195
+ exports.useAgentDetection = useAgentDetection;
196
+ exports.useDetectionMonitor = useDetectionMonitor;
197
+ //# sourceMappingURL=index.js.map
198
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/middleware.ts","../src/hooks.ts","../src/index.ts"],"names":["AgentDetector","NextResponse","response","useState","useCallback"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Next.js middleware for AgentShield\n */\n\nimport { NextRequest, NextResponse } from 'next/server';\nimport { AgentDetector } from '@kya-os/agentshield';\nimport type { NextJSMiddlewareConfig } from './types';\n\n/**\n * Create AgentShield middleware for Next.js\n */\nexport function createAgentShieldMiddleware(\n config: Partial<NextJSMiddlewareConfig> = {}\n) {\n const detector = new AgentDetector(config);\n \n // Wire up event handlers if provided\n if (config.events) {\n Object.entries(config.events).forEach(([event, handler]) => {\n detector.on(event as any, handler as any);\n });\n }\n\n const {\n onAgentDetected = 'log',\n onDetection,\n skipPaths = [],\n blockedResponse = {\n status: 403,\n message: 'Access denied: Automated agent detected',\n headers: { 'Content-Type': 'application/json' },\n },\n redirectUrl = '/blocked',\n rewriteUrl = '/blocked',\n } = config;\n\n return async (request: NextRequest): Promise<NextResponse> => {\n try {\n // Check if path should be skipped\n const shouldSkip = skipPaths.some(pattern => {\n if (typeof pattern === 'string') {\n return request.nextUrl.pathname.startsWith(pattern);\n }\n return pattern.test(request.nextUrl.pathname);\n });\n\n if (shouldSkip) {\n // Mark as skipped in request\n (request as any).agentShield = { skipped: true };\n return NextResponse.next();\n }\n\n // Prepare request context\n const context = {\n userAgent: request.headers.get('user-agent') ?? undefined,\n ipAddress: request.ip ?? request.headers.get('x-forwarded-for') ?? undefined,\n headers: Object.fromEntries(request.headers.entries()),\n url: request.url,\n method: request.method,\n timestamp: new Date(),\n };\n\n // Analyze request\n const result = await detector.analyze(context);\n\n // Handle detection result\n if (\n result.isAgent &&\n result.confidence >= (config.confidenceThreshold ?? 0.7)\n ) {\n // Call custom detection handler if provided\n if (onDetection) {\n const customResponse = await onDetection(request, result);\n if (customResponse) {\n return customResponse;\n }\n }\n\n // Handle based on configuration\n switch (onAgentDetected) {\n case 'block': {\n const response = NextResponse.json(\n {\n error: blockedResponse.message,\n detected: true,\n confidence: result.confidence,\n timestamp: result.timestamp,\n },\n { status: blockedResponse.status }\n );\n\n if (blockedResponse.headers) {\n Object.entries(blockedResponse.headers).forEach(\n ([key, value]) => {\n response.headers.set(key, value);\n }\n );\n }\n \n // Emit blocked event\n detector.emit('agent.blocked', result, context);\n\n return response;\n }\n\n case 'redirect':\n return NextResponse.redirect(new URL(redirectUrl, request.url));\n\n case 'rewrite':\n return NextResponse.rewrite(new URL(rewriteUrl, request.url));\n\n case 'log':\n console.warn('AgentShield: Agent detected', {\n ipAddress: context.ipAddress,\n userAgent: context.userAgent,\n confidence: result.confidence,\n reasons: result.reasons,\n pathname: request.nextUrl.pathname,\n });\n break;\n\n case 'allow':\n default:\n // Emit allowed event for high-confidence agents\n if (result.isAgent && result.confidence >= (config.confidenceThreshold ?? 0.7)) {\n detector.emit('agent.allowed', result, context);\n }\n // Continue processing\n break;\n }\n }\n\n // Add detection result to request for API routes\n (request as any).agentShield = {\n result,\n skipped: false,\n };\n\n // Add detection result to response headers for debugging\n const response = NextResponse.next();\n response.headers.set('x-agentshield-detected', result.isAgent.toString());\n response.headers.set(\n 'x-agentshield-confidence',\n result.confidence.toString()\n );\n\n return response;\n } catch (error) {\n console.error('AgentShield middleware error:', error);\n return NextResponse.next(); // Continue on error\n }\n };\n}\n\n/**\n * Convenience function for basic setup\n */\nexport function agentShield(config: Partial<NextJSMiddlewareConfig> = {}) {\n return createAgentShieldMiddleware(config);\n}\n","/**\n * React hooks for AgentShield in Next.js applications\n */\n\nimport { useState, useCallback } from 'react';\nimport { AgentDetector } from '@kya-os/agentshield';\nimport type { DetectionResult, AgentShieldConfig } from '@kya-os/agentshield';\nimport type { DetectionContext } from './types';\n\n/**\n * Hook for client-side agent detection\n */\nexport function useAgentDetection(config: Partial<AgentShieldConfig> = {}) {\n const [detector] = useState(() => new AgentDetector(config));\n const [isDetecting, setIsDetecting] = useState(false);\n const [lastResult, setLastResult] = useState<DetectionResult | null>(null);\n\n const detect = useCallback(async () => {\n setIsDetecting(true);\n try {\n const context = {\n userAgent: navigator.userAgent,\n headers: {}, // Client-side headers are limited\n timestamp: new Date(),\n };\n\n const result = await detector.analyze(context);\n setLastResult(result);\n return result;\n } finally {\n setIsDetecting(false);\n }\n }, [detector]);\n\n return {\n detect,\n isDetecting,\n lastResult,\n detector,\n };\n}\n\n/**\n * Hook for monitoring detection results\n */\nexport function useDetectionMonitor(\n onDetection?: (context: DetectionContext) => void\n) {\n const [detectionHistory, setDetectionHistory] = useState<DetectionResult[]>(\n []\n );\n\n const addDetection = useCallback(\n (result: DetectionResult, request?: any) => {\n setDetectionHistory(prev => [...prev, result].slice(-100)); // Keep last 100\n\n if (onDetection && request) {\n onDetection({\n result,\n request,\n userAgent: request.headers?.get?.('user-agent'),\n ip: request.ip,\n });\n }\n },\n [onDetection]\n );\n\n const clearHistory = useCallback(() => {\n setDetectionHistory([]);\n }, []);\n\n const getStats = useCallback(() => {\n const total = detectionHistory.length;\n const detected = detectionHistory.filter(r => r.isAgent).length;\n const avgConfidence =\n total > 0\n ? detectionHistory.reduce((sum, r) => sum + r.confidence, 0) / total\n : 0;\n\n return {\n total,\n detected,\n avgConfidence,\n detectionRate: total > 0 ? detected / total : 0,\n };\n }, [detectionHistory]);\n\n return {\n detectionHistory,\n addDetection,\n clearHistory,\n getStats,\n };\n}\n","/**\n * @fileoverview AgentShield Next.js Integration\n * @version 0.1.0\n * @license MIT OR Apache-2.0\n */\n\nexport * from './middleware';\nexport * from './types';\nexport * from './hooks';\n\n/**\n * Library version\n */\nexport const VERSION = '0.1.0';\n"]}
package/dist/index.mjs ADDED
@@ -0,0 +1,192 @@
1
+ import { NextResponse } from 'next/server';
2
+ import { AgentDetector } from '@kya-os/agentshield';
3
+ import { useState, useCallback } from 'react';
4
+
5
+ // src/middleware.ts
6
+ function createAgentShieldMiddleware(config = {}) {
7
+ const detector = new AgentDetector(config);
8
+ if (config.events) {
9
+ Object.entries(config.events).forEach(([event, handler]) => {
10
+ detector.on(event, handler);
11
+ });
12
+ }
13
+ const {
14
+ onAgentDetected = "log",
15
+ onDetection,
16
+ skipPaths = [],
17
+ blockedResponse = {
18
+ status: 403,
19
+ message: "Access denied: Automated agent detected",
20
+ headers: { "Content-Type": "application/json" }
21
+ },
22
+ redirectUrl = "/blocked",
23
+ rewriteUrl = "/blocked"
24
+ } = config;
25
+ return async (request) => {
26
+ try {
27
+ const shouldSkip = skipPaths.some((pattern) => {
28
+ if (typeof pattern === "string") {
29
+ return request.nextUrl.pathname.startsWith(pattern);
30
+ }
31
+ return pattern.test(request.nextUrl.pathname);
32
+ });
33
+ if (shouldSkip) {
34
+ request.agentShield = { skipped: true };
35
+ return NextResponse.next();
36
+ }
37
+ const context = {
38
+ userAgent: request.headers.get("user-agent") ?? void 0,
39
+ ipAddress: request.ip ?? request.headers.get("x-forwarded-for") ?? void 0,
40
+ headers: Object.fromEntries(request.headers.entries()),
41
+ url: request.url,
42
+ method: request.method,
43
+ timestamp: /* @__PURE__ */ new Date()
44
+ };
45
+ const result = await detector.analyze(context);
46
+ if (result.isAgent && result.confidence >= (config.confidenceThreshold ?? 0.7)) {
47
+ if (onDetection) {
48
+ const customResponse = await onDetection(request, result);
49
+ if (customResponse) {
50
+ return customResponse;
51
+ }
52
+ }
53
+ switch (onAgentDetected) {
54
+ case "block": {
55
+ const response2 = NextResponse.json(
56
+ {
57
+ error: blockedResponse.message,
58
+ detected: true,
59
+ confidence: result.confidence,
60
+ timestamp: result.timestamp
61
+ },
62
+ { status: blockedResponse.status }
63
+ );
64
+ if (blockedResponse.headers) {
65
+ Object.entries(blockedResponse.headers).forEach(
66
+ ([key, value]) => {
67
+ response2.headers.set(key, value);
68
+ }
69
+ );
70
+ }
71
+ detector.emit("agent.blocked", result, context);
72
+ return response2;
73
+ }
74
+ case "redirect":
75
+ return NextResponse.redirect(new URL(redirectUrl, request.url));
76
+ case "rewrite":
77
+ return NextResponse.rewrite(new URL(rewriteUrl, request.url));
78
+ case "log":
79
+ console.warn("AgentShield: Agent detected", {
80
+ ipAddress: context.ipAddress,
81
+ userAgent: context.userAgent,
82
+ confidence: result.confidence,
83
+ reasons: result.reasons,
84
+ pathname: request.nextUrl.pathname
85
+ });
86
+ break;
87
+ case "allow":
88
+ default:
89
+ if (result.isAgent && result.confidence >= (config.confidenceThreshold ?? 0.7)) {
90
+ detector.emit("agent.allowed", result, context);
91
+ }
92
+ break;
93
+ }
94
+ }
95
+ request.agentShield = {
96
+ result,
97
+ skipped: false
98
+ };
99
+ const response = NextResponse.next();
100
+ response.headers.set("x-agentshield-detected", result.isAgent.toString());
101
+ response.headers.set(
102
+ "x-agentshield-confidence",
103
+ result.confidence.toString()
104
+ );
105
+ return response;
106
+ } catch (error) {
107
+ console.error("AgentShield middleware error:", error);
108
+ return NextResponse.next();
109
+ }
110
+ };
111
+ }
112
+ function agentShield(config = {}) {
113
+ return createAgentShieldMiddleware(config);
114
+ }
115
+ function useAgentDetection(config = {}) {
116
+ const [detector] = useState(() => new AgentDetector(config));
117
+ const [isDetecting, setIsDetecting] = useState(false);
118
+ const [lastResult, setLastResult] = useState(null);
119
+ const detect = useCallback(async () => {
120
+ setIsDetecting(true);
121
+ try {
122
+ const context = {
123
+ userAgent: navigator.userAgent,
124
+ headers: {},
125
+ // Client-side headers are limited
126
+ timestamp: /* @__PURE__ */ new Date()
127
+ };
128
+ const result = await detector.analyze(context);
129
+ setLastResult(result);
130
+ return result;
131
+ } finally {
132
+ setIsDetecting(false);
133
+ }
134
+ }, [detector]);
135
+ return {
136
+ detect,
137
+ isDetecting,
138
+ lastResult,
139
+ detector
140
+ };
141
+ }
142
+ function useDetectionMonitor(onDetection) {
143
+ const [detectionHistory, setDetectionHistory] = useState(
144
+ []
145
+ );
146
+ const addDetection = useCallback(
147
+ (result, request) => {
148
+ setDetectionHistory((prev) => [...prev, result].slice(-100));
149
+ if (onDetection && request) {
150
+ onDetection({
151
+ result,
152
+ request,
153
+ userAgent: request.headers?.get?.("user-agent"),
154
+ ip: request.ip
155
+ });
156
+ }
157
+ },
158
+ [onDetection]
159
+ );
160
+ const clearHistory = useCallback(() => {
161
+ setDetectionHistory([]);
162
+ }, []);
163
+ const getStats = useCallback(() => {
164
+ const total = detectionHistory.length;
165
+ const detected = detectionHistory.filter((r) => r.isAgent).length;
166
+ const avgConfidence = total > 0 ? detectionHistory.reduce((sum, r) => sum + r.confidence, 0) / total : 0;
167
+ return {
168
+ total,
169
+ detected,
170
+ avgConfidence,
171
+ detectionRate: total > 0 ? detected / total : 0
172
+ };
173
+ }, [detectionHistory]);
174
+ return {
175
+ detectionHistory,
176
+ addDetection,
177
+ clearHistory,
178
+ getStats
179
+ };
180
+ }
181
+
182
+ // src/index.ts
183
+ var VERSION = "0.1.0";
184
+ /**
185
+ * @fileoverview AgentShield Next.js Integration
186
+ * @version 0.1.0
187
+ * @license MIT OR Apache-2.0
188
+ */
189
+
190
+ export { VERSION, agentShield, createAgentShieldMiddleware, useAgentDetection, useDetectionMonitor };
191
+ //# sourceMappingURL=index.mjs.map
192
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/middleware.ts","../src/hooks.ts","../src/index.ts"],"names":["response","AgentDetector"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Next.js middleware for AgentShield\n */\n\nimport { NextRequest, NextResponse } from 'next/server';\nimport { AgentDetector } from '@kya-os/agentshield';\nimport type { NextJSMiddlewareConfig } from './types';\n\n/**\n * Create AgentShield middleware for Next.js\n */\nexport function createAgentShieldMiddleware(\n config: Partial<NextJSMiddlewareConfig> = {}\n) {\n const detector = new AgentDetector(config);\n \n // Wire up event handlers if provided\n if (config.events) {\n Object.entries(config.events).forEach(([event, handler]) => {\n detector.on(event as any, handler as any);\n });\n }\n\n const {\n onAgentDetected = 'log',\n onDetection,\n skipPaths = [],\n blockedResponse = {\n status: 403,\n message: 'Access denied: Automated agent detected',\n headers: { 'Content-Type': 'application/json' },\n },\n redirectUrl = '/blocked',\n rewriteUrl = '/blocked',\n } = config;\n\n return async (request: NextRequest): Promise<NextResponse> => {\n try {\n // Check if path should be skipped\n const shouldSkip = skipPaths.some(pattern => {\n if (typeof pattern === 'string') {\n return request.nextUrl.pathname.startsWith(pattern);\n }\n return pattern.test(request.nextUrl.pathname);\n });\n\n if (shouldSkip) {\n // Mark as skipped in request\n (request as any).agentShield = { skipped: true };\n return NextResponse.next();\n }\n\n // Prepare request context\n const context = {\n userAgent: request.headers.get('user-agent') ?? undefined,\n ipAddress: request.ip ?? request.headers.get('x-forwarded-for') ?? undefined,\n headers: Object.fromEntries(request.headers.entries()),\n url: request.url,\n method: request.method,\n timestamp: new Date(),\n };\n\n // Analyze request\n const result = await detector.analyze(context);\n\n // Handle detection result\n if (\n result.isAgent &&\n result.confidence >= (config.confidenceThreshold ?? 0.7)\n ) {\n // Call custom detection handler if provided\n if (onDetection) {\n const customResponse = await onDetection(request, result);\n if (customResponse) {\n return customResponse;\n }\n }\n\n // Handle based on configuration\n switch (onAgentDetected) {\n case 'block': {\n const response = NextResponse.json(\n {\n error: blockedResponse.message,\n detected: true,\n confidence: result.confidence,\n timestamp: result.timestamp,\n },\n { status: blockedResponse.status }\n );\n\n if (blockedResponse.headers) {\n Object.entries(blockedResponse.headers).forEach(\n ([key, value]) => {\n response.headers.set(key, value);\n }\n );\n }\n \n // Emit blocked event\n detector.emit('agent.blocked', result, context);\n\n return response;\n }\n\n case 'redirect':\n return NextResponse.redirect(new URL(redirectUrl, request.url));\n\n case 'rewrite':\n return NextResponse.rewrite(new URL(rewriteUrl, request.url));\n\n case 'log':\n console.warn('AgentShield: Agent detected', {\n ipAddress: context.ipAddress,\n userAgent: context.userAgent,\n confidence: result.confidence,\n reasons: result.reasons,\n pathname: request.nextUrl.pathname,\n });\n break;\n\n case 'allow':\n default:\n // Emit allowed event for high-confidence agents\n if (result.isAgent && result.confidence >= (config.confidenceThreshold ?? 0.7)) {\n detector.emit('agent.allowed', result, context);\n }\n // Continue processing\n break;\n }\n }\n\n // Add detection result to request for API routes\n (request as any).agentShield = {\n result,\n skipped: false,\n };\n\n // Add detection result to response headers for debugging\n const response = NextResponse.next();\n response.headers.set('x-agentshield-detected', result.isAgent.toString());\n response.headers.set(\n 'x-agentshield-confidence',\n result.confidence.toString()\n );\n\n return response;\n } catch (error) {\n console.error('AgentShield middleware error:', error);\n return NextResponse.next(); // Continue on error\n }\n };\n}\n\n/**\n * Convenience function for basic setup\n */\nexport function agentShield(config: Partial<NextJSMiddlewareConfig> = {}) {\n return createAgentShieldMiddleware(config);\n}\n","/**\n * React hooks for AgentShield in Next.js applications\n */\n\nimport { useState, useCallback } from 'react';\nimport { AgentDetector } from '@kya-os/agentshield';\nimport type { DetectionResult, AgentShieldConfig } from '@kya-os/agentshield';\nimport type { DetectionContext } from './types';\n\n/**\n * Hook for client-side agent detection\n */\nexport function useAgentDetection(config: Partial<AgentShieldConfig> = {}) {\n const [detector] = useState(() => new AgentDetector(config));\n const [isDetecting, setIsDetecting] = useState(false);\n const [lastResult, setLastResult] = useState<DetectionResult | null>(null);\n\n const detect = useCallback(async () => {\n setIsDetecting(true);\n try {\n const context = {\n userAgent: navigator.userAgent,\n headers: {}, // Client-side headers are limited\n timestamp: new Date(),\n };\n\n const result = await detector.analyze(context);\n setLastResult(result);\n return result;\n } finally {\n setIsDetecting(false);\n }\n }, [detector]);\n\n return {\n detect,\n isDetecting,\n lastResult,\n detector,\n };\n}\n\n/**\n * Hook for monitoring detection results\n */\nexport function useDetectionMonitor(\n onDetection?: (context: DetectionContext) => void\n) {\n const [detectionHistory, setDetectionHistory] = useState<DetectionResult[]>(\n []\n );\n\n const addDetection = useCallback(\n (result: DetectionResult, request?: any) => {\n setDetectionHistory(prev => [...prev, result].slice(-100)); // Keep last 100\n\n if (onDetection && request) {\n onDetection({\n result,\n request,\n userAgent: request.headers?.get?.('user-agent'),\n ip: request.ip,\n });\n }\n },\n [onDetection]\n );\n\n const clearHistory = useCallback(() => {\n setDetectionHistory([]);\n }, []);\n\n const getStats = useCallback(() => {\n const total = detectionHistory.length;\n const detected = detectionHistory.filter(r => r.isAgent).length;\n const avgConfidence =\n total > 0\n ? detectionHistory.reduce((sum, r) => sum + r.confidence, 0) / total\n : 0;\n\n return {\n total,\n detected,\n avgConfidence,\n detectionRate: total > 0 ? detected / total : 0,\n };\n }, [detectionHistory]);\n\n return {\n detectionHistory,\n addDetection,\n clearHistory,\n getStats,\n };\n}\n","/**\n * @fileoverview AgentShield Next.js Integration\n * @version 0.1.0\n * @license MIT OR Apache-2.0\n */\n\nexport * from './middleware';\nexport * from './types';\nexport * from './hooks';\n\n/**\n * Library version\n */\nexport const VERSION = '0.1.0';\n"]}
@@ -0,0 +1,73 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ import { AgentShieldConfig, DetectionResult, AgentShieldEvents } from '@kya-os/agentshield';
3
+
4
+ /**
5
+ * Next.js-specific type definitions
6
+ */
7
+
8
+ /**
9
+ * Next.js middleware configuration
10
+ */
11
+ interface NextJSMiddlewareConfig extends Partial<AgentShieldConfig> {
12
+ /**
13
+ * Action to take when an agent is detected
14
+ */
15
+ onAgentDetected?: 'block' | 'redirect' | 'rewrite' | 'allow' | 'log';
16
+ /**
17
+ * Custom handler for agent detection
18
+ * @deprecated Use 'events' instead. Will be removed in v1.0.0
19
+ */
20
+ onDetection?: (req: NextRequest, result: DetectionResult) => NextResponse | Promise<NextResponse> | void | Promise<void>;
21
+ /**
22
+ * Event handlers for detection events
23
+ */
24
+ events?: Partial<AgentShieldEvents>;
25
+ /**
26
+ * Path patterns to skip detection
27
+ */
28
+ skipPaths?: string[] | RegExp[];
29
+ /**
30
+ * Response when blocking agents
31
+ */
32
+ blockedResponse?: {
33
+ status: number;
34
+ message: string;
35
+ headers?: Record<string, string>;
36
+ };
37
+ /**
38
+ * Redirect URL when redirecting detected agents
39
+ */
40
+ redirectUrl?: string;
41
+ /**
42
+ * Rewrite URL when rewriting requests from detected agents
43
+ */
44
+ rewriteUrl?: string;
45
+ /**
46
+ * Confidence threshold for agent detection
47
+ */
48
+ confidenceThreshold?: number;
49
+ }
50
+ /**
51
+ * Detection context for hooks
52
+ */
53
+ interface DetectionContext {
54
+ result: DetectionResult;
55
+ request: NextRequest;
56
+ userAgent?: string;
57
+ ip?: string;
58
+ }
59
+
60
+ /**
61
+ * Next.js middleware for AgentShield
62
+ */
63
+
64
+ /**
65
+ * Create AgentShield middleware for Next.js
66
+ */
67
+ declare function createAgentShieldMiddleware(config?: Partial<NextJSMiddlewareConfig>): (request: NextRequest) => Promise<NextResponse>;
68
+ /**
69
+ * Convenience function for basic setup
70
+ */
71
+ declare function agentShield(config?: Partial<NextJSMiddlewareConfig>): (request: NextRequest) => Promise<NextResponse>;
72
+
73
+ export { type DetectionContext as D, type NextJSMiddlewareConfig as N, agentShield as a, createAgentShieldMiddleware as c };
@@ -0,0 +1,73 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ import { AgentShieldConfig, DetectionResult, AgentShieldEvents } from '@kya-os/agentshield';
3
+
4
+ /**
5
+ * Next.js-specific type definitions
6
+ */
7
+
8
+ /**
9
+ * Next.js middleware configuration
10
+ */
11
+ interface NextJSMiddlewareConfig extends Partial<AgentShieldConfig> {
12
+ /**
13
+ * Action to take when an agent is detected
14
+ */
15
+ onAgentDetected?: 'block' | 'redirect' | 'rewrite' | 'allow' | 'log';
16
+ /**
17
+ * Custom handler for agent detection
18
+ * @deprecated Use 'events' instead. Will be removed in v1.0.0
19
+ */
20
+ onDetection?: (req: NextRequest, result: DetectionResult) => NextResponse | Promise<NextResponse> | void | Promise<void>;
21
+ /**
22
+ * Event handlers for detection events
23
+ */
24
+ events?: Partial<AgentShieldEvents>;
25
+ /**
26
+ * Path patterns to skip detection
27
+ */
28
+ skipPaths?: string[] | RegExp[];
29
+ /**
30
+ * Response when blocking agents
31
+ */
32
+ blockedResponse?: {
33
+ status: number;
34
+ message: string;
35
+ headers?: Record<string, string>;
36
+ };
37
+ /**
38
+ * Redirect URL when redirecting detected agents
39
+ */
40
+ redirectUrl?: string;
41
+ /**
42
+ * Rewrite URL when rewriting requests from detected agents
43
+ */
44
+ rewriteUrl?: string;
45
+ /**
46
+ * Confidence threshold for agent detection
47
+ */
48
+ confidenceThreshold?: number;
49
+ }
50
+ /**
51
+ * Detection context for hooks
52
+ */
53
+ interface DetectionContext {
54
+ result: DetectionResult;
55
+ request: NextRequest;
56
+ userAgent?: string;
57
+ ip?: string;
58
+ }
59
+
60
+ /**
61
+ * Next.js middleware for AgentShield
62
+ */
63
+
64
+ /**
65
+ * Create AgentShield middleware for Next.js
66
+ */
67
+ declare function createAgentShieldMiddleware(config?: Partial<NextJSMiddlewareConfig>): (request: NextRequest) => Promise<NextResponse>;
68
+ /**
69
+ * Convenience function for basic setup
70
+ */
71
+ declare function agentShield(config?: Partial<NextJSMiddlewareConfig>): (request: NextRequest) => Promise<NextResponse>;
72
+
73
+ export { type DetectionContext as D, type NextJSMiddlewareConfig as N, agentShield as a, createAgentShieldMiddleware as c };
@@ -0,0 +1,3 @@
1
+ import 'next/server';
2
+ export { a as agentShield, c as createAgentShieldMiddleware } from './middleware-OvcbG6s2.mjs';
3
+ import '@kya-os/agentshield';
@@ -0,0 +1,3 @@
1
+ import 'next/server';
2
+ export { a as agentShield, c as createAgentShieldMiddleware } from './middleware-OvcbG6s2.js';
3
+ import '@kya-os/agentshield';