@yaotoshi/auth-sdk 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +216 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +38 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +189 -0
- package/dist/index.js.map +1 -0
- package/package.json +28 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
YaotoshiAuth: () => YaotoshiAuth
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(index_exports);
|
|
26
|
+
|
|
27
|
+
// src/pkce.ts
|
|
28
|
+
function generateRandomBytes(length) {
|
|
29
|
+
const array = new Uint8Array(length);
|
|
30
|
+
crypto.getRandomValues(array);
|
|
31
|
+
return array;
|
|
32
|
+
}
|
|
33
|
+
function base64UrlEncode(buffer) {
|
|
34
|
+
const bytes = new Uint8Array(buffer);
|
|
35
|
+
let binary = "";
|
|
36
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
37
|
+
binary += String.fromCharCode(bytes[i]);
|
|
38
|
+
}
|
|
39
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
40
|
+
}
|
|
41
|
+
function generateCodeVerifier() {
|
|
42
|
+
const bytes = generateRandomBytes(32);
|
|
43
|
+
return base64UrlEncode(bytes);
|
|
44
|
+
}
|
|
45
|
+
async function generateCodeChallenge(verifier) {
|
|
46
|
+
const encoder = new TextEncoder();
|
|
47
|
+
const data = encoder.encode(verifier);
|
|
48
|
+
const digest = await crypto.subtle.digest("SHA-256", data);
|
|
49
|
+
return base64UrlEncode(digest);
|
|
50
|
+
}
|
|
51
|
+
function generateState() {
|
|
52
|
+
const bytes = generateRandomBytes(16);
|
|
53
|
+
return base64UrlEncode(bytes);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/storage.ts
|
|
57
|
+
var AuthStorage = class {
|
|
58
|
+
constructor(prefix = "yaotoshi_auth") {
|
|
59
|
+
this.prefix = prefix;
|
|
60
|
+
}
|
|
61
|
+
key(name) {
|
|
62
|
+
return `${this.prefix}_${name}`;
|
|
63
|
+
}
|
|
64
|
+
get(name) {
|
|
65
|
+
try {
|
|
66
|
+
return sessionStorage.getItem(this.key(name));
|
|
67
|
+
} catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
set(name, value) {
|
|
72
|
+
try {
|
|
73
|
+
sessionStorage.setItem(this.key(name), value);
|
|
74
|
+
} catch {
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
remove(name) {
|
|
78
|
+
try {
|
|
79
|
+
sessionStorage.removeItem(this.key(name));
|
|
80
|
+
} catch {
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
getPersistent(name) {
|
|
84
|
+
try {
|
|
85
|
+
return localStorage.getItem(this.key(name));
|
|
86
|
+
} catch {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
setPersistent(name, value) {
|
|
91
|
+
try {
|
|
92
|
+
localStorage.setItem(this.key(name), value);
|
|
93
|
+
} catch {
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
removePersistent(name) {
|
|
97
|
+
try {
|
|
98
|
+
localStorage.removeItem(this.key(name));
|
|
99
|
+
} catch {
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
clearAll() {
|
|
103
|
+
this.remove("code_verifier");
|
|
104
|
+
this.remove("state");
|
|
105
|
+
this.removePersistent("access_token");
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
// src/client.ts
|
|
110
|
+
var YaotoshiAuth = class {
|
|
111
|
+
constructor(config) {
|
|
112
|
+
this.config = {
|
|
113
|
+
scopes: ["openid", "email"],
|
|
114
|
+
postLogoutRedirectUri: void 0,
|
|
115
|
+
storagePrefix: "yaotoshi_auth",
|
|
116
|
+
...config
|
|
117
|
+
};
|
|
118
|
+
this.storage = new AuthStorage(this.config.storagePrefix);
|
|
119
|
+
}
|
|
120
|
+
async login() {
|
|
121
|
+
const codeVerifier = generateCodeVerifier();
|
|
122
|
+
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
123
|
+
const state = generateState();
|
|
124
|
+
this.storage.set("code_verifier", codeVerifier);
|
|
125
|
+
this.storage.set("state", state);
|
|
126
|
+
const params = new URLSearchParams({
|
|
127
|
+
response_type: "code",
|
|
128
|
+
client_id: this.config.clientId,
|
|
129
|
+
redirect_uri: this.config.redirectUri,
|
|
130
|
+
scope: (this.config.scopes ?? ["openid", "email"]).join(" "),
|
|
131
|
+
state,
|
|
132
|
+
code_challenge: codeChallenge,
|
|
133
|
+
code_challenge_method: "S256"
|
|
134
|
+
});
|
|
135
|
+
window.location.href = `${this.config.accountsUrl}/authorize?${params.toString()}`;
|
|
136
|
+
}
|
|
137
|
+
async handleCallback() {
|
|
138
|
+
const params = new URLSearchParams(window.location.search);
|
|
139
|
+
const code = params.get("code");
|
|
140
|
+
const state = params.get("state");
|
|
141
|
+
const error = params.get("error");
|
|
142
|
+
if (error) {
|
|
143
|
+
throw new Error(`Authorization error: ${error}`);
|
|
144
|
+
}
|
|
145
|
+
if (!code || !state) {
|
|
146
|
+
throw new Error("Missing code or state in callback");
|
|
147
|
+
}
|
|
148
|
+
const savedState = this.storage.get("state");
|
|
149
|
+
if (state !== savedState) {
|
|
150
|
+
throw new Error("State mismatch \u2014 possible CSRF attack");
|
|
151
|
+
}
|
|
152
|
+
const codeVerifier = this.storage.get("code_verifier");
|
|
153
|
+
if (!codeVerifier) {
|
|
154
|
+
throw new Error("Missing code verifier \u2014 login flow may have been interrupted");
|
|
155
|
+
}
|
|
156
|
+
const tokenResponse = await fetch(`${this.config.accountsUrl}/api/proxy/token`, {
|
|
157
|
+
method: "POST",
|
|
158
|
+
headers: { "Content-Type": "application/json" },
|
|
159
|
+
body: JSON.stringify({
|
|
160
|
+
grant_type: "authorization_code",
|
|
161
|
+
code,
|
|
162
|
+
client_id: this.config.clientId,
|
|
163
|
+
redirect_uri: this.config.redirectUri,
|
|
164
|
+
code_verifier: codeVerifier
|
|
165
|
+
})
|
|
166
|
+
});
|
|
167
|
+
if (!tokenResponse.ok) {
|
|
168
|
+
const err = await tokenResponse.json().catch(() => ({}));
|
|
169
|
+
throw new Error(err.message || "Token exchange failed");
|
|
170
|
+
}
|
|
171
|
+
const tokenData = await tokenResponse.json();
|
|
172
|
+
this.storage.remove("code_verifier");
|
|
173
|
+
this.storage.remove("state");
|
|
174
|
+
this.storage.setPersistent("access_token", tokenData.access_token);
|
|
175
|
+
const user = await this.getUser(tokenData.access_token);
|
|
176
|
+
return { accessToken: tokenData.access_token, user };
|
|
177
|
+
}
|
|
178
|
+
async getUser(token) {
|
|
179
|
+
const accessToken = token || this.getAccessToken();
|
|
180
|
+
if (!accessToken) {
|
|
181
|
+
throw new Error("No access token available");
|
|
182
|
+
}
|
|
183
|
+
const response = await fetch(`${this.config.accountsUrl}/api/proxy/me`, {
|
|
184
|
+
headers: { Authorization: `Bearer ${accessToken}` }
|
|
185
|
+
});
|
|
186
|
+
if (!response.ok) {
|
|
187
|
+
if (response.status === 401) {
|
|
188
|
+
this.storage.removePersistent("access_token");
|
|
189
|
+
}
|
|
190
|
+
throw new Error("Failed to fetch user info");
|
|
191
|
+
}
|
|
192
|
+
return response.json();
|
|
193
|
+
}
|
|
194
|
+
logout() {
|
|
195
|
+
const token = this.getAccessToken();
|
|
196
|
+
this.storage.clearAll();
|
|
197
|
+
const params = new URLSearchParams();
|
|
198
|
+
if (token) params.set("token", token);
|
|
199
|
+
if (this.config.clientId) params.set("client_id", this.config.clientId);
|
|
200
|
+
if (this.config.postLogoutRedirectUri) {
|
|
201
|
+
params.set("post_logout_redirect_uri", this.config.postLogoutRedirectUri);
|
|
202
|
+
}
|
|
203
|
+
window.location.href = `${this.config.accountsUrl}/api/proxy/logout?${params.toString()}`;
|
|
204
|
+
}
|
|
205
|
+
isAuthenticated() {
|
|
206
|
+
return !!this.getAccessToken();
|
|
207
|
+
}
|
|
208
|
+
getAccessToken() {
|
|
209
|
+
return this.storage.getPersistent("access_token");
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
213
|
+
0 && (module.exports = {
|
|
214
|
+
YaotoshiAuth
|
|
215
|
+
});
|
|
216
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/pkce.ts","../src/storage.ts","../src/client.ts"],"sourcesContent":["export { YaotoshiAuth } from './client';\nexport type { YaotoshiAuthConfig, TokenResponse, UserInfo, AuthResult } from './types';\n","function generateRandomBytes(length: number): Uint8Array {\n const array = new Uint8Array(length);\n crypto.getRandomValues(array);\n return array;\n}\n\nfunction base64UrlEncode(buffer: ArrayBuffer): string {\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nexport function generateCodeVerifier(): string {\n const bytes = generateRandomBytes(32);\n return base64UrlEncode(bytes);\n}\n\nexport async function generateCodeChallenge(verifier: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const digest = await crypto.subtle.digest('SHA-256', data);\n return base64UrlEncode(digest);\n}\n\nexport function generateState(): string {\n const bytes = generateRandomBytes(16);\n return base64UrlEncode(bytes);\n}\n","export class AuthStorage {\n private prefix: string;\n\n constructor(prefix = 'yaotoshi_auth') {\n this.prefix = prefix;\n }\n\n private key(name: string): string {\n return `${this.prefix}_${name}`;\n }\n\n get(name: string): string | null {\n try {\n return sessionStorage.getItem(this.key(name));\n } catch {\n return null;\n }\n }\n\n set(name: string, value: string): void {\n try {\n sessionStorage.setItem(this.key(name), value);\n } catch {\n // Storage unavailable\n }\n }\n\n remove(name: string): void {\n try {\n sessionStorage.removeItem(this.key(name));\n } catch {\n // Storage unavailable\n }\n }\n\n getPersistent(name: string): string | null {\n try {\n return localStorage.getItem(this.key(name));\n } catch {\n return null;\n }\n }\n\n setPersistent(name: string, value: string): void {\n try {\n localStorage.setItem(this.key(name), value);\n } catch {\n // Storage unavailable\n }\n }\n\n removePersistent(name: string): void {\n try {\n localStorage.removeItem(this.key(name));\n } catch {\n // Storage unavailable\n }\n }\n\n clearAll(): void {\n this.remove('code_verifier');\n this.remove('state');\n this.removePersistent('access_token');\n }\n}\n","import { generateCodeVerifier, generateCodeChallenge, generateState } from './pkce';\nimport { AuthStorage } from './storage';\nimport type { YaotoshiAuthConfig, TokenResponse, UserInfo, AuthResult } from './types';\n\nexport class YaotoshiAuth {\n private config: Required<Pick<YaotoshiAuthConfig, 'clientId' | 'redirectUri' | 'accountsUrl'>> &\n YaotoshiAuthConfig;\n private storage: AuthStorage;\n\n constructor(config: YaotoshiAuthConfig) {\n this.config = {\n scopes: ['openid', 'email'],\n postLogoutRedirectUri: undefined,\n storagePrefix: 'yaotoshi_auth',\n ...config,\n };\n this.storage = new AuthStorage(this.config.storagePrefix);\n }\n\n async login(): Promise<void> {\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = await generateCodeChallenge(codeVerifier);\n const state = generateState();\n\n this.storage.set('code_verifier', codeVerifier);\n this.storage.set('state', state);\n\n const params = new URLSearchParams({\n response_type: 'code',\n client_id: this.config.clientId,\n redirect_uri: this.config.redirectUri,\n scope: (this.config.scopes ?? ['openid', 'email']).join(' '),\n state,\n code_challenge: codeChallenge,\n code_challenge_method: 'S256',\n });\n\n window.location.href = `${this.config.accountsUrl}/authorize?${params.toString()}`;\n }\n\n async handleCallback(): Promise<AuthResult> {\n const params = new URLSearchParams(window.location.search);\n const code = params.get('code');\n const state = params.get('state');\n const error = params.get('error');\n\n if (error) {\n throw new Error(`Authorization error: ${error}`);\n }\n\n if (!code || !state) {\n throw new Error('Missing code or state in callback');\n }\n\n const savedState = this.storage.get('state');\n if (state !== savedState) {\n throw new Error('State mismatch — possible CSRF attack');\n }\n\n const codeVerifier = this.storage.get('code_verifier');\n if (!codeVerifier) {\n throw new Error('Missing code verifier — login flow may have been interrupted');\n }\n\n // Exchange code for token\n const tokenResponse = await fetch(`${this.config.accountsUrl}/api/proxy/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'authorization_code',\n code,\n client_id: this.config.clientId,\n redirect_uri: this.config.redirectUri,\n code_verifier: codeVerifier,\n }),\n });\n\n if (!tokenResponse.ok) {\n const err = await tokenResponse.json().catch(() => ({}));\n throw new Error(err.message || 'Token exchange failed');\n }\n\n const tokenData: TokenResponse = await tokenResponse.json();\n\n // Clean up PKCE state\n this.storage.remove('code_verifier');\n this.storage.remove('state');\n\n // Persist the access token\n this.storage.setPersistent('access_token', tokenData.access_token);\n\n // Fetch user info\n const user = await this.getUser(tokenData.access_token);\n\n return { accessToken: tokenData.access_token, user };\n }\n\n async getUser(token?: string): Promise<UserInfo> {\n const accessToken = token || this.getAccessToken();\n if (!accessToken) {\n throw new Error('No access token available');\n }\n\n const response = await fetch(`${this.config.accountsUrl}/api/proxy/me`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n this.storage.removePersistent('access_token');\n }\n throw new Error('Failed to fetch user info');\n }\n\n return response.json();\n }\n\n logout(): void {\n const token = this.getAccessToken();\n this.storage.clearAll();\n\n const params = new URLSearchParams();\n if (token) params.set('token', token);\n if (this.config.clientId) params.set('client_id', this.config.clientId);\n if (this.config.postLogoutRedirectUri) {\n params.set('post_logout_redirect_uri', this.config.postLogoutRedirectUri);\n }\n\n window.location.href = `${this.config.accountsUrl}/api/proxy/logout?${params.toString()}`;\n }\n\n isAuthenticated(): boolean {\n return !!this.getAccessToken();\n }\n\n getAccessToken(): string | null {\n return this.storage.getPersistent('access_token');\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Configuration options for the YaotoshiAuth client. */
|
|
2
|
+
interface YaotoshiAuthConfig {
|
|
3
|
+
clientId: string;
|
|
4
|
+
redirectUri: string;
|
|
5
|
+
postLogoutRedirectUri?: string;
|
|
6
|
+
accountsUrl: string;
|
|
7
|
+
scopes?: string[];
|
|
8
|
+
storagePrefix?: string;
|
|
9
|
+
}
|
|
10
|
+
interface TokenResponse {
|
|
11
|
+
access_token: string;
|
|
12
|
+
token_type: string;
|
|
13
|
+
expires_in: number;
|
|
14
|
+
scope: string;
|
|
15
|
+
}
|
|
16
|
+
interface UserInfo {
|
|
17
|
+
sub: string;
|
|
18
|
+
email: string;
|
|
19
|
+
email_verified: boolean;
|
|
20
|
+
}
|
|
21
|
+
interface AuthResult {
|
|
22
|
+
accessToken: string;
|
|
23
|
+
user: UserInfo;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
declare class YaotoshiAuth {
|
|
27
|
+
private config;
|
|
28
|
+
private storage;
|
|
29
|
+
constructor(config: YaotoshiAuthConfig);
|
|
30
|
+
login(): Promise<void>;
|
|
31
|
+
handleCallback(): Promise<AuthResult>;
|
|
32
|
+
getUser(token?: string): Promise<UserInfo>;
|
|
33
|
+
logout(): void;
|
|
34
|
+
isAuthenticated(): boolean;
|
|
35
|
+
getAccessToken(): string | null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { type AuthResult, type TokenResponse, type UserInfo, YaotoshiAuth, type YaotoshiAuthConfig };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Configuration options for the YaotoshiAuth client. */
|
|
2
|
+
interface YaotoshiAuthConfig {
|
|
3
|
+
clientId: string;
|
|
4
|
+
redirectUri: string;
|
|
5
|
+
postLogoutRedirectUri?: string;
|
|
6
|
+
accountsUrl: string;
|
|
7
|
+
scopes?: string[];
|
|
8
|
+
storagePrefix?: string;
|
|
9
|
+
}
|
|
10
|
+
interface TokenResponse {
|
|
11
|
+
access_token: string;
|
|
12
|
+
token_type: string;
|
|
13
|
+
expires_in: number;
|
|
14
|
+
scope: string;
|
|
15
|
+
}
|
|
16
|
+
interface UserInfo {
|
|
17
|
+
sub: string;
|
|
18
|
+
email: string;
|
|
19
|
+
email_verified: boolean;
|
|
20
|
+
}
|
|
21
|
+
interface AuthResult {
|
|
22
|
+
accessToken: string;
|
|
23
|
+
user: UserInfo;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
declare class YaotoshiAuth {
|
|
27
|
+
private config;
|
|
28
|
+
private storage;
|
|
29
|
+
constructor(config: YaotoshiAuthConfig);
|
|
30
|
+
login(): Promise<void>;
|
|
31
|
+
handleCallback(): Promise<AuthResult>;
|
|
32
|
+
getUser(token?: string): Promise<UserInfo>;
|
|
33
|
+
logout(): void;
|
|
34
|
+
isAuthenticated(): boolean;
|
|
35
|
+
getAccessToken(): string | null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export { type AuthResult, type TokenResponse, type UserInfo, YaotoshiAuth, type YaotoshiAuthConfig };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
// src/pkce.ts
|
|
2
|
+
function generateRandomBytes(length) {
|
|
3
|
+
const array = new Uint8Array(length);
|
|
4
|
+
crypto.getRandomValues(array);
|
|
5
|
+
return array;
|
|
6
|
+
}
|
|
7
|
+
function base64UrlEncode(buffer) {
|
|
8
|
+
const bytes = new Uint8Array(buffer);
|
|
9
|
+
let binary = "";
|
|
10
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
11
|
+
binary += String.fromCharCode(bytes[i]);
|
|
12
|
+
}
|
|
13
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
14
|
+
}
|
|
15
|
+
function generateCodeVerifier() {
|
|
16
|
+
const bytes = generateRandomBytes(32);
|
|
17
|
+
return base64UrlEncode(bytes);
|
|
18
|
+
}
|
|
19
|
+
async function generateCodeChallenge(verifier) {
|
|
20
|
+
const encoder = new TextEncoder();
|
|
21
|
+
const data = encoder.encode(verifier);
|
|
22
|
+
const digest = await crypto.subtle.digest("SHA-256", data);
|
|
23
|
+
return base64UrlEncode(digest);
|
|
24
|
+
}
|
|
25
|
+
function generateState() {
|
|
26
|
+
const bytes = generateRandomBytes(16);
|
|
27
|
+
return base64UrlEncode(bytes);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// src/storage.ts
|
|
31
|
+
var AuthStorage = class {
|
|
32
|
+
constructor(prefix = "yaotoshi_auth") {
|
|
33
|
+
this.prefix = prefix;
|
|
34
|
+
}
|
|
35
|
+
key(name) {
|
|
36
|
+
return `${this.prefix}_${name}`;
|
|
37
|
+
}
|
|
38
|
+
get(name) {
|
|
39
|
+
try {
|
|
40
|
+
return sessionStorage.getItem(this.key(name));
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
set(name, value) {
|
|
46
|
+
try {
|
|
47
|
+
sessionStorage.setItem(this.key(name), value);
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
remove(name) {
|
|
52
|
+
try {
|
|
53
|
+
sessionStorage.removeItem(this.key(name));
|
|
54
|
+
} catch {
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
getPersistent(name) {
|
|
58
|
+
try {
|
|
59
|
+
return localStorage.getItem(this.key(name));
|
|
60
|
+
} catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
setPersistent(name, value) {
|
|
65
|
+
try {
|
|
66
|
+
localStorage.setItem(this.key(name), value);
|
|
67
|
+
} catch {
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
removePersistent(name) {
|
|
71
|
+
try {
|
|
72
|
+
localStorage.removeItem(this.key(name));
|
|
73
|
+
} catch {
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
clearAll() {
|
|
77
|
+
this.remove("code_verifier");
|
|
78
|
+
this.remove("state");
|
|
79
|
+
this.removePersistent("access_token");
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// src/client.ts
|
|
84
|
+
var YaotoshiAuth = class {
|
|
85
|
+
constructor(config) {
|
|
86
|
+
this.config = {
|
|
87
|
+
scopes: ["openid", "email"],
|
|
88
|
+
postLogoutRedirectUri: void 0,
|
|
89
|
+
storagePrefix: "yaotoshi_auth",
|
|
90
|
+
...config
|
|
91
|
+
};
|
|
92
|
+
this.storage = new AuthStorage(this.config.storagePrefix);
|
|
93
|
+
}
|
|
94
|
+
async login() {
|
|
95
|
+
const codeVerifier = generateCodeVerifier();
|
|
96
|
+
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
97
|
+
const state = generateState();
|
|
98
|
+
this.storage.set("code_verifier", codeVerifier);
|
|
99
|
+
this.storage.set("state", state);
|
|
100
|
+
const params = new URLSearchParams({
|
|
101
|
+
response_type: "code",
|
|
102
|
+
client_id: this.config.clientId,
|
|
103
|
+
redirect_uri: this.config.redirectUri,
|
|
104
|
+
scope: (this.config.scopes ?? ["openid", "email"]).join(" "),
|
|
105
|
+
state,
|
|
106
|
+
code_challenge: codeChallenge,
|
|
107
|
+
code_challenge_method: "S256"
|
|
108
|
+
});
|
|
109
|
+
window.location.href = `${this.config.accountsUrl}/authorize?${params.toString()}`;
|
|
110
|
+
}
|
|
111
|
+
async handleCallback() {
|
|
112
|
+
const params = new URLSearchParams(window.location.search);
|
|
113
|
+
const code = params.get("code");
|
|
114
|
+
const state = params.get("state");
|
|
115
|
+
const error = params.get("error");
|
|
116
|
+
if (error) {
|
|
117
|
+
throw new Error(`Authorization error: ${error}`);
|
|
118
|
+
}
|
|
119
|
+
if (!code || !state) {
|
|
120
|
+
throw new Error("Missing code or state in callback");
|
|
121
|
+
}
|
|
122
|
+
const savedState = this.storage.get("state");
|
|
123
|
+
if (state !== savedState) {
|
|
124
|
+
throw new Error("State mismatch \u2014 possible CSRF attack");
|
|
125
|
+
}
|
|
126
|
+
const codeVerifier = this.storage.get("code_verifier");
|
|
127
|
+
if (!codeVerifier) {
|
|
128
|
+
throw new Error("Missing code verifier \u2014 login flow may have been interrupted");
|
|
129
|
+
}
|
|
130
|
+
const tokenResponse = await fetch(`${this.config.accountsUrl}/api/proxy/token`, {
|
|
131
|
+
method: "POST",
|
|
132
|
+
headers: { "Content-Type": "application/json" },
|
|
133
|
+
body: JSON.stringify({
|
|
134
|
+
grant_type: "authorization_code",
|
|
135
|
+
code,
|
|
136
|
+
client_id: this.config.clientId,
|
|
137
|
+
redirect_uri: this.config.redirectUri,
|
|
138
|
+
code_verifier: codeVerifier
|
|
139
|
+
})
|
|
140
|
+
});
|
|
141
|
+
if (!tokenResponse.ok) {
|
|
142
|
+
const err = await tokenResponse.json().catch(() => ({}));
|
|
143
|
+
throw new Error(err.message || "Token exchange failed");
|
|
144
|
+
}
|
|
145
|
+
const tokenData = await tokenResponse.json();
|
|
146
|
+
this.storage.remove("code_verifier");
|
|
147
|
+
this.storage.remove("state");
|
|
148
|
+
this.storage.setPersistent("access_token", tokenData.access_token);
|
|
149
|
+
const user = await this.getUser(tokenData.access_token);
|
|
150
|
+
return { accessToken: tokenData.access_token, user };
|
|
151
|
+
}
|
|
152
|
+
async getUser(token) {
|
|
153
|
+
const accessToken = token || this.getAccessToken();
|
|
154
|
+
if (!accessToken) {
|
|
155
|
+
throw new Error("No access token available");
|
|
156
|
+
}
|
|
157
|
+
const response = await fetch(`${this.config.accountsUrl}/api/proxy/me`, {
|
|
158
|
+
headers: { Authorization: `Bearer ${accessToken}` }
|
|
159
|
+
});
|
|
160
|
+
if (!response.ok) {
|
|
161
|
+
if (response.status === 401) {
|
|
162
|
+
this.storage.removePersistent("access_token");
|
|
163
|
+
}
|
|
164
|
+
throw new Error("Failed to fetch user info");
|
|
165
|
+
}
|
|
166
|
+
return response.json();
|
|
167
|
+
}
|
|
168
|
+
logout() {
|
|
169
|
+
const token = this.getAccessToken();
|
|
170
|
+
this.storage.clearAll();
|
|
171
|
+
const params = new URLSearchParams();
|
|
172
|
+
if (token) params.set("token", token);
|
|
173
|
+
if (this.config.clientId) params.set("client_id", this.config.clientId);
|
|
174
|
+
if (this.config.postLogoutRedirectUri) {
|
|
175
|
+
params.set("post_logout_redirect_uri", this.config.postLogoutRedirectUri);
|
|
176
|
+
}
|
|
177
|
+
window.location.href = `${this.config.accountsUrl}/api/proxy/logout?${params.toString()}`;
|
|
178
|
+
}
|
|
179
|
+
isAuthenticated() {
|
|
180
|
+
return !!this.getAccessToken();
|
|
181
|
+
}
|
|
182
|
+
getAccessToken() {
|
|
183
|
+
return this.storage.getPersistent("access_token");
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
export {
|
|
187
|
+
YaotoshiAuth
|
|
188
|
+
};
|
|
189
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/pkce.ts","../src/storage.ts","../src/client.ts"],"sourcesContent":["function generateRandomBytes(length: number): Uint8Array {\n const array = new Uint8Array(length);\n crypto.getRandomValues(array);\n return array;\n}\n\nfunction base64UrlEncode(buffer: ArrayBuffer): string {\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');\n}\n\nexport function generateCodeVerifier(): string {\n const bytes = generateRandomBytes(32);\n return base64UrlEncode(bytes);\n}\n\nexport async function generateCodeChallenge(verifier: string): Promise<string> {\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const digest = await crypto.subtle.digest('SHA-256', data);\n return base64UrlEncode(digest);\n}\n\nexport function generateState(): string {\n const bytes = generateRandomBytes(16);\n return base64UrlEncode(bytes);\n}\n","export class AuthStorage {\n private prefix: string;\n\n constructor(prefix = 'yaotoshi_auth') {\n this.prefix = prefix;\n }\n\n private key(name: string): string {\n return `${this.prefix}_${name}`;\n }\n\n get(name: string): string | null {\n try {\n return sessionStorage.getItem(this.key(name));\n } catch {\n return null;\n }\n }\n\n set(name: string, value: string): void {\n try {\n sessionStorage.setItem(this.key(name), value);\n } catch {\n // Storage unavailable\n }\n }\n\n remove(name: string): void {\n try {\n sessionStorage.removeItem(this.key(name));\n } catch {\n // Storage unavailable\n }\n }\n\n getPersistent(name: string): string | null {\n try {\n return localStorage.getItem(this.key(name));\n } catch {\n return null;\n }\n }\n\n setPersistent(name: string, value: string): void {\n try {\n localStorage.setItem(this.key(name), value);\n } catch {\n // Storage unavailable\n }\n }\n\n removePersistent(name: string): void {\n try {\n localStorage.removeItem(this.key(name));\n } catch {\n // Storage unavailable\n }\n }\n\n clearAll(): void {\n this.remove('code_verifier');\n this.remove('state');\n this.removePersistent('access_token');\n }\n}\n","import { generateCodeVerifier, generateCodeChallenge, generateState } from './pkce';\nimport { AuthStorage } from './storage';\nimport type { YaotoshiAuthConfig, TokenResponse, UserInfo, AuthResult } from './types';\n\nexport class YaotoshiAuth {\n private config: Required<Pick<YaotoshiAuthConfig, 'clientId' | 'redirectUri' | 'accountsUrl'>> &\n YaotoshiAuthConfig;\n private storage: AuthStorage;\n\n constructor(config: YaotoshiAuthConfig) {\n this.config = {\n scopes: ['openid', 'email'],\n postLogoutRedirectUri: undefined,\n storagePrefix: 'yaotoshi_auth',\n ...config,\n };\n this.storage = new AuthStorage(this.config.storagePrefix);\n }\n\n async login(): Promise<void> {\n const codeVerifier = generateCodeVerifier();\n const codeChallenge = await generateCodeChallenge(codeVerifier);\n const state = generateState();\n\n this.storage.set('code_verifier', codeVerifier);\n this.storage.set('state', state);\n\n const params = new URLSearchParams({\n response_type: 'code',\n client_id: this.config.clientId,\n redirect_uri: this.config.redirectUri,\n scope: (this.config.scopes ?? ['openid', 'email']).join(' '),\n state,\n code_challenge: codeChallenge,\n code_challenge_method: 'S256',\n });\n\n window.location.href = `${this.config.accountsUrl}/authorize?${params.toString()}`;\n }\n\n async handleCallback(): Promise<AuthResult> {\n const params = new URLSearchParams(window.location.search);\n const code = params.get('code');\n const state = params.get('state');\n const error = params.get('error');\n\n if (error) {\n throw new Error(`Authorization error: ${error}`);\n }\n\n if (!code || !state) {\n throw new Error('Missing code or state in callback');\n }\n\n const savedState = this.storage.get('state');\n if (state !== savedState) {\n throw new Error('State mismatch — possible CSRF attack');\n }\n\n const codeVerifier = this.storage.get('code_verifier');\n if (!codeVerifier) {\n throw new Error('Missing code verifier — login flow may have been interrupted');\n }\n\n // Exchange code for token\n const tokenResponse = await fetch(`${this.config.accountsUrl}/api/proxy/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'authorization_code',\n code,\n client_id: this.config.clientId,\n redirect_uri: this.config.redirectUri,\n code_verifier: codeVerifier,\n }),\n });\n\n if (!tokenResponse.ok) {\n const err = await tokenResponse.json().catch(() => ({}));\n throw new Error(err.message || 'Token exchange failed');\n }\n\n const tokenData: TokenResponse = await tokenResponse.json();\n\n // Clean up PKCE state\n this.storage.remove('code_verifier');\n this.storage.remove('state');\n\n // Persist the access token\n this.storage.setPersistent('access_token', tokenData.access_token);\n\n // Fetch user info\n const user = await this.getUser(tokenData.access_token);\n\n return { accessToken: tokenData.access_token, user };\n }\n\n async getUser(token?: string): Promise<UserInfo> {\n const accessToken = token || this.getAccessToken();\n if (!accessToken) {\n throw new Error('No access token available');\n }\n\n const response = await fetch(`${this.config.accountsUrl}/api/proxy/me`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n\n if (!response.ok) {\n if (response.status === 401) {\n this.storage.removePersistent('access_token');\n }\n throw new Error('Failed to fetch user info');\n }\n\n return response.json();\n }\n\n logout(): void {\n const token = this.getAccessToken();\n this.storage.clearAll();\n\n const params = new URLSearchParams();\n if (token) params.set('token', token);\n if (this.config.clientId) params.set('client_id', this.config.clientId);\n if (this.config.postLogoutRedirectUri) {\n params.set('post_logout_redirect_uri', this.config.postLogoutRedirectUri);\n }\n\n window.location.href = `${this.config.accountsUrl}/api/proxy/logout?${params.toString()}`;\n }\n\n isAuthenticated(): boolean {\n return !!this.getAccessToken();\n }\n\n getAccessToken(): string | null {\n return this.storage.getPersistent('access_token');\n }\n}\n"],"mappings":";AAAA,SAAS,oBAAoB,QAA4B;AACvD,QAAM,QAAQ,IAAI,WAAW,MAAM;AACnC,SAAO,gBAAgB,KAAK;AAC5B,SAAO;AACT;AAEA,SAAS,gBAAgB,QAA6B;AACpD,QAAM,QAAQ,IAAI,WAAW,MAAM;AACnC,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,cAAU,OAAO,aAAa,MAAM,CAAC,CAAC;AAAA,EACxC;AACA,SAAO,KAAK,MAAM,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,GAAG,EAAE,QAAQ,OAAO,EAAE;AAC/E;AAEO,SAAS,uBAA+B;AAC7C,QAAM,QAAQ,oBAAoB,EAAE;AACpC,SAAO,gBAAgB,KAAK;AAC9B;AAEA,eAAsB,sBAAsB,UAAmC;AAC7E,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,OAAO,QAAQ,OAAO,QAAQ;AACpC,QAAM,SAAS,MAAM,OAAO,OAAO,OAAO,WAAW,IAAI;AACzD,SAAO,gBAAgB,MAAM;AAC/B;AAEO,SAAS,gBAAwB;AACtC,QAAM,QAAQ,oBAAoB,EAAE;AACpC,SAAO,gBAAgB,KAAK;AAC9B;;;AC9BO,IAAM,cAAN,MAAkB;AAAA,EAGvB,YAAY,SAAS,iBAAiB;AACpC,SAAK,SAAS;AAAA,EAChB;AAAA,EAEQ,IAAI,MAAsB;AAChC,WAAO,GAAG,KAAK,MAAM,IAAI,IAAI;AAAA,EAC/B;AAAA,EAEA,IAAI,MAA6B;AAC/B,QAAI;AACF,aAAO,eAAe,QAAQ,KAAK,IAAI,IAAI,CAAC;AAAA,IAC9C,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,IAAI,MAAc,OAAqB;AACrC,QAAI;AACF,qBAAe,QAAQ,KAAK,IAAI,IAAI,GAAG,KAAK;AAAA,IAC9C,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,OAAO,MAAoB;AACzB,QAAI;AACF,qBAAe,WAAW,KAAK,IAAI,IAAI,CAAC;AAAA,IAC1C,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,cAAc,MAA6B;AACzC,QAAI;AACF,aAAO,aAAa,QAAQ,KAAK,IAAI,IAAI,CAAC;AAAA,IAC5C,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,cAAc,MAAc,OAAqB;AAC/C,QAAI;AACF,mBAAa,QAAQ,KAAK,IAAI,IAAI,GAAG,KAAK;AAAA,IAC5C,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,iBAAiB,MAAoB;AACnC,QAAI;AACF,mBAAa,WAAW,KAAK,IAAI,IAAI,CAAC;AAAA,IACxC,QAAQ;AAAA,IAER;AAAA,EACF;AAAA,EAEA,WAAiB;AACf,SAAK,OAAO,eAAe;AAC3B,SAAK,OAAO,OAAO;AACnB,SAAK,iBAAiB,cAAc;AAAA,EACtC;AACF;;;AC5DO,IAAM,eAAN,MAAmB;AAAA,EAKxB,YAAY,QAA4B;AACtC,SAAK,SAAS;AAAA,MACZ,QAAQ,CAAC,UAAU,OAAO;AAAA,MAC1B,uBAAuB;AAAA,MACvB,eAAe;AAAA,MACf,GAAG;AAAA,IACL;AACA,SAAK,UAAU,IAAI,YAAY,KAAK,OAAO,aAAa;AAAA,EAC1D;AAAA,EAEA,MAAM,QAAuB;AAC3B,UAAM,eAAe,qBAAqB;AAC1C,UAAM,gBAAgB,MAAM,sBAAsB,YAAY;AAC9D,UAAM,QAAQ,cAAc;AAE5B,SAAK,QAAQ,IAAI,iBAAiB,YAAY;AAC9C,SAAK,QAAQ,IAAI,SAAS,KAAK;AAE/B,UAAM,SAAS,IAAI,gBAAgB;AAAA,MACjC,eAAe;AAAA,MACf,WAAW,KAAK,OAAO;AAAA,MACvB,cAAc,KAAK,OAAO;AAAA,MAC1B,QAAQ,KAAK,OAAO,UAAU,CAAC,UAAU,OAAO,GAAG,KAAK,GAAG;AAAA,MAC3D;AAAA,MACA,gBAAgB;AAAA,MAChB,uBAAuB;AAAA,IACzB,CAAC;AAED,WAAO,SAAS,OAAO,GAAG,KAAK,OAAO,WAAW,cAAc,OAAO,SAAS,CAAC;AAAA,EAClF;AAAA,EAEA,MAAM,iBAAsC;AAC1C,UAAM,SAAS,IAAI,gBAAgB,OAAO,SAAS,MAAM;AACzD,UAAM,OAAO,OAAO,IAAI,MAAM;AAC9B,UAAM,QAAQ,OAAO,IAAI,OAAO;AAChC,UAAM,QAAQ,OAAO,IAAI,OAAO;AAEhC,QAAI,OAAO;AACT,YAAM,IAAI,MAAM,wBAAwB,KAAK,EAAE;AAAA,IACjD;AAEA,QAAI,CAAC,QAAQ,CAAC,OAAO;AACnB,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AAEA,UAAM,aAAa,KAAK,QAAQ,IAAI,OAAO;AAC3C,QAAI,UAAU,YAAY;AACxB,YAAM,IAAI,MAAM,4CAAuC;AAAA,IACzD;AAEA,UAAM,eAAe,KAAK,QAAQ,IAAI,eAAe;AACrD,QAAI,CAAC,cAAc;AACjB,YAAM,IAAI,MAAM,mEAA8D;AAAA,IAChF;AAGA,UAAM,gBAAgB,MAAM,MAAM,GAAG,KAAK,OAAO,WAAW,oBAAoB;AAAA,MAC9E,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU;AAAA,QACnB,YAAY;AAAA,QACZ;AAAA,QACA,WAAW,KAAK,OAAO;AAAA,QACvB,cAAc,KAAK,OAAO;AAAA,QAC1B,eAAe;AAAA,MACjB,CAAC;AAAA,IACH,CAAC;AAED,QAAI,CAAC,cAAc,IAAI;AACrB,YAAM,MAAM,MAAM,cAAc,KAAK,EAAE,MAAM,OAAO,CAAC,EAAE;AACvD,YAAM,IAAI,MAAM,IAAI,WAAW,uBAAuB;AAAA,IACxD;AAEA,UAAM,YAA2B,MAAM,cAAc,KAAK;AAG1D,SAAK,QAAQ,OAAO,eAAe;AACnC,SAAK,QAAQ,OAAO,OAAO;AAG3B,SAAK,QAAQ,cAAc,gBAAgB,UAAU,YAAY;AAGjE,UAAM,OAAO,MAAM,KAAK,QAAQ,UAAU,YAAY;AAEtD,WAAO,EAAE,aAAa,UAAU,cAAc,KAAK;AAAA,EACrD;AAAA,EAEA,MAAM,QAAQ,OAAmC;AAC/C,UAAM,cAAc,SAAS,KAAK,eAAe;AACjD,QAAI,CAAC,aAAa;AAChB,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AAEA,UAAM,WAAW,MAAM,MAAM,GAAG,KAAK,OAAO,WAAW,iBAAiB;AAAA,MACtE,SAAS,EAAE,eAAe,UAAU,WAAW,GAAG;AAAA,IACpD,CAAC;AAED,QAAI,CAAC,SAAS,IAAI;AAChB,UAAI,SAAS,WAAW,KAAK;AAC3B,aAAK,QAAQ,iBAAiB,cAAc;AAAA,MAC9C;AACA,YAAM,IAAI,MAAM,2BAA2B;AAAA,IAC7C;AAEA,WAAO,SAAS,KAAK;AAAA,EACvB;AAAA,EAEA,SAAe;AACb,UAAM,QAAQ,KAAK,eAAe;AAClC,SAAK,QAAQ,SAAS;AAEtB,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,MAAO,QAAO,IAAI,SAAS,KAAK;AACpC,QAAI,KAAK,OAAO,SAAU,QAAO,IAAI,aAAa,KAAK,OAAO,QAAQ;AACtE,QAAI,KAAK,OAAO,uBAAuB;AACrC,aAAO,IAAI,4BAA4B,KAAK,OAAO,qBAAqB;AAAA,IAC1E;AAEA,WAAO,SAAS,OAAO,GAAG,KAAK,OAAO,WAAW,qBAAqB,OAAO,SAAS,CAAC;AAAA,EACzF;AAAA,EAEA,kBAA2B;AACzB,WAAO,CAAC,CAAC,KAAK,eAAe;AAAA,EAC/B;AAAA,EAEA,iBAAgC;AAC9B,WAAO,KAAK,QAAQ,cAAc,cAAc;AAAA,EAClD;AACF;","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@yaotoshi/auth-sdk",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Authentication SDK for Yaotoshi ecosystem apps",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"require": "./dist/index.cjs"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsup",
|
|
22
|
+
"dev": "tsup --watch"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"tsup": "^8.0.0",
|
|
26
|
+
"typescript": "^5.7.0"
|
|
27
|
+
}
|
|
28
|
+
}
|