@workos-inc/node 5.2.0 → 6.0.0-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,32 +1,41 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
4
10
  };
5
11
  Object.defineProperty(exports, "__esModule", { value: true });
6
12
  exports.Webhooks = void 0;
7
- const crypto_1 = __importDefault(require("crypto"));
8
13
  const exceptions_1 = require("../common/exceptions");
9
14
  const serializers_1 = require("../common/serializers");
10
15
  class Webhooks {
11
16
  constructEvent({ payload, sigHeader, secret, tolerance = 180000, }) {
12
- const options = { payload, sigHeader, secret, tolerance };
13
- this.verifyHeader(options);
14
- const webhookPayload = payload;
15
- return (0, serializers_1.deserializeEvent)(webhookPayload);
17
+ return __awaiter(this, void 0, void 0, function* () {
18
+ const options = { payload, sigHeader, secret, tolerance };
19
+ yield this.verifyHeader(options);
20
+ const webhookPayload = payload;
21
+ return (0, serializers_1.deserializeEvent)(webhookPayload);
22
+ });
16
23
  }
17
24
  verifyHeader({ payload, sigHeader, secret, tolerance = 180000, }) {
18
- const [timestamp, signatureHash] = this.getTimestampAndSignatureHash(sigHeader);
19
- if (!signatureHash || Object.keys(signatureHash).length === 0) {
20
- throw new exceptions_1.SignatureVerificationException('No signature hash found with expected scheme v1');
21
- }
22
- if (parseInt(timestamp, 10) < Date.now() - tolerance) {
23
- throw new exceptions_1.SignatureVerificationException('Timestamp outside the tolerance zone');
24
- }
25
- const expectedSig = this.computeSignature(timestamp, payload, secret);
26
- if (this.secureCompare(expectedSig, signatureHash) === false) {
27
- throw new exceptions_1.SignatureVerificationException('Signature hash does not match the expected signature hash for payload');
28
- }
29
- return true;
25
+ return __awaiter(this, void 0, void 0, function* () {
26
+ const [timestamp, signatureHash] = this.getTimestampAndSignatureHash(sigHeader);
27
+ if (!signatureHash || Object.keys(signatureHash).length === 0) {
28
+ throw new exceptions_1.SignatureVerificationException('No signature hash found with expected scheme v1');
29
+ }
30
+ if (parseInt(timestamp, 10) < Date.now() - tolerance) {
31
+ throw new exceptions_1.SignatureVerificationException('Timestamp outside the tolerance zone');
32
+ }
33
+ const expectedSig = yield this.computeSignature(timestamp, payload, secret);
34
+ if ((yield this.secureCompare(expectedSig, signatureHash)) === false) {
35
+ throw new exceptions_1.SignatureVerificationException('Signature hash does not match the expected signature hash for payload');
36
+ }
37
+ return true;
38
+ });
30
39
  }
31
40
  getTimestampAndSignatureHash(sigHeader) {
32
41
  const signature = sigHeader;
@@ -39,31 +48,44 @@ class Webhooks {
39
48
  return [timestamp, signatureHash];
40
49
  }
41
50
  computeSignature(timestamp, payload, secret) {
42
- payload = JSON.stringify(payload);
43
- const signedPayload = `${timestamp}.${payload}`;
44
- const expectedSignature = crypto_1.default
45
- .createHmac('sha256', secret)
46
- .update(signedPayload)
47
- .digest()
48
- .toString('hex');
49
- return expectedSignature;
51
+ return __awaiter(this, void 0, void 0, function* () {
52
+ payload = JSON.stringify(payload);
53
+ const signedPayload = `${timestamp}.${payload}`;
54
+ const key = yield crypto.subtle.importKey('raw', new TextEncoder().encode(secret), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
55
+ const signatureBuffer = yield crypto.subtle.sign('HMAC', key, new TextEncoder().encode(signedPayload));
56
+ // crypto.subtle returns the signature in base64 format. This must be
57
+ // encoded in hex to match the CryptoProvider contract. We map each byte in
58
+ // the buffer to its corresponding hex octet and then combine into a string.
59
+ const signatureBytes = new Uint8Array(signatureBuffer);
60
+ const signatureHexCodes = new Array(signatureBytes.length);
61
+ for (let i = 0; i < signatureBytes.length; i++) {
62
+ signatureHexCodes[i] = byteHexMapping[signatureBytes[i]];
63
+ }
64
+ return signatureHexCodes.join('');
65
+ });
50
66
  }
51
67
  secureCompare(stringA, stringB) {
52
- const strA = Buffer.from(stringA);
53
- const strB = Buffer.from(stringB);
54
- if (strA.length !== strB.length) {
55
- return false;
56
- }
57
- if (crypto_1.default.timingSafeEqual) {
58
- return crypto_1.default.timingSafeEqual(strA, strB);
59
- }
60
- const len = strA.length;
61
- let result = 0;
62
- for (let i = 0; i < len; ++i) {
63
- // tslint:disable-next-line:no-bitwise
64
- result |= strA[i] ^ strB[i];
65
- }
66
- return result === 0;
68
+ return __awaiter(this, void 0, void 0, function* () {
69
+ const bufferA = Buffer.from(stringA);
70
+ const bufferB = Buffer.from(stringB);
71
+ if (bufferA.length !== bufferB.length) {
72
+ return false;
73
+ }
74
+ const algorithm = { name: 'HMAC', hash: 'SHA-256' };
75
+ const key = (yield crypto.subtle.generateKey(algorithm, false, [
76
+ 'sign',
77
+ 'verify',
78
+ ]));
79
+ const hmac = yield crypto.subtle.sign(algorithm, key, bufferA);
80
+ const equal = yield crypto.subtle.verify(algorithm, key, hmac, bufferB);
81
+ return equal;
82
+ });
67
83
  }
68
84
  }
69
85
  exports.Webhooks = Webhooks;
86
+ // Cached mapping of byte to hex representation. We do this once to avoid re-
87
+ // computing every time we need to convert the result of a signature to hex.
88
+ const byteHexMapping = new Array(256);
89
+ for (let i = 0; i < byteHexMapping.length; i++) {
90
+ byteHexMapping[i] = i.toString(16).padStart(2, '0');
91
+ }
@@ -1,4 +1,13 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
13
  };
@@ -90,76 +99,77 @@ describe('Webhooks', () => {
90
99
  });
91
100
  describe('constructEvent', () => {
92
101
  describe('with the correct payload, sig_header, and secret', () => {
93
- it('returns a webhook event', () => {
102
+ it('returns a webhook event', () => __awaiter(void 0, void 0, void 0, function* () {
94
103
  const sigHeader = `t=${timestamp}, v1=${signatureHash}`;
95
104
  const options = { payload, sigHeader, secret };
96
- const webhook = workos.webhooks.constructEvent(options);
105
+ const webhook = yield workos.webhooks.constructEvent(options);
97
106
  expect(webhook.data).toEqual(expectation);
98
107
  expect(webhook.event).toEqual('dsync.user.created');
99
108
  expect(webhook.id).toEqual('wh_123');
100
- });
109
+ }));
101
110
  });
102
111
  describe('with the correct payload, sig_header, secret, and tolerance', () => {
103
- it('returns a webhook event', () => {
112
+ it('returns a webhook event', () => __awaiter(void 0, void 0, void 0, function* () {
104
113
  const sigHeader = `t=${timestamp}, v1=${signatureHash}`;
105
114
  const options = { payload, sigHeader, secret, tolerance: 200 };
106
- const webhook = workos.webhooks.constructEvent(options);
115
+ const webhook = yield workos.webhooks.constructEvent(options);
107
116
  expect(webhook.data).toEqual(expectation);
108
117
  expect(webhook.event).toEqual('dsync.user.created');
109
118
  expect(webhook.id).toEqual('wh_123');
110
- });
119
+ }));
111
120
  });
112
121
  describe('with an empty header', () => {
113
- it('raises an error', () => {
122
+ it('raises an error', () => __awaiter(void 0, void 0, void 0, function* () {
114
123
  const sigHeader = '';
115
124
  const options = { payload, sigHeader, secret };
116
- expect(() => workos.webhooks.constructEvent(options)).toThrowError(exceptions_1.SignatureVerificationException);
117
- });
125
+ yield expect(workos.webhooks.constructEvent(options)).rejects.toThrowError(exceptions_1.SignatureVerificationException);
126
+ }));
118
127
  });
119
128
  describe('with an empty signature hash', () => {
120
- it('raises an error', () => {
129
+ it('raises an error', () => __awaiter(void 0, void 0, void 0, function* () {
121
130
  const sigHeader = `t=${timestamp}, v1=`;
122
131
  const options = { payload, sigHeader, secret };
123
- expect(() => workos.webhooks.constructEvent(options)).toThrowError(exceptions_1.SignatureVerificationException);
124
- });
132
+ yield expect(workos.webhooks.constructEvent(options)).rejects.toThrowError(exceptions_1.SignatureVerificationException);
133
+ }));
125
134
  });
126
135
  describe('with an incorrect signature hash', () => {
127
- it('raises an error', () => {
136
+ it('raises an error', () => __awaiter(void 0, void 0, void 0, function* () {
128
137
  const sigHeader = `t=${timestamp}, v1=99999`;
129
138
  const options = { payload, sigHeader, secret };
130
- expect(() => workos.webhooks.constructEvent(options)).toThrowError(exceptions_1.SignatureVerificationException);
131
- });
139
+ yield expect(workos.webhooks.constructEvent(options)).rejects.toThrowError(exceptions_1.SignatureVerificationException);
140
+ }));
132
141
  });
133
142
  describe('with an incorrect payload', () => {
134
- it('raises an error', () => {
143
+ it('raises an error', () => __awaiter(void 0, void 0, void 0, function* () {
135
144
  const sigHeader = `t=${timestamp}, v1=${signatureHash}`;
136
145
  payload = 'invalid';
137
146
  const options = { payload, sigHeader, secret };
138
- expect(() => workos.webhooks.constructEvent(options)).toThrowError(exceptions_1.SignatureVerificationException);
139
- });
147
+ yield expect(workos.webhooks.constructEvent(options)).rejects.toThrowError(exceptions_1.SignatureVerificationException);
148
+ }));
140
149
  });
141
150
  describe('with an incorrect webhook secret', () => {
142
- it('raises an error', () => {
151
+ it('raises an error', () => __awaiter(void 0, void 0, void 0, function* () {
143
152
  const sigHeader = `t=${timestamp}, v1=${signatureHash}`;
144
153
  secret = 'invalid';
145
154
  const options = { payload, sigHeader, secret };
146
- expect(() => workos.webhooks.constructEvent(options)).toThrowError(exceptions_1.SignatureVerificationException);
147
- });
155
+ yield expect(workos.webhooks.constructEvent(options)).rejects.toThrowError(exceptions_1.SignatureVerificationException);
156
+ }));
148
157
  });
149
158
  describe('with a timestamp outside tolerance', () => {
150
- it('raises an error', () => {
159
+ it('raises an error', () => __awaiter(void 0, void 0, void 0, function* () {
151
160
  const sigHeader = `t=9999, v1=${signatureHash}`;
152
161
  const options = { payload, sigHeader, secret };
153
- expect(() => workos.webhooks.constructEvent(options)).toThrowError(exceptions_1.SignatureVerificationException);
154
- });
162
+ yield expect(workos.webhooks.constructEvent(options)).rejects.toThrowError(exceptions_1.SignatureVerificationException);
163
+ }));
155
164
  });
156
165
  });
157
166
  describe('verifyHeader', () => {
158
- it('returns true when the signature is valid', () => {
167
+ it('returns true when the signature is valid', () => __awaiter(void 0, void 0, void 0, function* () {
159
168
  const sigHeader = `t=${timestamp}, v1=${signatureHash}`;
160
169
  const options = { payload, sigHeader, secret };
161
- expect(() => workos.webhooks.verifyHeader(options)).toBeTruthy();
162
- });
170
+ const result = yield workos.webhooks.verifyHeader(options);
171
+ expect(result).toBeTruthy();
172
+ }));
163
173
  });
164
174
  describe('getTimestampAndSignatureHash', () => {
165
175
  it('returns the timestamp and signature when the signature is valid', () => {
@@ -172,9 +182,9 @@ describe('Webhooks', () => {
172
182
  });
173
183
  });
174
184
  describe('computeSignature', () => {
175
- it('returns the computed signature', () => {
176
- const signature = workos.webhooks.computeSignature(timestamp, payload, secret);
185
+ it('returns the computed signature', () => __awaiter(void 0, void 0, void 0, function* () {
186
+ const signature = yield workos.webhooks.computeSignature(timestamp, payload, secret);
177
187
  expect(signature).toEqual(signatureHash);
178
- });
188
+ }));
179
189
  });
180
190
  });
package/lib/workos.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { AxiosResponse } from 'axios';
2
1
  import { GetOptions, PostOptions, PutOptions, WorkOSOptions } from './common/interfaces';
3
2
  import { DirectorySync } from './directory-sync/directory-sync';
4
3
  import { Events } from './events/events';
@@ -29,10 +28,16 @@ export declare class WorkOS {
29
28
  readonly userManagement: UserManagement;
30
29
  constructor(key?: string | undefined, options?: WorkOSOptions);
31
30
  get version(): string;
32
- post<T = any, D = any, P = any>(path: string, entity: P, options?: PostOptions): Promise<AxiosResponse<T, D>>;
33
- get<T = any, D = any>(path: string, options?: GetOptions): Promise<AxiosResponse<T, D>>;
34
- put<T = any, D = any>(path: string, entity: any, options?: PutOptions): Promise<AxiosResponse<T, D>>;
35
- delete<T = any, D = any>(path: string, query?: any): Promise<AxiosResponse<T, D>>;
31
+ post<Result = any, Entity = any>(path: string, entity: Entity, options?: PostOptions): Promise<{
32
+ data: Result;
33
+ }>;
34
+ get<Result = any>(path: string, options?: GetOptions): Promise<{
35
+ data: Result;
36
+ }>;
37
+ put<Result = any, Entity = any>(path: string, entity: Entity, options?: PutOptions): Promise<{
38
+ data: Result;
39
+ }>;
40
+ delete(path: string, query?: any): Promise<void>;
36
41
  emitWarning(warning: string): void;
37
- private handleAxiosError;
42
+ private handleFetchError;
38
43
  }
package/lib/workos.js CHANGED
@@ -8,12 +8,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
11
  Object.defineProperty(exports, "__esModule", { value: true });
15
12
  exports.WorkOS = void 0;
16
- const axios_1 = __importDefault(require("axios"));
17
13
  const exceptions_1 = require("./common/exceptions");
18
14
  const directory_sync_1 = require("./directory-sync/directory-sync");
19
15
  const events_1 = require("./events/events");
@@ -27,7 +23,8 @@ const mfa_1 = require("./mfa/mfa");
27
23
  const audit_logs_1 = require("./audit-logs/audit-logs");
28
24
  const user_management_1 = require("./user-management/user-management");
29
25
  const bad_request_exception_1 = require("./common/exceptions/bad-request.exception");
30
- const VERSION = '5.2.0';
26
+ const fetch_client_1 = require("./common/utils/fetch-client");
27
+ const VERSION = '6.0.0-rc.2';
31
28
  const DEFAULT_HOSTNAME = 'api.workos.com';
32
29
  class WorkOS {
33
30
  constructor(key, options = {}) {
@@ -46,7 +43,8 @@ class WorkOS {
46
43
  this.events = new events_1.Events(this);
47
44
  this.userManagement = new user_management_1.UserManagement(this);
48
45
  if (!key) {
49
- this.key = process.env.WORKOS_API_KEY;
46
+ // process might be undefined in some environments
47
+ this.key = process === null || process === void 0 ? void 0 : process.env.WORKOS_API_KEY;
50
48
  if (!this.key) {
51
49
  throw new exceptions_1.NoApiKeyProvidedException();
52
50
  }
@@ -61,7 +59,7 @@ class WorkOS {
61
59
  if (port) {
62
60
  this.baseURL = this.baseURL + `:${port}`;
63
61
  }
64
- this.client = axios_1.default.create(Object.assign(Object.assign({}, options.axios), { baseURL: this.baseURL, headers: Object.assign(Object.assign({}, (_a = options.axios) === null || _a === void 0 ? void 0 : _a.headers), { Authorization: `Bearer ${this.key}`, 'User-Agent': `workos-node/${VERSION}` }) }));
62
+ this.client = new fetch_client_1.FetchClient(this.baseURL, Object.assign(Object.assign({}, options.config), { headers: Object.assign(Object.assign({}, (_a = options.config) === null || _a === void 0 ? void 0 : _a.headers), { Authorization: `Bearer ${this.key}`, 'User-Agent': `workos-node/${VERSION}` }) }));
65
63
  }
66
64
  get version() {
67
65
  return VERSION;
@@ -79,7 +77,7 @@ class WorkOS {
79
77
  });
80
78
  }
81
79
  catch (error) {
82
- this.handleAxiosError({ path, error });
80
+ this.handleFetchError({ path, error });
83
81
  throw error;
84
82
  }
85
83
  });
@@ -91,14 +89,12 @@ class WorkOS {
91
89
  return yield this.client.get(path, {
92
90
  params: options.query,
93
91
  headers: accessToken
94
- ? {
95
- Authorization: `Bearer ${accessToken}`,
96
- }
92
+ ? { Authorization: `Bearer ${accessToken}` }
97
93
  : undefined,
98
94
  });
99
95
  }
100
96
  catch (error) {
101
- this.handleAxiosError({ path, error });
97
+ this.handleFetchError({ path, error });
102
98
  throw error;
103
99
  }
104
100
  });
