@dotdev/harmony-sdk 1.19.0 → 1.21.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,9 +1,11 @@
1
+ import { AxiosInstance } from "axios";
1
2
  import { IAxiosRetryConfig } from "axios-retry";
2
3
  import { AuthenticationToken, Carrier, CarrierShipment, CreateDiaryQueryParams, Diary, DispatchData, GetCarrierShipmentByTimeQueryParams, GetDiaryQueryParams, GetDispatchDataByTimeQueryParams, ProcessInvoiceQueryParams, ProcessReturnsQueryParams, ProcessSaleOrderQueryParams, ProcessSaleOrderWithoutPaymentQueryParams, SizeGrid, Stock, StockBarcode, StockCategory, StockClassification, StockClassificationType, StockColor, StockLevel, StockLevelLookupQueryParams, StockLookupRequestParams, Warehouse } from "./modules";
3
4
  import { GiftVoucher, GiftVoucherLookupQueryParams, GiftVoucherReservationQueryParams, GiftVoucherUsedQueryParams, GiftVoucherVerificationKeyQueryParams } from "./modules/gift-voucher/types";
5
+ import { RequestConfig } from "./types";
4
6
  export declare class HarmonyAPI {
5
7
  private baseUrl;
6
- private axiosInstance;
8
+ axiosInstance: AxiosInstance;
7
9
  private authModule;
8
10
  private stockLookupModule;
9
11
  private stockLevelLookupModule;
@@ -11,7 +13,7 @@ export declare class HarmonyAPI {
11
13
  private carrierModule;
12
14
  private diaryModule;
13
15
  private giftVoucherModule;
14
- constructor(url: string, axiosRetryConfig?: IAxiosRetryConfig);
16
+ constructor(url: string, axiosRetryConfig?: IAxiosRetryConfig, config?: RequestConfig);
15
17
  authenticate(authToken: AuthenticationToken): Promise<string>;
16
18
  stockLookup(params: StockLookupRequestParams, sessionId: string): Promise<Stock[]>;
17
19
  stockCategoryLookup(sessionId: string): Promise<StockCategory[]>;
@@ -16,12 +16,14 @@ export class HarmonyAPI {
16
16
  carrierModule;
17
17
  diaryModule;
18
18
  giftVoucherModule;
19
- constructor(url, axiosRetryConfig) {
19
+ constructor(url, axiosRetryConfig, config) {
20
20
  this.baseUrl = url;
21
21
  this.axiosInstance = axios.create({
22
22
  baseURL: this.baseUrl,
23
23
  headers: {
24
+ ...config?.headers,
24
25
  "Content-Type": "text/xml;charset=UTF-8",
26
+ "Accept-Encoding": "gzip, deflate, br", // Override default Accept-Encoding
25
27
  },
26
28
  httpsAgent: new https.Agent({
27
29
  rejectUnauthorized: false,
@@ -2,6 +2,7 @@ import axios from "axios";
2
2
  import { promisify } from "util";
3
3
  import { parseString } from "xml2js";
4
4
  import { RequestError } from "../errors";
5
+ import logger from "./logger";
5
6
  import { Utils } from "./utils";
6
7
  export * from "./utils";
7
8
  const parseXml = promisify(parseString);
@@ -9,36 +10,41 @@ export class ApiHelper {
9
10
  static async sendSoapRequest(endpoint, axiosInstance, requestBody, type = "POST") {
10
11
  const url = `${endpoint}?wsdl`;
11
12
  let response;
12
- let defaultConfig = {
13
- headers: {
14
- 'Accept-Encoding': 'gzip, deflate, br' //Override default Accept-Encoding
15
- }
16
- };
17
13
  try {
18
14
  let response;
19
15
  switch (type) {
20
16
  case "GET":
21
- response = await axiosInstance.get(url, {
22
- ...defaultConfig,
23
- params: {},
17
+ response = await axiosInstance.get(url).catch((error) => {
18
+ logger.error(error.toJSON(), `Error while sending request to ${endpoint} endpoint`);
19
+ throw error;
24
20
  });
25
21
  break;
26
22
  case "POST":
27
23
  default:
28
- response = await axiosInstance.post(url, requestBody, {
29
- ...defaultConfig
30
- // headers: {
31
- // 'SOAPAction': request.action
32
- // }
24
+ response = await axiosInstance
25
+ .post(url, requestBody)
26
+ .catch((error) => {
27
+ logger.error(error.toJSON(), `Error while sending request to ${endpoint} endpoint`);
28
+ throw error;
33
29
  });
34
30
  break;
35
31
  }
36
- console.debug(`Harmony response (success) - size [${+response?.headers?.['content-length']}]: `, { response: response?.data });
32
+ const logs = logger.child({
33
+ request: requestBody,
34
+ response: response?.data,
35
+ size: +response?.headers?.["content-length"],
36
+ status: response?.status,
37
+ });
38
+ logs.debug(`Received Harmony response: `);
37
39
  const result = (await parseXml(response?.data)); // fix type
38
40
  return result["S:Envelope"]["S:Body"][0];
39
41
  }
40
42
  catch (error) {
41
- console.error(`Harmony reponse (fail): `, { response });
43
+ const logs = logger.child({
44
+ request: requestBody,
45
+ error: error,
46
+ });
47
+ logs.error(`Error while when sending request to Harmony`);
42
48
  throw await ApiHelper.parseError(error);
43
49
  }
44
50
  }
@@ -89,7 +95,10 @@ export class ApiHelper {
89
95
  ? `ns2:${methodName[0]}Response`
90
96
  : `ns2:${methodName}Response`;
91
97
  const requestBody = ApiHelper.createServiceRequestBody(methodName, sessionId, serviceAlias, body);
92
- console.debug(`Harmony request body`, { request: requestBody });
98
+ const child = logger.child({
99
+ request: requestBody,
100
+ });
101
+ child.debug(`Sending API request`);
93
102
  const response = await ApiHelper.sendSoapRequest(serviceName, axios, requestBody);
94
103
  return response[responseMethodName][0];
95
104
  }
@@ -100,8 +109,6 @@ export class ApiHelper {
100
109
  return new RequestError(`API request failed with status ${error.response.status}: {code: ${parsedError?.code}, name: ${parsedError?.name}, message: ${parsedError?.message}}`);
101
110
  }
102
111
  else if (error?.request) {
103
- console.log(`The following request was sent to server`);
104
- console.log(error?.toJSON());
105
112
  return new RequestError("No response received from the server during API call");
106
113
  }
107
114
  else {
@@ -0,0 +1,2 @@
1
+ declare const logger: import("pino").Logger<never, boolean>;
2
+ export default logger;
@@ -0,0 +1,3 @@
1
+ import pino from "pino";
2
+ const logger = pino();
3
+ export default logger;
@@ -1,4 +1,6 @@
1
+ import { HarmonyAPI } from "../HarmonyAPI";
1
2
  import { Utils } from "./utils";
3
+ jest.unmock("axios");
2
4
  describe("Utils", () => {
3
5
  test("isEmptyArray", () => {
4
6
  expect.assertions(7);
@@ -94,3 +96,15 @@ describe("Utils", () => {
94
96
  });
95
97
  });
96
98
  });
99
+ describe("Misc", () => {
100
+ test("Axios should pass through request headers correctly", () => {
101
+ const harmonyApi = new HarmonyAPI("test", undefined, {
102
+ headers: { "test-header": "test-value" },
103
+ });
104
+ expect(harmonyApi.axiosInstance.defaults.headers["test-header"]).toEqual("test-value");
105
+ // Default header for Content-Type should be set to text/xml;charset=UTF-8
106
+ expect(harmonyApi.axiosInstance.defaults.headers["Content-Type"]).toEqual("text/xml;charset=UTF-8");
107
+ // Check if Accept-Encoding is set to gzip, deflate, br for compression support (currently enabled for S2)
108
+ expect(harmonyApi.axiosInstance.defaults.headers["Accept-Encoding"]).toEqual("gzip, deflate, br");
109
+ });
110
+ });
@@ -22,7 +22,6 @@ export class AuthModule {
22
22
  <S:Body>${loginBody}</S:Body>
23
23
  </S:Envelope>
24
24
  `;
25
- console.debug(`Authenticating with Harmony. Request body: ${soapEnvelope}`);
26
25
  try {
27
26
  const response = await ApiHelper.sendSoapRequest("/AuthenticationService/AuthenticationService", this.axiosInstance, soapEnvelope);
28
27
  const token = response["ns2:LoginResponse"][0]["token"][0];
@@ -4,3 +4,6 @@ export * from "../modules/carrier/types";
4
4
  export * from "../modules/point-of-sale/types";
5
5
  export * from "../modules/stock-level-lookup/types";
6
6
  export * from "../modules/stock-lookup/types";
7
+ export type RequestConfig = {
8
+ headers?: Record<string, string>;
9
+ };
@@ -3,4 +3,3 @@ export * from "../modules/carrier/types";
3
3
  export * from "../modules/point-of-sale/types";
4
4
  export * from "../modules/stock-level-lookup/types";
5
5
  export * from "../modules/stock-lookup/types";
6
- // other types could be added here
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dotdev/harmony-sdk",
3
- "version": "1.19.0",
3
+ "version": "1.21.0",
4
4
  "description": "Harmony API SDK",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -19,6 +19,7 @@
19
19
  "dependencies": {
20
20
  "axios": "^1.7.2",
21
21
  "axios-retry": "^4.5.0",
22
+ "pino": "^9.7.0",
22
23
  "xml2js": "0.6.2"
23
24
  },
24
25
  "devDependencies": {