@getpeppr/cli 0.1.1 → 0.2.1
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/dist/index.js +483 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -162,11 +162,494 @@ 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: "Dupont & Fils SPRL",
|
|
179
|
+
peppolId: "0208:BE0123456789",
|
|
180
|
+
street: "Avenue Louise 54",
|
|
181
|
+
city: "Bruxelles",
|
|
182
|
+
postalCode: "1050",
|
|
183
|
+
country: "BE"
|
|
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: 21
|
|
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
|
+
paymentReference: "+++000/0000/00097+++"
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
// src/templates/credit-note.ts
|
|
213
|
+
var CREDIT_NOTE_TEMPLATE = {
|
|
214
|
+
number: "CN-2026-001",
|
|
215
|
+
date: "2026-02-01",
|
|
216
|
+
currency: "EUR",
|
|
217
|
+
isCreditNote: true,
|
|
218
|
+
invoiceReference: "INV-2026-001",
|
|
219
|
+
from: {
|
|
220
|
+
name: "Dupont & Fils SPRL",
|
|
221
|
+
peppolId: "0208:BE0123456789",
|
|
222
|
+
street: "Avenue Louise 54",
|
|
223
|
+
city: "Bruxelles",
|
|
224
|
+
postalCode: "1050",
|
|
225
|
+
country: "BE"
|
|
226
|
+
},
|
|
227
|
+
to: {
|
|
228
|
+
name: "M\xFCller & Partner GmbH",
|
|
229
|
+
peppolId: "0204:DE987654321",
|
|
230
|
+
street: "Friedrichstra\xDFe 123",
|
|
231
|
+
city: "Berlin",
|
|
232
|
+
postalCode: "10117",
|
|
233
|
+
country: "DE"
|
|
234
|
+
},
|
|
235
|
+
lines: [
|
|
236
|
+
{
|
|
237
|
+
description: "Avoir partiel \u2014 Conseil en transformation num\xE9rique",
|
|
238
|
+
quantity: 2,
|
|
239
|
+
unitPrice: 950,
|
|
240
|
+
vatRate: 21
|
|
241
|
+
}
|
|
242
|
+
],
|
|
243
|
+
note: "Avoir pour prestations non r\xE9alis\xE9es \u2014 r\xE9f. INV-2026-001"
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
// src/commands/init.ts
|
|
247
|
+
function registerInitCommand(program2) {
|
|
248
|
+
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(
|
|
249
|
+
(filename, options) => {
|
|
250
|
+
const resolved = resolve2(filename);
|
|
251
|
+
if (existsSync2(resolved) && !options.force) {
|
|
252
|
+
console.error(
|
|
253
|
+
`Error: ${filename} already exists. Use --force to overwrite.`
|
|
254
|
+
);
|
|
255
|
+
process.exit(2);
|
|
256
|
+
}
|
|
257
|
+
const template = options.creditNote ? CREDIT_NOTE_TEMPLATE : INVOICE_TEMPLATE;
|
|
258
|
+
try {
|
|
259
|
+
writeFileSync(
|
|
260
|
+
resolved,
|
|
261
|
+
JSON.stringify(template, null, 2) + "\n",
|
|
262
|
+
"utf-8"
|
|
263
|
+
);
|
|
264
|
+
} catch {
|
|
265
|
+
console.error(`Error: could not write file \u2014 ${resolved}`);
|
|
266
|
+
process.exit(2);
|
|
267
|
+
}
|
|
268
|
+
console.error(`${pc2.green("\u2713")} Created ${filename}
|
|
269
|
+
|
|
270
|
+
Next steps:
|
|
271
|
+
1. Edit the file with your invoice data
|
|
272
|
+
2. Validate: getpeppr validate ${filename}
|
|
273
|
+
3. Convert to XML: getpeppr convert ${filename}`);
|
|
274
|
+
process.exit(0);
|
|
275
|
+
}
|
|
276
|
+
);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// src/commands/convert.ts
|
|
280
|
+
import { writeFileSync as writeFileSync2 } from "fs";
|
|
281
|
+
import pc3 from "picocolors";
|
|
282
|
+
import {
|
|
283
|
+
buildInvoiceXml,
|
|
284
|
+
buildCreditNoteXml
|
|
285
|
+
} from "@getpeppr/sdk";
|
|
286
|
+
function registerConvertCommand(program2) {
|
|
287
|
+
program2.command("convert").description(
|
|
288
|
+
"Convert a getpeppr JSON invoice to Peppol BIS 3.0 UBL XML"
|
|
289
|
+
).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(
|
|
290
|
+
async (file, options) => {
|
|
291
|
+
const parseResult = readJsonFile(file);
|
|
292
|
+
if (!parseResult.ok) {
|
|
293
|
+
process.stderr.write(parseResult.error + "\n");
|
|
294
|
+
process.exit(2);
|
|
295
|
+
}
|
|
296
|
+
if (typeof parseResult.data !== "object" || parseResult.data === null || Array.isArray(parseResult.data)) {
|
|
297
|
+
process.stderr.write(
|
|
298
|
+
"Error: JSON file must contain an object, not an array or primitive\n"
|
|
299
|
+
);
|
|
300
|
+
process.exit(2);
|
|
301
|
+
}
|
|
302
|
+
const input = parseResult.data;
|
|
303
|
+
if (options.validate) {
|
|
304
|
+
const result = runValidation(input);
|
|
305
|
+
const formatted = formatValidationResult(file, result);
|
|
306
|
+
if (!result.valid) {
|
|
307
|
+
process.stderr.write(formatted + "\n");
|
|
308
|
+
process.exit(1);
|
|
309
|
+
}
|
|
310
|
+
if (result.totalWarnings > 0) {
|
|
311
|
+
process.stderr.write(formatted + "\n");
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
const isCreditNote = input.isCreditNote === true;
|
|
315
|
+
let xml;
|
|
316
|
+
try {
|
|
317
|
+
if (isCreditNote) {
|
|
318
|
+
xml = buildCreditNoteXml(input);
|
|
319
|
+
} else {
|
|
320
|
+
xml = buildInvoiceXml(input);
|
|
321
|
+
}
|
|
322
|
+
} catch (err) {
|
|
323
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
324
|
+
process.stderr.write(`Error: XML generation failed \u2014 ${message}
|
|
325
|
+
`);
|
|
326
|
+
process.exit(2);
|
|
327
|
+
}
|
|
328
|
+
xml = xml.replace(/^[ \t]*\n/gm, "");
|
|
329
|
+
const docType = isCreditNote ? "UBL 2.1 CreditNote" : "UBL 2.1 Invoice";
|
|
330
|
+
if (options.output) {
|
|
331
|
+
writeFileSync2(options.output, xml, "utf-8");
|
|
332
|
+
process.stderr.write(
|
|
333
|
+
`${pc3.green("\u2713")} Converted to ${options.output} (${docType})
|
|
334
|
+
`
|
|
335
|
+
);
|
|
336
|
+
} else {
|
|
337
|
+
process.stdout.write(xml + "\n");
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
// src/commands/lookup.ts
|
|
344
|
+
import pc4 from "picocolors";
|
|
345
|
+
|
|
346
|
+
// src/lib/peppol-directory.ts
|
|
347
|
+
var BASE_URL = "https://directory.peppol.eu/search/1.0/json";
|
|
348
|
+
function stripQuotes(name) {
|
|
349
|
+
if (name.startsWith('"') && name.endsWith('"') && name.length >= 2) {
|
|
350
|
+
return name.slice(1, -1);
|
|
351
|
+
}
|
|
352
|
+
return name;
|
|
353
|
+
}
|
|
354
|
+
function pickBestName(names) {
|
|
355
|
+
if (names.length === 0) return "";
|
|
356
|
+
const english = names.find((n) => n.language === "en");
|
|
357
|
+
return (english ?? names[0]).name;
|
|
358
|
+
}
|
|
359
|
+
function mapDocType(urn) {
|
|
360
|
+
if (urn.includes("Invoice-2::Invoice##")) return "invoice";
|
|
361
|
+
if (urn.includes("CreditNote-2::CreditNote##")) return "credit_note";
|
|
362
|
+
if (urn.includes("ApplicationResponse")) return "application_response";
|
|
363
|
+
if (urn.includes("Order-2::Order##")) return "order";
|
|
364
|
+
if (urn.includes("DespatchAdvice")) return "despatch_advice";
|
|
365
|
+
return null;
|
|
366
|
+
}
|
|
367
|
+
function findVatIdentifier(identifiers) {
|
|
368
|
+
const match = identifiers.find((id) => {
|
|
369
|
+
const s = id.scheme.toLowerCase();
|
|
370
|
+
return s.includes("vat") || s.includes("cbe") || s.includes("tax");
|
|
371
|
+
});
|
|
372
|
+
return match?.value;
|
|
373
|
+
}
|
|
374
|
+
function parseMatch(raw) {
|
|
375
|
+
const entity = raw.entities[0];
|
|
376
|
+
const rawName = entity ? pickBestName(entity.name) : "";
|
|
377
|
+
const name = stripQuotes(rawName);
|
|
378
|
+
const country = entity?.countryCode ?? "";
|
|
379
|
+
const capabilities = (raw.docTypes ?? []).map((dt) => mapDocType(dt.value)).filter((c) => c !== null).filter((c, i, arr) => arr.indexOf(c) === i);
|
|
380
|
+
const vatNumber = entity?.identifiers ? findVatIdentifier(entity.identifiers) : void 0;
|
|
381
|
+
const contactEmail = entity?.contacts?.find((c) => c.email)?.email;
|
|
382
|
+
const website = entity?.websites && entity.websites.length > 0 ? entity.websites[0] : void 0;
|
|
383
|
+
return {
|
|
384
|
+
name,
|
|
385
|
+
peppolId: raw.participantID.value,
|
|
386
|
+
country,
|
|
387
|
+
capabilities,
|
|
388
|
+
registrationDate: entity?.regDate,
|
|
389
|
+
vatNumber,
|
|
390
|
+
contactEmail,
|
|
391
|
+
website
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
async function lookupParticipant(scheme, id) {
|
|
395
|
+
const participantParam = `iso6523-actorid-upis::${scheme}:${id}`;
|
|
396
|
+
const url = `${BASE_URL}?participant=${encodeURIComponent(participantParam)}`;
|
|
397
|
+
const response = await fetch(url);
|
|
398
|
+
const data = await response.json();
|
|
399
|
+
if (!data.matches || data.matches.length === 0) {
|
|
400
|
+
return null;
|
|
401
|
+
}
|
|
402
|
+
return parseMatch(data.matches[0]);
|
|
403
|
+
}
|
|
404
|
+
async function searchParticipants(opts) {
|
|
405
|
+
const params = new URLSearchParams();
|
|
406
|
+
if (opts.name) params.set("name", opts.name);
|
|
407
|
+
if (opts.country) params.set("country", opts.country);
|
|
408
|
+
const url = `${BASE_URL}?${params.toString()}`;
|
|
409
|
+
const response = await fetch(url);
|
|
410
|
+
const data = await response.json();
|
|
411
|
+
const allMatches = (data.matches ?? []).map(parseMatch);
|
|
412
|
+
const limit = opts.limit ?? 10;
|
|
413
|
+
const matches = allMatches.slice(0, limit);
|
|
414
|
+
const totalCount = data["total-result-count"] ?? 0;
|
|
415
|
+
const hasMore = totalCount > matches.length;
|
|
416
|
+
return {
|
|
417
|
+
matches,
|
|
418
|
+
totalCount,
|
|
419
|
+
hasMore
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// src/commands/lookup.ts
|
|
424
|
+
var COUNTRY_NAMES = {
|
|
425
|
+
AT: "Austria",
|
|
426
|
+
BE: "Belgium",
|
|
427
|
+
BG: "Bulgaria",
|
|
428
|
+
HR: "Croatia",
|
|
429
|
+
CY: "Cyprus",
|
|
430
|
+
CZ: "Czechia",
|
|
431
|
+
DK: "Denmark",
|
|
432
|
+
EE: "Estonia",
|
|
433
|
+
FI: "Finland",
|
|
434
|
+
FR: "France",
|
|
435
|
+
DE: "Germany",
|
|
436
|
+
GR: "Greece",
|
|
437
|
+
HU: "Hungary",
|
|
438
|
+
IS: "Iceland",
|
|
439
|
+
IE: "Ireland",
|
|
440
|
+
IT: "Italy",
|
|
441
|
+
LV: "Latvia",
|
|
442
|
+
LT: "Lithuania",
|
|
443
|
+
LU: "Luxembourg",
|
|
444
|
+
MT: "Malta",
|
|
445
|
+
NL: "Netherlands",
|
|
446
|
+
NO: "Norway",
|
|
447
|
+
PL: "Poland",
|
|
448
|
+
PT: "Portugal",
|
|
449
|
+
RO: "Romania",
|
|
450
|
+
SK: "Slovakia",
|
|
451
|
+
SI: "Slovenia",
|
|
452
|
+
ES: "Spain",
|
|
453
|
+
SE: "Sweden",
|
|
454
|
+
CH: "Switzerland",
|
|
455
|
+
GB: "United Kingdom",
|
|
456
|
+
US: "United States",
|
|
457
|
+
AU: "Australia",
|
|
458
|
+
CA: "Canada",
|
|
459
|
+
SG: "Singapore",
|
|
460
|
+
JP: "Japan",
|
|
461
|
+
NZ: "New Zealand"
|
|
462
|
+
};
|
|
463
|
+
function countryLabel(code) {
|
|
464
|
+
const name = COUNTRY_NAMES[code.toUpperCase()];
|
|
465
|
+
return name ? `${name} (${code})` : code;
|
|
466
|
+
}
|
|
467
|
+
function formatLookupResult(match) {
|
|
468
|
+
const lines = [];
|
|
469
|
+
lines.push(`${pc4.green("\u2713")} ${match.name}`);
|
|
470
|
+
lines.push(` ${pc4.dim("Peppol ID")} ${match.peppolId}`);
|
|
471
|
+
lines.push(` ${pc4.dim("Country")} ${countryLabel(match.country)}`);
|
|
472
|
+
if (match.registrationDate) {
|
|
473
|
+
lines.push(` ${pc4.dim("Registered")} ${match.registrationDate}`);
|
|
474
|
+
}
|
|
475
|
+
if (match.vatNumber) {
|
|
476
|
+
lines.push(` ${pc4.dim("VAT")} ${match.vatNumber}`);
|
|
477
|
+
}
|
|
478
|
+
if (match.capabilities.length > 0) {
|
|
479
|
+
lines.push(
|
|
480
|
+
` ${pc4.dim("Capabilities")} ${match.capabilities.join(", ")}`
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
if (match.contactEmail) {
|
|
484
|
+
lines.push(` ${pc4.dim("Contact")} ${match.contactEmail}`);
|
|
485
|
+
}
|
|
486
|
+
if (match.website) {
|
|
487
|
+
lines.push(` ${pc4.dim("Website")} ${match.website}`);
|
|
488
|
+
}
|
|
489
|
+
return lines.join("\n");
|
|
490
|
+
}
|
|
491
|
+
function formatSearchResults(result) {
|
|
492
|
+
const lines = [];
|
|
493
|
+
const plural = result.totalCount === 1 ? "participant" : "participants";
|
|
494
|
+
lines.push(`Found ${result.totalCount} ${plural}:
|
|
495
|
+
`);
|
|
496
|
+
const nameW = 26;
|
|
497
|
+
const idW = 23;
|
|
498
|
+
const countryW = 9;
|
|
499
|
+
lines.push(
|
|
500
|
+
` ${"Name".padEnd(nameW)}${"Peppol ID".padEnd(idW)}${"Country".padEnd(countryW)}Capabilities`
|
|
501
|
+
);
|
|
502
|
+
lines.push(` ${"\u2500".repeat(nameW + idW + countryW + 20)}`);
|
|
503
|
+
for (const m of result.matches) {
|
|
504
|
+
const name = m.name.length > nameW - 1 ? m.name.slice(0, nameW - 2) + "\u2026" : m.name;
|
|
505
|
+
const caps = m.capabilities.join(", ");
|
|
506
|
+
lines.push(
|
|
507
|
+
` ${name.padEnd(nameW)}${m.peppolId.padEnd(idW)}${m.country.padEnd(countryW)}${caps}`
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
if (result.hasMore) {
|
|
511
|
+
lines.push(
|
|
512
|
+
`
|
|
513
|
+
${pc4.dim(`Showing ${result.matches.length} of ${result.totalCount} results.`)}`
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
return lines.join("\n");
|
|
517
|
+
}
|
|
518
|
+
function validatePeppolId(raw) {
|
|
519
|
+
const colonIndex = raw.indexOf(":");
|
|
520
|
+
if (colonIndex === -1) {
|
|
521
|
+
return {
|
|
522
|
+
ok: false,
|
|
523
|
+
error: `Invalid Peppol ID format: "${raw}". Expected format: scheme:id (e.g. 0208:BE0685660237)`
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
const scheme = raw.slice(0, colonIndex);
|
|
527
|
+
const id = raw.slice(colonIndex + 1);
|
|
528
|
+
if (!/^\d{4}$/.test(scheme)) {
|
|
529
|
+
return {
|
|
530
|
+
ok: false,
|
|
531
|
+
error: `Invalid scheme "${scheme}". Must be exactly 4 digits (e.g. 0208).`
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
if (!/^[A-Za-z0-9:.\-]+$/.test(id)) {
|
|
535
|
+
return {
|
|
536
|
+
ok: false,
|
|
537
|
+
error: `Invalid participant ID "${id}". Only letters, digits, colons, dots and hyphens are allowed.`
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
return { ok: true, scheme, id };
|
|
541
|
+
}
|
|
542
|
+
function registerLookupCommand(program2) {
|
|
543
|
+
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(
|
|
544
|
+
async (peppolId, options) => {
|
|
545
|
+
const isSearch = Boolean(options.name);
|
|
546
|
+
const isLookup = Boolean(peppolId);
|
|
547
|
+
if (!isSearch && !isLookup) {
|
|
548
|
+
process.stderr.write(
|
|
549
|
+
"Provide a Peppol ID or use --name to search.\n"
|
|
550
|
+
);
|
|
551
|
+
process.exit(2);
|
|
552
|
+
}
|
|
553
|
+
if (options.country) {
|
|
554
|
+
const normalized = options.country.toUpperCase();
|
|
555
|
+
if (!/^[A-Z]{2}$/.test(normalized)) {
|
|
556
|
+
process.stderr.write(
|
|
557
|
+
`Invalid country code "${options.country}". Must be 2 letters (e.g. BE, DE, FR).
|
|
558
|
+
`
|
|
559
|
+
);
|
|
560
|
+
process.exit(2);
|
|
561
|
+
}
|
|
562
|
+
options.country = normalized;
|
|
563
|
+
}
|
|
564
|
+
if (isLookup) {
|
|
565
|
+
await handleLookup(peppolId, options);
|
|
566
|
+
} else {
|
|
567
|
+
await handleSearch(options);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
);
|
|
571
|
+
}
|
|
572
|
+
async function handleLookup(peppolId, options) {
|
|
573
|
+
const parsed = validatePeppolId(peppolId);
|
|
574
|
+
if (!parsed.ok) {
|
|
575
|
+
process.stderr.write(parsed.error + "\n");
|
|
576
|
+
process.exit(2);
|
|
577
|
+
}
|
|
578
|
+
let result;
|
|
579
|
+
try {
|
|
580
|
+
result = await lookupParticipant(parsed.scheme, parsed.id);
|
|
581
|
+
} catch {
|
|
582
|
+
process.stderr.write(
|
|
583
|
+
`${pc4.red("\u2717")} Could not reach Peppol Directory. Check your internet connection.
|
|
584
|
+
`
|
|
585
|
+
);
|
|
586
|
+
process.exit(2);
|
|
587
|
+
}
|
|
588
|
+
if (!result) {
|
|
589
|
+
if (options.json) {
|
|
590
|
+
console.log(JSON.stringify(null));
|
|
591
|
+
} else {
|
|
592
|
+
process.stderr.write(
|
|
593
|
+
`${pc4.red("\u2717")} Participant not found: ${peppolId}
|
|
594
|
+
`
|
|
595
|
+
);
|
|
596
|
+
}
|
|
597
|
+
process.exit(1);
|
|
598
|
+
}
|
|
599
|
+
if (options.json) {
|
|
600
|
+
console.log(JSON.stringify(result, null, 2));
|
|
601
|
+
} else {
|
|
602
|
+
console.log(formatLookupResult(result));
|
|
603
|
+
}
|
|
604
|
+
process.exit(0);
|
|
605
|
+
}
|
|
606
|
+
async function handleSearch(options) {
|
|
607
|
+
if (options.name && options.name.length < 3) {
|
|
608
|
+
process.stderr.write(
|
|
609
|
+
`Search name must be at least 3 characters. Got: "${options.name}"
|
|
610
|
+
`
|
|
611
|
+
);
|
|
612
|
+
process.exit(2);
|
|
613
|
+
}
|
|
614
|
+
const limit = parseInt(options.limit ?? "10", 10);
|
|
615
|
+
let result;
|
|
616
|
+
try {
|
|
617
|
+
result = await searchParticipants({
|
|
618
|
+
name: options.name,
|
|
619
|
+
country: options.country,
|
|
620
|
+
limit
|
|
621
|
+
});
|
|
622
|
+
} catch {
|
|
623
|
+
process.stderr.write(
|
|
624
|
+
`${pc4.red("\u2717")} Could not reach Peppol Directory. Check your internet connection.
|
|
625
|
+
`
|
|
626
|
+
);
|
|
627
|
+
process.exit(2);
|
|
628
|
+
}
|
|
629
|
+
if (result.matches.length === 0) {
|
|
630
|
+
if (options.json) {
|
|
631
|
+
console.log(JSON.stringify(result, null, 2));
|
|
632
|
+
} else {
|
|
633
|
+
process.stderr.write("No participants found.\n");
|
|
634
|
+
}
|
|
635
|
+
process.exit(1);
|
|
636
|
+
}
|
|
637
|
+
if (options.json) {
|
|
638
|
+
console.log(JSON.stringify(result, null, 2));
|
|
639
|
+
} else {
|
|
640
|
+
console.log(formatSearchResults(result));
|
|
641
|
+
}
|
|
642
|
+
process.exit(0);
|
|
643
|
+
}
|
|
644
|
+
|
|
165
645
|
// src/index.ts
|
|
166
646
|
var require2 = createRequire(import.meta.url);
|
|
167
647
|
var { version } = require2("../package.json");
|
|
168
648
|
var program = new Command();
|
|
169
649
|
program.name("getpeppr").description("CLI tool for Peppol e-invoice validation and development").version(version);
|
|
170
650
|
registerValidateCommand(program);
|
|
651
|
+
registerInitCommand(program);
|
|
652
|
+
registerConvertCommand(program);
|
|
653
|
+
registerLookupCommand(program);
|
|
171
654
|
program.parse();
|
|
172
655
|
//# 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":"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","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: \"Dupont & Fils SPRL\",\n peppolId: \"0208:BE0123456789\",\n street: \"Avenue Louise 54\",\n city: \"Bruxelles\",\n postalCode: \"1050\",\n country: \"BE\",\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: 21,\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 paymentReference: \"+++000/0000/00097+++\",\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: \"Dupont & Fils SPRL\",\n peppolId: \"0208:BE0123456789\",\n street: \"Avenue Louise 54\",\n city: \"Bruxelles\",\n postalCode: \"1050\",\n country: \"BE\",\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: 21,\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"]}
|