mates-fullstack 1.0.0-beta.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.
Files changed (202) hide show
  1. package/README.md +311 -0
  2. package/dist/arctic-auth.d.ts +101 -0
  3. package/dist/arctic-auth.d.ts.map +1 -0
  4. package/dist/arctic-auth.js +538 -0
  5. package/dist/arctic-auth.js.map +1 -0
  6. package/dist/asset-manifest.d.ts +14 -0
  7. package/dist/asset-manifest.d.ts.map +1 -0
  8. package/dist/asset-manifest.js +102 -0
  9. package/dist/asset-manifest.js.map +1 -0
  10. package/dist/browser.d.ts +18 -0
  11. package/dist/browser.d.ts.map +1 -0
  12. package/dist/browser.js +25 -0
  13. package/dist/browser.js.map +1 -0
  14. package/dist/build-esbuild.d.ts +29 -0
  15. package/dist/build-esbuild.d.ts.map +1 -0
  16. package/dist/build-esbuild.js +699 -0
  17. package/dist/build-esbuild.js.map +1 -0
  18. package/dist/build-prod.d.ts +126 -0
  19. package/dist/build-prod.d.ts.map +1 -0
  20. package/dist/build-prod.js +1014 -0
  21. package/dist/build-prod.js.map +1 -0
  22. package/dist/cli-new.d.ts +14 -0
  23. package/dist/cli-new.d.ts.map +1 -0
  24. package/dist/cli-new.js +637 -0
  25. package/dist/cli-new.js.map +1 -0
  26. package/dist/client.d.ts +43 -0
  27. package/dist/client.d.ts.map +1 -0
  28. package/dist/client.js +130 -0
  29. package/dist/client.js.map +1 -0
  30. package/dist/cors.d.ts +16 -0
  31. package/dist/cors.d.ts.map +1 -0
  32. package/dist/cors.js +60 -0
  33. package/dist/cors.js.map +1 -0
  34. package/dist/ctx.d.ts +78 -0
  35. package/dist/ctx.d.ts.map +1 -0
  36. package/dist/ctx.js +280 -0
  37. package/dist/ctx.js.map +1 -0
  38. package/dist/dev-watcher.d.ts +23 -0
  39. package/dist/dev-watcher.d.ts.map +1 -0
  40. package/dist/dev-watcher.js +136 -0
  41. package/dist/dev-watcher.js.map +1 -0
  42. package/dist/docs-generator.d.ts +69 -0
  43. package/dist/docs-generator.d.ts.map +1 -0
  44. package/dist/docs-generator.js +557 -0
  45. package/dist/docs-generator.js.map +1 -0
  46. package/dist/docs-page.d.ts +20 -0
  47. package/dist/docs-page.d.ts.map +1 -0
  48. package/dist/docs-page.js +1152 -0
  49. package/dist/docs-page.js.map +1 -0
  50. package/dist/download.d.ts +78 -0
  51. package/dist/download.d.ts.map +1 -0
  52. package/dist/download.js +202 -0
  53. package/dist/download.js.map +1 -0
  54. package/dist/env-loader.d.ts +76 -0
  55. package/dist/env-loader.d.ts.map +1 -0
  56. package/dist/env-loader.js +213 -0
  57. package/dist/env-loader.js.map +1 -0
  58. package/dist/errors.d.ts +146 -0
  59. package/dist/errors.d.ts.map +1 -0
  60. package/dist/errors.js +386 -0
  61. package/dist/errors.js.map +1 -0
  62. package/dist/head.d.ts +31 -0
  63. package/dist/head.d.ts.map +1 -0
  64. package/dist/head.js +245 -0
  65. package/dist/head.js.map +1 -0
  66. package/dist/index.d.ts +30 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.js +30 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/internal-prefixes.d.ts +16 -0
  71. package/dist/internal-prefixes.d.ts.map +1 -0
  72. package/dist/internal-prefixes.js +16 -0
  73. package/dist/internal-prefixes.js.map +1 -0
  74. package/dist/internal.d.ts +25 -0
  75. package/dist/internal.d.ts.map +1 -0
  76. package/dist/internal.js +25 -0
  77. package/dist/internal.js.map +1 -0
  78. package/dist/jwt.d.ts +166 -0
  79. package/dist/jwt.d.ts.map +1 -0
  80. package/dist/jwt.js +261 -0
  81. package/dist/jwt.js.map +1 -0
  82. package/dist/log.d.ts +44 -0
  83. package/dist/log.d.ts.map +1 -0
  84. package/dist/log.js +66 -0
  85. package/dist/log.js.map +1 -0
  86. package/dist/logger.d.ts +76 -0
  87. package/dist/logger.d.ts.map +1 -0
  88. package/dist/logger.js +138 -0
  89. package/dist/logger.js.map +1 -0
  90. package/dist/main-runner.d.ts +59 -0
  91. package/dist/main-runner.d.ts.map +1 -0
  92. package/dist/main-runner.js +157 -0
  93. package/dist/main-runner.js.map +1 -0
  94. package/dist/mates-auth.d.ts +82 -0
  95. package/dist/mates-auth.d.ts.map +1 -0
  96. package/dist/mates-auth.js +323 -0
  97. package/dist/mates-auth.js.map +1 -0
  98. package/dist/middleware.d.ts +30 -0
  99. package/dist/middleware.d.ts.map +1 -0
  100. package/dist/middleware.js +67 -0
  101. package/dist/middleware.js.map +1 -0
  102. package/dist/project-resolver.d.ts +102 -0
  103. package/dist/project-resolver.d.ts.map +1 -0
  104. package/dist/project-resolver.js +271 -0
  105. package/dist/project-resolver.js.map +1 -0
  106. package/dist/rate-limit.d.ts +37 -0
  107. package/dist/rate-limit.d.ts.map +1 -0
  108. package/dist/rate-limit.js +109 -0
  109. package/dist/rate-limit.js.map +1 -0
  110. package/dist/redirect.d.ts +84 -0
  111. package/dist/redirect.d.ts.map +1 -0
  112. package/dist/redirect.js +105 -0
  113. package/dist/redirect.js.map +1 -0
  114. package/dist/renderer.d.ts +91 -0
  115. package/dist/renderer.d.ts.map +1 -0
  116. package/dist/renderer.js +630 -0
  117. package/dist/renderer.js.map +1 -0
  118. package/dist/request-logger.d.ts +12 -0
  119. package/dist/request-logger.d.ts.map +1 -0
  120. package/dist/request-logger.js +55 -0
  121. package/dist/request-logger.js.map +1 -0
  122. package/dist/rest.d.ts +25 -0
  123. package/dist/rest.d.ts.map +1 -0
  124. package/dist/rest.js +93 -0
  125. package/dist/rest.js.map +1 -0
  126. package/dist/router.d.ts +71 -0
  127. package/dist/router.d.ts.map +1 -0
  128. package/dist/router.js +222 -0
  129. package/dist/router.js.map +1 -0
  130. package/dist/rpc-registry.d.ts +84 -0
  131. package/dist/rpc-registry.d.ts.map +1 -0
  132. package/dist/rpc-registry.js +271 -0
  133. package/dist/rpc-registry.js.map +1 -0
  134. package/dist/rpc-runner.d.ts +82 -0
  135. package/dist/rpc-runner.d.ts.map +1 -0
  136. package/dist/rpc-runner.js +564 -0
  137. package/dist/rpc-runner.js.map +1 -0
  138. package/dist/sanitize.d.ts +61 -0
  139. package/dist/sanitize.d.ts.map +1 -0
  140. package/dist/sanitize.js +193 -0
  141. package/dist/sanitize.js.map +1 -0
  142. package/dist/security-headers.d.ts +114 -0
  143. package/dist/security-headers.d.ts.map +1 -0
  144. package/dist/security-headers.js +121 -0
  145. package/dist/security-headers.js.map +1 -0
  146. package/dist/server-fn.d.ts +323 -0
  147. package/dist/server-fn.d.ts.map +1 -0
  148. package/dist/server-fn.js +373 -0
  149. package/dist/server-fn.js.map +1 -0
  150. package/dist/server-public.d.ts +13 -0
  151. package/dist/server-public.d.ts.map +1 -0
  152. package/dist/server-public.js +12 -0
  153. package/dist/server-public.js.map +1 -0
  154. package/dist/server-timeout.d.ts +38 -0
  155. package/dist/server-timeout.d.ts.map +1 -0
  156. package/dist/server-timeout.js +46 -0
  157. package/dist/server-timeout.js.map +1 -0
  158. package/dist/server.d.ts +100 -0
  159. package/dist/server.d.ts.map +1 -0
  160. package/dist/server.js +1218 -0
  161. package/dist/server.js.map +1 -0
  162. package/dist/socket-router.d.ts +153 -0
  163. package/dist/socket-router.d.ts.map +1 -0
  164. package/dist/socket-router.js +612 -0
  165. package/dist/socket-router.js.map +1 -0
  166. package/dist/sso.d.ts +90 -0
  167. package/dist/sso.d.ts.map +1 -0
  168. package/dist/sso.js +261 -0
  169. package/dist/sso.js.map +1 -0
  170. package/dist/ssr-context.d.ts +49 -0
  171. package/dist/ssr-context.d.ts.map +1 -0
  172. package/dist/ssr-context.js +85 -0
  173. package/dist/ssr-context.js.map +1 -0
  174. package/dist/ssr-globals.d.ts +32 -0
  175. package/dist/ssr-globals.d.ts.map +1 -0
  176. package/dist/ssr-globals.js +1010 -0
  177. package/dist/ssr-globals.js.map +1 -0
  178. package/dist/ssr-template.d.ts +73 -0
  179. package/dist/ssr-template.d.ts.map +1 -0
  180. package/dist/ssr-template.js +507 -0
  181. package/dist/ssr-template.js.map +1 -0
  182. package/dist/stack-mapper.d.ts +25 -0
  183. package/dist/stack-mapper.d.ts.map +1 -0
  184. package/dist/stack-mapper.js +139 -0
  185. package/dist/stack-mapper.js.map +1 -0
  186. package/dist/stream.d.ts +89 -0
  187. package/dist/stream.d.ts.map +1 -0
  188. package/dist/stream.js +299 -0
  189. package/dist/stream.js.map +1 -0
  190. package/dist/upload.d.ts +69 -0
  191. package/dist/upload.d.ts.map +1 -0
  192. package/dist/upload.js +110 -0
  193. package/dist/upload.js.map +1 -0
  194. package/dist/validate.d.ts +58 -0
  195. package/dist/validate.d.ts.map +1 -0
  196. package/dist/validate.js +89 -0
  197. package/dist/validate.js.map +1 -0
  198. package/dist/verify-package.d.ts +3 -0
  199. package/dist/verify-package.d.ts.map +1 -0
  200. package/dist/verify-package.js +128 -0
  201. package/dist/verify-package.js.map +1 -0
  202. package/package.json +79 -0
