@ripwords/myinvois-client 0.0.6 → 0.0.7
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/dist/cjs/index.cjs +9 -4
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/index.cjs +75 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +9 -4
- package/package.json +5 -1
- package/rolldown.config.ts +1 -1
- package/src/utils/MyInvoisClient.ts +12 -3
- package/test/MyInvoisClient.test.ts +10 -6
package/dist/cjs/index.cjs
CHANGED
|
@@ -5,11 +5,13 @@ var MyInvoisClient = class {
|
|
|
5
5
|
baseUrl;
|
|
6
6
|
clientId;
|
|
7
7
|
clientSecret;
|
|
8
|
+
debug;
|
|
8
9
|
token = "";
|
|
9
10
|
tokenExpiration;
|
|
10
|
-
constructor(clientId, clientSecret, environment) {
|
|
11
|
+
constructor(clientId, clientSecret, environment, debug = false) {
|
|
11
12
|
this.clientId = clientId;
|
|
12
13
|
this.clientSecret = clientSecret;
|
|
14
|
+
this.debug = debug;
|
|
13
15
|
if (environment === "sandbox") this.baseUrl = "https://preprod-api.myinvois.hasil.gov.my";
|
|
14
16
|
else this.baseUrl = "https://api.myinvois.hasil.gov.my";
|
|
15
17
|
}
|
|
@@ -29,11 +31,14 @@ var MyInvoisClient = class {
|
|
|
29
31
|
this.token = tokenResponse.access_token;
|
|
30
32
|
this.tokenExpiration = new Date(Date.now() + tokenResponse.expires_in * 1e3);
|
|
31
33
|
} catch (error) {
|
|
32
|
-
console.error(error);
|
|
34
|
+
if (this.debug) console.error(error);
|
|
33
35
|
}
|
|
34
36
|
}
|
|
35
37
|
async getToken() {
|
|
36
|
-
if (!this.tokenExpiration || this.tokenExpiration < new Date())
|
|
38
|
+
if (!this.tokenExpiration || this.tokenExpiration < new Date()) {
|
|
39
|
+
if (this.debug) console.log("Refreshing token");
|
|
40
|
+
await this.refreshToken();
|
|
41
|
+
}
|
|
37
42
|
return this.token;
|
|
38
43
|
}
|
|
39
44
|
async fetch(path, options = {}) {
|
|
@@ -59,7 +64,7 @@ var MyInvoisClient = class {
|
|
|
59
64
|
if (response.status === 200) return true;
|
|
60
65
|
return false;
|
|
61
66
|
} catch (error) {
|
|
62
|
-
console.error(error);
|
|
67
|
+
if (this.debug) console.error(error);
|
|
63
68
|
return false;
|
|
64
69
|
}
|
|
65
70
|
}
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["clientId: string","clientSecret: string","environment: 'sandbox' | 'production'","tokenResponse: TokenResponse","path: string","options: Parameters<typeof fetch>[1]","tin: string","nric: string"],"sources":["../../src/utils/MyInvoisClient.ts"],"sourcesContent":["interface TokenResponse {\n access_token: string\n expires_in: number\n}\n\nexport class MyInvoisClient {\n private readonly baseUrl: string\n private readonly clientId: string\n private readonly clientSecret: string\n private token = ''\n private tokenExpiration: Date | undefined\n\n constructor(\n clientId: string,\n clientSecret: string,\n environment: 'sandbox' | 'production',\n ) {\n this.clientId = clientId\n this.clientSecret = clientSecret\n\n if (environment === 'sandbox') {\n this.baseUrl = 'https://preprod-api.myinvois.hasil.gov.my'\n } else {\n this.baseUrl = 'https://api.myinvois.hasil.gov.my'\n }\n }\n\n private async refreshToken() {\n try {\n const response = await fetch(`${this.baseUrl}/connect/token`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: this.clientId,\n client_secret: this.clientSecret,\n scope: 'InvoicingAPI',\n }),\n })\n\n const tokenResponse: TokenResponse = await response.json()\n\n this.token = tokenResponse.access_token\n this.tokenExpiration = new Date(\n Date.now() + tokenResponse.expires_in * 1000,\n )\n } catch (error) {\n console.error(error)\n }\n }\n\n private async getToken() {\n if (!this.tokenExpiration || this.tokenExpiration < new Date()) {\n await this.refreshToken()\n }\n\n return this.token\n }\n\n private async fetch(path: string, options: Parameters<typeof fetch>[1] = {}) {\n const token = await this.getToken()\n\n return fetch(`${this.baseUrl}${path}`, {\n ...options,\n headers: { ...options.headers, Authorization: `Bearer ${token}` },\n })\n }\n\n /**\n * Validates a TIN against a NRIC\n *\n * @param tin\n * @param nric\n * @returns\n */\n async verifyTin(tin: string, nric: string) {\n try {\n const response = await this.fetch(\n `/api/v1.0/taxpayer/validate/${tin}?idType=NRIC&idValue=${nric}`,\n {\n method: 'GET',\n },\n )\n\n if (response.status === 200) {\n return true\n }\n\n return false\n } catch (error) {\n console.error(error)\n return false\n }\n }\n}\n"],"mappings":";;;IAKa,iBAAN,MAAqB;CAC1B,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAQ,QAAQ;CAChB,AAAQ;CAER,YACEA,UACAC,cACAC,
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["clientId: string","clientSecret: string","environment: 'sandbox' | 'production'","debug: boolean","tokenResponse: TokenResponse","path: string","options: Parameters<typeof fetch>[1]","tin: string","nric: string"],"sources":["../../src/utils/MyInvoisClient.ts"],"sourcesContent":["interface TokenResponse {\n access_token: string\n expires_in: number\n}\n\nexport class MyInvoisClient {\n private readonly baseUrl: string\n private readonly clientId: string\n private readonly clientSecret: string\n private readonly debug: boolean\n private token = ''\n private tokenExpiration: Date | undefined\n\n constructor(\n clientId: string,\n clientSecret: string,\n environment: 'sandbox' | 'production',\n debug: boolean = false,\n ) {\n this.clientId = clientId\n this.clientSecret = clientSecret\n this.debug = debug\n if (environment === 'sandbox') {\n this.baseUrl = 'https://preprod-api.myinvois.hasil.gov.my'\n } else {\n this.baseUrl = 'https://api.myinvois.hasil.gov.my'\n }\n }\n\n private async refreshToken() {\n try {\n const response = await fetch(`${this.baseUrl}/connect/token`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: this.clientId,\n client_secret: this.clientSecret,\n scope: 'InvoicingAPI',\n }),\n })\n\n const tokenResponse: TokenResponse = await response.json()\n\n this.token = tokenResponse.access_token\n this.tokenExpiration = new Date(\n Date.now() + tokenResponse.expires_in * 1000,\n )\n } catch (error) {\n if (this.debug) {\n console.error(error)\n }\n }\n }\n\n private async getToken() {\n if (!this.tokenExpiration || this.tokenExpiration < new Date()) {\n if (this.debug) {\n console.log('Refreshing token')\n }\n await this.refreshToken()\n }\n\n return this.token\n }\n\n private async fetch(path: string, options: Parameters<typeof fetch>[1] = {}) {\n const token = await this.getToken()\n\n return fetch(`${this.baseUrl}${path}`, {\n ...options,\n headers: { ...options.headers, Authorization: `Bearer ${token}` },\n })\n }\n\n /**\n * Validates a TIN against a NRIC\n *\n * @param tin\n * @param nric\n * @returns\n */\n async verifyTin(tin: string, nric: string) {\n try {\n const response = await this.fetch(\n `/api/v1.0/taxpayer/validate/${tin}?idType=NRIC&idValue=${nric}`,\n {\n method: 'GET',\n },\n )\n\n if (response.status === 200) {\n return true\n }\n\n return false\n } catch (error) {\n if (this.debug) {\n console.error(error)\n }\n return false\n }\n }\n}\n"],"mappings":";;;IAKa,iBAAN,MAAqB;CAC1B,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAQ,QAAQ;CAChB,AAAQ;CAER,YACEA,UACAC,cACAC,aACAC,QAAiB,OACjB;AACA,OAAK,WAAW;AAChB,OAAK,eAAe;AACpB,OAAK,QAAQ;AACb,MAAI,gBAAgB,UAClB,MAAK,UAAU;MAEf,MAAK,UAAU;CAElB;CAED,MAAc,eAAe;AAC3B,MAAI;GACF,MAAM,WAAW,MAAM,OAAO,EAAE,KAAK,QAAQ,iBAAiB;IAC5D,QAAQ;IACR,SAAS,EACP,gBAAgB,oCACjB;IACD,MAAM,IAAI,gBAAgB;KACxB,YAAY;KACZ,WAAW,KAAK;KAChB,eAAe,KAAK;KACpB,OAAO;IACR;GACF,EAAC;GAEF,MAAMC,gBAA+B,MAAM,SAAS,MAAM;AAE1D,QAAK,QAAQ,cAAc;AAC3B,QAAK,kBAAkB,IAAI,KACzB,KAAK,KAAK,GAAG,cAAc,aAAa;EAE3C,SAAQ,OAAO;AACd,OAAI,KAAK,MACP,SAAQ,MAAM,MAAM;EAEvB;CACF;CAED,MAAc,WAAW;AACvB,OAAK,KAAK,mBAAmB,KAAK,kBAAkB,IAAI,QAAQ;AAC9D,OAAI,KAAK,MACP,SAAQ,IAAI,mBAAmB;AAEjC,SAAM,KAAK,cAAc;EAC1B;AAED,SAAO,KAAK;CACb;CAED,MAAc,MAAMC,MAAcC,UAAuC,CAAE,GAAE;EAC3E,MAAM,QAAQ,MAAM,KAAK,UAAU;AAEnC,SAAO,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,GAAG;GACrC,GAAG;GACH,SAAS;IAAE,GAAG,QAAQ;IAAS,gBAAgB,SAAS,MAAM;GAAG;EAClE,EAAC;CACH;;;;;;;;CASD,MAAM,UAAUC,KAAaC,MAAc;AACzC,MAAI;GACF,MAAM,WAAW,MAAM,KAAK,OACzB,8BAA8B,IAAI,uBAAuB,KAAK,GAC/D,EACE,QAAQ,MACT,EACF;AAED,OAAI,SAAS,WAAW,IACtB,QAAO;AAGT,UAAO;EACR,SAAQ,OAAO;AACd,OAAI,KAAK,MACP,SAAQ,MAAM,MAAM;AAEtB,UAAO;EACR;CACF;AACF"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
//#region src/utils/MyInvoisClient.ts
|
|
4
|
+
var MyInvoisClient = class {
|
|
5
|
+
baseUrl;
|
|
6
|
+
clientId;
|
|
7
|
+
clientSecret;
|
|
8
|
+
debug;
|
|
9
|
+
token = "";
|
|
10
|
+
tokenExpiration;
|
|
11
|
+
constructor(clientId, clientSecret, environment, debug = false) {
|
|
12
|
+
this.clientId = clientId;
|
|
13
|
+
this.clientSecret = clientSecret;
|
|
14
|
+
this.debug = debug;
|
|
15
|
+
if (environment === "sandbox") this.baseUrl = "https://preprod-api.myinvois.hasil.gov.my";
|
|
16
|
+
else this.baseUrl = "https://api.myinvois.hasil.gov.my";
|
|
17
|
+
}
|
|
18
|
+
async refreshToken() {
|
|
19
|
+
try {
|
|
20
|
+
const response = await fetch(`${this.baseUrl}/connect/token`, {
|
|
21
|
+
method: "POST",
|
|
22
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
23
|
+
body: new URLSearchParams({
|
|
24
|
+
grant_type: "client_credentials",
|
|
25
|
+
client_id: this.clientId,
|
|
26
|
+
client_secret: this.clientSecret,
|
|
27
|
+
scope: "InvoicingAPI"
|
|
28
|
+
})
|
|
29
|
+
});
|
|
30
|
+
const tokenResponse = await response.json();
|
|
31
|
+
this.token = tokenResponse.access_token;
|
|
32
|
+
this.tokenExpiration = new Date(Date.now() + tokenResponse.expires_in * 1e3);
|
|
33
|
+
} catch (error) {
|
|
34
|
+
if (this.debug) console.error(error);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async getToken() {
|
|
38
|
+
if (!this.tokenExpiration || this.tokenExpiration < new Date()) {
|
|
39
|
+
if (this.debug) console.log("Refreshing token");
|
|
40
|
+
await this.refreshToken();
|
|
41
|
+
}
|
|
42
|
+
return this.token;
|
|
43
|
+
}
|
|
44
|
+
async fetch(path, options = {}) {
|
|
45
|
+
const token = await this.getToken();
|
|
46
|
+
return fetch(`${this.baseUrl}${path}`, {
|
|
47
|
+
...options,
|
|
48
|
+
headers: {
|
|
49
|
+
...options.headers,
|
|
50
|
+
Authorization: `Bearer ${token}`
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Validates a TIN against a NRIC
|
|
56
|
+
*
|
|
57
|
+
* @param tin
|
|
58
|
+
* @param nric
|
|
59
|
+
* @returns
|
|
60
|
+
*/
|
|
61
|
+
async verifyTin(tin, nric) {
|
|
62
|
+
try {
|
|
63
|
+
const response = await this.fetch(`/api/v1.0/taxpayer/validate/${tin}?idType=NRIC&idValue=${nric}`, { method: "GET" });
|
|
64
|
+
if (response.status === 200) return true;
|
|
65
|
+
return false;
|
|
66
|
+
} catch (error) {
|
|
67
|
+
if (this.debug) console.error(error);
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
//#endregion
|
|
74
|
+
exports.MyInvoisClient = MyInvoisClient
|
|
75
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["clientId: string","clientSecret: string","environment: 'sandbox' | 'production'","debug: boolean","tokenResponse: TokenResponse","path: string","options: Parameters<typeof fetch>[1]","tin: string","nric: string"],"sources":["../src/utils/MyInvoisClient.ts"],"sourcesContent":["interface TokenResponse {\n access_token: string\n expires_in: number\n}\n\nexport class MyInvoisClient {\n private readonly baseUrl: string\n private readonly clientId: string\n private readonly clientSecret: string\n private readonly debug: boolean\n private token = ''\n private tokenExpiration: Date | undefined\n\n constructor(\n clientId: string,\n clientSecret: string,\n environment: 'sandbox' | 'production',\n debug: boolean = false,\n ) {\n this.clientId = clientId\n this.clientSecret = clientSecret\n this.debug = debug\n if (environment === 'sandbox') {\n this.baseUrl = 'https://preprod-api.myinvois.hasil.gov.my'\n } else {\n this.baseUrl = 'https://api.myinvois.hasil.gov.my'\n }\n }\n\n private async refreshToken() {\n try {\n const response = await fetch(`${this.baseUrl}/connect/token`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: this.clientId,\n client_secret: this.clientSecret,\n scope: 'InvoicingAPI',\n }),\n })\n\n const tokenResponse: TokenResponse = await response.json()\n\n this.token = tokenResponse.access_token\n this.tokenExpiration = new Date(\n Date.now() + tokenResponse.expires_in * 1000,\n )\n } catch (error) {\n if (this.debug) {\n console.error(error)\n }\n }\n }\n\n private async getToken() {\n if (!this.tokenExpiration || this.tokenExpiration < new Date()) {\n if (this.debug) {\n console.log('Refreshing token')\n }\n await this.refreshToken()\n }\n\n return this.token\n }\n\n private async fetch(path: string, options: Parameters<typeof fetch>[1] = {}) {\n const token = await this.getToken()\n\n return fetch(`${this.baseUrl}${path}`, {\n ...options,\n headers: { ...options.headers, Authorization: `Bearer ${token}` },\n })\n }\n\n /**\n * Validates a TIN against a NRIC\n *\n * @param tin\n * @param nric\n * @returns\n */\n async verifyTin(tin: string, nric: string) {\n try {\n const response = await this.fetch(\n `/api/v1.0/taxpayer/validate/${tin}?idType=NRIC&idValue=${nric}`,\n {\n method: 'GET',\n },\n )\n\n if (response.status === 200) {\n return true\n }\n\n return false\n } catch (error) {\n if (this.debug) {\n console.error(error)\n }\n return false\n }\n }\n}\n"],"mappings":";;;IAKa,iBAAN,MAAqB;CAC1B,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAQ,QAAQ;CAChB,AAAQ;CAER,YACEA,UACAC,cACAC,aACAC,QAAiB,OACjB;AACA,OAAK,WAAW;AAChB,OAAK,eAAe;AACpB,OAAK,QAAQ;AACb,MAAI,gBAAgB,UAClB,MAAK,UAAU;MAEf,MAAK,UAAU;CAElB;CAED,MAAc,eAAe;AAC3B,MAAI;GACF,MAAM,WAAW,MAAM,OAAO,EAAE,KAAK,QAAQ,iBAAiB;IAC5D,QAAQ;IACR,SAAS,EACP,gBAAgB,oCACjB;IACD,MAAM,IAAI,gBAAgB;KACxB,YAAY;KACZ,WAAW,KAAK;KAChB,eAAe,KAAK;KACpB,OAAO;IACR;GACF,EAAC;GAEF,MAAMC,gBAA+B,MAAM,SAAS,MAAM;AAE1D,QAAK,QAAQ,cAAc;AAC3B,QAAK,kBAAkB,IAAI,KACzB,KAAK,KAAK,GAAG,cAAc,aAAa;EAE3C,SAAQ,OAAO;AACd,OAAI,KAAK,MACP,SAAQ,MAAM,MAAM;EAEvB;CACF;CAED,MAAc,WAAW;AACvB,OAAK,KAAK,mBAAmB,KAAK,kBAAkB,IAAI,QAAQ;AAC9D,OAAI,KAAK,MACP,SAAQ,IAAI,mBAAmB;AAEjC,SAAM,KAAK,cAAc;EAC1B;AAED,SAAO,KAAK;CACb;CAED,MAAc,MAAMC,MAAcC,UAAuC,CAAE,GAAE;EAC3E,MAAM,QAAQ,MAAM,KAAK,UAAU;AAEnC,SAAO,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,GAAG;GACrC,GAAG;GACH,SAAS;IAAE,GAAG,QAAQ;IAAS,gBAAgB,SAAS,MAAM;GAAG;EAClE,EAAC;CACH;;;;;;;;CASD,MAAM,UAAUC,KAAaC,MAAc;AACzC,MAAI;GACF,MAAM,WAAW,MAAM,KAAK,OACzB,8BAA8B,IAAI,uBAAuB,KAAK,GAC/D,EACE,QAAQ,MACT,EACF;AAED,OAAI,SAAS,WAAW,IACtB,QAAO;AAGT,UAAO;EACR,SAAQ,OAAO;AACd,OAAI,KAAK,MACP,SAAQ,MAAM,MAAM;AAEtB,UAAO;EACR;CACF;AACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3790,9 +3790,10 @@ declare class MyInvoisClient {
|
|
|
3790
3790
|
private readonly baseUrl;
|
|
3791
3791
|
private readonly clientId;
|
|
3792
3792
|
private readonly clientSecret;
|
|
3793
|
+
private readonly debug;
|
|
3793
3794
|
private token;
|
|
3794
3795
|
private tokenExpiration;
|
|
3795
|
-
constructor(clientId: string, clientSecret: string, environment: 'sandbox' | 'production');
|
|
3796
|
+
constructor(clientId: string, clientSecret: string, environment: 'sandbox' | 'production', debug?: boolean);
|
|
3796
3797
|
private refreshToken;
|
|
3797
3798
|
private getToken;
|
|
3798
3799
|
private fetch;
|
package/dist/index.js
CHANGED
|
@@ -4,11 +4,13 @@ var MyInvoisClient = class {
|
|
|
4
4
|
baseUrl;
|
|
5
5
|
clientId;
|
|
6
6
|
clientSecret;
|
|
7
|
+
debug;
|
|
7
8
|
token = "";
|
|
8
9
|
tokenExpiration;
|
|
9
|
-
constructor(clientId, clientSecret, environment) {
|
|
10
|
+
constructor(clientId, clientSecret, environment, debug = false) {
|
|
10
11
|
this.clientId = clientId;
|
|
11
12
|
this.clientSecret = clientSecret;
|
|
13
|
+
this.debug = debug;
|
|
12
14
|
if (environment === "sandbox") this.baseUrl = "https://preprod-api.myinvois.hasil.gov.my";
|
|
13
15
|
else this.baseUrl = "https://api.myinvois.hasil.gov.my";
|
|
14
16
|
}
|
|
@@ -28,11 +30,14 @@ var MyInvoisClient = class {
|
|
|
28
30
|
this.token = tokenResponse.access_token;
|
|
29
31
|
this.tokenExpiration = new Date(Date.now() + tokenResponse.expires_in * 1e3);
|
|
30
32
|
} catch (error) {
|
|
31
|
-
console.error(error);
|
|
33
|
+
if (this.debug) console.error(error);
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
36
|
async getToken() {
|
|
35
|
-
if (!this.tokenExpiration || this.tokenExpiration < new Date())
|
|
37
|
+
if (!this.tokenExpiration || this.tokenExpiration < new Date()) {
|
|
38
|
+
if (this.debug) console.log("Refreshing token");
|
|
39
|
+
await this.refreshToken();
|
|
40
|
+
}
|
|
36
41
|
return this.token;
|
|
37
42
|
}
|
|
38
43
|
async fetch(path, options = {}) {
|
|
@@ -58,7 +63,7 @@ var MyInvoisClient = class {
|
|
|
58
63
|
if (response.status === 200) return true;
|
|
59
64
|
return false;
|
|
60
65
|
} catch (error) {
|
|
61
|
-
console.error(error);
|
|
66
|
+
if (this.debug) console.error(error);
|
|
62
67
|
return false;
|
|
63
68
|
}
|
|
64
69
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ripwords/myinvois-client",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "src/index.ts",
|
|
6
6
|
"devDependencies": {
|
|
@@ -12,6 +12,10 @@
|
|
|
12
12
|
"rolldown-plugin-dts": "^0.7.0",
|
|
13
13
|
"vitest": "^3.1.1"
|
|
14
14
|
},
|
|
15
|
+
"exports": {
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"require": "./dist/index.cjs"
|
|
18
|
+
},
|
|
15
19
|
"peerDependencies": {
|
|
16
20
|
"typescript": "^5"
|
|
17
21
|
},
|
package/rolldown.config.ts
CHANGED
|
@@ -7,6 +7,7 @@ export class MyInvoisClient {
|
|
|
7
7
|
private readonly baseUrl: string
|
|
8
8
|
private readonly clientId: string
|
|
9
9
|
private readonly clientSecret: string
|
|
10
|
+
private readonly debug: boolean
|
|
10
11
|
private token = ''
|
|
11
12
|
private tokenExpiration: Date | undefined
|
|
12
13
|
|
|
@@ -14,10 +15,11 @@ export class MyInvoisClient {
|
|
|
14
15
|
clientId: string,
|
|
15
16
|
clientSecret: string,
|
|
16
17
|
environment: 'sandbox' | 'production',
|
|
18
|
+
debug: boolean = false,
|
|
17
19
|
) {
|
|
18
20
|
this.clientId = clientId
|
|
19
21
|
this.clientSecret = clientSecret
|
|
20
|
-
|
|
22
|
+
this.debug = debug
|
|
21
23
|
if (environment === 'sandbox') {
|
|
22
24
|
this.baseUrl = 'https://preprod-api.myinvois.hasil.gov.my'
|
|
23
25
|
} else {
|
|
@@ -47,12 +49,17 @@ export class MyInvoisClient {
|
|
|
47
49
|
Date.now() + tokenResponse.expires_in * 1000,
|
|
48
50
|
)
|
|
49
51
|
} catch (error) {
|
|
50
|
-
|
|
52
|
+
if (this.debug) {
|
|
53
|
+
console.error(error)
|
|
54
|
+
}
|
|
51
55
|
}
|
|
52
56
|
}
|
|
53
57
|
|
|
54
58
|
private async getToken() {
|
|
55
59
|
if (!this.tokenExpiration || this.tokenExpiration < new Date()) {
|
|
60
|
+
if (this.debug) {
|
|
61
|
+
console.log('Refreshing token')
|
|
62
|
+
}
|
|
56
63
|
await this.refreshToken()
|
|
57
64
|
}
|
|
58
65
|
|
|
@@ -90,7 +97,9 @@ export class MyInvoisClient {
|
|
|
90
97
|
|
|
91
98
|
return false
|
|
92
99
|
} catch (error) {
|
|
93
|
-
|
|
100
|
+
if (this.debug) {
|
|
101
|
+
console.error(error)
|
|
102
|
+
}
|
|
94
103
|
return false
|
|
95
104
|
}
|
|
96
105
|
}
|
|
@@ -12,15 +12,16 @@ describe('MyInvoisClient', () => {
|
|
|
12
12
|
|
|
13
13
|
beforeEach(() => {
|
|
14
14
|
vi.clearAllMocks()
|
|
15
|
-
client = new MyInvoisClient('test-id', 'test-secret', 'sandbox')
|
|
15
|
+
client = new MyInvoisClient('test-id', 'test-secret', 'sandbox', false)
|
|
16
16
|
})
|
|
17
17
|
|
|
18
18
|
describe('constructor', () => {
|
|
19
19
|
it('should set sandbox URL when environment is sandbox', () => {
|
|
20
20
|
const sandboxClient = new MyInvoisClient(
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
'test-id',
|
|
22
|
+
'test-secret',
|
|
23
23
|
'sandbox',
|
|
24
|
+
true,
|
|
24
25
|
)
|
|
25
26
|
expect((sandboxClient as any).baseUrl).toBe(
|
|
26
27
|
'https://preprod-api.myinvois.hasil.gov.my',
|
|
@@ -29,9 +30,10 @@ describe('MyInvoisClient', () => {
|
|
|
29
30
|
|
|
30
31
|
it('should set production URL when environment is production', () => {
|
|
31
32
|
const prodClient = new MyInvoisClient(
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
'test-id',
|
|
34
|
+
'test-secret',
|
|
34
35
|
'production',
|
|
36
|
+
true,
|
|
35
37
|
)
|
|
36
38
|
expect((prodClient as any).baseUrl).toBe(
|
|
37
39
|
'https://api.myinvois.hasil.gov.my',
|
|
@@ -64,7 +66,7 @@ describe('MyInvoisClient', () => {
|
|
|
64
66
|
access_token: 'test-token',
|
|
65
67
|
expires_in: 3600,
|
|
66
68
|
}
|
|
67
|
-
|
|
69
|
+
|
|
68
70
|
mockFetch
|
|
69
71
|
.mockResolvedValueOnce({
|
|
70
72
|
ok: true,
|
|
@@ -153,6 +155,8 @@ describe('MyInvoisClient', () => {
|
|
|
153
155
|
} as Response)
|
|
154
156
|
|
|
155
157
|
await client.verifyTin('123', '456')
|
|
158
|
+
vi.setSystemTime(new Date(Date.now() + 1000 * 8000))
|
|
159
|
+
await client.verifyTin('123', '456')
|
|
156
160
|
|
|
157
161
|
expect(mockFetch).toHaveBeenCalledWith(
|
|
158
162
|
`https://preprod-api.myinvois.hasil.gov.my/api/v1.0/taxpayer/validate/123?idType=NRIC&idValue=456`,
|