auth101 0.1.1 → 0.1.2
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.
- package/package.json +1 -1
- package/dist/index.cjs +0 -176
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -121
- package/dist/index.d.ts +0 -121
- package/dist/index.js +0 -173
- package/dist/index.js.map +0 -1
package/package.json
CHANGED
package/dist/index.cjs
DELETED
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
// src/storage.ts
|
|
4
|
-
var MemoryStorage = class {
|
|
5
|
-
constructor() {
|
|
6
|
-
this._map = /* @__PURE__ */ new Map();
|
|
7
|
-
}
|
|
8
|
-
getItem(key) {
|
|
9
|
-
return this._map.get(key) ?? null;
|
|
10
|
-
}
|
|
11
|
-
setItem(key, value) {
|
|
12
|
-
this._map.set(key, value);
|
|
13
|
-
}
|
|
14
|
-
removeItem(key) {
|
|
15
|
-
this._map.delete(key);
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
function resolveStorage(storage) {
|
|
19
|
-
if (storage === null) {
|
|
20
|
-
return new MemoryStorage();
|
|
21
|
-
}
|
|
22
|
-
if (storage !== void 0) {
|
|
23
|
-
return storage;
|
|
24
|
-
}
|
|
25
|
-
if (typeof window !== "undefined" && window.localStorage) {
|
|
26
|
-
return window.localStorage;
|
|
27
|
-
}
|
|
28
|
-
return new MemoryStorage();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// src/client.ts
|
|
32
|
-
var DEFAULT_STORAGE_KEY = "auth101_token";
|
|
33
|
-
var Auth101Client = class {
|
|
34
|
-
constructor(options) {
|
|
35
|
-
if (!options.baseURL) {
|
|
36
|
-
throw new Error("[auth101] baseURL is required");
|
|
37
|
-
}
|
|
38
|
-
this._baseURL = options.baseURL.replace(/\/$/, "");
|
|
39
|
-
this._storage = resolveStorage(options.storage);
|
|
40
|
-
this._storageKey = options.storageKey ?? DEFAULT_STORAGE_KEY;
|
|
41
|
-
this._fetchOptions = options.fetchOptions ?? {};
|
|
42
|
-
}
|
|
43
|
-
// ── Token management ────────────────────────────────────────────────────────
|
|
44
|
-
/** Returns the stored JWT, or `null` if the user is not signed in. */
|
|
45
|
-
getToken() {
|
|
46
|
-
return this._storage.getItem(this._storageKey);
|
|
47
|
-
}
|
|
48
|
-
/** Manually store a token (e.g. after server-side sign-in). */
|
|
49
|
-
setToken(token) {
|
|
50
|
-
this._storage.setItem(this._storageKey, token);
|
|
51
|
-
}
|
|
52
|
-
/** Remove the stored token. */
|
|
53
|
-
clearToken() {
|
|
54
|
-
this._storage.removeItem(this._storageKey);
|
|
55
|
-
}
|
|
56
|
-
// ── Auth methods ────────────────────────────────────────────────────────────
|
|
57
|
-
/**
|
|
58
|
-
* Register a new user with email and password.
|
|
59
|
-
*
|
|
60
|
-
* On success the token is persisted automatically.
|
|
61
|
-
* Returns `{ data: { user, token }, error: null }` or `{ data: null, error }`.
|
|
62
|
-
*/
|
|
63
|
-
async signUp(input) {
|
|
64
|
-
const result = await this._post("/sign-up/email", input);
|
|
65
|
-
if (result.data?.token) {
|
|
66
|
-
this.setToken(result.data.token);
|
|
67
|
-
}
|
|
68
|
-
return result;
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Sign in with email and password.
|
|
72
|
-
*
|
|
73
|
-
* On success the token is persisted automatically.
|
|
74
|
-
* Returns `{ data: { user, token }, error: null }` or `{ data: null, error }`.
|
|
75
|
-
*/
|
|
76
|
-
async signIn(input) {
|
|
77
|
-
const result = await this._post("/sign-in/email", input);
|
|
78
|
-
if (result.data?.token) {
|
|
79
|
-
this.setToken(result.data.token);
|
|
80
|
-
}
|
|
81
|
-
return result;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Sign out the current user.
|
|
85
|
-
*
|
|
86
|
-
* The token is always cleared from storage regardless of the backend response.
|
|
87
|
-
* Returns `{ data: { success: true }, error: null }` or `{ data: null, error }`.
|
|
88
|
-
*/
|
|
89
|
-
async signOut() {
|
|
90
|
-
const token = this.getToken();
|
|
91
|
-
if (!token) {
|
|
92
|
-
this.clearToken();
|
|
93
|
-
return { data: { success: true }, error: null };
|
|
94
|
-
}
|
|
95
|
-
const result = await this._post("/sign-out", void 0, token);
|
|
96
|
-
this.clearToken();
|
|
97
|
-
return result;
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Fetch the currently authenticated user from the backend.
|
|
101
|
-
*
|
|
102
|
-
* Returns `{ data: { user }, error: null }` or `{ data: null, error }`.
|
|
103
|
-
*/
|
|
104
|
-
async getSession() {
|
|
105
|
-
const token = this.getToken();
|
|
106
|
-
if (!token) {
|
|
107
|
-
return {
|
|
108
|
-
data: null,
|
|
109
|
-
error: { message: "Not signed in", code: "UNAUTHORIZED" }
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
return this._get("/session", token);
|
|
113
|
-
}
|
|
114
|
-
// ── Internal HTTP helpers ───────────────────────────────────────────────────
|
|
115
|
-
async _post(path, body, token) {
|
|
116
|
-
return this._request("POST", path, body, token);
|
|
117
|
-
}
|
|
118
|
-
async _get(path, token) {
|
|
119
|
-
return this._request("GET", path, void 0, token);
|
|
120
|
-
}
|
|
121
|
-
async _request(method, path, body, token) {
|
|
122
|
-
const headers = {
|
|
123
|
-
"Content-Type": "application/json",
|
|
124
|
-
...this._fetchOptions.headers
|
|
125
|
-
};
|
|
126
|
-
if (token) {
|
|
127
|
-
headers["Authorization"] = `Bearer ${token}`;
|
|
128
|
-
}
|
|
129
|
-
const init = {
|
|
130
|
-
...this._fetchOptions,
|
|
131
|
-
method,
|
|
132
|
-
headers,
|
|
133
|
-
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
134
|
-
};
|
|
135
|
-
let response;
|
|
136
|
-
try {
|
|
137
|
-
response = await fetch(`${this._baseURL}${path}`, init);
|
|
138
|
-
} catch (cause) {
|
|
139
|
-
return {
|
|
140
|
-
data: null,
|
|
141
|
-
error: {
|
|
142
|
-
message: "Network error \u2014 could not reach the server",
|
|
143
|
-
code: "NETWORK_ERROR"
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
let json;
|
|
148
|
-
try {
|
|
149
|
-
json = await response.json();
|
|
150
|
-
} catch {
|
|
151
|
-
return {
|
|
152
|
-
data: null,
|
|
153
|
-
error: {
|
|
154
|
-
message: `Unexpected response from server (status ${response.status})`,
|
|
155
|
-
code: "PARSE_ERROR"
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
if (!response.ok || isBackendError(json)) {
|
|
160
|
-
const err = isBackendError(json) ? json.error : { message: `Request failed with status ${response.status}`, code: "HTTP_ERROR" };
|
|
161
|
-
return { data: null, error: err };
|
|
162
|
-
}
|
|
163
|
-
return { data: json, error: null };
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
function isBackendError(json) {
|
|
167
|
-
return typeof json === "object" && json !== null && "error" in json && typeof json.error === "object";
|
|
168
|
-
}
|
|
169
|
-
function createAuth101Client(options) {
|
|
170
|
-
return new Auth101Client(options);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
exports.Auth101Client = Auth101Client;
|
|
174
|
-
exports.createAuth101Client = createAuth101Client;
|
|
175
|
-
//# sourceMappingURL=index.cjs.map
|
|
176
|
-
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/storage.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.cjs","sourcesContent":["import type { StorageLike } from \"./types\"\r\n\r\n/**\r\n * In-memory fallback used when localStorage is unavailable (SSR, Node, tests).\r\n * Token is lost when the instance is garbage-collected.\r\n */\r\nclass MemoryStorage implements StorageLike {\r\n private readonly _map = new Map<string, string>()\r\n\r\n getItem(key: string): string | null {\r\n return this._map.get(key) ?? null\r\n }\r\n\r\n setItem(key: string, value: string): void {\r\n this._map.set(key, value)\r\n }\r\n\r\n removeItem(key: string): void {\r\n this._map.delete(key)\r\n }\r\n}\r\n\r\n/**\r\n * Resolve a storage backend in priority order:\r\n *\r\n * 1. Explicit `null` → no persistence, always return `MemoryStorage`\r\n * 2. Explicit object → use as-is (duck-typed StorageLike)\r\n * 3. `undefined` → try `localStorage`, fall back to `MemoryStorage`\r\n */\r\nexport function resolveStorage(storage: StorageLike | null | undefined): StorageLike {\r\n if (storage === null) {\r\n return new MemoryStorage()\r\n }\r\n\r\n if (storage !== undefined) {\r\n return storage\r\n }\r\n\r\n if (typeof window !== \"undefined\" && window.localStorage) {\r\n return window.localStorage\r\n }\r\n\r\n return new MemoryStorage()\r\n}\r\n","import { resolveStorage } from \"./storage\"\r\nimport type {\r\n Auth101ClientOptions,\r\n AuthResult,\r\n BackendError,\r\n SessionResponse,\r\n SignInInput,\r\n SignInResponse,\r\n SignOutResponse,\r\n SignUpInput,\r\n SignUpResponse,\r\n StorageLike,\r\n} from \"./types\"\r\n\r\nconst DEFAULT_STORAGE_KEY = \"auth101_token\"\r\n\r\nexport class Auth101Client {\r\n private readonly _baseURL: string\r\n private readonly _storage: StorageLike\r\n private readonly _storageKey: string\r\n private readonly _fetchOptions: RequestInit\r\n\r\n constructor(options: Auth101ClientOptions) {\r\n if (!options.baseURL) {\r\n throw new Error(\"[auth101] baseURL is required\")\r\n }\r\n\r\n this._baseURL = options.baseURL.replace(/\\/$/, \"\")\r\n this._storage = resolveStorage(options.storage)\r\n this._storageKey = options.storageKey ?? DEFAULT_STORAGE_KEY\r\n this._fetchOptions = options.fetchOptions ?? {}\r\n }\r\n\r\n // ── Token management ────────────────────────────────────────────────────────\r\n\r\n /** Returns the stored JWT, or `null` if the user is not signed in. */\r\n getToken(): string | null {\r\n return this._storage.getItem(this._storageKey)\r\n }\r\n\r\n /** Manually store a token (e.g. after server-side sign-in). */\r\n setToken(token: string): void {\r\n this._storage.setItem(this._storageKey, token)\r\n }\r\n\r\n /** Remove the stored token. */\r\n clearToken(): void {\r\n this._storage.removeItem(this._storageKey)\r\n }\r\n\r\n // ── Auth methods ────────────────────────────────────────────────────────────\r\n\r\n /**\r\n * Register a new user with email and password.\r\n *\r\n * On success the token is persisted automatically.\r\n * Returns `{ data: { user, token }, error: null }` or `{ data: null, error }`.\r\n */\r\n async signUp(input: SignUpInput): Promise<AuthResult<SignUpResponse>> {\r\n const result = await this._post<SignUpResponse>(\"/sign-up/email\", input)\r\n\r\n if (result.data?.token) {\r\n this.setToken(result.data.token)\r\n }\r\n\r\n return result\r\n }\r\n\r\n /**\r\n * Sign in with email and password.\r\n *\r\n * On success the token is persisted automatically.\r\n * Returns `{ data: { user, token }, error: null }` or `{ data: null, error }`.\r\n */\r\n async signIn(input: SignInInput): Promise<AuthResult<SignInResponse>> {\r\n const result = await this._post<SignInResponse>(\"/sign-in/email\", input)\r\n\r\n if (result.data?.token) {\r\n this.setToken(result.data.token)\r\n }\r\n\r\n return result\r\n }\r\n\r\n /**\r\n * Sign out the current user.\r\n *\r\n * The token is always cleared from storage regardless of the backend response.\r\n * Returns `{ data: { success: true }, error: null }` or `{ data: null, error }`.\r\n */\r\n async signOut(): Promise<AuthResult<SignOutResponse>> {\r\n const token = this.getToken()\r\n\r\n if (!token) {\r\n this.clearToken()\r\n return { data: { success: true }, error: null }\r\n }\r\n\r\n const result = await this._post<SignOutResponse>(\"/sign-out\", undefined, token)\r\n this.clearToken()\r\n return result\r\n }\r\n\r\n /**\r\n * Fetch the currently authenticated user from the backend.\r\n *\r\n * Returns `{ data: { user }, error: null }` or `{ data: null, error }`.\r\n */\r\n async getSession(): Promise<AuthResult<SessionResponse>> {\r\n const token = this.getToken()\r\n\r\n if (!token) {\r\n return {\r\n data: null,\r\n error: { message: \"Not signed in\", code: \"UNAUTHORIZED\" },\r\n }\r\n }\r\n\r\n return this._get<SessionResponse>(\"/session\", token)\r\n }\r\n\r\n // ── Internal HTTP helpers ───────────────────────────────────────────────────\r\n\r\n private async _post<T>(\r\n path: string,\r\n body: object | undefined,\r\n token?: string,\r\n ): Promise<AuthResult<T>> {\r\n return this._request<T>(\"POST\", path, body, token)\r\n }\r\n\r\n private async _get<T>(path: string, token?: string): Promise<AuthResult<T>> {\r\n return this._request<T>(\"GET\", path, undefined, token)\r\n }\r\n\r\n private async _request<T>(\r\n method: string,\r\n path: string,\r\n body: object | undefined,\r\n token?: string,\r\n ): Promise<AuthResult<T>> {\r\n const headers: Record<string, string> = {\r\n \"Content-Type\": \"application/json\",\r\n ...(this._fetchOptions.headers as Record<string, string> | undefined),\r\n }\r\n\r\n if (token) {\r\n headers[\"Authorization\"] = `Bearer ${token}`\r\n }\r\n\r\n const init: RequestInit = {\r\n ...this._fetchOptions,\r\n method,\r\n headers,\r\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\r\n }\r\n\r\n let response: Response\r\n\r\n try {\r\n response = await fetch(`${this._baseURL}${path}`, init)\r\n } catch (cause) {\r\n return {\r\n data: null,\r\n error: {\r\n message: \"Network error — could not reach the server\",\r\n code: \"NETWORK_ERROR\",\r\n },\r\n }\r\n }\r\n\r\n let json: unknown\r\n\r\n try {\r\n json = await response.json()\r\n } catch {\r\n return {\r\n data: null,\r\n error: {\r\n message: `Unexpected response from server (status ${response.status})`,\r\n code: \"PARSE_ERROR\",\r\n },\r\n }\r\n }\r\n\r\n if (!response.ok || isBackendError(json)) {\r\n const err = isBackendError(json)\r\n ? (json as { error: BackendError }).error\r\n : { message: `Request failed with status ${response.status}`, code: \"HTTP_ERROR\" }\r\n\r\n return { data: null, error: err }\r\n }\r\n\r\n return { data: json as T, error: null }\r\n }\r\n}\r\n\r\nfunction isBackendError(json: unknown): boolean {\r\n return (\r\n typeof json === \"object\" &&\r\n json !== null &&\r\n \"error\" in json &&\r\n typeof (json as { error: unknown }).error === \"object\"\r\n )\r\n}\r\n\r\n// ── Factory ───────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Create an `Auth101Client` instance.\r\n *\r\n * @example\r\n * ```ts\r\n * const auth = createAuth101Client({ baseURL: \"http://localhost:8000/auth\" })\r\n *\r\n * const { data, error } = await auth.signIn({ email, password })\r\n * if (data) console.log(data.user)\r\n * ```\r\n */\r\nexport function createAuth101Client(options: Auth101ClientOptions): Auth101Client {\r\n return new Auth101Client(options)\r\n}\r\n"]}
|
package/dist/index.d.cts
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
interface User {
|
|
2
|
-
id: string;
|
|
3
|
-
email: string;
|
|
4
|
-
is_active: boolean;
|
|
5
|
-
}
|
|
6
|
-
interface SignUpInput {
|
|
7
|
-
email: string;
|
|
8
|
-
password: string;
|
|
9
|
-
}
|
|
10
|
-
interface SignInInput {
|
|
11
|
-
email: string;
|
|
12
|
-
password: string;
|
|
13
|
-
}
|
|
14
|
-
interface SignUpResponse {
|
|
15
|
-
user: User;
|
|
16
|
-
token: string;
|
|
17
|
-
}
|
|
18
|
-
interface SignInResponse {
|
|
19
|
-
user: User;
|
|
20
|
-
token: string;
|
|
21
|
-
}
|
|
22
|
-
interface SignOutResponse {
|
|
23
|
-
success: boolean;
|
|
24
|
-
}
|
|
25
|
-
interface SessionResponse {
|
|
26
|
-
user: User;
|
|
27
|
-
}
|
|
28
|
-
interface BackendError {
|
|
29
|
-
message: string;
|
|
30
|
-
code: string;
|
|
31
|
-
}
|
|
32
|
-
interface AuthResult<T> {
|
|
33
|
-
data: T | null;
|
|
34
|
-
error: BackendError | null;
|
|
35
|
-
}
|
|
36
|
-
interface StorageLike {
|
|
37
|
-
getItem(key: string): string | null;
|
|
38
|
-
setItem(key: string, value: string): void;
|
|
39
|
-
removeItem(key: string): void;
|
|
40
|
-
}
|
|
41
|
-
interface Auth101ClientOptions {
|
|
42
|
-
/**
|
|
43
|
-
* Base URL where auth101 is mounted on your backend, e.g.
|
|
44
|
-
* `"http://localhost:8000/auth"` — no trailing slash.
|
|
45
|
-
*/
|
|
46
|
-
baseURL: string;
|
|
47
|
-
/**
|
|
48
|
-
* Custom storage implementation for persisting the token.
|
|
49
|
-
* Defaults to `localStorage` in browser environments.
|
|
50
|
-
* Pass `null` to keep the token in memory only (useful for SSR or testing).
|
|
51
|
-
*/
|
|
52
|
-
storage?: StorageLike | null;
|
|
53
|
-
/**
|
|
54
|
-
* Key used to store the token in the provided storage.
|
|
55
|
-
* Defaults to `"auth101_token"`.
|
|
56
|
-
*/
|
|
57
|
-
storageKey?: string;
|
|
58
|
-
/**
|
|
59
|
-
* Default `RequestInit` options merged into every `fetch` call.
|
|
60
|
-
* Useful for setting custom headers, credentials mode, etc.
|
|
61
|
-
*/
|
|
62
|
-
fetchOptions?: RequestInit;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
declare class Auth101Client {
|
|
66
|
-
private readonly _baseURL;
|
|
67
|
-
private readonly _storage;
|
|
68
|
-
private readonly _storageKey;
|
|
69
|
-
private readonly _fetchOptions;
|
|
70
|
-
constructor(options: Auth101ClientOptions);
|
|
71
|
-
/** Returns the stored JWT, or `null` if the user is not signed in. */
|
|
72
|
-
getToken(): string | null;
|
|
73
|
-
/** Manually store a token (e.g. after server-side sign-in). */
|
|
74
|
-
setToken(token: string): void;
|
|
75
|
-
/** Remove the stored token. */
|
|
76
|
-
clearToken(): void;
|
|
77
|
-
/**
|
|
78
|
-
* Register a new user with email and password.
|
|
79
|
-
*
|
|
80
|
-
* On success the token is persisted automatically.
|
|
81
|
-
* Returns `{ data: { user, token }, error: null }` or `{ data: null, error }`.
|
|
82
|
-
*/
|
|
83
|
-
signUp(input: SignUpInput): Promise<AuthResult<SignUpResponse>>;
|
|
84
|
-
/**
|
|
85
|
-
* Sign in with email and password.
|
|
86
|
-
*
|
|
87
|
-
* On success the token is persisted automatically.
|
|
88
|
-
* Returns `{ data: { user, token }, error: null }` or `{ data: null, error }`.
|
|
89
|
-
*/
|
|
90
|
-
signIn(input: SignInInput): Promise<AuthResult<SignInResponse>>;
|
|
91
|
-
/**
|
|
92
|
-
* Sign out the current user.
|
|
93
|
-
*
|
|
94
|
-
* The token is always cleared from storage regardless of the backend response.
|
|
95
|
-
* Returns `{ data: { success: true }, error: null }` or `{ data: null, error }`.
|
|
96
|
-
*/
|
|
97
|
-
signOut(): Promise<AuthResult<SignOutResponse>>;
|
|
98
|
-
/**
|
|
99
|
-
* Fetch the currently authenticated user from the backend.
|
|
100
|
-
*
|
|
101
|
-
* Returns `{ data: { user }, error: null }` or `{ data: null, error }`.
|
|
102
|
-
*/
|
|
103
|
-
getSession(): Promise<AuthResult<SessionResponse>>;
|
|
104
|
-
private _post;
|
|
105
|
-
private _get;
|
|
106
|
-
private _request;
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Create an `Auth101Client` instance.
|
|
110
|
-
*
|
|
111
|
-
* @example
|
|
112
|
-
* ```ts
|
|
113
|
-
* const auth = createAuth101Client({ baseURL: "http://localhost:8000/auth" })
|
|
114
|
-
*
|
|
115
|
-
* const { data, error } = await auth.signIn({ email, password })
|
|
116
|
-
* if (data) console.log(data.user)
|
|
117
|
-
* ```
|
|
118
|
-
*/
|
|
119
|
-
declare function createAuth101Client(options: Auth101ClientOptions): Auth101Client;
|
|
120
|
-
|
|
121
|
-
export { Auth101Client, type Auth101ClientOptions, type AuthResult, type BackendError, type SessionResponse, type SignInInput, type SignInResponse, type SignOutResponse, type SignUpInput, type SignUpResponse, type StorageLike, type User, createAuth101Client };
|
package/dist/index.d.ts
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
interface User {
|
|
2
|
-
id: string;
|
|
3
|
-
email: string;
|
|
4
|
-
is_active: boolean;
|
|
5
|
-
}
|
|
6
|
-
interface SignUpInput {
|
|
7
|
-
email: string;
|
|
8
|
-
password: string;
|
|
9
|
-
}
|
|
10
|
-
interface SignInInput {
|
|
11
|
-
email: string;
|
|
12
|
-
password: string;
|
|
13
|
-
}
|
|
14
|
-
interface SignUpResponse {
|
|
15
|
-
user: User;
|
|
16
|
-
token: string;
|
|
17
|
-
}
|
|
18
|
-
interface SignInResponse {
|
|
19
|
-
user: User;
|
|
20
|
-
token: string;
|
|
21
|
-
}
|
|
22
|
-
interface SignOutResponse {
|
|
23
|
-
success: boolean;
|
|
24
|
-
}
|
|
25
|
-
interface SessionResponse {
|
|
26
|
-
user: User;
|
|
27
|
-
}
|
|
28
|
-
interface BackendError {
|
|
29
|
-
message: string;
|
|
30
|
-
code: string;
|
|
31
|
-
}
|
|
32
|
-
interface AuthResult<T> {
|
|
33
|
-
data: T | null;
|
|
34
|
-
error: BackendError | null;
|
|
35
|
-
}
|
|
36
|
-
interface StorageLike {
|
|
37
|
-
getItem(key: string): string | null;
|
|
38
|
-
setItem(key: string, value: string): void;
|
|
39
|
-
removeItem(key: string): void;
|
|
40
|
-
}
|
|
41
|
-
interface Auth101ClientOptions {
|
|
42
|
-
/**
|
|
43
|
-
* Base URL where auth101 is mounted on your backend, e.g.
|
|
44
|
-
* `"http://localhost:8000/auth"` — no trailing slash.
|
|
45
|
-
*/
|
|
46
|
-
baseURL: string;
|
|
47
|
-
/**
|
|
48
|
-
* Custom storage implementation for persisting the token.
|
|
49
|
-
* Defaults to `localStorage` in browser environments.
|
|
50
|
-
* Pass `null` to keep the token in memory only (useful for SSR or testing).
|
|
51
|
-
*/
|
|
52
|
-
storage?: StorageLike | null;
|
|
53
|
-
/**
|
|
54
|
-
* Key used to store the token in the provided storage.
|
|
55
|
-
* Defaults to `"auth101_token"`.
|
|
56
|
-
*/
|
|
57
|
-
storageKey?: string;
|
|
58
|
-
/**
|
|
59
|
-
* Default `RequestInit` options merged into every `fetch` call.
|
|
60
|
-
* Useful for setting custom headers, credentials mode, etc.
|
|
61
|
-
*/
|
|
62
|
-
fetchOptions?: RequestInit;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
declare class Auth101Client {
|
|
66
|
-
private readonly _baseURL;
|
|
67
|
-
private readonly _storage;
|
|
68
|
-
private readonly _storageKey;
|
|
69
|
-
private readonly _fetchOptions;
|
|
70
|
-
constructor(options: Auth101ClientOptions);
|
|
71
|
-
/** Returns the stored JWT, or `null` if the user is not signed in. */
|
|
72
|
-
getToken(): string | null;
|
|
73
|
-
/** Manually store a token (e.g. after server-side sign-in). */
|
|
74
|
-
setToken(token: string): void;
|
|
75
|
-
/** Remove the stored token. */
|
|
76
|
-
clearToken(): void;
|
|
77
|
-
/**
|
|
78
|
-
* Register a new user with email and password.
|
|
79
|
-
*
|
|
80
|
-
* On success the token is persisted automatically.
|
|
81
|
-
* Returns `{ data: { user, token }, error: null }` or `{ data: null, error }`.
|
|
82
|
-
*/
|
|
83
|
-
signUp(input: SignUpInput): Promise<AuthResult<SignUpResponse>>;
|
|
84
|
-
/**
|
|
85
|
-
* Sign in with email and password.
|
|
86
|
-
*
|
|
87
|
-
* On success the token is persisted automatically.
|
|
88
|
-
* Returns `{ data: { user, token }, error: null }` or `{ data: null, error }`.
|
|
89
|
-
*/
|
|
90
|
-
signIn(input: SignInInput): Promise<AuthResult<SignInResponse>>;
|
|
91
|
-
/**
|
|
92
|
-
* Sign out the current user.
|
|
93
|
-
*
|
|
94
|
-
* The token is always cleared from storage regardless of the backend response.
|
|
95
|
-
* Returns `{ data: { success: true }, error: null }` or `{ data: null, error }`.
|
|
96
|
-
*/
|
|
97
|
-
signOut(): Promise<AuthResult<SignOutResponse>>;
|
|
98
|
-
/**
|
|
99
|
-
* Fetch the currently authenticated user from the backend.
|
|
100
|
-
*
|
|
101
|
-
* Returns `{ data: { user }, error: null }` or `{ data: null, error }`.
|
|
102
|
-
*/
|
|
103
|
-
getSession(): Promise<AuthResult<SessionResponse>>;
|
|
104
|
-
private _post;
|
|
105
|
-
private _get;
|
|
106
|
-
private _request;
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Create an `Auth101Client` instance.
|
|
110
|
-
*
|
|
111
|
-
* @example
|
|
112
|
-
* ```ts
|
|
113
|
-
* const auth = createAuth101Client({ baseURL: "http://localhost:8000/auth" })
|
|
114
|
-
*
|
|
115
|
-
* const { data, error } = await auth.signIn({ email, password })
|
|
116
|
-
* if (data) console.log(data.user)
|
|
117
|
-
* ```
|
|
118
|
-
*/
|
|
119
|
-
declare function createAuth101Client(options: Auth101ClientOptions): Auth101Client;
|
|
120
|
-
|
|
121
|
-
export { Auth101Client, type Auth101ClientOptions, type AuthResult, type BackendError, type SessionResponse, type SignInInput, type SignInResponse, type SignOutResponse, type SignUpInput, type SignUpResponse, type StorageLike, type User, createAuth101Client };
|
package/dist/index.js
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
// src/storage.ts
|
|
2
|
-
var MemoryStorage = class {
|
|
3
|
-
constructor() {
|
|
4
|
-
this._map = /* @__PURE__ */ new Map();
|
|
5
|
-
}
|
|
6
|
-
getItem(key) {
|
|
7
|
-
return this._map.get(key) ?? null;
|
|
8
|
-
}
|
|
9
|
-
setItem(key, value) {
|
|
10
|
-
this._map.set(key, value);
|
|
11
|
-
}
|
|
12
|
-
removeItem(key) {
|
|
13
|
-
this._map.delete(key);
|
|
14
|
-
}
|
|
15
|
-
};
|
|
16
|
-
function resolveStorage(storage) {
|
|
17
|
-
if (storage === null) {
|
|
18
|
-
return new MemoryStorage();
|
|
19
|
-
}
|
|
20
|
-
if (storage !== void 0) {
|
|
21
|
-
return storage;
|
|
22
|
-
}
|
|
23
|
-
if (typeof window !== "undefined" && window.localStorage) {
|
|
24
|
-
return window.localStorage;
|
|
25
|
-
}
|
|
26
|
-
return new MemoryStorage();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// src/client.ts
|
|
30
|
-
var DEFAULT_STORAGE_KEY = "auth101_token";
|
|
31
|
-
var Auth101Client = class {
|
|
32
|
-
constructor(options) {
|
|
33
|
-
if (!options.baseURL) {
|
|
34
|
-
throw new Error("[auth101] baseURL is required");
|
|
35
|
-
}
|
|
36
|
-
this._baseURL = options.baseURL.replace(/\/$/, "");
|
|
37
|
-
this._storage = resolveStorage(options.storage);
|
|
38
|
-
this._storageKey = options.storageKey ?? DEFAULT_STORAGE_KEY;
|
|
39
|
-
this._fetchOptions = options.fetchOptions ?? {};
|
|
40
|
-
}
|
|
41
|
-
// ── Token management ────────────────────────────────────────────────────────
|
|
42
|
-
/** Returns the stored JWT, or `null` if the user is not signed in. */
|
|
43
|
-
getToken() {
|
|
44
|
-
return this._storage.getItem(this._storageKey);
|
|
45
|
-
}
|
|
46
|
-
/** Manually store a token (e.g. after server-side sign-in). */
|
|
47
|
-
setToken(token) {
|
|
48
|
-
this._storage.setItem(this._storageKey, token);
|
|
49
|
-
}
|
|
50
|
-
/** Remove the stored token. */
|
|
51
|
-
clearToken() {
|
|
52
|
-
this._storage.removeItem(this._storageKey);
|
|
53
|
-
}
|
|
54
|
-
// ── Auth methods ────────────────────────────────────────────────────────────
|
|
55
|
-
/**
|
|
56
|
-
* Register a new user with email and password.
|
|
57
|
-
*
|
|
58
|
-
* On success the token is persisted automatically.
|
|
59
|
-
* Returns `{ data: { user, token }, error: null }` or `{ data: null, error }`.
|
|
60
|
-
*/
|
|
61
|
-
async signUp(input) {
|
|
62
|
-
const result = await this._post("/sign-up/email", input);
|
|
63
|
-
if (result.data?.token) {
|
|
64
|
-
this.setToken(result.data.token);
|
|
65
|
-
}
|
|
66
|
-
return result;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Sign in with email and password.
|
|
70
|
-
*
|
|
71
|
-
* On success the token is persisted automatically.
|
|
72
|
-
* Returns `{ data: { user, token }, error: null }` or `{ data: null, error }`.
|
|
73
|
-
*/
|
|
74
|
-
async signIn(input) {
|
|
75
|
-
const result = await this._post("/sign-in/email", input);
|
|
76
|
-
if (result.data?.token) {
|
|
77
|
-
this.setToken(result.data.token);
|
|
78
|
-
}
|
|
79
|
-
return result;
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Sign out the current user.
|
|
83
|
-
*
|
|
84
|
-
* The token is always cleared from storage regardless of the backend response.
|
|
85
|
-
* Returns `{ data: { success: true }, error: null }` or `{ data: null, error }`.
|
|
86
|
-
*/
|
|
87
|
-
async signOut() {
|
|
88
|
-
const token = this.getToken();
|
|
89
|
-
if (!token) {
|
|
90
|
-
this.clearToken();
|
|
91
|
-
return { data: { success: true }, error: null };
|
|
92
|
-
}
|
|
93
|
-
const result = await this._post("/sign-out", void 0, token);
|
|
94
|
-
this.clearToken();
|
|
95
|
-
return result;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Fetch the currently authenticated user from the backend.
|
|
99
|
-
*
|
|
100
|
-
* Returns `{ data: { user }, error: null }` or `{ data: null, error }`.
|
|
101
|
-
*/
|
|
102
|
-
async getSession() {
|
|
103
|
-
const token = this.getToken();
|
|
104
|
-
if (!token) {
|
|
105
|
-
return {
|
|
106
|
-
data: null,
|
|
107
|
-
error: { message: "Not signed in", code: "UNAUTHORIZED" }
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
return this._get("/session", token);
|
|
111
|
-
}
|
|
112
|
-
// ── Internal HTTP helpers ───────────────────────────────────────────────────
|
|
113
|
-
async _post(path, body, token) {
|
|
114
|
-
return this._request("POST", path, body, token);
|
|
115
|
-
}
|
|
116
|
-
async _get(path, token) {
|
|
117
|
-
return this._request("GET", path, void 0, token);
|
|
118
|
-
}
|
|
119
|
-
async _request(method, path, body, token) {
|
|
120
|
-
const headers = {
|
|
121
|
-
"Content-Type": "application/json",
|
|
122
|
-
...this._fetchOptions.headers
|
|
123
|
-
};
|
|
124
|
-
if (token) {
|
|
125
|
-
headers["Authorization"] = `Bearer ${token}`;
|
|
126
|
-
}
|
|
127
|
-
const init = {
|
|
128
|
-
...this._fetchOptions,
|
|
129
|
-
method,
|
|
130
|
-
headers,
|
|
131
|
-
...body !== void 0 ? { body: JSON.stringify(body) } : {}
|
|
132
|
-
};
|
|
133
|
-
let response;
|
|
134
|
-
try {
|
|
135
|
-
response = await fetch(`${this._baseURL}${path}`, init);
|
|
136
|
-
} catch (cause) {
|
|
137
|
-
return {
|
|
138
|
-
data: null,
|
|
139
|
-
error: {
|
|
140
|
-
message: "Network error \u2014 could not reach the server",
|
|
141
|
-
code: "NETWORK_ERROR"
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
let json;
|
|
146
|
-
try {
|
|
147
|
-
json = await response.json();
|
|
148
|
-
} catch {
|
|
149
|
-
return {
|
|
150
|
-
data: null,
|
|
151
|
-
error: {
|
|
152
|
-
message: `Unexpected response from server (status ${response.status})`,
|
|
153
|
-
code: "PARSE_ERROR"
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
if (!response.ok || isBackendError(json)) {
|
|
158
|
-
const err = isBackendError(json) ? json.error : { message: `Request failed with status ${response.status}`, code: "HTTP_ERROR" };
|
|
159
|
-
return { data: null, error: err };
|
|
160
|
-
}
|
|
161
|
-
return { data: json, error: null };
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
function isBackendError(json) {
|
|
165
|
-
return typeof json === "object" && json !== null && "error" in json && typeof json.error === "object";
|
|
166
|
-
}
|
|
167
|
-
function createAuth101Client(options) {
|
|
168
|
-
return new Auth101Client(options);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
export { Auth101Client, createAuth101Client };
|
|
172
|
-
//# sourceMappingURL=index.js.map
|
|
173
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/storage.ts","../src/client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type { StorageLike } from \"./types\"\r\n\r\n/**\r\n * In-memory fallback used when localStorage is unavailable (SSR, Node, tests).\r\n * Token is lost when the instance is garbage-collected.\r\n */\r\nclass MemoryStorage implements StorageLike {\r\n private readonly _map = new Map<string, string>()\r\n\r\n getItem(key: string): string | null {\r\n return this._map.get(key) ?? null\r\n }\r\n\r\n setItem(key: string, value: string): void {\r\n this._map.set(key, value)\r\n }\r\n\r\n removeItem(key: string): void {\r\n this._map.delete(key)\r\n }\r\n}\r\n\r\n/**\r\n * Resolve a storage backend in priority order:\r\n *\r\n * 1. Explicit `null` → no persistence, always return `MemoryStorage`\r\n * 2. Explicit object → use as-is (duck-typed StorageLike)\r\n * 3. `undefined` → try `localStorage`, fall back to `MemoryStorage`\r\n */\r\nexport function resolveStorage(storage: StorageLike | null | undefined): StorageLike {\r\n if (storage === null) {\r\n return new MemoryStorage()\r\n }\r\n\r\n if (storage !== undefined) {\r\n return storage\r\n }\r\n\r\n if (typeof window !== \"undefined\" && window.localStorage) {\r\n return window.localStorage\r\n }\r\n\r\n return new MemoryStorage()\r\n}\r\n","import { resolveStorage } from \"./storage\"\r\nimport type {\r\n Auth101ClientOptions,\r\n AuthResult,\r\n BackendError,\r\n SessionResponse,\r\n SignInInput,\r\n SignInResponse,\r\n SignOutResponse,\r\n SignUpInput,\r\n SignUpResponse,\r\n StorageLike,\r\n} from \"./types\"\r\n\r\nconst DEFAULT_STORAGE_KEY = \"auth101_token\"\r\n\r\nexport class Auth101Client {\r\n private readonly _baseURL: string\r\n private readonly _storage: StorageLike\r\n private readonly _storageKey: string\r\n private readonly _fetchOptions: RequestInit\r\n\r\n constructor(options: Auth101ClientOptions) {\r\n if (!options.baseURL) {\r\n throw new Error(\"[auth101] baseURL is required\")\r\n }\r\n\r\n this._baseURL = options.baseURL.replace(/\\/$/, \"\")\r\n this._storage = resolveStorage(options.storage)\r\n this._storageKey = options.storageKey ?? DEFAULT_STORAGE_KEY\r\n this._fetchOptions = options.fetchOptions ?? {}\r\n }\r\n\r\n // ── Token management ────────────────────────────────────────────────────────\r\n\r\n /** Returns the stored JWT, or `null` if the user is not signed in. */\r\n getToken(): string | null {\r\n return this._storage.getItem(this._storageKey)\r\n }\r\n\r\n /** Manually store a token (e.g. after server-side sign-in). */\r\n setToken(token: string): void {\r\n this._storage.setItem(this._storageKey, token)\r\n }\r\n\r\n /** Remove the stored token. */\r\n clearToken(): void {\r\n this._storage.removeItem(this._storageKey)\r\n }\r\n\r\n // ── Auth methods ────────────────────────────────────────────────────────────\r\n\r\n /**\r\n * Register a new user with email and password.\r\n *\r\n * On success the token is persisted automatically.\r\n * Returns `{ data: { user, token }, error: null }` or `{ data: null, error }`.\r\n */\r\n async signUp(input: SignUpInput): Promise<AuthResult<SignUpResponse>> {\r\n const result = await this._post<SignUpResponse>(\"/sign-up/email\", input)\r\n\r\n if (result.data?.token) {\r\n this.setToken(result.data.token)\r\n }\r\n\r\n return result\r\n }\r\n\r\n /**\r\n * Sign in with email and password.\r\n *\r\n * On success the token is persisted automatically.\r\n * Returns `{ data: { user, token }, error: null }` or `{ data: null, error }`.\r\n */\r\n async signIn(input: SignInInput): Promise<AuthResult<SignInResponse>> {\r\n const result = await this._post<SignInResponse>(\"/sign-in/email\", input)\r\n\r\n if (result.data?.token) {\r\n this.setToken(result.data.token)\r\n }\r\n\r\n return result\r\n }\r\n\r\n /**\r\n * Sign out the current user.\r\n *\r\n * The token is always cleared from storage regardless of the backend response.\r\n * Returns `{ data: { success: true }, error: null }` or `{ data: null, error }`.\r\n */\r\n async signOut(): Promise<AuthResult<SignOutResponse>> {\r\n const token = this.getToken()\r\n\r\n if (!token) {\r\n this.clearToken()\r\n return { data: { success: true }, error: null }\r\n }\r\n\r\n const result = await this._post<SignOutResponse>(\"/sign-out\", undefined, token)\r\n this.clearToken()\r\n return result\r\n }\r\n\r\n /**\r\n * Fetch the currently authenticated user from the backend.\r\n *\r\n * Returns `{ data: { user }, error: null }` or `{ data: null, error }`.\r\n */\r\n async getSession(): Promise<AuthResult<SessionResponse>> {\r\n const token = this.getToken()\r\n\r\n if (!token) {\r\n return {\r\n data: null,\r\n error: { message: \"Not signed in\", code: \"UNAUTHORIZED\" },\r\n }\r\n }\r\n\r\n return this._get<SessionResponse>(\"/session\", token)\r\n }\r\n\r\n // ── Internal HTTP helpers ───────────────────────────────────────────────────\r\n\r\n private async _post<T>(\r\n path: string,\r\n body: object | undefined,\r\n token?: string,\r\n ): Promise<AuthResult<T>> {\r\n return this._request<T>(\"POST\", path, body, token)\r\n }\r\n\r\n private async _get<T>(path: string, token?: string): Promise<AuthResult<T>> {\r\n return this._request<T>(\"GET\", path, undefined, token)\r\n }\r\n\r\n private async _request<T>(\r\n method: string,\r\n path: string,\r\n body: object | undefined,\r\n token?: string,\r\n ): Promise<AuthResult<T>> {\r\n const headers: Record<string, string> = {\r\n \"Content-Type\": \"application/json\",\r\n ...(this._fetchOptions.headers as Record<string, string> | undefined),\r\n }\r\n\r\n if (token) {\r\n headers[\"Authorization\"] = `Bearer ${token}`\r\n }\r\n\r\n const init: RequestInit = {\r\n ...this._fetchOptions,\r\n method,\r\n headers,\r\n ...(body !== undefined ? { body: JSON.stringify(body) } : {}),\r\n }\r\n\r\n let response: Response\r\n\r\n try {\r\n response = await fetch(`${this._baseURL}${path}`, init)\r\n } catch (cause) {\r\n return {\r\n data: null,\r\n error: {\r\n message: \"Network error — could not reach the server\",\r\n code: \"NETWORK_ERROR\",\r\n },\r\n }\r\n }\r\n\r\n let json: unknown\r\n\r\n try {\r\n json = await response.json()\r\n } catch {\r\n return {\r\n data: null,\r\n error: {\r\n message: `Unexpected response from server (status ${response.status})`,\r\n code: \"PARSE_ERROR\",\r\n },\r\n }\r\n }\r\n\r\n if (!response.ok || isBackendError(json)) {\r\n const err = isBackendError(json)\r\n ? (json as { error: BackendError }).error\r\n : { message: `Request failed with status ${response.status}`, code: \"HTTP_ERROR\" }\r\n\r\n return { data: null, error: err }\r\n }\r\n\r\n return { data: json as T, error: null }\r\n }\r\n}\r\n\r\nfunction isBackendError(json: unknown): boolean {\r\n return (\r\n typeof json === \"object\" &&\r\n json !== null &&\r\n \"error\" in json &&\r\n typeof (json as { error: unknown }).error === \"object\"\r\n )\r\n}\r\n\r\n// ── Factory ───────────────────────────────────────────────────────────────────\r\n\r\n/**\r\n * Create an `Auth101Client` instance.\r\n *\r\n * @example\r\n * ```ts\r\n * const auth = createAuth101Client({ baseURL: \"http://localhost:8000/auth\" })\r\n *\r\n * const { data, error } = await auth.signIn({ email, password })\r\n * if (data) console.log(data.user)\r\n * ```\r\n */\r\nexport function createAuth101Client(options: Auth101ClientOptions): Auth101Client {\r\n return new Auth101Client(options)\r\n}\r\n"]}
|