@tryghost/referrer-parser 0.0.2 → 0.1.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.cjs CHANGED
@@ -9417,34 +9417,12 @@ class ReferrerParser {
9417
9417
  * Parse a referrer URL to get source, medium and hostname
9418
9418
  *
9419
9419
  * @param referrerUrlStr - URL of the referrer
9420
- * @returns Parsed referrer data with source, medium and URL
9420
+ * @param referrerSource - Source of the referrer
9421
+ * @param referrerMedium - Medium of the referrer
9422
+ * @returns Parsed referrer data with source, medium and URL. Internal referrers return null values.
9421
9423
  */
9422
- parse(referrerUrlStr) {
9423
- if (!referrerUrlStr) {
9424
- return {
9425
- referrerSource: "Direct",
9426
- referrerMedium: null,
9427
- referrerUrl: null
9428
- };
9429
- }
9424
+ parse(referrerUrlStr, referrerSource, referrerMedium) {
9430
9425
  const referrerUrl = this.getUrlFromStr(referrerUrlStr);
9431
- if (!referrerUrl) {
9432
- return {
9433
- referrerSource: "Direct",
9434
- referrerMedium: null,
9435
- referrerUrl: null
9436
- };
9437
- }
9438
- if (referrerUrl.hostname === "checkout.stripe.com") {
9439
- return {
9440
- referrerSource: "Direct",
9441
- referrerMedium: null,
9442
- referrerUrl: null
9443
- };
9444
- }
9445
- const urlParams = new URLSearchParams(referrerUrl.search);
9446
- const referrerSource = urlParams.get("utm_source") || urlParams.get("source") || null;
9447
- const referrerMedium = urlParams.get("utm_medium") || urlParams.get("medium") || null;
9448
9426
  if (this.isGhostExploreRef({ referrerUrl, referrerSource })) {
9449
9427
  return {
9450
9428
  referrerSource: "Ghost Explore",
@@ -9456,12 +9434,12 @@ class ReferrerParser {
9456
9434
  return {
9457
9435
  referrerSource: "Ghost.org",
9458
9436
  referrerMedium: "Ghost Network",
9459
- referrerUrl: referrerUrl == null ? void 0 : referrerUrl.hostname
9437
+ referrerUrl: (referrerUrl == null ? void 0 : referrerUrl.hostname) ?? null
9460
9438
  };
9461
9439
  }
9462
- if (this.isGhostNewsletter({ referrerSource })) {
9440
+ if (referrerSource && this.isGhostNewsletter({ referrerSource })) {
9463
9441
  return {
9464
- referrerSource: referrerSource.replace(/-newsletter$/, " newsletter"),
9442
+ referrerSource: referrerSource.replace(/-/g, " "),
9465
9443
  referrerMedium: "Email",
9466
9444
  referrerUrl: (referrerUrl == null ? void 0 : referrerUrl.hostname) ?? null
9467
9445
  };
@@ -9491,7 +9469,7 @@ class ReferrerParser {
9491
9469
  };
9492
9470
  }
9493
9471
  return {
9494
- referrerSource: "Direct",
9472
+ referrerSource: null,
9495
9473
  referrerMedium: null,
9496
9474
  referrerUrl: null
9497
9475
  };
@@ -9586,24 +9564,25 @@ class ReferrerParser {
9586
9564
  * @returns True if the referrer is from Ghost Explore
9587
9565
  */
9588
9566
  isGhostExploreRef({ referrerUrl, referrerSource }) {
9567
+ var _a, _b, _c;
9589
9568
  if (referrerSource === "ghost-explore") {
9590
9569
  return true;
9591
9570
  }
9592
9571
  if (!referrerUrl) {
9593
9572
  return false;
9594
9573
  }
9595
- if (referrerUrl.hostname === "explore.ghost.io") {
9574
+ if ((referrerUrl == null ? void 0 : referrerUrl.hostname) && ((_a = this.adminUrl) == null ? void 0 : _a.hostname) === (referrerUrl == null ? void 0 : referrerUrl.hostname) && ((_c = referrerUrl == null ? void 0 : referrerUrl.pathname) == null ? void 0 : _c.startsWith((_b = this.adminUrl) == null ? void 0 : _b.pathname))) {
9596
9575
  return true;
9597
9576
  }
9598
- if (referrerUrl.hostname === "try.ghost.org" && referrerUrl.pathname.startsWith("/explore")) {
9577
+ if (referrerUrl.hostname === "ghost.org" && referrerUrl.pathname.startsWith("/explore")) {
9599
9578
  return true;
9600
9579
  }
9601
9580
  return false;
9602
9581
  }
9603
9582
  }
9604
- function parse(referrerUrl, options = {}) {
9583
+ function parse(referrerUrl, options = {}, referrerSource, referrerMedium) {
9605
9584
  const parser = new ReferrerParser(options);
9606
- return parser.parse(referrerUrl);
9585
+ return parser.parse(referrerUrl, referrerSource, referrerMedium);
9607
9586
  }
9608
9587
  exports.ReferrerParser = ReferrerParser;
9609
9588
  exports.parse = parse;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../lib/ReferrerParser.ts","../index.ts"],"sourcesContent":["/**\n * Interface for parsed referrer data\n */\nexport interface ReferrerData {\n /** The identified source of the referral traffic */\n referrerSource: string | null;\n /** The identified medium of the referral traffic */\n referrerMedium: string | null;\n /** The hostname of the referral URL */\n referrerUrl: string | null;\n}\n\n/**\n * Configuration options for the parser\n */\nexport interface ParserOptions {\n /** URL of the site for identifying internal traffic */\n siteUrl?: string;\n /** URL of the admin panel for identifying admin traffic */\n adminUrl?: string;\n}\n\n/**\n * Interface for referrer source data\n */\ninterface ReferrerSourceData {\n source: string;\n medium: string;\n}\n\n// Import known referrers data\nimport knownReferrers from './referrers.json';\n\n/**\n * Parses referrer URLs to determine source and medium\n */\nexport class ReferrerParser {\n private adminUrl: URL | null;\n private siteUrl: URL | null;\n\n /**\n * Creates a new referrer parser instance\n * \n * @param options - Configuration options\n */\n constructor(options: ParserOptions = {}) {\n this.adminUrl = this.getUrlFromStr(options.adminUrl || '');\n this.siteUrl = this.getUrlFromStr(options.siteUrl || '');\n }\n\n /**\n * Parse a referrer URL to get source, medium and hostname\n * \n * @param referrerUrlStr - URL of the referrer\n * @returns Parsed referrer data with source, medium and URL\n */\n parse(referrerUrlStr: string): ReferrerData {\n if (!referrerUrlStr) {\n return {\n referrerSource: 'Direct',\n referrerMedium: null,\n referrerUrl: null\n };\n }\n\n const referrerUrl = this.getUrlFromStr(referrerUrlStr);\n if (!referrerUrl) {\n return {\n referrerSource: 'Direct',\n referrerMedium: null,\n referrerUrl: null\n };\n }\n\n // Skip Stripe checkout URLs\n if (referrerUrl.hostname === 'checkout.stripe.com') {\n return {\n referrerSource: 'Direct',\n referrerMedium: null,\n referrerUrl: null\n };\n }\n\n // Check for source/medium in query parameters\n const urlParams = new URLSearchParams(referrerUrl.search);\n const referrerSource = urlParams.get('utm_source') || urlParams.get('source') || null;\n const referrerMedium = urlParams.get('utm_medium') || urlParams.get('medium') || null;\n\n // If referrer is Ghost Explore\n if (this.isGhostExploreRef({referrerUrl, referrerSource})) {\n return {\n referrerSource: 'Ghost Explore',\n referrerMedium: 'Ghost Network',\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n // If referrer is Ghost.org\n if (this.isGhostOrgUrl(referrerUrl)) {\n return {\n referrerSource: 'Ghost.org',\n referrerMedium: 'Ghost Network',\n referrerUrl: referrerUrl?.hostname\n };\n }\n\n // Check for Ghost Newsletter\n if (this.isGhostNewsletter({referrerSource})) {\n return {\n referrerSource: referrerSource!.replace(/-newsletter$/, ' newsletter'),\n referrerMedium: 'Email',\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n // If referrer source is available from parameters\n if (referrerSource) {\n const urlData = this.getDataFromUrl(referrerUrl);\n const knownSource = Object.values(knownReferrers as Record<string, ReferrerSourceData>).find(referrer => \n referrer.source.toLowerCase() === referrerSource.toLowerCase());\n \n return {\n referrerSource: knownSource?.source || referrerSource,\n referrerMedium: knownSource?.medium || referrerMedium || urlData?.medium || null,\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n // If referrer is known external URL\n if (!this.isSiteDomain(referrerUrl)) {\n const urlData = this.getDataFromUrl(referrerUrl);\n\n // Use known source/medium if available\n if (urlData) {\n return {\n referrerSource: urlData?.source ?? null,\n referrerMedium: urlData?.medium ?? null,\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n \n // Use the hostname as a source\n return {\n referrerSource: referrerUrl?.hostname ?? null,\n referrerMedium: null,\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n return {\n referrerSource: 'Direct',\n referrerMedium: null,\n referrerUrl: null\n };\n }\n\n /**\n * Fetches referrer data from known external URLs\n * \n * @param url - The URL to match against known referrers\n * @returns Matched referrer data or null if not found\n */\n getDataFromUrl(url: URL | null): ReferrerSourceData | null {\n // Handle null url case\n if (!url) {\n return null;\n }\n\n // Allow matching both \"google.ac/products\" and \"google.ac\" as a source\n const urlHostPath = url.hostname + url.pathname;\n const urlDataKey = Object.keys(knownReferrers as Record<string, ReferrerSourceData>).sort((a, b) => {\n // The longer key has higher priority so google.ac/products is selected before google.ac\n return b.length - a.length;\n }).find((source) => {\n return urlHostPath.startsWith(source);\n });\n\n return urlDataKey ? (knownReferrers as Record<string, ReferrerSourceData>)[urlDataKey] : null;\n }\n\n /**\n * Return URL object for provided URL string\n * \n * @param url - URL string to parse\n * @returns Parsed URL object or null if invalid\n */\n getUrlFromStr(url: string): URL | null {\n if (!url) {\n return null;\n }\n \n try {\n return new URL(url);\n } catch (e) {\n return null;\n }\n }\n\n /**\n * Determine whether the provided URL is a link to the site\n * \n * @param url - URL to check\n * @returns True if the URL belongs to the configured site\n */\n isSiteDomain(url: URL | null): boolean {\n try {\n // If we don't have siteUrl configured, we can't detect internal traffic\n if (!this.siteUrl) {\n return false;\n }\n\n if (!url) {\n return false;\n }\n\n if (this.siteUrl.hostname === url.hostname) {\n if (url.pathname.startsWith(this.siteUrl.pathname)) {\n return true;\n }\n return false;\n }\n return false;\n } catch (e) {\n return false;\n }\n }\n\n /**\n * Determine whether referrer is a Ghost newsletter\n * \n * @param deps - Input parameters\n * @returns True if the referrer is a Ghost newsletter\n */\n isGhostNewsletter({referrerSource}: {referrerSource: string | null}): boolean {\n if (!referrerSource) {\n return false;\n }\n // if referrer source ends with -newsletter\n return referrerSource.endsWith('-newsletter');\n }\n\n /**\n * Determine whether referrer is a Ghost.org URL\n * \n * @param referrerUrl - The referrer URL to check\n * @returns True if the referrer is from Ghost.org\n */\n isGhostOrgUrl(referrerUrl: URL | null): boolean {\n if (!referrerUrl) {\n return false;\n }\n return referrerUrl.hostname === 'ghost.org';\n }\n\n /**\n * Determine whether referrer is Ghost Explore\n * \n * @param deps - Input parameters\n * @returns True if the referrer is from Ghost Explore\n */\n isGhostExploreRef({referrerUrl, referrerSource}: {referrerUrl: URL | null, referrerSource?: string | null}): boolean {\n // Always check for ghost-explore source param\n if (referrerSource === 'ghost-explore') {\n return true;\n }\n\n if (!referrerUrl) {\n return false;\n }\n\n // Check domain for explore.ghost.io and try.ghost.org/explore\n if (referrerUrl.hostname === 'explore.ghost.io') {\n return true;\n }\n\n if (referrerUrl.hostname === 'try.ghost.org' && referrerUrl.pathname.startsWith('/explore')) {\n return true;\n }\n\n return false;\n }\n} ","import { ReferrerParser } from './lib/ReferrerParser';\nimport type { ReferrerData, ParserOptions } from './lib/ReferrerParser';\n\n/**\n * Parse a referrer URL to get source, medium and hostname\n * \n * @param referrerUrl - URL of the referrer to parse\n * @param options - Configuration options\n * @returns Parsed referrer data with source, medium and URL\n * \n * @example\n * // Basic usage\n * const result = parse('https://www.google.com/search?q=ghost+cms');\n * // result: { referrerSource: 'Google', referrerMedium: 'search', referrerUrl: 'www.google.com' }\n * \n * @example\n * // With site configuration\n * const result = parse('https://example.com/blog?utm_source=newsletter', {\n * siteUrl: 'https://example.com'\n * });\n */\nfunction parse(referrerUrl: string, options: ParserOptions = {}): ReferrerData {\n const parser = new ReferrerParser(options);\n return parser.parse(referrerUrl);\n}\n\nexport {\n parse,\n ReferrerParser\n};\n\nexport type {\n ReferrerData,\n ParserOptions\n}; "],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
1
+ {"version":3,"file":"index.cjs","sources":["../lib/ReferrerParser.ts","../index.ts"],"sourcesContent":["/**\n * Interface for parsed referrer data\n */\nexport interface ReferrerData {\n /** The identified source of the referral traffic */\n referrerSource: string | null;\n /** The identified medium of the referral traffic */\n referrerMedium: string | null;\n /** The hostname of the referral URL */\n referrerUrl: string | null;\n}\n\n/**\n * Configuration options for the parser\n */\nexport interface ParserOptions {\n /** URL of the site for identifying internal traffic */\n siteUrl?: string;\n /** URL of the admin panel for identifying admin traffic */\n adminUrl?: string;\n}\n\n/**\n * Interface for referrer source data\n */\ninterface ReferrerSourceData {\n source: string;\n medium: string;\n}\n\n// Import known referrers data\nimport knownReferrers from './referrers.json';\n\n/**\n * Parses referrer URLs to determine source and medium\n */\nexport class ReferrerParser {\n private adminUrl: URL | null;\n private siteUrl: URL | null;\n\n /**\n * Creates a new referrer parser instance\n * \n * @param options - Configuration options\n */\n constructor(options: ParserOptions = {}) {\n this.adminUrl = this.getUrlFromStr(options.adminUrl || '');\n this.siteUrl = this.getUrlFromStr(options.siteUrl || '');\n }\n\n /**\n * Parse a referrer URL to get source, medium and hostname\n * \n * @param referrerUrlStr - URL of the referrer\n * @param referrerSource - Source of the referrer\n * @param referrerMedium - Medium of the referrer\n * @returns Parsed referrer data with source, medium and URL. Internal referrers return null values.\n */\n parse(referrerUrlStr: string, referrerSource?: string, referrerMedium?: string): ReferrerData {\n const referrerUrl = this.getUrlFromStr(referrerUrlStr);\n\n // Ghost-specific cases\n if (this.isGhostExploreRef({referrerUrl, referrerSource})) {\n return {\n referrerSource: 'Ghost Explore',\n referrerMedium: 'Ghost Network',\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n // If referrer is Ghost.org\n if (this.isGhostOrgUrl(referrerUrl)) {\n return {\n referrerSource: 'Ghost.org',\n referrerMedium: 'Ghost Network',\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n // Check for Ghost Newsletter\n if (referrerSource && this.isGhostNewsletter({referrerSource})) {\n return {\n referrerSource: referrerSource.replace(/-/g, ' '),\n referrerMedium: 'Email',\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n // If referrer source is available from parameters\n if (referrerSource) {\n const urlData = this.getDataFromUrl(referrerUrl);\n const knownSource = Object.values(knownReferrers as Record<string, ReferrerSourceData>).find(referrer => \n referrer.source.toLowerCase() === referrerSource.toLowerCase());\n \n return {\n referrerSource: knownSource?.source || referrerSource,\n referrerMedium: knownSource?.medium || referrerMedium || urlData?.medium || null,\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n // If referrer is known external URL\n if (!this.isSiteDomain(referrerUrl)) {\n const urlData = this.getDataFromUrl(referrerUrl);\n\n // Use known source/medium if available\n if (urlData) {\n return {\n referrerSource: urlData?.source ?? null,\n referrerMedium: urlData?.medium ?? null,\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n \n // Use the hostname as a source\n return {\n referrerSource: referrerUrl?.hostname ?? null,\n referrerMedium: null,\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n return {\n referrerSource: null,\n referrerMedium: null,\n referrerUrl: null\n }\n }\n\n /**\n * Fetches referrer data from known external URLs\n * \n * @param url - The URL to match against known referrers\n * @returns Matched referrer data or null if not found\n */\n getDataFromUrl(url: URL | null): ReferrerSourceData | null {\n // Handle null url case\n if (!url) {\n return null;\n }\n\n // Allow matching both \"google.ac/products\" and \"google.ac\" as a source\n const urlHostPath = url.hostname + url.pathname;\n const urlDataKey = Object.keys(knownReferrers as Record<string, ReferrerSourceData>).sort((a, b) => {\n // The longer key has higher priority so google.ac/products is selected before google.ac\n return b.length - a.length;\n }).find((source) => {\n return urlHostPath.startsWith(source);\n });\n\n return urlDataKey ? (knownReferrers as Record<string, ReferrerSourceData>)[urlDataKey] : null;\n }\n\n /**\n * Return URL object for provided URL string\n * \n * @param url - URL string to parse\n * @returns Parsed URL object or null if invalid\n */\n getUrlFromStr(url: string): URL | null {\n if (!url) {\n return null;\n }\n \n try {\n return new URL(url);\n } catch (e) {\n return null;\n }\n }\n\n /**\n * Determine whether the provided URL is a link to the site\n * \n * @param url - URL to check\n * @returns True if the URL belongs to the configured site\n */\n isSiteDomain(url: URL | null): boolean {\n try {\n // If we don't have siteUrl configured, we can't detect internal traffic\n if (!this.siteUrl) {\n return false;\n }\n\n if (!url) {\n return false;\n }\n\n if (this.siteUrl.hostname === url.hostname) {\n if (url.pathname.startsWith(this.siteUrl.pathname)) {\n return true;\n }\n return false;\n }\n return false;\n } catch (e) {\n return false;\n }\n }\n\n /**\n * Determine whether referrer is a Ghost newsletter\n * \n * @param deps - Input parameters\n * @returns True if the referrer is a Ghost newsletter\n */\n isGhostNewsletter({referrerSource}: {referrerSource: string | null}): boolean {\n if (!referrerSource) {\n return false;\n }\n // if referrer source ends with -newsletter\n return referrerSource.endsWith('-newsletter');\n }\n\n /**\n * Determine whether referrer is a Ghost.org URL\n * \n * @param referrerUrl - The referrer URL to check\n * @returns True if the referrer is from Ghost.org\n */\n isGhostOrgUrl(referrerUrl: URL | null): boolean {\n if (!referrerUrl) {\n return false;\n }\n return referrerUrl.hostname === 'ghost.org';\n }\n\n /**\n * Determine whether referrer is Ghost Explore\n * \n * @param deps - Input parameters\n * @returns True if the referrer is from Ghost Explore\n */\n isGhostExploreRef({referrerUrl, referrerSource}: {referrerUrl: URL | null, referrerSource?: string | null}): boolean {\n if (referrerSource === 'ghost-explore') {\n return true;\n }\n\n if (!referrerUrl) {\n return false;\n }\n\n if (referrerUrl?.hostname\n && this.adminUrl?.hostname === referrerUrl?.hostname\n && referrerUrl?.pathname?.startsWith(this.adminUrl?.pathname)\n ) {\n return true;\n }\n\n if (referrerUrl.hostname === 'ghost.org' && referrerUrl.pathname.startsWith('/explore')) {\n return true;\n }\n\n return false;\n }\n} ","import { ReferrerParser } from './lib/ReferrerParser';\nimport type { ReferrerData, ParserOptions } from './lib/ReferrerParser';\n\n/**\n * Parse a referrer URL to get source, medium and hostname\n * \n * @param referrerUrl - URL of the referrer to parse\n * @param options - Configuration options\n * @param referrerSource - Optional source to override URL parameters\n * @param referrerMedium - Optional medium to override URL parameters\n * @returns Parsed referrer data with source, medium and URL\n * \n * @example\n * // Basic usage\n * const result = parse('https://www.google.com/search?q=ghost+cms');\n * // result: { referrerSource: 'Google', referrerMedium: 'search', referrerUrl: 'www.google.com' }\n * \n * @example\n * // With site configuration\n * const result = parse('https://example.com/blog?utm_source=newsletter', {\n * siteUrl: 'https://example.com'\n * });\n * \n * @example\n * // With explicit source and medium\n * const result = parse('https://example.com', {}, 'newsletter', 'email');\n */\nfunction parse(\n referrerUrl: string, \n options: ParserOptions = {}, \n referrerSource?: string, \n referrerMedium?: string\n): ReferrerData {\n const parser = new ReferrerParser(options);\n return parser.parse(referrerUrl, referrerSource, referrerMedium);\n}\n\nexport {\n parse,\n ReferrerParser\n};\n\nexport type {\n ReferrerData,\n ParserOptions\n}; "],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
package/dist/index.d.ts CHANGED
@@ -5,6 +5,8 @@ import { ReferrerParser, ReferrerData, ParserOptions } from './lib/ReferrerParse
5
5
  *
6
6
  * @param referrerUrl - URL of the referrer to parse
7
7
  * @param options - Configuration options
8
+ * @param referrerSource - Optional source to override URL parameters
9
+ * @param referrerMedium - Optional medium to override URL parameters
8
10
  * @returns Parsed referrer data with source, medium and URL
9
11
  *
10
12
  * @example
@@ -17,7 +19,11 @@ import { ReferrerParser, ReferrerData, ParserOptions } from './lib/ReferrerParse
17
19
  * const result = parse('https://example.com/blog?utm_source=newsletter', {
18
20
  * siteUrl: 'https://example.com'
19
21
  * });
22
+ *
23
+ * @example
24
+ * // With explicit source and medium
25
+ * const result = parse('https://example.com', {}, 'newsletter', 'email');
20
26
  */
21
- declare function parse(referrerUrl: string, options?: ParserOptions): ReferrerData;
27
+ declare function parse(referrerUrl: string, options?: ParserOptions, referrerSource?: string, referrerMedium?: string): ReferrerData;
22
28
  export { parse, ReferrerParser };
23
29
  export type { ReferrerData, ParserOptions };
package/dist/index.js CHANGED
@@ -9415,34 +9415,12 @@ class ReferrerParser {
9415
9415
  * Parse a referrer URL to get source, medium and hostname
9416
9416
  *
9417
9417
  * @param referrerUrlStr - URL of the referrer
9418
- * @returns Parsed referrer data with source, medium and URL
9418
+ * @param referrerSource - Source of the referrer
9419
+ * @param referrerMedium - Medium of the referrer
9420
+ * @returns Parsed referrer data with source, medium and URL. Internal referrers return null values.
9419
9421
  */
9420
- parse(referrerUrlStr) {
9421
- if (!referrerUrlStr) {
9422
- return {
9423
- referrerSource: "Direct",
9424
- referrerMedium: null,
9425
- referrerUrl: null
9426
- };
9427
- }
9422
+ parse(referrerUrlStr, referrerSource, referrerMedium) {
9428
9423
  const referrerUrl = this.getUrlFromStr(referrerUrlStr);
9429
- if (!referrerUrl) {
9430
- return {
9431
- referrerSource: "Direct",
9432
- referrerMedium: null,
9433
- referrerUrl: null
9434
- };
9435
- }
9436
- if (referrerUrl.hostname === "checkout.stripe.com") {
9437
- return {
9438
- referrerSource: "Direct",
9439
- referrerMedium: null,
9440
- referrerUrl: null
9441
- };
9442
- }
9443
- const urlParams = new URLSearchParams(referrerUrl.search);
9444
- const referrerSource = urlParams.get("utm_source") || urlParams.get("source") || null;
9445
- const referrerMedium = urlParams.get("utm_medium") || urlParams.get("medium") || null;
9446
9424
  if (this.isGhostExploreRef({ referrerUrl, referrerSource })) {
9447
9425
  return {
9448
9426
  referrerSource: "Ghost Explore",
@@ -9454,12 +9432,12 @@ class ReferrerParser {
9454
9432
  return {
9455
9433
  referrerSource: "Ghost.org",
9456
9434
  referrerMedium: "Ghost Network",
9457
- referrerUrl: referrerUrl == null ? void 0 : referrerUrl.hostname
9435
+ referrerUrl: (referrerUrl == null ? void 0 : referrerUrl.hostname) ?? null
9458
9436
  };
9459
9437
  }
9460
- if (this.isGhostNewsletter({ referrerSource })) {
9438
+ if (referrerSource && this.isGhostNewsletter({ referrerSource })) {
9461
9439
  return {
9462
- referrerSource: referrerSource.replace(/-newsletter$/, " newsletter"),
9440
+ referrerSource: referrerSource.replace(/-/g, " "),
9463
9441
  referrerMedium: "Email",
9464
9442
  referrerUrl: (referrerUrl == null ? void 0 : referrerUrl.hostname) ?? null
9465
9443
  };
@@ -9489,7 +9467,7 @@ class ReferrerParser {
9489
9467
  };
9490
9468
  }
9491
9469
  return {
9492
- referrerSource: "Direct",
9470
+ referrerSource: null,
9493
9471
  referrerMedium: null,
9494
9472
  referrerUrl: null
9495
9473
  };
@@ -9584,24 +9562,25 @@ class ReferrerParser {
9584
9562
  * @returns True if the referrer is from Ghost Explore
9585
9563
  */
9586
9564
  isGhostExploreRef({ referrerUrl, referrerSource }) {
9565
+ var _a, _b, _c;
9587
9566
  if (referrerSource === "ghost-explore") {
9588
9567
  return true;
9589
9568
  }
9590
9569
  if (!referrerUrl) {
9591
9570
  return false;
9592
9571
  }
9593
- if (referrerUrl.hostname === "explore.ghost.io") {
9572
+ if ((referrerUrl == null ? void 0 : referrerUrl.hostname) && ((_a = this.adminUrl) == null ? void 0 : _a.hostname) === (referrerUrl == null ? void 0 : referrerUrl.hostname) && ((_c = referrerUrl == null ? void 0 : referrerUrl.pathname) == null ? void 0 : _c.startsWith((_b = this.adminUrl) == null ? void 0 : _b.pathname))) {
9594
9573
  return true;
9595
9574
  }
9596
- if (referrerUrl.hostname === "try.ghost.org" && referrerUrl.pathname.startsWith("/explore")) {
9575
+ if (referrerUrl.hostname === "ghost.org" && referrerUrl.pathname.startsWith("/explore")) {
9597
9576
  return true;
9598
9577
  }
9599
9578
  return false;
9600
9579
  }
9601
9580
  }
9602
- function parse(referrerUrl, options = {}) {
9581
+ function parse(referrerUrl, options = {}, referrerSource, referrerMedium) {
9603
9582
  const parser = new ReferrerParser(options);
9604
- return parser.parse(referrerUrl);
9583
+ return parser.parse(referrerUrl, referrerSource, referrerMedium);
9605
9584
  }
9606
9585
  export {
9607
9586
  ReferrerParser,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../lib/ReferrerParser.ts","../index.ts"],"sourcesContent":["/**\n * Interface for parsed referrer data\n */\nexport interface ReferrerData {\n /** The identified source of the referral traffic */\n referrerSource: string | null;\n /** The identified medium of the referral traffic */\n referrerMedium: string | null;\n /** The hostname of the referral URL */\n referrerUrl: string | null;\n}\n\n/**\n * Configuration options for the parser\n */\nexport interface ParserOptions {\n /** URL of the site for identifying internal traffic */\n siteUrl?: string;\n /** URL of the admin panel for identifying admin traffic */\n adminUrl?: string;\n}\n\n/**\n * Interface for referrer source data\n */\ninterface ReferrerSourceData {\n source: string;\n medium: string;\n}\n\n// Import known referrers data\nimport knownReferrers from './referrers.json';\n\n/**\n * Parses referrer URLs to determine source and medium\n */\nexport class ReferrerParser {\n private adminUrl: URL | null;\n private siteUrl: URL | null;\n\n /**\n * Creates a new referrer parser instance\n * \n * @param options - Configuration options\n */\n constructor(options: ParserOptions = {}) {\n this.adminUrl = this.getUrlFromStr(options.adminUrl || '');\n this.siteUrl = this.getUrlFromStr(options.siteUrl || '');\n }\n\n /**\n * Parse a referrer URL to get source, medium and hostname\n * \n * @param referrerUrlStr - URL of the referrer\n * @returns Parsed referrer data with source, medium and URL\n */\n parse(referrerUrlStr: string): ReferrerData {\n if (!referrerUrlStr) {\n return {\n referrerSource: 'Direct',\n referrerMedium: null,\n referrerUrl: null\n };\n }\n\n const referrerUrl = this.getUrlFromStr(referrerUrlStr);\n if (!referrerUrl) {\n return {\n referrerSource: 'Direct',\n referrerMedium: null,\n referrerUrl: null\n };\n }\n\n // Skip Stripe checkout URLs\n if (referrerUrl.hostname === 'checkout.stripe.com') {\n return {\n referrerSource: 'Direct',\n referrerMedium: null,\n referrerUrl: null\n };\n }\n\n // Check for source/medium in query parameters\n const urlParams = new URLSearchParams(referrerUrl.search);\n const referrerSource = urlParams.get('utm_source') || urlParams.get('source') || null;\n const referrerMedium = urlParams.get('utm_medium') || urlParams.get('medium') || null;\n\n // If referrer is Ghost Explore\n if (this.isGhostExploreRef({referrerUrl, referrerSource})) {\n return {\n referrerSource: 'Ghost Explore',\n referrerMedium: 'Ghost Network',\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n // If referrer is Ghost.org\n if (this.isGhostOrgUrl(referrerUrl)) {\n return {\n referrerSource: 'Ghost.org',\n referrerMedium: 'Ghost Network',\n referrerUrl: referrerUrl?.hostname\n };\n }\n\n // Check for Ghost Newsletter\n if (this.isGhostNewsletter({referrerSource})) {\n return {\n referrerSource: referrerSource!.replace(/-newsletter$/, ' newsletter'),\n referrerMedium: 'Email',\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n // If referrer source is available from parameters\n if (referrerSource) {\n const urlData = this.getDataFromUrl(referrerUrl);\n const knownSource = Object.values(knownReferrers as Record<string, ReferrerSourceData>).find(referrer => \n referrer.source.toLowerCase() === referrerSource.toLowerCase());\n \n return {\n referrerSource: knownSource?.source || referrerSource,\n referrerMedium: knownSource?.medium || referrerMedium || urlData?.medium || null,\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n // If referrer is known external URL\n if (!this.isSiteDomain(referrerUrl)) {\n const urlData = this.getDataFromUrl(referrerUrl);\n\n // Use known source/medium if available\n if (urlData) {\n return {\n referrerSource: urlData?.source ?? null,\n referrerMedium: urlData?.medium ?? null,\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n \n // Use the hostname as a source\n return {\n referrerSource: referrerUrl?.hostname ?? null,\n referrerMedium: null,\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n return {\n referrerSource: 'Direct',\n referrerMedium: null,\n referrerUrl: null\n };\n }\n\n /**\n * Fetches referrer data from known external URLs\n * \n * @param url - The URL to match against known referrers\n * @returns Matched referrer data or null if not found\n */\n getDataFromUrl(url: URL | null): ReferrerSourceData | null {\n // Handle null url case\n if (!url) {\n return null;\n }\n\n // Allow matching both \"google.ac/products\" and \"google.ac\" as a source\n const urlHostPath = url.hostname + url.pathname;\n const urlDataKey = Object.keys(knownReferrers as Record<string, ReferrerSourceData>).sort((a, b) => {\n // The longer key has higher priority so google.ac/products is selected before google.ac\n return b.length - a.length;\n }).find((source) => {\n return urlHostPath.startsWith(source);\n });\n\n return urlDataKey ? (knownReferrers as Record<string, ReferrerSourceData>)[urlDataKey] : null;\n }\n\n /**\n * Return URL object for provided URL string\n * \n * @param url - URL string to parse\n * @returns Parsed URL object or null if invalid\n */\n getUrlFromStr(url: string): URL | null {\n if (!url) {\n return null;\n }\n \n try {\n return new URL(url);\n } catch (e) {\n return null;\n }\n }\n\n /**\n * Determine whether the provided URL is a link to the site\n * \n * @param url - URL to check\n * @returns True if the URL belongs to the configured site\n */\n isSiteDomain(url: URL | null): boolean {\n try {\n // If we don't have siteUrl configured, we can't detect internal traffic\n if (!this.siteUrl) {\n return false;\n }\n\n if (!url) {\n return false;\n }\n\n if (this.siteUrl.hostname === url.hostname) {\n if (url.pathname.startsWith(this.siteUrl.pathname)) {\n return true;\n }\n return false;\n }\n return false;\n } catch (e) {\n return false;\n }\n }\n\n /**\n * Determine whether referrer is a Ghost newsletter\n * \n * @param deps - Input parameters\n * @returns True if the referrer is a Ghost newsletter\n */\n isGhostNewsletter({referrerSource}: {referrerSource: string | null}): boolean {\n if (!referrerSource) {\n return false;\n }\n // if referrer source ends with -newsletter\n return referrerSource.endsWith('-newsletter');\n }\n\n /**\n * Determine whether referrer is a Ghost.org URL\n * \n * @param referrerUrl - The referrer URL to check\n * @returns True if the referrer is from Ghost.org\n */\n isGhostOrgUrl(referrerUrl: URL | null): boolean {\n if (!referrerUrl) {\n return false;\n }\n return referrerUrl.hostname === 'ghost.org';\n }\n\n /**\n * Determine whether referrer is Ghost Explore\n * \n * @param deps - Input parameters\n * @returns True if the referrer is from Ghost Explore\n */\n isGhostExploreRef({referrerUrl, referrerSource}: {referrerUrl: URL | null, referrerSource?: string | null}): boolean {\n // Always check for ghost-explore source param\n if (referrerSource === 'ghost-explore') {\n return true;\n }\n\n if (!referrerUrl) {\n return false;\n }\n\n // Check domain for explore.ghost.io and try.ghost.org/explore\n if (referrerUrl.hostname === 'explore.ghost.io') {\n return true;\n }\n\n if (referrerUrl.hostname === 'try.ghost.org' && referrerUrl.pathname.startsWith('/explore')) {\n return true;\n }\n\n return false;\n }\n} ","import { ReferrerParser } from './lib/ReferrerParser';\nimport type { ReferrerData, ParserOptions } from './lib/ReferrerParser';\n\n/**\n * Parse a referrer URL to get source, medium and hostname\n * \n * @param referrerUrl - URL of the referrer to parse\n * @param options - Configuration options\n * @returns Parsed referrer data with source, medium and URL\n * \n * @example\n * // Basic usage\n * const result = parse('https://www.google.com/search?q=ghost+cms');\n * // result: { referrerSource: 'Google', referrerMedium: 'search', referrerUrl: 'www.google.com' }\n * \n * @example\n * // With site configuration\n * const result = parse('https://example.com/blog?utm_source=newsletter', {\n * siteUrl: 'https://example.com'\n * });\n */\nfunction parse(referrerUrl: string, options: ParserOptions = {}): ReferrerData {\n const parser = new ReferrerParser(options);\n return parser.parse(referrerUrl);\n}\n\nexport {\n parse,\n ReferrerParser\n};\n\nexport type {\n ReferrerData,\n ParserOptions\n}; "],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
1
+ {"version":3,"file":"index.js","sources":["../lib/ReferrerParser.ts","../index.ts"],"sourcesContent":["/**\n * Interface for parsed referrer data\n */\nexport interface ReferrerData {\n /** The identified source of the referral traffic */\n referrerSource: string | null;\n /** The identified medium of the referral traffic */\n referrerMedium: string | null;\n /** The hostname of the referral URL */\n referrerUrl: string | null;\n}\n\n/**\n * Configuration options for the parser\n */\nexport interface ParserOptions {\n /** URL of the site for identifying internal traffic */\n siteUrl?: string;\n /** URL of the admin panel for identifying admin traffic */\n adminUrl?: string;\n}\n\n/**\n * Interface for referrer source data\n */\ninterface ReferrerSourceData {\n source: string;\n medium: string;\n}\n\n// Import known referrers data\nimport knownReferrers from './referrers.json';\n\n/**\n * Parses referrer URLs to determine source and medium\n */\nexport class ReferrerParser {\n private adminUrl: URL | null;\n private siteUrl: URL | null;\n\n /**\n * Creates a new referrer parser instance\n * \n * @param options - Configuration options\n */\n constructor(options: ParserOptions = {}) {\n this.adminUrl = this.getUrlFromStr(options.adminUrl || '');\n this.siteUrl = this.getUrlFromStr(options.siteUrl || '');\n }\n\n /**\n * Parse a referrer URL to get source, medium and hostname\n * \n * @param referrerUrlStr - URL of the referrer\n * @param referrerSource - Source of the referrer\n * @param referrerMedium - Medium of the referrer\n * @returns Parsed referrer data with source, medium and URL. Internal referrers return null values.\n */\n parse(referrerUrlStr: string, referrerSource?: string, referrerMedium?: string): ReferrerData {\n const referrerUrl = this.getUrlFromStr(referrerUrlStr);\n\n // Ghost-specific cases\n if (this.isGhostExploreRef({referrerUrl, referrerSource})) {\n return {\n referrerSource: 'Ghost Explore',\n referrerMedium: 'Ghost Network',\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n // If referrer is Ghost.org\n if (this.isGhostOrgUrl(referrerUrl)) {\n return {\n referrerSource: 'Ghost.org',\n referrerMedium: 'Ghost Network',\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n // Check for Ghost Newsletter\n if (referrerSource && this.isGhostNewsletter({referrerSource})) {\n return {\n referrerSource: referrerSource.replace(/-/g, ' '),\n referrerMedium: 'Email',\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n // If referrer source is available from parameters\n if (referrerSource) {\n const urlData = this.getDataFromUrl(referrerUrl);\n const knownSource = Object.values(knownReferrers as Record<string, ReferrerSourceData>).find(referrer => \n referrer.source.toLowerCase() === referrerSource.toLowerCase());\n \n return {\n referrerSource: knownSource?.source || referrerSource,\n referrerMedium: knownSource?.medium || referrerMedium || urlData?.medium || null,\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n // If referrer is known external URL\n if (!this.isSiteDomain(referrerUrl)) {\n const urlData = this.getDataFromUrl(referrerUrl);\n\n // Use known source/medium if available\n if (urlData) {\n return {\n referrerSource: urlData?.source ?? null,\n referrerMedium: urlData?.medium ?? null,\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n \n // Use the hostname as a source\n return {\n referrerSource: referrerUrl?.hostname ?? null,\n referrerMedium: null,\n referrerUrl: referrerUrl?.hostname ?? null\n };\n }\n\n return {\n referrerSource: null,\n referrerMedium: null,\n referrerUrl: null\n }\n }\n\n /**\n * Fetches referrer data from known external URLs\n * \n * @param url - The URL to match against known referrers\n * @returns Matched referrer data or null if not found\n */\n getDataFromUrl(url: URL | null): ReferrerSourceData | null {\n // Handle null url case\n if (!url) {\n return null;\n }\n\n // Allow matching both \"google.ac/products\" and \"google.ac\" as a source\n const urlHostPath = url.hostname + url.pathname;\n const urlDataKey = Object.keys(knownReferrers as Record<string, ReferrerSourceData>).sort((a, b) => {\n // The longer key has higher priority so google.ac/products is selected before google.ac\n return b.length - a.length;\n }).find((source) => {\n return urlHostPath.startsWith(source);\n });\n\n return urlDataKey ? (knownReferrers as Record<string, ReferrerSourceData>)[urlDataKey] : null;\n }\n\n /**\n * Return URL object for provided URL string\n * \n * @param url - URL string to parse\n * @returns Parsed URL object or null if invalid\n */\n getUrlFromStr(url: string): URL | null {\n if (!url) {\n return null;\n }\n \n try {\n return new URL(url);\n } catch (e) {\n return null;\n }\n }\n\n /**\n * Determine whether the provided URL is a link to the site\n * \n * @param url - URL to check\n * @returns True if the URL belongs to the configured site\n */\n isSiteDomain(url: URL | null): boolean {\n try {\n // If we don't have siteUrl configured, we can't detect internal traffic\n if (!this.siteUrl) {\n return false;\n }\n\n if (!url) {\n return false;\n }\n\n if (this.siteUrl.hostname === url.hostname) {\n if (url.pathname.startsWith(this.siteUrl.pathname)) {\n return true;\n }\n return false;\n }\n return false;\n } catch (e) {\n return false;\n }\n }\n\n /**\n * Determine whether referrer is a Ghost newsletter\n * \n * @param deps - Input parameters\n * @returns True if the referrer is a Ghost newsletter\n */\n isGhostNewsletter({referrerSource}: {referrerSource: string | null}): boolean {\n if (!referrerSource) {\n return false;\n }\n // if referrer source ends with -newsletter\n return referrerSource.endsWith('-newsletter');\n }\n\n /**\n * Determine whether referrer is a Ghost.org URL\n * \n * @param referrerUrl - The referrer URL to check\n * @returns True if the referrer is from Ghost.org\n */\n isGhostOrgUrl(referrerUrl: URL | null): boolean {\n if (!referrerUrl) {\n return false;\n }\n return referrerUrl.hostname === 'ghost.org';\n }\n\n /**\n * Determine whether referrer is Ghost Explore\n * \n * @param deps - Input parameters\n * @returns True if the referrer is from Ghost Explore\n */\n isGhostExploreRef({referrerUrl, referrerSource}: {referrerUrl: URL | null, referrerSource?: string | null}): boolean {\n if (referrerSource === 'ghost-explore') {\n return true;\n }\n\n if (!referrerUrl) {\n return false;\n }\n\n if (referrerUrl?.hostname\n && this.adminUrl?.hostname === referrerUrl?.hostname\n && referrerUrl?.pathname?.startsWith(this.adminUrl?.pathname)\n ) {\n return true;\n }\n\n if (referrerUrl.hostname === 'ghost.org' && referrerUrl.pathname.startsWith('/explore')) {\n return true;\n }\n\n return false;\n }\n} ","import { ReferrerParser } from './lib/ReferrerParser';\nimport type { ReferrerData, ParserOptions } from './lib/ReferrerParser';\n\n/**\n * Parse a referrer URL to get source, medium and hostname\n * \n * @param referrerUrl - URL of the referrer to parse\n * @param options - Configuration options\n * @param referrerSource - Optional source to override URL parameters\n * @param referrerMedium - Optional medium to override URL parameters\n * @returns Parsed referrer data with source, medium and URL\n * \n * @example\n * // Basic usage\n * const result = parse('https://www.google.com/search?q=ghost+cms');\n * // result: { referrerSource: 'Google', referrerMedium: 'search', referrerUrl: 'www.google.com' }\n * \n * @example\n * // With site configuration\n * const result = parse('https://example.com/blog?utm_source=newsletter', {\n * siteUrl: 'https://example.com'\n * });\n * \n * @example\n * // With explicit source and medium\n * const result = parse('https://example.com', {}, 'newsletter', 'email');\n */\nfunction parse(\n referrerUrl: string, \n options: ParserOptions = {}, \n referrerSource?: string, \n referrerMedium?: string\n): ReferrerData {\n const parser = new ReferrerParser(options);\n return parser.parse(referrerUrl, referrerSource, referrerMedium);\n}\n\nexport {\n parse,\n ReferrerParser\n};\n\nexport type {\n ReferrerData,\n ParserOptions\n}; "],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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"}
@@ -41,9 +41,11 @@ export declare class ReferrerParser {
41
41
  * Parse a referrer URL to get source, medium and hostname
42
42
  *
43
43
  * @param referrerUrlStr - URL of the referrer
44
- * @returns Parsed referrer data with source, medium and URL
44
+ * @param referrerSource - Source of the referrer
45
+ * @param referrerMedium - Medium of the referrer
46
+ * @returns Parsed referrer data with source, medium and URL. Internal referrers return null values.
45
47
  */
46
- parse(referrerUrlStr: string): ReferrerData;
48
+ parse(referrerUrlStr: string, referrerSource?: string, referrerMedium?: string): ReferrerData;
47
49
  /**
48
50
  * Fetches referrer data from known external URLs
49
51
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tryghost/referrer-parser",
3
- "version": "0.0.2",
3
+ "version": "0.1.0",
4
4
  "description": "Simple library for parsing referrer URLs",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -67,5 +67,5 @@
67
67
  "publishConfig": {
68
68
  "access": "public"
69
69
  },
70
- "gitHead": "c69c4c3ad837302b4ff64bbef7dc6dd59150222e"
70
+ "gitHead": "03afe1f4459d475adf2b9869f341b4269c1a5665"
71
71
  }