tempest-react-sdk 0.34.0 → 0.36.0

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 (259) hide show
  1. package/README.md +72 -68
  2. package/dist/audio/audio-output.cjs +2 -0
  3. package/dist/audio/audio-output.cjs.map +1 -0
  4. package/dist/audio/audio-output.js +17 -0
  5. package/dist/audio/audio-output.js.map +1 -0
  6. package/dist/audio/audio-player.cjs +1 -1
  7. package/dist/audio/audio-player.cjs.map +1 -1
  8. package/dist/audio/audio-player.js +21 -20
  9. package/dist/audio/audio-player.js.map +1 -1
  10. package/dist/audio/audio-recorder.cjs +2 -0
  11. package/dist/audio/audio-recorder.cjs.map +1 -0
  12. package/dist/audio/audio-recorder.js +30 -0
  13. package/dist/audio/audio-recorder.js.map +1 -0
  14. package/dist/audio/duration.cjs +2 -0
  15. package/dist/audio/duration.cjs.map +1 -0
  16. package/dist/audio/duration.js +10 -0
  17. package/dist/audio/duration.js.map +1 -0
  18. package/dist/audio/level-meter.cjs +2 -0
  19. package/dist/audio/level-meter.cjs.map +1 -0
  20. package/dist/audio/level-meter.js +34 -0
  21. package/dist/audio/level-meter.js.map +1 -0
  22. package/dist/audio/media-access.cjs +2 -0
  23. package/dist/audio/media-access.cjs.map +1 -0
  24. package/dist/audio/media-access.js +51 -0
  25. package/dist/audio/media-access.js.map +1 -0
  26. package/dist/audio/use-audio-recorder.cjs +2 -0
  27. package/dist/audio/use-audio-recorder.cjs.map +1 -0
  28. package/dist/audio/use-audio-recorder.js +94 -0
  29. package/dist/audio/use-audio-recorder.js.map +1 -0
  30. package/dist/audio/use-audio.cjs.map +1 -1
  31. package/dist/audio/use-audio.js.map +1 -1
  32. package/dist/audio/use-microphone.cjs +2 -0
  33. package/dist/audio/use-microphone.cjs.map +1 -0
  34. package/dist/audio/use-microphone.js +54 -0
  35. package/dist/audio/use-microphone.js.map +1 -0
  36. package/dist/audio/wav.cjs +2 -0
  37. package/dist/audio/wav.cjs.map +1 -0
  38. package/dist/audio/wav.js +49 -0
  39. package/dist/audio/wav.js.map +1 -0
  40. package/dist/auth/passkey.cjs +2 -0
  41. package/dist/auth/passkey.cjs.map +1 -0
  42. package/dist/auth/passkey.js +171 -0
  43. package/dist/auth/passkey.js.map +1 -0
  44. package/dist/auth/use-passkey.cjs +2 -0
  45. package/dist/auth/use-passkey.cjs.map +1 -0
  46. package/dist/auth/use-passkey.js +120 -0
  47. package/dist/auth/use-passkey.js.map +1 -0
  48. package/dist/br/PixQRCode.cjs +2 -0
  49. package/dist/br/PixQRCode.cjs.map +1 -0
  50. package/dist/br/PixQRCode.js +70 -0
  51. package/dist/br/PixQRCode.js.map +1 -0
  52. package/dist/br/PixQRCode.module.cjs +2 -0
  53. package/dist/br/PixQRCode.module.cjs.map +1 -0
  54. package/dist/br/PixQRCode.module.js +15 -0
  55. package/dist/br/PixQRCode.module.js.map +1 -0
  56. package/dist/br/boleto.cjs +2 -0
  57. package/dist/br/boleto.cjs.map +1 -0
  58. package/dist/br/boleto.js +225 -0
  59. package/dist/br/boleto.js.map +1 -0
  60. package/dist/br/holidays.cjs +2 -0
  61. package/dist/br/holidays.cjs.map +1 -0
  62. package/dist/br/holidays.js +148 -0
  63. package/dist/br/holidays.js.map +1 -0
  64. package/dist/br/nfe.cjs +2 -0
  65. package/dist/br/nfe.cjs.map +1 -0
  66. package/dist/br/nfe.js +104 -0
  67. package/dist/br/nfe.js.map +1 -0
  68. package/dist/br/pix.cjs +2 -0
  69. package/dist/br/pix.cjs.map +1 -0
  70. package/dist/br/pix.js +148 -0
  71. package/dist/br/pix.js.map +1 -0
  72. package/dist/br.cjs +1 -1
  73. package/dist/br.cjs.map +1 -1
  74. package/dist/br.d.ts +878 -0
  75. package/dist/br.js +7 -2
  76. package/dist/br.js.map +1 -1
  77. package/dist/capture/barcode.cjs +2 -0
  78. package/dist/capture/barcode.cjs.map +1 -0
  79. package/dist/capture/barcode.js +59 -0
  80. package/dist/capture/barcode.js.map +1 -0
  81. package/dist/capture/media-recorder.cjs +2 -0
  82. package/dist/capture/media-recorder.cjs.map +1 -0
  83. package/dist/capture/media-recorder.js +64 -0
  84. package/dist/capture/media-recorder.js.map +1 -0
  85. package/dist/capture/use-barcode-scanner.cjs +2 -0
  86. package/dist/capture/use-barcode-scanner.cjs.map +1 -0
  87. package/dist/capture/use-barcode-scanner.js +86 -0
  88. package/dist/capture/use-barcode-scanner.js.map +1 -0
  89. package/dist/capture/use-screen-capture.cjs +2 -0
  90. package/dist/capture/use-screen-capture.cjs.map +1 -0
  91. package/dist/capture/use-screen-capture.js +79 -0
  92. package/dist/capture/use-screen-capture.js.map +1 -0
  93. package/dist/capture/use-speech-recognition.cjs +2 -0
  94. package/dist/capture/use-speech-recognition.cjs.map +1 -0
  95. package/dist/capture/use-speech-recognition.js +118 -0
  96. package/dist/capture/use-speech-recognition.js.map +1 -0
  97. package/dist/capture/use-torch.cjs +2 -0
  98. package/dist/capture/use-torch.cjs.map +1 -0
  99. package/dist/capture/use-torch.js +33 -0
  100. package/dist/capture/use-torch.js.map +1 -0
  101. package/dist/capture/use-video-recorder.cjs +2 -0
  102. package/dist/capture/use-video-recorder.cjs.map +1 -0
  103. package/dist/capture/use-video-recorder.js +90 -0
  104. package/dist/capture/use-video-recorder.js.map +1 -0
  105. package/dist/capture/video-recorder.cjs +2 -0
  106. package/dist/capture/video-recorder.cjs.map +1 -0
  107. package/dist/capture/video-recorder.js +31 -0
  108. package/dist/capture/video-recorder.js.map +1 -0
  109. package/dist/components/AIChat/AIChat.cjs +1 -1
  110. package/dist/components/AIChat/AIChat.cjs.map +1 -1
  111. package/dist/components/AIChat/AIChat.js +93 -97
  112. package/dist/components/AIChat/AIChat.js.map +1 -1
  113. package/dist/components/AIChat/AIChatComposer.cjs +1 -1
  114. package/dist/components/AIChat/AIChatComposer.cjs.map +1 -1
  115. package/dist/components/AIChat/AIChatComposer.js +2 -1
  116. package/dist/components/AIChat/AIChatComposer.js.map +1 -1
  117. package/dist/components/AIChat/AIChatTurn.cjs +2 -2
  118. package/dist/components/AIChat/AIChatTurn.js +6 -6
  119. package/dist/components/AIChat/AIChatTurn.js.map +1 -1
  120. package/dist/components/Alert/Alert.module.cjs.map +1 -1
  121. package/dist/components/Alert/Alert.module.js.map +1 -1
  122. package/dist/components/AudioPlayer/AudioPlayer.cjs +2 -0
  123. package/dist/components/AudioPlayer/AudioPlayer.cjs.map +1 -0
  124. package/dist/components/AudioPlayer/AudioPlayer.js +123 -0
  125. package/dist/components/AudioPlayer/AudioPlayer.js.map +1 -0
  126. package/dist/components/AudioPlayer/AudioPlayer.module.cjs +2 -0
  127. package/dist/components/AudioPlayer/AudioPlayer.module.cjs.map +1 -0
  128. package/dist/components/AudioPlayer/AudioPlayer.module.js +12 -0
  129. package/dist/components/AudioPlayer/AudioPlayer.module.js.map +1 -0
  130. package/dist/components/AudioRecorder/AudioRecorder.cjs +2 -0
  131. package/dist/components/AudioRecorder/AudioRecorder.cjs.map +1 -0
  132. package/dist/components/AudioRecorder/AudioRecorder.js +179 -0
  133. package/dist/components/AudioRecorder/AudioRecorder.js.map +1 -0
  134. package/dist/components/AudioRecorder/AudioRecorder.module.cjs +2 -0
  135. package/dist/components/AudioRecorder/AudioRecorder.module.cjs.map +1 -0
  136. package/dist/components/AudioRecorder/AudioRecorder.module.js +19 -0
  137. package/dist/components/AudioRecorder/AudioRecorder.module.js.map +1 -0
  138. package/dist/components/Badge/Badge.module.cjs.map +1 -1
  139. package/dist/components/Badge/Badge.module.js.map +1 -1
  140. package/dist/components/BarcodeScanner/BarcodeScanner.cjs +2 -0
  141. package/dist/components/BarcodeScanner/BarcodeScanner.cjs.map +1 -0
  142. package/dist/components/BarcodeScanner/BarcodeScanner.js +123 -0
  143. package/dist/components/BarcodeScanner/BarcodeScanner.js.map +1 -0
  144. package/dist/components/BarcodeScanner/BarcodeScanner.module.cjs +2 -0
  145. package/dist/components/BarcodeScanner/BarcodeScanner.module.cjs.map +1 -0
  146. package/dist/components/BarcodeScanner/BarcodeScanner.module.js +22 -0
  147. package/dist/components/BarcodeScanner/BarcodeScanner.module.js.map +1 -0
  148. package/dist/components/BottomNavigation/BottomNavigation.module.cjs.map +1 -1
  149. package/dist/components/BottomNavigation/BottomNavigation.module.js.map +1 -1
  150. package/dist/components/Button/Button.module.cjs.map +1 -1
  151. package/dist/components/Button/Button.module.js.map +1 -1
  152. package/dist/components/Combobox/Combobox.module.cjs.map +1 -1
  153. package/dist/components/Combobox/Combobox.module.js.map +1 -1
  154. package/dist/components/DataTable/DataTable.cjs +1 -1
  155. package/dist/components/DataTable/DataTable.cjs.map +1 -1
  156. package/dist/components/DataTable/DataTable.js +203 -66
  157. package/dist/components/DataTable/DataTable.js.map +1 -1
  158. package/dist/components/DataTable/DataTable.module.cjs +1 -1
  159. package/dist/components/DataTable/DataTable.module.cjs.map +1 -1
  160. package/dist/components/DataTable/DataTable.module.js +9 -3
  161. package/dist/components/DataTable/DataTable.module.js.map +1 -1
  162. package/dist/components/DataTable/EditableCell.cjs +2 -0
  163. package/dist/components/DataTable/EditableCell.cjs.map +1 -0
  164. package/dist/components/DataTable/EditableCell.js +77 -0
  165. package/dist/components/DataTable/EditableCell.js.map +1 -0
  166. package/dist/components/DataTable/edit-labels.cjs +2 -0
  167. package/dist/components/DataTable/edit-labels.cjs.map +1 -0
  168. package/dist/components/DataTable/edit-labels.js +11 -0
  169. package/dist/components/DataTable/edit-labels.js.map +1 -0
  170. package/dist/components/DateRangePicker/DateRangePicker.module.cjs.map +1 -1
  171. package/dist/components/DateRangePicker/DateRangePicker.module.js.map +1 -1
  172. package/dist/components/MultiSelect/MultiSelect.module.cjs.map +1 -1
  173. package/dist/components/MultiSelect/MultiSelect.module.js.map +1 -1
  174. package/dist/components/NavigationRail/NavigationRail.module.cjs.map +1 -1
  175. package/dist/components/NavigationRail/NavigationRail.module.js.map +1 -1
  176. package/dist/components/SyncStatusBadge/SyncStatusBadge.cjs +1 -1
  177. package/dist/components/SyncStatusBadge/SyncStatusBadge.cjs.map +1 -1
  178. package/dist/components/SyncStatusBadge/SyncStatusBadge.js +33 -32
  179. package/dist/components/SyncStatusBadge/SyncStatusBadge.js.map +1 -1
  180. package/dist/components/Toast/ToastProvider.cjs +1 -1
  181. package/dist/components/Toast/ToastProvider.cjs.map +1 -1
  182. package/dist/components/Toast/ToastProvider.js +1 -2
  183. package/dist/components/Toast/ToastProvider.js.map +1 -1
  184. package/dist/hooks/use-announce.cjs +2 -0
  185. package/dist/hooks/use-announce.cjs.map +1 -0
  186. package/dist/hooks/use-announce.js +50 -0
  187. package/dist/hooks/use-announce.js.map +1 -0
  188. package/dist/hooks/use-media-devices.cjs +2 -0
  189. package/dist/hooks/use-media-devices.cjs.map +1 -0
  190. package/dist/hooks/use-media-devices.js +46 -0
  191. package/dist/hooks/use-media-devices.js.map +1 -0
  192. package/dist/hooks/use-media-permission.cjs +2 -0
  193. package/dist/hooks/use-media-permission.cjs.map +1 -0
  194. package/dist/hooks/use-media-permission.js +33 -0
  195. package/dist/hooks/use-media-permission.js.map +1 -0
  196. package/dist/http/resumable-upload.cjs +2 -0
  197. package/dist/http/resumable-upload.cjs.map +1 -0
  198. package/dist/http/resumable-upload.js +249 -0
  199. package/dist/http/resumable-upload.js.map +1 -0
  200. package/dist/perf/cache-size.cjs +2 -0
  201. package/dist/perf/cache-size.cjs.map +1 -0
  202. package/dist/perf/cache-size.js +16 -0
  203. package/dist/perf/cache-size.js.map +1 -0
  204. package/dist/perf/device.cjs +2 -0
  205. package/dist/perf/device.cjs.map +1 -0
  206. package/dist/perf/device.js +22 -0
  207. package/dist/perf/device.js.map +1 -0
  208. package/dist/perf/format.cjs +2 -0
  209. package/dist/perf/format.cjs.map +1 -0
  210. package/dist/perf/format.js +8 -0
  211. package/dist/perf/format.js.map +1 -0
  212. package/dist/perf/profiler.cjs +2 -0
  213. package/dist/perf/profiler.cjs.map +1 -0
  214. package/dist/perf/profiler.js +46 -0
  215. package/dist/perf/profiler.js.map +1 -0
  216. package/dist/styles.css +1 -1
  217. package/dist/tempest-react-sdk.cjs +1 -1
  218. package/dist/tempest-react-sdk.d.ts +2705 -38
  219. package/dist/tempest-react-sdk.js +268 -240
  220. package/dist/vision/core/timing.cjs +2 -0
  221. package/dist/vision/core/timing.cjs.map +1 -0
  222. package/dist/vision/core/timing.js +24 -0
  223. package/dist/vision/core/timing.js.map +1 -0
  224. package/dist/vision/index.cjs +1 -1
  225. package/dist/vision/index.cjs.map +1 -1
  226. package/dist/vision/index.js +16 -15
  227. package/dist/vision/index.js.map +1 -1
  228. package/dist/vision/postprocess/detection.cjs +1 -1
  229. package/dist/vision/postprocess/detection.cjs.map +1 -1
  230. package/dist/vision/postprocess/detection.js +2 -2
  231. package/dist/vision/postprocess/detection.js.map +1 -1
  232. package/dist/vision/postprocess/segmentation.cjs +1 -1
  233. package/dist/vision/postprocess/segmentation.cjs.map +1 -1
  234. package/dist/vision/postprocess/segmentation.js +1 -1
  235. package/dist/vision/postprocess/segmentation.js.map +1 -1
  236. package/dist/vision/results.cjs +1 -1
  237. package/dist/vision/results.cjs.map +1 -1
  238. package/dist/vision/results.js +18 -13
  239. package/dist/vision/results.js.map +1 -1
  240. package/dist/vision/tasks/classifier.cjs +1 -1
  241. package/dist/vision/tasks/classifier.cjs.map +1 -1
  242. package/dist/vision/tasks/classifier.js +46 -39
  243. package/dist/vision/tasks/classifier.js.map +1 -1
  244. package/dist/vision/tasks/detector.cjs +1 -1
  245. package/dist/vision/tasks/detector.cjs.map +1 -1
  246. package/dist/vision/tasks/detector.js +40 -33
  247. package/dist/vision/tasks/detector.js.map +1 -1
  248. package/dist/vision/tasks/segmenter.cjs +1 -1
  249. package/dist/vision/tasks/segmenter.cjs.map +1 -1
  250. package/dist/vision/tasks/segmenter.js +35 -28
  251. package/dist/vision/tasks/segmenter.js.map +1 -1
  252. package/dist/vision/use-camera-stream.cjs +1 -1
  253. package/dist/vision/use-camera-stream.cjs.map +1 -1
  254. package/dist/vision/use-camera-stream.js +40 -57
  255. package/dist/vision/use-camera-stream.js.map +1 -1
  256. package/dist/vision.cjs +1 -1
  257. package/dist/vision.d.ts +93 -13
  258. package/dist/vision.js +21 -20
  259. package/package.json +1 -1
