@getpeppr/cli 0.1.0 → 0.2.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.md ADDED
@@ -0,0 +1,146 @@
1
+ # @getpeppr/cli
2
+
3
+ The first Peppol e-invoice validator on npm. Validate invoices offline against Peppol BIS 3.0 business rules, structure checks, and country-specific requirements.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # Run directly (no install)
9
+ npx @getpeppr/cli validate invoice.json
10
+
11
+ # Or install globally
12
+ npm install -g @getpeppr/cli
13
+ getpeppr validate invoice.json
14
+ ```
15
+
16
+ ## Usage
17
+
18
+ ### Validate an invoice
19
+
20
+ ```bash
21
+ getpeppr validate invoice.json
22
+ ```
23
+
24
+ Output:
25
+
26
+ ```
27
+ Validating: invoice.json
28
+
29
+ ── Structure ──────────────────────────────
30
+ ✓ No errors
31
+
32
+ ── Business Rules (Peppol BIS 3.0) ───────
33
+ ✓ All rules passed
34
+
35
+ ── Country Rules ────────────────────────────
36
+ ⚠ No structured communication reference (BE-02)
37
+
38
+ ── Summary ──────────────────────────────────
39
+ ✓ Invoice is valid (1 warning)
40
+ ```
41
+
42
+ ### Flags
43
+
44
+ | Flag | Description |
45
+ |------|-------------|
46
+ | `--json` | Machine-readable JSON output |
47
+ | `--quiet` | Exit code only, no output |
48
+ | `--version` | Show version number |
49
+ | `--help` | Show help |
50
+
51
+ ### Exit codes
52
+
53
+ | Code | Meaning |
54
+ |------|---------|
55
+ | `0` | Invoice is valid (may have warnings) |
56
+ | `1` | Invoice has errors — non-compliant |
57
+ | `2` | File not found or invalid JSON |
58
+
59
+ ### JSON output
60
+
61
+ ```bash
62
+ getpeppr validate invoice.json --json
63
+ ```
64
+
65
+ Returns a structured result with errors and warnings grouped by category:
66
+
67
+ ```json
68
+ {
69
+ "structure": { "errors": [], "warnings": [] },
70
+ "schematron": { "errors": [], "warnings": [] },
71
+ "countryRules": { "errors": [], "warnings": [] },
72
+ "totalErrors": 0,
73
+ "totalWarnings": 1,
74
+ "valid": true
75
+ }
76
+ ```
77
+
78
+ ### CI/CD integration
79
+
80
+ ```bash
81
+ # Fail pipeline if invoice is invalid
82
+ getpeppr validate invoice.json --quiet || exit 1
83
+ ```
84
+
85
+ ## What it validates
86
+
87
+ The CLI runs three validation engines from the [@getpeppr/sdk](https://www.npmjs.com/package/@getpeppr/sdk):
88
+
89
+ 1. **Structure** — Required fields, type checks, format validation
90
+ 2. **Business Rules** — Peppol BIS 3.0 / EN 16931 compliance (BR-xx, BR-CO-xx, PEPPOL-xx rules)
91
+ 3. **Country Rules** — Belgium (BE), France (FR), Italy (IT), Netherlands (NL), Germany (DE)
92
+
93
+ All validation runs offline — no API key or network connection required.
94
+
95
+ ## Invoice format
96
+
97
+ The input file must be a JSON object matching the getpeppr `InvoiceInput` type:
98
+
99
+ ```json
100
+ {
101
+ "number": "INV-2026-001",
102
+ "date": "2026-04-07",
103
+ "dueDate": "2026-05-07",
104
+ "currency": "EUR",
105
+ "buyerReference": "PO-12345",
106
+ "to": {
107
+ "name": "Buyer Company",
108
+ "peppolId": "0208:BE0123456789",
109
+ "street": "123 Main St",
110
+ "city": "Brussels",
111
+ "postalCode": "1050",
112
+ "country": "BE"
113
+ },
114
+ "lines": [
115
+ {
116
+ "description": "Consulting services",
117
+ "quantity": 10,
118
+ "unitPrice": 150,
119
+ "vatRate": 21
120
+ }
121
+ ]
122
+ }
123
+ ```
124
+
125
+ See the [full type reference](https://getpeppr.dev/docs/types/) for all available fields.
126
+
127
+ ## Ready to send?
128
+
129
+ Once your invoice validates, send it to the Peppol network with the getpeppr SDK:
130
+
131
+ ```bash
132
+ npm install @getpeppr/sdk
133
+ ```
134
+
135
+ ```typescript
136
+ import { Peppol } from "@getpeppr/sdk";
137
+
138
+ const peppol = new Peppol({ apiKey: "your-api-key" });
139
+ const result = await peppol.invoices.send(invoice);
140
+ ```
141
+
142
+ Sign up at [getpeppr.dev](https://getpeppr.dev) to get your API key.
143
+
144
+ ## License
145
+
146
+ MIT
package/dist/index.js CHANGED
@@ -162,11 +162,493 @@ function registerValidateCommand(program2) {
162
162
  });
163
163
  }
164
164
 
165
+ // src/commands/init.ts
166
+ import { existsSync as existsSync2, writeFileSync } from "fs";
167
+ import { resolve as resolve2 } from "path";
168
+ import pc2 from "picocolors";
169
+
170
+ // src/templates/invoice.ts
171
+ var INVOICE_TEMPLATE = {
172
+ number: "INV-2026-001",
173
+ date: "2026-01-15",
174
+ dueDate: "2026-02-15",
175
+ currency: "EUR",
176
+ buyerReference: "PO-2026-042",
177
+ from: {
178
+ name: "Soci\xE9t\xE9 \xC9clair SARL",
179
+ peppolId: "0009:FR12345678901",
180
+ street: "14 Rue de la Paix",
181
+ city: "Paris",
182
+ postalCode: "75002",
183
+ country: "FR"
184
+ },
185
+ to: {
186
+ name: "M\xFCller & Partner GmbH",
187
+ peppolId: "0204:DE987654321",
188
+ street: "Friedrichstra\xDFe 123",
189
+ city: "Berlin",
190
+ postalCode: "10117",
191
+ country: "DE"
192
+ },
193
+ lines: [
194
+ {
195
+ description: "Conseil en transformation num\xE9rique",
196
+ quantity: 10,
197
+ unitPrice: 950,
198
+ vatRate: 20
199
+ },
200
+ {
201
+ description: "Software license \u2014 annual subscription",
202
+ quantity: 1,
203
+ unitPrice: 2400,
204
+ vatRate: 0,
205
+ vatCategory: "AE"
206
+ }
207
+ ],
208
+ paymentTerms: "Net 30 days"
209
+ };
210
+
211
+ // src/templates/credit-note.ts
212
+ var CREDIT_NOTE_TEMPLATE = {
213
+ number: "CN-2026-001",
214
+ date: "2026-02-01",
215
+ currency: "EUR",
216
+ isCreditNote: true,
217
+ invoiceReference: "INV-2026-001",
218
+ from: {
219
+ name: "Soci\xE9t\xE9 \xC9clair SARL",
220
+ peppolId: "0009:FR12345678901",
221
+ street: "14 Rue de la Paix",
222
+ city: "Paris",
223
+ postalCode: "75002",
224
+ country: "FR"
225
+ },
226
+ to: {
227
+ name: "M\xFCller & Partner GmbH",
228
+ peppolId: "0204:DE987654321",
229
+ street: "Friedrichstra\xDFe 123",
230
+ city: "Berlin",
231
+ postalCode: "10117",
232
+ country: "DE"
233
+ },
234
+ lines: [
235
+ {
236
+ description: "Avoir partiel \u2014 Conseil en transformation num\xE9rique",
237
+ quantity: 2,
238
+ unitPrice: 950,
239
+ vatRate: 20
240
+ }
241
+ ],
242
+ note: "Avoir pour prestations non r\xE9alis\xE9es \u2014 r\xE9f. INV-2026-001"
243
+ };
244
+
245
+ // src/commands/init.ts
246
+ function registerInitCommand(program2) {
247
+ program2.command("init").description("Scaffold a starter invoice JSON file").argument("[filename]", "output filename", "invoice.json").option("--credit-note", "generate a credit note template instead").option("--force", "overwrite existing file").action(
248
+ (filename, options) => {
249
+ const resolved = resolve2(filename);
250
+ if (existsSync2(resolved) && !options.force) {
251
+ console.error(
252
+ `Error: ${filename} already exists. Use --force to overwrite.`
253
+ );
254
+ process.exit(2);
255
+ }
256
+ const template = options.creditNote ? CREDIT_NOTE_TEMPLATE : INVOICE_TEMPLATE;
257
+ try {
258
+ writeFileSync(
259
+ resolved,
260
+ JSON.stringify(template, null, 2) + "\n",
261
+ "utf-8"
262
+ );
263
+ } catch {
264
+ console.error(`Error: could not write file \u2014 ${resolved}`);
265
+ process.exit(2);
266
+ }
267
+ console.error(`${pc2.green("\u2713")} Created ${filename}
268
+
269
+ Next steps:
270
+ 1. Edit the file with your invoice data
271
+ 2. Validate: getpeppr validate ${filename}
272
+ 3. Convert to XML: getpeppr convert ${filename}`);
273
+ process.exit(0);
274
+ }
275
+ );
276
+ }
277
+
278
+ // src/commands/convert.ts
279
+ import { writeFileSync as writeFileSync2 } from "fs";
280
+ import pc3 from "picocolors";
281
+ import {
282
+ buildInvoiceXml,
283
+ buildCreditNoteXml
284
+ } from "@getpeppr/sdk";
285
+ function registerConvertCommand(program2) {
286
+ program2.command("convert").description(
287
+ "Convert a getpeppr JSON invoice to Peppol BIS 3.0 UBL XML"
288
+ ).argument("<file>", "path to invoice JSON file").option("-o, --output <file>", "write XML to file instead of stdout").option("--validate", "validate the invoice before converting").action(
289
+ async (file, options) => {
290
+ const parseResult = readJsonFile(file);
291
+ if (!parseResult.ok) {
292
+ process.stderr.write(parseResult.error + "\n");
293
+ process.exit(2);
294
+ }
295
+ if (typeof parseResult.data !== "object" || parseResult.data === null || Array.isArray(parseResult.data)) {
296
+ process.stderr.write(
297
+ "Error: JSON file must contain an object, not an array or primitive\n"
298
+ );
299
+ process.exit(2);
300
+ }
301
+ const input = parseResult.data;
302
+ if (options.validate) {
303
+ const result = runValidation(input);
304
+ const formatted = formatValidationResult(file, result);
305
+ if (!result.valid) {
306
+ process.stderr.write(formatted + "\n");
307
+ process.exit(1);
308
+ }
309
+ if (result.totalWarnings > 0) {
310
+ process.stderr.write(formatted + "\n");
311
+ }
312
+ }
313
+ const isCreditNote = input.isCreditNote === true;
314
+ let xml;
315
+ try {
316
+ if (isCreditNote) {
317
+ xml = buildCreditNoteXml(input);
318
+ } else {
319
+ xml = buildInvoiceXml(input);
320
+ }
321
+ } catch (err) {
322
+ const message = err instanceof Error ? err.message : "Unknown error";
323
+ process.stderr.write(`Error: XML generation failed \u2014 ${message}
324
+ `);
325
+ process.exit(2);
326
+ }
327
+ xml = xml.replace(/^[ \t]*\n/gm, "");
328
+ const docType = isCreditNote ? "UBL 2.1 CreditNote" : "UBL 2.1 Invoice";
329
+ if (options.output) {
330
+ writeFileSync2(options.output, xml, "utf-8");
331
+ process.stderr.write(
332
+ `${pc3.green("\u2713")} Converted to ${options.output} (${docType})
333
+ `
334
+ );
335
+ } else {
336
+ process.stdout.write(xml + "\n");
337
+ }
338
+ }
339
+ );
340
+ }
341
+
342
+ // src/commands/lookup.ts
343
+ import pc4 from "picocolors";
344
+
345
+ // src/lib/peppol-directory.ts
346
+ var BASE_URL = "https://directory.peppol.eu/search/1.0/json";
347
+ function stripQuotes(name) {
348
+ if (name.startsWith('"') && name.endsWith('"') && name.length >= 2) {
349
+ return name.slice(1, -1);
350
+ }
351
+ return name;
352
+ }
353
+ function pickBestName(names) {
354
+ if (names.length === 0) return "";
355
+ const english = names.find((n) => n.language === "en");
356
+ return (english ?? names[0]).name;
357
+ }
358
+ function mapDocType(urn) {
359
+ if (urn.includes("Invoice-2::Invoice##")) return "invoice";
360
+ if (urn.includes("CreditNote-2::CreditNote##")) return "credit_note";
361
+ if (urn.includes("ApplicationResponse")) return "application_response";
362
+ if (urn.includes("Order-2::Order##")) return "order";
363
+ if (urn.includes("DespatchAdvice")) return "despatch_advice";
364
+ return null;
365
+ }
366
+ function findVatIdentifier(identifiers) {
367
+ const match = identifiers.find((id) => {
368
+ const s = id.scheme.toLowerCase();
369
+ return s.includes("vat") || s.includes("cbe") || s.includes("tax");
370
+ });
371
+ return match?.value;
372
+ }
373
+ function parseMatch(raw) {
374
+ const entity = raw.entities[0];
375
+ const rawName = entity ? pickBestName(entity.name) : "";
376
+ const name = stripQuotes(rawName);
377
+ const country = entity?.countryCode ?? "";
378
+ const capabilities = (raw.docTypes ?? []).map((dt) => mapDocType(dt.value)).filter((c) => c !== null).filter((c, i, arr) => arr.indexOf(c) === i);
379
+ const vatNumber = entity?.identifiers ? findVatIdentifier(entity.identifiers) : void 0;
380
+ const contactEmail = entity?.contacts?.find((c) => c.email)?.email;
381
+ const website = entity?.websites && entity.websites.length > 0 ? entity.websites[0] : void 0;
382
+ return {
383
+ name,
384
+ peppolId: raw.participantID.value,
385
+ country,
386
+ capabilities,
387
+ registrationDate: entity?.regDate,
388
+ vatNumber,
389
+ contactEmail,
390
+ website
391
+ };
392
+ }
393
+ async function lookupParticipant(scheme, id) {
394
+ const participantParam = `iso6523-actorid-upis::${scheme}:${id}`;
395
+ const url = `${BASE_URL}?participant=${encodeURIComponent(participantParam)}`;
396
+ const response = await fetch(url);
397
+ const data = await response.json();
398
+ if (!data.matches || data.matches.length === 0) {
399
+ return null;
400
+ }
401
+ return parseMatch(data.matches[0]);
402
+ }
403
+ async function searchParticipants(opts) {
404
+ const params = new URLSearchParams();
405
+ if (opts.name) params.set("name", opts.name);
406
+ if (opts.country) params.set("country", opts.country);
407
+ const url = `${BASE_URL}?${params.toString()}`;
408
+ const response = await fetch(url);
409
+ const data = await response.json();
410
+ const allMatches = (data.matches ?? []).map(parseMatch);
411
+ const limit = opts.limit ?? 10;
412
+ const matches = allMatches.slice(0, limit);
413
+ const totalCount = data["total-result-count"] ?? 0;
414
+ const hasMore = totalCount > matches.length;
415
+ return {
416
+ matches,
417
+ totalCount,
418
+ hasMore
419
+ };
420
+ }
421
+
422
+ // src/commands/lookup.ts
423
+ var COUNTRY_NAMES = {
424
+ AT: "Austria",
425
+ BE: "Belgium",
426
+ BG: "Bulgaria",
427
+ HR: "Croatia",
428
+ CY: "Cyprus",
429
+ CZ: "Czechia",
430
+ DK: "Denmark",
431
+ EE: "Estonia",
432
+ FI: "Finland",
433
+ FR: "France",
434
+ DE: "Germany",
435
+ GR: "Greece",
436
+ HU: "Hungary",
437
+ IS: "Iceland",
438
+ IE: "Ireland",
439
+ IT: "Italy",
440
+ LV: "Latvia",
441
+ LT: "Lithuania",
442
+ LU: "Luxembourg",
443
+ MT: "Malta",
444
+ NL: "Netherlands",
445
+ NO: "Norway",
446
+ PL: "Poland",
447
+ PT: "Portugal",
448
+ RO: "Romania",
449
+ SK: "Slovakia",
450
+ SI: "Slovenia",
451
+ ES: "Spain",
452
+ SE: "Sweden",
453
+ CH: "Switzerland",
454
+ GB: "United Kingdom",
455
+ US: "United States",
456
+ AU: "Australia",
457
+ CA: "Canada",
458
+ SG: "Singapore",
459
+ JP: "Japan",
460
+ NZ: "New Zealand"
461
+ };
462
+ function countryLabel(code) {
463
+ const name = COUNTRY_NAMES[code.toUpperCase()];
464
+ return name ? `${name} (${code})` : code;
465
+ }
466
+ function formatLookupResult(match) {
467
+ const lines = [];
468
+ lines.push(`${pc4.green("\u2713")} ${match.name}`);
469
+ lines.push(` ${pc4.dim("Peppol ID")} ${match.peppolId}`);
470
+ lines.push(` ${pc4.dim("Country")} ${countryLabel(match.country)}`);
471
+ if (match.registrationDate) {
472
+ lines.push(` ${pc4.dim("Registered")} ${match.registrationDate}`);
473
+ }
474
+ if (match.vatNumber) {
475
+ lines.push(` ${pc4.dim("VAT")} ${match.vatNumber}`);
476
+ }
477
+ if (match.capabilities.length > 0) {
478
+ lines.push(
479
+ ` ${pc4.dim("Capabilities")} ${match.capabilities.join(", ")}`
480
+ );
481
+ }
482
+ if (match.contactEmail) {
483
+ lines.push(` ${pc4.dim("Contact")} ${match.contactEmail}`);
484
+ }
485
+ if (match.website) {
486
+ lines.push(` ${pc4.dim("Website")} ${match.website}`);
487
+ }
488
+ return lines.join("\n");
489
+ }
490
+ function formatSearchResults(result) {
491
+ const lines = [];
492
+ const plural = result.totalCount === 1 ? "participant" : "participants";
493
+ lines.push(`Found ${result.totalCount} ${plural}:
494
+ `);
495
+ const nameW = 26;
496
+ const idW = 23;
497
+ const countryW = 9;
498
+ lines.push(
499
+ ` ${"Name".padEnd(nameW)}${"Peppol ID".padEnd(idW)}${"Country".padEnd(countryW)}Capabilities`
500
+ );
501
+ lines.push(` ${"\u2500".repeat(nameW + idW + countryW + 20)}`);
502
+ for (const m of result.matches) {
503
+ const name = m.name.length > nameW - 1 ? m.name.slice(0, nameW - 2) + "\u2026" : m.name;
504
+ const caps = m.capabilities.join(", ");
505
+ lines.push(
506
+ ` ${name.padEnd(nameW)}${m.peppolId.padEnd(idW)}${m.country.padEnd(countryW)}${caps}`
507
+ );
508
+ }
509
+ if (result.hasMore) {
510
+ lines.push(
511
+ `
512
+ ${pc4.dim(`Showing ${result.matches.length} of ${result.totalCount} results.`)}`
513
+ );
514
+ }
515
+ return lines.join("\n");
516
+ }
517
+ function validatePeppolId(raw) {
518
+ const colonIndex = raw.indexOf(":");
519
+ if (colonIndex === -1) {
520
+ return {
521
+ ok: false,
522
+ error: `Invalid Peppol ID format: "${raw}". Expected format: scheme:id (e.g. 0208:BE0685660237)`
523
+ };
524
+ }
525
+ const scheme = raw.slice(0, colonIndex);
526
+ const id = raw.slice(colonIndex + 1);
527
+ if (!/^\d{4}$/.test(scheme)) {
528
+ return {
529
+ ok: false,
530
+ error: `Invalid scheme "${scheme}". Must be exactly 4 digits (e.g. 0208).`
531
+ };
532
+ }
533
+ if (!/^[A-Za-z0-9:.\-]+$/.test(id)) {
534
+ return {
535
+ ok: false,
536
+ error: `Invalid participant ID "${id}". Only letters, digits, colons, dots and hyphens are allowed.`
537
+ };
538
+ }
539
+ return { ok: true, scheme, id };
540
+ }
541
+ function registerLookupCommand(program2) {
542
+ program2.command("lookup").description("Look up a participant in the Peppol Directory").argument("[peppolId]", "Peppol participant ID (format: scheme:id)").option("--name <name>", "search by company name (min 3 chars)").option("--country <code>", "filter by ISO 2-letter country code").option("--json", "output results as JSON").option("--limit <n>", "max results (default 10)", "10").action(
543
+ async (peppolId, options) => {
544
+ const isSearch = Boolean(options.name);
545
+ const isLookup = Boolean(peppolId);
546
+ if (!isSearch && !isLookup) {
547
+ process.stderr.write(
548
+ "Provide a Peppol ID or use --name to search.\n"
549
+ );
550
+ process.exit(2);
551
+ }
552
+ if (options.country) {
553
+ const normalized = options.country.toUpperCase();
554
+ if (!/^[A-Z]{2}$/.test(normalized)) {
555
+ process.stderr.write(
556
+ `Invalid country code "${options.country}". Must be 2 letters (e.g. BE, DE, FR).
557
+ `
558
+ );
559
+ process.exit(2);
560
+ }
561
+ options.country = normalized;
562
+ }
563
+ if (isLookup) {
564
+ await handleLookup(peppolId, options);
565
+ } else {
566
+ await handleSearch(options);
567
+ }
568
+ }
569
+ );
570
+ }
571
+ async function handleLookup(peppolId, options) {
572
+ const parsed = validatePeppolId(peppolId);
573
+ if (!parsed.ok) {
574
+ process.stderr.write(parsed.error + "\n");
575
+ process.exit(2);
576
+ }
577
+ let result;
578
+ try {
579
+ result = await lookupParticipant(parsed.scheme, parsed.id);
580
+ } catch {
581
+ process.stderr.write(
582
+ `${pc4.red("\u2717")} Could not reach Peppol Directory. Check your internet connection.
583
+ `
584
+ );
585
+ process.exit(2);
586
+ }
587
+ if (!result) {
588
+ if (options.json) {
589
+ console.log(JSON.stringify(null));
590
+ } else {
591
+ process.stderr.write(
592
+ `${pc4.red("\u2717")} Participant not found: ${peppolId}
593
+ `
594
+ );
595
+ }
596
+ process.exit(1);
597
+ }
598
+ if (options.json) {
599
+ console.log(JSON.stringify(result, null, 2));
600
+ } else {
601
+ console.log(formatLookupResult(result));
602
+ }
603
+ process.exit(0);
604
+ }
605
+ async function handleSearch(options) {
606
+ if (options.name && options.name.length < 3) {
607
+ process.stderr.write(
608
+ `Search name must be at least 3 characters. Got: "${options.name}"
609
+ `
610
+ );
611
+ process.exit(2);
612
+ }
613
+ const limit = parseInt(options.limit ?? "10", 10);
614
+ let result;
615
+ try {
616
+ result = await searchParticipants({
617
+ name: options.name,
618
+ country: options.country,
619
+ limit
620
+ });
621
+ } catch {
622
+ process.stderr.write(
623
+ `${pc4.red("\u2717")} Could not reach Peppol Directory. Check your internet connection.
624
+ `
625
+ );
626
+ process.exit(2);
627
+ }
628
+ if (result.matches.length === 0) {
629
+ if (options.json) {
630
+ console.log(JSON.stringify(result, null, 2));
631
+ } else {
632
+ process.stderr.write("No participants found.\n");
633
+ }
634
+ process.exit(1);
635
+ }
636
+ if (options.json) {
637
+ console.log(JSON.stringify(result, null, 2));
638
+ } else {
639
+ console.log(formatSearchResults(result));
640
+ }
641
+ process.exit(0);
642
+ }
643
+
165
644
  // src/index.ts
166
645
  var require2 = createRequire(import.meta.url);
167
646
  var { version } = require2("../package.json");
168
647
  var program = new Command();
169
648
  program.name("getpeppr").description("CLI tool for Peppol e-invoice validation and development").version(version);
170
649
  registerValidateCommand(program);
650
+ registerInitCommand(program);
651
+ registerConvertCommand(program);
652
+ registerLookupCommand(program);
171
653
  program.parse();
172
654
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/utils/file.ts","../src/formatters/validation.ts","../src/commands/validate.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { Command } from \"commander\";\nimport { registerValidateCommand } from \"./commands/validate.js\";\n\nconst require = createRequire(import.meta.url);\nconst { version } = require(\"../package.json\") as { version: string };\n\nconst program = new Command();\n\nprogram\n .name(\"getpeppr\")\n .description(\"CLI tool for Peppol e-invoice validation and development\")\n .version(version);\n\nregisterValidateCommand(program);\n\nprogram.parse();\n","import { readFileSync, existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nexport type FileReadResult =\n | { ok: true; data: unknown }\n | { ok: false; error: string };\n\nexport function readJsonFile(filePath: string): FileReadResult {\n const resolved = resolve(filePath);\n\n if (!existsSync(resolved)) {\n return { ok: false, error: `Error: file not found — ${resolved}` };\n }\n\n let content: string;\n try {\n content = readFileSync(resolved, \"utf-8\");\n } catch {\n return { ok: false, error: `Error: could not read file — ${resolved}` };\n }\n\n try {\n const data: unknown = JSON.parse(content);\n return { ok: true, data };\n } catch {\n return { ok: false, error: `Error: invalid JSON in file — ${resolved}` };\n }\n}\n","import pc from \"picocolors\";\nimport type { MergedValidationResult } from \"../commands/validate.js\";\nimport type { ValidationError, ValidationWarning, SchematronViolation } from \"@getpeppr/sdk\";\n\nfunction sectionHeader(title: string): string {\n const pad = 45 - title.length - 4;\n return pc.dim(`── ${title} ${\"─\".repeat(Math.max(pad, 3))}`);\n}\n\nfunction formatError(item: ValidationError | SchematronViolation): string {\n const ruleId = \"ruleId\" in item && item.ruleId ? pc.dim(` (${item.ruleId})`) : \"\";\n const field = \"field\" in item && item.field ? `${item.field} — ` : \"\";\n return ` ${pc.red(\"✗\")} ${field}${item.message}${ruleId}`;\n}\n\nfunction formatWarning(item: ValidationWarning | SchematronViolation): string {\n const ruleId = \"ruleId\" in item && item.ruleId ? pc.dim(` (${item.ruleId})`) : \"\";\n const field = \"field\" in item && item.field ? `${item.field} — ` : \"\";\n return ` ${pc.yellow(\"⚠\")} ${field}${item.message}${ruleId}`;\n}\n\nfunction formatSection(\n title: string,\n errors: (ValidationError | SchematronViolation)[],\n warnings: (ValidationWarning | SchematronViolation)[],\n): string {\n const lines: string[] = [sectionHeader(title)];\n\n if (errors.length === 0 && warnings.length === 0) {\n lines.push(` ${pc.green(\"✓\")} All rules passed`);\n return lines.join(\"\\n\");\n }\n\n if (errors.length === 0) {\n lines.push(` ${pc.green(\"✓\")} No errors`);\n }\n\n for (const err of errors) {\n lines.push(formatError(err));\n }\n\n for (const warn of warnings) {\n lines.push(formatWarning(warn));\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function formatValidationResult(\n filename: string,\n result: MergedValidationResult,\n): string {\n const lines: string[] = [];\n\n lines.push(`\\nValidating: ${pc.bold(filename)}\\n`);\n\n lines.push(\n formatSection(\n \"Structure\",\n result.structure.errors,\n result.structure.warnings,\n ),\n );\n lines.push(\"\");\n\n lines.push(\n formatSection(\n \"Business Rules (Peppol BIS 3.0)\",\n result.schematron.errors,\n result.schematron.warnings,\n ),\n );\n lines.push(\"\");\n\n lines.push(\n formatSection(\n \"Country Rules\",\n result.countryRules.errors,\n result.countryRules.warnings,\n ),\n );\n lines.push(\"\");\n\n // Summary\n lines.push(sectionHeader(\"Summary\"));\n const { totalErrors, totalWarnings, valid } = result;\n\n if (valid && totalWarnings === 0) {\n lines.push(` ${pc.green(pc.bold(\"✓ Invoice is valid\"))}`);\n } else if (valid) {\n lines.push(\n ` ${pc.green(pc.bold(\"✓ Invoice is valid\"))} ${pc.dim(`(${totalWarnings} warning${totalWarnings === 1 ? \"\" : \"s\"})`)}`,\n );\n } else {\n const parts: string[] = [];\n parts.push(`${totalErrors} error${totalErrors === 1 ? \"\" : \"s\"}`);\n if (totalWarnings > 0) {\n parts.push(`${totalWarnings} warning${totalWarnings === 1 ? \"\" : \"s\"}`);\n }\n lines.push(\n ` ${pc.red(pc.bold(`✗ ${parts.join(\", \")}`))} — invoice non-compliant`,\n );\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n","import type { Command } from \"commander\";\nimport { readJsonFile } from \"../utils/file.js\";\nimport { formatValidationResult } from \"../formatters/validation.js\";\nimport {\n validateInvoice,\n validateSchematron,\n validateCountryRules,\n type InvoiceInput,\n type ValidationError,\n type ValidationWarning,\n type SchematronViolation,\n} from \"@getpeppr/sdk\";\n\nexport interface MergedValidationResult {\n structure: {\n errors: ValidationError[];\n warnings: ValidationWarning[];\n };\n schematron: {\n errors: SchematronViolation[];\n warnings: SchematronViolation[];\n };\n countryRules: {\n errors: ValidationError[];\n warnings: ValidationWarning[];\n };\n totalErrors: number;\n totalWarnings: number;\n valid: boolean;\n}\n\nexport function runValidation(input: InvoiceInput): MergedValidationResult {\n const structure = validateInvoice(input);\n const schematron = validateSchematron(input);\n const countryRules = validateCountryRules(input);\n\n const totalErrors =\n structure.errors.length +\n schematron.errors.length +\n countryRules.errors.length;\n\n const totalWarnings =\n structure.warnings.length +\n schematron.warnings.length +\n countryRules.warnings.length;\n\n return {\n structure: { errors: structure.errors, warnings: structure.warnings },\n schematron: { errors: schematron.errors, warnings: schematron.warnings },\n countryRules: {\n errors: countryRules.errors,\n warnings: countryRules.warnings,\n },\n totalErrors,\n totalWarnings,\n valid: totalErrors === 0,\n };\n}\n\nexport function registerValidateCommand(program: Command): void {\n program\n .command(\"validate\")\n .description(\"Validate a Peppol invoice JSON file\")\n .argument(\"<file>\", \"path to invoice JSON file\")\n .option(\"--json\", \"output results as JSON\")\n .option(\"--quiet\", \"exit code only, no output\")\n .action(async (file: string, options: { json?: boolean; quiet?: boolean }) => {\n // 1. Read and parse the JSON file\n // Fatal errors always go to stderr regardless of --quiet (UNIX convention)\n const parseResult = readJsonFile(file);\n if (!parseResult.ok) {\n process.stderr.write(parseResult.error + \"\\n\");\n process.exit(2);\n }\n\n if (\n typeof parseResult.data !== \"object\" ||\n parseResult.data === null ||\n Array.isArray(parseResult.data)\n ) {\n process.stderr.write(\n \"Error: JSON file must contain an object, not an array or primitive\\n\",\n );\n process.exit(2);\n }\n\n const input = parseResult.data as InvoiceInput;\n\n // 2. Run all 3 validators\n const result = runValidation(input);\n\n // 3. Output\n if (options.quiet) {\n process.exit(result.valid ? 0 : 1);\n }\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n process.exit(result.valid ? 0 : 1);\n }\n\n // 4. Formatted output\n const output = formatValidationResult(file, result);\n console.log(output);\n process.exit(result.valid ? 0 : 1);\n });\n}\n"],"mappings":";;;AAAA,SAAS,qBAAqB;AAC9B,SAAS,eAAe;;;ACDxB,SAAS,cAAc,kBAAkB;AACzC,SAAS,eAAe;AAMjB,SAAS,aAAa,UAAkC;AAC7D,QAAM,WAAW,QAAQ,QAAQ;AAEjC,MAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,WAAO,EAAE,IAAI,OAAO,OAAO,gCAA2B,QAAQ,GAAG;AAAA,EACnE;AAEA,MAAI;AACJ,MAAI;AACF,cAAU,aAAa,UAAU,OAAO;AAAA,EAC1C,QAAQ;AACN,WAAO,EAAE,IAAI,OAAO,OAAO,qCAAgC,QAAQ,GAAG;AAAA,EACxE;AAEA,MAAI;AACF,UAAM,OAAgB,KAAK,MAAM,OAAO;AACxC,WAAO,EAAE,IAAI,MAAM,KAAK;AAAA,EAC1B,QAAQ;AACN,WAAO,EAAE,IAAI,OAAO,OAAO,sCAAiC,QAAQ,GAAG;AAAA,EACzE;AACF;;;AC3BA,OAAO,QAAQ;AAIf,SAAS,cAAc,OAAuB;AAC5C,QAAM,MAAM,KAAK,MAAM,SAAS;AAChC,SAAO,GAAG,IAAI,gBAAM,KAAK,IAAI,SAAI,OAAO,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE;AAC7D;AAEA,SAAS,YAAY,MAAqD;AACxE,QAAM,SAAS,YAAY,QAAQ,KAAK,SAAS,GAAG,IAAI,KAAK,KAAK,MAAM,GAAG,IAAI;AAC/E,QAAM,QAAQ,WAAW,QAAQ,KAAK,QAAQ,GAAG,KAAK,KAAK,aAAQ;AACnE,SAAO,KAAK,GAAG,IAAI,QAAG,CAAC,IAAI,KAAK,GAAG,KAAK,OAAO,GAAG,MAAM;AAC1D;AAEA,SAAS,cAAc,MAAuD;AAC5E,QAAM,SAAS,YAAY,QAAQ,KAAK,SAAS,GAAG,IAAI,KAAK,KAAK,MAAM,GAAG,IAAI;AAC/E,QAAM,QAAQ,WAAW,QAAQ,KAAK,QAAQ,GAAG,KAAK,KAAK,aAAQ;AACnE,SAAO,KAAK,GAAG,OAAO,QAAG,CAAC,IAAI,KAAK,GAAG,KAAK,OAAO,GAAG,MAAM;AAC7D;AAEA,SAAS,cACP,OACA,QACA,UACQ;AACR,QAAM,QAAkB,CAAC,cAAc,KAAK,CAAC;AAE7C,MAAI,OAAO,WAAW,KAAK,SAAS,WAAW,GAAG;AAChD,UAAM,KAAK,KAAK,GAAG,MAAM,QAAG,CAAC,mBAAmB;AAChD,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAEA,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,KAAK,KAAK,GAAG,MAAM,QAAG,CAAC,YAAY;AAAA,EAC3C;AAEA,aAAW,OAAO,QAAQ;AACxB,UAAM,KAAK,YAAY,GAAG,CAAC;AAAA,EAC7B;AAEA,aAAW,QAAQ,UAAU;AAC3B,UAAM,KAAK,cAAc,IAAI,CAAC;AAAA,EAChC;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEO,SAAS,uBACd,UACA,QACQ;AACR,QAAM,QAAkB,CAAC;AAEzB,QAAM,KAAK;AAAA,cAAiB,GAAG,KAAK,QAAQ,CAAC;AAAA,CAAI;AAEjD,QAAM;AAAA,IACJ;AAAA,MACE;AAAA,MACA,OAAO,UAAU;AAAA,MACjB,OAAO,UAAU;AAAA,IACnB;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM;AAAA,IACJ;AAAA,MACE;AAAA,MACA,OAAO,WAAW;AAAA,MAClB,OAAO,WAAW;AAAA,IACpB;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAEb,QAAM;AAAA,IACJ;AAAA,MACE;AAAA,MACA,OAAO,aAAa;AAAA,MACpB,OAAO,aAAa;AAAA,IACtB;AAAA,EACF;AACA,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,cAAc,SAAS,CAAC;AACnC,QAAM,EAAE,aAAa,eAAe,MAAM,IAAI;AAE9C,MAAI,SAAS,kBAAkB,GAAG;AAChC,UAAM,KAAK,KAAK,GAAG,MAAM,GAAG,KAAK,yBAAoB,CAAC,CAAC,EAAE;AAAA,EAC3D,WAAW,OAAO;AAChB,UAAM;AAAA,MACJ,KAAK,GAAG,MAAM,GAAG,KAAK,yBAAoB,CAAC,CAAC,IAAI,GAAG,IAAI,IAAI,aAAa,WAAW,kBAAkB,IAAI,KAAK,GAAG,GAAG,CAAC;AAAA,IACvH;AAAA,EACF,OAAO;AACL,UAAM,QAAkB,CAAC;AACzB,UAAM,KAAK,GAAG,WAAW,SAAS,gBAAgB,IAAI,KAAK,GAAG,EAAE;AAChE,QAAI,gBAAgB,GAAG;AACrB,YAAM,KAAK,GAAG,aAAa,WAAW,kBAAkB,IAAI,KAAK,GAAG,EAAE;AAAA,IACxE;AACA,UAAM;AAAA,MACJ,KAAK,GAAG,IAAI,GAAG,KAAK,UAAK,MAAM,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;AAAA,IAC/C;AAAA,EACF;AAEA,QAAM,KAAK,EAAE;AACb,SAAO,MAAM,KAAK,IAAI;AACxB;;;ACvGA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AAoBA,SAAS,cAAc,OAA6C;AACzE,QAAM,YAAY,gBAAgB,KAAK;AACvC,QAAM,aAAa,mBAAmB,KAAK;AAC3C,QAAM,eAAe,qBAAqB,KAAK;AAE/C,QAAM,cACJ,UAAU,OAAO,SACjB,WAAW,OAAO,SAClB,aAAa,OAAO;AAEtB,QAAM,gBACJ,UAAU,SAAS,SACnB,WAAW,SAAS,SACpB,aAAa,SAAS;AAExB,SAAO;AAAA,IACL,WAAW,EAAE,QAAQ,UAAU,QAAQ,UAAU,UAAU,SAAS;AAAA,IACpE,YAAY,EAAE,QAAQ,WAAW,QAAQ,UAAU,WAAW,SAAS;AAAA,IACvE,cAAc;AAAA,MACZ,QAAQ,aAAa;AAAA,MACrB,UAAU,aAAa;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA,OAAO,gBAAgB;AAAA,EACzB;AACF;AAEO,SAAS,wBAAwBA,UAAwB;AAC9D,EAAAA,SACG,QAAQ,UAAU,EAClB,YAAY,qCAAqC,EACjD,SAAS,UAAU,2BAA2B,EAC9C,OAAO,UAAU,wBAAwB,EACzC,OAAO,WAAW,2BAA2B,EAC7C,OAAO,OAAO,MAAc,YAAiD;AAG5E,UAAM,cAAc,aAAa,IAAI;AACrC,QAAI,CAAC,YAAY,IAAI;AACnB,cAAQ,OAAO,MAAM,YAAY,QAAQ,IAAI;AAC7C,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QACE,OAAO,YAAY,SAAS,YAC5B,YAAY,SAAS,QACrB,MAAM,QAAQ,YAAY,IAAI,GAC9B;AACA,cAAQ,OAAO;AAAA,QACb;AAAA,MACF;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,QAAQ,YAAY;AAG1B,UAAM,SAAS,cAAc,KAAK;AAGlC,QAAI,QAAQ,OAAO;AACjB,cAAQ,KAAK,OAAO,QAAQ,IAAI,CAAC;AAAA,IACnC;AAEA,QAAI,QAAQ,MAAM;AAChB,cAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC3C,cAAQ,KAAK,OAAO,QAAQ,IAAI,CAAC;AAAA,IACnC;AAGA,UAAM,SAAS,uBAAuB,MAAM,MAAM;AAClD,YAAQ,IAAI,MAAM;AAClB,YAAQ,KAAK,OAAO,QAAQ,IAAI,CAAC;AAAA,EACnC,CAAC;AACL;;;AHtGA,IAAMC,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,EAAE,QAAQ,IAAIA,SAAQ,iBAAiB;AAE7C,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,UAAU,EACf,YAAY,0DAA0D,EACtE,QAAQ,OAAO;AAElB,wBAAwB,OAAO;AAE/B,QAAQ,MAAM;","names":["program","require"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/utils/file.ts","../src/formatters/validation.ts","../src/commands/validate.ts","../src/commands/init.ts","../src/templates/invoice.ts","../src/templates/credit-note.ts","../src/commands/convert.ts","../src/commands/lookup.ts","../src/lib/peppol-directory.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { Command } from \"commander\";\nimport { registerValidateCommand } from \"./commands/validate.js\";\nimport { registerInitCommand } from \"./commands/init.js\";\nimport { registerConvertCommand } from \"./commands/convert.js\";\nimport { registerLookupCommand } from \"./commands/lookup.js\";\n\nconst require = createRequire(import.meta.url);\nconst { version } = require(\"../package.json\") as { version: string };\n\nconst program = new Command();\n\nprogram\n .name(\"getpeppr\")\n .description(\"CLI tool for Peppol e-invoice validation and development\")\n .version(version);\n\nregisterValidateCommand(program);\nregisterInitCommand(program);\nregisterConvertCommand(program);\nregisterLookupCommand(program);\n\nprogram.parse();\n","import { readFileSync, existsSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\n\nexport type FileReadResult =\n | { ok: true; data: unknown }\n | { ok: false; error: string };\n\nexport function readJsonFile(filePath: string): FileReadResult {\n const resolved = resolve(filePath);\n\n if (!existsSync(resolved)) {\n return { ok: false, error: `Error: file not found — ${resolved}` };\n }\n\n let content: string;\n try {\n content = readFileSync(resolved, \"utf-8\");\n } catch {\n return { ok: false, error: `Error: could not read file — ${resolved}` };\n }\n\n try {\n const data: unknown = JSON.parse(content);\n return { ok: true, data };\n } catch {\n return { ok: false, error: `Error: invalid JSON in file — ${resolved}` };\n }\n}\n","import pc from \"picocolors\";\nimport type { MergedValidationResult } from \"../commands/validate.js\";\nimport type { ValidationError, ValidationWarning, SchematronViolation } from \"@getpeppr/sdk\";\n\nfunction sectionHeader(title: string): string {\n const pad = 45 - title.length - 4;\n return pc.dim(`── ${title} ${\"─\".repeat(Math.max(pad, 3))}`);\n}\n\nfunction formatError(item: ValidationError | SchematronViolation): string {\n const ruleId = \"ruleId\" in item && item.ruleId ? pc.dim(` (${item.ruleId})`) : \"\";\n const field = \"field\" in item && item.field ? `${item.field} — ` : \"\";\n return ` ${pc.red(\"✗\")} ${field}${item.message}${ruleId}`;\n}\n\nfunction formatWarning(item: ValidationWarning | SchematronViolation): string {\n const ruleId = \"ruleId\" in item && item.ruleId ? pc.dim(` (${item.ruleId})`) : \"\";\n const field = \"field\" in item && item.field ? `${item.field} — ` : \"\";\n return ` ${pc.yellow(\"⚠\")} ${field}${item.message}${ruleId}`;\n}\n\nfunction formatSection(\n title: string,\n errors: (ValidationError | SchematronViolation)[],\n warnings: (ValidationWarning | SchematronViolation)[],\n): string {\n const lines: string[] = [sectionHeader(title)];\n\n if (errors.length === 0 && warnings.length === 0) {\n lines.push(` ${pc.green(\"✓\")} All rules passed`);\n return lines.join(\"\\n\");\n }\n\n if (errors.length === 0) {\n lines.push(` ${pc.green(\"✓\")} No errors`);\n }\n\n for (const err of errors) {\n lines.push(formatError(err));\n }\n\n for (const warn of warnings) {\n lines.push(formatWarning(warn));\n }\n\n return lines.join(\"\\n\");\n}\n\nexport function formatValidationResult(\n filename: string,\n result: MergedValidationResult,\n): string {\n const lines: string[] = [];\n\n lines.push(`\\nValidating: ${pc.bold(filename)}\\n`);\n\n lines.push(\n formatSection(\n \"Structure\",\n result.structure.errors,\n result.structure.warnings,\n ),\n );\n lines.push(\"\");\n\n lines.push(\n formatSection(\n \"Business Rules (Peppol BIS 3.0)\",\n result.schematron.errors,\n result.schematron.warnings,\n ),\n );\n lines.push(\"\");\n\n lines.push(\n formatSection(\n \"Country Rules\",\n result.countryRules.errors,\n result.countryRules.warnings,\n ),\n );\n lines.push(\"\");\n\n // Summary\n lines.push(sectionHeader(\"Summary\"));\n const { totalErrors, totalWarnings, valid } = result;\n\n if (valid && totalWarnings === 0) {\n lines.push(` ${pc.green(pc.bold(\"✓ Invoice is valid\"))}`);\n } else if (valid) {\n lines.push(\n ` ${pc.green(pc.bold(\"✓ Invoice is valid\"))} ${pc.dim(`(${totalWarnings} warning${totalWarnings === 1 ? \"\" : \"s\"})`)}`,\n );\n } else {\n const parts: string[] = [];\n parts.push(`${totalErrors} error${totalErrors === 1 ? \"\" : \"s\"}`);\n if (totalWarnings > 0) {\n parts.push(`${totalWarnings} warning${totalWarnings === 1 ? \"\" : \"s\"}`);\n }\n lines.push(\n ` ${pc.red(pc.bold(`✗ ${parts.join(\", \")}`))} — invoice non-compliant`,\n );\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n","import type { Command } from \"commander\";\nimport { readJsonFile } from \"../utils/file.js\";\nimport { formatValidationResult } from \"../formatters/validation.js\";\nimport {\n validateInvoice,\n validateSchematron,\n validateCountryRules,\n type InvoiceInput,\n type ValidationError,\n type ValidationWarning,\n type SchematronViolation,\n} from \"@getpeppr/sdk\";\n\nexport interface MergedValidationResult {\n structure: {\n errors: ValidationError[];\n warnings: ValidationWarning[];\n };\n schematron: {\n errors: SchematronViolation[];\n warnings: SchematronViolation[];\n };\n countryRules: {\n errors: ValidationError[];\n warnings: ValidationWarning[];\n };\n totalErrors: number;\n totalWarnings: number;\n valid: boolean;\n}\n\nexport function runValidation(input: InvoiceInput): MergedValidationResult {\n const structure = validateInvoice(input);\n const schematron = validateSchematron(input);\n const countryRules = validateCountryRules(input);\n\n const totalErrors =\n structure.errors.length +\n schematron.errors.length +\n countryRules.errors.length;\n\n const totalWarnings =\n structure.warnings.length +\n schematron.warnings.length +\n countryRules.warnings.length;\n\n return {\n structure: { errors: structure.errors, warnings: structure.warnings },\n schematron: { errors: schematron.errors, warnings: schematron.warnings },\n countryRules: {\n errors: countryRules.errors,\n warnings: countryRules.warnings,\n },\n totalErrors,\n totalWarnings,\n valid: totalErrors === 0,\n };\n}\n\nexport function registerValidateCommand(program: Command): void {\n program\n .command(\"validate\")\n .description(\"Validate a Peppol invoice JSON file\")\n .argument(\"<file>\", \"path to invoice JSON file\")\n .option(\"--json\", \"output results as JSON\")\n .option(\"--quiet\", \"exit code only, no output\")\n .action(async (file: string, options: { json?: boolean; quiet?: boolean }) => {\n // 1. Read and parse the JSON file\n // Fatal errors always go to stderr regardless of --quiet (UNIX convention)\n const parseResult = readJsonFile(file);\n if (!parseResult.ok) {\n process.stderr.write(parseResult.error + \"\\n\");\n process.exit(2);\n }\n\n if (\n typeof parseResult.data !== \"object\" ||\n parseResult.data === null ||\n Array.isArray(parseResult.data)\n ) {\n process.stderr.write(\n \"Error: JSON file must contain an object, not an array or primitive\\n\",\n );\n process.exit(2);\n }\n\n const input = parseResult.data as InvoiceInput;\n\n // 2. Run all 3 validators\n const result = runValidation(input);\n\n // 3. Output\n if (options.quiet) {\n process.exit(result.valid ? 0 : 1);\n }\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n process.exit(result.valid ? 0 : 1);\n }\n\n // 4. Formatted output\n const output = formatValidationResult(file, result);\n console.log(output);\n process.exit(result.valid ? 0 : 1);\n });\n}\n","import { existsSync, writeFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { INVOICE_TEMPLATE } from \"../templates/invoice.js\";\nimport { CREDIT_NOTE_TEMPLATE } from \"../templates/credit-note.js\";\n\nexport function registerInitCommand(program: Command): void {\n program\n .command(\"init\")\n .description(\"Scaffold a starter invoice JSON file\")\n .argument(\"[filename]\", \"output filename\", \"invoice.json\")\n .option(\"--credit-note\", \"generate a credit note template instead\")\n .option(\"--force\", \"overwrite existing file\")\n .action(\n (\n filename: string,\n options: { creditNote?: boolean; force?: boolean },\n ) => {\n const resolved = resolve(filename);\n\n if (existsSync(resolved) && !options.force) {\n console.error(\n `Error: ${filename} already exists. Use --force to overwrite.`,\n );\n process.exit(2);\n }\n\n const template = options.creditNote\n ? CREDIT_NOTE_TEMPLATE\n : INVOICE_TEMPLATE;\n\n try {\n writeFileSync(\n resolved,\n JSON.stringify(template, null, 2) + \"\\n\",\n \"utf-8\",\n );\n } catch {\n console.error(`Error: could not write file — ${resolved}`);\n process.exit(2);\n }\n\n console.error(`${pc.green(\"\\u2713\")} Created ${filename}\n\n Next steps:\n 1. Edit the file with your invoice data\n 2. Validate: getpeppr validate ${filename}\n 3. Convert to XML: getpeppr convert ${filename}`);\n\n process.exit(0);\n },\n );\n}\n","import type { InvoiceInput } from \"@getpeppr/sdk\";\n\nexport const INVOICE_TEMPLATE: InvoiceInput = {\n number: \"INV-2026-001\",\n date: \"2026-01-15\",\n dueDate: \"2026-02-15\",\n currency: \"EUR\",\n buyerReference: \"PO-2026-042\",\n from: {\n name: \"Soci\\u00e9t\\u00e9 \\u00c9clair SARL\",\n peppolId: \"0009:FR12345678901\",\n street: \"14 Rue de la Paix\",\n city: \"Paris\",\n postalCode: \"75002\",\n country: \"FR\",\n },\n to: {\n name: \"M\\u00fcller & Partner GmbH\",\n peppolId: \"0204:DE987654321\",\n street: \"Friedrichstra\\u00dfe 123\",\n city: \"Berlin\",\n postalCode: \"10117\",\n country: \"DE\",\n },\n lines: [\n {\n description: \"Conseil en transformation num\\u00e9rique\",\n quantity: 10,\n unitPrice: 950,\n vatRate: 20,\n },\n {\n description: \"Software license \\u2014 annual subscription\",\n quantity: 1,\n unitPrice: 2400,\n vatRate: 0,\n vatCategory: \"AE\",\n },\n ],\n paymentTerms: \"Net 30 days\",\n};\n","import type { InvoiceInput } from \"@getpeppr/sdk\";\n\nexport const CREDIT_NOTE_TEMPLATE: InvoiceInput = {\n number: \"CN-2026-001\",\n date: \"2026-02-01\",\n currency: \"EUR\",\n isCreditNote: true,\n invoiceReference: \"INV-2026-001\",\n from: {\n name: \"Soci\\u00e9t\\u00e9 \\u00c9clair SARL\",\n peppolId: \"0009:FR12345678901\",\n street: \"14 Rue de la Paix\",\n city: \"Paris\",\n postalCode: \"75002\",\n country: \"FR\",\n },\n to: {\n name: \"M\\u00fcller & Partner GmbH\",\n peppolId: \"0204:DE987654321\",\n street: \"Friedrichstra\\u00dfe 123\",\n city: \"Berlin\",\n postalCode: \"10117\",\n country: \"DE\",\n },\n lines: [\n {\n description: \"Avoir partiel \\u2014 Conseil en transformation num\\u00e9rique\",\n quantity: 2,\n unitPrice: 950,\n vatRate: 20,\n },\n ],\n note: \"Avoir pour prestations non r\\u00e9alis\\u00e9es \\u2014 r\\u00e9f. INV-2026-001\",\n};\n","import { writeFileSync } from \"node:fs\";\nimport type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport { readJsonFile } from \"../utils/file.js\";\nimport { runValidation } from \"./validate.js\";\nimport { formatValidationResult } from \"../formatters/validation.js\";\nimport {\n buildInvoiceXml,\n buildCreditNoteXml,\n type InvoiceInput,\n type CreditNoteInput,\n} from \"@getpeppr/sdk\";\n\nexport function registerConvertCommand(program: Command): void {\n program\n .command(\"convert\")\n .description(\n \"Convert a getpeppr JSON invoice to Peppol BIS 3.0 UBL XML\",\n )\n .argument(\"<file>\", \"path to invoice JSON file\")\n .option(\"-o, --output <file>\", \"write XML to file instead of stdout\")\n .option(\"--validate\", \"validate the invoice before converting\")\n .action(\n async (\n file: string,\n options: { output?: string; validate?: boolean },\n ) => {\n // 1. Read and parse the JSON file\n const parseResult = readJsonFile(file);\n if (!parseResult.ok) {\n process.stderr.write(parseResult.error + \"\\n\");\n process.exit(2);\n }\n\n if (\n typeof parseResult.data !== \"object\" ||\n parseResult.data === null ||\n Array.isArray(parseResult.data)\n ) {\n process.stderr.write(\n \"Error: JSON file must contain an object, not an array or primitive\\n\",\n );\n process.exit(2);\n }\n\n const input = parseResult.data as InvoiceInput;\n\n // 2. If --validate, run validation first\n if (options.validate) {\n const result = runValidation(input);\n const formatted = formatValidationResult(file, result);\n\n if (!result.valid) {\n // Errors: show on stderr, exit 1, NO XML\n process.stderr.write(formatted + \"\\n\");\n process.exit(1);\n }\n\n if (result.totalWarnings > 0) {\n // Warnings only: show on stderr, continue to conversion\n process.stderr.write(formatted + \"\\n\");\n }\n }\n\n // 3. Detect document type\n const isCreditNote = input.isCreditNote === true;\n\n // 4. Generate XML\n let xml: string;\n try {\n if (isCreditNote) {\n xml = buildCreditNoteXml(input as CreditNoteInput);\n } else {\n xml = buildInvoiceXml(input);\n }\n } catch (err: unknown) {\n const message =\n err instanceof Error ? err.message : \"Unknown error\";\n process.stderr.write(`Error: XML generation failed — ${message}\\n`);\n process.exit(2);\n }\n\n // 5. Clean empty lines from XML\n xml = xml.replace(/^[ \\t]*\\n/gm, \"\");\n\n // 6. Output\n const docType = isCreditNote\n ? \"UBL 2.1 CreditNote\"\n : \"UBL 2.1 Invoice\";\n\n if (options.output) {\n writeFileSync(options.output, xml, \"utf-8\");\n process.stderr.write(\n `${pc.green(\"✓\")} Converted to ${options.output} (${docType})\\n`,\n );\n } else {\n process.stdout.write(xml + \"\\n\");\n }\n },\n );\n}\n","import type { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport {\n lookupParticipant,\n searchParticipants,\n type DirectoryMatch,\n type SearchResult,\n} from \"../lib/peppol-directory.js\";\n\n// ─── Country name helper ──────────────────────────\n\nconst COUNTRY_NAMES: Record<string, string> = {\n AT: \"Austria\",\n BE: \"Belgium\",\n BG: \"Bulgaria\",\n HR: \"Croatia\",\n CY: \"Cyprus\",\n CZ: \"Czechia\",\n DK: \"Denmark\",\n EE: \"Estonia\",\n FI: \"Finland\",\n FR: \"France\",\n DE: \"Germany\",\n GR: \"Greece\",\n HU: \"Hungary\",\n IS: \"Iceland\",\n IE: \"Ireland\",\n IT: \"Italy\",\n LV: \"Latvia\",\n LT: \"Lithuania\",\n LU: \"Luxembourg\",\n MT: \"Malta\",\n NL: \"Netherlands\",\n NO: \"Norway\",\n PL: \"Poland\",\n PT: \"Portugal\",\n RO: \"Romania\",\n SK: \"Slovakia\",\n SI: \"Slovenia\",\n ES: \"Spain\",\n SE: \"Sweden\",\n CH: \"Switzerland\",\n GB: \"United Kingdom\",\n US: \"United States\",\n AU: \"Australia\",\n CA: \"Canada\",\n SG: \"Singapore\",\n JP: \"Japan\",\n NZ: \"New Zealand\",\n};\n\nfunction countryLabel(code: string): string {\n const name = COUNTRY_NAMES[code.toUpperCase()];\n return name ? `${name} (${code})` : code;\n}\n\n// ─── Output formatting ───────────────────────────\n\nfunction formatLookupResult(match: DirectoryMatch): string {\n const lines: string[] = [];\n lines.push(`${pc.green(\"\\u2713\")} ${match.name}`);\n lines.push(` ${pc.dim(\"Peppol ID\")} ${match.peppolId}`);\n lines.push(` ${pc.dim(\"Country\")} ${countryLabel(match.country)}`);\n if (match.registrationDate) {\n lines.push(` ${pc.dim(\"Registered\")} ${match.registrationDate}`);\n }\n if (match.vatNumber) {\n lines.push(` ${pc.dim(\"VAT\")} ${match.vatNumber}`);\n }\n if (match.capabilities.length > 0) {\n lines.push(\n ` ${pc.dim(\"Capabilities\")} ${match.capabilities.join(\", \")}`,\n );\n }\n if (match.contactEmail) {\n lines.push(` ${pc.dim(\"Contact\")} ${match.contactEmail}`);\n }\n if (match.website) {\n lines.push(` ${pc.dim(\"Website\")} ${match.website}`);\n }\n return lines.join(\"\\n\");\n}\n\nfunction formatSearchResults(result: SearchResult): string {\n const lines: string[] = [];\n const plural = result.totalCount === 1 ? \"participant\" : \"participants\";\n lines.push(`Found ${result.totalCount} ${plural}:\\n`);\n\n // Column headers\n const nameW = 26;\n const idW = 23;\n const countryW = 9;\n\n lines.push(\n ` ${\"Name\".padEnd(nameW)}${\"Peppol ID\".padEnd(idW)}${\"Country\".padEnd(countryW)}Capabilities`,\n );\n lines.push(` ${\"─\".repeat(nameW + idW + countryW + 20)}`);\n\n for (const m of result.matches) {\n const name = m.name.length > nameW - 1 ? m.name.slice(0, nameW - 2) + \"…\" : m.name;\n const caps = m.capabilities.join(\", \");\n lines.push(\n ` ${name.padEnd(nameW)}${m.peppolId.padEnd(idW)}${m.country.padEnd(countryW)}${caps}`,\n );\n }\n\n if (result.hasMore) {\n lines.push(\n `\\n ${pc.dim(`Showing ${result.matches.length} of ${result.totalCount} results.`)}`,\n );\n }\n\n return lines.join(\"\\n\");\n}\n\n// ─── Input validation ─────────────────────────────\n\nfunction validatePeppolId(raw: string): {\n ok: true;\n scheme: string;\n id: string;\n} | { ok: false; error: string } {\n const colonIndex = raw.indexOf(\":\");\n if (colonIndex === -1) {\n return {\n ok: false,\n error: `Invalid Peppol ID format: \"${raw}\". Expected format: scheme:id (e.g. 0208:BE0685660237)`,\n };\n }\n\n const scheme = raw.slice(0, colonIndex);\n const id = raw.slice(colonIndex + 1);\n\n if (!/^\\d{4}$/.test(scheme)) {\n return {\n ok: false,\n error: `Invalid scheme \"${scheme}\". Must be exactly 4 digits (e.g. 0208).`,\n };\n }\n\n if (!/^[A-Za-z0-9:.\\-]+$/.test(id)) {\n return {\n ok: false,\n error: `Invalid participant ID \"${id}\". Only letters, digits, colons, dots and hyphens are allowed.`,\n };\n }\n\n return { ok: true, scheme, id };\n}\n\n// ─── Command registration ─────────────────────────\n\nexport function registerLookupCommand(program: Command): void {\n program\n .command(\"lookup\")\n .description(\"Look up a participant in the Peppol Directory\")\n .argument(\"[peppolId]\", \"Peppol participant ID (format: scheme:id)\")\n .option(\"--name <name>\", \"search by company name (min 3 chars)\")\n .option(\"--country <code>\", \"filter by ISO 2-letter country code\")\n .option(\"--json\", \"output results as JSON\")\n .option(\"--limit <n>\", \"max results (default 10)\", \"10\")\n .action(\n async (\n peppolId: string | undefined,\n options: {\n name?: string;\n country?: string;\n json?: boolean;\n limit?: string;\n },\n ) => {\n const isSearch = Boolean(options.name);\n const isLookup = Boolean(peppolId);\n\n // Must have at least one criterion\n if (!isSearch && !isLookup) {\n process.stderr.write(\n \"Provide a Peppol ID or use --name to search.\\n\",\n );\n process.exit(2);\n }\n\n // Validate --country format\n if (options.country) {\n const normalized = options.country.toUpperCase();\n if (!/^[A-Z]{2}$/.test(normalized)) {\n process.stderr.write(\n `Invalid country code \"${options.country}\". Must be 2 letters (e.g. BE, DE, FR).\\n`,\n );\n process.exit(2);\n }\n options.country = normalized;\n }\n\n if (isLookup) {\n await handleLookup(peppolId!, options);\n } else {\n await handleSearch(options);\n }\n },\n );\n}\n\n// ─── Lookup handler ───────────────────────────────\n\nasync function handleLookup(\n peppolId: string,\n options: { json?: boolean },\n): Promise<void> {\n const parsed = validatePeppolId(peppolId);\n if (!parsed.ok) {\n process.stderr.write(parsed.error + \"\\n\");\n process.exit(2);\n }\n\n let result: DirectoryMatch | null;\n\n try {\n result = await lookupParticipant(parsed.scheme, parsed.id);\n } catch {\n process.stderr.write(\n `${pc.red(\"\\u2717\")} Could not reach Peppol Directory. Check your internet connection.\\n`,\n );\n process.exit(2);\n }\n\n if (!result) {\n if (options.json) {\n console.log(JSON.stringify(null));\n } else {\n process.stderr.write(\n `${pc.red(\"\\u2717\")} Participant not found: ${peppolId}\\n`,\n );\n }\n process.exit(1);\n }\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(formatLookupResult(result));\n }\n process.exit(0);\n}\n\n// ─── Search handler ───────────────────────────────\n\nasync function handleSearch(options: {\n name?: string;\n country?: string;\n json?: boolean;\n limit?: string;\n}): Promise<void> {\n if (options.name && options.name.length < 3) {\n process.stderr.write(\n `Search name must be at least 3 characters. Got: \"${options.name}\"\\n`,\n );\n process.exit(2);\n }\n\n const limit = parseInt(options.limit ?? \"10\", 10);\n\n let result: SearchResult;\n\n try {\n result = await searchParticipants({\n name: options.name,\n country: options.country,\n limit,\n });\n } catch {\n process.stderr.write(\n `${pc.red(\"\\u2717\")} Could not reach Peppol Directory. Check your internet connection.\\n`,\n );\n process.exit(2);\n }\n\n if (result.matches.length === 0) {\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n process.stderr.write(\"No participants found.\\n\");\n }\n process.exit(1);\n }\n\n if (options.json) {\n console.log(JSON.stringify(result, null, 2));\n } else {\n console.log(formatSearchResults(result));\n }\n process.exit(0);\n}\n","const BASE_URL = \"https://directory.peppol.eu/search/1.0/json\";\n\n// ─── Public types ─────────────────────────────────\n\nexport interface DirectoryMatch {\n name: string;\n peppolId: string;\n country: string;\n capabilities: string[];\n registrationDate?: string;\n vatNumber?: string;\n contactEmail?: string;\n website?: string;\n}\n\nexport interface SearchResult {\n matches: DirectoryMatch[];\n totalCount: number;\n hasMore: boolean;\n}\n\n// ─── Response types (Peppol Directory JSON) ───────\n\ninterface DirectoryParticipantID {\n scheme: string;\n value: string;\n}\n\ninterface DirectoryDocType {\n scheme: string;\n value: string;\n}\n\ninterface DirectoryEntity {\n name: Array<{ name: string; language?: string }>;\n countryCode: string;\n geoInfo?: string;\n identifiers?: Array<{ scheme: string; value: string }>;\n websites?: string[];\n contacts?: Array<{ type: string; name?: string; email?: string }>;\n additionalInfo?: string;\n regDate?: string;\n}\n\ninterface DirectoryMatchRaw {\n participantID: DirectoryParticipantID;\n docTypes?: DirectoryDocType[];\n entities: DirectoryEntity[];\n}\n\ninterface DirectoryResponse {\n \"total-result-count\": number;\n \"result-page-index\": number;\n \"result-page-count\": number;\n matches: DirectoryMatchRaw[];\n}\n\n// ─── Parsing helpers ──────────────────────────────\n\nexport function stripQuotes(name: string): string {\n if (name.startsWith('\"') && name.endsWith('\"') && name.length >= 2) {\n return name.slice(1, -1);\n }\n return name;\n}\n\nexport function pickBestName(\n names: Array<{ name: string; language?: string }>,\n): string {\n if (names.length === 0) return \"\";\n const english = names.find((n) => n.language === \"en\");\n return (english ?? names[0]).name;\n}\n\nexport function mapDocType(urn: string): string | null {\n if (urn.includes(\"Invoice-2::Invoice##\")) return \"invoice\";\n if (urn.includes(\"CreditNote-2::CreditNote##\")) return \"credit_note\";\n if (urn.includes(\"ApplicationResponse\")) return \"application_response\";\n if (urn.includes(\"Order-2::Order##\")) return \"order\";\n if (urn.includes(\"DespatchAdvice\")) return \"despatch_advice\";\n return null;\n}\n\nexport function findVatIdentifier(\n identifiers: Array<{ scheme: string; value: string }>,\n): string | undefined {\n const match = identifiers.find((id) => {\n const s = id.scheme.toLowerCase();\n return s.includes(\"vat\") || s.includes(\"cbe\") || s.includes(\"tax\");\n });\n return match?.value;\n}\n\nexport function parseParticipantId(value: string): {\n scheme: string;\n id: string;\n} {\n const colonIndex = value.indexOf(\":\");\n if (colonIndex === -1) {\n return { scheme: \"\", id: value };\n }\n return {\n scheme: value.slice(0, colonIndex),\n id: value.slice(colonIndex + 1),\n };\n}\n\n// ─── Internal: parse a raw match ──────────────────\n\nfunction parseMatch(raw: DirectoryMatchRaw): DirectoryMatch {\n const entity = raw.entities[0];\n const rawName = entity ? pickBestName(entity.name) : \"\";\n const name = stripQuotes(rawName);\n const country = entity?.countryCode ?? \"\";\n\n const capabilities = (raw.docTypes ?? [])\n .map((dt) => mapDocType(dt.value))\n .filter((c): c is string => c !== null)\n // Deduplicate\n .filter((c, i, arr) => arr.indexOf(c) === i);\n\n const vatNumber = entity?.identifiers\n ? findVatIdentifier(entity.identifiers)\n : undefined;\n\n const contactEmail = entity?.contacts?.find((c) => c.email)?.email;\n const website =\n entity?.websites && entity.websites.length > 0\n ? entity.websites[0]\n : undefined;\n\n return {\n name,\n peppolId: raw.participantID.value,\n country,\n capabilities,\n registrationDate: entity?.regDate,\n vatNumber,\n contactEmail,\n website,\n };\n}\n\n// ─── Public API ───────────────────────────────────\n\nexport async function lookupParticipant(\n scheme: string,\n id: string,\n): Promise<DirectoryMatch | null> {\n const participantParam = `iso6523-actorid-upis::${scheme}:${id}`;\n const url = `${BASE_URL}?participant=${encodeURIComponent(participantParam)}`;\n\n const response = await fetch(url);\n const data = (await response.json()) as DirectoryResponse;\n\n if (!data.matches || data.matches.length === 0) {\n return null;\n }\n\n return parseMatch(data.matches[0]);\n}\n\nexport async function searchParticipants(opts: {\n name?: string;\n country?: string;\n limit?: number;\n}): Promise<SearchResult> {\n const params = new URLSearchParams();\n if (opts.name) params.set(\"name\", opts.name);\n if (opts.country) params.set(\"country\", opts.country);\n\n const url = `${BASE_URL}?${params.toString()}`;\n\n const response = await fetch(url);\n const data = (await response.json()) as DirectoryResponse;\n\n const allMatches = (data.matches ?? []).map(parseMatch);\n\n const limit = opts.limit ?? 10;\n const matches = allMatches.slice(0, limit);\n\n const totalCount = data[\"total-result-count\"] ?? 0;\n const hasMore = totalCount > matches.length;\n\n return {\n matches,\n totalCount,\n hasMore,\n };\n}\n"],"mappings":"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","names":["program","existsSync","resolve","pc","program","resolve","existsSync","pc","writeFileSync","pc","program","writeFileSync","pc","pc","pc","program","require"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getpeppr/cli",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "CLI tool for Peppol e-invoice validation and development",
5
5
  "type": "module",
6
6
  "bin": {