arca-siradig 1.0.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 (49) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +311 -0
  3. package/dist/src/arca/deductions.d.ts +71 -0
  4. package/dist/src/arca/deductions.js +636 -0
  5. package/dist/src/arca/employees.d.ts +10 -0
  6. package/dist/src/arca/employees.js +80 -0
  7. package/dist/src/arca/form.d.ts +39 -0
  8. package/dist/src/arca/form.js +143 -0
  9. package/dist/src/arca/http.d.ts +14 -0
  10. package/dist/src/arca/http.js +108 -0
  11. package/dist/src/arca/menu.d.ts +6 -0
  12. package/dist/src/arca/menu.js +36 -0
  13. package/dist/src/arca/personal-data.d.ts +4 -0
  14. package/dist/src/arca/personal-data.js +62 -0
  15. package/dist/src/arca/persons.d.ts +11 -0
  16. package/dist/src/arca/persons.js +115 -0
  17. package/dist/src/arca/receipt-types.d.ts +4 -0
  18. package/dist/src/arca/receipt-types.js +39 -0
  19. package/dist/src/arca/session.d.ts +27 -0
  20. package/dist/src/arca/session.js +165 -0
  21. package/dist/src/arca/submission.d.ts +22 -0
  22. package/dist/src/arca/submission.js +140 -0
  23. package/dist/src/arca/submitted-forms.d.ts +12 -0
  24. package/dist/src/arca/submitted-forms.js +54 -0
  25. package/dist/src/cli/errors.d.ts +1 -0
  26. package/dist/src/cli/errors.js +11 -0
  27. package/dist/src/cli/help.d.ts +6 -0
  28. package/dist/src/cli/help.js +301 -0
  29. package/dist/src/cli/index.d.ts +2 -0
  30. package/dist/src/cli/index.js +810 -0
  31. package/dist/src/cli/options.d.ts +120 -0
  32. package/dist/src/cli/options.js +419 -0
  33. package/dist/src/cli/prompts.d.ts +9 -0
  34. package/dist/src/cli/prompts.js +99 -0
  35. package/dist/src/cli/render.d.ts +13 -0
  36. package/dist/src/cli/render.js +262 -0
  37. package/dist/src/cli/structured-output.d.ts +4 -0
  38. package/dist/src/cli/structured-output.js +92 -0
  39. package/dist/src/files/pdf.d.ts +3 -0
  40. package/dist/src/files/pdf.js +43 -0
  41. package/dist/src/files/private.d.ts +4 -0
  42. package/dist/src/files/private.js +21 -0
  43. package/dist/src/security/errors.d.ts +2 -0
  44. package/dist/src/security/errors.js +22 -0
  45. package/dist/src/session/store.d.ts +15 -0
  46. package/dist/src/session/store.js +35 -0
  47. package/dist/src/types.d.ts +106 -0
  48. package/dist/src/types.js +1 -0
  49. package/package.json +59 -0
