@workos-inc/node 5.1.4 → 6.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,13 +8,17 @@ 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
+ };
11
14
  Object.defineProperty(exports, "__esModule", { value: true });
12
- const axios_1 = require("axios");
15
+ const jest_fetch_mock_1 = __importDefault(require("jest-fetch-mock"));
13
16
  const exceptions_1 = require("../common/exceptions");
14
17
  const bad_request_exception_1 = require("../common/exceptions/bad-request.exception");
15
18
  const workos_mock_response_1 = require("../common/utils/workos-mock-response");
16
19
  const workos_1 = require("../workos");
17
20
  const serializers_1 = require("./serializers");
21
+ const fetch_error_1 = require("../common/utils/fetch-error");
18
22
  const event = {
19
23
  action: 'document.updated',
20
24
  occurredAt: new Date(),
@@ -38,6 +42,7 @@ const event = {
38
42
  },
39
43
  };
40
44
  describe('AuditLogs', () => {
45
+ beforeEach(() => jest_fetch_mock_1.default.resetMocks());
41
46
  describe('createEvent', () => {
42
47
  describe('with an idempotency key', () => {
43
48
  it('includes an idempotency key with request', () => __awaiter(void 0, void 0, void 0, function* () {
@@ -69,7 +74,10 @@ describe('AuditLogs', () => {
69
74
  it('throws an UnauthorizedException', () => __awaiter(void 0, void 0, void 0, function* () {
70
75
  const workosSpy = jest.spyOn(workos_1.WorkOS.prototype, 'post');
71
76
  workosSpy.mockImplementationOnce(() => {
72
- throw new axios_1.AxiosError('Could not authorize the request. Maybe your API key is invalid?', '401');
77
+ throw new fetch_error_1.FetchError({
78
+ message: 'Could not authorize the request. Maybe your API key is invalid?',
79
+ response: { status: 401, headers: new Headers(), data: {} },
80
+ });
73
81
  });
74
82
  const workos = new workos_1.WorkOS('invalid apikey');
75
83
  yield expect(workos.auditLogs.createEvent('org_123', event)).rejects.toThrowError(new exceptions_1.UnauthorizedException('a-request-id'));
@@ -172,7 +180,10 @@ describe('AuditLogs', () => {
172
180
  rangeEnd: new Date(),
173
181
  };
174
182
  workosSpy.mockImplementationOnce(() => {
175
- throw new axios_1.AxiosError('Could not authorize the request. Maybe your API key is invalid?', '401');
183
+ throw new fetch_error_1.FetchError({
184
+ message: 'Could not authorize the request. Maybe your API key is invalid?',
185
+ response: { status: 401, headers: new Headers(), data: {} },
186
+ });
176
187
  });
177
188
  const workos = new workos_1.WorkOS('invalid apikey');
178
189
  yield expect(workos.auditLogs.createExport(options)).rejects.toThrowError(new exceptions_1.UnauthorizedException('a-request-id'));
@@ -209,7 +220,10 @@ describe('AuditLogs', () => {
209
220
  it('throws an UnauthorizedException', () => __awaiter(void 0, void 0, void 0, function* () {
210
221
  const workosSpy = jest.spyOn(workos_1.WorkOS.prototype, 'get');
211
222
  workosSpy.mockImplementationOnce(() => {
212
- throw new axios_1.AxiosError('Could not authorize the request. Maybe your API key is invalid?', '401');
223
+ throw new fetch_error_1.FetchError({
224
+ message: 'Could not authorize the request. Maybe your API key is invalid?',
225
+ response: { status: 401, headers: new Headers(), data: {} },
226
+ });
213
227
  });
214
228
  const workos = new workos_1.WorkOS('invalid apikey');
215
229
  yield expect(workos.auditLogs.getExport('audit_log_export_1234')).rejects.toThrowError(new exceptions_1.UnauthorizedException('a-request-id'));
@@ -1,7 +1,6 @@
1
- import { AxiosRequestConfig } from 'axios';
2
1
  export interface WorkOSOptions {
3
2
  apiHostname?: string;
4
3
  https?: boolean;
5
4
  port?: number;
6
- axios?: Omit<AxiosRequestConfig, 'baseURL'>;
5
+ config?: RequestInit;
7
6
  }
@@ -0,0 +1,29 @@
1
+ export declare class FetchClient {
2
+ readonly baseURL: string;
3
+ readonly options?: RequestInit | undefined;
4
+ constructor(baseURL: string, options?: RequestInit | undefined);
5
+ get(path: string, options: {
6
+ params?: Record<string, any>;
7
+ headers?: HeadersInit;
8
+ }): Promise<{
9
+ data: any;
10
+ }>;
11
+ post<Entity = any>(path: string, entity: Entity, options: {
12
+ params?: Record<string, any>;
13
+ headers?: HeadersInit;
14
+ }): Promise<{
15
+ data: any;
16
+ }>;
17
+ put<Entity = any>(path: string, entity: Entity, options: {
18
+ params?: Record<string, any>;
19
+ headers?: HeadersInit;
20
+ }): Promise<{
21
+ data: any;
22
+ }>;
23
+ delete(path: string, options: {
24
+ params?: Record<string, any>;
25
+ headers?: HeadersInit;
26
+ }): Promise<void>;
27
+ private getResourceURL;
28
+ private fetch;
29
+ }
@@ -0,0 +1,97 @@
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
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.FetchClient = void 0;
13
+ const fetch_error_1 = require("./fetch-error");
14
+ class FetchClient {
15
+ constructor(baseURL, options) {
16
+ this.baseURL = baseURL;
17
+ this.options = options;
18
+ }
19
+ get(path, options) {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ const resourceURL = this.getResourceURL(path, options.params);
22
+ const response = yield this.fetch(resourceURL, {
23
+ headers: options.headers,
24
+ });
25
+ return { data: yield response.json() };
26
+ });
27
+ }
28
+ post(path, entity, options) {
29
+ return __awaiter(this, void 0, void 0, function* () {
30
+ const resourceURL = this.getResourceURL(path, options.params);
31
+ const bodyIsSearchParams = entity instanceof URLSearchParams;
32
+ const contentTypeHeader = bodyIsSearchParams
33
+ ? { 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' }
34
+ : undefined;
35
+ const body = bodyIsSearchParams ? entity : JSON.stringify(entity);
36
+ const response = yield this.fetch(resourceURL, {
37
+ method: 'POST',
38
+ headers: Object.assign(Object.assign({}, contentTypeHeader), options.headers),
39
+ body,
40
+ });
41
+ return { data: yield response.json() };
42
+ });
43
+ }
44
+ put(path, entity, options) {
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ const resourceURL = this.getResourceURL(path, options.params);
47
+ const response = yield this.fetch(resourceURL, {
48
+ method: 'PUT',
49
+ headers: options.headers,
50
+ body: JSON.stringify(entity),
51
+ });
52
+ return { data: yield response.json() };
53
+ });
54
+ }
55
+ delete(path, options) {
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ const resourceURL = this.getResourceURL(path, options.params);
58
+ yield this.fetch(resourceURL, {
59
+ method: 'DELETE',
60
+ headers: options.headers,
61
+ });
62
+ });
63
+ }
64
+ getResourceURL(path, params) {
65
+ const queryString = getQueryString(params);
66
+ const url = new URL([path, queryString].filter(Boolean).join('?'), this.baseURL);
67
+ return url.toString();
68
+ }
69
+ fetch(url, options) {
70
+ var _a;
71
+ return __awaiter(this, void 0, void 0, function* () {
72
+ const response = yield fetch(url, Object.assign(Object.assign(Object.assign({}, this.options), options), { headers: Object.assign(Object.assign({ Accept: 'application/json, text/plain, */*', 'Content-Type': 'application/json' }, (_a = this.options) === null || _a === void 0 ? void 0 : _a.headers), options === null || options === void 0 ? void 0 : options.headers) }));
73
+ if (!response.ok) {
74
+ throw new fetch_error_1.FetchError({
75
+ message: response.statusText,
76
+ response: {
77
+ status: response.status,
78
+ headers: response.headers,
79
+ data: yield response.json(),
80
+ },
81
+ });
82
+ }
83
+ return response;
84
+ });
85
+ }
86
+ }
87
+ exports.FetchClient = FetchClient;
88
+ function getQueryString(queryObj) {
89
+ if (!queryObj)
90
+ return undefined;
91
+ const sanitizedQueryObj = {};
92
+ Object.entries(queryObj).forEach(([param, value]) => {
93
+ if (value !== '' && value !== undefined)
94
+ sanitizedQueryObj[param] = value;
95
+ });
96
+ return new URLSearchParams(sanitizedQueryObj).toString();
97
+ }
@@ -0,0 +1,13 @@
1
+ export declare class FetchError<T> extends Error {
2
+ readonly name: string;
3
+ readonly message: string;
4
+ readonly response: {
5
+ status: number;
6
+ headers: Headers;
7
+ data: T;
8
+ };
9
+ constructor({ message, response, }: {
10
+ message: string;
11
+ readonly response: FetchError<T>['response'];
12
+ });
13
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FetchError = void 0;
4
+ class FetchError extends Error {
5
+ constructor({ message, response, }) {
6
+ super(message);
7
+ this.name = 'FetchError';
8
+ this.message = 'The request could not be completed.';
9
+ this.message = message;
10
+ this.response = response;
11
+ }
12
+ }
13
+ exports.FetchError = FetchError;
@@ -0,0 +1,8 @@
1
+ import { MockParams } from 'jest-fetch-mock';
2
+ export declare function fetchOnce(response?: any, { status, ...rest }?: MockParams): import("jest-fetch-mock").FetchMock;
3
+ export declare function fetchURL(): string | Request | undefined;
4
+ export declare function fetchSearchParams(): {
5
+ [k: string]: string;
6
+ };
7
+ export declare function fetchHeaders(): HeadersInit | undefined;
8
+ export declare function fetchBody(): any;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.fetchBody = exports.fetchHeaders = exports.fetchSearchParams = exports.fetchURL = exports.fetchOnce = void 0;
18
+ const jest_fetch_mock_1 = __importDefault(require("jest-fetch-mock"));
19
+ function fetchOnce(response = {}, _a = {}) {
20
+ var { status = 200 } = _a, rest = __rest(_a, ["status"]);
21
+ return jest_fetch_mock_1.default.once(JSON.stringify(response), Object.assign({ status }, rest));
22
+ }
23
+ exports.fetchOnce = fetchOnce;
24
+ function fetchURL() {
25
+ return jest_fetch_mock_1.default.mock.calls[0][0];
26
+ }
27
+ exports.fetchURL = fetchURL;
28
+ function fetchSearchParams() {
29
+ return Object.fromEntries(new URL(String(fetchURL())).searchParams);
30
+ }
31
+ exports.fetchSearchParams = fetchSearchParams;
32
+ function fetchHeaders() {
33
+ var _a;
34
+ return (_a = jest_fetch_mock_1.default.mock.calls[0][1]) === null || _a === void 0 ? void 0 : _a.headers;
35
+ }
36
+ exports.fetchHeaders = fetchHeaders;
37
+ function fetchBody() {
38
+ var _a;
39
+ const body = (_a = jest_fetch_mock_1.default.mock.calls[0][1]) === null || _a === void 0 ? void 0 : _a.body;
40
+ if (body instanceof URLSearchParams) {
41
+ return body.toString();
42
+ }
43
+ return JSON.parse(String(body));
44
+ }
45
+ exports.fetchBody = fetchBody;
@@ -12,12 +12,11 @@ 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 workos_1 = require("../workos");
18
- const mock = new axios_mock_adapter_1.default(axios_1.default);
19
18
  describe('DirectorySync', () => {
20
- afterEach(() => mock.resetHistory());
19
+ beforeEach(() => jest_fetch_mock_1.default.resetMocks());
21
20
  const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
22
21
  const directory = {
23
22
  id: 'directory_123',
@@ -127,16 +126,15 @@ describe('DirectorySync', () => {
127
126
  data: [directoryResponse],
128
127
  list_metadata: {},
129
128
  };
130
- mock
131
- .onGet('/directories', {
132
- domain: 'google.com',
133
- organization_id: 'org_1234',
134
- })
135
- .replyOnce(200, directoryListResponse);
129
+ (0, test_utils_1.fetchOnce)(directoryListResponse);
136
130
  const subject = yield workos.directorySync.listDirectories({
137
131
  domain: 'google.com',
138
132
  organizationId: 'org_1234',
139
133
  });
134
+ expect((0, test_utils_1.fetchSearchParams)()).toMatchObject({
135
+ domain: 'google.com',
136
+ organization_id: 'org_1234',
137
+ });
140
138
  expect(subject).toMatchObject({
141
139
  object: 'list',
142
140
  list: {
@@ -154,23 +152,21 @@ describe('DirectorySync', () => {
154
152
  });
155
153
  describe('getDirectory', () => {
156
154
  it(`requests a Directory`, () => __awaiter(void 0, void 0, void 0, function* () {
157
- mock
158
- .onGet('/directories/directory_123')
159
- .replyOnce(200, directoryResponse);
155
+ (0, test_utils_1.fetchOnce)(directoryResponse);
160
156
  const subject = yield workos.directorySync.getDirectory('directory_123');
161
157
  expect(subject).toEqual(directory);
162
158
  }));
163
159
  });
164
160
  describe('deleteDirectory', () => {
165
161
  it('sends a request to delete the directory', () => __awaiter(void 0, void 0, void 0, function* () {
166
- mock.onDelete('/directories/directory_123').replyOnce(202, {});
162
+ (0, test_utils_1.fetchOnce)({}, { status: 202 });
167
163
  yield workos.directorySync.deleteDirectory('directory_123');
168
- expect(mock.history.delete[0].url).toEqual('/directories/directory_123');
164
+ expect((0, test_utils_1.fetchURL)()).toContain('/directories/directory_123');
169
165
  }));
170
166
  });
171
167
  describe('getGroup', () => {
172
168
  it(`requests a Directory Group`, () => __awaiter(void 0, void 0, void 0, function* () {
173
- mock.onGet('/directory_groups/dir_grp_123').replyOnce(200, groupResponse);
169
+ (0, test_utils_1.fetchOnce)(groupResponse);
174
170
  const subject = yield workos.directorySync.getGroup('dir_grp_123');
175
171
  expect(subject).toEqual(group);
176
172
  }));
@@ -183,14 +179,13 @@ describe('DirectorySync', () => {
183
179
  };
184
180
  describe('with a Directory', () => {
185
181
  it(`requests a Directory's Groups`, () => __awaiter(void 0, void 0, void 0, function* () {
186
- mock
187
- .onGet('/directory_groups', {
188
- directory: 'directory_123',
189
- })
190
- .replyOnce(200, groupListResponse);
182
+ (0, test_utils_1.fetchOnce)(groupListResponse);
191
183
  const subject = yield workos.directorySync.listGroups({
192
184
  directory: 'directory_123',
193
185
  });
186
+ expect((0, test_utils_1.fetchSearchParams)()).toMatchObject({
187
+ directory: 'directory_123',
188
+ });
194
189
  expect(subject).toMatchObject({
195
190
  object: 'list',
196
191
  list: {
@@ -207,14 +202,13 @@ describe('DirectorySync', () => {
207
202
  });
208
203
  describe('with a User', () => {
209
204
  it(`requests a Directory's Groups`, () => __awaiter(void 0, void 0, void 0, function* () {
210
- mock
211
- .onGet('/directory_groups', {
212
- user: 'directory_usr_123',
213
- })
214
- .replyOnce(200, groupListResponse);
205
+ (0, test_utils_1.fetchOnce)(groupListResponse);
215
206
  const subject = yield workos.directorySync.listGroups({
216
207
  user: 'directory_usr_123',
217
208
  });
209
+ expect((0, test_utils_1.fetchSearchParams)()).toMatchObject({
210
+ user: 'directory_usr_123',
211
+ });
218
212
  expect(subject).toEqual({
219
213
  object: 'list',
220
214
  list: {
@@ -238,14 +232,13 @@ describe('DirectorySync', () => {
238
232
  };
239
233
  describe('with a Directory', () => {
240
234
  it(`requests a Directory's Users`, () => __awaiter(void 0, void 0, void 0, function* () {
241
- mock
242
- .onGet('/directory_users', {
243
- directory: 'directory_123',
244
- })
245
- .replyOnce(200, userWithGroupListResponse);
235
+ (0, test_utils_1.fetchOnce)(userWithGroupListResponse);
246
236
  const subject = yield workos.directorySync.listUsers({
247
237
  directory: 'directory_123',
248
238
  });
239
+ expect((0, test_utils_1.fetchSearchParams)()).toMatchObject({
240
+ directory: 'directory_123',
241
+ });
249
242
  expect(subject).toMatchObject({
250
243
  object: 'list',
251
244
  list: {
@@ -261,11 +254,7 @@ describe('DirectorySync', () => {
261
254
  }));
262
255
  describe('with custom attributes', () => {
263
256
  it('returns the custom attributes, using the provided type', () => __awaiter(void 0, void 0, void 0, function* () {
264
- mock
265
- .onGet('/directory_users', {
266
- directory: 'directory_123',
267
- })
268
- .replyOnce(200, {
257
+ (0, test_utils_1.fetchOnce)({
269
258
  data: [
270
259
  {
271
260
  object: 'directory_user',
@@ -322,10 +311,13 @@ describe('DirectorySync', () => {
322
311
  ],
323
312
  },
324
313
  ],
325
- });
314
+ }, { status: 200 });
326
315
  const users = yield workos.directorySync.listUsers({
327
316
  directory: 'directory_123',
328
317
  });
318
+ expect((0, test_utils_1.fetchSearchParams)()).toMatchObject({
319
+ directory: 'directory_123',
320
+ });
329
321
  const managerIds = users.data.map((user) => user.customAttributes.managerId);
330
322
  expect(managerIds).toEqual([
331
323
  '99f1817b-149c-4438-b80f-a272c3406109',
@@ -336,14 +328,13 @@ describe('DirectorySync', () => {
336
328
  });
337
329
  describe('with a Group', () => {
338
330
  it(`requests a Directory's Users`, () => __awaiter(void 0, void 0, void 0, function* () {
339
- mock
340
- .onGet('/directory_users', {
341
- group: 'directory_grp_123',
342
- })
343
- .replyOnce(200, userWithGroupListResponse);
331
+ (0, test_utils_1.fetchOnce)(userWithGroupListResponse);
344
332
  const subject = yield workos.directorySync.listUsers({
345
333
  group: 'directory_grp_123',
346
334
  });
335
+ expect((0, test_utils_1.fetchSearchParams)()).toMatchObject({
336
+ group: 'directory_grp_123',
337
+ });
347
338
  expect(subject).toMatchObject({
348
339
  object: 'list',
349
340
  list: {
@@ -361,9 +352,7 @@ describe('DirectorySync', () => {
361
352
  });
362
353
  describe('getUser', () => {
363
354
  it(`requests a Directory User`, () => __awaiter(void 0, void 0, void 0, function* () {
364
- mock
365
- .onGet('/directory_users/dir_usr_123')
366
- .replyOnce(200, userWithGroupResponse);
355
+ (0, test_utils_1.fetchOnce)(userWithGroupResponse);
367
356
  const subject = yield workos.directorySync.getUser('dir_usr_123');
368
357
  expect(subject).toEqual(userWithGroup);
369
358
  }));
@@ -12,13 +12,12 @@ 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 workos_1 = require("../workos");
18
18
  const interfaces_1 = require("../sso/interfaces");
19
- const mock = new axios_mock_adapter_1.default(axios_1.default);
20
19
  describe('Event', () => {
21
- afterEach(() => mock.resetHistory());
20
+ beforeEach(() => jest_fetch_mock_1.default.resetMocks());
22
21
  const workos = new workos_1.WorkOS('sk_test_Sz3IQjepeSWaI4cMS4ms4sMuU');
23
22
  const event = {
24
23
  id: 'event_01234ABCD',
@@ -60,7 +59,7 @@ describe('Event', () => {
60
59
  list_metadata: {},
61
60
  };
62
61
  it(`requests Events`, () => __awaiter(void 0, void 0, void 0, function* () {
63
- mock.onGet('/events', {}).replyOnce(200, eventsListResponse);
62
+ (0, test_utils_1.fetchOnce)(eventsListResponse);
64
63
  const subject = yield workos.events.listEvents({});
65
64
  expect(subject).toEqual({
66
65
  object: 'list',
@@ -69,7 +68,7 @@ describe('Event', () => {
69
68
  });
70
69
  }));
71
70
  it(`requests Events with a valid event name`, () => __awaiter(void 0, void 0, void 0, function* () {
72
- mock.onGet('/events').replyOnce(200, eventsListResponse);
71
+ (0, test_utils_1.fetchOnce)(eventsListResponse);
73
72
  const list = yield workos.events.listEvents({
74
73
  events: ['connection.activated'],
75
74
  });