@emilgroup/translation-sdk 1.0.1-beta.4 → 1.1.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/.openapi-generator/FILES +0 -3
- package/README.md +26 -9
- package/api/translation-api.ts +117 -141
- package/api.ts +4 -2
- package/base.ts +97 -140
- package/common.ts +3 -2
- package/configuration.ts +8 -9
- package/dist/api/translation-api.d.ts +106 -124
- package/dist/api/translation-api.js +93 -100
- package/dist/api.d.ts +0 -1
- package/dist/api.js +0 -1
- package/dist/base.d.ts +13 -22
- package/dist/base.js +153 -125
- package/dist/common.d.ts +1 -0
- package/dist/common.js +4 -3
- package/dist/configuration.d.ts +7 -6
- package/dist/configuration.js +0 -8
- package/dist/models/create-product-language-request-dto.d.ts +1 -1
- package/dist/models/index.d.ts +0 -2
- package/dist/models/index.js +0 -2
- package/dist/models/product-language-class.d.ts +4 -4
- package/models/create-product-language-request-dto.ts +1 -1
- package/models/index.ts +0 -2
- package/models/product-language-class.ts +4 -4
- package/package.json +5 -2
- package/tsconfig.json +0 -1
- package/api/default-api.ts +0 -124
- package/dist/api/default-api.d.ts +0 -70
- package/dist/api/default-api.js +0 -200
- package/dist/models/inline-response200.d.ts +0 -54
- package/dist/models/inline-response200.js +0 -15
- package/dist/models/inline-response503.d.ts +0 -54
- package/dist/models/inline-response503.js +0 -15
- package/models/inline-response200.ts +0 -48
- package/models/inline-response503.ts +0 -48
package/api.ts
CHANGED
|
@@ -15,15 +15,17 @@
|
|
|
15
15
|
|
|
16
16
|
import { Configuration } from './configuration';
|
|
17
17
|
import globalAxios, { AxiosPromise, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
18
|
+
// URLSearchParams not necessarily used
|
|
19
|
+
// @ts-ignore
|
|
20
|
+
import { URL, URLSearchParams } from 'url';
|
|
21
|
+
import FormData from 'form-data'
|
|
18
22
|
// Some imports not used depending on template conditions
|
|
19
23
|
// @ts-ignore
|
|
20
24
|
import { DUMMY_BASE_URL, assertParamExists, setApiKeyToObject, setBasicAuthToObject, setBearerAuthToObject, setOAuthToObject, setSearchParams, serializeDataIfNeeded, toPathString, createRequestFunction } from './common';
|
|
21
25
|
// @ts-ignore
|
|
22
26
|
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from './base';
|
|
23
|
-
import { DefaultApi } from './api';
|
|
24
27
|
import { TranslationApi } from './api';
|
|
25
28
|
|
|
26
29
|
|
|
27
|
-
export * from './api/default-api';
|
|
28
30
|
export * from './api/translation-api';
|
|
29
31
|
|
package/base.ts
CHANGED
|
@@ -14,13 +14,20 @@
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
import { Configuration } from "./configuration";
|
|
17
|
-
import { defaultStorage } from "./common";
|
|
18
17
|
// Some imports not used depending on template conditions
|
|
19
18
|
// @ts-ignore
|
|
20
19
|
import globalAxios, { AxiosPromise, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
|
|
21
|
-
|
|
20
|
+
import * as fs from 'fs';
|
|
21
|
+
import * as path from 'path';
|
|
22
|
+
import * as os from 'os';
|
|
22
23
|
|
|
23
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';
|
|
29
|
+
|
|
30
|
+
const filePath = os.homedir() + path.sep + CONFIG_DIRECTORY + path.sep + CONFIG_FILENAME;
|
|
24
31
|
/**
|
|
25
32
|
*
|
|
26
33
|
* @export
|
|
@@ -34,25 +41,13 @@ export const COLLECTION_FORMATS = {
|
|
|
34
41
|
|
|
35
42
|
export interface LoginClass {
|
|
36
43
|
accessToken: string;
|
|
37
|
-
permissions: string
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export interface SwitchWorkspaceRequest {
|
|
41
|
-
username: string;
|
|
42
|
-
targetWorkspace: string;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export interface SwitchWorkspaceResponseClass {
|
|
46
|
-
accessToken: string;
|
|
47
|
-
permissions: string;
|
|
44
|
+
permissions: Array<string>;
|
|
48
45
|
}
|
|
49
46
|
|
|
50
47
|
export enum Environment {
|
|
51
48
|
Production = 'https://apiv2.emil.de',
|
|
52
49
|
Test = 'https://apiv2-test.emil.de',
|
|
53
|
-
Staging = 'https://apiv2-staging.emil.de',
|
|
54
50
|
Development = 'https://apiv2-dev.emil.de',
|
|
55
|
-
ProductionZurich = 'https://eu-central-2.apiv2.emil.de',
|
|
56
51
|
}
|
|
57
52
|
|
|
58
53
|
let _retry_count = 0
|
|
@@ -72,14 +67,7 @@ export interface RequestArgs {
|
|
|
72
67
|
options: AxiosRequestConfig;
|
|
73
68
|
}
|
|
74
69
|
|
|
75
|
-
interface TokenData {
|
|
76
|
-
accessToken?: string;
|
|
77
|
-
username?: string;
|
|
78
|
-
permissions?: string;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
70
|
const NETWORK_ERROR_MESSAGE = "Network Error";
|
|
82
|
-
const TOKEN_DATA = 'APP_TOKEN';
|
|
83
71
|
|
|
84
72
|
/**
|
|
85
73
|
*
|
|
@@ -87,54 +75,80 @@ const TOKEN_DATA = 'APP_TOKEN';
|
|
|
87
75
|
* @class BaseAPI
|
|
88
76
|
*/
|
|
89
77
|
export class BaseAPI {
|
|
90
|
-
protected configuration: Configuration
|
|
91
|
-
private
|
|
92
|
-
|
|
93
|
-
constructor(configuration?: Configuration,
|
|
94
|
-
protected basePath: string = BASE_PATH,
|
|
95
|
-
protected axios: AxiosInstance = globalAxios) {
|
|
96
|
-
|
|
97
|
-
this.loadTokenData();
|
|
78
|
+
protected configuration: Configuration;
|
|
79
|
+
private username?: string;
|
|
80
|
+
private password?: string;
|
|
98
81
|
|
|
82
|
+
constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) {
|
|
99
83
|
if (configuration) {
|
|
100
|
-
const { accessToken } = this.tokenData;
|
|
101
84
|
this.configuration = configuration;
|
|
102
85
|
this.basePath = configuration.basePath || this.basePath;
|
|
103
|
-
|
|
104
|
-
// Use config token if provided, otherwise use tokenData token
|
|
105
|
-
const configToken = this.configuration.accessToken;
|
|
106
|
-
const storedToken = accessToken ? `Bearer ${accessToken}` : '';
|
|
107
|
-
this.configuration.accessToken = configToken || storedToken;
|
|
108
86
|
} else {
|
|
109
|
-
const { accessToken, username } = this.tokenData;
|
|
110
|
-
|
|
111
87
|
this.configuration = new Configuration({
|
|
112
88
|
basePath: this.basePath,
|
|
113
|
-
accessToken: accessToken ? `Bearer ${accessToken}` : '',
|
|
114
|
-
username,
|
|
115
89
|
});
|
|
116
90
|
}
|
|
117
91
|
|
|
118
92
|
this.attachInterceptor(axios);
|
|
119
93
|
}
|
|
120
94
|
|
|
121
|
-
|
|
122
|
-
this.
|
|
95
|
+
async initialize(env: Environment = Environment.Production) {
|
|
96
|
+
this.configuration.basePath = env;
|
|
97
|
+
|
|
98
|
+
await this.loadCredentials();
|
|
99
|
+
|
|
100
|
+
if (this.username) {
|
|
101
|
+
await this.authorize(this.username, this.password);
|
|
102
|
+
this.password = null; // to avoid keeping password loaded in memory.
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private async loadCredentials() {
|
|
107
|
+
try {
|
|
108
|
+
await this.readConfigFile();
|
|
109
|
+
} catch (error) {
|
|
110
|
+
console.warn(`No credentials file found. Check that ${filePath} exists.`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
this.readEnvVariables();
|
|
114
|
+
|
|
115
|
+
if (!this.username) {
|
|
116
|
+
console.info(`No credentials found in credentials file or environment variables. Either provide some or use
|
|
117
|
+
authorize() function.`);
|
|
118
|
+
}
|
|
123
119
|
}
|
|
124
120
|
|
|
125
|
-
|
|
126
|
-
|
|
121
|
+
private async readConfigFile() {
|
|
122
|
+
const file = await fs.promises.readFile(filePath, 'utf-8');
|
|
123
|
+
|
|
124
|
+
const lines = file.split(os.EOL)
|
|
125
|
+
.filter(Boolean);
|
|
126
|
+
|
|
127
|
+
lines.forEach((line: string) => {
|
|
128
|
+
if (line.startsWith(KEY_USERNAME)) {
|
|
129
|
+
this.username = line.length > KEY_USERNAME.length + 1 ? line.substring(KEY_USERNAME.length + 1) : '';
|
|
130
|
+
} else if (line.startsWith(KEY_PASSWORD)) {
|
|
131
|
+
this.password = line.length > KEY_PASSWORD.length + 1 ? line.substring(KEY_PASSWORD.length + 1) : '';
|
|
132
|
+
}
|
|
133
|
+
});
|
|
127
134
|
}
|
|
128
135
|
|
|
129
|
-
|
|
130
|
-
if (
|
|
131
|
-
|
|
136
|
+
private readEnvVariables(): boolean {
|
|
137
|
+
if (process.env.EMIL_USERNAME) {
|
|
138
|
+
this.username = process.env.EMIL_USERNAME;
|
|
139
|
+
this.password = process.env.EMIL_PASSWORD || '';
|
|
140
|
+
|
|
141
|
+
return true;
|
|
132
142
|
}
|
|
133
143
|
|
|
134
|
-
return
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
selectEnvironment(env: Environment) {
|
|
148
|
+
this.configuration.basePath = env;
|
|
135
149
|
}
|
|
136
150
|
|
|
137
|
-
async authorize(username: string, password: string
|
|
151
|
+
async authorize(username: string, password: string): Promise<void> {
|
|
138
152
|
const options: AxiosRequestConfig = {
|
|
139
153
|
method: 'POST',
|
|
140
154
|
url: `${this.configuration.basePath}/authservice/v1/login`,
|
|
@@ -148,100 +162,50 @@ export class BaseAPI {
|
|
|
148
162
|
|
|
149
163
|
const response = await globalAxios.request<LoginClass>(options);
|
|
150
164
|
|
|
151
|
-
const { data: { accessToken
|
|
152
|
-
|
|
165
|
+
const { data: { accessToken } } = response;
|
|
153
166
|
this.configuration.username = username;
|
|
154
167
|
this.configuration.accessToken = `Bearer ${accessToken}`;
|
|
155
|
-
this.tokenData.username = username;
|
|
156
|
-
this.tokenData.accessToken = accessToken;
|
|
157
|
-
this.tokenData.permissions = permissions;
|
|
158
168
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
await this.switchWorkspace(targetWorkspace);
|
|
162
|
-
} else {
|
|
163
|
-
// Only store if no workspace switch (since switchWorkspace will store after switching)
|
|
164
|
-
this.storeTokenData({
|
|
165
|
-
...this.tokenData
|
|
166
|
-
});
|
|
167
|
-
}
|
|
169
|
+
const refreshToken = this.extractRefreshToken(response)
|
|
170
|
+
this.configuration.refreshToken = refreshToken;
|
|
168
171
|
}
|
|
169
172
|
|
|
170
|
-
async
|
|
171
|
-
const
|
|
172
|
-
method: 'POST',
|
|
173
|
-
url: `${this.configuration.basePath}/authservice/v1/workspaces/switch`,
|
|
174
|
-
headers: {
|
|
175
|
-
'Content-Type': 'application/json',
|
|
176
|
-
'Authorization': `Bearer ${this.configuration.accessToken}`,
|
|
177
|
-
},
|
|
178
|
-
data: {
|
|
179
|
-
username: this.configuration.username,
|
|
180
|
-
targetWorkspace,
|
|
181
|
-
} as SwitchWorkspaceRequest,
|
|
182
|
-
withCredentials: true,
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
const response = await globalAxios.request<SwitchWorkspaceResponseClass>(options);
|
|
186
|
-
|
|
187
|
-
const { data: { accessToken, permissions } } = response;
|
|
173
|
+
async refreshTokenInternal(): Promise<string> {
|
|
174
|
+
const { username, refreshToken } = this.configuration;
|
|
188
175
|
|
|
189
|
-
this.configuration.accessToken = `Bearer ${accessToken}`;
|
|
190
|
-
this.tokenData.accessToken = accessToken;
|
|
191
|
-
this.tokenData.permissions = permissions;
|
|
192
176
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
async refreshTokenInternal(): Promise<LoginClass> {
|
|
199
|
-
const { username } = this.configuration;
|
|
200
|
-
|
|
201
|
-
if (!username) {
|
|
202
|
-
throw new Error('Failed to refresh token.');
|
|
177
|
+
if (!username || !refreshToken) {
|
|
178
|
+
return '';
|
|
203
179
|
}
|
|
204
180
|
|
|
205
|
-
const refreshTokenAxios = globalAxios.create()
|
|
206
|
-
refreshTokenAxios.interceptors.response.use(response => {
|
|
207
|
-
const { permissions } = response.data;
|
|
208
|
-
|
|
209
|
-
this.tokenData.permissions = permissions;
|
|
210
|
-
this.storeTokenData(this.tokenData);
|
|
211
|
-
|
|
212
|
-
return response;
|
|
213
|
-
})
|
|
214
|
-
|
|
215
181
|
const options: AxiosRequestConfig = {
|
|
216
182
|
method: 'POST',
|
|
217
183
|
url: `${this.configuration.basePath}/authservice/v1/refresh-token`,
|
|
218
184
|
headers: {
|
|
219
185
|
'Content-Type': 'application/json',
|
|
186
|
+
Cookie: refreshToken,
|
|
220
187
|
},
|
|
221
188
|
data: { username: username },
|
|
222
189
|
withCredentials: true,
|
|
223
190
|
};
|
|
224
191
|
|
|
225
|
-
const
|
|
226
|
-
return response.data;
|
|
227
|
-
}
|
|
192
|
+
const { data: { accessToken } } = await globalAxios.request<LoginClass>(options);
|
|
228
193
|
|
|
229
|
-
|
|
230
|
-
if (typeof window !== 'undefined') {
|
|
231
|
-
defaultStorage().set<TokenData>(TOKEN_DATA, tokenData);
|
|
232
|
-
}
|
|
194
|
+
return accessToken;
|
|
233
195
|
}
|
|
234
196
|
|
|
235
|
-
|
|
236
|
-
if (
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
197
|
+
private extractRefreshToken(response: AxiosResponse): string {
|
|
198
|
+
if (response.headers && response.headers['set-cookie']
|
|
199
|
+
&& response.headers['set-cookie'].length > 0) {
|
|
200
|
+
|
|
201
|
+
return `${response.headers['set-cookie'][0].split(';')[0]};`;
|
|
240
202
|
}
|
|
203
|
+
|
|
204
|
+
return '';
|
|
241
205
|
}
|
|
242
206
|
|
|
243
|
-
|
|
244
|
-
this.
|
|
207
|
+
getConfiguration(): Configuration {
|
|
208
|
+
return this.configuration;
|
|
245
209
|
}
|
|
246
210
|
|
|
247
211
|
private attachInterceptor(axios: AxiosInstance) {
|
|
@@ -251,26 +215,19 @@ export class BaseAPI {
|
|
|
251
215
|
},
|
|
252
216
|
async (err) => {
|
|
253
217
|
let originalConfig = err.config;
|
|
254
|
-
if (err.response
|
|
218
|
+
if (err.response) {
|
|
255
219
|
// Access Token was expired
|
|
256
|
-
if (
|
|
257
|
-
&& !originalConfig._retry) {
|
|
220
|
+
if (err.response.status === 401 && !originalConfig._retry) {
|
|
258
221
|
originalConfig._retry = true;
|
|
259
222
|
try {
|
|
260
|
-
const
|
|
223
|
+
const tokenString = await this.refreshTokenInternal();
|
|
261
224
|
const accessToken = `Bearer ${tokenString}`;
|
|
262
|
-
this.tokenData.permissions = permissions;
|
|
263
225
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
originalConfig.headers['Authorization'] = accessToken;
|
|
226
|
+
originalConfig.headers['Authorization'] = `Bearer ${accessToken}`
|
|
267
227
|
|
|
268
228
|
this.configuration.accessToken = accessToken;
|
|
269
|
-
this.tokenData.accessToken = tokenString;
|
|
270
|
-
|
|
271
|
-
this.storeTokenData(this.tokenData);
|
|
272
229
|
|
|
273
|
-
return axios(originalConfig);
|
|
230
|
+
return axios.request(originalConfig);
|
|
274
231
|
} catch (_error) {
|
|
275
232
|
if (_error.response && _error.response.data) {
|
|
276
233
|
return Promise.reject(_error.response.data);
|
|
@@ -278,23 +235,23 @@ export class BaseAPI {
|
|
|
278
235
|
return Promise.reject(_error);
|
|
279
236
|
}
|
|
280
237
|
}
|
|
281
|
-
|
|
238
|
+
if (err.response.status === 403 && err.response.data) {
|
|
239
|
+
return Promise.reject(err.response.data);
|
|
240
|
+
}
|
|
241
|
+
} else if(err.message === NETWORK_ERROR_MESSAGE
|
|
242
|
+
&& err.isAxiosError
|
|
282
243
|
&& originalConfig.headers.hasOwnProperty('Authorization')
|
|
283
244
|
&& _retry_count < 4
|
|
284
|
-
)
|
|
245
|
+
){
|
|
285
246
|
_retry_count++;
|
|
286
247
|
try {
|
|
287
|
-
const
|
|
248
|
+
const tokenString = await this.refreshTokenInternal();
|
|
288
249
|
const accessToken = `Bearer ${tokenString}`;
|
|
289
|
-
this.tokenData.permissions = permissions;
|
|
290
250
|
|
|
291
251
|
_retry = true;
|
|
292
|
-
originalConfig.headers['Authorization'] = accessToken;
|
|
252
|
+
originalConfig.headers['Authorization'] = accessToken;
|
|
293
253
|
|
|
294
254
|
this.configuration.accessToken = accessToken;
|
|
295
|
-
this.tokenData.accessToken = tokenString;
|
|
296
|
-
|
|
297
|
-
this.storeTokenData(this.tokenData);
|
|
298
255
|
|
|
299
256
|
return axios.request({
|
|
300
257
|
...originalConfig,
|
|
@@ -304,7 +261,7 @@ export class BaseAPI {
|
|
|
304
261
|
return Promise.reject(_error.response.data);
|
|
305
262
|
}
|
|
306
263
|
return Promise.reject(_error);
|
|
307
|
-
}
|
|
264
|
+
}
|
|
308
265
|
}
|
|
309
266
|
return Promise.reject(err);
|
|
310
267
|
}
|
|
@@ -319,7 +276,7 @@ export class BaseAPI {
|
|
|
319
276
|
* @extends {Error}
|
|
320
277
|
*/
|
|
321
278
|
export class RequiredError extends Error {
|
|
322
|
-
|
|
279
|
+
name: "RequiredError" = "RequiredError";
|
|
323
280
|
constructor(public field: string, msg?: string) {
|
|
324
281
|
super(msg);
|
|
325
282
|
}
|
package/common.ts
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import { Configuration } from "./configuration";
|
|
17
17
|
import { RequiredError, RequestArgs } from "./base";
|
|
18
18
|
import { AxiosInstance, AxiosResponse } from 'axios';
|
|
19
|
+
import { URL, URLSearchParams } from 'url';
|
|
19
20
|
/**
|
|
20
21
|
*
|
|
21
22
|
* @export
|
|
@@ -65,7 +66,7 @@ export const setBearerAuthToObject = async function (object: any, configuration?
|
|
|
65
66
|
const accessToken = typeof configuration.accessToken === 'function'
|
|
66
67
|
? await configuration.accessToken()
|
|
67
68
|
: await configuration.accessToken;
|
|
68
|
-
object["Authorization"] =
|
|
69
|
+
object["Authorization"] = "Bearer " + accessToken;
|
|
69
70
|
}
|
|
70
71
|
}
|
|
71
72
|
|
|
@@ -78,7 +79,7 @@ export const setOAuthToObject = async function (object: any, name: string, scope
|
|
|
78
79
|
const localVarAccessTokenValue = typeof configuration.accessToken === 'function'
|
|
79
80
|
? await configuration.accessToken(name, scopes)
|
|
80
81
|
: await configuration.accessToken;
|
|
81
|
-
object["Authorization"] =
|
|
82
|
+
object["Authorization"] = "Bearer " + localVarAccessTokenValue;
|
|
82
83
|
}
|
|
83
84
|
}
|
|
84
85
|
|
package/configuration.ts
CHANGED
|
@@ -74,6 +74,14 @@ export class Configuration {
|
|
|
74
74
|
*/
|
|
75
75
|
formDataCtor?: new () => any;
|
|
76
76
|
|
|
77
|
+
/**
|
|
78
|
+
* parameter for automatically refreshing access token for oauth2 security
|
|
79
|
+
*
|
|
80
|
+
* @type {string}
|
|
81
|
+
* @memberof Configuration
|
|
82
|
+
*/
|
|
83
|
+
refreshToken?: string;
|
|
84
|
+
|
|
77
85
|
constructor(param: ConfigurationParameters = {}) {
|
|
78
86
|
this.apiKey = param.apiKey;
|
|
79
87
|
this.username = param.username;
|
|
@@ -98,13 +106,4 @@ export class Configuration {
|
|
|
98
106
|
const jsonMime: RegExp = new RegExp('^(application\/json|[^;/ \t]+\/[^;/ \t]+[+]json)[ \t]*(;.*)?$', 'i');
|
|
99
107
|
return mime !== null && (jsonMime.test(mime) || mime.toLowerCase() === 'application/json-patch+json');
|
|
100
108
|
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Returns "Bearer" token.
|
|
104
|
-
* @param token - access token.
|
|
105
|
-
* @return Bearer token.
|
|
106
|
-
*/
|
|
107
|
-
public getBearerToken(token?: string): string {
|
|
108
|
-
return ('' + token).startsWith("Bearer") ? token : "Bearer " + token;
|
|
109
|
-
}
|
|
110
109
|
}
|