jira-invoice 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.
- package/README.es.md +142 -0
- package/README.md +142 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +415 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.js +18 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/parser.d.ts +11 -0
- package/dist/parser.js +190 -0
- package/dist/parser.js.map +1 -0
- package/dist/renderer.d.ts +15 -0
- package/dist/renderer.js +235 -0
- package/dist/renderer.js.map +1 -0
- package/dist/setup.d.ts +10 -0
- package/dist/setup.js +176 -0
- package/dist/setup.js.map +1 -0
- package/dist/store.d.ts +7 -0
- package/dist/store.js +22 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +34 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +36 -0
package/dist/setup.js
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wizard de configuración inicial y gestión de empresas.
|
|
3
|
+
*/
|
|
4
|
+
import { input, confirm, select } from "@inquirer/prompts";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import { saveConfig } from "./store.js";
|
|
7
|
+
function slugify(name) {
|
|
8
|
+
return name
|
|
9
|
+
.toLowerCase()
|
|
10
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
11
|
+
.replace(/^-|-$/g, "");
|
|
12
|
+
}
|
|
13
|
+
// ── Setup wizard (primera ejecución) ────────────────────────────────────────
|
|
14
|
+
export async function runSetupWizard() {
|
|
15
|
+
console.log();
|
|
16
|
+
console.log(chalk.blue("┌─────────────────────────────────────────┐"));
|
|
17
|
+
console.log(chalk.blue("│") + chalk.bold.white(" ⚙️ Configuración inicial") + chalk.blue(" │"));
|
|
18
|
+
console.log(chalk.blue("│") + chalk.dim(" Se guardará en ~/.invoice/config.json") + chalk.blue(" │"));
|
|
19
|
+
console.log(chalk.blue("└─────────────────────────────────────────┘"));
|
|
20
|
+
console.log();
|
|
21
|
+
// Datos personales (FROM)
|
|
22
|
+
console.log(chalk.bold("Tus datos (emisor de la factura):"));
|
|
23
|
+
console.log();
|
|
24
|
+
const user = {
|
|
25
|
+
name: await input({ message: "Nombre completo:" }),
|
|
26
|
+
email: await input({ message: "Email:" }),
|
|
27
|
+
addr1: await input({ message: "Dirección línea 1:" }),
|
|
28
|
+
addr2: await input({ message: "Dirección línea 2 (ciudad, país):" }),
|
|
29
|
+
};
|
|
30
|
+
console.log();
|
|
31
|
+
console.log(chalk.bold("Primera empresa (receptor):"));
|
|
32
|
+
console.log();
|
|
33
|
+
const company = await promptCompany();
|
|
34
|
+
const config = { user, companies: [company] };
|
|
35
|
+
saveConfig(config);
|
|
36
|
+
console.log();
|
|
37
|
+
console.log(chalk.green("✓") + " Configuración guardada en " + chalk.cyan("~/.invoice/config.json"));
|
|
38
|
+
console.log();
|
|
39
|
+
return config;
|
|
40
|
+
}
|
|
41
|
+
// ── Agregar empresa ─────────────────────────────────────────────────────────
|
|
42
|
+
async function promptCompany() {
|
|
43
|
+
const name = await input({ message: "Nombre de la empresa:" });
|
|
44
|
+
const addr1 = await input({ message: "Dirección línea 1:" });
|
|
45
|
+
const addr2 = await input({ message: "Dirección línea 2:" });
|
|
46
|
+
const addr3 = await input({ message: "Dirección línea 3 (país):" });
|
|
47
|
+
const currency = await input({ message: "Moneda:", default: "USD" });
|
|
48
|
+
const rateStr = await input({
|
|
49
|
+
message: `Tarifa por hora (${currency}):`,
|
|
50
|
+
validate: (v) => (!isNaN(parseFloat(v)) && parseFloat(v) > 0) || "Ingresa un número válido",
|
|
51
|
+
});
|
|
52
|
+
const hasLimit = await confirm({ message: "¿Tiene límite de horas por día?", default: true });
|
|
53
|
+
let maxHoursPerDay = null;
|
|
54
|
+
if (hasLimit) {
|
|
55
|
+
const maxStr = await input({
|
|
56
|
+
message: "Máximo de horas por día:",
|
|
57
|
+
default: "8",
|
|
58
|
+
validate: (v) => (!isNaN(parseFloat(v)) && parseFloat(v) > 0) || "Ingresa un número válido",
|
|
59
|
+
});
|
|
60
|
+
maxHoursPerDay = parseFloat(maxStr);
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
id: slugify(name),
|
|
64
|
+
name,
|
|
65
|
+
addr1,
|
|
66
|
+
addr2,
|
|
67
|
+
addr3,
|
|
68
|
+
rate: parseFloat(rateStr),
|
|
69
|
+
currency,
|
|
70
|
+
maxHoursPerDay,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
export async function addCompanyWizard(config) {
|
|
74
|
+
console.log();
|
|
75
|
+
console.log(chalk.bold("Nueva empresa:"));
|
|
76
|
+
console.log();
|
|
77
|
+
const company = await promptCompany();
|
|
78
|
+
config.companies.push(company);
|
|
79
|
+
saveConfig(config);
|
|
80
|
+
console.log();
|
|
81
|
+
console.log(chalk.green("✓") + ` Empresa ${chalk.bold(company.name)} agregada`);
|
|
82
|
+
return company;
|
|
83
|
+
}
|
|
84
|
+
// ── Seleccionar empresa ─────────────────────────────────────────────────────
|
|
85
|
+
const ADD_NEW = "__add_new__";
|
|
86
|
+
const EDIT = "__edit__";
|
|
87
|
+
const EDIT_USER = "__edit_user__";
|
|
88
|
+
export async function selectCompany(config) {
|
|
89
|
+
const choices = [
|
|
90
|
+
...config.companies.map((c) => ({
|
|
91
|
+
name: `${c.name} (${c.rate} ${c.currency ?? "USD"}/h${c.maxHoursPerDay ? `, max ${c.maxHoursPerDay}h/día` : ""})`,
|
|
92
|
+
value: c.id,
|
|
93
|
+
})),
|
|
94
|
+
{ name: chalk.blue("+ Agregar nueva empresa"), value: ADD_NEW },
|
|
95
|
+
{ name: chalk.yellow("✏ Editar empresa"), value: EDIT },
|
|
96
|
+
{ name: chalk.yellow("✏ Editar mis datos"), value: EDIT_USER },
|
|
97
|
+
];
|
|
98
|
+
const selected = await select({
|
|
99
|
+
message: "🏢 Selecciona la empresa:",
|
|
100
|
+
choices,
|
|
101
|
+
});
|
|
102
|
+
if (selected === ADD_NEW) {
|
|
103
|
+
const company = await addCompanyWizard(config);
|
|
104
|
+
return { company, config };
|
|
105
|
+
}
|
|
106
|
+
if (selected === EDIT) {
|
|
107
|
+
const company = await editCompanyWizard(config);
|
|
108
|
+
return { company, config };
|
|
109
|
+
}
|
|
110
|
+
if (selected === EDIT_USER) {
|
|
111
|
+
await editUserWizard(config);
|
|
112
|
+
return selectCompany(config);
|
|
113
|
+
}
|
|
114
|
+
const company = config.companies.find((c) => c.id === selected);
|
|
115
|
+
return { company, config };
|
|
116
|
+
}
|
|
117
|
+
// ── Editar datos del usuario ────────────────────────────────────────────────
|
|
118
|
+
async function editUserWizard(config) {
|
|
119
|
+
console.log();
|
|
120
|
+
console.log(chalk.bold("Editando tus datos") + chalk.dim(" (enter para mantener valor actual)"));
|
|
121
|
+
console.log();
|
|
122
|
+
config.user.name = await input({ message: "Nombre completo:", default: config.user.name });
|
|
123
|
+
config.user.email = await input({ message: "Email:", default: config.user.email });
|
|
124
|
+
config.user.addr1 = await input({ message: "Dirección línea 1:", default: config.user.addr1 });
|
|
125
|
+
config.user.addr2 = await input({ message: "Dirección línea 2 (ciudad, país):", default: config.user.addr2 });
|
|
126
|
+
saveConfig(config);
|
|
127
|
+
console.log();
|
|
128
|
+
console.log(chalk.green("✓") + " Datos actualizados");
|
|
129
|
+
}
|
|
130
|
+
// ── Editar empresa ──────────────────────────────────────────────────────────
|
|
131
|
+
async function editCompanyWizard(config) {
|
|
132
|
+
const companyChoices = config.companies.map((c) => ({
|
|
133
|
+
name: c.name,
|
|
134
|
+
value: c.id,
|
|
135
|
+
}));
|
|
136
|
+
const companyId = await select({
|
|
137
|
+
message: "¿Cuál empresa deseas editar?",
|
|
138
|
+
choices: companyChoices,
|
|
139
|
+
});
|
|
140
|
+
const company = config.companies.find((c) => c.id === companyId);
|
|
141
|
+
console.log();
|
|
142
|
+
console.log(chalk.bold(`Editando ${company.name}`) + chalk.dim(" (enter para mantener valor actual)"));
|
|
143
|
+
console.log();
|
|
144
|
+
company.name = await input({ message: "Nombre:", default: company.name });
|
|
145
|
+
company.id = slugify(company.name);
|
|
146
|
+
company.addr1 = await input({ message: "Dirección línea 1:", default: company.addr1 });
|
|
147
|
+
company.addr2 = await input({ message: "Dirección línea 2:", default: company.addr2 });
|
|
148
|
+
company.addr3 = await input({ message: "Dirección línea 3 (país):", default: company.addr3 });
|
|
149
|
+
company.currency = await input({ message: "Moneda:", default: company.currency ?? "USD" });
|
|
150
|
+
const rateStr = await input({
|
|
151
|
+
message: `Tarifa por hora (${company.currency}):`,
|
|
152
|
+
default: String(company.rate),
|
|
153
|
+
validate: (v) => (!isNaN(parseFloat(v)) && parseFloat(v) > 0) || "Ingresa un número válido",
|
|
154
|
+
});
|
|
155
|
+
company.rate = parseFloat(rateStr);
|
|
156
|
+
const hasLimit = await confirm({
|
|
157
|
+
message: "¿Tiene límite de horas por día?",
|
|
158
|
+
default: company.maxHoursPerDay !== null,
|
|
159
|
+
});
|
|
160
|
+
if (hasLimit) {
|
|
161
|
+
const maxStr = await input({
|
|
162
|
+
message: "Máximo de horas por día:",
|
|
163
|
+
default: String(company.maxHoursPerDay ?? 8),
|
|
164
|
+
validate: (v) => (!isNaN(parseFloat(v)) && parseFloat(v) > 0) || "Ingresa un número válido",
|
|
165
|
+
});
|
|
166
|
+
company.maxHoursPerDay = parseFloat(maxStr);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
company.maxHoursPerDay = null;
|
|
170
|
+
}
|
|
171
|
+
saveConfig(config);
|
|
172
|
+
console.log();
|
|
173
|
+
console.log(chalk.green("✓") + ` Empresa ${chalk.bold(company.name)} actualizada`);
|
|
174
|
+
return company;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistencia de configuración en ~/.invoice/config.json
|
|
3
|
+
*/
|
|
4
|
+
import type { AppConfig } from "./types.js";
|
|
5
|
+
export declare function configExists(): boolean;
|
|
6
|
+
export declare function loadConfig(): AppConfig;
|
|
7
|
+
export declare function saveConfig(config: AppConfig): void;
|
package/dist/store.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistencia de configuración en ~/.invoice/config.json
|
|
3
|
+
*/
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { homedir } from "node:os";
|
|
6
|
+
import { join } from "node:path";
|
|
7
|
+
const CONFIG_DIR = join(homedir(), ".invoice");
|
|
8
|
+
const CONFIG_FILE = join(CONFIG_DIR, "config.json");
|
|
9
|
+
export function configExists() {
|
|
10
|
+
return existsSync(CONFIG_FILE);
|
|
11
|
+
}
|
|
12
|
+
export function loadConfig() {
|
|
13
|
+
const raw = readFileSync(CONFIG_FILE, "utf-8");
|
|
14
|
+
return JSON.parse(raw);
|
|
15
|
+
}
|
|
16
|
+
export function saveConfig(config) {
|
|
17
|
+
if (!existsSync(CONFIG_DIR)) {
|
|
18
|
+
mkdirSync(CONFIG_DIR, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), "utf-8");
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAC/C,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD,MAAM,UAAU,YAAY;IAC1B,OAAO,UAAU,CAAC,WAAW,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,GAAG,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAiB;IAC1C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IACD,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACvE,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface WorkEntry {
|
|
2
|
+
date: Date;
|
|
3
|
+
ticket: string;
|
|
4
|
+
desc: string;
|
|
5
|
+
hours: number;
|
|
6
|
+
rawHours: number;
|
|
7
|
+
}
|
|
8
|
+
export type CsvFormat = "pivot" | "date_col";
|
|
9
|
+
export interface ContactInfo {
|
|
10
|
+
name: string;
|
|
11
|
+
email: string;
|
|
12
|
+
addr1: string;
|
|
13
|
+
addr2: string;
|
|
14
|
+
}
|
|
15
|
+
export interface BillToInfo {
|
|
16
|
+
name: string;
|
|
17
|
+
addr1: string;
|
|
18
|
+
addr2: string;
|
|
19
|
+
addr3: string;
|
|
20
|
+
}
|
|
21
|
+
export interface Company {
|
|
22
|
+
id: string;
|
|
23
|
+
name: string;
|
|
24
|
+
addr1: string;
|
|
25
|
+
addr2: string;
|
|
26
|
+
addr3: string;
|
|
27
|
+
rate: number;
|
|
28
|
+
currency: string;
|
|
29
|
+
maxHoursPerDay: number | null;
|
|
30
|
+
}
|
|
31
|
+
export interface AppConfig {
|
|
32
|
+
user: ContactInfo;
|
|
33
|
+
companies: Company[];
|
|
34
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jira-invoice",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CLI para generar invoices PDF desde CSV de Jira",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"jira-invoice": "dist/index.js",
|
|
8
|
+
"invoice": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"dev": "tsx src/index.ts",
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"start": "node dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"@inquirer/prompts": "^7",
|
|
17
|
+
"chalk": "^5",
|
|
18
|
+
"cli-table3": "^0.6",
|
|
19
|
+
"commander": "^13",
|
|
20
|
+
"csv-parse": "^5",
|
|
21
|
+
"ora": "^8",
|
|
22
|
+
"pdfmake": "^0.2"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/node": "^22",
|
|
26
|
+
"@types/pdfmake": "^0.2",
|
|
27
|
+
"tsx": "^4",
|
|
28
|
+
"typescript": "^5.7"
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"dist"
|
|
32
|
+
],
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
}
|
|
36
|
+
}
|