@parsrun/server 0.1.28 → 0.1.29

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.
@@ -1,489 +1,10 @@
1
- import { HonoContext, HonoNext, CorsConfig, ApiResponse } from '../context.js';
2
- import * as hono from 'hono';
3
- import * as hono_utils_types from 'hono/utils/types';
4
- import { ErrorTransport } from '@parsrun/core/transports';
1
+ export { h as ApiError, A as AuthMiddlewareOptions, B as BadRequestError, i as ConflictError, C as CsrfOptions, E as ErrorHandlerOptions, F as ForbiddenError, I as InternalError, J as JwtPayload, b as JwtVerifier, M as MemoryRateLimitStorage, N as NotFoundError, D as QuotaCheckResult, y as QuotaEnforcementOptions, Q as QuotaExceededError, z as QuotaManagerLike, R as RateLimitError, k as RateLimitOptions, l as RateLimitStorage, p as RequestLoggerOptions, S as ServiceUnavailableError, U as UnauthorizedError, t as UsageServiceLike, s as UsageTrackingOptions, V as ValidationError, a as auth, d as cors, c as createAuthMiddleware, w as createQuotaEnforcement, j as createRateLimiter, q as createUsageTracking, e as csrf, f as doubleSubmitCookie, g as errorHandler, x as multiQuotaEnforcement, n as notFoundHandler, o as optionalAuth, v as quotaEnforcement, r as rateLimit, m as requestLogger, u as usageTracking } from '../quota-enforcement-CN3z5bfc.js';
2
+ import { HonoContext, HonoNext, TraceContext } from '../context.js';
3
+ import 'hono';
4
+ import 'hono/utils/types';
5
+ import '@parsrun/core/transports';
5
6
  import '@parsrun/core';
6
7
 
