urlpurify 2.2.1 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -45
- package/dist/clean.d.mts +1 -0
- package/dist/clean.mjs +56 -19
- package/dist/defaults.d.mts +7 -1
- package/dist/defaults.mjs +160 -3
- package/dist/index.d.mts +79 -4
- package/dist/index.mjs +79 -4
- package/dist/node_modules/entities/dist/decode-codepoint.mjs +2 -2
- package/dist/node_modules/entities/dist/decode.mjs +262 -247
- package/dist/node_modules/entities/dist/generated/decode-data-html.mjs +8 -4
- package/dist/node_modules/entities/dist/internal/decode-data-format.mjs +116 -0
- package/dist/node_modules/trousse/dist/is.mjs +7 -1
- package/dist/node_modules/trousse/dist/locales.mjs +21 -0
- package/dist/node_modules/trousse/dist/matching.mjs +22 -20
- package/dist/node_modules/trousse/dist/urls.mjs +186 -53
- package/dist/pathTarget.mjs +2 -2
- package/dist/tracking/clickAttribution.mjs +26 -1
- package/dist/tracking/housekeeping.mjs +13 -1
- package/dist/tracking/session.d.mts +2 -0
- package/dist/tracking/session.mjs +12 -0
- package/dist/types.d.mts +7 -1
- package/dist/unwraps/a8Net.mjs +1 -1
- package/dist/unwraps/acast.mjs +1 -1
- package/dist/unwraps/accesstrade.mjs +1 -1
- package/dist/unwraps/aceml.mjs +2 -2
- package/dist/unwraps/adcell.mjs +1 -1
- package/dist/unwraps/addThis.d.mts +2 -0
- package/dist/unwraps/addThis.mjs +17 -0
- package/dist/unwraps/addToAny.d.mts +2 -0
- package/dist/unwraps/addToAny.mjs +21 -0
- package/dist/unwraps/addToAnySubscribe.d.mts +2 -0
- package/dist/unwraps/addToAnySubscribe.mjs +8 -0
- package/dist/unwraps/addToMyYahoo.d.mts +2 -0
- package/dist/unwraps/addToMyYahoo.mjs +29 -0
- package/dist/unwraps/adfly.mjs +1 -1
- package/dist/unwraps/admitad.mjs +1 -1
- package/dist/unwraps/affilae.mjs +2 -1
- package/dist/unwraps/affiliatesOne.mjs +1 -1
- package/dist/unwraps/allblog.mjs +1 -1
- package/dist/unwraps/amazonAffiliate.mjs +5 -4
- package/dist/unwraps/amazonSes.mjs +2 -2
- package/dist/unwraps/ampCache.mjs +4 -3
- package/dist/unwraps/ampCacheImage.mjs +1 -1
- package/dist/unwraps/anchor.mjs +1 -1
- package/dist/unwraps/anonymouse.mjs +1 -1
- package/dist/unwraps/antennaPod.d.mts +2 -0
- package/dist/unwraps/antennaPod.mjs +15 -0
- package/dist/unwraps/anytimePlayer.d.mts +2 -0
- package/dist/unwraps/anytimePlayer.mjs +17 -0
- package/dist/unwraps/apptrkr.mjs +2 -1
- package/dist/unwraps/archiveToday.mjs +2 -2
- package/dist/unwraps/arquivo.mjs +1 -1
- package/dist/unwraps/arttrack.mjs +1 -1
- package/dist/unwraps/augure.mjs +3 -3
- package/dist/unwraps/awesound.mjs +1 -1
- package/dist/unwraps/axigen.mjs +2 -1
- package/dist/unwraps/bacLacWebArchive.mjs +1 -1
- package/dist/unwraps/bananatag.mjs +1 -1
- package/dist/unwraps/big5Gate.mjs +1 -1
- package/dist/unwraps/bing.mjs +7 -7
- package/dist/unwraps/bingAds.mjs +4 -4
- package/dist/unwraps/bitrix.mjs +2 -1
- package/dist/unwraps/bitrixBanner.mjs +2 -1
- package/dist/unwraps/blinkList.d.mts +2 -0
- package/dist/unwraps/blinkList.mjs +8 -0
- package/dist/unwraps/bloggerBlogThis.d.mts +2 -0
- package/dist/unwraps/bloggerBlogThis.mjs +16 -0
- package/dist/unwraps/bloggerImageProxy.mjs +2 -1
- package/dist/unwraps/bloglines.d.mts +2 -0
- package/dist/unwraps/bloglines.mjs +21 -0
- package/dist/unwraps/bridgyFed.mjs +1 -1
- package/dist/unwraps/buffer.d.mts +2 -0
- package/dist/unwraps/buffer.mjs +23 -0
- package/dist/unwraps/buybox.mjs +1 -1
- package/dist/unwraps/buzzstream.mjs +1 -1
- package/dist/unwraps/checkPointHarmony.mjs +2 -2
- package/dist/unwraps/cjNetwork.mjs +3 -3
- package/dist/unwraps/claritas.mjs +2 -2
- package/dist/unwraps/cleverbridge.mjs +1 -1
- package/dist/unwraps/cloudhq.mjs +1 -1
- package/dist/unwraps/cloze.mjs +1 -1
- package/dist/unwraps/cohst.mjs +1 -1
- package/dist/unwraps/contactMonkey.mjs +3 -2
- package/dist/unwraps/convertiser.mjs +1 -1
- package/dist/unwraps/cse360.mjs +1 -1
- package/dist/unwraps/dasBlog.mjs +1 -1
- package/dist/unwraps/datalifeEngine.mjs +5 -4
- package/dist/unwraps/delicious.d.mts +2 -0
- package/dist/unwraps/delicious.mjs +15 -0
- package/dist/unwraps/deployer.mjs +2 -2
- package/dist/unwraps/derefMail.mjs +4 -3
- package/dist/unwraps/deviantartOutgoing.mjs +1 -1
- package/dist/unwraps/diasporaShare.d.mts +2 -0
- package/dist/unwraps/diasporaShare.mjs +16 -0
- package/dist/unwraps/diggSubmit.d.mts +2 -0
- package/dist/unwraps/diggSubmit.mjs +11 -0
- package/dist/unwraps/digikala.mjs +3 -3
- package/dist/unwraps/diigoPost.d.mts +2 -0
- package/dist/unwraps/diigoPost.mjs +12 -0
- package/dist/unwraps/disqus.mjs +2 -1
- package/dist/unwraps/dstats.mjs +2 -2
- package/dist/unwraps/eClick.mjs +1 -1
- package/dist/unwraps/easyMarketing.mjs +3 -3
- package/dist/unwraps/ebayRover.mjs +1 -1
- package/dist/unwraps/ebuzzing.mjs +1 -1
- package/dist/unwraps/edgepilot.mjs +1 -1
- package/dist/unwraps/effiliation.mjs +1 -1
- package/dist/unwraps/elasticEmail.mjs +2 -1
- package/dist/unwraps/epn.mjs +1 -1
- package/dist/unwraps/eulerian.mjs +1 -1
- package/dist/unwraps/evernoteClip.d.mts +2 -0
- package/dist/unwraps/evernoteClip.mjs +8 -0
- package/dist/unwraps/exciteTranslate.mjs +1 -1
- package/dist/unwraps/facebook.mjs +1 -1
- package/dist/unwraps/facebookShare.d.mts +2 -0
- package/dist/unwraps/facebookShare.mjs +25 -0
- package/dist/unwraps/feed2js.d.mts +2 -0
- package/dist/unwraps/feed2js.mjs +16 -0
- package/dist/unwraps/feedStatistics.mjs +2 -2
- package/dist/unwraps/feedValidator.d.mts +2 -0
- package/dist/unwraps/feedValidator.mjs +12 -0
- package/dist/unwraps/feedblitz.mjs +1 -1
- package/dist/unwraps/feedland.d.mts +2 -0
- package/dist/unwraps/feedland.mjs +12 -0
- package/dist/unwraps/feedly.d.mts +2 -0
- package/dist/unwraps/feedly.mjs +28 -0
- package/dist/unwraps/feedsportal.mjs +1 -1
- package/dist/unwraps/firebaseDynamicLinks.mjs +1 -1
- package/dist/unwraps/firstory.mjs +3 -3
- package/dist/unwraps/fiveByFive.mjs +2 -2
- package/dist/unwraps/flattrSubmit.d.mts +2 -0
- package/dist/unwraps/flattrSubmit.mjs +8 -0
- package/dist/unwraps/flipboardShare.d.mts +2 -0
- package/dist/unwraps/flipboardShare.mjs +15 -0
- package/dist/unwraps/fortimail.mjs +2 -1
- package/dist/unwraps/friendFeed.d.mts +2 -0
- package/dist/unwraps/friendFeed.mjs +18 -0
- package/dist/unwraps/gabCompose.d.mts +2 -0
- package/dist/unwraps/gabCompose.mjs +8 -0
- package/dist/unwraps/genericCarrier.d.mts +2 -0
- package/dist/unwraps/genericCarrier.mjs +31 -0
- package/dist/unwraps/gfnLinkProxy.mjs +3 -3
- package/dist/unwraps/godcaster.mjs +2 -2
- package/dist/unwraps/googleAmpViewer.mjs +2 -2
- package/dist/unwraps/googleBookmarks.d.mts +2 -0
- package/dist/unwraps/googleBookmarks.mjs +8 -0
- package/dist/unwraps/googleBuzz.d.mts +2 -0
- package/dist/unwraps/googleBuzz.mjs +8 -0
- package/dist/unwraps/googleNewsModern.mjs +2 -3
- package/dist/unwraps/googlePlusShare.d.mts +2 -0
- package/dist/unwraps/googlePlusShare.mjs +11 -0
- package/dist/unwraps/googlePodcasts.d.mts +2 -0
- package/dist/unwraps/googlePodcasts.mjs +27 -0
- package/dist/unwraps/googleReader.d.mts +2 -0
- package/dist/unwraps/googleReader.mjs +20 -0
- package/dist/unwraps/googleTranslate.mjs +5 -5
- package/dist/unwraps/govdelivery.mjs +3 -2
- package/dist/unwraps/hackerNewsSubmit.d.mts +2 -0
- package/dist/unwraps/hackerNewsSubmit.mjs +8 -0
- package/dist/unwraps/hasoffers.mjs +2 -1
- package/dist/unwraps/hatenaBookmark.d.mts +2 -0
- package/dist/unwraps/hatenaBookmark.mjs +22 -0
- package/dist/unwraps/hirkereso.mjs +1 -1
- package/dist/unwraps/horde.mjs +1 -1
- package/dist/unwraps/hubspotSidekick.mjs +1 -1
- package/dist/unwraps/impact.mjs +2 -2
- package/dist/unwraps/indexHu.mjs +2 -1
- package/dist/unwraps/inoreader.d.mts +2 -0
- package/dist/unwraps/inoreader.mjs +22 -0
- package/dist/unwraps/instapaperSave.d.mts +2 -0
- package/dist/unwraps/instapaperSave.mjs +11 -0
- package/dist/unwraps/invisionNoExternalLinks.mjs +1 -1
- package/dist/unwraps/involveAsia.mjs +1 -1
- package/dist/unwraps/jive.mjs +2 -1
- package/dist/unwraps/klook.mjs +2 -1
- package/dist/unwraps/lazada.mjs +1 -1
- package/dist/unwraps/letscast.mjs +1 -1
- package/dist/unwraps/lineShare.d.mts +2 -0
- package/dist/unwraps/lineShare.mjs +25 -0
- package/dist/unwraps/linkA.mjs +1 -1
- package/dist/unwraps/linkedin.mjs +1 -1
- package/dist/unwraps/linkedinShare.d.mts +2 -0
- package/dist/unwraps/linkedinShare.mjs +15 -0
- package/dist/unwraps/linksynergy.mjs +2 -2
- package/dist/unwraps/linktrust.mjs +3 -3
- package/dist/unwraps/linkwise.mjs +1 -1
- package/dist/unwraps/livedoorReader.d.mts +2 -0
- package/dist/unwraps/livedoorReader.mjs +12 -0
- package/dist/unwraps/locWebArchive.mjs +1 -1
- package/dist/unwraps/locaweb.mjs +2 -1
- package/dist/unwraps/logicboard.mjs +1 -1
- package/dist/unwraps/magellan.mjs +1 -1
- package/dist/unwraps/mail2easy.mjs +1 -1
- package/dist/unwraps/mailchimp.mjs +1 -1
- package/dist/unwraps/mailinblack.mjs +6 -4
- package/dist/unwraps/mailstat.mjs +1 -1
- package/dist/unwraps/mailtrack.mjs +1 -1
- package/dist/unwraps/mandrill.mjs +3 -3
- package/dist/unwraps/medium.mjs +5 -5
- package/dist/unwraps/meneameSubmit.d.mts +2 -0
- package/dist/unwraps/meneameSubmit.mjs +11 -0
- package/dist/unwraps/meweShare.d.mts +2 -0
- package/dist/unwraps/meweShare.mjs +8 -0
- package/dist/unwraps/mimecast.mjs +1 -1
- package/dist/unwraps/ministryCloud.mjs +1 -1
- package/dist/unwraps/mintDownloads.mjs +1 -1
- package/dist/unwraps/mintFeeder.mjs +2 -1
- package/dist/unwraps/mohtwize.mjs +6 -4
- package/dist/unwraps/morss.d.mts +2 -0
- package/dist/unwraps/morss.mjs +13 -0
- package/dist/unwraps/mozillaOutgoing.mjs +3 -3
- package/dist/unwraps/myAolFeeds.d.mts +2 -0
- package/dist/unwraps/myAolFeeds.mjs +8 -0
- package/dist/unwraps/narrativ.mjs +1 -1
- package/dist/unwraps/natlibNz.mjs +1 -1
- package/dist/unwraps/ncls.mjs +2 -1
- package/dist/unwraps/ndlWarp.mjs +2 -2
- package/dist/unwraps/netaffiliation.mjs +1 -1
- package/dist/unwraps/netvibes.d.mts +2 -0
- package/dist/unwraps/netvibes.mjs +7 -0
- package/dist/unwraps/newsGator.d.mts +2 -0
- package/dist/unwraps/newsGator.mjs +17 -0
- package/dist/unwraps/newswire.mjs +3 -3
- package/dist/unwraps/nicoMs.mjs +1 -1
- package/dist/unwraps/nimble.mjs +1 -1
- package/dist/unwraps/nlaWebarchive.mjs +3 -3
- package/dist/unwraps/okShare.d.mts +2 -0
- package/dist/unwraps/okShare.mjs +23 -0
- package/dist/unwraps/op3.mjs +1 -1
- package/dist/unwraps/outlookSafelinks.mjs +1 -1
- package/dist/unwraps/pageflakes.d.mts +2 -0
- package/dist/unwraps/pageflakes.mjs +8 -0
- package/dist/unwraps/pagefreezer.mjs +2 -2
- package/dist/unwraps/partnerAds.mjs +2 -2
- package/dist/unwraps/pbs.mjs +1 -1
- package/dist/unwraps/pinterestPin.d.mts +2 -0
- package/dist/unwraps/pinterestPin.mjs +85 -0
- package/dist/unwraps/pipedrive.mjs +1 -1
- package/dist/unwraps/playerFm.d.mts +2 -0
- package/dist/unwraps/playerFm.mjs +16 -0
- package/dist/unwraps/pocketSave.d.mts +2 -0
- package/dist/unwraps/pocketSave.mjs +15 -0
- package/dist/unwraps/podcastAddict.d.mts +2 -0
- package/dist/unwraps/podcastAddict.mjs +14 -0
- package/dist/unwraps/podcastReady.d.mts +2 -0
- package/dist/unwraps/podcastReady.mjs +8 -0
- package/dist/unwraps/podcorn.mjs +1 -1
- package/dist/unwraps/podkite.mjs +1 -1
- package/dist/unwraps/podscribe.mjs +1 -1
- package/dist/unwraps/podsights.mjs +1 -1
- package/dist/unwraps/podup.mjs +2 -3
- package/dist/unwraps/postAffiliatePro.mjs +1 -1
- package/dist/unwraps/postmark.mjs +1 -1
- package/dist/unwraps/prNewswire.mjs +2 -2
- package/dist/unwraps/prezly.mjs +1 -1
- package/dist/unwraps/proofpointV3.mjs +3 -3
- package/dist/unwraps/prweb.mjs +2 -2
- package/dist/unwraps/prxPlayer.d.mts +2 -0
- package/dist/unwraps/prxPlayer.mjs +16 -0
- package/dist/unwraps/qqMailReader.d.mts +2 -0
- package/dist/unwraps/qqMailReader.mjs +8 -0
- package/dist/unwraps/qualityClick.mjs +2 -1
- package/dist/unwraps/qzoneShare.d.mts +2 -0
- package/dist/unwraps/qzoneShare.mjs +8 -0
- package/dist/unwraps/rakutenAffiliate.mjs +3 -3
- package/dist/unwraps/redditOut.mjs +1 -1
- package/dist/unwraps/redditSubmit.d.mts +2 -0
- package/dist/unwraps/redditSubmit.mjs +19 -0
- package/dist/unwraps/researchgate.mjs +1 -1
- package/dist/unwraps/reviveAdserver.mjs +2 -2
- package/dist/unwraps/rssBoardValidator.d.mts +2 -0
- package/dist/unwraps/rssBoardValidator.mjs +8 -0
- package/dist/unwraps/salesdoubler.mjs +1 -1
- package/dist/unwraps/saleshandy.mjs +1 -1
- package/dist/unwraps/segmentfault.mjs +2 -2
- package/dist/unwraps/serendipity.mjs +3 -3
- package/dist/unwraps/shareaholic.d.mts +2 -0
- package/dist/unwraps/shareaholic.mjs +12 -0
- package/dist/unwraps/slashdotBookmark.d.mts +2 -0
- package/dist/unwraps/slashdotBookmark.mjs +11 -0
- package/dist/unwraps/smartredirect.mjs +1 -1
- package/dist/unwraps/sophos.mjs +2 -2
- package/dist/unwraps/soundOn.mjs +1 -1
- package/dist/unwraps/stay22.mjs +1 -1
- package/dist/unwraps/streamsend.mjs +1 -1
- package/dist/unwraps/stumbleuponSubmit.d.mts +2 -0
- package/dist/unwraps/stumbleuponSubmit.mjs +14 -0
- package/dist/unwraps/subscribeByEmail.d.mts +2 -0
- package/dist/unwraps/subscribeByEmail.mjs +10 -0
- package/dist/unwraps/subscribeOnAndroid.d.mts +2 -0
- package/dist/unwraps/subscribeOnAndroid.mjs +10 -0
- package/dist/unwraps/subscribeRu.mjs +1 -1
- package/dist/unwraps/substack.mjs +2 -3
- package/dist/unwraps/surly.mjs +1 -1
- package/dist/unwraps/swap.mjs +1 -1
- package/dist/unwraps/symantecClicktime.mjs +1 -1
- package/dist/unwraps/symplicity.mjs +1 -1
- package/dist/unwraps/teacup.mjs +1 -1
- package/dist/unwraps/technoratiFaves.d.mts +2 -0
- package/dist/unwraps/technoratiFaves.mjs +10 -0
- package/dist/unwraps/telegramShare.d.mts +2 -0
- package/dist/unwraps/telegramShare.mjs +18 -0
- package/dist/unwraps/theRegister.mjs +1 -1
- package/dist/unwraps/threadsIntent.d.mts +2 -0
- package/dist/unwraps/threadsIntent.mjs +16 -0
- package/dist/unwraps/toucharcade.mjs +1 -1
- package/dist/unwraps/tracdelight.mjs +1 -1
- package/dist/unwraps/trxHub.mjs +1 -1
- package/dist/unwraps/tumblrShare.d.mts +2 -0
- package/dist/unwraps/tumblrShare.mjs +13 -0
- package/dist/unwraps/twitterIntent.d.mts +2 -0
- package/dist/unwraps/twitterIntent.mjs +17 -0
- package/dist/unwraps/twoCheckout.mjs +2 -1
- package/dist/unwraps/ukWebArchive.mjs +1 -1
- package/dist/unwraps/ukgwa.mjs +1 -1
- package/dist/unwraps/unescoWebArchive.mjs +1 -1
- package/dist/unwraps/unisender.mjs +3 -3
- package/dist/unwraps/upAudio.mjs +1 -1
- package/dist/unwraps/vadeSecure.mjs +1 -1
- package/dist/unwraps/valuePress.mjs +2 -2
- package/dist/unwraps/vanilla.mjs +1 -1
- package/dist/unwraps/vbulletin.mjs +1 -1
- package/dist/unwraps/vefsafn.mjs +2 -2
- package/dist/unwraps/vgWort.mjs +1 -1
- package/dist/unwraps/vkShare.d.mts +2 -0
- package/dist/unwraps/vkShare.mjs +16 -0
- package/dist/unwraps/vocus.mjs +1 -1
- package/dist/unwraps/voxnest.mjs +1 -1
- package/dist/unwraps/w3cFeedValidator.d.mts +2 -0
- package/dist/unwraps/w3cFeedValidator.mjs +8 -0
- package/dist/unwraps/webArchive.mjs +5 -5
- package/dist/unwraps/webcitation.mjs +1 -1
- package/dist/unwraps/webharvest.mjs +1 -1
- package/dist/unwraps/weiboShare.d.mts +2 -0
- package/dist/unwraps/weiboShare.mjs +8 -0
- package/dist/unwraps/weserv.mjs +2 -2
- package/dist/unwraps/wikizero.mjs +2 -2
- package/dist/unwraps/windowsLive.d.mts +2 -0
- package/dist/unwraps/windowsLive.mjs +13 -0
- package/dist/unwraps/windowsLiveFavorites.d.mts +2 -0
- package/dist/unwraps/windowsLiveFavorites.mjs +8 -0
- package/dist/unwraps/wpPoczta.mjs +2 -2
- package/dist/unwraps/wykop.d.mts +2 -0
- package/dist/unwraps/wykop.mjs +11 -0
- package/dist/unwraps/xengentr.mjs +4 -3
- package/dist/unwraps/xianguo.d.mts +2 -0
- package/dist/unwraps/xianguo.mjs +8 -0
- package/dist/unwraps/xiaoyuzhou.mjs +1 -1
- package/dist/unwraps/ximalaya.mjs +3 -3
- package/dist/unwraps/xingShare.d.mts +2 -0
- package/dist/unwraps/xingShare.mjs +16 -0
- package/dist/unwraps/yahooBookmarks.d.mts +2 -0
- package/dist/unwraps/yahooBookmarks.mjs +38 -0
- package/dist/unwraps/yahooJapan.mjs +2 -3
- package/dist/unwraps/yahooJapanAmpViewer.mjs +2 -2
- package/dist/unwraps/yahooMailImage.mjs +2 -1
- package/dist/unwraps/yahooSearch.mjs +2 -2
- package/dist/unwraps/yamm.mjs +2 -1
- package/dist/unwraps/yandexMail.mjs +4 -3
- package/dist/unwraps/yandexTranslate.mjs +1 -1
- package/dist/unwraps/yandexTurbo.mjs +4 -4
- package/dist/unwraps/yesware.mjs +2 -2
- package/dist/unwraps/yourMembership.mjs +2 -1
- package/dist/unwraps/zencastr.mjs +1 -1
- package/dist/unwraps/zix.mjs +1 -1
- package/dist/unwraps/zscalerIsolation.mjs +1 -1
- package/dist/utils.mjs +9 -42
- package/package.json +4 -4
- package/dist/node_modules/entities/dist/internal/bin-trie-flags.mjs +0 -50
- package/dist/node_modules/entities/dist/internal/decode-shared.mjs +0 -143
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isNullish } from "./is.mjs";
|
|
2
|
-
import {
|
|
1
|
+
import { isFunction, isNullish, isString } from "./is.mjs";
|
|
2
|
+
import { isAnyOf, toPatternList } from "./matching.mjs";
|
|
3
3
|
import { decodeHTMLStrict } from "../../entities/dist/decode.mjs";
|
|
4
4
|
// node_modules/trousse/dist/urls.js
|
|
5
5
|
const httpSchemes = ["http:", "https:"];
|
|
@@ -11,6 +11,9 @@ const parseUrl = (value, base) => {
|
|
|
11
11
|
return new URL(value, base);
|
|
12
12
|
} catch {}
|
|
13
13
|
};
|
|
14
|
+
const getPathSegments = (value) => {
|
|
15
|
+
return parseUrl(value)?.pathname.split("/").filter(Boolean) ?? [];
|
|
16
|
+
};
|
|
14
17
|
const getHostname = (url) => {
|
|
15
18
|
const hostname = parseUrl(url)?.hostname;
|
|
16
19
|
if (!hostname) return;
|
|
@@ -19,19 +22,48 @@ const getHostname = (url) => {
|
|
|
19
22
|
const nonAsciiRegex = /[\u0080-\uffff]/;
|
|
20
23
|
const normalizeDomain = (domain) => {
|
|
21
24
|
const trimmed = domain.trim();
|
|
22
|
-
const bare = trimmed.endsWith(".") ? trimmed.slice(0, -1) : trimmed;
|
|
25
|
+
const bare = trimmed.endsWith(".") ? trimmed.slice(0, -1).trimEnd() : trimmed;
|
|
23
26
|
if (!nonAsciiRegex.test(bare)) return bare;
|
|
24
27
|
return parseUrl(`http://${bare}`)?.hostname ?? bare;
|
|
25
28
|
};
|
|
29
|
+
const getParentDomains = (hostname) => {
|
|
30
|
+
const parents = [];
|
|
31
|
+
for (let index = hostname.indexOf("."); index !== -1; index = hostname.indexOf(".", index + 1)) parents.push(hostname.slice(index + 1));
|
|
32
|
+
return parents;
|
|
33
|
+
};
|
|
34
|
+
const keepValue = (value) => value;
|
|
35
|
+
const endsWithDomain = (lowerHostname, domain) => {
|
|
36
|
+
const lowerDomain = domain.toLowerCase();
|
|
37
|
+
if (lowerHostname.at(-lowerDomain.length - 1) !== ".") return false;
|
|
38
|
+
return !lowerDomain || isAnyOf(lowerHostname.slice(-lowerDomain.length), lowerDomain, keepValue);
|
|
39
|
+
};
|
|
26
40
|
const isHostOf = (url, hosts) => {
|
|
27
41
|
const hostname = getHostname(url);
|
|
28
42
|
if (!hostname) return false;
|
|
29
|
-
|
|
43
|
+
const lowerHostname = hostname.toLowerCase();
|
|
44
|
+
for (const host of toPatternList(hosts)) {
|
|
45
|
+
if (host instanceof RegExp) {
|
|
46
|
+
if (isAnyOf(hostname, host)) return true;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (isAnyOf(lowerHostname, normalizeDomain(host).toLowerCase(), keepValue)) return true;
|
|
50
|
+
}
|
|
51
|
+
return false;
|
|
30
52
|
};
|
|
31
53
|
const isSubdomainOf = (url, domains) => {
|
|
32
54
|
const hostname = getHostname(url);
|
|
33
55
|
if (!hostname) return false;
|
|
34
|
-
|
|
56
|
+
const lowerHostname = hostname.toLowerCase();
|
|
57
|
+
const patterns = [];
|
|
58
|
+
for (const domain of toPatternList(domains)) {
|
|
59
|
+
if (domain instanceof RegExp) {
|
|
60
|
+
patterns.push(domain);
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (endsWithDomain(lowerHostname, normalizeDomain(domain))) return true;
|
|
64
|
+
}
|
|
65
|
+
if (patterns.length === 0) return false;
|
|
66
|
+
return getParentDomains(hostname).some((parent) => isAnyOf(parent, patterns));
|
|
35
67
|
};
|
|
36
68
|
const isHttpUrl = (url) => {
|
|
37
69
|
const scheme = parseUrl(url)?.protocol;
|
|
@@ -44,10 +76,16 @@ const isHostOrSubdomainOf = (url, domains) => {
|
|
|
44
76
|
const getSubdomain = (url, domains) => {
|
|
45
77
|
const hostname = getHostname(url)?.toLowerCase();
|
|
46
78
|
if (!hostname) return;
|
|
47
|
-
|
|
48
|
-
for (const domain of
|
|
49
|
-
|
|
50
|
-
|
|
79
|
+
let parents;
|
|
80
|
+
for (const domain of toPatternList(domains)) {
|
|
81
|
+
if (isString(domain)) {
|
|
82
|
+
const name = normalizeDomain(domain);
|
|
83
|
+
if (name && endsWithDomain(hostname, name)) return hostname.slice(0, -name.length - 1);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (!parents) parents = getParentDomains(hostname);
|
|
87
|
+
const parent = parents.find((candidate) => isAnyOf(candidate, domain));
|
|
88
|
+
if (parent) return hostname.slice(0, -parent.length - 1);
|
|
51
89
|
}
|
|
52
90
|
};
|
|
53
91
|
const escapeRunRegex = /(?:%[0-9A-Fa-f]{2})+/g;
|
|
@@ -81,6 +119,43 @@ const decodeEscapeRun = (run) => {
|
|
|
81
119
|
const decodePercent = (value) => {
|
|
82
120
|
return value.replace(escapeRunRegex, decodeEscapeRun);
|
|
83
121
|
};
|
|
122
|
+
const decodeBase64Binary = (value) => {
|
|
123
|
+
try {
|
|
124
|
+
return atob(value);
|
|
125
|
+
} catch {}
|
|
126
|
+
};
|
|
127
|
+
const utf8Decoder = /* @__PURE__ */ new TextDecoder("utf-8", { fatal: true });
|
|
128
|
+
const isUtf8Binary = (binary) => {
|
|
129
|
+
try {
|
|
130
|
+
utf8Decoder.decode(Uint8Array.from(binary, (char) => char.charCodeAt(0)));
|
|
131
|
+
return true;
|
|
132
|
+
} catch {
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
const decodeBase64 = (value) => {
|
|
137
|
+
const binary = decodeBase64Binary(value);
|
|
138
|
+
if (binary === void 0) return;
|
|
139
|
+
let encoded = "";
|
|
140
|
+
for (let index = 0; index < binary.length; index++) {
|
|
141
|
+
const byte = binary.charCodeAt(index);
|
|
142
|
+
if (byte < 128 && binary[index] !== "%") {
|
|
143
|
+
encoded += binary[index];
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
encoded += `%${byte.toString(16).toUpperCase().padStart(2, "0")}`;
|
|
147
|
+
}
|
|
148
|
+
return decodePercent(encoded);
|
|
149
|
+
};
|
|
150
|
+
const toBase64 = (base64Url) => {
|
|
151
|
+
return base64Url.replaceAll("-", "+").replaceAll("_", "/");
|
|
152
|
+
};
|
|
153
|
+
const decodeBase64Url = (value) => {
|
|
154
|
+
return decodeBase64(toBase64(value));
|
|
155
|
+
};
|
|
156
|
+
const decodeBase64UrlBinary = (value) => {
|
|
157
|
+
return decodeBase64Binary(toBase64(value));
|
|
158
|
+
};
|
|
84
159
|
const readRawPairs = (text, prefix) => {
|
|
85
160
|
if (text === void 0) return;
|
|
86
161
|
const pairs = [];
|
|
@@ -100,7 +175,7 @@ const readRawPairs = (text, prefix) => {
|
|
|
100
175
|
const readQuerySource = (source, options) => {
|
|
101
176
|
if (options?.decodeValues === false) return readRawPairs(source instanceof URL ? source.search : source?.toString(), "?");
|
|
102
177
|
if (source instanceof URL) return source.searchParams;
|
|
103
|
-
if (
|
|
178
|
+
if (isString(source)) return new URLSearchParams(source);
|
|
104
179
|
return source;
|
|
105
180
|
};
|
|
106
181
|
const readParamValues = (params, name, options) => {
|
|
@@ -142,6 +217,7 @@ const ipv4Regex = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
|
|
|
142
217
|
const ipv6Regex = /^([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}$/i;
|
|
143
218
|
const wwwPrefixRegex = /^(?:www\.)+(?=.*\.)/;
|
|
144
219
|
const ipv6BracketsRegex = /^\[|\]$/g;
|
|
220
|
+
const hostnameLabelRegex = /^[a-z0-9_-]+$/i;
|
|
145
221
|
const unreservedCharsRegex = /[a-zA-Z0-9._~-]/;
|
|
146
222
|
const httpsLetterRegex = /s/i;
|
|
147
223
|
const schemePrefixRegex = /^https?:\/\//;
|
|
@@ -166,12 +242,13 @@ const validUrlRegex = /^https?:\/\/(?:www\.|[a-vx-z0-9])/i;
|
|
|
166
242
|
const schemeSeparator = String.raw`\.*[:\s=\\/][:\s=.\\/]*`;
|
|
167
243
|
const separatorChar = String.raw`(?:[:\s=.\\/]|%20|%c2%a0)`;
|
|
168
244
|
const leadingSchemeSeparator = String.raw`\.*(?::${separatorChar}*|[\s=\\/]${separatorChar}+)`;
|
|
169
|
-
const doubledSchemeRegex = /* @__PURE__ */ new RegExp(String.raw`^\/?[htps]{2,7}${leadingSchemeSeparator}([htps]{2,7})(?!:\d|[^/?#\\]*@)(${schemeSeparator})
|
|
170
|
-
const singleMalformedRegex = /* @__PURE__ */ new RegExp(String.raw`^\/?(h[htps():]{1,10}|t{1,2}ps?)(${leadingSchemeSeparator})
|
|
245
|
+
const doubledSchemeRegex = /* @__PURE__ */ new RegExp(String.raw`^\/?[htps]{2,7}${leadingSchemeSeparator}([htps]{2,7})(?!:\d|[^/?#\\]*@)(${schemeSeparator})(www[./]+)?`, "i");
|
|
246
|
+
const singleMalformedRegex = /* @__PURE__ */ new RegExp(String.raw`^\/?(h[htps():]{1,10}|t{1,2}ps?)(${leadingSchemeSeparator})(www[./]+)?`, "i");
|
|
171
247
|
const isSchemeToken = (token, separator) => {
|
|
172
248
|
const lowered = token.toLowerCase();
|
|
173
249
|
return `${token}${separator}`.includes(":") || lowered.includes("t") && lowered.includes("p");
|
|
174
250
|
};
|
|
251
|
+
const brokenSlashEscapeRegex = /^[^/]*\/[,.]/;
|
|
175
252
|
const fixMalformedScheme = (url) => {
|
|
176
253
|
if (validUrlRegex.test(url) && !doubledSchemeRegex.test(url)) return url;
|
|
177
254
|
const doubledMatch = doubledSchemeRegex.exec(url);
|
|
@@ -179,6 +256,7 @@ const fixMalformedScheme = (url) => {
|
|
|
179
256
|
const inner = doubledMatch[1];
|
|
180
257
|
const www = doubledMatch[3];
|
|
181
258
|
const rest = url.slice(doubledMatch[0].length);
|
|
259
|
+
if (brokenSlashEscapeRegex.test(`${doubledMatch[2]}${rest}`)) return url;
|
|
182
260
|
return `${httpsLetterRegex.test(inner) ? "https://" : "http://"}${www ? "www." : ""}${rest}`;
|
|
183
261
|
}
|
|
184
262
|
const singleMatch = singleMalformedRegex.exec(url);
|
|
@@ -186,10 +264,32 @@ const fixMalformedScheme = (url) => {
|
|
|
186
264
|
const fullMatch = singleMatch[0];
|
|
187
265
|
const www = singleMatch[3];
|
|
188
266
|
const rest = url.slice(fullMatch.length);
|
|
267
|
+
if (brokenSlashEscapeRegex.test(`${singleMatch[2]}${rest}`)) return url;
|
|
189
268
|
return `${httpsLetterRegex.test(fullMatch) ? "https://" : "http://"}${www ? "www." : ""}${rest}`;
|
|
190
269
|
}
|
|
191
270
|
return url;
|
|
192
271
|
};
|
|
272
|
+
const authorityRegex = /^(?:[a-z][a-z\d+.-]*:)?\/\/[^/?#\\]*/i;
|
|
273
|
+
const doubledDotRegex = /(?<!\.)\.\.(?!\.)/g;
|
|
274
|
+
const trailingHostJunkChars = [
|
|
275
|
+
")",
|
|
276
|
+
",",
|
|
277
|
+
"'",
|
|
278
|
+
"&"
|
|
279
|
+
];
|
|
280
|
+
const fixMalformedHost = (url) => {
|
|
281
|
+
const authority = authorityRegex.exec(url)?.[0];
|
|
282
|
+
if (!authority) return url;
|
|
283
|
+
const hostStart = Math.max(authority.indexOf("//") + 2, authority.lastIndexOf("@") + 1);
|
|
284
|
+
const host = authority.slice(hostStart);
|
|
285
|
+
let hostEnd = host.length;
|
|
286
|
+
while (hostEnd > 0 && trailingHostJunkChars.includes(host.charAt(hostEnd - 1))) hostEnd--;
|
|
287
|
+
let fixedHost = host.slice(0, hostEnd).replace(doubledDotRegex, ".");
|
|
288
|
+
if (fixedHost.startsWith(".") && !fixedHost.startsWith("..")) fixedHost = fixedHost.slice(1);
|
|
289
|
+
if (fixedHost.endsWith(".")) return url;
|
|
290
|
+
if (!fixedHost || fixedHost.startsWith(",")) return url;
|
|
291
|
+
return `${url.slice(0, hostStart)}${fixedHost}${url.slice(authority.length)}`;
|
|
292
|
+
};
|
|
193
293
|
const segmentEdgeSpace = "(?:\\s|%(?:09|0A|0D|20))";
|
|
194
294
|
const valueEdgeSpace = "(?:\\s|\\+|%(?:09|0A|0D|20))";
|
|
195
295
|
new RegExp(`^${segmentEdgeSpace}+|(?<!${segmentEdgeSpace})${segmentEdgeSpace}+$`, "gi");
|
|
@@ -248,6 +348,7 @@ const resolveUrl = (url, base) => {
|
|
|
248
348
|
resolvedUrl = trimmedUrl.includes("&") ? decodeHTMLStrict(trimmedUrl) : trimmedUrl;
|
|
249
349
|
resolvedUrl = resolveFeedScheme(resolvedUrl);
|
|
250
350
|
if (!base || schemeColonRegex.test(resolvedUrl) || missingColonSchemeRegex.test(resolvedUrl)) resolvedUrl = fixMalformedScheme(resolvedUrl);
|
|
351
|
+
resolvedUrl = fixMalformedHost(resolvedUrl);
|
|
251
352
|
if (base) {
|
|
252
353
|
const resolved = parseUrl(resolvedUrl, base) ?? parseUrl(resolvedUrl);
|
|
253
354
|
if (!resolved) return;
|
|
@@ -259,23 +360,43 @@ const resolveUrl = (url, base) => {
|
|
|
259
360
|
if (!parsed || !isHttpUrl(parsed)) return;
|
|
260
361
|
return parsed.href;
|
|
261
362
|
};
|
|
363
|
+
const valueShapeEscapeRegex = /(%(?:26|23|25|2B|3B))/gi;
|
|
364
|
+
const nameShapeEscapeRegex = /(%(?:26|23|25|2B|3B|3D))/gi;
|
|
365
|
+
const decodeQueryPart = (part, shapeRegex) => {
|
|
366
|
+
return part.replace(plusRegex, "%20").split(shapeRegex).map((chunk, index) => index % 2 ? chunk.toUpperCase() : decodePercent(chunk)).join("");
|
|
367
|
+
};
|
|
368
|
+
const canonicalizeQuery = (search) => {
|
|
369
|
+
return `?${search.slice(1).split("&").map((pair) => {
|
|
370
|
+
const at = pair.indexOf("=");
|
|
371
|
+
if (at === -1) return decodeQueryPart(pair, nameShapeEscapeRegex);
|
|
372
|
+
return `${decodeQueryPart(pair.slice(0, at), nameShapeEscapeRegex)}=${decodeQueryPart(pair.slice(at + 1), valueShapeEscapeRegex)}`;
|
|
373
|
+
}).join("&")}`;
|
|
374
|
+
};
|
|
262
375
|
const decodeAndNormalizeEncoding = (value) => {
|
|
263
376
|
if (!value.includes("%")) return value;
|
|
264
|
-
return value.replace(
|
|
265
|
-
const charCode = Number.parseInt(hex, 16);
|
|
377
|
+
return value.replace(percentEscapeRegex, (hex) => {
|
|
378
|
+
const charCode = Number.parseInt(hex.slice(1), 16);
|
|
266
379
|
const char = String.fromCharCode(charCode);
|
|
267
380
|
if (unreservedCharsRegex.test(char)) return char;
|
|
268
|
-
return
|
|
381
|
+
return hex.toUpperCase();
|
|
269
382
|
});
|
|
270
383
|
};
|
|
271
|
-
const
|
|
272
|
-
const
|
|
384
|
+
const decodeQueryComponent = (component) => {
|
|
385
|
+
const spaced = component.replace(plusRegex, " ");
|
|
273
386
|
try {
|
|
274
|
-
return decodeURIComponent(
|
|
387
|
+
return decodeURIComponent(spaced);
|
|
275
388
|
} catch {
|
|
276
|
-
return
|
|
389
|
+
return spaced;
|
|
277
390
|
}
|
|
278
391
|
};
|
|
392
|
+
const decodeQueryKey = (pair) => {
|
|
393
|
+
return decodeQueryComponent(pair.split("=")[0]);
|
|
394
|
+
};
|
|
395
|
+
const decodeQueryValue = (pair) => {
|
|
396
|
+
const separatorIndex = pair.indexOf("=");
|
|
397
|
+
if (separatorIndex === -1) return;
|
|
398
|
+
return decodeQueryComponent(pair.slice(separatorIndex + 1));
|
|
399
|
+
};
|
|
279
400
|
const compareQueryPairs = (a, b) => {
|
|
280
401
|
const keyA = decodeQueryKey(a);
|
|
281
402
|
const keyB = decodeQueryKey(b);
|
|
@@ -289,41 +410,46 @@ const lowercaseQueryPair = (pair) => {
|
|
|
289
410
|
});
|
|
290
411
|
};
|
|
291
412
|
const normalizeUrl = (url, options) => {
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
413
|
+
const parsed = parseUrl(options.normalizeUnicode ? url.normalize("NFC") : url);
|
|
414
|
+
if (!parsed) return url;
|
|
415
|
+
if (options.stripHostTrailingDot && parsed.hostname.endsWith(".")) parsed.hostname = parsed.hostname.slice(0, -1);
|
|
416
|
+
if (options.stripAuthentication) {
|
|
417
|
+
parsed.username = "";
|
|
418
|
+
parsed.password = "";
|
|
419
|
+
}
|
|
420
|
+
if (options.stripWww) parsed.hostname = stripWww(parsed.hostname);
|
|
421
|
+
if (options.stripHash) parsed.hash = "";
|
|
422
|
+
let pathname = parsed.pathname;
|
|
423
|
+
if (options.normalizeEncoding) pathname = decodeAndNormalizeEncoding(pathname);
|
|
424
|
+
if (options.collapseSlashes) pathname = pathname.replace(repeatedSlashesRegex, "/");
|
|
425
|
+
if (options.stripTrailingSlash && pathname.length > 1 && pathname.endsWith("/")) pathname = pathname.slice(0, -1);
|
|
426
|
+
parsed.pathname = pathname;
|
|
427
|
+
if (options.normalizeEncoding && parsed.search.length > 1) {
|
|
428
|
+
parsed.search = canonicalizeQuery(parsed.search);
|
|
429
|
+
parsed.search = parsed.search.replace(percentEscapeRegex, (hex) => hex.toUpperCase());
|
|
430
|
+
}
|
|
431
|
+
if (options.normalizeEncoding && parsed.hash.includes("%")) parsed.hash = decodeAndNormalizeEncoding(parsed.hash);
|
|
432
|
+
if (options.stripQuery) parsed.search = "";
|
|
433
|
+
if (parsed.search && (options.stripQueryParams || options.lowercaseQuery)) {
|
|
434
|
+
let pairs = parsed.search.slice(1).split("&");
|
|
435
|
+
if (isFunction(options.stripQueryParams)) {
|
|
436
|
+
const isStripped = options.stripQueryParams;
|
|
437
|
+
pairs = pairs.filter((pair) => {
|
|
438
|
+
return pair && !isStripped(decodeQueryKey(pair), decodeQueryValue(pair), parsed);
|
|
439
|
+
});
|
|
440
|
+
} else if (options.stripQueryParams) {
|
|
441
|
+
const strippedSet = getStrippedParamsSet(options.stripQueryParams);
|
|
442
|
+
pairs = pairs.filter((pair) => pair && !strippedSet.has(decodeQueryKey(pair).toLowerCase()));
|
|
317
443
|
}
|
|
318
|
-
if (options.
|
|
319
|
-
|
|
320
|
-
let result = parsed.href;
|
|
321
|
-
if (options.stripRootSlash && result === `${parsed.origin}/`) result = parsed.origin;
|
|
322
|
-
if (options.stripScheme ?? options.stripProtocol) result = result.replace(schemePrefixRegex, "");
|
|
323
|
-
return result;
|
|
324
|
-
} catch {
|
|
325
|
-
return url;
|
|
444
|
+
if (options.lowercaseQuery) pairs = pairs.map(lowercaseQueryPair);
|
|
445
|
+
parsed.search = pairs.join("&");
|
|
326
446
|
}
|
|
447
|
+
if (options.sortQueryParams && parsed.search.includes("&")) parsed.search = parsed.search.slice(1).split("&").filter(Boolean).sort(compareQueryPairs).join("&");
|
|
448
|
+
if (options.stripEmptyQuery && !parsed.search) parsed.search = "";
|
|
449
|
+
let result = parsed.href;
|
|
450
|
+
if (options.stripRootSlash && result === `${parsed.origin}/`) result = parsed.origin;
|
|
451
|
+
if (options.stripScheme ?? options.stripProtocol) result = result.replace(schemePrefixRegex, "");
|
|
452
|
+
return result;
|
|
327
453
|
};
|
|
328
454
|
const stripWww = (hostname) => {
|
|
329
455
|
return hostname.replace(wwwPrefixRegex, "");
|
|
@@ -331,4 +457,11 @@ const stripWww = (hostname) => {
|
|
|
331
457
|
const isIpAddress = (hostname) => {
|
|
332
458
|
return ipv4Regex.test(hostname) || ipv6Regex.test(hostname.replace(ipv6BracketsRegex, ""));
|
|
333
459
|
};
|
|
334
|
-
|
|
460
|
+
const isHostname = (host) => {
|
|
461
|
+
if (isIpAddress(host)) return true;
|
|
462
|
+
return (host.endsWith(".") ? host.slice(0, -1) : host).split(".").every((label) => {
|
|
463
|
+
return label.length <= 63 && hostnameLabelRegex.test(label);
|
|
464
|
+
});
|
|
465
|
+
};
|
|
466
|
+
const percentEscapeRegex = /%[0-9a-f]{2}/gi;
|
|
467
|
+
export { addMissingScheme, decodeBase64, decodeBase64Binary, decodeBase64Url, decodeBase64UrlBinary, decodePercent, fixMalformedHost, fixMalformedScheme, getPathSegments, getQueryParam, getQueryParamValues, getSubdomain, hasQueryParam, isHostOf, isHostOrSubdomainOf, isHostname, isHttpUrl, isIpAddress, isSubdomainOf, isUtf8Binary, normalizeUrl, parseUrl, resolveFeedScheme, resolveUrl, stripWww };
|
package/dist/pathTarget.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// src/pathTarget.ts
|
|
2
2
|
const leadingSlashesRegex = /^\/+/;
|
|
3
3
|
const schemeRegex = /^https?:/i;
|
|
4
|
-
const getPathTarget = (url, prefixRegex, scheme = "https:") => {
|
|
4
|
+
const getPathTarget = (url, prefixRegex, scheme = "https:", suffix = `${url.search}${url.hash}`) => {
|
|
5
5
|
const match = url.pathname.match(prefixRegex);
|
|
6
6
|
if (!match) return;
|
|
7
7
|
const path = url.pathname.slice(match[0].length).replace(leadingSlashesRegex, "");
|
|
8
8
|
if (!path) return;
|
|
9
|
-
const target = `${path}${
|
|
9
|
+
const target = `${path}${suffix}`;
|
|
10
10
|
if (schemeRegex.test(target)) return target;
|
|
11
11
|
return `${scheme}//${target}`;
|
|
12
12
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// src/tracking/clickAttribution.ts
|
|
2
|
+
const everyNameRegex = /^/;
|
|
2
3
|
const clickAttributionParams = [
|
|
3
4
|
"gclid",
|
|
4
5
|
"dclid",
|
|
@@ -47,6 +48,30 @@ const clickAttributionParams = [
|
|
|
47
48
|
"spm",
|
|
48
49
|
"trk",
|
|
49
50
|
"wickedid",
|
|
50
|
-
/^hsa_[a-z0-9_]
|
|
51
|
+
/^hsa_[a-z0-9_]+$/,
|
|
52
|
+
{
|
|
53
|
+
name: /^(?!(?:modal_id|vid)$)/,
|
|
54
|
+
hosts: /(?:^|\.)(?:douyin|iesdouyin)\.com$/
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: everyNameRegex,
|
|
58
|
+
hosts: /(?:^|\.)(?:kuaishou\.com|m\.chenzhongtech\.com)$|^m\.gifshow\.com$/
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: everyNameRegex,
|
|
62
|
+
hosts: ["post.smzdm.com", "smzdm.com"]
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: /^(?!(?:id|shopid|skuids|suitid|wareid)$)/,
|
|
66
|
+
hosts: ["item.jd.com", "item.m.jd.com"]
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: /^(?!id$)/,
|
|
70
|
+
hosts: ["y.music.163.com"]
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: /^(?!xsec_token$)/,
|
|
74
|
+
hosts: /(?:^|\.)xiaohongshu\.com$/
|
|
75
|
+
}
|
|
51
76
|
];
|
|
52
77
|
export { clickAttributionParams };
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
+
import { parseUrl, stripWww } from "../node_modules/trousse/dist/urls.mjs";
|
|
1
2
|
// src/tracking/housekeeping.ts
|
|
3
|
+
const refDelimitersRegex = /[\s/?#\\:@]/;
|
|
4
|
+
const isSelfReferral = (value, host) => {
|
|
5
|
+
if (refDelimitersRegex.test(value)) return false;
|
|
6
|
+
const refUrl = parseUrl(`http://${value}`);
|
|
7
|
+
if (!refUrl) return false;
|
|
8
|
+
return stripWww(refUrl.hostname) === host;
|
|
9
|
+
};
|
|
2
10
|
const housekeepingParams = [
|
|
3
11
|
"usqp",
|
|
4
12
|
"guccounter",
|
|
@@ -24,6 +32,10 @@ const housekeepingParams = [
|
|
|
24
32
|
"rebuildcache",
|
|
25
33
|
"kontrol_health_check_timestamp",
|
|
26
34
|
"at_preview_index",
|
|
27
|
-
"__readwiseLocation"
|
|
35
|
+
"__readwiseLocation",
|
|
36
|
+
{
|
|
37
|
+
name: "ref",
|
|
38
|
+
value: isSelfReferral
|
|
39
|
+
}
|
|
28
40
|
];
|
|
29
41
|
export { housekeepingParams };
|
package/dist/types.d.mts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
export type UrlUnwrapper = (url: URL) => string | undefined;
|
|
2
|
-
export type
|
|
2
|
+
export type TrackingValueTest = (value: string, host: string) => boolean;
|
|
3
|
+
export type TrackingEntry = {
|
|
4
|
+
name: string | RegExp;
|
|
5
|
+
value?: RegExp | TrackingValueTest;
|
|
6
|
+
hosts?: Array<string> | RegExp;
|
|
7
|
+
};
|
|
8
|
+
export type TrackingParam = string | RegExp | TrackingEntry;
|
|
3
9
|
export type CleanUrlOptions = {
|
|
4
10
|
unwrappers?: Array<UrlUnwrapper>;
|
|
5
11
|
trackingParams?: Array<TrackingParam>;
|
package/dist/unwraps/a8Net.mjs
CHANGED
|
@@ -14,7 +14,7 @@ const extractDeeplinkTarget = createParamExtractor({
|
|
|
14
14
|
hosts: "ow.a8.net",
|
|
15
15
|
params: ["url"]
|
|
16
16
|
});
|
|
17
|
-
const deeplinkPathRegex = /^\/s\d+\/redirect_v2\.php
|
|
17
|
+
const deeplinkPathRegex = /^\/s\d+\/redirect_v2\.php$/i;
|
|
18
18
|
const unwrapA8Net = (url) => {
|
|
19
19
|
if (deeplinkPathRegex.test(url.pathname)) return extractDeeplinkTarget(url);
|
|
20
20
|
return extractRedirectTarget(url);
|
package/dist/unwraps/acast.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isHostOf } from "../node_modules/trousse/dist/urls.mjs";
|
|
2
2
|
import { getPathTarget } from "../pathTarget.mjs";
|
|
3
3
|
// src/unwraps/acast.ts
|
|
4
|
-
const flexPrefixRegex = /^\/s\/[^/]+\/u
|
|
4
|
+
const flexPrefixRegex = /^\/s\/[^/]+\/u\//i;
|
|
5
5
|
const unwrapAcast = (url) => {
|
|
6
6
|
if (!isHostOf(url, "flex2.acast.com")) return;
|
|
7
7
|
return getPathTarget(url, flexPrefixRegex, url.protocol);
|
|
@@ -9,7 +9,7 @@ const hosts = [
|
|
|
9
9
|
"pub.accesstrade.vn",
|
|
10
10
|
"click.accesstrade.in.th"
|
|
11
11
|
];
|
|
12
|
-
const pathRegex = /^\/(?:sp\/cc|at\/c\.html|adv\.php|deep_link\/\d+(?:\/\d+)?)
|
|
12
|
+
const pathRegex = /^\/(?:sp\/cc|at\/c\.html|adv\.php|deep_link\/\d+(?:\/\d+)?)$/i;
|
|
13
13
|
const unwrapAccesstrade = (url) => {
|
|
14
14
|
if (!isHostOf(url, hosts) || !pathRegex.test(url.pathname)) return;
|
|
15
15
|
return getParamTarget(url, "url");
|
package/dist/unwraps/aceml.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { decodePercent, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
|
|
2
|
-
import { createParamExtractor
|
|
1
|
+
import { decodeBase64, decodePercent, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
|
|
2
|
+
import { createParamExtractor } from "../utils.mjs";
|
|
3
3
|
// src/unwraps/aceml.ts
|
|
4
4
|
const encodedSchemeRegex = /^https?%3A/i;
|
|
5
5
|
const baseExtractor = createParamExtractor({
|
package/dist/unwraps/adcell.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createParamExtractor } from "../utils.mjs";
|
|
2
2
|
// src/unwraps/adcell.ts
|
|
3
|
-
const clickPathRegex = /^\/(?:p\/click|click\.php|promotion\/click\/promoId\/\d+\/slotId\/\d+)
|
|
3
|
+
const clickPathRegex = /^\/(?:p\/click|click\.php|promotion\/click\/promoId\/\d+\/slotId\/\d+)$/i;
|
|
4
4
|
const extractTarget = createParamExtractor({
|
|
5
5
|
hosts: ["t.adcell.com", "www.adcell.de"],
|
|
6
6
|
params: ["param0"]
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { isAnyOf } from "../node_modules/trousse/dist/matching.mjs";
|
|
2
|
+
import { isHostOf } from "../node_modules/trousse/dist/urls.mjs";
|
|
3
|
+
import { getParamTarget } from "../utils.mjs";
|
|
4
|
+
// src/unwraps/addThis.ts
|
|
5
|
+
const bookmarkHosts = ["www.addthis.com"];
|
|
6
|
+
const apiHosts = ["api.addthis.com"];
|
|
7
|
+
const offerPathRegex = /^\/oexchange\/0\.8\/(?:forward\/[^/]+\/)?offer$/i;
|
|
8
|
+
const isCarrierPath = (url) => {
|
|
9
|
+
if (isHostOf(url, bookmarkHosts)) return isAnyOf(url.pathname, "/bookmark.php");
|
|
10
|
+
if (isHostOf(url, apiHosts)) return offerPathRegex.test(url.pathname);
|
|
11
|
+
return false;
|
|
12
|
+
};
|
|
13
|
+
const unwrapAddThis = (url) => {
|
|
14
|
+
if (!isCarrierPath(url)) return;
|
|
15
|
+
return getParamTarget(url, "url");
|
|
16
|
+
};
|
|
17
|
+
export { unwrapAddThis };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { isAnyOf } from "../node_modules/trousse/dist/matching.mjs";
|
|
2
|
+
import { isHostOf, isHttpUrl, parseUrl } from "../node_modules/trousse/dist/urls.mjs";
|
|
3
|
+
import { getParamTarget } from "../utils.mjs";
|
|
4
|
+
// src/unwraps/addToAny.ts
|
|
5
|
+
const hosts = ["www.addtoany.com", "addtoany.com"];
|
|
6
|
+
const servicePathRegex = /^\/add_to\/[^/]+$/i;
|
|
7
|
+
const menuPaths = ["/share", "/share_save"];
|
|
8
|
+
const getMenuTarget = (url) => {
|
|
9
|
+
const target = getParamTarget(url, "linkurl");
|
|
10
|
+
if (target) return target;
|
|
11
|
+
const fragment = parseUrl(`?${url.hash.slice(1)}`, url);
|
|
12
|
+
return fragment && getParamTarget(fragment, "url");
|
|
13
|
+
};
|
|
14
|
+
const unwrapAddToAny = (url) => {
|
|
15
|
+
if (!isHostOf(url, hosts)) return;
|
|
16
|
+
let target;
|
|
17
|
+
if (servicePathRegex.test(url.pathname) || isAnyOf(url.pathname, "/email")) target = getParamTarget(url, "linkurl");
|
|
18
|
+
else if (isAnyOf(url.pathname, menuPaths)) target = getMenuTarget(url);
|
|
19
|
+
if (target && isHttpUrl(target)) return target;
|
|
20
|
+
};
|
|
21
|
+
export { unwrapAddToAny };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createParamExtractor } from "../utils.mjs";
|
|
2
|
+
// src/unwraps/addToAnySubscribe.ts
|
|
3
|
+
const unwrapAddToAnySubscribe = createParamExtractor({
|
|
4
|
+
hosts: ["addtoany.com", "www.addtoany.com"],
|
|
5
|
+
path: "/subscribe",
|
|
6
|
+
params: ["linkurl", "url"]
|
|
7
|
+
});
|
|
8
|
+
export { unwrapAddToAnySubscribe };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { isAnyOf } from "../node_modules/trousse/dist/matching.mjs";
|
|
2
|
+
import { isHostOf } from "../node_modules/trousse/dist/urls.mjs";
|
|
3
|
+
import { createParamExtractor, getParamTarget } from "../utils.mjs";
|
|
4
|
+
// src/unwraps/addToMyYahoo.ts
|
|
5
|
+
const hosts = ["add.my.yahoo.com", "add.my.yahoo.co.jp"];
|
|
6
|
+
const usRedirectPathRegex = /^\/my\/[^*]*\*https?:\/\/add\.my\.yahoo\.(?:com\/(?:rss|content)|co\.jp\/rss)$/i;
|
|
7
|
+
const jpRedirectPathRegex = /^\/myyahoo\/[^*]*\*https?:\/\/add\.my\.yahoo\.(?:com\/(?:rss|content)|co\.jp\/rss)$/i;
|
|
8
|
+
const unwrapRss = createParamExtractor({
|
|
9
|
+
hosts,
|
|
10
|
+
path: "/rss",
|
|
11
|
+
params: ["url"]
|
|
12
|
+
});
|
|
13
|
+
const unwrapContent = createParamExtractor({
|
|
14
|
+
hosts: "add.my.yahoo.com",
|
|
15
|
+
path: "/content",
|
|
16
|
+
params: ["url"]
|
|
17
|
+
});
|
|
18
|
+
const unwrapAddToMyYahoo = (url) => {
|
|
19
|
+
if (isHostOf(url, "us.rd.yahoo.com")) {
|
|
20
|
+
if (!isAnyOf(url.pathname, usRedirectPathRegex)) return;
|
|
21
|
+
return getParamTarget(url, "url");
|
|
22
|
+
}
|
|
23
|
+
if (isHostOf(url, "rd.yahoo.co.jp")) {
|
|
24
|
+
if (!isAnyOf(url.pathname, jpRedirectPathRegex)) return;
|
|
25
|
+
return getParamTarget(url, "url");
|
|
26
|
+
}
|
|
27
|
+
return unwrapRss(url) ?? unwrapContent(url);
|
|
28
|
+
};
|
|
29
|
+
export { unwrapAddToMyYahoo };
|
package/dist/unwraps/adfly.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isHostOf, isHttpUrl } from "../node_modules/trousse/dist/urls.mjs";
|
|
2
2
|
// src/unwraps/adfly.ts
|
|
3
|
-
const pathRegex = /^\/\d+\/(?:banner\/|int\/)?(.+)
|
|
3
|
+
const pathRegex = /^\/\d+\/(?:banner\/|int\/)?(.+)$/i;
|
|
4
4
|
const schemeRegex = /^https?:/i;
|
|
5
5
|
const hostRegex = /^[\da-z-]+(?:\.[\da-z-]+)+(?:[/:]|$)/i;
|
|
6
6
|
const unwrapAdfly = (url) => {
|
package/dist/unwraps/admitad.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createParamExtractor } from "../utils.mjs";
|
|
2
2
|
// src/unwraps/admitad.ts
|
|
3
|
-
const clickPathRegex = /^\/(?:g|goto)\/[0-9a-z]
|
|
3
|
+
const clickPathRegex = /^\/(?:g|goto)\/[0-9a-z]+\/$/i;
|
|
4
4
|
const extractTarget = createParamExtractor({
|
|
5
5
|
hosts: [
|
|
6
6
|
"ad.admitad.com",
|
package/dist/unwraps/affilae.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { isAnyOf } from "../node_modules/trousse/dist/matching.mjs";
|
|
1
2
|
import { isHostOf } from "../node_modules/trousse/dist/urls.mjs";
|
|
2
3
|
import { getParamTarget } from "../utils.mjs";
|
|
3
4
|
// src/unwraps/affilae.ts
|
|
4
5
|
const unwrapAffilae = (url) => {
|
|
5
|
-
if (!isHostOf(url, "lb.affilae.com") || url.pathname
|
|
6
|
+
if (!isHostOf(url, "lb.affilae.com") || !isAnyOf(url.pathname, "/r/")) return;
|
|
6
7
|
return getParamTarget(url, "lp", -1);
|
|
7
8
|
};
|
|
8
9
|
export { unwrapAffilae };
|