@dotdev/harmony-sdk 1.0.6
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 +88 -0
- package/dist/HarmonyAPI.d.ts +37 -0
- package/dist/HarmonyAPI.js +113 -0
- package/dist/errors/index.d.ts +15 -0
- package/dist/errors/index.js +18 -0
- package/dist/helpers/index.d.ts +50 -0
- package/dist/helpers/index.js +167 -0
- package/dist/helpers/index.spec.d.ts +1 -0
- package/dist/helpers/index.spec.js +147 -0
- package/dist/helpers/mapper.d.ts +2 -0
- package/dist/helpers/mapper.js +28 -0
- package/dist/helpers/utils.d.ts +71 -0
- package/dist/helpers/utils.js +133 -0
- package/dist/helpers/utils.spec.d.ts +1 -0
- package/dist/helpers/utils.spec.js +96 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/modules/auth/auth.module.d.ts +7 -0
- package/dist/modules/auth/auth.module.js +42 -0
- package/dist/modules/auth/auth.module.spec.d.ts +1 -0
- package/dist/modules/auth/auth.module.spec.js +55 -0
- package/dist/modules/auth/index.d.ts +2 -0
- package/dist/modules/auth/index.js +2 -0
- package/dist/modules/auth/types/index.d.ts +7 -0
- package/dist/modules/auth/types/index.js +1 -0
- package/dist/modules/carrier/carrier.module.d.ts +10 -0
- package/dist/modules/carrier/carrier.module.js +39 -0
- package/dist/modules/carrier/carrier.module.spec.d.ts +1 -0
- package/dist/modules/carrier/carrier.module.spec.js +187 -0
- package/dist/modules/carrier/index.d.ts +3 -0
- package/dist/modules/carrier/index.js +3 -0
- package/dist/modules/carrier/mappings/index.d.ts +5 -0
- package/dist/modules/carrier/mappings/index.js +36 -0
- package/dist/modules/carrier/types/index.d.ts +42 -0
- package/dist/modules/carrier/types/index.js +2 -0
- package/dist/modules/diary/diary.module.d.ts +9 -0
- package/dist/modules/diary/diary.module.js +28 -0
- package/dist/modules/diary/index.d.ts +3 -0
- package/dist/modules/diary/index.js +3 -0
- package/dist/modules/diary/mappings/diary.mapper.d.ts +4 -0
- package/dist/modules/diary/mappings/diary.mapper.js +101 -0
- package/dist/modules/diary/mappings/diary.mapper.spec.d.ts +1 -0
- package/dist/modules/diary/mappings/diary.mapper.spec.js +18 -0
- package/dist/modules/diary/mappings/index.d.ts +1 -0
- package/dist/modules/diary/mappings/index.js +1 -0
- package/dist/modules/diary/types/diary.interface.d.ts +138 -0
- package/dist/modules/diary/types/diary.interface.js +24 -0
- package/dist/modules/diary/types/index.d.ts +1 -0
- package/dist/modules/diary/types/index.js +1 -0
- package/dist/modules/gift-voucher/gift-voucher.module.d.ts +12 -0
- package/dist/modules/gift-voucher/gift-voucher.module.js +55 -0
- package/dist/modules/gift-voucher/gift-voucher.module.spec.d.ts +1 -0
- package/dist/modules/gift-voucher/gift-voucher.module.spec.js +296 -0
- package/dist/modules/gift-voucher/index.d.ts +1 -0
- package/dist/modules/gift-voucher/index.js +1 -0
- package/dist/modules/gift-voucher/mappings/index.d.ts +6 -0
- package/dist/modules/gift-voucher/mappings/index.js +70 -0
- package/dist/modules/gift-voucher/mappings/index.spec.d.ts +1 -0
- package/dist/modules/gift-voucher/mappings/index.spec.js +21 -0
- package/dist/modules/gift-voucher/types/index.d.ts +92 -0
- package/dist/modules/gift-voucher/types/index.js +1 -0
- package/dist/modules/index.d.ts +8 -0
- package/dist/modules/index.js +8 -0
- package/dist/modules/point-of-sale/index.d.ts +3 -0
- package/dist/modules/point-of-sale/index.js +3 -0
- package/dist/modules/point-of-sale/mappings/index.d.ts +1 -0
- package/dist/modules/point-of-sale/mappings/index.js +1 -0
- package/dist/modules/point-of-sale/mappings/process-sale-order.mapper.d.ts +6 -0
- package/dist/modules/point-of-sale/mappings/process-sale-order.mapper.js +142 -0
- package/dist/modules/point-of-sale/point-of-sale.module.d.ts +43 -0
- package/dist/modules/point-of-sale/point-of-sale.module.js +64 -0
- package/dist/modules/point-of-sale/point-of-sale.module.spec.d.ts +1 -0
- package/dist/modules/point-of-sale/point-of-sale.module.spec.js +205 -0
- package/dist/modules/point-of-sale/types/cancel-existing-sales-order.interface.d.ts +13 -0
- package/dist/modules/point-of-sale/types/cancel-existing-sales-order.interface.js +1 -0
- package/dist/modules/point-of-sale/types/index.d.ts +124 -0
- package/dist/modules/point-of-sale/types/index.js +31 -0
- package/dist/modules/point-of-sale/types/modify-existing-sales-order.interface.d.ts +12 -0
- package/dist/modules/point-of-sale/types/modify-existing-sales-order.interface.js +1 -0
- package/dist/modules/point-of-sale/types/process-returns.interface.d.ts +17 -0
- package/dist/modules/point-of-sale/types/process-returns.interface.js +1 -0
- package/dist/modules/point-of-sale/types/process-sale-order.interface.d.ts +67 -0
- package/dist/modules/point-of-sale/types/process-sale-order.interface.js +1 -0
- package/dist/modules/shared/index.d.ts +1 -0
- package/dist/modules/shared/index.js +1 -0
- package/dist/modules/shared/types/index.d.ts +93 -0
- package/dist/modules/shared/types/index.js +53 -0
- package/dist/modules/stock-level-lookup/index.d.ts +3 -0
- package/dist/modules/stock-level-lookup/index.js +3 -0
- package/dist/modules/stock-level-lookup/mappings/index.d.ts +1 -0
- package/dist/modules/stock-level-lookup/mappings/index.js +1 -0
- package/dist/modules/stock-level-lookup/mappings/stock-level-lookup.mapper.d.ts +4 -0
- package/dist/modules/stock-level-lookup/mappings/stock-level-lookup.mapper.js +78 -0
- package/dist/modules/stock-level-lookup/mappings/stock-level-lookup.mapper.spec.d.ts +1 -0
- package/dist/modules/stock-level-lookup/mappings/stock-level-lookup.mapper.spec.js +57 -0
- package/dist/modules/stock-level-lookup/stock-level-lookup.module.d.ts +10 -0
- package/dist/modules/stock-level-lookup/stock-level-lookup.module.js +39 -0
- package/dist/modules/stock-level-lookup/stock-level-lookup.module.spec.d.ts +1 -0
- package/dist/modules/stock-level-lookup/stock-level-lookup.module.spec.js +317 -0
- package/dist/modules/stock-level-lookup/types/index.d.ts +1 -0
- package/dist/modules/stock-level-lookup/types/index.js +1 -0
- package/dist/modules/stock-level-lookup/types/stock-level-lookup.interface.d.ts +162 -0
- package/dist/modules/stock-level-lookup/types/stock-level-lookup.interface.js +61 -0
- package/dist/modules/stock-lookup/index.d.ts +3 -0
- package/dist/modules/stock-lookup/index.js +3 -0
- package/dist/modules/stock-lookup/mappings/index.d.ts +1 -0
- package/dist/modules/stock-lookup/mappings/index.js +1 -0
- package/dist/modules/stock-lookup/mappings/stock-lookup.mapper.d.ts +22 -0
- package/dist/modules/stock-lookup/mappings/stock-lookup.mapper.js +156 -0
- package/dist/modules/stock-lookup/mappings/stock-lookup.mapper.spec.d.ts +1 -0
- package/dist/modules/stock-lookup/mappings/stock-lookup.mapper.spec.js +92 -0
- package/dist/modules/stock-lookup/stock-lookup.module.d.ts +65 -0
- package/dist/modules/stock-lookup/stock-lookup.module.js +141 -0
- package/dist/modules/stock-lookup/stock-lookup.module.spec.d.ts +1 -0
- package/dist/modules/stock-lookup/stock-lookup.module.spec.js +419 -0
- package/dist/modules/stock-lookup/types/index.d.ts +1 -0
- package/dist/modules/stock-lookup/types/index.js +1 -0
- package/dist/modules/stock-lookup/types/stock-lookup.interface.d.ts +242 -0
- package/dist/modules/stock-lookup/types/stock-lookup.interface.js +82 -0
- package/dist/modules/stock-lookup/types/stock-lookup.interface.spec.d.ts +1 -0
- package/dist/modules/stock-lookup/types/stock-lookup.interface.spec.js +76 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.js +6 -0
- package/package.json +39 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export declare abstract class Utils {
|
|
2
|
+
/**
|
|
3
|
+
* Check if an object is an empty array or not an array
|
|
4
|
+
*
|
|
5
|
+
* @static
|
|
6
|
+
* @param {*} obj object to check
|
|
7
|
+
* @returns {boolean} true if object is an empty array
|
|
8
|
+
*/
|
|
9
|
+
static isEmptyArray(obj: any): boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Check if an object is a non-empty array.
|
|
12
|
+
*
|
|
13
|
+
* @static
|
|
14
|
+
* @param {*} obj object to check
|
|
15
|
+
* @returns {boolean} true if object is a non-empty array
|
|
16
|
+
*/
|
|
17
|
+
static nonEmptyArray(obj: any): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Chcek if an object is an empty string or not a string
|
|
20
|
+
*
|
|
21
|
+
* @static
|
|
22
|
+
* @param {*} obj object to check
|
|
23
|
+
* @returns {boolean} true if object is an empty string
|
|
24
|
+
*/
|
|
25
|
+
static isEmptyString(obj: any): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Check if an object is a non-empty string.
|
|
28
|
+
*
|
|
29
|
+
* @static
|
|
30
|
+
* @param {*} obj object to check
|
|
31
|
+
* @returns {boolean} true if object is a non-empty string
|
|
32
|
+
*/
|
|
33
|
+
static nonEmptyString(obj: any): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Convert a value to a number.
|
|
36
|
+
*
|
|
37
|
+
* @static
|
|
38
|
+
* @param {*} obj object to convert to a number
|
|
39
|
+
* @returns {number} the converted number
|
|
40
|
+
*/
|
|
41
|
+
static toNumber(obj: any): number;
|
|
42
|
+
static checkMaxStringLength(str: any, length: number, propName?: string): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Remove all empty spaces within a string, including new lines and tabs...
|
|
45
|
+
*
|
|
46
|
+
* @static
|
|
47
|
+
* @param {string} str to remove empty spaces from
|
|
48
|
+
* @returns {string} string with empty spaces removed
|
|
49
|
+
*/
|
|
50
|
+
static removeEmptySpaces(str: string): string;
|
|
51
|
+
static isXmlEqualJson(xml: string, json: any): Promise<boolean>;
|
|
52
|
+
/**
|
|
53
|
+
* Recursively convert an object into xml format
|
|
54
|
+
*
|
|
55
|
+
* @static
|
|
56
|
+
* @param {*} obj
|
|
57
|
+
* @returns {string}
|
|
58
|
+
*/
|
|
59
|
+
static toXml(obj: object, parent?: string): string;
|
|
60
|
+
static deleteUndefinedProps(obj: any): any;
|
|
61
|
+
static deleteEmptyProps(obj: any): any;
|
|
62
|
+
/**
|
|
63
|
+
* Returns first element of an array.
|
|
64
|
+
* Responses extracted from XML have all properties in the format of arrays of 1 element. This is used to extract value out of those properties
|
|
65
|
+
*
|
|
66
|
+
* @static
|
|
67
|
+
* @param {*} prop property array to extract
|
|
68
|
+
* @returns {*} first value in the array
|
|
69
|
+
*/
|
|
70
|
+
static getFirst(prop: any): string;
|
|
71
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { promisify } from "util";
|
|
2
|
+
import { parseString } from "xml2js";
|
|
3
|
+
const parseXml = promisify(parseString);
|
|
4
|
+
export class Utils {
|
|
5
|
+
/**
|
|
6
|
+
* Check if an object is an empty array or not an array
|
|
7
|
+
*
|
|
8
|
+
* @static
|
|
9
|
+
* @param {*} obj object to check
|
|
10
|
+
* @returns {boolean} true if object is an empty array
|
|
11
|
+
*/
|
|
12
|
+
static isEmptyArray(obj) {
|
|
13
|
+
return !Utils.nonEmptyArray(obj);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Check if an object is a non-empty array.
|
|
17
|
+
*
|
|
18
|
+
* @static
|
|
19
|
+
* @param {*} obj object to check
|
|
20
|
+
* @returns {boolean} true if object is a non-empty array
|
|
21
|
+
*/
|
|
22
|
+
static nonEmptyArray(obj) {
|
|
23
|
+
return Array.isArray(obj) && obj.length > 0;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Chcek if an object is an empty string or not a string
|
|
27
|
+
*
|
|
28
|
+
* @static
|
|
29
|
+
* @param {*} obj object to check
|
|
30
|
+
* @returns {boolean} true if object is an empty string
|
|
31
|
+
*/
|
|
32
|
+
static isEmptyString(obj) {
|
|
33
|
+
return !Utils.nonEmptyString(obj);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Check if an object is a non-empty string.
|
|
37
|
+
*
|
|
38
|
+
* @static
|
|
39
|
+
* @param {*} obj object to check
|
|
40
|
+
* @returns {boolean} true if object is a non-empty string
|
|
41
|
+
*/
|
|
42
|
+
static nonEmptyString(obj) {
|
|
43
|
+
return typeof obj === "string" && obj.trim() !== "";
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Convert a value to a number.
|
|
47
|
+
*
|
|
48
|
+
* @static
|
|
49
|
+
* @param {*} obj object to convert to a number
|
|
50
|
+
* @returns {number} the converted number
|
|
51
|
+
*/
|
|
52
|
+
static toNumber(obj) {
|
|
53
|
+
const num = Number(obj);
|
|
54
|
+
if (isNaN(num))
|
|
55
|
+
throw new Error(`Provided value [${obj}] is not a number.`);
|
|
56
|
+
return num;
|
|
57
|
+
}
|
|
58
|
+
static checkMaxStringLength(str, length, propName = "property") {
|
|
59
|
+
if (!(typeof str === "string" && str.length <= length))
|
|
60
|
+
throw new Error(`Provided ${propName} exceeds maximum length of ${length} characters.`);
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Remove all empty spaces within a string, including new lines and tabs...
|
|
65
|
+
*
|
|
66
|
+
* @static
|
|
67
|
+
* @param {string} str to remove empty spaces from
|
|
68
|
+
* @returns {string} string with empty spaces removed
|
|
69
|
+
*/
|
|
70
|
+
static removeEmptySpaces(str) {
|
|
71
|
+
return str.replace(/\s/g, "");
|
|
72
|
+
}
|
|
73
|
+
static async isXmlEqualJson(xml, json) {
|
|
74
|
+
const result = (await parseXml(`<result>${xml}</result>`))["result"];
|
|
75
|
+
// Test that each key value pair matches the expected
|
|
76
|
+
for (const k in result) {
|
|
77
|
+
const val = result[k][0];
|
|
78
|
+
if (json[k] !== val)
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Recursively convert an object into xml format
|
|
85
|
+
*
|
|
86
|
+
* @static
|
|
87
|
+
* @param {*} obj
|
|
88
|
+
* @returns {string}
|
|
89
|
+
*/
|
|
90
|
+
static toXml(obj, parent) {
|
|
91
|
+
if (obj == null)
|
|
92
|
+
return "";
|
|
93
|
+
let str = "";
|
|
94
|
+
const open = parent ? `<${parent}>` : "";
|
|
95
|
+
const close = parent ? `</${parent}>` : "";
|
|
96
|
+
if (Array.isArray(obj)) {
|
|
97
|
+
str += obj.map((o) => open + Utils.toXml(o) + close).join("");
|
|
98
|
+
}
|
|
99
|
+
else if (typeof obj === "object") {
|
|
100
|
+
let valStr = "";
|
|
101
|
+
for (const k in obj) {
|
|
102
|
+
const val = obj[k];
|
|
103
|
+
if (!(val == null)) {
|
|
104
|
+
valStr += `${Utils.toXml(val, k)}`;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
str += open + valStr + close;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
str += open + obj + close;
|
|
111
|
+
}
|
|
112
|
+
return str;
|
|
113
|
+
}
|
|
114
|
+
static deleteUndefinedProps(obj) {
|
|
115
|
+
Object.keys(obj).forEach((key) => obj[key] === undefined && delete obj[key]);
|
|
116
|
+
return obj;
|
|
117
|
+
}
|
|
118
|
+
static deleteEmptyProps(obj) {
|
|
119
|
+
Object.keys(obj).forEach((key) => [undefined, null, ""].includes(obj[key]) && delete obj[key]);
|
|
120
|
+
return obj;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Returns first element of an array.
|
|
124
|
+
* Responses extracted from XML have all properties in the format of arrays of 1 element. This is used to extract value out of those properties
|
|
125
|
+
*
|
|
126
|
+
* @static
|
|
127
|
+
* @param {*} prop property array to extract
|
|
128
|
+
* @returns {*} first value in the array
|
|
129
|
+
*/
|
|
130
|
+
static getFirst(prop) {
|
|
131
|
+
return (prop ?? [])[0];
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Utils } from "./utils";
|
|
2
|
+
describe("Utils", () => {
|
|
3
|
+
test("isEmptyArray", () => {
|
|
4
|
+
expect.assertions(7);
|
|
5
|
+
const nonEmpty = [1, 2, 3];
|
|
6
|
+
const nonEmptyStr = ["1", "2", "3"];
|
|
7
|
+
expect(Utils.isEmptyArray(nonEmpty)).toBe(false);
|
|
8
|
+
expect(Utils.isEmptyArray(nonEmptyStr)).toBe(false);
|
|
9
|
+
expect(Utils.isEmptyArray([])).toBe(true);
|
|
10
|
+
expect(Utils.isEmptyArray("")).toBe(true);
|
|
11
|
+
expect(Utils.isEmptyArray("asadf")).toBe(true);
|
|
12
|
+
expect(Utils.isEmptyArray(null)).toBe(true);
|
|
13
|
+
expect(Utils.isEmptyArray(undefined)).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
test("isEmptyString", () => {
|
|
16
|
+
expect.assertions(6);
|
|
17
|
+
const nonEmpty = "test";
|
|
18
|
+
expect(Utils.isEmptyString(nonEmpty)).toBe(false);
|
|
19
|
+
expect(Utils.isEmptyString([])).toBe(true);
|
|
20
|
+
expect(Utils.isEmptyString(["1", "2", "3"])).toBe(true);
|
|
21
|
+
expect(Utils.isEmptyString("")).toBe(true);
|
|
22
|
+
expect(Utils.isEmptyString(null)).toBe(true);
|
|
23
|
+
expect(Utils.isEmptyString(undefined)).toBe(true);
|
|
24
|
+
});
|
|
25
|
+
test("toNumber", () => {
|
|
26
|
+
const invalidValues = [undefined, "abc", "123abc", {}, "*&^*"];
|
|
27
|
+
for (const i of invalidValues) {
|
|
28
|
+
expect(() => Utils.toNumber(i)).toThrow(`Provided value [${i}] is not a number.`);
|
|
29
|
+
}
|
|
30
|
+
expect(Utils.toNumber("123")).toBe(123);
|
|
31
|
+
expect(Utils.toNumber("123.45")).toBe(123.45);
|
|
32
|
+
expect(Utils.toNumber(true)).toBe(1);
|
|
33
|
+
expect(Utils.toNumber(false)).toBe(0);
|
|
34
|
+
expect(Utils.toNumber("")).toBe(0);
|
|
35
|
+
expect(Utils.toNumber(null)).toBe(0);
|
|
36
|
+
});
|
|
37
|
+
test("toXml should convert to XML string successfully", () => {
|
|
38
|
+
const obj = {
|
|
39
|
+
name: "John Doe",
|
|
40
|
+
age: 30,
|
|
41
|
+
city: "New York",
|
|
42
|
+
hobbies: ["reading", "painting"],
|
|
43
|
+
address: {
|
|
44
|
+
street: "123 Main St",
|
|
45
|
+
city: "New York",
|
|
46
|
+
state: "NY",
|
|
47
|
+
zip: "10001",
|
|
48
|
+
},
|
|
49
|
+
count: 0,
|
|
50
|
+
nullable: null,
|
|
51
|
+
};
|
|
52
|
+
const expectedXml = `
|
|
53
|
+
<name>John Doe</name>
|
|
54
|
+
<age>30</age>
|
|
55
|
+
<city>New York</city>
|
|
56
|
+
<hobbies>reading</hobbies>
|
|
57
|
+
<hobbies>painting</hobbies>
|
|
58
|
+
<address>
|
|
59
|
+
<street>123 Main St</street>
|
|
60
|
+
<city>New York</city>
|
|
61
|
+
<state>NY</state>
|
|
62
|
+
<zip>10001</zip>
|
|
63
|
+
</address>
|
|
64
|
+
<count>0</count>
|
|
65
|
+
`;
|
|
66
|
+
expect(Utils.removeEmptySpaces(Utils.toXml(obj))).toEqual(Utils.removeEmptySpaces(expectedXml));
|
|
67
|
+
});
|
|
68
|
+
test("deleteUndefinedProps() should remove undefined properties", () => {
|
|
69
|
+
const obj = {
|
|
70
|
+
"1": true,
|
|
71
|
+
"2": "test",
|
|
72
|
+
"3": undefined,
|
|
73
|
+
"4": null,
|
|
74
|
+
};
|
|
75
|
+
Utils.deleteUndefinedProps(obj);
|
|
76
|
+
expect(obj).toEqual({
|
|
77
|
+
"1": true,
|
|
78
|
+
"2": "test",
|
|
79
|
+
"4": null,
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
test("deleteEmptyProps() should remove all empty properties", () => {
|
|
83
|
+
const obj = {
|
|
84
|
+
"1": true,
|
|
85
|
+
"2": "test",
|
|
86
|
+
"3": undefined,
|
|
87
|
+
"4": null,
|
|
88
|
+
"5": "",
|
|
89
|
+
};
|
|
90
|
+
Utils.deleteEmptyProps(obj);
|
|
91
|
+
expect(obj).toEqual({
|
|
92
|
+
"1": true,
|
|
93
|
+
"2": "test",
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
});
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { AuthenticationError } from "../../errors";
|
|
2
|
+
import { ApiHelper } from "../../helpers";
|
|
3
|
+
export class AuthModule {
|
|
4
|
+
axiosInstance;
|
|
5
|
+
constructor(axiosInstance) {
|
|
6
|
+
this.axiosInstance = axiosInstance;
|
|
7
|
+
}
|
|
8
|
+
async authenticate(authToken) {
|
|
9
|
+
// @todo: TBC whether using `xmlbuilder` or template string
|
|
10
|
+
const authHeader = `
|
|
11
|
+
<ns2:AuthenticationToken xmlns:ns2="http://auth.ws.fbsaust.com.au" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
|
|
12
|
+
<username>${authToken.username}</username>
|
|
13
|
+
<method>${authToken.method}</method>
|
|
14
|
+
<password>${authToken.password}</password>
|
|
15
|
+
<timeout>${authToken.timeout}${authToken.timeoutUnit}</timeout>
|
|
16
|
+
</ns2:AuthenticationToken>
|
|
17
|
+
`;
|
|
18
|
+
const loginBody = '<ns2:Login xmlns:ns2="http://auth.ws.fbsaust.com.au"/>';
|
|
19
|
+
const soapEnvelope = `
|
|
20
|
+
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
|
|
21
|
+
<S:Header>${authHeader}</S:Header>
|
|
22
|
+
<S:Body>${loginBody}</S:Body>
|
|
23
|
+
</S:Envelope>
|
|
24
|
+
`;
|
|
25
|
+
try {
|
|
26
|
+
const response = await ApiHelper.sendSoapRequest("/AuthenticationService/AuthenticationService", this.axiosInstance, soapEnvelope);
|
|
27
|
+
const token = response["ns2:LoginResponse"][0]["token"][0];
|
|
28
|
+
if (!token) {
|
|
29
|
+
throw new AuthenticationError("No token received in the authentication response");
|
|
30
|
+
}
|
|
31
|
+
return token;
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
if (error instanceof AuthenticationError) {
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
throw new AuthenticationError(`An unexpected error occurred: ${error.message}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { ApiHelper, Utils } from "../../helpers";
|
|
3
|
+
import { AuthModule } from "./auth.module";
|
|
4
|
+
jest.mock("axios");
|
|
5
|
+
const mAxios = axios;
|
|
6
|
+
const sessionId = ""; // process.env.SESSION_ID as string;
|
|
7
|
+
describe("AuthModule", () => {
|
|
8
|
+
let authModule;
|
|
9
|
+
beforeAll(() => {
|
|
10
|
+
authModule = new AuthModule(mAxios);
|
|
11
|
+
});
|
|
12
|
+
test("authenticate successfully", async () => {
|
|
13
|
+
const mockedSendApiRequest = jest.spyOn(ApiHelper, "sendSoapRequest");
|
|
14
|
+
const authToken = {
|
|
15
|
+
username: "test-username",
|
|
16
|
+
password: "test-password",
|
|
17
|
+
method: "Basic",
|
|
18
|
+
timeout: 365,
|
|
19
|
+
timeoutUnit: "day",
|
|
20
|
+
};
|
|
21
|
+
const mockedToken = "CI03GWHZzXO0VJQ6JSLJoPwWijXTIPilphKvlLhLHcjDQ3yrr6eJeTK6wxDb8XZb";
|
|
22
|
+
const mockedResponse = {
|
|
23
|
+
data: `
|
|
24
|
+
<?xml version='1.0' encoding='UTF-8'?>
|
|
25
|
+
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
|
|
26
|
+
<S:Body>
|
|
27
|
+
<ns2:LoginResponse xmlns:ns2="http://auth.ws.fbsaust.com.au">
|
|
28
|
+
<token>${mockedToken}</token>
|
|
29
|
+
</ns2:LoginResponse>
|
|
30
|
+
</S:Body>
|
|
31
|
+
</S:Envelope>
|
|
32
|
+
`,
|
|
33
|
+
};
|
|
34
|
+
mAxios.post.mockResolvedValueOnce(mockedResponse);
|
|
35
|
+
const token = await authModule.authenticate(authToken);
|
|
36
|
+
expect(mockedSendApiRequest).toHaveBeenCalled();
|
|
37
|
+
expect(mAxios.post).toHaveBeenCalled();
|
|
38
|
+
expect(Utils.removeEmptySpaces(mAxios.post.mock.calls[0][1])).toEqual(Utils.removeEmptySpaces(`
|
|
39
|
+
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
|
|
40
|
+
<S:Header>
|
|
41
|
+
<ns2:AuthenticationToken xmlns:ns2="http://auth.ws.fbsaust.com.au" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
|
|
42
|
+
<username>${authToken.username}</username>
|
|
43
|
+
<method>${authToken.method}</method>
|
|
44
|
+
<password>${authToken.password}</password>
|
|
45
|
+
<timeout>${authToken.timeout}${authToken.timeoutUnit}</timeout>
|
|
46
|
+
</ns2:AuthenticationToken>
|
|
47
|
+
</S:Header>
|
|
48
|
+
<S:Body>
|
|
49
|
+
<ns2:Login xmlns:ns2="http://auth.ws.fbsaust.com.au"/>
|
|
50
|
+
</S:Body>
|
|
51
|
+
</S:Envelope>
|
|
52
|
+
`));
|
|
53
|
+
expect(token).toEqual(mockedToken);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AxiosInstance } from "axios";
|
|
2
|
+
import { Carrier, CarrierShipment, GetCarrierShipmentByTimeQueryParams } from "./types";
|
|
3
|
+
export declare class CarrierModule {
|
|
4
|
+
private axiosInstance;
|
|
5
|
+
private readonly SERVICE_URL;
|
|
6
|
+
constructor(axiosInstance: AxiosInstance);
|
|
7
|
+
getCarrier(sessionId: string): Promise<Carrier[]>;
|
|
8
|
+
getCarrierShipmentByOrderNumber(orderNo: string, sessionId: string): Promise<CarrierShipment[]>;
|
|
9
|
+
getCarrierShipmentBySysTime(params: GetCarrierShipmentByTimeQueryParams, sessionId: string): Promise<CarrierShipment[]>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ApiHelper } from "../../helpers";
|
|
2
|
+
import { ServiceAlias } from "../shared";
|
|
3
|
+
import { mapCarrier, mapCarrierShipment, mapGetCarrierShipmentByOrderNumber, mapGetCarrierShipmentByTimeQueryParams, } from "./mappings";
|
|
4
|
+
export class CarrierModule {
|
|
5
|
+
axiosInstance;
|
|
6
|
+
SERVICE_URL = `CarrierShipmentService/CarrierShipmentService`;
|
|
7
|
+
constructor(axiosInstance) {
|
|
8
|
+
this.axiosInstance = axiosInstance;
|
|
9
|
+
}
|
|
10
|
+
async getCarrier(sessionId) {
|
|
11
|
+
try {
|
|
12
|
+
const response = await ApiHelper.sendServiceRequest(this.SERVICE_URL, `GetCarrier`, sessionId, ServiceAlias.CARRIER, this.axiosInstance);
|
|
13
|
+
return response?.Carrier?.map(mapCarrier);
|
|
14
|
+
}
|
|
15
|
+
catch (error) {
|
|
16
|
+
throw await ApiHelper.parseError(error);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
async getCarrierShipmentByOrderNumber(orderNo, sessionId) {
|
|
20
|
+
try {
|
|
21
|
+
const bodyStr = mapGetCarrierShipmentByOrderNumber(orderNo);
|
|
22
|
+
const response = await ApiHelper.sendServiceRequest(this.SERVICE_URL, ["GetCarrierShipmentByOrderNumber", "Request"], sessionId, ServiceAlias.CARRIER, this.axiosInstance, bodyStr);
|
|
23
|
+
return response?.CarrierShipment?.map(mapCarrierShipment);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
throw await ApiHelper.parseError(error);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async getCarrierShipmentBySysTime(params, sessionId) {
|
|
30
|
+
try {
|
|
31
|
+
const bodyStr = mapGetCarrierShipmentByTimeQueryParams(params);
|
|
32
|
+
const response = await ApiHelper.sendServiceRequest(this.SERVICE_URL, ["GetCarrierShipmentBySysModTime", "Request"], sessionId, ServiceAlias.CARRIER, this.axiosInstance, bodyStr);
|
|
33
|
+
return response?.CarrierShipment?.map(mapCarrierShipment);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
throw await ApiHelper.parseError(error);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|