@emilgroup/notification-sdk-node 1.2.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 +18 -2
- package/base.ts +16 -8
- package/dist/base.d.ts +4 -2
- package/dist/base.js +26 -20
- package/dist/models/send-notification-request-dto.d.ts +6 -0
- package/models/send-notification-request-dto.ts +6 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,11 +17,11 @@ Although this package can be used in both TypeScript and JavaScript, it is inten
|
|
|
17
17
|
Navigate to the folder of your consuming project and run one of the following commands:
|
|
18
18
|
|
|
19
19
|
```
|
|
20
|
-
npm install @emilgroup/notification-sdk-node@1.
|
|
20
|
+
npm install @emilgroup/notification-sdk-node@1.3.0 --save
|
|
21
21
|
```
|
|
22
22
|
or
|
|
23
23
|
```
|
|
24
|
-
yarn add @emilgroup/notification-sdk-node@1.
|
|
24
|
+
yarn add @emilgroup/notification-sdk-node@1.3.0
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
And then you can import `LayoutApi`.
|
|
@@ -47,6 +47,22 @@ export EMIL_USERNAME=XXXXX@XXXX.XXX
|
|
|
47
47
|
export EMIL_PASSWORD=XXXXXXXXXXXXXX
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
## Base path
|
|
51
|
+
|
|
52
|
+
To select the basic path for using the API, we can use two approaches. The first is to use one of the predefined environments, and the second is to specify the domain as a string.
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { LayoutApi, Environment } from '@emilgroup/notification-sdk-node'
|
|
56
|
+
|
|
57
|
+
const LayoutsApi = new LayoutApi();
|
|
58
|
+
|
|
59
|
+
// Allows you to simply choose environment. It will usually be Environment.Production.
|
|
60
|
+
LayoutsApi.selectEnvironment(Environment.Production);
|
|
61
|
+
|
|
62
|
+
// For advanced users, use the custom baseUrl of the website you need to connect to.
|
|
63
|
+
LayoutsApi.selectBasePath('https://my-custom-domain.com');
|
|
64
|
+
```
|
|
65
|
+
|
|
50
66
|
## Example
|
|
51
67
|
|
|
52
68
|
Here is a basic functionning example:
|
package/base.ts
CHANGED
|
@@ -41,7 +41,7 @@ export const COLLECTION_FORMATS = {
|
|
|
41
41
|
|
|
42
42
|
export interface LoginClass {
|
|
43
43
|
accessToken: string;
|
|
44
|
-
permissions:
|
|
44
|
+
permissions: string;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
export enum Environment {
|
|
@@ -79,6 +79,7 @@ export class BaseAPI {
|
|
|
79
79
|
protected configuration: Configuration;
|
|
80
80
|
private username?: string;
|
|
81
81
|
private password?: string;
|
|
82
|
+
private permissions?: string;
|
|
82
83
|
|
|
83
84
|
constructor(configuration?: Configuration, protected basePath: string = BASE_PATH, protected axios: AxiosInstance = globalAxios) {
|
|
84
85
|
if (configuration) {
|
|
@@ -149,6 +150,10 @@ export class BaseAPI {
|
|
|
149
150
|
this.configuration.basePath = env;
|
|
150
151
|
}
|
|
151
152
|
|
|
153
|
+
getPermissions(): Array<string> {
|
|
154
|
+
return this.permissions.split(',');
|
|
155
|
+
}
|
|
156
|
+
|
|
152
157
|
async authorize(username: string, password: string): Promise<void> {
|
|
153
158
|
const options: AxiosRequestConfig = {
|
|
154
159
|
method: 'POST',
|
|
@@ -163,20 +168,21 @@ export class BaseAPI {
|
|
|
163
168
|
|
|
164
169
|
const response = await globalAxios.request<LoginClass>(options);
|
|
165
170
|
|
|
166
|
-
const { data: { accessToken } } = response;
|
|
171
|
+
const { data: { accessToken, permissions } } = response;
|
|
167
172
|
this.configuration.username = username;
|
|
168
173
|
this.configuration.accessToken = `Bearer ${accessToken}`;
|
|
174
|
+
this.permissions = permissions;
|
|
169
175
|
|
|
170
176
|
const refreshToken = this.extractRefreshToken(response)
|
|
171
177
|
this.configuration.refreshToken = refreshToken;
|
|
172
178
|
}
|
|
173
179
|
|
|
174
|
-
async refreshTokenInternal(): Promise<
|
|
180
|
+
async refreshTokenInternal(): Promise<LoginClass> {
|
|
175
181
|
const { username, refreshToken } = this.configuration;
|
|
176
182
|
|
|
177
183
|
|
|
178
184
|
if (!username || !refreshToken) {
|
|
179
|
-
|
|
185
|
+
throw new Error('Failed to refresh token.');
|
|
180
186
|
}
|
|
181
187
|
|
|
182
188
|
const options: AxiosRequestConfig = {
|
|
@@ -190,9 +196,9 @@ export class BaseAPI {
|
|
|
190
196
|
withCredentials: true,
|
|
191
197
|
};
|
|
192
198
|
|
|
193
|
-
const
|
|
199
|
+
const response = await globalAxios.request<LoginClass>(options);
|
|
194
200
|
|
|
195
|
-
return
|
|
201
|
+
return response.data;
|
|
196
202
|
}
|
|
197
203
|
|
|
198
204
|
private extractRefreshToken(response: AxiosResponse): string {
|
|
@@ -221,8 +227,9 @@ export class BaseAPI {
|
|
|
221
227
|
if (err.response.status === 401 && !originalConfig._retry) {
|
|
222
228
|
originalConfig._retry = true;
|
|
223
229
|
try {
|
|
224
|
-
const tokenString = await this.refreshTokenInternal();
|
|
230
|
+
const { accessToken: tokenString, permissions } = await this.refreshTokenInternal();
|
|
225
231
|
const accessToken = `Bearer ${tokenString}`;
|
|
232
|
+
this.permissions = permissions;
|
|
226
233
|
|
|
227
234
|
originalConfig.headers['Authorization'] = `Bearer ${accessToken}`
|
|
228
235
|
|
|
@@ -246,8 +253,9 @@ export class BaseAPI {
|
|
|
246
253
|
){
|
|
247
254
|
_retry_count++;
|
|
248
255
|
try {
|
|
249
|
-
const tokenString = await this.refreshTokenInternal();
|
|
256
|
+
const { accessToken: tokenString, permissions } = await this.refreshTokenInternal();
|
|
250
257
|
const accessToken = `Bearer ${tokenString}`;
|
|
258
|
+
this.permissions = permissions;
|
|
251
259
|
|
|
252
260
|
_retry = true;
|
|
253
261
|
originalConfig.headers['Authorization'] = accessToken;
|
package/dist/base.d.ts
CHANGED
|
@@ -24,7 +24,7 @@ export declare const COLLECTION_FORMATS: {
|
|
|
24
24
|
};
|
|
25
25
|
export interface LoginClass {
|
|
26
26
|
accessToken: string;
|
|
27
|
-
permissions:
|
|
27
|
+
permissions: string;
|
|
28
28
|
}
|
|
29
29
|
export declare enum Environment {
|
|
30
30
|
Production = "https://apiv2.emil.de",
|
|
@@ -53,14 +53,16 @@ export declare class BaseAPI {
|
|
|
53
53
|
protected configuration: Configuration;
|
|
54
54
|
private username?;
|
|
55
55
|
private password?;
|
|
56
|
+
private permissions?;
|
|
56
57
|
constructor(configuration?: Configuration, basePath?: string, axios?: AxiosInstance);
|
|
57
58
|
initialize(env?: Environment): Promise<void>;
|
|
58
59
|
private loadCredentials;
|
|
59
60
|
private readConfigFile;
|
|
60
61
|
private readEnvVariables;
|
|
61
62
|
selectEnvironment(env: Environment): void;
|
|
63
|
+
getPermissions(): Array<string>;
|
|
62
64
|
authorize(username: string, password: string): Promise<void>;
|
|
63
|
-
refreshTokenInternal(): Promise<
|
|
65
|
+
refreshTokenInternal(): Promise<LoginClass>;
|
|
64
66
|
private extractRefreshToken;
|
|
65
67
|
getConfiguration(): Configuration;
|
|
66
68
|
private attachInterceptor;
|
package/dist/base.js
CHANGED
|
@@ -242,11 +242,14 @@ var BaseAPI = /** @class */ (function () {
|
|
|
242
242
|
BaseAPI.prototype.selectEnvironment = function (env) {
|
|
243
243
|
this.configuration.basePath = env;
|
|
244
244
|
};
|
|
245
|
+
BaseAPI.prototype.getPermissions = function () {
|
|
246
|
+
return this.permissions.split(',');
|
|
247
|
+
};
|
|
245
248
|
BaseAPI.prototype.authorize = function (username, password) {
|
|
246
249
|
return __awaiter(this, void 0, void 0, function () {
|
|
247
|
-
var options, response, accessToken, refreshToken;
|
|
248
|
-
return __generator(this, function (
|
|
249
|
-
switch (
|
|
250
|
+
var options, response, _a, accessToken, permissions, refreshToken;
|
|
251
|
+
return __generator(this, function (_b) {
|
|
252
|
+
switch (_b.label) {
|
|
250
253
|
case 0:
|
|
251
254
|
options = {
|
|
252
255
|
method: 'POST',
|
|
@@ -260,10 +263,11 @@ var BaseAPI = /** @class */ (function () {
|
|
|
260
263
|
};
|
|
261
264
|
return [4 /*yield*/, axios_1.default.request(options)];
|
|
262
265
|
case 1:
|
|
263
|
-
response =
|
|
264
|
-
|
|
266
|
+
response = _b.sent();
|
|
267
|
+
_a = response.data, accessToken = _a.accessToken, permissions = _a.permissions;
|
|
265
268
|
this.configuration.username = username;
|
|
266
269
|
this.configuration.accessToken = "Bearer ".concat(accessToken);
|
|
270
|
+
this.permissions = permissions;
|
|
267
271
|
refreshToken = this.extractRefreshToken(response);
|
|
268
272
|
this.configuration.refreshToken = refreshToken;
|
|
269
273
|
return [2 /*return*/];
|
|
@@ -273,13 +277,13 @@ var BaseAPI = /** @class */ (function () {
|
|
|
273
277
|
};
|
|
274
278
|
BaseAPI.prototype.refreshTokenInternal = function () {
|
|
275
279
|
return __awaiter(this, void 0, void 0, function () {
|
|
276
|
-
var _a, username, refreshToken, options,
|
|
280
|
+
var _a, username, refreshToken, options, response;
|
|
277
281
|
return __generator(this, function (_b) {
|
|
278
282
|
switch (_b.label) {
|
|
279
283
|
case 0:
|
|
280
284
|
_a = this.configuration, username = _a.username, refreshToken = _a.refreshToken;
|
|
281
285
|
if (!username || !refreshToken) {
|
|
282
|
-
|
|
286
|
+
throw new Error('Failed to refresh token.');
|
|
283
287
|
}
|
|
284
288
|
options = {
|
|
285
289
|
method: 'POST',
|
|
@@ -293,8 +297,8 @@ var BaseAPI = /** @class */ (function () {
|
|
|
293
297
|
};
|
|
294
298
|
return [4 /*yield*/, axios_1.default.request(options)];
|
|
295
299
|
case 1:
|
|
296
|
-
|
|
297
|
-
return [2 /*return*/,
|
|
300
|
+
response = _b.sent();
|
|
301
|
+
return [2 /*return*/, response.data];
|
|
298
302
|
}
|
|
299
303
|
});
|
|
300
304
|
});
|
|
@@ -314,26 +318,27 @@ var BaseAPI = /** @class */ (function () {
|
|
|
314
318
|
axios.interceptors.response.use(function (res) {
|
|
315
319
|
return res;
|
|
316
320
|
}, function (err) { return __awaiter(_this, void 0, void 0, function () {
|
|
317
|
-
var originalConfig, tokenString, accessToken, _error_1, tokenString, accessToken, _error_2;
|
|
318
|
-
return __generator(this, function (
|
|
319
|
-
switch (
|
|
321
|
+
var originalConfig, _a, tokenString, permissions, accessToken, _error_1, _b, tokenString, permissions, accessToken, _error_2;
|
|
322
|
+
return __generator(this, function (_c) {
|
|
323
|
+
switch (_c.label) {
|
|
320
324
|
case 0:
|
|
321
325
|
originalConfig = err.config;
|
|
322
326
|
if (!err.response) return [3 /*break*/, 5];
|
|
323
327
|
if (!(err.response.status === 401 && !originalConfig._retry)) return [3 /*break*/, 4];
|
|
324
328
|
originalConfig._retry = true;
|
|
325
|
-
|
|
329
|
+
_c.label = 1;
|
|
326
330
|
case 1:
|
|
327
|
-
|
|
331
|
+
_c.trys.push([1, 3, , 4]);
|
|
328
332
|
return [4 /*yield*/, this.refreshTokenInternal()];
|
|
329
333
|
case 2:
|
|
330
|
-
|
|
334
|
+
_a = _c.sent(), tokenString = _a.accessToken, permissions = _a.permissions;
|
|
331
335
|
accessToken = "Bearer ".concat(tokenString);
|
|
336
|
+
this.permissions = permissions;
|
|
332
337
|
originalConfig.headers['Authorization'] = "Bearer ".concat(accessToken);
|
|
333
338
|
this.configuration.accessToken = accessToken;
|
|
334
339
|
return [2 /*return*/, axios.request(originalConfig)];
|
|
335
340
|
case 3:
|
|
336
|
-
_error_1 =
|
|
341
|
+
_error_1 = _c.sent();
|
|
337
342
|
if (_error_1.response && _error_1.response.data) {
|
|
338
343
|
return [2 /*return*/, Promise.reject(_error_1.response.data)];
|
|
339
344
|
}
|
|
@@ -349,19 +354,20 @@ var BaseAPI = /** @class */ (function () {
|
|
|
349
354
|
&& originalConfig.headers.hasOwnProperty('Authorization')
|
|
350
355
|
&& _retry_count < 4)) return [3 /*break*/, 9];
|
|
351
356
|
_retry_count++;
|
|
352
|
-
|
|
357
|
+
_c.label = 6;
|
|
353
358
|
case 6:
|
|
354
|
-
|
|
359
|
+
_c.trys.push([6, 8, , 9]);
|
|
355
360
|
return [4 /*yield*/, this.refreshTokenInternal()];
|
|
356
361
|
case 7:
|
|
357
|
-
|
|
362
|
+
_b = _c.sent(), tokenString = _b.accessToken, permissions = _b.permissions;
|
|
358
363
|
accessToken = "Bearer ".concat(tokenString);
|
|
364
|
+
this.permissions = permissions;
|
|
359
365
|
_retry = true;
|
|
360
366
|
originalConfig.headers['Authorization'] = accessToken;
|
|
361
367
|
this.configuration.accessToken = accessToken;
|
|
362
368
|
return [2 /*return*/, axios.request(__assign({}, originalConfig))];
|
|
363
369
|
case 8:
|
|
364
|
-
_error_2 =
|
|
370
|
+
_error_2 = _c.sent();
|
|
365
371
|
if (_error_2.response && _error_2.response.data) {
|
|
366
372
|
return [2 /*return*/, Promise.reject(_error_2.response.data)];
|
|
367
373
|
}
|
|
@@ -57,6 +57,12 @@ export interface SendNotificationRequestDto {
|
|
|
57
57
|
* @memberof SendNotificationRequestDto
|
|
58
58
|
*/
|
|
59
59
|
'attachments': Array<string>;
|
|
60
|
+
/**
|
|
61
|
+
* It is possible to use the product slug to fetch a different senderEmail from the tenant settings. It should be in the form of productSlug_sender-email
|
|
62
|
+
* @type {string}
|
|
63
|
+
* @memberof SendNotificationRequestDto
|
|
64
|
+
*/
|
|
65
|
+
'productSlug'?: string;
|
|
60
66
|
/**
|
|
61
67
|
* Payload is used by the template engine to replace all template variables with proper data. For more information, please go to https://github.com/flosch/pongo2.
|
|
62
68
|
* @type {object}
|
|
@@ -62,6 +62,12 @@ export interface SendNotificationRequestDto {
|
|
|
62
62
|
* @memberof SendNotificationRequestDto
|
|
63
63
|
*/
|
|
64
64
|
'attachments': Array<string>;
|
|
65
|
+
/**
|
|
66
|
+
* It is possible to use the product slug to fetch a different senderEmail from the tenant settings. It should be in the form of productSlug_sender-email
|
|
67
|
+
* @type {string}
|
|
68
|
+
* @memberof SendNotificationRequestDto
|
|
69
|
+
*/
|
|
70
|
+
'productSlug'?: string;
|
|
65
71
|
/**
|
|
66
72
|
* Payload is used by the template engine to replace all template variables with proper data. For more information, please go to https://github.com/flosch/pongo2.
|
|
67
73
|
* @type {object}
|