@agentstats/sdk 0.5.0 → 0.5.1

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/server.d.cts CHANGED
@@ -1,12 +1,35 @@
1
- //#region src/bots.d.ts
2
1
  /**
3
- * Known bots, AI crawlers and AI agents, recognised by their User-Agent. This is the
4
- * table the AgentStats server classifies hits with, so what `detectBot()` says in your
5
- * app is what your dashboard shows.
2
+ * AgentStats server integration — see which AI crawlers and agents visit your
3
+ * site (GPTBot, ClaudeBot, PerplexityBot, ChatGPT agent, Google-Agent, …),
4
+ * including the ones that never run JavaScript.
6
5
  *
7
- * Sources: vendor documentation (OpenAI, Anthropic, Perplexity, Google, Microsoft,
8
- * Apple, Common Crawl, DuckDuckGo, Mistral) and the ai-robots-txt community list,
9
- * checked September 2026.
6
+ * Runs on Node and on edge runtimes (no Node built-ins). What leaves your server:
7
+ * - bot-like requests: method, URL, status, user agent, IP (used to verify the
8
+ * bot against the vendor's published ranges, then discarded) and Web Bot Auth
9
+ * signature headers;
10
+ * - visits referred by an AI assistant (chatgpt.com, perplexity.ai, …): URL and
11
+ * referrer host only;
12
+ * - everything else: a per-day count of page views. Nothing about humans.
13
+ *
14
+ * import { createAgentStats } from '@agentstats/sdk/server'
15
+ * const lens = createAgentStats({ serverKey: process.env.AGENTSTATS_SERVER_KEY })
16
+ * app.use(lens.express()) // Express / Connect: res.locals.bot
17
+ * export default defineNitroPlugin(lens.nitro()) // Nuxt / Nitro: event.context.bot
18
+ * export const handle = lens.sveltekit() // SvelteKit: event.locals.bot
19
+ * export const onRequest = lens.astro() // Astro: Astro.locals.bot
20
+ * app.use(lens.hono()) // Hono: c.get('bot')
21
+ * lens.track(request, { waitUntil, response }) // Next.js proxy, Workers, Bun, Deno
22
+ *
23
+ * Every adapter also hands you `detectBot()`'s answer for the request, and `detectBot`
24
+ * works on its own (no key needed): `detectBot(request).isAI`.
25
+ *
26
+ * With an `apiKey` (an API's key, `al_api_…`), the same adapters also track your API: calls an
27
+ * AI agent made (a Web Bot Auth signature, an `X-AI-Agent` header, an agent's User-Agent, or a
28
+ * credential you name in `apiCaller`) with method, route pattern, status and duration, and a
29
+ * per-day count of every other call. Never bodies, query strings or credentials: the caller is
30
+ * sent as an HMAC of its credential, keyed with your API key.
31
+ *
32
+ * const lens = createAgentStats({ apiKey: process.env.AGENTSTATS_API_KEY }) // API-only server
10
33
  */
11
34
  type BotCategory = 'training' | 'search' | 'assistant' | 'agent' | 'search_engine' | 'other';
12
35
  /** Categories that count as "AI traffic". Search engines and other bots are shown separately. */
@@ -126,6 +149,10 @@ export declare const BOT_PRODUCTS: {
126
149
  name: string;
127
150
  operator: string;
128
151
  };
