@ripwords/myinvois-client 0.1.2 → 0.1.4

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.
Files changed (343) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/package.json +4 -5
  3. package/src/index.ts +2 -1
  4. package/src/types/documents.d.ts +17 -10
  5. package/src/utils/document.ts +2 -2
  6. package/test/dynamicInvoiceFeatures.test.ts +2 -0
  7. package/test/signAndSubmitInvoice.test.ts +2 -0
  8. package/test/signature-diagnostics.test.ts +2 -0
  9. package/bun.lock +0 -460
  10. package/dist/0X-CG1S1WKn.d.ts +0 -210
  11. package/dist/0X-ChfmeAYF.d.cts +0 -211
  12. package/dist/1X-CmlbG02M.d.ts +0 -111
  13. package/dist/1X-DFikQbP0.d.cts +0 -20
  14. package/dist/1X-DbFshzup.d.ts +0 -19
  15. package/dist/1X-jFrFCOs0.d.cts +0 -112
  16. package/dist/2X-5cE4ojEX.d.cts +0 -140
  17. package/dist/2X-DA6J6Wd7.d.ts +0 -139
  18. package/dist/2X-FWZ1rYVt.d.cts +0 -40
  19. package/dist/2X-eC_p0QJf.d.ts +0 -39
  20. package/dist/3X-D9duw0Ro.d.cts +0 -21
  21. package/dist/3X-DbfkwdkO.d.ts +0 -20
  22. package/dist/3X-GxuN79Ax.d.ts +0 -61
  23. package/dist/3X-r9xbWJ2l.d.cts +0 -62
  24. package/dist/4X-1ZkK-uH5.d.cts +0 -31
  25. package/dist/4X-CLO9OuKa.d.cts +0 -265
  26. package/dist/4X-CnHtgO6u.d.ts +0 -30
  27. package/dist/4X-DYz_nYSD.d.ts +0 -264
  28. package/dist/5X-BzPEdkbC.d.ts +0 -21
  29. package/dist/5X-BziH0a09.d.cts +0 -77
  30. package/dist/5X-Cfe39fFc.d.cts +0 -22
  31. package/dist/5X-kBF74qx1.d.ts +0 -76
  32. package/dist/6X-BceErbps.d.cts +0 -105
  33. package/dist/6X-C_xpeu6J.d.ts +0 -15
  34. package/dist/6X-DLWEe1bP.d.cts +0 -16
  35. package/dist/6X-sQZfT0ZK.d.ts +0 -104
  36. package/dist/7X-Bet2agJ6.d.ts +0 -15
  37. package/dist/7X-BoKQxMoO.d.ts +0 -70
  38. package/dist/7X-CucHYQsA.d.cts +0 -16
  39. package/dist/7X-CwPAqozm.d.cts +0 -71
  40. package/dist/8X-BIjJ9kaV.d.cts +0 -110
  41. package/dist/8X-BOEWATU3.d.ts +0 -109
  42. package/dist/8X-CJpqd5xp.d.cts +0 -19
  43. package/dist/8X-s5AzkHR-.d.ts +0 -18
  44. package/dist/9X-BBDP1gZ6.d.ts +0 -14
  45. package/dist/9X-CP5Xp6bE.d.cts +0 -98
  46. package/dist/9X-D3aOVCnz.d.cts +0 -15
  47. package/dist/9X-DAAZV4sr.d.ts +0 -97
  48. package/dist/AX-CmpMMhII.d.ts +0 -110
  49. package/dist/AX-DFzpxGOT.d.cts +0 -111
  50. package/dist/BX-CyiqNE6b.d.cts +0 -115
  51. package/dist/BX-j78z_ju_.d.ts +0 -114
  52. package/dist/CX-B6rEhQx7.d.ts +0 -127
  53. package/dist/CX-BTPvC3Dv.d.cts +0 -128
  54. package/dist/DX-BD4-hTCh.d.cts +0 -115
  55. package/dist/DX-CAmMnx5a.d.ts +0 -114
  56. package/dist/EX-CXhSC85J.d.ts +0 -106
  57. package/dist/EX-mTHCH0Yk.d.cts +0 -107
  58. package/dist/FX-DOOMoQl2.d.cts +0 -127
  59. package/dist/FX-DYVIJ3l0.d.ts +0 -126
  60. package/dist/GX-8URJ7WHz.d.cts +0 -136
  61. package/dist/GX-eBOVHqi6.d.ts +0 -135
  62. package/dist/HX-49z8CzsE.d.cts +0 -126
  63. package/dist/HX-Dz5T0xXI.d.ts +0 -125
  64. package/dist/IX-B6kblmBs.d.cts +0 -23
  65. package/dist/IX-PiKYro5a.d.ts +0 -22
  66. package/dist/JX-DMwHLGEE.d.cts +0 -104
  67. package/dist/JX-Dvnt0mSK.d.ts +0 -103
  68. package/dist/KX-BUb8e0yg.d.ts +0 -150
  69. package/dist/KX-DaJPkefl.d.cts +0 -151
  70. package/dist/LX-BnILxjdS.d.cts +0 -123
  71. package/dist/LX-l5ZBaGov.d.ts +0 -122
  72. package/dist/MX-BbPO8mTj.d.cts +0 -153
  73. package/dist/MX-C7C15AWi.d.ts +0 -152
  74. package/dist/NX-C7nFVC-D.d.ts +0 -121
  75. package/dist/NX-xy5uw7H3.d.cts +0 -122
  76. package/dist/OX-CIzARbON.d.cts +0 -26
  77. package/dist/OX-Dmkvcaij.d.ts +0 -25
  78. package/dist/PX-BKZ14N7N.d.ts +0 -120
  79. package/dist/PX-CL8waFgx.d.cts +0 -121
  80. package/dist/QX-6xdSNtxZ.d.ts +0 -58
  81. package/dist/QX-BowAYqZb.d.cts +0 -59
  82. package/dist/RX-DFoiOK5q.d.ts +0 -22
  83. package/dist/RX-fWoWcHTG.d.cts +0 -23
  84. package/dist/SX-CZ3e31OT.d.cts +0 -40
  85. package/dist/SX-D-Szi9wa.d.ts +0 -39
  86. package/dist/TX-CJhJ-HYX.d.cts +0 -31
  87. package/dist/TX-DTfkGsqn.d.ts +0 -30
  88. package/dist/UX-Bw4HHAj4.d.ts +0 -17
  89. package/dist/UX-P7-u2y70.d.cts +0 -18
  90. package/dist/VX-C8Eu5gQf.d.cts +0 -17
  91. package/dist/VX-DCv5x_hi.d.ts +0 -16
  92. package/dist/WX-BYtJ5_if.d.ts +0 -25
  93. package/dist/WX-DkiaqB2V.d.cts +0 -26
  94. package/dist/XX-D4p4iK-a.d.cts +0 -828
  95. package/dist/XX-Jo1yJO3A.d.ts +0 -827
  96. package/dist/YX-BvGmEsVG.d.ts +0 -19
  97. package/dist/YX-Du8zv9qz.d.cts +0 -20
  98. package/dist/ZX-B4jFD-21.d.cts +0 -22
  99. package/dist/ZX-B59AJcBY.d.ts +0 -21
  100. package/dist/api/platform/platformLogin.d.ts +0 -65
  101. package/dist/api/platform/platformLogin.js +0 -3
  102. package/dist/certificate-DFK-788s.cjs +0 -62
  103. package/dist/certificate-DFK-788s.cjs.map +0 -1
  104. package/dist/certificate-aooIRf9A.js +0 -49
  105. package/dist/chunk-CUT6urMc.cjs +0 -30
  106. package/dist/classification-codes-B15PbWxz.d.cts +0 -118
  107. package/dist/classification-codes-BKxV-rO9.d.ts +0 -117
  108. package/dist/country-code-CQuaiQm2.d.ts +0 -542
  109. package/dist/country-code-DPeNFMMi.d.cts +0 -543
  110. package/dist/currencies-BYJK-m6v.d.ts +0 -207
  111. package/dist/currencies-S5g1gzBU.d.cts +0 -208
  112. package/dist/document-DMIMRJV0.cjs +0 -472
  113. package/dist/document-DMIMRJV0.cjs.map +0 -1
  114. package/dist/document-NQos5fSr.js +0 -405
  115. package/dist/documents-BVG7KIKY.d.ts +0 -847
  116. package/dist/documents-C066EC9m.d.cts +0 -848
  117. package/dist/e-invoice-BuwtFnlI.d.cts +0 -44
  118. package/dist/e-invoice-CmbLQkHw.d.ts +0 -43
  119. package/dist/getBaseUrl-CO7Jp27d.cjs +0 -14
  120. package/dist/getBaseUrl-CO7Jp27d.cjs.map +0 -1
  121. package/dist/getBaseUrl-R3IdgCu3.js +0 -7
  122. package/dist/index-0-EvC6Nv.d.ts +0 -15
  123. package/dist/index-D2_HVwCz.d.cts +0 -16
  124. package/dist/index.cjs +0 -309
  125. package/dist/index.cjs.map +0 -1
  126. package/dist/index.d.ts +0 -233
  127. package/dist/index.js +0 -308
  128. package/dist/index10.cjs +0 -0
  129. package/dist/index11.cjs +0 -34
  130. package/dist/index11.cjs.map +0 -1
  131. package/dist/index12.cjs +0 -24
  132. package/dist/index12.cjs.map +0 -1
  133. package/dist/index13.cjs +0 -0
  134. package/dist/index14.cjs +0 -13
  135. package/dist/index14.cjs.map +0 -1
  136. package/dist/index15.cjs +0 -4
  137. package/dist/index16.cjs +0 -13
  138. package/dist/index17.cjs +0 -3
  139. package/dist/index18.cjs +0 -340
  140. package/dist/index18.cjs.map +0 -1
  141. package/dist/index19.cjs +0 -329
  142. package/dist/index19.cjs.map +0 -1
  143. package/dist/index2.cjs +0 -62
  144. package/dist/index2.cjs.map +0 -1
  145. package/dist/index20.cjs +0 -140
  146. package/dist/index20.cjs.map +0 -1
  147. package/dist/index21.cjs +0 -3
  148. package/dist/index22.cjs +0 -208
  149. package/dist/index22.cjs.map +0 -1
  150. package/dist/index23.cjs +0 -109
  151. package/dist/index23.cjs.map +0 -1
  152. package/dist/index24.cjs +0 -137
  153. package/dist/index24.cjs.map +0 -1
  154. package/dist/index25.cjs +0 -64
  155. package/dist/index25.cjs.map +0 -1
  156. package/dist/index26.cjs +0 -267
  157. package/dist/index26.cjs.map +0 -1
  158. package/dist/index27.cjs +0 -79
  159. package/dist/index27.cjs.map +0 -1
  160. package/dist/index28.cjs +0 -107
  161. package/dist/index28.cjs.map +0 -1
  162. package/dist/index29.cjs +0 -73
  163. package/dist/index29.cjs.map +0 -1
  164. package/dist/index3.cjs +0 -532
  165. package/dist/index3.cjs.map +0 -1
  166. package/dist/index30.cjs +0 -112
  167. package/dist/index30.cjs.map +0 -1
  168. package/dist/index31.cjs +0 -100
  169. package/dist/index31.cjs.map +0 -1
  170. package/dist/index32.cjs +0 -18
  171. package/dist/index32.cjs.map +0 -1
  172. package/dist/index33.cjs +0 -38
  173. package/dist/index33.cjs.map +0 -1
  174. package/dist/index34.cjs +0 -19
  175. package/dist/index34.cjs.map +0 -1
  176. package/dist/index35.cjs +0 -29
  177. package/dist/index35.cjs.map +0 -1
  178. package/dist/index36.cjs +0 -20
  179. package/dist/index36.cjs.map +0 -1
  180. package/dist/index37.cjs +0 -14
  181. package/dist/index37.cjs.map +0 -1
  182. package/dist/index38.cjs +0 -14
  183. package/dist/index38.cjs.map +0 -1
  184. package/dist/index39.cjs +0 -17
  185. package/dist/index39.cjs.map +0 -1
  186. package/dist/index4.cjs +0 -196
  187. package/dist/index4.cjs.map +0 -1
  188. package/dist/index40.cjs +0 -13
  189. package/dist/index40.cjs.map +0 -1
  190. package/dist/index41.cjs +0 -108
  191. package/dist/index41.cjs.map +0 -1
  192. package/dist/index42.cjs +0 -113
  193. package/dist/index42.cjs.map +0 -1
  194. package/dist/index43.cjs +0 -126
  195. package/dist/index43.cjs.map +0 -1
  196. package/dist/index44.cjs +0 -113
  197. package/dist/index44.cjs.map +0 -1
  198. package/dist/index45.cjs +0 -105
  199. package/dist/index45.cjs.map +0 -1
  200. package/dist/index46.cjs +0 -125
  201. package/dist/index46.cjs.map +0 -1
  202. package/dist/index47.cjs +0 -134
  203. package/dist/index47.cjs.map +0 -1
  204. package/dist/index48.cjs +0 -124
  205. package/dist/index48.cjs.map +0 -1
  206. package/dist/index49.cjs +0 -21
  207. package/dist/index49.cjs.map +0 -1
  208. package/dist/index5.cjs +0 -0
  209. package/dist/index50.cjs +0 -102
  210. package/dist/index50.cjs.map +0 -1
  211. package/dist/index51.cjs +0 -149
  212. package/dist/index51.cjs.map +0 -1
  213. package/dist/index52.cjs +0 -121
  214. package/dist/index52.cjs.map +0 -1
  215. package/dist/index53.cjs +0 -151
  216. package/dist/index53.cjs.map +0 -1
  217. package/dist/index54.cjs +0 -120
  218. package/dist/index54.cjs.map +0 -1
  219. package/dist/index55.cjs +0 -24
  220. package/dist/index55.cjs.map +0 -1
  221. package/dist/index56.cjs +0 -119
  222. package/dist/index56.cjs.map +0 -1
  223. package/dist/index57.cjs +0 -54
  224. package/dist/index57.cjs.map +0 -1
  225. package/dist/index58.cjs +0 -21
  226. package/dist/index58.cjs.map +0 -1
  227. package/dist/index58.cts.map +0 -1
  228. package/dist/index59.cjs +0 -35
  229. package/dist/index59.cjs.map +0 -1
  230. package/dist/index59.cts.map +0 -1
  231. package/dist/index6.cjs +0 -25
  232. package/dist/index6.cjs.map +0 -1
  233. package/dist/index60.cjs +0 -29
  234. package/dist/index60.cjs.map +0 -1
  235. package/dist/index60.cts.map +0 -1
  236. package/dist/index61.cjs +0 -16
  237. package/dist/index61.cjs.map +0 -1
  238. package/dist/index61.cts.map +0 -1
  239. package/dist/index62.cjs +0 -15
  240. package/dist/index62.cjs.map +0 -1
  241. package/dist/index62.cts.map +0 -1
  242. package/dist/index63.cjs +0 -24
  243. package/dist/index63.cjs.map +0 -1
  244. package/dist/index63.cts.map +0 -1
  245. package/dist/index64.cjs +0 -419
  246. package/dist/index64.cjs.map +0 -1
  247. package/dist/index64.cts.map +0 -1
  248. package/dist/index65.cjs +0 -15
  249. package/dist/index65.cjs.map +0 -1
  250. package/dist/index65.cts.map +0 -1
  251. package/dist/index66.cjs +0 -16
  252. package/dist/index66.cjs.map +0 -1
  253. package/dist/index66.cts.map +0 -1
  254. package/dist/index7.cjs +0 -0
  255. package/dist/index8.cjs +0 -0
  256. package/dist/index9.cjs +0 -25
  257. package/dist/index9.cjs.map +0 -1
  258. package/dist/msic-codes-CPWVNnpq.d.cts +0 -26
  259. package/dist/msic-codes-DToUqTI6.d.ts +0 -25
  260. package/dist/payment-modes-DA7uBIGb.d.ts +0 -43
  261. package/dist/payment-modes-FX88uyhP.d.cts +0 -44
  262. package/dist/platformLogin-PGzMhw1X.cjs +0 -37
  263. package/dist/platformLogin-PGzMhw1X.cjs.map +0 -1
  264. package/dist/platformLogin-f0bNAoZI.js +0 -30
  265. package/dist/signatures-BKi9DP2K.d.cts +0 -173
  266. package/dist/signatures-CG175mpg.d.ts +0 -172
  267. package/dist/state-codes-CNp_6051.d.cts +0 -62
  268. package/dist/state-codes-dvoTe5pC.d.ts +0 -61
  269. package/dist/tax-types-CgwxONDS.d.cts +0 -42
  270. package/dist/tax-types-tosH5I0q.d.ts +0 -41
  271. package/dist/types/classification-codes.d.ts +0 -2
  272. package/dist/types/country-code.d.ts +0 -2
  273. package/dist/types/currencies.d.ts +0 -2
  274. package/dist/types/documents.d.ts +0 -7
  275. package/dist/types/e-invoice.d.ts +0 -2
  276. package/dist/types/index.d.ts +0 -58
  277. package/dist/types/msic/0X.d.ts +0 -2
  278. package/dist/types/msic/1X.d.ts +0 -2
  279. package/dist/types/msic/2X.d.ts +0 -2
  280. package/dist/types/msic/3X.d.ts +0 -2
  281. package/dist/types/msic/4X.d.ts +0 -2
  282. package/dist/types/msic/5X.d.ts +0 -2
  283. package/dist/types/msic/6X.d.ts +0 -2
  284. package/dist/types/msic/7X.d.ts +0 -2
  285. package/dist/types/msic/8X.d.ts +0 -2
  286. package/dist/types/msic/9X.d.ts +0 -2
  287. package/dist/types/msic-codes.d.ts +0 -12
  288. package/dist/types/payment-modes.d.ts +0 -2
  289. package/dist/types/signatures.d.ts +0 -2
  290. package/dist/types/state-codes.d.ts +0 -2
  291. package/dist/types/tax-types.d.ts +0 -2
  292. package/dist/types/unit/1X.d.ts +0 -2
  293. package/dist/types/unit/2X.d.ts +0 -2
  294. package/dist/types/unit/3X.d.ts +0 -2
  295. package/dist/types/unit/4X.d.ts +0 -2
  296. package/dist/types/unit/5X.d.ts +0 -2
  297. package/dist/types/unit/6X.d.ts +0 -2
  298. package/dist/types/unit/7X.d.ts +0 -2
  299. package/dist/types/unit/8X.d.ts +0 -2
  300. package/dist/types/unit/9X.d.ts +0 -2
  301. package/dist/types/unit/AX.d.ts +0 -2
  302. package/dist/types/unit/BX.d.ts +0 -2
  303. package/dist/types/unit/CX.d.ts +0 -2
  304. package/dist/types/unit/DX.d.ts +0 -2
  305. package/dist/types/unit/EX.d.ts +0 -2
  306. package/dist/types/unit/FX.d.ts +0 -2
  307. package/dist/types/unit/GX.d.ts +0 -2
  308. package/dist/types/unit/HX.d.ts +0 -2
  309. package/dist/types/unit/IX.d.ts +0 -2
  310. package/dist/types/unit/JX.d.ts +0 -2
  311. package/dist/types/unit/KX.d.ts +0 -2
  312. package/dist/types/unit/LX.d.ts +0 -2
  313. package/dist/types/unit/MX.d.ts +0 -2
  314. package/dist/types/unit/NX.d.ts +0 -2
  315. package/dist/types/unit/OX.d.ts +0 -2
  316. package/dist/types/unit/PX.d.ts +0 -2
  317. package/dist/types/unit/QX.d.ts +0 -2
  318. package/dist/types/unit/RX.d.ts +0 -2
  319. package/dist/types/unit/SX.d.ts +0 -2
  320. package/dist/types/unit/TX.d.ts +0 -2
  321. package/dist/types/unit/UX.d.ts +0 -2
  322. package/dist/types/unit/VX.d.ts +0 -2
  323. package/dist/types/unit/WX.d.ts +0 -2
  324. package/dist/types/unit/XX.d.ts +0 -2
  325. package/dist/types/unit/YX.d.ts +0 -2
  326. package/dist/types/unit/ZX.d.ts +0 -2
  327. package/dist/types/unit-types.d.ts +0 -37
  328. package/dist/unit-types-BKZxwVYQ.d.ts +0 -55
  329. package/dist/unit-types-CaOA5ZDG.d.cts +0 -56
  330. package/dist/utils/base64.d.ts +0 -5
  331. package/dist/utils/base64.js +0 -10
  332. package/dist/utils/certificate.d.ts +0 -22
  333. package/dist/utils/certificate.js +0 -3
  334. package/dist/utils/document.d.ts +0 -135
  335. package/dist/utils/document.js +0 -3
  336. package/dist/utils/getBaseUrl.d.ts +0 -4
  337. package/dist/utils/getBaseUrl.js +0 -3
  338. package/dist/utils/helpers.d.ts +0 -271
  339. package/dist/utils/helpers.js +0 -330
  340. package/dist/utils/signature-diagnostics.d.ts +0 -93
  341. package/dist/utils/signature-diagnostics.js +0 -326
  342. package/dist/utils/validation.d.ts +0 -46
  343. package/dist/utils/validation.js +0 -134
