@workos-inc/node 7.60.0 → 7.62.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/common/exceptions/parse-error.d.ts +8 -0
- package/lib/common/exceptions/parse-error.js +13 -0
- package/lib/user-management/fixtures/list-sessions.json +22 -0
- package/lib/user-management/interfaces/index.d.ts +1 -0
- package/lib/user-management/interfaces/index.js +1 -0
- package/lib/user-management/interfaces/list-sessions-options.interface.d.ts +5 -0
- package/lib/user-management/interfaces/list-sessions-options.interface.js +2 -0
- package/lib/user-management/interfaces/session.interface.d.ts +14 -0
- package/lib/user-management/serializers/index.d.ts +2 -0
- package/lib/user-management/serializers/index.js +2 -0
- package/lib/user-management/serializers/list-sessions-options.serializer.d.ts +2 -0
- package/lib/user-management/serializers/list-sessions-options.serializer.js +5 -0
- package/lib/user-management/serializers/session.serializer.js +6 -0
- package/lib/user-management/session.d.ts +1 -1
- package/lib/user-management/session.js +3 -3
- package/lib/user-management/session.spec.js +1 -1
- package/lib/user-management/user-management.d.ts +4 -3
- package/lib/user-management/user-management.js +6 -1
- package/lib/user-management/user-management.spec.js +30 -0
- package/lib/workos.d.ts +1 -0
- package/lib/workos.js +40 -7
- package/lib/workos.spec.js +65 -0
- package/package.json +1 -1
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { RequestException } from '../interfaces/request-exception.interface';
|
|
2
|
+
export declare class ParseError extends Error implements RequestException {
|
|
3
|
+
readonly name = "ParseError";
|
|
4
|
+
readonly status = 500;
|
|
5
|
+
readonly rawBody: string;
|
|
6
|
+
readonly requestID: string;
|
|
7
|
+
constructor(message: string, rawBody: string, requestID: string);
|
|
8
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ParseError = void 0;
|
|
4
|
+
class ParseError extends Error {
|
|
5
|
+
constructor(message, rawBody, requestID) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = 'ParseError';
|
|
8
|
+
this.status = 500;
|
|
9
|
+
this.rawBody = rawBody;
|
|
10
|
+
this.requestID = requestID;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.ParseError = ParseError;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"object": "list",
|
|
3
|
+
"data": [
|
|
4
|
+
{
|
|
5
|
+
"object": "session",
|
|
6
|
+
"id": "session_01K0T5TNC755C7FGRQFJRS4QK5",
|
|
7
|
+
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",
|
|
8
|
+
"ip_address": "192.168.65.1",
|
|
9
|
+
"user_id": "user_01K0T5T62NBSETXQD3NVGEA2RN",
|
|
10
|
+
"auth_method": "oauth",
|
|
11
|
+
"status": "active",
|
|
12
|
+
"expires_at": "2026-07-22T22:59:48.743Z",
|
|
13
|
+
"ended_at": null,
|
|
14
|
+
"created_at": "2025-07-23T04:59:48.738Z",
|
|
15
|
+
"updated_at": "2025-07-23T04:59:48.738Z"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"list_metadata": {
|
|
19
|
+
"before": null,
|
|
20
|
+
"after": null
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -25,6 +25,7 @@ export * from './invitation.interface';
|
|
|
25
25
|
export * from './list-auth-factors-options.interface';
|
|
26
26
|
export * from './list-invitations-options.interface';
|
|
27
27
|
export * from './list-organization-memberships-options.interface';
|
|
28
|
+
export * from './list-sessions-options.interface';
|
|
28
29
|
export * from './list-users-options.interface';
|
|
29
30
|
export * from './magic-auth.interface';
|
|
30
31
|
export * from './oauth-tokens.interface';
|
|
@@ -41,6 +41,7 @@ __exportStar(require("./invitation.interface"), exports);
|
|
|
41
41
|
__exportStar(require("./list-auth-factors-options.interface"), exports);
|
|
42
42
|
__exportStar(require("./list-invitations-options.interface"), exports);
|
|
43
43
|
__exportStar(require("./list-organization-memberships-options.interface"), exports);
|
|
44
|
+
__exportStar(require("./list-sessions-options.interface"), exports);
|
|
44
45
|
__exportStar(require("./list-users-options.interface"), exports);
|
|
45
46
|
__exportStar(require("./magic-auth.interface"), exports);
|
|
46
47
|
__exportStar(require("./oauth-tokens.interface"), exports);
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Impersonator } from './impersonator.interface';
|
|
2
|
+
export type AuthMethod = 'external_auth' | 'impersonation' | 'magic_code' | 'migrated_session' | 'oauth' | 'passkey' | 'password' | 'sso' | 'unknown';
|
|
3
|
+
export type SessionStatus = 'active' | 'expired' | 'revoked';
|
|
2
4
|
export interface Session {
|
|
3
5
|
object: 'session';
|
|
4
6
|
id: string;
|
|
@@ -7,6 +9,12 @@ export interface Session {
|
|
|
7
9
|
userAgent: string | null;
|
|
8
10
|
organizationId?: string;
|
|
9
11
|
impersonator?: Impersonator;
|
|
12
|
+
authMethod: AuthMethod;
|
|
13
|
+
status: SessionStatus;
|
|
14
|
+
expiresAt: string;
|
|
15
|
+
endedAt: string | null;
|
|
16
|
+
createdAt: string;
|
|
17
|
+
updatedAt: string;
|
|
10
18
|
}
|
|
11
19
|
export interface SessionResponse {
|
|
12
20
|
object: 'session';
|
|
@@ -16,4 +24,10 @@ export interface SessionResponse {
|
|
|
16
24
|
user_agent: string | null;
|
|
17
25
|
organization_id?: string;
|
|
18
26
|
impersonator?: Impersonator;
|
|
27
|
+
auth_method: AuthMethod;
|
|
28
|
+
status: SessionStatus;
|
|
29
|
+
expires_at: string;
|
|
30
|
+
ended_at: string | null;
|
|
31
|
+
created_at: string;
|
|
32
|
+
updated_at: string;
|
|
19
33
|
}
|
|
@@ -12,10 +12,12 @@ export * from './email-verification.serializer';
|
|
|
12
12
|
export * from './enroll-auth-factor-options.serializer';
|
|
13
13
|
export * from './factor.serializer';
|
|
14
14
|
export * from './invitation.serializer';
|
|
15
|
+
export * from './list-sessions-options.serializer';
|
|
15
16
|
export * from './magic-auth.serializer';
|
|
16
17
|
export * from './password-reset.serializer';
|
|
17
18
|
export * from './reset-password-options.serializer';
|
|
18
19
|
export * from './send-password-reset-email.serializer';
|
|
20
|
+
export * from './session.serializer';
|
|
19
21
|
export * from './create-user-options.serializer';
|
|
20
22
|
export * from './send-magic-auth-code-options.serializer';
|
|
21
23
|
export * from './update-user-options.serializer';
|
|
@@ -28,10 +28,12 @@ __exportStar(require("./email-verification.serializer"), exports);
|
|
|
28
28
|
__exportStar(require("./enroll-auth-factor-options.serializer"), exports);
|
|
29
29
|
__exportStar(require("./factor.serializer"), exports);
|
|
30
30
|
__exportStar(require("./invitation.serializer"), exports);
|
|
31
|
+
__exportStar(require("./list-sessions-options.serializer"), exports);
|
|
31
32
|
__exportStar(require("./magic-auth.serializer"), exports);
|
|
32
33
|
__exportStar(require("./password-reset.serializer"), exports);
|
|
33
34
|
__exportStar(require("./reset-password-options.serializer"), exports);
|
|
34
35
|
__exportStar(require("./send-password-reset-email.serializer"), exports);
|
|
36
|
+
__exportStar(require("./session.serializer"), exports);
|
|
35
37
|
__exportStar(require("./create-user-options.serializer"), exports);
|
|
36
38
|
__exportStar(require("./send-magic-auth-code-options.serializer"), exports);
|
|
37
39
|
__exportStar(require("./update-user-options.serializer"), exports);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.serializeListSessionsOptions = void 0;
|
|
4
|
+
const serializeListSessionsOptions = (options) => (Object.assign({}, options));
|
|
5
|
+
exports.serializeListSessionsOptions = serializeListSessionsOptions;
|
|
@@ -9,5 +9,11 @@ const deserializeSession = (session) => ({
|
|
|
9
9
|
userAgent: session.user_agent,
|
|
10
10
|
organizationId: session.organization_id,
|
|
11
11
|
impersonator: session.impersonator,
|
|
12
|
+
authMethod: session.auth_method,
|
|
13
|
+
status: session.status,
|
|
14
|
+
expiresAt: session.expires_at,
|
|
15
|
+
endedAt: session.ended_at,
|
|
16
|
+
createdAt: session.created_at,
|
|
17
|
+
updatedAt: session.updated_at,
|
|
12
18
|
});
|
|
13
19
|
exports.deserializeSession = deserializeSession;
|
|
@@ -9,11 +9,11 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
12
|
+
exports.CookieSession = void 0;
|
|
13
13
|
const jose_1 = require("jose");
|
|
14
14
|
const oauth_exception_1 = require("../common/exceptions/oauth.exception");
|
|
15
15
|
const interfaces_1 = require("./interfaces");
|
|
16
|
-
class
|
|
16
|
+
class CookieSession {
|
|
17
17
|
constructor(userManagement, sessionData, cookiePassword) {
|
|
18
18
|
if (!cookiePassword) {
|
|
19
19
|
throw new Error('cookiePassword is required');
|
|
@@ -180,4 +180,4 @@ class Session {
|
|
|
180
180
|
});
|
|
181
181
|
}
|
|
182
182
|
}
|
|
183
|
-
exports.
|
|
183
|
+
exports.CookieSession = CookieSession;
|
|
@@ -64,7 +64,7 @@ describe('Session', () => {
|
|
|
64
64
|
sessionData: 'sessionData',
|
|
65
65
|
cookiePassword: 'cookiePassword',
|
|
66
66
|
});
|
|
67
|
-
expect(session).toBeInstanceOf(session_1.
|
|
67
|
+
expect(session).toBeInstanceOf(session_1.CookieSession);
|
|
68
68
|
});
|
|
69
69
|
});
|
|
70
70
|
describe('authenticate', () => {
|
|
@@ -3,7 +3,7 @@ import { IronSessionProvider } from '../common/iron-session/iron-session-provide
|
|
|
3
3
|
import { AutoPaginatable } from '../common/utils/pagination';
|
|
4
4
|
import { Challenge } from '../mfa/interfaces';
|
|
5
5
|
import { WorkOS } from '../workos';
|
|
6
|
-
import { AuthenticateWithCodeOptions, AuthenticateWithCodeAndVerifierOptions, AuthenticateWithMagicAuthOptions, AuthenticateWithPasswordOptions, AuthenticateWithRefreshTokenOptions, AuthenticateWithTotpOptions, AuthenticationResponse, CreateMagicAuthOptions, CreatePasswordResetOptions, CreateUserOptions, EmailVerification, EnrollAuthFactorOptions, ListAuthFactorsOptions, ListUsersOptions, MagicAuth, PasswordReset, ResetPasswordOptions, SendMagicAuthCodeOptions, SendPasswordResetEmailOptions, SendVerificationEmailOptions, UpdateUserOptions, User, VerifyEmailOptions } from './interfaces';
|
|
6
|
+
import { AuthenticateWithCodeOptions, AuthenticateWithCodeAndVerifierOptions, AuthenticateWithMagicAuthOptions, AuthenticateWithPasswordOptions, AuthenticateWithRefreshTokenOptions, AuthenticateWithTotpOptions, AuthenticationResponse, CreateMagicAuthOptions, CreatePasswordResetOptions, CreateUserOptions, EmailVerification, EnrollAuthFactorOptions, ListAuthFactorsOptions, ListSessionsOptions, ListUsersOptions, MagicAuth, PasswordReset, ResetPasswordOptions, SendMagicAuthCodeOptions, SendPasswordResetEmailOptions, SendVerificationEmailOptions, Session, UpdateUserOptions, User, VerifyEmailOptions } from './interfaces';
|
|
7
7
|
import { AuthenticateWithEmailVerificationOptions } from './interfaces/authenticate-with-email-verification-options.interface';
|
|
8
8
|
import { AuthenticateWithOrganizationSelectionOptions } from './interfaces/authenticate-with-organization-selection.interface';
|
|
9
9
|
import { AuthenticateWithSessionCookieFailedResponse, AuthenticateWithSessionCookieOptions, AuthenticateWithSessionCookieSuccessResponse, SessionCookieData } from './interfaces/authenticate-with-session-cookie.interface';
|
|
@@ -20,7 +20,7 @@ import { RevokeSessionOptions } from './interfaces/revoke-session-options.interf
|
|
|
20
20
|
import { SendInvitationOptions } from './interfaces/send-invitation-options.interface';
|
|
21
21
|
import { SessionHandlerOptions } from './interfaces/session-handler-options.interface';
|
|
22
22
|
import { UpdateOrganizationMembershipOptions } from './interfaces/update-organization-membership-options.interface';
|
|
23
|
-
import {
|
|
23
|
+
import { CookieSession } from './session';
|
|
24
24
|
export declare class UserManagement {
|
|
25
25
|
private readonly workos;
|
|
26
26
|
private _jwks;
|
|
@@ -39,7 +39,7 @@ export declare class UserManagement {
|
|
|
39
39
|
loadSealedSession(options: {
|
|
40
40
|
sessionData: string;
|
|
41
41
|
cookiePassword: string;
|
|
42
|
-
}):
|
|
42
|
+
}): CookieSession;
|
|
43
43
|
getUser(userId: string): Promise<User>;
|
|
44
44
|
getUserByExternalId(externalId: string): Promise<User>;
|
|
45
45
|
listUsers(options?: ListUsersOptions): Promise<AutoPaginatable<User>>;
|
|
@@ -91,6 +91,7 @@ export declare class UserManagement {
|
|
|
91
91
|
authenticationChallenge: Challenge;
|
|
92
92
|
}>;
|
|
93
93
|
listAuthFactors(options: ListAuthFactorsOptions): Promise<AutoPaginatable<Factor>>;
|
|
94
|
+
listSessions(userId: string, options?: ListSessionsOptions): Promise<AutoPaginatable<Session>>;
|
|
94
95
|
deleteUser(userId: string): Promise<void>;
|
|
95
96
|
getUserIdentities(userId: string): Promise<Identity[]>;
|
|
96
97
|
getOrganizationMembership(organizationMembershipId: string): Promise<OrganizationMembership>;
|
|
@@ -83,7 +83,7 @@ class UserManagement {
|
|
|
83
83
|
* @returns The session class.
|
|
84
84
|
*/
|
|
85
85
|
loadSealedSession(options) {
|
|
86
|
-
return new session_1.
|
|
86
|
+
return new session_1.CookieSession(this, options.sessionData, options.cookiePassword);
|
|
87
87
|
}
|
|
88
88
|
getUser(userId) {
|
|
89
89
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -434,6 +434,11 @@ class UserManagement {
|
|
|
434
434
|
return new pagination_1.AutoPaginatable(yield (0, fetch_and_deserialize_1.fetchAndDeserialize)(this.workos, `/user_management/users/${userId}/auth_factors`, factor_serializer_1.deserializeFactor, restOfOptions), (params) => (0, fetch_and_deserialize_1.fetchAndDeserialize)(this.workos, `/user_management/users/${userId}/auth_factors`, factor_serializer_1.deserializeFactor, params), restOfOptions);
|
|
435
435
|
});
|
|
436
436
|
}
|
|
437
|
+
listSessions(userId, options) {
|
|
438
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
439
|
+
return new pagination_1.AutoPaginatable(yield (0, fetch_and_deserialize_1.fetchAndDeserialize)(this.workos, `/user_management/users/${userId}/sessions`, serializers_2.deserializeSession, options ? (0, serializers_2.serializeListSessionsOptions)(options) : undefined), (params) => (0, fetch_and_deserialize_1.fetchAndDeserialize)(this.workos, `/user_management/users/${userId}/sessions`, serializers_2.deserializeSession, params), options ? (0, serializers_2.serializeListSessionsOptions)(options) : undefined);
|
|
440
|
+
});
|
|
441
|
+
}
|
|
437
442
|
deleteUser(userId) {
|
|
438
443
|
return __awaiter(this, void 0, void 0, function* () {
|
|
439
444
|
yield this.workos.delete(`/user_management/users/${userId}`);
|
|
@@ -44,6 +44,7 @@ const invitation_json_1 = __importDefault(require("./fixtures/invitation.json"))
|
|
|
44
44
|
const list_factors_json_1 = __importDefault(require("./fixtures/list-factors.json"));
|
|
45
45
|
const list_invitations_json_1 = __importDefault(require("./fixtures/list-invitations.json"));
|
|
46
46
|
const list_organization_memberships_json_1 = __importDefault(require("./fixtures/list-organization-memberships.json"));
|
|
47
|
+
const list_sessions_json_1 = __importDefault(require("./fixtures/list-sessions.json"));
|
|
47
48
|
const list_users_json_1 = __importDefault(require("./fixtures/list-users.json"));
|
|
48
49
|
const magic_auth_json_1 = __importDefault(require("./fixtures/magic_auth.json"));
|
|
49
50
|
const organization_membership_json_1 = __importDefault(require("./fixtures/organization-membership.json"));
|
|
@@ -1297,6 +1298,35 @@ describe('UserManagement', () => {
|
|
|
1297
1298
|
});
|
|
1298
1299
|
}));
|
|
1299
1300
|
});
|
|
1301
|
+
describe('listSessions', () => {
|
|
1302
|
+
it('sends a listSessions request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1303
|
+
(0, test_utils_1.fetchOnce)(list_sessions_json_1.default);
|
|
1304
|
+
const resp = yield workos.userManagement.listSessions(userId);
|
|
1305
|
+
expect((0, test_utils_1.fetchURL)()).toContain(`/user_management/users/${userId}/sessions`);
|
|
1306
|
+
expect(resp).toMatchObject({
|
|
1307
|
+
object: 'list',
|
|
1308
|
+
data: [
|
|
1309
|
+
{
|
|
1310
|
+
object: 'session',
|
|
1311
|
+
id: 'session_01K0T5TNC755C7FGRQFJRS4QK5',
|
|
1312
|
+
userId: 'user_01K0T5T62NBSETXQD3NVGEA2RN',
|
|
1313
|
+
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36',
|
|
1314
|
+
ipAddress: '192.168.65.1',
|
|
1315
|
+
authMethod: 'oauth',
|
|
1316
|
+
status: 'active',
|
|
1317
|
+
expiresAt: '2026-07-22T22:59:48.743Z',
|
|
1318
|
+
endedAt: null,
|
|
1319
|
+
createdAt: '2025-07-23T04:59:48.738Z',
|
|
1320
|
+
updatedAt: '2025-07-23T04:59:48.738Z',
|
|
1321
|
+
},
|
|
1322
|
+
],
|
|
1323
|
+
listMetadata: {
|
|
1324
|
+
before: null,
|
|
1325
|
+
after: null,
|
|
1326
|
+
},
|
|
1327
|
+
});
|
|
1328
|
+
}));
|
|
1329
|
+
});
|
|
1300
1330
|
describe('deleteUser', () => {
|
|
1301
1331
|
it('sends a deleteUser request', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
1302
1332
|
(0, test_utils_1.fetchOnce)();
|
package/lib/workos.d.ts
CHANGED
package/lib/workos.js
CHANGED
|
@@ -31,7 +31,8 @@ const widgets_1 = require("./widgets/widgets");
|
|
|
31
31
|
const actions_1 = require("./actions/actions");
|
|
32
32
|
const vault_1 = require("./vault/vault");
|
|
33
33
|
const conflict_exception_1 = require("./common/exceptions/conflict.exception");
|
|
34
|
-
const
|
|
34
|
+
const parse_error_1 = require("./common/exceptions/parse-error");
|
|
35
|
+
const VERSION = '7.62.0';
|
|
35
36
|
const DEFAULT_HOSTNAME = 'api.workos.com';
|
|
36
37
|
const HEADER_AUTHORIZATION = 'Authorization';
|
|
37
38
|
const HEADER_IDEMPOTENCY_KEY = 'Idempotency-Key';
|
|
@@ -115,17 +116,24 @@ class WorkOS {
|
|
|
115
116
|
if (options.warrantToken) {
|
|
116
117
|
requestHeaders[HEADER_WARRANT_TOKEN] = options.warrantToken;
|
|
117
118
|
}
|
|
119
|
+
let res;
|
|
118
120
|
try {
|
|
119
|
-
|
|
121
|
+
res = yield this.client.post(path, entity, {
|
|
120
122
|
params: options.query,
|
|
121
123
|
headers: requestHeaders,
|
|
122
124
|
});
|
|
123
|
-
return { data: yield res.toJSON() };
|
|
124
125
|
}
|
|
125
126
|
catch (error) {
|
|
126
127
|
this.handleHttpError({ path, error });
|
|
127
128
|
throw error;
|
|
128
129
|
}
|
|
130
|
+
try {
|
|
131
|
+
return { data: yield res.toJSON() };
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
yield this.handleParseError(error, res);
|
|
135
|
+
throw error;
|
|
136
|
+
}
|
|
129
137
|
});
|
|
130
138
|
}
|
|
131
139
|
get(path, options = {}) {
|
|
@@ -137,17 +145,24 @@ class WorkOS {
|
|
|
137
145
|
if (options.warrantToken) {
|
|
138
146
|
requestHeaders[HEADER_WARRANT_TOKEN] = options.warrantToken;
|
|
139
147
|
}
|
|
148
|
+
let res;
|
|
140
149
|
try {
|
|
141
|
-
|
|
150
|
+
res = yield this.client.get(path, {
|
|
142
151
|
params: options.query,
|
|
143
152
|
headers: requestHeaders,
|
|
144
153
|
});
|
|
145
|
-
return { data: yield res.toJSON() };
|
|
146
154
|
}
|
|
147
155
|
catch (error) {
|
|
148
156
|
this.handleHttpError({ path, error });
|
|
149
157
|
throw error;
|
|
150
158
|
}
|
|
159
|
+
try {
|
|
160
|
+
return { data: yield res.toJSON() };
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
yield this.handleParseError(error, res);
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
151
166
|
});
|
|
152
167
|
}
|
|
153
168
|
put(path, entity, options = {}) {
|
|
@@ -156,17 +171,24 @@ class WorkOS {
|
|
|
156
171
|
if (options.idempotencyKey) {
|
|
157
172
|
requestHeaders[HEADER_IDEMPOTENCY_KEY] = options.idempotencyKey;
|
|
158
173
|
}
|
|
174
|
+
let res;
|
|
159
175
|
try {
|
|
160
|
-
|
|
176
|
+
res = yield this.client.put(path, entity, {
|
|
161
177
|
params: options.query,
|
|
162
178
|
headers: requestHeaders,
|
|
163
179
|
});
|
|
164
|
-
return { data: yield res.toJSON() };
|
|
165
180
|
}
|
|
166
181
|
catch (error) {
|
|
167
182
|
this.handleHttpError({ path, error });
|
|
168
183
|
throw error;
|
|
169
184
|
}
|
|
185
|
+
try {
|
|
186
|
+
return { data: yield res.toJSON() };
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
yield this.handleParseError(error, res);
|
|
190
|
+
throw error;
|
|
191
|
+
}
|
|
170
192
|
});
|
|
171
193
|
}
|
|
172
194
|
delete(path, query) {
|
|
@@ -186,6 +208,17 @@ class WorkOS {
|
|
|
186
208
|
// tslint:disable-next-line:no-console
|
|
187
209
|
console.warn(`WorkOS: ${warning}`);
|
|
188
210
|
}
|
|
211
|
+
handleParseError(error, res) {
|
|
212
|
+
var _a;
|
|
213
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
214
|
+
if (error instanceof SyntaxError) {
|
|
215
|
+
const rawResponse = res.getRawResponse();
|
|
216
|
+
const requestID = (_a = rawResponse.headers.get('X-Request-ID')) !== null && _a !== void 0 ? _a : '';
|
|
217
|
+
const rawBody = yield rawResponse.text();
|
|
218
|
+
throw new parse_error_1.ParseError(error.message, rawBody, requestID);
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
189
222
|
handleHttpError({ path, error }) {
|
|
190
223
|
var _a;
|
|
191
224
|
if (!(error instanceof http_client_1.HttpClientError)) {
|
package/lib/workos.spec.js
CHANGED
|
@@ -16,6 +16,7 @@ const jest_fetch_mock_1 = __importDefault(require("jest-fetch-mock"));
|
|
|
16
16
|
const test_utils_1 = require("./common/utils/test-utils");
|
|
17
17
|
const promises_1 = __importDefault(require("fs/promises"));
|
|
18
18
|
const exceptions_1 = require("./common/exceptions");
|
|
19
|
+
const parse_error_1 = require("./common/exceptions/parse-error");
|
|
19
20
|
const index_1 = require("./index");
|
|
20
21
|
const index_worker_1 = require("./index.worker");
|
|
21
22
|
const rate_limit_exceeded_exception_1 = require("./common/exceptions/rate-limit-exceeded.exception");
|
|
@@ -218,6 +219,70 @@ describe('WorkOS', () => {
|
|
|
218
219
|
expect((0, test_utils_1.fetchBody)({ raw: true })).toBe('');
|
|
219
220
|
}));
|
|
220
221
|
});
|
|
222
|
+
describe('when the api responds with invalid JSON', () => {
|
|
223
|
+
it('throws a ParseError', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
224
|
+
const mockResponse = {
|
|
225
|
+
ok: true,
|
|
226
|
+
status: 200,
|
|
227
|
+
headers: new Headers({
|
|
228
|
+
'X-Request-ID': 'a-request-id',
|
|
229
|
+
'content-type': 'application/json',
|
|
230
|
+
}),
|
|
231
|
+
text: () => Promise.resolve('invalid json{'),
|
|
232
|
+
json: () => Promise.reject(new SyntaxError('Invalid JSON')),
|
|
233
|
+
};
|
|
234
|
+
jest_fetch_mock_1.default.mockResolvedValueOnce(mockResponse);
|
|
235
|
+
const workos = new index_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
236
|
+
const error = yield workos.post('/path', {}).catch((e) => e);
|
|
237
|
+
expect(error).toBeInstanceOf(parse_error_1.ParseError);
|
|
238
|
+
expect(error.rawBody).toBe('invalid json{');
|
|
239
|
+
expect(error.requestID).toBe('a-request-id');
|
|
240
|
+
}));
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
describe('get', () => {
|
|
244
|
+
describe('when the api responds with invalid JSON', () => {
|
|
245
|
+
it('throws a ParseError', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
246
|
+
const mockResponse = {
|
|
247
|
+
ok: true,
|
|
248
|
+
status: 200,
|
|
249
|
+
headers: new Headers({
|
|
250
|
+
'X-Request-ID': 'a-request-id',
|
|
251
|
+
'content-type': 'application/json',
|
|
252
|
+
}),
|
|
253
|
+
text: () => Promise.resolve('malformed json}'),
|
|
254
|
+
json: () => Promise.reject(new SyntaxError('Invalid JSON')),
|
|
255
|
+
};
|
|
256
|
+
jest_fetch_mock_1.default.mockResolvedValueOnce(mockResponse);
|
|
257
|
+
const workos = new index_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
258
|
+
const error = yield workos.get('/path').catch((e) => e);
|
|
259
|
+
expect(error).toBeInstanceOf(parse_error_1.ParseError);
|
|
260
|
+
expect(error.rawBody).toBe('malformed json}');
|
|
261
|
+
expect(error.requestID).toBe('a-request-id');
|
|
262
|
+
}));
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
describe('put', () => {
|
|
266
|
+
describe('when the api responds with invalid JSON', () => {
|
|
267
|
+
it('throws a ParseError', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
268
|
+
const mockResponse = {
|
|
269
|
+
ok: true,
|
|
270
|
+
status: 200,
|
|
271
|
+
headers: new Headers({
|
|
272
|
+
'X-Request-ID': 'a-request-id',
|
|
273
|
+
'content-type': 'application/json',
|
|
274
|
+
}),
|
|
275
|
+
text: () => Promise.resolve('broken json['),
|
|
276
|
+
json: () => Promise.reject(new SyntaxError('Invalid JSON')),
|
|
277
|
+
};
|
|
278
|
+
jest_fetch_mock_1.default.mockResolvedValueOnce(mockResponse);
|
|
279
|
+
const workos = new index_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
|
|
280
|
+
const error = yield workos.put('/path', {}).catch((e) => e);
|
|
281
|
+
expect(error).toBeInstanceOf(parse_error_1.ParseError);
|
|
282
|
+
expect(error.rawBody).toBe('broken json[');
|
|
283
|
+
expect(error.requestID).toBe('a-request-id');
|
|
284
|
+
}));
|
|
285
|
+
});
|
|
221
286
|
});
|
|
222
287
|
describe('when in an environment that does not support fetch', () => {
|
|
223
288
|
const fetchFn = globalThis.fetch;
|
package/package.json
CHANGED