@usequota/nextjs 0.2.1 → 0.3.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @usequota/nextjs
2
2
 
3
- Next.js SDK for [Quota](https://usequota.app) - AI credit wallet and multi-provider inference API.
3
+ Next.js SDK for [Quota](https://usequota.ai) - AI credit wallet and multi-provider inference API.
4
4
 
5
5
  ## Installation
6
6
 
@@ -409,7 +409,7 @@ export const POST = withQuotaAuth(
409
409
  // user is guaranteed to exist
410
410
  // accessToken can proxy requests through Quota
411
411
  const response = await fetch(
412
- "https://api.usequota.app/v1/chat/completions",
412
+ "https://api.usequota.ai/v1/chat/completions",
413
413
  {
414
414
  method: "POST",
415
415
  headers: {
package/dist/index.d.mts CHANGED
@@ -4,7 +4,7 @@ import * as react from 'react';
4
4
  import { ReactNode } from 'react';
5
5
  import { QuotaUser, CreditPackage } from '@usequota/types';
6
6
  export { ChatCompletionRequest, ChatCompletionResponse, ChatMessage, CreditPackage, QuotaError as QuotaErrorResponse, QuotaMetadata, QuotaSession, QuotaUser, Tool, ToolCall } from '@usequota/types';
7
- export { Q as QuotaError, a as QuotaInsufficientCreditsError, b as QuotaNotConnectedError, d as QuotaRateLimitError, c as QuotaTokenExpiredError } from './errors-CmNx3kSz.mjs';
7
+ export { QuotaError, QuotaInsufficientCreditsError, QuotaNotConnectedError, QuotaRateLimitError, QuotaTokenExpiredError, VerifyWebhookOptions, WebhookEvent, createWebhookHandler, parseWebhook, verifyWebhookSignature } from '@usequota/core';
8
8
 
9
9
  /**
10
10
  * @usequota/nextjs - Next.js middleware for OAuth callback handling
@@ -25,7 +25,7 @@ interface QuotaConfig {
25
25
  clientSecret: string;
26
26
  /**
27
27
  * Quota API base URL
28
- * @default 'https://api.usequota.app'
28
+ * @default 'https://api.usequota.ai'
29
29
  */
30
30
  baseUrl?: string;
31
31
  /**
@@ -136,7 +136,7 @@ interface QuotaProviderProps {
136
136
  clientId: string;
137
137
  /**
138
138
  * Quota API base URL
139
- * @default 'https://api.usequota.app'
139
+ * @default 'https://api.usequota.ai'
140
140
  */
141
141
  baseUrl?: string;
142
142
  /**
@@ -541,103 +541,4 @@ interface QuotaUserMenuProps {
541
541
  */
542
542
  declare function QuotaUserMenu({ className, onBuyCredits, onLogout, showBuyCredits, children, }: QuotaUserMenuProps): react_jsx_runtime.JSX.Element | null;
543
543
 
544
- /**
545
- * Webhook event types sent by Quota
546
- */
547
- interface WebhookEvent {
548
- /** Unique event identifier */
549
- id: string;
550
- /** Event type */
551
- type: "user.connected" | "user.disconnected" | "balance.updated" | "balance.low" | "usage.completed";
552
- /** ISO 8601 timestamp when event was created */
553
- created_at: string;
554
- /** Event-specific data payload */
555
- data: Record<string, unknown>;
556
- }
557
- /**
558
- * Options for verifying webhook signatures
559
- */
560
- interface VerifyWebhookOptions {
561
- /** Raw webhook payload (string or Buffer) */
562
- payload: string | Buffer;
563
- /** Signature from X-Quota-Signature header */
564
- signature: string;
565
- /** Webhook secret from Quota dashboard */
566
- secret: string;
567
- }
568
- /**
569
- * Verify a webhook signature from Quota using HMAC-SHA256
570
- *
571
- * @param options - Verification options
572
- * @returns true if signature is valid, false otherwise
573
- *
574
- * @example
575
- * ```typescript
576
- * const isValid = verifyWebhookSignature({
577
- * payload: rawBody,
578
- * signature: request.headers.get('x-quota-signature')!,
579
- * secret: process.env.QUOTA_WEBHOOK_SECRET!
580
- * });
581
- * ```
582
- */
583
- declare function verifyWebhookSignature({ payload, signature, secret, }: VerifyWebhookOptions): boolean;
584
- /**
585
- * Parse and verify a webhook request
586
- * For use in Next.js API routes (App Router)
587
- *
588
- * @param req - Next.js Request object
589
- * @param secret - Webhook secret from Quota dashboard
590
- * @returns Parsed and verified webhook event
591
- * @throws Error if signature is missing or invalid
592
- *
593
- * @example
594
- * ```typescript
595
- * // app/api/quota/webhook/route.ts
596
- * export async function POST(req: Request) {
597
- * try {
598
- * const event = await parseWebhook(req, process.env.QUOTA_WEBHOOK_SECRET!);
599
- *
600
- * if (event.type === 'balance.low') {
601
- * await sendLowBalanceEmail(event.data);
602
- * }
603
- *
604
- * return Response.json({ received: true });
605
- * } catch (error) {
606
- * return Response.json({ error: error.message }, { status: 400 });
607
- * }
608
- * }
609
- * ```
610
- */
611
- declare function parseWebhook(req: Request, secret: string): Promise<WebhookEvent>;
612
- /**
613
- * Create a webhook handler for Next.js App Router
614
- * Automatically verifies signatures and routes events to handlers
615
- *
616
- * @param secret - Webhook secret from Quota dashboard
617
- * @param handlers - Map of event types to handler functions
618
- * @returns Next.js route handler function
619
- *
620
- * @example
621
- * ```typescript
622
- * // app/api/quota/webhook/route.ts
623
- * import { createWebhookHandler } from '@usequota/nextjs';
624
- *
625
- * export const POST = createWebhookHandler(process.env.QUOTA_WEBHOOK_SECRET!, {
626
- * 'balance.low': async (event) => {
627
- * // Send email notification
628
- * await sendLowBalanceEmail(event.data.user_id, event.data.current_balance);
629
- * },
630
- * 'user.connected': async (event) => {
631
- * // Track new user connection
632
- * await analytics.track('user_connected', event.data);
633
- * },
634
- * 'usage.completed': async (event) => {
635
- * // Log usage for analytics
636
- * await logUsage(event.data);
637
- * }
638
- * });
639
- * ```
640
- */
641
- declare function createWebhookHandler(secret: string, handlers: Partial<Record<WebhookEvent["type"], (event: WebhookEvent) => Promise<void>>>): (req: Request) => Promise<Response>;
642
-
643
- export { QuotaBalance, type QuotaBalanceProps, QuotaBuyCredits, type QuotaBuyCreditsProps, type QuotaConfig, QuotaConnectButton, type QuotaConnectButtonProps, QuotaContext, type QuotaContextValue, type QuotaFetchStrategy, QuotaProvider, type QuotaProviderProps, QuotaUserMenu, type QuotaUserMenuProps, type VerifyWebhookOptions, type WebhookEvent, createQuotaMiddleware, createWebhookHandler, parseWebhook, useQuota, useQuotaAuth, useQuotaBalance, useQuotaPackages, useQuotaUser, verifyWebhookSignature };
544
+ export { QuotaBalance, type QuotaBalanceProps, QuotaBuyCredits, type QuotaBuyCreditsProps, type QuotaConfig, QuotaConnectButton, type QuotaConnectButtonProps, QuotaContext, type QuotaContextValue, type QuotaFetchStrategy, QuotaProvider, type QuotaProviderProps, QuotaUserMenu, type QuotaUserMenuProps, createQuotaMiddleware, useQuota, useQuotaAuth, useQuotaBalance, useQuotaPackages, useQuotaUser };
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ import * as react from 'react';
4
4
  import { ReactNode } from 'react';
5
5
  import { QuotaUser, CreditPackage } from '@usequota/types';
6
6
  export { ChatCompletionRequest, ChatCompletionResponse, ChatMessage, CreditPackage, QuotaError as QuotaErrorResponse, QuotaMetadata, QuotaSession, QuotaUser, Tool, ToolCall } from '@usequota/types';
7
- export { Q as QuotaError, a as QuotaInsufficientCreditsError, b as QuotaNotConnectedError, d as QuotaRateLimitError, c as QuotaTokenExpiredError } from './errors-CmNx3kSz.js';
7
+ export { QuotaError, QuotaInsufficientCreditsError, QuotaNotConnectedError, QuotaRateLimitError, QuotaTokenExpiredError, VerifyWebhookOptions, WebhookEvent, createWebhookHandler, parseWebhook, verifyWebhookSignature } from '@usequota/core';
8
8
 
9
9
  /**
10
10
  * @usequota/nextjs - Next.js middleware for OAuth callback handling
@@ -25,7 +25,7 @@ interface QuotaConfig {
25
25
  clientSecret: string;
26
26
  /**
27
27
  * Quota API base URL
28
- * @default 'https://api.usequota.app'
28
+ * @default 'https://api.usequota.ai'
29
29
  */
30
30
  baseUrl?: string;
31
31
  /**
@@ -136,7 +136,7 @@ interface QuotaProviderProps {
136
136
  clientId: string;
137
137
  /**
138
138
  * Quota API base URL
139
- * @default 'https://api.usequota.app'
139
+ * @default 'https://api.usequota.ai'
140
140
  */
141
141
  baseUrl?: string;
142
142
  /**
@@ -541,103 +541,4 @@ interface QuotaUserMenuProps {
541
541
  */
542
542
  declare function QuotaUserMenu({ className, onBuyCredits, onLogout, showBuyCredits, children, }: QuotaUserMenuProps): react_jsx_runtime.JSX.Element | null;
543
543
 
544
- /**
545
- * Webhook event types sent by Quota
546
- */
547
- interface WebhookEvent {
548
- /** Unique event identifier */
549
- id: string;
550
- /** Event type */
551
- type: "user.connected" | "user.disconnected" | "balance.updated" | "balance.low" | "usage.completed";
552
- /** ISO 8601 timestamp when event was created */
553
- created_at: string;
554
- /** Event-specific data payload */
555
- data: Record<string, unknown>;
556
- }
557
- /**
558
- * Options for verifying webhook signatures
559
- */
560
- interface VerifyWebhookOptions {
561
- /** Raw webhook payload (string or Buffer) */
562
- payload: string | Buffer;
563
- /** Signature from X-Quota-Signature header */
564
- signature: string;
565
- /** Webhook secret from Quota dashboard */
566
- secret: string;
567
- }
568
- /**
569
- * Verify a webhook signature from Quota using HMAC-SHA256
570
- *
571
- * @param options - Verification options
572
- * @returns true if signature is valid, false otherwise
573
- *
574
- * @example
575
- * ```typescript
576
- * const isValid = verifyWebhookSignature({
577
- * payload: rawBody,
578
- * signature: request.headers.get('x-quota-signature')!,
579
- * secret: process.env.QUOTA_WEBHOOK_SECRET!
580
- * });
581
- * ```
582
- */
583
- declare function verifyWebhookSignature({ payload, signature, secret, }: VerifyWebhookOptions): boolean;
584
- /**
585
- * Parse and verify a webhook request
586
- * For use in Next.js API routes (App Router)
587
- *
588
- * @param req - Next.js Request object
589
- * @param secret - Webhook secret from Quota dashboard
590
- * @returns Parsed and verified webhook event
591
- * @throws Error if signature is missing or invalid
592
- *
593
- * @example
594
- * ```typescript
595
- * // app/api/quota/webhook/route.ts
596
- * export async function POST(req: Request) {
597
- * try {
598
- * const event = await parseWebhook(req, process.env.QUOTA_WEBHOOK_SECRET!);
599
- *
600
- * if (event.type === 'balance.low') {
601
- * await sendLowBalanceEmail(event.data);
602
- * }
603
- *
604
- * return Response.json({ received: true });
605
- * } catch (error) {
606
- * return Response.json({ error: error.message }, { status: 400 });
607
- * }
608
- * }
609
- * ```
610
- */
611
- declare function parseWebhook(req: Request, secret: string): Promise<WebhookEvent>;
612
- /**
613
- * Create a webhook handler for Next.js App Router
614
- * Automatically verifies signatures and routes events to handlers
615
- *
616
- * @param secret - Webhook secret from Quota dashboard
617
- * @param handlers - Map of event types to handler functions
618
- * @returns Next.js route handler function
619
- *
620
- * @example
621
- * ```typescript
622
- * // app/api/quota/webhook/route.ts
623
- * import { createWebhookHandler } from '@usequota/nextjs';
624
- *
625
- * export const POST = createWebhookHandler(process.env.QUOTA_WEBHOOK_SECRET!, {
626
- * 'balance.low': async (event) => {
627
- * // Send email notification
628
- * await sendLowBalanceEmail(event.data.user_id, event.data.current_balance);
629
- * },
630
- * 'user.connected': async (event) => {
631
- * // Track new user connection
632
- * await analytics.track('user_connected', event.data);
633
- * },
634
- * 'usage.completed': async (event) => {
635
- * // Log usage for analytics
636
- * await logUsage(event.data);
637
- * }
638
- * });
639
- * ```
640
- */
641
- declare function createWebhookHandler(secret: string, handlers: Partial<Record<WebhookEvent["type"], (event: WebhookEvent) => Promise<void>>>): (req: Request) => Promise<Response>;
642
-
643
- export { QuotaBalance, type QuotaBalanceProps, QuotaBuyCredits, type QuotaBuyCreditsProps, type QuotaConfig, QuotaConnectButton, type QuotaConnectButtonProps, QuotaContext, type QuotaContextValue, type QuotaFetchStrategy, QuotaProvider, type QuotaProviderProps, QuotaUserMenu, type QuotaUserMenuProps, type VerifyWebhookOptions, type WebhookEvent, createQuotaMiddleware, createWebhookHandler, parseWebhook, useQuota, useQuotaAuth, useQuotaBalance, useQuotaPackages, useQuotaUser, verifyWebhookSignature };
544
+ export { QuotaBalance, type QuotaBalanceProps, QuotaBuyCredits, type QuotaBuyCreditsProps, type QuotaConfig, QuotaConnectButton, type QuotaConnectButtonProps, QuotaContext, type QuotaContextValue, type QuotaFetchStrategy, QuotaProvider, type QuotaProviderProps, QuotaUserMenu, type QuotaUserMenuProps, createQuotaMiddleware, useQuota, useQuotaAuth, useQuotaBalance, useQuotaPackages, useQuotaUser };
package/dist/index.js CHANGED
@@ -1,9 +1,7 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
2
  var __defProp = Object.defineProperty;
4
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
6
  var __export = (target, all) => {
9
7
  for (var name in all)
@@ -17,14 +15,6 @@ var __copyProps = (to, from, except, desc) => {
17
15
  }
18
16
  return to;
19
17
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
19
 
30
20
  // src/index.ts
@@ -34,28 +24,28 @@ __export(index_exports, {
34
24
  QuotaBuyCredits: () => QuotaBuyCredits,
35
25
  QuotaConnectButton: () => QuotaConnectButton,
36
26
  QuotaContext: () => QuotaContext,
37
- QuotaError: () => QuotaError,
38
- QuotaInsufficientCreditsError: () => QuotaInsufficientCreditsError,
39
- QuotaNotConnectedError: () => QuotaNotConnectedError,
27
+ QuotaError: () => import_core.QuotaError,
28
+ QuotaInsufficientCreditsError: () => import_core.QuotaInsufficientCreditsError,
29
+ QuotaNotConnectedError: () => import_core.QuotaNotConnectedError,
40
30
  QuotaProvider: () => QuotaProvider,
41
- QuotaRateLimitError: () => QuotaRateLimitError,
42
- QuotaTokenExpiredError: () => QuotaTokenExpiredError,
31
+ QuotaRateLimitError: () => import_core.QuotaRateLimitError,
32
+ QuotaTokenExpiredError: () => import_core.QuotaTokenExpiredError,
43
33
  QuotaUserMenu: () => QuotaUserMenu,
44
34
  createQuotaMiddleware: () => createQuotaMiddleware,
45
- createWebhookHandler: () => createWebhookHandler,
46
- parseWebhook: () => parseWebhook,
35
+ createWebhookHandler: () => import_core2.createWebhookHandler,
36
+ parseWebhook: () => import_core2.parseWebhook,
47
37
  useQuota: () => useQuota,
48
38
  useQuotaAuth: () => useQuotaAuth,
49
39
  useQuotaBalance: () => useQuotaBalance,
50
40
  useQuotaPackages: () => useQuotaPackages,
51
41
  useQuotaUser: () => useQuotaUser,
52
- verifyWebhookSignature: () => verifyWebhookSignature
42
+ verifyWebhookSignature: () => import_core2.verifyWebhookSignature
53
43
  });
54
44
  module.exports = __toCommonJS(index_exports);
55
45
 
56
46
  // src/middleware.ts
57
47
  var import_server = require("next/server");
58
- var DEFAULT_BASE_URL = "https://api.usequota.app";
48
+ var DEFAULT_BASE_URL = "https://api.usequota.ai";
59
49
  var DEFAULT_CALLBACK_PATH = "/api/quota/callback";
60
50
  var DEFAULT_COOKIE_PREFIX = "quota";
61
51
  var DEFAULT_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
@@ -120,7 +110,8 @@ function createQuotaMiddleware(config) {
120
110
  headers: {
121
111
  "Content-Type": "application/json"
122
112
  },
123
- body: JSON.stringify(tokenBody)
113
+ body: JSON.stringify(tokenBody),
114
+ signal: AbortSignal.timeout(1e4)
124
115
  });
125
116
  if (!tokenResponse.ok) {
126
117
  const errorData = await tokenResponse.json();
@@ -137,16 +128,6 @@ function createQuotaMiddleware(config) {
137
128
  redirectUrl.searchParams.set("quota_success", "true");
138
129
  const response = import_server.NextResponse.redirect(redirectUrl);
139
130
  if ("access_token" in tokenData) {
140
- const cookieOptions = [
141
- `Path=${cookiePath}`,
142
- "HttpOnly",
143
- "Secure",
144
- "SameSite=Lax",
145
- `Max-Age=${cookieMaxAge}`
146
- ];
147
- if (cookieDomain) {
148
- cookieOptions.push(`Domain=${cookieDomain}`);
149
- }
150
131
  response.cookies.set(
151
132
  `${cookiePrefix}_access_token`,
152
133
  tokenData.access_token,
@@ -203,7 +184,7 @@ function createQuotaMiddleware(config) {
203
184
  var import_react = require("react");
204
185
  var import_jsx_runtime = require("react/jsx-runtime");
205
186
  var QuotaContext = (0, import_react.createContext)(null);
206
- var DEFAULT_BASE_URL2 = "https://api.usequota.app";
187
+ var DEFAULT_BASE_URL2 = "https://api.usequota.ai";
207
188
  var DEFAULT_CALLBACK_PATH2 = "/api/quota/callback";
208
189
  var DEFAULT_API_PATH = "/api/quota/me";
209
190
  function QuotaProvider({
@@ -965,135 +946,9 @@ function LogoutIcon() {
965
946
  );
966
947
  }
967
948
 
968
- // src/errors.ts
969
- var QuotaError = class extends Error {
970
- /** Machine-readable error code */
971
- code;
972
- /** HTTP status code associated with this error */
973
- statusCode;
974
- /** Optional hint for resolving the error */
975
- hint;
976
- constructor(message, code, statusCode, hint) {
977
- super(message);
978
- this.name = "QuotaError";
979
- this.code = code;
980
- this.statusCode = statusCode;
981
- this.hint = hint;
982
- Object.setPrototypeOf(this, new.target.prototype);
983
- }
984
- };
985
- var QuotaInsufficientCreditsError = class extends QuotaError {
986
- /** Current balance (if available) */
987
- balance;
988
- /** Credits required for the operation (if available) */
989
- required;
990
- constructor(message, options) {
991
- super(
992
- message ?? "Insufficient credits to complete this operation",
993
- "insufficient_credits",
994
- 402,
995
- "Purchase more credits or reduce usage"
996
- );
997
- this.name = "QuotaInsufficientCreditsError";
998
- this.balance = options?.balance;
999
- this.required = options?.required;
1000
- Object.setPrototypeOf(this, new.target.prototype);
1001
- }
1002
- };
1003
- var QuotaNotConnectedError = class extends QuotaError {
1004
- constructor(message) {
1005
- super(
1006
- message ?? "User has not connected a Quota account",
1007
- "not_connected",
1008
- 401,
1009
- "Connect your Quota account to use this feature"
1010
- );
1011
- this.name = "QuotaNotConnectedError";
1012
- Object.setPrototypeOf(this, new.target.prototype);
1013
- }
1014
- };
1015
- var QuotaTokenExpiredError = class extends QuotaError {
1016
- constructor(message) {
1017
- super(
1018
- message ?? "Quota access token has expired and could not be refreshed",
1019
- "token_expired",
1020
- 401,
1021
- "Reconnect your Quota account"
1022
- );
1023
- this.name = "QuotaTokenExpiredError";
1024
- Object.setPrototypeOf(this, new.target.prototype);
1025
- }
1026
- };
1027
- var QuotaRateLimitError = class extends QuotaError {
1028
- /** Seconds until the rate limit resets */
1029
- retryAfter;
1030
- constructor(message, retryAfter) {
1031
- super(
1032
- message ?? "Rate limit exceeded",
1033
- "rate_limit_exceeded",
1034
- 429,
1035
- "Wait before retrying"
1036
- );
1037
- this.name = "QuotaRateLimitError";
1038
- this.retryAfter = retryAfter ?? 60;
1039
- Object.setPrototypeOf(this, new.target.prototype);
1040
- }
1041
- };
1042
-
1043
- // src/webhooks.ts
1044
- var import_crypto = __toESM(require("crypto"));
1045
- function verifyWebhookSignature({
1046
- payload,
1047
- signature,
1048
- secret
1049
- }) {
1050
- const payloadString = typeof payload === "string" ? payload : payload.toString("utf8");
1051
- const hmac = import_crypto.default.createHmac("sha256", secret);
1052
- hmac.update(payloadString);
1053
- const expectedSignature = hmac.digest("hex");
1054
- try {
1055
- return import_crypto.default.timingSafeEqual(
1056
- Buffer.from(signature, "hex"),
1057
- Buffer.from(expectedSignature, "hex")
1058
- );
1059
- } catch {
1060
- return false;
1061
- }
1062
- }
1063
- async function parseWebhook(req, secret) {
1064
- const signature = req.headers.get("x-quota-signature");
1065
- if (!signature) {
1066
- throw new Error("Missing X-Quota-Signature header");
1067
- }
1068
- const payload = await req.text();
1069
- if (!verifyWebhookSignature({ payload, signature, secret })) {
1070
- throw new Error("Invalid webhook signature");
1071
- }
1072
- return JSON.parse(payload);
1073
- }
1074
- function createWebhookHandler(secret, handlers) {
1075
- return async (req) => {
1076
- try {
1077
- const event = await parseWebhook(req, secret);
1078
- const handler = handlers[event.type];
1079
- if (handler) {
1080
- await handler(event);
1081
- }
1082
- return new Response(JSON.stringify({ received: true }), {
1083
- status: 200,
1084
- headers: { "Content-Type": "application/json" }
1085
- });
1086
- } catch (error) {
1087
- console.error("Webhook error:", error);
1088
- return new Response(
1089
- JSON.stringify({
1090
- error: error instanceof Error ? error.message : "Unknown error"
1091
- }),
1092
- { status: 400, headers: { "Content-Type": "application/json" } }
1093
- );
1094
- }
1095
- };
1096
- }
949
+ // src/index.ts
950
+ var import_core = require("@usequota/core");
951
+ var import_core2 = require("@usequota/core");
1097
952
  // Annotate the CommonJS export names for ESM import in node:
1098
953
  0 && (module.exports = {
1099
954
  QuotaBalance,
package/dist/index.mjs CHANGED
@@ -1,14 +1,6 @@
1
- import {
2
- QuotaError,
3
- QuotaInsufficientCreditsError,
4
- QuotaNotConnectedError,
5
- QuotaRateLimitError,
6
- QuotaTokenExpiredError
7
- } from "./chunk-BMI3VFWV.mjs";
8
-
9
1
  // src/middleware.ts
10
2
  import { NextResponse } from "next/server";
11
- var DEFAULT_BASE_URL = "https://api.usequota.app";
3
+ var DEFAULT_BASE_URL = "https://api.usequota.ai";
12
4
  var DEFAULT_CALLBACK_PATH = "/api/quota/callback";
13
5
  var DEFAULT_COOKIE_PREFIX = "quota";
14
6
  var DEFAULT_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;
@@ -73,7 +65,8 @@ function createQuotaMiddleware(config) {
73
65
  headers: {
74
66
  "Content-Type": "application/json"
75
67
  },
76
- body: JSON.stringify(tokenBody)
68
+ body: JSON.stringify(tokenBody),
69
+ signal: AbortSignal.timeout(1e4)
77
70
  });
78
71
  if (!tokenResponse.ok) {
79
72
  const errorData = await tokenResponse.json();
@@ -90,16 +83,6 @@ function createQuotaMiddleware(config) {
90
83
  redirectUrl.searchParams.set("quota_success", "true");
91
84
  const response = NextResponse.redirect(redirectUrl);
92
85
  if ("access_token" in tokenData) {
93
- const cookieOptions = [
94
- `Path=${cookiePath}`,
95
- "HttpOnly",
96
- "Secure",
97
- "SameSite=Lax",
98
- `Max-Age=${cookieMaxAge}`
99
- ];
100
- if (cookieDomain) {
101
- cookieOptions.push(`Domain=${cookieDomain}`);
102
- }
103
86
  response.cookies.set(
104
87
  `${cookiePrefix}_access_token`,
105
88
  tokenData.access_token,
@@ -162,7 +145,7 @@ import {
162
145
  } from "react";
163
146
  import { jsx } from "react/jsx-runtime";
164
147
  var QuotaContext = createContext(null);
165
- var DEFAULT_BASE_URL2 = "https://api.usequota.app";
148
+ var DEFAULT_BASE_URL2 = "https://api.usequota.ai";
166
149
  var DEFAULT_CALLBACK_PATH2 = "/api/quota/callback";
167
150
  var DEFAULT_API_PATH = "/api/quota/me";
168
151
  function QuotaProvider({
@@ -929,60 +912,19 @@ function LogoutIcon() {
929
912
  );
930
913
  }
931
914
 
932
- // src/webhooks.ts
933
- import crypto from "crypto";
934
- function verifyWebhookSignature({
935
- payload,
936
- signature,
937
- secret
938
- }) {
939
- const payloadString = typeof payload === "string" ? payload : payload.toString("utf8");
940
- const hmac = crypto.createHmac("sha256", secret);
941
- hmac.update(payloadString);
942
- const expectedSignature = hmac.digest("hex");
943
- try {
944
- return crypto.timingSafeEqual(
945
- Buffer.from(signature, "hex"),
946
- Buffer.from(expectedSignature, "hex")
947
- );
948
- } catch {
949
- return false;
950
- }
951
- }
952
- async function parseWebhook(req, secret) {
953
- const signature = req.headers.get("x-quota-signature");
954
- if (!signature) {
955
- throw new Error("Missing X-Quota-Signature header");
956
- }
957
- const payload = await req.text();
958
- if (!verifyWebhookSignature({ payload, signature, secret })) {
959
- throw new Error("Invalid webhook signature");
960
- }
961
- return JSON.parse(payload);
962
- }
963
- function createWebhookHandler(secret, handlers) {
964
- return async (req) => {
965
- try {
966
- const event = await parseWebhook(req, secret);
967
- const handler = handlers[event.type];
968
- if (handler) {
969
- await handler(event);
970
- }
971
- return new Response(JSON.stringify({ received: true }), {
972
- status: 200,
973
- headers: { "Content-Type": "application/json" }
974
- });
975
- } catch (error) {
976
- console.error("Webhook error:", error);
977
- return new Response(
978
- JSON.stringify({
979
- error: error instanceof Error ? error.message : "Unknown error"
980
- }),
981
- { status: 400, headers: { "Content-Type": "application/json" } }
982
- );
983
- }
984
- };
985
- }
915
+ // src/index.ts
916
+ import {
917
+ QuotaError,
918
+ QuotaInsufficientCreditsError,
919
+ QuotaNotConnectedError,
920
+ QuotaTokenExpiredError,
921
+ QuotaRateLimitError
922
+ } from "@usequota/core";
923
+ import {
924
+ verifyWebhookSignature,
925
+ parseWebhook,
926
+ createWebhookHandler
927
+ } from "@usequota/core";
986
928
  export {
987
929
  QuotaBalance,
988
930
  QuotaBuyCredits,