authula 0.7.16 → 0.8.0-beta.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 (40) hide show
  1. package/README.md +196 -40
  2. package/dist/{index.js → core-Csdt31Tx.js} +6 -17
  3. package/dist/core-Csdt31Tx.js.map +1 -0
  4. package/dist/core.d.ts +2 -0
  5. package/dist/core.js +4 -0
  6. package/dist/{custom-fetch-CXJ4-i7I.js → custom-fetch-DJxn7nVP.js} +26 -10
  7. package/dist/custom-fetch-DJxn7nVP.js.map +1 -0
  8. package/dist/framework-client-CsGjKPXl.d.ts +8 -0
  9. package/dist/framework-client-D-yGjqAx.js +50 -0
  10. package/dist/framework-client-D-yGjqAx.js.map +1 -0
  11. package/dist/{index-xeVPFZn7.d.ts → index-Cuok0NWW.d.ts} +2 -448
  12. package/dist/models.d.ts +2 -0
  13. package/dist/models.js +11 -0
  14. package/dist/models.js.map +1 -0
  15. package/dist/plugins.d.ts +513 -0
  16. package/dist/plugins.js +2472 -0
  17. package/dist/plugins.js.map +1 -0
  18. package/dist/react.d.ts +3728 -0
  19. package/dist/{plugins/index.js → react.js} +975 -1256
  20. package/dist/react.js.map +1 -0
  21. package/dist/{rolldown-runtime-w6R9maHv.js → rolldown-runtime-CNh9ExCG.js} +1 -2
  22. package/dist/sdk-Cu28BXFh.d.ts +102 -0
  23. package/dist/solid.d.ts +3955 -0
  24. package/dist/solid.js +5461 -0
  25. package/dist/solid.js.map +1 -0
  26. package/dist/svelte.d.ts +3368 -0
  27. package/dist/svelte.js +5500 -0
  28. package/dist/svelte.js.map +1 -0
  29. package/dist/vue.d.ts +3289 -0
  30. package/dist/vue.js +5644 -0
  31. package/dist/vue.js.map +1 -0
  32. package/dist/zod.d.ts +3862 -0
  33. package/dist/zod.js +1480 -0
  34. package/dist/zod.js.map +1 -0
  35. package/package.json +61 -9
  36. package/dist/custom-fetch-CXJ4-i7I.js.map +0 -1
  37. package/dist/index.d.ts +0 -2
  38. package/dist/index.js.map +0 -1
  39. package/dist/plugins/index.d.ts +0 -4908
  40. package/dist/plugins/index.js.map +0 -1
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  </p>
4
4
 
5
5
  <p align="center">
6
- This Node.js SDK provides seamless integration with an Authula server for both client-side and server-side applications and is framework agnostic.
6
+ This Node.js SDK provides seamless integration with an Authula server for client-side and server-side applications. Import only the pieces you need from a framework subpath.
7
7
  </p>
8
8
 
9
9
  <div align="center">
@@ -22,70 +22,218 @@ This Node.js SDK provides seamless integration with an Authula server for both c
22
22
 
23
23
  ## Features
24
24
 
25
- - **Framework Agnostic**: Works with Next.js/React, Vue.js and more
25
+ - **Framework subpaths**: `authula/core`, `authula/models`, `authula/plugins`, `authula/zod`, `authula/react`, `authula/vue`, `authula/solid`, `authula/svelte`
26
26
  - **Full TypeScript Support**: Complete TypeScript definitions with strict typing
27
27
  - **CSRF Protection**: Automatic CSRF token handling for mutating requests
28
28
  - **Multiple Auth Methods**: Email/password, OAuth2, JWT-based authentication
29
29
  - **Plugin Architecture**: Extensible plugin system for custom authentication flows
30
30
  - **Automatic Token Refresh**: Built-in bearer token refresh mechanism
31
- - **Built-in support for Zod and Tanstack Query**: provides types and zod schemas out of the box along with tanstack query code for all available methods.
31
+ - **Built-in Zod and TanStack Query support**: Zod schemas from `authula/zod` and per-framework TanStack Query hooks
32
32
 
33
33
  ## Installation
34
34
 
35
+ Install `authula` plus the TanStack Query adapter for your framework:
36
+
37
+ ```bash
38
+ # React
39
+ pnpm add authula @tanstack/react-query
40
+
41
+ # Vue
42
+ pnpm add authula @tanstack/vue-query
43
+
44
+ # Solid
45
+ pnpm add authula @tanstack/solid-query
46
+
47
+ # Svelte
48
+ pnpm add authula @tanstack/svelte-query
49
+ ```
50
+
51
+ The framework runtime (`react`, `vue`, `solid-js`, `svelte`) is already present in
52
+ your app and is declared as an optional peer, not installed by `authula`.
53
+
54
+ Core-only/server users need no query adapter and no framework runtime:
55
+
35
56
  ```bash
36
- npm install authula
37
- # or
38
- yarn add authula
39
- # or
40
57
  pnpm add authula
41
58
  ```
42
59
 
60
+ ## Imports
61
+
62
+ | Import | Contents |
63
+ | ----------------- | ---------------------------------------------------------------------- |
64
+ | `authula/core` | `AuthulaClient`, core `createClient` (direct methods only), `ApiError` |
65
+ | `authula/models` | Generated TypeScript models and enum values |
66
+ | `authula/zod` | Generated Zod schemas |
67
+ | `authula/plugins` | Plugin classes |
68
+ | `authula/react` | React `createClient`, hooks/types, core re-export |
69
+ | `authula/vue` | Vue `createClient`, hooks/types, core re-export |
70
+ | `authula/solid` | Solid `createClient`, hooks/types, core re-export |
71
+ | `authula/svelte` | Svelte `createClient`, hooks/types, core re-export |
72
+
73
+ There is no `authula` root import. Always use a subpath.
74
+
43
75
  ## Quick Start
