@codefox-inc/oauth-provider 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +572 -0
  3. package/dist/client/_generated/_ignore.d.ts +1 -0
  4. package/dist/client/_generated/_ignore.d.ts.map +1 -0
  5. package/dist/client/_generated/_ignore.js +3 -0
  6. package/dist/client/_generated/_ignore.js.map +1 -0
  7. package/dist/client/auth-config.d.ts +85 -0
  8. package/dist/client/auth-config.d.ts.map +1 -0
  9. package/dist/client/auth-config.js +81 -0
  10. package/dist/client/auth-config.js.map +1 -0
  11. package/dist/client/auth-helper.d.ts +81 -0
  12. package/dist/client/auth-helper.d.ts.map +1 -0
  13. package/dist/client/auth-helper.js +97 -0
  14. package/dist/client/auth-helper.js.map +1 -0
  15. package/dist/client/index.d.ts +189 -0
  16. package/dist/client/index.d.ts.map +1 -0
  17. package/dist/client/index.js +230 -0
  18. package/dist/client/index.js.map +1 -0
  19. package/dist/client/routes.d.ts +94 -0
  20. package/dist/client/routes.d.ts.map +1 -0
  21. package/dist/client/routes.js +113 -0
  22. package/dist/client/routes.js.map +1 -0
  23. package/dist/component/_generated/api.d.ts +44 -0
  24. package/dist/component/_generated/api.d.ts.map +1 -0
  25. package/dist/component/_generated/api.js +31 -0
  26. package/dist/component/_generated/api.js.map +1 -0
  27. package/dist/component/_generated/component.d.ts +123 -0
  28. package/dist/component/_generated/component.d.ts.map +1 -0
  29. package/dist/component/_generated/component.js +11 -0
  30. package/dist/component/_generated/component.js.map +1 -0
  31. package/dist/component/_generated/dataModel.d.ts +46 -0
  32. package/dist/component/_generated/dataModel.d.ts.map +1 -0
  33. package/dist/component/_generated/dataModel.js +11 -0
  34. package/dist/component/_generated/dataModel.js.map +1 -0
  35. package/dist/component/_generated/server.d.ts +121 -0
  36. package/dist/component/_generated/server.d.ts.map +1 -0
  37. package/dist/component/_generated/server.js +78 -0
  38. package/dist/component/_generated/server.js.map +1 -0
  39. package/dist/component/clientManagement.d.ts +39 -0
  40. package/dist/component/clientManagement.d.ts.map +1 -0
  41. package/dist/component/clientManagement.js +169 -0
  42. package/dist/component/clientManagement.js.map +1 -0
  43. package/dist/component/constants.d.ts +31 -0
  44. package/dist/component/constants.d.ts.map +1 -0
  45. package/dist/component/constants.js +36 -0
  46. package/dist/component/constants.js.map +1 -0
  47. package/dist/component/convex.config.d.ts +3 -0
  48. package/dist/component/convex.config.d.ts.map +1 -0
  49. package/dist/component/convex.config.js +3 -0
  50. package/dist/component/convex.config.js.map +1 -0
  51. package/dist/component/handlers.d.ts +143 -0
  52. package/dist/component/handlers.d.ts.map +1 -0
  53. package/dist/component/handlers.js +624 -0
  54. package/dist/component/handlers.js.map +1 -0
  55. package/dist/component/mutations.d.ts +111 -0
  56. package/dist/component/mutations.d.ts.map +1 -0
  57. package/dist/component/mutations.js +459 -0
  58. package/dist/component/mutations.js.map +1 -0
  59. package/dist/component/queries.d.ts +127 -0
  60. package/dist/component/queries.d.ts.map +1 -0
  61. package/dist/component/queries.js +145 -0
  62. package/dist/component/queries.js.map +1 -0
  63. package/dist/component/schema.d.ts +116 -0
  64. package/dist/component/schema.d.ts.map +1 -0
  65. package/dist/component/schema.js +77 -0
  66. package/dist/component/schema.js.map +1 -0
  67. package/dist/component/token_security.d.ts +53 -0
  68. package/dist/component/token_security.d.ts.map +1 -0
  69. package/dist/component/token_security.js +91 -0
  70. package/dist/component/token_security.js.map +1 -0
  71. package/dist/lib/convex-types.d.ts +21 -0
  72. package/dist/lib/convex-types.d.ts.map +1 -0
  73. package/dist/lib/convex-types.js +2 -0
  74. package/dist/lib/convex-types.js.map +1 -0
  75. package/dist/lib/oauth.d.ts +123 -0
  76. package/dist/lib/oauth.d.ts.map +1 -0
  77. package/dist/lib/oauth.js +295 -0
  78. package/dist/lib/oauth.js.map +1 -0
  79. package/dist/react/index.d.ts +2 -0
  80. package/dist/react/index.d.ts.map +1 -0
  81. package/dist/react/index.js +6 -0
  82. package/dist/react/index.js.map +1 -0
  83. package/package.json +121 -0
  84. package/src/client/__tests__/auth-config.test.ts +244 -0
  85. package/src/client/__tests__/auth-helper.test.ts +273 -0
  86. package/src/client/__tests__/oauth-provider.test.ts +418 -0
  87. package/src/client/__tests__/routes.test.ts +428 -0
  88. package/src/client/_generated/_ignore.ts +1 -0
  89. package/src/client/auth-config.ts +157 -0
  90. package/src/client/auth-helper.ts +201 -0
  91. package/src/client/index.ts +326 -0
  92. package/src/client/routes.ts +251 -0
  93. package/src/component/__tests__/oauth.test.ts +3310 -0
  94. package/src/component/__tests__/rfc-compliance.test.ts +788 -0
  95. package/src/component/__tests__/token-security.test.ts +133 -0
  96. package/src/component/_generated/api.ts +60 -0
  97. package/src/component/_generated/component.ts +201 -0
  98. package/src/component/_generated/dataModel.ts +60 -0
  99. package/src/component/_generated/server.ts +156 -0
  100. package/src/component/clientManagement.ts +189 -0
  101. package/src/component/constants.ts +40 -0
  102. package/src/component/convex.config.ts +3 -0
  103. package/src/component/handlers.ts +964 -0
  104. package/src/component/mutations.ts +531 -0
  105. package/src/component/queries.ts +165 -0
  106. package/src/component/schema.ts +92 -0
  107. package/src/component/token_security.ts +102 -0
  108. package/src/lib/__tests__/oauth-helpers.test.ts +143 -0
  109. package/src/lib/__tests__/oauth-jwt.test.ts +405 -0
  110. package/src/lib/convex-types.ts +37 -0
  111. package/src/lib/oauth.ts +412 -0
  112. package/src/react/index.ts +7 -0
  113. package/src/test.ts +21 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convex-types.d.ts","sourceRoot":"","sources":["../../src/lib/convex-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACR,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,kBAAkB,EACrB,MAAM,eAAe,CAAC;AAEvB;;;;;;;;;GASG;AACH,MAAM,MAAM,WAAW,GAAG;IACtB,QAAQ,CAAC,CAAC,SAAS,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,CAAC,EAC7D,KAAK,EAAE,CAAC,EACR,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IACvC,WAAW,CAAC,CAAC,SAAS,iBAAiB,CAAC,UAAU,EAAE,kBAAkB,CAAC,EACnE,QAAQ,EAAE,CAAC,EACX,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,cAAc,GAAG;IACxC,SAAS,CAAC,CAAC,SAAS,iBAAiB,CAAC,QAAQ,EAAE,kBAAkB,CAAC,EAC/D,MAAM,EAAE,CAAC,EACT,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;CACrC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=convex-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convex-types.js","sourceRoot":"","sources":["../../src/lib/convex-types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,123 @@