package/README.md ADDED
@@ -0,0 +1,311 @@
1
+ # mates-fullstack
2
+
3
+ TypeScript-first full-stack framework for Mates apps. It adds SSR, direct RPC-style server functions, raw HTTP escape hatches, WebSockets, static assets, and production builds without requiring a compiler in production.
4
+
5
+ **Custom SSR engine** — no DOM, no happy-dom, no per-request global patching, fully concurrent. `TemplateResult` objects are serialized directly to HTML using a 300-line pure-JS serializer. No virtual DOM, no fake browser, no overhead per request.
6
+
7
+ No JSX. No virtual DOM. No Express/Hono/Fastify. Runtime server is pure Node.js (`node:http`). Bundling and TypeScript transforms use esbuild.
8
+
9
+ ---
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npm install mates-fullstack-beta mates
15
+ ```
16
+
17
+ Add scripts to your app:
18
+
19
+ ```json
20
+ {
21
+ "scripts": {
22
+ "dev": "mates-fullstack dev",
23
+ "build": "mates-fullstack build",
24
+ "start": "mates-fullstack start"
25
+ }
26
+ }
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Project structure
32
+
33
+ `mates-fullstack` is convention-based; no config file is required.
34
+
35
+ ```txt
36
+ my-app/
37
+ client/
38
+ App.ts # SSR root component and client router
39
+ client.ts # browser entry; calls renderX(App, ...)
40
+ server/
41
+ api/ # RPC functions callable from client imports
42
+ helpers/ # server-only utilities; never bundled for browser
43
+ main.ts # optional middleware registration
44
+ socket/ # optional WebSocket handlers
45
+ shared/ # code/types used by both sides
46
+ public/ # static files copied to dist/public in production
47
+ package.json
48
+ ```
49
+
50
+ ---
51
+
52
+ ## Minimal app
53
+
54
+ ### `client/App.ts`
55
+
56
+ ```ts
57
+ import { html } from "mates";
58
+
59
+ export default () => {
60
+ return () => html`<h1>Hello from mates-fullstack</h1>`;
61
+ };
62
+ ```
63
+
64
+ ### `client/client.ts`
65
+
66
+ ```ts
67
+ import { renderX } from "mates";
68
+ import App from "./App";
69
+
70
+ renderX(App, document.getElementById("app")!);
71
+ ```
72
+
73
+ ### `server/api/todos.ts`
74
+
75
+ ```ts
76
+ import type { ServerCtx } from "mates-fullstack";
77
+ import { ValidationError } from "mates-fullstack";
78
+
79
+ export async function listTodos(_payload: {}, _ctx: ServerCtx) {
80
+ return [{ id: 1, title: "Write docs" }];
81
+ }
82
+
83
+ export async function addTodo(payload: { title: string }, _ctx: ServerCtx) {
84
+ if (!payload.title.trim()) {
85
+ throw new ValidationError("Invalid todo", {
86
+ fields: { title: "Required" },
87
+ });
88
+ }
89
+ return { id: Date.now(), title: payload.title };
90
+ }
91
+ ```
92
+
93
+ ### Client code calls server functions directly
94
+
95
+ ```ts
96
+ import { asyncAction, html } from "mates";
97
+ import { listTodos } from "../server/api/todos";
98
+
99
+ const TodoPage = () => {
100
+ const load = asyncAction(() => listTodos({}));
101
+ load();
102
+
103
+ return () => html`
104
+ <pre>${JSON.stringify(load.data(), null, 2)}</pre>
105
+ `;
106
+ };
107
+ ```
108
+
109
+ During development and production builds, imports from `server/api/**` are converted into browser-safe RPC stubs. Imports from any other `server/**` path are blocked from client code.
110
+
111
+ ---
112
+
113
+ ## Commands
114
+
115
+ ```bash
116
+ npm run dev # native ESM dev server, no browser bundle
117
+ npm run build # production client bundle + compiled server runtime
118
+ npm run start # start production server from dist/
119
+ ```
120
+
121
+ ### Development mode
122
+
123
+ Development intentionally serves source modules instead of a client bundle:
124
+
125
+ - app source modules: `/_src/**`
126
+ - package modules: `/_pkg/**`
127
+ - framework helpers: `/_mates/**`
128
+ - import map injected into the HTML shell
129
+ - chokidar watches `client/`, `server/`, `shared/`, `public/`, `.env*`, and config files
130
+ - reload generation is owned by the parent dev process and delivered through SSE
131
+
132
+ This makes stack traces point at source-like module URLs and keeps rebuilds fast.
133
+
134
+ ---
135
+
136
+ ## Authentication
137
+
138
+ ### Email/Password + Social Login
139
+
140
+ `mates-fullstack` provides a complete auth system out of the box. Access tokens are short-lived (15 min default), stored in httpOnly cookies. Refresh tokens (30 days) live in a separate httpOnly cookie and rotate automatically, with JTI replay detection.
141
+
142
+ ```ts
143
+ // server/main.ts
144
+ import { matesAuth, auth, useArctic } from "mates-fullstack";
145
+
146
+ matesAuth({ secret: process.env.AUTH_JWT_SECRET! });
147
+
148
+ useArctic({
149
+ google: {
150
+ clientId: process.env.GOOGLE_CLIENT_ID!,
151
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
152
+ onSuccess: async (profile, ctx) => {
153
+ const user = await db.users.upsert({ ... });
154
+ await auth.login(ctx, { userId: user.id, email: user.email });
155
+ },
156
+ },
157
+ });
158
+ ```
159
+
160
+ Routes `/auth/google` and `/auth/google/callback` are registered automatically. `onSuccess` gives you full control — call `auth.login()` to issue tokens, or skip it to just link accounts.
161
+
162
+ 10 built-in OAuth providers: Google, GitHub, Discord, Microsoft, Twitter, LinkedIn, Facebook, Apple, Spotify, GitLab. Custom providers via `arcticProvider({ handler, ... })`.
163
+
164
+ ### Cross-Domain SSO
165
+
166
+ For apps on different domains sharing one auth server. The auth server signs a 30-second code JWT with a shared secret — each app verifies it locally, no round-trip needed.
167
+
168
+ ```ts
169
+ // auth.com/server/main.ts
170
+ import { useSsoProvider } from "mates-fullstack";
171
+
172
+ useSsoProvider({
173
+ secret: process.env.SSO_SECRET!,
174
+ login: "/login",
175
+ allowedOrigins: ["https://app1.com", "https://app2.com"],
176
+ });
177
+
178
+ // app1.com/server/main.ts
179
+ import { useSsoClient } from "mates-fullstack";
180
+
181
+ useSsoClient({
182
+ authUrl: "https://auth.com",
183
+ secret: process.env.SSO_SECRET!,
184
+ protected: ["/dashboard", "/settings"],
185
+ });
186
+ ```
187
+
188
+ Each app issues its own httpOnly session cookies. Works with social login — put `useArctic()` on the auth server, `useSsoClient()` on every app.
189
+
190
+ ---
191
+
192
+ ## Middleware
193
+
194
+ All middleware registers globally in `server/main.ts` and runs in registration order.
195
+
196
+ **Recommended `server/main.ts`:**
197
+ ```ts
198
+ import {
199
+ matesAuth, requestLogger, useSecurityHeaders, useCors, rateLimit,
200
+ } from "mates-fullstack";
201
+
202
+ matesAuth({ secret: process.env.AUTH_JWT_SECRET! });
203
+ requestLogger({ skip: [/^\/health$/, /^\/_mates\//] });
204
+ useSecurityHeaders();
205
+ useCors({ origins: "https://app.example.com" });
206
+ rateLimit({ max: 10, window: "15m", pathPrefix: "/auth" });
207
+ rateLimit({ max: 300, window: "1m" });
208
+ ```
209
+
210
+ ### Request Logger
211
+
212
+ ```ts
213
+ requestLogger({ skip: [/^\/health$/, /^\/assets\//] });
214
+ ```
215
+
216
+ Logs every request (method, path, IP) on arrival and every RPC response (status, ms) on completion. Stamps `x-request-id` on every response. Structured logging — NDJSON in production, pretty-printed in dev.
217
+
218
+ ### Security Headers
219
+
220
+ ```ts
221
+ useSecurityHeaders();
222
+ useSecurityHeaders({ contentSecurityPolicy: "default-src 'self'", xFrameOptions: "DENY" });
223
+ ```
224
+
225
+ Sets 14 standard security headers on every response — complete helmet-equivalent coverage. Every header individually overridable or disableable. HSTS auto-enabled in production, skipped in dev. CSP and Permissions-Policy are opt-in.
226
+
227
+ ### CORS
228
+
229
+ ```ts
230
+ useCors({ origins: "https://app.example.com", credentials: true });
231
+ useCors({ origins: (origin) => origin.endsWith(".example.com") });
232
+ ```
233
+
234
+ Handles preflight `OPTIONS` automatically (returns 204). Reflects origin when `credentials: true` as required by the CORS spec. Sets `Vary: Origin`.
235
+
236
+ ### Rate Limiting
237
+
238
+ ```ts
239
+ rateLimit({ max: 100, window: "1m" }); // all routes
240
+ rateLimit({ max: 10, window: "15m", pathPrefix: "/auth" }); // auth only
241
+ rateLimit({ max: 5, window: "1h", key: (_req, ctx) => String(ctx.auth.userId) }); // per-user
242
+ ```
243
+
244
+ Sliding-window counter, in-memory. Returns 429 with `Retry-After` and `X-RateLimit-*` headers. Auto-evicts expired entries. Custom key function for per-user or per-endpoint limiting.
245
+
246
+ ### Raw HTTP hooks
247
+
248
+ For cases where an external service dictates the HTTP contract (webhooks, custom OAuth flows):
249
+
250
+ ```ts
251
+ import { onHttpRequest } from "mates-fullstack";
252
+
253
+ onHttpRequest(async (req, ctx) => {
254
+ const url = new URL(req.url);
255
+ if (req.method === "POST" && url.pathname === "/stripe-webhook") {
256
+ const body = await req.text();
257
+ await handleWebhook(body, ctx.reqHeaders["stripe-signature"]);
258
+ return new Response("ok");
259
+ }
260
+ });
261
+ ```
262
+
263
+ ---
264
+
265
+ ## Request Limits / Resource Protection
266
+
267
+ Built-in limits prevent CPU and memory exhaustion. All have safe defaults — override only to tune for your app.
268
+
269
+ ```ts
270
+ // server/main.ts — at the top, before middleware
271
+ import { configureRpcRunner } from "mates-fullstack/internal";
272
+
273
+ configureRpcRunner({
274
+ maxJsonBytes: 5 * 1024 * 1024, // default 1MB
275
+ maxJsonDepth: 30, // default 50
276
+ maxArrayLength: 5000, // default 10_000
277
+ maxStringLength: 50_000, // default 100_000
278
+ maxUploadBytes: 50 * 1024 * 1024, // default 10MB
279
+ maxMultipartParts: 100, // default 200
280
+ });
281
+ ```
282
+
283
+ Or set server-level limits when starting:
284
+
285
+ ```ts
286
+ await startServer({
287
+ maxConnections: 2000, // default 1000
288
+ staticStreamTimeout: 120_000, // default 60s
289
+ maxSseClients: 1000, // default 500
290
+ });
291
+ ```
292
+
293
+ All defaults are active without any configuration call. See `DOCS.md` for full details.
294
+
295
+ ---
296
+
297
+ ## Public entrypoints
298
+
299
+ | Import | Use for |
300
+ |---|---|
301
+ | `mates-fullstack` | stable app API: errors, redirects, middleware registration, `ServerCtx`, validation/sanitize/upload helpers |
302
+ | `mates-fullstack/client` | browser hydration and RPC helpers |
303
+ | `mates-fullstack/browser` | browser-safe error/redirect/stream/download helpers |
304
+ | `mates-fullstack/server` | server-safe helpers and middleware runners |
305
+ | `mates-fullstack/internal` | unstable build/runtime/scanner internals for tooling |
306
+
307
+ ---
308
+
309
+ ## License
310
+
311
+ MIT
@@ -0,0 +1,101 @@
1
+ import { type OAuth2Tokens } from "arctic";
2
+ import type { CookieOptions, Context } from "./ctx.js";
3
+ export type ArcticBuiltInProvider = "apple" | "discord" | "facebook" | "github" | "gitlab" | "google" | "linkedin" | "microsoft" | "spotify" | "twitter";
4
+ export interface ArcticTokenSet {
5
+ accessToken: string | null;
6
+ refreshToken: string | null;
7
+ idToken: string | null;
8
+ tokenType: string | null;
9
+ expiresAt: Date | null;
10
+ scopes: string[] | null;
11
+ raw: object;
12
+ }
13
+ export interface ArcticProfile<Raw = unknown> {
14
+ provider: string;
15
+ id: string;
16
+ email: string | null;
17
+ name: string | null;
18
+ avatar: string | null;
19
+ username?: string | null;
20
+ raw: Raw;
21
+ tokens: ArcticTokenSet;
22
+ }
23
+ export interface ArcticProviderConfig {
24
+ clientId: string;
25
+ clientSecret?: string | null;
26
+ redirectUri?: string;
27
+ scopes?: string[];
28
+ /** Microsoft Entra ID tenant. Defaults to "common". */
29
+ tenant?: string;
30
+ /** Apple Team ID. */
31
+ teamId?: string;
32
+ /** Apple Key ID. */
33
+ keyId?: string;
34
+ /** Apple private key in PKCS#8 PEM format. */
35
+ privateKey?: string;
36
+ /** GitLab base URL. Defaults to https://gitlab.com. */
37
+ baseURL?: string;
38
+ /** Override the built-in profile fetcher or add one for custom providers. */
39
+ profile?: ArcticProfileLoader;
40
+ /** Override whether this provider uses PKCE. */
41
+ usesPKCE?: boolean;
42
+ /**
43
+ * Called after the provider returns a profile.
44
+ * Return the claims to bake into the JWT — typically after an upsert in your DB.
45
+ */
46
+ onSuccess: ArcticSuccessHandler;
47
+ }
48
+ export type ArcticProvidersConfig = Partial<Record<ArcticBuiltInProvider | string, ArcticProviderConfig | ArcticCustomProvider>>;
49
+ /**
50
+ * Called after the provider returns a verified profile.
51
+ * You are fully in control — call `auth.login(ctx, claims)` to issue tokens,
52
+ * update the DB to link an account, or do nothing at all.
53
+ * Return a path string to override the post-OAuth redirect.
54
+ */
55
+ export type ArcticSuccessHandler = (profile: ArcticProfile, ctx: Context) => string | void | Promise<string | void>;
56
+ export interface ArcticUseOptions {
57
+ /** Route base for OAuth endpoints. Default: "/auth". */
58
+ basePath?: string;
59
+ /** Default redirect after login. Default: "/". */
60
+ afterLogin?: string;
61
+ /** Redirect after OAuth failure. If omitted, failures return JSON. */
62
+ onErrorRedirect?: string;
63
+ /** Cookie path/domain/sameSite/secure controls for temporary OAuth cookies. */
64
+ cookie?: Pick<CookieOptions, "path" | "domain" | "sameSite" | "secure">;
65
+ /** Temporary OAuth state cookie lifetime in seconds. Default: 10 minutes. */
66
+ stateMaxAge?: number;
67
+ }
68
+ export interface ArcticProviderHandler {
69
+ defaultScopes: string[];
70
+ usesPKCE: boolean;
71
+ start(config: ArcticProviderConfig, redirectUri: string, state: string, codeVerifier: string | null): Promise<URL> | URL;
72
+ callback(config: ArcticProviderConfig, redirectUri: string, code: string, codeVerifier: string | null, providerName: string): Promise<ArcticProfile>;
73
+ }
74
+ export interface ArcticCustomProvider extends ArcticProviderConfig {
75
+ handler: ArcticProviderHandler;
76
+ }
77
+ export type ArcticProfileLoader = (tokens: OAuth2Tokens, providerName: string) => Promise<Omit<ArcticProfile, "provider" | "tokens">>;
78
+ /**
79
+ * Register social login routes for every configured provider.
80
+ *
81
+ * The framework automatically handles:
82
+ * GET /auth/:provider — redirect to provider
83
+ * GET /auth/:provider/callback — exchange code, call onSuccess, set cookies
84
+ *
85
+ * @example
86
+ * useArctic({
87
+ * google: {
88
+ * clientId: process.env.GOOGLE_CLIENT_ID!,
89
+ * clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
90
+ * onSuccess: async (profile) => {
91
+ * const user = await db.upsert({ provider: profile.provider, providerId: profile.id, ... });
92
+ * return { userId: user.id, email: user.email, roles: user.roles };
93
+ * },
94
+ * },
95
+ * });
96
+ */
97
+ export declare function useArctic(providers: ArcticProvidersConfig, options?: ArcticUseOptions): void;
98
+ /** Define a custom Arctic provider adapter for providers without a built-in profile normalizer. */
99
+ export declare function arcticProvider(config: ArcticCustomProvider): ArcticCustomProvider;
100
+ export declare function listArcticProviders(): ArcticBuiltInProvider[];
101
+ //# sourceMappingURL=arctic-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"arctic-auth.d.ts","sourceRoot":"","sources":["../src/arctic-auth.ts"],"names":[],"mappings":"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"}