152
+ ai: {
153
+ name: string;
154
+ operator: string;
155
+ };
129
156
  coding: {
130
157
  name: string;
131
158
  operator: string;
@@ -138,6 +165,10 @@ export declare const BOT_PRODUCTS: {
138
165
  name: string;
139
166
  operator: string;
140
167
  };
168
+ searchengines: {
169
+ name: string;
170
+ operator: string;
171
+ };
141
172
  automation: {
142
173
  name: string;
143
174
  operator: string;
@@ -154,6 +185,26 @@ export declare const BOT_PRODUCTS: {
154
185
  name: string;
155
186
  operator: string;
156
187
  };
188
+ feeds: {
189
+ name: string;
190
+ operator: string;
191
+ };
192
+ security: {
193
+ name: string;
194
+ operator: string;
195
+ };
196
+ archive: {
197
+ name: string;
198
+ operator: string;
199
+ };
200
+ research: {
201
+ name: string;
202
+ operator: string;
203
+ };
204
+ ads: {
205
+ name: string;
206
+ operator: string;
207
+ };
157
208
  tools: {
158
209
  name: string;
159
210
  operator: string;
@@ -171,11 +222,10 @@ interface BotPattern {
171
222
  category: BotCategory;
172
223
  /** Matched against the User-Agent header. `null` = only identified another way (signature). */
173
224
  pattern: RegExp | null;
225
+ /** Who runs it, when its product groups several vendors ("Other AI bots"). Else the product's operator. */
226
+ operator?: string;
174
227
  }
175
- /**
176
- * Order matters: the first matching pattern wins, so specific tokens come
177
- * before the vendor's generic ones and the catch-all patterns come last.
178
- */
228
+ /** Every bot this SDK recognises, in the order they're tried: the first match wins, catch-alls last. */
179
229
  export declare const BOT_PATTERNS: BotPattern[];
180
230
  /** Identify a bot from its User-Agent. Returns null for (what looks like) a normal browser. */
181
231
  export declare function classifyUserAgent(ua: string | null | undefined): BotPattern | null;
@@ -226,16 +276,14 @@ type DetectInput = Request | Headers | {
226
276
  * detectBot(req) // Node / Express IncomingMessage
227
277
  */
228
278
  export declare function detectBot(input: DetectInput): BotDetection;
229
- //#endregion
230
- //#region src/server.d.ts
231
- export declare const SERVER_SDK_VERSION = "0.3.1";
279
+ export declare const SERVER_SDK_VERSION = "0.3.2";
232
280
  export interface ServerOptions {
233
281
  /**
234
282
  * Secret server key from Site settings (`al_srv_…`). Never expose it to browsers.
235
283
  * Without one, the adapters still detect bots but nothing is sent.
236
284
  */
237
285
  serverKey?: string | undefined;
238
- /** Hits endpoint, e.g. `https://your-host/api/ingest/hits`. Defaults to `AGENTSTATS_ENDPOINT` or the build-time default. */
286
+ /** Hits endpoint. Defaults to `AGENTSTATS_ENDPOINT`, then `https://agentstats.io/api/ingest/hits`. */
239
287
  endpoint?: string;
240
288
  /**
241
289
  * Secret key of an API in your project (Project settings → APIs, `al_api_…`). Turns on API
@@ -380,6 +428,7 @@ export declare class AgentStatsServer {
380
428
  track(request: Request, init?: {
381
429
  status?: number | null;
382
430
  ip?: string | null;
431
+ remoteAddress?: string | null;
383
432
  response?: {
384
433
  headers: Headers;
385
434
  } | null;
@@ -411,9 +460,10 @@ export declare class AgentStatsServer {
411
460
  /** Astro: `export const onRequest = lens.astro()` in `src/middleware.ts` (or inside `sequence()`). The detection is on `Astro.locals.bot`. */
412
461
  astro(): (context: AstroContextLike, next: () => Promise<Response>) => Promise<Response>;
413
462
  /**
414
- * Nuxt / Nitro plugin: `export default defineNitroPlugin(lens.nitro())` in `server/plugins/agentstats.ts`.
463
+ * Nuxt / Nitro plugin: `export default defineNitroPlugin(lens.nitro())` in `server/plugins/agentstats.ts`
464
+ * (Nitro v3: `export default definePlugin(lens.nitro())`).
415
465
  * The detection is on `event.context.bot` in server routes, and on `useRequestEvent()?.context.bot` in pages.
416
- * Works on every Nitro preset (Node, Vercel, Netlify, Cloudflare…).
466
+ * Works on every Nitro preset (Node, Vercel, Netlify, Cloudflare…), on Nitro v2 (h3 v1) and v3 (h3 v2).
417
467
  */
418
468
  nitro(): (nitroApp: {
419
469
  hooks: {
@@ -509,8 +559,16 @@ export interface H3EventLike {
509
559
  web?: {
510
560
  request?: Request;
511
561
  };
562
+ /** h3 v2 (Nitro v3): the request (srvx adds `ip`), its parsed URL and the response being prepared. */
563
+ req?: Request & {
564
+ ip?: string;
565
+ };
566
+ url?: URL;
567
+ res?: {
568
+ status?: number;
569
+ headers: Headers;
570
+ };
512
571
  waitUntil?: WaitUntil;
513
572
  }
514
573
  export declare function createAgentStats(options: ServerOptions): AgentStatsServer;
515
- //#endregion
516
574
  export { type BotCategory, type BotDetection, type BotPattern, type BotProduct, type BotProductId, type DetectInput, createAgentStats as default };
package/dist/server.d.ts CHANGED
@@ -1,12 +1,35 @@
1
- //#region src/bots.d.ts
2
1
  /**
3
- * Known bots, AI crawlers and AI agents, recognised by their User-Agent. This is the
4
- * table the AgentStats server classifies hits with, so what `detectBot()` says in your
5
- * app is what your dashboard shows.
2
+ * AgentStats server integration — see which AI crawlers and agents visit your
3
+ * site (GPTBot, ClaudeBot, PerplexityBot, ChatGPT agent, Google-Agent, …),
4
+ * including the ones that never run JavaScript.
6
5
  *
7
- * Sources: vendor documentation (OpenAI, Anthropic, Perplexity, Google, Microsoft,
8
- * Apple, Common Crawl, DuckDuckGo, Mistral) and the ai-robots-txt community list,
9
- * checked September 2026.
6
+ * Runs on Node and on edge runtimes (no Node built-ins). What leaves your server:
7
+ * - bot-like requests: method, URL, status, user agent, IP (used to verify the
8
+ * bot against the vendor's published ranges, then discarded) and Web Bot Auth
9
+ * signature headers;
10
+ * - visits referred by an AI assistant (chatgpt.com, perplexity.ai, …): URL and
11
+ * referrer host only;
12
+ * - everything else: a per-day count of page views. Nothing about humans.
13
+ *
14
+ * import { createAgentStats } from '@agentstats/sdk/server'
15
+ * const lens = createAgentStats({ serverKey: process.env.AGENTSTATS_SERVER_KEY })
16
+ * app.use(lens.express()) // Express / Connect: res.locals.bot
17
+ * export default defineNitroPlugin(lens.nitro()) // Nuxt / Nitro: event.context.bot
18
+ * export const handle = lens.sveltekit() // SvelteKit: event.locals.bot
19
+ * export const onRequest = lens.astro() // Astro: Astro.locals.bot
20
+ * app.use(lens.hono()) // Hono: c.get('bot')
21
+ * lens.track(request, { waitUntil, response }) // Next.js proxy, Workers, Bun, Deno
22
+ *
23
+ * Every adapter also hands you `detectBot()`'s answer for the request, and `detectBot`
24
+ * works on its own (no key needed): `detectBot(request).isAI`.
25
+ *
26
+ * With an `apiKey` (an API's key, `al_api_…`), the same adapters also track your API: calls an
27
+ * AI agent made (a Web Bot Auth signature, an `X-AI-Agent` header, an agent's User-Agent, or a
28
+ * credential you name in `apiCaller`) with method, route pattern, status and duration, and a
29
+ * per-day count of every other call. Never bodies, query strings or credentials: the caller is
30
+ * sent as an HMAC of its credential, keyed with your API key.
31
+ *
32
+ * const lens = createAgentStats({ apiKey: process.env.AGENTSTATS_API_KEY }) // API-only server
10
33
  */
11
34
  type BotCategory = 'training' | 'search' | 'assistant' | 'agent' | 'search_engine' | 'other';
12
35
  /** Categories that count as "AI traffic". Search engines and other bots are shown separately. */
@@ -126,6 +149,10 @@ export declare const BOT_PRODUCTS: {
126
149
  name: string;
127
150
  operator: string;
128
151
  };
152
+ ai: {
153
+ name: string;
154
+ operator: string;
155
+ };
129
156
  coding: {
130
157
  name: string;
131
158
  operator: string;
@@ -138,6 +165,10 @@ export declare const BOT_PRODUCTS: {
138
165
  name: string;
139
166
  operator: string;
140
167
  };
168
+ searchengines: {
169
+ name: string;
170
+ operator: string;
171
+ };
141
172
  automation: {
142
173
  name: string;
143
174
  operator: string;
@@ -154,6 +185,26 @@ export declare const BOT_PRODUCTS: {
154
185
  name: string;
155
186
  operator: string;
156
187
  };
188
+ feeds: {
189
+ name: string;
190
+ operator: string;
191
+ };
192
+ security: {
193
+ name: string;
194
+ operator: string;
195
+ };
196
+ archive: {
197
+ name: string;
198
+ operator: string;
199
+ };
200
+ research: {
201
+ name: string;
202
+ operator: string;
203
+ };
204
+ ads: {
205
+ name: string;
206
+ operator: string;
207
+ };
157
208
  tools: {
158
209
  name: string;
159
210
  operator: string;
@@ -171,11 +222,10 @@ interface BotPattern {
171
222
  category: BotCategory;
172
223
  /** Matched against the User-Agent header. `null` = only identified another way (signature). */
173
224
  pattern: RegExp | null;
225
+ /** Who runs it, when its product groups several vendors ("Other AI bots"). Else the product's operator. */
226
+ operator?: string;
174
227
  }
175
- /**
176
- * Order matters: the first matching pattern wins, so specific tokens come
177
- * before the vendor's generic ones and the catch-all patterns come last.
178
- */
228
+ /** Every bot this SDK recognises, in the order they're tried: the first match wins, catch-alls last. */
179
229
  export declare const BOT_PATTERNS: BotPattern[];
180
230
  /** Identify a bot from its User-Agent. Returns null for (what looks like) a normal browser. */
181
231
  export declare function classifyUserAgent(ua: string | null | undefined): BotPattern | null;
@@ -226,16 +276,14 @@ type DetectInput = Request | Headers | {
226
276
  * detectBot(req) // Node / Express IncomingMessage
227
277
  */
228
278
  export declare function detectBot(input: DetectInput): BotDetection;
229
- //#endregion
230
- //#region src/server.d.ts
231
- export declare const SERVER_SDK_VERSION = "0.3.1";
279
+ export declare const SERVER_SDK_VERSION = "0.3.2";
232
280
  export interface ServerOptions {
233
281
  /**
234
282
  * Secret server key from Site settings (`al_srv_…`). Never expose it to browsers.
235
283
  * Without one, the adapters still detect bots but nothing is sent.
236
284
  */
237
285
  serverKey?: string | undefined;
238
- /** Hits endpoint, e.g. `https://your-host/api/ingest/hits`. Defaults to `AGENTSTATS_ENDPOINT` or the build-time default. */
286
+ /** Hits endpoint. Defaults to `AGENTSTATS_ENDPOINT`, then `https://agentstats.io/api/ingest/hits`. */
239
287
  endpoint?: string;
240
288
  /**
241
289
  * Secret key of an API in your project (Project settings → APIs, `al_api_…`). Turns on API
@@ -380,6 +428,7 @@ export declare class AgentStatsServer {
380
428
  track(request: Request, init?: {
381
429
  status?: number | null;
382
430
  ip?: string | null;
431
+ remoteAddress?: string | null;
383
432
  response?: {
384
433
  headers: Headers;
385
434
  } | null;
@@ -411,9 +460,10 @@ export declare class AgentStatsServer {
411
460
  /** Astro: `export const onRequest = lens.astro()` in `src/middleware.ts` (or inside `sequence()`). The detection is on `Astro.locals.bot`. */
412
461
  astro(): (context: AstroContextLike, next: () => Promise<Response>) => Promise<Response>;
413
462
  /**
414
- * Nuxt / Nitro plugin: `export default defineNitroPlugin(lens.nitro())` in `server/plugins/agentstats.ts`.
463
+ * Nuxt / Nitro plugin: `export default defineNitroPlugin(lens.nitro())` in `server/plugins/agentstats.ts`
464
+ * (Nitro v3: `export default definePlugin(lens.nitro())`).
415
465
  * The detection is on `event.context.bot` in server routes, and on `useRequestEvent()?.context.bot` in pages.
416
- * Works on every Nitro preset (Node, Vercel, Netlify, Cloudflare…).
466
+ * Works on every Nitro preset (Node, Vercel, Netlify, Cloudflare…), on Nitro v2 (h3 v1) and v3 (h3 v2).
417
467
  */
418
468
  nitro(): (nitroApp: {
419
469
  hooks: {
@@ -509,8 +559,16 @@ export interface H3EventLike {
509
559
  web?: {
510
560
  request?: Request;
511
561
  };
562
+ /** h3 v2 (Nitro v3): the request (srvx adds `ip`), its parsed URL and the response being prepared. */
563
+ req?: Request & {
564
+ ip?: string;
565
+ };
566
+ url?: URL;
567
+ res?: {
568
+ status?: number;
569
+ headers: Headers;
570
+ };
512
571
  waitUntil?: WaitUntil;
513
572
  }
514
573
  export declare function createAgentStats(options: ServerOptions): AgentStatsServer;
515
- //#endregion
516
574
  export { type BotCategory, type BotDetection, type BotPattern, type BotProduct, type BotProductId, type DetectInput, createAgentStats as default };