@sisense/sdk-rest-client 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,18 @@
1
1
  /// <reference lib="dom" />
2
2
  import { Authenticator } from './interfaces.js';
3
+ export interface HttpClientRequestConfig {
4
+ skipTrackingParam?: boolean;
5
+ nonJSONBody?: boolean;
6
+ returnBlob?: boolean;
7
+ }
3
8
  export declare class HttpClient {
4
9
  readonly auth: Authenticator;
5
10
  readonly url: string;
6
11
  readonly env: string;
7
12
  constructor(url: string, auth: Authenticator, env: string);
8
13
  login(): Promise<boolean>;
9
- call<T = unknown>(url: string, config: RequestInit): Promise<T>;
10
- post<T = unknown>(endpoint: string, data: unknown, options?: RequestInit, abortSignal?: AbortSignal): Promise<T>;
11
- get<T = unknown>(endpoint: string, request?: RequestInit): Promise<T>;
12
- delete<T = void>(endpoint: string, request?: RequestInit): Promise<T>;
14
+ call<T = unknown>(url: string, config: RequestInit, requestConfig?: HttpClientRequestConfig): Promise<T>;
15
+ post<T = unknown>(endpoint: string, data: unknown, options?: RequestInit, abortSignal?: AbortSignal, config?: HttpClientRequestConfig): Promise<T>;
16
+ get<T = unknown>(endpoint: string, request?: RequestInit, config?: HttpClientRequestConfig): Promise<T>;
17
+ delete<T = void>(endpoint: string, request?: RequestInit, config?: HttpClientRequestConfig): Promise<T>;
13
18
  }
@@ -42,7 +42,7 @@ export class HttpClient {
42
42
  return this.auth.authenticate();
43
43
  });
44
44
  }