@@ -1,405 +0,0 @@
1
- import crypto, { X509Certificate } from "crypto";
2
-
3
- //#region src/utils/document.ts
4
- /**
5
- * MyInvois v1.1 Document Generation and Signing Utilities
6
- * Strictly follows: https://sdk.myinvois.hasil.gov.my/documents/invoice-v1-1
7
- * JSON Signature Guide: https://sdk.myinvois.hasil.gov.my/signature-creation-json/
8
- */
9
- /**
10
- * Helper function to recursively sort object keys for JSON canonicalization
11
- */
12
- function sortObjectKeys(obj) {
13
- if (obj === null || typeof obj !== "object") return obj;
14
- if (Array.isArray(obj)) return obj.map(sortObjectKeys);
15
- const sortedObj = {};
16
- const keys = Object.keys(obj).sort();
17
- for (const key of keys) sortedObj[key] = sortObjectKeys(obj[key]);
18
- return sortedObj;
19
- }
20
- /**
21
- * Enhanced canonicalization following MyInvois specification exactly
22
- * Key changes: ensure consistent ordering and formatting
23
- */
24
- const canonicalizeJSON = (obj) => {
25
- const sortedObj = sortObjectKeys(obj);
26
- return JSON.stringify(sortedObj, null, 0);
27
- };
28
- /**
29
- * Generates a clean invoice object following MyInvois v1.1 specification exactly
30
- * This is the base invoice structure WITHOUT signature elements (for hash calculation)
31
- *
32
- * Key requirements from working documents:
33
- * - All mandatory fields must be present
34
- * - Many optional fields must be present even if empty
35
- * - Specific field ordering and structure
36
- * - Correct listID values (e.g., "3166-1" not "ISO3166-1")
37
- */
38
- const generateCleanInvoiceObject = (invoice) => {
39
- return {
40
- ID: [{ _: invoice.eInvoiceCodeOrNumber }],
41
- IssueDate: [{ _: invoice.eInvoiceDate }],
42
- IssueTime: [{ _: invoice.eInvoiceTime }],
43
- InvoiceTypeCode: [{
44
- _: invoice.eInvoiceTypeCode,
45
- listVersionID: invoice.eInvoiceVersion || "1.1"
46
- }],
47
- DocumentCurrencyCode: [{ _: invoice.invoiceCurrencyCode }],
48
- AccountingSupplierParty: [{ Party: [{
49
- IndustryClassificationCode: [{
50
- _: "47900",
51
- name: "Other retail sale in non-specialised stores"
52
- }],
53
- PartyIdentification: [{ ID: [{
54
- _: invoice.supplier.tin,
55
- schemeID: "TIN"
56
- }] }, { ID: [{
57
- _: invoice.supplier.registrationNumber,
58
- schemeID: invoice.supplier.registrationType || "NRIC"
59
- }] }],
60
- PostalAddress: [{
61
- CityName: [{ _: invoice.supplier.address.cityName }],
62
- CountrySubentityCode: [{ _: invoice.supplier.address.state }],
63
- AddressLine: [{ Line: [{ _: invoice.supplier.address.addressLine0 }] }],
64
- Country: [{ IdentificationCode: [{
65
- _: invoice.supplier.address.country || "MYS",
66
- listID: "3166-1",
67
- listAgencyID: "ISO"
68
- }] }]
69
- }],
70
- PartyLegalEntity: [{ RegistrationName: [{ _: invoice.supplier.name }] }],
71
- Contact: [{ Telephone: [{ _: invoice.supplier.contactNumber || "" }] }]
72
- }] }],
73
- AccountingCustomerParty: [{ Party: [{
74
- PartyIdentification: [
75
- { ID: [{
76
- _: invoice.buyer.tin,
77
- schemeID: "TIN"
78
- }] },
79
- { ID: [{
80
- _: invoice.buyer.registrationNumber,
81
- schemeID: invoice.buyer.registrationType || "NRIC"
82
- }] },
83
- { ID: [{
84
- _: invoice.buyer.sstRegistrationNumber || "NA",
85
- schemeID: "SST"
86
- }] }
87
- ],
88
- PostalAddress: [{
89
- CityName: [{ _: invoice.buyer.address.cityName }],
90
- CountrySubentityCode: [{ _: invoice.buyer.address.state }],
91
- AddressLine: [{ Line: [{ _: invoice.buyer.address.addressLine0 }] }],
92
- Country: [{ IdentificationCode: [{
93
- _: invoice.buyer.address.country || "MYS",
94
- listID: "3166-1",
95
- listAgencyID: "ISO"
96
- }] }]
97
- }],
98
- PartyLegalEntity: [{ RegistrationName: [{ _: invoice.buyer.name }] }],
99
- Contact: [{ Telephone: [{ _: invoice.buyer.contactNumber || "" }] }]
100
- }] }],
101
- TaxTotal: [{
102
- TaxAmount: [{
103
- _: invoice.taxTotal.taxAmount,
104
- currencyID: invoice.invoiceCurrencyCode
105
- }],
106
- TaxSubtotal: [{
107
- TaxableAmount: [{
108
- _: invoice.legalMonetaryTotal.taxExclusiveAmount,
109
- currencyID: invoice.invoiceCurrencyCode
110
- }],
111
- TaxAmount: [{
112
- _: invoice.taxTotal.taxAmount,
113
- currencyID: invoice.invoiceCurrencyCode
114
- }],
115
- TaxCategory: [{
116
- ID: [{ _: invoice.invoiceLineItems[0]?.taxType || "01" }],
117
- TaxScheme: [{ ID: [{
118
- _: "OTH",
119
- schemeAgencyID: "6",
120
- schemeID: "UN/ECE 5153"
121
- }] }]
122
- }]
123
- }]
124
- }],
125
- LegalMonetaryTotal: [{
126
- LineExtensionAmount: [{
127
- _: invoice.legalMonetaryTotal.taxExclusiveAmount,
128
- currencyID: invoice.invoiceCurrencyCode
129
- }],
130
- TaxExclusiveAmount: [{
131
- _: invoice.legalMonetaryTotal.taxExclusiveAmount,
132
- currencyID: invoice.invoiceCurrencyCode
133
- }],
134
- TaxInclusiveAmount: [{
135
- _: invoice.legalMonetaryTotal.taxInclusiveAmount,
136
- currencyID: invoice.invoiceCurrencyCode
137
- }],
138
- PayableAmount: [{
139
- _: invoice.legalMonetaryTotal.payableAmount,
140
- currencyID: invoice.invoiceCurrencyCode
141
- }]
142
- }],
143
- InvoiceLine: invoice.invoiceLineItems.map((item, index) => ({
144
- ID: [{ _: (index + 1).toString() }],
145
- Item: [{
146
- CommodityClassification: [{ ItemClassificationCode: [{
147
- _: item.itemClassificationCode,
148
- listID: "CLASS"
149
- }] }],
150
- Description: [{ _: item.itemDescription }]
151
- }],
152
- ItemPriceExtension: [{ Amount: [{
153
- _: item.totalTaxableAmountPerLine,
154
- currencyID: invoice.invoiceCurrencyCode
155
- }] }],
156
- LineExtensionAmount: [{
157
- _: item.totalTaxableAmountPerLine,
158
- currencyID: invoice.invoiceCurrencyCode
159
- }],
160
- Price: [{ PriceAmount: [{
161
- _: item.unitPrice,
162
- currencyID: invoice.invoiceCurrencyCode
163
- }] }],
164
- TaxTotal: [{
165
- TaxAmount: [{
166
- _: item.taxAmount,
167
- currencyID: invoice.invoiceCurrencyCode
168
- }],
169
- TaxSubtotal: [{
170
- TaxableAmount: [{
171
- _: item.totalTaxableAmountPerLine,
172
- currencyID: invoice.invoiceCurrencyCode
173
- }],
174
- TaxAmount: [{
175
- _: item.taxAmount,
176
- currencyID: invoice.invoiceCurrencyCode
177
- }],
178
- TaxCategory: [{
179
- ID: [{ _: item.taxType }],
180
- TaxScheme: [{ ID: [{
181
- _: "OTH",
182
- schemeAgencyID: "6",
183
- schemeID: "UN/ECE 5153"
184
- }] }]
185
- }]
186
- }]
187
- }]
188
- })),
189
- TaxExchangeRate: invoice.currencyExchangeRate ? [{
190
- SourceCurrencyCode: [{ _: invoice.invoiceCurrencyCode }],
191
- TargetCurrencyCode: [{ _: "MYR" }],
192
- CalculationRate: [{ _: invoice.currencyExchangeRate }]
193
- }] : void 0
194
- };
195
- };
196
- /**
197
- * Generates the complete UBL document structure with namespace declarations
198
- */
199
- const generateCleanUBLDocument = (invoices) => {
200
- return {
201
- _D: "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2",
202
- _A: "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2",
203
- _B: "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2",
204
- Invoice: invoices.map(generateCleanInvoiceObject)
205
- };
206
- };
207
- /**
208
- * Step 2: Calculate Document Digest
209
- * FIXED: Remove UBLExtensions and Signature before hashing (DS322)
210
- * Based on working implementation pattern
211
- */
212
- const calculateDocumentDigest = (invoices) => {
213
- const cleanDocument = generateCleanUBLDocument(invoices);
214
- const documentForHashing = JSON.parse(JSON.stringify(cleanDocument));
215
- if (documentForHashing.Invoice && Array.isArray(documentForHashing.Invoice)) documentForHashing.Invoice.forEach((invoice) => {
216
- delete invoice.UBLExtensions;
217
- delete invoice.Signature;
218
- });
219
- const documentString = JSON.stringify(documentForHashing);
220
- const hash = crypto.createHash("sha256");
221
- hash.update(documentString, "utf8");
222
- return hash.digest("base64");
223
- };
224
- /**
225
- * Step 4: Calculate Certificate Digest
226
- * Enhanced to handle certificate content properly
227
- */
228
- const calculateCertificateDigest = (certificatePem) => {
229
- const certificateContent = certificatePem.replace(/-----BEGIN CERTIFICATE-----/g, "").replace(/-----END CERTIFICATE-----/g, "").replace(/\s+/g, "");
230
- const certificateBinary = Buffer.from(certificateContent, "base64");
231
- const hash = crypto.createHash("sha256");
232
- hash.update(certificateBinary);
233
- return hash.digest("base64");
234
- };
235
- /**
236
- * Enhanced certificate info extraction with better error handling
237
- * FIXED: Normalize issuer name format to match MyInvois expectations (DS326)
238
- */
239
- const extractCertificateInfo = (certificatePem) => {
240
- try {
241
- const cert = new X509Certificate(certificatePem);
242
- const serialNumberHex = cert.serialNumber;
243
- const normalizeDistinguishedName = (dn) => {
244
- const normalized = dn.split("\n").map((line) => line.trim()).filter((line) => line.length > 0).join(", ");
245
- return normalized.replace(/\s*=\s*/g, "=").replace(/,\s+/g, ", ").replace(/\r/g, "").replace(/\s{2,}/g, " ").trim();
246
- };
247
- const formatSerialNumber = (serialHex) => {
248
- const decimal = BigInt("0x" + serialHex).toString();
249
- return decimal;
250
- };
251
- return {
252
- issuerName: normalizeDistinguishedName(cert.issuer),
253
- serialNumber: formatSerialNumber(serialNumberHex),
254
- subjectName: normalizeDistinguishedName(cert.subject)
255
- };
256
- } catch (error) {
257
- throw new Error(`Failed to extract certificate info: ${error instanceof Error ? error.message : String(error)}`);
258
- }
259
- };
260
- /**
261
- * Step 5: Create SignedProperties with enhanced structure
262
- * FIXED: Simplified structure to match MyInvois expectations (DS320)
263
- * Following MyInvois JSON signature specification exactly
264
- */
265
- const createSignedProperties = (certificateDigest, signingTime, issuerName, serialNumber) => {
266
- return { SignedProperties: [{
267
- Id: "id-xades-signed-props",
268
- SignedSignatureProperties: [{
269
- SigningTime: [{ _: signingTime }],
270
- SigningCertificate: [{ Cert: [{
271
- CertDigest: [{
272
- DigestMethod: [{ Algorithm: "http://www.w3.org/2001/04/xmlenc#sha256" }],
273
- DigestValue: [{ _: certificateDigest }]
274
- }],
275
- IssuerSerial: [{
276
- X509IssuerName: [{ _: issuerName }],
277
- X509SerialNumber: [{ _: serialNumber }]
278
- }]
279
- }] }]
280
- }]
281
- }] };
282
- };
283
- /**
284
- * Step 6: Calculate SignedProperties Digest
285
- * FIXED: Add Target wrapper and use direct JSON stringify (DS320)
286
- * Based on working implementation pattern
287
- */
288
- const calculateSignedPropertiesDigest = (signedProperties) => {
289
- const signedPropertiesWithTarget = {
290
- Target: "signature",
291
- SignedProperties: signedProperties.SignedProperties
292
- };
293
- const signedPropertiesString = JSON.stringify(signedPropertiesWithTarget);
294
- const hash = crypto.createHash("sha256");
295
- hash.update(signedPropertiesString, "utf8");
296
- return hash.digest("base64");
297
- };
298
- /**
299
- * Step 3: Create SignedInfo and calculate signature
300
- * Enhanced with better structure and signature generation
301
- */
302
- const createSignedInfoAndSign = (docDigest, propsDigest, privateKeyPem) => {
303
- const signedInfo = {
304
- CanonicalizationMethod: [{
305
- _: "",
306
- Algorithm: "http://www.w3.org/2006/12/xml-c14n11"
307
- }],
308
- SignatureMethod: [{
309
- _: "",
310
- Algorithm: "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
311
- }],
312
- Reference: [{
313
- Id: "id-doc-signed-data",
314
- Type: "",
315
- URI: "",
316
- DigestMethod: [{
317
- _: "",
318
- Algorithm: "http://www.w3.org/2001/04/xmlenc#sha256"
319
- }],
320
- DigestValue: [{ _: docDigest }]
321
- }, {
322
- Id: "id-xades-signed-props",
323
- Type: "http://uri.etsi.org/01903/v1.3.2#SignedProperties",
324
- URI: "#id-xades-signed-props",
325
- DigestMethod: [{
326
- _: "",
327
- Algorithm: "http://www.w3.org/2001/04/xmlenc#sha256"
328
- }],
329
- DigestValue: [{ _: propsDigest }]
330
- }]
331
- };
332
- const signedInfoString = JSON.stringify(signedInfo);
333
- try {
334
- const signer = crypto.createSign("RSA-SHA256");
335
- signer.update(signedInfoString, "utf8");
336
- const signatureValue = signer.sign(privateKeyPem, "base64");
337
- return {
338
- signedInfo,
339
- signatureValue
340
- };
341
- } catch (error) {
342
- throw new Error(`Signature generation failed: ${error instanceof Error ? error.message : String(error)}`);
343
- }
344
- };
345
- /**
346
- * Complete document generation with signatures
347
- * Follows the complete MyInvois JSON signature creation process (Steps 1-7)
348
- */
349
- const generateCompleteDocument = (invoices, signingCredentials) => {
350
- try {
351
- const docDigest = calculateDocumentDigest(invoices);
352
- const signingTime = (/* @__PURE__ */ new Date()).toISOString();
353
- const certInfo = extractCertificateInfo(signingCredentials.certificatePem);
354
- const certificateDigest = calculateCertificateDigest(signingCredentials.certificatePem);
355
- const signedProperties = createSignedProperties(certificateDigest, signingTime, certInfo.issuerName, certInfo.serialNumber);
356
- const propsDigest = calculateSignedPropertiesDigest(signedProperties);
357
- const { signedInfo, signatureValue } = createSignedInfoAndSign(docDigest, propsDigest, signingCredentials.privateKeyPem);
358
- const certificate = signingCredentials.certificatePem.replace(/-----BEGIN CERTIFICATE-----/g, "").replace(/-----END CERTIFICATE-----/g, "").replace(/\s+/g, "");
359
- const signedInvoices = invoices.map((invoice) => {
360
- const cleanInvoice = generateCleanInvoiceObject(invoice);
361
- return {
362
- ...cleanInvoice,
363
- UBLExtensions: [{ UBLExtension: [{
364
- ExtensionURI: [{ _: "urn:oasis:names:specification:ubl:dsig:enveloped:xades" }],
365
- ExtensionContent: [{ UBLDocumentSignatures: [{ SignatureInformation: [{
366
- ID: [{ _: "urn:oasis:names:specification:ubl:signature:1" }],
367
- ReferencedSignatureID: [{ _: "urn:oasis:names:specification:ubl:signature:Invoice" }],
368
- Signature: [{
369
- Id: "signature",
370
- Object: [{ QualifyingProperties: [{
371
- Target: "signature",
372
- SignedProperties: signedProperties.SignedProperties
373
- }] }],
374
- KeyInfo: [{ X509Data: [{
375
- X509Certificate: [{ _: certificate }],
376
- X509SubjectName: [{ _: certInfo.subjectName }],
377
- X509IssuerSerial: [{
378
- X509IssuerName: [{ _: certInfo.issuerName }],
379
- X509SerialNumber: [{ _: certInfo.serialNumber }]
380
- }]
381
- }] }],
382
- SignatureValue: [{ _: signatureValue }],
383
- SignedInfo: [signedInfo]
384
- }]
385
- }] }] }]
386
- }] }],
387
- Signature: [{
388
- ID: [{ _: "urn:oasis:names:specification:ubl:signature:Invoice" }],
389
- SignatureMethod: [{ _: "urn:oasis:names:specification:ubl:dsig:enveloped:xades" }]
390
- }]
391
- };
392
- });
393
- return {
394
- _D: "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2",
395
- _A: "urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2",
396
- _B: "urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2",
397
- Invoice: signedInvoices
398
- };
399
- } catch (error) {
400
- throw new Error(`Document generation failed: ${error instanceof Error ? error.message : String(error)}`);
401
- }
402
- };
403
-
404
- //#endregion
405
- export { calculateCertificateDigest, calculateDocumentDigest, calculateSignedPropertiesDigest, canonicalizeJSON, createSignedInfoAndSign, createSignedProperties, extractCertificateInfo, generateCleanInvoiceObject, generateCleanUBLDocument, generateCompleteDocument, sortObjectKeys };