arcli 1.8.0 → 2.1.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 (280) hide show
  1. package/CHANGELOG.md +110 -1
  2. package/README.md +17 -16
  3. package/dist/cli/arca-runtime.d.ts +20 -0
  4. package/dist/cli/arca-runtime.js +42 -0
  5. package/dist/cli/arca-runtime.js.map +1 -0
  6. package/dist/cli/commands/billing.command.batch.d.ts +15 -5
  7. package/dist/cli/commands/billing.command.batch.js +28 -11
  8. package/dist/cli/commands/billing.command.batch.js.map +1 -1
  9. package/dist/cli/commands/billing.command.interactive-preview.js +4 -1
  10. package/dist/cli/commands/billing.command.interactive-preview.js.map +1 -1
  11. package/dist/cli/commands/billing.command.options.js +18 -16
  12. package/dist/cli/commands/billing.command.options.js.map +1 -1
  13. package/dist/cli/commands/billing.command.output.d.ts +4 -0
  14. package/dist/cli/commands/billing.command.output.js +3 -2
  15. package/dist/cli/commands/billing.command.output.js.map +1 -1
  16. package/dist/cli/commands/billing.command.parser.d.ts +7 -0
  17. package/dist/cli/commands/billing.command.parser.js +85 -43
  18. package/dist/cli/commands/billing.command.parser.js.map +1 -1
  19. package/dist/cli/commands/billing.command.pdf.d.ts +1 -1
  20. package/dist/cli/commands/billing.command.pdf.js +17 -2
  21. package/dist/cli/commands/billing.command.pdf.js.map +1 -1
  22. package/dist/cli/commands/billing.command.shared.d.ts +22 -3
  23. package/dist/cli/commands/billing.command.shared.js +84 -47
  24. package/dist/cli/commands/billing.command.shared.js.map +1 -1
  25. package/dist/cli/commands/config.command.d.ts +3 -4
  26. package/dist/cli/commands/config.command.js +43 -41
  27. package/dist/cli/commands/config.command.js.map +1 -1
  28. package/dist/cli/commands/cuit-argument.d.ts +2 -0
  29. package/dist/cli/commands/cuit-argument.js +10 -0
  30. package/dist/cli/commands/cuit-argument.js.map +1 -0
  31. package/dist/cli/commands/fce-obligation.command.js +6 -13
  32. package/dist/cli/commands/fce-obligation.command.js.map +1 -1
  33. package/dist/cli/commands/interactive.command.js +8 -6
  34. package/dist/cli/commands/interactive.command.js.map +1 -1
  35. package/dist/cli/commands/padron.command.d.ts +2 -0
  36. package/dist/cli/commands/padron.command.js +47 -0
  37. package/dist/cli/commands/padron.command.js.map +1 -0
  38. package/dist/cli/commands/parameters.command.js +8 -7
  39. package/dist/cli/commands/parameters.command.js.map +1 -1
  40. package/dist/cli/commands/pdf.command.js +17 -30
  41. package/dist/cli/commands/pdf.command.js.map +1 -1
  42. package/dist/cli/commands/vouchers.command.js +9 -9
  43. package/dist/cli/commands/vouchers.command.js.map +1 -1
  44. package/dist/cli/error-output.d.ts +25 -0
  45. package/dist/cli/error-output.js +86 -0
  46. package/dist/cli/error-output.js.map +1 -0
  47. package/dist/cli/global-options.d.ts +26 -0
  48. package/dist/cli/global-options.js +56 -0
  49. package/dist/cli/global-options.js.map +1 -0
  50. package/dist/cli/help-argv.d.ts +5 -0
  51. package/dist/cli/help-argv.js +21 -0
  52. package/dist/cli/help-argv.js.map +1 -0
  53. package/dist/cli/help.d.ts +2 -0
  54. package/dist/cli/help.js +78 -31
  55. package/dist/cli/help.js.map +1 -1
  56. package/dist/cli/ignored-global-options.d.ts +6 -0
  57. package/dist/cli/ignored-global-options.js +33 -0
  58. package/dist/cli/ignored-global-options.js.map +1 -0
  59. package/dist/cli/index.js +16 -26
  60. package/dist/cli/index.js.map +1 -1
  61. package/dist/cli/interactive/advanced-options.js +2 -2
  62. package/dist/cli/interactive/advanced-options.js.map +1 -1
  63. package/dist/cli/interactive/config.flow.d.ts +1 -2
  64. package/dist/cli/interactive/config.flow.js +4 -3
  65. package/dist/cli/interactive/config.flow.js.map +1 -1
  66. package/dist/cli/interactive/interactive-mode.js +108 -9
  67. package/dist/cli/interactive/interactive-mode.js.map +1 -1
  68. package/dist/cli/interactive/invoice-picker.js +3 -2
  69. package/dist/cli/interactive/invoice-picker.js.map +1 -1
  70. package/dist/cli/interactive/invoice.flow.d.ts +2 -0
  71. package/dist/cli/interactive/invoice.flow.js +4 -3
  72. package/dist/cli/interactive/invoice.flow.js.map +1 -1
  73. package/dist/cli/interactive/note.flow.d.ts +4 -0
  74. package/dist/cli/interactive/note.flow.js +25 -11
  75. package/dist/cli/interactive/note.flow.js.map +1 -1
  76. package/dist/cli/interactive/pdf.flow.js +33 -22
  77. package/dist/cli/interactive/pdf.flow.js.map +1 -1
  78. package/dist/cli/interactive/prompts.d.ts +3 -1
  79. package/dist/cli/interactive/prompts.js +8 -4
  80. package/dist/cli/interactive/prompts.js.map +1 -1
  81. package/dist/cli/interactive/receiver-padron.d.ts +29 -0
  82. package/dist/cli/interactive/receiver-padron.js +53 -0
  83. package/dist/cli/interactive/receiver-padron.js.map +1 -0
  84. package/dist/cli/interactive/repeat.flow.js +25 -10
  85. package/dist/cli/interactive/repeat.flow.js.map +1 -1
  86. package/dist/cli/interactive/session.js +4 -1
  87. package/dist/cli/interactive/session.js.map +1 -1
  88. package/dist/cli/interactive/update.flow.d.ts +6 -0
  89. package/dist/cli/interactive/update.flow.js +26 -0
  90. package/dist/cli/interactive/update.flow.js.map +1 -0
  91. package/dist/cli/interactive/validators.js +8 -4
  92. package/dist/cli/interactive/validators.js.map +1 -1
  93. package/dist/cli/option-parsers.d.ts +6 -0
  94. package/dist/cli/option-parsers.js +34 -0
  95. package/dist/cli/option-parsers.js.map +1 -0
  96. package/dist/cli/program.d.ts +5 -1
  97. package/dist/cli/program.js +8 -2
  98. package/dist/cli/program.js.map +1 -1
  99. package/dist/cli/version.d.ts +1 -1
  100. package/dist/cli/version.js +1 -1
  101. package/dist/lib/dates/arca-date.d.ts +13 -0
  102. package/dist/lib/dates/arca-date.js +28 -11
  103. package/dist/lib/dates/arca-date.js.map +1 -1
  104. package/dist/lib/errors/app-error.d.ts +4 -1
  105. package/dist/lib/errors/app-error.js +5 -1
  106. package/dist/lib/errors/app-error.js.map +1 -1
  107. package/dist/lib/files/restrict-to-owner.d.ts +7 -0
  108. package/dist/lib/files/restrict-to-owner.js +19 -0
  109. package/dist/lib/files/restrict-to-owner.js.map +1 -0
  110. package/dist/lib/files/write-new-file.d.ts +5 -0
  111. package/dist/lib/files/write-new-file.js +30 -0
  112. package/dist/lib/files/write-new-file.js.map +1 -0
  113. package/dist/lib/identity/format-cuit.d.ts +2 -0
  114. package/dist/lib/identity/format-cuit.js +6 -0
  115. package/dist/lib/identity/format-cuit.js.map +1 -0
  116. package/dist/lib/links.d.ts +2 -0
  117. package/dist/lib/links.js +2 -0
  118. package/dist/lib/links.js.map +1 -1
  119. package/dist/lib/numbers/argentine-amount.d.ts +23 -0
  120. package/dist/lib/numbers/argentine-amount.js +37 -0
  121. package/dist/lib/numbers/argentine-amount.js.map +1 -0
  122. package/dist/lib/numbers/strict-integer.d.ts +4 -0
  123. package/dist/lib/numbers/strict-integer.js +10 -0
  124. package/dist/lib/numbers/strict-integer.js.map +1 -0
  125. package/dist/lib/security/certificate.d.ts +5 -1
  126. package/dist/lib/security/certificate.js +10 -7
  127. package/dist/lib/security/certificate.js.map +1 -1
  128. package/dist/lib/security/pem.js +5 -1
  129. package/dist/lib/security/pem.js.map +1 -1
  130. package/dist/modules/billing/billing-response.js +15 -2
  131. package/dist/modules/billing/billing-response.js.map +1 -1
  132. package/dist/modules/billing/billing.amounts.d.ts +2 -0
  133. package/dist/modules/billing/billing.amounts.js +6 -3
  134. package/dist/modules/billing/billing.amounts.js.map +1 -1
  135. package/dist/modules/billing/billing.associated-vouchers.js +14 -3
  136. package/dist/modules/billing/billing.associated-vouchers.js.map +1 -1
  137. package/dist/modules/billing/billing.batch.js +13 -1
  138. package/dist/modules/billing/billing.batch.js.map +1 -1
  139. package/dist/modules/billing/billing.date-range.js +31 -9
  140. package/dist/modules/billing/billing.date-range.js.map +1 -1
  141. package/dist/modules/billing/billing.display.js +9 -5
  142. package/dist/modules/billing/billing.display.js.map +1 -1
  143. package/dist/modules/billing/billing.errors.d.ts +12 -0
  144. package/dist/modules/billing/billing.errors.js +18 -0
  145. package/dist/modules/billing/billing.errors.js.map +1 -0
  146. package/dist/modules/billing/billing.json-input.d.ts +58 -0
  147. package/dist/modules/billing/billing.json-input.js +279 -0
  148. package/dist/modules/billing/billing.json-input.js.map +1 -0
  149. package/dist/modules/billing/billing.padron.d.ts +14 -0
  150. package/dist/modules/billing/billing.padron.js +55 -0
  151. package/dist/modules/billing/billing.padron.js.map +1 -0
  152. package/dist/modules/billing/billing.schemas.d.ts +5 -0
  153. package/dist/modules/billing/billing.schemas.js +19 -5
  154. package/dist/modules/billing/billing.schemas.js.map +1 -1
  155. package/dist/modules/billing/billing.serialize.d.ts +1 -0
  156. package/dist/modules/billing/billing.serialize.js +5 -12
  157. package/dist/modules/billing/billing.serialize.js.map +1 -1
  158. package/dist/modules/billing/billing.service.d.ts +3 -0
  159. package/dist/modules/billing/billing.service.js +31 -3
  160. package/dist/modules/billing/billing.service.js.map +1 -1
  161. package/dist/modules/billing/billing.text.js +4 -12
  162. package/dist/modules/billing/billing.text.js.map +1 -1
  163. package/dist/modules/billing/billing.types.internal.d.ts +10 -2
  164. package/dist/modules/billing/billing.validation.js +4 -0
  165. package/dist/modules/billing/billing.validation.js.map +1 -1
  166. package/dist/modules/config/certificate-expiry.d.ts +42 -0
  167. package/dist/modules/config/certificate-expiry.js +91 -0
  168. package/dist/modules/config/certificate-expiry.js.map +1 -0
  169. package/dist/modules/config/config-doctor.d.ts +5 -4
  170. package/dist/modules/config/config-doctor.js +8 -16
  171. package/dist/modules/config/config-doctor.js.map +1 -1
  172. package/dist/modules/config/config-value-parser.d.ts +1 -1
  173. package/dist/modules/config/config-value-parser.js +24 -20
  174. package/dist/modules/config/config-value-parser.js.map +1 -1
  175. package/dist/modules/config/config.presenter.d.ts +2 -0
  176. package/dist/modules/config/config.presenter.js +6 -0
  177. package/dist/modules/config/config.presenter.js.map +1 -1
  178. package/dist/modules/config/config.schemas.d.ts +4 -2
  179. package/dist/modules/config/config.schemas.js +3 -0
  180. package/dist/modules/config/config.schemas.js.map +1 -1
  181. package/dist/modules/config/config.sections.js +6 -1
  182. package/dist/modules/config/config.sections.js.map +1 -1
  183. package/dist/modules/config/config.service.d.ts +5 -0
  184. package/dist/modules/config/config.service.js +62 -14
  185. package/dist/modules/config/config.service.js.map +1 -1
  186. package/dist/modules/examples/examples.d.ts +5 -0
  187. package/dist/modules/examples/examples.js +34 -29
  188. package/dist/modules/examples/examples.js.map +1 -1
  189. package/dist/modules/interactive/amount-input.d.ts +3 -5
  190. package/dist/modules/interactive/amount-input.js +9 -26
  191. package/dist/modules/interactive/amount-input.js.map +1 -1
  192. package/dist/modules/interactive/config-fields.js +8 -1
  193. package/dist/modules/interactive/config-fields.js.map +1 -1
  194. package/dist/modules/interactive/equivalent-command.js +8 -10
  195. package/dist/modules/interactive/equivalent-command.js.map +1 -1
  196. package/dist/modules/interactive/invoice-copy.d.ts +19 -0
  197. package/dist/modules/interactive/invoice-copy.js +26 -0
  198. package/dist/modules/interactive/invoice-copy.js.map +1 -0
  199. package/dist/modules/interactive/periods.d.ts +2 -2
  200. package/dist/modules/interactive/periods.js +8 -4
  201. package/dist/modules/interactive/periods.js.map +1 -1
  202. package/dist/modules/padron/padron.d.ts +46 -0
  203. package/dist/modules/padron/padron.js +24 -0
  204. package/dist/modules/padron/padron.js.map +1 -0
  205. package/dist/modules/padron/padron.presenter.d.ts +7 -0
  206. package/dist/modules/padron/padron.presenter.js +49 -0
  207. package/dist/modules/padron/padron.presenter.js.map +1 -0
  208. package/dist/modules/parameters/health.d.ts +17 -0
  209. package/dist/modules/parameters/health.js +29 -0
  210. package/dist/modules/parameters/health.js.map +1 -0
  211. package/dist/modules/parameters/parameters.presenter.js +5 -2
  212. package/dist/modules/parameters/parameters.presenter.js.map +1 -1
  213. package/dist/modules/pdf/pdf.errors.d.ts +0 -1
  214. package/dist/modules/pdf/pdf.errors.js +1 -3
  215. package/dist/modules/pdf/pdf.errors.js.map +1 -1
  216. package/dist/modules/storybook/showcase.js +21 -5
  217. package/dist/modules/storybook/showcase.js.map +1 -1
  218. package/dist/modules/update-check/changelog.d.ts +23 -0
  219. package/dist/modules/update-check/changelog.js +99 -0
  220. package/dist/modules/update-check/changelog.js.map +1 -0
  221. package/dist/modules/update-check/update-check.presenter.d.ts +4 -0
  222. package/dist/modules/update-check/update-check.presenter.js +80 -2
  223. package/dist/modules/update-check/update-check.presenter.js.map +1 -1
  224. package/dist/modules/update-check/update-check.service.d.ts +3 -0
  225. package/dist/modules/update-check/update-check.service.js +2 -2
  226. package/dist/modules/update-check/update-check.service.js.map +1 -1
  227. package/dist/modules/vouchers/voucher-history.presenter.d.ts +3 -3
  228. package/dist/modules/vouchers/voucher-history.presenter.js +27 -7
  229. package/dist/modules/vouchers/voucher-history.presenter.js.map +1 -1
  230. package/dist/services/arca/arca-billing.gateway.d.ts +8 -2
  231. package/dist/services/arca/arca-billing.gateway.js +17 -2
  232. package/dist/services/arca/arca-billing.gateway.js.map +1 -1
  233. package/dist/services/arca/arca-client.factory.d.ts +2 -1
  234. package/dist/services/arca/arca-client.factory.js +5 -0
  235. package/dist/services/arca/arca-client.factory.js.map +1 -1
  236. package/dist/services/arca/arca-context.resolver.d.ts +11 -0
  237. package/dist/services/arca/arca-context.resolver.js +17 -1
  238. package/dist/services/arca/arca-context.resolver.js.map +1 -1
  239. package/dist/services/arca/arca-padron.gateway.d.ts +9 -0
  240. package/dist/services/arca/arca-padron.gateway.js +104 -0
  241. package/dist/services/arca/arca-padron.gateway.js.map +1 -0
  242. package/dist/services/clipboard/clipboard.d.ts +2 -0
  243. package/dist/services/clipboard/clipboard.js +17 -0
  244. package/dist/services/clipboard/clipboard.js.map +1 -0
  245. package/dist/services/pdf/escape-html.d.ts +6 -0
  246. package/dist/services/pdf/escape-html.js +25 -0
  247. package/dist/services/pdf/escape-html.js.map +1 -0
  248. package/dist/services/pdf/pdf-exporter.d.ts +6 -3
  249. package/dist/services/pdf/pdf-exporter.js +13 -10
  250. package/dist/services/pdf/pdf-exporter.js.map +1 -1
  251. package/dist/ui/components/certificateBanner.d.ts +11 -0
  252. package/dist/ui/components/certificateBanner.js +9 -0
  253. package/dist/ui/components/certificateBanner.js.map +1 -0
  254. package/dist/ui/components/index.d.ts +1 -0
  255. package/dist/ui/components/index.js +1 -0
  256. package/dist/ui/components/index.js.map +1 -1
  257. package/dist/ui/components/statusBar.d.ts +15 -4
  258. package/dist/ui/components/statusBar.js +16 -11
  259. package/dist/ui/components/statusBar.js.map +1 -1
  260. package/dist/ui/presenters/config.presenter.d.ts +1 -1
  261. package/dist/ui/presenters/config.presenter.js +1 -1
  262. package/dist/ui/presenters/config.presenter.js.map +1 -1
  263. package/dist/ui/presenters/errors.presenter.js +8 -4
  264. package/dist/ui/presenters/errors.presenter.js.map +1 -1
  265. package/dist/ui/presenters/errors.zod-presenter.js +5 -26
  266. package/dist/ui/presenters/errors.zod-presenter.js.map +1 -1
  267. package/dist/ui/primitives/renderLogo.d.ts +2 -1
  268. package/dist/ui/primitives/renderLogo.js +21 -4
  269. package/dist/ui/primitives/renderLogo.js.map +1 -1
  270. package/dist/ui/primitives/renderPanel.d.ts +2 -0
  271. package/dist/ui/primitives/renderPanel.js +15 -5
  272. package/dist/ui/primitives/renderPanel.js.map +1 -1
  273. package/dist/ui/stream/terminal-stream.d.ts +11 -0
  274. package/dist/ui/stream/terminal-stream.js +27 -1
  275. package/dist/ui/stream/terminal-stream.js.map +1 -1
  276. package/dist/ui/theme/theme.d.ts +3 -3
  277. package/dist/ui/theme/theme.js +14 -3
  278. package/dist/ui/theme/theme.js.map +1 -1
  279. package/llms.txt +65 -45
  280. package/package.json +1 -1