@@ -116,7 +112,7 @@ class WorkOS {
116
112
  });
117
113
  }
118
114
  catch (error) {
119
- this.handleAxiosError({ path, error });
115
+ this.handleFetchError({ path, error });
120
116
  throw error;
121
117
  }
122
118
  });
@@ -124,35 +120,36 @@ class WorkOS {
124
120
  delete(path, query) {
125
121
  return __awaiter(this, void 0, void 0, function* () {
126
122
  try {
127
- return yield this.client.delete(path, {
123
+ yield this.client.delete(path, {
128
124
  params: query,
129
125
  });
130
126
  }
131
127
  catch (error) {
132
- this.handleAxiosError({ path, error });
128
+ this.handleFetchError({ path, error });
133
129
  throw error;
134
130
  }
135
131
  });
136
132
  }
137
133
  emitWarning(warning) {
138
- if (typeof process.emitWarning !== 'function') {
134
+ // process might be undefined in some environments
135
+ if (typeof (process === null || process === void 0 ? void 0 : process.emitWarning) !== 'function') {
139
136
  // tslint:disable:no-console
140
137
  return console.warn(`WorkOS: ${warning}`);
141
138
  }
142
139
  return process.emitWarning(warning, 'WorkOS');
143
140
  }
144
- handleAxiosError({ path, error }) {
141
+ handleFetchError({ path, error }) {
142
+ var _a;
145
143
  const { response } = error;
146
144
  if (response) {
147
145
  const { status, data, headers } = response;
148
- const requestID = headers['X-Request-ID'];
146
+ const requestID = (_a = headers.get('X-Request-ID')) !== null && _a !== void 0 ? _a : '';
149
147
  const { code, error_description: errorDescription, error, errors, message, } = data;
150
148
  switch (status) {
151
149
  case 401: {
152
150
  throw new exceptions_1.UnauthorizedException(requestID);
153
151
  }
154
152
  case 422: {
155
- const { errors } = data;
156
153
  throw new exceptions_1.UnprocessableEntityException({
157
154
  code,
158
155
  errors,
@@ -12,13 +12,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
- const axios_1 = __importDefault(require("axios"));
16
- const axios_mock_adapter_1 = __importDefault(require("axios-mock-adapter"));
15
+ const jest_fetch_mock_1 = __importDefault(require("jest-fetch-mock"));
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
19
  const workos_1 = require("./workos");
20
- const mock = new axios_mock_adapter_1.default(axios_1.default);
21
20
  describe('WorkOS', () => {
21
+ beforeEach(() => jest_fetch_mock_1.default.resetMocks());
22
22
  describe('constructor', () => {
23
23
  const OLD_ENV = process.env;
24
24
  beforeEach(() => {
@@ -66,18 +66,18 @@ describe('WorkOS', () => {
66
66
  expect(workos.baseURL).toEqual('https://localhost:4000');
67
67
  });
68
68
  });
69
- describe('when the `axios` option is provided', () => {
70
- it('applies the configuration to the Axios client', () => __awaiter(void 0, void 0, void 0, function* () {
71
- mock.onPost().reply(200, 'OK', { 'X-Request-ID': 'a-request-id' });
69
+ describe('when the `config` option is provided', () => {
70
+ it('applies the configuration to the fetch client', () => __awaiter(void 0, void 0, void 0, function* () {
71
+ (0, test_utils_1.fetchOnce)('{}', { headers: { 'X-Request-ID': 'a-request-id' } });
72
72
  const workos = new workos_1.WorkOS('sk_test', {
73
- axios: {
73
+ config: {
74
74
  headers: {
75
75
  'X-My-Custom-Header': 'Hey there!',
76
76
  },
77
77
  },
78
78
  });
79
79
  yield workos.post('/somewhere', {});
80
- expect(mock.history.post[0].headers).toMatchObject({
80
+ expect((0, test_utils_1.fetchHeaders)()).toMatchObject({
81
81
  'X-My-Custom-Header': 'Hey there!',
82
82
  });
83
83
  }));
@@ -96,9 +96,7 @@ describe('WorkOS', () => {
96
96
  describe('when the api responds with a 404', () => {
97
97
  it('throws a NotFoundException', () => __awaiter(void 0, void 0, void 0, function* () {
98
98
  const message = 'Not Found';
99
- mock.onPost().reply(404, {
100
- message,
101
- }, { 'X-Request-ID': 'a-request-id' });
99
+ (0, test_utils_1.fetchOnce)({ message }, { status: 404, headers: { 'X-Request-ID': 'a-request-id' } });
102
100
  const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
103
101
  yield expect(workos.post('/path', {})).rejects.toStrictEqual(new exceptions_1.NotFoundException({
104
102
  message,
@@ -109,10 +107,7 @@ describe('WorkOS', () => {
109
107
  it('preserves the error code, status, and message from the underlying response', () => __awaiter(void 0, void 0, void 0, function* () {
110
108
  const message = 'The thing you are looking for is not here.';
111
109
  const code = 'thing-not-found';
112
- mock.onPost().reply(404, {
113
- code,
114
- message,
115
- }, { 'X-Request-ID': 'a-request-id' });
110
+ (0, test_utils_1.fetchOnce)({ code, message }, { status: 404, headers: { 'X-Request-ID': 'a-request-id' } });
116
111
  const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
117
112
  yield expect(workos.post('/path', {})).rejects.toMatchObject({
118
113
  code,
@@ -123,9 +118,7 @@ describe('WorkOS', () => {
123
118
  it('includes the path in the message if there is no message in the response', () => __awaiter(void 0, void 0, void 0, function* () {
124
119
  const code = 'thing-not-found';
125
120
  const path = '/path/to/thing/that-aint-there';
126
- mock.onPost().reply(404, {
127
- code,
128
- }, { 'X-Request-ID': 'a-request-id' });
121
+ (0, test_utils_1.fetchOnce)({ code }, { status: 404, headers: { 'X-Request-ID': 'a-request-id' } });
129
122
  const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
130
123
  yield expect(workos.post(path, {})).rejects.toMatchObject({
131
124
  code,
@@ -136,8 +129,9 @@ describe('WorkOS', () => {
136
129
  });
137
130
  describe('when the api responds with a 500 and no error/error_description', () => {
138
131
  it('throws an GenericServerException', () => __awaiter(void 0, void 0, void 0, function* () {
139
- mock.onPost().reply(500, {}, {
140
- 'X-Request-ID': 'a-request-id',
132
+ (0, test_utils_1.fetchOnce)({}, {
133
+ status: 500,
134
+ headers: { 'X-Request-ID': 'a-request-id' },
141
135
  });
142
136
  const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
143
137
  yield expect(workos.post('/path', {})).rejects.toStrictEqual(new exceptions_1.GenericServerException(500, undefined, {}, 'a-request-id'));
@@ -145,8 +139,9 @@ describe('WorkOS', () => {
145
139
  });
146
140
  describe('when the api responds with a 400 and an error/error_description', () => {
147
141
  it('throws an OauthException', () => __awaiter(void 0, void 0, void 0, function* () {
148
- mock.onPost().reply(400, { error: 'error', error_description: 'error description' }, {
149
- 'X-Request-ID': 'a-request-id',
142
+ (0, test_utils_1.fetchOnce)({ error: 'error', error_description: 'error description' }, {
143
+ status: 400,
144
+ headers: { 'X-Request-ID': 'a-request-id' },
150
145
  });
151
146
  const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
152
147
  yield expect(workos.post('/path', {})).rejects.toStrictEqual(new exceptions_1.OauthException(400, 'a-request-id', 'error', 'error description', { error: 'error', error_description: 'error description' }));
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "5.2.0",
2
+ "version": "6.0.0-rc.2",
3
3
  "name": "@workos-inc/node",
4
4
  "author": "WorkOS",
5
5
  "description": "A Node wrapper for the WorkOS API",
@@ -34,15 +34,16 @@
34
34
  "prepublishOnly": "yarn run build"
35
35
  },
36
36
  "dependencies": {
37
- "axios": "~1.6.5",
38
37
  "pluralize": "8.0.0"
39
38
  },
40
39
  "devDependencies": {
40
+ "@peculiar/webcrypto": "^1.4.5",
41
41
  "@types/jest": "29.5.3",
42
42
  "@types/node": "14.18.54",
43
43
  "@types/pluralize": "0.0.30",
44
44
  "axios-mock-adapter": "1.21.5",
45
45
  "jest": "29.6.2",
46
+ "jest-fetch-mock": "^3.0.3",
46
47
  "prettier": "2.8.8",
47
48
  "supertest": "6.3.3",
48
49
  "ts-jest": "29.1.1",