@emilgroup/account-sdk-node 1.0.0 → 1.3.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.
package/README.md CHANGED
@@ -1,11 +1,6 @@
1
- ## @emilgroup/account-sdk-node@1.0.0
1
+ # Emil Account SDK for Nodejs
2
2
 
3
- This TypeScript/JavaScript client utilizes [axios](https://github.com/axios/axios). The generated Node module can be used in the following environments:
4
-
5
- Environment
6
- * Node.js
7
- * Webpack
8
- * Browserify
3
+ This TypeScript/JavaScript client utilizes [axios](https://github.com/axios/axios). The generated Node module can be used with Nodejs based applications.
9
4
 
10
5
  Language level
11
6
  * ES5 - you must have a Promises/A+ library installed
@@ -15,15 +10,20 @@ Module system
15
10
  * CommonJS
16
11
  * ES6 module system
17
12
 
18
- It can be used in both TypeScript and JavaScript. In TypeScript, the definition should be automatically resolved via `package.json`. ([Reference](http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html))
13
+ Although this package can be used in both TypeScript and JavaScript, it is intended to be used with TypeScript. The definition should be automatically resolved via `package.json`. ([Reference](http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html)). For more information, you can go to [Emil Api documentation](https://emil.stoplight.io/docs/emil-api/).
19
14
 
20
- ### Consuming
15
+ ## Consuming
21
16
 
22
- navigate to the folder of your consuming project and run one of the following commands.
17
+ Navigate to the folder of your consuming project and run one of the following commands:
23
18
 
24
19
  ```
25
- npm install @emilgroup/account-sdk-node@1.0.0 --save
20
+ npm install @emilgroup/account-sdk-node@1.3.0 --save
21
+ ```
22
+ or
23
+ ```
24
+ yarn add @emilgroup/account-sdk-node@1.3.0
26
25
  ```
26
+
27
27
  And then you can import `AccountsApi`.
28
28
 
29
29
  ```ts
@@ -31,15 +31,32 @@ import { AccountsApi } from '@emilgroup/account-sdk-node'
31
31
 
32
32
  const accountsApi = new AccountsApi();
33
33
  ```
34
+ ## Credentials
35
+
36
+ To use authentication protected endpoints, you have to first authorize. To do so, the easiest way is to provide a configuration file under `~/.emil/credentials` with the following content:
37
+
38
+ ```shell
39
+ emil_username=XXXXX@XXXX.XXX
40
+ emil_password=XXXXXXXXXXXXXX
41
+ ```
42
+
43
+ It is also possible to provide environment variables instead:
44
+
45
+ ```shell
46
+ export EMIL_USERNAME=XXXXX@XXXX.XXX
47
+ export EMIL_PASSWORD=XXXXXXXXXXXXXX
48
+ ```
49
+
50
+ ## Example
34
51
 
35
- To use authentication protected endpoints, you have to first authorize. To do so, use the `authorize` function in `AccountsApi`:
52
+ Here is a basic functionning example:
36
53
 
37
54
  ```ts
38
55
  async function listAccounts(): Promise<Void> {
39
56
  try {
40
57
  const accountsApi = new AccountsApi();
41
58
 
42
- await accountsApi.authorize('username', 'password');
59
+ await accountsApi.initialize(); // should be called only once per Api.
43
60
 
44
61
  const { data: { items } } = await accountsApi.listAccounts();
45
62
 
package/api.ts CHANGED
@@ -33,4 +33,5 @@ export * from './api/accounts-api';
33
33
  export enum Environment {
34
34
  Production = 'https://apiv2.emil.de',
35
35
  Test = 'https://apiv2-test.emil.de',
36
+ Development = 'https://apiv2-dev.emil.de',
36
37
  }
package/base.ts CHANGED
@@ -17,9 +17,17 @@ import { Configuration } from "./configuration";
17
17
  // Some imports not used depending on template conditions
18
18
  // @ts-ignore
19
19
  import globalAxios, { AxiosPromise, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
20
+ import * as fs from 'fs';
21
+ import * as path from 'path';
22
+ import * as os from 'os';
20
23
 
21
- export const BASE_PATH = "http://localhost".replace(/\/+$/, "");
24
+ export const BASE_PATH = "https://apiv2.emil.de".replace(/\/+$/, "");
25
+ const CONFIG_DIRECTORY = '.emil';
26
+ const CONFIG_FILENAME = 'credentials';
27
+ const KEY_USERNAME = 'emil_username';
28
+ const KEY_PASSWORD = 'emil_password';
22
29
 
30
+ const filePath = os.homedir() + path.sep + CONFIG_DIRECTORY + path.sep + CONFIG_FILENAME;
23
31
  /**
24
32
  *
25
33
  * @export
@@ -34,7 +42,6 @@ export const COLLECTION_FORMATS = {
34
42
  export interface LoginClass {
35
43
  accessToken: string;
36
44
  permissions: Array<string>;
37
- newPasswordRequired: boolean;
38
45
  }
39
46
 
40
47
  export enum Environment {
@@ -42,6 +49,13 @@ export enum Environment {
42
49
  Test = 'https://apiv2-test.emil.de',
43
50
  }
44
51
 
52
+ let _retry_count = 0
53
+ let _retry = null
54
+
55
+ export function resetRetry() {
56
+ _retry_count = 0
57
+ }
58
+
45
59
  /**
46
60
  *
47
61
  * @export
@@ -52,6 +66,8 @@ export interface RequestArgs {
52
66
  options: AxiosRequestConfig;
53
67
  }
54
68
 
69
+ const NETWORK_ERROR_MESSAGE = "Network Error";
70
+
55
71
  /**
56
72
  *
57
73
  * @export
@@ -59,6 +75,8 @@ export interface RequestArgs {
59
75
  */
60
76
  export class BaseAPI {
61
77
  protected configuration: Configuration;
78
+ private username?: string;
79
+ private password?: string;
62
80
 
63
81
  constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) {
64
82
  if (configuration) {
@@ -70,51 +88,61 @@ export class BaseAPI {
70
88
  });
71
89
  }
72
90
 
73
- axios.interceptors.response.use(
74
- (res) => {
75
- return res;
76
- },
77
- async (err) => {
78
- const originalConfig = err.config;
79
- if (err.response) {
80
- // Access Token was expired
81
- if (err.response.status === 401 && !originalConfig._retry) {
82
- originalConfig._retry = true;
83
- try {
84
- const tokenString = await this.refreshToken();
85
- const accessToken = `Bearer ${tokenString}`;
91
+ this.attachInterceptor(axios);
92
+ }
86
93
 
87
- const localVarHeaderParameter = {} as any;
88
- localVarHeaderParameter['Authorization'] = accessToken;
94
+ async initialize(env: Environment = Environment.Production) {
95
+ this.configuration.basePath = env;
89
96
 
90
- originalConfig.headers = {
91
- ...originalConfig.headers,
92
- ...localVarHeaderParameter,
93
- };
97
+ await this.loadCredentials();
94
98
 
95
- this.configuration.accessToken = accessToken;
99
+ if (this.username) {
100
+ await this.authorize(this.username, this.password);
101
+ this.password = null; // to avoid keeping password loaded in memory.
102
+ }
103
+ }
96
104
 
97
- return axios(originalConfig);
98
- } catch (_error) {
99
- if (_error.response && _error.response.data) {
100
- return Promise.reject(_error.response.data);
101
- }
102
- return Promise.reject(_error);
103
- }
104
- }
105
- if (err.response.status === 403 && err.response.data) {
106
- return Promise.reject(err.response.data);
107
- }
108
- }
109
- return Promise.reject(err);
110
- }
111
- );
105
+ private async loadCredentials() {
106
+ try {
107
+ await this.readConfigFile();
108
+ } catch (error) {
109
+ console.warn(`No credentials file found. Check that ${filePath} exists.`);
110
+ }
111
+
112
+ this.readEnvVariables();
113
+
114
+ if (!this.username) {
115
+ console.info(`No credentials found in credentials file or environment variables. Either provide some or use
116
+ authorize() function.`);
117
+ }
112
118
  }
113
119
 
114
- getConfiguration(): Configuration {
115
- return this.configuration;
120
+ private async readConfigFile() {
121
+ const file = await fs.promises.readFile(filePath, 'utf-8');
122
+
123
+ const lines = file.split(os.EOL)
124
+ .filter(Boolean);
125
+
126
+ lines.forEach((line: string) => {
127
+ if (line.startsWith(KEY_USERNAME)) {
128
+ this.username = line.length > KEY_USERNAME.length + 1 ? line.substring(KEY_USERNAME.length + 1) : '';
129
+ } else if (line.startsWith(KEY_PASSWORD)) {
130
+ this.password = line.length > KEY_PASSWORD.length + 1 ? line.substring(KEY_PASSWORD.length + 1) : '';
131
+ }
132
+ });
116
133
  }
117
134
 
135
+ private readEnvVariables(): boolean {
136
+ if (process.env.EMIL_USERNAME) {
137
+ this.username = process.env.EMIL_USERNAME;
138
+ this.password = process.env.EMIL_PASSWORD || '';
139
+
140
+ return true;
141
+ }
142
+
143
+ return false;
144
+ }
145
+
118
146
  selectEnvironment(env: Environment) {
119
147
  this.configuration.basePath = env;
120
148
  }
@@ -123,26 +151,27 @@ export class BaseAPI {
123
151
  const options: AxiosRequestConfig = {
124
152
  method: 'POST',
125
153
  url: `${this.configuration.basePath}/authservice/v1/login`,
126
- headers: {'Content-Type': 'application/json'},
154
+ headers: { 'Content-Type': 'application/json' },
127
155
  data: {
128
- username,
156
+ username,
129
157
  password,
130
158
  },
131
159
  withCredentials: true,
132
160
  };
133
161
 
134
162
  const response = await globalAxios.request<LoginClass>(options);
135
-
136
- const { data: { accessToken } } = response;
137
- const refreshToken = this.extractRefreshToken(response)
138
163
 
164
+ const { data: { accessToken } } = response;
139
165
  this.configuration.username = username;
140
166
  this.configuration.accessToken = `Bearer ${accessToken}`;
167
+
168
+ const refreshToken = this.extractRefreshToken(response)
141
169
  this.configuration.refreshToken = refreshToken;
142
170
  }
143
171
 
144
172
  async refreshToken(): Promise<string> {
145
173
  const { username, refreshToken } = this.configuration;
174
+
146
175
 
147
176
  if (!username || !refreshToken) {
148
177
  return '';
@@ -152,10 +181,10 @@ export class BaseAPI {
152
181
  method: 'POST',
153
182
  url: `${this.configuration.basePath}/authservice/v1/refresh-token`,
154
183
  headers: {
155
- 'Content-Type': 'application/json',
184
+ 'Content-Type': 'application/json',
156
185
  Cookie: refreshToken,
157
186
  },
158
- data: {username: username},
187
+ data: { username: username },
159
188
  withCredentials: true,
160
189
  };
161
190
 
@@ -165,14 +194,78 @@ export class BaseAPI {
165
194
  }
166
195
 
167
196
  private extractRefreshToken(response: AxiosResponse): string {
168
- if (response.headers && response.headers['set-cookie']
169
- && response.headers['set-cookie'].length > 0) {
197
+ if (response.headers && response.headers['set-cookie']
198
+ && response.headers['set-cookie'].length > 0) {
170
199
 
171
200
  return `${response.headers['set-cookie'][0].split(';')[0]};`;
172
201
  }
173
202
 
174
203
  return '';
175
204
  }
205
+
206
+ getConfiguration(): Configuration {
207
+ return this.configuration;
208
+ }
209
+
210
+ private attachInterceptor(axios: AxiosInstance) {
211
+ axios.interceptors.response.use(
212
+ (res) => {
213
+ return res;
214
+ },
215
+ async (err) => {
216
+ let originalConfig = err.config;
217
+ if (err.response) {
218
+ // Access Token was expired
219
+ if (err.response.status === 401 && !originalConfig._retry) {
220
+ originalConfig._retry = true;
221
+ try {
222
+ const tokenString = await this.refreshToken();
223
+ const accessToken = `Bearer ${tokenString}`;
224
+
225
+ originalConfig.headers['Authorization'] = `Bearer ${accessToken}`
226
+
227
+ this.configuration.accessToken = accessToken;
228
+
229
+ return axios.request(originalConfig);
230
+ } catch (_error) {
231
+ if (_error.response && _error.response.data) {
232
+ return Promise.reject(_error.response.data);
233
+ }
234
+ return Promise.reject(_error);
235
+ }
236
+ }
237
+ if (err.response.status === 403 && err.response.data) {
238
+ return Promise.reject(err.response.data);
239
+ }
240
+ } else if(err.message === NETWORK_ERROR_MESSAGE
241
+ && err.isAxiosError
242
+ && originalConfig.headers.hasOwnProperty('Authorization')
243
+ && _retry_count < 4
244
+ ){
245
+ _retry_count++;
246
+ try {
247
+ const tokenString = await this.refreshToken();
248
+ const accessToken = `Bearer ${tokenString}`;
249
+
250
+ _retry = true;
251
+ originalConfig.headers['Authorization'] = accessToken;
252
+
253
+ this.configuration.accessToken = accessToken;
254
+
255
+ return axios.request({
256
+ ...originalConfig,
257
+ });
258
+ } catch (_error) {
259
+ if (_error.response && _error.response.data) {
260
+ return Promise.reject(_error.response.data);
261
+ }
262
+ return Promise.reject(_error);
263
+ }
264
+ }
265
+ return Promise.reject(err);
266
+ }
267
+ );
268
+ }
176
269
  };
177
270
 
178
271
  /**
@@ -187,3 +280,4 @@ export class RequiredError extends Error {
187
280
  super(msg);
188
281
  }
189
282
  }
283
+
package/common.ts CHANGED
@@ -136,3 +136,64 @@ export const createRequestFunction = function (axiosArgs: RequestArgs, globalAxi
136
136
  return axios.request<T, R>(axiosRequestArgs);
137
137
  };
138
138
  }
139
+
140
+ /* tslint:disable */
141
+ /* eslint-disable */
142
+ /**
143
+ * EMIL AccountService
144
+ * The EMIL AccountService API description
145
+ *
146
+ * The version of the OpenAPI document: 1.0
147
+ *
148
+ *
149
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
150
+ * https://openapi-generator.tech
151
+ * Do not edit the class manually.
152
+ */
153
+
154
+
155
+ export interface IStorageConverter<D, SD> {
156
+ toStorageData( data: D ): SD;
157
+ fromStorageData( storageData: SD ): D;
158
+ }
159
+
160
+ export interface IStorage {
161
+ get<T>( key: string, converter?: IStorageConverter<T, any> ): T | null;
162
+ set<T>( key: string, value: T, converter?: IStorageConverter<T, any> ): void;
163
+ }
164
+
165
+ export class LocalStorage implements IStorage {
166
+ readonly storage: Storage;
167
+
168
+ constructor() {
169
+ this.storage = localStorage;
170
+ }
171
+
172
+ get<T>( key: string, converter?: IStorageConverter<T, any> ): T | null {
173
+ const jsonValue = this.storage.getItem( key );
174
+ if ( jsonValue === null ) {
175
+ return null;
176
+ }
177
+ const value = JSON.parse( jsonValue );
178
+ if ( converter !== undefined ) {
179
+ return converter.fromStorageData( value );
180
+ } else {
181
+ return value as T;
182
+ }
183
+ }
184
+
185
+ set<T>( key: string, value: T, converter?: IStorageConverter<T, any> ): void {
186
+ let valueToStore: any = value;
187
+ if ( converter !== undefined ) {
188
+ valueToStore = converter.toStorageData( value );
189
+ }
190
+ const jsonValue = JSON.stringify( valueToStore );
191
+ this.storage.setItem( key, jsonValue );
192
+ }
193
+ }
194
+
195
+ let _defaultStorage: IStorage = null;
196
+
197
+ export const defaultStorage = (): IStorage => {
198
+ return _defaultStorage || (_defaultStorage = new LocalStorage());
199
+ };
@@ -53,7 +53,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
53
53
  function verb(n) { return function (v) { return step([n, v]); }; }
54
54
  function step(op) {
55
55
  if (f) throw new TypeError("Generator is already executing.");
56
- while (_) try {
56
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
57
57
  if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
58
58
  if (y = 0, t) op = [op[0] & 2, t.value];
59
59
  switch (op[0]) {
package/dist/api.d.ts CHANGED
@@ -12,5 +12,6 @@
12
12
  export * from './api/accounts-api';
13
13
  export declare enum Environment {
14
14
  Production = "https://apiv2.emil.de",
15
- Test = "https://apiv2-test.emil.de"
15
+ Test = "https://apiv2-test.emil.de",
16
+ Development = "https://apiv2-dev.emil.de"
16
17
  }
package/dist/api.js CHANGED
@@ -33,4 +33,5 @@ var Environment;
33
33
  (function (Environment) {
34
34
  Environment["Production"] = "https://apiv2.emil.de";
35
35
  Environment["Test"] = "https://apiv2-test.emil.de";
36
+ Environment["Development"] = "https://apiv2-dev.emil.de";
36
37
  })(Environment = exports.Environment || (exports.Environment = {}));
package/dist/base.d.ts CHANGED
@@ -25,12 +25,12 @@ export declare const COLLECTION_FORMATS: {
25
25
  export interface LoginClass {
26
26
  accessToken: string;
27
27
  permissions: Array<string>;
28
- newPasswordRequired: boolean;
29
28
  }
30
29
  export declare enum Environment {
31
30
  Production = "https://apiv2.emil.de",
32
31
  Test = "https://apiv2-test.emil.de"
33
32
  }
33
+ export declare function resetRetry(): void;
34
34
  /**
35
35
  *
36
36
  * @export
@@ -49,12 +49,19 @@ export declare class BaseAPI {
49
49
  protected basePath: string;
50
50
  protected axios: AxiosInstance;
51
51
  protected configuration: Configuration;
52
+ private username?;
53
+ private password?;
52
54
  constructor(configuration?: Configuration, basePath?: string, axios?: AxiosInstance);
53
- getConfiguration(): Configuration;
55
+ initialize(env?: Environment): Promise<void>;
56
+ private loadCredentials;
57
+ private readConfigFile;
58
+ private readEnvVariables;
54
59
  selectEnvironment(env: Environment): void;
55
60
  authorize(username: string, password: string): Promise<void>;
56
61
  refreshToken(): Promise<string>;
57
62
  private extractRefreshToken;
63
+ getConfiguration(): Configuration;
64
+ private attachInterceptor;
58
65
  }
59
66
  /**
60
67
  *
package/dist/base.js CHANGED
@@ -38,6 +38,29 @@ var __assign = (this && this.__assign) || function () {
38
38
  };
39
39
  return __assign.apply(this, arguments);
40
40
  };
41
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
42
+ if (k2 === undefined) k2 = k;
43
+ var desc = Object.getOwnPropertyDescriptor(m, k);
44
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
45
+ desc = { enumerable: true, get: function() { return m[k]; } };
46
+ }
47
+ Object.defineProperty(o, k2, desc);
48
+ }) : (function(o, m, k, k2) {
49
+ if (k2 === undefined) k2 = k;
50
+ o[k2] = m[k];
51
+ }));
52
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
53
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
54
+ }) : function(o, v) {
55
+ o["default"] = v;
56
+ });
57
+ var __importStar = (this && this.__importStar) || function (mod) {
58
+ if (mod && mod.__esModule) return mod;
59
+ var result = {};
60
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
61
+ __setModuleDefault(result, mod);
62
+ return result;
63
+ };
41
64
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
42
65
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
43
66
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -53,7 +76,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
53
76
  function verb(n) { return function (v) { return step([n, v]); }; }
54
77
  function step(op) {
55
78
  if (f) throw new TypeError("Generator is already executing.");
56
- while (_) try {
79
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
57
80
  if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
58
81
  if (y = 0, t) op = [op[0] & 2, t.value];
59
82
  switch (op[0]) {
@@ -78,12 +101,20 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
78
101
  return (mod && mod.__esModule) ? mod : { "default": mod };
79
102
  };
80
103
  Object.defineProperty(exports, "__esModule", { value: true });
81
- exports.RequiredError = exports.BaseAPI = exports.Environment = exports.COLLECTION_FORMATS = exports.BASE_PATH = void 0;
104
+ exports.RequiredError = exports.BaseAPI = exports.resetRetry = exports.Environment = exports.COLLECTION_FORMATS = exports.BASE_PATH = void 0;
82
105
  var configuration_1 = require("./configuration");
83
106
  // Some imports not used depending on template conditions
84
107
  // @ts-ignore
85
108
  var axios_1 = __importDefault(require("axios"));
86
- exports.BASE_PATH = "http://localhost".replace(/\/+$/, "");
109
+ var fs = __importStar(require("fs"));
110
+ var path = __importStar(require("path"));
111
+ var os = __importStar(require("os"));
112
+ exports.BASE_PATH = "https://apiv2.emil.de".replace(/\/+$/, "");
113
+ var CONFIG_DIRECTORY = '.emil';
114
+ var CONFIG_FILENAME = 'credentials';
115
+ var KEY_USERNAME = 'emil_username';
116
+ var KEY_PASSWORD = 'emil_password';
117
+ var filePath = os.homedir() + path.sep + CONFIG_DIRECTORY + path.sep + CONFIG_FILENAME;
87
118
  /**
88
119
  *
89
120
  * @export
@@ -99,6 +130,13 @@ var Environment;
99
130
  Environment["Production"] = "https://apiv2.emil.de";
100
131
  Environment["Test"] = "https://apiv2-test.emil.de";
101
132
  })(Environment = exports.Environment || (exports.Environment = {}));
133
+ var _retry_count = 0;
134
+ var _retry = null;
135
+ function resetRetry() {
136
+ _retry_count = 0;
137
+ }
138
+ exports.resetRetry = resetRetry;
139
+ var NETWORK_ERROR_MESSAGE = "Network Error";
102
140
  /**
103
141
  *
104
142
  * @export
@@ -108,7 +146,6 @@ var BaseAPI = /** @class */ (function () {
108
146
  function BaseAPI(configuration, basePath, axios) {
109
147
  if (basePath === void 0) { basePath = exports.BASE_PATH; }
110
148
  if (axios === void 0) { axios = axios_1.default; }
111
- var _this = this;
112
149
  this.basePath = basePath;
113
150
  this.axios = axios;
114
151
  if (configuration) {
@@ -120,47 +157,85 @@ var BaseAPI = /** @class */ (function () {
120
157
  basePath: this.basePath,
121
158
  });
122
159
  }
123
- axios.interceptors.response.use(function (res) {
124
- return res;
125
- }, function (err) { return __awaiter(_this, void 0, void 0, function () {
126
- var originalConfig, tokenString, accessToken, localVarHeaderParameter, _error_1;
160
+ this.attachInterceptor(axios);
161
+ }
162
+ BaseAPI.prototype.initialize = function (env) {
163
+ if (env === void 0) { env = Environment.Production; }
164
+ return __awaiter(this, void 0, void 0, function () {
127
165
  return __generator(this, function (_a) {
128
166
  switch (_a.label) {
129
167
  case 0:
130
- originalConfig = err.config;
131
- if (!err.response) return [3 /*break*/, 5];
132
- if (!(err.response.status === 401 && !originalConfig._retry)) return [3 /*break*/, 4];
133
- originalConfig._retry = true;
134
- _a.label = 1;
168
+ this.configuration.basePath = env;
169
+ return [4 /*yield*/, this.loadCredentials()];
135
170
  case 1:
136
- _a.trys.push([1, 3, , 4]);
137
- return [4 /*yield*/, this.refreshToken()];
171
+ _a.sent();
172
+ if (!this.username) return [3 /*break*/, 3];
173
+ return [4 /*yield*/, this.authorize(this.username, this.password)];
138
174
  case 2:
139
- tokenString = _a.sent();
140
- accessToken = "Bearer ".concat(tokenString);
141
- localVarHeaderParameter = {};
142
- localVarHeaderParameter['Authorization'] = accessToken;
143
- originalConfig.headers = __assign(__assign({}, originalConfig.headers), localVarHeaderParameter);
144
- this.configuration.accessToken = accessToken;
145
- return [2 /*return*/, axios(originalConfig)];
175
+ _a.sent();
176
+ this.password = null; // to avoid keeping password loaded in memory.
177
+ _a.label = 3;
178
+ case 3: return [2 /*return*/];
179
+ }
180
+ });
181
+ });
182
+ };
183
+ BaseAPI.prototype.loadCredentials = function () {
184
+ return __awaiter(this, void 0, void 0, function () {
185
+ var error_1;
186
+ return __generator(this, function (_a) {
187
+ switch (_a.label) {
188
+ case 0:
189
+ _a.trys.push([0, 2, , 3]);
190
+ return [4 /*yield*/, this.readConfigFile()];
191
+ case 1:
192
+ _a.sent();
193
+ return [3 /*break*/, 3];
194
+ case 2:
195
+ error_1 = _a.sent();
196
+ console.warn("No credentials file found. Check that ".concat(filePath, " exists."));
197
+ return [3 /*break*/, 3];
146
198
  case 3:
147
- _error_1 = _a.sent();
148
- if (_error_1.response && _error_1.response.data) {
149
- return [2 /*return*/, Promise.reject(_error_1.response.data)];
150
- }
151
- return [2 /*return*/, Promise.reject(_error_1)];
152
- case 4:
153
- if (err.response.status === 403 && err.response.data) {
154
- return [2 /*return*/, Promise.reject(err.response.data)];
199
+ this.readEnvVariables();
200
+ if (!this.username) {
201
+ console.info("No credentials found in credentials file or environment variables. Either provide some or use \n authorize() function.");
155
202
  }
156
- _a.label = 5;
157
- case 5: return [2 /*return*/, Promise.reject(err)];
203
+ return [2 /*return*/];
158
204
  }
159
205
  });
160
- }); });
161
- }
162
- BaseAPI.prototype.getConfiguration = function () {
163
- return this.configuration;
206
+ });
207
+ };
208
+ BaseAPI.prototype.readConfigFile = function () {
209
+ return __awaiter(this, void 0, void 0, function () {
210
+ var file, lines;
211
+ var _this = this;
212
+ return __generator(this, function (_a) {
213
+ switch (_a.label) {
214
+ case 0: return [4 /*yield*/, fs.promises.readFile(filePath, 'utf-8')];
215
+ case 1:
216
+ file = _a.sent();
217
+ lines = file.split(os.EOL)
218
+ .filter(Boolean);
219
+ lines.forEach(function (line) {
220
+ if (line.startsWith(KEY_USERNAME)) {
221
+ _this.username = line.length > KEY_USERNAME.length + 1 ? line.substring(KEY_USERNAME.length + 1) : '';
222
+ }
223
+ else if (line.startsWith(KEY_PASSWORD)) {
224
+ _this.password = line.length > KEY_PASSWORD.length + 1 ? line.substring(KEY_PASSWORD.length + 1) : '';
225
+ }
226
+ });
227
+ return [2 /*return*/];
228
+ }
229
+ });
230
+ });
231
+ };
232
+ BaseAPI.prototype.readEnvVariables = function () {
233
+ if (process.env.EMIL_USERNAME) {
234
+ this.username = process.env.EMIL_USERNAME;
235
+ this.password = process.env.EMIL_PASSWORD || '';
236
+ return true;
237
+ }
238
+ return false;
164
239
  };
165
240
  BaseAPI.prototype.selectEnvironment = function (env) {
166
241
  this.configuration.basePath = env;
@@ -185,9 +260,9 @@ var BaseAPI = /** @class */ (function () {
185
260
  case 1:
186
261
  response = _a.sent();
187
262
  accessToken = response.data.accessToken;
188
- refreshToken = this.extractRefreshToken(response);
189
263
  this.configuration.username = username;
190
264
  this.configuration.accessToken = "Bearer ".concat(accessToken);
265
+ refreshToken = this.extractRefreshToken(response);
191
266
  this.configuration.refreshToken = refreshToken;
192
267
  return [2 /*return*/];
193
268
  }
@@ -229,6 +304,71 @@ var BaseAPI = /** @class */ (function () {
229
304
  }
230
305
  return '';
231
306
  };
307
+ BaseAPI.prototype.getConfiguration = function () {
308
+ return this.configuration;
309
+ };
310
+ BaseAPI.prototype.attachInterceptor = function (axios) {
311
+ var _this = this;
312
+ axios.interceptors.response.use(function (res) {
313
+ return res;
314
+ }, function (err) { return __awaiter(_this, void 0, void 0, function () {
315
+ var originalConfig, tokenString, accessToken, _error_1, tokenString, accessToken, _error_2;
316
+ return __generator(this, function (_a) {
317
+ switch (_a.label) {
318
+ case 0:
319
+ originalConfig = err.config;
320
+ if (!err.response) return [3 /*break*/, 5];
321
+ if (!(err.response.status === 401 && !originalConfig._retry)) return [3 /*break*/, 4];
322
+ originalConfig._retry = true;
323
+ _a.label = 1;
324
+ case 1:
325
+ _a.trys.push([1, 3, , 4]);
326
+ return [4 /*yield*/, this.refreshToken()];
327
+ case 2:
328
+ tokenString = _a.sent();
329
+ accessToken = "Bearer ".concat(tokenString);
330
+ originalConfig.headers['Authorization'] = "Bearer ".concat(accessToken);
331
+ this.configuration.accessToken = accessToken;
332
+ return [2 /*return*/, axios.request(originalConfig)];
333
+ case 3:
334
+ _error_1 = _a.sent();
335
+ if (_error_1.response && _error_1.response.data) {
336
+ return [2 /*return*/, Promise.reject(_error_1.response.data)];
337
+ }
338
+ return [2 /*return*/, Promise.reject(_error_1)];
339
+ case 4:
340
+ if (err.response.status === 403 && err.response.data) {
341
+ return [2 /*return*/, Promise.reject(err.response.data)];
342
+ }
343
+ return [3 /*break*/, 9];
344
+ case 5:
345
+ if (!(err.message === NETWORK_ERROR_MESSAGE
346
+ && err.isAxiosError
347
+ && originalConfig.headers.hasOwnProperty('Authorization')
348
+ && _retry_count < 4)) return [3 /*break*/, 9];
349
+ _retry_count++;
350
+ _a.label = 6;
351
+ case 6:
352
+ _a.trys.push([6, 8, , 9]);
353
+ return [4 /*yield*/, this.refreshToken()];
354
+ case 7:
355
+ tokenString = _a.sent();
356
+ accessToken = "Bearer ".concat(tokenString);
357
+ _retry = true;
358
+ originalConfig.headers['Authorization'] = accessToken;
359
+ this.configuration.accessToken = accessToken;
360
+ return [2 /*return*/, axios.request(__assign({}, originalConfig))];
361
+ case 8:
362
+ _error_2 = _a.sent();
363
+ if (_error_2.response && _error_2.response.data) {
364
+ return [2 /*return*/, Promise.reject(_error_2.response.data)];
365
+ }
366
+ return [2 /*return*/, Promise.reject(_error_2)];
367
+ case 9: return [2 /*return*/, Promise.reject(err)];
368
+ }
369
+ });
370
+ }); });
371
+ };
232
372
  return BaseAPI;
233
373
  }());
234
374
  exports.BaseAPI = BaseAPI;
package/dist/common.d.ts CHANGED
@@ -64,3 +64,29 @@ export declare const toPathString: (url: URL) => string;
64
64
  * @export
65
65
  */
66
66
  export declare const createRequestFunction: (axiosArgs: RequestArgs, globalAxios: AxiosInstance, BASE_PATH: string, configuration?: Configuration) => <T = unknown, R = AxiosResponse<T, any>>(axios?: AxiosInstance, basePath?: string) => Promise<R>;
67
+ /**
68
+ * EMIL AccountService
69
+ * The EMIL AccountService API description
70
+ *
71
+ * The version of the OpenAPI document: 1.0
72
+ *
73
+ *
74
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
75
+ * https://openapi-generator.tech
76
+ * Do not edit the class manually.
77
+ */
78
+ export interface IStorageConverter<D, SD> {
79
+ toStorageData(data: D): SD;
80
+ fromStorageData(storageData: SD): D;
81
+ }
82
+ export interface IStorage {
83
+ get<T>(key: string, converter?: IStorageConverter<T, any>): T | null;
84
+ set<T>(key: string, value: T, converter?: IStorageConverter<T, any>): void;
85
+ }
86
+ export declare class LocalStorage implements IStorage {
87
+ readonly storage: Storage;
88
+ constructor();
89
+ get<T>(key: string, converter?: IStorageConverter<T, any>): T | null;
90
+ set<T>(key: string, value: T, converter?: IStorageConverter<T, any>): void;
91
+ }
92
+ export declare const defaultStorage: () => IStorage;
package/dist/common.js CHANGED
@@ -38,7 +38,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
38
38
  function verb(n) { return function (v) { return step([n, v]); }; }
39
39
  function step(op) {
40
40
  if (f) throw new TypeError("Generator is already executing.");
41
- while (_) try {
41
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
42
42
  if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
43
43
  if (y = 0, t) op = [op[0] & 2, t.value];
44
44
  switch (op[0]) {
@@ -60,7 +60,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
60
60
  }
61
61
  };
62
62
  Object.defineProperty(exports, "__esModule", { value: true });
63
- exports.createRequestFunction = exports.toPathString = exports.serializeDataIfNeeded = exports.setSearchParams = exports.setOAuthToObject = exports.setBearerAuthToObject = exports.setBasicAuthToObject = exports.setApiKeyToObject = exports.assertParamExists = exports.DUMMY_BASE_URL = void 0;
63
+ exports.defaultStorage = exports.LocalStorage = exports.createRequestFunction = exports.toPathString = exports.serializeDataIfNeeded = exports.setSearchParams = exports.setOAuthToObject = exports.setBearerAuthToObject = exports.setBasicAuthToObject = exports.setApiKeyToObject = exports.assertParamExists = exports.DUMMY_BASE_URL = void 0;
64
64
  var base_1 = require("./base");
65
65
  var url_1 = require("url");
66
66
  /**
@@ -242,3 +242,36 @@ var createRequestFunction = function (axiosArgs, globalAxios, BASE_PATH, configu
242
242
  };
243
243
  };
244
244
  exports.createRequestFunction = createRequestFunction;
245
+ var LocalStorage = /** @class */ (function () {
246
+ function LocalStorage() {
247
+ this.storage = localStorage;
248
+ }
249
+ LocalStorage.prototype.get = function (key, converter) {
250
+ var jsonValue = this.storage.getItem(key);
251
+ if (jsonValue === null) {
252
+ return null;
253
+ }
254
+ var value = JSON.parse(jsonValue);
255
+ if (converter !== undefined) {
256
+ return converter.fromStorageData(value);
257
+ }
258
+ else {
259
+ return value;
260
+ }
261
+ };
262
+ LocalStorage.prototype.set = function (key, value, converter) {
263
+ var valueToStore = value;
264
+ if (converter !== undefined) {
265
+ valueToStore = converter.toStorageData(value);
266
+ }
267
+ var jsonValue = JSON.stringify(valueToStore);
268
+ this.storage.setItem(key, jsonValue);
269
+ };
270
+ return LocalStorage;
271
+ }());
272
+ exports.LocalStorage = LocalStorage;
273
+ var _defaultStorage = null;
274
+ var defaultStorage = function () {
275
+ return _defaultStorage || (_defaultStorage = new LocalStorage());
276
+ };
277
+ exports.defaultStorage = defaultStorage;
@@ -122,11 +122,11 @@ export interface AccountClass {
122
122
  * @type {object}
123
123
  * @memberof AccountClass
124
124
  */
125
- 'metadata': object;
125
+ 'metadata'?: object;
126
126
  /**
127
127
  * Optional field contain custom fields
128
128
  * @type {object}
129
129
  * @memberof AccountClass
130
130
  */
131
- 'customFields': object;
131
+ 'customFields'?: object;
132
132
  }
@@ -99,4 +99,4 @@ export declare const CreateAccountRequestDtoGenderEnum: {
99
99
  readonly Female: "female";
100
100
  readonly Unspecified: "unspecified";
101
101
  };
102
- export declare type CreateAccountRequestDtoGenderEnum = typeof CreateAccountRequestDtoGenderEnum[keyof typeof CreateAccountRequestDtoGenderEnum];
102
+ export type CreateAccountRequestDtoGenderEnum = typeof CreateAccountRequestDtoGenderEnum[keyof typeof CreateAccountRequestDtoGenderEnum];
@@ -105,4 +105,4 @@ export declare const UpdateAccountRequestDtoGenderEnum: {
105
105
  readonly Female: "female";
106
106
  readonly Unspecified: "unspecified";
107
107
  };
108
- export declare type UpdateAccountRequestDtoGenderEnum = typeof UpdateAccountRequestDtoGenderEnum[keyof typeof UpdateAccountRequestDtoGenderEnum];
108
+ export type UpdateAccountRequestDtoGenderEnum = typeof UpdateAccountRequestDtoGenderEnum[keyof typeof UpdateAccountRequestDtoGenderEnum];
@@ -127,12 +127,12 @@ export interface AccountClass {
127
127
  * @type {object}
128
128
  * @memberof AccountClass
129
129
  */
130
- 'metadata': object;
130
+ 'metadata'?: object;
131
131
  /**
132
132
  * Optional field contain custom fields
133
133
  * @type {object}
134
134
  * @memberof AccountClass
135
135
  */
136
- 'customFields': object;
136
+ 'customFields'?: object;
137
137
  }
138
138
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emilgroup/account-sdk-node",
3
- "version": "1.0.0",
3
+ "version": "1.3.0",
4
4
  "description": "OpenAPI client for @emilgroup/account-sdk-node",
5
5
  "author": "OpenAPI-Generator Contributors",
6
6
  "keywords": [
@@ -18,12 +18,12 @@
18
18
  "prepare": "npm run build"
19
19
  },
20
20
  "dependencies": {
21
- "axios": "^0.26.1",
21
+ "axios": "^0.27.2",
22
22
  "form-data": "^4.0.0",
23
23
  "url": "^0.11.0"
24
24
  },
25
25
  "devDependencies": {
26
- "@types/node": "^12.11.5",
26
+ "@types/node": "^12.11.5",
27
27
  "typescript": "^4.0"
28
28
  }
29
29
  }