-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.ts
151 lines (133 loc) · 4.09 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import axios, { Method } from "axios"
import crypto from "crypto"
import { Invoice } from "./types";
const LF = '\u000a';
const md5 = (body: any): string => {
if (typeof body === "object" && !(body instanceof Buffer)) {
body = JSON.stringify(body)
}
return crypto.createHash("md5").update(body).digest("hex")
}
const hmac = (content: string, clientSecret: string): string => {
return crypto
.createHmac("sha256", clientSecret)
.update(content)
.digest("base64")
}
let _client: Fivaldi;
export const configure = (clientIdentifier: string, clientSecret: string, fivaldiPartner: string): Fivaldi => {
_client = new Fivaldi(clientIdentifier, clientSecret, fivaldiPartner)
return _client
}
export const getClient = (): Fivaldi => {
if(!_client){
throw new Error("You must configure the module before accessing the client")
}
return _client
}
export class Fivaldi {
clientIdentifier: string;
clientSecret: string;
fivaldiPartner: string;
constructor(clientIdentifier: string, clientSecret: string, fivaldiPartner: string){
this.clientIdentifier = clientIdentifier;
this.clientSecret = clientSecret;
this.fivaldiPartner = fivaldiPartner;
}
request = async (config: {
method: Method,
body?: any,
uri?: string,
query?: string
}): Promise<any> => {
const baseUrl = "https://api.fivaldi.net"
const { body, method, uri } = config;
let bodyMD5 = ""
let contentType = ""
const query = config.query || ""
const timestamp: string = Math.floor(new Date().getTime() / 1000).toString();
let headers = [
{ key: "X-Fivaldi-Partner", value: this.fivaldiPartner},
{ key: "X-Fivaldi-Timestamp", value: timestamp },
]
if (body) {
bodyMD5 = md5(body)
contentType = "application/json"
headers.push({ key: "Content-Type", value: contentType })
}
let stringToSign: string = [
method || "GET",
bodyMD5,
contentType,
...headers.sort(function (a, b) {
return a.key.toLowerCase().localeCompare(b.key.toLowerCase())
}).filter(header => header.key.startsWith("X-Fivaldi"))
.map(header => `${header.key.trim().toLowerCase()}:${typeof header.value === "string" ? header.value.trim() : header.value}`),
uri
].join(LF);
if (query) {
stringToSign += LF + query;
}
const mac = hmac(
stringToSign,
this.clientSecret
);
headers.push({ key: "Authorization", value: `Fivaldi ${mac}`})
const axiosResponse = await axios({
method,
url: baseUrl + uri + query,
headers: headers.reduce((result, header) => {
result[header.key] = header.value;
return result;
}, {}),
data: body
});
return axiosResponse.data
}
/**
* @param body
* @description Create a signle new invoice.
* @example Fivaldi.createInvoice(body)
*/
async createInvoice(body: Invoice): Promise<any> {
return await this.request({
body,
method: "POST",
uri: `/customer/api/companies/${this.clientIdentifier}/sales/sales-order`
});
}
/**
* @param body
* @description Create multiple new invoices.
* @example Fivaldi.createInvoices(body)
*/
async createMultipleInvoices(body: Invoice): Promise<any> {
return await this.request({
body,
method: "POST",
uri: `/customer/api/companies/${this.clientIdentifier}/sales/multiple-sales-orders`
});
}
/**
*
* @param customerId
* @description Get details of a single customer.
* @example Fivaldi.getCustomer(customerId)
*/
async getCustomerDetails(customerId: string): Promise<any> {
return await this.request({
method: "GET",
uri: `/customer/api/companies/${this.clientIdentifier}/customers/${customerId}`
});
}
/**
* @description Get company's invoicing details and default values for different params.
* @example Fivaldi.getCompanyDetails()
*/
async getCompanyInvoicingDetails(): Promise<any> {
return await this.request({
method: "GET",
uri: `/customer/api/companies/${this.clientIdentifier}/sales/company-invoicing-details`
});
}
}