urlpurify 2.2.0 → 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 -20
- 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 +23 -13
- package/dist/node_modules/trousse/dist/urls.mjs +203 -51
- 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 +3 -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 +3 -2
- 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/cake.mjs +2 -2
- 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 +3 -3
- 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 +3 -3
- 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/drupalOembed.mjs +3 -5
- 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 +3 -2
- 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 +4 -5
- 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/finalsite.mjs +2 -2
- package/dist/unwraps/firebaseDynamicLinks.mjs +3 -2
- 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 +3 -2
- 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 +13 -13
- 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 +3 -2
- 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 +3 -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 +3 -2
- 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/okRu.mjs +3 -2
- 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/proofpointV2.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 +4 -3
- 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 +4 -4
- 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 +4 -4
- 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 +3 -2
- 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 +3 -2
- 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 +4 -3
- 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 +4 -4
- 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/worldNomads.mjs +2 -1
- 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 +3 -2
- 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;
|
|
@@ -41,6 +73,21 @@ const isHttpUrl = (url) => {
|
|
|
41
73
|
const isHostOrSubdomainOf = (url, domains) => {
|
|
42
74
|
return isHostOf(url, domains) || isSubdomainOf(url, domains);
|
|
43
75
|
};
|
|
76
|
+
const getSubdomain = (url, domains) => {
|
|
77
|
+
const hostname = getHostname(url)?.toLowerCase();
|
|
78
|
+
if (!hostname) return;
|
|
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);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
44
91
|
const escapeRunRegex = /(?:%[0-9A-Fa-f]{2})+/g;
|
|
45
92
|
const getSequenceLength = (byte) => {
|
|
46
93
|
if (byte < 128) return 1;
|
|
@@ -72,6 +119,43 @@ const decodeEscapeRun = (run) => {
|
|
|
72
119
|
const decodePercent = (value) => {
|
|
73
120
|
return value.replace(escapeRunRegex, decodeEscapeRun);
|
|
74
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
|
+
};
|
|
75
159
|
const readRawPairs = (text, prefix) => {
|
|
76
160
|
if (text === void 0) return;
|
|
77
161
|
const pairs = [];
|
|
@@ -91,7 +175,7 @@ const readRawPairs = (text, prefix) => {
|
|
|
91
175
|
const readQuerySource = (source, options) => {
|
|
92
176
|
if (options?.decodeValues === false) return readRawPairs(source instanceof URL ? source.search : source?.toString(), "?");
|
|
93
177
|
if (source instanceof URL) return source.searchParams;
|
|
94
|
-
if (
|
|
178
|
+
if (isString(source)) return new URLSearchParams(source);
|
|
95
179
|
return source;
|
|
96
180
|
};
|
|
97
181
|
const readParamValues = (params, name, options) => {
|
|
@@ -105,9 +189,21 @@ const readParamValues = (params, name, options) => {
|
|
|
105
189
|
}
|
|
106
190
|
return values;
|
|
107
191
|
};
|
|
192
|
+
const hasParam = (params, name) => {
|
|
193
|
+
if (!params) return false;
|
|
194
|
+
const lowercaseName = name.toLowerCase();
|
|
195
|
+
for (const [key] of params) if (key.toLowerCase() === lowercaseName) return true;
|
|
196
|
+
return false;
|
|
197
|
+
};
|
|
198
|
+
const hasQueryParam = (source, name) => {
|
|
199
|
+
return hasParam(readQuerySource(source), name);
|
|
200
|
+
};
|
|
108
201
|
const getQueryParamValues = (source, name, options) => {
|
|
109
202
|
return readParamValues(readQuerySource(source, options), name, options);
|
|
110
203
|
};
|
|
204
|
+
const getQueryParam = (source, name, options) => {
|
|
205
|
+
return getQueryParamValues(source, name, options)[0];
|
|
206
|
+
};
|
|
111
207
|
const strippedParamsCache = /* @__PURE__ */ new WeakMap();
|
|
112
208
|
const getStrippedParamsSet = (params) => {
|
|
113
209
|
let cached = strippedParamsCache.get(params);
|
|
@@ -121,6 +217,7 @@ const ipv4Regex = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/;
|
|
|
121
217
|
const ipv6Regex = /^([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}$/i;
|
|
122
218
|
const wwwPrefixRegex = /^(?:www\.)+(?=.*\.)/;
|
|
123
219
|
const ipv6BracketsRegex = /^\[|\]$/g;
|
|
220
|
+
const hostnameLabelRegex = /^[a-z0-9_-]+$/i;
|
|
124
221
|
const unreservedCharsRegex = /[a-zA-Z0-9._~-]/;
|
|
125
222
|
const httpsLetterRegex = /s/i;
|
|
126
223
|
const schemePrefixRegex = /^https?:\/\//;
|
|
@@ -145,12 +242,13 @@ const validUrlRegex = /^https?:\/\/(?:www\.|[a-vx-z0-9])/i;
|
|
|
145
242
|
const schemeSeparator = String.raw`\.*[:\s=\\/][:\s=.\\/]*`;
|
|
146
243
|
const separatorChar = String.raw`(?:[:\s=.\\/]|%20|%c2%a0)`;
|
|
147
244
|
const leadingSchemeSeparator = String.raw`\.*(?::${separatorChar}*|[\s=\\/]${separatorChar}+)`;
|
|
148
|
-
const doubledSchemeRegex = /* @__PURE__ */ new RegExp(String.raw`^\/?[htps]{2,7}${leadingSchemeSeparator}([htps]{2,7})(?!:\d|[^/?#\\]*@)(${schemeSeparator})
|
|
149
|
-
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");
|
|
150
247
|
const isSchemeToken = (token, separator) => {
|
|
151
248
|
const lowered = token.toLowerCase();
|
|
152
249
|
return `${token}${separator}`.includes(":") || lowered.includes("t") && lowered.includes("p");
|
|
153
250
|
};
|
|
251
|
+
const brokenSlashEscapeRegex = /^[^/]*\/[,.]/;
|
|
154
252
|
const fixMalformedScheme = (url) => {
|
|
155
253
|
if (validUrlRegex.test(url) && !doubledSchemeRegex.test(url)) return url;
|
|
156
254
|
const doubledMatch = doubledSchemeRegex.exec(url);
|
|
@@ -158,6 +256,7 @@ const fixMalformedScheme = (url) => {
|
|
|
158
256
|
const inner = doubledMatch[1];
|
|
159
257
|
const www = doubledMatch[3];
|
|
160
258
|
const rest = url.slice(doubledMatch[0].length);
|
|
259
|
+
if (brokenSlashEscapeRegex.test(`${doubledMatch[2]}${rest}`)) return url;
|
|
161
260
|
return `${httpsLetterRegex.test(inner) ? "https://" : "http://"}${www ? "www." : ""}${rest}`;
|
|
162
261
|
}
|
|
163
262
|
const singleMatch = singleMalformedRegex.exec(url);
|
|
@@ -165,10 +264,32 @@ const fixMalformedScheme = (url) => {
|
|
|
165
264
|
const fullMatch = singleMatch[0];
|
|
166
265
|
const www = singleMatch[3];
|
|
167
266
|
const rest = url.slice(fullMatch.length);
|
|
267
|
+
if (brokenSlashEscapeRegex.test(`${singleMatch[2]}${rest}`)) return url;
|
|
168
268
|
return `${httpsLetterRegex.test(fullMatch) ? "https://" : "http://"}${www ? "www." : ""}${rest}`;
|
|
169
269
|
}
|
|
170
270
|
return url;
|
|
171
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
|
+
};
|
|
172
293
|
const segmentEdgeSpace = "(?:\\s|%(?:09|0A|0D|20))";
|
|
173
294
|
const valueEdgeSpace = "(?:\\s|\\+|%(?:09|0A|0D|20))";
|
|
174
295
|
new RegExp(`^${segmentEdgeSpace}+|(?<!${segmentEdgeSpace})${segmentEdgeSpace}+$`, "gi");
|
|
@@ -227,6 +348,7 @@ const resolveUrl = (url, base) => {
|
|
|
227
348
|
resolvedUrl = trimmedUrl.includes("&") ? decodeHTMLStrict(trimmedUrl) : trimmedUrl;
|
|
228
349
|
resolvedUrl = resolveFeedScheme(resolvedUrl);
|
|
229
350
|
if (!base || schemeColonRegex.test(resolvedUrl) || missingColonSchemeRegex.test(resolvedUrl)) resolvedUrl = fixMalformedScheme(resolvedUrl);
|
|
351
|
+
resolvedUrl = fixMalformedHost(resolvedUrl);
|
|
230
352
|
if (base) {
|
|
231
353
|
const resolved = parseUrl(resolvedUrl, base) ?? parseUrl(resolvedUrl);
|
|
232
354
|
if (!resolved) return;
|
|
@@ -238,23 +360,43 @@ const resolveUrl = (url, base) => {
|
|
|
238
360
|
if (!parsed || !isHttpUrl(parsed)) return;
|
|
239
361
|
return parsed.href;
|
|
240
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
|
+
};
|
|
241
375
|
const decodeAndNormalizeEncoding = (value) => {
|
|
242
376
|
if (!value.includes("%")) return value;
|
|
243
|
-
return value.replace(
|
|
244
|
-
const charCode = Number.parseInt(hex, 16);
|
|
377
|
+
return value.replace(percentEscapeRegex, (hex) => {
|
|
378
|
+
const charCode = Number.parseInt(hex.slice(1), 16);
|
|
245
379
|
const char = String.fromCharCode(charCode);
|
|
246
380
|
if (unreservedCharsRegex.test(char)) return char;
|
|
247
|
-
return
|
|
381
|
+
return hex.toUpperCase();
|
|
248
382
|
});
|
|
249
383
|
};
|
|
250
|
-
const
|
|
251
|
-
const
|
|
384
|
+
const decodeQueryComponent = (component) => {
|
|
385
|
+
const spaced = component.replace(plusRegex, " ");
|
|
252
386
|
try {
|
|
253
|
-
return decodeURIComponent(
|
|
387
|
+
return decodeURIComponent(spaced);
|
|
254
388
|
} catch {
|
|
255
|
-
return
|
|
389
|
+
return spaced;
|
|
256
390
|
}
|
|
257
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
|
+
};
|
|
258
400
|
const compareQueryPairs = (a, b) => {
|
|
259
401
|
const keyA = decodeQueryKey(a);
|
|
260
402
|
const keyB = decodeQueryKey(b);
|
|
@@ -268,41 +410,46 @@ const lowercaseQueryPair = (pair) => {
|
|
|
268
410
|
});
|
|
269
411
|
};
|
|
270
412
|
const normalizeUrl = (url, options) => {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
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()));
|
|
296
443
|
}
|
|
297
|
-
if (options.
|
|
298
|
-
|
|
299
|
-
let result = parsed.href;
|
|
300
|
-
if (options.stripRootSlash && result === `${parsed.origin}/`) result = parsed.origin;
|
|
301
|
-
if (options.stripScheme ?? options.stripProtocol) result = result.replace(schemePrefixRegex, "");
|
|
302
|
-
return result;
|
|
303
|
-
} catch {
|
|
304
|
-
return url;
|
|
444
|
+
if (options.lowercaseQuery) pairs = pairs.map(lowercaseQueryPair);
|
|
445
|
+
parsed.search = pairs.join("&");
|
|
305
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;
|
|
306
453
|
};
|
|
307
454
|
const stripWww = (hostname) => {
|
|
308
455
|
return hostname.replace(wwwPrefixRegex, "");
|
|
@@ -310,6 +457,11 @@ const stripWww = (hostname) => {
|
|
|
310
457
|
const isIpAddress = (hostname) => {
|
|
311
458
|
return ipv4Regex.test(hostname) || ipv6Regex.test(hostname.replace(ipv6BracketsRegex, ""));
|
|
312
459
|
};
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
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) => {
|