@@ -0,0 +1,120 @@
1
+ export type OutputFormat = "text" | "json";
2
+ export type HelpCommand = {
3
+ kind: "help";
4
+ headless: boolean;
5
+ topic: "root" | "login" | "logout" | "persons" | "personal-data" | "employees" | "deductions" | "form";
6
+ };
7
+ export type InteractiveCommand = {
8
+ kind: "interactive";
9
+ headless: boolean;
10
+ };
11
+ export type LogoutCommand = {
12
+ kind: "logout";
13
+ };
14
+ export type LoginCommand = {
15
+ kind: "login";
16
+ headless: boolean;
17
+ cuit?: string;
18
+ password?: string;
19
+ hasExplicitCredentials: boolean;
20
+ };
21
+ export type PersonsListCommand = {
22
+ kind: "persons-list";
23
+ headless: boolean;
24
+ format: OutputFormat;
25
+ };
26
+ export type PersonsSelectCommand = {
27
+ kind: "persons-select";
28
+ headless: boolean;
29
+ person: string;
30
+ };
31
+ export type PersonsPersonalDataShowCommand = {
32
+ kind: "persons-personal-data-show";
33
+ headless: boolean;
34
+ person?: string;
35
+ format: OutputFormat;
36
+ };
37
+ export type PersonsEmployeesListCommand = {
38
+ kind: "persons-employees-list";
39
+ headless: boolean;
40
+ person?: string;
41
+ format: OutputFormat;
42
+ };
43
+ export type PersonsEmployeesShowCommand = {
44
+ kind: "persons-employees-show";
45
+ headless: boolean;
46
+ person?: string;
47
+ employeeCuit: string;
48
+ format: OutputFormat;
49
+ };
50
+ export type FormDeductionsListCommand = {
51
+ period?: number;
52
+ kind: "form-deductions-list";
53
+ headless: boolean;
54
+ person?: string;
55
+ format: OutputFormat;
56
+ };
57
+ export type FormDeductionsListReceiptTypesCommand = {
58
+ kind: "form-deductions-list-receipt-types";
59
+ headless: boolean;
60
+ format: OutputFormat;
61
+ };
62
+ export type FormDeductionsShowCommand = {
63
+ period?: number;
64
+ kind: "form-deductions-show";
65
+ headless: boolean;
66
+ person?: string;
67
+ deductionId: string;
68
+ format: OutputFormat;
69
+ };
70
+ export type FormDeductionsAddItemCommand = {
71
+ period: number;
72
+ person?: string;
73
+ kind: "form-deductions-add-item";
74
+ headless: boolean;
75
+ deductionType: string;
76
+ cuit: string;
77
+ month: number;
78
+ amount: string;
79
+ };
80
+ export type FormDeductionsAddItemReceiptCommand = {
81
+ period: number;
82
+ person?: string;
83
+ kind: "form-deductions-add-item-receipt";
84
+ headless: boolean;
85
+ deductionType: string;
86
+ cuit: string;
87
+ month: number;
88
+ date: string;
89
+ receiptType: string;
90
+ number: string;
91
+ amount: string;
92
+ reimbursedAmount?: string;
93
+ };
94
+ export type FormDeductionsRemoveItemReceiptCommand = {
95
+ period: number;
96
+ person?: string;
97
+ kind: "form-deductions-remove-item-receipt";
98
+ headless: boolean;
99
+ deductionType: string;
100
+ cuit: string;
101
+ number: string;
102
+ };
103
+ export type FormPreviewCommand = {
104
+ kind: "form-summary" | "form-show" | "form-print";
105
+ headless: boolean;
106
+ person?: string;
107
+ period?: number;
108
+ format: OutputFormat;
109
+ path?: string;
110
+ };
111
+ export type FormSubmitCommand = {
112
+ kind: "form-submit";
113
+ headless: boolean;
114
+ person?: string;
115
+ period: number;
116
+ accept: boolean;
117
+ format: OutputFormat;
118
+ };
119
+ export type CliCommand = FormSubmitCommand | FormPreviewCommand | HelpCommand | InteractiveCommand | LogoutCommand | LoginCommand | PersonsListCommand | PersonsSelectCommand | PersonsPersonalDataShowCommand | PersonsEmployeesListCommand | PersonsEmployeesShowCommand | FormDeductionsListCommand | FormDeductionsListReceiptTypesCommand | FormDeductionsShowCommand | FormDeductionsAddItemCommand | FormDeductionsAddItemReceiptCommand | FormDeductionsRemoveItemReceiptCommand;
120
+ export declare function parseCliOptions(args: string[]): CliCommand;
@@ -0,0 +1,419 @@
1
+ export function parseCliOptions(args) {
2
+ let accept = false;
3
+ let headless = true;
4
+ let interactive = false;
5
+ let help = false;
6
+ let cuit;
7
+ let password;
8
+ let person;
9
+ let employeeCuit;
10
+ let deductionType;
11
+ let month;
12
+ let date;
13
+ let receiptType;
14
+ let number;
15
+ let amount;
16
+ let reimbursedAmount;
17
+ let period;
18
+ let path;
19
+ let format = "text";
20
+ const positionals = [];
21
+ for (let index = 0; index < args.length; index += 1) {
22
+ const arg = args[index];
23
+ if (arg === "--help" || arg === "-h") {
24
+ help = true;
25
+ continue;
26
+ }
27
+ if (arg === "--interactive" || arg === "-i") {
28
+ interactive = true;
29
+ continue;
30
+ }
31
+ if (arg === "--headless") {
32
+ headless = parseBooleanFlagValue(readFlagValue(args, index, "--headless"), "--headless");
33
+ index += 1;
34
+ continue;
35
+ }
36
+ if (arg.startsWith("--headless=")) {
37
+ headless = parseBooleanFlagValue(arg.slice("--headless=".length), "--headless");
38
+ continue;
39
+ }
40
+ if (arg === "--cuit") {
41
+ cuit = readFlagValue(args, index, arg);
42
+ index += 1;
43
+ continue;
44
+ }
45
+ if (arg.startsWith("--cuit=")) {
46
+ cuit = arg.slice("--cuit=".length);
47
+ continue;
48
+ }
49
+ if (arg === "--password") {
50
+ password = readFlagValue(args, index, arg);
51
+ index += 1;
52
+ continue;
53
+ }
54
+ if (arg.startsWith("--password=")) {
55
+ password = arg.slice("--password=".length);
56
+ continue;
57
+ }
58
+ if (arg === "--person") {
59
+ person = readFlagValue(args, index, "--person");
60
+ index += 1;
61
+ continue;
62
+ }
63
+ if (arg.startsWith("--person=")) {
64
+ person = arg.slice("--person=".length);
65
+ continue;
66
+ }
67
+ if (arg === "--employee-cuit") {
68
+ employeeCuit = readFlagValue(args, index, "--employee-cuit");
69
+ index += 1;
70
+ continue;
71
+ }
72
+ if (arg.startsWith("--employee-cuit=")) {
73
+ employeeCuit = arg.slice("--employee-cuit=".length);
74
+ continue;
75
+ }
76
+ if (arg === "--type") {
77
+ deductionType = readFlagValue(args, index, "--type");
78
+ index += 1;
79
+ continue;
80
+ }
81
+ if (arg.startsWith("--type=")) {
82
+ deductionType = arg.slice("--type=".length);
83
+ continue;
84
+ }
85
+ if (arg === "--month") {
86
+ month = readFlagValue(args, index, "--month");
87
+ index += 1;
88
+ continue;
89
+ }
90
+ if (arg.startsWith("--month=")) {
91
+ month = arg.slice("--month=".length);
92
+ continue;
93
+ }
94
+ if (arg === "--date") {
95
+ date = readFlagValue(args, index, "--date");
96
+ index += 1;
97
+ continue;
98
+ }
99
+ if (arg.startsWith("--date=")) {
100
+ date = arg.slice("--date=".length);
101
+ continue;
102
+ }
103
+ if (arg === "--receipt-type") {
104
+ receiptType = readFlagValue(args, index, "--receipt-type");
105
+ index += 1;
106
+ continue;
107
+ }
108
+ if (arg.startsWith("--receipt-type=")) {
109
+ receiptType = arg.slice("--receipt-type=".length);
110
+ continue;
111
+ }
112
+ if (arg === "--number") {
113
+ number = readFlagValue(args, index, "--number");
114
+ index += 1;
115
+ continue;
116
+ }
117
+ if (arg.startsWith("--number=")) {
118
+ number = arg.slice("--number=".length);
119
+ continue;
120
+ }
121
+ if (arg === "--amount") {
122
+ amount = readFlagValue(args, index, "--amount");
123
+ index += 1;
124
+ continue;
125
+ }
126
+ if (arg.startsWith("--amount=")) {
127
+ amount = arg.slice("--amount=".length);
128
+ continue;
129
+ }
130
+ if (arg === "--reimbursed-amount") {
131
+ reimbursedAmount = readFlagValue(args, index, "--reimbursed-amount");
132
+ index += 1;
133
+ continue;
134
+ }
135
+ if (arg.startsWith("--reimbursed-amount=")) {
136
+ reimbursedAmount = arg.slice("--reimbursed-amount=".length);
137
+ continue;
138
+ }
139
+ if (arg === "--period" || arg.startsWith("--period=")) {
140
+ const value = arg === "--period" ? readFlagValue(args, index++, "--period") : arg.slice(9);
141
+ if (!/^[12]\d{3}$/.test(value))
142
+ throw new Error("--period expects a four-digit fiscal year.");
143
+ period = Number(value);
144
+ continue;
145
+ }
146
+ if (arg === "--path" || arg.startsWith("--path=")) {
147
+ path = arg === "--path" ? readFlagValue(args, index++, "--path") : arg.slice(7);
148
+ continue;
149
+ }
150
+ if (arg === "--aceptar") {
151
+ accept = true;
152
+ continue;
153
+ }
154
+ if (arg === "--format") {
155
+ format = parseOutputFormat(readFlagValue(args, index, "--format"));
156
+ index += 1;
157
+ continue;
158
+ }
159
+ if (arg.startsWith("--format=")) {
160
+ format = parseOutputFormat(arg.slice("--format=".length));
161
+ continue;
162
+ }
163
+ if (arg.startsWith("-")) {
164
+ throw new Error(`Unknown option: ${arg.split("=", 1)[0]}`);
165
+ }
166
+ positionals.push(arg);
167
+ }
168
+ if (positionals[0] === "deductions") {
169
+ throw new Error("Unknown command: deductions. Use arca-siradig form deductions <command>.");
170
+ }
171
+ if (help || args.length === 0) {
172
+ return { kind: "help", headless, topic: inferHelpTopic(positionals) };
173
+ }
174
+ if (accept && !(positionals[0] === "form" && positionals[1] === "submit")) {
175
+ throw new Error("--aceptar is only supported for form submit.");
176
+ }
177
+ if (period !== undefined && positionals[0] !== "form") {
178
+ throw new Error("--period is only supported for form commands.");
179
+ }
180
+ if (path !== undefined && !(positionals[0] === "form" && positionals[1] === "print")) {
181
+ throw new Error("--path is only supported for form print.");
182
+ }
183
+ if (positionals[0] === "form" && positionals[1] === "submit" && positionals.length === 2) {
184
+ return { kind: "form-submit", headless, person, period: requirePeriod(period), accept, format };
185
+ }
186
+ if (positionals[0] === "form" &&
187
+ positionals.length === 2 &&
188
+ ["show", "summary", "print"].includes(positionals[1])) {
189
+ return {
190
+ kind: positionals[1] === "show"
191
+ ? "form-show"
192
+ : positionals[1] === "summary"
193
+ ? "form-summary"
194
+ : "form-print",
195
+ headless,
196
+ person,
197
+ period,
198
+ format,
199
+ ...(positionals[1] === "print" ? { path: readRequiredFlag(path, "--path") } : {}),
200
+ };
201
+ }
202
+ const formContext = period === undefined ? {} : { period };
203
+ const deductionPositionals = positionals[0] === "form" && positionals[1] === "deductions" ? positionals.slice(2) : [];
204
+ if (interactive) {
205
+ return { kind: "interactive", headless };
206
+ }
207
+ if (positionals[0] === "login" && positionals.length === 1) {
208
+ return {
209
+ kind: "login",
210
+ headless,
211
+ cuit,
212
+ password,
213
+ hasExplicitCredentials: Boolean(cuit || password),
214
+ };
215
+ }
216
+ if (positionals[0] === "logout" && positionals.length === 1) {
217
+ return { kind: "logout" };
218
+ }
219
+ if (positionals[0] === "persons" && positionals[1] === "list" && positionals.length === 2) {
220
+ return { kind: "persons-list", headless, format };
221
+ }
222
+ if (positionals[0] === "persons" && positionals[1] === "select" && positionals.length === 3) {
223
+ return {
224
+ kind: "persons-select",
225
+ headless,
226
+ person: positionals[2],
227
+ };
228
+ }
229
+ if (positionals[0] === "personal-data" &&
230
+ positionals[1] === "show" &&
231
+ (positionals.length === 2 || positionals.length === 3)) {
232
+ return {
233
+ kind: "persons-personal-data-show",
234
+ headless,
235
+ person: person ?? positionals[2],
236
+ format,
237
+ };
238
+ }
239
+ if (positionals[0] === "employees" &&
240
+ positionals[1] === "list" &&
241
+ (positionals.length === 2 || positionals.length === 3)) {
242
+ return {
243
+ kind: "persons-employees-list",
244
+ headless,
245
+ person: person ?? positionals[2],
246
+ format,
247
+ };
248
+ }
249
+ if (positionals[0] === "employees" &&
250
+ positionals[1] === "show" &&
251
+ (positionals.length === 2 || positionals.length === 3)) {
252
+ return {
253
+ kind: "persons-employees-show",
254
+ headless,
255
+ person: person ?? positionals[2],
256
+ employeeCuit: readRequiredFlag(employeeCuit, "--employee-cuit"),
257
+ format,
258
+ };
259
+ }
260
+ if (deductionPositionals[0] === "list-receipt-types" && deductionPositionals.length === 1) {
261
+ if (period !== undefined)
262
+ throw new Error("The receipt type catalog does not have a fiscal period.");
263
+ return {
264
+ kind: "form-deductions-list-receipt-types",
265
+ headless,
266
+ format,
267
+ };
268
+ }
269
+ if (deductionPositionals[0] === "list" && deductionPositionals.length === 1) {
270
+ return {
271
+ kind: "form-deductions-list",
272
+ ...formContext,
273
+ headless,
274
+ person,
275
+ format,
276
+ };
277
+ }
278
+ if (deductionPositionals[0] === "show" && deductionPositionals.length === 2) {
279
+ return {
280
+ kind: "form-deductions-show",
281
+ ...formContext,
282
+ headless,
283
+ deductionId: readRequiredPositional(deductionPositionals[1], "deduction id"),
284
+ person,
285
+ format,
286
+ };
287
+ }
288
+ if (deductionPositionals[0] === "add-item" && deductionPositionals.length === 1) {
289
+ return {
290
+ kind: "form-deductions-add-item",
291
+ period: requirePeriod(period),
292
+ ...(person === undefined ? {} : { person }),
293
+ headless,
294
+ deductionType: readRequiredFlag(deductionType, "--type"),
295
+ cuit: readRequiredFlag(cuit, "--cuit"),
296
+ month: parseRequiredMonth(month, "--month"),
297
+ amount: readRequiredFlag(amount, "--amount"),
298
+ };
299
+ }
300
+ if (deductionPositionals[0] === "add-item-receipt" && deductionPositionals.length === 1) {
301
+ const normalizedDeductionType = readRequiredFlag(deductionType, "--type");
302
+ const isMedicalExpenses = normalizedDeductionType === "gastos-medicos";
303
+ if (date && period !== undefined && Number(date.slice(0, 4)) !== period) {
304
+ throw new Error("--date must belong to the fiscal year specified by --period.");
305
+ }
306
+ return {
307
+ kind: "form-deductions-add-item-receipt",
308
+ period: requirePeriod(period),
309
+ ...(person === undefined ? {} : { person }),
310
+ headless,
311
+ deductionType: normalizedDeductionType,
312
+ cuit: readRequiredFlag(cuit, "--cuit"),
313
+ month: parseRequiredMonth(month, "--month"),
314
+ date: readRequiredFlag(date, "--date"),
315
+ receiptType: readRequiredFlag(receiptType, "--receipt-type"),
316
+ number: readRequiredFlag(number, "--number"),
317
+ amount: readRequiredFlag(amount, "--amount"),
318
+ reimbursedAmount: isMedicalExpenses
319
+ ? readRequiredFlag(reimbursedAmount, "--reimbursed-amount")
320
+ : reimbursedAmount,
321
+ };
322
+ }
323
+ if (deductionPositionals[0] === "remove-item-receipt" && deductionPositionals.length === 1) {
324
+ return {
325
+ kind: "form-deductions-remove-item-receipt",
326
+ period: requirePeriod(period),
327
+ ...(person === undefined ? {} : { person }),
328
+ headless,
329
+ deductionType: deductionType?.trim() || "gastos-medicos",
330
+ cuit: readRequiredFlag(cuit, "--cuit"),
331
+ number: readRequiredFlag(number, "--number"),
332
+ };
333
+ }
334
+ if (positionals.length === 1) {
335
+ const [command] = positionals;
336
+ if (command === "login" ||
337
+ command === "persons" ||
338
+ command === "personal-data" ||
339
+ command === "employees" ||
340
+ command === "form" ||
341
+ command === "logout") {
342
+ return { kind: "help", headless, topic: command };
343
+ }
344
+ }
345
+ if (positionals[0] === "form" && positionals[1] === "deductions" && positionals.length === 2) {
346
+ return { kind: "help", headless, topic: "deductions" };
347
+ }
348
+ if (positionals[0] === "persons" && positionals[1] === "select" && positionals.length === 2) {
349
+ return { kind: "help", headless, topic: "persons" };
350
+ }
351
+ throw new Error(`Unknown command: ${positionals[0] ?? "(missing)"}`);
352
+ }
353
+ function requirePeriod(period) {
354
+ if (period === undefined)
355
+ throw new Error("--period is required for changes to a form.");
356
+ return period;
357
+ }
358
+ function readFlagValue(args, index, flagName) {
359
+ const value = args[index + 1];
360
+ if (!value || value.startsWith("-")) {
361
+ throw new Error(`${flagName} expects a value.`);
362
+ }
363
+ return value;
364
+ }
365
+ function parseBooleanFlagValue(value, flagName) {
366
+ if (value === "true") {
367
+ return true;
368
+ }
369
+ if (value === "false") {
370
+ return false;
371
+ }
372
+ throw new Error(`${flagName} expects "true" or "false".`);
373
+ }
374
+ function parseOutputFormat(value) {
375
+ if (value === "text" || value === "json") {
376
+ return value;
377
+ }
378
+ throw new Error('--format expects "text" or "json".');
379
+ }
380
+ function readRequiredFlag(value, flagName) {
381
+ if (!value || value.trim().length === 0) {
382
+ throw new Error(`${flagName} is required.`);
383
+ }
384
+ return value.trim();
385
+ }
386
+ function readRequiredPositional(value, label) {
387
+ if (!value || value.trim().length === 0) {
388
+ throw new Error(`${label} is required.`);
389
+ }
390
+ return value.trim();
391
+ }
392
+ function parseRequiredMonth(value, flagName) {
393
+ const rawValue = readRequiredFlag(value, flagName);
394
+ const month = Number.parseInt(rawValue, 10);
395
+ if (!/^\d{1,2}$/.test(rawValue) || !Number.isInteger(month) || month < 1 || month > 12) {
396
+ throw new Error(`${flagName} expects an integer from 1 to 12.`);
397
+ }
398
+ return month;
399
+ }
400
+ function inferHelpTopic(positionals) {
401
+ if (positionals[0] === "persons") {
402
+ return "persons";
403
+ }
404
+ if (positionals[0] === "personal-data") {
405
+ return "personal-data";
406
+ }
407
+ if (positionals[0] === "employees") {
408
+ return "employees";
409
+ }
410
+ if (positionals[0] === "login") {
411
+ return "login";
412
+ }
413
+ if (positionals[0] === "form")
414
+ return positionals[1] === "deductions" ? "deductions" : "form";
415
+ if (positionals[0] === "logout") {
416
+ return "logout";
417
+ }
418
+ return "root";
419
+ }
@@ -0,0 +1,9 @@
1
+ import type { ArcaCredentials, MenuItem, Person } from "../types.js";
2
+ export declare function promptFormSubmission(): Promise<boolean>;
3
+ export declare function promptCredentials(defaults: Partial<ArcaCredentials>, options?: {
4
+ usePasswordDefault?: boolean;
5
+ }): Promise<ArcaCredentials>;
6
+ export declare function promptMissingCredentials(values: Partial<ArcaCredentials>, defaults: Partial<ArcaCredentials>): Promise<ArcaCredentials>;
7
+ export declare function promptPerson(persons: Person[]): Promise<Person>;
8
+ export declare function promptMenuItem(items: MenuItem[]): Promise<MenuItem>;
9
+ export declare function promptPersonalDataAction(): Promise<"main-menu">;
@@ -0,0 +1,99 @@
1
+ import { input, password, select } from "@inquirer/prompts";
2
+ const MAIN_MENU_ACTION = "main-menu";
3
+ export async function promptFormSubmission() {
4
+ try {
5
+ return await select({
6
+ message: "¿Querés generar la presentación y enviarla al empleador?",
7
+ default: false,
8
+ choices: [
9
+ { name: "Cancelar", value: false },
10
+ { name: "Aceptar — Generar Presentación", value: true },
11
+ ],
12
+ }, { output: process.stderr });
13
+ }
14
+ catch (error) {
15
+ if (error instanceof Error && ["ExitPromptError", "AbortPromptError"].includes(error.name)) {
16
+ return false;
17
+ }
18
+ throw error;
19
+ }
20
+ }
21
+ export async function promptCredentials(defaults, options = {}) {
22
+ const usePasswordDefault = options.usePasswordDefault ?? true;
23
+ const cuit = await input({
24
+ message: "CUIT/CUIL:",
25
+ default: defaults.cuit,
26
+ validate: (value) => (value.trim().length > 0 ? true : "Ingresá un CUIT/CUIL."),
27
+ });
28
+ const normalizedCuit = cuit.trim();
29
+ const normalizedDefaultCuit = defaults.cuit?.trim();
30
+ const passwordDefault = usePasswordDefault && normalizedCuit === normalizedDefaultCuit ? defaults.password : undefined;
31
+ const passwordMessage = passwordDefault
32
+ ? `Clave fiscal (${maskSecret(passwordDefault)}; presioná enter para usarla):`
33
+ : "Clave fiscal:";
34
+ const passwordValue = await password({
35
+ message: passwordMessage,
36
+ mask: "*",
37
+ validate: (value) => (value.length > 0 || passwordDefault ? true : "Ingresá la clave fiscal."),
38
+ });
39
+ return {
40
+ cuit: normalizedCuit,
41
+ password: passwordValue.length > 0 ? passwordValue : (passwordDefault ?? ""),
42
+ };
43
+ }
44
+ export async function promptMissingCredentials(values, defaults) {
45
+ const cuit = values.cuit ??
46
+ (await input({
47
+ message: "CUIT/CUIL:",
48
+ default: defaults.cuit,
49
+ validate: (value) => (value.trim().length > 0 ? true : "Ingresá un CUIT/CUIL."),
50
+ })).trim();
51
+ const passwordDefault = cuit === defaults.cuit?.trim() ? defaults.password : undefined;
52
+ const resolvedPassword = values.password ??
53
+ (await promptPassword({
54
+ defaultPassword: passwordDefault,
55
+ defaultLabel: passwordDefault
56
+ ? `Clave fiscal (${maskSecret(passwordDefault)}; presioná enter para usarla):`
57
+ : "Clave fiscal:",
58
+ }));
59
+ return { cuit, password: resolvedPassword };
60
+ }
61
+ export async function promptPerson(persons) {
62
+ const person = await select({
63
+ message: "Seleccione la persona a representar:",
64
+ choices: persons.map((item) => ({
65
+ name: item.id ? `${item.id}: ${item.name}` : item.name,
66
+ value: item,
67
+ })),
68
+ });
69
+ return person;
70
+ }
71
+ export async function promptMenuItem(items) {
72
+ const item = await select({
73
+ message: "Seleccione una acción:",
74
+ choices: items.map((menuItem) => ({
75
+ name: menuItem.label,
76
+ value: menuItem,
77
+ disabled: menuItem.enabled ? false : "No disponible en esta versión",
78
+ })),
79
+ });
80
+ return item;
81
+ }
82
+ export async function promptPersonalDataAction() {
83
+ console.log();
84
+ return select({
85
+ message: "Seleccione una opción:",
86
+ choices: [{ name: "Menú Principal", value: MAIN_MENU_ACTION }],
87
+ });
88
+ }
89
+ function maskSecret(secret) {
90
+ return "*".repeat(Math.max(secret.length, 4));
91
+ }
92
+ async function promptPassword(options) {
93
+ const passwordValue = await password({
94
+ message: options.defaultLabel,
95
+ mask: "*",
96
+ validate: (value) => value.length > 0 || options.defaultPassword ? true : "Ingresá la clave fiscal.",
97
+ });
98
+ return passwordValue.length > 0 ? passwordValue : (options.defaultPassword ?? "");
99
+ }
@@ -0,0 +1,13 @@
1
+ import type { FormSummary } from "../arca/form.js";
2
+ import type { DataGroup, DeductionDetailView, DeductionSummary, EmployeeSummary, PersonalDataGroup, ReceiptType } from "../types.js";
3
+ export declare function printFormSummary(summary: FormSummary): void;
4
+ export declare function renderFormSummary(summary: FormSummary, options?: {
5
+ color?: boolean;
6
+ width?: number;
7
+ }): string;
8
+ export declare function printPersonalData(groups: PersonalDataGroup[]): void;
9
+ export declare function printEmployees(employees: EmployeeSummary[]): void;
10
+ export declare function printEmployeeData(groups: DataGroup[]): void;
11
+ export declare function printDeductions(deductions: DeductionSummary[]): void;
12
+ export declare function printReceiptTypes(receiptTypes: ReceiptType[]): void;
13
+ export declare function printDeductionDetail(detail: DeductionDetailView): void;