@logto/client 1.1.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/errors.cjs ADDED
@@ -0,0 +1,17 @@
1
+ 'use strict';
2
+
3
+ const logtoClientErrorCodes = Object.freeze({
4
+ 'sign_in_session.invalid': 'Invalid sign-in session.',
5
+ 'sign_in_session.not_found': 'Sign-in session not found.',
6
+ not_authenticated: 'Not authenticated.',
7
+ fetch_user_info_failed: 'Unable to fetch user info. The access token may be invalid.',
8
+ });
9
+ class LogtoClientError extends Error {
10
+ constructor(code, data) {
11
+ super(logtoClientErrorCodes[code]);
12
+ this.code = code;
13
+ this.data = data;
14
+ }
15
+ }
16
+
17
+ exports.LogtoClientError = LogtoClientError;
package/lib/errors.d.ts CHANGED
@@ -1,13 +1,10 @@
1
- import type { NormalizeKeyPaths } from '@silverhand/essentials';
2
1
  declare const logtoClientErrorCodes: Readonly<{
3
- sign_in_session: {
4
- invalid: string;
5
- not_found: string;
6
- };
2
+ 'sign_in_session.invalid': "Invalid sign-in session.";
3
+ 'sign_in_session.not_found': "Sign-in session not found.";
7
4
  not_authenticated: "Not authenticated.";
8
5
  fetch_user_info_failed: "Unable to fetch user info. The access token may be invalid.";
9
6
  }>;