1
+ import { exportJWK } from "jose";
2
+ import type { JWTPayload } from "jose";
3
+ import type { Auth } from "convex/server";
4
+ import type { RunActionCtx } from "./convex-types.js";
5
+ /**
6
+ * OAuth 2.1 Provider Configuration
7
+ */
8
+ export interface OAuthConfig {
9
+ privateKey: string;
10
+ jwks: string;
11
+ keyId?: string;
12
+ siteUrl: string;
13
+ convexSiteUrl?: string;
14
+ allowedOrigins?: string;
15
+ allowedScopes?: string[];
16
+ getUserId?: (ctx: RunActionCtx & {
17
+ auth: Auth;
18
+ }, request: Request) => Promise<string | null> | string | null;
19
+ checkAuthorization?: (ctx: RunActionCtx & {
20
+ auth: Auth;
21
+ }, userId: string, clientId?: string) => Promise<boolean>;
22
+ allowDynamicClientRegistration?: boolean;
23
+ prefix?: string;
24
+ }
25
+ /**
26
+ * User Profile for UserInfo endpoint
27
+ */
28
+ export interface UserProfile {
29
+ sub: string;
30
+ name?: string;
31
+ email?: string;
32
+ picture?: string;
33
+ email_verified?: boolean;
34
+ }
35
+ type JoseJWK = Awaited<ReturnType<typeof exportJWK>>;
36
+ /**
37
+ * Reset key cache (for testing)
38
+ */
39
+ export declare function resetKeysForTest(): void;
40
+ /**
41
+ * Get Public JWK (for JWKS endpoint)
42
+ * @deprecated Use getJWKS instead
43
+ */
44
+ export declare function getPublicJWK(publicKeyPEM: string): Promise<JoseJWK>;
45
+ /**
46
+ * Get JWKS for the JWKS endpoint
47
+ * Adds kid: "default-key" to each key if not present (for compatibility with Convex Auth JWKS)
48
+ */
49
+ export declare function getJWKS(config: OAuthConfig): Promise<{
50
+ keys: JoseJWK[];
51
+ }>;
52
+ export declare function getSigningKeyId(config: OAuthConfig): string;
53
+ /**
54
+ * Sign a JWT using the private key
55
+ */
56
+ export declare function sign(payload: Record<string, unknown>, subject: string, audience: string, expiresIn: string | number, privateKeyPEM: string, issuer?: string, keyId?: string): Promise<string>;
57
+ /**
58
+ * Verify Access Token using Public Key (PEM) or JWKS
59
+ */
60
+ export declare function verifyAccessToken(token: string, publicKeyOrConfig: string | OAuthConfig, issuerUrl: string, expectedAudience?: string): Promise<JWTPayload>;
61
+ /**
62
+ * Generate a random code (Authorization Code)
63
+ */
64
+ export declare function generateCode(length?: number): string;
65
+ /**
66
+ * Generate a cryptographically strong Client Secret (hex string)
67
+ */
68
+ export declare function generateClientSecret(length?: number): string;
69
+ /**
70
+ * Get Issuer URL helper
71
+ */
72
+ export declare function getIssuerUrl(config: OAuthConfig): string;
73
+ /**
74
+ * Normalize OAuth prefix for consistent URL building.
75
+ * Ensures a leading slash, trims a trailing slash, and treats "/" as root ("").
76
+ */
77
+ export declare function normalizePrefix(prefix?: string): string;
78
+ /**
79
+ * CORS Helper - Get allowed origin
80
+ */
81
+ export declare function getAllowedOrigin(origin: string | null, config: OAuthConfig): string | null;
82
+ /**
83
+ * Create CORS headers
84
+ */
85
+ export declare function createCorsHeaders(origin: string | null, config: OAuthConfig, methods?: string): Record<string, string>;
86
+ /**
87
+ * Handle CORS preflight OPTIONS request
88
+ */
89
+ export declare function handleCorsOptions(request: Request, config: OAuthConfig, methods?: string): Response | null;
90
+ /**
91
+ * OAuth Error Class
92
+ */
93
+ export declare class OAuthError extends Error {
94
+ code: string;
95
+ statusCode: number;
96
+ constructor(code: string, message: string, statusCode?: number);
97
+ toResponse(headers: Record<string, string>): Response;
98
+ }
99
+ /**
100
+ * Default OAuth issuer pattern
101
+ * Used to identify OAuth tokens by checking if issuer URL contains this pattern
102
+ */
103
+ export declare const DEFAULT_OAUTH_ISSUER_PATTERN = "/oauth";
104
+ /**
105
+ * Check if an identity is from an OAuth token
106
+ * @param identity - User identity from ctx.auth.getUserIdentity()
107
+ * @param issuerPattern - Pattern to match in issuer URL (default: "/oauth")
108
+ * @returns true if the identity is from an OAuth token
109
+ */
110
+ export declare function isOAuthToken(identity: {
111
+ issuer?: string;
112
+ subject?: string;
113
+ } | null | undefined, issuerPattern?: string): boolean;
114
+ /**
115
+ * Extract client ID from an OAuth token identity
116
+ * @param identity - User identity from ctx.auth.getUserIdentity()
117
+ * @returns Client ID if present, undefined otherwise
118
+ */
119
+ export declare function getOAuthClientId(identity: {
120
+ cid?: string;
121
+ } | null | undefined): string | undefined;
122
+ export {};
123
+ //# sourceMappingURL=oauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,295 @@
1
+ import { SignJWT, importPKCS8, exportJWK, jwtVerify, importSPKI, createLocalJWKSet } from "jose";
2
+ const keyCache = new Map();
3
+ const jwkCache = new Map();
4
+ const jwksKeyCache = new Map();
5
+ const DEFAULT_KEY_ID = "default-key";
6
+ /**
7
+ * Reset key cache (for testing)
8
+ */
9
+ export function resetKeysForTest() {
10
+ keyCache.clear();
11
+ jwkCache.clear();
12
+ jwksKeyCache.clear();
13
+ }
14
+ /**
15
+ * Get Private Key from PEM string
16
+ */
17
+ async function getPrivateKey(privateKeyPEM) {
18
+ const cacheKey = `private:${privateKeyPEM}`;
19
+ const cached = keyCache.get(cacheKey);
20
+ if (cached)
21
+ return cached;
22
+ const key = await importPKCS8(privateKeyPEM, "RS256");
23
+ keyCache.set(cacheKey, key);
24
+ return key;
25
+ }
26
+ /**
27
+ * Get Public Key from PEM string
28
+ */
29
+ async function getPublicKey(publicKeyPEM) {
30
+ const cacheKey = `public:${publicKeyPEM}`;
31
+ const cached = keyCache.get(cacheKey);
32
+ if (cached)
33
+ return cached;
34
+ const key = await importSPKI(publicKeyPEM, "RS256", { extractable: true });
35
+ keyCache.set(cacheKey, key);
36
+ return key;
37
+ }
38
+ /**
39
+ * Get Public JWK (for JWKS endpoint)
40
+ * @deprecated Use getJWKS instead
41
+ */
42
+ export async function getPublicJWK(publicKeyPEM) {
43
+ const cacheKey = `jwk:${publicKeyPEM}`;
44
+ const cached = jwkCache.get(cacheKey);
45
+ if (cached)
46
+ return cached;
47
+ const key = await getPublicKey(publicKeyPEM);
48
+ const jwk = await exportJWK(key);
49
+ // Remove private fields
50
+ const { d: _d, p: _p, q: _q, dp: _dp, dq: _dq, qi: _qi, ...publicKey } = jwk;
51
+ const result = { ...publicKey, use: "sig", alg: "RS256", kid: "default-key" };
52
+ jwkCache.set(cacheKey, result);
53
+ return result;
54
+ }
55
+ /**
56
+ * Get JWKS for the JWKS endpoint
57
+ * Adds kid: "default-key" to each key if not present (for compatibility with Convex Auth JWKS)
58
+ */
59
+ export async function getJWKS(config) {
60
+ const jwks = JSON.parse(config.jwks);
61
+ const keyId = getSigningKeyId(config);
62
+ jwks.keys = jwks.keys.map((key) => {
63
+ const { d: _d, p: _p, q: _q, dp: _dp, dq: _dq, qi: _qi, oth: _oth, k: _k, ...publicKey } = key;
64
+ return {
65
+ ...publicKey,
66
+ kid: publicKey.kid ?? keyId,
67
+ };
68
+ });
69
+ return jwks;
70
+ }
71
+ function ensureKidOnJwksKeys(keys, keyId) {
72
+ return keys.map((key) => ({
73
+ ...key,
74
+ kid: key.kid ?? keyId,
75
+ }));
76
+ }
77
+ export function getSigningKeyId(config) {
78
+ if (config.keyId)
79
+ return config.keyId;
80
+ try {
81
+ const jwks = JSON.parse(config.jwks);
82
+ const kid = jwks.keys?.[0]?.kid;
83
+ if (typeof kid === "string" && kid.length > 0) {
84
+ return kid;
85
+ }
86
+ }
87
+ catch {
88
+ // Fall through to default when jwks is invalid.
89
+ }
90
+ return DEFAULT_KEY_ID;
91
+ }
92
+ /**
93
+ * Sign a JWT using the private key
94
+ */
95
+ export async function sign(payload, subject, audience, expiresIn, privateKeyPEM, issuer, keyId = DEFAULT_KEY_ID) {
96
+ const privateKey = await getPrivateKey(privateKeyPEM);
97
+ const jwt = new SignJWT(payload)
98
+ .setProtectedHeader({ alg: "RS256", kid: keyId })
99
+ .setIssuedAt()
100
+ .setSubject(subject)
101
+ .setAudience(audience)
102
+ .setExpirationTime(expiresIn);
103
+ if (issuer) {
104
+ jwt.setIssuer(issuer);
105
+ }
106
+ return jwt.sign(privateKey);
107
+ }
108
+ /**
109
+ * Verify Access Token using Public Key (PEM) or JWKS
110
+ */
111
+ export async function verifyAccessToken(token, publicKeyOrConfig, issuerUrl, expectedAudience = "convex") {
112
+ let publicKey;
113
+ if (typeof publicKeyOrConfig === "string") {
114
+ // Legacy: PEM string
115
+ publicKey = await getPublicKey(publicKeyOrConfig);
116
+ }
117
+ else {
118
+ // New: OAuthConfig - get key from jwks or publicKey
119
+ publicKey = await getVerificationKey(publicKeyOrConfig);
120
+ }
121
+ const options = {
122
+ issuer: issuerUrl,
123
+ audience: expectedAudience,
124
+ };
125
+ const { payload } = typeof publicKey === "function"
126
+ ? await jwtVerify(token, publicKey, options)
127
+ : await jwtVerify(token, publicKey, options);
128
+ return payload;
129
+ }
130
+ /**
131
+ * Get verification key from config (JWKS)
132
+ */
133
+ async function getVerificationKey(config) {
134
+ const cached = jwksKeyCache.get(config.jwks);
135
+ if (cached)
136
+ return cached;
137
+ const jwks = JSON.parse(config.jwks);
138
+ if (!jwks.keys?.length) {
139
+ throw new Error("jwks must include at least one key");
140
+ }
141
+ const normalized = { keys: ensureKidOnJwksKeys(jwks.keys, getSigningKeyId(config)) };
142
+ const localJwks = createLocalJWKSet(normalized);
143
+ jwksKeyCache.set(config.jwks, localJwks);
144
+ return localJwks;
145
+ }
146
+ /**
147
+ * Generate a random code (Authorization Code)
148
+ */
149
+ export function generateCode(length = 32) {
150
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
151
+ let result = "";
152
+ const randomValues = new Uint32Array(length);
153
+ crypto.getRandomValues(randomValues);
154
+ for (let i = 0; i < length; i++) {
155
+ result += chars[randomValues[i] % chars.length];
156
+ }
157
+ return result;
158
+ }
159
+ /**
160
+ * Generate a cryptographically strong Client Secret (hex string)
161
+ */
162
+ export function generateClientSecret(length = 64) {
163
+ const array = new Uint8Array(length);
164
+ crypto.getRandomValues(array);
165
+ return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');
166
+ }
167
+ /**
168
+ * Get Issuer URL helper
169
+ */
170
+ export function getIssuerUrl(config) {
171
+ const issuerBaseUrl = config.convexSiteUrl ?? config.siteUrl;
172
+ const prefix = normalizePrefix(config.prefix);
173
+ return issuerBaseUrl + prefix;
174
+ }
175
+ /**
176
+ * Normalize OAuth prefix for consistent URL building.
177
+ * Ensures a leading slash, trims a trailing slash, and treats "/" as root ("").
178
+ */
179
+ export function normalizePrefix(prefix) {
180
+ const raw = (prefix ?? "/oauth").trim();
181
+ if (!raw || raw === "/")
182
+ return "";
183
+ let normalized = raw.startsWith("/") ? raw : `/${raw}`;
184
+ if (normalized.length > 1 && normalized.endsWith("/")) {
185
+ normalized = normalized.slice(0, -1);
186
+ }
187
+ return normalized;
188
+ }
189
+ /**
190
+ * CORS Helper - Get allowed origin
191
+ */
192
+ export function getAllowedOrigin(origin, config) {
193
+ // 1. CLI / Non-browser clients (No Origin header)
194
+ if (!origin)
195
+ return null;
196
+ // 2. Browser clients (Verified Origins)
197
+ const toOrigin = (value) => {
198
+ if (!value)
199
+ return null;
200
+ try {
201
+ return new URL(value).origin;
202
+ }
203
+ catch {
204
+ return null;
205
+ }
206
+ };
207
+ const allowedList = (config.allowedOrigins || "")
208
+ .split(",")
209
+ .map((u) => toOrigin(u.trim()))
210
+ .filter((u) => !!u);
211
+ const siteOrigin = toOrigin(config.siteUrl);
212
+ const convexOrigin = toOrigin(config.convexSiteUrl);
213
+ if (allowedList.includes(origin))
214
+ return origin;
215
+ if (siteOrigin && origin === siteOrigin)
216
+ return origin;
217
+ if (convexOrigin && origin === convexOrigin)
218
+ return origin;
219
+ // Allow Localhost (Development tools & Inspectors)
220
+ if (/^http:\/\/localhost(:\d+)?$/.test(origin))
221
+ return origin;
222
+ if (/^http:\/\/127\.0\.0\.1(:\d+)?$/.test(origin))
223
+ return origin;
224
+ return null;
225
+ }
226
+ /**
227
+ * Create CORS headers
228
+ */
229
+ export function createCorsHeaders(origin, config, methods = "GET, POST, OPTIONS") {
230
+ const headers = {
231
+ "Content-Type": "application/json",
232
+ "Access-Control-Allow-Methods": methods,
233
+ "Access-Control-Allow-Headers": "Content-Type, Authorization, mcp-protocol-version",
234
+ };
235
+ const allowedOrigin = getAllowedOrigin(origin, config);
236
+ if (allowedOrigin) {
237
+ headers["Access-Control-Allow-Origin"] = allowedOrigin;
238
+ }
239
+ return headers;
240
+ }
241
+ /**
242
+ * Handle CORS preflight OPTIONS request
243
+ */
244
+ export function handleCorsOptions(request, config, methods = "GET, POST, OPTIONS") {
245
+ if (request.method === "OPTIONS") {
246
+ const origin = request.headers.get("Origin");
247
+ return new Response(null, { headers: createCorsHeaders(origin, config, methods) });
248
+ }
249
+ return null;
250
+ }
251
+ /**
252
+ * OAuth Error Class
253
+ */
254
+ export class OAuthError extends Error {
255
+ code;
256
+ statusCode;
257
+ constructor(code, message, statusCode = 400) {
258
+ super(message);
259
+ this.code = code;
260
+ this.statusCode = statusCode;
261
+ this.name = "OAuthError";
262
+ }
263
+ toResponse(headers) {
264
+ return new Response(JSON.stringify({
265
+ error: this.code,
266
+ error_description: this.message,
267
+ }), { status: this.statusCode, headers });
268
+ }
269
+ }
270
+ // ============================================================================
271
+ // OAuth Token Detection Helpers
272
+ // ============================================================================
273
+ /**
274
+ * Default OAuth issuer pattern
275
+ * Used to identify OAuth tokens by checking if issuer URL contains this pattern
276
+ */
277
+ export const DEFAULT_OAUTH_ISSUER_PATTERN = "/oauth";
278
+ /**
279
+ * Check if an identity is from an OAuth token
280
+ * @param identity - User identity from ctx.auth.getUserIdentity()
281
+ * @param issuerPattern - Pattern to match in issuer URL (default: "/oauth")
282
+ * @returns true if the identity is from an OAuth token
283
+ */
284
+ export function isOAuthToken(identity, issuerPattern = DEFAULT_OAUTH_ISSUER_PATTERN) {
285
+ return !!(identity?.issuer?.includes(issuerPattern) && identity?.subject);
286
+ }
287
+ /**
288
+ * Extract client ID from an OAuth token identity
289
+ * @param identity - User identity from ctx.auth.getUserIdentity()
290
+ * @returns Client ID if present, undefined otherwise
291
+ */
292
+ export function getOAuthClientId(identity) {
293
+ return identity?.cid;
294
+ }
295
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/lib/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,OAAO,EACP,WAAW,EACX,SAAS,EACT,SAAS,EACT,UAAU,EACV,iBAAiB,EACpB,MAAM,MAAM,CAAC;AAqCd,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAmB,CAAC;AAC5C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAmB,CAAC;AAC5C,MAAM,YAAY,GAAG,IAAI,GAAG,EAAgD,CAAC;AAC7E,MAAM,cAAc,GAAG,aAAa,CAAC;AAErC;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC5B,QAAQ,CAAC,KAAK,EAAE,CAAC;IACjB,QAAQ,CAAC,KAAK,EAAE,CAAC;IACjB,YAAY,CAAC,KAAK,EAAE,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,aAAa,CAAC,aAAqB;IAC9C,MAAM,QAAQ,GAAG,WAAW,aAAa,EAAE,CAAC;IAC5C,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,GAAG,GAAG,MAAM,WAAW,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACtD,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC5B,OAAO,GAAG,CAAC;AACf,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,YAAY,CAAC,YAAoB;IAC5C,MAAM,QAAQ,GAAG,UAAU,YAAY,EAAE,CAAC;IAC1C,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,YAAY,EAAE,OAAO,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3E,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IAC5B,OAAO,GAAG,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,YAAoB;IACnD,MAAM,QAAQ,GAAG,OAAO,YAAY,EAAE,CAAC;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,CAAC;IAC7C,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;IAEjC,wBAAwB;IACxB,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,SAAS,EAAE,GAAG,GAAG,CAAC;IAE7E,MAAM,MAAM,GAAG,EAAE,GAAG,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC;IAC9E,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,MAAmB;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAwB,CAAC;IAC5D,MAAM,KAAK,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC9B,MAAM,EACF,CAAC,EAAE,EAAE,EACL,CAAC,EAAE,EAAE,EACL,CAAC,EAAE,EAAE,EACL,EAAE,EAAE,GAAG,EACP,EAAE,EAAE,GAAG,EACP,EAAE,EAAE,GAAG,EACP,GAAG,EAAE,IAAI,EACT,CAAC,EAAE,EAAE,EACL,GAAG,SAAS,EACf,GAAG,GASH,CAAC;QAEF,OAAO;YACH,GAAG,SAAS;YACZ,GAAG,EAAE,SAAS,CAAC,GAAG,IAAI,KAAK;SAC9B,CAAC;IACN,CAAC,CAAC,CAAC;IAEH,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAe,EAAE,KAAa;IACvD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACtB,GAAG,GAAG;QACN,GAAG,EAAE,GAAG,CAAC,GAAG,IAAI,KAAK;KACxB,CAAC,CAAC,CAAC;AACR,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAmB;IAC/C,IAAI,MAAM,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC;IACtC,IAAI,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAyB,CAAC;QAC7D,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC;QAChC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,OAAO,GAAG,CAAC;QACf,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACL,gDAAgD;IACpD,CAAC;IACD,OAAO,cAAc,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CACtB,OAAgC,EAChC,OAAe,EACf,QAAgB,EAChB,SAA0B,EAC1B,aAAqB,EACrB,MAAe,EACf,QAAgB,cAAc;IAE9B,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,CAAC;IAEtD,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;SAC3B,kBAAkB,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC;SAChD,WAAW,EAAE;SACb,UAAU,CAAC,OAAO,CAAC;SACnB,WAAW,CAAC,QAAQ,CAAC;SACrB,iBAAiB,CAAC,SAAS,CAAC,CAAC;IAElC,IAAI,MAAM,EAAE,CAAC;QACT,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACnC,KAAa,EACb,iBAAuC,EACvC,SAAiB,EACjB,mBAA2B,QAAQ;IAEnC,IAAI,SAAyD,CAAC;IAE9D,IAAI,OAAO,iBAAiB,KAAK,QAAQ,EAAE,CAAC;QACxC,qBAAqB;QACrB,SAAS,GAAG,MAAM,YAAY,CAAC,iBAAiB,CAAC,CAAC;IACtD,CAAC;SAAM,CAAC;QACJ,oDAAoD;QACpD,SAAS,GAAG,MAAM,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;IAC5D,CAAC;IAED,MAAM,OAAO,GAAG;QACZ,MAAM,EAAE,SAAS;QACjB,QAAQ,EAAE,gBAAgB;KAC7B,CAAC;IACF,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,SAAS,KAAK,UAAU;QAC/C,CAAC,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC;QAC5C,CAAC,CAAC,MAAM,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAEjD,OAAO,OAAO,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,kBAAkB,CAC7B,MAAmB;IAEnB,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAE1B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAwB,CAAC;IAC5D,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,UAAU,GAAG,EAAE,IAAI,EAAE,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;IACrF,MAAM,SAAS,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAChD,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACzC,OAAO,SAAS,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAM,GAAG,EAAE;IACpC,MAAM,KAAK,GAAG,oEAAoE,CAAC;IACnF,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,MAAM,YAAY,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,CAAC,eAAe,CAAC,YAAY,CAAC,CAAC;IACrC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAM,GAAG,EAAE;IAC5C,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC9B,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAClF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,MAAmB;IAC5C,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,MAAM,CAAC,OAAO,CAAC;IAC7D,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9C,OAAO,aAAa,GAAG,MAAM,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAe;IAC3C,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;IACxC,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,EAAE,CAAC;IACnC,IAAI,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;IACvD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QACpD,UAAU,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,UAAU,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAqB,EAAE,MAAmB;IACvE,kDAAkD;IAClD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,wCAAwC;IACxC,MAAM,QAAQ,GAAG,CAAC,KAAyB,EAAiB,EAAE;QAC1D,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,IAAI,CAAC;YACD,OAAO,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,IAAI,CAAC;QAChB,CAAC;IACL,CAAC,CAAC;IACF,MAAM,WAAW,GAAG,CAAC,MAAM,CAAC,cAAc,IAAI,EAAE,CAAC;SAC5C,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;SAC9B,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACrC,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAEpD,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAChD,IAAI,UAAU,IAAI,MAAM,KAAK,UAAU;QAAE,OAAO,MAAM,CAAC;IACvD,IAAI,YAAY,IAAI,MAAM,KAAK,YAAY;QAAE,OAAO,MAAM,CAAC;IAE3D,mDAAmD;IACnD,IAAI,6BAA6B,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAC9D,IAAI,gCAAgC,CAAC,IAAI,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IAEjE,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC7B,MAAqB,EACrB,MAAmB,EACnB,UAAkB,oBAAoB;IAEtC,MAAM,OAAO,GAA2B;QACpC,cAAc,EAAE,kBAAkB;QAClC,8BAA8B,EAAE,OAAO;QACvC,8BAA8B,EAAE,mDAAmD;KACtF,CAAC;IACF,MAAM,aAAa,GAAG,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvD,IAAI,aAAa,EAAE,CAAC;QAChB,OAAO,CAAC,6BAA6B,CAAC,GAAG,aAAa,CAAC;IAC3D,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC7B,OAAgB,EAChB,MAAmB,EACnB,UAAkB,oBAAoB;IAEtC,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC7C,OAAO,IAAI,QAAQ,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACvF,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,UAAW,SAAQ,KAAK;IAEtB;IAEA;IAHX,YACW,IAAY,EACnB,OAAe,EACR,aAAqB,GAAG;QAE/B,KAAK,CAAC,OAAO,CAAC,CAAC;QAJR,SAAI,GAAJ,IAAI,CAAQ;QAEZ,eAAU,GAAV,UAAU,CAAc;QAG/B,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC7B,CAAC;IAED,UAAU,CAAC,OAA+B;QACtC,OAAO,IAAI,QAAQ,CACf,IAAI,CAAC,SAAS,CAAC;YACX,KAAK,EAAE,IAAI,CAAC,IAAI;YAChB,iBAAiB,EAAE,IAAI,CAAC,OAAO;SAClC,CAAC,EACF,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CACvC,CAAC;IACN,CAAC;CACJ;AAED,+EAA+E;AAC/E,gCAAgC;AAChC,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,QAAQ,CAAC;AAErD;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CACxB,QAAkE,EAClE,gBAAwB,4BAA4B;IAEpD,OAAO,CAAC,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,IAAI,QAAQ,EAAE,OAAO,CAAC,CAAC;AAC9E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC5B,QAA6C;IAE7C,OAAO,QAAQ,EAAE,GAAG,CAAC;AACzB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const useMyComponent: () => {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc,UAE1B,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use client";
2
+ // This is where React components / hooks go.
3
+ export const useMyComponent = () => {
4
+ return {};
5
+ };
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/react/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,6CAA6C;AAE7C,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,EAAE;IACjC,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,121 @@
1
+ {
2
+ "name": "@codefox-inc/oauth-provider",
3
+ "description": "OAuth 2.1 / OpenID Connect Provider for Convex Auth (Beta).",
4
+ "repository": "github:codefox-inc/convex-oauth-provider",
5
+ "homepage": "https://github.com/codefox-inc/convex-oauth-provider#readme",
6
+ "bugs": {
7
+ "url": "https://github.com/codefox-inc/convex-oauth-provider/issues"
8
+ },
9
+ "version": "0.2.0",
10
+ "license": "Apache-2.0",
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "keywords": [
15
+ "convex",
16
+ "component",
17
+ "oauth",
18
+ "oauth2",
19
+ "openid-connect",
20
+ "oidc",
21
+ "authentication",
22
+ "authorization"
23
+ ],
24
+ "type": "module",
25
+ "scripts": {
26
+ "dev": "run-p -r 'dev:*'",
27
+ "dev:backend": "convex dev --typecheck-components",
28
+ "dev:frontend": "cd example && vite --clearScreen false",
29
+ "dev:build": "chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'npm run build:codegen' --initial",
30
+ "dev:worker": "cd example && wrangler dev --port 8787 2>&1 | cat",
31
+ "predev": "path-exists .env.local dist || (npm run build && convex dev --once)",
32
+ "build": "tsc --project ./tsconfig.build.json",
33
+ "build:codegen": "npx convex codegen --component-dir ./src/component && npm run build",
34
+ "build:clean": "rm -rf dist *.tsbuildinfo && npm run build:codegen",
35
+ "typecheck": "tsc --noEmit && tsc -p example && tsc -p example/convex",
36
+ "lint": "eslint .",
37
+ "all": "run-p -r 'dev:*' 'test:watch'",
38
+ "test": "vitest run --typecheck",
39
+ "test:watch": "vitest --typecheck --clearScreen false",
40
+ "test:debug": "vitest --inspect-brk --no-file-parallelism",
41
+ "test:coverage": "vitest run --coverage --coverage.reporter=text",
42
+ "changeset": "changeset",
43
+ "version": "changeset version && npm install --package-lock-only",
44
+ "release": "npm run build && changeset publish"
45
+ },
46
+ "files": [
47
+ "dist",
48
+ "src"
49
+ ],
50
+ "exports": {
51
+ "./package.json": "./package.json",
52
+ ".": {
53
+ "types": "./dist/client/index.d.ts",
54
+ "default": "./dist/client/index.js"
55
+ },
56
+ "./react": {
57
+ "types": "./dist/react/index.d.ts",
58
+ "default": "./dist/react/index.js"
59
+ },
60
+ "./test": "./src/test.ts",
61
+ "./_generated/component.js": {
62
+ "types": "./dist/component/_generated/component.d.ts"
63
+ },
64
+ "./convex.config": {
65
+ "types": "./dist/component/convex.config.d.ts",
66
+ "default": "./dist/component/convex.config.js"
67
+ },
68
+ "./convex.config.js": {
69
+ "types": "./dist/component/convex.config.d.ts",
70
+ "default": "./dist/component/convex.config.js"
71
+ }
72
+ },
73
+ "peerDependencies": {
74
+ "convex": "^1.31.6",
75
+ "react": "^18.2.0 || ^19.0.0"
76
+ },
77
+ "dependencies": {
78
+ "bcryptjs": "^2.4.3",
79
+ "jose": "^5.9.6"
80
+ },
81
+ "devDependencies": {
82
+ "@changesets/cli": "^2.27.1",
83
+ "@cloudflare/workers-types": "^4.20260123.0",
84
+ "@convex-dev/auth": "^0.0.88",
85
+ "@convex-dev/eslint-plugin": "^1.1.1",
86
+ "@edge-runtime/vm": "^5.0.0",
87
+ "@eslint/eslintrc": "^3.3.3",
88
+ "@eslint/js": "9.39.2",
89
+ "@modelcontextprotocol/sdk": "^1.25.3",
90
+ "@types/bcryptjs": "^2.4.6",
91
+ "@types/node": "^24.10.9",
92
+ "@types/react": "^19.2.9",
93
+ "@types/react-dom": "^19.2.3",
94
+ "@vitejs/plugin-react": "^5.1.2",
95
+ "@vitest/coverage-v8": "^4.0.17",
96
+ "chokidar-cli": "3.0.0",
97
+ "convex": "1.31.6",
98
+ "convex-test": "0.0.41",
99
+ "cpy-cli": "^6.0.0",
100
+ "eslint": "9.39.2",
101
+ "eslint-plugin-react": "^7.37.5",
102
+ "eslint-plugin-react-hooks": "^7.0.1",
103
+ "eslint-plugin-react-refresh": "^0.4.26",
104
+ "globals": "^17.0.0",
105
+ "hono": "^4.11.5",
106
+ "npm-run-all2": "8.0.4",
107
+ "path-exists-cli": "2.0.0",
108
+ "pkg-pr-new": "^0.0.62",
109
+ "prettier": "3.8.1",
110
+ "react": "^19.2.3",
111
+ "react-dom": "^19.2.3",
112
+ "react-router-dom": "^7.6.2",
113
+ "typescript": "5.9.3",
114
+ "typescript-eslint": "8.53.1",
115
+ "vite": "7.3.1",
116
+ "vitest": "4.0.17",
117
+ "wrangler": "^4.15.2"
118
+ },
119
+ "types": "./dist/client/index.d.ts",
120
+ "module": "./dist/client/index.js"
121
+ }