authula 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.
@@ -0,0 +1,124 @@
1
+ import { z } from "zod";
2
+ import { toCamelCaseKeys, toSnakeCaseKeys } from "es-toolkit";
3
+
4
+ //#region src/types/schemas.ts
5
+ const userSchema = z.object({
6
+ id: z.uuid(),
7
+ name: z.string().nonempty(),
8
+ email: z.email(),
9
+ emailVerified: z.boolean(),
10
+ image: z.string().nullish(),
11
+ metadata: z.record(z.string(), z.unknown()).nullish(),
12
+ createdAt: z.iso.datetime(),
13
+ updatedAt: z.iso.datetime()
14
+ });
15
+ const accountSchema = z.object({
16
+ id: z.uuid(),
17
+ userId: z.string().nonempty(),
18
+ accountId: z.string().nonempty(),
19
+ providerId: z.string().nonempty(),
20
+ accessToken: z.string().nullish(),
21
+ refreshToken: z.string().nullish(),
22
+ idToken: z.string().nullish(),
23
+ accessTokenExpiresAt: z.iso.datetime().nullish(),
24
+ refreshTokenExpiresAt: z.iso.datetime().nullish(),
25
+ scope: z.string().nullish(),
26
+ password: z.string().nullish(),
27
+ createdAt: z.iso.datetime(),
28
+ updatedAt: z.iso.datetime()
29
+ });
30
+ const sessionSchema = z.object({
31
+ id: z.uuid(),
32
+ userId: z.string().nonempty(),
33
+ token: z.string().nonempty(),
34
+ expiresAt: z.iso.datetime(),
35
+ ipAddress: z.string().nullish(),
36
+ userAgent: z.string().nullish(),
37
+ createdAt: z.iso.datetime(),
38
+ updatedAt: z.iso.datetime()
39
+ });
40
+ const verificationTypeSchema = z.enum([
41
+ "email_verification",
42
+ "password_reset_request",
43
+ "email_reset_request"
44
+ ]);
45
+ const verificationSchema = z.object({
46
+ id: z.uuid(),
47
+ userId: z.string().nullish(),
48
+ identifier: z.string().nonempty(),
49
+ token: z.string().nonempty(),
50
+ type: verificationTypeSchema,
51
+ expiresAt: z.iso.datetime(),
52
+ createdAt: z.iso.datetime(),
53
+ updatedAt: z.iso.datetime()
54
+ });
55
+
56
+ //#endregion
57
+ //#region src/fetch.ts
58
+ async function wrappedFetch(client, endpoint, options = {}) {
59
+ const headers = new Headers(options.headers || {});
60
+ let cookieStore = null;
61
+ if (client.config.cookies) {
62
+ cookieStore = await client.config.cookies();
63
+ const cookieHeader = cookieStore.getAll().map((c) => `${c.name}=${c.value}`).join("; ");
64
+ if (cookieHeader) headers.set("cookie", cookieHeader);
65
+ }
66
+ const controller = new AbortController();
67
+ const abortTimeout = client.config.fetchOptions?.abortTimeout;
68
+ if (abortTimeout) setTimeout(() => controller.abort(), abortTimeout * 1e3);
69
+ const ctx = {
70
+ url: `${client.config.url}${endpoint}`,
71
+ init: {
72
+ method: options.method ?? "GET",
73
+ headers,
74
+ body: options.body ? JSON.stringify(toSnakeCaseKeys(options.body)) : void 0,
75
+ credentials: "include",
76
+ signal: controller.signal
77
+ },
78
+ meta: {}
79
+ };
80
+ await client.runBeforeFetch(ctx);
81
+ let res = await fetch(ctx.url, ctx.init);
82
+ if (await client.runAfterFetch(ctx, res) === "retry" && !ctx.meta.retry) {
83
+ ctx.meta.retry = true;
84
+ res = await fetch(ctx.url, ctx.init);
85
+ }
86
+ const setCookieHeaders = res.headers.getSetCookie?.() ?? res.headers.get("set-cookie")?.split(", ") ?? null;
87
+ if (!res.ok) throw new Error(await res.text());
88
+ const resData = await res.json();
89
+ if (cookieStore && setCookieHeaders) for (const raw of setCookieHeaders) {
90
+ const [pair, ...attrs] = raw.split(";");
91
+ const [name, value] = pair.split("=");
92
+ if (!name || !value) continue;
93
+ const options = {};
94
+ for (const attr of attrs) {
95
+ const [k, v] = attr.trim().split("=");
96
+ switch (k.toLowerCase()) {
97
+ case "path":
98
+ options.path = v;
99
+ break;
100
+ case "expires":
101
+ options.expires = new Date(v);
102
+ break;
103
+ case "max-age":
104
+ options.maxAge = Number(v);
105
+ break;
106
+ case "httponly":
107
+ options.httpOnly = true;
108
+ break;
109
+ case "secure":
110
+ options.secure = true;
111
+ break;
112
+ case "samesite":
113
+ options.sameSite = v?.toLowerCase();
114
+ break;
115
+ }
116
+ }
117
+ cookieStore.set(name.trim(), decodeURIComponent(value.trim()), options);
118
+ }
119
+ return toCamelCaseKeys(resData);
120
+ }
121
+
122
+ //#endregion
123
+ export { verificationSchema as a, userSchema as i, accountSchema as n, verificationTypeSchema as o, sessionSchema as r, wrappedFetch as t };
124
+ //# sourceMappingURL=fetch-B4O1awi2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-B4O1awi2.js","names":[],"sources":["../src/types/schemas.ts","../src/fetch.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const userSchema = z.object({\n id: z.uuid(),\n name: z.string().nonempty(),\n email: z.email(),\n emailVerified: z.boolean(),\n image: z.string().nullish(),\n metadata: z.record(z.string(), z.unknown()).nullish(),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime(),\n});\nexport type User = z.infer<typeof userSchema>;\n\nexport const accountSchema = z.object({\n id: z.uuid(),\n userId: z.string().nonempty(),\n accountId: z.string().nonempty(),\n providerId: z.string().nonempty(),\n accessToken: z.string().nullish(),\n refreshToken: z.string().nullish(),\n idToken: z.string().nullish(),\n accessTokenExpiresAt: z.iso.datetime().nullish(),\n refreshTokenExpiresAt: z.iso.datetime().nullish(),\n scope: z.string().nullish(),\n password: z.string().nullish(),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime(),\n});\nexport type Account = z.infer<typeof accountSchema>;\n\nexport const sessionSchema = z.object({\n id: z.uuid(),\n userId: z.string().nonempty(),\n token: z.string().nonempty(),\n expiresAt: z.iso.datetime(),\n ipAddress: z.string().nullish(),\n userAgent: z.string().nullish(),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime(),\n});\nexport type Session = z.infer<typeof sessionSchema>;\n\nexport const verificationTypeSchema = z.enum([\n \"email_verification\",\n \"password_reset_request\",\n \"email_reset_request\",\n]);\nexport type VerificationType = z.infer<typeof verificationTypeSchema>;\n\nexport const verificationSchema = z.object({\n id: z.uuid(),\n userId: z.string().nullish(),\n identifier: z.string().nonempty(),\n token: z.string().nonempty(),\n type: verificationTypeSchema,\n expiresAt: z.iso.datetime(),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime(),\n});\nexport type Verification = z.infer<typeof verificationSchema>;\n","import { toCamelCaseKeys, toSnakeCaseKeys } from \"es-toolkit\";\n\nimport type { AuthulaClient } from \"./client\";\nimport type { CookieStore, FetchContext, FetchRequestOptions } from \"./types\";\n\nexport async function wrappedFetch<T>(\n client: AuthulaClient,\n endpoint: string,\n options: FetchRequestOptions = {},\n): Promise<T> {\n const headers = new Headers(options.headers || {});\n\n let cookieStore: CookieStore | null = null;\n\n if (client.config.cookies) {\n cookieStore = await client.config.cookies();\n\n const cookieHeader = cookieStore\n .getAll()\n .map((c) => `${c.name}=${c.value}`)\n .join(\"; \");\n\n if (cookieHeader) {\n headers.set(\"cookie\", cookieHeader);\n }\n }\n\n const controller = new AbortController();\n const abortTimeout = client.config.fetchOptions?.abortTimeout;\n\n if (abortTimeout) {\n setTimeout(() => controller.abort(), abortTimeout * 1000);\n }\n\n const ctx: FetchContext = {\n url: `${client.config.url}${endpoint}`,\n init: {\n method: options.method ?? \"GET\",\n headers,\n body: options.body\n ? JSON.stringify(toSnakeCaseKeys(options.body))\n : undefined,\n credentials: \"include\",\n signal: controller.signal,\n },\n meta: {},\n };\n\n await client.runBeforeFetch(ctx);\n\n let res = await fetch(ctx.url, ctx.init);\n\n const action = await client.runAfterFetch(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 const setCookieHeaders =\n res.headers.getSetCookie?.() ??\n res.headers.get(\"set-cookie\")?.split(\", \") ??\n null;\n\n if (!res.ok) {\n throw new Error(await res.text());\n }\n\n const resData = await res.json();\n\n // Apply Set-Cookie back into Next.js store (SSR only)\n if (cookieStore && setCookieHeaders) {\n for (const raw of setCookieHeaders) {\n const [pair, ...attrs] = raw.split(\";\");\n const [name, value] = pair.split(\"=\");\n\n if (!name || !value) continue;\n\n const options: Record<string, any> = {};\n\n for (const attr of attrs) {\n const [k, v] = attr.trim().split(\"=\");\n\n switch (k.toLowerCase()) {\n case \"path\":\n options.path = v;\n break;\n case \"expires\":\n options.expires = new Date(v);\n break;\n case \"max-age\":\n options.maxAge = Number(v);\n break;\n case \"httponly\":\n options.httpOnly = true;\n break;\n case \"secure\":\n options.secure = true;\n break;\n case \"samesite\":\n options.sameSite = v?.toLowerCase();\n break;\n }\n }\n\n cookieStore.set(name.trim(), decodeURIComponent(value.trim()), options);\n }\n }\n\n return toCamelCaseKeys(resData) as T;\n}\n"],"mappings":"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"}
@@ -0,0 +1,159 @@
1
+ let zod = require("zod");
2
+ let es_toolkit = require("es-toolkit");
3
+
4
+ //#region src/types/schemas.ts
5
+ const userSchema = zod.z.object({
6
+ id: zod.z.uuid(),
7
+ name: zod.z.string().nonempty(),
8
+ email: zod.z.email(),
9
+ emailVerified: zod.z.boolean(),
10
+ image: zod.z.string().nullish(),
11
+ metadata: zod.z.record(zod.z.string(), zod.z.unknown()).nullish(),
12
+ createdAt: zod.z.iso.datetime(),
13
+ updatedAt: zod.z.iso.datetime()
14
+ });
15
+ const accountSchema = zod.z.object({
16
+ id: zod.z.uuid(),
17
+ userId: zod.z.string().nonempty(),
18
+ accountId: zod.z.string().nonempty(),
19
+ providerId: zod.z.string().nonempty(),
20
+ accessToken: zod.z.string().nullish(),
21
+ refreshToken: zod.z.string().nullish(),
22
+ idToken: zod.z.string().nullish(),
23
+ accessTokenExpiresAt: zod.z.iso.datetime().nullish(),
24
+ refreshTokenExpiresAt: zod.z.iso.datetime().nullish(),
25
+ scope: zod.z.string().nullish(),
26
+ password: zod.z.string().nullish(),
27
+ createdAt: zod.z.iso.datetime(),
28
+ updatedAt: zod.z.iso.datetime()
29
+ });
30
+ const sessionSchema = zod.z.object({
31
+ id: zod.z.uuid(),
32
+ userId: zod.z.string().nonempty(),
33
+ token: zod.z.string().nonempty(),
34
+ expiresAt: zod.z.iso.datetime(),
35
+ ipAddress: zod.z.string().nullish(),
36
+ userAgent: zod.z.string().nullish(),
37
+ createdAt: zod.z.iso.datetime(),
38
+ updatedAt: zod.z.iso.datetime()
39
+ });
40
+ const verificationTypeSchema = zod.z.enum([
41
+ "email_verification",
42
+ "password_reset_request",
43
+ "email_reset_request"
44
+ ]);
45
+ const verificationSchema = zod.z.object({
46
+ id: zod.z.uuid(),
47
+ userId: zod.z.string().nullish(),
48
+ identifier: zod.z.string().nonempty(),
49
+ token: zod.z.string().nonempty(),
50
+ type: verificationTypeSchema,
51
+ expiresAt: zod.z.iso.datetime(),
52
+ createdAt: zod.z.iso.datetime(),
53
+ updatedAt: zod.z.iso.datetime()
54
+ });
55
+
56
+ //#endregion
57
+ //#region src/fetch.ts
58
+ async function wrappedFetch(client, endpoint, options = {}) {
59
+ const headers = new Headers(options.headers || {});
60
+ let cookieStore = null;
61
+ if (client.config.cookies) {
62
+ cookieStore = await client.config.cookies();
63
+ const cookieHeader = cookieStore.getAll().map((c) => `${c.name}=${c.value}`).join("; ");
64
+ if (cookieHeader) headers.set("cookie", cookieHeader);
65
+ }
66
+ const controller = new AbortController();
67
+ const abortTimeout = client.config.fetchOptions?.abortTimeout;
68
+ if (abortTimeout) setTimeout(() => controller.abort(), abortTimeout * 1e3);
69
+ const ctx = {
70
+ url: `${client.config.url}${endpoint}`,
71
+ init: {
72
+ method: options.method ?? "GET",
73
+ headers,
74
+ body: options.body ? JSON.stringify((0, es_toolkit.toSnakeCaseKeys)(options.body)) : void 0,
75
+ credentials: "include",
76
+ signal: controller.signal
77
+ },
78
+ meta: {}
79
+ };
80
+ await client.runBeforeFetch(ctx);
81
+ let res = await fetch(ctx.url, ctx.init);
82
+ if (await client.runAfterFetch(ctx, res) === "retry" && !ctx.meta.retry) {
83
+ ctx.meta.retry = true;
84
+ res = await fetch(ctx.url, ctx.init);
85
+ }
86
+ const setCookieHeaders = res.headers.getSetCookie?.() ?? res.headers.get("set-cookie")?.split(", ") ?? null;
87
+ if (!res.ok) throw new Error(await res.text());
88
+ const resData = await res.json();
89
+ if (cookieStore && setCookieHeaders) for (const raw of setCookieHeaders) {
90
+ const [pair, ...attrs] = raw.split(";");
91
+ const [name, value] = pair.split("=");
92
+ if (!name || !value) continue;
93
+ const options = {};
94
+ for (const attr of attrs) {
95
+ const [k, v] = attr.trim().split("=");
96
+ switch (k.toLowerCase()) {
97
+ case "path":
98
+ options.path = v;
99
+ break;
100
+ case "expires":
101
+ options.expires = new Date(v);
102
+ break;
103
+ case "max-age":
104
+ options.maxAge = Number(v);
105
+ break;
106
+ case "httponly":
107
+ options.httpOnly = true;
108
+ break;
109
+ case "secure":
110
+ options.secure = true;
111
+ break;
112
+ case "samesite":
113
+ options.sameSite = v?.toLowerCase();
114
+ break;
115
+ }
116
+ }
117
+ cookieStore.set(name.trim(), decodeURIComponent(value.trim()), options);
118
+ }
119
+ return (0, es_toolkit.toCamelCaseKeys)(resData);
120
+ }
121
+
122
+ //#endregion
123
+ Object.defineProperty(exports, 'accountSchema', {
124
+ enumerable: true,
125
+ get: function () {
126
+ return accountSchema;
127
+ }
128
+ });
129
+ Object.defineProperty(exports, 'sessionSchema', {
130
+ enumerable: true,
131
+ get: function () {
132
+ return sessionSchema;
133
+ }
134
+ });
135
+ Object.defineProperty(exports, 'userSchema', {
136
+ enumerable: true,
137
+ get: function () {
138
+ return userSchema;
139
+ }
140
+ });
141
+ Object.defineProperty(exports, 'verificationSchema', {
142
+ enumerable: true,
143
+ get: function () {
144
+ return verificationSchema;
145
+ }
146
+ });
147
+ Object.defineProperty(exports, 'verificationTypeSchema', {
148
+ enumerable: true,
149
+ get: function () {
150
+ return verificationTypeSchema;
151
+ }
152
+ });
153
+ Object.defineProperty(exports, 'wrappedFetch', {
154
+ enumerable: true,
155
+ get: function () {
156
+ return wrappedFetch;
157
+ }
158
+ });
159
+ //# sourceMappingURL=fetch-q98rEoAp.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-q98rEoAp.cjs","names":["z"],"sources":["../src/types/schemas.ts","../src/fetch.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const userSchema = z.object({\n id: z.uuid(),\n name: z.string().nonempty(),\n email: z.email(),\n emailVerified: z.boolean(),\n image: z.string().nullish(),\n metadata: z.record(z.string(), z.unknown()).nullish(),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime(),\n});\nexport type User = z.infer<typeof userSchema>;\n\nexport const accountSchema = z.object({\n id: z.uuid(),\n userId: z.string().nonempty(),\n accountId: z.string().nonempty(),\n providerId: z.string().nonempty(),\n accessToken: z.string().nullish(),\n refreshToken: z.string().nullish(),\n idToken: z.string().nullish(),\n accessTokenExpiresAt: z.iso.datetime().nullish(),\n refreshTokenExpiresAt: z.iso.datetime().nullish(),\n scope: z.string().nullish(),\n password: z.string().nullish(),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime(),\n});\nexport type Account = z.infer<typeof accountSchema>;\n\nexport const sessionSchema = z.object({\n id: z.uuid(),\n userId: z.string().nonempty(),\n token: z.string().nonempty(),\n expiresAt: z.iso.datetime(),\n ipAddress: z.string().nullish(),\n userAgent: z.string().nullish(),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime(),\n});\nexport type Session = z.infer<typeof sessionSchema>;\n\nexport const verificationTypeSchema = z.enum([\n \"email_verification\",\n \"password_reset_request\",\n \"email_reset_request\",\n]);\nexport type VerificationType = z.infer<typeof verificationTypeSchema>;\n\nexport const verificationSchema = z.object({\n id: z.uuid(),\n userId: z.string().nullish(),\n identifier: z.string().nonempty(),\n token: z.string().nonempty(),\n type: verificationTypeSchema,\n expiresAt: z.iso.datetime(),\n createdAt: z.iso.datetime(),\n updatedAt: z.iso.datetime(),\n});\nexport type Verification = z.infer<typeof verificationSchema>;\n","import { toCamelCaseKeys, toSnakeCaseKeys } from \"es-toolkit\";\n\nimport type { AuthulaClient } from \"./client\";\nimport type { CookieStore, FetchContext, FetchRequestOptions } from \"./types\";\n\nexport async function wrappedFetch<T>(\n client: AuthulaClient,\n endpoint: string,\n options: FetchRequestOptions = {},\n): Promise<T> {\n const headers = new Headers(options.headers || {});\n\n let cookieStore: CookieStore | null = null;\n\n if (client.config.cookies) {\n cookieStore = await client.config.cookies();\n\n const cookieHeader = cookieStore\n .getAll()\n .map((c) => `${c.name}=${c.value}`)\n .join(\"; \");\n\n if (cookieHeader) {\n headers.set(\"cookie\", cookieHeader);\n }\n }\n\n const controller = new AbortController();\n const abortTimeout = client.config.fetchOptions?.abortTimeout;\n\n if (abortTimeout) {\n setTimeout(() => controller.abort(), abortTimeout * 1000);\n }\n\n const ctx: FetchContext = {\n url: `${client.config.url}${endpoint}`,\n init: {\n method: options.method ?? \"GET\",\n headers,\n body: options.body\n ? JSON.stringify(toSnakeCaseKeys(options.body))\n : undefined,\n credentials: \"include\",\n signal: controller.signal,\n },\n meta: {},\n };\n\n await client.runBeforeFetch(ctx);\n\n let res = await fetch(ctx.url, ctx.init);\n\n const action = await client.runAfterFetch(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 const setCookieHeaders =\n res.headers.getSetCookie?.() ??\n res.headers.get(\"set-cookie\")?.split(\", \") ??\n null;\n\n if (!res.ok) {\n throw new Error(await res.text());\n }\n\n const resData = await res.json();\n\n // Apply Set-Cookie back into Next.js store (SSR only)\n if (cookieStore && setCookieHeaders) {\n for (const raw of setCookieHeaders) {\n const [pair, ...attrs] = raw.split(\";\");\n const [name, value] = pair.split(\"=\");\n\n if (!name || !value) continue;\n\n const options: Record<string, any> = {};\n\n for (const attr of attrs) {\n const [k, v] = attr.trim().split(\"=\");\n\n switch (k.toLowerCase()) {\n case \"path\":\n options.path = v;\n break;\n case \"expires\":\n options.expires = new Date(v);\n break;\n case \"max-age\":\n options.maxAge = Number(v);\n break;\n case \"httponly\":\n options.httpOnly = true;\n break;\n case \"secure\":\n options.secure = true;\n break;\n case \"samesite\":\n options.sameSite = v?.toLowerCase();\n break;\n }\n }\n\n cookieStore.set(name.trim(), decodeURIComponent(value.trim()), options);\n }\n }\n\n return toCamelCaseKeys(resData) as T;\n}\n"],"mappings":"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"}
package/dist/index.cjs ADDED
@@ -0,0 +1,60 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_fetch = require('./fetch-q98rEoAp.cjs');
3
+ let es_toolkit = require("es-toolkit");
4
+
5
+ //#region src/client.ts
6
+ var AuthulaClient = class {
7
+ config;
8
+ plugins;
9
+ beforeFetchHooks = [];
10
+ afterFetchHooks = [];
11
+ constructor(options) {
12
+ this.plugins = options.plugins;
13
+ const { plugins, ...rest } = options;
14
+ this.config = rest;
15
+ for (const plugin of this.plugins) {
16
+ if ("attachCookies" in plugin && this.config.cookies) plugin.attachCookies(this.config.cookies);
17
+ this[plugin.id] = plugin.init(this);
18
+ }
19
+ }
20
+ registerBeforeFetch(hook) {
21
+ this.beforeFetchHooks.push(hook);
22
+ }
23
+ registerAfterFetch(hook) {
24
+ this.afterFetchHooks.push(hook);
25
+ }
26
+ async runBeforeFetch(ctx) {
27
+ for (const hook of this.beforeFetchHooks) await hook(ctx);
28
+ }
29
+ async runAfterFetch(ctx, res) {
30
+ for (const hook of this.afterFetchHooks) if (await hook(ctx, res) === "retry") return "retry";
31
+ }
32
+ async getMe() {
33
+ return require_fetch.wrappedFetch(this, "/me", { method: "GET" });
34
+ }
35
+ async signOut(data) {
36
+ return require_fetch.wrappedFetch(this, "/sign-out", {
37
+ method: "POST",
38
+ body: (0, es_toolkit.toSnakeCaseKeys)(data)
39
+ });
40
+ }
41
+ getPlugin(id) {
42
+ return this.plugins.find((plugin) => plugin.id === id);
43
+ }
44
+ };
45
+
46
+ //#endregion
47
+ //#region src/sdk.ts
48
+ function createClient(options) {
49
+ return new AuthulaClient(options);
50
+ }
51
+
52
+ //#endregion
53
+ exports.AuthulaClient = AuthulaClient;
54
+ exports.accountSchema = require_fetch.accountSchema;
55
+ exports.createClient = createClient;
56
+ exports.sessionSchema = require_fetch.sessionSchema;
57
+ exports.userSchema = require_fetch.userSchema;
58
+ exports.verificationSchema = require_fetch.verificationSchema;
59
+ exports.verificationTypeSchema = require_fetch.verificationTypeSchema;
60
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","names":["wrappedFetch"],"sources":["../src/client.ts","../src/sdk.ts"],"sourcesContent":["import { toSnakeCaseKeys } from \"es-toolkit\";\n\nimport { wrappedFetch } from \"./fetch\";\nimport type {\n FetchContext,\n AuthulaClientConfig,\n AuthulaClientOptions,\n SignOutRequest,\n SignOutResponse,\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 if (\"attachCookies\" in plugin && this.config.cookies) {\n (plugin as any).attachCookies(this.config.cookies);\n }\n (this as any)[plugin.id] = plugin.init(this);\n }\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 async getMe<T = unknown>(): Promise<T> {\n return wrappedFetch<T>(this, \"/me\", {\n method: \"GET\",\n });\n }\n\n public async signOut(data: SignOutRequest): Promise<SignOutResponse> {\n return wrappedFetch<SignOutResponse>(this, \"/sign-out\", {\n method: \"POST\",\n body: toSnakeCaseKeys(data),\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","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 }\n ? M\n : 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":";;;;;AAcA,IAAa,gBAAb,MAA2B;CACzB,AAAgB;CAChB,AAAiB;CACjB,AAAiB,mBAAsC,EAAE;CACzD,AAAiB,kBAAoC,EAAE;CAEvD,YAAY,SAA+B;AACzC,OAAK,UAAU,QAAQ;EAEvB,MAAM,EAAE,SAAS,GAAG,SAAS;AAC7B,OAAK,SAAS;AAEd,OAAK,MAAM,UAAU,KAAK,SAAS;AACjC,OAAI,mBAAmB,UAAU,KAAK,OAAO,QAC3C,CAAC,OAAe,cAAc,KAAK,OAAO,QAAQ;AAEpD,GAAC,KAAa,OAAO,MAAM,OAAO,KAAK,KAAK;;;CAIhD,AAAO,oBAAoB,MAA6B;AACtD,OAAK,iBAAiB,KAAK,KAAK;;CAGlC,AAAO,mBAAmB,MAA4B;AACpD,OAAK,gBAAgB,KAAK,KAAK;;CAGjC,MAAa,eAAe,KAAkC;AAC5D,OAAK,MAAM,QAAQ,KAAK,iBACtB,OAAM,KAAK,IAAI;;CAInB,MAAa,cAAc,KAAmB,KAAe;AAC3D,OAAK,MAAM,QAAQ,KAAK,gBAEtB,KADe,MAAM,KAAK,KAAK,IAAI,KACpB,QACb,QAAO;;CAKb,MAAa,QAAiC;AAC5C,SAAOA,2BAAgB,MAAM,OAAO,EAClC,QAAQ,OACT,CAAC;;CAGJ,MAAa,QAAQ,MAAgD;AACnE,SAAOA,2BAA8B,MAAM,aAAa;GACtD,QAAQ;GACR,sCAAsB,KAAK;GAC5B,CAAC;;CAGJ,AAAO,UAA4B,IAA2B;AAC5D,SAAO,KAAK,QAAQ,MAAM,WAAW,OAAO,OAAO,GAAG;;;;;;AC3D1D,SAAgB,aACd,SACsB;AACtB,QAAO,IAAI,cAAc,QAAe"}
@@ -0,0 +1,2 @@
1
+ import { C as AfterFetchHook, E as FetchRequestOptions, S as verificationTypeSchema, T as FetchContext, _ as VerificationType, a as SignOutResponse, b as userSchema, c as FetchOptions, d as CookieProvider, f as CookieStore, g as Verification, h as User, i as SignOutRequest, l as Plugin, m as Session, n as createClient, o as AuthulaClientConfig, p as Account, r as GetMeResponse, s as AuthulaClientOptions, u as AuthulaClient, v as accountSchema, w as BeforeFetchHook, x as verificationSchema, y as sessionSchema } from "./sdk-DV73pbRH.cjs";
2
+ export { Account, AfterFetchHook, AuthulaClient, AuthulaClientConfig, AuthulaClientOptions, BeforeFetchHook, CookieProvider, CookieStore, FetchContext, FetchOptions, FetchRequestOptions, GetMeResponse, Plugin, Session, SignOutRequest, SignOutResponse, User, Verification, VerificationType, accountSchema, createClient, sessionSchema, userSchema, verificationSchema, verificationTypeSchema };
@@ -0,0 +1,2 @@
1
+ import { C as AfterFetchHook, E as FetchRequestOptions, S as verificationTypeSchema, T as FetchContext, _ as VerificationType, a as SignOutResponse, b as userSchema, c as FetchOptions, d as CookieProvider, f as CookieStore, g as Verification, h as User, i as SignOutRequest, l as Plugin, m as Session, n as createClient, o as AuthulaClientConfig, p as Account, r as GetMeResponse, s as AuthulaClientOptions, u as AuthulaClient, v as accountSchema, w as BeforeFetchHook, x as verificationSchema, y as sessionSchema } from "./sdk-BWoai6MP.js";
2
+ export { Account, AfterFetchHook, AuthulaClient, AuthulaClientConfig, AuthulaClientOptions, BeforeFetchHook, CookieProvider, CookieStore, FetchContext, FetchOptions, FetchRequestOptions, GetMeResponse, Plugin, Session, SignOutRequest, SignOutResponse, User, Verification, VerificationType, accountSchema, createClient, sessionSchema, userSchema, verificationSchema, verificationTypeSchema };
package/dist/index.js ADDED
@@ -0,0 +1,53 @@
1
+ import { a as verificationSchema, i as userSchema, n as accountSchema, o as verificationTypeSchema, r as sessionSchema, t as wrappedFetch } from "./fetch-B4O1awi2.js";
2
+ import { toSnakeCaseKeys } from "es-toolkit";
3
+
4
+ //#region src/client.ts
5
+ var AuthulaClient = class {
6
+ config;
7
+ plugins;
8
+ beforeFetchHooks = [];
9
+ afterFetchHooks = [];
10
+ constructor(options) {
11
+ this.plugins = options.plugins;
12
+ const { plugins, ...rest } = options;
13
+ this.config = rest;
14
+ for (const plugin of this.plugins) {
15
+ if ("attachCookies" in plugin && this.config.cookies) plugin.attachCookies(this.config.cookies);
16
+ this[plugin.id] = plugin.init(this);
17
+ }
18
+ }
19
+ registerBeforeFetch(hook) {
20
+ this.beforeFetchHooks.push(hook);
21
+ }
22
+ registerAfterFetch(hook) {
23
+ this.afterFetchHooks.push(hook);
24
+ }
25
+ async runBeforeFetch(ctx) {
26
+ for (const hook of this.beforeFetchHooks) await hook(ctx);
27
+ }
28
+ async runAfterFetch(ctx, res) {
29
+ for (const hook of this.afterFetchHooks) if (await hook(ctx, res) === "retry") return "retry";
30
+ }
31
+ async getMe() {
32
+ return wrappedFetch(this, "/me", { method: "GET" });
33
+ }
34
+ async signOut(data) {
35
+ return wrappedFetch(this, "/sign-out", {
36
+ method: "POST",
37
+ body: toSnakeCaseKeys(data)
38
+ });
39
+ }
40
+ getPlugin(id) {
41
+ return this.plugins.find((plugin) => plugin.id === id);
42
+ }
43
+ };
44
+
45
+ //#endregion
46
+ //#region src/sdk.ts
47
+ function createClient(options) {
48
+ return new AuthulaClient(options);
49
+ }
50
+
51
+ //#endregion
52
+ export { AuthulaClient, accountSchema, createClient, sessionSchema, userSchema, verificationSchema, verificationTypeSchema };
53
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/client.ts","../src/sdk.ts"],"sourcesContent":["import { toSnakeCaseKeys } from \"es-toolkit\";\n\nimport { wrappedFetch } from \"./fetch\";\nimport type {\n FetchContext,\n AuthulaClientConfig,\n AuthulaClientOptions,\n SignOutRequest,\n SignOutResponse,\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 if (\"attachCookies\" in plugin && this.config.cookies) {\n (plugin as any).attachCookies(this.config.cookies);\n }\n (this as any)[plugin.id] = plugin.init(this);\n }\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 async getMe<T = unknown>(): Promise<T> {\n return wrappedFetch<T>(this, \"/me\", {\n method: \"GET\",\n });\n }\n\n public async signOut(data: SignOutRequest): Promise<SignOutResponse> {\n return wrappedFetch<SignOutResponse>(this, \"/sign-out\", {\n method: \"POST\",\n body: toSnakeCaseKeys(data),\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","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 }\n ? M\n : 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":";;;;AAcA,IAAa,gBAAb,MAA2B;CACzB,AAAgB;CAChB,AAAiB;CACjB,AAAiB,mBAAsC,EAAE;CACzD,AAAiB,kBAAoC,EAAE;CAEvD,YAAY,SAA+B;AACzC,OAAK,UAAU,QAAQ;EAEvB,MAAM,EAAE,SAAS,GAAG,SAAS;AAC7B,OAAK,SAAS;AAEd,OAAK,MAAM,UAAU,KAAK,SAAS;AACjC,OAAI,mBAAmB,UAAU,KAAK,OAAO,QAC3C,CAAC,OAAe,cAAc,KAAK,OAAO,QAAQ;AAEpD,GAAC,KAAa,OAAO,MAAM,OAAO,KAAK,KAAK;;;CAIhD,AAAO,oBAAoB,MAA6B;AACtD,OAAK,iBAAiB,KAAK,KAAK;;CAGlC,AAAO,mBAAmB,MAA4B;AACpD,OAAK,gBAAgB,KAAK,KAAK;;CAGjC,MAAa,eAAe,KAAkC;AAC5D,OAAK,MAAM,QAAQ,KAAK,iBACtB,OAAM,KAAK,IAAI;;CAInB,MAAa,cAAc,KAAmB,KAAe;AAC3D,OAAK,MAAM,QAAQ,KAAK,gBAEtB,KADe,MAAM,KAAK,KAAK,IAAI,KACpB,QACb,QAAO;;CAKb,MAAa,QAAiC;AAC5C,SAAO,aAAgB,MAAM,OAAO,EAClC,QAAQ,OACT,CAAC;;CAGJ,MAAa,QAAQ,MAAgD;AACnE,SAAO,aAA8B,MAAM,aAAa;GACtD,QAAQ;GACR,MAAM,gBAAgB,KAAK;GAC5B,CAAC;;CAGJ,AAAO,UAA4B,IAA2B;AAC5D,SAAO,KAAK,QAAQ,MAAM,WAAW,OAAO,OAAO,GAAG;;;;;;AC3D1D,SAAgB,aACd,SACsB;AACtB,QAAO,IAAI,cAAc,QAAe"}