@gw2me/client 0.9.2 → 0.9.4
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/base64-p0iUDSbg.js +1 -0
- package/dist/dpop.d.ts +22 -4
- package/dist/dpop.js +1 -1
- package/dist/index.d.ts +204 -127
- package/dist/index.js +1 -1
- package/dist/pkce.d.ts +11 -6
- package/dist/pkce.js +1 -1
- package/dist/types-Bqy6G8sj.d.ts +39 -0
- package/package.json +13 -11
- package/dist/chunk-EXOYQILJ.js +0 -1
- package/dist/chunk-OSZ7DOEH.js +0 -1
- package/dist/types-yBP8cksw.d.ts +0 -34
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(e){let t=e instanceof ArrayBuffer?new Uint8Array(e):e;return Uint8Array.prototype.toBase64===void 0?btoa(String.fromCharCode(...t)).replace(/\+/g,`-`).replace(/\//g,`_`).replace(/=+$/,``):t.toBase64({alphabet:`base64url`,omitPadding:!0})}export{e as t};
|
package/dist/dpop.d.ts
CHANGED
|
@@ -1,7 +1,25 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { r as DPoPParams } from "./types-Bqy6G8sj.js";
|
|
2
2
|
|
|
3
|
+
//#region src/dpop.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Generates a new key pair for use with DPoP.
|
|
6
|
+
* @see https://gw2.me/dev/docs/access-tokens#dpop
|
|
7
|
+
*/
|
|
3
8
|
declare function generateDPoPKeyPair(): Promise<CryptoKeyPair>;
|
|
4
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Creates a DPoP proof JWT with the given parameters and key pair.
|
|
11
|
+
* @see https://gw2.me/dev/docs/access-tokens#dpop
|
|
12
|
+
*/
|
|
13
|
+
declare function createDPoPJwt({
|
|
14
|
+
htm,
|
|
15
|
+
htu,
|
|
16
|
+
nonce,
|
|
17
|
+
accessToken
|
|
18
|
+
}: DPoPParams, keyPair: CryptoKeyPair): Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Calculates the JWK thumbprint for a given public key.
|
|
21
|
+
* @see https://gw2.me/dev/docs/access-tokens#dpop
|
|
22
|
+
*/
|
|
5
23
|
declare function jwkThumbprint(key: CryptoKey): Promise<string>;
|
|
6
|
-
|
|
7
|
-
export { createDPoPJwt, generateDPoPKeyPair, jwkThumbprint };
|
|
24
|
+
//#endregion
|
|
25
|
+
export { createDPoPJwt, generateDPoPKeyPair, jwkThumbprint };
|
package/dist/dpop.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{t as e}from"./base64-p0iUDSbg.js";function t(){return crypto.subtle.generateKey({name:`ECDSA`,namedCurve:`P-256`},!1,[`sign`])}async function n({htm:t,htu:n,nonce:r,accessToken:o},s){let c=JSON.stringify({alg:`ES256`,typ:`dpop+jwt`,jwk:await a(s.publicKey)}),l=JSON.stringify({iat:Math.floor(Date.now()/1e3),jti:e(crypto.getRandomValues(new Uint8Array(32))),htm:t,htu:n,nonce:r,ath:o?e(await crypto.subtle.digest(`SHA-256`,i(o))):void 0}),u=`${e(i(c))}.${e(i(l))}`;return`${u}.${e(await crypto.subtle.sign({name:`ECDSA`,hash:`SHA-256`},s.privateKey,i(u)))}`}const r=new TextEncoder;function i(e){return r.encode(e)}async function a(e){let{kty:t,e:n,k:r,n:i,x:a,y:o,crv:s}=await crypto.subtle.exportKey(`jwk`,e);return{e:n,k:r,crv:s,kty:t,n:i,x:a,y:o}}async function o(t){let n=JSON.stringify(await a(t));return e(await crypto.subtle.digest(`SHA-256`,i(n)))}export{n as createDPoPJwt,t as generateDPoPKeyPair,o as jwkThumbprint};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,169 +1,246 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { D as DPoPParams } from './types-yBP8cksw.js';
|
|
1
|
+
import { a as Scope, i as Options, n as DPoPCallback, r as DPoPParams, t as ClientInfo } from "./types-Bqy6G8sj.js";
|
|
3
2
|
|
|
3
|
+
//#region src/api.d.ts
|
|
4
4
|
interface UserResponse {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
sub: string;
|
|
6
|
+
user: {
|
|
7
|
+
id: string;
|
|
8
|
+
name: string;
|
|
9
|
+
email?: string;
|
|
10
|
+
emailVerified?: boolean;
|
|
11
|
+
};
|
|
12
|
+
settings?: unknown;
|
|
13
13
|
}
|
|
14
14
|
interface AccountsResponse {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
accounts: {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
shared: boolean;
|
|
19
|
+
verified?: boolean;
|
|
20
|
+
displayName?: string | null;
|
|
21
|
+
}[];
|
|
22
22
|
}
|
|
23
23
|
interface SubtokenOptions {
|
|
24
|
-
|
|
24
|
+
permissions?: string[];
|
|
25
25
|
}
|
|
26
26
|
interface SubtokenResponse {
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
subtoken: string;
|
|
28
|
+
expiresAt: string;
|
|
29
29
|
}
|
|
30
30
|
interface ApiOptions extends Options {
|
|
31
|
-
|
|
31
|
+
dpop?: DPoPCallback;
|
|
32
32
|
}
|
|
33
33
|
declare class Gw2MeApi {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
#private;
|
|
35
|
+
private access_token;
|
|
36
|
+
private options?;
|
|
37
|
+
constructor(access_token: string, options?: Partial<ApiOptions> | undefined);
|
|
38
|
+
/**
|
|
39
|
+
* Fetches information about the current user. Requires the `identify` scope.
|
|
40
|
+
* @see https://gw2.me/dev/docs/users
|
|
41
|
+
*/
|
|
42
|
+
user(): Promise<UserResponse>;
|
|
43
|
+
/**
|
|
44
|
+
* Stores user-specific settings.
|
|
45
|
+
* @see https://gw2.me/dev/docs/users#settings
|
|
46
|
+
*/
|
|
47
|
+
saveSettings(settings: unknown): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Fetches the Guild Wars 2 accounts linked to the current user. Requires the `accounts` scope.
|
|
50
|
+
* @see https://gw2.me/dev/docs/gw2-api#accounts
|
|
51
|
+
*/
|
|
52
|
+
accounts(): Promise<AccountsResponse>;
|
|
53
|
+
/**
|
|
54
|
+
* Generates a subtoken that can be used to authenticate to the Guild Wars 2 API.
|
|
55
|
+
* @see https://gw2.me/dev/docs/gw2-api#subtoken
|
|
56
|
+
*/
|
|
57
|
+
subtoken(accountId: string, options?: SubtokenOptions): Promise<SubtokenResponse>;
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
//#region src/fed-cm.d.ts
|
|
44
61
|
interface FedCMRequestOptions {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
62
|
+
scopes: Scope[];
|
|
63
|
+
mediation?: CredentialMediationRequirement;
|
|
64
|
+
mode?: "passive" | "active";
|
|
65
|
+
signal?: AbortSignal;
|
|
66
|
+
code_challenge: string;
|
|
67
|
+
code_challenge_method: "S256";
|
|
68
|
+
/** @default true */
|
|
69
|
+
include_granted_scopes?: boolean;
|
|
53
70
|
}
|
|
54
71
|
declare class Gw2MeFedCM {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
72
|
+
#private;
|
|
73
|
+
constructor(configUrl: URL, clientId: string);
|
|
74
|
+
/**
|
|
75
|
+
* Check if FedCM is supported in the current environment.
|
|
76
|
+
*/
|
|
77
|
+
isSupported(): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Start a FedCM sign-in flow with the given options. Resolves with the credential containing the access token on success, or null if the user cancels the flow.
|
|
80
|
+
* @see https://gw2.me/dev/docs/fed-cm
|
|
81
|
+
*/
|
|
82
|
+
request({
|
|
83
|
+
scopes,
|
|
84
|
+
mediation,
|
|
85
|
+
signal,
|
|
86
|
+
mode,
|
|
87
|
+
code_challenge,
|
|
88
|
+
code_challenge_method,
|
|
89
|
+
include_granted_scopes
|
|
90
|
+
}: FedCMRequestOptions): Promise<null | {
|
|
91
|
+
token: string;
|
|
92
|
+
type: "identity";
|
|
93
|
+
}>;
|
|
62
94
|
}
|
|
63
|
-
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region src/client.d.ts
|
|
64
97
|
interface AuthorizationUrlParams {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
98
|
+
redirect_uri: string;
|
|
99
|
+
scopes: Scope[];
|
|
100
|
+
state?: string;
|
|
101
|
+
code_challenge?: string;
|
|
102
|
+
code_challenge_method?: "S256";
|
|
103
|
+
dpop_jkt?: string;
|
|
104
|
+
prompt?: "none" | "consent";
|
|
105
|
+
include_granted_scopes?: boolean;
|
|
106
|
+
verified_accounts_only?: boolean;
|
|
74
107
|
}
|
|
75
108
|
interface PushedAuthorizationRequestParams extends AuthorizationUrlParams {
|
|
76
|
-
|
|
109
|
+
dpop?: DPoPCallback;
|
|
77
110
|
}
|
|
78
111
|
interface AuthorizationUrlRequestUriParams {
|
|
79
|
-
|
|
112
|
+
request_uri: string;
|
|
80
113
|
}
|
|
81
|
-
type TokenType =
|
|
114
|
+
type TokenType = "Bearer" | "DPoP";
|
|
82
115
|
interface AuthTokenParams {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
116
|
+
code: string;
|
|
117
|
+
token_type?: TokenType;
|
|
118
|
+
redirect_uri: string;
|
|
119
|
+
code_verifier?: string;
|
|
120
|
+
dpop?: DPoPCallback;
|
|
88
121
|
}
|
|
89
122
|
interface RefreshTokenParams {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
123
|
+
refresh_token: string;
|
|
124
|
+
refresh_token_type?: TokenType;
|
|
125
|
+
dpop?: DPoPCallback;
|
|
93
126
|
}
|
|
94
127
|
interface TokenResponse {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
128
|
+
access_token: string;
|
|
129
|
+
issued_token_type: "urn:ietf:params:oauth:token-type:access_token";
|
|
130
|
+
token_type: TokenType;
|
|
131
|
+
expires_in: number;
|
|
132
|
+
refresh_token?: string;
|
|
133
|
+
scope: string;
|
|
101
134
|
}
|
|
102
135
|
interface RevokeTokenParams {
|
|
103
|
-
|
|
136
|
+
token: string;
|
|
104
137
|
}
|
|
105
138
|
interface IntrospectTokenParams {
|
|
106
|
-
|
|
139
|
+
token: string;
|
|
107
140
|
}
|
|
108
141
|
declare namespace IntrospectTokenResponse {
|
|
109
|
-
|
|
110
|
-
|
|
142
|
+
interface Inactive {
|
|
143
|
+
active: false;
|
|
144
|
+
}
|
|
145
|
+
namespace Active {
|
|
146
|
+
interface Common {
|
|
147
|
+
active: true;
|
|
148
|
+
scope: string;
|
|
149
|
+
client_id: string;
|
|
150
|
+
exp?: number;
|
|
111
151
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
active: true;
|
|
115
|
-
scope: string;
|
|
116
|
-
client_id: string;
|
|
117
|
-
exp?: number;
|
|
118
|
-
}
|
|
119
|
-
interface Bearer extends Common {
|
|
120
|
-
token_type: 'Bearer';
|
|
121
|
-
}
|
|
122
|
-
interface DPoP extends Common {
|
|
123
|
-
token_type: 'DPoP';
|
|
124
|
-
cnf: {
|
|
125
|
-
jkt: string;
|
|
126
|
-
};
|
|
127
|
-
}
|
|
152
|
+
interface Bearer extends Common {
|
|
153
|
+
token_type: "Bearer";
|
|
128
154
|
}
|
|
129
|
-
|
|
155
|
+
interface DPoP extends Common {
|
|
156
|
+
token_type: "DPoP";
|
|
157
|
+
cnf: {
|
|
158
|
+
jkt: string;
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
type Active = Active.Bearer | Active.DPoP;
|
|
130
163
|
}
|
|
131
164
|
type IntrospectTokenResponse = IntrospectTokenResponse.Inactive | IntrospectTokenResponse.Active;
|
|
132
165
|
interface PushedAuthorizationRequestResponse {
|
|
133
|
-
|
|
134
|
-
|
|
166
|
+
request_uri: string;
|
|
167
|
+
expires_in: number;
|
|
135
168
|
}
|
|
136
169
|
declare class Gw2MeClient {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
170
|
+
#private;
|
|
171
|
+
private options?;
|
|
172
|
+
constructor(client: ClientInfo, options?: Partial<Options> | undefined);
|
|
173
|
+
/**
|
|
174
|
+
* Generate an authorization URL with the given parameters you can navigate the user to in order to start the authorization code flow.
|
|
175
|
+
* @see https://gw2.me/dev/docs/access-tokens#user-authorization
|
|
176
|
+
*/
|
|
177
|
+
getAuthorizationUrl(params: AuthorizationUrlParams | AuthorizationUrlRequestUriParams): string;
|
|
178
|
+
/**
|
|
179
|
+
* Create a pushed authorization request (PAR) with the given parameters.
|
|
180
|
+
* The returned `request_uri` can the be passed to {@link getAuthorizationUrl} to start the authorization code flow.
|
|
181
|
+
* @see https://gw2.me/dev/docs/access-tokens#par
|
|
182
|
+
*/
|
|
183
|
+
pushAuthorizationRequest(params: PushedAuthorizationRequestParams): Promise<PushedAuthorizationRequestResponse>;
|
|
184
|
+
/**
|
|
185
|
+
* Exchanges an authorization code for an access token.
|
|
186
|
+
* @see https://gw2.me/dev/docs/access-tokens#access-token
|
|
187
|
+
*/
|
|
188
|
+
getAccessToken({
|
|
189
|
+
code,
|
|
190
|
+
token_type,
|
|
191
|
+
redirect_uri,
|
|
192
|
+
code_verifier,
|
|
193
|
+
dpop
|
|
194
|
+
}: AuthTokenParams): Promise<TokenResponse>;
|
|
195
|
+
/**
|
|
196
|
+
* Use a refresh token to get a new access token.
|
|
197
|
+
* @see https://gw2.me/dev/docs/refresh-tokens
|
|
198
|
+
*/
|
|
199
|
+
refreshToken({
|
|
200
|
+
refresh_token,
|
|
201
|
+
refresh_token_type,
|
|
202
|
+
dpop
|
|
203
|
+
}: RefreshTokenParams): Promise<TokenResponse>;
|
|
204
|
+
/**
|
|
205
|
+
* Revokes an access or refresh token, making it invalid for further use.
|
|
206
|
+
*/
|
|
207
|
+
revokeToken({
|
|
208
|
+
token
|
|
209
|
+
}: RevokeTokenParams): Promise<void>;
|
|
210
|
+
/**
|
|
211
|
+
* Fetch metadata about an access or refresh token.
|
|
212
|
+
*/
|
|
213
|
+
introspectToken({
|
|
214
|
+
token
|
|
215
|
+
}: IntrospectTokenParams): Promise<IntrospectTokenResponse>;
|
|
216
|
+
/**
|
|
217
|
+
* Parses the search params received from gw2.me on the redirect url (code and state).
|
|
218
|
+
* If gw2.me returned an error response, this will throw an error.
|
|
219
|
+
*
|
|
220
|
+
* @returns The code and optional state.
|
|
221
|
+
*/
|
|
222
|
+
parseAuthorizationResponseSearchParams(searchParams: URLSearchParams): {
|
|
223
|
+
code: string;
|
|
224
|
+
state: string | undefined;
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* Access the gw2.me API.
|
|
228
|
+
*/
|
|
229
|
+
api(access_token: string, options?: Partial<Omit<ApiOptions, keyof Options>>): Gw2MeApi;
|
|
230
|
+
/**
|
|
231
|
+
* Use Federated Credential Management (FedCM) to sign in users.
|
|
232
|
+
* @see https://gw2.me/dev/docs/fed-cm
|
|
233
|
+
*/
|
|
234
|
+
get fedCM(): Gw2MeFedCM;
|
|
235
|
+
}
|
|
236
|
+
//#endregion
|
|
237
|
+
//#region src/error.d.ts
|
|
238
|
+
declare class Gw2MeError extends Error {}
|
|
162
239
|
declare class Gw2MeOAuthError extends Gw2MeError {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
240
|
+
error: string;
|
|
241
|
+
error_description?: string | undefined;
|
|
242
|
+
error_uri?: string | undefined;
|
|
243
|
+
constructor(error: string, error_description?: string | undefined, error_uri?: string | undefined);
|
|
167
244
|
}
|
|
168
|
-
|
|
169
|
-
export {
|
|
245
|
+
//#endregion
|
|
246
|
+
export { AccountsResponse, ApiOptions, AuthTokenParams, AuthorizationUrlParams, AuthorizationUrlRequestUriParams, ClientInfo, DPoPCallback, DPoPParams, FedCMRequestOptions, Gw2MeApi, Gw2MeClient, Gw2MeError, Gw2MeFedCM, Gw2MeOAuthError, IntrospectTokenParams, IntrospectTokenResponse, Options, PushedAuthorizationRequestParams, PushedAuthorizationRequestResponse, RefreshTokenParams, RevokeTokenParams, Scope, SubtokenOptions, SubtokenResponse, TokenResponse, TokenType, UserResponse };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
let e=function(e){return e.Identify=`identify`,e.Email=`email`,e.Accounts=`accounts`,e.Accounts_Verified=`accounts.verified`,e.Accounts_DisplayName=`accounts.displayName`,e.GW2_Account=`gw2:account`,e.GW2_Inventories=`gw2:inventories`,e.GW2_Characters=`gw2:characters`,e.GW2_Tradingpost=`gw2:tradingpost`,e.GW2_Wallet=`gw2:wallet`,e.GW2_Unlocks=`gw2:unlocks`,e.GW2_Pvp=`gw2:pvp`,e.GW2_Wvw=`gw2:wvw`,e.GW2_Builds=`gw2:builds`,e.GW2_Progression=`gw2:progression`,e.GW2_Guilds=`gw2:guilds`,e}({});var t=class extends Error{},n=class extends t{constructor(e,t,n){super(`Received ${e}`+(t?`: ${t}`:``)+(n?` (${n})`:``)),this.error=e,this.error_description=t,this.error_uri=n}};async function r(e){if(await i(e),!a(e))throw new t(`gw2.me did not return a valid JSON response`);return e.json()}async function i(e){if(!e.ok){let n;throw a(e)&&(n=(await e.json()).error_description),new t(`gw2.me returned an error: ${n??`Unknown error`}`)}}function a(e){return e.headers.get(`Content-Type`)?.split(`;`)[0].trim().toLowerCase()===`application/json`}var o=class{constructor(e,t){this.access_token=e,this.options=t}user(){return this.#t(`api/user`).then(e=>fetch(e)).then(r)}saveSettings(e){return this.#t(`api/user/settings`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)}).then(e=>fetch(e)).then(i)}accounts(){return this.#t(`api/accounts`).then(e=>fetch(e)).then(r)}subtoken(e,t){let n=this.#e(`api/accounts/${e}/subtoken`);return t?.permissions&&n.searchParams.set(`permissions`,t.permissions.join(`,`)),this.#t(n).then(e=>fetch(e)).then(r)}#e(e){return new URL(e,this.options?.url||`https://gw2.me/`)}async#t(e,t){let n=e instanceof URL?e:this.#e(e),r=this.options?.dpop,i=new Headers(t?.headers);return i.set(`Authorization`,`${r?`DPoP`:`Bearer`} ${this.access_token}`),r&&i.set(`DPoP`,await r({htm:t?.method??`GET`,htu:n.toString(),accessToken:this.access_token})),new Request(n,{cache:`no-cache`,...t,headers:i})}},s=class{#e;#t;constructor(e,t){this.#e=e,this.#t=t}isSupported(){return typeof window<`u`&&`IdentityCredential`in window}request({scopes:n,mediation:r,signal:i,mode:a,code_challenge:o,code_challenge_method:s,include_granted_scopes:c}){if(!this.isSupported())throw new t(`FedCM is not supported`);return navigator.credentials.get({mediation:r,signal:i,identity:{providers:[{configURL:this.#e,clientId:this.#t,fields:[n.includes(e.Identify)&&`name`,n.includes(e.Email)&&`email`].filter(Boolean),nonce:`${s}:${o}`,params:{scope:n.join(` `),code_challenge:o,code_challenge_method:s,include_granted_scopes:c}}],mode:a}})}},c=class{#e;#t;constructor(e,t){this.options=t,this.#e=e,this.#t=new s(this.#n(`/fed-cm/config.json`),e.client_id)}#n(e){return new URL(e,this.options?.url||`https://gw2.me/`)}#r(){if(!this.#e.client_secret)throw new t(`client_secret is required`);return`Basic ${btoa(`${this.#e.client_id}:${this.#e.client_secret}`)}`}getAuthorizationUrl(e){let t=`request_uri`in e?new URLSearchParams({client_id:this.#e.client_id,response_type:`code`,request_uri:e.request_uri}):l(this.#e.client_id,e);return this.#n(`/oauth2/authorize?${t.toString()}`).toString()}async pushAuthorizationRequest(e){let t=this.#n(`/oauth2/par`),n={"Content-Type":`application/x-www-form-urlencoded`};e.dpop&&(n.DPoP=await e.dpop({htm:`POST`,htu:t.toString()}));let i=l(this.#e.client_id,e);return this.#e.client_secret&&(n.Authorization=this.#r()),await fetch(t,{method:`POST`,headers:n,body:i,cache:`no-store`}).then(r)}async getAccessToken({code:e,token_type:t,redirect_uri:n,code_verifier:i,dpop:a}){let o=new URLSearchParams({grant_type:`authorization_code`,code:e,client_id:this.#e.client_id,redirect_uri:n}),s={"Content-Type":`application/x-www-form-urlencoded`};this.#e.client_secret&&(s.Authorization=this.#r()),i&&o.set(`code_verifier`,i);let c=this.#n(`/api/token`);return a&&(s.DPoP=await a({htm:`POST`,htu:c.toString(),accessToken:t===`DPoP`?e:void 0})),await fetch(c,{method:`POST`,headers:s,body:o,cache:`no-store`}).then(r)}async refreshToken({refresh_token:e,refresh_token_type:t,dpop:n}){let i=new URLSearchParams({grant_type:`refresh_token`,refresh_token:e,client_id:this.#e.client_id}),a={"Content-Type":`application/x-www-form-urlencoded`};this.#e.client_secret&&(a.Authorization=this.#r());let o=this.#n(`/api/token`);return n&&(a.DPoP=await n({htm:`POST`,htu:o.toString(),accessToken:t===`DPoP`?e:void 0})),await fetch(o,{method:`POST`,headers:a,body:i,cache:`no-store`}).then(r)}async revokeToken({token:e}){let t=new URLSearchParams({token:e}),n={"Content-Type":`application/x-www-form-urlencoded`};this.#e.client_secret&&(n.Authorization=this.#r()),await fetch(this.#n(`/api/token/revoke`),{method:`POST`,cache:`no-store`,headers:n,body:t}).then(r)}async introspectToken({token:e}){let t=new URLSearchParams({token:e}),n={"Content-Type":`application/x-www-form-urlencoded`};return this.#e.client_secret&&(n.Authorization=this.#r()),await fetch(this.#n(`/api/token/introspect`),{method:`POST`,cache:`no-store`,headers:n,body:t}).then(r)}parseAuthorizationResponseSearchParams(e){let r=this.#n(`/`).origin,i=e.get(`iss`);if(!i)throw new t("Issuer Identifier verification failed: parameter `iss` is missing");if(i!==r)throw new t(`Issuer Identifier verification failed: expected "${r}", got "${i}"`);let a=e.get(`error`);if(a)throw new n(a,e.get(`error_description`)??void 0,e.get(`error_uri`)??void 0);let o=e.get(`code`);if(!o)throw new t("Parameter `code` is missing");return{code:o,state:e.get(`state`)||void 0}}api(e,t){return new o(e,{...this.options,...t})}get fedCM(){return this.#t}};function l(e,{redirect_uri:t,scopes:n,state:r,code_challenge:i,code_challenge_method:a,dpop_jkt:o,prompt:s,include_granted_scopes:c,verified_accounts_only:l}){let u=new URLSearchParams({client_id:e,response_type:`code`,redirect_uri:t,scope:n.join(` `)});return r&&u.append(`state`,r),i&&a&&(u.append(`code_challenge`,i),u.append(`code_challenge_method`,a)),o&&u.append(`dpop_jkt`,o),s&&u.append(`prompt`,s),c&&u.append(`include_granted_scopes`,`true`),l&&u.append(`verified_accounts_only`,`true`),u}export{o as Gw2MeApi,c as Gw2MeClient,t as Gw2MeError,n as Gw2MeOAuthError,e as Scope};
|
package/dist/pkce.d.ts
CHANGED
|
@@ -1,11 +1,16 @@
|
|
|
1
|
+
//#region src/pkce.d.ts
|
|
1
2
|
interface PKCEChallenge {
|
|
2
|
-
|
|
3
|
-
|
|
3
|
+
code_challenge: string;
|
|
4
|
+
code_challenge_method: "S256";
|
|
4
5
|
}
|
|
5
6
|
interface PKCEPair {
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
challenge: PKCEChallenge;
|
|
8
|
+
code_verifier: string;
|
|
8
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Generates a PKCE pair containing a random code verifier and a corresponding code challenge.
|
|
12
|
+
* @see https://gw2.me/dev/docs/access-tokens#pkce
|
|
13
|
+
*/
|
|
9
14
|
declare function generatePKCEPair(): Promise<PKCEPair>;
|
|
10
|
-
|
|
11
|
-
export {
|
|
15
|
+
//#endregion
|
|
16
|
+
export { PKCEChallenge, PKCEPair, generatePKCEPair };
|
package/dist/pkce.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{t as e}from"./base64-p0iUDSbg.js";async function t(){let t=new Uint8Array(32);crypto.getRandomValues(t);let n=e(t),r=new TextEncoder,i=await crypto.subtle.digest(`SHA-256`,r.encode(n));return{code_verifier:n,challenge:{code_challenge_method:`S256`,code_challenge:e(new Uint8Array(i))}}}export{t as generatePKCEPair};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
//#region src/types.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Scopes supported by gw2.me.
|
|
4
|
+
* @see https://gw2.me/dev/docs/scopes
|
|
5
|
+
*/
|
|
6
|
+
declare enum Scope {
|
|
7
|
+
Identify = "identify",
|
|
8
|
+
Email = "email",
|
|
9
|
+
Accounts = "accounts",
|
|
10
|
+
Accounts_Verified = "accounts.verified",
|
|
11
|
+
Accounts_DisplayName = "accounts.displayName",
|
|
12
|
+
GW2_Account = "gw2:account",
|
|
13
|
+
GW2_Inventories = "gw2:inventories",
|
|
14
|
+
GW2_Characters = "gw2:characters",
|
|
15
|
+
GW2_Tradingpost = "gw2:tradingpost",
|
|
16
|
+
GW2_Wallet = "gw2:wallet",
|
|
17
|
+
GW2_Unlocks = "gw2:unlocks",
|
|
18
|
+
GW2_Pvp = "gw2:pvp",
|
|
19
|
+
GW2_Wvw = "gw2:wvw",
|
|
20
|
+
GW2_Builds = "gw2:builds",
|
|
21
|
+
GW2_Progression = "gw2:progression",
|
|
22
|
+
GW2_Guilds = "gw2:guilds"
|
|
23
|
+
}
|
|
24
|
+
interface ClientInfo {
|
|
25
|
+
client_id: string;
|
|
26
|
+
client_secret?: string;
|
|
27
|
+
}
|
|
28
|
+
interface Options {
|
|
29
|
+
url: string;
|
|
30
|
+
}
|
|
31
|
+
interface DPoPParams {
|
|
32
|
+
htm: "POST" | "GET" | (string & {});
|
|
33
|
+
htu: string;
|
|
34
|
+
nonce?: string;
|
|
35
|
+
accessToken?: string;
|
|
36
|
+
}
|
|
37
|
+
type DPoPCallback = (params: DPoPParams) => string | Promise<string>;
|
|
38
|
+
//#endregion
|
|
39
|
+
export { Scope as a, Options as i, DPoPCallback as n, DPoPParams as r, ClientInfo as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gw2me/client",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.4",
|
|
4
4
|
"description": "gw2.me client library",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -30,8 +30,10 @@
|
|
|
30
30
|
"oauth2"
|
|
31
31
|
],
|
|
32
32
|
"files": [
|
|
33
|
-
"dist
|
|
33
|
+
"dist/*.js",
|
|
34
|
+
"dist/*.d.ts"
|
|
34
35
|
],
|
|
36
|
+
"sideEffects": false,
|
|
35
37
|
"author": "darthmaim",
|
|
36
38
|
"license": "MIT",
|
|
37
39
|
"bugs": {
|
|
@@ -39,24 +41,24 @@
|
|
|
39
41
|
},
|
|
40
42
|
"homepage": "https://github.com/gw2treasures/gw2.me#readme",
|
|
41
43
|
"devDependencies": {
|
|
42
|
-
"@
|
|
44
|
+
"@arethetypeswrong/core": "0.18.2",
|
|
45
|
+
"@gw2treasures/eslint-config": "0.2.1",
|
|
43
46
|
"@gw2treasures/publish-package": "0.1.0",
|
|
44
47
|
"@gw2treasures/tsconfig": "0.0.1",
|
|
45
|
-
"
|
|
46
|
-
"
|
|
48
|
+
"@types/node": "24.12.0",
|
|
49
|
+
"eslint": "9.39.4",
|
|
50
|
+
"publint": "0.3.18",
|
|
51
|
+
"tsdown": "0.21.4",
|
|
47
52
|
"typescript": "5.9.3",
|
|
48
|
-
"typescript-eslint": "8.
|
|
49
|
-
"undici-types": "7.
|
|
53
|
+
"typescript-eslint": "8.57.1",
|
|
54
|
+
"undici-types": "7.24.4"
|
|
50
55
|
},
|
|
51
56
|
"publishConfig": {
|
|
52
57
|
"access": "public",
|
|
53
58
|
"provenance": true
|
|
54
59
|
},
|
|
55
60
|
"scripts": {
|
|
56
|
-
"build": "
|
|
57
|
-
"build:local": "tsup src/index.ts src/dpop.ts src/pkce.ts --format esm && tsc --emitDeclarationOnly --declaration --declarationMap",
|
|
58
|
-
"build:ci": "tsup src/index.ts src/dpop.ts src/pkce.ts --format esm --minify --dts",
|
|
59
|
-
"clean": "rm -rf dist/",
|
|
61
|
+
"build": "tsdown src/index.ts src/dpop.ts src/pkce.ts",
|
|
60
62
|
"lint": "eslint .",
|
|
61
63
|
"publish-package": "gw2treasures-publish-package"
|
|
62
64
|
}
|
package/dist/chunk-EXOYQILJ.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function a(r){let e=r instanceof ArrayBuffer?new Uint8Array(r):r;return btoa(String.fromCharCode(...e)).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}export{a};
|
package/dist/chunk-OSZ7DOEH.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var f=a=>{throw TypeError(a)};var d=(a,b,c)=>b.has(a)||f("Cannot "+c);var g=(a,b,c)=>(d(a,b,"read from private field"),c?c.call(a):b.get(a)),h=(a,b,c)=>b.has(a)?f("Cannot add the same private member more than once"):b instanceof WeakSet?b.add(a):b.set(a,c),i=(a,b,c,e)=>(d(a,b,"write to private field"),e?e.call(a,c):b.set(a,c),c),j=(a,b,c)=>(d(a,b,"access private method"),c);export{g as a,h as b,i as c,j as d};
|
package/dist/types-yBP8cksw.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
declare enum Scope {
|
|
2
|
-
Identify = "identify",
|
|
3
|
-
Email = "email",
|
|
4
|
-
Accounts = "accounts",
|
|
5
|
-
Accounts_Verified = "accounts.verified",
|
|
6
|
-
Accounts_DisplayName = "accounts.displayName",
|
|
7
|
-
GW2_Account = "gw2:account",
|
|
8
|
-
GW2_Inventories = "gw2:inventories",
|
|
9
|
-
GW2_Characters = "gw2:characters",
|
|
10
|
-
GW2_Tradingpost = "gw2:tradingpost",
|
|
11
|
-
GW2_Wallet = "gw2:wallet",
|
|
12
|
-
GW2_Unlocks = "gw2:unlocks",
|
|
13
|
-
GW2_Pvp = "gw2:pvp",
|
|
14
|
-
GW2_Wvw = "gw2:wvw",
|
|
15
|
-
GW2_Builds = "gw2:builds",
|
|
16
|
-
GW2_Progression = "gw2:progression",
|
|
17
|
-
GW2_Guilds = "gw2:guilds"
|
|
18
|
-
}
|
|
19
|
-
interface ClientInfo {
|
|
20
|
-
client_id: string;
|
|
21
|
-
client_secret?: string;
|
|
22
|
-
}
|
|
23
|
-
interface Options {
|
|
24
|
-
url: string;
|
|
25
|
-
}
|
|
26
|
-
interface DPoPParams {
|
|
27
|
-
htm: 'POST' | 'GET' | (string & {});
|
|
28
|
-
htu: string;
|
|
29
|
-
nonce?: string;
|
|
30
|
-
accessToken?: string;
|
|
31
|
-
}
|
|
32
|
-
type DPoPCallback = (params: DPoPParams) => string | Promise<string>;
|
|
33
|
-
|
|
34
|
-
export { type ClientInfo as C, type DPoPParams as D, type Options as O, Scope as S, type DPoPCallback as a };
|