adstxt-validator 1.2.5 → 1.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +24 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -587,7 +587,8 @@ async function validateWithOptimizedProvider(publisherDomain, records, provider,
587
587
  records.forEach((record) => {
588
588
  if (!record.is_valid)
589
589
  return; // Skip invalid records
590
- const domain = record.domain.toLowerCase();
590
+ // CRITICAL FIX: Normalize domain by trimming whitespace
591
+ const domain = record.domain.toLowerCase().trim();
591
592
  // Initialize arrays if not exists
592
593
  if (!domainToSellerIds.has(domain)) {
593
594
  domainToSellerIds.set(domain, []);
@@ -600,6 +601,8 @@ async function validateWithOptimizedProvider(publisherDomain, records, provider,
600
601
  // Batch fetch sellers for all domains
601
602
  const domainSellersMap = new Map();
602
603
  const domainMetadataMap = new Map();
604
+ // Track which domains actually have sellers.json (separate from whether matching sellers were found)
605
+ const domainHasSellersJsonMap = new Map();
603
606
  for (const [domain, sellerIds] of domainToSellerIds) {
604
607
  try {
605
608
  logger.info(`Fetching ${sellerIds.length} sellers for domain: ${domain}`);
@@ -609,8 +612,11 @@ async function validateWithOptimizedProvider(publisherDomain, records, provider,
609
612
  logger.info(`No sellers.json found for domain: ${domain}`);
610
613
  domainSellersMap.set(domain, new Map());
611
614
  domainMetadataMap.set(domain, {});
615
+ domainHasSellersJsonMap.set(domain, false);
612
616
  continue;
613
617
  }
618
+ // Domain has sellers.json - record this explicitly before fetching matching sellers
619
+ domainHasSellersJsonMap.set(domain, true);
614
620
  // Batch fetch sellers
615
621
  const batchResult = await provider.batchGetSellers(domain, sellerIds);
616
622
  // Convert to Map for efficient lookup
@@ -628,6 +634,10 @@ async function validateWithOptimizedProvider(publisherDomain, records, provider,
628
634
  logger.error(`Error fetching sellers for domain ${domain}:`, error);
629
635
  domainSellersMap.set(domain, new Map());
630
636
  domainMetadataMap.set(domain, {});
637
+ // On error, we can't confirm sellers.json exists
638
+ if (!domainHasSellersJsonMap.has(domain)) {
639
+ domainHasSellersJsonMap.set(domain, false);
640
+ }
631
641
  }
632
642
  }
633
643
  // Validate each record using the fetched data
@@ -635,10 +645,14 @@ async function validateWithOptimizedProvider(publisherDomain, records, provider,
635
645
  if (!record.is_valid) {
636
646
  return record; // Skip invalid records
637
647
  }
638
- const domain = record.domain.toLowerCase();
648
+ // CRITICAL FIX: Normalize domain by trimming whitespace (must match the same normalization as above)
649
+ const domain = record.domain.toLowerCase().trim();
639
650
  const sellersMap = domainSellersMap.get(domain) || new Map();
640
651
  const metadata = domainMetadataMap.get(domain) || {};
641
- return await validateSingleRecordOptimized(record, publisherDomain, sellersMap, metadata, allEntries);
652
+ // Use explicit sellers.json existence flag to avoid false "noSellersJson" when
653
+ // sellers.json exists but no matching seller IDs were found
654
+ const hasSellersJson = domainHasSellersJsonMap.get(domain) ?? (sellersMap.size > 0 || Object.keys(metadata).length > 0);
655
+ return await validateSingleRecordOptimized(record, publisherDomain, sellersMap, metadata, allEntries, hasSellersJson);
642
656
  }));
643
657
  logger.info(`After optimized sellers.json validation: ${validatedRecords.length} records, ${validatedRecords.filter((r) => r.has_warning).length} with warnings`);
644
658
  return validatedRecords;
@@ -646,11 +660,15 @@ async function validateWithOptimizedProvider(publisherDomain, records, provider,
646
660
  /**
647
661
  * Validate a single record using optimized data structures
648
662
  */
649
- async function validateSingleRecordOptimized(record, publisherDomain, sellersMap, metadata, allEntries) {
663
+ async function validateSingleRecordOptimized(record, publisherDomain, sellersMap, metadata, allEntries, hasSellersJson) {
650
664
  // Initialize validation result
651
665
  const validationResult = createInitialValidationResult();
652
- // Check if sellers.json exists for this domain
653
- validationResult.hasSellerJson = sellersMap.size > 0 || Object.keys(metadata).length > 0;
666
+ // Check if sellers.json exists for this domain.
667
+ // Use the explicit hasSellersJson flag when provided to correctly handle the case where
668
+ // sellers.json exists but no matching seller IDs were found (which produces an empty sellersMap).
669
+ validationResult.hasSellerJson = hasSellersJson !== undefined
670
+ ? hasSellersJson
671
+ : (sellersMap.size > 0 || Object.keys(metadata).length > 0);
654
672
  if (!validationResult.hasSellerJson) {
655
673
  return createWarningRecord(record, exports.VALIDATION_KEYS.NO_SELLERS_JSON, { domain: record.domain }, Severity.WARNING, { validation_results: validationResult });
656
674
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adstxt-validator",
3
- "version": "1.2.5",
3
+ "version": "1.2.7",
4
4
  "description": "A TypeScript library for validating ads.txt files and sellers.json files",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",