44
76
 
45
- ### Basic Setup
77
+ Import `createClient` from your framework subpath. The client it returns has
78
+ both direct methods and that framework's query hooks attached to each plugin:
79
+
80
+ ```ts
81
+ const client = createClient({ url, plugins: [new CorePlugin()] });
46
82
 
47
- `Client instance`:
83
+ await client.core.getMe(); // direct request method
84
+ client.core.useGetMe(); // React/Vue/Solid hook
85
+ client.core.createGetMe(); // Svelte hook
86
+ ```
48
87
 
49
- Use with SPA (Vite etc.)
88
+ Hooks are bound to the client instance that created them, so their URL, cookies,
89
+ and CSRF/bearer hooks always come from that client. They still use the TanStack
90
+ Query client from your app's `QueryClientProvider` (or equivalent).
50
91
 
51
- ```typescript
52
- import { createClient } from "authula";
92
+ ### React
93
+
94
+ ```tsx
95
+ import { createClient } from "authula/react";
53
96
  import { CorePlugin, EmailPasswordPlugin } from "authula/plugins";
54
97
 
55
- const authulaBrowserClient = createClient({
56
- // Your Authula server URL
98
+ const client = createClient({
57
99
  url: "http://localhost:8080/api/auth",
58
100
  plugins: [new CorePlugin(), new EmailPasswordPlugin()],
59
101
  });
60
102
 
61
- // Direct method call
62
- const response = await authulaBrowserClient.core.getMe();
63
-
64
- // Tanstack Query
65
- const { data, error, isLoading, isError } = await authulaBrowserClient.core.useGetMe();
103
+ function Profile() {
104
+ const { data, isLoading, isError } = client.core.useGetMe();
105
+ if (isLoading) return <p>Loading…</p>;
106
+ if (isError) return <p>Not signed in</p>;
107
+ return <p>{data?.user?.email}</p>;
108
+ }
66
109
  ```
67
110
 
68
- `Server instance`:
111
+ ### Vue
69
112
 
70
- Use with SSR frameworks e.g. Next.js/Tanstack Start etc.
113
+ ```vue
114
+ <script setup lang="ts">
115
+ import { createClient } from "authula/vue";
116
+ import { CorePlugin, EmailPasswordPlugin } from "authula/plugins";
71
117
 
72
- ```typescript
73
- import { cookies } from "next/headers";
118
+ const client = createClient({
119
+ url: "http://localhost:8080/api/auth",
120
+ plugins: [new CorePlugin(), new EmailPasswordPlugin()],
121
+ });
122
+
123
+ const { data, isLoading, isError } = client.core.useGetMe();
124
+ </script>
125
+
126
+ <template>
127
+ <p v-if="isLoading">Loading…</p>
128
+ <p v-else-if="isError">Not signed in</p>
129
+ <p v-else>{{ data?.user?.email }}</p>
130
+ </template>
131
+ ```
74
132
 
75
- import { createClient } from "authula";
133
+ ### Solid
134
+
135
+ ```tsx
136
+ import { createClient } from "authula/solid";
76
137
  import { CorePlugin, EmailPasswordPlugin } from "authula/plugins";
77
138
 
78
- const authulaServerClient = createClient({
79
- // Your Authula server URL
139
+ const client = createClient({
80
140
  url: "http://localhost:8080/api/auth",
81
141
  plugins: [new CorePlugin(), new EmailPasswordPlugin()],
82
- // For frameworks other than Next.js, you may need to implement this cookies object manually by implementing the interface.
83
- cookies: cookies,
84
142
  });
85
143
 
86
- // Now you can use the client...
144
+ function Profile() {
145
+ const query = client.core.useGetMe();
146
+ if (query.isLoading) return <p>Loading…</p>;
147
+ if (query.isError) return <p>Not signed in</p>;
148
+ return <p>{query.data?.user?.email}</p>;
149
+ }
150
+ ```
151
+
152
+ ### Svelte
153
+
154
+ ```svelte
155
+ <script lang="ts">
156
+ import { createClient } from "authula/svelte";
157
+ import { CorePlugin, EmailPasswordPlugin } from "authula/plugins";
87
158
 
88
- const response = await authulaServerClient.core.getMe();
159
+ const client = createClient({
160
+ url: "http://localhost:8080/api/auth",
161
+ plugins: [new CorePlugin(), new EmailPasswordPlugin()],
162
+ });
163
+
164
+ const query = client.core.createGetMe();
165
+ </script>
166
+
167
+ {#if $query.isLoading}
168
+ <p>Loading…</p>
169
+ {:else if $query.isError}
170
+ <p>Not signed in</p>
171
+ {:else}
172
+ <p>{$query.data?.user?.email}</p>
173
+ {/if}
174
+ ```
175
+
176
+ Raw hooks are still exported from each framework subpath for convenience:
177
+
178
+ ```ts
179
+ import { createClient, useGetMe } from "authula/react";
180
+ ```
181
+
182
+ The raw hook resolves the most recently created client as its default. Prefer
183
+ `client.core.useGetMe()` when you need a specific client instance, such as SSR.
184
+
185
+ ### Direct methods and models
186
+
187
+ For server-side or core-only usage, import `createClient` from `authula/core`.
188
+ It provides direct methods without query hooks:
189
+
190
+ ```ts
191
+ import { createClient } from "authula/core";
192
+ import { CorePlugin } from "authula/plugins";
193
+ import type { User } from "authula/models";
194
+
195
+ const client = createClient({
196
+ url: "http://localhost:8080/api/auth",
197
+ plugins: [new CorePlugin()],
198
+ });
199
+
200
+ const me = await client.core.getMe();
201
+
202
+ const user: User = me.data.user;
203
+ ```
204
+
205
+ ### Zod schemas
206
+
207
+ ```ts
208
+ import * as schemas from "authula/zod";
209
+
210
+ const result = schemas.SignInRequest.safeParse(input);
211
+ ```
212
+
213
+ ## Server-side rendering
214
+
215
+ - Client-bound hooks (`client.core.useGetMe()`) use the cookies and URL of the
216
+ client instance they came from, so create one client per request when using
217
+ hooks during SSR.
218
+ - Use direct client methods (`await client.core.getMe()`) when possible.
219
+ - Raw hook imports (`import { useGetMe } from "authula/react"`) use the most
220
+ recently created client globally, so avoid them for request-scoped SSR.
221
+ - Per-call overrides are supported and take precedence over the client config:
222
+ `client.core.useGetMe({ request: { baseUrl, cookies } })`.
223
+
224
+ ```ts
225
+ import { cookies } from "next/headers";
226
+
227
+ import { createClient } from "authula/react";
228
+ import { CorePlugin } from "authula/plugins";
229
+
230
+ const client = createClient({
231
+ url: "http://localhost:8080/api/auth",
232
+ plugins: [new CorePlugin()],
233
+ cookies,
234
+ });
235
+
236
+ const me = await client.core.getMe();
89
237
  ```
90
238
 
91
239
  ## Available Plugins
@@ -109,8 +257,6 @@ The following plugins are available in this SDK:
109
257
 
110
258
  ### Fetch Options
111
259
 
112
- Configure fetch behavior with timeout and other options:
113
-
114
260
  ```typescript
115
261
  const authulaClient = createClient({
116
262
  url: "http://localhost:8080/auth",
@@ -126,33 +272,43 @@ const authulaClient = createClient({
126
272
 
127
273
  ### Custom Hooks
128
274
 
129
- Add custom before/after fetch hooks for advanced customization:
130
-
131
275
  ```typescript
132
276
  const authulaClient = createClient({
133
277
  url: "http://localhost:8080/auth",
134
278
  plugins: [new CorePlugin()],
135
279
  });
136
280
 
137
- // Register a before fetch hook
138
281
  authulaClient.registerBeforeFetch(async (ctx) => {
139
282
  console.log(`Making request to: ${ctx.url}`);
140
- // Modify context if needed
141
283
  ctx.init.headers = {
142
284
  ...ctx.init.headers,
143
285
  "X-Custom-Header": "value",
144
286
  };
145
287
  });
146
288
 
147
- // Register an after fetch hook
148
289
  authulaClient.registerAfterFetch(async (ctx, response) => {
149
290
  console.log(`Received response: ${response.status}`);
150
- if (response.status >= 400) {
151
- // Handle error
152
- }
153
291
  });
154
292
  ```
155
293
 
294
+ ## Migration from 0.7.x to 0.8.0
295
+
296
+ | Before | After |
297
+ | ---------------------------------------- | ------------------------------------------------------------------ |
298
+ | `import { createClient } from "authula"` | `import { createClient } from "authula/react"` (or your framework) |
299
+ | `import type { User } from "authula"` | `import type { User } from "authula/models"` |
300
+ | `client.core.useGetMe()` | unchanged when `createClient` comes from a framework subpath |
301
+ | `authula/plugins` | unchanged |
302
+ | zod schemas inaccessible | `import * as schemas from "authula/zod"` |
303
+
304
+ For core-only or server code, `authula/core` also exports `createClient`, but its
305
+ clients expose direct methods only (no query hooks).
306
+
307
+ `@tanstack/react-query` was previously a direct dependency and is now an optional
308
+ peer, so existing React users must add it explicitly. The same applies to the
309
+ other TanStack adapters and to the framework runtimes (`react`, `vue`,
310
+ `solid-js`, `svelte`), which are optional peers supplied by your app.
311
+
156
312
  ## Contributing
157
313
 
158
314
  Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
@@ -1,17 +1,7 @@
1
- import { t as ApiError } from "./custom-fetch-CXJ4-i7I.js";
1
+ import { r as setDefaultClient } from "./custom-fetch-DJxn7nVP.js";
2
2
  import { parseCookie } from "cookie";
3
3
 
4
- //#region src/gen/models/organization-invitation-status.ts
5
- const OrganizationInvitationStatus = {
6
- pending: "pending",
7
- accepted: "accepted",
8
- rejected: "rejected",
9
- revoked: "revoked",
10
- expired: "expired"
11
- };
12
-
13
- //#endregion
14
- //#region src/client.ts
4
+ // src/core/client.ts
15
5
  var AuthulaClient = class {
16
6
  config;
17
7
  plugins;
@@ -22,6 +12,7 @@ var AuthulaClient = class {
22
12
  const { plugins: _, ...rest } = options;
23
13
  this.config = rest;
24
14
  for (const plugin of this.plugins) this[plugin.id] = plugin.init(this);
15
+ setDefaultClient(this);
25
16
  }
26
17
  registerBeforeFetch(hook) {
27
18
  this.beforeFetchHooks.push(hook);
@@ -55,12 +46,10 @@ var AuthulaClient = class {
55
46
  }
56
47
  };
57
48
 
58
- //#endregion
59
- //#region src/sdk.ts
49
+ // src/core/sdk.ts
60
50
  function createClient(options) {
61
51
  return new AuthulaClient(options);
62
52
  }
63
53
 
64
- //#endregion
65
- export { ApiError, AuthulaClient, OrganizationInvitationStatus, createClient };
66
- //# sourceMappingURL=index.js.map
54
+ export { AuthulaClient as n, createClient as t };
55
+ //# sourceMappingURL=core-Csdt31Tx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core-Csdt31Tx.js","names":[],"sources":["../src/core/client.ts","../src/core/sdk.ts"],"sourcesContent":["import { parseCookie } from \"cookie\";\n\nimport { setDefaultClient } from \"./runtime\";\nimport type {\n FetchContext,\n AuthulaClientConfig,\n AuthulaClientOptions,\n Plugin,\n BeforeFetchHook,\n AfterFetchHook,\n} from \"./types\";\n\nexport class AuthulaClient {\n public readonly config: AuthulaClientConfig;\n private readonly plugins: Array<Plugin>;\n private readonly beforeFetchHooks: BeforeFetchHook[] = [];\n private readonly afterFetchHooks: AfterFetchHook[] = [];\n\n constructor(options: AuthulaClientOptions) {\n this.plugins = options.plugins || [];\n\n const { plugins: _, ...rest } = options;\n this.config = rest;\n\n for (const plugin of this.plugins) {\n (this as any)[plugin.id] = plugin.init(this);\n }\n\n setDefaultClient(this);\n }\n\n public registerBeforeFetch(hook: BeforeFetchHook): void {\n this.beforeFetchHooks.push(hook);\n }\n\n public registerAfterFetch(hook: AfterFetchHook): void {\n this.afterFetchHooks.push(hook);\n }\n\n public async runBeforeFetch(ctx: FetchContext): Promise<void> {\n for (const hook of this.beforeFetchHooks) {\n await hook(ctx);\n }\n }\n\n public async runAfterFetch(ctx: FetchContext, res: Response) {\n for (const hook of this.afterFetchHooks) {\n const result = await hook(ctx, res);\n if (result === \"retry\") {\n return \"retry\";\n }\n }\n }\n\n public getPlugin<T extends Plugin>(id: string): T | undefined {\n return this.plugins.find((plugin) => plugin.id === id) as T | undefined;\n }\n\n public async getCookie(name: string): Promise<string | undefined> {\n const all = await this.getAllCookies();\n return all ? all[name] : undefined;\n }\n\n public async getAllCookies(): Promise<Record<string, string | undefined> | undefined> {\n if (this.config.cookies) {\n try {\n const store = await this.config.cookies();\n const all = store.getAll();\n const map: Record<string, string> = {};\n for (const c of all) {\n map[c.name] = c.value;\n }\n return map;\n } catch {\n return undefined;\n }\n }\n\n if (typeof document !== \"undefined\") {\n return parseCookie(document.cookie);\n }\n\n return undefined;\n }\n}\n","import { AuthulaClient } from \"./client\";\nimport type { AuthulaClientOptions, Plugin } from \"./types\";\n\n// Helper to extract plugin methods\nexport type InferPluginMethods<P> = P extends { init: (client: any) => infer M } ? M : never;\n\nexport type ClientWithPlugins<T extends readonly Plugin[]> = AuthulaClient & {\n [P in T[number] as P[\"id\"]]: InferPluginMethods<P>;\n};\n\nexport function createClient<const T extends readonly Plugin[]>(\n options: Omit<AuthulaClientOptions, \"plugins\"> & { plugins: T },\n): ClientWithPlugins<T> {\n return new AuthulaClient(options as any) as ClientWithPlugins<T>;\n}\n"],"mappings":";;;;AAYA,IAAa,gBAAb,MAA2B;CACzB,AAAgB;CAChB,AAAiB;CACjB,AAAiB,mBAAsC,CAAC;CACxD,AAAiB,kBAAoC,CAAC;CAEtD,YAAY,SAA+B;EACzC,KAAK,UAAU,QAAQ,WAAW,CAAC;EAEnC,MAAM,EAAE,SAAS,GAAG,GAAG,SAAS;EAChC,KAAK,SAAS;EAEd,KAAK,MAAM,UAAU,KAAK,SACxB,AAAC,KAAa,OAAO,MAAM,OAAO,KAAK,IAAI;EAG7C,iBAAiB,IAAI;CACvB;CAEA,AAAO,oBAAoB,MAA6B;EACtD,KAAK,iBAAiB,KAAK,IAAI;CACjC;CAEA,AAAO,mBAAmB,MAA4B;EACpD,KAAK,gBAAgB,KAAK,IAAI;CAChC;CAEA,MAAa,eAAe,KAAkC;EAC5D,KAAK,MAAM,QAAQ,KAAK,kBACtB,MAAM,KAAK,GAAG;CAElB;CAEA,MAAa,cAAc,KAAmB,KAAe;EAC3D,KAAK,MAAM,QAAQ,KAAK,iBAEtB,IAAI,MADiB,KAAK,KAAK,GAAG,MACnB,SACb,OAAO;CAGb;CAEA,AAAO,UAA4B,IAA2B;EAC5D,OAAO,KAAK,QAAQ,MAAM,WAAW,OAAO,OAAO,EAAE;CACvD;CAEA,MAAa,UAAU,MAA2C;EAChE,MAAM,MAAM,MAAM,KAAK,cAAc;EACrC,OAAO,MAAM,IAAI,QAAQ;CAC3B;CAEA,MAAa,gBAAyE;EACpF,IAAI,KAAK,OAAO,SACd,IAAI;GAEF,MAAM,OAAM,MADQ,KAAK,OAAO,QAAQ,EACvB,CAAC,OAAO;GACzB,MAAM,MAA8B,CAAC;GACrC,KAAK,MAAM,KAAK,KACd,IAAI,EAAE,QAAQ,EAAE;GAElB,OAAO;EACT,QAAQ;GACN;EACF;EAGF,IAAI,OAAO,aAAa,aACtB,OAAO,YAAY,SAAS,MAAM;CAItC;AACF;;;AC1EA,SAAgB,aACd,SACsB;CACtB,OAAO,IAAI,cAAc,OAAc;AACzC"}
package/dist/core.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import { c as CookieAttributes, d as Plugin, f as AuthulaClient, h as FetchContext, i as ApiError, l as CookieStore, m as BeforeFetchHook, n as InferPluginMethods, o as AuthulaClientConfig, p as AfterFetchHook, r as createClient, s as AuthulaClientOptions, t as ClientWithPlugins, u as FetchOptions } from "./sdk-Cu28BXFh.js";
2
+ export { AfterFetchHook, ApiError, AuthulaClient, AuthulaClientConfig, AuthulaClientOptions, BeforeFetchHook, type ClientWithPlugins, CookieAttributes, CookieStore, FetchContext, FetchOptions, type InferPluginMethods, Plugin, createClient };
package/dist/core.js ADDED
@@ -0,0 +1,4 @@
1
+ import { t as ApiError } from "./custom-fetch-DJxn7nVP.js";
2
+ import { n as AuthulaClient, t as createClient } from "./core-Csdt31Tx.js";
3
+
4
+ export { ApiError, AuthulaClient, createClient };
@@ -1,7 +1,18 @@
1
1
  import { parseSetCookie } from "cookie";
2
2
  import { toCamelCaseKeys, toSnakeCaseKeys } from "es-toolkit";
3
3
 
4
- //#region src/mutators/custom-fetch.ts
4
+ // src/core/runtime.ts
5
+ const DEFAULT_CLIENT = Symbol.for("authula.default-client");
6
+ const globalStore = globalThis;
7
+ const store = globalStore[DEFAULT_CLIENT] ??= {};
8
+ function setDefaultClient(client) {
9
+ store.client = client;
10
+ }
11
+ function getDefaultClient() {
12
+ return store.client;
13
+ }
14
+
15
+ // src/core/mutators/custom-fetch.ts
5
16
  var ApiError = class extends Error {
6
17
  status;
7
18
  data;
@@ -80,12 +91,18 @@ function convertQueryKeysToSnakeCase(url) {
80
91
  return `${base}?${snakeParams.toString()}`;
81
92
  }
82
93
  async function customFetch(url, options) {
83
- const resolvedUrl = convertQueryKeysToSnakeCase(prependBase(url, options?.baseUrl ?? ""));
94
+ const client = options?.baseUrl === void 0 ? getDefaultClient() : void 0;
95
+ const baseUrl = options?.baseUrl ?? client?.config.url.replace(/\/+$/, "") ?? "";
96
+ const cookies = options?.cookies ?? client?.config.cookies;
97
+ const onBeforeFetch = options?.onBeforeFetch ?? (client ? client.runBeforeFetch.bind(client) : void 0);
98
+ const onAfterFetch = options?.onAfterFetch ?? (client ? client.runAfterFetch.bind(client) : void 0);
99
+ if (!baseUrl && !/^https?:\/\//.test(url)) throw new Error("No Authula client configured. Call createClient() before using Authula hooks, or pass a baseUrl request option.");
100
+ const resolvedUrl = convertQueryKeysToSnakeCase(prependBase(url, baseUrl));
84
101
  const headers = new Headers(options?.headers || {});
85
102
  let cookieStore = null;
86
103
  let resolvedCookies;
87
- if (options?.cookies) try {
88
- cookieStore = await options.cookies();
104
+ if (cookies) try {
105
+ cookieStore = await cookies();
89
106
  const all = cookieStore.getAll();
90
107
  if (all.length > 0 && !headers.has("cookie")) headers.set("cookie", all.map((c) => `${c.name}=${c.value}`).join("; "));
91
108
  resolvedCookies = {};
@@ -105,10 +122,10 @@ async function customFetch(url, options) {
105
122
  meta: {},
106
123
  cookies: resolvedCookies
107
124
  };
108
- if (options?.onBeforeFetch) await options.onBeforeFetch(ctx);
125
+ if (onBeforeFetch) await onBeforeFetch(ctx);
109
126
  let res = await fetch(ctx.url, ctx.init);
110
- if (options?.onAfterFetch) {
111
- if (await options.onAfterFetch(ctx, res) === "retry" && !ctx.meta.retry) {
127
+ if (onAfterFetch) {
128
+ if (await onAfterFetch(ctx, res) === "retry" && !ctx.meta.retry) {
112
129
  ctx.meta.retry = true;
113
130
  res = await fetch(ctx.url, ctx.init);
114
131
  }
@@ -125,6 +142,5 @@ async function customFetch(url, options) {
125
142
  return toCamelCaseKeys(data);
126
143
  }
127
144
 
128
- //#endregion
129
- export { customFetch as n, ApiError as t };
130
- //# sourceMappingURL=custom-fetch-CXJ4-i7I.js.map
145
+ export { customFetch as n, setDefaultClient as r, ApiError as t };
146
+ //# sourceMappingURL=custom-fetch-DJxn7nVP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-fetch-DJxn7nVP.js","names":[],"sources":["../src/core/runtime.ts","../src/core/mutators/custom-fetch.ts"],"sourcesContent":["import type { AuthulaClient } from \"./client\";\n\nconst DEFAULT_CLIENT = Symbol.for(\"authula.default-client\");\n\ntype RuntimeStore = {\n client?: AuthulaClient;\n};\n\nconst globalStore = globalThis as unknown as Record<symbol, RuntimeStore | undefined>;\nconst store = (globalStore[DEFAULT_CLIENT] ??= {});\n\nexport function setDefaultClient(client: AuthulaClient | undefined): void {\n store.client = client;\n}\n\nexport function getDefaultClient(): AuthulaClient | undefined {\n return store.client;\n}\n","import { parseSetCookie } from \"cookie\";\nimport { toCamelCaseKeys, toSnakeCaseKeys } from \"es-toolkit\";\n\nimport type { FetchContext, CookieStore } from \"../types\";\nimport { getDefaultClient } from \"../runtime\";\n\nexport class ApiError extends Error {\n status: number;\n data: any;\n headers: Headers;\n\n constructor(message: string, status: number, data: any, headers: Headers) {\n super(message || `Request failed with status ${status}`);\n this.name = \"ApiError\";\n this.status = status;\n this.data = data;\n this.headers = headers;\n }\n}\n\nfunction prependBase(url: string, base: string): string {\n if (!base) {\n return url;\n }\n if (/^https?:\\/\\//.test(url)) {\n return url.replace(/^https?:\\/\\/[^/]+/, base);\n }\n return `${base}${url.startsWith(\"/\") ? url : `/${url}`}`;\n}\n\nfunction convertRequestBodyToSnakeCase(\n body: BodyInit | null | undefined,\n): BodyInit | null | undefined {\n if (typeof body !== \"string\") {\n return body;\n }\n try {\n const parsed = JSON.parse(body);\n return parsed !== null && typeof parsed === \"object\"\n ? JSON.stringify(toSnakeCaseKeys(parsed))\n : body;\n } catch {\n return body;\n }\n}\n\nasync function parseJsonBody(res: Response): Promise<any> {\n if ([204, 205, 304].includes(res.status)) {\n return null;\n }\n const text = await res.text();\n return text ? JSON.parse(text) : null;\n}\n\nconst KNOWN_COOKIE_ATTRS = new Set([\n \"path\",\n \"domain\",\n \"expires\",\n \"maxAge\",\n \"httpOnly\",\n \"secure\",\n \"sameSite\",\n]);\n\nfunction parseSetCookieToStore(raw: string, store: CookieStore): void {\n let parsed: Record<string, any>;\n try {\n parsed = parseSetCookie(raw) as Record<string, any>;\n } catch {\n return;\n }\n if (!parsed) {\n return;\n }\n\n const { name, value, ...attrs } = parsed;\n const normalized: Record<string, any> = {};\n for (const [k, v] of Object.entries(attrs)) {\n const lower = k.toLowerCase();\n if (KNOWN_COOKIE_ATTRS.has(k)) {\n normalized[k] = v;\n } else if (lower === \"maxage\") normalized[\"maxAge\"] = v;\n else if (lower === \"httponly\") normalized[\"httpOnly\"] = v;\n else if (lower === \"samesite\") normalized[\"sameSite\"] = v;\n }\n\n try {\n store.set(name, value, normalized);\n } catch {\n // store may be immutable during SSR render\n }\n}\n\nexport function convertQueryKeysToSnakeCase(url: string): string {\n const qIndex = url.indexOf(\"?\");\n if (qIndex === -1) {\n return url;\n }\n\n const base = url.slice(0, qIndex);\n const searchParams = new URLSearchParams(url.slice(qIndex + 1));\n const snakeParams = new URLSearchParams();\n\n for (const [key, value] of searchParams.entries()) {\n const snakeKey = key.replace(/[A-Z]/g, (c) => `_${c.toLowerCase()}`);\n snakeParams.append(snakeKey, value);\n }\n\n return `${base}?${snakeParams.toString()}`;\n}\n\nexport async function customFetch<T>(\n url: string,\n options?: RequestInit & {\n method?: string;\n baseUrl?: string;\n cookies?: () => CookieStore | Promise<CookieStore>;\n onBeforeFetch?: (ctx: FetchContext) => Promise<void>;\n onAfterFetch?: (ctx: FetchContext, res: Response) => Promise<\"retry\" | void>;\n },\n): Promise<T> {\n const client = options?.baseUrl === undefined ? getDefaultClient() : undefined;\n const baseUrl = options?.baseUrl ?? client?.config.url.replace(/\\/+$/, \"\") ?? \"\";\n const cookies = options?.cookies ?? client?.config.cookies;\n const onBeforeFetch =\n options?.onBeforeFetch ?? (client ? client.runBeforeFetch.bind(client) : undefined);\n const onAfterFetch =\n options?.onAfterFetch ?? (client ? client.runAfterFetch.bind(client) : undefined);\n\n if (!baseUrl && !/^https?:\\/\\//.test(url)) {\n throw new Error(\n \"No Authula client configured. Call createClient() before using Authula hooks, or pass a baseUrl request option.\",\n );\n }\n\n const resolvedUrl = convertQueryKeysToSnakeCase(prependBase(url, baseUrl));\n\n const headers = new Headers(options?.headers || {});\n\n let cookieStore: CookieStore | null = null;\n let resolvedCookies: Record<string, string> | undefined;\n if (cookies) {\n try {\n cookieStore = await cookies();\n const all = cookieStore.getAll();\n if (all.length > 0 && !headers.has(\"cookie\")) {\n headers.set(\"cookie\", all.map((c) => `${c.name}=${c.value}`).join(\"; \"));\n }\n resolvedCookies = {};\n for (const c of all) {\n resolvedCookies[c.name] = c.value;\n }\n } catch {\n cookieStore = null;\n }\n }\n\n const ctx: FetchContext = {\n url: resolvedUrl,\n init: {\n method: options?.method ?? \"GET\",\n headers,\n body: convertRequestBodyToSnakeCase(options?.body),\n credentials: \"include\",\n signal: options?.signal ?? null,\n },\n meta: {},\n cookies: resolvedCookies,\n };\n\n if (onBeforeFetch) {\n await onBeforeFetch(ctx);\n }\n\n let res = await fetch(ctx.url, ctx.init);\n\n if (onAfterFetch) {\n const action = await onAfterFetch(ctx, res);\n if (action === \"retry\" && !ctx.meta.retry) {\n ctx.meta.retry = true;\n res = await fetch(ctx.url, ctx.init);\n }\n }\n\n if (cookieStore) {\n const values: string[] =\n typeof res.headers.getSetCookie === \"function\"\n ? res.headers.getSetCookie()\n : (res.headers.get(\"set-cookie\")?.split(\", \") ?? []);\n for (const raw of values) {\n parseSetCookieToStore(raw, cookieStore);\n }\n }\n\n const data = await parseJsonBody(res);\n\n if (!res.ok) {\n const message =\n typeof data === \"object\" && data !== null && \"message\" in data ? String(data.message) : \"\";\n throw new ApiError(message, res.status, data, res.headers);\n }\n\n return toCamelCaseKeys(data) as T;\n}\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { d as Plugin, f as AuthulaClient, n as InferPluginMethods } from "./sdk-Cu28BXFh.js";
2
+ type HookPrefix = "use" | "create";
3
+ type HookName<Prefix extends HookPrefix, Method extends PropertyKey> = Method extends string ? `${Prefix}${Capitalize<Method>}` : never;
4
+ type PluginHooks<P extends Plugin, G extends object, Prefix extends HookPrefix> = { [K in keyof G as K extends HookName<Prefix, keyof InferPluginMethods<P>> ? K : never]: G[K]; };
5
+ type WithFrameworkApi<P extends Plugin, G extends object, Prefix extends HookPrefix> = [InferPluginMethods<P>] extends [void] ? InferPluginMethods<P> : InferPluginMethods<P> & PluginHooks<P, G, Prefix>;
6
+ type ClientWithPluginHooks<T extends readonly Plugin[], G extends object, Prefix extends HookPrefix> = AuthulaClient & { [P in T[number] as P["id"]]: WithFrameworkApi<P, G, Prefix>; };
7
+ export { ClientWithPluginHooks as t };
8
+ //# sourceMappingURL=framework-client-CsGjKPXl.d.ts.map
@@ -0,0 +1,50 @@
1
+ // src/core/framework-client.ts
2
+ function hookName(prefix, method) {
3
+ return `${prefix}${method.charAt(0).toUpperCase()}${method.slice(1)}`;
4
+ }
5
+ function createRequestContext(client) {
6
+ return {
7
+ baseUrl: client.config.url.replace(/\/+$/, ""),
8
+ cookies: client.config.cookies,
9
+ onBeforeFetch: (ctx) => client.runBeforeFetch(ctx),
10
+ onAfterFetch: (ctx, res) => client.runAfterFetch(ctx, res)
11
+ };
12
+ }
13
+ function wrapHook(hook, client) {
14
+ const requestContext = createRequestContext(client);
15
+ return (...args) => {
16
+ let optionsIdx = Math.max(0, hook.length - 2);
17
+ if (args[optionsIdx] != null && typeof args[optionsIdx] !== "object") optionsIdx = Math.max(0, hook.length - 1);
18
+ while (args.length <= optionsIdx) args.push(void 0);
19
+ const existing = args[optionsIdx];
20
+ const existingOptions = typeof existing === "object" && existing !== null ? existing : {};
21
+ const existingRequest = existingOptions.request;
22
+ args[optionsIdx] = {
23
+ ...existingOptions,
24
+ request: {
25
+ ...requestContext,
26
+ ...existingRequest
27
+ }
28
+ };
29
+ return hook(...args);
30
+ };
31
+ }
32
+ function attachFrameworkHooks(client, plugins, generated, prefix) {
33
+ const generatedHooks = generated;
34
+ const pluginApis = client;
35
+ for (const plugin of plugins) {
36
+ const api = pluginApis[plugin.id];
37
+ if (!api || typeof api !== "object") continue;
38
+ const pluginApi = api;
39
+ for (const [method, value] of Object.entries(pluginApi)) {
40
+ if (typeof value !== "function") continue;
41
+ const name = hookName(prefix, method);
42
+ const hook = generatedHooks[name];
43
+ if (typeof hook === "function") pluginApi[name] = wrapHook(hook, client);
44
+ }
45
+ }
46
+ return client;
47
+ }
48
+
49
+ export { attachFrameworkHooks as t };
50
+ //# sourceMappingURL=framework-client-D-yGjqAx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-client-D-yGjqAx.js","names":[],"sources":["../src/core/framework-client.ts"],"sourcesContent":["import type { AuthulaClient } from \"./client\";\nimport type { InferPluginMethods } from \"./sdk\";\nimport type { Plugin } from \"./types\";\n\nexport type HookPrefix = \"use\" | \"create\";\n\ntype HookName<Prefix extends HookPrefix, Method extends PropertyKey> = Method extends string\n ? `${Prefix}${Capitalize<Method>}`\n : never;\n\ntype PluginHooks<P extends Plugin, G extends object, Prefix extends HookPrefix> = {\n [K in keyof G as K extends HookName<Prefix, keyof InferPluginMethods<P>> ? K : never]: G[K];\n};\n\ntype WithFrameworkApi<P extends Plugin, G extends object, Prefix extends HookPrefix> = [\n InferPluginMethods<P>,\n] extends [void]\n ? InferPluginMethods<P>\n : InferPluginMethods<P> & PluginHooks<P, G, Prefix>;\n\nexport type ClientWithPluginHooks<\n T extends readonly Plugin[],\n G extends object,\n Prefix extends HookPrefix,\n> = AuthulaClient & {\n [P in T[number] as P[\"id\"]]: WithFrameworkApi<P, G, Prefix>;\n};\n\ntype AnyFunction = (...args: any[]) => any;\n\nfunction hookName(prefix: HookPrefix, method: string): string {\n return `${prefix}${method.charAt(0).toUpperCase()}${method.slice(1)}`;\n}\n\nfunction createRequestContext(client: AuthulaClient) {\n return {\n baseUrl: client.config.url.replace(/\\/+$/, \"\"),\n cookies: client.config.cookies,\n onBeforeFetch: (ctx: any) => client.runBeforeFetch(ctx),\n onAfterFetch: (ctx: any, res: Response) => client.runAfterFetch(ctx, res),\n };\n}\n\nexport function wrapHook(hook: AnyFunction, client: AuthulaClient): AnyFunction {\n const requestContext = createRequestContext(client);\n\n return (...args: any[]) => {\n let optionsIdx = Math.max(0, hook.length - 2);\n if (args[optionsIdx] != null && typeof args[optionsIdx] !== \"object\") {\n optionsIdx = Math.max(0, hook.length - 1);\n }\n while (args.length <= optionsIdx) {\n args.push(undefined);\n }\n\n const existing = args[optionsIdx];\n const existingOptions = typeof existing === \"object\" && existing !== null ? existing : {};\n const existingRequest = (existingOptions as { request?: object }).request;\n\n args[optionsIdx] = {\n ...existingOptions,\n // Explicit per-call values win over the client defaults, so SSR callers\n // can override cookies/baseUrl for a single request.\n request: { ...requestContext, ...existingRequest },\n };\n\n return hook(...args);\n };\n}\n\nexport function attachFrameworkHooks<\n T extends readonly Plugin[],\n G extends object,\n Prefix extends HookPrefix,\n>(\n client: AuthulaClient,\n plugins: T,\n generated: G,\n prefix: Prefix,\n): ClientWithPluginHooks<T, G, Prefix> {\n const generatedHooks = generated as Record<string, unknown>;\n const pluginApis = client as unknown as Record<string, unknown>;\n\n for (const plugin of plugins) {\n const api = pluginApis[plugin.id];\n if (!api || typeof api !== \"object\") {\n continue;\n }\n\n const pluginApi = api as Record<string, unknown>;\n for (const [method, value] of Object.entries(pluginApi)) {\n if (typeof value !== \"function\") {\n continue;\n }\n\n const name = hookName(prefix, method);\n const hook = generatedHooks[name];\n if (typeof hook === \"function\") {\n pluginApi[name] = wrapHook(hook as AnyFunction, client);\n }\n }\n }\n\n return client as ClientWithPluginHooks<T, G, Prefix>;\n}\n"],"mappings":";AA8BA,SAAS,SAAS,QAAoB,QAAwB;CAC5D,OAAO,GAAG,SAAS,OAAO,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,OAAO,MAAM,CAAC;AACpE;AAEA,SAAS,qBAAqB,QAAuB;CACnD,OAAO;EACL,SAAS,OAAO,OAAO,IAAI,QAAQ,QAAQ,EAAE;EAC7C,SAAS,OAAO,OAAO;EACvB,gBAAgB,QAAa,OAAO,eAAe,GAAG;EACtD,eAAe,KAAU,QAAkB,OAAO,cAAc,KAAK,GAAG;CAC1E;AACF;AAEA,SAAgB,SAAS,MAAmB,QAAoC;CAC9E,MAAM,iBAAiB,qBAAqB,MAAM;CAElD,QAAQ,GAAG,SAAgB;EACzB,IAAI,aAAa,KAAK,IAAI,GAAG,KAAK,SAAS,CAAC;EAC5C,IAAI,KAAK,eAAe,QAAQ,OAAO,KAAK,gBAAgB,UAC1D,aAAa,KAAK,IAAI,GAAG,KAAK,SAAS,CAAC;EAE1C,OAAO,KAAK,UAAU,YACpB,KAAK,KAAK,MAAS;EAGrB,MAAM,WAAW,KAAK;EACtB,MAAM,kBAAkB,OAAO,aAAa,YAAY,aAAa,OAAO,WAAW,CAAC;EACxF,MAAM,kBAAmB,gBAAyC;EAElE,KAAK,cAAc;GACjB,GAAG;GAGH,SAAS;IAAE,GAAG;IAAgB,GAAG;GAAgB;EACnD;EAEA,OAAO,KAAK,GAAG,IAAI;CACrB;AACF;AAEA,SAAgB,qBAKd,QACA,SACA,WACA,QACqC;CACrC,MAAM,iBAAiB;CACvB,MAAM,aAAa;CAEnB,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,MAAM,WAAW,OAAO;EAC9B,IAAI,CAAC,OAAO,OAAO,QAAQ,UACzB;EAGF,MAAM,YAAY;EAClB,KAAK,MAAM,CAAC,QAAQ,UAAU,OAAO,QAAQ,SAAS,GAAG;GACvD,IAAI,OAAO,UAAU,YACnB;GAGF,MAAM,OAAO,SAAS,QAAQ,MAAM;GACpC,MAAM,OAAO,eAAe;GAC5B,IAAI,OAAO,SAAS,YAClB,UAAU,QAAQ,SAAS,MAAqB,MAAM;EAE1D;CACF;CAEA,OAAO;AACT"}