@@ -0,0 +1,26 @@
1
+ import { BACK } from '../../modules/interactive/wizard.js';
2
+ import { extractChangelog, fetchChangelog } from '../../modules/update-check/changelog.js';
3
+ import { renderUpdateDetails, UPDATE_COMMAND } from '../../modules/update-check/update-check.presenter.js';
4
+ import { copyToClipboard } from '../../services/clipboard/clipboard.js';
5
+ import { noticePanel, writeTerminalOutput } from '../../ui/index.js';
6
+ import { startSpinner } from '../spinner.js';
7
+ import { chooseStep } from './prompts.js';
8
+ /**
9
+ * Muestra la version nueva y sus novedades. Con "Cerrar para actualizar" copia el comando al portapapeles y
10
+ * devuelve `true` para que el modo interactivo termine: arcli no se puede reemplazar a si mismo mientras corre.
11
+ */
12
+ export async function runUpdateFlow(update) {
13
+ const spinner = startSpinner('Buscando las novedades...');
14
+ const markdown = await fetchChangelog(update.latestVersion);
15
+ spinner?.stop();
16
+ writeTerminalOutput(renderUpdateDetails(update, markdown === undefined ? undefined : extractChangelog(markdown, update.currentVersion, update.latestVersion)));
17
+ // "← Volver" (o Esc) lo agrega chooseStep, igual que en el resto de los menus.
18
+ if ((await chooseStep('¿Actualizamos?', [{ name: 'Cerrar para actualizar', value: 'cerrar' }])) === BACK) {
19
+ return false;
20
+ }
21
+ writeTerminalOutput(copyToClipboard(UPDATE_COMMAND)
22
+ ? noticePanel(`Comando copiado. Pegalo en la terminal y apreta Enter:\n${UPDATE_COMMAND}`, 'success')
23
+ : noticePanel(`No se pudo copiar el comando. Ejecutalo en la terminal:\n${UPDATE_COMMAND}`, 'warning'));
24
+ return true;
25
+ }
26
+ //# sourceMappingURL=update.flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.flow.js","sourceRoot":"","sources":["../../../src/cli/interactive/update.flow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kCAAkC,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACxF,OAAO,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,mDAAmD,CAAC;AAExG,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAyB;IAC3D,MAAM,OAAO,GAAG,YAAY,CAAC,2BAA2B,CAAC,CAAC;IAC1D,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;IAE5D,OAAO,EAAE,IAAI,EAAE,CAAC;IAChB,mBAAmB,CACjB,mBAAmB,CACjB,MAAM,EACN,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,aAAa,CAAC,CAC7G,CACF,CAAC;IAEF,+EAA+E;IAC/E,IAAI,CAAC,MAAM,UAAU,CAAC,gBAAgB,EAAE,CAAC,EAAE,IAAI,EAAE,wBAAwB,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;QACzG,OAAO,KAAK,CAAC;IACf,CAAC;IAED,mBAAmB,CACjB,eAAe,CAAC,cAAc,CAAC;QAC7B,CAAC,CAAC,WAAW,CAAC,2DAA2D,cAAc,EAAE,EAAE,SAAS,CAAC;QACrG,CAAC,CAAC,WAAW,CAAC,4DAA4D,cAAc,EAAE,EAAE,SAAS,CAAC,CACzG,CAAC;IAEF,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -1,7 +1,8 @@
1
1
  import { parseArgentineDateInputAsArcaDate } from '../../lib/dates/arca-date.js';