7
- /**
8
- * @parsrun/server - Auth Middleware
9
- * JWT authentication middleware
10
- */
11
-
12
- /**
13
- * JWT payload structure
14
- */
15
- interface JwtPayload {
16
- sub: string;
17
- email?: string;
18
- tenantId?: string;
19
- role?: string;
20
- permissions?: string[];
21
- iat?: number;
22
- exp?: number;
23
- jti?: string;
24
- }
25
- /**
26
- * JWT verification function type
27
- */
28
- type JwtVerifier = (token: string) => Promise<JwtPayload | null>;
29
- /**
30
- * Auth middleware options
31
- */
32
- interface AuthMiddlewareOptions {
33
- /** JWT verification function */
34
- verify: JwtVerifier;
35
- /** Header name for token (default: Authorization) */
36
- header?: string;
37
- /** Token prefix (default: Bearer) */
38
- prefix?: string;
39
- /** Cookie name for token (alternative to header) */
40
- cookie?: string;
41
- /** Skip auth for certain requests */
42
- skip?: (c: HonoContext) => boolean;
43
- /** Custom error message */
44
- message?: string;
45
- }
46
- /**
47
- * Auth middleware - requires valid JWT
48
- *
49
- * @example
50
- * ```typescript
51
- * import { verifyJwt } from '@parsrun/auth';
52
- *
53
- * const authMiddleware = auth({
54
- * verify: (token) => verifyJwt(token, secret),
55
- * cookie: 'auth_token',
56
- * });
57
- *
58
- * app.use('/api/*', authMiddleware);
59
- *
60
- * // Access user in handlers
61
- * app.get('/api/me', (c) => {
62
- * const user = c.get('user');
63
- * return c.json({ user });
64
- * });
65
- * ```
66
- */
67
- declare function auth(options: AuthMiddlewareOptions): (c: HonoContext, next: HonoNext) => Promise<void>;
68
- /**
69
- * Optional auth middleware - sets user if token present, but doesn't require it
70
- *
71
- * @example
72
- * ```typescript
73
- * app.use('/api/public/*', optionalAuth({
74
- * verify: (token) => verifyJwt(token, secret),
75
- * }));
76
- *
77
- * // User may or may not be present
78
- * app.get('/api/public/items', (c) => {
79
- * const user = c.get('user'); // may be undefined
80
- * // Return different data based on auth status
81
- * });
82
- * ```
83
- */
84
- declare function optionalAuth(options: Omit<AuthMiddlewareOptions, "message">): (c: HonoContext, next: HonoNext) => Promise<void>;
85
- /**
86
- * Create auth middleware from verifier function
87
- *
88
- * @example
89
- * ```typescript
90
- * const { auth, optionalAuth } = createAuthMiddleware({
91
- * verify: async (token) => {
92
- * return verifyJwt(token, process.env.JWT_SECRET);
93
- * },
94
- * cookie: 'session',
95
- * });
96
- *
97
- * app.use('/api/*', auth);
98
- * app.use('/public/*', optionalAuth);
99
- * ```
100
- */
101
- declare function createAuthMiddleware(baseOptions: Omit<AuthMiddlewareOptions, "skip" | "message">): {
102
- auth: (options?: Partial<AuthMiddlewareOptions>) => (c: HonoContext, next: HonoNext) => Promise<void>;
103
- optionalAuth: (options?: Partial<Omit<AuthMiddlewareOptions, "message">>) => (c: HonoContext, next: HonoNext) => Promise<void>;
104
- };
105
-
106
- /**
107
- * @parsrun/server - CORS Middleware
108
- * Cross-Origin Resource Sharing configuration
109
- */
110
-
111
- /**
112
- * CORS middleware
113
- *
114
- * @example
115
- * ```typescript
116
- * app.use('*', cors({
117
- * origin: ['https://example.com', 'https://app.example.com'],
118
- * credentials: true,
119
- * }));
120
- * ```
121
- */
122
- declare function cors(config?: Partial<CorsConfig>): (c: HonoContext, next: HonoNext) => Promise<Response | void>;
123
-
124
- /**
125
- * @parsrun/server - CSRF Middleware
126
- * Cross-Site Request Forgery protection
127
- */
128
-
129
- /**
130
- * CSRF options
131
- */
132
- interface CsrfOptions {
133
- /** Cookie name for CSRF token */
134
- cookieName?: string;
135
- /** Header name for CSRF token */
136
- headerName?: string;
137
- /** Methods that require CSRF validation */
138
- methods?: string[];
139
- /** Paths to exclude from CSRF protection */
140
- excludePaths?: string[];
141
- /** Skip CSRF for certain requests */
142
- skip?: (c: HonoContext) => boolean;
143
- /** Token generator */
144
- generateToken?: () => string;
145
- /** Cookie options */
146
- cookie?: {
147
- secure?: boolean;
148
- httpOnly?: boolean;
149
- sameSite?: "strict" | "lax" | "none";
150
- path?: string;
151
- maxAge?: number;
152
- };
153
- }
154
- /**
155
- * CSRF protection middleware
156
- *
157
- * @example
158
- * ```typescript
159
- * app.use('*', csrf({
160
- * cookieName: '_csrf',
161
- * headerName: 'X-CSRF-Token',
162
- * methods: ['POST', 'PUT', 'PATCH', 'DELETE'],
163
- * cookie: {
164
- * secure: true,
165
- * sameSite: 'strict',
166
- * },
167
- * }));
168
- *
169
- * // Get token in handler
170
- * app.get('/csrf-token', (c) => {
171
- * return c.json({ token: c.get('csrfToken') });
172
- * });
173
- * ```
174
- */
175
- declare function csrf(options?: CsrfOptions): (c: HonoContext, next: HonoNext) => Promise<void>;
176
- /**
177
- * Double Submit Cookie pattern
178
- * Generates a token and validates it matches between cookie and header
179
- */
180
- declare function doubleSubmitCookie(options?: CsrfOptions): (c: HonoContext, next: HonoNext) => Promise<void>;
181
-
182
- /**
183
- * Base API error class
184
- */
185
- declare class ApiError extends Error {
186
- readonly statusCode: number;
187
- readonly code: string;
188
- readonly details?: Record<string, unknown> | undefined;
189
- constructor(statusCode: number, code: string, message: string, details?: Record<string, unknown> | undefined);
190
- toResponse(): ApiResponse<never>;
191
- }
192
- /**
193
- * 400 Bad Request
194
- */
195
- declare class BadRequestError extends ApiError {
196
- constructor(message?: string, details?: Record<string, unknown>);
197
- }
198
- /**
199
- * 401 Unauthorized
200
- */
201
- declare class UnauthorizedError extends ApiError {
202
- constructor(message?: string, details?: Record<string, unknown>);
203
- }
204
- /**
205
- * 403 Forbidden
206
- */
207
- declare class ForbiddenError extends ApiError {
208
- constructor(message?: string, details?: Record<string, unknown>);
209
- }
210
- /**
211
- * 404 Not Found
212
- */
213
- declare class NotFoundError extends ApiError {
214
- constructor(message?: string, details?: Record<string, unknown>);
215
- }
216
- /**
217
- * 409 Conflict
218
- */
219
- declare class ConflictError extends ApiError {
220
- constructor(message?: string, details?: Record<string, unknown>);
221
- }
222
- /**
223
- * 422 Unprocessable Entity (Validation Error)
224
- */
225
- declare class ValidationError extends ApiError {
226
- constructor(message?: string, details?: Record<string, unknown>);
227
- }
228
- /**
229
- * 429 Too Many Requests
230
- */
231
- declare class RateLimitError extends ApiError {
232
- readonly retryAfter?: number | undefined;
233
- constructor(message?: string, retryAfter?: number | undefined);
234
- }
235
- /**
236
- * 500 Internal Server Error
237
- */
238
- declare class InternalError extends ApiError {
239
- constructor(message?: string, details?: Record<string, unknown>);
240
- }
241
- /**
242
- * 503 Service Unavailable
243
- */
244
- declare class ServiceUnavailableError extends ApiError {
245
- constructor(message?: string, details?: Record<string, unknown>);
246
- }
247
- /**
248
- * Error handler options
249
- */
250
- interface ErrorHandlerOptions {
251
- /** Include stack trace in development */
252
- includeStack?: boolean;
253
- /** Custom error logger */
254
- onError?: (error: Error, c: HonoContext) => void;
255
- /**
256
- * Error transport for external error tracking (e.g., Sentry)
257
- * Automatically captures exceptions with request context
258
- */
259
- errorTransport?: ErrorTransport;
260
- /**
261
- * Capture all errors including 4xx client errors
262
- * By default, only 5xx server errors are captured
263
- * @default false
264
- */
265
- captureAllErrors?: boolean;
266
- /**
267
- * Custom function to determine if an error should be captured
268
- * Overrides the default captureAllErrors behavior
269
- */
270
- shouldCapture?: (error: Error, statusCode: number) => boolean;
271
- }
272
- /**
273
- * Global error handler middleware
274
- *
275
- * @example Basic usage
276
- * ```typescript
277
- * app.use('*', errorHandler({
278
- * includeStack: process.env.NODE_ENV === 'development',
279
- * onError: (error, c) => {
280
- * console.error(`[${c.get('requestId')}]`, error);
281
- * },
282
- * }));
283
- * ```
284
- *
285
- * @example With Sentry error tracking
286
- * ```typescript
287
- * import { SentryTransport } from '@parsrun/core/transports';
288
- *
289
- * const sentry = new SentryTransport({
290
- * dsn: process.env.SENTRY_DSN!,
291
- * environment: process.env.NODE_ENV,
292
- * });
293
- *
294
- * app.use('*', errorHandler({
295
- * errorTransport: sentry,
296
- * captureAllErrors: false, // Only capture 5xx errors
297
- * }));
298
- * ```
299
- */
300
- declare function errorHandler(options?: ErrorHandlerOptions): (c: HonoContext, next: HonoNext) => Promise<(Response & hono.TypedResponse<{
301
- success: boolean;
302
- error?: {
303
- code: string;
304
- message: string;
305
- details?: {
306
- [x: string]: hono_utils_types.JSONValue;
307
- } | undefined;
308
- } | undefined;
309
- meta?: {
310
- page?: number | undefined | undefined;
311
- limit?: number | undefined | undefined;
312
- total?: number | undefined | undefined;
313
- requestId?: string | undefined | undefined;
314
- } | undefined;
315
- }, 400, "json">) | (Response & hono.TypedResponse<{
316
- success: boolean;
317
- error?: {
318
- code: string;
319
- message: string;
320
- details?: {
321
- [x: string]: hono_utils_types.JSONValue;
322
- } | undefined;
323
- } | undefined;
324
- meta?: {
325
- page?: number | undefined | undefined;
326
- limit?: number | undefined | undefined;
327
- total?: number | undefined | undefined;
328
- requestId?: string | undefined | undefined;
329
- } | undefined;
330
- }, 500, "json">) | undefined>;
331
- /**
332
- * Not found handler
333
- *
334
- * @example
335
- * ```typescript
336
- * app.notFound(notFoundHandler);
337
- * ```
338
- */
339
- declare function notFoundHandler(c: HonoContext): Response & hono.TypedResponse<{
340
- success: boolean;
341
- error?: {
342
- code: string;
343
- message: string;
344
- details?: {
345
- [x: string]: hono_utils_types.JSONValue;
346
- } | undefined;
347
- } | undefined;
348
- meta?: {
349
- page?: number | undefined | undefined;
350
- limit?: number | undefined | undefined;
351
- total?: number | undefined | undefined;
352
- requestId?: string | undefined | undefined;
353
- } | undefined;
354
- }, 404, "json">;
355
-
356
- /**
357
- * @parsrun/server - Rate Limit Middleware
358
- * Request throttling with multiple storage backends
359
- */
360
-
361
- /**
362
- * Rate limit storage interface
363
- */
364
- interface RateLimitStorage {
365
- /** Get current count for key */
366
- get(key: string): Promise<number>;
367
- /** Increment count and set expiry */
368
- increment(key: string, windowMs: number): Promise<number>;
369
- /** Reset count for key */
370
- reset(key: string): Promise<void>;
371
- }
372
- /**
373
- * In-memory rate limit storage
374
- * For single-instance deployments or development
375
- */
376
- declare class MemoryRateLimitStorage implements RateLimitStorage {
377
- private store;
378
- get(key: string): Promise<number>;
379
- increment(key: string, windowMs: number): Promise<number>;
380
- reset(key: string): Promise<void>;
381
- /** Clean up expired entries */
382
- cleanup(): void;
383
- }
384
- /**
385
- * Rate limit options
386
- */
387
- interface RateLimitOptions {
388
- /** Time window in milliseconds */
389
- windowMs?: number;
390
- /** Maximum requests per window */
391
- max?: number;
392
- /** Generate key from request (default: IP address) */
393
- keyGenerator?: (c: HonoContext) => string;
394
- /** Skip rate limiting for certain requests */
395
- skip?: (c: HonoContext) => boolean;
396
- /** Custom storage backend */
397
- storage?: RateLimitStorage;
398
- /** Error message */
399
- message?: string;
400
- /** Include rate limit headers */
401
- headers?: boolean;
402
- /** Handler when limit is exceeded */
403
- onLimitReached?: (c: HonoContext, key: string) => void;
404
- }
405
- /**
406
- * Rate limit middleware
407
- *
408
- * @example
409
- * ```typescript
410
- * // Basic usage - 100 requests per minute
411
- * app.use('/api/*', rateLimit({
412
- * windowMs: 60 * 1000,
413
- * max: 100,
414
- * }));
415
- *
416
- * // Per-user rate limiting
417
- * app.use('/api/*', rateLimit({
418
- * keyGenerator: (c) => c.get('user')?.id ?? getIP(c),
419
- * max: 1000,
420
- * }));
421
- *
422
- * // Strict limit for auth endpoints
423
- * app.use('/api/auth/*', rateLimit({
424
- * windowMs: 15 * 60 * 1000, // 15 minutes
425
- * max: 5,
426
- * message: 'Too many login attempts',
427
- * }));
428
- * ```
429
- */
430
- declare function rateLimit(options?: RateLimitOptions): (c: HonoContext, next: HonoNext) => Promise<void>;
431
- /**
432
- * Create rate limiter for specific routes
433
- *
434
- * @example
435
- * ```typescript
436
- * const apiLimiter = createRateLimiter({
437
- * windowMs: 60000,
438
- * max: 100,
439
- * });
440
- *
441
- * app.use('/api/*', apiLimiter.middleware);
442
- *
443
- * // Reset limit for a user after successful auth
444
- * await apiLimiter.reset('user:123');
445
- * ```
446
- */
447
- declare function createRateLimiter(options?: RateLimitOptions): {
448
- middleware: (c: HonoContext, next: HonoNext) => Promise<void>;
449
- storage: RateLimitStorage;
450
- reset: (key: string) => Promise<void>;
451
- get: (key: string) => Promise<number>;
452
- };
453
-
454
- /**
455
- * @parsrun/server - Request Logger Middleware
456
- * HTTP request/response logging
457
- */
458
-
459
- /**
460
- * Request logger options
461
- */
462
- interface RequestLoggerOptions {
463
- /** Skip logging for certain paths */
464
- skip?: (c: HonoContext) => boolean;
465
- /** Custom log format */
466
- format?: "json" | "combined" | "short";
467
- /** Include request body in logs */
468
- includeBody?: boolean;
469
- /** Include response body in logs (be careful with large responses) */
470
- includeResponseBody?: boolean;
471
- /** Maximum body length to log */
472
- maxBodyLength?: number;
473
- }
474
- /**
475
- * Request logger middleware
476
- *
477
- * @example
478
- * ```typescript
479
- * app.use('*', requestLogger({
480
- * skip: (c) => c.req.path === '/health',
481
- * format: 'json',
482
- * }));
483
- * ```
484
- */
485
- declare function requestLogger(options?: RequestLoggerOptions): (c: HonoContext, next: HonoNext) => Promise<void>;
486
-
487
8
  /**
488
9
  * @parsrun/server - Tracing Middleware
489
10
  * Request correlation and distributed tracing support
@@ -521,20 +42,7 @@ interface TracingOptions {
521
42
  */
