@flexbe/sdk 0.1.0 → 0.1.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.
package/README.md CHANGED
@@ -5,15 +5,15 @@ A TypeScript SDK for interacting with the Flexbe API. Works in both Node.js and
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install @flexbe/sdk-ts
8
+ npm install @flexbe/sdk
9
9
  ```
10
10
 
11
11
  ## Usage
12
12
 
13
13
  ```typescript
14
- import { FlexbeClient } from '@flexbe/sdk-ts';
14
+ import { FlexbeClient } from '@flexbe/sdk';
15
15
 
16
- // Initialize the client
16
+ // Initialize the client with API Key authentication
17
17
  const client = new FlexbeClient({
18
18
  apiKey: 'your-api-key',
19
19
  siteId: 'your-site-id', // optional, required for site-specific endpoints
@@ -21,6 +21,14 @@ const client = new FlexbeClient({
21
21
  timeout: 30000, // optional, defaults to 30 seconds
22
22
  });
23
23
 
24
+ // Or initialize with JWT Bearer token authentication
25
+ const client = new FlexbeClient({
26
+ authType: 'bearer',
27
+ siteId: 'your-site-id', // optional, required for site-specific endpoints
28
+ baseUrl: 'https://api.flexbe.com', // optional
29
+ timeout: 30000, // optional, defaults to 30 seconds
30
+ });
31
+
24
32
  // Using the Pages API
25
33
  try {
26
34
  // Get list of pages
@@ -44,18 +52,21 @@ try {
44
52
  ## Features
45
53
 
46
54
  - TypeScript support with full type definitions
47
- - API Key authentication
55
+ - Multiple authentication methods:
56
+ - API Key authentication
57
+ - JWT Bearer token authentication with automatic token refresh (uses cookie-based authentication)
48
58
  - Automatic error handling
49
59
  - Configurable timeout and base URL
50
60
  - Native fetch API support (works in both Node.js and browser)
51
61
  - Site-specific endpoints support
52
62
  - Query parameter handling
53
63
  - Request timeout handling
64
+ - Token sharing between browser tabs (for JWT authentication)
54
65
 
55
66
  ## Environment Variables
56
67
 
57
68
  The SDK supports the following environment variables:
58
- - `FLEXBE_API_KEY`: Your API key
69
+ - `FLEXBE_API_KEY`: Your API key (required for API Key authentication)
59
70
  - `FLEXBE_API_URL`: Base URL (defaults to 'https://api.flexbe.com')
60
71
  - `FLEXBE_SITE_ID`: Your site ID
61
72
 
@@ -0,0 +1,86 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { FlexbeAuth } from './auth';
11
+ export class ApiClient {
12
+ constructor(config) {
13
+ this.config = config;
14
+ this.auth = new FlexbeAuth(config);
15
+ }
16
+ replaceSiteId(url) {
17
+ if (!this.config.siteId) {
18
+ return url;
19
+ }
20
+ return url.replace(/:siteId:/g, this.config.siteId);
21
+ }
22
+ buildUrl(path, params) {
23
+ const processedPath = this.replaceSiteId(path);
24
+ const searchParams = new URLSearchParams();
25
+ if (params) {
26
+ Object.entries(params).forEach(([key, value]) => {
27
+ if (value !== undefined && value !== null) {
28
+ searchParams.append(key, String(value));
29
+ }
30
+ });
31
+ }
32
+ return `${processedPath}${searchParams.toString() ? `?${searchParams.toString()}` : ''}`;
33
+ }
34
+ request(config) {
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ try {
37
+ yield this.auth.ensureInitialized();
38
+ const controller = new AbortController();
39
+ const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
40
+ const url = this.buildUrl(config.url, config.params);
41
+ const headers = Object.assign(Object.assign({}, (yield this.auth.getAuthHeaders())), config.headers);
42
+ const response = yield fetch(this.config.baseUrl + url, Object.assign(Object.assign({}, config), { headers, signal: controller.signal }));
43
+ clearTimeout(timeoutId);
44
+ if (!response.ok) {
45
+ const defaultError = { message: response.statusText };
46
+ const errorData = yield response.json().catch(() => defaultError);
47
+ const error = {
48
+ message: errorData.message || response.statusText,
49
+ code: errorData.code,
50
+ status: response.status,
51
+ details: errorData.details,
52
+ };
53
+ throw error;
54
+ }
55
+ const data = yield response.json();
56
+ return {
57
+ data,
58
+ status: response.status,
59
+ statusText: response.statusText,
60
+ };
61
+ }
62
+ catch (error) {
63
+ if (error instanceof Error && error.name === 'AbortError') {
64
+ const timeoutError = {
65
+ message: 'Request timeout',
66
+ status: 408,
67
+ };
68
+ throw timeoutError;
69
+ }
70
+ throw error;
71
+ }
72
+ });
73
+ }
74
+ get(url, config) {
75
+ return this.request(Object.assign(Object.assign({}, config), { method: 'GET', url }));
76
+ }
77
+ post(url, data, config) {
78
+ return this.request(Object.assign(Object.assign({}, config), { method: 'POST', url, body: JSON.stringify(data) }));
79
+ }
80
+ put(url, data, config) {
81
+ return this.request(Object.assign(Object.assign({}, config), { method: 'PUT', url, body: JSON.stringify(data) }));
82
+ }
83
+ delete(url, config) {
84
+ return this.request(Object.assign(Object.assign({}, config), { method: 'DELETE', url }));
85
+ }
86
+ }
@@ -0,0 +1,118 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { TokenManager } from './token-manager';
11
+ export class FlexbeAuth {
12
+ constructor(config) {
13
+ this.initialized = false;
14
+ this.initializing = false;
15
+ this.config = config;
16
+ this.tokenManager = TokenManager.getInstance();
17
+ if (this.config.authType === 'bearer') {
18
+ // Check if we have a valid token in storage
19
+ const existingToken = this.tokenManager.getToken();
20
+ if (existingToken) {
21
+ this.initialized = true;
22
+ }
23
+ // Don't start initialization here, let ensureInitialized handle it
24
+ }
25
+ else {
26
+ this.initialized = true;
27
+ }
28
+ }
29
+ initializeBearerAuth() {
30
+ return __awaiter(this, void 0, void 0, function* () {
31
+ if (this.initializing) {
32
+ // Wait for the ongoing initialization to complete
33
+ while (this.initializing) {
34
+ yield new Promise(resolve => setTimeout(resolve, 100));
35
+ }
36
+ return;
37
+ }
38
+ try {
39
+ this.initializing = true;
40
+ const controller = new AbortController();
41
+ const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
42
+ const response = yield fetch('/oauth/token', {
43
+ method: 'POST',
44
+ headers: {
45
+ 'Content-Type': 'application/json',
46
+ },
47
+ body: JSON.stringify({
48
+ grant_type: 'client_credentials',
49
+ }),
50
+ credentials: 'include',
51
+ signal: controller.signal,
52
+ });
53
+ clearTimeout(timeoutId);
54
+ if (!response.ok) {
55
+ const defaultError = { message: response.statusText };
56
+ const errorData = yield response.json().catch(() => defaultError);
57
+ const error = {
58
+ message: errorData.message || response.statusText,
59
+ code: errorData.code,
60
+ status: response.status,
61
+ details: errorData.details,
62
+ };
63
+ throw error;
64
+ }
65
+ const data = yield response.json();
66
+ this.tokenManager.setToken(data);
67
+ this.initialized = true;
68
+ }
69
+ catch (error) {
70
+ console.error('Failed to initialize bearer authentication:', error);
71
+ this.initialized = false; // Reset initialized state on error
72
+ throw error;
73
+ }
74
+ finally {
75
+ this.initializing = false;
76
+ }
77
+ });
78
+ }
79
+ ensureInitialized() {
80
+ return __awaiter(this, void 0, void 0, function* () {
81
+ if (this.config.authType !== 'bearer' || this.initialized) {
82
+ return;
83
+ }
84
+ yield this.initializeBearerAuth();
85
+ });
86
+ }
87
+ getAuthHeaders() {
88
+ return __awaiter(this, void 0, void 0, function* () {
89
+ yield this.ensureInitialized();
90
+ const headers = {
91
+ 'Content-Type': 'application/json',
92
+ };
93
+ if (this.config.authType === 'apiKey') {
94
+ headers['x-api-key'] = this.config.apiKey;
95
+ }
96
+ else if (this.config.authType === 'bearer') {
97
+ const token = this.tokenManager.getToken();
98
+ if (!token) {
99
+ // If no token is available, try to initialize again
100
+ this.initialized = false;
101
+ yield this.ensureInitialized();
102
+ const newToken = this.tokenManager.getToken();
103
+ if (!newToken) {
104
+ throw new Error('No valid bearer token available');
105
+ }
106
+ headers['Authorization'] = `Bearer ${newToken}`;
107
+ }
108
+ else {
109
+ headers['Authorization'] = `Bearer ${token}`;
110
+ }
111
+ }
112
+ return headers;
113
+ });
114
+ }
115
+ isInitialized() {
116
+ return this.initialized;
117
+ }
118
+ }
@@ -1,13 +1,5 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  import { Pages } from './pages';
2
+ import { ApiClient } from './api-client';
11
3
  export class FlexbeClient {
12
4
  constructor(config) {
13
5
  const getEnvVar = (key) => {
@@ -21,89 +13,12 @@ export class FlexbeClient {
21
13
  timeout: (config === null || config === void 0 ? void 0 : config.timeout) || 30000,
22
14
  apiKey: (config === null || config === void 0 ? void 0 : config.apiKey) || getEnvVar('FLEXBE_API_KEY') || '',
23
15
  siteId: (config === null || config === void 0 ? void 0 : config.siteId) || getEnvVar('FLEXBE_SITE_ID'),
16
+ authType: (config === null || config === void 0 ? void 0 : config.authType) || 'apiKey',
24
17
  };
25
- if (!this.config.apiKey) {
26
- throw new Error('API key is required. Please provide it either through config or FLEXBE_API_KEY environment variable.');
18
+ if (this.config.authType === 'apiKey' && !this.config.apiKey) {
19
+ throw new Error('API key is required when using apiKey authentication. Please provide it either through config or FLEXBE_API_KEY environment variable.');
27
20
  }
28
- this.pages = new Pages(this);
29
- }
30
- buildUrl(path, params) {
31
- const searchParams = new URLSearchParams();
32
- if (params) {
33
- Object.entries(params).forEach(([key, value]) => {
34
- if (value !== undefined && value !== null) {
35
- searchParams.append(key, String(value));
36
- }
37
- });
38
- }
39
- return `${path}${searchParams.toString() ? `?${searchParams.toString()}` : ''}`;
40
- }
41
- request(config) {
42
- return __awaiter(this, void 0, void 0, function* () {
43
- try {
44
- const controller = new AbortController();
45
- const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
46
- const url = this.buildUrl(config.url, config.params);
47
- const response = yield fetch(this.config.baseUrl + url, Object.assign(Object.assign({}, config), { headers: Object.assign({ 'Authorization': `Bearer ${this.config.apiKey}`, 'Content-Type': 'application/json' }, config.headers), signal: controller.signal }));
48
- clearTimeout(timeoutId);
49
- if (!response.ok) {
50
- const defaultError = { message: response.statusText };
51
- const errorData = yield response.json().catch(() => defaultError);
52
- const error = {
53
- message: errorData.message || response.statusText,
54
- code: errorData.code,
55
- status: response.status,
56
- details: errorData.details,
57
- };
58
- throw error;
59
- }
60
- const data = yield response.json();
61
- return {
62
- data,
63
- status: response.status,
64
- statusText: response.statusText,
65
- };
66
- }
67
- catch (error) {
68
- if (error instanceof Error && error.name === 'AbortError') {
69
- const timeoutError = {
70
- message: 'Request timeout',
71
- status: 408,
72
- };
73
- throw timeoutError;
74
- }
75
- throw error;
76
- }
77
- });
78
- }
79
- get(url, config) {
80
- return this.request(Object.assign(Object.assign({}, config), { method: 'GET', url }));
81
- }
82
- post(url, data, config) {
83
- return this.request(Object.assign(Object.assign({}, config), { method: 'POST', url, body: JSON.stringify(data) }));
84
- }
85
- put(url, data, config) {
86
- return this.request(Object.assign(Object.assign({}, config), { method: 'PUT', url, body: JSON.stringify(data) }));
87
- }
88
- delete(url, config) {
89
- return this.request(Object.assign(Object.assign({}, config), { method: 'DELETE', url }));
90
- }
91
- getSiteUrl(path) {
92
- if (!this.config.siteId) {
93
- return path;
94
- }
95
- return `/sites/${this.config.siteId}${path}`;
96
- }
97
- sitesGet(path, config) {
98
- return this.get(this.getSiteUrl(path), config);
99
- }
100
- sitesPost(path, data, config) {
101
- return this.post(this.getSiteUrl(path), data, config);
102
- }
103
- sitesPut(path, data, config) {
104
- return this.put(this.getSiteUrl(path), data, config);
105
- }
106
- sitesDelete(path, config) {
107
- return this.delete(this.getSiteUrl(path), config);
21
+ this.api = new ApiClient(this.config);
22
+ this.pages = new Pages(this.api);
108
23
  }
109
24
  }
@@ -8,15 +8,15 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  export class Pages {
11
- constructor(client) {
12
- this.client = client;
11
+ constructor(api) {
12
+ this.api = api;
13
13
  }
14
14
  /**
15
15
  * Get list of pages for a site
16
16
  */
17
17
  getPages(params) {
18
18
  return __awaiter(this, void 0, void 0, function* () {
19
- const response = yield this.client.sitesGet('/pages', { params });
19
+ const response = yield this.api.get('/sites/:siteId:/pages', { params });
20
20
  return response.data;
21
21
  });
22
22
  }
@@ -25,7 +25,7 @@ export class Pages {
25
25
  */
26
26
  getPage(pageId) {
27
27
  return __awaiter(this, void 0, void 0, function* () {
28
- const response = yield this.client.sitesGet(`/pages/${pageId}`);
28
+ const response = yield this.api.get(`/sites/:siteId:/pages/${pageId}`);
29
29
  return response.data;
30
30
  });
31
31
  }
@@ -0,0 +1,132 @@
1
+ const TOKEN_STORAGE_KEY = 'flexbe_jwt_token';
2
+ const REFRESH_THRESHOLD = 0.8; // Refresh when 80% of token lifetime has passed
3
+ export class TokenManager {
4
+ constructor() {
5
+ this.token = null;
6
+ this.refreshInterval = null;
7
+ this.initializeFromStorage();
8
+ this.setupStorageListener();
9
+ }
10
+ static getInstance() {
11
+ if (!TokenManager.instance) {
12
+ TokenManager.instance = new TokenManager();
13
+ }
14
+ return TokenManager.instance;
15
+ }
16
+ initializeFromStorage() {
17
+ if (typeof window !== 'undefined') {
18
+ const storedToken = localStorage.getItem(TOKEN_STORAGE_KEY);
19
+ if (storedToken) {
20
+ try {
21
+ this.token = JSON.parse(storedToken);
22
+ if (this.token.expiresAt > Date.now()) {
23
+ console.log('Reusing stored token:', {
24
+ expiresIn: `${Math.round((this.token.expiresAt - Date.now()) / 1000)} seconds`,
25
+ expiresAt: new Date(this.token.expiresAt).toISOString(),
26
+ });
27
+ this.startRefreshInterval();
28
+ }
29
+ else {
30
+ this.clearToken();
31
+ }
32
+ }
33
+ catch (error) {
34
+ console.error('Failed to parse stored token:', error);
35
+ this.clearToken();
36
+ }
37
+ }
38
+ }
39
+ }
40
+ setupStorageListener() {
41
+ if (typeof window !== 'undefined') {
42
+ window.addEventListener('storage', (event) => {
43
+ if (event.key === TOKEN_STORAGE_KEY) {
44
+ if (event.newValue) {
45
+ try {
46
+ const newToken = JSON.parse(event.newValue);
47
+ if (newToken.expiresAt > Date.now()) {
48
+ this.token = newToken;
49
+ console.log('Token updated from storage:', {
50
+ expiresIn: `${Math.round((newToken.expiresAt - Date.now()) / 1000)} seconds`,
51
+ expiresAt: new Date(newToken.expiresAt).toISOString(),
52
+ });
53
+ this.startRefreshInterval();
54
+ }
55
+ else {
56
+ this.clearToken();
57
+ }
58
+ }
59
+ catch (error) {
60
+ console.error('Failed to parse token from storage event:', error);
61
+ this.clearToken();
62
+ }
63
+ }
64
+ else {
65
+ this.clearToken();
66
+ }
67
+ }
68
+ });
69
+ }
70
+ }
71
+ getExpirationFromToken(token) {
72
+ try {
73
+ const [, payload] = token.split('.');
74
+ const decodedPayload = JSON.parse(atob(payload));
75
+ return decodedPayload.exp * 1000; // Convert to milliseconds
76
+ }
77
+ catch (error) {
78
+ console.error('Failed to parse token expiration:', error);
79
+ return Date.now() + (4 * 60 * 1000); // Default to 4 minutes if parsing fails
80
+ }
81
+ }
82
+ startRefreshInterval() {
83
+ if (this.refreshInterval) {
84
+ clearInterval(this.refreshInterval);
85
+ }
86
+ if (this.token) {
87
+ const tokenLifetime = this.token.expiresAt - (this.token.expiresAt - 4 * 60 * 1000); // 4 minutes in milliseconds
88
+ const refreshTime = Math.round(tokenLifetime * REFRESH_THRESHOLD);
89
+ console.log('Setting up token refresh:', {
90
+ tokenLifetime: `${Math.round(tokenLifetime / 1000)} seconds`,
91
+ refreshIn: `${Math.round(refreshTime / 1000)} seconds`,
92
+ refreshAt: new Date(Date.now() + refreshTime).toISOString(),
93
+ });
94
+ this.refreshInterval = window.setInterval(() => {
95
+ this.clearToken();
96
+ }, refreshTime);
97
+ }
98
+ }
99
+ setToken(tokenResponse) {
100
+ const expiresAt = this.getExpirationFromToken(tokenResponse.accessToken);
101
+ this.token = {
102
+ accessToken: tokenResponse.accessToken,
103
+ expiresAt,
104
+ };
105
+ const expiresIn = Math.round((expiresAt - Date.now()) / 1000);
106
+ console.log('New access token obtained:', {
107
+ expiresIn: `${expiresIn} seconds`,
108
+ expiresAt: new Date(expiresAt).toISOString(),
109
+ });
110
+ if (typeof window !== 'undefined') {
111
+ localStorage.setItem(TOKEN_STORAGE_KEY, JSON.stringify(this.token));
112
+ }
113
+ this.startRefreshInterval();
114
+ }
115
+ getToken() {
116
+ if (this.token && this.token.expiresAt > Date.now()) {
117
+ return this.token.accessToken;
118
+ }
119
+ this.clearToken();
120
+ return null;
121
+ }
122
+ clearToken() {
123
+ this.token = null;
124
+ if (this.refreshInterval) {
125
+ clearInterval(this.refreshInterval);
126
+ this.refreshInterval = null;
127
+ }
128
+ if (typeof window !== 'undefined') {
129
+ localStorage.removeItem(TOKEN_STORAGE_KEY);
130
+ }
131
+ }
132
+ }
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ApiClient = void 0;
4
+ const auth_1 = require("./auth");
5
+ class ApiClient {
6
+ constructor(config) {
7
+ this.config = config;
8
+ this.auth = new auth_1.FlexbeAuth(config);
9
+ }
10
+ replaceSiteId(url) {
11
+ if (!this.config.siteId) {
12
+ return url;
13
+ }
14
+ return url.replace(/:siteId:/g, this.config.siteId);
15
+ }
16
+ buildUrl(path, params) {
17
+ const processedPath = this.replaceSiteId(path);
18
+ const searchParams = new URLSearchParams();
19
+ if (params) {
20
+ Object.entries(params).forEach(([key, value]) => {
21
+ if (value !== undefined && value !== null) {
22
+ searchParams.append(key, String(value));
23
+ }
24
+ });
25
+ }
26
+ return `${processedPath}${searchParams.toString() ? `?${searchParams.toString()}` : ''}`;
27
+ }
28
+ async request(config) {
29
+ try {
30
+ await this.auth.ensureInitialized();
31
+ const controller = new AbortController();
32
+ const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
33
+ const url = this.buildUrl(config.url, config.params);
34
+ const headers = {
35
+ ...(await this.auth.getAuthHeaders()),
36
+ ...config.headers,
37
+ };
38
+ const response = await fetch(this.config.baseUrl + url, {
39
+ ...config,
40
+ headers,
41
+ signal: controller.signal,
42
+ });
43
+ clearTimeout(timeoutId);
44
+ if (!response.ok) {
45
+ const defaultError = { message: response.statusText };
46
+ const errorData = await response.json().catch(() => defaultError);
47
+ const error = {
48
+ message: errorData.message || response.statusText,
49
+ code: errorData.code,
50
+ status: response.status,
51
+ details: errorData.details,
52
+ };
53
+ throw error;
54
+ }
55
+ const data = await response.json();
56
+ return {
57
+ data,
58
+ status: response.status,
59
+ statusText: response.statusText,
60
+ };
61
+ }
62
+ catch (error) {
63
+ if (error instanceof Error && error.name === 'AbortError') {
64
+ const timeoutError = {
65
+ message: 'Request timeout',
66
+ status: 408,
67
+ };
68
+ throw timeoutError;
69
+ }
70
+ throw error;
71
+ }
72
+ }
73
+ get(url, config) {
74
+ return this.request({ ...config, method: 'GET', url });
75
+ }
76
+ post(url, data, config) {
77
+ return this.request({ ...config, method: 'POST', url, body: JSON.stringify(data) });
78
+ }
79
+ put(url, data, config) {
80
+ return this.request({ ...config, method: 'PUT', url, body: JSON.stringify(data) });
81
+ }
82
+ delete(url, config) {
83
+ return this.request({ ...config, method: 'DELETE', url });
84
+ }
85
+ }
86
+ exports.ApiClient = ApiClient;