@taxora/sdk 1.5.0 → 1.7.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/dist/index.js CHANGED
@@ -2315,8 +2315,22 @@ function toRejectedCandidates(value) {
2315
2315
  }
2316
2316
  return candidates;
2317
2317
  }
2318
+ function toOfficialAddress(value) {
2319
+ if (typeof value !== "object" || value === null || Array.isArray(value)) {
2320
+ return void 0;
2321
+ }
2322
+ const record = value;
2323
+ const address = {};
2324
+ for (const key of ["street", "postal_code", "city", "country"]) {
2325
+ const part = typeof record[key] === "string" ? record[key].trim() : "";
2326
+ if (part !== "") {
2327
+ address[key] = part;
2328
+ }
2329
+ }
2330
+ return Object.keys(address).length > 0 ? address : void 0;
2331
+ }
2318
2332
  var SmartEnrichmentResource = class _SmartEnrichmentResource {
2319
- constructor(status, vatNumber, vatType, confidence, matchedCompanyName, matchedAddress, country, source, mode = void 0, providerVerdicts = [], addressQuality = void 0, rejectedCandidates = [], sourceUrl = void 0, registeredOwner = void 0, sourceUrls = []) {
2333
+ constructor(status, vatNumber, vatType, confidence, matchedCompanyName, matchedAddress, country, source, mode = void 0, providerVerdicts = [], addressQuality = void 0, rejectedCandidates = [], sourceUrl = void 0, registeredOwner = void 0, sourceUrls = [], taxNumber = void 0, vatValid = void 0, aiScore = void 0, nameMatch = void 0, officialName = void 0, officialAddress = void 0, taxNumberType = void 0, taxNumberLabel = void 0, taxNumberSource = void 0) {
2320
2334
  this.status = status;
2321
2335
  this.vatNumber = vatNumber;
2322
2336
  this.vatType = vatType;
@@ -2332,6 +2346,15 @@ var SmartEnrichmentResource = class _SmartEnrichmentResource {
2332
2346
  this.sourceUrl = sourceUrl;
2333
2347
  this.registeredOwner = registeredOwner;
2334
2348
  this.sourceUrls = sourceUrls;
2349
+ this.taxNumber = taxNumber;
2350
+ this.vatValid = vatValid;
2351
+ this.aiScore = aiScore;
2352
+ this.nameMatch = nameMatch;
2353
+ this.officialName = officialName;
2354
+ this.officialAddress = officialAddress;
2355
+ this.taxNumberType = taxNumberType;
2356
+ this.taxNumberLabel = taxNumberLabel;
2357
+ this.taxNumberSource = taxNumberSource;
2335
2358
  }
2336
2359
  status;
2337
2360
  vatNumber;
@@ -2348,6 +2371,19 @@ var SmartEnrichmentResource = class _SmartEnrichmentResource {
2348
2371
  sourceUrl;
2349
2372
  registeredOwner;
2350
2373
  sourceUrls;
2374
+ taxNumber;
2375
+ vatValid;
2376
+ aiScore;
2377
+ nameMatch;
2378
+ officialName;
2379
+ officialAddress;
2380
+ taxNumberType;
2381
+ taxNumberLabel;
2382
+ taxNumberSource;
2383
+ /** True when the register knows the number under a different name than the one requested. */
2384
+ nameMismatch() {
2385
+ return this.nameMatch === "mismatch";
2386
+ }
2351
2387
  /** True when a VAT number was found but rejected by the official check. */
2352
2388
  hasRejectedCandidates() {
2353
2389
  return this.rejectedCandidates.length > 0;
@@ -2385,7 +2421,16 @@ var SmartEnrichmentResource = class _SmartEnrichmentResource {
2385
2421
  toRejectedCandidates(data["rejectedCandidates"]),
2386
2422
  url && isWebUrl(url) ? url : void 0,
2387
2423
  text("registeredOwner"),
2388
- Array.isArray(urls) ? [...new Set(urls.filter(isWebUrl).map((u) => u.trim()))] : []
2424
+ Array.isArray(urls) ? [...new Set(urls.filter(isWebUrl).map((u) => u.trim()))] : [],
2425
+ text("taxNumber"),
2426
+ typeof data["vatValid"] === "boolean" ? data["vatValid"] : void 0,
2427
+ num("aiScore"),
2428
+ data["nameMatch"] === "ok" || data["nameMatch"] === "mismatch" ? data["nameMatch"] : void 0,
2429
+ text("officialName"),
2430
+ toOfficialAddress(data["officialAddress"]),
2431
+ text("taxNumberType"),
2432
+ text("taxNumberLabel"),
2433
+ data["taxNumberSource"] === "vat_id" || data["taxNumberSource"] === "company_website" ? data["taxNumberSource"] : void 0
2389
2434
  );
2390
2435
  }
2391
2436
  toArray() {
@@ -2404,7 +2449,16 @@ var SmartEnrichmentResource = class _SmartEnrichmentResource {
2404
2449
  rejectedCandidates: this.rejectedCandidates.map((c) => ({ vatNumber: c.vatNumber, reason: c.reason })),
2405
2450
  sourceUrl: this.sourceUrl ?? null,
2406
2451
  registeredOwner: this.registeredOwner ?? null,
2407
- sourceUrls: this.sourceUrls
2452
+ sourceUrls: this.sourceUrls,
2453
+ taxNumber: this.taxNumber ?? null,
2454
+ vatValid: this.vatValid ?? null,
2455
+ aiScore: this.aiScore ?? null,
2456
+ nameMatch: this.nameMatch ?? null,
2457
+ officialName: this.officialName ?? null,
2458
+ officialAddress: this.officialAddress ?? null,
2459
+ taxNumberType: this.taxNumberType ?? null,
2460
+ taxNumberLabel: this.taxNumberLabel ?? null,
2461
+ taxNumberSource: this.taxNumberSource ?? null
2408
2462
  };
2409
2463
  }
2410
2464
  };
@@ -3412,6 +3466,123 @@ var VatValidationAddressInput = class _VatValidationAddressInput {
3412
3466
  }
3413
3467
  };
3414
3468
 
3469
+ // src/dto/LocalTaxNumberReport.ts
3470
+ var LocalTaxNumberRow = class _LocalTaxNumberRow {
3471
+ constructor(companyName, requestedName, country, vatNumber, vatStatus, taxNumber, taxNumberName, taxNumberSource, source, checkedAt, checkId) {
3472
+ this.companyName = companyName;
3473
+ this.requestedName = requestedName;
3474
+ this.country = country;
3475
+ this.vatNumber = vatNumber;
3476
+ this.vatStatus = vatStatus;
3477
+ this.taxNumber = taxNumber;
3478
+ this.taxNumberName = taxNumberName;
3479
+ this.taxNumberSource = taxNumberSource;
3480
+ this.source = source;
3481
+ this.checkedAt = checkedAt;
3482
+ this.checkId = checkId;
3483
+ }
3484
+ companyName;
3485
+ requestedName;
3486
+ country;
3487
+ vatNumber;
3488
+ vatStatus;
3489
+ taxNumber;
3490
+ taxNumberName;
3491
+ taxNumberSource;
3492
+ source;
3493
+ checkedAt;
3494
+ checkId;
3495
+ /** One CSV row keyed by column name. */
3496
+ static fromArray(data) {
3497
+ const cell = (key) => {
3498
+ const value = data[key];
3499
+ const trimmed = typeof value === "string" ? value.trim() : "";
3500
+ return trimmed === "" ? null : trimmed;
3501
+ };
3502
+ return new _LocalTaxNumberRow(
3503
+ cell("companyName"),
3504
+ cell("requestedName"),
3505
+ cell("country"),
3506
+ cell("vatNumber"),
3507
+ cell("vatStatus"),
3508
+ cell("taxNumber"),
3509
+ cell("taxNumberName"),
3510
+ cell("taxNumberSource"),
3511
+ cell("source"),
3512
+ cell("checkedAt"),
3513
+ cell("checkId")
3514
+ );
3515
+ }
3516
+ toArray() {
3517
+ return {
3518
+ companyName: this.companyName,
3519
+ requestedName: this.requestedName,
3520
+ country: this.country,
3521
+ vatNumber: this.vatNumber,
3522
+ vatStatus: this.vatStatus,
3523
+ taxNumber: this.taxNumber,
3524
+ taxNumberName: this.taxNumberName,
3525
+ taxNumberSource: this.taxNumberSource,
3526
+ source: this.source,
3527
+ checkedAt: this.checkedAt,
3528
+ checkId: this.checkId
3529
+ };
3530
+ }
3531
+ };
3532
+ function parseCsvRecords(csv) {
3533
+ const records = [];
3534
+ let record = [];
3535
+ let cell = "";
3536
+ let quoted = false;
3537
+ for (let i = 0; i < csv.length; i++) {
3538
+ const ch = csv[i];
3539
+ if (quoted) {
3540
+ if (ch === '"') {
3541
+ if (csv[i + 1] === '"') {
3542
+ cell += '"';
3543
+ i++;
3544
+ } else {
3545
+ quoted = false;
3546
+ }
3547
+ } else {
3548
+ cell += ch;
3549
+ }
3550
+ } else if (ch === '"') {
3551
+ quoted = true;
3552
+ } else if (ch === ",") {
3553
+ record.push(cell);
3554
+ cell = "";
3555
+ } else if (ch === "\n" || ch === "\r") {
3556
+ if (ch === "\r" && csv[i + 1] === "\n") i++;
3557
+ record.push(cell);
3558
+ records.push(record);
3559
+ record = [];
3560
+ cell = "";
3561
+ } else {
3562
+ cell += ch;
3563
+ }
3564
+ }
3565
+ if (cell !== "" || record.length > 0) {
3566
+ record.push(cell);
3567
+ records.push(record);
3568
+ }
3569
+ return records.filter((r) => !(r.length === 1 && r[0] === ""));
3570
+ }
3571
+ function parseLocalTaxNumbersCsv(csv) {
3572
+ const [header, ...records] = parseCsvRecords(csv.replace(/^\uFEFF/, ""));
3573
+ if (!header) {
3574
+ return [];
3575
+ }
3576
+ const names = header.map((name) => name.trim());
3577
+ return records.map((cells) => {
3578
+ const row = {};
3579
+ names.forEach((name, i) => {
3580
+ row[name] = cells[i];
3581
+ });
3582
+ return LocalTaxNumberRow.fromArray(row);
3583
+ });
3584
+ }
3585
+
3415
3586
  // src/endpoints/VatEndpoint.ts
3416
3587
  var DATE_REGEX2 = /^\d{4}-\d{2}-\d{2}$/;
3417
3588
  var VatEndpoint = class {
@@ -3522,6 +3693,69 @@ var VatEndpoint = class {
3522
3693
  return new Uint8Array(buffer);
3523
3694
  });
3524
3695
  }
3696
+ /**
3697
+ * Local tax numbers report as raw CSV (UTF-8 with BOM, comma-separated): every company checked —
3698
+ * single and bulk VAT checks and Smart Enrichment lookups — once, with its local tax number
3699
+ * (taxNumber, taxNumberName, taxNumberSource). Digit-only taxNumber cells carry a leading TAB so
3700
+ * Excel keeps them as text; `localTaxNumbers()` strips it for you.
3701
+ */
3702
+ async localTaxNumbersCsv(options = {}) {
3703
+ const params = this.localTaxNumbersParams(options);
3704
+ if (options.onlyWithTaxNumber !== void 0) {
3705
+ params.set("only_with_tax_number", options.onlyWithTaxNumber ? "1" : "0");
3706
+ }
3707
+ const url = this.withQuery(`${this.baseUrl}/reports/local-tax-numbers`, params);
3708
+ return withRetries(this.retryPolicy, "Local tax numbers report", async () => {
3709
+ const headers = this.buildHeaders();
3710
+ delete headers["Content-Type"];
3711
+ headers["Accept"] = "text/csv, application/json";
3712
+ const response = await this.httpClient.request("GET", url, { headers });
3713
+ if (response.status === 422) {
3714
+ await this.parseJsonResponse(response);
3715
+ }
3716
+ const text = new TextDecoder("utf-8", { ignoreBOM: true }).decode(await response.arrayBuffer());
3717
+ if (!response.ok) {
3718
+ throw new HttpException(
3719
+ describeApiError(text, response.status),
3720
+ response.status,
3721
+ text,
3722
+ {},
3723
+ response.headers.get("retry-after")
3724
+ );
3725
+ }
3726
+ return text;
3727
+ });
3728
+ }
3729
+ /** The local tax numbers report, parsed: one row per company (same filters as `localTaxNumbersCsv()`). */
3730
+ async localTaxNumbers(options = {}) {
3731
+ return parseLocalTaxNumbersCsv(await this.localTaxNumbersCsv(options));
3732
+ }
3733
+ /** How many companies the report would list for the filters, and how many have a tax number. */
3734
+ async localTaxNumbersSummary(options = {}) {
3735
+ const url = this.withQuery(
3736
+ `${this.baseUrl}/reports/local-tax-numbers/summary`,
3737
+ this.localTaxNumbersParams(options)
3738
+ );
3739
+ return withRetries(this.retryPolicy, "Local tax numbers summary", async () => {
3740
+ const response = await this.sendRequest("GET", url);
3741
+ const data = await this.parseJsonResponse(response);
3742
+ const count = (key) => typeof data[key] === "number" ? data[key] : 0;
3743
+ return { companies: count("companies"), withTaxNumber: count("withTaxNumber") };
3744
+ });
3745
+ }
3746
+ localTaxNumbersParams(options) {
3747
+ const params = new URLSearchParams();
3748
+ if (options.dateFrom !== void 0) params.set("date_from", this.formatDate(options.dateFrom));
3749
+ if (options.dateTo !== void 0) params.set("date_to", this.formatDate(options.dateTo));
3750
+ for (const country of options.countries ?? []) {
3751
+ params.append("countries[]", country.trim().toUpperCase());
3752
+ }
3753
+ return params;
3754
+ }
3755
+ withQuery(url, params) {
3756
+ const queryString = params.toString();
3757
+ return queryString ? `${url}?${queryString}` : url;
3758
+ }
3525
3759
  buildHeaders() {
3526
3760
  const headers = {
3527
3761
  "Content-Type": "application/json",
@@ -3682,7 +3916,7 @@ var AuthRetryHttpClient = class {
3682
3916
  };
3683
3917
 
3684
3918
  // src/version.ts
3685
- var SDK_VERSION = "1.5.0";
3919
+ var SDK_VERSION = "1.7.0";
3686
3920
 
3687
3921
  // src/http/SdkVersionHttpClient.ts
3688
3922
  var SDK_VERSION_HEADER = "X-Taxora-SDK-Version";
@@ -3895,6 +4129,7 @@ export {
3895
4129
  ImportResult,
3896
4130
  InMemoryTokenStorage,
3897
4131
  Language,
4132
+ LocalTaxNumberRow,
3898
4133
  LoginIdentifier,
3899
4134
  NorwegianOrgNumber,
3900
4135
  PeppolLookupResult,
@@ -3947,6 +4182,7 @@ export {
3947
4182
  generateWebhookSignatureHeader,
3948
4183
  getBaseUrl,
3949
4184
  getFailedVatStates,
4185
+ parseLocalTaxNumbersCsv,
3950
4186
  parseWebhookSignatureHeader,
3951
4187
  toComplianceDocumentType,
3952
4188
  toComplianceEnrollmentStatus,