@technomoron/apicore-client 1.0.0-beta.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.
@@ -0,0 +1,636 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2025 Bjørn Erik Jacobsen / Technomoron
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.ApiResponse = void 0;
10
+ function isPlainObject(value) {
11
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
12
+ }
13
+ function getErrorMessage(error) {
14
+ if (error instanceof Error) {
15
+ return error.message || undefined;
16
+ }
17
+ if (isPlainObject(error)) {
18
+ const potentialMessage = error['message'];
19
+ if (typeof potentialMessage === 'string') {
20
+ return potentialMessage;
21
+ }
22
+ }
23
+ return undefined;
24
+ }
25
+ function getErrorCode(error) {
26
+ if (isPlainObject(error)) {
27
+ const potentialCode = error['code'];
28
+ if (typeof potentialCode === 'string') {
29
+ return potentialCode;
30
+ }
31
+ }
32
+ return undefined;
33
+ }
34
+ function hasErrorName(error, expected) {
35
+ if (isPlainObject(error)) {
36
+ const potentialName = error['name'];
37
+ if (typeof potentialName === 'string') {
38
+ return potentialName === expected;
39
+ }
40
+ }
41
+ return false;
42
+ }
43
+ /**
44
+ * Parses an error message from various error types
45
+ * @param {unknown} error - The error to parse
46
+ * @param {string} def - Default message if no message can be extracted
47
+ * @returns {string} The extracted error message or default message
48
+ */
49
+ function parseMessage(error, def = '') {
50
+ if (typeof error === 'string') {
51
+ return error;
52
+ }
53
+ const message = getErrorMessage(error);
54
+ if (message) {
55
+ return message;
56
+ }
57
+ return def || '[Unknown error type - neither string, Error nor has .message]';
58
+ }
59
+ class ApiResponse {
60
+ constructor(response = {}) {
61
+ this.success = false;
62
+ this.code = 500;
63
+ this.message = '[No Message]';
64
+ this.data = null;
65
+ this.errors = {};
66
+ this.success = response.success ?? false;
67
+ this.code = response.code ?? 500;
68
+ this.message = parseMessage(response.message, '[No Message]');
69
+ this.data = response.data ?? null;
70
+ this.errors = response.errors ?? {};
71
+ }
72
+ /**
73
+ * Creates a successful response with the provided data
74
+ * @param {T} data - The response data
75
+ * @param {Partial<ApiResponseData<T>>} overrides - Optional overrides for response properties
76
+ * @returns {ApiResponse<T>} A configured successful response
77
+ */
78
+ static ok(data, overrides = {}) {
79
+ return new ApiResponse({
80
+ success: true,
81
+ code: 200,
82
+ message: 'OK',
83
+ data,
84
+ ...overrides
85
+ });
86
+ }
87
+ /**
88
+ * Creates an error response with the provided message
89
+ * @param {unknown} messageOrError - The error message, error object, or existing ApiResponse
90
+ * @param {Partial<ApiResponseData<T>>} overrides - Optional overrides for response properties
91
+ * @returns {ApiResponse<T>} A configured error response
92
+ */
93
+ static error(messageOrError, overrides = {}) {
94
+ if (messageOrError instanceof ApiResponse) {
95
+ return messageOrError;
96
+ }
97
+ // Use parseMessage to handle any error type consistently
98
+ const message = parseMessage(messageOrError, 'Unknown error');
99
+ return new ApiResponse({
100
+ success: false,
101
+ code: overrides.code ?? 500,
102
+ message,
103
+ data: null,
104
+ ...overrides
105
+ });
106
+ }
107
+ /**
108
+ * Adds a named error to the errors collection
109
+ * @param {string} name - The name/key for the error
110
+ * @param {string} value - The error message
111
+ */
112
+ addError(name, value) {
113
+ this.errors[name] = value;
114
+ }
115
+ /**
116
+ * Type guard to check if the response is successful and contains data
117
+ * When this returns true, TypeScript narrows the type to ensure data is not null
118
+ * @returns {boolean} True if the response is successful and contains data
119
+ */
120
+ isSuccess() {
121
+ return this.success && this.data !== null;
122
+ }
123
+ }
124
+ exports.ApiResponse = ApiResponse;
125
+ class ApiClient {
126
+ constructor(apiUrl, config = {}) {
127
+ this.apiKey = null;
128
+ this.aToken = null;
129
+ this.rToken = null;
130
+ // Shared promise so that concurrent 401s all await the same refresh attempt.
131
+ this._refreshPromise = null;
132
+ this.timeoutMs = 15000;
133
+ this.maxRetries = 1;
134
+ this.debug = false;
135
+ this.tokens = true;
136
+ this.apiUrl = apiUrl.endsWith('/') ? apiUrl.slice(0, -1) : apiUrl;
137
+ this.apiKey = config.apiKey ?? null;
138
+ this.timeoutMs = config.timeout ?? 15000;
139
+ this.maxRetries = config.maxRetries ?? 1;
140
+ this.debug = config.debug ?? false;
141
+ this.tokens = config.enableTokens ?? true;
142
+ }
143
+ /**
144
+ * Updates the client configuration
145
+ * @param {Partial<ApiClientConfig>} config - Configuration updates
146
+ */
147
+ configure(config) {
148
+ if (config.apiKey !== undefined)
149
+ this.apiKey = config.apiKey;
150
+ if (config.timeout !== undefined && config.timeout !== null)
151
+ this.timeoutMs = config.timeout;
152
+ if (config.maxRetries !== undefined && config.maxRetries !== null)
153
+ this.maxRetries = config.maxRetries;
154
+ if (config.debug !== undefined && config.debug !== null)
155
+ this.debug = config.debug;
156
+ if (config.enableTokens !== undefined && config.enableTokens !== null)
157
+ this.tokens = config.enableTokens;
158
+ }
159
+ /**
160
+ * Gets the current configuration
161
+ * @returns {ApiClientConfig} Current configuration
162
+ */
163
+ getConfig() {
164
+ return {
165
+ // Omit the raw API key — return a boolean sentinel so callers can check
166
+ // whether a key is configured without being able to extract its value.
167
+ apiKey: this.apiKey ? '***' : null,
168
+ timeout: this.timeoutMs,
169
+ maxRetries: this.maxRetries,
170
+ debug: this.debug,
171
+ enableTokens: this.tokens
172
+ };
173
+ }
174
+ tryStringify(obj) {
175
+ try {
176
+ return JSON.stringify(obj);
177
+ }
178
+ catch (err) {
179
+ if (this.debug) {
180
+ console.error('[ApiClient] JSON.stringify failed:', err);
181
+ }
182
+ throw ApiResponse.error('Failed to serialize request body', {
183
+ code: 400
184
+ });
185
+ }
186
+ }
187
+ /**
188
+ * Retrieves the stored access token
189
+ * Designed to be overridden in subclasses for custom token storage
190
+ * @returns {string|null} The current access token or null if not set
191
+ */
192
+ get_access_token() {
193
+ return this.aToken;
194
+ }
195
+ /**
196
+ * Stores the access token
197
+ * Designed to be overridden in subclasses for custom token storage
198
+ * @param {string|null} access - The access token to store, or null to clear
199
+ */
200
+ set_access_token(access) {
201
+ this.aToken = access;
202
+ }
203
+ /**
204
+ * Retrieves the stored refresh token
205
+ * Designed to be overridden in subclasses for custom token storage
206
+ * @returns {string|null} The current refresh token or null if not set
207
+ */
208
+ get_refresh_token() {
209
+ return this.rToken;
210
+ }
211
+ /**
212
+ * Stores the refresh token
213
+ * Designed to be overridden in subclasses for custom token storage
214
+ * @param {string|null} refresh - The refresh token to store, or null to clear
215
+ */
216
+ set_refresh_token(refresh) {
217
+ this.rToken = refresh;
218
+ }
219
+ /**
220
+ * Sets the API key for authentication
221
+ * Designed to be overridden in subclasses for custom API key storage
222
+ * @param {string|null} apikey - The API key to use for authentication, or null to clear
223
+ */
224
+ set_apikey(apikey) {
225
+ this.apiKey = apikey;
226
+ }
227
+ /**
228
+ * Retrieves the stored API key
229
+ * Designed to be overridden in subclasses for custom API key storage
230
+ * @returns {string|null} The current API key or null if not set
231
+ */
232
+ get_apikey() {
233
+ return this.apiKey;
234
+ }
235
+ /**
236
+ * Builds authentication headers based on current configuration
237
+ * @returns {Record<string, string>} Headers object with authentication if available
238
+ */
239
+ buildAuthHeaders() {
240
+ const headers = {};
241
+ if (this.apiKey) {
242
+ headers.Authorization = `Bearer ${this.apiKey}`;
243
+ }
244
+ else if (this.tokens) {
245
+ const accessToken = this.get_access_token();
246
+ if (accessToken) {
247
+ headers.Authorization = `Bearer ${accessToken}`;
248
+ }
249
+ }
250
+ return headers;
251
+ }
252
+ /**
253
+ * A drop‑in replacement for fetch() that handles timeouts and
254
+ * normalized network errors and throws an ApiResponse on failure.
255
+ * Uses the instance's configured timeout value.
256
+ */
257
+ async safeFetch(input, init = {}) {
258
+ const controller = new AbortController();
259
+ const id = setTimeout(() => controller.abort(), this.timeoutMs);
260
+ const headers = new Headers(init.headers);
261
+ const authHeaders = this.buildAuthHeaders();
262
+ for (const [k, v] of Object.entries(authHeaders)) {
263
+ headers.set(k, v);
264
+ }
265
+ const method = (init.method ?? 'GET').toUpperCase();
266
+ if (method !== 'GET' &&
267
+ init.body !== undefined &&
268
+ init.body !== null &&
269
+ !headers.has('Content-Type') &&
270
+ !(init.body instanceof FormData)) {
271
+ headers.set('Content-Type', 'application/json');
272
+ }
273
+ if (this.debug) {
274
+ console.log('[safeFetch] Request:', input);
275
+ console.log('[safeFetch] Method:', method);
276
+ console.log('[safeFetch] Headers:', headers);
277
+ }
278
+ try {
279
+ const res = await fetch(input, {
280
+ ...init,
281
+ headers,
282
+ signal: controller.signal
283
+ });
284
+ return res;
285
+ }
286
+ catch (err) {
287
+ if (hasErrorName(err, 'AbortError')) {
288
+ throw ApiResponse.error('Fetch timed out', { code: 504 });
289
+ }
290
+ let reason = '';
291
+ let status = 500;
292
+ const isBrowser = typeof window !== 'undefined' &&
293
+ typeof window.document !== 'undefined';
294
+ if (isBrowser) {
295
+ // Browser environment
296
+ if (err instanceof TypeError && err.message === 'Failed to fetch') {
297
+ reason = 'Possible CORS issue or server unreachable';
298
+ status = 503;
299
+ }
300
+ else {
301
+ reason = getErrorMessage(err) || 'Unknown browser fetch error';
302
+ }
303
+ }
304
+ else {
305
+ // Node.js environment
306
+ switch (getErrorCode(err)) {
307
+ case 'ECONNREFUSED':
308
+ reason = 'Connection refused by server';
309
+ status = 503;
310
+ break;
311
+ case 'ENOTFOUND':
312
+ reason = 'DNS lookup failed - host not found';
313
+ status = 503;
314
+ break;
315
+ case 'ETIMEDOUT':
316
+ reason = 'Connection timed out';
317
+ status = 504;
318
+ break;
319
+ case 'ECONNRESET':
320
+ reason = 'Connection reset by server';
321
+ status = 503;
322
+ break;
323
+ case 'EHOSTUNREACH':
324
+ reason = 'Host unreachable';
325
+ status = 503;
326
+ break;
327
+ default:
328
+ reason = getErrorMessage(err) || 'Unknown network error';
329
+ }
330
+ }
331
+ throw ApiResponse.error(`Fetch failed: ${reason}`, { code: status });
332
+ }
333
+ finally {
334
+ clearTimeout(id);
335
+ }
336
+ }
337
+ /**
338
+ * Safely parses JSON response with proper error handling
339
+ * @param {Response} response - The fetch response
340
+ * @returns {Promise<RawApiResponse<T>>} The parsed JSON data
341
+ */
342
+ async parseJsonResponse(response) {
343
+ try {
344
+ return (await response.json());
345
+ }
346
+ catch (err) {
347
+ throw ApiResponse.error(`Failed to parse JSON response: ${parseMessage(err)}`, {
348
+ code: response.status
349
+ });
350
+ }
351
+ }
352
+ async login(username, password, domain = '', fingerprint = '') {
353
+ try {
354
+ const loginBody = { login: username, password };
355
+ if (domain)
356
+ loginBody.domain = domain;
357
+ if (fingerprint)
358
+ loginBody.fingerprint = fingerprint;
359
+ const response = await this.safeFetch(`${this.apiUrl}/api/auth/v1/login`, {
360
+ method: 'POST',
361
+ body: this.tryStringify(loginBody),
362
+ credentials: 'include'
363
+ });
364
+ const jsondata = await this.parseJsonResponse(response);
365
+ if (this.debug) {
366
+ console.log('Login Response Headers:');
367
+ response.headers.forEach((value, name) => {
368
+ console.log(`${name}: ${value}`);
369
+ });
370
+ }
371
+ if (response.ok) {
372
+ // Type-safe access to token data — only update tokens when explicitly present
373
+ const tokenData = jsondata.data;
374
+ if (tokenData?.accessToken !== undefined) {
375
+ this.set_access_token(tokenData.accessToken ?? null);
376
+ }
377
+ if (tokenData?.refreshToken !== undefined) {
378
+ this.set_refresh_token(tokenData.refreshToken ?? null);
379
+ }
380
+ return ApiResponse.ok(jsondata.data, {
381
+ message: jsondata.message || 'Login successful',
382
+ code: response.status
383
+ });
384
+ }
385
+ else {
386
+ return ApiResponse.error(jsondata.message || 'Login Failed', {
387
+ code: response.status,
388
+ errors: jsondata.errors || {}
389
+ });
390
+ }
391
+ }
392
+ catch (e) {
393
+ if (e instanceof ApiResponse) {
394
+ return e;
395
+ }
396
+ return ApiResponse.error(e);
397
+ }
398
+ }
399
+ async logout(token = '') {
400
+ try {
401
+ // Use the caller-supplied token; fall back to the stored refresh token so
402
+ // that cookieless environments (Node.js, no cookie jar) still revoke the token.
403
+ const refreshToken = token || this.get_refresh_token() || '';
404
+ const response = await this.safeFetch(`${this.apiUrl}/api/auth/v1/logout`, {
405
+ method: 'POST',
406
+ body: refreshToken ? this.tryStringify({ token: refreshToken }) : '{}',
407
+ credentials: 'include'
408
+ });
409
+ const jsondata = await this.parseJsonResponse(response);
410
+ if (this.debug) {
411
+ console.log('Logout Response Headers:');
412
+ response.headers.forEach((value, name) => {
413
+ console.log(`${name}: ${value}`);
414
+ });
415
+ }
416
+ // Always clear local tokens on logout attempt, regardless of server response
417
+ this.set_access_token(null);
418
+ this.set_refresh_token(null);
419
+ if (!response.ok) {
420
+ return ApiResponse.error(jsondata.message || 'Logout Failed', {
421
+ code: response.status,
422
+ errors: jsondata.errors || {}
423
+ });
424
+ }
425
+ return ApiResponse.ok(jsondata.data, {
426
+ message: jsondata.message || 'Logout Successful',
427
+ code: response.status
428
+ });
429
+ }
430
+ catch (e) {
431
+ if (e instanceof ApiResponse) {
432
+ return e;
433
+ }
434
+ return ApiResponse.error(e);
435
+ }
436
+ }
437
+ async refreshAccessToken() {
438
+ // Serialise concurrent refresh attempts: if a refresh is already in flight,
439
+ // await it instead of launching a second one (which would fail because the
440
+ // server rotates the refresh token on every use).
441
+ if (this._refreshPromise) {
442
+ return this._refreshPromise;
443
+ }
444
+ this._refreshPromise = this.performRefresh();
445
+ try {
446
+ return (await this._refreshPromise);
447
+ }
448
+ finally {
449
+ this._refreshPromise = null;
450
+ }
451
+ }
452
+ async performRefresh() {
453
+ try {
454
+ if (!this.get_refresh_token()) {
455
+ return ApiResponse.error('No Refresh Token Available', { code: 401 });
456
+ }
457
+ const response = await this.safeFetch(`${this.apiUrl}/api/auth/v1/refresh`, {
458
+ method: 'POST',
459
+ body: this.tryStringify({ refreshToken: this.get_refresh_token() }),
460
+ credentials: 'include'
461
+ });
462
+ const jsondata = await this.parseJsonResponse(response);
463
+ if (!response.ok) {
464
+ // Clear stale tokens when the server rejects the refresh token.
465
+ if (response.status === 401 || response.status === 403) {
466
+ this.set_access_token(null);
467
+ this.set_refresh_token(null);
468
+ }
469
+ return ApiResponse.error(jsondata.message || 'Token Refresh Failed', {
470
+ code: response.status,
471
+ errors: jsondata.errors || {}
472
+ });
473
+ }
474
+ // Only update tokens when the field is explicitly present in the response.
475
+ const tokenData = jsondata.data;
476
+ if (tokenData?.accessToken !== undefined) {
477
+ this.set_access_token(tokenData.accessToken ?? null);
478
+ }
479
+ if (tokenData?.refreshToken !== undefined) {
480
+ this.set_refresh_token(tokenData.refreshToken ?? null);
481
+ }
482
+ return ApiResponse.ok(jsondata.data, {
483
+ message: jsondata.message || 'Token Refreshed',
484
+ code: response.status
485
+ });
486
+ }
487
+ catch (e) {
488
+ if (e instanceof ApiResponse) {
489
+ return e;
490
+ }
491
+ return ApiResponse.error(e);
492
+ }
493
+ }
494
+ async fetchWithRetry(url, init = {}) {
495
+ let allowAuthRetry = true;
496
+ // Iterative retry loop to avoid deep call stack
497
+ for (let timeoutRetryCount = 0; timeoutRetryCount <= this.maxRetries; timeoutRetryCount++) {
498
+ try {
499
+ const response = await this.safeFetch(url, {
500
+ ...init,
501
+ credentials: 'include'
502
+ });
503
+ // Parse JSON with type safety
504
+ const payload = await this.parseJsonResponse(response);
505
+ // Success case (HTTP layer)
506
+ // If the API uses a JSON { success: false } shape even on 2xx, respect it.
507
+ if (response.ok) {
508
+ if (payload.success === false) {
509
+ return ApiResponse.error(payload.message || 'Request failed', {
510
+ code: payload.code ?? response.status,
511
+ errors: payload.errors || {}
512
+ });
513
+ }
514
+ return ApiResponse.ok(payload.data, {
515
+ message: payload.message || 'OK',
516
+ code: payload.code ?? response.status,
517
+ errors: payload.errors || {}
518
+ });
519
+ }
520
+ // If using API key, don't retry on auth failures
521
+ if (this.apiKey) {
522
+ return ApiResponse.error(payload.message || 'Request failed with API key authentication', {
523
+ code: response.status,
524
+ errors: payload.errors || {}
525
+ });
526
+ }
527
+ // Try to refresh token on 401 (only once)
528
+ if (allowAuthRetry && response.status === 401 && this.get_refresh_token()) {
529
+ if (this.debug) {
530
+ console.log('Received 401, attempting token refresh...');
531
+ }
532
+ const refreshRes = await this.refreshAccessToken();
533
+ if (!refreshRes.success) {
534
+ return ApiResponse.error(refreshRes.message, {
535
+ code: refreshRes.code,
536
+ errors: refreshRes.errors
537
+ });
538
+ }
539
+ // Allow one more iteration but disable further auth retries
540
+ timeoutRetryCount = 0;
541
+ allowAuthRetry = false;
542
+ continue; // Retry with new token
543
+ }
544
+ // Final fallback error
545
+ return ApiResponse.error(payload.message || 'Unable to serve request', {
546
+ code: response.status,
547
+ errors: payload.errors || {}
548
+ });
549
+ }
550
+ catch (err) {
551
+ // Handle thrown ApiResponse errors from safeFetch or parseJsonResponse
552
+ if (err instanceof ApiResponse) {
553
+ // Check if this is a timeout error and we can retry
554
+ if (err.code === 504 && timeoutRetryCount < this.maxRetries) {
555
+ if (this.debug) {
556
+ console.log(`Request timed out, retrying... (attempt ${timeoutRetryCount + 1}/${this.maxRetries + 1})`);
557
+ }
558
+ continue; // Retry
559
+ }
560
+ return err; // Return error
561
+ }
562
+ return ApiResponse.error(err);
563
+ }
564
+ }
565
+ // This should never be reached, but TypeScript needs it
566
+ return ApiResponse.error('Maximum retries exceeded', { code: 500 });
567
+ }
568
+ /**
569
+ * Performs a generic HTTP request to the API
570
+ * @param {'GET'|'POST'|'PUT'|'DELETE'} method - The HTTP method to use
571
+ * @param {string} command - The API endpoint path
572
+ * @param {SerializableBody} [body] - Optional request body (for POST/PUT/DELETE requests)
573
+ * @returns {Promise<ApiResponse<T>>} A promise resolving to the API response
574
+ * @template T - The expected type of the response data
575
+ */
576
+ async request(method, command, body, files) {
577
+ const url = `${this.apiUrl}${command}`;
578
+ const options = {
579
+ method
580
+ };
581
+ if (files && files.length > 0) {
582
+ const form = new FormData();
583
+ if (body !== undefined && body !== null) {
584
+ if (isPlainObject(body)) {
585
+ for (const [key, value] of Object.entries(body)) {
586
+ form.append(key, typeof value === 'object' && value !== null ? JSON.stringify(value) : String(value));
587
+ }
588
+ }
589
+ else {
590
+ form.append('payload', this.tryStringify(body));
591
+ }
592
+ }
593
+ for (const fileEntry of files) {
594
+ if (Array.isArray(fileEntry)) {
595
+ const [name, file] = fileEntry;
596
+ form.append(name, file);
597
+ }
598
+ else {
599
+ form.append('files', fileEntry); // default field name
600
+ }
601
+ }
602
+ options.body = form;
603
+ }
604
+ else if (body !== undefined) {
605
+ try {
606
+ options.body = this.tryStringify(body);
607
+ }
608
+ catch (e) {
609
+ return ApiResponse.error(e);
610
+ }
611
+ }
612
+ if (this.debug) {
613
+ console.log(`Making ${method} request to: ${url} (timeout: ${this.timeoutMs}ms, max retries: ${this.maxRetries})`);
614
+ if (body !== undefined) {
615
+ console.log('Request body:', options.body);
616
+ }
617
+ }
618
+ return this.fetchWithRetry(url, options);
619
+ }
620
+ async get(command) {
621
+ return this.request('GET', command);
622
+ }
623
+ async post(command, body, files) {
624
+ return this.request('POST', command, body, files);
625
+ }
626
+ async put(command, body) {
627
+ return this.request('PUT', command, body);
628
+ }
629
+ async delete(command, body) {
630
+ return this.request('DELETE', command, body);
631
+ }
632
+ async ping() {
633
+ return this.get('/api/v1/ping');
634
+ }
635
+ }
636
+ exports.default = ApiClient;
@@ -0,0 +1,4 @@
1
+ export { default as ApiClient, ApiResponse } from './apicore-client.js';
2
+ export { default } from './apicore-client.js';
3
+ export type { maybeFile } from './apicore-client.js';
4
+ export type { ApiClientConfig, ApiResponseData, AuthIdentifier, AuthTokenData, LogoutResponseData, PingResponseData, SafeUser, WhoAmIResponseData } from './apicore-client.js';
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = exports.ApiResponse = exports.ApiClient = void 0;
7
+ var apicore_client_js_1 = require("./apicore-client.js");
8
+ Object.defineProperty(exports, "ApiClient", { enumerable: true, get: function () { return __importDefault(apicore_client_js_1).default; } });
9
+ Object.defineProperty(exports, "ApiResponse", { enumerable: true, get: function () { return apicore_client_js_1.ApiResponse; } });
10
+ var apicore_client_js_2 = require("./apicore-client.js");
11
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(apicore_client_js_2).default; } });