522
43
  trustIncoming?: boolean;
523
44
  }
524
- /**
525
- * W3C Trace Context - Parsed traceparent header
526
- * Format: {version}-{trace-id}-{parent-id}-{trace-flags}
527
- */
528
- interface TraceContext {
529
- /** Trace version (currently "00") */
530
- version: string;
531
- /** 32 hex character trace ID */
532
- traceId: string;
533
- /** 16 hex character parent span ID */
534
- parentId: string;
535
- /** Trace flags (sampled, etc.) */
536
- traceFlags: number;
537
- }
45
+
538
46
  /**
539
47
  * Parse W3C traceparent header
540
48
  * Format: 00-{trace-id}-{parent-id}-{trace-flags}
@@ -554,20 +62,6 @@ declare function generateSpanId(): string;
554
62
  * Create a traceparent header value
555
63
  */
556
64
  declare function createTraceparent(traceId: string, spanId: string, sampled?: boolean): string;
557
- /**
558
- * Extended context for tracing
559
- * These values are set on the context for downstream middleware/handlers
560
- */
561
- declare module "../context.js" {
562
- interface ServerContextVariables {
563
- /** W3C trace context (if propagation is enabled) */
564
- traceContext?: TraceContext;
565
- /** Current span ID for this request */
566
- spanId?: string;
567
- /** Tracestate header value (for forwarding) */
568
- traceState?: string;
569
- }
570
- }
571
65
  /**
572
66
  * Tracing middleware
573
67
  *
@@ -627,262 +121,4 @@ declare function tracing(options?: TracingOptions): (c: HonoContext, next: HonoN
627
121
  */