2
- import { parseAmountInput } from '../../modules/interactive/amount-input.js';
2
+ import { EXCHANGE_RATE_DECIMALS, parseArgentineAmount } from '../../lib/numbers/argentine-amount.js';
3
3
  export function validateAmount(value) {
4
- return parseAmountInput(value) ? true : 'Ingresa un monto mayor a 0, por ejemplo 150000 o 1500,50.';
4
+ const result = parseArgentineAmount(value);
5
+ return result.ok ? true : `Monto invalido: ${result.reason}. Por ejemplo 150000, 150.000 o 1.500,50.`;
5
6
  }
6
7
  export function validateCuit(value) {
7
8
  return /^\d{11}$/.test(value.replace(/-/g, '')) ? true : 'El CUIT tiene 11 digitos.';
@@ -29,7 +30,10 @@ export function validateOptionalAmount(value) {
29
30
  return value.trim() === '' ? true : validateAmount(value);
30
31
  }
31
32
  export function validateExchangeRate(value) {
32
- const rate = parseAmountInput(value);
33
- return rate && rate !== 1 ? true : 'Ingresa la cotizacion acordada, por ejemplo 1200 o 1185,50.';
33
+ const result = parseArgentineAmount(value, { maxDecimals: EXCHANGE_RATE_DECIMALS });
34
+ if (!result.ok) {
35
+ return `Cotizacion invalida: ${result.reason}. Por ejemplo 1200 o 1.185,50.`;
36
+ }
37
+ return result.value !== 1 ? true : 'Ingresa la cotizacion acordada, por ejemplo 1200 o 1.185,50.';
34
38
  }
35
39
  //# sourceMappingURL=validators.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"validators.js","sourceRoot":"","sources":["../../../src/cli/interactive/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAC;AAE1E,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,2DAA2D,CAAC;AACtG,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,2BAA2B,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,6BAA6B,CAAC;AAC3F,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,IAAI,CAAC;QACH,iCAAiC,CAAC,KAAK,CAAC,CAAC;QAEzC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,sEAAsE,CAAC;IAChF,CAAC;AACH,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,OAAO,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAErC,OAAO,IAAI,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,6DAA6D,CAAC;AACnG,CAAC"}
1
+ {"version":3,"file":"validators.js","sourceRoot":"","sources":["../../../src/cli/interactive/validators.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iCAAiC,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAElG,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAE3C,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,MAAM,CAAC,MAAM,2CAA2C,CAAC;AACxG,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,2BAA2B,CAAC;AACvF,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,6BAA6B,CAAC;AAC3F,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,OAAO,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,IAAI,CAAC;QACH,iCAAiC,CAAC,KAAK,CAAC,CAAC;QAEzC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,sEAAsE,CAAC;IAChF,CAAC;AACH,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,OAAO,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,EAAE,EAAE,WAAW,EAAE,sBAAsB,EAAE,CAAC,CAAC;IAEpF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,OAAO,wBAAwB,MAAM,CAAC,MAAM,gCAAgC,CAAC;IAC/E,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,8DAA8D,CAAC;AACpG,CAAC"}
@@ -0,0 +1,6 @@
1
+ /** Montos como en Argentina: punto para miles y coma para decimales. */
2
+ export declare function amountOption(flag: string, maxDecimals?: number): (value: string) => number;
3
+ /** Entero solo con digitos: `--pv 3a` es un error, no un 3. */
4
+ export declare function integerOption(flag: string): (value: string) => number;
5
+ /** CUIT, CUIL o DNI: acepta guiones y puntos (`20-11111111-2`). */
6
+ export declare function documentNumberOption(flag: string): (value: string) => number;
@@ -0,0 +1,34 @@
1
+ import { InputValidationError } from '../lib/errors/app-error.js';
2
+ import { parseArgentineAmount } from '../lib/numbers/argentine-amount.js';
3
+ import { parseDocumentNumber, parseStrictInteger } from '../lib/numbers/strict-integer.js';
4
+ /** Montos como en Argentina: punto para miles y coma para decimales. */
5
+ export function amountOption(flag, maxDecimals) {
6
+ return (value) => {
7
+ const result = parseArgentineAmount(value, { maxDecimals });
8
+ if (!result.ok) {
9
+ throw new InputValidationError(`${flag} "${value}" no es valido: ${result.reason}.`);
10
+ }
11
+ return result.value;
12
+ };
13
+ }
14
+ /** Entero solo con digitos: `--pv 3a` es un error, no un 3. */
15
+ export function integerOption(flag) {
16
+ return (value) => {
17
+ const parsed = parseStrictInteger(value);
18
+ if (parsed === undefined) {
19
+ throw new InputValidationError(`${flag} "${value}" no es valido: tiene que ser un numero entero.`);
20
+ }
21
+ return parsed;
22
+ };
23
+ }
24
+ /** CUIT, CUIL o DNI: acepta guiones y puntos (`20-11111111-2`). */
25
+ export function documentNumberOption(flag) {
26
+ return (value) => {
27
+ const parsed = parseDocumentNumber(value);
28
+ if (parsed === undefined) {
29
+ throw new InputValidationError(`${flag} "${value}" no es valido: use solo numeros, con o sin guiones.`);
30
+ }
31
+ return parsed;
32
+ };
33
+ }
34
+ //# sourceMappingURL=option-parsers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"option-parsers.js","sourceRoot":"","sources":["../../src/cli/option-parsers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAExF,wEAAwE;AACxE,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,WAAoB;IAC7D,OAAO,CAAC,KAAK,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,oBAAoB,CAAC,KAAK,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;QAE5D,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,MAAM,IAAI,oBAAoB,CAAC,GAAG,IAAI,KAAK,KAAK,mBAAmB,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QACvF,CAAC;QAED,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,CAAC,KAAK,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAEzC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,oBAAoB,CAAC,GAAG,IAAI,KAAK,KAAK,iDAAiD,CAAC,CAAC;QACrG,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,CAAC,KAAK,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QAE1C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,oBAAoB,CAAC,GAAG,IAAI,KAAK,KAAK,sDAAsD,CAAC,CAAC;QAC1G,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
@@ -1,2 +1,6 @@
1
1
  import { Command } from 'commander';
2
- export declare function createProgram(): Command;
2
+ export interface CreateProgramOptions {
3
+ /** Si los errores salen en JSON; se consulta recien al fallar. Por defecto, texto. */
4
+ readonly errorsAsJson?: () => boolean;
5
+ }
6
+ export declare function createProgram(options?: CreateProgramOptions): Command;
@@ -1,19 +1,23 @@
1
1
  import { Command } from 'commander';
2
- import { registerGlobalOptions } from './commands/billing.command.shared.js';
3
2
  import { registerBillingFamilyCommands } from './commands/billing-family.command.js';
4
3
  import { registerBillingShortcutCommands } from './commands/billing-shortcuts.command.js';
5
4
  import { registerConfigCommand } from './commands/config.command.js';
6
5
  import { registerExamplesCommand } from './commands/examples.command.js';
7
6
  import { registerFceObligationCommand } from './commands/fce-obligation.command.js';
8
7
  import { registerInteractiveCommand } from './commands/interactive.command.js';
8
+ import { registerPadronCommand } from './commands/padron.command.js';
9
9
  import { registerParametersCommands } from './commands/parameters.command.js';
10
10
  import { registerPdfCommand } from './commands/pdf.command.js';
11
11
  import { registerStorybookCommand } from './commands/storybook.command.js';
12
12
  import { registerVoucherQueryCommands } from './commands/vouchers.command.js';
13
+ import { configureUsageErrors } from './error-output.js';
14
+ import { registerGlobalOptions } from './global-options.js';
13
15
  import { configureSpanishHelp, createProgramHeader, createProgramHelp } from './help.js';
16
+ import { warnAboutIgnoredGlobalOptions } from './ignored-global-options.js';
14
17
  import { CLI_VERSION } from './version.js';
15
- export function createProgram() {
18
+ export function createProgram(options = {}) {
16
19
  const program = new Command();
20
+ configureUsageErrors(program, options.errorsAsJson ?? (() => false));
17
21
  program
18
22
  .name('arcli')
19
23
  .description('Emití y revisá comprobantes ARCA desde terminal con una UX mas simple, validaciones claras y salida lista para automatizar.')
@@ -21,12 +25,14 @@ export function createProgram() {
21
25
  .showHelpAfterError('(usa "ayuda" para ver comandos y ejemplos)');
22
26
  configureSpanishHelp(program);
23
27
  registerGlobalOptions(program);
28
+ warnAboutIgnoredGlobalOptions(program);
24
29
  registerBillingShortcutCommands(program);
25
30
  registerBillingFamilyCommands(program);
26
31
  registerConfigCommand(program);
27
32
  registerExamplesCommand(program);
28
33
  registerFceObligationCommand(program);
29
34
  registerInteractiveCommand(program);
35
+ registerPadronCommand(program);
30
36
  registerPdfCommand(program);
31
37
  registerParametersCommands(program);
32
38
  registerVoucherQueryCommands(program);
@@ -1 +1 @@
1
- {"version":3,"file":"program.js","sourceRoot":"","sources":["../../src/cli/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAC;AACvF,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AACtF,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,OAAO,CAAC;SACb,WAAW,CACV,6HAA6H,CAC9H;SACA,OAAO,CAAC,WAAW,CAAC;SACpB,kBAAkB,CAAC,4CAA4C,CAAC,CAAC;IAEpE,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAE/B,+BAA+B,CAAC,OAAO,CAAC,CAAC;IACzC,6BAA6B,CAAC,OAAO,CAAC,CAAC;IACvC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,4BAA4B,CAAC,OAAO,CAAC,CAAC;IACtC,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACpC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACpC,4BAA4B,CAAC,OAAO,CAAC,CAAC;IACtC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAElC,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtG,OAAO,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEnG,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"program.js","sourceRoot":"","sources":["../../src/cli/program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,6BAA6B,EAAE,MAAM,mCAAmC,CAAC;AAClF,OAAO,EAAE,+BAA+B,EAAE,MAAM,sCAAsC,CAAC;AACvF,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AACjF,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AACtF,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAOxC,MAAM,UAAU,aAAa,CAAC,UAAgC,EAAE;IAC9D,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,YAAY,IAAI,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAErE,OAAO;SACJ,IAAI,CAAC,OAAO,CAAC;SACb,WAAW,CACV,6HAA6H,CAC9H;SACA,OAAO,CAAC,WAAW,CAAC;SACpB,kBAAkB,CAAC,4CAA4C,CAAC,CAAC;IAEpE,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,6BAA6B,CAAC,OAAO,CAAC,CAAC;IAEvC,+BAA+B,CAAC,OAAO,CAAC,CAAC;IACzC,6BAA6B,CAAC,OAAO,CAAC,CAAC;IACvC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,4BAA4B,CAAC,OAAO,CAAC,CAAC;IACtC,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACpC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC5B,0BAA0B,CAAC,OAAO,CAAC,CAAC;IACpC,4BAA4B,CAAC,OAAO,CAAC,CAAC;IACtC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAElC,OAAO,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtG,OAAO,CAAC,WAAW,CAAC,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEnG,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -1 +1 @@
1
- export declare const CLI_VERSION = "1.8.0";
1
+ export declare const CLI_VERSION = "2.1.0";
@@ -1,2 +1,2 @@
1
- export const CLI_VERSION = '1.8.0';
1
+ export const CLI_VERSION = '2.1.0';
2
2
  //# sourceMappingURL=version.js.map
@@ -1,3 +1,16 @@
1
+ export interface CalendarDate {
2
+ readonly day: number;
3
+ /** 1 a 12. */
4
+ readonly month: number;
5
+ readonly year: number;
6
+ }
7
+ /**
8
+ * Dia calendario en Argentina de un instante. ARCA trabaja con la fecha argentina: en un servidor con TZ=UTC,
9
+ * despues de las 21 hs la fecha local ya es la del dia siguiente.
10
+ */
11
+ export declare function toArgentineCalendarDate(value: Date): CalendarDate;
12
+ export declare function calendarDateToArcaDate(value: CalendarDate): string;
13
+ /** Fecha ARCA (yyyymmdd) del dia en Argentina en ese instante. */
1
14
  export declare function formatDateAsArcaDate(value: Date): string;
2
15
  /** Dias entre dos fechas ARCA (yyyymmdd): positivo si `to` es posterior a `from`. */
3
16
  export declare function diffArcaDatesInDays(from: string, to: string): number;
@@ -1,11 +1,25 @@
1
1
  import { InputValidationError } from '../errors/app-error.js';
2
2
  const ARGENTINE_DATE_FORMAT_HINT = 'Use D, DD, D-MM, D/MM, D-MM-YY, D/MM/YY, D-MM-YYYY o D/MM/YYYY.';
3
- // Usa la fecha local: con toISOString, despues de las 21 hs en Argentina la fecha saltaba al dia siguiente.
3
+ const ARGENTINE_DATE_PARTS = new Intl.DateTimeFormat('en-CA', {
4
+ day: '2-digit',
5
+ month: '2-digit',
6
+ timeZone: 'America/Argentina/Buenos_Aires',
7
+ year: 'numeric',
8
+ });
9
+ /**
10
+ * Dia calendario en Argentina de un instante. ARCA trabaja con la fecha argentina: en un servidor con TZ=UTC,
11
+ * despues de las 21 hs la fecha local ya es la del dia siguiente.
12
+ */
13
+ export function toArgentineCalendarDate(value) {
14
+ const parts = Object.fromEntries(ARGENTINE_DATE_PARTS.formatToParts(value).map((part) => [part.type, part.value]));
15
+ return { day: Number(parts.day), month: Number(parts.month), year: Number(parts.year) };
16
+ }
17
+ export function calendarDateToArcaDate(value) {
18
+ return `${value.year}${String(value.month).padStart(2, '0')}${String(value.day).padStart(2, '0')}`;
19
+ }
20
+ /** Fecha ARCA (yyyymmdd) del dia en Argentina en ese instante. */
4
21
  export function formatDateAsArcaDate(value) {
5
- const year = String(value.getFullYear());
6
- const month = String(value.getMonth() + 1).padStart(2, '0');
7
- const day = String(value.getDate()).padStart(2, '0');
8
- return `${year}${month}${day}`;
22
+ return calendarDateToArcaDate(toArgentineCalendarDate(value));
9
23
  }
10
24
  function arcaDateToUtcTime(value) {
11
25
  return Date.UTC(Number(value.slice(0, 4)), Number(value.slice(4, 6)) - 1, Number(value.slice(6, 8)));
@@ -27,18 +41,21 @@ export function parseArgentineDateInputAsArcaDate(value, referenceDate = new Dat
27
41
  throw new InputValidationError(`La fecha "${value}" no es valida. ${ARGENTINE_DATE_FORMAT_HINT}`);
28
42
  }
29
43
  const [, rawDay, , rawMonth, explicitYear] = dateMatch;
44
+ const today = toArgentineCalendarDate(referenceDate);
30
45
  const day = rawDay.padStart(2, '0');
31
- const month = (rawMonth ?? String(referenceDate.getMonth() + 1)).padStart(2, '0');
32
- const year = resolveYear(explicitYear, referenceDate);
33
- const date = new Date(Number(year), Number(month) - 1, Number(day));
34
- if (date.getFullYear() !== Number(year) || date.getMonth() !== Number(month) - 1 || date.getDate() !== Number(day)) {
46
+ const month = (rawMonth ?? String(today.month)).padStart(2, '0');
47
+ const year = resolveYear(explicitYear, today);
48
+ const date = new Date(Date.UTC(Number(year), Number(month) - 1, Number(day)));
49
+ if (date.getUTCFullYear() !== Number(year) ||
50
+ date.getUTCMonth() !== Number(month) - 1 ||
51
+ date.getUTCDate() !== Number(day)) {
35
52
  throw new InputValidationError(`La fecha "${value}" no es valida.`);
36
53
  }
37
54
  return `${year}${month}${day}`;
38
55
  }
39
- function resolveYear(explicitYear, referenceDate) {
56
+ function resolveYear(explicitYear, today) {
40
57
  if (!explicitYear) {
41
- return String(referenceDate.getFullYear());
58
+ return String(today.year);
42
59
  }
43
60
  return explicitYear.length === 2 ? `20${explicitYear}` : explicitYear;
44
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"arca-date.js","sourceRoot":"","sources":["../../../src/lib/dates/arca-date.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"arca-date.js","sourceRoot":"","sources":["../../../src/lib/dates/arca-date.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,0BAA0B,GAAG,iEAAiE,CAAC;AASrG,MAAM,oBAAoB,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;IAC5D,GAAG,EAAE,SAAS;IACd,KAAK,EAAE,SAAS;IAChB,QAAQ,EAAE,gCAAgC;IAC1C,IAAI,EAAE,SAAS;CAChB,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAW;IACjD,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,oBAAoB,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEnH,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,KAAmB;IACxD,OAAO,GAAG,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AACrG,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,oBAAoB,CAAC,KAAW;IAC9C,OAAO,sBAAsB,CAAC,uBAAuB,CAAC,KAAK,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;AACvG,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,mBAAmB,CAAC,IAAY,EAAE,EAAU;IAC1D,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,iBAAiB,CAAC,EAAE,CAAC,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAG,MAAgB;IAC7C,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7E,CAAC;AAED,MAAM,UAAU,6BAA6B,CAAC,KAAa;IACzD,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,iCAAiC,CAAC,KAAa,EAAE,aAAa,GAAG,IAAI,IAAI,EAAE;IACzF,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IACrC,MAAM,SAAS,GAAG,qDAAqD,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IAE9F,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,oBAAoB,CAAC,aAAa,KAAK,mBAAmB,0BAA0B,EAAE,CAAC,CAAC;IACpG,CAAC;IAED,MAAM,CAAC,EAAE,MAAM,EAAE,AAAD,EAAG,QAAQ,EAAE,YAAY,CAAC,GAAG,SAAS,CAAC;IACvD,MAAM,KAAK,GAAG,uBAAuB,CAAC,aAAa,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,CAAC,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjE,MAAM,IAAI,GAAG,WAAW,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAE9E,IACE,IAAI,CAAC,cAAc,EAAE,KAAK,MAAM,CAAC,IAAI,CAAC;QACtC,IAAI,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;QACxC,IAAI,CAAC,UAAU,EAAE,KAAK,MAAM,CAAC,GAAG,CAAC,EACjC,CAAC;QACD,MAAM,IAAI,oBAAoB,CAAC,aAAa,KAAK,iBAAiB,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,GAAG,EAAE,CAAC;AACjC,CAAC;AAED,SAAS,WAAW,CAAC,YAAgC,EAAE,KAAmB;IACxE,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,YAAY,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,YAAY,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC;AACxE,CAAC"}
@@ -1,13 +1,16 @@
1
1
  export declare class AppError extends Error {
2
2
  readonly code: string;
3
3
  readonly details?: Record<string, unknown>;
4
+ /** Que hacer ahora; sale como "Sugerencia" en texto y `sugerencia` en JSON. */
5
+ readonly suggestion?: string;
4
6
  constructor(message: string, options: {
5
7
  code: string;
6
8
  details?: Record<string, unknown>;
9
+ suggestion?: string;
7
10
  });
8
11
  }
9
12
  export declare class ConfigurationError extends AppError {
10
- constructor(message: string, details?: Record<string, unknown>);
13
+ constructor(message: string, details?: Record<string, unknown>, suggestion?: string);
11
14
  }
12
15
  export declare class InputValidationError extends AppError {
13
16
  constructor(message: string, details?: Record<string, unknown>);
@@ -1,18 +1,22 @@
1
1
  export class AppError extends Error {
2
2
  code;
3
3
  details;
4
+ /** Que hacer ahora; sale como "Sugerencia" en texto y `sugerencia` en JSON. */
5
+ suggestion;
4
6
  constructor(message, options) {
5
7
  super(message);
6
8
  this.name = 'AppError';
7
9
  this.code = options.code;
8
10
  this.details = options.details;
11
+ this.suggestion = options.suggestion;
9
12
  }
10
13
  }
11
14
  export class ConfigurationError extends AppError {
12
- constructor(message, details) {
15
+ constructor(message, details, suggestion) {
13
16
  super(message, {
14
17
  code: 'CONFIGURATION_ERROR',
15
18
  details,
19
+ suggestion,
16
20
  });
17
21
  this.name = 'ConfigurationError';
18
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"app-error.js","sourceRoot":"","sources":["../../../src/lib/errors/app-error.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjB,IAAI,CAAS;IACb,OAAO,CAA2B;IAElD,YAAmB,OAAe,EAAE,OAA4D;QAC9F,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IACjC,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,QAAQ;IAC9C,YAAmB,OAAe,EAAE,OAAiC;QACnE,KAAK,CAAC,OAAO,EAAE;YACb,IAAI,EAAE,qBAAqB;YAC3B,OAAO;SACR,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,QAAQ;IAChD,YAAmB,OAAe,EAAE,OAAiC;QACnE,KAAK,CAAC,OAAO,EAAE;YACb,IAAI,EAAE,wBAAwB;YAC9B,OAAO;SACR,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF"}
1
+ {"version":3,"file":"app-error.js","sourceRoot":"","sources":["../../../src/lib/errors/app-error.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,QAAS,SAAQ,KAAK;IACjB,IAAI,CAAS;IACb,OAAO,CAA2B;IAClD,+EAA+E;IAC/D,UAAU,CAAU;IAEpC,YACE,OAAe,EACf,OAAiF;QAEjF,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACvC,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,QAAQ;IAC9C,YAAmB,OAAe,EAAE,OAAiC,EAAE,UAAmB;QACxF,KAAK,CAAC,OAAO,EAAE;YACb,IAAI,EAAE,qBAAqB;YAC3B,OAAO;YACP,UAAU;SACX,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,QAAQ;IAChD,YAAmB,OAAe,EAAE,OAAiC;QACnE,KAAK,CAAC,OAAO,EAAE;YACb,IAAI,EAAE,wBAAwB;YAC9B,OAAO;SACR,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACrC,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ /** Permisos solo para el dueno en archivos y carpetas nuevos: tickets de ARCA, config y PDFs. */
2
+ export declare const OWNER_ONLY_UMASK = 63;
3
+ /**
4
+ * Deja una carpeta existente en 0700. Alcanza para proteger lo de adentro (por ejemplo tickets viejos en 0644):
5
+ * sin permiso de la carpeta, nadie mas llega a los archivos. Si no es nuestra o el sistema no lo soporta, sigue.
6
+ */
7
+ export declare function restrictFolderToOwner(path: string): void;
@@ -0,0 +1,19 @@
1
+ import { chmodSync, existsSync } from 'node:fs';
2
+ /** Permisos solo para el dueno en archivos y carpetas nuevos: tickets de ARCA, config y PDFs. */
3
+ export const OWNER_ONLY_UMASK = 0o077;
4
+ /**
5
+ * Deja una carpeta existente en 0700. Alcanza para proteger lo de adentro (por ejemplo tickets viejos en 0644):
6
+ * sin permiso de la carpeta, nadie mas llega a los archivos. Si no es nuestra o el sistema no lo soporta, sigue.
7
+ */
8
+ export function restrictFolderToOwner(path) {
9
+ if (process.platform === 'win32' || !existsSync(path)) {
10
+ return;
11
+ }
12
+ try {
13
+ chmodSync(path, 0o700);
14
+ }
15
+ catch {
16
+ // Carpeta de otro usuario o sistema de archivos sin permisos POSIX: no es motivo para frenar el comando.
17
+ }
18
+ }
19
+ //# sourceMappingURL=restrict-to-owner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restrict-to-owner.js","sourceRoot":"","sources":["../../../src/lib/files/restrict-to-owner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEhD,iGAAiG;AACjG,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAEtC;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACtD,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,yGAAyG;IAC3G,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Escribe sin pisar nunca un archivo existente: si `factura.pdf` ya esta, prueba `factura-2.pdf`, `factura-3.pdf`...
3
+ * Usa `wx`, asi que tampoco pisa un archivo creado entre el chequeo y la escritura. Devuelve la ruta usada.
4
+ */
5
+ export declare function writeNewFile(path: string, data: Uint8Array): string;
@@ -0,0 +1,30 @@
1
+ import { writeFileSync } from 'node:fs';
2
+ import { extname } from 'node:path';
3
+ const MAX_ATTEMPTS = 1000;
4
+ function withSuffix(path, attempt) {
5
+ if (attempt === 1) {
6
+ return path;
7
+ }
8
+ const extension = extname(path);
9
+ return `${path.slice(0, path.length - extension.length)}-${attempt}${extension}`;
10
+ }
11
+ /**
12
+ * Escribe sin pisar nunca un archivo existente: si `factura.pdf` ya esta, prueba `factura-2.pdf`, `factura-3.pdf`...
13
+ * Usa `wx`, asi que tampoco pisa un archivo creado entre el chequeo y la escritura. Devuelve la ruta usada.
14
+ */
15
+ export function writeNewFile(path, data) {
16
+ for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt += 1) {
17
+ const candidate = withSuffix(path, attempt);
18
+ try {
19
+ writeFileSync(candidate, data, { flag: 'wx' });
20
+ return candidate;
21
+ }
22
+ catch (error) {
23
+ if (error.code !== 'EEXIST') {
24
+ throw error;
25
+ }
26
+ }
27
+ }
28
+ throw new Error(`No se pudo guardar ${path}: ya existen ${MAX_ATTEMPTS} archivos con ese nombre.`);
29
+ }
30
+ //# sourceMappingURL=write-new-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-new-file.js","sourceRoot":"","sources":["../../../src/lib/files/write-new-file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,YAAY,GAAG,IAAI,CAAC;AAE1B,SAAS,UAAU,CAAC,IAAY,EAAE,OAAe;IAC/C,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,IAAI,OAAO,GAAG,SAAS,EAAE,CAAC;AACnF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,IAAgB;IACzD,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,YAAY,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QAC5D,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAE5C,IAAI,CAAC;YACH,aAAa,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAE/C,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACvD,MAAM,KAAK,CAAC;YACd,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,sBAAsB,IAAI,gBAAgB,YAAY,2BAA2B,CAAC,CAAC;AACrG,CAAC"}
@@ -0,0 +1,2 @@
1
+ /** CUIT o CUIL con guiones, como lo muestra ARCA: `20409509763` → `20-40950976-3`. Si no tiene 11 digitos, sin cambios. */
2
+ export declare function formatCuit(value: number | string): string;
@@ -0,0 +1,6 @@
1
+ /** CUIT o CUIL con guiones, como lo muestra ARCA: `20409509763` → `20-40950976-3`. Si no tiene 11 digitos, sin cambios. */
2
+ export function formatCuit(value) {
3
+ const digits = String(value);
4
+ return /^\d{11}$/.test(digits) ? `${digits.slice(0, 2)}-${digits.slice(2, 10)}-${digits.slice(10)}` : digits;
5
+ }
6
+ //# sourceMappingURL=format-cuit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-cuit.js","sourceRoot":"","sources":["../../../src/lib/identity/format-cuit.ts"],"names":[],"mappings":"AAAA,2HAA2H;AAC3H,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAE7B,OAAO,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;AAC/G,CAAC"}
@@ -1,2 +1,4 @@
1
1
  /** URL publica de la guia para sacar los certificados de ARCA (testing y produccion). */
2
2
  export declare const CERTIFICATE_GUIDE_URL = "https://github.com/LcsGrz/arcli/blob/main/docs/obtencion-certificados.md";
3
+ /** Seccion de la guia que explica como crear un punto de venta para web service. */
4
+ export declare const POINT_OF_SALE_GUIDE_URL = "https://github.com/LcsGrz/arcli/blob/main/docs/obtencion-certificados.md#punto-de-venta-para-web-service";
package/dist/lib/links.js CHANGED
@@ -1,3 +1,5 @@
1
1
  /** URL publica de la guia para sacar los certificados de ARCA (testing y produccion). */
2
2
  export const CERTIFICATE_GUIDE_URL = 'https://github.com/LcsGrz/arcli/blob/main/docs/obtencion-certificados.md';
3
+ /** Seccion de la guia que explica como crear un punto de venta para web service. */
4
+ export const POINT_OF_SALE_GUIDE_URL = `${CERTIFICATE_GUIDE_URL}#punto-de-venta-para-web-service`;
3
5
  //# sourceMappingURL=links.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"links.js","sourceRoot":"","sources":["../../src/lib/links.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,MAAM,CAAC,MAAM,qBAAqB,GAAG,0EAA0E,CAAC"}
1
+ {"version":3,"file":"links.js","sourceRoot":"","sources":["../../src/lib/links.ts"],"names":[],"mappings":"AAAA,yFAAyF;AACzF,MAAM,CAAC,MAAM,qBAAqB,GAAG,0EAA0E,CAAC;AAEhH,oFAAoF;AACpF,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,qBAAqB,kCAAkC,CAAC"}
@@ -0,0 +1,23 @@
1
+ /** Decimales de un importe en ARCA. */
2
+ export declare const AMOUNT_DECIMALS = 2;
3
+ /** Decimales de una cotizacion en ARCA (MonCotiz). */
4
+ export declare const EXCHANGE_RATE_DECIMALS = 6;
5
+ export type ArgentineAmountResult = {
6
+ readonly ok: true;
7
+ readonly value: number;
8
+ } | {
9
+ readonly ok: false;
10
+ readonly reason: string;
11
+ };
12
+ /**
13
+ * Interpreta un monto escrito como en Argentina: el punto separa miles y la coma separa decimales.
14
+ * `15000`, `15.000`, `1500,50` y `1.500,50` son validos; `1500.50` no, porque un grupo de miles
15
+ * siempre tiene 3 digitos. Acepta un `$` adelante y espacios.
16
+ */
17
+ export declare function parseArgentineAmount(raw: string, options?: {
18
+ readonly maxDecimals?: number;
19
+ }): ArgentineAmountResult;
20
+ /** Escribe un numero como lo lee `parseArgentineAmount`: `1234.5` pasa a `1234,5`. */
21
+ export declare function formatArgentineAmountInput(value: number): string;
22
+ /** `true` si el numero no tiene mas de `decimals` decimales: 100.55 si, 100.555 no. */
23
+ export declare function hasAtMostDecimals(value: number, decimals: number): boolean;
@@ -0,0 +1,37 @@
1
+ import Big from 'big.js';
2
+ /** Decimales de un importe en ARCA. */
3
+ export const AMOUNT_DECIMALS = 2;
4
+ /** Decimales de una cotizacion en ARCA (MonCotiz). */
5
+ export const EXCHANGE_RATE_DECIMALS = 6;
6
+ const FORMAT_HINT = 'use punto para miles y coma para decimales, por ejemplo 15000, 15.000 o 1.500,50';
7
+ /**
8
+ * Interpreta un monto escrito como en Argentina: el punto separa miles y la coma separa decimales.
9
+ * `15000`, `15.000`, `1500,50` y `1.500,50` son validos; `1500.50` no, porque un grupo de miles
10
+ * siempre tiene 3 digitos. Acepta un `$` adelante y espacios.
11
+ */
12
+ export function parseArgentineAmount(raw, options = {}) {
13
+ const maxDecimals = options.maxDecimals ?? AMOUNT_DECIMALS;
14
+ const value = raw.trim().replace(/^\$/, '').replace(/\s/g, '');
15
+ const match = /^(\d{1,3}(?:\.\d{3})+|\d+)(?:,(\d+))?$/.exec(value);
16
+ if (!match) {
17
+ return { ok: false, reason: /^\d+\.\d{1,2}$/.test(value) ? 'use coma para los decimales' : FORMAT_HINT };
18
+ }
19
+ const [, integerPart = '', decimalPart = ''] = match;
20
+ if (decimalPart.length > maxDecimals) {
21
+ return { ok: false, reason: `use hasta ${maxDecimals} decimales` };
22
+ }
23
+ const amount = Number(`${integerPart.replace(/\./g, '')}.${decimalPart || '0'}`);
24
+ if (!Number.isFinite(amount) || amount <= 0) {
25
+ return { ok: false, reason: 'tiene que ser mayor a 0' };
26
+ }
27
+ return { ok: true, value: amount };
28
+ }
29
+ /** Escribe un numero como lo lee `parseArgentineAmount`: `1234.5` pasa a `1234,5`. */
30
+ export function formatArgentineAmountInput(value) {
31
+ return String(value).replace('.', ',');
32
+ }
33
+ /** `true` si el numero no tiene mas de `decimals` decimales: 100.55 si, 100.555 no. */
34
+ export function hasAtMostDecimals(value, decimals) {
35
+ return Number.isFinite(value) && new Big(value).round(decimals, Big.roundDown).eq(value);
36
+ }
37
+ //# sourceMappingURL=argentine-amount.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"argentine-amount.js","sourceRoot":"","sources":["../../../src/lib/numbers/argentine-amount.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,QAAQ,CAAC;AAEzB,uCAAuC;AACvC,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC;AAEjC,sDAAsD;AACtD,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAKxC,MAAM,WAAW,GAAG,kFAAkF,CAAC;AAEvG;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAClC,GAAW,EACX,UAA6C,EAAE;IAE/C,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,eAAe,CAAC;IAC3D,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,wCAAwC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEnE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3G,CAAC;IAED,MAAM,CAAC,EAAE,WAAW,GAAG,EAAE,EAAE,WAAW,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC;IAErD,IAAI,WAAW,CAAC,MAAM,GAAG,WAAW,EAAE,CAAC;QACrC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,WAAW,YAAY,EAAE,CAAC;IACrE,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,WAAW,IAAI,GAAG,EAAE,CAAC,CAAC;IAEjF,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAC5C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;IAC1D,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACrC,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,0BAA0B,CAAC,KAAa;IACtD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,iBAAiB,CAAC,KAAa,EAAE,QAAgB;IAC/D,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;AAC3F,CAAC"}
@@ -0,0 +1,4 @@
1
+ /** Entero positivo escrito solo con digitos: `3` si, `3a`, `3.5` o `-3` no. */
2
+ export declare function parseStrictInteger(raw: string): number | undefined;
3
+ /** Numero de documento (CUIT, CUIL o DNI): acepta guiones, puntos y espacios, como `20-11111111-2` o `30.111.222`. */
4
+ export declare function parseDocumentNumber(raw: string): number | undefined;
@@ -0,0 +1,10 @@
1
+ /** Entero positivo escrito solo con digitos: `3` si, `3a`, `3.5` o `-3` no. */
2
+ export function parseStrictInteger(raw) {
3
+ const value = raw.trim();
4
+ return /^\d+$/.test(value) ? Number(value) : undefined;
5
+ }
6
+ /** Numero de documento (CUIT, CUIL o DNI): acepta guiones, puntos y espacios, como `20-11111111-2` o `30.111.222`. */
7
+ export function parseDocumentNumber(raw) {
8
+ return parseStrictInteger(raw.replace(/[-.\s]/g, ''));
9
+ }
10
+ //# sourceMappingURL=strict-integer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strict-integer.js","sourceRoot":"","sources":["../../../src/lib/numbers/strict-integer.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAEzB,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACzD,CAAC;AAED,sHAAsH;AACtH,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,OAAO,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;AACxD,CAAC"}
@@ -1,7 +1,11 @@
1
1
  export interface CertificateExpiry {
2
+ /** Dias calendario en Argentina hasta el vencimiento: 0 si vence hoy, negativo si ya vencio. */
2
3
  readonly daysRemaining: number;
3
4
  readonly expiresAt: Date;
4
5
  readonly isExpired: boolean;
5
6
  }
6
- export declare function readCertificateExpiry(pemContent: string): CertificateExpiry;
7
+ /** Vencido desde el instante exacto de `notAfter`; los dias se cuentan en fechas argentinas, no en horas. */
8
+ export declare function computeCertificateExpiry(expiresAt: Date, now?: Date): CertificateExpiry;
9
+ /** Lee la fecha de vencimiento del PEM. Es local, sin red; tira si el contenido no es un certificado X.509. */
10
+ export declare function readCertificateExpiry(pemContent: string, now?: Date): CertificateExpiry;
7
11
  export declare function isCertificateExpiringSoon(expiry: CertificateExpiry, thresholdDays: number): boolean;
@@ -1,15 +1,18 @@
1
1
  import { X509Certificate } from 'node:crypto';
2
- const MS_PER_DAY = 24 * 60 * 60 * 1000;
3
- export function readCertificateExpiry(pemContent) {
4
- const certificate = new X509Certificate(pemContent);
5
- const expiresAt = new Date(certificate.validTo);
6
- const daysRemaining = Math.ceil((expiresAt.getTime() - Date.now()) / MS_PER_DAY);
2
+ import { diffArcaDatesInDays, formatDateAsArcaDate } from '../dates/arca-date.js';
3
+ /** Vencido desde el instante exacto de `notAfter`; los dias se cuentan en fechas argentinas, no en horas. */
4
+ export function computeCertificateExpiry(expiresAt, now = new Date()) {
7
5
  return {
8
- daysRemaining,
6
+ daysRemaining: diffArcaDatesInDays(formatDateAsArcaDate(now), formatDateAsArcaDate(expiresAt)),
9
7
  expiresAt,
10
- isExpired: daysRemaining < 0,
8
+ isExpired: expiresAt.getTime() <= now.getTime(),
11
9
  };
12
10
  }
11
+ /** Lee la fecha de vencimiento del PEM. Es local, sin red; tira si el contenido no es un certificado X.509. */
12
+ export function readCertificateExpiry(pemContent, now = new Date()) {
13
+ const certificate = new X509Certificate(pemContent);
14
+ return computeCertificateExpiry(new Date(certificate.validTo), now);
15
+ }
13
16
  export function isCertificateExpiringSoon(expiry, thresholdDays) {
14
17
  return !expiry.isExpired && expiry.daysRemaining <= thresholdDays;
15
18
  }
@@ -1 +1 @@
1
- {"version":3,"file":"certificate.js","sourceRoot":"","sources":["../../../src/lib/security/certificate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAQvC,MAAM,UAAU,qBAAqB,CAAC,UAAkB;IACtD,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC,UAAU,CAAC,CAAC;IACpD,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,UAAU,CAAC,CAAC;IAEjF,OAAO;QACL,aAAa;QACb,SAAS;QACT,SAAS,EAAE,aAAa,GAAG,CAAC;KAC7B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAyB,EAAE,aAAqB;IACxF,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,aAAa,IAAI,aAAa,CAAC;AACpE,CAAC"}
1
+ {"version":3,"file":"certificate.js","sourceRoot":"","sources":["../../../src/lib/security/certificate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAS/E,6GAA6G;AAC7G,MAAM,UAAU,wBAAwB,CAAC,SAAe,EAAE,MAAY,IAAI,IAAI,EAAE;IAC9E,OAAO;QACL,aAAa,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,GAAG,CAAC,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC;QAC9F,SAAS;QACT,SAAS,EAAE,SAAS,CAAC,OAAO,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE;KAChD,CAAC;AACJ,CAAC;AAED,+GAA+G;AAC/G,MAAM,UAAU,qBAAqB,CAAC,UAAkB,EAAE,MAAY,IAAI,IAAI,EAAE;IAC9E,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC,UAAU,CAAC,CAAC;IAEpD,OAAO,wBAAwB,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;AACtE,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAyB,EAAE,aAAqB;IACxF,OAAO,CAAC,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,aAAa,IAAI,aAAa,CAAC;AACpE,CAAC"}
@@ -8,7 +8,7 @@ function acceptedPemHeaders(kind) {
8
8
  if (kind === 'certificado') {
9
9
  return ['BEGIN CERTIFICATE'];
10
10
  }
11
- return ['BEGIN PRIVATE KEY', 'BEGIN RSA PRIVATE KEY', 'BEGIN EC PRIVATE KEY', 'BEGIN ENCRYPTED PRIVATE KEY'];
11
+ return ['BEGIN PRIVATE KEY', 'BEGIN RSA PRIVATE KEY', 'BEGIN EC PRIVATE KEY'];
12
12
  }
13
13
  export function ensurePathExists(filePath, label) {
14
14
  if (!existsSync(filePath)) {
@@ -19,6 +19,10 @@ export function ensurePathExists(filePath, label) {
19
19
  }
20
20
  export function ensurePemFormat(content, filePath, label) {
21
21
  const normalizedContent = content.trim();
22
+ // El SDK no recibe passphrase: con una clave cifrada fallaria recien al hablar con ARCA, con un error confuso.
23
+ if (label === 'clave privada' && normalizedContent.includes('-----BEGIN ENCRYPTED PRIVATE KEY-----')) {
24
+ throw new ConfigurationError(`La clave privada esta cifrada con contrasena y ARCLI no puede usarla: ${maskPath(filePath)}. Generala sin contrasena o descifrala con "openssl pkey -in clave.key -out clave-sin-pass.key".`, { path: maskPath(filePath) });
25
+ }
22
26
  const hasAcceptedHeader = acceptedPemHeaders(label).some((header) => normalizedContent.includes(`-----${header}-----`));
23
27
  const hasAcceptedFooter = normalizedContent.includes('-----END');
24
28
  if (!hasAcceptedHeader || !hasAcceptedFooter) {