initial commit
This commit is contained in:
21
node_modules/parse-url/LICENSE
generated
vendored
Normal file
21
node_modules/parse-url/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-22 Ionică Bizău <bizauionica@gmail.com> (https://ionicabizau.net)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
412
node_modules/parse-url/README.md
generated
vendored
Normal file
412
node_modules/parse-url/README.md
generated
vendored
Normal file
@@ -0,0 +1,412 @@
|
||||
<!-- Please do not edit this file. Edit the `blah` field in the `package.json` instead. If in doubt, open an issue. -->
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# parse-url
|
||||
|
||||
[![Support me on Patreon][badge_patreon]][patreon] [![Buy me a book][badge_amazon]][amazon] [![PayPal][badge_paypal_donate]][paypal-donations] [](https://github.com/IonicaBizau/ama) [](https://www.npmjs.com/package/parse-url) [](https://www.npmjs.com/package/parse-url) [](https://www.codementor.io/johnnyb?utm_source=github&utm_medium=button&utm_term=johnnyb&utm_campaign=github)
|
||||
|
||||
<a href="https://www.buymeacoffee.com/H96WwChMy" target="_blank"><img src="https://www.buymeacoffee.com/assets/img/custom_images/yellow_img.png" alt="Buy Me A Coffee"></a>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
> An advanced url parser supporting git urls too.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
For low-level path parsing, check out [`parse-path`](https://github.com/IonicaBizau/parse-path). This very module is designed to parse urls. By default the urls are normalized.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## :cloud: Installation
|
||||
|
||||
```sh
|
||||
# Using npm
|
||||
npm install --save parse-url
|
||||
|
||||
# Using yarn
|
||||
yarn add parse-url
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## :clipboard: Example
|
||||
|
||||
|
||||
|
||||
```js
|
||||
// Dependencies
|
||||
import parseUrl from "../lib/index.js";
|
||||
|
||||
console.log(parseUrl("http://ionicabizau.net/blog"))
|
||||
// {
|
||||
// protocols: [ 'http' ],
|
||||
// protocol: 'http',
|
||||
// port: '',
|
||||
// resource: 'ionicabizau.net',
|
||||
// user: '',
|
||||
// password: '',
|
||||
// pathname: '/blog',
|
||||
// hash: '',
|
||||
// search: '',
|
||||
// href: 'http://ionicabizau.net/blog',
|
||||
// query: {}
|
||||
// }
|
||||
|
||||
console.log(parseUrl("http://domain.com/path/name?foo=bar&bar=42#some-hash"))
|
||||
// {
|
||||
// protocols: [ 'http' ],
|
||||
// protocol: 'http',
|
||||
// port: '',
|
||||
// resource: 'domain.com',
|
||||
// user: '',
|
||||
// password: '',
|
||||
// pathname: '/path/name',
|
||||
// hash: 'some-hash',
|
||||
// search: 'foo=bar&bar=42',
|
||||
// href: 'http://domain.com/path/name?foo=bar&bar=42#some-hash',
|
||||
// query: { foo: 'bar', bar: '42' }
|
||||
// }
|
||||
|
||||
// If you want to parse fancy Git urls, turn off the automatic url normalization
|
||||
console.log(parseUrl("git+ssh://git@host.xz/path/name.git", false))
|
||||
// {
|
||||
// protocols: [ 'git', 'ssh' ],
|
||||
// protocol: 'git',
|
||||
// port: '',
|
||||
// resource: 'host.xz',
|
||||
// user: 'git',
|
||||
// password: '',
|
||||
// pathname: '/path/name.git',
|
||||
// hash: '',
|
||||
// search: '',
|
||||
// href: 'git+ssh://git@host.xz/path/name.git',
|
||||
// query: {}
|
||||
// }
|
||||
|
||||
console.log(parseUrl("git@github.com:IonicaBizau/git-stats.git", false))
|
||||
// {
|
||||
// protocols: [ 'ssh' ],
|
||||
// protocol: 'ssh',
|
||||
// port: '',
|
||||
// resource: 'github.com',
|
||||
// user: 'git',
|
||||
// password: '',
|
||||
// pathname: '/IonicaBizau/git-stats.git',
|
||||
// hash: '',
|
||||
// search: '',
|
||||
// href: 'git@github.com:IonicaBizau/git-stats.git',
|
||||
// query: {}
|
||||
// }
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## :question: Get Help
|
||||
|
||||
There are few ways to get help:
|
||||
|
||||
|
||||
|
||||
1. Please [post questions on Stack Overflow](https://stackoverflow.com/questions/ask). You can open issues with questions, as long you add a link to your Stack Overflow question.
|
||||
2. For bug reports and feature requests, open issues. :bug:
|
||||
3. For direct and quick help, you can [use Codementor](https://www.codementor.io/johnnyb). :rocket:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## :memo: Documentation
|
||||
|
||||
|
||||
### `interopDefaultLegacy()`
|
||||
#__PURE__
|
||||
|
||||
### `parseUrl(url, normalize)`
|
||||
Parses the input url.
|
||||
|
||||
**Note**: This *throws* if invalid urls are provided.
|
||||
|
||||
#### Params
|
||||
|
||||
- **String** `url`: The input url.
|
||||
- **Boolean|Object** `normalize`: Whether to normalize the url or not. Default is `false`. If `true`, the url will
|
||||
be normalized. If an object, it will be the
|
||||
options object sent to [`normalize-url`](https://github.com/sindresorhus/normalize-url).
|
||||
|
||||
For SSH urls, normalize won't work.
|
||||
|
||||
#### Return
|
||||
- **Object** An object containing the following fields:
|
||||
- `protocols` (Array): An array with the url protocols (usually it has one element).
|
||||
- `protocol` (String): The first protocol, `"ssh"` (if the url is a ssh url) or `"file"`.
|
||||
- `port` (null|Number): The domain port.
|
||||
- `resource` (String): The url domain (including subdomains).
|
||||
- `user` (String): The authentication user (usually for ssh urls).
|
||||
- `pathname` (String): The url pathname.
|
||||
- `hash` (String): The url hash.
|
||||
- `search` (String): The url querystring value.
|
||||
- `href` (String): The input url.
|
||||
- `query` (Object): The url querystring, parsed as object.
|
||||
- `parse_failed` (Boolean): Whether the parsing failed or not.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## :yum: How to contribute
|
||||
Have an idea? Found a bug? See [how to contribute][contributing].
|
||||
|
||||
|
||||
## :sparkling_heart: Support my projects
|
||||
I open-source almost everything I can, and I try to reply to everyone needing help using these projects. Obviously,
|
||||
this takes time. You can integrate and use these projects in your applications *for free*! You can even change the source code and redistribute (even resell it).
|
||||
|
||||
However, if you get some profit from this or just want to encourage me to continue creating stuff, there are few ways you can do it:
|
||||
|
||||
|
||||
- Starring and sharing the projects you like :rocket:
|
||||
- [![Buy me a book][badge_amazon]][amazon]—I love books! I will remember you after years if you buy me one. :grin: :book:
|
||||
- [![PayPal][badge_paypal]][paypal-donations]—You can make one-time donations via PayPal. I'll probably buy a ~~coffee~~ tea. :tea:
|
||||
- [![Support me on Patreon][badge_patreon]][patreon]—Set up a recurring monthly donation and you will get interesting news about what I'm doing (things that I don't share with everyone).
|
||||
- **Bitcoin**—You can send me bitcoins at this address (or scanning the code below): `1P9BRsmazNQcuyTxEqveUsnf5CERdq35V6`
|
||||
|
||||

|
||||
|
||||
|
||||
Thanks! :heart:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## :dizzy: Where is this library used?
|
||||
If you are using this library in one of your projects, add it in this list. :sparkles:
|
||||
|
||||
- `git-up`
|
||||
- `@semantic-release/gitlab`
|
||||
- `lien`
|
||||
- `stun`
|
||||
- `@open-wa/wa-automate`
|
||||
- `kakapo`
|
||||
- `parse-db-uri`
|
||||
- `fuge-runner`
|
||||
- `url-local`
|
||||
- `build-plugin-ssr`
|
||||
- `rucksack`
|
||||
- `egg-muc-custom-loader`
|
||||
- `hologit`
|
||||
- `@enkeledi/react-native-week-month-date-picker`
|
||||
- `normalize-ssh`
|
||||
- `robots-agent`
|
||||
- `warp-api`
|
||||
- `normalize-id`
|
||||
- `xl-git-up`
|
||||
- `warp-server`
|
||||
- `@hemith/react-native-tnk`
|
||||
- `@kriblet/wa-automate`
|
||||
- `@notnuzzel/crawl`
|
||||
- `gitlab-backup-util-harduino`
|
||||
- `miguelcostero-ng2-toasty`
|
||||
- `native-kakao-login`
|
||||
- `npm_one_1_2_3`
|
||||
- `react-native-biometric-authenticate`
|
||||
- `react-native-arunmeena1987`
|
||||
- `react-native-contact-list`
|
||||
- `react-native-payu-payment-testing`
|
||||
- `react-native-is7`
|
||||
- `react-native-my-first-try-arun-ramya`
|
||||
- `react-native-kakao-maps`
|
||||
- `react-native-ytximkit`
|
||||
- `rn-adyen-dropin`
|
||||
- `begg`
|
||||
- `@positionex/position-sdk`
|
||||
- `@corelmax/react-native-my2c2p-sdk`
|
||||
- `@felipesimmi/react-native-datalogic-module`
|
||||
- `@hawkingnetwork/react-native-tab-view`
|
||||
- `@jprustv/sulla-hotfix`
|
||||
- `@mergulhao/wa-automate`
|
||||
- `cli-live-tutorial`
|
||||
- `drowl-base-theme-iconset`
|
||||
- `native-apple-login`
|
||||
- `react-native-cplus`
|
||||
- `npm_qwerty`
|
||||
- `vrt-cli`
|
||||
- `vue-cli-plugin-ice-builder`
|
||||
- `react-native-arunjeyam1987`
|
||||
- `soajs.repositories`
|
||||
- `ssh-host-manager`
|
||||
- `native-zip`
|
||||
- `graphmilker`
|
||||
- `react-native-bubble-chart`
|
||||
- `verify-aws-sns-signature`
|
||||
- `@dataparty/api`
|
||||
- `react-native-flyy`
|
||||
- `@react-18-pdf/root`
|
||||
- `@apardellass/react-native-audio-stream`
|
||||
- `@geeky-apo/react-native-advanced-clipboard`
|
||||
- `@hsui/plugin-wss`
|
||||
- `blitzzz`
|
||||
- `candlelabssdk`
|
||||
- `@roshub/api`
|
||||
- `@saad27/react-native-bottom-tab-tour`
|
||||
- `generator-bootstrap-boilerplate-template`
|
||||
- `npm_one_12_34_1_`
|
||||
- `npm_one_2_2`
|
||||
- `payutesting`
|
||||
- `react-native-responsive-size`
|
||||
- `vue-cli-plugin-ut-builder`
|
||||
- `xbuilder-forms`
|
||||
- `deploy-versioning`
|
||||
- `eval-spider`
|
||||
- `homebridge-pushcutter`
|
||||
- `@con-test/react-native-concent-common`
|
||||
- `tumblr-text`
|
||||
- `react-native-shekhar-bridge-test`
|
||||
- `loast`
|
||||
- `react-feedback-sdk`
|
||||
- `@oiti/documentoscopy-react-native`
|
||||
- `@snyk/sweater-comb`
|
||||
- `@angga30prabu/wa-modified`
|
||||
- `@hstech/utils`
|
||||
- `birken-react-native-community-image-editor`
|
||||
- `get-tarball-cli`
|
||||
- `luojia-cli-dev`
|
||||
- `reac-native-arun-ramya-test`
|
||||
- `react-native-plugpag-wrapper`
|
||||
- `react-native-pulsator-native`
|
||||
- `react-native-arun-ramya-test`
|
||||
- `react-native-arunramya151`
|
||||
- `react-native-transtracker-library`
|
||||
- `workpad`
|
||||
- `delta-screen`
|
||||
- `microbe.js`
|
||||
- `ndla-source-map-resolver`
|
||||
- `@jfilipe-sparta/react-native-module_2`
|
||||
- `cogoportutils`
|
||||
- `@lakutata-module/service`
|
||||
- `@buganto/client`
|
||||
- `@mockswitch/cli`
|
||||
- `angularvezba`
|
||||
- `api-reach-react-native-fix`
|
||||
- `react-native-syan-photo-picker`
|
||||
- `@wecraftapps/react-native-use-keyboard`
|
||||
- `hui-plugin-wss`
|
||||
- `l2forlerna`
|
||||
- `native-google-login`
|
||||
- `raact-native-arunramya151`
|
||||
- `react-native-modal-progress-bar`
|
||||
- `react-native-test-module-hhh`
|
||||
- `react-native-jsi-device-info`
|
||||
- `react-native-badge-control`
|
||||
- `wander-cli`
|
||||
- `heroku-wp-environment-sync`
|
||||
- `hubot-will-it-connect`
|
||||
- `normalize-ssh-url`
|
||||
- `ba-js-cookie-banner`
|
||||
- `ts-scraper`
|
||||
- `electron-info`
|
||||
- `rn-tm-notify`
|
||||
- `native-date-picker-module`
|
||||
- `@ndla/source-map-resolver`
|
||||
- `@jimengio/mocked-proxy`
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## :scroll: License
|
||||
|
||||
[MIT][license] © [Ionică Bizău][website]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
[license]: /LICENSE
|
||||
[website]: https://ionicabizau.net
|
||||
[contributing]: /CONTRIBUTING.md
|
||||
[docs]: /DOCUMENTATION.md
|
||||
[badge_patreon]: https://ionicabizau.github.io/badges/patreon.svg
|
||||
[badge_amazon]: https://ionicabizau.github.io/badges/amazon.svg
|
||||
[badge_paypal]: https://ionicabizau.github.io/badges/paypal.svg
|
||||
[badge_paypal_donate]: https://ionicabizau.github.io/badges/paypal_donate.svg
|
||||
[patreon]: https://www.patreon.com/ionicabizau
|
||||
[amazon]: http://amzn.eu/hRo9sIZ
|
||||
[paypal-donations]: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=RVXDDLKKLQRJW
|
||||
340
node_modules/parse-url/dist/index.js
generated
vendored
Executable file
340
node_modules/parse-url/dist/index.js
generated
vendored
Executable file
@@ -0,0 +1,340 @@
|
||||
'use strict';
|
||||
|
||||
var parsePath = require('parse-path');
|
||||
|
||||
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
||||
|
||||
var parsePath__default = /*#__PURE__*/_interopDefaultLegacy(parsePath);
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
|
||||
const DATA_URL_DEFAULT_MIME_TYPE = 'text/plain';
|
||||
const DATA_URL_DEFAULT_CHARSET = 'us-ascii';
|
||||
|
||||
const testParameter = (name, filters) => filters.some(filter => filter instanceof RegExp ? filter.test(name) : filter === name);
|
||||
|
||||
const normalizeDataURL = (urlString, {stripHash}) => {
|
||||
const match = /^data:(?<type>[^,]*?),(?<data>[^#]*?)(?:#(?<hash>.*))?$/.exec(urlString);
|
||||
|
||||
if (!match) {
|
||||
throw new Error(`Invalid URL: ${urlString}`);
|
||||
}
|
||||
|
||||
let {type, data, hash} = match.groups;
|
||||
const mediaType = type.split(';');
|
||||
hash = stripHash ? '' : hash;
|
||||
|
||||
let isBase64 = false;
|
||||
if (mediaType[mediaType.length - 1] === 'base64') {
|
||||
mediaType.pop();
|
||||
isBase64 = true;
|
||||
}
|
||||
|
||||
// Lowercase MIME type
|
||||
const mimeType = (mediaType.shift() || '').toLowerCase();
|
||||
const attributes = mediaType
|
||||
.map(attribute => {
|
||||
let [key, value = ''] = attribute.split('=').map(string => string.trim());
|
||||
|
||||
// Lowercase `charset`
|
||||
if (key === 'charset') {
|
||||
value = value.toLowerCase();
|
||||
|
||||
if (value === DATA_URL_DEFAULT_CHARSET) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
return `${key}${value ? `=${value}` : ''}`;
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
const normalizedMediaType = [
|
||||
...attributes,
|
||||
];
|
||||
|
||||
if (isBase64) {
|
||||
normalizedMediaType.push('base64');
|
||||
}
|
||||
|
||||
if (normalizedMediaType.length > 0 || (mimeType && mimeType !== DATA_URL_DEFAULT_MIME_TYPE)) {
|
||||
normalizedMediaType.unshift(mimeType);
|
||||
}
|
||||
|
||||
return `data:${normalizedMediaType.join(';')},${isBase64 ? data.trim() : data}${hash ? `#${hash}` : ''}`;
|
||||
};
|
||||
|
||||
function normalizeUrl(urlString, options) {
|
||||
options = {
|
||||
defaultProtocol: 'http:',
|
||||
normalizeProtocol: true,
|
||||
forceHttp: false,
|
||||
forceHttps: false,
|
||||
stripAuthentication: true,
|
||||
stripHash: false,
|
||||
stripTextFragment: true,
|
||||
stripWWW: true,
|
||||
removeQueryParameters: [/^utm_\w+/i],
|
||||
removeTrailingSlash: true,
|
||||
removeSingleSlash: true,
|
||||
removeDirectoryIndex: false,
|
||||
sortQueryParameters: true,
|
||||
...options,
|
||||
};
|
||||
|
||||
urlString = urlString.trim();
|
||||
|
||||
// Data URL
|
||||
if (/^data:/i.test(urlString)) {
|
||||
return normalizeDataURL(urlString, options);
|
||||
}
|
||||
|
||||
if (/^view-source:/i.test(urlString)) {
|
||||
throw new Error('`view-source:` is not supported as it is a non-standard protocol');
|
||||
}
|
||||
|
||||
const hasRelativeProtocol = urlString.startsWith('//');
|
||||
const isRelativeUrl = !hasRelativeProtocol && /^\.*\//.test(urlString);
|
||||
|
||||
// Prepend protocol
|
||||
if (!isRelativeUrl) {
|
||||
urlString = urlString.replace(/^(?!(?:\w+:)?\/\/)|^\/\//, options.defaultProtocol);
|
||||
}
|
||||
|
||||
const urlObject = new URL(urlString);
|
||||
|
||||
if (options.forceHttp && options.forceHttps) {
|
||||
throw new Error('The `forceHttp` and `forceHttps` options cannot be used together');
|
||||
}
|
||||
|
||||
if (options.forceHttp && urlObject.protocol === 'https:') {
|
||||
urlObject.protocol = 'http:';
|
||||
}
|
||||
|
||||
if (options.forceHttps && urlObject.protocol === 'http:') {
|
||||
urlObject.protocol = 'https:';
|
||||
}
|
||||
|
||||
// Remove auth
|
||||
if (options.stripAuthentication) {
|
||||
urlObject.username = '';
|
||||
urlObject.password = '';
|
||||
}
|
||||
|
||||
// Remove hash
|
||||
if (options.stripHash) {
|
||||
urlObject.hash = '';
|
||||
} else if (options.stripTextFragment) {
|
||||
urlObject.hash = urlObject.hash.replace(/#?:~:text.*?$/i, '');
|
||||
}
|
||||
|
||||
// Remove duplicate slashes if not preceded by a protocol
|
||||
// NOTE: This could be implemented using a single negative lookbehind
|
||||
// regex, but we avoid that to maintain compatibility with older js engines
|
||||
// which do not have support for that feature.
|
||||
if (urlObject.pathname) {
|
||||
// TODO: Replace everything below with `urlObject.pathname = urlObject.pathname.replace(/(?<!\b[a-z][a-z\d+\-.]{1,50}:)\/{2,}/g, '/');` when Safari supports negative lookbehind.
|
||||
|
||||
// Split the string by occurrences of this protocol regex, and perform
|
||||
// duplicate-slash replacement on the strings between those occurrences
|
||||
// (if any).
|
||||
const protocolRegex = /\b[a-z][a-z\d+\-.]{1,50}:\/\//g;
|
||||
|
||||
let lastIndex = 0;
|
||||
let result = '';
|
||||
for (;;) {
|
||||
const match = protocolRegex.exec(urlObject.pathname);
|
||||
if (!match) {
|
||||
break;
|
||||
}
|
||||
|
||||
const protocol = match[0];
|
||||
const protocolAtIndex = match.index;
|
||||
const intermediate = urlObject.pathname.slice(lastIndex, protocolAtIndex);
|
||||
|
||||
result += intermediate.replace(/\/{2,}/g, '/');
|
||||
result += protocol;
|
||||
lastIndex = protocolAtIndex + protocol.length;
|
||||
}
|
||||
|
||||
const remnant = urlObject.pathname.slice(lastIndex, urlObject.pathname.length);
|
||||
result += remnant.replace(/\/{2,}/g, '/');
|
||||
|
||||
urlObject.pathname = result;
|
||||
}
|
||||
|
||||
// Decode URI octets
|
||||
if (urlObject.pathname) {
|
||||
try {
|
||||
urlObject.pathname = decodeURI(urlObject.pathname);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
// Remove directory index
|
||||
if (options.removeDirectoryIndex === true) {
|
||||
options.removeDirectoryIndex = [/^index\.[a-z]+$/];
|
||||
}
|
||||
|
||||
if (Array.isArray(options.removeDirectoryIndex) && options.removeDirectoryIndex.length > 0) {
|
||||
let pathComponents = urlObject.pathname.split('/');
|
||||
const lastComponent = pathComponents[pathComponents.length - 1];
|
||||
|
||||
if (testParameter(lastComponent, options.removeDirectoryIndex)) {
|
||||
pathComponents = pathComponents.slice(0, -1);
|
||||
urlObject.pathname = pathComponents.slice(1).join('/') + '/';
|
||||
}
|
||||
}
|
||||
|
||||
if (urlObject.hostname) {
|
||||
// Remove trailing dot
|
||||
urlObject.hostname = urlObject.hostname.replace(/\.$/, '');
|
||||
|
||||
// Remove `www.`
|
||||
if (options.stripWWW && /^www\.(?!www\.)[a-z\-\d]{1,63}\.[a-z.\-\d]{2,63}$/.test(urlObject.hostname)) {
|
||||
// Each label should be max 63 at length (min: 1).
|
||||
// Source: https://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names
|
||||
// Each TLD should be up to 63 characters long (min: 2).
|
||||
// It is technically possible to have a single character TLD, but none currently exist.
|
||||
urlObject.hostname = urlObject.hostname.replace(/^www\./, '');
|
||||
}
|
||||
}
|
||||
|
||||
// Remove query unwanted parameters
|
||||
if (Array.isArray(options.removeQueryParameters)) {
|
||||
// eslint-disable-next-line unicorn/no-useless-spread -- We are intentionally spreading to get a copy.
|
||||
for (const key of [...urlObject.searchParams.keys()]) {
|
||||
if (testParameter(key, options.removeQueryParameters)) {
|
||||
urlObject.searchParams.delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (options.removeQueryParameters === true) {
|
||||
urlObject.search = '';
|
||||
}
|
||||
|
||||
// Sort query parameters
|
||||
if (options.sortQueryParameters) {
|
||||
urlObject.searchParams.sort();
|
||||
|
||||
// Calling `.sort()` encodes the search parameters, so we need to decode them again.
|
||||
try {
|
||||
urlObject.search = decodeURIComponent(urlObject.search);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
if (options.removeTrailingSlash) {
|
||||
urlObject.pathname = urlObject.pathname.replace(/\/$/, '');
|
||||
}
|
||||
|
||||
const oldUrlString = urlString;
|
||||
|
||||
// Take advantage of many of the Node `url` normalizations
|
||||
urlString = urlObject.toString();
|
||||
|
||||
if (!options.removeSingleSlash && urlObject.pathname === '/' && !oldUrlString.endsWith('/') && urlObject.hash === '') {
|
||||
urlString = urlString.replace(/\/$/, '');
|
||||
}
|
||||
|
||||
// Remove ending `/` unless removeSingleSlash is false
|
||||
if ((options.removeTrailingSlash || urlObject.pathname === '/') && urlObject.hash === '' && options.removeSingleSlash) {
|
||||
urlString = urlString.replace(/\/$/, '');
|
||||
}
|
||||
|
||||
// Restore relative protocol, if applicable
|
||||
if (hasRelativeProtocol && !options.normalizeProtocol) {
|
||||
urlString = urlString.replace(/^http:\/\//, '//');
|
||||
}
|
||||
|
||||
// Remove http/https
|
||||
if (options.stripProtocol) {
|
||||
urlString = urlString.replace(/^(?:https?:)?\/\//, '');
|
||||
}
|
||||
|
||||
return urlString;
|
||||
}
|
||||
|
||||
// Dependencies
|
||||
|
||||
/**
|
||||
* parseUrl
|
||||
* Parses the input url.
|
||||
*
|
||||
* **Note**: This *throws* if invalid urls are provided.
|
||||
*
|
||||
* @name parseUrl
|
||||
* @function
|
||||
* @param {String} url The input url.
|
||||
* @param {Boolean|Object} normalize Whether to normalize the url or not.
|
||||
* Default is `false`. If `true`, the url will
|
||||
* be normalized. If an object, it will be the
|
||||
* options object sent to [`normalize-url`](https://github.com/sindresorhus/normalize-url).
|
||||
*
|
||||
* For SSH urls, normalize won't work.
|
||||
*
|
||||
* @return {Object} An object containing the following fields:
|
||||
*
|
||||
* - `protocols` (Array): An array with the url protocols (usually it has one element).
|
||||
* - `protocol` (String): The first protocol, `"ssh"` (if the url is a ssh url) or `"file"`.
|
||||
* - `port` (null|Number): The domain port.
|
||||
* - `resource` (String): The url domain (including subdomains).
|
||||
* - `user` (String): The authentication user (usually for ssh urls).
|
||||
* - `pathname` (String): The url pathname.
|
||||
* - `hash` (String): The url hash.
|
||||
* - `search` (String): The url querystring value.
|
||||
* - `href` (String): The input url.
|
||||
* - `query` (Object): The url querystring, parsed as object.
|
||||
* - `parse_failed` (Boolean): Whether the parsing failed or not.
|
||||
*/
|
||||
const parseUrl = (url, normalize = false) => {
|
||||
|
||||
// Constants
|
||||
const GIT_RE = /^(?:([a-z_][a-z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:]([\~,\.\w,\-,\_,\/]+?(?:\.git|\/)?)$/;
|
||||
|
||||
const throwErr = msg => {
|
||||
const err = new Error(msg);
|
||||
err.subject_url = url;
|
||||
throw err
|
||||
};
|
||||
|
||||
if (typeof url !== "string" || !url.trim()) {
|
||||
throwErr("Invalid url.");
|
||||
}
|
||||
|
||||
if (url.length > parseUrl.MAX_INPUT_LENGTH) {
|
||||
throwErr("Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH.");
|
||||
}
|
||||
|
||||
if (normalize) {
|
||||
if (typeof normalize !== "object") {
|
||||
normalize = {
|
||||
stripHash: false
|
||||
};
|
||||
}
|
||||
url = normalizeUrl(url, normalize);
|
||||
}
|
||||
|
||||
const parsed = parsePath__default["default"](url);
|
||||
|
||||
// Potential git-ssh urls
|
||||
if (parsed.parse_failed) {
|
||||
const matched = parsed.href.match(GIT_RE);
|
||||
|
||||
if (matched) {
|
||||
parsed.protocols = ["ssh"];
|
||||
parsed.protocol = "ssh";
|
||||
parsed.resource = matched[2];
|
||||
parsed.host = matched[2];
|
||||
parsed.user = matched[1];
|
||||
parsed.pathname = `/${matched[3]}`;
|
||||
parsed.parse_failed = false;
|
||||
} else {
|
||||
throwErr("URL parsing failed.");
|
||||
}
|
||||
}
|
||||
|
||||
return parsed;
|
||||
};
|
||||
|
||||
parseUrl.MAX_INPUT_LENGTH = 2048;
|
||||
|
||||
module.exports = parseUrl;
|
||||
334
node_modules/parse-url/dist/index.mjs
generated
vendored
Executable file
334
node_modules/parse-url/dist/index.mjs
generated
vendored
Executable file
@@ -0,0 +1,334 @@
|
||||
import parsePath from 'parse-path';
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
|
||||
const DATA_URL_DEFAULT_MIME_TYPE = 'text/plain';
|
||||
const DATA_URL_DEFAULT_CHARSET = 'us-ascii';
|
||||
|
||||
const testParameter = (name, filters) => filters.some(filter => filter instanceof RegExp ? filter.test(name) : filter === name);
|
||||
|
||||
const normalizeDataURL = (urlString, {stripHash}) => {
|
||||
const match = /^data:(?<type>[^,]*?),(?<data>[^#]*?)(?:#(?<hash>.*))?$/.exec(urlString);
|
||||
|
||||
if (!match) {
|
||||
throw new Error(`Invalid URL: ${urlString}`);
|
||||
}
|
||||
|
||||
let {type, data, hash} = match.groups;
|
||||
const mediaType = type.split(';');
|
||||
hash = stripHash ? '' : hash;
|
||||
|
||||
let isBase64 = false;
|
||||
if (mediaType[mediaType.length - 1] === 'base64') {
|
||||
mediaType.pop();
|
||||
isBase64 = true;
|
||||
}
|
||||
|
||||
// Lowercase MIME type
|
||||
const mimeType = (mediaType.shift() || '').toLowerCase();
|
||||
const attributes = mediaType
|
||||
.map(attribute => {
|
||||
let [key, value = ''] = attribute.split('=').map(string => string.trim());
|
||||
|
||||
// Lowercase `charset`
|
||||
if (key === 'charset') {
|
||||
value = value.toLowerCase();
|
||||
|
||||
if (value === DATA_URL_DEFAULT_CHARSET) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
return `${key}${value ? `=${value}` : ''}`;
|
||||
})
|
||||
.filter(Boolean);
|
||||
|
||||
const normalizedMediaType = [
|
||||
...attributes,
|
||||
];
|
||||
|
||||
if (isBase64) {
|
||||
normalizedMediaType.push('base64');
|
||||
}
|
||||
|
||||
if (normalizedMediaType.length > 0 || (mimeType && mimeType !== DATA_URL_DEFAULT_MIME_TYPE)) {
|
||||
normalizedMediaType.unshift(mimeType);
|
||||
}
|
||||
|
||||
return `data:${normalizedMediaType.join(';')},${isBase64 ? data.trim() : data}${hash ? `#${hash}` : ''}`;
|
||||
};
|
||||
|
||||
function normalizeUrl(urlString, options) {
|
||||
options = {
|
||||
defaultProtocol: 'http:',
|
||||
normalizeProtocol: true,
|
||||
forceHttp: false,
|
||||
forceHttps: false,
|
||||
stripAuthentication: true,
|
||||
stripHash: false,
|
||||
stripTextFragment: true,
|
||||
stripWWW: true,
|
||||
removeQueryParameters: [/^utm_\w+/i],
|
||||
removeTrailingSlash: true,
|
||||
removeSingleSlash: true,
|
||||
removeDirectoryIndex: false,
|
||||
sortQueryParameters: true,
|
||||
...options,
|
||||
};
|
||||
|
||||
urlString = urlString.trim();
|
||||
|
||||
// Data URL
|
||||
if (/^data:/i.test(urlString)) {
|
||||
return normalizeDataURL(urlString, options);
|
||||
}
|
||||
|
||||
if (/^view-source:/i.test(urlString)) {
|
||||
throw new Error('`view-source:` is not supported as it is a non-standard protocol');
|
||||
}
|
||||
|
||||
const hasRelativeProtocol = urlString.startsWith('//');
|
||||
const isRelativeUrl = !hasRelativeProtocol && /^\.*\//.test(urlString);
|
||||
|
||||
// Prepend protocol
|
||||
if (!isRelativeUrl) {
|
||||
urlString = urlString.replace(/^(?!(?:\w+:)?\/\/)|^\/\//, options.defaultProtocol);
|
||||
}
|
||||
|
||||
const urlObject = new URL(urlString);
|
||||
|
||||
if (options.forceHttp && options.forceHttps) {
|
||||
throw new Error('The `forceHttp` and `forceHttps` options cannot be used together');
|
||||
}
|
||||
|
||||
if (options.forceHttp && urlObject.protocol === 'https:') {
|
||||
urlObject.protocol = 'http:';
|
||||
}
|
||||
|
||||
if (options.forceHttps && urlObject.protocol === 'http:') {
|
||||
urlObject.protocol = 'https:';
|
||||
}
|
||||
|
||||
// Remove auth
|
||||
if (options.stripAuthentication) {
|
||||
urlObject.username = '';
|
||||
urlObject.password = '';
|
||||
}
|
||||
|
||||
// Remove hash
|
||||
if (options.stripHash) {
|
||||
urlObject.hash = '';
|
||||
} else if (options.stripTextFragment) {
|
||||
urlObject.hash = urlObject.hash.replace(/#?:~:text.*?$/i, '');
|
||||
}
|
||||
|
||||
// Remove duplicate slashes if not preceded by a protocol
|
||||
// NOTE: This could be implemented using a single negative lookbehind
|
||||
// regex, but we avoid that to maintain compatibility with older js engines
|
||||
// which do not have support for that feature.
|
||||
if (urlObject.pathname) {
|
||||
// TODO: Replace everything below with `urlObject.pathname = urlObject.pathname.replace(/(?<!\b[a-z][a-z\d+\-.]{1,50}:)\/{2,}/g, '/');` when Safari supports negative lookbehind.
|
||||
|
||||
// Split the string by occurrences of this protocol regex, and perform
|
||||
// duplicate-slash replacement on the strings between those occurrences
|
||||
// (if any).
|
||||
const protocolRegex = /\b[a-z][a-z\d+\-.]{1,50}:\/\//g;
|
||||
|
||||
let lastIndex = 0;
|
||||
let result = '';
|
||||
for (;;) {
|
||||
const match = protocolRegex.exec(urlObject.pathname);
|
||||
if (!match) {
|
||||
break;
|
||||
}
|
||||
|
||||
const protocol = match[0];
|
||||
const protocolAtIndex = match.index;
|
||||
const intermediate = urlObject.pathname.slice(lastIndex, protocolAtIndex);
|
||||
|
||||
result += intermediate.replace(/\/{2,}/g, '/');
|
||||
result += protocol;
|
||||
lastIndex = protocolAtIndex + protocol.length;
|
||||
}
|
||||
|
||||
const remnant = urlObject.pathname.slice(lastIndex, urlObject.pathname.length);
|
||||
result += remnant.replace(/\/{2,}/g, '/');
|
||||
|
||||
urlObject.pathname = result;
|
||||
}
|
||||
|
||||
// Decode URI octets
|
||||
if (urlObject.pathname) {
|
||||
try {
|
||||
urlObject.pathname = decodeURI(urlObject.pathname);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
// Remove directory index
|
||||
if (options.removeDirectoryIndex === true) {
|
||||
options.removeDirectoryIndex = [/^index\.[a-z]+$/];
|
||||
}
|
||||
|
||||
if (Array.isArray(options.removeDirectoryIndex) && options.removeDirectoryIndex.length > 0) {
|
||||
let pathComponents = urlObject.pathname.split('/');
|
||||
const lastComponent = pathComponents[pathComponents.length - 1];
|
||||
|
||||
if (testParameter(lastComponent, options.removeDirectoryIndex)) {
|
||||
pathComponents = pathComponents.slice(0, -1);
|
||||
urlObject.pathname = pathComponents.slice(1).join('/') + '/';
|
||||
}
|
||||
}
|
||||
|
||||
if (urlObject.hostname) {
|
||||
// Remove trailing dot
|
||||
urlObject.hostname = urlObject.hostname.replace(/\.$/, '');
|
||||
|
||||
// Remove `www.`
|
||||
if (options.stripWWW && /^www\.(?!www\.)[a-z\-\d]{1,63}\.[a-z.\-\d]{2,63}$/.test(urlObject.hostname)) {
|
||||
// Each label should be max 63 at length (min: 1).
|
||||
// Source: https://en.wikipedia.org/wiki/Hostname#Restrictions_on_valid_host_names
|
||||
// Each TLD should be up to 63 characters long (min: 2).
|
||||
// It is technically possible to have a single character TLD, but none currently exist.
|
||||
urlObject.hostname = urlObject.hostname.replace(/^www\./, '');
|
||||
}
|
||||
}
|
||||
|
||||
// Remove query unwanted parameters
|
||||
if (Array.isArray(options.removeQueryParameters)) {
|
||||
// eslint-disable-next-line unicorn/no-useless-spread -- We are intentionally spreading to get a copy.
|
||||
for (const key of [...urlObject.searchParams.keys()]) {
|
||||
if (testParameter(key, options.removeQueryParameters)) {
|
||||
urlObject.searchParams.delete(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (options.removeQueryParameters === true) {
|
||||
urlObject.search = '';
|
||||
}
|
||||
|
||||
// Sort query parameters
|
||||
if (options.sortQueryParameters) {
|
||||
urlObject.searchParams.sort();
|
||||
|
||||
// Calling `.sort()` encodes the search parameters, so we need to decode them again.
|
||||
try {
|
||||
urlObject.search = decodeURIComponent(urlObject.search);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
if (options.removeTrailingSlash) {
|
||||
urlObject.pathname = urlObject.pathname.replace(/\/$/, '');
|
||||
}
|
||||
|
||||
const oldUrlString = urlString;
|
||||
|
||||
// Take advantage of many of the Node `url` normalizations
|
||||
urlString = urlObject.toString();
|
||||
|
||||
if (!options.removeSingleSlash && urlObject.pathname === '/' && !oldUrlString.endsWith('/') && urlObject.hash === '') {
|
||||
urlString = urlString.replace(/\/$/, '');
|
||||
}
|
||||
|
||||
// Remove ending `/` unless removeSingleSlash is false
|
||||
if ((options.removeTrailingSlash || urlObject.pathname === '/') && urlObject.hash === '' && options.removeSingleSlash) {
|
||||
urlString = urlString.replace(/\/$/, '');
|
||||
}
|
||||
|
||||
// Restore relative protocol, if applicable
|
||||
if (hasRelativeProtocol && !options.normalizeProtocol) {
|
||||
urlString = urlString.replace(/^http:\/\//, '//');
|
||||
}
|
||||
|
||||
// Remove http/https
|
||||
if (options.stripProtocol) {
|
||||
urlString = urlString.replace(/^(?:https?:)?\/\//, '');
|
||||
}
|
||||
|
||||
return urlString;
|
||||
}
|
||||
|
||||
// Dependencies
|
||||
|
||||
/**
|
||||
* parseUrl
|
||||
* Parses the input url.
|
||||
*
|
||||
* **Note**: This *throws* if invalid urls are provided.
|
||||
*
|
||||
* @name parseUrl
|
||||
* @function
|
||||
* @param {String} url The input url.
|
||||
* @param {Boolean|Object} normalize Whether to normalize the url or not.
|
||||
* Default is `false`. If `true`, the url will
|
||||
* be normalized. If an object, it will be the
|
||||
* options object sent to [`normalize-url`](https://github.com/sindresorhus/normalize-url).
|
||||
*
|
||||
* For SSH urls, normalize won't work.
|
||||
*
|
||||
* @return {Object} An object containing the following fields:
|
||||
*
|
||||
* - `protocols` (Array): An array with the url protocols (usually it has one element).
|
||||
* - `protocol` (String): The first protocol, `"ssh"` (if the url is a ssh url) or `"file"`.
|
||||
* - `port` (null|Number): The domain port.
|
||||
* - `resource` (String): The url domain (including subdomains).
|
||||
* - `user` (String): The authentication user (usually for ssh urls).
|
||||
* - `pathname` (String): The url pathname.
|
||||
* - `hash` (String): The url hash.
|
||||
* - `search` (String): The url querystring value.
|
||||
* - `href` (String): The input url.
|
||||
* - `query` (Object): The url querystring, parsed as object.
|
||||
* - `parse_failed` (Boolean): Whether the parsing failed or not.
|
||||
*/
|
||||
const parseUrl = (url, normalize = false) => {
|
||||
|
||||
// Constants
|
||||
const GIT_RE = /^(?:([a-z_][a-z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:]([\~,\.\w,\-,\_,\/]+?(?:\.git|\/)?)$/;
|
||||
|
||||
const throwErr = msg => {
|
||||
const err = new Error(msg);
|
||||
err.subject_url = url;
|
||||
throw err
|
||||
};
|
||||
|
||||
if (typeof url !== "string" || !url.trim()) {
|
||||
throwErr("Invalid url.");
|
||||
}
|
||||
|
||||
if (url.length > parseUrl.MAX_INPUT_LENGTH) {
|
||||
throwErr("Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH.");
|
||||
}
|
||||
|
||||
if (normalize) {
|
||||
if (typeof normalize !== "object") {
|
||||
normalize = {
|
||||
stripHash: false
|
||||
};
|
||||
}
|
||||
url = normalizeUrl(url, normalize);
|
||||
}
|
||||
|
||||
const parsed = parsePath(url);
|
||||
|
||||
// Potential git-ssh urls
|
||||
if (parsed.parse_failed) {
|
||||
const matched = parsed.href.match(GIT_RE);
|
||||
|
||||
if (matched) {
|
||||
parsed.protocols = ["ssh"];
|
||||
parsed.protocol = "ssh";
|
||||
parsed.resource = matched[2];
|
||||
parsed.host = matched[2];
|
||||
parsed.user = matched[1];
|
||||
parsed.pathname = `/${matched[3]}`;
|
||||
parsed.parse_failed = false;
|
||||
} else {
|
||||
throwErr("URL parsing failed.");
|
||||
}
|
||||
}
|
||||
|
||||
return parsed;
|
||||
};
|
||||
|
||||
parseUrl.MAX_INPUT_LENGTH = 2048;
|
||||
|
||||
export { parseUrl as default };
|
||||
18
node_modules/parse-url/index.d.ts
generated
vendored
Normal file
18
node_modules/parse-url/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
declare interface ParsedUrl {
|
||||
protocols: string[];
|
||||
protocol: string;
|
||||
port?: string;
|
||||
resource: string;
|
||||
user: string;
|
||||
pathname: string;
|
||||
hash: string;
|
||||
search: string;
|
||||
href: string;
|
||||
query: {
|
||||
[key: string]: any;
|
||||
}
|
||||
}
|
||||
|
||||
declare function parseUrl(url: string, normalize?: boolean | Object): ParsedUrl;
|
||||
|
||||
export = parseUrl
|
||||
67
node_modules/parse-url/package.json
generated
vendored
Normal file
67
node_modules/parse-url/package.json
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"name": "parse-url",
|
||||
"version": "8.1.0",
|
||||
"description": "An advanced url parser supporting git urls too.",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
"types": "./index.d.ts",
|
||||
"exports": {
|
||||
"types": "./index.d.ts",
|
||||
"require": "./dist/index.js",
|
||||
"import": "./dist/index.mjs"
|
||||
},
|
||||
"directories": {
|
||||
"example": "example",
|
||||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node test/index.mjs",
|
||||
"build": "pkgroll"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/IonicaBizau/parse-url.git"
|
||||
},
|
||||
"keywords": [
|
||||
"parse",
|
||||
"url",
|
||||
"node",
|
||||
"git",
|
||||
"advanced"
|
||||
],
|
||||
"author": "Ionică Bizău <bizauionica@gmail.com> (https://ionicabizau.net)",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/IonicaBizau/parse-url/issues"
|
||||
},
|
||||
"homepage": "https://github.com/IonicaBizau/parse-url",
|
||||
"devDependencies": {
|
||||
"normalize-url": "^7.0.3",
|
||||
"pkgroll": "^1.4.0",
|
||||
"tester": "^1.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"parse-path": "^7.0.0"
|
||||
},
|
||||
"files": [
|
||||
"bin/",
|
||||
"app/",
|
||||
"lib/",
|
||||
"dist/",
|
||||
"src/",
|
||||
"scripts/",
|
||||
"resources/",
|
||||
"menu/",
|
||||
"cli.js",
|
||||
"index.js",
|
||||
"index.d.ts",
|
||||
"bloggify.js",
|
||||
"bloggify.json",
|
||||
"bloggify/"
|
||||
],
|
||||
"blah": {
|
||||
"description": [
|
||||
"For low-level path parsing, check out [`parse-path`](https://github.com/IonicaBizau/parse-path). This very module is designed to parse urls. By default the urls are normalized."
|
||||
]
|
||||
}
|
||||
}
|
||||
87
node_modules/parse-url/src/index.js
generated
vendored
Normal file
87
node_modules/parse-url/src/index.js
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
// Dependencies
|
||||
import parsePath from "parse-path";
|
||||
import normalizeUrl from "normalize-url";
|
||||
|
||||
/**
|
||||
* parseUrl
|
||||
* Parses the input url.
|
||||
*
|
||||
* **Note**: This *throws* if invalid urls are provided.
|
||||
*
|
||||
* @name parseUrl
|
||||
* @function
|
||||
* @param {String} url The input url.
|
||||
* @param {Boolean|Object} normalize Whether to normalize the url or not.
|
||||
* Default is `false`. If `true`, the url will
|
||||
* be normalized. If an object, it will be the
|
||||
* options object sent to [`normalize-url`](https://github.com/sindresorhus/normalize-url).
|
||||
*
|
||||
* For SSH urls, normalize won't work.
|
||||
*
|
||||
* @return {Object} An object containing the following fields:
|
||||
*
|
||||
* - `protocols` (Array): An array with the url protocols (usually it has one element).
|
||||
* - `protocol` (String): The first protocol, `"ssh"` (if the url is a ssh url) or `"file"`.
|
||||
* - `port` (null|Number): The domain port.
|
||||
* - `resource` (String): The url domain (including subdomains).
|
||||
* - `user` (String): The authentication user (usually for ssh urls).
|
||||
* - `pathname` (String): The url pathname.
|
||||
* - `hash` (String): The url hash.
|
||||
* - `search` (String): The url querystring value.
|
||||
* - `href` (String): The input url.
|
||||
* - `query` (Object): The url querystring, parsed as object.
|
||||
* - `parse_failed` (Boolean): Whether the parsing failed or not.
|
||||
*/
|
||||
const parseUrl = (url, normalize = false) => {
|
||||
|
||||
// Constants
|
||||
const GIT_RE = /^(?:([a-z_][a-z0-9_-]{0,31})@|https?:\/\/)([\w\.\-@]+)[\/:]([\~,\.\w,\-,\_,\/]+?(?:\.git|\/)?)$/
|
||||
|
||||
const throwErr = msg => {
|
||||
const err = new Error(msg)
|
||||
err.subject_url = url
|
||||
throw err
|
||||
}
|
||||
|
||||
if (typeof url !== "string" || !url.trim()) {
|
||||
throwErr("Invalid url.")
|
||||
}
|
||||
|
||||
if (url.length > parseUrl.MAX_INPUT_LENGTH) {
|
||||
throwErr("Input exceeds maximum length. If needed, change the value of parseUrl.MAX_INPUT_LENGTH.")
|
||||
}
|
||||
|
||||
if (normalize) {
|
||||
if (typeof normalize !== "object") {
|
||||
normalize = {
|
||||
stripHash: false
|
||||
}
|
||||
}
|
||||
url = normalizeUrl(url, normalize)
|
||||
}
|
||||
|
||||
const parsed = parsePath(url)
|
||||
|
||||
// Potential git-ssh urls
|
||||
if (parsed.parse_failed) {
|
||||
const matched = parsed.href.match(GIT_RE)
|
||||
|
||||
if (matched) {
|
||||
parsed.protocols = ["ssh"]
|
||||
parsed.protocol = "ssh"
|
||||
parsed.resource = matched[2]
|
||||
parsed.host = matched[2]
|
||||
parsed.user = matched[1]
|
||||
parsed.pathname = `/${matched[3]}`
|
||||
parsed.parse_failed = false
|
||||
} else {
|
||||
throwErr("URL parsing failed.")
|
||||
}
|
||||
}
|
||||
|
||||
return parsed;
|
||||
}
|
||||
|
||||
parseUrl.MAX_INPUT_LENGTH = 2048
|
||||
|
||||
export default parseUrl;
|
||||
Reference in New Issue
Block a user