@dotdev/harmony-sdk 1.0.1
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 +132 -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
package/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# Harmony SDK
|
|
2
|
+
|
|
3
|
+
Harmony SDK is a TypeScript library for interacting with the Harmony API. It provides a set of modules to perform various operations such as authentication, stock lookup, stock level lookup, point of sale operations, carrier management, diary management, and gift voucher handling.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Installation](#installation)
|
|
8
|
+
- [Usage](#usage)
|
|
9
|
+
- [Development](#development)
|
|
10
|
+
- [Implemented Endpoints](#implemented-endpoints)
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
To install the Harmony SDK, use the following command:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @dotapparel/harmony-sdk
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
or if you're using pnpm:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pnpm add @dotapparel/harmony-sdk
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
Here's a basic example of how to use the Harmony SDK:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { HarmonyAPI, AuthenticationToken } from '@dotapparel/harmony-sdk';
|
|
32
|
+
|
|
33
|
+
const api = new HarmonyAPI('https://your-harmony-api-url.com');
|
|
34
|
+
|
|
35
|
+
async function main() {
|
|
36
|
+
const authToken: AuthenticationToken = {
|
|
37
|
+
// Fill in your authentication details
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
const sessionId = await api.authenticate(authToken);
|
|
42
|
+
console.log('Authenticated successfully. Session ID:', sessionId);
|
|
43
|
+
|
|
44
|
+
// Example: Perform a stock lookup
|
|
45
|
+
const stockLookupParams = {
|
|
46
|
+
// Fill in your stock lookup parameters
|
|
47
|
+
};
|
|
48
|
+
const stockResults = await api.stockLookup(stockLookupParams, sessionId);
|
|
49
|
+
console.log('Stock lookup results:', stockResults);
|
|
50
|
+
|
|
51
|
+
// Use other methods as needed...
|
|
52
|
+
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error('Error:', error);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
main();
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Development
|
|
62
|
+
|
|
63
|
+
To set up the development environment:
|
|
64
|
+
|
|
65
|
+
1. Clone the repository:
|
|
66
|
+
```bash
|
|
67
|
+
git clone https://github.com/your-repo/harmony-sdk.git
|
|
68
|
+
cd harmony-sdk
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
2. Install dependencies:
|
|
72
|
+
```bash
|
|
73
|
+
pnpm install
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
3. Build the project:
|
|
77
|
+
```bash
|
|
78
|
+
pnpm run build
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
4. Run tests:
|
|
82
|
+
```bash
|
|
83
|
+
pnpm test
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
5. To watch for changes during development:
|
|
87
|
+
```bash
|
|
88
|
+
pnpm run watch
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Implemented Endpoints
|
|
92
|
+
|
|
93
|
+
The Harmony SDK implements the following endpoints:
|
|
94
|
+
|
|
95
|
+
1. Authentication
|
|
96
|
+
- `authenticate(authToken: AuthenticationToken): Promise<string>`
|
|
97
|
+
|
|
98
|
+
2. Stock Lookup Module
|
|
99
|
+
- `stockLookup(params: StockLookupRequestParams, sessionId: string): Promise<Stock[]>`
|
|
100
|
+
- `stockCategoryLookup(sessionId: string): Promise<StockCategory[]>`
|
|
101
|
+
- `stockBarcodeLookup(params: StockLookupRequestParams, sessionId: string): Promise<StockBarcode[]>`
|
|
102
|
+
- `stockColorLookup(sessionId: string): Promise<StockColor[]>`
|
|
103
|
+
- `sizeGridLookup(sessionId: string): Promise<SizeGrid[]>`
|
|
104
|
+
- `stockClassificationLookup(sessionId: string, searchType?: StockClassificationType): Promise<StockClassification[]>`
|
|
105
|
+
|
|
106
|
+
3. Stock Level Lookup Module
|
|
107
|
+
- `warehouseLookup(sessionId: string): Promise<Warehouse[]>`
|
|
108
|
+
- `stockLevelLookup(params: StockLevelLookupQueryParams, sessionId: string): Promise<StockLevel[]>`
|
|
109
|
+
- `stockLevelLookupByWarehouseQuickView(params: StockLevelLookupQueryParams, sessionId: string): Promise<StockLevel[]>`
|
|
110
|
+
|
|
111
|
+
4. Point of Sale Module
|
|
112
|
+
- `processSalesOrder(params: ProcessSaleOrderQueryParams, sessionId: string): Promise<boolean>`
|
|
113
|
+
- `processReturns(params: ProcessSaleOrderQueryParams, sessionId: string): Promise<boolean>`
|
|
114
|
+
- `modifyExistingSalesOrder(params: ProcessSaleOrderQueryParams, sessionId: string): Promise<boolean>`
|
|
115
|
+
- `cancelExistingSalesOrder(params: ProcessSaleOrderQueryParams, sessionId: string): Promise<boolean>`
|
|
116
|
+
|
|
117
|
+
5. Carrier Module
|
|
118
|
+
- `getCarrier(sessionId: string): Promise<Carrier[]>`
|
|
119
|
+
- `getCarrierShipmentByOrderNo(orderNo: string, sessionId: string): Promise<CarrierShipment[]>`
|
|
120
|
+
- `getCarrierBySysTime(params: GetCarrierShipmentByTimeQueryParams, sessionId: string): Promise<CarrierShipment[]>`
|
|
121
|
+
|
|
122
|
+
6. Diary Module
|
|
123
|
+
- `getDiaryBy(params: GetDiaryQueryParams, sessionId: string): Promise<Diary[]>`
|
|
124
|
+
- `createDiary(params: CreateDiaryQueryParams, sessionId: string): Promise<boolean>`
|
|
125
|
+
|
|
126
|
+
7. Gift Voucher Module
|
|
127
|
+
- `giftVoucherLookup(params: GiftVoucherLookupQueryParams, sessionId: string): Promise<GiftVoucher[]>`
|
|
128
|
+
- `giftVoucherVerificationKey(params: GiftVoucherVerificationKeyQueryParams, sessionId: string): Promise<string>`
|
|
129
|
+
- `giftVoucherReservation(params: GiftVoucherReservationQueryParams, sessionId: string): Promise<string>`
|
|
130
|
+
- `giftVoucherUsed(params: GiftVoucherUsedQueryParams, sessionId: string): Promise<number>`
|
|
131
|
+
|
|
132
|
+
For detailed information on each endpoint and its parameters, please refer to the source code and type definitions.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { AuthenticationToken, Carrier, CarrierShipment, CreateDiaryQueryParams, Diary, GetCarrierShipmentByTimeQueryParams, GetDiaryQueryParams, ProcessSaleOrderQueryParams, SizeGrid, Stock, StockBarcode, StockCategory, StockClassification, StockClassificationType, StockColor, StockLevel, StockLevelLookupQueryParams, StockLookupRequestParams, Warehouse } from "./modules";
|
|
2
|
+
import { GiftVoucher, GiftVoucherLookupQueryParams, GiftVoucherReservationQueryParams, GiftVoucherUsedQueryParams, GiftVoucherVerificationKeyQueryParams } from "./modules/gift-voucher/types";
|
|
3
|
+
export declare class HarmonyAPI {
|
|
4
|
+
private baseUrl;
|
|
5
|
+
private axiosInstance;
|
|
6
|
+
private authModule;
|
|
7
|
+
private stockLookupModule;
|
|
8
|
+
private stockLevelLookupModule;
|
|
9
|
+
private pointOfSaleModule;
|
|
10
|
+
private carrierModule;
|
|
11
|
+
private diaryModule;
|
|
12
|
+
private giftVoucherModule;
|
|
13
|
+
constructor(url: string);
|
|
14
|
+
authenticate(authToken: AuthenticationToken): Promise<string>;
|
|
15
|
+
stockLookup(params: StockLookupRequestParams, sessionId: string): Promise<Stock[]>;
|
|
16
|
+
stockCategoryLookup(sessionId: string): Promise<StockCategory[]>;
|
|
17
|
+
stockBarcodeLookup(params: StockLookupRequestParams, sessionId: string): Promise<StockBarcode[]>;
|
|
18
|
+
stockColorLookup(sessionId: string): Promise<StockColor[]>;
|
|
19
|
+
sizeGridLookup(sessionId: string): Promise<SizeGrid[]>;
|
|
20
|
+
stockClassificationLookup(sessionId: string, searchType?: StockClassificationType): Promise<StockClassification[]>;
|
|
21
|
+
warehouseLookup(sessionId: string): Promise<Warehouse[]>;
|
|
22
|
+
stockLevelLookup(params: StockLevelLookupQueryParams, sessionId: string): Promise<StockLevel[]>;
|
|
23
|
+
stockLevelLookupByWarehouseQuickView(params: StockLevelLookupQueryParams, sessionId: string): Promise<StockLevel[]>;
|
|
24
|
+
processSalesOrder(params: ProcessSaleOrderQueryParams, sessionId: string): Promise<boolean>;
|
|
25
|
+
processReturns(params: ProcessSaleOrderQueryParams, sessionId: string): Promise<boolean>;
|
|
26
|
+
modifyExistingSalesOrder(params: ProcessSaleOrderQueryParams, sessionId: string): Promise<boolean>;
|
|
27
|
+
cancelExistingSalesOrder(params: ProcessSaleOrderQueryParams, sessionId: string): Promise<boolean>;
|
|
28
|
+
getCarrier(sessionId: string): Promise<Carrier[]>;
|
|
29
|
+
getCarrierShipmentByOrderNo(orderNo: string, sessionId: string): Promise<CarrierShipment[]>;
|
|
30
|
+
getCarrierBySysTime(params: GetCarrierShipmentByTimeQueryParams, sessionId: string): Promise<CarrierShipment[]>;
|
|
31
|
+
getDiaryBy(params: GetDiaryQueryParams, sessionId: string): Promise<Diary[]>;
|
|
32
|
+
createDiary(params: CreateDiaryQueryParams, sessionId: string): Promise<boolean>;
|
|
33
|
+
giftVoucherLookup(params: GiftVoucherLookupQueryParams, sessionId: string): Promise<GiftVoucher[]>;
|
|
34
|
+
giftVoucherVerificationKey(params: GiftVoucherVerificationKeyQueryParams, sessionId: string): Promise<string>;
|
|
35
|
+
giftVoucherReservation(params: GiftVoucherReservationQueryParams, sessionId: string): Promise<string>;
|
|
36
|
+
giftVoucherUsed(params: GiftVoucherUsedQueryParams, sessionId: string): Promise<number>;
|
|
37
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import * as https from "https";
|
|
3
|
+
import { promisify } from "util";
|
|
4
|
+
import { parseString } from "xml2js";
|
|
5
|
+
import { AuthModule, CarrierModule, DiaryModule, GiftVoucherModule, PointOfSaleModule, StockClassificationType, StockLevelLookupModule, StockLookupModule, } from "./modules";
|
|
6
|
+
require("tls").DEFAULT_MIN_VERSION = "TLSv1";
|
|
7
|
+
const parseXml = promisify(parseString);
|
|
8
|
+
export class HarmonyAPI {
|
|
9
|
+
baseUrl;
|
|
10
|
+
axiosInstance;
|
|
11
|
+
authModule;
|
|
12
|
+
stockLookupModule;
|
|
13
|
+
stockLevelLookupModule;
|
|
14
|
+
pointOfSaleModule;
|
|
15
|
+
carrierModule;
|
|
16
|
+
diaryModule;
|
|
17
|
+
giftVoucherModule;
|
|
18
|
+
constructor(url) {
|
|
19
|
+
this.baseUrl = url;
|
|
20
|
+
this.axiosInstance = axios.create({
|
|
21
|
+
baseURL: this.baseUrl,
|
|
22
|
+
headers: {
|
|
23
|
+
"Content-Type": "text/xml;charset=UTF-8",
|
|
24
|
+
},
|
|
25
|
+
httpsAgent: new https.Agent({
|
|
26
|
+
rejectUnauthorized: false,
|
|
27
|
+
}),
|
|
28
|
+
});
|
|
29
|
+
// Initialise modules that correspond to Harmony API services
|
|
30
|
+
this.authModule = new AuthModule(this.axiosInstance);
|
|
31
|
+
this.stockLookupModule = new StockLookupModule(this.axiosInstance);
|
|
32
|
+
this.stockLevelLookupModule = new StockLevelLookupModule(this.axiosInstance);
|
|
33
|
+
this.pointOfSaleModule = new PointOfSaleModule(this.axiosInstance);
|
|
34
|
+
this.carrierModule = new CarrierModule(this.axiosInstance);
|
|
35
|
+
this.diaryModule = new DiaryModule(this.axiosInstance);
|
|
36
|
+
this.giftVoucherModule = new GiftVoucherModule(this.axiosInstance);
|
|
37
|
+
}
|
|
38
|
+
async authenticate(authToken) {
|
|
39
|
+
return await this.authModule.authenticate(authToken);
|
|
40
|
+
}
|
|
41
|
+
// Stock lookup module
|
|
42
|
+
async stockLookup(params, sessionId) {
|
|
43
|
+
return await this.stockLookupModule.stockLookup(params, sessionId);
|
|
44
|
+
}
|
|
45
|
+
async stockCategoryLookup(sessionId) {
|
|
46
|
+
return await this.stockLookupModule.stockCategoryLookup(sessionId);
|
|
47
|
+
}
|
|
48
|
+
async stockBarcodeLookup(params, sessionId) {
|
|
49
|
+
return await this.stockLookupModule.stockBarcodeLookup(params, sessionId);
|
|
50
|
+
}
|
|
51
|
+
async stockColorLookup(sessionId) {
|
|
52
|
+
return await this.stockLookupModule.stockColorLookup(sessionId);
|
|
53
|
+
}
|
|
54
|
+
async sizeGridLookup(sessionId) {
|
|
55
|
+
return await this.stockLookupModule.sizeGridLookup(sessionId);
|
|
56
|
+
}
|
|
57
|
+
async stockClassificationLookup(sessionId, searchType = StockClassificationType.STK1) {
|
|
58
|
+
return await this.stockLookupModule.stockClassificationLookup(sessionId, searchType);
|
|
59
|
+
}
|
|
60
|
+
// Stock level lookup module
|
|
61
|
+
async warehouseLookup(sessionId) {
|
|
62
|
+
return await this.stockLevelLookupModule.warehouseLookup(sessionId);
|
|
63
|
+
}
|
|
64
|
+
async stockLevelLookup(params, sessionId) {
|
|
65
|
+
return await this.stockLevelLookupModule.stockLevelLookup(params, sessionId);
|
|
66
|
+
}
|
|
67
|
+
async stockLevelLookupByWarehouseQuickView(params, sessionId) {
|
|
68
|
+
return await this.stockLevelLookupModule.stockLevelLookupByWarehouseQuickView(params, sessionId);
|
|
69
|
+
}
|
|
70
|
+
// Point of sale module
|
|
71
|
+
async processSalesOrder(params, sessionId) {
|
|
72
|
+
return await this.pointOfSaleModule.processSalesOrder(params, sessionId);
|
|
73
|
+
}
|
|
74
|
+
async processReturns(params, sessionId) {
|
|
75
|
+
return await this.pointOfSaleModule.processReturns(params, sessionId);
|
|
76
|
+
}
|
|
77
|
+
async modifyExistingSalesOrder(params, sessionId) {
|
|
78
|
+
return await this.pointOfSaleModule.modifyExistingSalesOrder(params, sessionId);
|
|
79
|
+
}
|
|
80
|
+
async cancelExistingSalesOrder(params, sessionId) {
|
|
81
|
+
return await this.pointOfSaleModule.cancelExistingSalesOrder(params, sessionId);
|
|
82
|
+
}
|
|
83
|
+
// Carrier module
|
|
84
|
+
async getCarrier(sessionId) {
|
|
85
|
+
return await this.carrierModule.getCarrier(sessionId);
|
|
86
|
+
}
|
|
87
|
+
async getCarrierShipmentByOrderNo(orderNo, sessionId) {
|
|
88
|
+
return await this.carrierModule.getCarrierShipmentByOrderNumber(orderNo, sessionId);
|
|
89
|
+
}
|
|
90
|
+
async getCarrierBySysTime(params, sessionId) {
|
|
91
|
+
return await this.carrierModule.getCarrierShipmentBySysTime(params, sessionId);
|
|
92
|
+
}
|
|
93
|
+
// Diary module
|
|
94
|
+
async getDiaryBy(params, sessionId) {
|
|
95
|
+
return await this.diaryModule.getDiaryBy(params, sessionId);
|
|
96
|
+
}
|
|
97
|
+
async createDiary(params, sessionId) {
|
|
98
|
+
return await this.diaryModule.createDiary(params, sessionId);
|
|
99
|
+
}
|
|
100
|
+
// Gift voucher module
|
|
101
|
+
async giftVoucherLookup(params, sessionId) {
|
|
102
|
+
return this.giftVoucherModule.giftVoucherLookup(params, sessionId);
|
|
103
|
+
}
|
|
104
|
+
async giftVoucherVerificationKey(params, sessionId) {
|
|
105
|
+
return this.giftVoucherModule.giftVoucherVerificationKey(params, sessionId);
|
|
106
|
+
}
|
|
107
|
+
async giftVoucherReservation(params, sessionId) {
|
|
108
|
+
return this.giftVoucherModule.giftVoucherVerificationKey(params, sessionId);
|
|
109
|
+
}
|
|
110
|
+
async giftVoucherUsed(params, sessionId) {
|
|
111
|
+
return this.giftVoucherModule.giftVoucherUsed(params, sessionId);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare class HarmonyAPIError extends Error {
|
|
2
|
+
constructor(message: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class AuthenticationError extends HarmonyAPIError {
|
|
5
|
+
constructor(message: string);
|
|
6
|
+
}
|
|
7
|
+
export declare class RequestError extends HarmonyAPIError {
|
|
8
|
+
constructor(message: string);
|
|
9
|
+
}
|
|
10
|
+
export interface ApiError {
|
|
11
|
+
status?: string;
|
|
12
|
+
code?: string;
|
|
13
|
+
name?: string;
|
|
14
|
+
message?: string;
|
|
15
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export class HarmonyAPIError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = "HarmonyAPIError";
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export class AuthenticationError extends HarmonyAPIError {
|
|
8
|
+
constructor(message) {
|
|
9
|
+
super(message);
|
|
10
|
+
this.name = "AuthenticationError";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export class RequestError extends HarmonyAPIError {
|
|
14
|
+
constructor(message) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = "RequestError";
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { AxiosInstance } from "axios";
|
|
2
|
+
import { ApiError, RequestError } from "../errors";
|
|
3
|
+
import { ParamLimits, ServiceAlias } from "../modules";
|
|
4
|
+
export * from "./utils";
|
|
5
|
+
export declare abstract class ApiHelper {
|
|
6
|
+
static sendSoapRequest(endpoint: string, axiosInstance: AxiosInstance, requestBody?: string, type?: "GET" | "POST"): Promise<any>;
|
|
7
|
+
/**
|
|
8
|
+
* Helper function to create SOAP request body for Harmony API
|
|
9
|
+
*
|
|
10
|
+
* @static
|
|
11
|
+
* @param {(string | string[])} methodName
|
|
12
|
+
* @param {string} sessionId
|
|
13
|
+
* @param {ServiceAlias} serviceAlias
|
|
14
|
+
* @param {?string} [body]
|
|
15
|
+
* @returns {string}
|
|
16
|
+
*/
|
|
17
|
+
static createServiceRequestBody(methodName: string | string[], sessionId: string, serviceAlias: ServiceAlias, body?: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Private method to send SOAP request to different endpoint in Point Of Sale service in Harmony API
|
|
20
|
+
*
|
|
21
|
+
* @private
|
|
22
|
+
* @async
|
|
23
|
+
* @template R
|
|
24
|
+
* @param {string} methodName
|
|
25
|
+
* @param {string} sessionId
|
|
26
|
+
* @returns {Promise<R>}
|
|
27
|
+
*/
|
|
28
|
+
static sendServiceRequest<R>(serviceName: string, methodName: string | string[], sessionId: string, serviceAlias: ServiceAlias, axios: AxiosInstance, body?: string): Promise<R>;
|
|
29
|
+
static parseError(error: any): Promise<RequestError>;
|
|
30
|
+
/**
|
|
31
|
+
* Extract error response from Harmony in XML format and convert it to JSON format for ease of debugging
|
|
32
|
+
*
|
|
33
|
+
* @static
|
|
34
|
+
* @async
|
|
35
|
+
* @param {*} error XML error string
|
|
36
|
+
* @returns {Promise<ApiError>} JSON error object
|
|
37
|
+
*/
|
|
38
|
+
static parseHarmonyErrorResponse(error: any): Promise<ApiError>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Check whether the provided parameters meet the specified limits. If any parameter exceeds the limit, an error will be thrown.
|
|
42
|
+
* If all checks passed, return true.
|
|
43
|
+
*
|
|
44
|
+
* @export
|
|
45
|
+
* @template T
|
|
46
|
+
* @param {T} params set of parameters to be checked
|
|
47
|
+
* @param {ParamLimits<T>} limits limit object with same properties as the parameter object, with value of each key being a number or a function that returns a boolean
|
|
48
|
+
* @returns {boolean} returns true if all checks passed
|
|
49
|
+
*/
|
|
50
|
+
export declare function checkParamLimits<T>(params: T, limits: ParamLimits<T>): boolean;
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { promisify } from "util";
|
|
3
|
+
import { parseString } from "xml2js";
|
|
4
|
+
import { RequestError } from "../errors";
|
|
5
|
+
import { Utils } from "./utils";
|
|
6
|
+
export * from "./utils";
|
|
7
|
+
const parseXml = promisify(parseString);
|
|
8
|
+
export class ApiHelper {
|
|
9
|
+
static async sendSoapRequest(endpoint, axiosInstance, requestBody, type = "POST") {
|
|
10
|
+
const url = `${endpoint}?wsdl`;
|
|
11
|
+
try {
|
|
12
|
+
let response;
|
|
13
|
+
switch (type) {
|
|
14
|
+
case "GET":
|
|
15
|
+
response = await axiosInstance.get(url, {
|
|
16
|
+
params: {},
|
|
17
|
+
});
|
|
18
|
+
break;
|
|
19
|
+
case "POST":
|
|
20
|
+
default:
|
|
21
|
+
response = await axiosInstance.post(url, requestBody, {
|
|
22
|
+
// headers: {
|
|
23
|
+
// 'SOAPAction': request.action
|
|
24
|
+
// }
|
|
25
|
+
});
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
const result = (await parseXml(response?.data)); // fix type
|
|
29
|
+
return result["S:Envelope"]["S:Body"][0];
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
throw await ApiHelper.parseError(error);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Helper function to create SOAP request body for Harmony API
|
|
37
|
+
*
|
|
38
|
+
* @static
|
|
39
|
+
* @param {(string | string[])} methodName
|
|
40
|
+
* @param {string} sessionId
|
|
41
|
+
* @param {ServiceAlias} serviceAlias
|
|
42
|
+
* @param {?string} [body]
|
|
43
|
+
* @returns {string}
|
|
44
|
+
*/
|
|
45
|
+
static createServiceRequestBody(methodName, sessionId, serviceAlias, body) {
|
|
46
|
+
const soapNamespace = "S";
|
|
47
|
+
// Extract method name and construct corresponding properties for the body of the SOAP request and the response from the API
|
|
48
|
+
const bodyMethodName = Array.isArray(methodName)
|
|
49
|
+
? methodName.join("")
|
|
50
|
+
: methodName;
|
|
51
|
+
const soapBody = `<${serviceAlias}:${bodyMethodName}>${body ?? ""}</${serviceAlias}:${bodyMethodName}>`;
|
|
52
|
+
const soapHeader = `
|
|
53
|
+
<${serviceAlias}:SessionId>${sessionId}</${serviceAlias}:SessionId>
|
|
54
|
+
`;
|
|
55
|
+
return `
|
|
56
|
+
<${soapNamespace}:Envelope xmlns:${soapNamespace}="http://schemas.xmlsoap.org/soap/envelope/" xmlns:${serviceAlias}="http://${serviceAlias}.ws.fbsaust.com.au">
|
|
57
|
+
<${soapNamespace}:Header>
|
|
58
|
+
${soapHeader}
|
|
59
|
+
</${soapNamespace}:Header>
|
|
60
|
+
<${soapNamespace}:Body>
|
|
61
|
+
${soapBody}
|
|
62
|
+
</${soapNamespace}:Body>
|
|
63
|
+
</${soapNamespace}:Envelope>
|
|
64
|
+
`;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Private method to send SOAP request to different endpoint in Point Of Sale service in Harmony API
|
|
68
|
+
*
|
|
69
|
+
* @private
|
|
70
|
+
* @async
|
|
71
|
+
* @template R
|
|
72
|
+
* @param {string} methodName
|
|
73
|
+
* @param {string} sessionId
|
|
74
|
+
* @returns {Promise<R>}
|
|
75
|
+
*/
|
|
76
|
+
static async sendServiceRequest(serviceName, methodName, sessionId, serviceAlias, axios, body) {
|
|
77
|
+
// Extract method name and construct corresponding properties for the body of the SOAP request and the response from the API
|
|
78
|
+
const responseMethodName = Array.isArray(methodName)
|
|
79
|
+
? `ns2:${methodName[0]}Response`
|
|
80
|
+
: `ns2:${methodName}Response`;
|
|
81
|
+
const requestBody = ApiHelper.createServiceRequestBody(methodName, sessionId, serviceAlias, body);
|
|
82
|
+
const response = await ApiHelper.sendSoapRequest(serviceName, axios, requestBody);
|
|
83
|
+
return response[responseMethodName][0];
|
|
84
|
+
}
|
|
85
|
+
static async parseError(error) {
|
|
86
|
+
if (axios.isAxiosError(error)) {
|
|
87
|
+
if (error?.response) {
|
|
88
|
+
const parsedError = await ApiHelper.parseHarmonyErrorResponse(error?.response?.data);
|
|
89
|
+
return new RequestError(`API request failed with status ${error.response.status}: {code: ${parsedError?.code}, name: ${parsedError?.name}, message: ${parsedError?.message}}`);
|
|
90
|
+
}
|
|
91
|
+
else if (error?.request) {
|
|
92
|
+
return new RequestError("No response received from the server during API call");
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
return new RequestError(`API request setup failed: ${error?.message}`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
return new RequestError(`An unexpected error occurred during API request: ${JSON.stringify(error.message)}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Extract error response from Harmony in XML format and convert it to JSON format for ease of debugging
|
|
104
|
+
*
|
|
105
|
+
* @static
|
|
106
|
+
* @async
|
|
107
|
+
* @param {*} error XML error string
|
|
108
|
+
* @returns {Promise<ApiError>} JSON error object
|
|
109
|
+
*/
|
|
110
|
+
static async parseHarmonyErrorResponse(error) {
|
|
111
|
+
if (error == null)
|
|
112
|
+
return { code: "", name: "", message: "" };
|
|
113
|
+
const result = (await parseXml(error));
|
|
114
|
+
const errorDetails = result["S:Envelope"]["S:Body"][0]["S:Fault"][0];
|
|
115
|
+
// Extract error response body
|
|
116
|
+
const code = Utils.nonEmptyArray(errorDetails["faultcode"])
|
|
117
|
+
? errorDetails["faultcode"][0]
|
|
118
|
+
: "";
|
|
119
|
+
const name = Utils.nonEmptyArray(errorDetails["faultstring"])
|
|
120
|
+
? errorDetails["faultstring"][0]
|
|
121
|
+
: "";
|
|
122
|
+
// extract error message
|
|
123
|
+
const detail = errorDetails["detail"];
|
|
124
|
+
const fault = Utils.nonEmptyArray(detail)
|
|
125
|
+
? detail[0]["ns2:ServiceFault"]
|
|
126
|
+
: [];
|
|
127
|
+
const message = Utils.nonEmptyArray(fault) ? fault[0]["errorDetails"] : [];
|
|
128
|
+
return {
|
|
129
|
+
code,
|
|
130
|
+
name,
|
|
131
|
+
message: message[0] ?? "",
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Check whether the provided parameters meet the specified limits. If any parameter exceeds the limit, an error will be thrown.
|
|
137
|
+
* If all checks passed, return true.
|
|
138
|
+
*
|
|
139
|
+
* @export
|
|
140
|
+
* @template T
|
|
141
|
+
* @param {T} params set of parameters to be checked
|
|
142
|
+
* @param {ParamLimits<T>} limits limit object with same properties as the parameter object, with value of each key being a number or a function that returns a boolean
|
|
143
|
+
* @returns {boolean} returns true if all checks passed
|
|
144
|
+
*/
|
|
145
|
+
export function checkParamLimits(params, limits) {
|
|
146
|
+
for (const key in params) {
|
|
147
|
+
const val = params[key];
|
|
148
|
+
const limit = limits[key];
|
|
149
|
+
// Only perform checks if both param value and limit are defined
|
|
150
|
+
if (val && limit) {
|
|
151
|
+
// If limit type is a number a.k.a length limit, check if provided string value exceeds the length limit
|
|
152
|
+
if (typeof limit === "number") {
|
|
153
|
+
const valStr = typeof val === "string" ? val : val.toString();
|
|
154
|
+
if (valStr.length > limit) {
|
|
155
|
+
throw new Error(`Provided value for "${key}" exceeds limit of ${limit}`);
|
|
156
|
+
}
|
|
157
|
+
// Otherwise call limit function to determine whether value meets the condition
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
if (!limit(val)) {
|
|
161
|
+
throw new Error(`Invalid value for parameter "${key}": ${val}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|