@@ -0,0 +1,148 @@
1
+ //#region src/br/holidays.ts
2
+ var e = [
3
+ {
4
+ month: 1,
5
+ day: 1,
6
+ name: "Confraternização Universal",
7
+ kind: "national"
8
+ },
9
+ {
10
+ month: 4,
11
+ day: 21,
12
+ name: "Tiradentes",
13
+ kind: "national"
14
+ },
15
+ {
16
+ month: 5,
17
+ day: 1,
18
+ name: "Dia do Trabalho",
19
+ kind: "national"
20
+ },
21
+ {
22
+ month: 9,
23
+ day: 7,
24
+ name: "Independência do Brasil",
25
+ kind: "national"
26
+ },
27
+ {
28
+ month: 10,
29
+ day: 12,
30
+ name: "Nossa Senhora Aparecida",
31
+ kind: "national"
32
+ },
33
+ {
34
+ month: 11,
35
+ day: 2,
36
+ name: "Finados",
37
+ kind: "national"
38
+ },
39
+ {
40
+ month: 11,
41
+ day: 15,
42
+ name: "Proclamação da República",
43
+ kind: "national"
44
+ },
45
+ {
46
+ month: 11,
47
+ day: 20,
48
+ name: "Dia Nacional de Zumbi e da Consciência Negra",
49
+ kind: "national",
50
+ since: 2024
51
+ },
52
+ {
53
+ month: 12,
54
+ day: 25,
55
+ name: "Natal",
56
+ kind: "national"
57
+ }
58
+ ], t = [
59
+ {
60
+ offset: -48,
61
+ name: "Carnaval (segunda-feira)",
62
+ kind: "banking"
63
+ },
64
+ {
65
+ offset: -47,
66
+ name: "Carnaval (terça-feira)",
67
+ kind: "banking"
68
+ },
69
+ {
70
+ offset: -2,
71
+ name: "Sexta-feira da Paixão",
72
+ kind: "banking"
73
+ },
74
+ {
75
+ offset: 60,
76
+ name: "Corpus Christi",
77
+ kind: "banking"
78
+ }
79
+ ], n = ["national", "banking"], r = [0, 6], i = 864e5, a = 400;
80
+ function o(e, t, n) {
81
+ return `${String(e).padStart(4, "0")}-${String(t).padStart(2, "0")}-${String(n).padStart(2, "0")}`;
82
+ }
83
+ function s(e) {
84
+ if (typeof e == "string") {
85
+ let t = /^(\d{4})-(\d{2})-(\d{2})$/.exec(e.trim());
86
+ if (t === null) throw RangeError(`Expected a YYYY-MM-DD date, got ${JSON.stringify(e)}.`);
87
+ return new Date(Number(t[1]), Number(t[2]) - 1, Number(t[3]));
88
+ }
89
+ if (Number.isNaN(e.getTime())) throw RangeError("Received an Invalid Date.");
90
+ return new Date(e.getFullYear(), e.getMonth(), e.getDate());
91
+ }
92
+ function c(e) {
93
+ let t = s(e);
94
+ return o(t.getFullYear(), t.getMonth() + 1, t.getDate());
95
+ }
96
+ function l(e) {
97
+ let t = e % 19, n = Math.floor(e / 100), r = e % 100, i = Math.floor(n / 4), a = n % 4, o = Math.floor((n + 8) / 25), s = Math.floor((n - o + 1) / 3), c = (19 * t + n - i - s + 15) % 30, l = Math.floor(r / 4), u = r % 4, d = (32 + 2 * a + 2 * l - c - u) % 7, f = Math.floor((t + 11 * c + 22 * d) / 451), p = Math.floor((c + d - 7 * f + 114) / 31), m = (c + d - 7 * f + 114) % 31 + 1;
98
+ return new Date(e, p - 1, m);
99
+ }
100
+ function u(n) {
101
+ let r = e.filter((e) => e.since === void 0 || n >= e.since).map((e) => ({
102
+ date: o(n, e.month, e.day),
103
+ name: e.name,
104
+ kind: e.kind,
105
+ movable: !1
106
+ })), a = l(n);
107
+ for (let e of t) {
108
+ let t = new Date(a.getTime() + e.offset * i);
109
+ r.push({
110
+ date: o(t.getFullYear(), t.getMonth() + 1, t.getDate()),
111
+ name: e.name,
112
+ kind: e.kind,
113
+ movable: !0
114
+ });
115
+ }
116
+ return r.sort((e, t) => e.date.localeCompare(t.date));
117
+ }
118
+ function d(e, t) {
119
+ let r = t.kinds ?? n, i = new Set(u(e).filter((e) => r.includes(e.kind)).map((e) => e.date));
120
+ for (let e of t.extra ?? []) i.add(c(e));
121
+ return i;
122
+ }
123
+ function f(e, t = {}) {
124
+ let n = c(e);
125
+ return d(Number(n.slice(0, 4)), t).has(n);
126
+ }
127
+ function p(e, t = {}) {
128
+ let n = s(e);
129
+ return !(t.weekend ?? r).includes(n.getDay()) && !f(n, t);
130
+ }
131
+ function m(e, t = {}) {
132
+ let n = s(e);
133
+ for (let e = 0; e < a; e += 1) if (n.setDate(n.getDate() + 1), p(n, t)) return n;
134
+ throw RangeError(`No business day within ${a} days of ${c(e)} — check \`weekend\` and \`extra\`.`);
135
+ }
136
+ function h(e, t, n = {}) {
137
+ let r = s(e), i = t < 0 ? -1 : 1;
138
+ for (let o = 0; o < Math.abs(t); o += 1) {
139
+ let t = !1;
140
+ for (let e = 0; e < a && !t; e += 1) r.setDate(r.getDate() + i), t = p(r, n);
141
+ if (!t) throw RangeError(`No business day within ${a} days while walking from ${c(e)} — check \`weekend\` and \`extra\`.`);
142
+ }
143
+ return r;
144
+ }
145
+ //#endregion
146
+ export { h as addBusinessDays, l as easterSunday, u as holidaysFor, p as isBusinessDay, f as isHoliday, m as nextBusinessDay };
147
+
148
+ //# sourceMappingURL=holidays.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"holidays.js","names":[],"sources":["../../src/br/holidays.ts"],"sourcesContent":["/**\n * How binding a non-working day is.\n *\n * - `\"national\"` — a feriado nacional in federal law. Nobody works, and a\n * deadline that lands here moves.\n * - `\"banking\"` — not a statutory holiday, but a day the national financial\n * system does not operate: Carnaval (Monday and Tuesday), Sexta-feira da\n * Paixão and Corpus Christi. Bank branches are shut and compensation does not\n * run, so a boleto or a TED dated here settles later — but an employer may\n * legally require work, which is why the two kinds are separate.\n */\nexport type HolidayKind = \"national\" | \"banking\";\n\n/** One non-working day in a given year. */\nexport interface Holiday {\n /** `YYYY-MM-DD` in the local calendar. */\n date: string;\n /** Portuguese name, as the law or the Bacen calendar spells it. */\n name: string;\n kind: HolidayKind;\n /** `true` when the date is derived from Easter rather than fixed. */\n movable: boolean;\n}\n\n/** Anything these helpers accept as a day. */\nexport type DateInput = Date | string;\n\n/** Options shared by the calendar helpers. */\nexport interface BusinessDayOptions {\n /**\n * Which kinds count as non-working. Default `[\"national\", \"banking\"]`, i.e.\n * the Bacen calendar — the right default for anything money moves through.\n * Pass `[\"national\"]` for a labour-law calendar.\n */\n kinds?: readonly HolidayKind[];\n /**\n * Extra non-working days, as `YYYY-MM-DD` or `Date`. This is where state and\n * municipal holidays go: they are **not** in the built-in table and never will\n * be — there are 5 570 municipalities, each free to declare its own.\n */\n extra?: readonly DateInput[];\n /**\n * Days of the week that are not worked, `0` = Sunday. Default `[0, 6]`.\n */\n weekend?: readonly number[];\n}\n\n/** Fixed-date national holidays, with the year each became one. */\nconst FIXED_HOLIDAYS: readonly {\n month: number;\n day: number;\n name: string;\n kind: HolidayKind;\n since?: number;\n}[] = [\n { month: 1, day: 1, name: \"Confraternização Universal\", kind: \"national\" },\n { month: 4, day: 21, name: \"Tiradentes\", kind: \"national\" },\n { month: 5, day: 1, name: \"Dia do Trabalho\", kind: \"national\" },\n { month: 9, day: 7, name: \"Independência do Brasil\", kind: \"national\" },\n { month: 10, day: 12, name: \"Nossa Senhora Aparecida\", kind: \"national\" },\n { month: 11, day: 2, name: \"Finados\", kind: \"national\" },\n { month: 11, day: 15, name: \"Proclamação da República\", kind: \"national\" },\n {\n month: 11,\n day: 20,\n name: \"Dia Nacional de Zumbi e da Consciência Negra\",\n kind: \"national\",\n since: 2024,\n },\n { month: 12, day: 25, name: \"Natal\", kind: \"national\" },\n];\n\n/** Easter-relative holidays, as a day offset from Easter Sunday. */\nconst MOVABLE_HOLIDAYS: readonly { offset: number; name: string; kind: HolidayKind }[] = [\n { offset: -48, name: \"Carnaval (segunda-feira)\", kind: \"banking\" },\n { offset: -47, name: \"Carnaval (terça-feira)\", kind: \"banking\" },\n { offset: -2, name: \"Sexta-feira da Paixão\", kind: \"banking\" },\n { offset: 60, name: \"Corpus Christi\", kind: \"banking\" },\n];\n\nconst DEFAULT_KINDS: readonly HolidayKind[] = [\"national\", \"banking\"];\nconst DEFAULT_WEEKEND: readonly number[] = [0, 6];\nconst MS_PER_DAY = 86_400_000;\n\n/**\n * How far a walk may go before it is treated as a bug rather than a long holiday.\n *\n * A real calendar never has more than a handful of consecutive non-working days,\n * so hitting this means `extra` or `weekend` marked every day off, and looping\n * forever is worse than an error.\n */\nconst MAX_WALK_DAYS = 400;\n\n/** `YYYY-MM-DD` from a local-calendar date. */\nfunction toIso(year: number, month: number, day: number): string {\n return `${String(year).padStart(4, \"0\")}-${String(month).padStart(2, \"0\")}-${String(day).padStart(2, \"0\")}`;\n}\n\n/**\n * Local midnight for any accepted input.\n *\n * Everything here works on local calendar components, never on UTC: `new Date(y,\n * m, d)` and `getFullYear()/getMonth()/getDate()`. Going through `toISOString()`\n * would shift the day for every viewer east of Greenwich, and \"is today a\n * holiday\" is a question about the viewer's calendar.\n *\n * @throws {RangeError} When a string is not `YYYY-MM-DD` or a `Date` is invalid.\n */\nfunction toLocalDate(input: DateInput): Date {\n if (typeof input === \"string\") {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(input.trim());\n if (match === null) {\n throw new RangeError(`Expected a YYYY-MM-DD date, got ${JSON.stringify(input)}.`);\n }\n return new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3]));\n }\n if (Number.isNaN(input.getTime())) throw new RangeError(\"Received an Invalid Date.\");\n return new Date(input.getFullYear(), input.getMonth(), input.getDate());\n}\n\n/** `YYYY-MM-DD` for any accepted input. */\nfunction isoOf(input: DateInput): string {\n const date = toLocalDate(input);\n return toIso(date.getFullYear(), date.getMonth() + 1, date.getDate());\n}\n\n/**\n * Easter Sunday in the Gregorian calendar.\n *\n * The anonymous Gregorian computus (Meeus/Jones/Butcher): pure integer\n * arithmetic over the year, no tables and no dependency. It is exact for every\n * Gregorian year, which is why the four movable Brazilian holidays are derived\n * from it rather than listed.\n *\n * @param year - Gregorian year.\n * @returns Local midnight of Easter Sunday.\n *\n * @example\n * easterSunday(2026); // 2026-04-05\n */\nexport function easterSunday(year: number): Date {\n const a = year % 19;\n const b = Math.floor(year / 100);\n const c = year % 100;\n const d = Math.floor(b / 4);\n const e = b % 4;\n const f = Math.floor((b + 8) / 25);\n const g = Math.floor((b - f + 1) / 3);\n const h = (19 * a + b - d - g + 15) % 30;\n const i = Math.floor(c / 4);\n const k = c % 4;\n const l = (32 + 2 * e + 2 * i - h - k) % 7;\n const m = Math.floor((a + 11 * h + 22 * l) / 451);\n const month = Math.floor((h + l - 7 * m + 114) / 31);\n const day = ((h + l - 7 * m + 114) % 31) + 1;\n return new Date(year, month - 1, day);\n}\n\n/**\n * Every national non-working day in a year, ordered by date.\n *\n * **What is here:** the nine feriados nacionais in federal law (Lei 662/1949 as\n * amended by Lei 10.607/2002, Lei 6.802/1980 for 12 October, and Lei 14.759/2023\n * for 20 November, which is why that one only appears from 2024), plus the four\n * movable days the national financial system observes.\n *\n * **What is deliberately not here**, and will not be:\n *\n * - **State and municipal holidays.** A data magna varies by state and each of the\n * 5 570 municipalities may declare its own, including up to four religious\n * days. No table can be both complete and current; pass them through\n * `options.extra`.\n * - **Ponto facultativo.** A federal decree that lets public servants off is not a\n * holiday and binds nobody else, so it changes no deadline.\n * - **Pre-2002 history.** The table encodes the law as it stands today. Asking for\n * 1998 returns today's set shifted to 1998, not what was in force then.\n *\n * Carnaval, Sexta-feira da Paixão and Corpus Christi are the interesting case:\n * none of them is a feriado nacional in federal law, yet CMN Resolução 4.880/2020\n * closes the banks on all four days, so a payment cannot settle. They are returned\n * with `kind: \"banking\"` — counted by default, and excluded by passing\n * `kinds: [\"national\"]`.\n *\n * @param year - Gregorian year.\n * @returns The holidays of that year, ascending by date.\n *\n * @example\n * holidaysFor(2026).filter((holiday) => holiday.kind === \"national\").length; // 9\n */\nexport function holidaysFor(year: number): Holiday[] {\n const holidays: Holiday[] = FIXED_HOLIDAYS.filter(\n (entry) => entry.since === undefined || year >= entry.since,\n ).map((entry) => ({\n date: toIso(year, entry.month, entry.day),\n name: entry.name,\n kind: entry.kind,\n movable: false,\n }));\n\n const easter = easterSunday(year);\n for (const entry of MOVABLE_HOLIDAYS) {\n const date = new Date(easter.getTime() + entry.offset * MS_PER_DAY);\n holidays.push({\n date: toIso(date.getFullYear(), date.getMonth() + 1, date.getDate()),\n name: entry.name,\n kind: entry.kind,\n movable: true,\n });\n }\n\n return holidays.sort((left, right) => left.date.localeCompare(right.date));\n}\n\n/** The set of `YYYY-MM-DD` strings that count as off for a given year. */\nfunction offDays(year: number, options: BusinessDayOptions): Set<string> {\n const kinds = options.kinds ?? DEFAULT_KINDS;\n const days = new Set(\n holidaysFor(year)\n .filter((holiday) => kinds.includes(holiday.kind))\n .map((holiday) => holiday.date),\n );\n for (const entry of options.extra ?? []) days.add(isoOf(entry));\n return days;\n}\n\n/**\n * Whether a date is a national holiday.\n *\n * @param date - `YYYY-MM-DD` or a `Date`. Only the local calendar day matters.\n * @param options - See {@link BusinessDayOptions}. `weekend` is ignored here — a\n * Sunday is not a holiday, it is a Sunday.\n * @returns `true` when the day is in the table (or in `extra`).\n * @throws {RangeError} On a malformed string or an Invalid Date.\n *\n * @example\n * isHoliday(\"2026-11-20\"); // true\n * isHoliday(\"2026-02-17\"); // true — Carnaval\n * isHoliday(\"2026-02-17\", { kinds: [\"national\"] }); // false\n */\nexport function isHoliday(date: DateInput, options: BusinessDayOptions = {}): boolean {\n const iso = isoOf(date);\n return offDays(Number(iso.slice(0, 4)), options).has(iso);\n}\n\n/**\n * Whether a date is a working day: not a weekend, not a holiday.\n *\n * @param date - `YYYY-MM-DD` or a `Date`.\n * @param options - See {@link BusinessDayOptions}.\n * @returns `true` when work happens on that day.\n * @throws {RangeError} On a malformed string or an Invalid Date.\n *\n * @example\n * isBusinessDay(\"2026-04-03\"); // false — Sexta-feira da Paixão\n */\nexport function isBusinessDay(date: DateInput, options: BusinessDayOptions = {}): boolean {\n const local = toLocalDate(date);\n const weekend = options.weekend ?? DEFAULT_WEEKEND;\n if (weekend.includes(local.getDay())) return false;\n return !isHoliday(local, options);\n}\n\n/**\n * The first working day strictly after a date.\n *\n * Strictly after: calling it on a Wednesday returns Thursday, never the same\n * Wednesday. That is what a \"prazo de D+1\" means, and it makes the function safe\n * to call in a loop.\n *\n * @param date - `YYYY-MM-DD` or a `Date`.\n * @param options - See {@link BusinessDayOptions}.\n * @returns Local midnight of the next working day.\n * @throws {RangeError} On a malformed input, or when `options` marked so many days\n * off that no working day exists within {@link MAX_WALK_DAYS}.\n *\n * @example\n * nextBusinessDay(\"2026-12-24\"); // 2026-12-28 — the 25th is Natal, then a weekend\n */\nexport function nextBusinessDay(date: DateInput, options: BusinessDayOptions = {}): Date {\n const cursor = toLocalDate(date);\n for (let step = 0; step < MAX_WALK_DAYS; step += 1) {\n cursor.setDate(cursor.getDate() + 1);\n if (isBusinessDay(cursor, options)) return cursor;\n }\n throw new RangeError(\n `No business day within ${MAX_WALK_DAYS} days of ${isoOf(date)} — check \\`weekend\\` and \\`extra\\`.`,\n );\n}\n\n/**\n * Move a date by a number of working days.\n *\n * `n` days forward means `n` calls to {@link nextBusinessDay}; a negative `n`\n * walks backwards the same way. `n === 0` returns the day unchanged **even when it\n * is not a working day** — snapping silently would hide the case a caller most\n * needs to see.\n *\n * @param date - `YYYY-MM-DD` or a `Date`.\n * @param days - Working days to add. May be negative.\n * @param options - See {@link BusinessDayOptions}.\n * @returns Local midnight of the resulting day.\n * @throws {RangeError} On a malformed input, or on a calendar with no working days.\n *\n * @example\n * addBusinessDays(\"2026-04-01\", 2); // 2026-04-06 — skips Good Friday and the weekend\n */\nexport function addBusinessDays(\n date: DateInput,\n days: number,\n options: BusinessDayOptions = {},\n): Date {\n const cursor = toLocalDate(date);\n const direction = days < 0 ? -1 : 1;\n for (let moved = 0; moved < Math.abs(days); moved += 1) {\n let landed = false;\n for (let step = 0; step < MAX_WALK_DAYS && !landed; step += 1) {\n cursor.setDate(cursor.getDate() + direction);\n landed = isBusinessDay(cursor, options);\n }\n if (!landed) {\n throw new RangeError(\n `No business day within ${MAX_WALK_DAYS} days while walking from ${isoOf(date)} — ` +\n \"check `weekend` and `extra`.\",\n );\n }\n }\n return cursor;\n}\n"],"mappings":";AAgDA,IAAM,IAMA;CACF;EAAE,OAAO;EAAG,KAAK;EAAG,MAAM;EAA8B,MAAM;CAAW;CACzE;EAAE,OAAO;EAAG,KAAK;EAAI,MAAM;EAAc,MAAM;CAAW;CAC1D;EAAE,OAAO;EAAG,KAAK;EAAG,MAAM;EAAmB,MAAM;CAAW;CAC9D;EAAE,OAAO;EAAG,KAAK;EAAG,MAAM;EAA2B,MAAM;CAAW;CACtE;EAAE,OAAO;EAAI,KAAK;EAAI,MAAM;EAA2B,MAAM;CAAW;CACxE;EAAE,OAAO;EAAI,KAAK;EAAG,MAAM;EAAW,MAAM;CAAW;CACvD;EAAE,OAAO;EAAI,KAAK;EAAI,MAAM;EAA4B,MAAM;CAAW;CACzE;EACI,OAAO;EACP,KAAK;EACL,MAAM;EACN,MAAM;EACN,OAAO;CACX;CACA;EAAE,OAAO;EAAI,KAAK;EAAI,MAAM;EAAS,MAAM;CAAW;AAC1D,GAGM,IAAmF;CACrF;EAAE,QAAQ;EAAK,MAAM;EAA4B,MAAM;CAAU;CACjE;EAAE,QAAQ;EAAK,MAAM;EAA0B,MAAM;CAAU;CAC/D;EAAE,QAAQ;EAAI,MAAM;EAAyB,MAAM;CAAU;CAC7D;EAAE,QAAQ;EAAI,MAAM;EAAkB,MAAM;CAAU;AAC1D,GAEM,IAAwC,CAAC,YAAY,SAAS,GAC9D,IAAqC,CAAC,GAAG,CAAC,GAC1C,IAAa,OASb,IAAgB;AAGtB,SAAS,EAAM,GAAc,GAAe,GAAqB;CAC7D,OAAO,GAAG,OAAO,CAAI,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,GAAG,OAAO,CAAK,CAAC,CAAC,SAAS,GAAG,GAAG,EAAE,GAAG,OAAO,CAAG,CAAC,CAAC,SAAS,GAAG,GAAG;AAC5G;AAYA,SAAS,EAAY,GAAwB;CACzC,IAAI,OAAO,KAAU,UAAU;EAC3B,IAAM,IAAQ,4BAA4B,KAAK,EAAM,KAAK,CAAC;EAC3D,IAAI,MAAU,MACV,MAAU,WAAW,mCAAmC,KAAK,UAAU,CAAK,EAAE,EAAE;EAEpF,OAAO,IAAI,KAAK,OAAO,EAAM,EAAE,GAAG,OAAO,EAAM,EAAE,IAAI,GAAG,OAAO,EAAM,EAAE,CAAC;CAC5E;CACA,IAAI,OAAO,MAAM,EAAM,QAAQ,CAAC,GAAG,MAAU,WAAW,2BAA2B;CACnF,OAAO,IAAI,KAAK,EAAM,YAAY,GAAG,EAAM,SAAS,GAAG,EAAM,QAAQ,CAAC;AAC1E;AAGA,SAAS,EAAM,GAA0B;CACrC,IAAM,IAAO,EAAY,CAAK;CAC9B,OAAO,EAAM,EAAK,YAAY,GAAG,EAAK,SAAS,IAAI,GAAG,EAAK,QAAQ,CAAC;AACxE;AAgBA,SAAgB,EAAa,GAAoB;CAC7C,IAAM,IAAI,IAAO,IACX,IAAI,KAAK,MAAM,IAAO,GAAG,GACzB,IAAI,IAAO,KACX,IAAI,KAAK,MAAM,IAAI,CAAC,GACpB,IAAI,IAAI,GACR,IAAI,KAAK,OAAO,IAAI,KAAK,EAAE,GAC3B,IAAI,KAAK,OAAO,IAAI,IAAI,KAAK,CAAC,GAC9B,KAAK,KAAK,IAAI,IAAI,IAAI,IAAI,MAAM,IAChC,IAAI,KAAK,MAAM,IAAI,CAAC,GACpB,IAAI,IAAI,GACR,KAAK,KAAK,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,GACnC,IAAI,KAAK,OAAO,IAAI,KAAK,IAAI,KAAK,KAAK,GAAG,GAC1C,IAAQ,KAAK,OAAO,IAAI,IAAI,IAAI,IAAI,OAAO,EAAE,GAC7C,KAAQ,IAAI,IAAI,IAAI,IAAI,OAAO,KAAM;CAC3C,OAAO,IAAI,KAAK,GAAM,IAAQ,GAAG,CAAG;AACxC;AAiCA,SAAgB,EAAY,GAAyB;CACjD,IAAM,IAAsB,EAAe,QACtC,MAAU,EAAM,UAAU,KAAA,KAAa,KAAQ,EAAM,KAC1D,CAAC,CAAC,KAAK,OAAW;EACd,MAAM,EAAM,GAAM,EAAM,OAAO,EAAM,GAAG;EACxC,MAAM,EAAM;EACZ,MAAM,EAAM;EACZ,SAAS;CACb,EAAE,GAEI,IAAS,EAAa,CAAI;CAChC,KAAK,IAAM,KAAS,GAAkB;EAClC,IAAM,IAAO,IAAI,KAAK,EAAO,QAAQ,IAAI,EAAM,SAAS,CAAU;EAClE,EAAS,KAAK;GACV,MAAM,EAAM,EAAK,YAAY,GAAG,EAAK,SAAS,IAAI,GAAG,EAAK,QAAQ,CAAC;GACnE,MAAM,EAAM;GACZ,MAAM,EAAM;GACZ,SAAS;EACb,CAAC;CACL;CAEA,OAAO,EAAS,MAAM,GAAM,MAAU,EAAK,KAAK,cAAc,EAAM,IAAI,CAAC;AAC7E;AAGA,SAAS,EAAQ,GAAc,GAA0C;CACrE,IAAM,IAAQ,EAAQ,SAAS,GACzB,IAAO,IAAI,IACb,EAAY,CAAI,CAAC,CACZ,QAAQ,MAAY,EAAM,SAAS,EAAQ,IAAI,CAAC,CAAC,CACjD,KAAK,MAAY,EAAQ,IAAI,CACtC;CACA,KAAK,IAAM,KAAS,EAAQ,SAAS,CAAC,GAAG,EAAK,IAAI,EAAM,CAAK,CAAC;CAC9D,OAAO;AACX;AAgBA,SAAgB,EAAU,GAAiB,IAA8B,CAAC,GAAY;CAClF,IAAM,IAAM,EAAM,CAAI;CACtB,OAAO,EAAQ,OAAO,EAAI,MAAM,GAAG,CAAC,CAAC,GAAG,CAAO,CAAC,CAAC,IAAI,CAAG;AAC5D;AAaA,SAAgB,EAAc,GAAiB,IAA8B,CAAC,GAAY;CACtF,IAAM,IAAQ,EAAY,CAAI;CAG9B,OADA,EADgB,EAAQ,WAAW,EAAA,CACvB,SAAS,EAAM,OAAO,CAAC,KAC5B,CAAC,EAAU,GAAO,CAAO;AACpC;AAkBA,SAAgB,EAAgB,GAAiB,IAA8B,CAAC,GAAS;CACrF,IAAM,IAAS,EAAY,CAAI;CAC/B,KAAK,IAAI,IAAO,GAAG,IAAO,GAAe,KAAQ,GAE7C,IADA,EAAO,QAAQ,EAAO,QAAQ,IAAI,CAAC,GAC/B,EAAc,GAAQ,CAAO,GAAG,OAAO;CAE/C,MAAU,WACN,0BAA0B,EAAc,WAAW,EAAM,CAAI,EAAE,oCACnE;AACJ;AAmBA,SAAgB,EACZ,GACA,GACA,IAA8B,CAAC,GAC3B;CACJ,IAAM,IAAS,EAAY,CAAI,GACzB,IAAY,IAAO,IAAI,KAAK;CAClC,KAAK,IAAI,IAAQ,GAAG,IAAQ,KAAK,IAAI,CAAI,GAAG,KAAS,GAAG;EACpD,IAAI,IAAS;EACb,KAAK,IAAI,IAAO,GAAG,IAAO,KAAiB,CAAC,GAAQ,KAAQ,GAExD,AADA,EAAO,QAAQ,EAAO,QAAQ,IAAI,CAAS,GAC3C,IAAS,EAAc,GAAQ,CAAO;EAE1C,IAAI,CAAC,GACD,MAAU,WACN,0BAA0B,EAAc,2BAA2B,EAAM,CAAI,EAAE,oCAEnF;CAER;CACA,OAAO;AACX"}
@@ -0,0 +1,2 @@
1
+ var e=class extends Error{constructor(e){super(e),this.name=`ChaveNFeError`}},t={11:`RO`,12:`AC`,13:`AM`,14:`RR`,15:`PA`,16:`AP`,17:`TO`,21:`MA`,22:`PI`,23:`CE`,24:`RN`,25:`PB`,26:`PE`,27:`AL`,28:`SE`,29:`BA`,31:`MG`,32:`ES`,33:`RJ`,35:`SP`,41:`PR`,42:`SC`,43:`RS`,50:`MS`,51:`MT`,52:`GO`,53:`DF`},n={55:`NF-e`,57:`CT-e`,58:`MDF-e`,59:`SAT-CF-e`,63:`BP-e`,65:`NFC-e`,66:`NF3e`,67:`CT-e OS`},r={1:`Normal`,2:`Contingência FS-IA`,3:`Contingência SCAN`,4:`Contingência DPEC/EPEC`,5:`Contingência FS-DA`,6:`Contingência SVC-AN`,7:`Contingência SVC-RS`,9:`Contingência off-line (NFC-e)`},i=2,a=44,o=43,s=2e3;function c(e){return e.replace(/\D/g,``)}function l(t){if(!RegExp(`^\\d{${o}}$`).test(t))throw new e(`The check digit is computed over ${o} digits, got ${t.length}.`);let n=0;for(let e=0;e<t.length;e+=1){let r=t.length-1-e;n+=Number(t[e])*(i+r%8)}let r=n%11;return r===0||r===1?0:11-r}function u(e){let n=c(e);return n.length!==a||t[n.slice(0,2)]===void 0?!1:String(l(n.slice(0,o)))===n.slice(43)}function d(i){let u=c(i);if(u.length!==a)throw new e(`An access key has ${a} digits, got ${u.length}.`);let d=u.slice(0,2),f=t[d];if(f===void 0)throw new e(`${d} is not an IBGE code for a federative unit.`);let p=u.slice(2,6),m=Number(p.slice(2,4));if(m<1||m>12)throw new e(`Month ${p.slice(2,4)} in AAMM is not a month.`);let h=u.slice(43),g=l(u.slice(0,o));if(String(g)!==h)throw new e(`Check digit is ${h}, recomputed ${g}.`);let _=u.slice(20,22),v=u.slice(34,35);return{uf:f,cUF:d,anoMes:p,ano:s+Number(p.slice(0,2)),mes:m,cnpj:u.slice(6,20),modelo:_,modeloLabel:n[_]??null,serie:u.slice(22,25),numero:u.slice(25,34),tipoEmissao:v,tipoEmissaoLabel:r[v]??null,codigoNumerico:u.slice(35,43),dv:h}}function f(e){let t=c(e);return t.length===a?t.replace(/(\d{4})(?=\d)/g,`$1 `):e}exports.ChaveNFeError=e,exports.chaveNFeCheckDigit=l,exports.formatChaveNFe=f,exports.parseChaveNFe=d,exports.validateChaveNFe=u;
2
+ //# sourceMappingURL=nfe.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nfe.cjs","names":[],"sources":["../../src/br/nfe.ts"],"sourcesContent":["import type { UF } from \"./locations\";\n\n/**\n * A 44-digit fiscal access key could not be read.\n *\n * Its own class so a scanner screen can tell a bad key apart from a bug and show\n * the message to the operator unchanged.\n */\nexport class ChaveNFeError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ChaveNFeError\";\n }\n}\n\n/** A fiscal access key taken apart. */\nexport interface ChaveNFe {\n /** Federative unit of the issuer, resolved from {@link cUF}. */\n uf: UF;\n /** The raw 2-digit IBGE code, positions 1-2. */\n cUF: string;\n /** Positions 3-6, `AAMM` — the two-digit year and the month of issue. */\n anoMes: string;\n /** Four-digit year derived from {@link anoMes}. */\n ano: number;\n /** Month of issue, 1-12. */\n mes: number;\n /** Positions 7-20, the issuer's CNPJ. */\n cnpj: string;\n /** Positions 21-22, `mod`. `\"55\"` is an NF-e, `\"65\"` an NFC-e. */\n modelo: string;\n /** Human label for {@link modelo}, or `null` for a model outside the table. */\n modeloLabel: string | null;\n /** Positions 23-25. */\n serie: string;\n /** Positions 26-34, `nNF`. */\n numero: string;\n /** Position 35, `tpEmis`. */\n tipoEmissao: string;\n /** Human label for {@link tipoEmissao}, or `null` for a value outside the table. */\n tipoEmissaoLabel: string | null;\n /** Positions 36-43, `cNF` — the issuer's random code. */\n codigoNumerico: string;\n /** Position 44, `cDV`. */\n dv: string;\n}\n\n/**\n * IBGE code of each federative unit, as `cUF` carries it.\n *\n * Only the numeric codes live here — the acronyms are the `UF` union from\n * `./locations`, so a state added or renamed there flows through. Ported from the\n * IBGE table of \"códigos dos municípios\" (the two leading digits of every\n * municipality code), which is the same table the NF-e manual points at.\n */\nconst UF_BY_CODE: Record<string, UF> = {\n \"11\": \"RO\",\n \"12\": \"AC\",\n \"13\": \"AM\",\n \"14\": \"RR\",\n \"15\": \"PA\",\n \"16\": \"AP\",\n \"17\": \"TO\",\n \"21\": \"MA\",\n \"22\": \"PI\",\n \"23\": \"CE\",\n \"24\": \"RN\",\n \"25\": \"PB\",\n \"26\": \"PE\",\n \"27\": \"AL\",\n \"28\": \"SE\",\n \"29\": \"BA\",\n \"31\": \"MG\",\n \"32\": \"ES\",\n \"33\": \"RJ\",\n \"35\": \"SP\",\n \"41\": \"PR\",\n \"42\": \"SC\",\n \"43\": \"RS\",\n \"50\": \"MS\",\n \"51\": \"MT\",\n \"52\": \"GO\",\n \"53\": \"DF\",\n};\n\n/** The document models that share the 44-digit key layout. */\nconst MODELO_LABELS: Record<string, string> = {\n \"55\": \"NF-e\",\n \"57\": \"CT-e\",\n \"58\": \"MDF-e\",\n \"59\": \"SAT-CF-e\",\n \"63\": \"BP-e\",\n \"65\": \"NFC-e\",\n \"66\": \"NF3e\",\n \"67\": \"CT-e OS\",\n};\n\n/** `tpEmis` values from the NF-e manual. */\nconst TIPO_EMISSAO_LABELS: Record<string, string> = {\n \"1\": \"Normal\",\n \"2\": \"Contingência FS-IA\",\n \"3\": \"Contingência SCAN\",\n \"4\": \"Contingência DPEC/EPEC\",\n \"5\": \"Contingência FS-DA\",\n \"6\": \"Contingência SVC-AN\",\n \"7\": \"Contingência SVC-RS\",\n \"9\": \"Contingência off-line (NFC-e)\",\n};\n\n/** Weight cycle of the módulo 11 check digit, applied right to left. */\nconst DV_WEIGHT_FIRST = 2;\nconst DV_WEIGHT_LAST = 9;\n\n/** Length of the key, and of the body the check digit protects. */\nconst CHAVE_LENGTH = 44;\nconst CHAVE_BODY_LENGTH = 43;\n\n/** Century the two-digit `AAMM` year resolves into. NF-e went live in 2006. */\nconst CHAVE_YEAR_BASE = 2000;\n\n/** Digits of a key that may carry spaces or dots from a copy-paste. */\nfunction digits(value: string): string {\n return value.replace(/\\D/g, \"\");\n}\n\n/**\n * The check digit a 43-digit key body requires.\n *\n * Módulo 11: each digit is multiplied by weights cycling `2…9` from right to\n * left, the products are summed, and the digit is `11 - (sum mod 11)` — except\n * that a remainder of `0` or `1` yields `0`, since `11` and `10` do not fit one\n * position.\n *\n * Note this is the **fiscal** flavour of módulo 11. The cobrança boleto resolves\n * those same remainders to `1`; see `mod11DacCobranca` in `./boleto`.\n *\n * @param body - The first 43 digits of the key.\n * @returns The check digit, 0-9.\n * @throws {ChaveNFeError} When `body` is not exactly 43 digits.\n */\nexport function chaveNFeCheckDigit(body: string): number {\n if (!new RegExp(`^\\\\d{${CHAVE_BODY_LENGTH}}$`).test(body)) {\n throw new ChaveNFeError(\n `The check digit is computed over ${CHAVE_BODY_LENGTH} digits, got ${body.length}.`,\n );\n }\n const span = DV_WEIGHT_LAST - DV_WEIGHT_FIRST + 1;\n let sum = 0;\n for (let index = 0; index < body.length; index += 1) {\n const fromRight = body.length - 1 - index;\n sum += Number(body[index]) * (DV_WEIGHT_FIRST + (fromRight % span));\n }\n const remainder = sum % 11;\n return remainder === 0 || remainder === 1 ? 0 : 11 - remainder;\n}\n\n/**\n * Whether a fiscal access key is well formed.\n *\n * Three things have to hold: 44 digits, a `cUF` that is a real federative unit,\n * and a check digit that recomputes. It says nothing about whether the document\n * exists or was authorised — only SEFAZ can answer that — but it catches the\n * failure that actually happens, a key transcribed by hand or truncated by a\n * spreadsheet.\n *\n * @param chave - The key, with or without the spaces a DANFE prints.\n * @returns `true` when all three hold.\n *\n * @example\n * if (!validateChaveNFe(input)) setError(\"Chave inválida.\");\n */\nexport function validateChaveNFe(chave: string): boolean {\n const raw = digits(chave);\n if (raw.length !== CHAVE_LENGTH) return false;\n if (UF_BY_CODE[raw.slice(0, 2)] === undefined) return false;\n return String(chaveNFeCheckDigit(raw.slice(0, CHAVE_BODY_LENGTH))) === raw.slice(43);\n}\n\n/**\n * Read a 44-digit fiscal access key into its fields.\n *\n * The layout is fixed and shared by every document type that carries a key —\n * NF-e, NFC-e, CT-e, MDF-e — so `modelo` is what tells you which one you are\n * holding, not the length.\n *\n * ```text\n * 35 2601 12345678000195 55 001 000000123 1 12345678 4\n * cUF AAMM CNPJ mod série nNF tp cNF cDV\n * ```\n *\n * @param chave - The key, with or without the spaces a DANFE prints.\n * @returns The parsed key.\n * @throws {ChaveNFeError} On a length other than 44, an unknown `cUF`, a month\n * outside 1-12, or a check digit that does not recompute.\n *\n * @example\n * const { uf, cnpj, numero, modeloLabel } = parseChaveNFe(scanned);\n */\nexport function parseChaveNFe(chave: string): ChaveNFe {\n const raw = digits(chave);\n if (raw.length !== CHAVE_LENGTH) {\n throw new ChaveNFeError(`An access key has ${CHAVE_LENGTH} digits, got ${raw.length}.`);\n }\n\n const cUF = raw.slice(0, 2);\n const uf = UF_BY_CODE[cUF];\n if (uf === undefined) {\n throw new ChaveNFeError(`${cUF} is not an IBGE code for a federative unit.`);\n }\n\n const anoMes = raw.slice(2, 6);\n const mes = Number(anoMes.slice(2, 4));\n if (mes < 1 || mes > 12) {\n throw new ChaveNFeError(`Month ${anoMes.slice(2, 4)} in AAMM is not a month.`);\n }\n\n const dv = raw.slice(43);\n const expected = chaveNFeCheckDigit(raw.slice(0, CHAVE_BODY_LENGTH));\n if (String(expected) !== dv) {\n throw new ChaveNFeError(`Check digit is ${dv}, recomputed ${expected}.`);\n }\n\n const modelo = raw.slice(20, 22);\n const tipoEmissao = raw.slice(34, 35);\n return {\n uf,\n cUF,\n anoMes,\n ano: CHAVE_YEAR_BASE + Number(anoMes.slice(0, 2)),\n mes,\n cnpj: raw.slice(6, 20),\n modelo,\n modeloLabel: MODELO_LABELS[modelo] ?? null,\n serie: raw.slice(22, 25),\n numero: raw.slice(25, 34),\n tipoEmissao,\n tipoEmissaoLabel: TIPO_EMISSAO_LABELS[tipoEmissao] ?? null,\n codigoNumerico: raw.slice(35, 43),\n dv,\n };\n}\n\n/**\n * Group a key in blocks of four, the way a DANFE prints it.\n *\n * @param chave - The key, masked or not.\n * @returns Eleven groups of four digits separated by spaces, or the input\n * unchanged when it is not 44 digits — this is a display helper, not a validator.\n *\n * @example\n * formatChaveNFe(\"35260112345678000195550010000001231123456784\");\n * // \"3526 0112 3456 7800 0195 5500 1000 0001 2311 2345 6784\"\n */\nexport function formatChaveNFe(chave: string): string {\n const raw = digits(chave);\n if (raw.length !== CHAVE_LENGTH) return chave;\n return raw.replace(/(\\d{4})(?=\\d)/g, \"$1 \");\n}\n"],"mappings":"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"}
package/dist/br/nfe.js ADDED
@@ -0,0 +1,104 @@
1
+ //#region src/br/nfe.ts
2
+ var e = class extends Error {
3
+ constructor(e) {
4
+ super(e), this.name = "ChaveNFeError";
5
+ }
6
+ }, t = {
7
+ 11: "RO",
8
+ 12: "AC",
9
+ 13: "AM",
10
+ 14: "RR",
11
+ 15: "PA",
12
+ 16: "AP",
13
+ 17: "TO",
14
+ 21: "MA",
15
+ 22: "PI",
16
+ 23: "CE",
17
+ 24: "RN",
18
+ 25: "PB",
19
+ 26: "PE",
20
+ 27: "AL",
21
+ 28: "SE",
22
+ 29: "BA",
23
+ 31: "MG",
24
+ 32: "ES",
25
+ 33: "RJ",
26
+ 35: "SP",
27
+ 41: "PR",
28
+ 42: "SC",
29
+ 43: "RS",
30
+ 50: "MS",
31
+ 51: "MT",
32
+ 52: "GO",
33
+ 53: "DF"
34
+ }, n = {
35
+ 55: "NF-e",
36
+ 57: "CT-e",
37
+ 58: "MDF-e",
38
+ 59: "SAT-CF-e",
39
+ 63: "BP-e",
40
+ 65: "NFC-e",
41
+ 66: "NF3e",
42
+ 67: "CT-e OS"
43
+ }, r = {
44
+ 1: "Normal",
45
+ 2: "Contingência FS-IA",
46
+ 3: "Contingência SCAN",
47
+ 4: "Contingência DPEC/EPEC",
48
+ 5: "Contingência FS-DA",
49
+ 6: "Contingência SVC-AN",
50
+ 7: "Contingência SVC-RS",
51
+ 9: "Contingência off-line (NFC-e)"
52
+ }, i = 2, a = 44, o = 43, s = 2e3;
53
+ function c(e) {
54
+ return e.replace(/\D/g, "");
55
+ }
56
+ function l(t) {
57
+ if (!RegExp(`^\\d{${o}}$`).test(t)) throw new e(`The check digit is computed over ${o} digits, got ${t.length}.`);
58
+ let n = 0;
59
+ for (let e = 0; e < t.length; e += 1) {
60
+ let r = t.length - 1 - e;
61
+ n += Number(t[e]) * (i + r % 8);
62
+ }
63
+ let r = n % 11;
64
+ return r === 0 || r === 1 ? 0 : 11 - r;
65
+ }
66
+ function u(e) {
67
+ let n = c(e);
68
+ return n.length !== a || t[n.slice(0, 2)] === void 0 ? !1 : String(l(n.slice(0, o))) === n.slice(43);
69
+ }
70
+ function d(i) {
71
+ let u = c(i);
72
+ if (u.length !== a) throw new e(`An access key has ${a} digits, got ${u.length}.`);
73
+ let d = u.slice(0, 2), f = t[d];
74
+ if (f === void 0) throw new e(`${d} is not an IBGE code for a federative unit.`);
75
+ let p = u.slice(2, 6), m = Number(p.slice(2, 4));
76
+ if (m < 1 || m > 12) throw new e(`Month ${p.slice(2, 4)} in AAMM is not a month.`);
77
+ let h = u.slice(43), g = l(u.slice(0, o));
78
+ if (String(g) !== h) throw new e(`Check digit is ${h}, recomputed ${g}.`);
79
+ let _ = u.slice(20, 22), v = u.slice(34, 35);
80
+ return {
81
+ uf: f,
82
+ cUF: d,
83
+ anoMes: p,
84
+ ano: s + Number(p.slice(0, 2)),
85
+ mes: m,
86
+ cnpj: u.slice(6, 20),
87
+ modelo: _,
88
+ modeloLabel: n[_] ?? null,
89
+ serie: u.slice(22, 25),
90
+ numero: u.slice(25, 34),
91
+ tipoEmissao: v,
92
+ tipoEmissaoLabel: r[v] ?? null,
93
+ codigoNumerico: u.slice(35, 43),
94
+ dv: h
95
+ };
96
+ }
97
+ function f(e) {
98
+ let t = c(e);
99
+ return t.length === a ? t.replace(/(\d{4})(?=\d)/g, "$1 ") : e;
100
+ }
101
+ //#endregion
102
+ export { e as ChaveNFeError, l as chaveNFeCheckDigit, f as formatChaveNFe, d as parseChaveNFe, u as validateChaveNFe };
103
+
104
+ //# sourceMappingURL=nfe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nfe.js","names":[],"sources":["../../src/br/nfe.ts"],"sourcesContent":["import type { UF } from \"./locations\";\n\n/**\n * A 44-digit fiscal access key could not be read.\n *\n * Its own class so a scanner screen can tell a bad key apart from a bug and show\n * the message to the operator unchanged.\n */\nexport class ChaveNFeError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ChaveNFeError\";\n }\n}\n\n/** A fiscal access key taken apart. */\nexport interface ChaveNFe {\n /** Federative unit of the issuer, resolved from {@link cUF}. */\n uf: UF;\n /** The raw 2-digit IBGE code, positions 1-2. */\n cUF: string;\n /** Positions 3-6, `AAMM` — the two-digit year and the month of issue. */\n anoMes: string;\n /** Four-digit year derived from {@link anoMes}. */\n ano: number;\n /** Month of issue, 1-12. */\n mes: number;\n /** Positions 7-20, the issuer's CNPJ. */\n cnpj: string;\n /** Positions 21-22, `mod`. `\"55\"` is an NF-e, `\"65\"` an NFC-e. */\n modelo: string;\n /** Human label for {@link modelo}, or `null` for a model outside the table. */\n modeloLabel: string | null;\n /** Positions 23-25. */\n serie: string;\n /** Positions 26-34, `nNF`. */\n numero: string;\n /** Position 35, `tpEmis`. */\n tipoEmissao: string;\n /** Human label for {@link tipoEmissao}, or `null` for a value outside the table. */\n tipoEmissaoLabel: string | null;\n /** Positions 36-43, `cNF` — the issuer's random code. */\n codigoNumerico: string;\n /** Position 44, `cDV`. */\n dv: string;\n}\n\n/**\n * IBGE code of each federative unit, as `cUF` carries it.\n *\n * Only the numeric codes live here — the acronyms are the `UF` union from\n * `./locations`, so a state added or renamed there flows through. Ported from the\n * IBGE table of \"códigos dos municípios\" (the two leading digits of every\n * municipality code), which is the same table the NF-e manual points at.\n */\nconst UF_BY_CODE: Record<string, UF> = {\n \"11\": \"RO\",\n \"12\": \"AC\",\n \"13\": \"AM\",\n \"14\": \"RR\",\n \"15\": \"PA\",\n \"16\": \"AP\",\n \"17\": \"TO\",\n \"21\": \"MA\",\n \"22\": \"PI\",\n \"23\": \"CE\",\n \"24\": \"RN\",\n \"25\": \"PB\",\n \"26\": \"PE\",\n \"27\": \"AL\",\n \"28\": \"SE\",\n \"29\": \"BA\",\n \"31\": \"MG\",\n \"32\": \"ES\",\n \"33\": \"RJ\",\n \"35\": \"SP\",\n \"41\": \"PR\",\n \"42\": \"SC\",\n \"43\": \"RS\",\n \"50\": \"MS\",\n \"51\": \"MT\",\n \"52\": \"GO\",\n \"53\": \"DF\",\n};\n\n/** The document models that share the 44-digit key layout. */\nconst MODELO_LABELS: Record<string, string> = {\n \"55\": \"NF-e\",\n \"57\": \"CT-e\",\n \"58\": \"MDF-e\",\n \"59\": \"SAT-CF-e\",\n \"63\": \"BP-e\",\n \"65\": \"NFC-e\",\n \"66\": \"NF3e\",\n \"67\": \"CT-e OS\",\n};\n\n/** `tpEmis` values from the NF-e manual. */\nconst TIPO_EMISSAO_LABELS: Record<string, string> = {\n \"1\": \"Normal\",\n \"2\": \"Contingência FS-IA\",\n \"3\": \"Contingência SCAN\",\n \"4\": \"Contingência DPEC/EPEC\",\n \"5\": \"Contingência FS-DA\",\n \"6\": \"Contingência SVC-AN\",\n \"7\": \"Contingência SVC-RS\",\n \"9\": \"Contingência off-line (NFC-e)\",\n};\n\n/** Weight cycle of the módulo 11 check digit, applied right to left. */\nconst DV_WEIGHT_FIRST = 2;\nconst DV_WEIGHT_LAST = 9;\n\n/** Length of the key, and of the body the check digit protects. */\nconst CHAVE_LENGTH = 44;\nconst CHAVE_BODY_LENGTH = 43;\n\n/** Century the two-digit `AAMM` year resolves into. NF-e went live in 2006. */\nconst CHAVE_YEAR_BASE = 2000;\n\n/** Digits of a key that may carry spaces or dots from a copy-paste. */\nfunction digits(value: string): string {\n return value.replace(/\\D/g, \"\");\n}\n\n/**\n * The check digit a 43-digit key body requires.\n *\n * Módulo 11: each digit is multiplied by weights cycling `2…9` from right to\n * left, the products are summed, and the digit is `11 - (sum mod 11)` — except\n * that a remainder of `0` or `1` yields `0`, since `11` and `10` do not fit one\n * position.\n *\n * Note this is the **fiscal** flavour of módulo 11. The cobrança boleto resolves\n * those same remainders to `1`; see `mod11DacCobranca` in `./boleto`.\n *\n * @param body - The first 43 digits of the key.\n * @returns The check digit, 0-9.\n * @throws {ChaveNFeError} When `body` is not exactly 43 digits.\n */\nexport function chaveNFeCheckDigit(body: string): number {\n if (!new RegExp(`^\\\\d{${CHAVE_BODY_LENGTH}}$`).test(body)) {\n throw new ChaveNFeError(\n `The check digit is computed over ${CHAVE_BODY_LENGTH} digits, got ${body.length}.`,\n );\n }\n const span = DV_WEIGHT_LAST - DV_WEIGHT_FIRST + 1;\n let sum = 0;\n for (let index = 0; index < body.length; index += 1) {\n const fromRight = body.length - 1 - index;\n sum += Number(body[index]) * (DV_WEIGHT_FIRST + (fromRight % span));\n }\n const remainder = sum % 11;\n return remainder === 0 || remainder === 1 ? 0 : 11 - remainder;\n}\n\n/**\n * Whether a fiscal access key is well formed.\n *\n * Three things have to hold: 44 digits, a `cUF` that is a real federative unit,\n * and a check digit that recomputes. It says nothing about whether the document\n * exists or was authorised — only SEFAZ can answer that — but it catches the\n * failure that actually happens, a key transcribed by hand or truncated by a\n * spreadsheet.\n *\n * @param chave - The key, with or without the spaces a DANFE prints.\n * @returns `true` when all three hold.\n *\n * @example\n * if (!validateChaveNFe(input)) setError(\"Chave inválida.\");\n */\nexport function validateChaveNFe(chave: string): boolean {\n const raw = digits(chave);\n if (raw.length !== CHAVE_LENGTH) return false;\n if (UF_BY_CODE[raw.slice(0, 2)] === undefined) return false;\n return String(chaveNFeCheckDigit(raw.slice(0, CHAVE_BODY_LENGTH))) === raw.slice(43);\n}\n\n/**\n * Read a 44-digit fiscal access key into its fields.\n *\n * The layout is fixed and shared by every document type that carries a key —\n * NF-e, NFC-e, CT-e, MDF-e — so `modelo` is what tells you which one you are\n * holding, not the length.\n *\n * ```text\n * 35 2601 12345678000195 55 001 000000123 1 12345678 4\n * cUF AAMM CNPJ mod série nNF tp cNF cDV\n * ```\n *\n * @param chave - The key, with or without the spaces a DANFE prints.\n * @returns The parsed key.\n * @throws {ChaveNFeError} On a length other than 44, an unknown `cUF`, a month\n * outside 1-12, or a check digit that does not recompute.\n *\n * @example\n * const { uf, cnpj, numero, modeloLabel } = parseChaveNFe(scanned);\n */\nexport function parseChaveNFe(chave: string): ChaveNFe {\n const raw = digits(chave);\n if (raw.length !== CHAVE_LENGTH) {\n throw new ChaveNFeError(`An access key has ${CHAVE_LENGTH} digits, got ${raw.length}.`);\n }\n\n const cUF = raw.slice(0, 2);\n const uf = UF_BY_CODE[cUF];\n if (uf === undefined) {\n throw new ChaveNFeError(`${cUF} is not an IBGE code for a federative unit.`);\n }\n\n const anoMes = raw.slice(2, 6);\n const mes = Number(anoMes.slice(2, 4));\n if (mes < 1 || mes > 12) {\n throw new ChaveNFeError(`Month ${anoMes.slice(2, 4)} in AAMM is not a month.`);\n }\n\n const dv = raw.slice(43);\n const expected = chaveNFeCheckDigit(raw.slice(0, CHAVE_BODY_LENGTH));\n if (String(expected) !== dv) {\n throw new ChaveNFeError(`Check digit is ${dv}, recomputed ${expected}.`);\n }\n\n const modelo = raw.slice(20, 22);\n const tipoEmissao = raw.slice(34, 35);\n return {\n uf,\n cUF,\n anoMes,\n ano: CHAVE_YEAR_BASE + Number(anoMes.slice(0, 2)),\n mes,\n cnpj: raw.slice(6, 20),\n modelo,\n modeloLabel: MODELO_LABELS[modelo] ?? null,\n serie: raw.slice(22, 25),\n numero: raw.slice(25, 34),\n tipoEmissao,\n tipoEmissaoLabel: TIPO_EMISSAO_LABELS[tipoEmissao] ?? null,\n codigoNumerico: raw.slice(35, 43),\n dv,\n };\n}\n\n/**\n * Group a key in blocks of four, the way a DANFE prints it.\n *\n * @param chave - The key, masked or not.\n * @returns Eleven groups of four digits separated by spaces, or the input\n * unchanged when it is not 44 digits — this is a display helper, not a validator.\n *\n * @example\n * formatChaveNFe(\"35260112345678000195550010000001231123456784\");\n * // \"3526 0112 3456 7800 0195 5500 1000 0001 2311 2345 6784\"\n */\nexport function formatChaveNFe(chave: string): string {\n const raw = digits(chave);\n if (raw.length !== CHAVE_LENGTH) return chave;\n return raw.replace(/(\\d{4})(?=\\d)/g, \"$1 \");\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ const e=require("../forms/br-validators.cjs");var t=class extends Error{constructor(e){super(e),this.name=`PixError`}},n=4129,r=65535,i=65535,a=`00`,o=`01`,s=`26`,c=`52`,l=`53`,u=`54`,d=`58`,f=`59`,p=`60`,m=`61`,h=`62`,g=`63`,_=`00`,v=`01`,y=`02`,b=`25`,x=`05`,S=`br.gov.bcb.pix`,C=`01`,w=`11`,T=`12`,E=`0000`,D=`986`,O=`BR`,k=`***`,A=25,j=15,M=25,N=99,P=77;function F(e){let t=new TextEncoder().encode(e),a=r;for(let e of t){a^=e<<8;for(let e=0;e<8;e+=1)a=a&32768?(a<<1^n)&i:a<<1&i}return a.toString(16).toUpperCase().padStart(4,`0`)}function I(e){return e.replace(/\D/g,``)}function L(e,n){let r=e.normalize(`NFD`).replace(/\p{Diacritic}/gu,``);if(/[^\x20-\x7E]/.test(r))throw new t(`${n} has characters the BR Code cannot carry: ${JSON.stringify(e)}. Use unaccented ASCII.`);return r}function R(e,n){if(n.length>N)throw new t(`Tag ${e} is ${n.length} characters; the EMV length field holds at most ${N}.`);return`${e}${String(n.length).padStart(2,`0`)}${n}`}function z(t){let n=t.trim();if(n===``)return null;if(n.includes(`@`))return/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(n)&&n.length<=P?`email`:null;if(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(n))return`evp`;let r=I(n);return r.length===14?e.validateCNPJ(r)?`cnpj`:null:r.length===11&&e.validateCPF(r)?`cpf`:n.startsWith(`+`)?/^\+55\d{10,11}$/.test(`+${r}`)?`phone`:null:r.length===10||r.length===11||(r.length===12||r.length===13)&&r.startsWith(`55`)?`phone`:null}function B(e){let n=e.trim(),r=z(n);if(r===null)throw new t(`Not a Pix key: ${JSON.stringify(e)}. Expected a CPF, CNPJ, e-mail, phone (+5511987654321) or EVP (UUID).`);if(r===`email`||r===`evp`)return{type:r,value:n.toLowerCase()};if(r===`phone`){let e=I(n);return{type:r,value:`+55${e.length>11?e.slice(2):e}`}}return{type:r,value:I(n)}}function V(e){if(!Number.isFinite(e))throw new t(`Amount must be a finite number, got ${e}.`);if(e<=0)throw new t(`Amount must be positive, got ${e}. Omit \`amount\` for a QR whose value the payer types.`);let n=e.toFixed(2);if(n.length>13)throw new t(`Amount ${n} does not fit tag 54, which holds 13 characters.`);return n}function H(e,n,r){let i=L(e.trim(),r);if(i===``)throw new t(`${r} is required.`);if(i.length>n)throw new t(`${r} is ${i.length} characters; the BR Code allows ${n}. Shorten it — truncating here would silently change what the payer sees.`);return i}function U(e){let n=e?.trim()??``;if(n===``||n===k)return R(h,R(x,k));if(!RegExp(`^[A-Za-z0-9]{1,${M}}$`).test(n))throw new t(`txid must be 1 to ${M} letters or digits, got ${JSON.stringify(e)}.`);return R(h,R(x,n))}function W(e){let{value:n}=B(e.key),r=R(_,S)+R(v,n),i=e.description?.trim();if(i!==void 0&&i!==``&&(r+=R(y,L(i,`description`))),r.length>N)throw new t(`Tag 26 is ${r.length} characters, over the ${N} the length field allows. Shorten \`description\`.`);return R(s,r)}function G(e){let n=L(e.url.trim(),`url`).replace(/^https?:\/\//i,``);if(n===``)throw new t(`url is required for a dynamic BR Code.`);let r=R(_,S)+R(b,n);if(r.length>N)throw new t(`Tag 26 is ${r.length} characters, over the ${N} the length field allows. Shorten the payload URL.`);return R(s,r)}function K(e){let t=e.kind===`dynamic`,n=e.oneTime??t,r=R(a,C);r+=R(o,n?T:w),r+=t?G(e):W(e),r+=R(c,E),r+=R(l,D),!t&&e.amount!==void 0&&(r+=R(u,V(e.amount))),r+=R(d,O),r+=R(f,H(e.merchantName,A,`merchantName`)),r+=R(p,H(e.merchantCity,j,`merchantCity`));let i=e.postalCode===void 0?``:I(e.postalCode);i!==``&&(r+=R(m,i)),r+=U(t?k:e.txid);let s=`${r}${g}04`;return`${s}${F(s)}`}function q(e,n){let r=[],i=0;for(;i<e.length;){let a=e.slice(i,i+2),o=e.slice(i+2,i+4);if(!/^\d{2}$/.test(a)||!/^\d{2}$/.test(o))throw new t(`Malformed TLV in ${n} at offset ${i}: expected a 2-digit tag and length.`);let s=Number(o),c=i+4;if(c+s>e.length)throw new t(`Tag ${a} in ${n} declares ${s} characters but only ${e.length-c} remain.`);r.push({id:a,value:e.slice(c,c+s)}),i=c+s}return r}function J(e,t){return e.find(e=>e.id===t)?.value}function Y(e,n={}){let{requireCrc:r=!0}=n,i=e.trim();if(i.length<8)throw new t(`Payload is too short to be a BR Code.`);let a=i.length-8;if(i.slice(a,a+4)!==`${g}04`)throw new t("Payload does not end in a `6304` CRC tag.");let C=i.slice(-4).toUpperCase(),w=F(i.slice(0,-4)),E=C===w;if(!E&&r)throw new t(`CRC mismatch: payload says ${C}, recomputed ${w}.`);let D=q(i.slice(0,a),`payload`),O=J(D,s);if(O===void 0)throw new t(`Payload has no tag 26 (merchant account information).`);let k=q(O,`tag 26`),A=J(k,_);if(A?.toLowerCase()!==S)throw new t(`Tag 26 is not a Pix account: expected GUI ${S}, got ${JSON.stringify(A)}.`);let j=J(k,b),M=J(k,v),N=J(D,u),P=J(q(J(D,h)??``,`tag 62`),x);return{kind:j!==void 0&&M===void 0?`dynamic`:`static`,...M===void 0?{}:{key:M,keyType:z(M)??void 0},...j===void 0?{}:{url:j},merchantName:J(D,f)??``,merchantCity:J(D,p)??``,...N===void 0?{}:{amount:Number(N)},currency:J(D,l)??``,countryCode:J(D,d)??``,merchantCategoryCode:J(D,c)??``,...P===void 0?{}:{txid:P},...J(k,y)===void 0?{}:{description:J(k,y)},...J(D,m)===void 0?{}:{postalCode:J(D,m)},oneTime:J(D,o)===T,crc:C,crcValid:E,fields:D}}exports.PixError=t,exports.normalizePixKey=B,exports.parsePixPayload=Y,exports.pixCrc16=F,exports.pixKeyType=z,exports.pixPayload=K;
2
+ //# sourceMappingURL=pix.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pix.cjs","names":[],"sources":["../../src/br/pix.ts"],"sourcesContent":["import { validateCNPJ, validateCPF } from \"@/forms/br-validators\";\n\n/**\n * A Pix payload could not be built or read.\n *\n * Its own class so a caller can tell \"the operator typed a bad key\" apart from a\n * bug, and so an `ErrorBoundary` can render a form error instead of a crash.\n */\nexport class PixError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"PixError\";\n }\n}\n\n/** The five key formats DICT accepts. */\nexport type PixKeyType = \"cpf\" | \"cnpj\" | \"email\" | \"phone\" | \"evp\";\n\n/** A key after normalisation, ready to go into the payload. */\nexport interface NormalizedPixKey {\n type: PixKeyType;\n /** The exact string written into the BR Code. */\n value: string;\n}\n\n/** One TLV as it appeared in a payload, unknown tags included. */\nexport interface PixField {\n /** Two-character tag, e.g. `\"59\"`. */\n id: string;\n /** Raw value, still encoded when the tag is itself a template. */\n value: string;\n}\n\n/** A BR Code that carries the key — the one you print on a poster. */\nexport interface PixStaticInput {\n kind?: \"static\";\n /** CPF, CNPJ, e-mail, phone or EVP. Validated and normalised. */\n key: string;\n /** Payee name. Truncated by the spec at 25 characters — longer throws. */\n merchantName: string;\n /** Payee city. Truncated by the spec at 15 characters — longer throws. */\n merchantCity: string;\n /** Amount in BRL. Omit for a payer-chooses-the-value QR. */\n amount?: number;\n /** Reference the PSP echoes back, `[A-Za-z0-9]{1,25}`. Defaults to `\"***\"`. */\n txid?: string;\n /** Free text shown by some wallets. Goes into tag 26, sub-tag 02. */\n description?: string;\n /** CEP, digits only. Optional tag 61. */\n postalCode?: string;\n /** Single-use QR: sets tag 01 to `\"12\"` instead of `\"11\"`. */\n oneTime?: boolean;\n}\n\n/** A BR Code that carries a URL the wallet fetches to learn the amount. */\nexport interface PixDynamicInput {\n kind: \"dynamic\";\n /**\n * `payloadLocation` — the https URL the wallet GETs, **without** the scheme,\n * exactly as BACEN specifies (`pix.example.com/qr/v2/abc`).\n */\n url: string;\n merchantName: string;\n merchantCity: string;\n postalCode?: string;\n /** Single-use QR. Defaults to `true`, which is what a dynamic QR normally is. */\n oneTime?: boolean;\n}\n\n/** Everything `pixPayload` accepts. */\nexport type PixInput = PixStaticInput | PixDynamicInput;\n\n/** A payload taken apart again. */\nexport interface PixData {\n /** `\"dynamic\"` when tag 26 carried a URL instead of a key. */\n kind: \"static\" | \"dynamic\";\n /** Present on a static payload. */\n key?: string;\n keyType?: PixKeyType;\n /** Present on a dynamic payload. */\n url?: string;\n merchantName: string;\n merchantCity: string;\n /** Reais. `undefined` when the payer chooses the amount. */\n amount?: number;\n /** ISO 4217 numeric. `\"986\"` for BRL. */\n currency: string;\n countryCode: string;\n merchantCategoryCode: string;\n /** `\"***\"` on a reusable static QR that identifies no single transaction. */\n txid?: string;\n description?: string;\n postalCode?: string;\n /** Tag 01 read as `\"12\"`. */\n oneTime: boolean;\n /** The four hex characters that closed the payload. */\n crc: string;\n /** Whether those four characters match a recomputed CRC. */\n crcValid: boolean;\n /** Every top-level TLV, in payload order, unknown tags included. */\n fields: PixField[];\n}\n\n/** Options for {@link parsePixPayload}. */\nexport interface ParsePixOptions {\n /**\n * Throw when the checksum does not match. Default `true`.\n *\n * Turn it off only to inspect a payload you already know is broken: a BR Code\n * whose CRC fails has been corrupted in transit, and the account it now points\n * at is not the account the payee published.\n */\n requireCrc?: boolean;\n}\n\n/**\n * Generator polynomial of CRC-16/CCITT-FALSE, `x^16 + x^12 + x^5 + 1`.\n *\n * Taken from the CRC catalogue entry `CRC-16/IBM-3740` (alias CCITT-FALSE):\n * `width=16 poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000\n * check=0x29b1`. The BACEN \"Manual de Padrões para Iniciação do Pix\" names this\n * exact variant for tag 63.\n */\nconst CRC16_POLYNOMIAL = 0x1021;\n\n/** Register preset of CRC-16/CCITT-FALSE. Not zero — that is a different variant. */\nconst CRC16_INITIAL = 0xffff;\n\n/** Keeps the shift register 16 bits wide. */\nconst CRC16_MASK = 0xffff;\n\nconst TAG_PAYLOAD_FORMAT = \"00\";\nconst TAG_POINT_OF_INITIATION = \"01\";\nconst TAG_MERCHANT_ACCOUNT_INFO = \"26\";\nconst TAG_MERCHANT_CATEGORY_CODE = \"52\";\nconst TAG_TRANSACTION_CURRENCY = \"53\";\nconst TAG_TRANSACTION_AMOUNT = \"54\";\nconst TAG_COUNTRY_CODE = \"58\";\nconst TAG_MERCHANT_NAME = \"59\";\nconst TAG_MERCHANT_CITY = \"60\";\nconst TAG_POSTAL_CODE = \"61\";\nconst TAG_ADDITIONAL_DATA = \"62\";\nconst TAG_CRC = \"63\";\n\nconst MAI_TAG_GUI = \"00\";\nconst MAI_TAG_KEY = \"01\";\nconst MAI_TAG_DESCRIPTION = \"02\";\nconst MAI_TAG_URL = \"25\";\nconst ADDITIONAL_TAG_TXID = \"05\";\n\n/** Globally Unique Identifier that marks tag 26 as a Pix account. */\nconst PIX_GUI = \"br.gov.bcb.pix\";\n\nconst PAYLOAD_FORMAT_VERSION = \"01\";\nconst POINT_OF_INITIATION_REUSABLE = \"11\";\nconst POINT_OF_INITIATION_SINGLE_USE = \"12\";\nconst DEFAULT_MERCHANT_CATEGORY_CODE = \"0000\";\nconst CURRENCY_BRL = \"986\";\nconst COUNTRY_BR = \"BR\";\nconst TXID_UNSPECIFIED = \"***\";\n\nconst MAX_MERCHANT_NAME = 25;\nconst MAX_MERCHANT_CITY = 15;\nconst MAX_TXID = 25;\nconst MAX_TLV_VALUE = 99;\nconst MAX_EMAIL_KEY = 77;\n\n/**\n * CRC-16/CCITT-FALSE of a string, as four upper-case hex characters.\n *\n * Bitwise rather than table-driven: 200-odd characters at 8 shifts each is\n * nothing, and a 256-entry table is 2 KB of payload every consumer of the `/br`\n * entry would carry.\n *\n * The input is taken as UTF-8 bytes. A Pix payload is ASCII by construction —\n * {@link pixPayload} rejects anything else — but the function is exported and a\n * caller may hand it arbitrary text, and hashing UTF-16 code units would then\n * disagree with every other implementation.\n *\n * @param input - Bytes to run through the register.\n * @returns Four upper-case hex characters, zero-padded.\n *\n * @example\n * pixCrc16(\"123456789\"); // \"29B1\" — the catalogue check value\n */\nexport function pixCrc16(input: string): string {\n const bytes = new TextEncoder().encode(input);\n let crc = CRC16_INITIAL;\n for (const byte of bytes) {\n crc ^= byte << 8;\n for (let bit = 0; bit < 8; bit += 1) {\n crc =\n (crc & 0x8000) !== 0\n ? ((crc << 1) ^ CRC16_POLYNOMIAL) & CRC16_MASK\n : (crc << 1) & CRC16_MASK;\n }\n }\n return crc.toString(16).toUpperCase().padStart(4, \"0\");\n}\n\n/** Digits of a possibly masked value. */\nfunction digits(value: string): string {\n return value.replace(/\\D/g, \"\");\n}\n\n/**\n * Drop diacritics and reject whatever is left outside printable ASCII.\n *\n * The BR Code character set has no room for accents, and a wallet that meets one\n * either fails to parse the QR or shows mojibake. Stripping them is lossy but\n * legible (\"São Paulo\" → \"Sao Paulo\"), which beats both alternatives; anything\n * that is not a diacritic — an emoji, a CJK character — is a mistake the caller\n * has to see, so it throws.\n */\nfunction toPayloadText(value: string, field: string): string {\n const stripped = value.normalize(\"NFD\").replace(/\\p{Diacritic}/gu, \"\");\n if (/[^\\x20-\\x7E]/.test(stripped)) {\n throw new PixError(\n `${field} has characters the BR Code cannot carry: ${JSON.stringify(value)}. ` +\n \"Use unaccented ASCII.\",\n );\n }\n return stripped;\n}\n\n/** One `ID + 2-digit length + value` triple. */\nfunction tlv(id: string, value: string): string {\n if (value.length > MAX_TLV_VALUE) {\n throw new PixError(\n `Tag ${id} is ${value.length} characters; the EMV length field holds at most ${MAX_TLV_VALUE}.`,\n );\n }\n return `${id}${String(value.length).padStart(2, \"0\")}${value}`;\n}\n\n/**\n * Classify a Pix key, or `null` when it matches no accepted format.\n *\n * !!! warning \"CPF and a national phone number are both eleven digits\"\n * `\"11987654321\"` is a valid mobile number and could be a CPF. The check\n * digits break the tie: an 11-digit string is a CPF when its DV validates and\n * a phone otherwise. Pass phone keys as `+5511987654321` to remove the guess\n * entirely.\n *\n * @param key - Raw key, masked or not.\n * @returns The key type, or `null`.\n */\nexport function pixKeyType(key: string): PixKeyType | null {\n const trimmed = key.trim();\n if (trimmed === \"\") return null;\n\n if (trimmed.includes(\"@\")) {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]{2,}$/.test(trimmed) && trimmed.length <= MAX_EMAIL_KEY\n ? \"email\"\n : null;\n }\n if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(trimmed)) {\n return \"evp\";\n }\n\n const numbers = digits(trimmed);\n if (numbers.length === 14) return validateCNPJ(numbers) ? \"cnpj\" : null;\n if (numbers.length === 11 && validateCPF(numbers)) return \"cpf\";\n if (trimmed.startsWith(\"+\")) {\n return /^\\+55\\d{10,11}$/.test(`+${numbers}`) ? \"phone\" : null;\n }\n if (numbers.length === 10 || numbers.length === 11) return \"phone\";\n if (numbers.length === 12 || numbers.length === 13) {\n return numbers.startsWith(\"55\") ? \"phone\" : null;\n }\n return null;\n}\n\n/**\n * Validate a Pix key and return the exact string to write into the payload.\n *\n * Normalisation per type: CPF and CNPJ lose their mask, a phone becomes E.164\n * with the `+55` country code, an EVP is lower-cased, and an e-mail is\n * lower-cased because DICT stores it that way — a key that differs only in case\n * would otherwise fail to resolve.\n *\n * All validation lives in {@link pixKeyType}; past that gate the normalisation is\n * total, which is why the phone branch strips a country code purely on length\n * rather than re-checking the shape.\n *\n * @param key - Raw key, masked or not.\n * @returns The type and the normalised value.\n * @throws {PixError} When the key matches no accepted format, or when a document\n * key fails its check digits.\n *\n * @example\n * normalizePixKey(\"123.456.789-09\"); // { type: \"cpf\", value: \"12345678909\" }\n * normalizePixKey(\"(11) 98765-4321\"); // { type: \"phone\", value: \"+5511987654321\" }\n */\nexport function normalizePixKey(key: string): NormalizedPixKey {\n const trimmed = key.trim();\n const type = pixKeyType(trimmed);\n if (type === null) {\n throw new PixError(\n `Not a Pix key: ${JSON.stringify(key)}. Expected a CPF, CNPJ, e-mail, ` +\n \"phone (+5511987654321) or EVP (UUID).\",\n );\n }\n\n if (type === \"email\") return { type, value: trimmed.toLowerCase() };\n if (type === \"evp\") return { type, value: trimmed.toLowerCase() };\n if (type === \"phone\") {\n const numbers = digits(trimmed);\n return { type, value: `+55${numbers.length > 11 ? numbers.slice(2) : numbers}` };\n }\n return { type, value: digits(trimmed) };\n}\n\n/** Format an amount the way tag 54 wants it: dot separator, two decimals. */\nfunction toAmountField(amount: number): string {\n if (!Number.isFinite(amount)) {\n throw new PixError(`Amount must be a finite number, got ${amount}.`);\n }\n if (amount <= 0) {\n throw new PixError(\n `Amount must be positive, got ${amount}. Omit \\`amount\\` for a QR whose value the payer types.`,\n );\n }\n const field = amount.toFixed(2);\n if (field.length > 13) {\n throw new PixError(`Amount ${field} does not fit tag 54, which holds 13 characters.`);\n }\n return field;\n}\n\n/** Bound the two free-text identity fields the spec caps hard. */\nfunction toBoundedText(value: string, max: number, field: string): string {\n const text = toPayloadText(value.trim(), field);\n if (text === \"\") throw new PixError(`${field} is required.`);\n if (text.length > max) {\n throw new PixError(\n `${field} is ${text.length} characters; the BR Code allows ${max}. Shorten it — ` +\n \"truncating here would silently change what the payer sees.\",\n );\n }\n return text;\n}\n\n/** Tag 62, which exists only to carry the txid. */\nfunction additionalDataField(txid: string | undefined): string {\n const value = txid?.trim() ?? \"\";\n if (value === \"\" || value === TXID_UNSPECIFIED) {\n return tlv(TAG_ADDITIONAL_DATA, tlv(ADDITIONAL_TAG_TXID, TXID_UNSPECIFIED));\n }\n if (!new RegExp(`^[A-Za-z0-9]{1,${MAX_TXID}}$`).test(value)) {\n throw new PixError(\n `txid must be 1 to ${MAX_TXID} letters or digits, got ${JSON.stringify(txid)}.`,\n );\n }\n return tlv(TAG_ADDITIONAL_DATA, tlv(ADDITIONAL_TAG_TXID, value));\n}\n\n/** Tag 26 for a static payload: GUI, key and the optional description. */\nfunction staticMerchantAccount(input: PixStaticInput): string {\n const { value } = normalizePixKey(input.key);\n let inner = tlv(MAI_TAG_GUI, PIX_GUI) + tlv(MAI_TAG_KEY, value);\n const description = input.description?.trim();\n if (description !== undefined && description !== \"\") {\n inner += tlv(MAI_TAG_DESCRIPTION, toPayloadText(description, \"description\"));\n }\n if (inner.length > MAX_TLV_VALUE) {\n throw new PixError(\n `Tag 26 is ${inner.length} characters, over the ${MAX_TLV_VALUE} the length field allows. ` +\n \"Shorten `description`.\",\n );\n }\n return tlv(TAG_MERCHANT_ACCOUNT_INFO, inner);\n}\n\n/** Tag 26 for a dynamic payload: GUI plus the URL, and no key. */\nfunction dynamicMerchantAccount(input: PixDynamicInput): string {\n const url = toPayloadText(input.url.trim(), \"url\").replace(/^https?:\\/\\//i, \"\");\n if (url === \"\") throw new PixError(\"url is required for a dynamic BR Code.\");\n const inner = tlv(MAI_TAG_GUI, PIX_GUI) + tlv(MAI_TAG_URL, url);\n if (inner.length > MAX_TLV_VALUE) {\n throw new PixError(\n `Tag 26 is ${inner.length} characters, over the ${MAX_TLV_VALUE} the length field allows. ` +\n \"Shorten the payload URL.\",\n );\n }\n return tlv(TAG_MERCHANT_ACCOUNT_INFO, inner);\n}\n\n/**\n * Build a Pix \"Copia e Cola\" payload — the string behind a Pix QR code.\n *\n * The format is EMVCo MPM: a flat list of `ID + 2-digit length + value` triples,\n * closed by tag 63 holding a CRC-16/CCITT-FALSE over **everything before it,\n * including the literal `6304` header of tag 63 itself**. That last detail is the\n * one implementations get wrong; see {@link pixCrc16}.\n *\n * Two shapes come out of here:\n *\n * - **static** — tag 26 carries the key, so the QR is self-contained and can be\n * printed. Amount optional; a txid of `\"***\"` means \"identifies no single\n * transaction\", which is what a reusable poster QR wants.\n * - **dynamic** — tag 26 carries a URL instead, and the wallet fetches the amount\n * and payee from the PSP. Use it when the value is per-order. Defaults to\n * single-use (tag 01 = `12`).\n *\n * The distinction matters and is not cosmetic: a static QR settles against\n * whatever the payer typed, a dynamic one against what the PSP served, so a\n * charge that must reconcile to a cent needs the dynamic form.\n *\n * @param input - Static or dynamic payload description.\n * @returns The full payload, CRC included, ready to render as a QR or to copy.\n * @throws {PixError} On an unrecognised key, a field over its length cap, a\n * non-positive amount, or text that is not representable in the BR Code.\n *\n * @example\n * pixPayload({\n * key: \"12345678909\",\n * merchantName: \"Loja Tempest\",\n * merchantCity: \"São Paulo\",\n * amount: 25.5,\n * txid: \"PEDIDO123\",\n * });\n */\nexport function pixPayload(input: PixInput): string {\n const dynamic = input.kind === \"dynamic\";\n const oneTime = input.oneTime ?? dynamic;\n\n let payload = tlv(TAG_PAYLOAD_FORMAT, PAYLOAD_FORMAT_VERSION);\n payload += tlv(\n TAG_POINT_OF_INITIATION,\n oneTime ? POINT_OF_INITIATION_SINGLE_USE : POINT_OF_INITIATION_REUSABLE,\n );\n payload += dynamic ? dynamicMerchantAccount(input) : staticMerchantAccount(input);\n payload += tlv(TAG_MERCHANT_CATEGORY_CODE, DEFAULT_MERCHANT_CATEGORY_CODE);\n payload += tlv(TAG_TRANSACTION_CURRENCY, CURRENCY_BRL);\n if (!dynamic && input.amount !== undefined) {\n payload += tlv(TAG_TRANSACTION_AMOUNT, toAmountField(input.amount));\n }\n payload += tlv(TAG_COUNTRY_CODE, COUNTRY_BR);\n payload += tlv(\n TAG_MERCHANT_NAME,\n toBoundedText(input.merchantName, MAX_MERCHANT_NAME, \"merchantName\"),\n );\n payload += tlv(\n TAG_MERCHANT_CITY,\n toBoundedText(input.merchantCity, MAX_MERCHANT_CITY, \"merchantCity\"),\n );\n const postalCode = input.postalCode === undefined ? \"\" : digits(input.postalCode);\n if (postalCode !== \"\") payload += tlv(TAG_POSTAL_CODE, postalCode);\n payload += additionalDataField(dynamic ? TXID_UNSPECIFIED : input.txid);\n\n const withCrcHeader = `${payload}${TAG_CRC}04`;\n return `${withCrcHeader}${pixCrc16(withCrcHeader)}`;\n}\n\n/**\n * Split a flat run of TLVs. Stops cleanly at the first malformed triple.\n *\n * @throws {PixError} When a length prefix is not two digits or runs past the end.\n */\nfunction parseTlv(input: string, where: string): PixField[] {\n const fields: PixField[] = [];\n let cursor = 0;\n while (cursor < input.length) {\n const id = input.slice(cursor, cursor + 2);\n const rawLength = input.slice(cursor + 2, cursor + 4);\n if (!/^\\d{2}$/.test(id) || !/^\\d{2}$/.test(rawLength)) {\n throw new PixError(\n `Malformed TLV in ${where} at offset ${cursor}: expected a 2-digit tag and length.`,\n );\n }\n const length = Number(rawLength);\n const start = cursor + 4;\n if (start + length > input.length) {\n throw new PixError(\n `Tag ${id} in ${where} declares ${length} characters but only ${input.length - start} remain.`,\n );\n }\n fields.push({ id, value: input.slice(start, start + length) });\n cursor = start + length;\n }\n return fields;\n}\n\n/** First value for a tag, or `undefined`. */\nfunction pick(fields: readonly PixField[], id: string): string | undefined {\n return fields.find((field) => field.id === id)?.value;\n}\n\n/**\n * Read a Pix \"Copia e Cola\" payload back into its parts.\n *\n * Tolerant by design: tags the SDK does not know about are kept verbatim in\n * {@link PixData.fields} instead of raising, because PSPs do add their own\n * templates and a reader that rejects them is useless in production. What is\n * *not* tolerated is a broken frame — a length prefix that runs off the end, a\n * missing tag 63 — or a checksum mismatch, which means the string was corrupted\n * and no longer names the account the payee published.\n *\n * @param payload - The copia-e-cola string. Surrounding whitespace is ignored.\n * @param options - See {@link ParsePixOptions}.\n * @returns The decoded payload.\n * @throws {PixError} On a malformed frame, a missing CRC tag, a tag 26 that is\n * not a Pix account, or — unless `requireCrc` is `false` — a CRC mismatch.\n *\n * @example\n * const data = parsePixPayload(copied);\n * console.log(data.key, data.amount, data.txid);\n */\nexport function parsePixPayload(payload: string, options: ParsePixOptions = {}): PixData {\n const { requireCrc = true } = options;\n const text = payload.trim();\n if (text.length < 8) throw new PixError(\"Payload is too short to be a BR Code.\");\n\n const crcHeaderAt = text.length - 8;\n if (text.slice(crcHeaderAt, crcHeaderAt + 4) !== `${TAG_CRC}04`) {\n throw new PixError(\"Payload does not end in a `6304` CRC tag.\");\n }\n const crc = text.slice(-4).toUpperCase();\n const expected = pixCrc16(text.slice(0, -4));\n const crcValid = crc === expected;\n if (!crcValid && requireCrc) {\n throw new PixError(`CRC mismatch: payload says ${crc}, recomputed ${expected}.`);\n }\n\n const fields = parseTlv(text.slice(0, crcHeaderAt), \"payload\");\n const merchantAccount = pick(fields, TAG_MERCHANT_ACCOUNT_INFO);\n if (merchantAccount === undefined) {\n throw new PixError(\"Payload has no tag 26 (merchant account information).\");\n }\n const account = parseTlv(merchantAccount, \"tag 26\");\n const gui = pick(account, MAI_TAG_GUI);\n if (gui?.toLowerCase() !== PIX_GUI) {\n throw new PixError(\n `Tag 26 is not a Pix account: expected GUI ${PIX_GUI}, got ${JSON.stringify(gui)}.`,\n );\n }\n\n const url = pick(account, MAI_TAG_URL);\n const key = pick(account, MAI_TAG_KEY);\n const amountField = pick(fields, TAG_TRANSACTION_AMOUNT);\n const txid = pick(\n parseTlv(pick(fields, TAG_ADDITIONAL_DATA) ?? \"\", \"tag 62\"),\n ADDITIONAL_TAG_TXID,\n );\n\n return {\n kind: url !== undefined && key === undefined ? \"dynamic\" : \"static\",\n ...(key === undefined ? {} : { key, keyType: pixKeyType(key) ?? undefined }),\n ...(url === undefined ? {} : { url }),\n merchantName: pick(fields, TAG_MERCHANT_NAME) ?? \"\",\n merchantCity: pick(fields, TAG_MERCHANT_CITY) ?? \"\",\n ...(amountField === undefined ? {} : { amount: Number(amountField) }),\n currency: pick(fields, TAG_TRANSACTION_CURRENCY) ?? \"\",\n countryCode: pick(fields, TAG_COUNTRY_CODE) ?? \"\",\n merchantCategoryCode: pick(fields, TAG_MERCHANT_CATEGORY_CODE) ?? \"\",\n ...(txid === undefined ? {} : { txid }),\n ...(pick(account, MAI_TAG_DESCRIPTION) === undefined\n ? {}\n : { description: pick(account, MAI_TAG_DESCRIPTION) }),\n ...(pick(fields, TAG_POSTAL_CODE) === undefined\n ? {}\n : { postalCode: pick(fields, TAG_POSTAL_CODE) }),\n oneTime: pick(fields, TAG_POINT_OF_INITIATION) === POINT_OF_INITIATION_SINGLE_USE,\n crc,\n crcValid,\n fields,\n };\n}\n"],"mappings":"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"}
package/dist/br/pix.js ADDED
@@ -0,0 +1,148 @@
1
+ import { validateCNPJ as e, validateCPF as t } from "../forms/br-validators.js";
2
+ //#region src/br/pix.ts
3
+ var n = class extends Error {
4
+ constructor(e) {
5
+ super(e), this.name = "PixError";
6
+ }
7
+ }, r = 4129, i = 65535, a = 65535, o = "00", s = "01", c = "26", l = "52", u = "53", d = "54", f = "58", p = "59", m = "60", h = "61", g = "62", _ = "63", v = "00", y = "01", b = "02", x = "25", S = "05", C = "br.gov.bcb.pix", w = "01", T = "11", E = "12", D = "0000", O = "986", k = "BR", A = "***", j = 25, M = 15, N = 25, P = 99, F = 77;
8
+ function I(e) {
9
+ let t = new TextEncoder().encode(e), n = i;
10
+ for (let e of t) {
11
+ n ^= e << 8;
12
+ for (let e = 0; e < 8; e += 1) n = n & 32768 ? (n << 1 ^ r) & a : n << 1 & a;
13
+ }
14
+ return n.toString(16).toUpperCase().padStart(4, "0");
15
+ }
16
+ function L(e) {
17
+ return e.replace(/\D/g, "");
18
+ }
19
+ function R(e, t) {
20
+ let r = e.normalize("NFD").replace(/\p{Diacritic}/gu, "");
21
+ if (/[^\x20-\x7E]/.test(r)) throw new n(`${t} has characters the BR Code cannot carry: ${JSON.stringify(e)}. Use unaccented ASCII.`);
22
+ return r;
23
+ }
24
+ function z(e, t) {
25
+ if (t.length > P) throw new n(`Tag ${e} is ${t.length} characters; the EMV length field holds at most ${P}.`);
26
+ return `${e}${String(t.length).padStart(2, "0")}${t}`;
27
+ }
28
+ function B(n) {
29
+ let r = n.trim();
30
+ if (r === "") return null;
31
+ if (r.includes("@")) return /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/.test(r) && r.length <= F ? "email" : null;
32
+ if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(r)) return "evp";
33
+ let i = L(r);
34
+ return i.length === 14 ? e(i) ? "cnpj" : null : i.length === 11 && t(i) ? "cpf" : r.startsWith("+") ? /^\+55\d{10,11}$/.test(`+${i}`) ? "phone" : null : i.length === 10 || i.length === 11 || (i.length === 12 || i.length === 13) && i.startsWith("55") ? "phone" : null;
35
+ }
36
+ function V(e) {
37
+ let t = e.trim(), r = B(t);
38
+ if (r === null) throw new n(`Not a Pix key: ${JSON.stringify(e)}. Expected a CPF, CNPJ, e-mail, phone (+5511987654321) or EVP (UUID).`);
39
+ if (r === "email" || r === "evp") return {
40
+ type: r,
41
+ value: t.toLowerCase()
42
+ };
43
+ if (r === "phone") {
44
+ let e = L(t);
45
+ return {
46
+ type: r,
47
+ value: `+55${e.length > 11 ? e.slice(2) : e}`
48
+ };
49
+ }
50
+ return {
51
+ type: r,
52
+ value: L(t)
53
+ };
54
+ }
55
+ function H(e) {
56
+ if (!Number.isFinite(e)) throw new n(`Amount must be a finite number, got ${e}.`);
57
+ if (e <= 0) throw new n(`Amount must be positive, got ${e}. Omit \`amount\` for a QR whose value the payer types.`);
58
+ let t = e.toFixed(2);
59
+ if (t.length > 13) throw new n(`Amount ${t} does not fit tag 54, which holds 13 characters.`);
60
+ return t;
61
+ }
62
+ function U(e, t, r) {
63
+ let i = R(e.trim(), r);
64
+ if (i === "") throw new n(`${r} is required.`);
65
+ if (i.length > t) throw new n(`${r} is ${i.length} characters; the BR Code allows ${t}. Shorten it — truncating here would silently change what the payer sees.`);
66
+ return i;
67
+ }
68
+ function W(e) {
69
+ let t = e?.trim() ?? "";
70
+ if (t === "" || t === A) return z(g, z(S, A));
71
+ if (!RegExp(`^[A-Za-z0-9]{1,${N}}$`).test(t)) throw new n(`txid must be 1 to ${N} letters or digits, got ${JSON.stringify(e)}.`);
72
+ return z(g, z(S, t));
73
+ }
74
+ function G(e) {
75
+ let { value: t } = V(e.key), r = z(v, C) + z(y, t), i = e.description?.trim();
76
+ if (i !== void 0 && i !== "" && (r += z(b, R(i, "description"))), r.length > P) throw new n(`Tag 26 is ${r.length} characters, over the ${P} the length field allows. Shorten \`description\`.`);
77
+ return z(c, r);
78
+ }
79
+ function K(e) {
80
+ let t = R(e.url.trim(), "url").replace(/^https?:\/\//i, "");
81
+ if (t === "") throw new n("url is required for a dynamic BR Code.");
82
+ let r = z(v, C) + z(x, t);
83
+ if (r.length > P) throw new n(`Tag 26 is ${r.length} characters, over the ${P} the length field allows. Shorten the payload URL.`);
84
+ return z(c, r);
85
+ }
86
+ function q(e) {
87
+ let t = e.kind === "dynamic", n = e.oneTime ?? t, r = z(o, w);
88
+ r += z(s, n ? E : T), r += t ? K(e) : G(e), r += z(l, D), r += z(u, O), !t && e.amount !== void 0 && (r += z(d, H(e.amount))), r += z(f, k), r += z(p, U(e.merchantName, j, "merchantName")), r += z(m, U(e.merchantCity, M, "merchantCity"));
89
+ let i = e.postalCode === void 0 ? "" : L(e.postalCode);
90
+ i !== "" && (r += z(h, i)), r += W(t ? A : e.txid);
91
+ let a = `${r}${_}04`;
92
+ return `${a}${I(a)}`;
93
+ }
94
+ function J(e, t) {
95
+ let r = [], i = 0;
96
+ for (; i < e.length;) {
97
+ let a = e.slice(i, i + 2), o = e.slice(i + 2, i + 4);
98
+ if (!/^\d{2}$/.test(a) || !/^\d{2}$/.test(o)) throw new n(`Malformed TLV in ${t} at offset ${i}: expected a 2-digit tag and length.`);
99
+ let s = Number(o), c = i + 4;
100
+ if (c + s > e.length) throw new n(`Tag ${a} in ${t} declares ${s} characters but only ${e.length - c} remain.`);
101
+ r.push({
102
+ id: a,
103
+ value: e.slice(c, c + s)
104
+ }), i = c + s;
105
+ }
106
+ return r;
107
+ }
108
+ function Y(e, t) {
109
+ return e.find((e) => e.id === t)?.value;
110
+ }
111
+ function X(e, t = {}) {
112
+ let { requireCrc: r = !0 } = t, i = e.trim();
113
+ if (i.length < 8) throw new n("Payload is too short to be a BR Code.");
114
+ let a = i.length - 8;
115
+ if (i.slice(a, a + 4) !== `${_}04`) throw new n("Payload does not end in a `6304` CRC tag.");
116
+ let o = i.slice(-4).toUpperCase(), w = I(i.slice(0, -4)), T = o === w;
117
+ if (!T && r) throw new n(`CRC mismatch: payload says ${o}, recomputed ${w}.`);
118
+ let D = J(i.slice(0, a), "payload"), O = Y(D, c);
119
+ if (O === void 0) throw new n("Payload has no tag 26 (merchant account information).");
120
+ let k = J(O, "tag 26"), A = Y(k, v);
121
+ if (A?.toLowerCase() !== C) throw new n(`Tag 26 is not a Pix account: expected GUI ${C}, got ${JSON.stringify(A)}.`);
122
+ let j = Y(k, x), M = Y(k, y), N = Y(D, d), P = Y(J(Y(D, g) ?? "", "tag 62"), S);
123
+ return {
124
+ kind: j !== void 0 && M === void 0 ? "dynamic" : "static",
125
+ ...M === void 0 ? {} : {
126
+ key: M,
127
+ keyType: B(M) ?? void 0
128
+ },
129
+ ...j === void 0 ? {} : { url: j },
130
+ merchantName: Y(D, p) ?? "",
131
+ merchantCity: Y(D, m) ?? "",
132
+ ...N === void 0 ? {} : { amount: Number(N) },
133
+ currency: Y(D, u) ?? "",
134
+ countryCode: Y(D, f) ?? "",
135
+ merchantCategoryCode: Y(D, l) ?? "",
136
+ ...P === void 0 ? {} : { txid: P },
137
+ ...Y(k, b) === void 0 ? {} : { description: Y(k, b) },
138
+ ...Y(D, h) === void 0 ? {} : { postalCode: Y(D, h) },
139
+ oneTime: Y(D, s) === E,
140
+ crc: o,
141
+ crcValid: T,
142
+ fields: D
143
+ };
144
+ }
145
+ //#endregion
146
+ export { n as PixError, V as normalizePixKey, X as parsePixPayload, I as pixCrc16, B as pixKeyType, q as pixPayload };
147
+
148
+ //# sourceMappingURL=pix.js.map