clearauth 0.3.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 (88) hide show
  1. package/CHANGELOG.md +235 -0
  2. package/LICENSE +21 -0
  3. package/README.md +417 -0
  4. package/dist/auth/handler.d.ts +38 -0
  5. package/dist/auth/handler.js +483 -0
  6. package/dist/auth/handler.js.map +1 -0
  7. package/dist/auth/login.d.ts +69 -0
  8. package/dist/auth/login.js +103 -0
  9. package/dist/auth/login.js.map +1 -0
  10. package/dist/auth/register.d.ts +72 -0
  11. package/dist/auth/register.js +122 -0
  12. package/dist/auth/register.js.map +1 -0
  13. package/dist/auth/reset-password.d.ts +106 -0
  14. package/dist/auth/reset-password.js +213 -0
  15. package/dist/auth/reset-password.js.map +1 -0
  16. package/dist/auth/utils.d.ts +58 -0
  17. package/dist/auth/utils.js +121 -0
  18. package/dist/auth/utils.js.map +1 -0
  19. package/dist/auth/verify-email.d.ts +70 -0
  20. package/dist/auth/verify-email.js +137 -0
  21. package/dist/auth/verify-email.js.map +1 -0
  22. package/dist/createMechAuth.d.ts +178 -0
  23. package/dist/createMechAuth.js +215 -0
  24. package/dist/createMechAuth.js.map +1 -0
  25. package/dist/database/schema.d.ts +135 -0
  26. package/dist/database/schema.js +37 -0
  27. package/dist/database/schema.js.map +1 -0
  28. package/dist/edge.d.ts +4 -0
  29. package/dist/edge.js +6 -0
  30. package/dist/edge.js.map +1 -0
  31. package/dist/errors.d.ts +25 -0
  32. package/dist/errors.js +44 -0
  33. package/dist/errors.js.map +1 -0
  34. package/dist/handler.d.ts +100 -0
  35. package/dist/handler.js +213 -0
  36. package/dist/handler.js.map +1 -0
  37. package/dist/index.d.ts +22 -0
  38. package/dist/index.js +28 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/logger.d.ts +22 -0
  41. package/dist/logger.js +40 -0
  42. package/dist/logger.js.map +1 -0
  43. package/dist/mech-kysely.d.ts +22 -0
  44. package/dist/mech-kysely.js +88 -0
  45. package/dist/mech-kysely.js.map +1 -0
  46. package/dist/mech-sql-client.d.ts +85 -0
  47. package/dist/mech-sql-client.js +155 -0
  48. package/dist/mech-sql-client.js.map +1 -0
  49. package/dist/node.d.ts +4 -0
  50. package/dist/node.js +10 -0
  51. package/dist/node.js.map +1 -0
  52. package/dist/oauth/arctic-providers.d.ts +60 -0
  53. package/dist/oauth/arctic-providers.js +94 -0
  54. package/dist/oauth/arctic-providers.js.map +1 -0
  55. package/dist/oauth/callbacks.d.ts +155 -0
  56. package/dist/oauth/callbacks.js +286 -0
  57. package/dist/oauth/callbacks.js.map +1 -0
  58. package/dist/oauth/github.d.ts +47 -0
  59. package/dist/oauth/github.js +136 -0
  60. package/dist/oauth/github.js.map +1 -0
  61. package/dist/oauth/google.d.ts +49 -0
  62. package/dist/oauth/google.js +104 -0
  63. package/dist/oauth/google.js.map +1 -0
  64. package/dist/oauth/handler.d.ts +31 -0
  65. package/dist/oauth/handler.js +277 -0
  66. package/dist/oauth/handler.js.map +1 -0
  67. package/dist/password-hasher-argon2.d.ts +7 -0
  68. package/dist/password-hasher-argon2.js +16 -0
  69. package/dist/password-hasher-argon2.js.map +1 -0
  70. package/dist/password-hasher.d.ts +12 -0
  71. package/dist/password-hasher.js +115 -0
  72. package/dist/password-hasher.js.map +1 -0
  73. package/dist/react.d.ts +152 -0
  74. package/dist/react.js +296 -0
  75. package/dist/react.js.map +1 -0
  76. package/dist/types.d.ts +190 -0
  77. package/dist/types.js +7 -0
  78. package/dist/types.js.map +1 -0
  79. package/dist/utils/cors.d.ts +65 -0
  80. package/dist/utils/cors.js +152 -0
  81. package/dist/utils/cors.js.map +1 -0
  82. package/dist/utils/normalize-auth-path.d.ts +1 -0
  83. package/dist/utils/normalize-auth-path.js +8 -0
  84. package/dist/utils/normalize-auth-path.js.map +1 -0
  85. package/dist/validation.d.ts +23 -0
  86. package/dist/validation.js +70 -0
  87. package/dist/validation.js.map +1 -0
  88. package/package.json +93 -0
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Unified HTTP request handler for ClearAuth
3
+ *
4
+ * This module provides a single entry point for handling all authentication requests,
5
+ * automatically routing to the appropriate handler (OAuth or email/password).
6
+ *
7
+ * @module handler
8
+ */
9
+ import { handleOAuthRequest } from './oauth/handler.js';
10
+ import { handleAuthRequest } from './auth/handler.js';
11
+ import { handleCorsPreflightRequest, addCorsHeaders } from './utils/cors.js';
12
+ import { normalizeAuthPath } from './utils/normalize-auth-path.js';
13
+ /**
14
+ * Unified authentication request handler
15
+ *
16
+ * Automatically routes requests to the appropriate handler based on the URL path:
17
+ * - OAuth routes: `/auth/oauth/*`, `/auth/github/*`, `/auth/google/*`, `/auth/callback/*`
18
+ * - Email/password routes: All other `/auth/*` routes
19
+ *
20
+ * @param request - The HTTP request to handle
21
+ * @param config - ClearAuth configuration
22
+ * @returns HTTP response
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * // Cloudflare Workers
27
+ * export default {
28
+ * async fetch(request: Request, env: Env): Promise<Response> {
29
+ * const config: ClearAuthConfig = {
30
+ * database: createMechKysely({ appId: env.MECH_APP_ID, apiKey: env.MECH_API_KEY }),
31
+ * secret: env.AUTH_SECRET,
32
+ * baseUrl: 'https://yourdomain.com',
33
+ * oauth: {
34
+ * github: {
35
+ * clientId: env.GITHUB_CLIENT_ID,
36
+ * clientSecret: env.GITHUB_CLIENT_SECRET,
37
+ * redirectUri: 'https://yourdomain.com/auth/callback/github',
38
+ * },
39
+ * },
40
+ * }
41
+ * return handleClearAuthRequest(request, config)
42
+ * },
43
+ * }
44
+ * ```
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * // Next.js API route
49
+ * import { handleClearAuthRequest } from 'clearauth'
50
+ * import { config } from '@/lib/auth-config'
51
+ *
52
+ * export async function GET(request: Request) {
53
+ * return handleClearAuthRequest(request, config)
54
+ * }
55
+ *
56
+ * export async function POST(request: Request) {
57
+ * return handleClearAuthRequest(request, config)
58
+ * }
59
+ * ```
60
+ */
61
+ export async function handleClearAuthRequest(request, config) {
62
+ // Handle CORS preflight requests
63
+ if (request.method === 'OPTIONS' && config.cors) {
64
+ return handleCorsPreflightRequest(request, config.cors);
65
+ }
66
+ const url = new URL(request.url);
67
+ const pathname = url.pathname;
68
+ let response;
69
+ // Determine which handler to use based on path
70
+ if (isOAuthRoute(pathname)) {
71
+ response = await handleOAuthRequest(request, config);
72
+ }
73
+ else if (isAuthRoute(pathname)) {
74
+ response = await handleAuthRequest(request, config);
75
+ }
76
+ else {
77
+ response = new Response(JSON.stringify({
78
+ error: 'Not Found',
79
+ message: `Authentication route not found: ${pathname}`,
80
+ }), {
81
+ status: 404,
82
+ headers: { 'Content-Type': 'application/json' },
83
+ });
84
+ }
85
+ // Add CORS headers to response if configured
86
+ if (config.cors) {
87
+ response = addCorsHeaders(response, request, config.cors);
88
+ }
89
+ return response;
90
+ }
91
+ /**
92
+ * Check if the path is an OAuth route
93
+ *
94
+ * OAuth routes include:
95
+ * - `/auth/oauth/github` - GitHub OAuth login
96
+ * - `/auth/oauth/google` - Google OAuth login
97
+ * - `/auth/github/login` - GitHub OAuth login (alternative)
98
+ * - `/auth/google/login` - Google OAuth login (alternative)
99
+ * - `/auth/callback/github` - GitHub OAuth callback
100
+ * - `/auth/callback/google` - Google OAuth callback
101
+ * - `/auth/github/callback` - GitHub OAuth callback (alternative)
102
+ * - `/auth/google/callback` - Google OAuth callback (alternative)
103
+ *
104
+ * @param pathname - URL pathname to check
105
+ * @returns True if the path is an OAuth route
106
+ */
107
+ function isOAuthRoute(pathname) {
108
+ const normalizedPath = normalizeAuthPath(pathname);
109
+ // OAuth-specific patterns
110
+ const oauthPatterns = [
111
+ /^\/auth\/oauth\/(github|google)$/, // /auth/oauth/github, /auth/oauth/google
112
+ /^\/auth\/(github|google)\/login$/, // /auth/github/login, /auth/google/login
113
+ /^\/auth\/callback\/(github|google)$/, // /auth/callback/github, /auth/callback/google
114
+ /^\/auth\/(github|google)\/callback$/, // /auth/github/callback, /auth/google/callback
115
+ ];
116
+ return oauthPatterns.some(pattern => pattern.test(normalizedPath));
117
+ }
118
+ /**
119
+ * Check if the path is an email/password auth route
120
+ *
121
+ * Email/password routes include:
122
+ * - POST `/auth/register` - User registration
123
+ * - POST `/auth/verify-email` - Email verification
124
+ * - POST `/auth/resend-verification` - Resend verification email
125
+ * - POST `/auth/login` - User login
126
+ * - POST `/auth/logout` - User logout
127
+ * - POST `/auth/request-reset` - Request password reset token
128
+ * - POST `/auth/reset-password` - Reset password with token
129
+ * - GET `/auth/session` - Get current user session
130
+ *
131
+ * @param pathname - URL pathname to check
132
+ * @returns True if the path is an auth route
133
+ */
134
+ function isAuthRoute(pathname) {
135
+ const normalizedPath = normalizeAuthPath(pathname);
136
+ // Email/password auth patterns
137
+ const authPatterns = [
138
+ /^\/auth\/session$/,
139
+ /^\/auth\/register$/,
140
+ /^\/auth\/verify-email$/,
141
+ /^\/auth\/resend-verification$/,
142
+ /^\/auth\/login$/,
143
+ /^\/auth\/logout$/,
144
+ /^\/auth\/request-reset$/,
145
+ /^\/auth\/reset-password$/,
146
+ ];
147
+ return authPatterns.some(pattern => pattern.test(normalizedPath));
148
+ }
149
+ /**
150
+ * Get a list of all supported routes
151
+ *
152
+ * Useful for debugging and documentation purposes.
153
+ *
154
+ * @returns Object containing OAuth and auth routes
155
+ *
156
+ * @example
157
+ * ```typescript
158
+ * const routes = getSupportedRoutes()
159
+ * console.log('OAuth routes:', routes.oauth)
160
+ * console.log('Auth routes:', routes.auth)
161
+ * ```
162
+ */
163
+ export function getSupportedRoutes() {
164
+ return {
165
+ oauth: [
166
+ { method: 'GET', path: '/auth/oauth/github', description: 'Initiate GitHub OAuth flow' },
167
+ { method: 'GET', path: '/auth/github/login', description: 'Initiate GitHub OAuth flow (alternative)' },
168
+ { method: 'GET', path: '/auth/callback/github', description: 'GitHub OAuth callback' },
169
+ { method: 'GET', path: '/auth/github/callback', description: 'GitHub OAuth callback (alternative)' },
170
+ { method: 'GET', path: '/auth/oauth/google', description: 'Initiate Google OAuth flow' },
171
+ { method: 'GET', path: '/auth/google/login', description: 'Initiate Google OAuth flow (alternative)' },
172
+ { method: 'GET', path: '/auth/callback/google', description: 'Google OAuth callback' },
173
+ { method: 'GET', path: '/auth/google/callback', description: 'Google OAuth callback (alternative)' },
174
+ ],
175
+ auth: [
176
+ { method: 'GET', path: '/auth/session', description: 'Get current user session (from cookie)' },
177
+ { method: 'POST', path: '/auth/register', description: 'User registration with email and password' },
178
+ { method: 'POST', path: '/auth/verify-email', description: 'Verify email with token' },
179
+ { method: 'POST', path: '/auth/resend-verification', description: 'Resend email verification token' },
180
+ { method: 'POST', path: '/auth/login', description: 'User login with email and password' },
181
+ { method: 'POST', path: '/auth/logout', description: 'User logout (delete session)' },
182
+ { method: 'POST', path: '/auth/request-reset', description: 'Request password reset token' },
183
+ { method: 'POST', path: '/auth/reset-password', description: 'Reset password with token' },
184
+ ],
185
+ };
186
+ }
187
+ /**
188
+ * Health check endpoint
189
+ *
190
+ * Returns a simple health check response to verify the auth service is running.
191
+ *
192
+ * @returns HTTP response with health status
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * // In your handler
197
+ * if (url.pathname === '/auth/health') {
198
+ * return healthCheck()
199
+ * }
200
+ * ```
201
+ */
202
+ export function healthCheck() {
203
+ return new Response(JSON.stringify({
204
+ status: 'ok',
205
+ service: 'clearauth',
206
+ version: '0.3.0',
207
+ timestamp: new Date().toISOString(),
208
+ }), {
209
+ status: 200,
210
+ headers: { 'Content-Type': 'application/json' },
211
+ });
212
+ }
213
+ //# sourceMappingURL=handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAA;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAErD,OAAO,EAAE,0BAA0B,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAElE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,OAAgB,EAChB,MAAuB;IAEvB,iCAAiC;IACjC,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChD,OAAO,0BAA0B,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;IACzD,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAChC,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAA;IAE7B,IAAI,QAAkB,CAAA;IAEtB,+CAA+C;IAC/C,IAAI,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3B,QAAQ,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IACtD,CAAC;SAAM,IAAI,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC;QACjC,QAAQ,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IACrD,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,IAAI,QAAQ,CACrB,IAAI,CAAC,SAAS,CAAC;YACb,KAAK,EAAE,WAAW;YAClB,OAAO,EAAE,mCAAmC,QAAQ,EAAE;SACvD,CAAC,EACF;YACE,MAAM,EAAE,GAAG;YACX,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;SAChD,CACF,CAAA;IACH,CAAC;IAED,6CAA6C;IAC7C,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,QAAQ,GAAG,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;IAC3D,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAS,YAAY,CAAC,QAAgB;IACpC,MAAM,cAAc,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAA;IAElD,0BAA0B;IAC1B,MAAM,aAAa,GAAG;QACpB,kCAAkC,EAAY,yCAAyC;QACvF,kCAAkC,EAAY,yCAAyC;QACvF,qCAAqC,EAAS,+CAA+C;QAC7F,qCAAqC,EAAS,+CAA+C;KAC9F,CAAA;IAED,OAAO,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAA;AACpE,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,SAAS,WAAW,CAAC,QAAgB;IACnC,MAAM,cAAc,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAA;IAElD,+BAA+B;IAC/B,MAAM,YAAY,GAAG;QACnB,mBAAmB;QACnB,oBAAoB;QACpB,wBAAwB;QACxB,+BAA+B;QAC/B,iBAAiB;QACjB,kBAAkB;QAClB,yBAAyB;QACzB,0BAA0B;KAC3B,CAAA;IAED,OAAO,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAA;AACnE,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO;QACL,KAAK,EAAE;YACL,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE,WAAW,EAAE,4BAA4B,EAAE;YACxF,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE,WAAW,EAAE,0CAA0C,EAAE;YACtG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,uBAAuB,EAAE,WAAW,EAAE,uBAAuB,EAAE;YACtF,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,uBAAuB,EAAE,WAAW,EAAE,qCAAqC,EAAE;YACpG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE,WAAW,EAAE,4BAA4B,EAAE;YACxF,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,oBAAoB,EAAE,WAAW,EAAE,0CAA0C,EAAE;YACtG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,uBAAuB,EAAE,WAAW,EAAE,uBAAuB,EAAE;YACtF,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,uBAAuB,EAAE,WAAW,EAAE,qCAAqC,EAAE;SACrG;QACD,IAAI,EAAE;YACJ,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,eAAe,EAAE,WAAW,EAAE,wCAAwC,EAAE;YAC/F,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,EAAE,WAAW,EAAE,2CAA2C,EAAE;YACpG,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,EAAE,WAAW,EAAE,yBAAyB,EAAE;YACtF,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,2BAA2B,EAAE,WAAW,EAAE,iCAAiC,EAAE;YACrG,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,WAAW,EAAE,oCAAoC,EAAE;YAC1F,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,WAAW,EAAE,8BAA8B,EAAE;YACrF,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,EAAE,WAAW,EAAE,8BAA8B,EAAE;YAC5F,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,sBAAsB,EAAE,WAAW,EAAE,2BAA2B,EAAE;SAC3F;KACF,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,IAAI,QAAQ,CACjB,IAAI,CAAC,SAAS,CAAC;QACb,MAAM,EAAE,IAAI;QACZ,OAAO,EAAE,WAAW;QACpB,OAAO,EAAE,OAAO;QAChB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC,EACF;QACE,MAAM,EAAE,GAAG;QACX,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,22 @@
1
+ export * from "./errors.js";
2
+ export * from "./logger.js";
3
+ export * from "./validation.js";
4
+ export * from "./mech-sql-client.js";
5
+ export * from "./mech-kysely.js";
6
+ export * from "./createMechAuth.js";
7
+ export * from "./types.js";
8
+ export * from "./database/schema.js";
9
+ export * from "./oauth/arctic-providers.js";
10
+ export * from "./oauth/github.js";
11
+ export * from "./oauth/google.js";
12
+ export * from "./oauth/callbacks.js";
13
+ export * from "./oauth/handler.js";
14
+ export * from "./auth/utils.js";
15
+ export * from "./auth/register.js";
16
+ export * from "./auth/verify-email.js";
17
+ export * from "./auth/login.js";
18
+ export * from "./auth/reset-password.js";
19
+ export * from "./auth/handler.js";
20
+ export * from "./password-hasher.js";
21
+ export * from "./handler.js";
22
+ export * from "./utils/cors.js";
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ export * from "./errors.js";
2
+ export * from "./logger.js";
3
+ export * from "./validation.js";
4
+ export * from "./mech-sql-client.js";
5
+ export * from "./mech-kysely.js";
6
+ export * from "./createMechAuth.js";
7
+ // Type definitions
8
+ export * from "./types.js";
9
+ export * from "./database/schema.js";
10
+ // OAuth functionality
11
+ export * from "./oauth/arctic-providers.js";
12
+ export * from "./oauth/github.js";
13
+ export * from "./oauth/google.js";
14
+ export * from "./oauth/callbacks.js";
15
+ export * from "./oauth/handler.js";
16
+ // Email/Password authentication
17
+ export * from "./auth/utils.js";
18
+ export * from "./auth/register.js";
19
+ export * from "./auth/verify-email.js";
20
+ export * from "./auth/login.js";
21
+ export * from "./auth/reset-password.js";
22
+ export * from "./auth/handler.js";
23
+ export * from "./password-hasher.js";
24
+ // Unified handler (recommended entry point)
25
+ export * from "./handler.js";
26
+ // Utilities
27
+ export * from "./utils/cors.js";
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,sBAAsB,CAAA;AACpC,cAAc,kBAAkB,CAAA;AAChC,cAAc,qBAAqB,CAAA;AAEnC,mBAAmB;AACnB,cAAc,YAAY,CAAA;AAC1B,cAAc,sBAAsB,CAAA;AAEpC,sBAAsB;AACtB,cAAc,6BAA6B,CAAA;AAC3C,cAAc,mBAAmB,CAAA;AACjC,cAAc,mBAAmB,CAAA;AACjC,cAAc,sBAAsB,CAAA;AACpC,cAAc,oBAAoB,CAAA;AAElC,gCAAgC;AAChC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,oBAAoB,CAAA;AAClC,cAAc,wBAAwB,CAAA;AACtC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AAEjC,cAAc,sBAAsB,CAAA;AAEpC,4CAA4C;AAC5C,cAAc,cAAc,CAAA;AAE5B,YAAY;AACZ,cAAc,iBAAiB,CAAA"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Logger interface and utilities for ClearAuth
3
+ */
4
+ export type LogLevel = "debug" | "info" | "warn" | "error";
5
+ export interface Logger {
6
+ debug(message: string, data?: Record<string, any>): void;
7
+ info(message: string, data?: Record<string, any>): void;
8
+ warn(message: string, data?: Record<string, any>): void;
9
+ error(message: string, error?: Error | Record<string, any>): void;
10
+ }
11
+ /**
12
+ * No-op logger (default)
13
+ */
14
+ export declare const noOpLogger: Logger;
15
+ /**
16
+ * Console logger (for development)
17
+ */
18
+ export declare const consoleLogger: Logger;
19
+ /**
20
+ * Get logger based on environment
21
+ */
22
+ export declare function getDefaultLogger(): Logger;
package/dist/logger.js ADDED
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Logger interface and utilities for ClearAuth
3
+ */
4
+ /**
5
+ * No-op logger (default)
6
+ */
7
+ export const noOpLogger = {
8
+ debug: () => { },
9
+ info: () => { },
10
+ warn: () => { },
11
+ error: () => { }
12
+ };
13
+ /**
14
+ * Console logger (for development)
15
+ */
16
+ export const consoleLogger = {
17
+ debug: (message, data) => {
18
+ console.debug(`[clearauth:debug] ${message}`, data);
19
+ },
20
+ info: (message, data) => {
21
+ console.info(`[clearauth:info] ${message}`, data);
22
+ },
23
+ warn: (message, data) => {
24
+ console.warn(`[clearauth:warn] ${message}`, data);
25
+ },
26
+ error: (message, error) => {
27
+ console.error(`[clearauth:error] ${message}`, error);
28
+ }
29
+ };
30
+ /**
31
+ * Get logger based on environment
32
+ */
33
+ export function getDefaultLogger() {
34
+ const env = typeof process !== "undefined" ? process.env : undefined;
35
+ if (env?.NODE_ENV === "development" || env?.DEBUG === "clearauth") {
36
+ return consoleLogger;
37
+ }
38
+ return noOpLogger;
39
+ }
40
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAWH;;GAEG;AACH,MAAM,CAAC,MAAM,UAAU,GAAW;IAChC,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;IACf,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;CAChB,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAW;IACnC,KAAK,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;QACvB,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,EAAE,EAAE,IAAI,CAAC,CAAA;IACrD,CAAC;IACD,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;QACtB,OAAO,CAAC,IAAI,CAAC,oBAAoB,OAAO,EAAE,EAAE,IAAI,CAAC,CAAA;IACnD,CAAC;IACD,IAAI,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;QACtB,OAAO,CAAC,IAAI,CAAC,oBAAoB,OAAO,EAAE,EAAE,IAAI,CAAC,CAAA;IACnD,CAAC;IACD,KAAK,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;QACxB,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,EAAE,EAAE,KAAK,CAAC,CAAA;IACtD,CAAC;CACF,CAAA;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,GAAG,GAAG,OAAO,OAAO,KAAK,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAA;IACpE,IAAI,GAAG,EAAE,QAAQ,KAAK,aAAa,IAAI,GAAG,EAAE,KAAK,KAAK,WAAW,EAAE,CAAC;QAClE,OAAO,aAAa,CAAA;IACtB,CAAC;IACD,OAAO,UAAU,CAAA;AACnB,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Kysely dialect and driver implementation for Mech Storage
3
+ *
4
+ * This module provides a Kysely-compatible database driver that uses Mech Storage's
5
+ * PostgreSQL HTTP API as the backend. It allows Better Auth and other Kysely-based
6
+ * applications to use Mech Storage as their database without direct PostgreSQL connections.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { createMechKysely } from "clearauth"
11
+ * import { betterAuth } from "better-auth"
12
+ *
13
+ * const db = createMechKysely()
14
+ * const auth = betterAuth({
15
+ * database: { db, type: "postgres" }
16
+ * })
17
+ * ```
18
+ */
19
+ import { Kysely } from "kysely";
20
+ import { MechSqlClientConfig } from "./mech-sql-client.js";
21
+ export type MechKyselyConfig = MechSqlClientConfig;
22
+ export declare function createMechKysely(config: MechKyselyConfig): Kysely<any>;
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Kysely dialect and driver implementation for Mech Storage
3
+ *
4
+ * This module provides a Kysely-compatible database driver that uses Mech Storage's
5
+ * PostgreSQL HTTP API as the backend. It allows Better Auth and other Kysely-based
6
+ * applications to use Mech Storage as their database without direct PostgreSQL connections.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { createMechKysely } from "clearauth"
11
+ * import { betterAuth } from "better-auth"
12
+ *
13
+ * const db = createMechKysely()
14
+ * const auth = betterAuth({
15
+ * database: { db, type: "postgres" }
16
+ * })
17
+ * ```
18
+ */
19
+ import { Kysely, PostgresAdapter, PostgresIntrospector, PostgresQueryCompiler } from "kysely";
20
+ import { MechSqlClient } from "./mech-sql-client.js";
21
+ import { getDefaultLogger } from "./logger.js";
22
+ /**
23
+ * Database connection implementation for Mech Storage
24
+ *
25
+ * Implements Kysely's DatabaseConnection interface by delegating SQL execution
26
+ * to the MechSqlClient, which uses Mech Storage's HTTP API.
27
+ *
28
+ * @internal
29
+ */
30
+ class MechDatabaseConnection {
31
+ constructor(client) {
32
+ this.client = client;
33
+ }
34
+ async executeQuery(compiledQuery) {
35
+ const result = await this.client.execute(compiledQuery.sql, compiledQuery.parameters ?? []);
36
+ return {
37
+ rows: result.rows
38
+ };
39
+ }
40
+ async *streamQuery(compiledQuery) {
41
+ const result = await this.executeQuery(compiledQuery);
42
+ yield result;
43
+ }
44
+ }
45
+ class MechDriver {
46
+ constructor(config, logger) {
47
+ this.logger = logger ?? getDefaultLogger();
48
+ this.logger.debug("Creating MechDriver", { configProvided: !!config });
49
+ this.client = new MechSqlClient(config);
50
+ }
51
+ async init() {
52
+ this.logger.debug("MechDriver initialized");
53
+ }
54
+ async acquireConnection() {
55
+ return new MechDatabaseConnection(this.client);
56
+ }
57
+ async beginTransaction(_connection, _settings) { }
58
+ async commitTransaction(_connection) { }
59
+ async rollbackTransaction(_connection) { }
60
+ async releaseConnection(_connection) { }
61
+ async destroy() { }
62
+ }
63
+ class MechPostgresDialect {
64
+ constructor(config) {
65
+ this.config = config;
66
+ }
67
+ createAdapter() {
68
+ return new PostgresAdapter();
69
+ }
70
+ createDriver() {
71
+ return new MechDriver(this.config);
72
+ }
73
+ createIntrospector(db) {
74
+ return new PostgresIntrospector(db);
75
+ }
76
+ createQueryCompiler() {
77
+ return new PostgresQueryCompiler();
78
+ }
79
+ }
80
+ export function createMechKysely(config) {
81
+ const logger = config.logger ?? getDefaultLogger();
82
+ logger.debug("Creating Kysely instance with MechPostgresDialect");
83
+ const dialect = new MechPostgresDialect(config);
84
+ const db = new Kysely({ dialect });
85
+ logger.debug("Kysely instance created");
86
+ return db;
87
+ }
88
+ //# sourceMappingURL=mech-kysely.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mech-kysely.js","sourceRoot":"","sources":["../src/mech-kysely.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EACL,MAAM,EAGN,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EAMtB,MAAM,QAAQ,CAAA;AACf,OAAO,EAAE,aAAa,EAAuB,MAAM,sBAAsB,CAAA;AACzE,OAAO,EAAU,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEtD;;;;;;;GAOG;AACH,MAAM,sBAAsB;IAG1B,YAAY,MAAqB;QAC/B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED,KAAK,CAAC,YAAY,CAAI,aAA4B;QAChD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAI,aAAa,CAAC,GAAG,EAAE,aAAa,CAAC,UAAU,IAAI,EAAE,CAAC,CAAA;QAC9F,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;SACA,CAAA;IACrB,CAAC;IAED,KAAK,CAAC,CAAC,WAAW,CAAI,aAA4B;QAChD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,YAAY,CAAI,aAAa,CAAC,CAAA;QACxD,MAAM,MAAM,CAAA;IACd,CAAC;CACF;AAED,MAAM,UAAU;IAId,YAAY,MAA2B,EAAE,MAAe;QACtD,IAAI,CAAC,MAAM,GAAG,MAAM,IAAI,gBAAgB,EAAE,CAAA;QAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAA;QACtE,IAAI,CAAC,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,CAAA;IACzC,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAA;IAC7C,CAAC;IAED,KAAK,CAAC,iBAAiB;QACrB,OAAO,IAAI,sBAAsB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAChD,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,WAA+B,EAAE,SAA8B,IAAkB,CAAC;IAEzG,KAAK,CAAC,iBAAiB,CAAC,WAA+B,IAAkB,CAAC;IAE1E,KAAK,CAAC,mBAAmB,CAAC,WAA+B,IAAkB,CAAC;IAE5E,KAAK,CAAC,iBAAiB,CAAC,WAA+B,IAAkB,CAAC;IAE1E,KAAK,CAAC,OAAO,KAAmB,CAAC;CAClC;AAED,MAAM,mBAAmB;IAGvB,YAAY,MAA2B;QACrC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;IACtB,CAAC;IAED,aAAa;QACX,OAAO,IAAI,eAAe,EAAE,CAAA;IAC9B,CAAC;IAED,YAAY;QACV,OAAO,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IACpC,CAAC;IAED,kBAAkB,CAAC,EAAe;QAChC,OAAO,IAAI,oBAAoB,CAAC,EAAE,CAAC,CAAA;IACrC,CAAC;IAED,mBAAmB;QACjB,OAAO,IAAI,qBAAqB,EAAE,CAAA;IACpC,CAAC;CACF;AAID,MAAM,UAAU,gBAAgB,CAAC,MAAwB;IACvD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,gBAAgB,EAAE,CAAA;IAClD,MAAM,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAA;IACjE,MAAM,OAAO,GAAG,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAA;IAC/C,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;IAClC,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAA;IACvC,OAAO,EAAE,CAAA;AACX,CAAC"}
@@ -0,0 +1,85 @@
1
+ import { Logger } from "./logger.js";
2
+ /**
3
+ * Response type from Mech Storage PostgreSQL API
4
+ */
5
+ export type MechSqlResponse = {
6
+ success: boolean;
7
+ rows?: unknown[];
8
+ rowCount?: number;
9
+ error?: {
10
+ code: string;
11
+ message: string;
12
+ hints?: string[];
13
+ };
14
+ };
15
+ /**
16
+ * Configuration for MechSqlClient
17
+ *
18
+ * Minimal required config:
19
+ * - appId: Your Mech app ID
20
+ * - apiKey: Your Mech API key
21
+ *
22
+ * All other fields have sensible defaults:
23
+ * - baseUrl: defaults to "https://storage.mechdna.net"
24
+ * - appSchemaId: defaults to appId (most common case)
25
+ * - timeout: defaults to 30000ms
26
+ * - maxRetries: defaults to 2
27
+ */
28
+ export type MechSqlClientConfig = {
29
+ /** Mech Storage base URL. Defaults to "https://storage.mechdna.net" */
30
+ baseUrl?: string;
31
+ /** Mech App ID. Required */
32
+ appId: string;
33
+ /** Mech App Schema ID. Defaults to appId if not provided */
34
+ appSchemaId?: string;
35
+ /** Mech API Key. Required */
36
+ apiKey: string;
37
+ /** Request timeout in ms. Defaults to 30000 */
38
+ timeout?: number;
39
+ /** Custom logger instance */
40
+ logger?: Logger;
41
+ /** Max retry attempts for failed requests. Defaults to 2 */
42
+ maxRetries?: number;
43
+ };
44
+ /**
45
+ * HTTP client for Mech Storage PostgreSQL API
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * const client = new MechSqlClient()
50
+ * const { rows } = await client.execute("SELECT * FROM users WHERE id = $1", [123])
51
+ * ```
52
+ */
53
+ export declare class MechSqlClient {
54
+ private readonly baseUrl;
55
+ private readonly appId;
56
+ private readonly appSchemaId;
57
+ private readonly apiKey;
58
+ private readonly timeout;
59
+ private readonly logger;
60
+ private readonly maxRetries;
61
+ constructor(config: MechSqlClientConfig);
62
+ /**
63
+ * Execute a SQL query against Mech Storage
64
+ *
65
+ * @param sql - SQL query string (use $1, $2, etc. for parameters)
66
+ * @param params - Query parameters
67
+ * @returns Object with rows and rowCount
68
+ * @throws ClearAuthSqlError, ClearAuthNetworkError, ClearAuthTimeoutError, ClearAuthRateLimitError
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * const { rows } = await client.execute(
73
+ * "SELECT * FROM users WHERE email = $1",
74
+ * ["user@example.com"]
75
+ * )
76
+ * ```
77
+ */
78
+ execute<R = unknown>(sql: string, params?: readonly unknown[]): Promise<{
79
+ rows: R[];
80
+ rowCount: number;
81
+ }>;
82
+ private executeWithRetry;
83
+ private executeOnce;
84
+ private isRetryable;
85
+ }