45
- call(url, config) {
45
+ call(url, config, requestConfig) {
46
46
  return __awaiter(this, void 0, void 0, function* () {
47
47
  if (this.auth.isAuthenticating()) {
48
48
  return new Promise((res) => {
@@ -52,7 +52,7 @@ export class HttpClient {
52
52
  setTimeout(retry, 10);
53
53
  return;
54
54
  }
55
- void this.call(url, config).then((r) => res(r));
55
+ void this.call(url, config, requestConfig).then((r) => res(r));
56
56
  };
57
57
  retry();
58
58
  });
@@ -67,14 +67,14 @@ export class HttpClient {
67
67
  const trackedUrl = addQueryParamsToUrl(url, {
68
68
  trc: this.env,
69
69
  });
70
- const response = yield fetch(trackedUrl, config);
70
+ const response = yield fetch((requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.skipTrackingParam) ? url : trackedUrl, config);
71
71
  if (response.status === 204 || // No content
72
72
  response.status === 304 // Not modified
73
73
  ) {
74
74
  return undefined;
75
75
  }
76
76
  try {
77
- return (yield response.json());
77
+ return ((requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.returnBlob) ? yield response.blob() : yield response.json());
78
78
  }
79
79
  catch (e) {
80
80
  // some of APIs in Sisense returns 200 with empty body - so it's not possible
@@ -89,25 +89,25 @@ export class HttpClient {
89
89
  });
90
90
  }
91
91
  // eslint-disable-next-line max-params
92
- post(endpoint, data, options = {}, abortSignal) {
92
+ post(endpoint, data, options = {}, abortSignal, config) {
93
93
  return __awaiter(this, void 0, void 0, function* () {
94
- const request = Object.assign({ method: 'POST', body: JSON.stringify(data), headers: {
94
+ const request = Object.assign({ method: 'POST', body: ((config === null || config === void 0 ? void 0 : config.nonJSONBody) ? data : JSON.stringify(data)), headers: {
95
95
  Accept: 'application/json, text/plain, */*',
96
96
  'Content-Type': 'application/json;charset=UTF-8',
97
97
  }, signal: abortSignal }, options);
98
- return this.call(this.url + endpoint, request);
98
+ return this.call(this.url + endpoint, request, config);
99
99
  });
100
100
  }
101
- get(endpoint, request = {}) {
101
+ get(endpoint, request = {}, config) {
102
102
  return __awaiter(this, void 0, void 0, function* () {
103
103
  request.method = 'GET';
104
- return this.call(this.url + endpoint, request);
104
+ return this.call(this.url + endpoint, request, config);
105
105
  });
106
106
  }
107
- delete(endpoint, request = {}) {
107
+ delete(endpoint, request = {}, config) {
108
108
  return __awaiter(this, void 0, void 0, function* () {
109
109
  request.method = 'DELETE';
110
- return this.call(this.url + endpoint, request);
110
+ return this.call(this.url + endpoint, request, config);
111
111
  });
112
112
  }
113
113
  }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import './translation/initialize-i18n.js';
1
2
  export * from './interfaces.js';
2
3
  export { PasswordAuthenticator } from './password-authenticator.js';
3
4
  export { SsoAuthenticator } from './sso-authenticator.js';
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import './translation/initialize-i18n.js';
1
2
  export * from './interfaces.js';
2
3
  export { PasswordAuthenticator } from './password-authenticator.js';
3
4
  export { SsoAuthenticator } from './sso-authenticator.js';
@@ -2,10 +2,14 @@ import { BearerAuthenticator } from './bearer-authenticator.js';
2
2
  import { WatAuthenticator } from './wat-authenticator.js';
3
3
  import { PasswordAuthenticator } from './password-authenticator.js';
4
4
  import { SsoAuthenticator } from './sso-authenticator.js';
5
- import { ERROR_PREFIX } from './constants.js';
5
+ import { TranslatableError } from './translation/translatable-error.js';
6
6
  export function handleErrorResponse(response) {
7
7
  if (!response.ok) {
8
- throw Error(`${ERROR_PREFIX} Status: ${response.status}${response.statusText ? ' - ' + response.statusText : ''}`);
8
+ throw new TranslatableError('errors.responseError', {
9
+ status: response.status.toString(),
10
+ statusText: response.statusText,
11
+ context: response.statusText ? 'withStatusText' : 'onlyStatus',
12
+ });
9
13
  }
10
14
  return response;
11
15
  }
@@ -13,18 +17,14 @@ export function handleUnauthorizedResponse(response, auth) {
13
17
  auth.invalidate();
14
18
  // skip login redirect for token auth
15
19
  if (auth instanceof PasswordAuthenticator) {
16
- throw Error(`${ERROR_PREFIX} Username and password authentication was not successful. Check credentials.`);
20
+ throw new TranslatableError('errors.passwordAuthFailed');
17
21
  }
18
22
  if (auth instanceof BearerAuthenticator || auth instanceof WatAuthenticator) {
19
- throw Error(`${ERROR_PREFIX} Token authentication was not successful. Check credentials.`);
23
+ throw new TranslatableError('errors.tokenAuthFailed');
20
24
  }
21
- if (auth instanceof SsoAuthenticator) {
22
- if (!auth.isAuthenticating()) {
23
- // try to reauthenticate
24
- void auth.authenticate();
25
- }
26
- // throw error to display while waiting for redirect
27
- throw Error(`${ERROR_PREFIX} Not authenticated. Please wait for redirect or check SSO provider.`);
25
+ if (auth instanceof SsoAuthenticator && !auth.isAuthenticating()) {
26
+ // try to reauthenticate
27
+ void auth.authenticate();
28
28
  }
29
29
  return response;
30
30
  }
@@ -45,5 +45,5 @@ export function isNetworkError(responseError) {
45
45
  * @returns A promise that rejects with an error message.
46
46
  */
47
47
  export function handleNetworkError() {
48
- return Promise.reject(new Error("Network error. Probably you forgot to add your domain to 'CORS Allowed Origins' in Sisense Admin Panel -> Security Settings."));
48
+ return Promise.reject(new TranslatableError('errors.networkError'));
49
49
  }
@@ -8,6 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ import { TranslatableError } from './translation/translatable-error.js';
11
12
  export class SsoAuthenticator {
12
13
  constructor(url) {
13
14
  this._valid = true;
@@ -40,7 +41,7 @@ export class SsoAuthenticator {
40
41
  if (!res.isAuthenticated) {
41
42
  // SSO is disabled on instance, do not proceed
42
43
  if (!res.ssoEnabled)
43
- throw new Error('SSO is not enabled on target instance, please choose another authentication method');
44
+ throw new TranslatableError('errors.ssoNotEnabled');
44
45
  // redirect to login page
45
46
  window.location.href = `${res.loginUrl}?return_to=${window.location.href}`;
46
47
  }
@@ -0,0 +1,2 @@
1
+ export declare function initializeI18n(): import("@sisense/sdk-common").I18NextInitResult;
2
+ export declare const i18nextInstance: import("i18next").i18n;
@@ -0,0 +1,10 @@
1
+ import { initI18next } from '@sisense/sdk-common';
2
+ import { resources, PACKAGE_NAMESPACE } from './resources/index.js';
3
+ export function initializeI18n() {
4
+ return initI18next({
5
+ resource: resources,
6
+ language: 'en',
7
+ namespace: PACKAGE_NAMESPACE,
8
+ });
9
+ }
10
+ export const { i18nextInstance } = initializeI18n();
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Translation dictionary for English language.
3
+ */
4
+ export declare const translation: {
5
+ errorPrefix: string;
6
+ errors: {
7
+ networkError: string;
8
+ ssoNotEnabled: string;
9
+ passwordAuthFailed: string;
10
+ tokenAuthFailed: string;
11
+ responseError_onlyStatus: string;
12
+ responseError_withStatusText: string;
13
+ };
14
+ };
15
+ export declare type TranslationDictionary = typeof translation;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Translation dictionary for English language.
3
+ */
4
+ export const translation = {
5
+ errorPrefix: '[request-error]',
6
+ errors: {
7
+ networkError: "Network error. Probably you forgot to add your domain to 'CORS Allowed Origins' in Sisense Admin Panel -> Security Settings.",
8
+ ssoNotEnabled: 'SSO is not enabled on target instance, please choose another authentication method',
9
+ passwordAuthFailed: '$t(errorPrefix) Username and password authentication was not successful. Check credentials.',
10
+ tokenAuthFailed: '$t(errorPrefix) Token authentication was not successful. Check credentials.',
11
+ responseError_onlyStatus: '$t(errorPrefix) Status: {{status}}',
12
+ responseError_withStatusText: '$t(errorPrefix) Status: {{status}} - {{statusText}}',
13
+ },
14
+ };
@@ -0,0 +1,27 @@
1
+ import { TranslationDictionary } from './en.js';
2
+ export type { TranslationDictionary };
3
+ export declare const PACKAGE_NAMESPACE: "sdkRestClient";
4
+ export declare const resources: {
5
+ en: {
6
+ errorPrefix: string;
7
+ errors: {
8
+ networkError: string;
9
+ ssoNotEnabled: string;
10
+ passwordAuthFailed: string;
11
+ tokenAuthFailed: string;
12
+ responseError_onlyStatus: string;
13
+ responseError_withStatusText: string;
14
+ };
15
+ };
16
+ uk: {
17
+ errorPrefix: string;
18
+ errors: {
19
+ networkError: string;
20
+ ssoNotEnabled: string;
21
+ passwordAuthFailed: string;
22
+ tokenAuthFailed: string;
23
+ responseError_onlyStatus: string;
24
+ responseError_withStatusText: string;
25
+ };
26
+ };
27
+ };
@@ -0,0 +1,7 @@
1
+ import { translation as enDictionary } from './en.js';
2
+ import { translation as ukDictionary } from './uk.js';
3
+ export const PACKAGE_NAMESPACE = 'sdkRestClient';
4
+ export const resources = {
5
+ en: enDictionary,
6
+ uk: ukDictionary,
7
+ };
@@ -0,0 +1,5 @@
1
+ import { TranslationDictionary } from './index.js';
2
+ /**
3
+ * Translation dictionary for Ukrainian language.
4
+ */
5
+ export declare const translation: TranslationDictionary;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Translation dictionary for Ukrainian language.
3
+ */
4
+ export const translation = {
5
+ errorPrefix: '[request-error]',
6
+ errors: {
7
+ networkError: 'Помилка мережі. Можливо ви забули додати свій домен до «CORS Allowed Origins» в панелі адміністратора Sisense -> Security Settings.',
8
+ ssoNotEnabled: 'SSO не ввімкнено на цьому сервері, будь ласка, виберіть інший метод аутентифікації',
9
+ passwordAuthFailed: '$t(errorPrefix) Помилка автентифікації за допомогою імені користувача та пароля. Перевірте дані для входу.',
10
+ tokenAuthFailed: '$t(errorPrefix) Помилка автентифікації за допомогою токена. Перевірте дані для входу.',
11
+ responseError_onlyStatus: '$t(errorPrefix) Статус: {{status}}',
12
+ responseError_withStatusText: '$t(errorPrefix) Статус: {{status}} - {{statusText}}',
13
+ },
14
+ };
@@ -0,0 +1,5 @@
1
+ import { AbstractTranslatableError } from '@sisense/sdk-common';
2
+ import { PACKAGE_NAMESPACE } from './resources/index.js';
3
+ export declare class TranslatableError extends AbstractTranslatableError<typeof PACKAGE_NAMESPACE> {
4
+ constructor(translationKey: string, interpolationOptions?: Record<string, string>);
5
+ }
@@ -0,0 +1,11 @@
1
+ import { AbstractTranslatableError } from '@sisense/sdk-common';
2
+ import { i18nextInstance } from './initialize-i18n.js';
3
+ import { PACKAGE_NAMESPACE } from './resources/index.js';
4
+ export class TranslatableError extends AbstractTranslatableError {
5
+ constructor(translationKey, interpolationOptions) {
6
+ super(PACKAGE_NAMESPACE, {
7
+ key: translationKey,
8
+ interpolationOptions: interpolationOptions,
9
+ }, i18nextInstance.t);
10
+ }
11
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sisense/sdk-rest-client",
3
- "version": "0.14.0",
3
+ "version": "0.16.0",
4
4
  "type": "module",
5
5
  "exports": "./dist/index.js",
6
6
  "main": "./dist/index.js",
@@ -9,6 +9,7 @@
9
9
  "author": "Sisense",
10
10
  "license": "SEE LICENSE IN LICENSE.md",
11
11
  "dependencies": {
12
+ "@sisense/sdk-common": "^0.16.0",
12
13
  "fetch-intercept": "^2.4.0"
13
14
  },
14
15
  "scripts": {