628
122
  declare const tracingMiddleware: typeof tracing;
629
123
 
630
- /**
631
- * @parsrun/server - Usage Tracking Middleware
632
- * Automatically track API usage per request
633
- */
634
-
635
- /**
636
- * Usage service interface (from @parsrun/payments)
637
- * Defined here to avoid circular dependency
638
- */
639
- interface UsageServiceLike {
640
- trackUsage(options: {
641
- tenantId: string;
642
- customerId: string;
643
- subscriptionId?: string;
644
- featureKey: string;
645
- quantity?: number;
646
- metadata?: Record<string, unknown>;
647
- idempotencyKey?: string;
648
- }): Promise<unknown>;
649
- }
650
- /**
651
- * Usage tracking middleware options
652
- */
653
- interface UsageTrackingOptions {
654
- /**
655
- * Usage service instance
656
- */
657
- usageService: UsageServiceLike;
658
- /**
659
- * Feature key to track
660
- * Can be a static string or a function that extracts it from context
661
- * @default "api_calls"
662
- */
663
- featureKey?: string | ((c: HonoContext) => string);
664
- /**
665
- * Quantity to track
666
- * Can be a static number or a function that calculates it from context
667
- * @default 1
668
- */
669
- quantity?: number | ((c: HonoContext) => number);
670
- /**
671
- * Skip tracking for certain requests
672
- */
673
- skip?: (c: HonoContext) => boolean;
674
- /**
675
- * When to track: before or after the request
676
- * @default "response"
677
- */
678
- trackOn?: "request" | "response";
679
- /**
680
- * Only track successful responses (2xx)
681
- * @default true
682
- */
683
- successOnly?: boolean;
684
- /**
685
- * Custom customer ID extractor
686
- * @default Uses c.get("user")?.id
687
- */
688
- getCustomerId?: (c: HonoContext) => string | undefined;
689
- /**
690
- * Custom tenant ID extractor
691
- * @default Uses c.get("tenant")?.id or c.get("user")?.tenantId
692
- */
693
- getTenantId?: (c: HonoContext) => string | undefined;
694
- /**
695
- * Custom subscription ID extractor
696
- */
697
- getSubscriptionId?: (c: HonoContext) => string | undefined;
698
- /**
699
- * Include request metadata
700
- * @default true
701
- */
702
- includeMetadata?: boolean;
703
- /**
704
- * Generate idempotency key to prevent duplicates
705
- */
706
- getIdempotencyKey?: (c: HonoContext) => string | undefined;
707
- }
708
- /**
709
- * Usage tracking middleware
710
- *
711
- * Automatically tracks API usage for authenticated requests.
712
- *
713
- * @example
714
- * ```typescript
715
- * import { usageTracking } from "@parsrun/server";
716
- * import { createUsageService, createMemoryUsageStorage } from "@parsrun/payments";
717
- *
718
- * const usageService = createUsageService({
719
- * storage: createMemoryUsageStorage(),
720
- * });
721
- *
722
- * // Track all API calls
723
- * app.use("/api/*", usageTracking({
724
- * usageService,
725
- * featureKey: "api_calls",
726
- * }));
727
- *
728
- * // Track with custom feature key based on route
729
- * app.use("/api/ai/*", usageTracking({
730
- * usageService,
731
- * featureKey: "ai_requests",
732
- * quantity: (c) => {
733
- * // Track tokens used from response
734
- * return c.get("tokensUsed") ?? 1;
735
- * },
736
- * }));
737
- *
738
- * // Skip certain routes
739
- * app.use("/api/*", usageTracking({
740
- * usageService,
741
- * skip: (c) => c.req.path.startsWith("/api/health"),
742
- * }));
743
- * ```
744
- */
745
- declare function usageTracking(options: UsageTrackingOptions): (c: HonoContext, next: HonoNext) => Promise<void>;
746
- /**
747
- * Create usage tracking middleware with pre-configured options
748
- */
749
- declare function createUsageTracking(baseOptions: UsageTrackingOptions): (overrides?: Partial<UsageTrackingOptions>) => (c: HonoContext, next: HonoNext) => Promise<void>;
750
-
751
- /**
752
- * @parsrun/server - Quota Enforcement Middleware
753
- * Enforce usage quotas before processing requests
754
- */
755
-
756
- /**
757
- * Quota check result interface (from @parsrun/payments)
758
- */
759
- interface QuotaCheckResult {
760
- allowed: boolean;
761
- currentUsage: number;
762
- limit: number | null;
763
- remaining: number | null;
764
- wouldExceed: boolean;
765
- percentAfter: number | null;
766
- }
767
- /**
768
- * Quota manager interface (from @parsrun/payments)
769
- * Defined here to avoid circular dependency
770
- */
771
- interface QuotaManagerLike {
772
- checkQuota(customerId: string, featureKey: string, quantity?: number): Promise<QuotaCheckResult>;
773
- enforceQuota(customerId: string, featureKey: string, quantity?: number): Promise<void>;
774
- }
775
- /**
776
- * Quota exceeded error class
777
- */
778
- declare class QuotaExceededError extends Error {
779
- readonly featureKey: string;
780
- readonly limit: number | null;
781
- readonly currentUsage: number;
782
- readonly requestedQuantity: number;
783
- readonly statusCode = 429;
784
- readonly code = "QUOTA_EXCEEDED";
785
- constructor(featureKey: string, limit: number | null, currentUsage: number, requestedQuantity?: number);
786
- }
787
- /**
788
- * Quota enforcement middleware options
789
- */
790
- interface QuotaEnforcementOptions {
791
- /**
792
- * Quota manager instance
793
- */
794
- quotaManager: QuotaManagerLike;
795
- /**
796
- * Feature key to check
797
- * Can be a static string or a function that extracts it from context
798
- */
799
- featureKey: string | ((c: HonoContext) => string);
800
- /**
801
- * Quantity to check (default: 1)
802
- */
803
- quantity?: number | ((c: HonoContext) => number);
804
- /**
805
- * Skip quota check for certain requests
806
- */
807
- skip?: (c: HonoContext) => boolean;
808
- /**
809
- * Custom customer ID extractor
810
- * @default Uses c.get("user")?.id
811
- */
812
- getCustomerId?: (c: HonoContext) => string | undefined;
813
- /**
814
- * Include quota headers in response
815
- * @default true
816
- */
817
- includeHeaders?: boolean;
818
- /**
819
- * Custom error handler
820
- */
821
- onQuotaExceeded?: (c: HonoContext, result: QuotaCheckResult, featureKey: string) => Response | void;
822
- /**
823
- * Soft limit mode - warn but don't block
824
- * @default false
825
- */
826
- softLimit?: boolean;
827
- /**
828
- * Callback when quota is close to limit (>80%)
829
- */
830
- onQuotaWarning?: (c: HonoContext, result: QuotaCheckResult, featureKey: string) => void;
831
- }
832
- /**
833
- * Quota enforcement middleware
834
- *
835
- * Checks and enforces usage quotas before processing requests.
836
- *
837
- * @example
838
- * ```typescript
839
- * import { quotaEnforcement } from "@parsrun/server";
840
- * import { createQuotaManager, createMemoryUsageStorage } from "@parsrun/payments";
841
- *
842
- * const quotaManager = createQuotaManager({
843
- * storage: createMemoryUsageStorage(),
844
- * });
845
- *
846
- * // Enforce API call quota
847
- * app.use("/api/*", quotaEnforcement({
848
- * quotaManager,
849
- * featureKey: "api_calls",
850
- * }));
851
- *
852
- * // Enforce with dynamic feature key
853
- * app.use("/api/*", quotaEnforcement({
854
- * quotaManager,
855
- * featureKey: (c) => {
856
- * if (c.req.path.startsWith("/api/ai")) return "ai_requests";
857
- * return "api_calls";
858
- * },
859
- * }));
860
- *
861
- * // Soft limit mode (warn but allow)
862
- * app.use("/api/*", quotaEnforcement({
863
- * quotaManager,
864
- * featureKey: "api_calls",
865
- * softLimit: true,
866
- * onQuotaWarning: (c, result) => {
867
- * console.warn("Quota warning:", result);
868
- * },
869
- * }));
870
- * ```
871
- */
872
- declare function quotaEnforcement(options: QuotaEnforcementOptions): (c: HonoContext, next: HonoNext) => Promise<void | Response>;
873
- /**
874
- * Create quota enforcement middleware with pre-configured options
875
- */
876
- declare function createQuotaEnforcement(baseOptions: Omit<QuotaEnforcementOptions, "featureKey">): (featureKey: string | ((c: HonoContext) => string)) => (c: HonoContext, next: HonoNext) => Promise<void | Response>;
877
- /**
878
- * Multiple quota enforcement
879
- * Check multiple features at once
880
- */
881
- declare function multiQuotaEnforcement(options: Omit<QuotaEnforcementOptions, "featureKey"> & {
882
- features: Array<{
883
- featureKey: string;
884
- quantity?: number | ((c: HonoContext) => number);
885
- }>;
886
- }): (c: HonoContext, next: HonoNext) => Promise<void | Response>;
887
-
888
- export { ApiError, type AuthMiddlewareOptions, BadRequestError, ConflictError, type CsrfOptions, type ErrorHandlerOptions, ForbiddenError, InternalError, type JwtPayload, type JwtVerifier, MemoryRateLimitStorage, NotFoundError, type QuotaCheckResult, type QuotaEnforcementOptions, QuotaExceededError, type QuotaManagerLike, RateLimitError, type RateLimitOptions, type RateLimitStorage, type RequestLoggerOptions, ServiceUnavailableError, type TraceContext, type TracingOptions, UnauthorizedError, type UsageServiceLike, type UsageTrackingOptions, ValidationError, auth, cors, createAuthMiddleware, createQuotaEnforcement, createRateLimiter, createTraceparent, createUsageTracking, csrf, doubleSubmitCookie, errorHandler, generateSpanId, generateTraceId, multiQuotaEnforcement, notFoundHandler, optionalAuth, parseTraceparent, quotaEnforcement, rateLimit, requestLogger, tracing, tracingMiddleware, usageTracking };
124
+ export { TraceContext, type TracingOptions, createTraceparent, generateSpanId, generateTraceId, parseTraceparent, tracing, tracingMiddleware };