10
- export type LogtoClientErrorCode = NormalizeKeyPaths<typeof logtoClientErrorCodes>;
7
+ export type LogtoClientErrorCode = keyof typeof logtoClientErrorCodes;
11
8
  export declare class LogtoClientError extends Error {
12
9
  code: LogtoClientErrorCode;
13
10
  data: unknown;
package/lib/errors.js CHANGED
@@ -1,33 +1,15 @@
1
- 'use strict';
2
-
3
- var get = require('lodash.get');
4
-
5
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
-
7
- var get__default = /*#__PURE__*/_interopDefault(get);
8
-
9
1
  const logtoClientErrorCodes = Object.freeze({
10
- sign_in_session: {
11
- invalid: 'Invalid sign-in session.',
12
- not_found: 'Sign-in session not found.',
13
- },
2
+ 'sign_in_session.invalid': 'Invalid sign-in session.',
3
+ 'sign_in_session.not_found': 'Sign-in session not found.',
14
4
  not_authenticated: 'Not authenticated.',
15
5
  fetch_user_info_failed: 'Unable to fetch user info. The access token may be invalid.',
16
6
  });
17
- const getMessageByErrorCode = (errorCode) => {
18
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
19
- const message = get__default.default(logtoClientErrorCodes, errorCode);
20
- if (typeof message === 'string') {
21
- return message;
22
- }
23
- return errorCode;
24
- };
25
7
  class LogtoClientError extends Error {
26
8
  constructor(code, data) {
27
- super(getMessageByErrorCode(code));
9
+ super(logtoClientErrorCodes[code]);
28
10
  this.code = code;
29
11
  this.data = data;
30
12
  }
31
13
  }
32
14
 
33
- exports.LogtoClientError = LogtoClientError;
15
+ export { LogtoClientError };
@@ -1,21 +1,24 @@
1
- import { Prompt, withDefaultScopes, decodeIdToken, fetchUserInfo, generateSignInUri, verifyAndParseCodeFromCallbackUri, fetchTokenByAuthorizationCode, revoke, generateSignOutUri, fetchTokenByRefreshToken, fetchOidcConfig, verifyIdToken } from '@logto/js';
2
- export { LogtoError, LogtoRequestError, OidcError, Prompt, ReservedScope, UserScope } from '@logto/js';
3
- import { createRemoteJWKSet } from 'jose';
4
- import once from 'lodash.once';
5
- import { LogtoClientError } from './errors.mjs';
6
- import { isLogtoSignInSessionItem, isLogtoAccessTokenMap } from './types/index.mjs';
7
- import { buildAccessTokenKey, getDiscoveryEndpoint } from './utils/index.mjs';
8
- export { createRequester } from './utils/requester.mjs';
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var js = require('@logto/js');
6
+ var jose = require('jose');
7
+ var errors = require('./errors.cjs');
8
+ var index = require('./types/index.cjs');
9
+ var index$1 = require('./utils/index.cjs');
10
+ var once = require('./utils/once.cjs');
11
+ var requester = require('./utils/requester.cjs');
9
12
 
10
13
  class LogtoClient {
11
14
  constructor(logtoConfig, adapter) {
12
- this.getOidcConfig = once(this._getOidcConfig);
13
- this.getJwtVerifyGetKey = once(this._getJwtVerifyGetKey);
15
+ this.getOidcConfig = once.once(this._getOidcConfig);
16
+ this.getJwtVerifyGetKey = once.once(this._getJwtVerifyGetKey);
14
17
  this.accessTokenMap = new Map();
15
18
  this.logtoConfig = {
16
19
  ...logtoConfig,
17
- prompt: logtoConfig.prompt ?? Prompt.Consent,
18
- scopes: withDefaultScopes(logtoConfig.scopes).split(' '),
20
+ prompt: logtoConfig.prompt ?? js.Prompt.Consent,
21
+ scopes: js.withDefaultScopes(logtoConfig.scopes).split(' '),
19
22
  };
20
23
  this.adapter = adapter;
21
24
  void this.loadAccessTokenMap();
@@ -31,9 +34,9 @@ class LogtoClient {
31
34
  }
32
35
  async getAccessToken(resource) {
33
36
  if (!(await this.getIdToken())) {
34
- throw new LogtoClientError('not_authenticated');
37
+ throw new errors.LogtoClientError('not_authenticated');
35
38
  }
36
- const accessTokenKey = buildAccessTokenKey(resource);
39
+ const accessTokenKey = index$1.buildAccessTokenKey(resource);
37
40
  const accessToken = this.accessTokenMap.get(accessTokenKey);
38
41
  if (accessToken && accessToken.expiresAt > Date.now() / 1000) {
39
42
  return accessToken.token;
@@ -50,17 +53,17 @@ class LogtoClient {
50
53
  async getIdTokenClaims() {
51
54
  const idToken = await this.getIdToken();
52
55
  if (!idToken) {
53
- throw new LogtoClientError('not_authenticated');
56
+ throw new errors.LogtoClientError('not_authenticated');
54
57
  }
55
- return decodeIdToken(idToken);
58
+ return js.decodeIdToken(idToken);
56
59
  }
57
60
  async fetchUserInfo() {
58
61
  const { userinfoEndpoint } = await this.getOidcConfig();
59
62
  const accessToken = await this.getAccessToken();
60
63
  if (!accessToken) {
61
- throw new LogtoClientError('fetch_user_info_failed');
64
+ throw new errors.LogtoClientError('fetch_user_info_failed');
62
65
  }
63
- return fetchUserInfo(userinfoEndpoint, accessToken, this.adapter.requester);
66
+ return js.fetchUserInfo(userinfoEndpoint, accessToken, this.adapter.requester);
64
67
  }
65
68
  async signIn(redirectUri, interactionMode) {
66
69
  const { appId: clientId, prompt, resources, scopes } = this.logtoConfig;
@@ -68,7 +71,7 @@ class LogtoClient {
68
71
  const codeVerifier = this.adapter.generateCodeVerifier();
69
72
  const codeChallenge = await this.adapter.generateCodeChallenge(codeVerifier);
70
73
  const state = this.adapter.generateState();
71
- const signInUri = generateSignInUri({
74
+ const signInUri = js.generateSignInUri({
72
75
  authorizationEndpoint,
73
76
  clientId,
74
77
  redirectUri,
@@ -98,13 +101,13 @@ class LogtoClient {
98
101
  const { requester } = adapter;
99
102
  const signInSession = await this.getSignInSession();
100
103
  if (!signInSession) {
101
- throw new LogtoClientError('sign_in_session.not_found');
104
+ throw new errors.LogtoClientError('sign_in_session.not_found');
102
105
  }
103
106
  const { redirectUri, state, codeVerifier } = signInSession;
104
- const code = verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);
107
+ const code = js.verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);
105
108
  const { appId: clientId } = logtoConfig;
106
109
  const { tokenEndpoint } = await this.getOidcConfig();
107
- const codeTokenResponse = await fetchTokenByAuthorizationCode({
110
+ const codeTokenResponse = await js.fetchTokenByAuthorizationCode({
108
111
  clientId,
109
112
  tokenEndpoint,
110
113
  redirectUri,
@@ -121,13 +124,13 @@ class LogtoClient {
121
124
  const refreshToken = await this.getRefreshToken();
122
125
  if (refreshToken) {
123
126
  try {
124
- await revoke(revocationEndpoint, clientId, refreshToken, this.adapter.requester);
127
+ await js.revoke(revocationEndpoint, clientId, refreshToken, this.adapter.requester);
125
128
  }
126
129
  catch {
127
130
  // Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed
128
131
  }
129
132
  }
130
- const url = generateSignOutUri({
133
+ const url = js.generateSignOutUri({
131
134
  endSessionEndpoint,
132
135
  postLogoutRedirectUri,
133
136
  clientId,
@@ -144,8 +147,8 @@ class LogtoClient {
144
147
  return null;
145
148
  }
146
149
  const item = JSON.parse(jsonItem);
147
- if (!isLogtoSignInSessionItem(item)) {
148
- throw new LogtoClientError('sign_in_session.invalid');
150
+ if (!index.isLogtoSignInSessionItem(item)) {
151
+ throw new errors.LogtoClientError('sign_in_session.invalid');
149
152
  }
150
153
  return item;
151
154
  }
@@ -174,12 +177,12 @@ class LogtoClient {
174
177
  async getAccessTokenByRefreshToken(resource) {
175
178
  const currentRefreshToken = await this.getRefreshToken();
176
179
  if (!currentRefreshToken) {
177
- throw new LogtoClientError('not_authenticated');
180
+ throw new errors.LogtoClientError('not_authenticated');
178
181
  }
179
- const accessTokenKey = buildAccessTokenKey(resource);
182
+ const accessTokenKey = index$1.buildAccessTokenKey(resource);
180
183
  const { appId: clientId } = this.logtoConfig;
181
184
  const { tokenEndpoint } = await this.getOidcConfig();
182
- const { accessToken, refreshToken, idToken, scope, expiresIn } = await fetchTokenByRefreshToken({
185
+ const { accessToken, refreshToken, idToken, scope, expiresIn } = await js.fetchTokenByRefreshToken({
183
186
  clientId,
184
187
  tokenEndpoint,
185
188
  refreshToken: currentRefreshToken,
@@ -200,24 +203,24 @@ class LogtoClient {
200
203
  }
201
204
  async _getOidcConfig() {
202
205
  const { endpoint } = this.logtoConfig;
203
- const discoveryEndpoint = getDiscoveryEndpoint(endpoint);
204
- return fetchOidcConfig(discoveryEndpoint, this.adapter.requester);
206
+ const discoveryEndpoint = index$1.getDiscoveryEndpoint(endpoint);
207
+ return js.fetchOidcConfig(discoveryEndpoint, this.adapter.requester);
205
208
  }
206
209
  async _getJwtVerifyGetKey() {
207
210
  const { jwksUri } = await this.getOidcConfig();
208
- return createRemoteJWKSet(new URL(jwksUri));
211
+ return jose.createRemoteJWKSet(new URL(jwksUri));
209
212
  }
210
213
  async verifyIdToken(idToken) {
211
214
  const { appId } = this.logtoConfig;
212
215
  const { issuer } = await this.getOidcConfig();
213
216
  const jwtVerifyGetKey = await this.getJwtVerifyGetKey();
214
- await verifyIdToken(idToken, appId, issuer, jwtVerifyGetKey);
217
+ await js.verifyIdToken(idToken, appId, issuer, jwtVerifyGetKey);
215
218
  }
216
219
  async saveCodeToken({ refreshToken, idToken, scope, accessToken, expiresIn, }) {
217
220
  await this.setRefreshToken(refreshToken ?? null);
218
221
  await this.setIdToken(idToken);
219
222
  // NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)
220
- const accessTokenKey = buildAccessTokenKey();
223
+ const accessTokenKey = index$1.buildAccessTokenKey();
221
224
  const expiresAt = Date.now() / 1000 + expiresIn;
222
225
  this.accessTokenMap.set(accessTokenKey, { token: accessToken, scope, expiresAt });
223
226
  await this.saveAccessTokenMap();
@@ -237,7 +240,7 @@ class LogtoClient {
237
240
  }
238
241
  try {
239
242
  const json = JSON.parse(raw);
240
- if (!isLogtoAccessTokenMap(json)) {
243
+ if (!index.isLogtoAccessTokenMap(json)) {
241
244
  return;
242
245
  }
243
246
  this.accessTokenMap.clear();
@@ -251,4 +254,32 @@ class LogtoClient {
251
254
  }
252
255
  }
253
256
 
254
- export { LogtoClientError, LogtoClient as default, isLogtoAccessTokenMap, isLogtoSignInSessionItem };
257
+ Object.defineProperty(exports, 'LogtoError', {
258
+ enumerable: true,
259
+ get: function () { return js.LogtoError; }
260
+ });
261
+ Object.defineProperty(exports, 'LogtoRequestError', {
262
+ enumerable: true,
263
+ get: function () { return js.LogtoRequestError; }
264
+ });
265
+ Object.defineProperty(exports, 'OidcError', {
266
+ enumerable: true,
267
+ get: function () { return js.OidcError; }
268
+ });
269
+ Object.defineProperty(exports, 'Prompt', {
270
+ enumerable: true,
271
+ get: function () { return js.Prompt; }
272
+ });
273
+ Object.defineProperty(exports, 'ReservedScope', {
274
+ enumerable: true,
275
+ get: function () { return js.ReservedScope; }
276
+ });
277
+ Object.defineProperty(exports, 'UserScope', {
278
+ enumerable: true,
279
+ get: function () { return js.UserScope; }
280
+ });
281
+ exports.LogtoClientError = errors.LogtoClientError;
282
+ exports.isLogtoAccessTokenMap = index.isLogtoAccessTokenMap;
283
+ exports.isLogtoSignInSessionItem = index.isLogtoSignInSessionItem;
284
+ exports.createRequester = requester.createRequester;
285
+ exports.default = LogtoClient;
package/lib/index.d.ts CHANGED
@@ -1,25 +1,17 @@
1
1
  import type { IdTokenClaims, UserInfoResponse, InteractionMode } from '@logto/js';
2
2
  import type { Nullable } from '@silverhand/essentials';
3
- import type { ClientAdapter } from './adapter';
4
- import type { AccessToken, LogtoConfig, LogtoSignInSessionItem } from './types';
3
+ import type { ClientAdapter } from './adapter.js';
4
+ import type { AccessToken, LogtoConfig, LogtoSignInSessionItem } from './types/index.js';
5
5
  export type { IdTokenClaims, LogtoErrorCode, UserInfoResponse, InteractionMode } from '@logto/js';
6
6
  export { LogtoError, OidcError, Prompt, LogtoRequestError, ReservedScope, UserScope, } from '@logto/js';
7
- export * from './errors';
8
- export type { Storage, StorageKey, ClientAdapter } from './adapter';
9
- export { createRequester } from './utils';
10
- export * from './types';
7
+ export * from './errors.js';
8
+ export type { Storage, StorageKey, ClientAdapter } from './adapter.js';
9
+ export { createRequester } from './utils/index.js';
10
+ export * from './types/index.js';
11
11
  export default class LogtoClient {
12
12
  protected readonly logtoConfig: LogtoConfig;
13
- protected readonly getOidcConfig: () => Promise<import("@silverhand/essentials").KeysToCamelCase<{
14
- authorization_endpoint: string;
15
- token_endpoint: string;
16
- userinfo_endpoint: string;
17
- end_session_endpoint: string;
18
- revocation_endpoint: string;
19
- jwks_uri: string;
20
- issuer: string;
21
- }>>;
22
- protected readonly getJwtVerifyGetKey: () => Promise<(protectedHeader?: import("jose").JWSHeaderParameters | undefined, token?: import("jose").FlattenedJWSInput | undefined) => Promise<import("jose").KeyLike>>;
13
+ protected readonly getOidcConfig: typeof this._getOidcConfig;
14
+ protected readonly getJwtVerifyGetKey: (...args: unknown[]) => Promise<(protectedHeader?: import("jose").JWSHeaderParameters | undefined, token?: import("jose").FlattenedJWSInput | undefined) => Promise<import("jose").KeyLike>>;
23
15
  protected readonly adapter: ClientAdapter;
24
16
  protected readonly accessTokenMap: Map<string, AccessToken>;
25
17
  constructor(logtoConfig: LogtoConfig, adapter: ClientAdapter);
package/lib/index.js CHANGED
@@ -1,28 +1,21 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var js = require('@logto/js');
6
- var jose = require('jose');
7
- var once = require('lodash.once');
8
- var errors = require('./errors.js');
9
- var index = require('./types/index.js');
10
- var index$1 = require('./utils/index.js');
11
- var requester = require('./utils/requester.js');
12
-
13
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
14
-
15
- var once__default = /*#__PURE__*/_interopDefault(once);
1
+ import { Prompt, withDefaultScopes, decodeIdToken, fetchUserInfo, generateSignInUri, verifyAndParseCodeFromCallbackUri, fetchTokenByAuthorizationCode, revoke, generateSignOutUri, fetchTokenByRefreshToken, fetchOidcConfig, verifyIdToken } from '@logto/js';
2
+ export { LogtoError, LogtoRequestError, OidcError, Prompt, ReservedScope, UserScope } from '@logto/js';
3
+ import { createRemoteJWKSet } from 'jose';
4
+ import { LogtoClientError } from './errors.js';
5
+ import { isLogtoSignInSessionItem, isLogtoAccessTokenMap } from './types/index.js';
6
+ import { buildAccessTokenKey, getDiscoveryEndpoint } from './utils/index.js';
7
+ import { once } from './utils/once.js';
8
+ export { createRequester } from './utils/requester.js';
16
9
 
17
10
  class LogtoClient {
18
11
  constructor(logtoConfig, adapter) {
19
- this.getOidcConfig = once__default.default(this._getOidcConfig);
20
- this.getJwtVerifyGetKey = once__default.default(this._getJwtVerifyGetKey);
12
+ this.getOidcConfig = once(this._getOidcConfig);
13
+ this.getJwtVerifyGetKey = once(this._getJwtVerifyGetKey);
21
14
  this.accessTokenMap = new Map();
22
15
  this.logtoConfig = {
23
16
  ...logtoConfig,
24
- prompt: logtoConfig.prompt ?? js.Prompt.Consent,
25
- scopes: js.withDefaultScopes(logtoConfig.scopes).split(' '),
17
+ prompt: logtoConfig.prompt ?? Prompt.Consent,
18
+ scopes: withDefaultScopes(logtoConfig.scopes).split(' '),
26
19
  };
27
20
  this.adapter = adapter;
28
21
  void this.loadAccessTokenMap();
@@ -38,9 +31,9 @@ class LogtoClient {
38
31
  }
39
32
  async getAccessToken(resource) {
40
33
  if (!(await this.getIdToken())) {
41
- throw new errors.LogtoClientError('not_authenticated');
34
+ throw new LogtoClientError('not_authenticated');
42
35
  }
43
- const accessTokenKey = index$1.buildAccessTokenKey(resource);
36
+ const accessTokenKey = buildAccessTokenKey(resource);
44
37
  const accessToken = this.accessTokenMap.get(accessTokenKey);
45
38
  if (accessToken && accessToken.expiresAt > Date.now() / 1000) {
46
39
  return accessToken.token;
@@ -57,17 +50,17 @@ class LogtoClient {
57
50
  async getIdTokenClaims() {
58
51
  const idToken = await this.getIdToken();
59
52
  if (!idToken) {
60
- throw new errors.LogtoClientError('not_authenticated');
53
+ throw new LogtoClientError('not_authenticated');
61
54
  }
62
- return js.decodeIdToken(idToken);
55
+ return decodeIdToken(idToken);
63
56
  }
64
57
  async fetchUserInfo() {
65
58
  const { userinfoEndpoint } = await this.getOidcConfig();
66
59
  const accessToken = await this.getAccessToken();
67
60
  if (!accessToken) {
68
- throw new errors.LogtoClientError('fetch_user_info_failed');
61
+ throw new LogtoClientError('fetch_user_info_failed');
69
62
  }
70
- return js.fetchUserInfo(userinfoEndpoint, accessToken, this.adapter.requester);
63
+ return fetchUserInfo(userinfoEndpoint, accessToken, this.adapter.requester);
71
64
  }
72
65
  async signIn(redirectUri, interactionMode) {
73
66
  const { appId: clientId, prompt, resources, scopes } = this.logtoConfig;
@@ -75,7 +68,7 @@ class LogtoClient {
75
68
  const codeVerifier = this.adapter.generateCodeVerifier();
76
69
  const codeChallenge = await this.adapter.generateCodeChallenge(codeVerifier);
77
70
  const state = this.adapter.generateState();
78
- const signInUri = js.generateSignInUri({
71
+ const signInUri = generateSignInUri({
79
72
  authorizationEndpoint,
80
73
  clientId,
81
74
  redirectUri,
@@ -105,13 +98,13 @@ class LogtoClient {
105
98
  const { requester } = adapter;
106
99
  const signInSession = await this.getSignInSession();
107
100
  if (!signInSession) {
108
- throw new errors.LogtoClientError('sign_in_session.not_found');
101
+ throw new LogtoClientError('sign_in_session.not_found');
109
102
  }
110
103
  const { redirectUri, state, codeVerifier } = signInSession;
111
- const code = js.verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);
104
+ const code = verifyAndParseCodeFromCallbackUri(callbackUri, redirectUri, state);
112
105
  const { appId: clientId } = logtoConfig;
113
106
  const { tokenEndpoint } = await this.getOidcConfig();
114
- const codeTokenResponse = await js.fetchTokenByAuthorizationCode({
107
+ const codeTokenResponse = await fetchTokenByAuthorizationCode({
115
108
  clientId,
116
109
  tokenEndpoint,
117
110
  redirectUri,
@@ -128,13 +121,13 @@ class LogtoClient {
128
121
  const refreshToken = await this.getRefreshToken();
129
122
  if (refreshToken) {
130
123
  try {
131
- await js.revoke(revocationEndpoint, clientId, refreshToken, this.adapter.requester);
124
+ await revoke(revocationEndpoint, clientId, refreshToken, this.adapter.requester);
132
125
  }
133
126
  catch {
134
127
  // Do nothing at this point, as we don't want to break the sign-out flow even if the revocation is failed
135
128
  }
136
129
  }
137
- const url = js.generateSignOutUri({
130
+ const url = generateSignOutUri({
138
131
  endSessionEndpoint,
139
132
  postLogoutRedirectUri,
140
133
  clientId,
@@ -151,8 +144,8 @@ class LogtoClient {
151
144
  return null;
152
145
  }
153
146
  const item = JSON.parse(jsonItem);
154
- if (!index.isLogtoSignInSessionItem(item)) {
155
- throw new errors.LogtoClientError('sign_in_session.invalid');
147
+ if (!isLogtoSignInSessionItem(item)) {
148
+ throw new LogtoClientError('sign_in_session.invalid');
156
149
  }
157
150
  return item;
158
151
  }
@@ -181,12 +174,12 @@ class LogtoClient {
181
174
  async getAccessTokenByRefreshToken(resource) {
182
175
  const currentRefreshToken = await this.getRefreshToken();
183
176
  if (!currentRefreshToken) {
184
- throw new errors.LogtoClientError('not_authenticated');
177
+ throw new LogtoClientError('not_authenticated');
185
178
  }
186
- const accessTokenKey = index$1.buildAccessTokenKey(resource);
179
+ const accessTokenKey = buildAccessTokenKey(resource);
187
180
  const { appId: clientId } = this.logtoConfig;
188
181
  const { tokenEndpoint } = await this.getOidcConfig();
189
- const { accessToken, refreshToken, idToken, scope, expiresIn } = await js.fetchTokenByRefreshToken({
182
+ const { accessToken, refreshToken, idToken, scope, expiresIn } = await fetchTokenByRefreshToken({
190
183
  clientId,
191
184
  tokenEndpoint,
192
185
  refreshToken: currentRefreshToken,
@@ -207,24 +200,24 @@ class LogtoClient {
207
200
  }
208
201
  async _getOidcConfig() {
209
202
  const { endpoint } = this.logtoConfig;
210
- const discoveryEndpoint = index$1.getDiscoveryEndpoint(endpoint);
211
- return js.fetchOidcConfig(discoveryEndpoint, this.adapter.requester);
203
+ const discoveryEndpoint = getDiscoveryEndpoint(endpoint);
204
+ return fetchOidcConfig(discoveryEndpoint, this.adapter.requester);
212
205
  }
213
206
  async _getJwtVerifyGetKey() {
214
207
  const { jwksUri } = await this.getOidcConfig();
215
- return jose.createRemoteJWKSet(new URL(jwksUri));
208
+ return createRemoteJWKSet(new URL(jwksUri));
216
209
  }
217
210
  async verifyIdToken(idToken) {
218
211
  const { appId } = this.logtoConfig;
219
212
  const { issuer } = await this.getOidcConfig();
220
213
  const jwtVerifyGetKey = await this.getJwtVerifyGetKey();
221
- await js.verifyIdToken(idToken, appId, issuer, jwtVerifyGetKey);
214
+ await verifyIdToken(idToken, appId, issuer, jwtVerifyGetKey);
222
215
  }
223
216
  async saveCodeToken({ refreshToken, idToken, scope, accessToken, expiresIn, }) {
224
217
  await this.setRefreshToken(refreshToken ?? null);
225
218
  await this.setIdToken(idToken);
226
219
  // NOTE: Will add scope to accessTokenKey when needed. (Linear issue LOG-1589)
227
- const accessTokenKey = index$1.buildAccessTokenKey();
220
+ const accessTokenKey = buildAccessTokenKey();
228
221
  const expiresAt = Date.now() / 1000 + expiresIn;
229
222
  this.accessTokenMap.set(accessTokenKey, { token: accessToken, scope, expiresAt });
230
223
  await this.saveAccessTokenMap();
@@ -244,7 +237,7 @@ class LogtoClient {
244
237
  }
245
238
  try {
246
239
  const json = JSON.parse(raw);
247
- if (!index.isLogtoAccessTokenMap(json)) {
240
+ if (!isLogtoAccessTokenMap(json)) {
248
241
  return;
249
242
  }
250
243
  this.accessTokenMap.clear();
@@ -258,32 +251,4 @@ class LogtoClient {
258
251
  }
259
252
  }
260
253
 
261
- Object.defineProperty(exports, 'LogtoError', {
262
- enumerable: true,
263
- get: function () { return js.LogtoError; }
264
- });
265
- Object.defineProperty(exports, 'LogtoRequestError', {
266
- enumerable: true,
267
- get: function () { return js.LogtoRequestError; }
268
- });
269
- Object.defineProperty(exports, 'OidcError', {
270
- enumerable: true,
271
- get: function () { return js.OidcError; }
272
- });
273
- Object.defineProperty(exports, 'Prompt', {
274
- enumerable: true,
275
- get: function () { return js.Prompt; }
276
- });
277
- Object.defineProperty(exports, 'ReservedScope', {
278
- enumerable: true,
279
- get: function () { return js.ReservedScope; }
280
- });
281
- Object.defineProperty(exports, 'UserScope', {
282
- enumerable: true,
283
- get: function () { return js.UserScope; }
284
- });
285
- exports.LogtoClientError = errors.LogtoClientError;
286
- exports.isLogtoAccessTokenMap = index.isLogtoAccessTokenMap;
287
- exports.isLogtoSignInSessionItem = index.isLogtoSignInSessionItem;
288
- exports.createRequester = requester.createRequester;
289
- exports.default = LogtoClient;
254
+ export { LogtoClientError, LogtoClient as default, isLogtoAccessTokenMap, isLogtoSignInSessionItem };
package/lib/mock.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  /// <reference types="jest" />
2
2
  import { Prompt } from '@logto/js';
3
3
  import type { Nullable } from '@silverhand/essentials';
4
- import type { AccessToken, LogtoConfig, LogtoSignInSessionItem } from '.';
5
- import LogtoClient from '.';
6
- import type { Storage } from './adapter';
4
+ import type { Storage } from './adapter.js';
5
+ import type { AccessToken, LogtoConfig, LogtoSignInSessionItem } from './index.js';
6
+ import LogtoClient from './index.js';
7
7
  export declare const appId = "app_id_value";
8
8
  export declare const endpoint = "https://logto.dev";
9
9
  export declare class MockedStorage implements Storage {
@@ -1,17 +1,19 @@
1
- import { isArbitraryObject } from '@logto/js';
1
+ 'use strict';
2
+
3
+ var js = require('@logto/js');
2
4
 
3
5
  const isLogtoSignInSessionItem = (data) => {
4
- if (!isArbitraryObject(data)) {
6
+ if (!js.isArbitraryObject(data)) {
5
7
  return false;
6
8
  }
7
9
  return ['redirectUri', 'codeVerifier', 'state'].every((key) => typeof data[key] === 'string');
8
10
  };
9
11
  const isLogtoAccessTokenMap = (data) => {
10
- if (!isArbitraryObject(data)) {
12
+ if (!js.isArbitraryObject(data)) {
11
13
  return false;
12
14
  }
13
15
  return Object.values(data).every((value) => {
14
- if (!isArbitraryObject(value)) {
16
+ if (!js.isArbitraryObject(value)) {
15
17
  return false;
16
18
  }
17
19
  return (typeof value.token === 'string' &&
@@ -20,4 +22,5 @@ const isLogtoAccessTokenMap = (data) => {
20
22
  });
21
23
  };
22
24
 
23
- export { isLogtoAccessTokenMap, isLogtoSignInSessionItem };
25
+ exports.isLogtoAccessTokenMap = isLogtoAccessTokenMap;
26
+ exports.isLogtoSignInSessionItem = isLogtoSignInSessionItem;
@@ -1,19 +1,17 @@
1
- 'use strict';
2
-
3
- var js = require('@logto/js');
1
+ import { isArbitraryObject } from '@logto/js';
4
2
 
5
3
  const isLogtoSignInSessionItem = (data) => {
6
- if (!js.isArbitraryObject(data)) {
4
+ if (!isArbitraryObject(data)) {
7
5
  return false;
8
6
  }
9
7
  return ['redirectUri', 'codeVerifier', 'state'].every((key) => typeof data[key] === 'string');
10
8
  };
11
9
  const isLogtoAccessTokenMap = (data) => {
12
- if (!js.isArbitraryObject(data)) {
10
+ if (!isArbitraryObject(data)) {
13
11
  return false;
14
12
  }
15
13
  return Object.values(data).every((value) => {
16
- if (!js.isArbitraryObject(value)) {
14
+ if (!isArbitraryObject(value)) {
17
15
  return false;
18
16
  }
19
17
  return (typeof value.token === 'string' &&
@@ -22,5 +20,4 @@ const isLogtoAccessTokenMap = (data) => {
22
20
  });
23
21
  };
24
22
 
25
- exports.isLogtoAccessTokenMap = isLogtoAccessTokenMap;
26
- exports.isLogtoSignInSessionItem = isLogtoSignInSessionItem;
23
+ export { isLogtoAccessTokenMap, isLogtoSignInSessionItem };
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ var js = require('@logto/js');
4
+
5
+ const buildAccessTokenKey = (resource = '', scopes = []) => `${scopes.slice().sort().join(' ')}@${resource}`;
6
+ const getDiscoveryEndpoint = (endpoint) => new URL(js.discoveryPath, endpoint).toString();
7
+
8
+ exports.buildAccessTokenKey = buildAccessTokenKey;
9
+ exports.getDiscoveryEndpoint = getDiscoveryEndpoint;
@@ -1,3 +1,3 @@
1
- export * from './requester';
1
+ export * from './requester.js';
2
2
  export declare const buildAccessTokenKey: (resource?: string, scopes?: string[]) => string;
3
3
  export declare const getDiscoveryEndpoint: (endpoint: string) => string;
@@ -1,9 +1,6 @@
1
- 'use strict';
2
-
3
- var js = require('@logto/js');
1
+ import { discoveryPath } from '@logto/js';
4
2
 
5
3
  const buildAccessTokenKey = (resource = '', scopes = []) => `${scopes.slice().sort().join(' ')}@${resource}`;
6
- const getDiscoveryEndpoint = (endpoint) => new URL(js.discoveryPath, endpoint).toString();
4
+ const getDiscoveryEndpoint = (endpoint) => new URL(discoveryPath, endpoint).toString();
7
5
 
8
- exports.buildAccessTokenKey = buildAccessTokenKey;
9
- exports.getDiscoveryEndpoint = getDiscoveryEndpoint;
6
+ export { buildAccessTokenKey, getDiscoveryEndpoint };
@@ -0,0 +1,20 @@
1
+ 'use strict';
2
+
3
+ // TODO @sijie move to essentials
4
+ /* eslint-disable @silverhand/fp/no-let */
5
+ /* eslint-disable @silverhand/fp/no-mutation */
6
+ function once(function_) {
7
+ let called = false;
8
+ let result;
9
+ return function (...args) {
10
+ if (!called) {
11
+ called = true;
12
+ result = function_.apply(this, args);
13
+ }
14
+ return result;
15
+ };
16
+ }
17
+ /* eslint-enable @silverhand/fp/no-mutation */
18
+ /* eslint-enable @silverhand/fp/no-let */
19
+
20
+ exports.once = once;
@@ -0,0 +1,3 @@
1
+ type Procedure<T> = (...args: unknown[]) => T;
2
+ export declare function once<T>(function_: Procedure<T>): Procedure<T>;
3
+ export {};
@@ -0,0 +1,18 @@
1
+ // TODO @sijie move to essentials
2
+ /* eslint-disable @silverhand/fp/no-let */
3
+ /* eslint-disable @silverhand/fp/no-mutation */
4
+ function once(function_) {
5
+ let called = false;
6
+ let result;
7
+ return function (...args) {
8
+ if (!called) {
9
+ called = true;
10
+ result = function_.apply(this, args);
11
+ }
12
+ return result;
13
+ };
14
+ }
15
+ /* eslint-enable @silverhand/fp/no-mutation */
16
+ /* eslint-enable @silverhand/fp/no-let */
17
+
18
+ export { once };
@@ -1,19 +1,21 @@
1
- import { isLogtoRequestError, LogtoError, LogtoRequestError } from '@logto/js';
1
+ 'use strict';
2
+
3
+ var js = require('@logto/js');
2
4
 
3
5
  const createRequester = (fetchFunction) => {
4
6
  return async (...args) => {
5
7
  const response = await fetchFunction(...args);
6
8
  if (!response.ok) {
7
9
  const responseJson = await response.json();
8
- if (!isLogtoRequestError(responseJson)) {
9
- throw new LogtoError('unexpected_response_error', responseJson);
10
+ if (!js.isLogtoRequestError(responseJson)) {
11
+ throw new js.LogtoError('unexpected_response_error', responseJson);
10
12
  }
11
13
  // Expected request error from server
12
14
  const { code, message } = responseJson;
13
- throw new LogtoRequestError(code, message);
15
+ throw new js.LogtoRequestError(code, message);
14
16
  }
15
17
  return response.json();
16
18
  };
17
19
  };
18
20
 
19
- export { createRequester };
21
+ exports.createRequester = createRequester;
@@ -1,21 +1,19 @@
1
- 'use strict';
2
-
3
- var js = require('@logto/js');
1
+ import { isLogtoRequestError, LogtoError, LogtoRequestError } from '@logto/js';
4
2
 
5
3
  const createRequester = (fetchFunction) => {
6
4
  return async (...args) => {
7
5
  const response = await fetchFunction(...args);
8
6
  if (!response.ok) {
9
7
  const responseJson = await response.json();
10
- if (!js.isLogtoRequestError(responseJson)) {
11
- throw new js.LogtoError('unexpected_response_error', responseJson);
8
+ if (!isLogtoRequestError(responseJson)) {
9
+ throw new LogtoError('unexpected_response_error', responseJson);
12
10
  }
13
11
  // Expected request error from server
14
12
  const { code, message } = responseJson;
15
- throw new js.LogtoRequestError(code, message);
13
+ throw new LogtoRequestError(code, message);
16
14
  }
17
15
  return response.json();
18
16
  };
19
17
  };
20
18
 
21
- exports.createRequester = createRequester;
19
+ export { createRequester };
package/package.json CHANGED
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "name": "@logto/client",
3
- "version": "1.1.2",
4
- "source": "./src/index.ts",
5
- "main": "./lib/index.js",
3
+ "version": "2.0.0",
4
+ "type": "module",
5
+ "main": "./lib/index.cjs",
6
+ "module": "./lib/index.js",
7
+ "types": "./lib/index.d.ts",
6
8
  "exports": {
7
- "require": "./lib/index.js",
8
- "import": "./lib/index.mjs"
9
+ "types": "./lib/index.d.ts",
10
+ "require": "./lib/index.cjs",
11
+ "import": "./lib/index.js",
12
+ "default": "./lib/index.js"
9
13
  },
10
- "module": "./lib/index.mjs",
11
- "types": "./lib/index.d.ts",
12
14
  "files": [
13
15
  "lib"
14
16
  ],
@@ -18,33 +20,18 @@
18
20
  "url": "https://github.com/logto-io/js.git",
19
21
  "directory": "packages/client"
20
22
  },
21
- "scripts": {
22
- "dev:tsc": "tsc -p tsconfig.build.json -w --preserveWatchOutput",
23
- "precommit": "lint-staged",
24
- "check": "tsc --noEmit",
25
- "build": "rm -rf lib/ && tsc -p tsconfig.build.json --noEmit && rollup -c",
26
- "lint": "eslint --ext .ts src",
27
- "test": "jest",
28
- "test:coverage": "jest --silent --env=jsdom && jest --silent --coverage",
29
- "prepack": "pnpm test"
30
- },
31
23
  "dependencies": {
32
- "@logto/js": "^1.1.2",
33
- "@silverhand/essentials": "^2.6.1",
24
+ "@logto/js": "^2.0.0",
25
+ "@silverhand/essentials": "^2.6.2",
34
26
  "camelcase-keys": "^7.0.1",
35
- "jose": "^4.13.2",
36
- "lodash.get": "^4.4.2",
37
- "lodash.once": "^4.1.1"
27
+ "jose": "^4.13.2"
38
28
  },
39
29
  "devDependencies": {
40
- "@jest/types": "^29.5.0",
41
- "@silverhand/eslint-config": "^2.0.0",
42
- "@silverhand/ts-config": "^1.0.0",
30
+ "@silverhand/eslint-config": "^3.0.1",
31
+ "@silverhand/ts-config": "^3.0.0",
43
32
  "@swc/core": "^1.3.50",
44
33
  "@swc/jest": "^0.2.24",
45
34
  "@types/jest": "^29.5.0",
46
- "@types/lodash.get": "^4.4.6",
47
- "@types/lodash.once": "^4.1.7",
48
35
  "@types/node": "^18.0.0",
49
36
  "eslint": "^8.38.0",
50
37
  "jest": "^29.5.0",
@@ -63,5 +50,13 @@
63
50
  "publishConfig": {
64
51
  "access": "public"
65
52
  },
66
- "gitHead": "9e9a8b0887ef67baa7c3c564590bb06e7801d03e"
67
- }
53
+ "scripts": {
54
+ "dev:tsc": "tsc -p tsconfig.build.json -w --preserveWatchOutput",
55
+ "precommit": "lint-staged",
56
+ "check": "tsc --noEmit",
57
+ "build": "rm -rf lib/ && tsc -p tsconfig.build.json --noEmit && rollup -c",
58
+ "lint": "eslint --ext .ts src",
59
+ "test": "jest",
60
+ "test:coverage": "jest --silent --env=jsdom && jest --silent --coverage"
61
+ }
62
+ }
package/lib/errors.mjs DELETED
@@ -1,27 +0,0 @@
1
- import get from 'lodash.get';
2
-
3
- const logtoClientErrorCodes = Object.freeze({
4
- sign_in_session: {
5
- invalid: 'Invalid sign-in session.',
6
- not_found: 'Sign-in session not found.',
7
- },
8
- not_authenticated: 'Not authenticated.',
9
- fetch_user_info_failed: 'Unable to fetch user info. The access token may be invalid.',
10
- });
11
- const getMessageByErrorCode = (errorCode) => {
12
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
13
- const message = get(logtoClientErrorCodes, errorCode);
14
- if (typeof message === 'string') {
15
- return message;
16
- }
17
- return errorCode;
18
- };
19
- class LogtoClientError extends Error {
20
- constructor(code, data) {
21
- super(getMessageByErrorCode(code));
22
- this.code = code;
23
- this.data = data;
24
- }
25
- }
26
-
27
- export { LogtoClientError };
@@ -1,6 +0,0 @@
1
- import { discoveryPath } from '@logto/js';
2
-
3
- const buildAccessTokenKey = (resource = '', scopes = []) => `${scopes.slice().sort().join(' ')}@${resource}`;
4
- const getDiscoveryEndpoint = (endpoint) => new URL(discoveryPath, endpoint).toString();
5
-
6
- export { buildAccessTokenKey, getDiscoveryEndpoint };